diff options
Diffstat (limited to 'arch/arm')
49 files changed, 1007 insertions, 1677 deletions
diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c index af11dcdb7e2..25b79a29736 100644 --- a/arch/arm/mach-omap2/am35xx-emac.c +++ b/arch/arm/mach-omap2/am35xx-emac.c @@ -62,8 +62,7 @@ static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh,  {  	struct platform_device *pdev; -	pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len, -				 NULL, 0, false); +	pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len);  	if (IS_ERR(pdev)) {  		WARN(1, "Can't build omap_device for %s:%s.\n",  		     oh->class->name, oh->name); diff --git a/arch/arm/mach-omap2/cclock2420_data.c b/arch/arm/mach-omap2/cclock2420_data.c index ab7e952d207..0f0a97c1fcc 100644 --- a/arch/arm/mach-omap2/cclock2420_data.c +++ b/arch/arm/mach-omap2/cclock2420_data.c @@ -622,15 +622,10 @@ static struct clk_hw_omap gpios_fck_hw = {  DEFINE_STRUCT_CLK(gpios_fck, gpios_fck_parent_names, aes_ick_ops); -static struct clk wu_l4_ick; - -DEFINE_STRUCT_CLK_HW_OMAP(wu_l4_ick, "wkup_clkdm"); -DEFINE_STRUCT_CLK(wu_l4_ick, dpll_ck_parent_names, core_ck_ops); -  static struct clk gpios_ick;  static const char *gpios_ick_parent_names[] = { -	"wu_l4_ick", +	"sys_ck",  };  static struct clk_hw_omap gpios_ick_hw = { @@ -1682,13 +1677,6 @@ static struct clk_hw_omap wdt1_ick_hw = {  DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops); -static struct clk wdt1_osc_ck; - -static const struct clk_ops wdt1_osc_ck_ops = {}; - -DEFINE_STRUCT_CLK_HW_OMAP(wdt1_osc_ck, NULL); -DEFINE_STRUCT_CLK(wdt1_osc_ck, sys_ck_parent_names, wdt1_osc_ck_ops); -  static struct clk wdt3_fck;  static struct clk_hw_omap wdt3_fck_hw = { @@ -1767,7 +1755,6 @@ static struct omap_clk omap2420_clks[] = {  	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_242X),  	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_242X),  	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_242X), -	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_242X),  	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_242X),  	CLK(NULL,	"sys_clkout",	&sys_clkout,	CK_242X),  	CLK(NULL,	"sys_clkout2_src", &sys_clkout2_src, CK_242X), @@ -1797,7 +1784,6 @@ static struct omap_clk omap2420_clks[] = {  	/* L4 domain clocks */  	CLK(NULL,	"l4_ck",	&l4_ck,		CK_242X),  	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_242X), -	CLK(NULL,	"wu_l4_ick",	&wu_l4_ick,	CK_242X),  	/* virtual meta-group clock */  	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_242X),  	/* general l4 interface ck, multi-parent functional clk */ diff --git a/arch/arm/mach-omap2/cclock2430_data.c b/arch/arm/mach-omap2/cclock2430_data.c index eb3dab68d53..aed8f74ca07 100644 --- a/arch/arm/mach-omap2/cclock2430_data.c +++ b/arch/arm/mach-omap2/cclock2430_data.c @@ -601,15 +601,10 @@ static struct clk_hw_omap gpios_fck_hw = {  DEFINE_STRUCT_CLK(gpios_fck, gpio5_fck_parent_names, aes_ick_ops); -static struct clk wu_l4_ick; - -DEFINE_STRUCT_CLK_HW_OMAP(wu_l4_ick, "wkup_clkdm"); -DEFINE_STRUCT_CLK(wu_l4_ick, dpll_ck_parent_names, core_ck_ops); -  static struct clk gpios_ick;  static const char *gpios_ick_parent_names[] = { -	"wu_l4_ick", +	"sys_ck",  };  static struct clk_hw_omap gpios_ick_hw = { @@ -1811,13 +1806,6 @@ static struct clk_hw_omap wdt1_ick_hw = {  DEFINE_STRUCT_CLK(wdt1_ick, gpios_ick_parent_names, aes_ick_ops); -static struct clk wdt1_osc_ck; - -static const struct clk_ops wdt1_osc_ck_ops = {}; - -DEFINE_STRUCT_CLK_HW_OMAP(wdt1_osc_ck, NULL); -DEFINE_STRUCT_CLK(wdt1_osc_ck, sys_ck_parent_names, wdt1_osc_ck_ops); -  static struct clk wdt4_fck;  static struct clk_hw_omap wdt4_fck_hw = { @@ -1869,7 +1857,6 @@ static struct omap_clk omap2430_clks[] = {  	CLK(NULL,	"func_96m_ck",	&func_96m_ck,	CK_243X),  	CLK(NULL,	"func_48m_ck",	&func_48m_ck,	CK_243X),  	CLK(NULL,	"func_12m_ck",	&func_12m_ck,	CK_243X), -	CLK(NULL,	"ck_wdt1_osc",	&wdt1_osc_ck,	CK_243X),  	CLK(NULL,	"sys_clkout_src", &sys_clkout_src, CK_243X),  	CLK(NULL,	"sys_clkout",	&sys_clkout,	CK_243X),  	CLK(NULL,	"emul_ck",	&emul_ck,	CK_243X), @@ -1898,7 +1885,6 @@ static struct omap_clk omap2430_clks[] = {  	/* L4 domain clocks */  	CLK(NULL,	"l4_ck",	&l4_ck,		CK_243X),  	CLK(NULL,	"ssi_l4_ick",	&ssi_l4_ick,	CK_243X), -	CLK(NULL,	"wu_l4_ick",	&wu_l4_ick,	CK_243X),  	/* virtual meta-group clock */  	CLK(NULL,	"virt_prcm_set", &virt_prcm_set, CK_243X),  	/* general l4 interface ck, multi-parent functional clk */ diff --git a/arch/arm/mach-omap2/cclock44xx_data.c b/arch/arm/mach-omap2/cclock44xx_data.c index a2cc046b47f..cebe2b31943 100644 --- a/arch/arm/mach-omap2/cclock44xx_data.c +++ b/arch/arm/mach-omap2/cclock44xx_data.c @@ -16,6 +16,10 @@   * XXX Some of the ES1 clocks have been removed/changed; once support   * is added for discriminating clocks by ES level, these should be added back   * in. + * + * XXX All of the remaining MODULEMODE clock nodes should be removed + * once the drivers are updated to use pm_runtime or to use the appropriate + * upstream clock node for rate/parent selection.   */  #include <linux/kernel.h> @@ -315,7 +319,7 @@ DEFINE_CLK_DIVIDER(dpll_abe_m2_ck, "dpll_abe_ck", &dpll_abe_ck, 0x0,  		   OMAP4430_CM_DIV_M2_DPLL_ABE, OMAP4430_DPLL_CLKOUT_DIV_SHIFT,  		   OMAP4430_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); -static const struct clk_ops dmic_fck_ops = { +static const struct clk_ops dpll_hsd_ops = {  	.enable		= &omap2_dflt_clk_enable,  	.disable	= &omap2_dflt_clk_disable,  	.is_enabled	= &omap2_dflt_clk_is_enabled, @@ -325,6 +329,12 @@ static const struct clk_ops dmic_fck_ops = {  	.init		= &omap2_init_clk_clkdm,  }; +static const struct clk_ops func_dmic_abe_gfclk_ops = { +	.recalc_rate	= &omap2_clksel_recalc, +	.get_parent	= &omap2_clksel_find_parent_index, +	.set_parent	= &omap2_clksel_set_parent, +}; +  static const char *dpll_core_m3x2_ck_parents[] = {  	"dpll_core_x2_ck",  }; @@ -340,7 +350,7 @@ DEFINE_CLK_OMAP_MUX_GATE(dpll_core_m3x2_ck, NULL, dpll_core_m3x2_div,  			 OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,  			 OMAP4430_CM_DIV_M3_DPLL_CORE,  			 OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL, -			 dpll_core_m3x2_ck_parents, dmic_fck_ops); +			 dpll_core_m3x2_ck_parents, dpll_hsd_ops);  DEFINE_CLK_OMAP_HSDIVIDER(dpll_core_m7x2_ck, "dpll_core_x2_ck",  			  &dpll_core_x2_ck, 0x0, OMAP4430_CM_DIV_M7_DPLL_CORE, @@ -547,7 +557,7 @@ DEFINE_CLK_OMAP_MUX_GATE(dpll_per_m3x2_ck, NULL, dpll_per_m3x2_div,  			 OMAP4430_DPLL_CLKOUTHIF_DIV_MASK,  			 OMAP4430_CM_DIV_M3_DPLL_PER,  			 OMAP4430_DPLL_CLKOUTHIF_GATE_CTRL_SHIFT, NULL, -			 dpll_per_m3x2_ck_parents, dmic_fck_ops); +			 dpll_per_m3x2_ck_parents, dpll_hsd_ops);  DEFINE_CLK_OMAP_HSDIVIDER(dpll_per_m4x2_ck, "dpll_per_x2_ck", &dpll_per_x2_ck,  			  0x0, OMAP4430_CM_DIV_M4_DPLL_PER, @@ -749,10 +759,6 @@ DEFINE_CLK_GATE(aes2_fck, "l3_div_ck", &l3_div_ck, 0x0,  		OMAP4430_CM_L4SEC_AES2_CLKCTRL,  		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); -DEFINE_CLK_GATE(aess_fck, "aess_fclk", &aess_fclk, 0x0, -		OMAP4430_CM1_ABE_AESS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, -		0x0, NULL); -  DEFINE_CLK_GATE(bandgap_fclk, "sys_32k_ck", &sys_32k_ck, 0x0,  		OMAP4430_CM_WKUP_BANDGAP_CLKCTRL,  		OMAP4430_OPTFCLKEN_BGAP_32K_SHIFT, 0x0, NULL); @@ -774,11 +780,6 @@ DEFINE_CLK_GATE(bandgap_ts_fclk, "div_ts_ck", &div_ts_ck, 0x0,  		OMAP4460_OPTFCLKEN_TS_FCLK_SHIFT,  		0x0, NULL); -DEFINE_CLK_GATE(des3des_fck, "l4_div_ck", &l4_div_ck, 0x0, -		OMAP4430_CM_L4SEC_DES3DES_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, -		0x0, NULL); -  static const char *dmic_sync_mux_ck_parents[] = {  	"abe_24m_fclk", "syc_clk_div_ck", "func_24m_clk",  }; @@ -795,23 +796,13 @@ static const struct clksel func_dmic_abe_gfclk_sel[] = {  	{ .parent = NULL },  }; -static const char *dmic_fck_parents[] = { +static const char *func_dmic_abe_gfclk_parents[] = {  	"dmic_sync_mux_ck", "pad_clks_ck", "slimbus_clk",  }; -/* Merged func_dmic_abe_gfclk into dmic */ -static struct clk dmic_fck; - -DEFINE_CLK_OMAP_MUX_GATE(dmic_fck, "abe_clkdm", func_dmic_abe_gfclk_sel, -			 OMAP4430_CM1_ABE_DMIC_CLKCTRL, -			 OMAP4430_CLKSEL_SOURCE_MASK, -			 OMAP4430_CM1_ABE_DMIC_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 dmic_fck_parents, dmic_fck_ops); - -DEFINE_CLK_GATE(dsp_fck, "dpll_iva_m4x2_ck", &dpll_iva_m4x2_ck, 0x0, -		OMAP4430_CM_TESLA_TESLA_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); +DEFINE_CLK_OMAP_MUX(func_dmic_abe_gfclk, "abe_clkdm", func_dmic_abe_gfclk_sel, +		    OMAP4430_CM1_ABE_DMIC_CLKCTRL, OMAP4430_CLKSEL_SOURCE_MASK, +		    func_dmic_abe_gfclk_parents, func_dmic_abe_gfclk_ops);  DEFINE_CLK_GATE(dss_sys_clk, "syc_clk_div_ck", &syc_clk_div_ck, 0x0,  		OMAP4430_CM_DSS_DSS_CLKCTRL, @@ -833,177 +824,57 @@ DEFINE_CLK_GATE(dss_fck, "l3_div_ck", &l3_div_ck, 0x0,  		OMAP4430_CM_DSS_DSS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT,  		0x0, NULL); -DEFINE_CLK_GATE(efuse_ctrl_cust_fck, "sys_clkin_ck", &sys_clkin_ck, 0x0, -		OMAP4430_CM_CEFUSE_CEFUSE_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(emif1_fck, "ddrphy_ck", &ddrphy_ck, 0x0, -		OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(emif2_fck, "ddrphy_ck", &ddrphy_ck, 0x0, -		OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); -  DEFINE_CLK_DIVIDER(fdif_fck, "dpll_per_m4x2_ck", &dpll_per_m4x2_ck, 0x0,  		   OMAP4430_CM_CAM_FDIF_CLKCTRL, OMAP4430_CLKSEL_FCLK_SHIFT,  		   OMAP4430_CLKSEL_FCLK_WIDTH, CLK_DIVIDER_POWER_OF_TWO, NULL); -DEFINE_CLK_GATE(fpka_fck, "l4_div_ck", &l4_div_ck, 0x0, -		OMAP4430_CM_L4SEC_PKAEIP29_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); -  DEFINE_CLK_GATE(gpio1_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,  		OMAP4430_CM_WKUP_GPIO1_CLKCTRL,  		OMAP4430_OPTFCLKEN_DBCLK_SHIFT,	0x0, NULL); -DEFINE_CLK_GATE(gpio1_ick, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck, 0x0, -		OMAP4430_CM_WKUP_GPIO1_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); -  DEFINE_CLK_GATE(gpio2_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,  		OMAP4430_CM_L4PER_GPIO2_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,  		0x0, NULL); -DEFINE_CLK_GATE(gpio2_ick, "l4_div_ck", &l4_div_ck, 0x0, -		OMAP4430_CM_L4PER_GPIO2_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); -  DEFINE_CLK_GATE(gpio3_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,  		OMAP4430_CM_L4PER_GPIO3_CLKCTRL,  		OMAP4430_OPTFCLKEN_DBCLK_SHIFT, 0x0, NULL); -DEFINE_CLK_GATE(gpio3_ick, "l4_div_ck", &l4_div_ck, 0x0, -		OMAP4430_CM_L4PER_GPIO3_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); -  DEFINE_CLK_GATE(gpio4_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,  		OMAP4430_CM_L4PER_GPIO4_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,  		0x0, NULL); -DEFINE_CLK_GATE(gpio4_ick, "l4_div_ck", &l4_div_ck, 0x0, -		OMAP4430_CM_L4PER_GPIO4_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); -  DEFINE_CLK_GATE(gpio5_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,  		OMAP4430_CM_L4PER_GPIO5_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,  		0x0, NULL); -DEFINE_CLK_GATE(gpio5_ick, "l4_div_ck", &l4_div_ck, 0x0, -		OMAP4430_CM_L4PER_GPIO5_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); -  DEFINE_CLK_GATE(gpio6_dbclk, "sys_32k_ck", &sys_32k_ck, 0x0,  		OMAP4430_CM_L4PER_GPIO6_CLKCTRL, OMAP4430_OPTFCLKEN_DBCLK_SHIFT,  		0x0, NULL); -DEFINE_CLK_GATE(gpio6_ick, "l4_div_ck", &l4_div_ck, 0x0, -		OMAP4430_CM_L4PER_GPIO6_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(gpmc_ick, "l3_div_ck", &l3_div_ck, 0x0, -		OMAP4430_CM_L3_2_GPMC_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT, -		0x0, NULL); -  static const struct clksel sgx_clk_mux_sel[] = {  	{ .parent = &dpll_core_m7x2_ck, .rates = div_1_0_rates },  	{ .parent = &dpll_per_m7x2_ck, .rates = div_1_1_rates },  	{ .parent = NULL },  }; -static const char *gpu_fck_parents[] = { +static const char *sgx_clk_mux_parents[] = {  	"dpll_core_m7x2_ck", "dpll_per_m7x2_ck",  }; -/* Merged sgx_clk_mux into gpu */ -DEFINE_CLK_OMAP_MUX_GATE(gpu_fck, "l3_gfx_clkdm", sgx_clk_mux_sel, -			 OMAP4430_CM_GFX_GFX_CLKCTRL, -			 OMAP4430_CLKSEL_SGX_FCLK_MASK, -			 OMAP4430_CM_GFX_GFX_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 gpu_fck_parents, dmic_fck_ops); - -DEFINE_CLK_GATE(hdq1w_fck, "func_12m_fclk", &func_12m_fclk, 0x0, -		OMAP4430_CM_L4PER_HDQ1W_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); +DEFINE_CLK_OMAP_MUX(sgx_clk_mux, "l3_gfx_clkdm", sgx_clk_mux_sel, +		    OMAP4430_CM_GFX_GFX_CLKCTRL, OMAP4430_CLKSEL_SGX_FCLK_MASK, +		    sgx_clk_mux_parents, func_dmic_abe_gfclk_ops);  DEFINE_CLK_DIVIDER(hsi_fck, "dpll_per_m2x2_ck", &dpll_per_m2x2_ck, 0x0,  		   OMAP4430_CM_L3INIT_HSI_CLKCTRL, OMAP4430_CLKSEL_24_25_SHIFT,  		   OMAP4430_CLKSEL_24_25_WIDTH, CLK_DIVIDER_POWER_OF_TWO,  		   NULL); -DEFINE_CLK_GATE(i2c1_fck, "func_96m_fclk", &func_96m_fclk, 0x0, -		OMAP4430_CM_L4PER_I2C1_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(i2c2_fck, "func_96m_fclk", &func_96m_fclk, 0x0, -		OMAP4430_CM_L4PER_I2C2_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(i2c3_fck, "func_96m_fclk", &func_96m_fclk, 0x0, -		OMAP4430_CM_L4PER_I2C3_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(i2c4_fck, "func_96m_fclk", &func_96m_fclk, 0x0, -		OMAP4430_CM_L4PER_I2C4_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(ipu_fck, "ducati_clk_mux_ck", &ducati_clk_mux_ck, 0x0, -		OMAP4430_CM_DUCATI_DUCATI_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); -  DEFINE_CLK_GATE(iss_ctrlclk, "func_96m_fclk", &func_96m_fclk, 0x0,  		OMAP4430_CM_CAM_ISS_CLKCTRL, OMAP4430_OPTFCLKEN_CTRLCLK_SHIFT,  		0x0, NULL); -DEFINE_CLK_GATE(iss_fck, "ducati_clk_mux_ck", &ducati_clk_mux_ck, 0x0, -		OMAP4430_CM_CAM_ISS_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, -		0x0, NULL); - -DEFINE_CLK_GATE(iva_fck, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, 0x0, -		OMAP4430_CM_IVAHD_IVAHD_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(kbd_fck, "sys_32k_ck", &sys_32k_ck, 0x0, -		OMAP4430_CM_WKUP_KEYBOARD_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -static struct clk l3_instr_ick; - -static const char *l3_instr_ick_parent_names[] = { -	"l3_div_ck", -}; - -static const struct clk_ops l3_instr_ick_ops = { -	.enable		= &omap2_dflt_clk_enable, -	.disable	= &omap2_dflt_clk_disable, -	.is_enabled	= &omap2_dflt_clk_is_enabled, -	.init		= &omap2_init_clk_clkdm, -}; - -static struct clk_hw_omap l3_instr_ick_hw = { -	.hw = { -		.clk = &l3_instr_ick, -	}, -	.enable_reg	= OMAP4430_CM_L3INSTR_L3_INSTR_CLKCTRL, -	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL_SHIFT, -	.clkdm_name	= "l3_instr_clkdm", -}; - -DEFINE_STRUCT_CLK(l3_instr_ick, l3_instr_ick_parent_names, l3_instr_ick_ops); - -static struct clk l3_main_3_ick; -static struct clk_hw_omap l3_main_3_ick_hw = { -	.hw = { -		.clk = &l3_main_3_ick, -	}, -	.enable_reg	= OMAP4430_CM_L3INSTR_L3_3_CLKCTRL, -	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL_SHIFT, -	.clkdm_name	= "l3_instr_clkdm", -}; - -DEFINE_STRUCT_CLK(l3_main_3_ick, l3_instr_ick_parent_names, l3_instr_ick_ops); -  DEFINE_CLK_MUX(mcasp_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,  	       OMAP4430_CM1_ABE_MCASP_CLKCTRL,  	       OMAP4430_CLKSEL_INTERNAL_SOURCE_SHIFT, @@ -1016,17 +887,13 @@ static const struct clksel func_mcasp_abe_gfclk_sel[] = {  	{ .parent = NULL },  }; -static const char *mcasp_fck_parents[] = { +static const char *func_mcasp_abe_gfclk_parents[] = {  	"mcasp_sync_mux_ck", "pad_clks_ck", "slimbus_clk",  }; -/* Merged func_mcasp_abe_gfclk into mcasp */ -DEFINE_CLK_OMAP_MUX_GATE(mcasp_fck, "abe_clkdm", func_mcasp_abe_gfclk_sel, -			 OMAP4430_CM1_ABE_MCASP_CLKCTRL, -			 OMAP4430_CLKSEL_SOURCE_MASK, -			 OMAP4430_CM1_ABE_MCASP_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 mcasp_fck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(func_mcasp_abe_gfclk, "abe_clkdm", func_mcasp_abe_gfclk_sel, +		    OMAP4430_CM1_ABE_MCASP_CLKCTRL, OMAP4430_CLKSEL_SOURCE_MASK, +		    func_mcasp_abe_gfclk_parents, func_dmic_abe_gfclk_ops);  DEFINE_CLK_MUX(mcbsp1_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,  	       OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, @@ -1040,17 +907,14 @@ static const struct clksel func_mcbsp1_gfclk_sel[] = {  	{ .parent = NULL },  }; -static const char *mcbsp1_fck_parents[] = { +static const char *func_mcbsp1_gfclk_parents[] = {  	"mcbsp1_sync_mux_ck", "pad_clks_ck", "slimbus_clk",  }; -/* Merged func_mcbsp1_gfclk into mcbsp1 */ -DEFINE_CLK_OMAP_MUX_GATE(mcbsp1_fck, "abe_clkdm", func_mcbsp1_gfclk_sel, -			 OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, -			 OMAP4430_CLKSEL_SOURCE_MASK, -			 OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 mcbsp1_fck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(func_mcbsp1_gfclk, "abe_clkdm", func_mcbsp1_gfclk_sel, +		    OMAP4430_CM1_ABE_MCBSP1_CLKCTRL, +		    OMAP4430_CLKSEL_SOURCE_MASK, func_mcbsp1_gfclk_parents, +		    func_dmic_abe_gfclk_ops);  DEFINE_CLK_MUX(mcbsp2_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,  	       OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, @@ -1064,17 +928,14 @@ static const struct clksel func_mcbsp2_gfclk_sel[] = {  	{ .parent = NULL },  }; -static const char *mcbsp2_fck_parents[] = { +static const char *func_mcbsp2_gfclk_parents[] = {  	"mcbsp2_sync_mux_ck", "pad_clks_ck", "slimbus_clk",  }; -/* Merged func_mcbsp2_gfclk into mcbsp2 */ -DEFINE_CLK_OMAP_MUX_GATE(mcbsp2_fck, "abe_clkdm", func_mcbsp2_gfclk_sel, -			 OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, -			 OMAP4430_CLKSEL_SOURCE_MASK, -			 OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 mcbsp2_fck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(func_mcbsp2_gfclk, "abe_clkdm", func_mcbsp2_gfclk_sel, +		    OMAP4430_CM1_ABE_MCBSP2_CLKCTRL, +		    OMAP4430_CLKSEL_SOURCE_MASK, func_mcbsp2_gfclk_parents, +		    func_dmic_abe_gfclk_ops);  DEFINE_CLK_MUX(mcbsp3_sync_mux_ck, dmic_sync_mux_ck_parents, NULL, 0x0,  	       OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, @@ -1088,17 +949,14 @@ static const struct clksel func_mcbsp3_gfclk_sel[] = {  	{ .parent = NULL },  }; -static const char *mcbsp3_fck_parents[] = { +static const char *func_mcbsp3_gfclk_parents[] = {  	"mcbsp3_sync_mux_ck", "pad_clks_ck", "slimbus_clk",  }; -/* Merged func_mcbsp3_gfclk into mcbsp3 */ -DEFINE_CLK_OMAP_MUX_GATE(mcbsp3_fck, "abe_clkdm", func_mcbsp3_gfclk_sel, -			 OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, -			 OMAP4430_CLKSEL_SOURCE_MASK, -			 OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 mcbsp3_fck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(func_mcbsp3_gfclk, "abe_clkdm", func_mcbsp3_gfclk_sel, +		    OMAP4430_CM1_ABE_MCBSP3_CLKCTRL, +		    OMAP4430_CLKSEL_SOURCE_MASK, func_mcbsp3_gfclk_parents, +		    func_dmic_abe_gfclk_ops);  static const char *mcbsp4_sync_mux_ck_parents[] = {  	"func_96m_fclk", "per_abe_nc_fclk", @@ -1115,37 +973,14 @@ static const struct clksel per_mcbsp4_gfclk_sel[] = {  	{ .parent = NULL },  }; -static const char *mcbsp4_fck_parents[] = { +static const char *per_mcbsp4_gfclk_parents[] = {  	"mcbsp4_sync_mux_ck", "pad_clks_ck",  }; -/* Merged per_mcbsp4_gfclk into mcbsp4 */ -DEFINE_CLK_OMAP_MUX_GATE(mcbsp4_fck, "l4_per_clkdm", per_mcbsp4_gfclk_sel, -			 OMAP4430_CM_L4PER_MCBSP4_CLKCTRL, -			 OMAP4430_CLKSEL_SOURCE_24_24_MASK, -			 OMAP4430_CM_L4PER_MCBSP4_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 mcbsp4_fck_parents, dmic_fck_ops); - -DEFINE_CLK_GATE(mcpdm_fck, "pad_clks_ck", &pad_clks_ck, 0x0, -		OMAP4430_CM1_ABE_PDM_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, -		0x0, NULL); - -DEFINE_CLK_GATE(mcspi1_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_MCSPI1_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(mcspi2_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_MCSPI2_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(mcspi3_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_MCSPI3_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(mcspi4_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_MCSPI4_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); +DEFINE_CLK_OMAP_MUX(per_mcbsp4_gfclk, "l4_per_clkdm", per_mcbsp4_gfclk_sel, +		    OMAP4430_CM_L4PER_MCBSP4_CLKCTRL, +		    OMAP4430_CLKSEL_SOURCE_24_24_MASK, per_mcbsp4_gfclk_parents, +		    func_dmic_abe_gfclk_ops);  static const struct clksel hsmmc1_fclk_sel[] = {  	{ .parent = &func_64m_fclk, .rates = div_1_0_rates }, @@ -1153,69 +988,22 @@ static const struct clksel hsmmc1_fclk_sel[] = {  	{ .parent = NULL },  }; -static const char *mmc1_fck_parents[] = { +static const char *hsmmc1_fclk_parents[] = {  	"func_64m_fclk", "func_96m_fclk",  }; -/* Merged hsmmc1_fclk into mmc1 */ -DEFINE_CLK_OMAP_MUX_GATE(mmc1_fck, "l3_init_clkdm", hsmmc1_fclk_sel, -			 OMAP4430_CM_L3INIT_MMC1_CLKCTRL, OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM_L3INIT_MMC1_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 mmc1_fck_parents, dmic_fck_ops); - -/* Merged hsmmc2_fclk into mmc2 */ -DEFINE_CLK_OMAP_MUX_GATE(mmc2_fck, "l3_init_clkdm", hsmmc1_fclk_sel, -			 OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM_L3INIT_MMC2_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 mmc1_fck_parents, dmic_fck_ops); - -DEFINE_CLK_GATE(mmc3_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_MMCSD3_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(mmc4_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_MMCSD4_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(mmc5_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_MMCSD5_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(ocp2scp_usb_phy_phy_48m, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, -		OMAP4430_OPTFCLKEN_PHY_48M_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(ocp2scp_usb_phy_ick, "l4_div_ck", &l4_div_ck, 0x0, -		OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, -		OMAP4430_MODULEMODE_HWCTRL_SHIFT, 0x0, NULL); +DEFINE_CLK_OMAP_MUX(hsmmc1_fclk, "l3_init_clkdm", hsmmc1_fclk_sel, +		    OMAP4430_CM_L3INIT_MMC1_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops); -static struct clk ocp_wp_noc_ick; - -static struct clk_hw_omap ocp_wp_noc_ick_hw = { -	.hw = { -		.clk = &ocp_wp_noc_ick, -	}, -	.enable_reg	= OMAP4430_CM_L3INSTR_OCP_WP1_CLKCTRL, -	.enable_bit	= OMAP4430_MODULEMODE_HWCTRL_SHIFT, -	.clkdm_name	= "l3_instr_clkdm", -}; - -DEFINE_STRUCT_CLK(ocp_wp_noc_ick, l3_instr_ick_parent_names, l3_instr_ick_ops); - -DEFINE_CLK_GATE(rng_ick, "l4_div_ck", &l4_div_ck, 0x0, -		OMAP4430_CM_L4SEC_RNG_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT, -		0x0, NULL); +DEFINE_CLK_OMAP_MUX(hsmmc2_fclk, "l3_init_clkdm", hsmmc1_fclk_sel, +		    OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops);  DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0,  		OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL,  		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); -DEFINE_CLK_GATE(sl2if_ick, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, 0x0, -		OMAP4430_CM_IVAHD_SL2_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT, -		0x0, NULL); -  DEFINE_CLK_GATE(slimbus1_fclk_1, "func_24m_clk", &func_24m_clk, 0x0,  		OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,  		OMAP4430_OPTFCLKEN_FCLK1_SHIFT, 0x0, NULL); @@ -1232,10 +1020,6 @@ DEFINE_CLK_GATE(slimbus1_slimbus_clk, "slimbus_clk", &slimbus_clk, 0x0,  		OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL,  		OMAP4430_OPTFCLKEN_SLIMBUS_CLK_11_11_SHIFT, 0x0, NULL); -DEFINE_CLK_GATE(slimbus1_fck, "ocp_abe_iclk", &ocp_abe_iclk, 0x0, -		OMAP4430_CM1_ABE_SLIMBUS_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); -  DEFINE_CLK_GATE(slimbus2_fclk_1, "per_abe_24m_fclk", &per_abe_24m_fclk, 0x0,  		OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,  		OMAP4430_OPTFCLKEN_PERABE24M_GFCLK_SHIFT, 0x0, NULL); @@ -1249,10 +1033,6 @@ DEFINE_CLK_GATE(slimbus2_slimbus_clk, "pad_slimbus_core_clks_ck",  		OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL,  		OMAP4430_OPTFCLKEN_SLIMBUS_CLK_SHIFT, 0x0, NULL); -DEFINE_CLK_GATE(slimbus2_fck, "l4_div_ck", &l4_div_ck, 0x0, -		OMAP4430_CM_L4PER_SLIMBUS2_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); -  DEFINE_CLK_GATE(smartreflex_core_fck, "l4_wkup_clk_mux_ck", &l4_wkup_clk_mux_ck,  		0x0, OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,  		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); @@ -1271,52 +1051,35 @@ static const struct clksel dmt1_clk_mux_sel[] = {  	{ .parent = NULL },  }; -/* Merged dmt1_clk_mux into timer1 */ -DEFINE_CLK_OMAP_MUX_GATE(timer1_fck, "l4_wkup_clkdm", dmt1_clk_mux_sel, -			 OMAP4430_CM_WKUP_TIMER1_CLKCTRL, OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM_WKUP_TIMER1_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(dmt1_clk_mux, "l4_wkup_clkdm", dmt1_clk_mux_sel, +		    OMAP4430_CM_WKUP_TIMER1_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    abe_dpll_bypass_clk_mux_ck_parents, +		    func_dmic_abe_gfclk_ops); -/* Merged cm2_dm10_mux into timer10 */ -DEFINE_CLK_OMAP_MUX_GATE(timer10_fck, "l4_per_clkdm", dmt1_clk_mux_sel, -			 OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, -			 OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(cm2_dm10_mux, "l4_per_clkdm", dmt1_clk_mux_sel, +		    OMAP4430_CM_L4PER_DMTIMER10_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    abe_dpll_bypass_clk_mux_ck_parents, +		    func_dmic_abe_gfclk_ops); -/* Merged cm2_dm11_mux into timer11 */ -DEFINE_CLK_OMAP_MUX_GATE(timer11_fck, "l4_per_clkdm", dmt1_clk_mux_sel, -			 OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, -			 OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(cm2_dm11_mux, "l4_per_clkdm", dmt1_clk_mux_sel, +		    OMAP4430_CM_L4PER_DMTIMER11_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    abe_dpll_bypass_clk_mux_ck_parents, +		    func_dmic_abe_gfclk_ops); -/* Merged cm2_dm2_mux into timer2 */ -DEFINE_CLK_OMAP_MUX_GATE(timer2_fck, "l4_per_clkdm", dmt1_clk_mux_sel, -			 OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, -			 OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(cm2_dm2_mux, "l4_per_clkdm", dmt1_clk_mux_sel, +		    OMAP4430_CM_L4PER_DMTIMER2_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    abe_dpll_bypass_clk_mux_ck_parents, +		    func_dmic_abe_gfclk_ops); -/* Merged cm2_dm3_mux into timer3 */ -DEFINE_CLK_OMAP_MUX_GATE(timer3_fck, "l4_per_clkdm", dmt1_clk_mux_sel, -			 OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL, -			 OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(cm2_dm3_mux, "l4_per_clkdm", dmt1_clk_mux_sel, +		    OMAP4430_CM_L4PER_DMTIMER3_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    abe_dpll_bypass_clk_mux_ck_parents, +		    func_dmic_abe_gfclk_ops); -/* Merged cm2_dm4_mux into timer4 */ -DEFINE_CLK_OMAP_MUX_GATE(timer4_fck, "l4_per_clkdm", dmt1_clk_mux_sel, -			 OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL, -			 OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(cm2_dm4_mux, "l4_per_clkdm", dmt1_clk_mux_sel, +		    OMAP4430_CM_L4PER_DMTIMER4_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    abe_dpll_bypass_clk_mux_ck_parents, +		    func_dmic_abe_gfclk_ops);  static const struct clksel timer5_sync_mux_sel[] = {  	{ .parent = &syc_clk_div_ck, .rates = div_1_0_rates }, @@ -1324,61 +1087,30 @@ static const struct clksel timer5_sync_mux_sel[] = {  	{ .parent = NULL },  }; -static const char *timer5_fck_parents[] = { +static const char *timer5_sync_mux_parents[] = {  	"syc_clk_div_ck", "sys_32k_ck",  }; -/* Merged timer5_sync_mux into timer5 */ -DEFINE_CLK_OMAP_MUX_GATE(timer5_fck, "abe_clkdm", timer5_sync_mux_sel, -			 OMAP4430_CM1_ABE_TIMER5_CLKCTRL, OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM1_ABE_TIMER5_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 timer5_fck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(timer5_sync_mux, "abe_clkdm", timer5_sync_mux_sel, +		    OMAP4430_CM1_ABE_TIMER5_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    timer5_sync_mux_parents, func_dmic_abe_gfclk_ops); -/* Merged timer6_sync_mux into timer6 */ -DEFINE_CLK_OMAP_MUX_GATE(timer6_fck, "abe_clkdm", timer5_sync_mux_sel, -			 OMAP4430_CM1_ABE_TIMER6_CLKCTRL, OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM1_ABE_TIMER6_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 timer5_fck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(timer6_sync_mux, "abe_clkdm", timer5_sync_mux_sel, +		    OMAP4430_CM1_ABE_TIMER6_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    timer5_sync_mux_parents, func_dmic_abe_gfclk_ops); -/* Merged timer7_sync_mux into timer7 */ -DEFINE_CLK_OMAP_MUX_GATE(timer7_fck, "abe_clkdm", timer5_sync_mux_sel, -			 OMAP4430_CM1_ABE_TIMER7_CLKCTRL, OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM1_ABE_TIMER7_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 timer5_fck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(timer7_sync_mux, "abe_clkdm", timer5_sync_mux_sel, +		    OMAP4430_CM1_ABE_TIMER7_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    timer5_sync_mux_parents, func_dmic_abe_gfclk_ops); -/* Merged timer8_sync_mux into timer8 */ -DEFINE_CLK_OMAP_MUX_GATE(timer8_fck, "abe_clkdm", timer5_sync_mux_sel, -			 OMAP4430_CM1_ABE_TIMER8_CLKCTRL, OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM1_ABE_TIMER8_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 timer5_fck_parents, dmic_fck_ops); +DEFINE_CLK_OMAP_MUX(timer8_sync_mux, "abe_clkdm", timer5_sync_mux_sel, +		    OMAP4430_CM1_ABE_TIMER8_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    timer5_sync_mux_parents, func_dmic_abe_gfclk_ops); -/* Merged cm2_dm9_mux into timer9 */ -DEFINE_CLK_OMAP_MUX_GATE(timer9_fck, "l4_per_clkdm", dmt1_clk_mux_sel, -			 OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL, -			 OMAP4430_CLKSEL_MASK, -			 OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL, -			 OMAP4430_MODULEMODE_SWCTRL_SHIFT, NULL, -			 abe_dpll_bypass_clk_mux_ck_parents, dmic_fck_ops); - -DEFINE_CLK_GATE(uart1_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_UART1_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(uart2_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_UART2_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(uart3_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_UART3_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); - -DEFINE_CLK_GATE(uart4_fck, "func_48m_fclk", &func_48m_fclk, 0x0, -		OMAP4430_CM_L4PER_UART4_CLKCTRL, -		OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); +DEFINE_CLK_OMAP_MUX(cm2_dm9_mux, "l4_per_clkdm", dmt1_clk_mux_sel, +		    OMAP4430_CM_L4PER_DMTIMER9_CLKCTRL, OMAP4430_CLKSEL_MASK, +		    abe_dpll_bypass_clk_mux_ck_parents, +		    func_dmic_abe_gfclk_ops);  static struct clk usb_host_fs_fck; @@ -1512,18 +1244,6 @@ DEFINE_CLK_GATE(usim_fclk, "usim_ck", &usim_ck, 0x0,  		OMAP4430_CM_WKUP_USIM_CLKCTRL, OMAP4430_OPTFCLKEN_FCLK_SHIFT,  		0x0, NULL); -DEFINE_CLK_GATE(usim_fck, "sys_32k_ck", &sys_32k_ck, 0x0, -		OMAP4430_CM_WKUP_USIM_CLKCTRL, OMAP4430_MODULEMODE_HWCTRL_SHIFT, -		0x0, NULL); - -DEFINE_CLK_GATE(wd_timer2_fck, "sys_32k_ck", &sys_32k_ck, 0x0, -		OMAP4430_CM_WKUP_WDT2_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, -		0x0, NULL); - -DEFINE_CLK_GATE(wd_timer3_fck, "sys_32k_ck", &sys_32k_ck, 0x0, -		OMAP4430_CM1_ABE_WDT3_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, -		0x0, NULL); -  /* Remaining optional clocks */  static const char *pmd_stm_clock_mux_ck_parents[] = {  	"sys_clkin_ck", "dpll_core_m6x2_ck", "tie_low_clock_ck", @@ -1774,106 +1494,61 @@ static struct omap_clk omap44xx_clks[] = {  	CLK(NULL,	"syc_clk_div_ck",		&syc_clk_div_ck,	CK_443X),  	CLK(NULL,	"aes1_fck",			&aes1_fck,	CK_443X),  	CLK(NULL,	"aes2_fck",			&aes2_fck,	CK_443X), -	CLK(NULL,	"aess_fck",			&aess_fck,	CK_443X),  	CLK(NULL,	"bandgap_fclk",			&bandgap_fclk,	CK_443X),  	CLK(NULL,	"div_ts_ck",			&div_ts_ck,	CK_446X),  	CLK(NULL,	"bandgap_ts_fclk",		&bandgap_ts_fclk,	CK_446X), -	CLK(NULL,	"des3des_fck",			&des3des_fck,	CK_443X),  	CLK(NULL,	"dmic_sync_mux_ck",		&dmic_sync_mux_ck,	CK_443X), -	CLK(NULL,	"dmic_fck",			&dmic_fck,	CK_443X), -	CLK(NULL,	"dsp_fck",			&dsp_fck,	CK_443X), +	CLK(NULL,	"func_dmic_abe_gfclk",			&func_dmic_abe_gfclk,	CK_443X),  	CLK(NULL,	"dss_sys_clk",			&dss_sys_clk,	CK_443X),  	CLK(NULL,	"dss_tv_clk",			&dss_tv_clk,	CK_443X),  	CLK(NULL,	"dss_dss_clk",			&dss_dss_clk,	CK_443X),  	CLK(NULL,	"dss_48mhz_clk",		&dss_48mhz_clk,	CK_443X),  	CLK(NULL,	"dss_fck",			&dss_fck,	CK_443X),  	CLK("omapdss_dss",	"ick",			&dss_fck,	CK_443X), -	CLK(NULL,	"efuse_ctrl_cust_fck",		&efuse_ctrl_cust_fck,	CK_443X), -	CLK(NULL,	"emif1_fck",			&emif1_fck,	CK_443X), -	CLK(NULL,	"emif2_fck",			&emif2_fck,	CK_443X),  	CLK(NULL,	"fdif_fck",			&fdif_fck,	CK_443X), -	CLK(NULL,	"fpka_fck",			&fpka_fck,	CK_443X),  	CLK(NULL,	"gpio1_dbclk",			&gpio1_dbclk,	CK_443X), -	CLK(NULL,	"gpio1_ick",			&gpio1_ick,	CK_443X),  	CLK(NULL,	"gpio2_dbclk",			&gpio2_dbclk,	CK_443X), -	CLK(NULL,	"gpio2_ick",			&gpio2_ick,	CK_443X),  	CLK(NULL,	"gpio3_dbclk",			&gpio3_dbclk,	CK_443X), -	CLK(NULL,	"gpio3_ick",			&gpio3_ick,	CK_443X),  	CLK(NULL,	"gpio4_dbclk",			&gpio4_dbclk,	CK_443X), -	CLK(NULL,	"gpio4_ick",			&gpio4_ick,	CK_443X),  	CLK(NULL,	"gpio5_dbclk",			&gpio5_dbclk,	CK_443X), -	CLK(NULL,	"gpio5_ick",			&gpio5_ick,	CK_443X),  	CLK(NULL,	"gpio6_dbclk",			&gpio6_dbclk,	CK_443X), -	CLK(NULL,	"gpio6_ick",			&gpio6_ick,	CK_443X), -	CLK(NULL,	"gpmc_ick",			&gpmc_ick,	CK_443X), -	CLK(NULL,	"gpu_fck",			&gpu_fck,	CK_443X), -	CLK(NULL,	"hdq1w_fck",			&hdq1w_fck,	CK_443X), +	CLK(NULL,	"sgx_clk_mux",			&sgx_clk_mux,	CK_443X),  	CLK(NULL,	"hsi_fck",			&hsi_fck,	CK_443X), -	CLK(NULL,	"i2c1_fck",			&i2c1_fck,	CK_443X), -	CLK(NULL,	"i2c2_fck",			&i2c2_fck,	CK_443X), -	CLK(NULL,	"i2c3_fck",			&i2c3_fck,	CK_443X), -	CLK(NULL,	"i2c4_fck",			&i2c4_fck,	CK_443X), -	CLK(NULL,	"ipu_fck",			&ipu_fck,	CK_443X),  	CLK(NULL,	"iss_ctrlclk",			&iss_ctrlclk,	CK_443X), -	CLK(NULL,	"iss_fck",			&iss_fck,	CK_443X), -	CLK(NULL,	"iva_fck",			&iva_fck,	CK_443X), -	CLK(NULL,	"kbd_fck",			&kbd_fck,	CK_443X), -	CLK(NULL,	"l3_instr_ick",			&l3_instr_ick,	CK_443X), -	CLK(NULL,	"l3_main_3_ick",		&l3_main_3_ick,	CK_443X),  	CLK(NULL,	"mcasp_sync_mux_ck",		&mcasp_sync_mux_ck,	CK_443X), -	CLK(NULL,	"mcasp_fck",			&mcasp_fck,	CK_443X), +	CLK(NULL,	"func_mcasp_abe_gfclk",			&func_mcasp_abe_gfclk,	CK_443X),  	CLK(NULL,	"mcbsp1_sync_mux_ck",		&mcbsp1_sync_mux_ck,	CK_443X), -	CLK(NULL,	"mcbsp1_fck",			&mcbsp1_fck,	CK_443X), +	CLK(NULL,	"func_mcbsp1_gfclk",			&func_mcbsp1_gfclk,	CK_443X),  	CLK(NULL,	"mcbsp2_sync_mux_ck",		&mcbsp2_sync_mux_ck,	CK_443X), -	CLK(NULL,	"mcbsp2_fck",			&mcbsp2_fck,	CK_443X), +	CLK(NULL,	"func_mcbsp2_gfclk",			&func_mcbsp2_gfclk,	CK_443X),  	CLK(NULL,	"mcbsp3_sync_mux_ck",		&mcbsp3_sync_mux_ck,	CK_443X), -	CLK(NULL,	"mcbsp3_fck",			&mcbsp3_fck,	CK_443X), +	CLK(NULL,	"func_mcbsp3_gfclk",			&func_mcbsp3_gfclk,	CK_443X),  	CLK(NULL,	"mcbsp4_sync_mux_ck",		&mcbsp4_sync_mux_ck,	CK_443X), -	CLK(NULL,	"mcbsp4_fck",			&mcbsp4_fck,	CK_443X), -	CLK(NULL,	"mcpdm_fck",			&mcpdm_fck,	CK_443X), -	CLK(NULL,	"mcspi1_fck",			&mcspi1_fck,	CK_443X), -	CLK(NULL,	"mcspi2_fck",			&mcspi2_fck,	CK_443X), -	CLK(NULL,	"mcspi3_fck",			&mcspi3_fck,	CK_443X), -	CLK(NULL,	"mcspi4_fck",			&mcspi4_fck,	CK_443X), -	CLK(NULL,	"mmc1_fck",			&mmc1_fck,	CK_443X), -	CLK(NULL,	"mmc2_fck",			&mmc2_fck,	CK_443X), -	CLK(NULL,	"mmc3_fck",			&mmc3_fck,	CK_443X), -	CLK(NULL,	"mmc4_fck",			&mmc4_fck,	CK_443X), -	CLK(NULL,	"mmc5_fck",			&mmc5_fck,	CK_443X), -	CLK(NULL,	"ocp2scp_usb_phy_phy_48m",	&ocp2scp_usb_phy_phy_48m,	CK_443X), -	CLK(NULL,	"ocp2scp_usb_phy_ick",		&ocp2scp_usb_phy_ick,	CK_443X), -	CLK(NULL,	"ocp_wp_noc_ick",		&ocp_wp_noc_ick,	CK_443X), -	CLK(NULL,	"rng_ick",			&rng_ick,	CK_443X), -	CLK("omap_rng",	"ick",				&rng_ick,	CK_443X), +	CLK(NULL,	"per_mcbsp4_gfclk",			&per_mcbsp4_gfclk,	CK_443X), +	CLK(NULL,	"hsmmc1_fclk",			&hsmmc1_fclk,	CK_443X), +	CLK(NULL,	"hsmmc2_fclk",			&hsmmc2_fclk,	CK_443X),  	CLK(NULL,	"sha2md5_fck",			&sha2md5_fck,	CK_443X), -	CLK(NULL,	"sl2if_ick",			&sl2if_ick,	CK_443X),  	CLK(NULL,	"slimbus1_fclk_1",		&slimbus1_fclk_1,	CK_443X),  	CLK(NULL,	"slimbus1_fclk_0",		&slimbus1_fclk_0,	CK_443X),  	CLK(NULL,	"slimbus1_fclk_2",		&slimbus1_fclk_2,	CK_443X),  	CLK(NULL,	"slimbus1_slimbus_clk",		&slimbus1_slimbus_clk,	CK_443X), -	CLK(NULL,	"slimbus1_fck",			&slimbus1_fck,	CK_443X),  	CLK(NULL,	"slimbus2_fclk_1",		&slimbus2_fclk_1,	CK_443X),  	CLK(NULL,	"slimbus2_fclk_0",		&slimbus2_fclk_0,	CK_443X),  	CLK(NULL,	"slimbus2_slimbus_clk",		&slimbus2_slimbus_clk,	CK_443X), -	CLK(NULL,	"slimbus2_fck",			&slimbus2_fck,	CK_443X),  	CLK(NULL,	"smartreflex_core_fck",		&smartreflex_core_fck,	CK_443X),  	CLK(NULL,	"smartreflex_iva_fck",		&smartreflex_iva_fck,	CK_443X),  	CLK(NULL,	"smartreflex_mpu_fck",		&smartreflex_mpu_fck,	CK_443X), -	CLK(NULL,	"timer1_fck",			&timer1_fck,	CK_443X), -	CLK(NULL,	"timer10_fck",			&timer10_fck,	CK_443X), -	CLK(NULL,	"timer11_fck",			&timer11_fck,	CK_443X), -	CLK(NULL,	"timer2_fck",			&timer2_fck,	CK_443X), -	CLK(NULL,	"timer3_fck",			&timer3_fck,	CK_443X), -	CLK(NULL,	"timer4_fck",			&timer4_fck,	CK_443X), -	CLK(NULL,	"timer5_fck",			&timer5_fck,	CK_443X), -	CLK(NULL,	"timer6_fck",			&timer6_fck,	CK_443X), -	CLK(NULL,	"timer7_fck",			&timer7_fck,	CK_443X), -	CLK(NULL,	"timer8_fck",			&timer8_fck,	CK_443X), -	CLK(NULL,	"timer9_fck",			&timer9_fck,	CK_443X), -	CLK(NULL,	"uart1_fck",			&uart1_fck,	CK_443X), -	CLK(NULL,	"uart2_fck",			&uart2_fck,	CK_443X), -	CLK(NULL,	"uart3_fck",			&uart3_fck,	CK_443X), -	CLK(NULL,	"uart4_fck",			&uart4_fck,	CK_443X), +	CLK(NULL,	"dmt1_clk_mux",			&dmt1_clk_mux,	CK_443X), +	CLK(NULL,	"cm2_dm10_mux",			&cm2_dm10_mux,	CK_443X), +	CLK(NULL,	"cm2_dm11_mux",			&cm2_dm11_mux,	CK_443X), +	CLK(NULL,	"cm2_dm2_mux",			&cm2_dm2_mux,	CK_443X), +	CLK(NULL,	"cm2_dm3_mux",			&cm2_dm3_mux,	CK_443X), +	CLK(NULL,	"cm2_dm4_mux",			&cm2_dm4_mux,	CK_443X), +	CLK(NULL,	"timer5_sync_mux",		&timer5_sync_mux,	CK_443X), +	CLK(NULL,	"timer6_sync_mux",			&timer6_sync_mux,	CK_443X), +	CLK(NULL,	"timer7_sync_mux",			&timer7_sync_mux,	CK_443X), +	CLK(NULL,	"timer8_sync_mux",			&timer8_sync_mux,	CK_443X), +	CLK(NULL,	"cm2_dm9_mux",			&cm2_dm9_mux,	CK_443X),  	CLK(NULL,	"usb_host_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), @@ -1901,9 +1576,6 @@ static struct omap_clk omap44xx_clks[] = {  	CLK("usbhs_tll",	"usbtll_ick",		&usb_tll_hs_ick,	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), -	CLK(NULL,	"wd_timer2_fck",		&wd_timer2_fck,	CK_443X), -	CLK(NULL,	"wd_timer3_fck",		&wd_timer3_fck,	CK_443X),  	CLK(NULL,	"pmd_stm_clock_mux_ck",		&pmd_stm_clock_mux_ck,	CK_443X),  	CLK(NULL,	"pmd_trace_clk_mux_ck",		&pmd_trace_clk_mux_ck,	CK_443X),  	CLK(NULL,	"stm_clk_div_ck",		&stm_clk_div_ck,	CK_443X), @@ -1980,15 +1652,6 @@ static struct omap_clk omap44xx_clks[] = {  	CLK(NULL,	"cpufreq_ck",	&dpll_mpu_ck,	CK_443X),  }; -static const char *enable_init_clks[] = { -	"emif1_fck", -	"emif2_fck", -	"gpmc_ick", -	"l3_instr_ick", -	"l3_main_3_ick", -	"ocp_wp_noc_ick", -}; -  int __init omap4xxx_clk_init(void)  {  	u32 cpu_clkflg; @@ -2019,9 +1682,6 @@ int __init omap4xxx_clk_init(void)  	omap2_clk_disable_autoidle_all(); -	omap2_clk_enable_init_clocks(enable_init_clks, -				     ARRAY_SIZE(enable_init_clks)); -  	/*  	 * On OMAP4460 the ABE DPLL fails to turn on if in idle low-power  	 * state when turning the ABE clock domain. Workaround this by diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 7faf82d4e85..2da3b5ec010 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -92,8 +92,6 @@ static int _clkdm_register(struct clockdomain *clkdm)  	pwrdm_add_clkdm(pwrdm, clkdm); -	spin_lock_init(&clkdm->lock); -  	pr_debug("clockdomain: registered %s\n", clkdm->name);  	return 0; @@ -122,7 +120,7 @@ static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm,  	return cd;  } -/* +/**   * _autodep_lookup - resolve autodep clkdm names to clkdm pointers; store   * @autodep: struct clkdm_autodep * to resolve   * @@ -154,88 +152,206 @@ static void _autodep_lookup(struct clkdm_autodep *autodep)  	autodep->clkdm.ptr = clkdm;  } -/* - * _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable - * @clkdm: struct clockdomain * +/** + * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms + * @clkdm: clockdomain that we are resolving dependencies for + * @clkdm_deps: ptr to array of struct clkdm_deps to resolve   * - * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' - * in hardware-supervised mode.  Meant to be called from clock framework - * when a clock inside clockdomain 'clkdm' is enabled.	No return value. + * Iterates through @clkdm_deps, looking up the struct clockdomain named by + * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep. + * No return value. + */ +static void _resolve_clkdm_deps(struct clockdomain *clkdm, +				struct clkdm_dep *clkdm_deps) +{ +	struct clkdm_dep *cd; + +	for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { +		if (cd->clkdm) +			continue; +		cd->clkdm = _clkdm_lookup(cd->clkdm_name); + +		WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen", +		     clkdm->name, cd->clkdm_name); +	} +} + +/** + * _clkdm_add_wkdep - add a wakeup dependency from clkdm2 to clkdm1 (lockless) + * @clkdm1: wake this struct clockdomain * up (dependent) + * @clkdm2: when this struct clockdomain * wakes up (source)   * - * XXX autodeps are deprecated and should be removed at the earliest - * opportunity + * When the clockdomain represented by @clkdm2 wakes up, wake up + * @clkdm1. Implemented in hardware on the OMAP, this feature is + * designed to reduce wakeup latency of the dependent clockdomain @clkdm1. + * Returns -EINVAL if presented with invalid clockdomain pointers, + * -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or 0 upon + * success.   */ -void _clkdm_add_autodeps(struct clockdomain *clkdm) +static int _clkdm_add_wkdep(struct clockdomain *clkdm1, +			    struct clockdomain *clkdm2)  { -	struct clkdm_autodep *autodep; +	struct clkdm_dep *cd; +	int ret = 0; -	if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) -		return; +	if (!clkdm1 || !clkdm2) +		return -EINVAL; -	for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { -		if (IS_ERR(autodep->clkdm.ptr)) -			continue; +	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); +	if (IS_ERR(cd)) +		ret = PTR_ERR(cd); -		pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n", -			 clkdm->name, autodep->clkdm.ptr->name); +	if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep) +		ret = -EINVAL; + +	if (ret) { +		pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", +			 clkdm1->name, clkdm2->name); +		return ret; +	} + +	cd->wkdep_usecount++; +	if (cd->wkdep_usecount == 1) { +		pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n", +			 clkdm1->name, clkdm2->name); -		clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr); -		clkdm_add_wkdep(clkdm, autodep->clkdm.ptr); +		ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);  	} + +	return ret;  } -/* - * _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm - * @clkdm: struct clockdomain * +/** + * _clkdm_del_wkdep - remove a wakeup dep from clkdm2 to clkdm1 (lockless) + * @clkdm1: wake this struct clockdomain * up (dependent) + * @clkdm2: when this struct clockdomain * wakes up (source)   * - * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' - * in hardware-supervised mode.  Meant to be called from clock framework - * when a clock inside clockdomain 'clkdm' is disabled.  No return value. + * Remove a wakeup dependency causing @clkdm1 to wake up when @clkdm2 + * wakes up.  Returns -EINVAL if presented with invalid clockdomain + * pointers, -ENOENT if @clkdm2 cannot wake up clkdm1 in hardware, or + * 0 upon success. + */ +static int _clkdm_del_wkdep(struct clockdomain *clkdm1, +			    struct clockdomain *clkdm2) +{ +	struct clkdm_dep *cd; +	int ret = 0; + +	if (!clkdm1 || !clkdm2) +		return -EINVAL; + +	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs); +	if (IS_ERR(cd)) +		ret = PTR_ERR(cd); + +	if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep) +		ret = -EINVAL; + +	if (ret) { +		pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", +			 clkdm1->name, clkdm2->name); +		return ret; +	} + +	cd->wkdep_usecount--; +	if (cd->wkdep_usecount == 0) { +		pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n", +			 clkdm1->name, clkdm2->name); + +		ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2); +	} + +	return ret; +} + +/** + * _clkdm_add_sleepdep - add a sleep dependency from clkdm2 to clkdm1 (lockless) + * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) + * @clkdm2: when this struct clockdomain * is active (source)   * - * XXX autodeps are deprecated and should be removed at the earliest - * opportunity + * Prevent @clkdm1 from automatically going inactive (and then to + * retention or off) if @clkdm2 is active.  Returns -EINVAL if + * presented with invalid clockdomain pointers or called on a machine + * that does not support software-configurable hardware sleep + * dependencies, -ENOENT if the specified dependency cannot be set in + * hardware, or 0 upon success.   */ -void _clkdm_del_autodeps(struct clockdomain *clkdm) +static int _clkdm_add_sleepdep(struct clockdomain *clkdm1, +			       struct clockdomain *clkdm2)  { -	struct clkdm_autodep *autodep; +	struct clkdm_dep *cd; +	int ret = 0; -	if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) -		return; +	if (!clkdm1 || !clkdm2) +		return -EINVAL; -	for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { -		if (IS_ERR(autodep->clkdm.ptr)) -			continue; +	cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); +	if (IS_ERR(cd)) +		ret = PTR_ERR(cd); -		pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n", -			 clkdm->name, autodep->clkdm.ptr->name); +	if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep) +		ret = -EINVAL; -		clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr); -		clkdm_del_wkdep(clkdm, autodep->clkdm.ptr); +	if (ret) { +		pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", +			 clkdm1->name, clkdm2->name); +		return ret; +	} + +	cd->sleepdep_usecount++; +	if (cd->sleepdep_usecount == 1) { +		pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n", +			 clkdm1->name, clkdm2->name); + +		ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2);  	} + +	return ret;  }  /** - * _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms - * @clkdm: clockdomain that we are resolving dependencies for - * @clkdm_deps: ptr to array of struct clkdm_deps to resolve + * _clkdm_del_sleepdep - remove a sleep dep from clkdm2 to clkdm1 (lockless) + * @clkdm1: prevent this struct clockdomain * from sleeping (dependent) + * @clkdm2: when this struct clockdomain * is active (source)   * - * Iterates through @clkdm_deps, looking up the struct clockdomain named by - * clkdm_name and storing the clockdomain pointer in the struct clkdm_dep. - * No return value. + * Allow @clkdm1 to automatically go inactive (and then to retention or + * off), independent of the activity state of @clkdm2.  Returns -EINVAL + * if presented with invalid clockdomain pointers or called on a machine + * that does not support software-configurable hardware sleep dependencies, + * -ENOENT if the specified dependency cannot be cleared in hardware, or + * 0 upon success.   */ -static void _resolve_clkdm_deps(struct clockdomain *clkdm, -				struct clkdm_dep *clkdm_deps) +static int _clkdm_del_sleepdep(struct clockdomain *clkdm1, +			       struct clockdomain *clkdm2)  {  	struct clkdm_dep *cd; +	int ret = 0; -	for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) { -		if (cd->clkdm) -			continue; -		cd->clkdm = _clkdm_lookup(cd->clkdm_name); +	if (!clkdm1 || !clkdm2) +		return -EINVAL; -		WARN(!cd->clkdm, "clockdomain: %s: could not find clkdm %s while resolving dependencies - should never happen", -		     clkdm->name, cd->clkdm_name); +	cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); +	if (IS_ERR(cd)) +		ret = PTR_ERR(cd); + +	if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep) +		ret = -EINVAL; + +	if (ret) { +		pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", +			 clkdm1->name, clkdm2->name); +		return ret;  	} + +	cd->sleepdep_usecount--; +	if (cd->sleepdep_usecount == 0) { +		pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n", +			 clkdm1->name, clkdm2->name); + +		ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2); +	} + +	return ret;  }  /* Public functions */ @@ -456,30 +572,18 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)  int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  {  	struct clkdm_dep *cd; -	int ret = 0; +	int ret;  	if (!clkdm1 || !clkdm2)  		return -EINVAL;  	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);  	if (IS_ERR(cd)) -		ret = PTR_ERR(cd); +		return PTR_ERR(cd); -	if (!arch_clkdm || !arch_clkdm->clkdm_add_wkdep) -		ret = -EINVAL; - -	if (ret) { -		pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", -			 clkdm1->name, clkdm2->name); -		return ret; -	} - -	if (atomic_inc_return(&cd->wkdep_usecount) == 1) { -		pr_debug("clockdomain: hardware will wake up %s when %s wakes up\n", -			 clkdm1->name, clkdm2->name); - -		ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2); -	} +	pwrdm_lock(cd->clkdm->pwrdm.ptr); +	ret = _clkdm_add_wkdep(clkdm1, clkdm2); +	pwrdm_unlock(cd->clkdm->pwrdm.ptr);  	return ret;  } @@ -497,30 +601,18 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  {  	struct clkdm_dep *cd; -	int ret = 0; +	int ret;  	if (!clkdm1 || !clkdm2)  		return -EINVAL;  	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);  	if (IS_ERR(cd)) -		ret = PTR_ERR(cd); +		return PTR_ERR(cd); -	if (!arch_clkdm || !arch_clkdm->clkdm_del_wkdep) -		ret = -EINVAL; - -	if (ret) { -		pr_debug("clockdomain: hardware cannot set/clear wake up of %s when %s wakes up\n", -			 clkdm1->name, clkdm2->name); -		return ret; -	} - -	if (atomic_dec_return(&cd->wkdep_usecount) == 0) { -		pr_debug("clockdomain: hardware will no longer wake up %s after %s wakes up\n", -			 clkdm1->name, clkdm2->name); - -		ret = arch_clkdm->clkdm_del_wkdep(clkdm1, clkdm2); -	} +	pwrdm_lock(cd->clkdm->pwrdm.ptr); +	ret = _clkdm_del_wkdep(clkdm1, clkdm2); +	pwrdm_unlock(cd->clkdm->pwrdm.ptr);  	return ret;  } @@ -560,7 +652,7 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  		return ret;  	} -	/* XXX It's faster to return the atomic wkdep_usecount */ +	/* XXX It's faster to return the wkdep_usecount */  	return arch_clkdm->clkdm_read_wkdep(clkdm1, clkdm2);  } @@ -600,30 +692,18 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)  int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  {  	struct clkdm_dep *cd; -	int ret = 0; +	int ret;  	if (!clkdm1 || !clkdm2)  		return -EINVAL; -	cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); +	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);  	if (IS_ERR(cd)) -		ret = PTR_ERR(cd); +		return PTR_ERR(cd); -	if (!arch_clkdm || !arch_clkdm->clkdm_add_sleepdep) -		ret = -EINVAL; - -	if (ret) { -		pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", -			 clkdm1->name, clkdm2->name); -		return ret; -	} - -	if (atomic_inc_return(&cd->sleepdep_usecount) == 1) { -		pr_debug("clockdomain: will prevent %s from sleeping if %s is active\n", -			 clkdm1->name, clkdm2->name); - -		ret = arch_clkdm->clkdm_add_sleepdep(clkdm1, clkdm2); -	} +	pwrdm_lock(cd->clkdm->pwrdm.ptr); +	ret = _clkdm_add_sleepdep(clkdm1, clkdm2); +	pwrdm_unlock(cd->clkdm->pwrdm.ptr);  	return ret;  } @@ -643,30 +723,18 @@ int clkdm_add_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  {  	struct clkdm_dep *cd; -	int ret = 0; +	int ret;  	if (!clkdm1 || !clkdm2)  		return -EINVAL; -	cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs); +	cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);  	if (IS_ERR(cd)) -		ret = PTR_ERR(cd); +		return PTR_ERR(cd); -	if (!arch_clkdm || !arch_clkdm->clkdm_del_sleepdep) -		ret = -EINVAL; - -	if (ret) { -		pr_debug("clockdomain: hardware cannot set/clear sleep dependency affecting %s from %s\n", -			 clkdm1->name, clkdm2->name); -		return ret; -	} - -	if (atomic_dec_return(&cd->sleepdep_usecount) == 0) { -		pr_debug("clockdomain: will no longer prevent %s from sleeping if %s is active\n", -			 clkdm1->name, clkdm2->name); - -		ret = arch_clkdm->clkdm_del_sleepdep(clkdm1, clkdm2); -	} +	pwrdm_lock(cd->clkdm->pwrdm.ptr); +	ret = _clkdm_del_sleepdep(clkdm1, clkdm2); +	pwrdm_unlock(cd->clkdm->pwrdm.ptr);  	return ret;  } @@ -708,7 +776,7 @@ int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)  		return ret;  	} -	/* XXX It's faster to return the atomic sleepdep_usecount */ +	/* XXX It's faster to return the sleepdep_usecount */  	return arch_clkdm->clkdm_read_sleepdep(clkdm1, clkdm2);  } @@ -734,18 +802,17 @@ int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)  }  /** - * clkdm_sleep - force clockdomain sleep transition + * clkdm_sleep_nolock - force clockdomain sleep transition (lockless)   * @clkdm: struct clockdomain *   *   * Instruct the CM to force a sleep transition on the specified - * clockdomain @clkdm.  Returns -EINVAL if @clkdm is NULL or if - * clockdomain does not support software-initiated sleep; 0 upon - * success. + * clockdomain @clkdm.  Only for use by the powerdomain code.  Returns + * -EINVAL if @clkdm is NULL or if clockdomain does not support + * software-initiated sleep; 0 upon success.   */ -int clkdm_sleep(struct clockdomain *clkdm) +int clkdm_sleep_nolock(struct clockdomain *clkdm)  {  	int ret; -	unsigned long flags;  	if (!clkdm)  		return -EINVAL; @@ -761,26 +828,45 @@ int clkdm_sleep(struct clockdomain *clkdm)  	pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name); -	spin_lock_irqsave(&clkdm->lock, flags);  	clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;  	ret = arch_clkdm->clkdm_sleep(clkdm); -	spin_unlock_irqrestore(&clkdm->lock, flags); +	ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); +  	return ret;  }  /** - * clkdm_wakeup - force clockdomain wakeup transition + * clkdm_sleep - force clockdomain sleep transition   * @clkdm: struct clockdomain *   * - * Instruct the CM to force a wakeup transition on the specified - * clockdomain @clkdm.  Returns -EINVAL if @clkdm is NULL or if the - * clockdomain does not support software-controlled wakeup; 0 upon + * Instruct the CM to force a sleep transition on the specified + * clockdomain @clkdm.  Returns -EINVAL if @clkdm is NULL or if + * clockdomain does not support software-initiated sleep; 0 upon   * success.   */ -int clkdm_wakeup(struct clockdomain *clkdm) +int clkdm_sleep(struct clockdomain *clkdm) +{ +	int ret; + +	pwrdm_lock(clkdm->pwrdm.ptr); +	ret = clkdm_sleep_nolock(clkdm); +	pwrdm_unlock(clkdm->pwrdm.ptr); + +	return ret; +} + +/** + * clkdm_wakeup_nolock - force clockdomain wakeup transition (lockless) + * @clkdm: struct clockdomain * + * + * Instruct the CM to force a wakeup transition on the specified + * clockdomain @clkdm.  Only for use by the powerdomain code.  Returns + * -EINVAL if @clkdm is NULL or if the clockdomain does not support + * software-controlled wakeup; 0 upon success. + */ +int clkdm_wakeup_nolock(struct clockdomain *clkdm)  {  	int ret; -	unsigned long flags;  	if (!clkdm)  		return -EINVAL; @@ -796,28 +882,46 @@ int clkdm_wakeup(struct clockdomain *clkdm)  	pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name); -	spin_lock_irqsave(&clkdm->lock, flags);  	clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;  	ret = arch_clkdm->clkdm_wakeup(clkdm); -	ret |= pwrdm_state_switch(clkdm->pwrdm.ptr); -	spin_unlock_irqrestore(&clkdm->lock, flags); +	ret |= pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); +  	return ret;  }  /** - * clkdm_allow_idle - enable hwsup idle transitions for clkdm + * clkdm_wakeup - force clockdomain wakeup transition   * @clkdm: struct clockdomain *   * - * Allow the hardware to automatically switch the clockdomain @clkdm into - * active or idle states, as needed by downstream clocks.  If the + * Instruct the CM to force a wakeup transition on the specified + * clockdomain @clkdm.  Returns -EINVAL if @clkdm is NULL or if the + * clockdomain does not support software-controlled wakeup; 0 upon + * success. + */ +int clkdm_wakeup(struct clockdomain *clkdm) +{ +	int ret; + +	pwrdm_lock(clkdm->pwrdm.ptr); +	ret = clkdm_wakeup_nolock(clkdm); +	pwrdm_unlock(clkdm->pwrdm.ptr); + +	return ret; +} + +/** + * clkdm_allow_idle_nolock - enable hwsup idle transitions for clkdm + * @clkdm: struct clockdomain * + * + * Allow the hardware to automatically switch the clockdomain @clkdm + * into active or idle states, as needed by downstream clocks.  If the   * clockdomain has any downstream clocks enabled in the clock   * framework, wkdep/sleepdep autodependencies are added; this is so - * device drivers can read and write to the device.  No return value. + * device drivers can read and write to the device.  Only for use by + * the powerdomain code.  No return value.   */ -void clkdm_allow_idle(struct clockdomain *clkdm) +void clkdm_allow_idle_nolock(struct clockdomain *clkdm)  { -	unsigned long flags; -  	if (!clkdm)  		return; @@ -833,11 +937,26 @@ void clkdm_allow_idle(struct clockdomain *clkdm)  	pr_debug("clockdomain: enabling automatic idle transitions for %s\n",  		 clkdm->name); -	spin_lock_irqsave(&clkdm->lock, flags);  	clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED;  	arch_clkdm->clkdm_allow_idle(clkdm); -	pwrdm_state_switch(clkdm->pwrdm.ptr); -	spin_unlock_irqrestore(&clkdm->lock, flags); +	pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); +} + +/** + * clkdm_allow_idle - enable hwsup idle transitions for clkdm + * @clkdm: struct clockdomain * + * + * Allow the hardware to automatically switch the clockdomain @clkdm into + * active or idle states, as needed by downstream clocks.  If the + * clockdomain has any downstream clocks enabled in the clock + * framework, wkdep/sleepdep autodependencies are added; this is so + * device drivers can read and write to the device.  No return value. + */ +void clkdm_allow_idle(struct clockdomain *clkdm) +{ +	pwrdm_lock(clkdm->pwrdm.ptr); +	clkdm_allow_idle_nolock(clkdm); +	pwrdm_unlock(clkdm->pwrdm.ptr);  }  /** @@ -847,12 +966,11 @@ void clkdm_allow_idle(struct clockdomain *clkdm)   * Prevent the hardware from automatically switching the clockdomain   * @clkdm into inactive or idle states.  If the clockdomain has   * downstream clocks enabled in the clock framework, wkdep/sleepdep - * autodependencies are removed.  No return value. + * autodependencies are removed.  Only for use by the powerdomain + * code.  No return value.   */ -void clkdm_deny_idle(struct clockdomain *clkdm) +void clkdm_deny_idle_nolock(struct clockdomain *clkdm)  { -	unsigned long flags; -  	if (!clkdm)  		return; @@ -868,11 +986,25 @@ void clkdm_deny_idle(struct clockdomain *clkdm)  	pr_debug("clockdomain: disabling automatic idle transitions for %s\n",  		 clkdm->name); -	spin_lock_irqsave(&clkdm->lock, flags);  	clkdm->_flags &= ~_CLKDM_FLAG_HWSUP_ENABLED;  	arch_clkdm->clkdm_deny_idle(clkdm); -	pwrdm_state_switch(clkdm->pwrdm.ptr); -	spin_unlock_irqrestore(&clkdm->lock, flags); +	pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); +} + +/** + * clkdm_deny_idle - disable hwsup idle transitions for clkdm + * @clkdm: struct clockdomain * + * + * Prevent the hardware from automatically switching the clockdomain + * @clkdm into inactive or idle states.  If the clockdomain has + * downstream clocks enabled in the clock framework, wkdep/sleepdep + * autodependencies are removed.  No return value. + */ +void clkdm_deny_idle(struct clockdomain *clkdm) +{ +	pwrdm_lock(clkdm->pwrdm.ptr); +	clkdm_deny_idle_nolock(clkdm); +	pwrdm_unlock(clkdm->pwrdm.ptr);  }  /** @@ -889,14 +1021,11 @@ void clkdm_deny_idle(struct clockdomain *clkdm)  bool clkdm_in_hwsup(struct clockdomain *clkdm)  {  	bool ret; -	unsigned long flags;  	if (!clkdm)  		return false; -	spin_lock_irqsave(&clkdm->lock, flags);  	ret = (clkdm->_flags & _CLKDM_FLAG_HWSUP_ENABLED) ? true : false; -	spin_unlock_irqrestore(&clkdm->lock, flags);  	return ret;  } @@ -918,30 +1047,91 @@ bool clkdm_missing_idle_reporting(struct clockdomain *clkdm)  	return (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) ? true : false;  } +/* Public autodep handling functions (deprecated) */ + +/** + * clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable + * @clkdm: struct clockdomain * + * + * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm' + * in hardware-supervised mode.  Meant to be called from clock framework + * when a clock inside clockdomain 'clkdm' is enabled.	No return value. + * + * XXX autodeps are deprecated and should be removed at the earliest + * opportunity + */ +void clkdm_add_autodeps(struct clockdomain *clkdm) +{ +	struct clkdm_autodep *autodep; + +	if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) +		return; + +	for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { +		if (IS_ERR(autodep->clkdm.ptr)) +			continue; + +		pr_debug("clockdomain: %s: adding %s sleepdep/wkdep\n", +			 clkdm->name, autodep->clkdm.ptr->name); + +		_clkdm_add_sleepdep(clkdm, autodep->clkdm.ptr); +		_clkdm_add_wkdep(clkdm, autodep->clkdm.ptr); +	} +} + +/** + * clkdm_del_autodeps - remove auto sleepdeps/wkdeps from clkdm + * @clkdm: struct clockdomain * + * + * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm' + * in hardware-supervised mode.  Meant to be called from clock framework + * when a clock inside clockdomain 'clkdm' is disabled.  No return value. + * + * XXX autodeps are deprecated and should be removed at the earliest + * opportunity + */ +void clkdm_del_autodeps(struct clockdomain *clkdm) +{ +	struct clkdm_autodep *autodep; + +	if (!autodeps || clkdm->flags & CLKDM_NO_AUTODEPS) +		return; + +	for (autodep = autodeps; autodep->clkdm.ptr; autodep++) { +		if (IS_ERR(autodep->clkdm.ptr)) +			continue; + +		pr_debug("clockdomain: %s: removing %s sleepdep/wkdep\n", +			 clkdm->name, autodep->clkdm.ptr->name); + +		_clkdm_del_sleepdep(clkdm, autodep->clkdm.ptr); +		_clkdm_del_wkdep(clkdm, autodep->clkdm.ptr); +	} +} +  /* Clockdomain-to-clock/hwmod framework interface code */  static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)  { -	unsigned long flags; -  	if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable)  		return -EINVAL; -	spin_lock_irqsave(&clkdm->lock, flags); +	pwrdm_lock(clkdm->pwrdm.ptr);  	/*  	 * For arch's with no autodeps, clkcm_clk_enable  	 * should be called for every clock instance or hwmod that is  	 * enabled, so the clkdm can be force woken up.  	 */ -	if ((atomic_inc_return(&clkdm->usecount) > 1) && autodeps) { -		spin_unlock_irqrestore(&clkdm->lock, flags); +	clkdm->usecount++; +	if (clkdm->usecount > 1 && autodeps) { +		pwrdm_unlock(clkdm->pwrdm.ptr);  		return 0;  	}  	arch_clkdm->clkdm_clk_enable(clkdm); -	pwrdm_state_switch(clkdm->pwrdm.ptr); -	spin_unlock_irqrestore(&clkdm->lock, flags); +	pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); +	pwrdm_unlock(clkdm->pwrdm.ptr);  	pr_debug("clockdomain: %s: enabled\n", clkdm->name); @@ -990,36 +1180,34 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)   */  int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)  { -	unsigned long flags; -  	if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)  		return -EINVAL; -	spin_lock_irqsave(&clkdm->lock, flags); +	pwrdm_lock(clkdm->pwrdm.ptr);  	/* corner case: disabling unused clocks */ -	if ((__clk_get_enable_count(clk) == 0) && -	    (atomic_read(&clkdm->usecount) == 0)) +	if ((__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0)  		goto ccd_exit; -	if (atomic_read(&clkdm->usecount) == 0) { -		spin_unlock_irqrestore(&clkdm->lock, flags); +	if (clkdm->usecount == 0) { +		pwrdm_unlock(clkdm->pwrdm.ptr);  		WARN_ON(1); /* underflow */  		return -ERANGE;  	} -	if (atomic_dec_return(&clkdm->usecount) > 0) { -		spin_unlock_irqrestore(&clkdm->lock, flags); +	clkdm->usecount--; +	if (clkdm->usecount > 0) { +		pwrdm_unlock(clkdm->pwrdm.ptr);  		return 0;  	}  	arch_clkdm->clkdm_clk_disable(clkdm); -	pwrdm_state_switch(clkdm->pwrdm.ptr); +	pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);  	pr_debug("clockdomain: %s: disabled\n", clkdm->name);  ccd_exit: -	spin_unlock_irqrestore(&clkdm->lock, flags); +	pwrdm_unlock(clkdm->pwrdm.ptr);  	return 0;  } @@ -1072,8 +1260,6 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)   */  int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)  { -	unsigned long flags; -  	/* The clkdm attribute does not exist yet prior OMAP4 */  	if (cpu_is_omap24xx() || cpu_is_omap34xx())  		return 0; @@ -1086,22 +1272,23 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)  	if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)  		return -EINVAL; -	spin_lock_irqsave(&clkdm->lock, flags); +	pwrdm_lock(clkdm->pwrdm.ptr); -	if (atomic_read(&clkdm->usecount) == 0) { -		spin_unlock_irqrestore(&clkdm->lock, flags); +	if (clkdm->usecount == 0) { +		pwrdm_unlock(clkdm->pwrdm.ptr);  		WARN_ON(1); /* underflow */  		return -ERANGE;  	} -	if (atomic_dec_return(&clkdm->usecount) > 0) { -		spin_unlock_irqrestore(&clkdm->lock, flags); +	clkdm->usecount--; +	if (clkdm->usecount > 0) { +		pwrdm_unlock(clkdm->pwrdm.ptr);  		return 0;  	}  	arch_clkdm->clkdm_clk_disable(clkdm); -	pwrdm_state_switch(clkdm->pwrdm.ptr); -	spin_unlock_irqrestore(&clkdm->lock, flags); +	pwrdm_state_switch_nolock(clkdm->pwrdm.ptr); +	pwrdm_unlock(clkdm->pwrdm.ptr);  	pr_debug("clockdomain: %s: disabled\n", clkdm->name); diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index bc42446e23a..2da37656a69 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -15,7 +15,6 @@  #define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAIN_H  #include <linux/init.h> -#include <linux/spinlock.h>  #include "powerdomain.h"  #include "clock.h" @@ -92,8 +91,8 @@ struct clkdm_autodep {  struct clkdm_dep {  	const char *clkdm_name;  	struct clockdomain *clkdm; -	atomic_t wkdep_usecount; -	atomic_t sleepdep_usecount; +	s16 wkdep_usecount; +	s16 sleepdep_usecount;  };  /* Possible flags for struct clockdomain._flags */ @@ -137,9 +136,8 @@ struct clockdomain {  	const u16 clkdm_offs;  	struct clkdm_dep *wkdep_srcs;  	struct clkdm_dep *sleepdep_srcs; -	atomic_t usecount; +	int usecount;  	struct list_head node; -	spinlock_t lock;  };  /** @@ -196,12 +194,16 @@ int clkdm_del_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);  int clkdm_read_sleepdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2);  int clkdm_clear_all_sleepdeps(struct clockdomain *clkdm); +void clkdm_allow_idle_nolock(struct clockdomain *clkdm);  void clkdm_allow_idle(struct clockdomain *clkdm); +void clkdm_deny_idle_nolock(struct clockdomain *clkdm);  void clkdm_deny_idle(struct clockdomain *clkdm);  bool clkdm_in_hwsup(struct clockdomain *clkdm);  bool clkdm_missing_idle_reporting(struct clockdomain *clkdm); +int clkdm_wakeup_nolock(struct clockdomain *clkdm);  int clkdm_wakeup(struct clockdomain *clkdm); +int clkdm_sleep_nolock(struct clockdomain *clkdm);  int clkdm_sleep(struct clockdomain *clkdm);  int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); @@ -214,8 +216,9 @@ extern void __init omap243x_clockdomains_init(void);  extern void __init omap3xxx_clockdomains_init(void);  extern void __init am33xx_clockdomains_init(void);  extern void __init omap44xx_clockdomains_init(void); -extern void _clkdm_add_autodeps(struct clockdomain *clkdm); -extern void _clkdm_del_autodeps(struct clockdomain *clkdm); + +extern void clkdm_add_autodeps(struct clockdomain *clkdm); +extern void clkdm_del_autodeps(struct clockdomain *clkdm);  extern struct clkdm_ops omap2_clkdm_operations;  extern struct clkdm_ops omap3_clkdm_operations; diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c index db650690e9d..6774a53a387 100644 --- a/arch/arm/mach-omap2/cm2xxx.c +++ b/arch/arm/mach-omap2/cm2xxx.c @@ -273,9 +273,6 @@ int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)  static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm)  { -	if (atomic_read(&clkdm->usecount) > 0) -		_clkdm_add_autodeps(clkdm); -  	omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,  				       clkdm->clktrctrl_mask);  } @@ -284,9 +281,6 @@ static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm)  {  	omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,  					clkdm->clktrctrl_mask); - -	if (atomic_read(&clkdm->usecount) > 0) -		_clkdm_del_autodeps(clkdm);  }  static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm) @@ -298,18 +292,8 @@ static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm)  	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,  					      clkdm->clktrctrl_mask); - -	if (hwsup) { -		/* Disable HW transitions when we are changing deps */ -		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -						clkdm->clktrctrl_mask); -		_clkdm_add_autodeps(clkdm); -		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -					       clkdm->clktrctrl_mask); -	} else { -		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) -			omap2xxx_clkdm_wakeup(clkdm); -	} +	if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) +		omap2xxx_clkdm_wakeup(clkdm);  	return 0;  } @@ -324,17 +308,8 @@ static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm)  	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,  					      clkdm->clktrctrl_mask); -	if (hwsup) { -		/* Disable HW transitions when we are changing deps */ -		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -						clkdm->clktrctrl_mask); -		_clkdm_del_autodeps(clkdm); -		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -					       clkdm->clktrctrl_mask); -	} else { -		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) -			omap2xxx_clkdm_sleep(clkdm); -	} +	if (!hwsup && clkdm->flags & CLKDM_CAN_FORCE_SLEEP) +		omap2xxx_clkdm_sleep(clkdm);  	return 0;  } diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index c2086f2e86b..9061c307d91 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c @@ -186,7 +186,7 @@ static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)  			continue; /* only happens if data is erroneous */  		mask |= 1 << cd->clkdm->dep_bit; -		atomic_set(&cd->sleepdep_usecount, 0); +		cd->sleepdep_usecount = 0;  	}  	omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs,  				    OMAP3430_CM_SLEEPDEP); @@ -209,8 +209,8 @@ static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm)  static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm)  { -	if (atomic_read(&clkdm->usecount) > 0) -		_clkdm_add_autodeps(clkdm); +	if (clkdm->usecount > 0) +		clkdm_add_autodeps(clkdm);  	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,  				       clkdm->clktrctrl_mask); @@ -221,8 +221,8 @@ static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm)  	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,  					clkdm->clktrctrl_mask); -	if (atomic_read(&clkdm->usecount) > 0) -		_clkdm_del_autodeps(clkdm); +	if (clkdm->usecount > 0) +		clkdm_del_autodeps(clkdm);  }  static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) @@ -250,7 +250,7 @@ static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm)  		/* Disable HW transitions when we are changing deps */  		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,  						clkdm->clktrctrl_mask); -		_clkdm_add_autodeps(clkdm); +		clkdm_add_autodeps(clkdm);  		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,  					       clkdm->clktrctrl_mask);  	} else { @@ -287,7 +287,7 @@ static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm)  		/* Disable HW transitions when we are changing deps */  		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs,  						clkdm->clktrctrl_mask); -		_clkdm_del_autodeps(clkdm); +		clkdm_del_autodeps(clkdm);  		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs,  					       clkdm->clktrctrl_mask);  	} else { diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 7f9a464f01e..f0290f5566f 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -393,7 +393,7 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)  			continue; /* only happens if data is erroneous */  		mask |= 1 << cd->clkdm->dep_bit; -		atomic_set(&cd->wkdep_usecount, 0); +		cd->wkdep_usecount = 0;  	}  	omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition, diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 22590dbe8f1..80392fca86c 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -36,40 +36,66 @@  /* Mach specific information to be recorded in the C-state driver_data */  struct omap3_idle_statedata { -	u32 mpu_state; -	u32 core_state; +	u8 mpu_state; +	u8 core_state; +	u8 per_min_state; +	u8 flags;  };  static struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd; +/* + * Possible flag bits for struct omap3_idle_statedata.flags: + * + * OMAP_CPUIDLE_CX_NO_CLKDM_IDLE: don't allow the MPU clockdomain to go + *    inactive.  This in turn prevents the MPU DPLL from entering autoidle + *    mode, so wakeup latency is greatly reduced, at the cost of additional + *    energy consumption.  This also prevents the CORE clockdomain from + *    entering idle. + */ +#define OMAP_CPUIDLE_CX_NO_CLKDM_IDLE		BIT(0) + +/* + * Prevent PER OFF if CORE is not in RETention or OFF as this would + * disable PER wakeups completely. + */  static struct omap3_idle_statedata omap3_idle_data[] = {  	{  		.mpu_state = PWRDM_POWER_ON,  		.core_state = PWRDM_POWER_ON, +		/* In C1 do not allow PER state lower than CORE state */ +		.per_min_state = PWRDM_POWER_ON, +		.flags = OMAP_CPUIDLE_CX_NO_CLKDM_IDLE,  	},  	{  		.mpu_state = PWRDM_POWER_ON,  		.core_state = PWRDM_POWER_ON, +		.per_min_state = PWRDM_POWER_RET,  	},  	{  		.mpu_state = PWRDM_POWER_RET,  		.core_state = PWRDM_POWER_ON, +		.per_min_state = PWRDM_POWER_RET,  	},  	{  		.mpu_state = PWRDM_POWER_OFF,  		.core_state = PWRDM_POWER_ON, +		.per_min_state = PWRDM_POWER_RET,  	},  	{  		.mpu_state = PWRDM_POWER_RET,  		.core_state = PWRDM_POWER_RET, +		.per_min_state = PWRDM_POWER_OFF,  	},  	{  		.mpu_state = PWRDM_POWER_OFF,  		.core_state = PWRDM_POWER_RET, +		.per_min_state = PWRDM_POWER_OFF,  	},  	{  		.mpu_state = PWRDM_POWER_OFF,  		.core_state = PWRDM_POWER_OFF, +		.per_min_state = PWRDM_POWER_OFF,  	},  }; @@ -80,27 +106,25 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,  				int index)  {  	struct omap3_idle_statedata *cx = &omap3_idle_data[index]; -	u32 mpu_state = cx->mpu_state, core_state = cx->core_state;  	local_fiq_disable(); -	pwrdm_set_next_pwrst(mpu_pd, mpu_state); -	pwrdm_set_next_pwrst(core_pd, core_state); -  	if (omap_irq_pending() || need_resched())  		goto return_sleep_time;  	/* Deny idle for C1 */ -	if (index == 0) { +	if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE) {  		clkdm_deny_idle(mpu_pd->pwrdm_clkdms[0]); -		clkdm_deny_idle(core_pd->pwrdm_clkdms[0]); +	} else { +		pwrdm_set_next_pwrst(mpu_pd, cx->mpu_state); +		pwrdm_set_next_pwrst(core_pd, cx->core_state);  	}  	/*  	 * Call idle CPU PM enter notifier chain so that  	 * VFP context is saved.  	 */ -	if (mpu_state == PWRDM_POWER_OFF) +	if (cx->mpu_state == PWRDM_POWER_OFF)  		cpu_pm_enter();  	/* Execute ARM wfi */ @@ -110,17 +134,15 @@ static int __omap3_enter_idle(struct cpuidle_device *dev,  	 * Call idle CPU PM enter notifier chain to restore  	 * VFP context.  	 */ -	if (pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF) +	if (cx->mpu_state == PWRDM_POWER_OFF && +	    pwrdm_read_prev_pwrst(mpu_pd) == PWRDM_POWER_OFF)  		cpu_pm_exit();  	/* Re-allow idle for C1 */ -	if (index == 0) { +	if (cx->flags & OMAP_CPUIDLE_CX_NO_CLKDM_IDLE)  		clkdm_allow_idle(mpu_pd->pwrdm_clkdms[0]); -		clkdm_allow_idle(core_pd->pwrdm_clkdms[0]); -	}  return_sleep_time: -  	local_fiq_enable();  	return index; @@ -185,7 +207,7 @@ static int next_valid_state(struct cpuidle_device *dev,  	 * Start search from the next (lower) state.  	 */  	for (idx = index - 1; idx >= 0; idx--) { -		cx =  &omap3_idle_data[idx]; +		cx = &omap3_idle_data[idx];  		if ((cx->mpu_state >= mpu_deepest_state) &&  		    (cx->core_state >= core_deepest_state)) {  			next_index = idx; @@ -209,10 +231,9 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,  			       struct cpuidle_driver *drv,  			       int index)  { -	int new_state_idx; -	u32 core_next_state, per_next_state = 0, per_saved_state = 0; +	int new_state_idx, ret; +	u8 per_next_state, per_saved_state;  	struct omap3_idle_statedata *cx; -	int ret;  	/*  	 * Use only C1 if CAM is active. @@ -233,25 +254,13 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,  	/* Program PER state */  	cx = &omap3_idle_data[new_state_idx]; -	core_next_state = cx->core_state; -	per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd); -	if (new_state_idx == 0) { -		/* In C1 do not allow PER state lower than CORE state */ -		if (per_next_state < core_next_state) -			per_next_state = core_next_state; -	} else { -		/* -		 * Prevent PER OFF if CORE is not in RETention or OFF as this -		 * would disable PER wakeups completely. -		 */ -		if ((per_next_state == PWRDM_POWER_OFF) && -		    (core_next_state > PWRDM_POWER_RET)) -			per_next_state = PWRDM_POWER_RET; -	} -	/* Are we changing PER target state? */ -	if (per_next_state != per_saved_state) +	per_next_state = pwrdm_read_next_pwrst(per_pd); +	per_saved_state = per_next_state; +	if (per_next_state < cx->per_min_state) { +		per_next_state = cx->per_min_state;  		pwrdm_set_next_pwrst(per_pd, per_next_state); +	}  	ret = omap3_enter_idle(dev, drv, new_state_idx); diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 626f3ea3142..6ecc89adda8 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -61,8 +61,7 @@ static int __init omap3_l3_init(void)  	if (!oh)  		pr_err("could not look up %s\n", oh_name); -	pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0, -							   NULL, 0, 0); +	pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0);  	WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); @@ -96,8 +95,7 @@ static int __init omap4_l3_init(void)  			pr_err("could not look up %s\n", oh_name);  	} -	pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL, -						     0, NULL, 0, 0); +	pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL, 0);  	WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); @@ -273,7 +271,7 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data  	keypad_data = sdp4430_keypad_data;  	pdev = omap_device_build(name, id, oh, keypad_data, -			sizeof(struct omap4_keypad_platform_data), NULL, 0, 0); +				 sizeof(struct omap4_keypad_platform_data));  	if (IS_ERR(pdev)) {  		WARN(1, "Can't build omap_device for %s:%s.\n", @@ -297,7 +295,7 @@ static inline void __init omap_init_mbox(void)  		return;  	} -	pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, NULL, 0, 0); +	pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0);  	WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n",  						__func__, PTR_ERR(pdev));  } @@ -337,7 +335,7 @@ static void __init omap_init_mcpdm(void)  		return;  	} -	pdev = omap_device_build("omap-mcpdm", -1, oh, NULL, 0, NULL, 0, 0); +	pdev = omap_device_build("omap-mcpdm", -1, oh, NULL, 0);  	WARN(IS_ERR(pdev), "Can't build omap_device for omap-mcpdm.\n");  }  #else @@ -358,7 +356,7 @@ static void __init omap_init_dmic(void)  		return;  	} -	pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0, NULL, 0, 0); +	pdev = omap_device_build("omap-dmic", -1, oh, NULL, 0);  	WARN(IS_ERR(pdev), "Can't build omap_device for omap-dmic.\n");  }  #else @@ -384,8 +382,7 @@ static void __init omap_init_hdmi_audio(void)  		return;  	} -	pdev = omap_device_build("omap-hdmi-audio-dai", -		-1, oh, NULL, 0, NULL, 0, 0); +	pdev = omap_device_build("omap-hdmi-audio-dai", -1, oh, NULL, 0);  	WARN(IS_ERR(pdev),  	     "Can't build omap_device for omap-hdmi-audio-dai.\n"); @@ -429,8 +426,7 @@ static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused)  	}  	spi_num++; -	pdev = omap_device_build(name, spi_num, oh, pdata, -				sizeof(*pdata),	NULL, 0, 0); +	pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata));  	WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n",  				name, oh->name);  	kfree(pdata); @@ -460,7 +456,7 @@ static void omap_init_rng(void)  	if (!oh)  		return; -	pdev = omap_device_build("omap_rng", -1, oh, NULL, 0, NULL, 0, 0); +	pdev = omap_device_build("omap_rng", -1, oh, NULL, 0);  	WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n");  } @@ -689,8 +685,7 @@ static void __init omap_init_ocp2scp(void)  	pdata->dev_cnt	= dev_cnt; -	pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata), NULL, -								0, false); +	pdev = omap_device_build(name, bus_id, oh, pdata, sizeof(*pdata));  	if (IS_ERR(pdev)) {  		pr_err("Could not build omap_device for %s %s\n",  						name, oh_name); diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index cc75aaf6e76..ff37be1f6f9 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -226,7 +226,7 @@ static struct platform_device *create_dss_pdev(const char *pdev_name,  		dev_set_name(&pdev->dev, "%s", pdev->name);  	ohs[0] = oh; -	od = omap_device_alloc(pdev, ohs, 1, NULL, 0); +	od = omap_device_alloc(pdev, ohs, 1);  	if (IS_ERR(od)) {  		pr_err("Could not alloc omap_device for %s\n", pdev_name);  		r = -ENOMEM; diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index 612b9824987..491c5c8837f 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c @@ -248,7 +248,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)  	p->errata		= configure_dma_errata(); -	pdev = omap_device_build(name, 0, oh, p, sizeof(*p), NULL, 0, 0); +	pdev = omap_device_build(name, 0, oh, p, sizeof(*p));  	kfree(p);  	if (IS_ERR(pdev)) {  		pr_err("%s: Can't build omap_device for %s:%s.\n", diff --git a/arch/arm/mach-omap2/drm.c b/arch/arm/mach-omap2/drm.c index 2a2cfa88ddb..4d8d1a52ffe 100644 --- a/arch/arm/mach-omap2/drm.c +++ b/arch/arm/mach-omap2/drm.c @@ -51,8 +51,7 @@ static int __init omap_init_drm(void)  	oh = omap_hwmod_lookup("dmm");  	if (oh) { -		pdev = omap_device_build(oh->name, -1, oh, NULL, 0, NULL, 0, -					false); +		pdev = omap_device_build(oh->name, -1, oh, NULL, 0);  		WARN(IS_ERR(pdev), "Could not build omap_device for %s\n",  			oh->name);  	} diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c index 399acabc3d0..482ade1923b 100644 --- a/arch/arm/mach-omap2/gpio.c +++ b/arch/arm/mach-omap2/gpio.c @@ -131,8 +131,7 @@ static int __init omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)  	pwrdm = omap_hwmod_get_pwrdm(oh);  	pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm); -	pdev = omap_device_build(name, id - 1, oh, pdata, -				sizeof(*pdata),	NULL, 0, false); +	pdev = omap_device_build(name, id - 1, oh, pdata, sizeof(*pdata));  	kfree(pdata);  	if (IS_ERR(pdev)) { diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 8033cb747c8..bc0783364ad 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1220,7 +1220,7 @@ static int __init omap_gpmc_init(void)  		return -ENODEV;  	} -	pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0, NULL, 0, 0); +	pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0);  	WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);  	return IS_ERR(pdev) ? PTR_ERR(pdev) : 0; diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c index ab7bf181a10..b7aa8ba2ccb 100644 --- a/arch/arm/mach-omap2/hdq1w.c +++ b/arch/arm/mach-omap2/hdq1w.c @@ -87,7 +87,7 @@ static int __init omap_init_hdq(void)  	if (!oh)  		return 0; -	pdev = omap_device_build(devname, id, oh, NULL, 0, NULL, 0, 0); +	pdev = omap_device_build(devname, id, oh, NULL, 0);  	WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",  	     devname, oh->name); diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index 4a964338992..2ef1f8714fc 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -522,7 +522,7 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,  	}  	dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id); -	od = omap_device_alloc(pdev, ohs, 1, NULL, 0); +	od = omap_device_alloc(pdev, ohs, 1);  	if (IS_ERR(od)) {  		pr_err("Could not allocate od for %s\n", name);  		goto put_pdev; diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c index 1df9b5feda1..c3688903f3d 100644 --- a/arch/arm/mach-omap2/hwspinlock.c +++ b/arch/arm/mach-omap2/hwspinlock.c @@ -46,8 +46,7 @@ static int __init hwspinlocks_init(void)  		return -EINVAL;  	pdev = omap_device_build(dev_name, 0, oh, &omap_hwspinlock_pdata, -				sizeof(struct hwspinlock_pdata), -				NULL, 0, false); +				sizeof(struct hwspinlock_pdata));  	if (IS_ERR(pdev)) {  		pr_err("Can't build omap_device for %s:%s\n", dev_name,  								oh_name); diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c index b9074dde3b9..c11a23fa966 100644 --- a/arch/arm/mach-omap2/i2c.c +++ b/arch/arm/mach-omap2/i2c.c @@ -178,8 +178,7 @@ int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *i2c_pdata,  	if (cpu_is_omap34xx())  		pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;  	pdev = omap_device_build(name, bus_id, oh, pdata, -			sizeof(struct omap_i2c_bus_platform_data), -			NULL, 0, 0); +				 sizeof(struct omap_i2c_bus_platform_data));  	WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name);  	return PTR_RET(pdev); diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index df49f2a4946..453580410ae 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -101,7 +101,7 @@ static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused)  		count++;  	}  	pdev = omap_device_build_ss(name, id, oh_device, count, pdata, -				sizeof(*pdata), NULL, 0, false); +				    sizeof(*pdata));  	kfree(pdata);  	if (IS_ERR(pdev))  {  		pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c index aafdd4ca9f4..c52d8b4a3e9 100644 --- a/arch/arm/mach-omap2/msdi.c +++ b/arch/arm/mach-omap2/msdi.c @@ -150,7 +150,7 @@ void __init omap242x_init_mmc(struct omap_mmc_platform_data **mmc_data)  		return;  	}  	pdev = omap_device_build(dev_name, id, oh, mmc_data[0], -				 sizeof(struct omap_mmc_platform_data), NULL, 0, 0); +				 sizeof(struct omap_mmc_platform_data));  	if (IS_ERR(pdev))  		WARN(1, "Can'd build omap_device for %s:%s.\n",  					dev_name, oh->name); diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index 6da4f7ae9d7..f7f38c7fd5f 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -41,8 +41,7 @@ static int __init omap_iommu_dev_init(struct omap_hwmod *oh, void *unused)  		pdata->deassert_reset = omap_device_deassert_hardreset;  	} -	pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata), -				NULL, 0, 0); +	pdev = omap_device_build("omap-iommu", i, oh, pdata, sizeof(*pdata));  	kfree(pdata); diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index aac46bfdbeb..8bcb64bcdcd 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -87,37 +87,6 @@ static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)  }  /* - * Set the CPUx powerdomain's previous power state - */ -static inline void set_cpu_next_pwrst(unsigned int cpu_id, -				unsigned int power_state) -{ -	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); - -	pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); -} - -/* - * Read CPU's previous power state - */ -static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id) -{ -	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); - -	return pwrdm_read_prev_pwrst(pm_info->pwrdm); -} - -/* - * Clear the CPUx powerdomain's previous power state - */ -static inline void clear_cpu_prev_pwrst(unsigned int cpu_id) -{ -	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); - -	pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); -} - -/*   * Store the SCU power status value to scratchpad memory   */  static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) @@ -230,6 +199,7 @@ static void save_l2x0_context(void)   */  int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)  { +	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);  	unsigned int save_state = 0;  	unsigned int wakeup_cpu; @@ -268,7 +238,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)  		save_state = 2;  	cpu_clear_prev_logic_pwrst(cpu); -	set_cpu_next_pwrst(cpu, power_state); +	pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);  	set_cpu_wakeup_addr(cpu, virt_to_phys(omap4_cpu_resume));  	scu_pwrst_prepare(cpu, power_state);  	l2x0_pwrst_prepare(cpu, save_state); @@ -286,7 +256,7 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)  	 * domain transition  	 */  	wakeup_cpu = smp_processor_id(); -	set_cpu_next_pwrst(wakeup_cpu, PWRDM_POWER_ON); +	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);  	pwrdm_post_transition(NULL); @@ -300,8 +270,8 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)   */  int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)  { -	unsigned int cpu_state = 0;  	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu); +	unsigned int cpu_state = 0;  	if (omap_rev() == OMAP4430_REV_ES1_0)  		return -ENXIO; @@ -309,8 +279,8 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)  	if (power_state == PWRDM_POWER_OFF)  		cpu_state = 1; -	clear_cpu_prev_pwrst(cpu); -	set_cpu_next_pwrst(cpu, power_state); +	pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); +	pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);  	set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));  	scu_pwrst_prepare(cpu, power_state); @@ -321,7 +291,7 @@ int __cpuinit omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)  	 */  	omap4_finish_suspend(cpu_state); -	set_cpu_next_pwrst(cpu, PWRDM_POWER_ON); +	pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);  	return 0;  } diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index e065daa537c..6ee3ad3dd95 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -17,68 +17,15 @@   * to control power management and interconnect properties of their   * devices.   * - * In the medium- to long-term, this code should either be - * a) implemented via arch-specific pointers in platform_data - * or - * b) implemented as a proper omap_bus/omap_device in Linux, no more - *    platform_data func pointers + * In the medium- to long-term, this code should be implemented as a + * proper omap_bus/omap_device in Linux, no more platform_data func + * pointers   *   * - * Guidelines for usage by driver authors: - * - * 1. These functions are intended to be used by device drivers via - * function pointers in struct platform_data.  As an example, - * omap_device_enable() should be passed to the driver as - * - * struct foo_driver_platform_data { - * ... - *      int (*device_enable)(struct platform_device *pdev); - * ... - * } - * - * Note that the generic "device_enable" name is used, rather than - * "omap_device_enable".  This is so other architectures can pass in their - * own enable/disable functions here. - * - * This should be populated during device setup: - * - * ... - * pdata->device_enable = omap_device_enable; - * ... - * - * 2. Drivers should first check to ensure the function pointer is not null - * before calling it, as in: - * - * if (pdata->device_enable) - *     pdata->device_enable(pdev); - * - * This allows other architectures that don't use similar device_enable()/ - * device_shutdown() functions to execute normally. - * - * ... - * - * Suggested usage by device drivers: - * - * During device initialization: - * device_enable() - * - * During device idle: - * (save remaining device context if necessary) - * device_idle(); - * - * During device resume: - * device_enable(); - * (restore context if necessary) - * - * During device shutdown: - * device_shutdown() - * (device must be reinitialized at this point to use it again) - *   */  #undef DEBUG  #include <linux/kernel.h> -#include <linux/export.h>  #include <linux/platform_device.h>  #include <linux/slab.h>  #include <linux/err.h> @@ -92,155 +39,8 @@  #include "omap_device.h"  #include "omap_hwmod.h" -/* These parameters are passed to _omap_device_{de,}activate() */ -#define USE_WAKEUP_LAT			0 -#define IGNORE_WAKEUP_LAT		1 - -static int omap_early_device_register(struct platform_device *pdev); - -static struct omap_device_pm_latency omap_default_latency[] = { -	{ -		.deactivate_func = omap_device_idle_hwmods, -		.activate_func   = omap_device_enable_hwmods, -		.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, -	} -}; -  /* Private functions */ -/** - * _omap_device_activate - increase device readiness - * @od: struct omap_device * - * @ignore_lat: increase to latency target (0) or full readiness (1)? - * - * Increase readiness of omap_device @od (thus decreasing device - * wakeup latency, but consuming more power).  If @ignore_lat is - * IGNORE_WAKEUP_LAT, make the omap_device fully active.  Otherwise, - * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup - * latency is greater than the requested maximum wakeup latency, step - * backwards in the omap_device_pm_latency table to ensure the - * device's maximum wakeup latency is less than or equal to the - * requested maximum wakeup latency.  Returns 0. - */ -static int _omap_device_activate(struct omap_device *od, u8 ignore_lat) -{ -	struct timespec a, b, c; - -	dev_dbg(&od->pdev->dev, "omap_device: activating\n"); - -	while (od->pm_lat_level > 0) { -		struct omap_device_pm_latency *odpl; -		unsigned long long act_lat = 0; - -		od->pm_lat_level--; - -		odpl = od->pm_lats + od->pm_lat_level; - -		if (!ignore_lat && -		    (od->dev_wakeup_lat <= od->_dev_wakeup_lat_limit)) -			break; - -		read_persistent_clock(&a); - -		/* XXX check return code */ -		odpl->activate_func(od); - -		read_persistent_clock(&b); - -		c = timespec_sub(b, a); -		act_lat = timespec_to_ns(&c); - -		dev_dbg(&od->pdev->dev, -			"omap_device: pm_lat %d: activate: elapsed time %llu nsec\n", -			od->pm_lat_level, act_lat); - -		if (act_lat > odpl->activate_lat) { -			odpl->activate_lat_worst = act_lat; -			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) { -				odpl->activate_lat = act_lat; -				dev_dbg(&od->pdev->dev, -					"new worst case activate latency %d: %llu\n", -					od->pm_lat_level, act_lat); -			} else -				dev_warn(&od->pdev->dev, -					 "activate latency %d higher than expected. (%llu > %d)\n", -					 od->pm_lat_level, act_lat, -					 odpl->activate_lat); -		} - -		od->dev_wakeup_lat -= odpl->activate_lat; -	} - -	return 0; -} - -/** - * _omap_device_deactivate - decrease device readiness - * @od: struct omap_device * - * @ignore_lat: decrease to latency target (0) or full inactivity (1)? - * - * Decrease readiness of omap_device @od (thus increasing device - * wakeup latency, but conserving power).  If @ignore_lat is - * IGNORE_WAKEUP_LAT, make the omap_device fully inactive.  Otherwise, - * if @ignore_lat is USE_WAKEUP_LAT, and the device's maximum wakeup - * latency is less than the requested maximum wakeup latency, step - * forwards in the omap_device_pm_latency table to ensure the device's - * maximum wakeup latency is less than or equal to the requested - * maximum wakeup latency.  Returns 0. - */ -static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat) -{ -	struct timespec a, b, c; - -	dev_dbg(&od->pdev->dev, "omap_device: deactivating\n"); - -	while (od->pm_lat_level < od->pm_lats_cnt) { -		struct omap_device_pm_latency *odpl; -		unsigned long long deact_lat = 0; - -		odpl = od->pm_lats + od->pm_lat_level; - -		if (!ignore_lat && -		    ((od->dev_wakeup_lat + odpl->activate_lat) > -		     od->_dev_wakeup_lat_limit)) -			break; - -		read_persistent_clock(&a); - -		/* XXX check return code */ -		odpl->deactivate_func(od); - -		read_persistent_clock(&b); - -		c = timespec_sub(b, a); -		deact_lat = timespec_to_ns(&c); - -		dev_dbg(&od->pdev->dev, -			"omap_device: pm_lat %d: deactivate: elapsed time %llu nsec\n", -			od->pm_lat_level, deact_lat); - -		if (deact_lat > odpl->deactivate_lat) { -			odpl->deactivate_lat_worst = deact_lat; -			if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) { -				odpl->deactivate_lat = deact_lat; -				dev_dbg(&od->pdev->dev, -					"new worst case deactivate latency %d: %llu\n", -					od->pm_lat_level, deact_lat); -			} else -				dev_warn(&od->pdev->dev, -					 "deactivate latency %d higher than expected. (%llu > %d)\n", -					 od->pm_lat_level, deact_lat, -					 odpl->deactivate_lat); -		} - -		od->dev_wakeup_lat += odpl->activate_lat; - -		od->pm_lat_level++; -	} - -	return 0; -} -  static void _add_clkdev(struct omap_device *od, const char *clk_alias,  		       const char *clk_name)  { @@ -315,9 +115,6 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od,   * @oh: ptr to the single omap_hwmod that backs this omap_device   * @pdata: platform_data ptr to associate with the platform_device   * @pdata_len: amount of memory pointed to by @pdata - * @pm_lats: pointer to a omap_device_pm_latency array for this device - * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats - * @is_early_device: should the device be registered as an early device or not   *   * Function for building an omap_device already registered from device-tree   * @@ -356,7 +153,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)  		hwmods[i] = oh;  	} -	od = omap_device_alloc(pdev, hwmods, oh_cnt, NULL, 0); +	od = omap_device_alloc(pdev, hwmods, oh_cnt);  	if (!od) {  		dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n",  			oh_name); @@ -407,6 +204,39 @@ static int _omap_device_notifier_call(struct notifier_block *nb,  	return NOTIFY_DONE;  } +/** + * _omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods + * @od: struct omap_device *od + * + * Enable all underlying hwmods.  Returns 0. + */ +static int _omap_device_enable_hwmods(struct omap_device *od) +{ +	int i; + +	for (i = 0; i < od->hwmods_cnt; i++) +		omap_hwmod_enable(od->hwmods[i]); + +	/* XXX pass along return value here? */ +	return 0; +} + +/** + * _omap_device_idle_hwmods - call omap_hwmod_idle() on all hwmods + * @od: struct omap_device *od + * + * Idle all underlying hwmods.  Returns 0. + */ +static int _omap_device_idle_hwmods(struct omap_device *od) +{ +	int i; + +	for (i = 0; i < od->hwmods_cnt; i++) +		omap_hwmod_idle(od->hwmods[i]); + +	/* XXX pass along return value here? */ +	return 0; +}  /* Public functions for use by core code */ @@ -526,18 +356,14 @@ static int _od_fill_dma_resources(struct omap_device *od,   * @oh: ptr to the single omap_hwmod that backs this omap_device   * @pdata: platform_data ptr to associate with the platform_device   * @pdata_len: amount of memory pointed to by @pdata - * @pm_lats: pointer to a omap_device_pm_latency array for this device - * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats   *   * Convenience function for allocating an omap_device structure and filling - * hwmods, resources and pm_latency attributes. + * hwmods, and resources.   *   * Returns an struct omap_device pointer or ERR_PTR() on error;   */  struct omap_device *omap_device_alloc(struct platform_device *pdev, -					struct omap_hwmod **ohs, int oh_cnt, -					struct omap_device_pm_latency *pm_lats, -					int pm_lats_cnt) +					struct omap_hwmod **ohs, int oh_cnt)  {  	int ret = -ENOMEM;  	struct omap_device *od; @@ -626,18 +452,6 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,  		goto oda_exit3;  have_everything: -	if (!pm_lats) { -		pm_lats = omap_default_latency; -		pm_lats_cnt = ARRAY_SIZE(omap_default_latency); -	} - -	od->pm_lats_cnt = pm_lats_cnt; -	od->pm_lats = kmemdup(pm_lats, -			sizeof(struct omap_device_pm_latency) * pm_lats_cnt, -			GFP_KERNEL); -	if (!od->pm_lats) -		goto oda_exit3; -  	pdev->archdata.od = od;  	for (i = 0; i < oh_cnt; i++) { @@ -663,7 +477,6 @@ void omap_device_delete(struct omap_device *od)  		return;  	od->pdev->archdata.od = NULL; -	kfree(od->pm_lats);  	kfree(od->hwmods);  	kfree(od);  } @@ -675,9 +488,6 @@ void omap_device_delete(struct omap_device *od)   * @oh: ptr to the single omap_hwmod that backs this omap_device   * @pdata: platform_data ptr to associate with the platform_device   * @pdata_len: amount of memory pointed to by @pdata - * @pm_lats: pointer to a omap_device_pm_latency array for this device - * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats - * @is_early_device: should the device be registered as an early device or not   *   * Convenience function for building and registering a single   * omap_device record, which in turn builds and registers a @@ -685,11 +495,10 @@ void omap_device_delete(struct omap_device *od)   * information.  Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise,   * passes along the return value of omap_device_build_ss().   */ -struct platform_device __init *omap_device_build(const char *pdev_name, int pdev_id, -				      struct omap_hwmod *oh, void *pdata, -				      int pdata_len, -				      struct omap_device_pm_latency *pm_lats, -				      int pm_lats_cnt, int is_early_device) +struct platform_device __init *omap_device_build(const char *pdev_name, +						 int pdev_id, +						 struct omap_hwmod *oh, +						 void *pdata, int pdata_len)  {  	struct omap_hwmod *ohs[] = { oh }; @@ -697,8 +506,7 @@ struct platform_device __init *omap_device_build(const char *pdev_name, int pdev  		return ERR_PTR(-EINVAL);  	return omap_device_build_ss(pdev_name, pdev_id, ohs, 1, pdata, -				    pdata_len, pm_lats, pm_lats_cnt, -				    is_early_device); +				    pdata_len);  }  /** @@ -708,9 +516,6 @@ struct platform_device __init *omap_device_build(const char *pdev_name, int pdev   * @oh: ptr to the single omap_hwmod that backs this omap_device   * @pdata: platform_data ptr to associate with the platform_device   * @pdata_len: amount of memory pointed to by @pdata - * @pm_lats: pointer to a omap_device_pm_latency array for this device - * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats - * @is_early_device: should the device be registered as an early device or not   *   * Convenience function for building and registering an omap_device   * subsystem record.  Subsystem records consist of multiple @@ -718,11 +523,11 @@ struct platform_device __init *omap_device_build(const char *pdev_name, int pdev   * platform_device record.  Returns an ERR_PTR() on error, or passes   * along the return value of omap_device_register().   */ -struct platform_device __init *omap_device_build_ss(const char *pdev_name, int pdev_id, -					 struct omap_hwmod **ohs, int oh_cnt, -					 void *pdata, int pdata_len, -					 struct omap_device_pm_latency *pm_lats, -					 int pm_lats_cnt, int is_early_device) +struct platform_device __init *omap_device_build_ss(const char *pdev_name, +						    int pdev_id, +						    struct omap_hwmod **ohs, +						    int oh_cnt, void *pdata, +						    int pdata_len)  {  	int ret = -ENOMEM;  	struct platform_device *pdev; @@ -746,7 +551,7 @@ struct platform_device __init *omap_device_build_ss(const char *pdev_name, int p  	else  		dev_set_name(&pdev->dev, "%s", pdev->name); -	od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt); +	od = omap_device_alloc(pdev, ohs, oh_cnt);  	if (IS_ERR(od))  		goto odbs_exit1; @@ -754,10 +559,7 @@ struct platform_device __init *omap_device_build_ss(const char *pdev_name, int p  	if (ret)  		goto odbs_exit2; -	if (is_early_device) -		ret = omap_early_device_register(pdev); -	else -		ret = omap_device_register(pdev); +	ret = omap_device_register(pdev);  	if (ret)  		goto odbs_exit2; @@ -774,24 +576,6 @@ odbs_exit:  	return ERR_PTR(ret);  } -/** - * omap_early_device_register - register an omap_device as an early platform - * device. - * @od: struct omap_device * to register - * - * Register the omap_device structure.  This currently just calls - * platform_early_add_device() on the underlying platform_device. - * Returns 0 by default. - */ -static int __init omap_early_device_register(struct platform_device *pdev) -{ -	struct platform_device *devices[1]; - -	devices[0] = pdev; -	early_platform_add_devices(devices, 1); -	return 0; -} -  #ifdef CONFIG_PM_RUNTIME  static int _od_runtime_suspend(struct device *dev)  { @@ -902,10 +686,9 @@ int omap_device_register(struct platform_device *pdev)   * to be accessible and ready to operate.  This generally involves   * enabling clocks, setting SYSCONFIG registers; and in the future may   * involve remuxing pins.  Device drivers should call this function - * (through platform_data function pointers) where they would normally - * enable clocks, etc.  Returns -EINVAL if called when the omap_device - * is already enabled, or passes along the return value of - * _omap_device_activate(). + * indirectly via pm_runtime_get*().  Returns -EINVAL if called when + * the omap_device is already enabled, or passes along the return + * value of _omap_device_enable_hwmods().   */  int omap_device_enable(struct platform_device *pdev)  { @@ -921,14 +704,8 @@ int omap_device_enable(struct platform_device *pdev)  		return -EINVAL;  	} -	/* Enable everything if we're enabling this device from scratch */ -	if (od->_state == OMAP_DEVICE_STATE_UNKNOWN) -		od->pm_lat_level = od->pm_lats_cnt; - -	ret = _omap_device_activate(od, IGNORE_WAKEUP_LAT); +	ret = _omap_device_enable_hwmods(od); -	od->dev_wakeup_lat = 0; -	od->_dev_wakeup_lat_limit = UINT_MAX;  	od->_state = OMAP_DEVICE_STATE_ENABLED;  	return ret; @@ -938,14 +715,10 @@ int omap_device_enable(struct platform_device *pdev)   * omap_device_idle - idle an omap_device   * @od: struct omap_device * to idle   * - * Idle omap_device @od by calling as many .deactivate_func() entries - * in the omap_device's pm_lats table as is possible without exceeding - * the device's maximum wakeup latency limit, pm_lat_limit.  Device - * drivers should call this function (through platform_data function - * pointers) where they would normally disable clocks after operations - * complete, etc..  Returns -EINVAL if the omap_device is not + * Idle omap_device @od.  Device drivers call this function indirectly + * via pm_runtime_put*().  Returns -EINVAL if the omap_device is not   * currently enabled, or passes along the return value of - * _omap_device_deactivate(). + * _omap_device_idle_hwmods().   */  int omap_device_idle(struct platform_device *pdev)  { @@ -961,7 +734,7 @@ int omap_device_idle(struct platform_device *pdev)  		return -EINVAL;  	} -	ret = _omap_device_deactivate(od, USE_WAKEUP_LAT); +	ret = _omap_device_idle_hwmods(od);  	od->_state = OMAP_DEVICE_STATE_IDLE; @@ -969,42 +742,6 @@ int omap_device_idle(struct platform_device *pdev)  }  /** - * omap_device_shutdown - shut down an omap_device - * @od: struct omap_device * to shut down - * - * Shut down omap_device @od by calling all .deactivate_func() entries - * in the omap_device's pm_lats table and then shutting down all of - * the underlying omap_hwmods.  Used when a device is being "removed" - * or a device driver is being unloaded.  Returns -EINVAL if the - * omap_device is not currently enabled or idle, or passes along the - * return value of _omap_device_deactivate(). - */ -int omap_device_shutdown(struct platform_device *pdev) -{ -	int ret, i; -	struct omap_device *od; - -	od = to_omap_device(pdev); - -	if (od->_state != OMAP_DEVICE_STATE_ENABLED && -	    od->_state != OMAP_DEVICE_STATE_IDLE) { -		dev_warn(&pdev->dev, -			 "omap_device: %s() called from invalid state %d\n", -			 __func__, od->_state); -		return -EINVAL; -	} - -	ret = _omap_device_deactivate(od, IGNORE_WAKEUP_LAT); - -	for (i = 0; i < od->hwmods_cnt; i++) -		omap_hwmod_shutdown(od->hwmods[i]); - -	od->_state = OMAP_DEVICE_STATE_SHUTDOWN; - -	return ret; -} - -/**   * omap_device_assert_hardreset - set a device's hardreset line   * @pdev: struct platform_device * to reset   * @name: const char * name of the reset line @@ -1060,86 +797,6 @@ int omap_device_deassert_hardreset(struct platform_device *pdev,  }  /** - * omap_device_align_pm_lat - activate/deactivate device to match wakeup lat lim - * @od: struct omap_device * - * - * When a device's maximum wakeup latency limit changes, call some of - * the .activate_func or .deactivate_func function pointers in the - * omap_device's pm_lats array to ensure that the device's maximum - * wakeup latency is less than or equal to the new latency limit. - * Intended to be called by OMAP PM code whenever a device's maximum - * wakeup latency limit changes (e.g., via - * omap_pm_set_dev_wakeup_lat()).  Returns 0 if nothing needs to be - * done (e.g., if the omap_device is not currently idle, or if the - * wakeup latency is already current with the new limit) or passes - * along the return value of _omap_device_deactivate() or - * _omap_device_activate(). - */ -int omap_device_align_pm_lat(struct platform_device *pdev, -			     u32 new_wakeup_lat_limit) -{ -	int ret = -EINVAL; -	struct omap_device *od; - -	od = to_omap_device(pdev); - -	if (new_wakeup_lat_limit == od->dev_wakeup_lat) -		return 0; - -	od->_dev_wakeup_lat_limit = new_wakeup_lat_limit; - -	if (od->_state != OMAP_DEVICE_STATE_IDLE) -		return 0; -	else if (new_wakeup_lat_limit > od->dev_wakeup_lat) -		ret = _omap_device_deactivate(od, USE_WAKEUP_LAT); -	else if (new_wakeup_lat_limit < od->dev_wakeup_lat) -		ret = _omap_device_activate(od, USE_WAKEUP_LAT); - -	return ret; -} - -/** - * omap_device_get_pwrdm - return the powerdomain * associated with @od - * @od: struct omap_device * - * - * Return the powerdomain associated with the first underlying - * omap_hwmod for this omap_device.  Intended for use by core OMAP PM - * code.  Returns NULL on error or a struct powerdomain * upon - * success. - */ -struct powerdomain *omap_device_get_pwrdm(struct omap_device *od) -{ -	/* -	 * XXX Assumes that all omap_hwmod powerdomains are identical. -	 * This may not necessarily be true.  There should be a sanity -	 * check in here to WARN() if any difference appears. -	 */ -	if (!od->hwmods_cnt) -		return NULL; - -	return omap_hwmod_get_pwrdm(od->hwmods[0]); -} - -/** - * omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base - * @od: struct omap_device * - * - * Return the MPU's virtual address for the base of the hwmod, from - * the ioremap() that the hwmod code does.  Only valid if there is one - * hwmod associated with this device.  Returns NULL if there are zero - * or more than one hwmods associated with this omap_device; - * otherwise, passes along the return value from - * omap_hwmod_get_mpu_rt_va(). - */ -void __iomem *omap_device_get_rt_va(struct omap_device *od) -{ -	if (od->hwmods_cnt != 1) -		return NULL; - -	return omap_hwmod_get_mpu_rt_va(od->hwmods[0]); -} - -/**   * omap_device_get_by_hwmod_name() - convert a hwmod name to   * device pointer.   * @oh_name: name of the hwmod device @@ -1173,82 +830,6 @@ struct device *omap_device_get_by_hwmod_name(const char *oh_name)  	return &oh->od->pdev->dev;  } -EXPORT_SYMBOL(omap_device_get_by_hwmod_name); - -/* - * Public functions intended for use in omap_device_pm_latency - * .activate_func and .deactivate_func function pointers - */ - -/** - * omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods - * @od: struct omap_device *od - * - * Enable all underlying hwmods.  Returns 0. - */ -int omap_device_enable_hwmods(struct omap_device *od) -{ -	int i; - -	for (i = 0; i < od->hwmods_cnt; i++) -		omap_hwmod_enable(od->hwmods[i]); - -	/* XXX pass along return value here? */ -	return 0; -} - -/** - * omap_device_idle_hwmods - call omap_hwmod_idle() on all hwmods - * @od: struct omap_device *od - * - * Idle all underlying hwmods.  Returns 0. - */ -int omap_device_idle_hwmods(struct omap_device *od) -{ -	int i; - -	for (i = 0; i < od->hwmods_cnt; i++) -		omap_hwmod_idle(od->hwmods[i]); - -	/* XXX pass along return value here? */ -	return 0; -} - -/** - * omap_device_disable_clocks - disable all main and interface clocks - * @od: struct omap_device *od - * - * Disable the main functional clock and interface clock for all of the - * omap_hwmods associated with the omap_device.  Returns 0. - */ -int omap_device_disable_clocks(struct omap_device *od) -{ -	int i; - -	for (i = 0; i < od->hwmods_cnt; i++) -		omap_hwmod_disable_clocks(od->hwmods[i]); - -	/* XXX pass along return value here? */ -	return 0; -} - -/** - * omap_device_enable_clocks - enable all main and interface clocks - * @od: struct omap_device *od - * - * Enable the main functional clock and interface clock for all of the - * omap_hwmods associated with the omap_device.  Returns 0. - */ -int omap_device_enable_clocks(struct omap_device *od) -{ -	int i; - -	for (i = 0; i < od->hwmods_cnt; i++) -		omap_hwmod_enable_clocks(od->hwmods[i]); - -	/* XXX pass along return value here? */ -	return 0; -}  static struct notifier_block platform_nb = {  	.notifier_call = _omap_device_notifier_call, diff --git a/arch/arm/mach-omap2/omap_device.h b/arch/arm/mach-omap2/omap_device.h index 0933c599bf8..044c31d50e5 100644 --- a/arch/arm/mach-omap2/omap_device.h +++ b/arch/arm/mach-omap2/omap_device.h @@ -13,20 +13,12 @@   * it under the terms of the GNU General Public License version 2 as   * published by the Free Software Foundation.   * - * Eventually this type of functionality should either be - * a) implemented via arch-specific pointers in platform_device - * or - * b) implemented as a proper omap_bus/omap_device in Linux, no more - *    platform_device + * This type of functionality should be implemented as a proper + * omap_bus/omap_device in Linux.   *   * omap_device differs from omap_hwmod in that it includes external   * (e.g., board- and system-level) integration details.  omap_hwmod   * stores hardware data that is invariant for a given OMAP chip. - * - * To do: - * - GPIO integration - * - regulator integration - *   */  #ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H  #define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_OMAP_DEVICE_H @@ -45,19 +37,14 @@ extern struct dev_pm_domain omap_device_pm_domain;  #define OMAP_DEVICE_STATE_SHUTDOWN	3  /* omap_device.flags values */ -#define OMAP_DEVICE_SUSPENDED BIT(0) -#define OMAP_DEVICE_NO_IDLE_ON_SUSPEND BIT(1) +#define OMAP_DEVICE_SUSPENDED		BIT(0) +#define OMAP_DEVICE_NO_IDLE_ON_SUSPEND	BIT(1)  /**   * struct omap_device - omap_device wrapper for platform_devices   * @pdev: platform_device   * @hwmods: (one .. many per omap_device)   * @hwmods_cnt: ARRAY_SIZE() of @hwmods - * @pm_lats: ptr to an omap_device_pm_latency table - * @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats - * @pm_lat_level: array index of the last odpl entry executed - -1 if never - * @dev_wakeup_lat: dev wakeup latency in nanoseconds - * @_dev_wakeup_lat_limit: dev wakeup latency limit in nsec - set by OMAP PM   * @_state: one of OMAP_DEVICE_STATE_* (see above)   * @flags: device flags   * @_driver_status: one of BUS_NOTIFY_*_DRIVER from <linux/device.h> @@ -71,12 +58,7 @@ extern struct dev_pm_domain omap_device_pm_domain;  struct omap_device {  	struct platform_device		*pdev;  	struct omap_hwmod		**hwmods; -	struct omap_device_pm_latency	*pm_lats; -	u32				dev_wakeup_lat; -	u32				_dev_wakeup_lat_limit;  	unsigned long			_driver_status; -	u8				pm_lats_cnt; -	s8				pm_lat_level;  	u8				hwmods_cnt;  	u8				_state;  	u8                              flags; @@ -86,36 +68,25 @@ struct omap_device {  int omap_device_enable(struct platform_device *pdev);  int omap_device_idle(struct platform_device *pdev); -int omap_device_shutdown(struct platform_device *pdev);  /* Core code interface */  struct platform_device *omap_device_build(const char *pdev_name, int pdev_id, -				      struct omap_hwmod *oh, void *pdata, -				      int pdata_len, -				      struct omap_device_pm_latency *pm_lats, -				      int pm_lats_cnt, int is_early_device); +					  struct omap_hwmod *oh, void *pdata, +					  int pdata_len);  struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,  					 struct omap_hwmod **oh, int oh_cnt, -					 void *pdata, int pdata_len, -					 struct omap_device_pm_latency *pm_lats, -					 int pm_lats_cnt, int is_early_device); +					 void *pdata, int pdata_len);  struct omap_device *omap_device_alloc(struct platform_device *pdev, -				      struct omap_hwmod **ohs, int oh_cnt, -				      struct omap_device_pm_latency *pm_lats, -				      int pm_lats_cnt); +				      struct omap_hwmod **ohs, int oh_cnt);  void omap_device_delete(struct omap_device *od);  int omap_device_register(struct platform_device *pdev); -void __iomem *omap_device_get_rt_va(struct omap_device *od);  struct device *omap_device_get_by_hwmod_name(const char *oh_name);  /* OMAP PM interface */ -int omap_device_align_pm_lat(struct platform_device *pdev, -			     u32 new_wakeup_lat_limit); -struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);  int omap_device_get_context_loss_count(struct platform_device *pdev);  /* Other */ @@ -124,40 +95,6 @@ int omap_device_assert_hardreset(struct platform_device *pdev,  				 const char *name);  int omap_device_deassert_hardreset(struct platform_device *pdev,  				 const char *name); -int omap_device_idle_hwmods(struct omap_device *od); -int omap_device_enable_hwmods(struct omap_device *od); - -int omap_device_disable_clocks(struct omap_device *od); -int omap_device_enable_clocks(struct omap_device *od); - -/* - * Entries should be kept in latency order ascending - * - * deact_lat is the maximum number of microseconds required to complete - * deactivate_func() at the device's slowest OPP. - * - * act_lat is the maximum number of microseconds required to complete - * activate_func() at the device's slowest OPP. - * - * This will result in some suboptimal power management decisions at fast - * OPPs, but avoids having to recompute all device power management decisions - * if the system shifts from a fast OPP to a slow OPP (in order to meet - * latency requirements). - * - * XXX should deactivate_func/activate_func() take platform_device pointers - * rather than omap_device pointers? - */ -struct omap_device_pm_latency { -	u32 deactivate_lat; -	u32 deactivate_lat_worst; -	int (*deactivate_func)(struct omap_device *od); -	u32 activate_lat; -	u32 activate_lat_worst; -	int (*activate_func)(struct omap_device *od); -	u32 flags; -}; - -#define OMAP_DEVICE_LATENCY_AUTO_ADJUST BIT(1)  /* Get omap_device pointer from platform_device pointer */  static inline struct omap_device *to_omap_device(struct platform_device *pdev) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 6549439d8d5..30657b7c3e3 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -139,6 +139,8 @@  #include <linux/slab.h>  #include <linux/bootmem.h> +#include <asm/system_misc.h> +  #include "clock.h"  #include "omap_hwmod.h" @@ -2134,6 +2136,8 @@ static int _enable(struct omap_hwmod *oh)  	_enable_clocks(oh);  	if (soc_ops.enable_module)  		soc_ops.enable_module(oh); +	if (oh->flags & HWMOD_BLOCK_WFI) +		disable_hlt();  	if (soc_ops.update_context_lost)  		soc_ops.update_context_lost(oh); @@ -2195,6 +2199,8 @@ static int _idle(struct omap_hwmod *oh)  		_idle_sysc(oh);  	_del_initiator_dep(oh, mpu_oh); +	if (oh->flags & HWMOD_BLOCK_WFI) +		enable_hlt();  	if (soc_ops.disable_module)  		soc_ops.disable_module(oh); @@ -2303,6 +2309,8 @@ static int _shutdown(struct omap_hwmod *oh)  	if (oh->_state == _HWMOD_STATE_ENABLED) {  		_del_initiator_dep(oh, mpu_oh);  		/* XXX what about the other system initiators here? dma, dsp */ +		if (oh->flags & HWMOD_BLOCK_WFI) +			enable_hlt();  		if (soc_ops.disable_module)  			soc_ops.disable_module(oh);  		_disable_clocks(oh); diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 3ae852a522f..80c00e706d6 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -451,6 +451,14 @@ struct omap_hwmod_omap4_prcm {   *     enabled.  This prevents the hwmod code from being able to   *     enable and reset the IP block early.  XXX Eventually it should   *     be possible to query the clock framework for this information. + * HWMOD_BLOCK_WFI: Some OMAP peripherals apparently don't work + *     correctly if the MPU is allowed to go idle while the + *     peripherals are active.  This is apparently true for the I2C on + *     OMAP2420, and also the EMAC on AM3517/3505.  It's unlikely that + *     this is really true -- we're probably not configuring something + *     correctly, or this is being abused to deal with some PM latency + *     issues -- but we're currently suffering from a shortage of + *     folks who are able to track these issues down properly.   */  #define HWMOD_SWSUP_SIDLE			(1 << 0)  #define HWMOD_SWSUP_MSTANDBY			(1 << 1) @@ -462,6 +470,7 @@ struct omap_hwmod_omap4_prcm {  #define HWMOD_CONTROL_OPT_CLKS_IN_RESET		(1 << 7)  #define HWMOD_16BIT_REG				(1 << 8)  #define HWMOD_EXT_OPT_MAIN_CLK			(1 << 9) +#define HWMOD_BLOCK_WFI				(1 << 10)  /*   * omap_hwmod._int_flags definitions diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index b5efe58c0be..6a764af6c6d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -121,7 +121,12 @@ static struct omap_hwmod omap2420_i2c1_hwmod = {  	},  	.class		= &i2c_class,  	.dev_attr	= &i2c_dev_attr, -	.flags		= HWMOD_16BIT_REG, +	/* +	 * From mach-omap2/pm24xx.c: "Putting MPU into the WFI state +	 * while a transfer is active seems to cause the I2C block to +	 * timeout. Why? Good question." +	 */ +	.flags		= (HWMOD_16BIT_REG | HWMOD_BLOCK_WFI),  };  /* I2C2 */ diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 8bb2628df34..ac7e03ec952 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3493,7 +3493,12 @@ static struct omap_hwmod am35xx_emac_hwmod = {  	.name		= "davinci_emac",  	.mpu_irqs	= am35xx_emac_mpu_irqs,  	.class		= &am35xx_emac_class, -	.flags		= HWMOD_NO_IDLEST, +	/* +	 * According to Mark Greer, the MPU will not return from WFI +	 * when the EMAC signals an interrupt. +	 * http://www.spinics.net/lists/arm-kernel/msg174734.html +	 */ +	.flags		= (HWMOD_NO_IDLEST | HWMOD_BLOCK_WFI),  };  /* l3_core -> davinci emac interface */ diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 793f54ac7d1..a1849a88370 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -616,7 +616,7 @@ static struct omap_hwmod omap44xx_dmic_hwmod = {  	.clkdm_name	= "abe_clkdm",  	.mpu_irqs	= omap44xx_dmic_irqs,  	.sdma_reqs	= omap44xx_dmic_sdma_reqs, -	.main_clk	= "dmic_fck", +	.main_clk	= "func_dmic_abe_gfclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET, @@ -1161,7 +1161,7 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = {  	.class		= &omap44xx_gpio_hwmod_class,  	.clkdm_name	= "l4_wkup_clkdm",  	.mpu_irqs	= omap44xx_gpio1_irqs, -	.main_clk	= "gpio1_ick", +	.main_clk	= "l4_wkup_clk_mux_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_WKUP_GPIO1_CLKCTRL_OFFSET, @@ -1190,7 +1190,7 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,  	.mpu_irqs	= omap44xx_gpio2_irqs, -	.main_clk	= "gpio2_ick", +	.main_clk	= "l4_div_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_GPIO2_CLKCTRL_OFFSET, @@ -1219,7 +1219,7 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,  	.mpu_irqs	= omap44xx_gpio3_irqs, -	.main_clk	= "gpio3_ick", +	.main_clk	= "l4_div_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_GPIO3_CLKCTRL_OFFSET, @@ -1248,7 +1248,7 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,  	.mpu_irqs	= omap44xx_gpio4_irqs, -	.main_clk	= "gpio4_ick", +	.main_clk	= "l4_div_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_GPIO4_CLKCTRL_OFFSET, @@ -1277,7 +1277,7 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,  	.mpu_irqs	= omap44xx_gpio5_irqs, -	.main_clk	= "gpio5_ick", +	.main_clk	= "l4_div_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_GPIO5_CLKCTRL_OFFSET, @@ -1306,7 +1306,7 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.flags		= HWMOD_CONTROL_OPT_CLKS_IN_RESET,  	.mpu_irqs	= omap44xx_gpio6_irqs, -	.main_clk	= "gpio6_ick", +	.main_clk	= "l4_div_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_GPIO6_CLKCTRL_OFFSET, @@ -1405,7 +1405,7 @@ static struct omap_hwmod omap44xx_gpu_hwmod = {  	.class		= &omap44xx_gpu_hwmod_class,  	.clkdm_name	= "l3_gfx_clkdm",  	.mpu_irqs	= omap44xx_gpu_irqs, -	.main_clk	= "gpu_fck", +	.main_clk	= "sgx_clk_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET, @@ -1446,7 +1446,7 @@ static struct omap_hwmod omap44xx_hdq1w_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.flags		= HWMOD_INIT_NO_RESET, /* XXX temporary */  	.mpu_irqs	= omap44xx_hdq1w_irqs, -	.main_clk	= "hdq1w_fck", +	.main_clk	= "func_12m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET, @@ -1550,7 +1550,7 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = {  	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,  	.mpu_irqs	= omap44xx_i2c1_irqs,  	.sdma_reqs	= omap44xx_i2c1_sdma_reqs, -	.main_clk	= "i2c1_fck", +	.main_clk	= "func_96m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_I2C1_CLKCTRL_OFFSET, @@ -1580,7 +1580,7 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = {  	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,  	.mpu_irqs	= omap44xx_i2c2_irqs,  	.sdma_reqs	= omap44xx_i2c2_sdma_reqs, -	.main_clk	= "i2c2_fck", +	.main_clk	= "func_96m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_I2C2_CLKCTRL_OFFSET, @@ -1610,7 +1610,7 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = {  	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,  	.mpu_irqs	= omap44xx_i2c3_irqs,  	.sdma_reqs	= omap44xx_i2c3_sdma_reqs, -	.main_clk	= "i2c3_fck", +	.main_clk	= "func_96m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_I2C3_CLKCTRL_OFFSET, @@ -1640,7 +1640,7 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = {  	.flags		= HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT,  	.mpu_irqs	= omap44xx_i2c4_irqs,  	.sdma_reqs	= omap44xx_i2c4_sdma_reqs, -	.main_clk	= "i2c4_fck", +	.main_clk	= "func_96m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_I2C4_CLKCTRL_OFFSET, @@ -1743,7 +1743,7 @@ static struct omap_hwmod omap44xx_iss_hwmod = {  	.clkdm_name	= "iss_clkdm",  	.mpu_irqs	= omap44xx_iss_irqs,  	.sdma_reqs	= omap44xx_iss_sdma_reqs, -	.main_clk	= "iss_fck", +	.main_clk	= "ducati_clk_mux_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_CAM_ISS_CLKCTRL_OFFSET, @@ -1785,7 +1785,7 @@ static struct omap_hwmod omap44xx_iva_hwmod = {  	.mpu_irqs	= omap44xx_iva_irqs,  	.rst_lines	= omap44xx_iva_resets,  	.rst_lines_cnt	= ARRAY_SIZE(omap44xx_iva_resets), -	.main_clk	= "iva_fck", +	.main_clk	= "dpll_iva_m5x2_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_IVAHD_IVAHD_CLKCTRL_OFFSET, @@ -1829,7 +1829,7 @@ static struct omap_hwmod omap44xx_kbd_hwmod = {  	.class		= &omap44xx_kbd_hwmod_class,  	.clkdm_name	= "l4_wkup_clkdm",  	.mpu_irqs	= omap44xx_kbd_irqs, -	.main_clk	= "kbd_fck", +	.main_clk	= "sys_32k_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET, @@ -1920,7 +1920,7 @@ static struct omap_hwmod omap44xx_mcasp_hwmod = {  	.clkdm_name	= "abe_clkdm",  	.mpu_irqs	= omap44xx_mcasp_irqs,  	.sdma_reqs	= omap44xx_mcasp_sdma_reqs, -	.main_clk	= "mcasp_fck", +	.main_clk	= "func_mcasp_abe_gfclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET, @@ -1972,7 +1972,7 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = {  	.clkdm_name	= "abe_clkdm",  	.mpu_irqs	= omap44xx_mcbsp1_irqs,  	.sdma_reqs	= omap44xx_mcbsp1_sdma_reqs, -	.main_clk	= "mcbsp1_fck", +	.main_clk	= "func_mcbsp1_gfclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_MCBSP1_CLKCTRL_OFFSET, @@ -2007,7 +2007,7 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = {  	.clkdm_name	= "abe_clkdm",  	.mpu_irqs	= omap44xx_mcbsp2_irqs,  	.sdma_reqs	= omap44xx_mcbsp2_sdma_reqs, -	.main_clk	= "mcbsp2_fck", +	.main_clk	= "func_mcbsp2_gfclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_MCBSP2_CLKCTRL_OFFSET, @@ -2042,7 +2042,7 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = {  	.clkdm_name	= "abe_clkdm",  	.mpu_irqs	= omap44xx_mcbsp3_irqs,  	.sdma_reqs	= omap44xx_mcbsp3_sdma_reqs, -	.main_clk	= "mcbsp3_fck", +	.main_clk	= "func_mcbsp3_gfclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_MCBSP3_CLKCTRL_OFFSET, @@ -2077,7 +2077,7 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_mcbsp4_irqs,  	.sdma_reqs	= omap44xx_mcbsp4_sdma_reqs, -	.main_clk	= "mcbsp4_fck", +	.main_clk	= "per_mcbsp4_gfclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_MCBSP4_CLKCTRL_OFFSET, @@ -2140,7 +2140,7 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {  	.flags		= HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE,  	.mpu_irqs	= omap44xx_mcpdm_irqs,  	.sdma_reqs	= omap44xx_mcpdm_sdma_reqs, -	.main_clk	= "mcpdm_fck", +	.main_clk	= "pad_clks_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET, @@ -2201,7 +2201,7 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_mcspi1_irqs,  	.sdma_reqs	= omap44xx_mcspi1_sdma_reqs, -	.main_clk	= "mcspi1_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_MCSPI1_CLKCTRL_OFFSET, @@ -2237,7 +2237,7 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_mcspi2_irqs,  	.sdma_reqs	= omap44xx_mcspi2_sdma_reqs, -	.main_clk	= "mcspi2_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_MCSPI2_CLKCTRL_OFFSET, @@ -2273,7 +2273,7 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_mcspi3_irqs,  	.sdma_reqs	= omap44xx_mcspi3_sdma_reqs, -	.main_clk	= "mcspi3_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_MCSPI3_CLKCTRL_OFFSET, @@ -2307,7 +2307,7 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_mcspi4_irqs,  	.sdma_reqs	= omap44xx_mcspi4_sdma_reqs, -	.main_clk	= "mcspi4_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_MCSPI4_CLKCTRL_OFFSET, @@ -2363,7 +2363,7 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = {  	.clkdm_name	= "l3_init_clkdm",  	.mpu_irqs	= omap44xx_mmc1_irqs,  	.sdma_reqs	= omap44xx_mmc1_sdma_reqs, -	.main_clk	= "mmc1_fck", +	.main_clk	= "hsmmc1_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L3INIT_MMC1_CLKCTRL_OFFSET, @@ -2392,7 +2392,7 @@ static struct omap_hwmod omap44xx_mmc2_hwmod = {  	.clkdm_name	= "l3_init_clkdm",  	.mpu_irqs	= omap44xx_mmc2_irqs,  	.sdma_reqs	= omap44xx_mmc2_sdma_reqs, -	.main_clk	= "mmc2_fck", +	.main_clk	= "hsmmc2_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L3INIT_MMC2_CLKCTRL_OFFSET, @@ -2420,7 +2420,7 @@ static struct omap_hwmod omap44xx_mmc3_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_mmc3_irqs,  	.sdma_reqs	= omap44xx_mmc3_sdma_reqs, -	.main_clk	= "mmc3_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_MMCSD3_CLKCTRL_OFFSET, @@ -2448,7 +2448,7 @@ static struct omap_hwmod omap44xx_mmc4_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_mmc4_irqs,  	.sdma_reqs	= omap44xx_mmc4_sdma_reqs, -	.main_clk	= "mmc4_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_MMCSD4_CLKCTRL_OFFSET, @@ -2476,7 +2476,7 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_mmc5_irqs,  	.sdma_reqs	= omap44xx_mmc5_sdma_reqs, -	.main_clk	= "mmc5_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_MMCSD5_CLKCTRL_OFFSET, @@ -2725,7 +2725,7 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {  	.name		= "ocp2scp_usb_phy",  	.class		= &omap44xx_ocp2scp_hwmod_class,  	.clkdm_name	= "l3_init_clkdm", -	.main_clk	= "ocp2scp_usb_phy_phy_48m", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, @@ -3162,7 +3162,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {  	.clkdm_name	= "l4_wkup_clkdm",  	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,  	.mpu_irqs	= omap44xx_timer1_irqs, -	.main_clk	= "timer1_fck", +	.main_clk	= "dmt1_clk_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_WKUP_TIMER1_CLKCTRL_OFFSET, @@ -3185,7 +3185,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,  	.mpu_irqs	= omap44xx_timer2_irqs, -	.main_clk	= "timer2_fck", +	.main_clk	= "cm2_dm2_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET, @@ -3206,7 +3206,7 @@ static struct omap_hwmod omap44xx_timer3_hwmod = {  	.class		= &omap44xx_timer_hwmod_class,  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_timer3_irqs, -	.main_clk	= "timer3_fck", +	.main_clk	= "cm2_dm3_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET, @@ -3227,7 +3227,7 @@ static struct omap_hwmod omap44xx_timer4_hwmod = {  	.class		= &omap44xx_timer_hwmod_class,  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_timer4_irqs, -	.main_clk	= "timer4_fck", +	.main_clk	= "cm2_dm4_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET, @@ -3248,7 +3248,7 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {  	.class		= &omap44xx_timer_hwmod_class,  	.clkdm_name	= "abe_clkdm",  	.mpu_irqs	= omap44xx_timer5_irqs, -	.main_clk	= "timer5_fck", +	.main_clk	= "timer5_sync_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET, @@ -3270,8 +3270,7 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {  	.class		= &omap44xx_timer_hwmod_class,  	.clkdm_name	= "abe_clkdm",  	.mpu_irqs	= omap44xx_timer6_irqs, - -	.main_clk	= "timer6_fck", +	.main_clk	= "timer6_sync_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET, @@ -3293,7 +3292,7 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {  	.class		= &omap44xx_timer_hwmod_class,  	.clkdm_name	= "abe_clkdm",  	.mpu_irqs	= omap44xx_timer7_irqs, -	.main_clk	= "timer7_fck", +	.main_clk	= "timer7_sync_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET, @@ -3315,7 +3314,7 @@ static struct omap_hwmod omap44xx_timer8_hwmod = {  	.class		= &omap44xx_timer_hwmod_class,  	.clkdm_name	= "abe_clkdm",  	.mpu_irqs	= omap44xx_timer8_irqs, -	.main_clk	= "timer8_fck", +	.main_clk	= "timer8_sync_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET, @@ -3337,7 +3336,7 @@ static struct omap_hwmod omap44xx_timer9_hwmod = {  	.class		= &omap44xx_timer_hwmod_class,  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_timer9_irqs, -	.main_clk	= "timer9_fck", +	.main_clk	= "cm2_dm9_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET, @@ -3360,7 +3359,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.flags		= HWMOD_SET_DEFAULT_CLOCKACT,  	.mpu_irqs	= omap44xx_timer10_irqs, -	.main_clk	= "timer10_fck", +	.main_clk	= "cm2_dm10_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET, @@ -3382,7 +3381,7 @@ static struct omap_hwmod omap44xx_timer11_hwmod = {  	.class		= &omap44xx_timer_hwmod_class,  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_timer11_irqs, -	.main_clk	= "timer11_fck", +	.main_clk	= "cm2_dm11_mux",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET, @@ -3433,7 +3432,7 @@ static struct omap_hwmod omap44xx_uart1_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_uart1_irqs,  	.sdma_reqs	= omap44xx_uart1_sdma_reqs, -	.main_clk	= "uart1_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_UART1_CLKCTRL_OFFSET, @@ -3461,7 +3460,7 @@ static struct omap_hwmod omap44xx_uart2_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_uart2_irqs,  	.sdma_reqs	= omap44xx_uart2_sdma_reqs, -	.main_clk	= "uart2_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_UART2_CLKCTRL_OFFSET, @@ -3490,7 +3489,7 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {  	.flags		= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,  	.mpu_irqs	= omap44xx_uart3_irqs,  	.sdma_reqs	= omap44xx_uart3_sdma_reqs, -	.main_clk	= "uart3_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_UART3_CLKCTRL_OFFSET, @@ -3518,7 +3517,7 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {  	.clkdm_name	= "l4_per_clkdm",  	.mpu_irqs	= omap44xx_uart4_irqs,  	.sdma_reqs	= omap44xx_uart4_sdma_reqs, -	.main_clk	= "uart4_fck", +	.main_clk	= "func_48m_fclk",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_L4PER_UART4_CLKCTRL_OFFSET, @@ -3797,7 +3796,7 @@ static struct omap_hwmod omap44xx_wd_timer2_hwmod = {  	.class		= &omap44xx_wd_timer_hwmod_class,  	.clkdm_name	= "l4_wkup_clkdm",  	.mpu_irqs	= omap44xx_wd_timer2_irqs, -	.main_clk	= "wd_timer2_fck", +	.main_clk	= "sys_32k_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM_WKUP_WDT2_CLKCTRL_OFFSET, @@ -3818,7 +3817,7 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {  	.class		= &omap44xx_wd_timer_hwmod_class,  	.clkdm_name	= "abe_clkdm",  	.mpu_irqs	= omap44xx_wd_timer3_irqs, -	.main_clk	= "wd_timer3_fck", +	.main_clk	= "sys_32k_ck",  	.prcm = {  		.omap4 = {  			.clkctrl_offs = OMAP4_CM1_ABE_WDT3_CLKCTRL_OFFSET, diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index e2c291f52f9..6db89ae9238 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -83,10 +83,8 @@ static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user)  		strncmp(clkdm->name, "dpll", 4) == 0)  		return 0; -	seq_printf(s, "%s->%s (%d)", clkdm->name, -			clkdm->pwrdm.ptr->name, -			atomic_read(&clkdm->usecount)); -	seq_printf(s, "\n"); +	seq_printf(s, "%s->%s (%d)\n", clkdm->name, clkdm->pwrdm.ptr->name, +		   clkdm->usecount);  	return 0;  } diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index f4b3143a8b1..9a9be3c9f20 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -32,8 +32,6 @@  #include "pm.h"  #include "twl-common.h" -static struct omap_device_pm_latency *pm_lats; -  /*   * omap_pm_suspend: points to a function that does the SoC-specific   * suspend work @@ -82,7 +80,7 @@ static int __init _init_omap_device(char *name)  		 __func__, name))  		return -ENODEV; -	pdev = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false); +	pdev = omap_device_build(oh->name, 0, oh, NULL, 0);  	if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n",  		 __func__, name))  		return -ENODEV; @@ -108,80 +106,19 @@ static void __init omap2_init_processor_devices(void)  	}  } -/* Types of sleep_switch used in omap_set_pwrdm_state */ -#define FORCEWAKEUP_SWITCH	0 -#define LOWPOWERSTATE_SWITCH	1 -  int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)  { +	/* XXX The usecount test is racy */  	if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&  	    !(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))  		clkdm_allow_idle(clkdm);  	else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP && -		 atomic_read(&clkdm->usecount) == 0) +		 clkdm->usecount == 0)  		clkdm_sleep(clkdm);  	return 0;  }  /* - * This sets pwrdm state (other than mpu & core. Currently only ON & - * RET are supported. - */ -int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 pwrst) -{ -	u8 curr_pwrst, next_pwrst; -	int sleep_switch = -1, ret = 0, hwsup = 0; - -	if (!pwrdm || IS_ERR(pwrdm)) -		return -EINVAL; - -	while (!(pwrdm->pwrsts & (1 << pwrst))) { -		if (pwrst == PWRDM_POWER_OFF) -			return ret; -		pwrst--; -	} - -	next_pwrst = pwrdm_read_next_pwrst(pwrdm); -	if (next_pwrst == pwrst) -		return ret; - -	curr_pwrst = pwrdm_read_pwrst(pwrdm); -	if (curr_pwrst < PWRDM_POWER_ON) { -		if ((curr_pwrst > pwrst) && -			(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) { -			sleep_switch = LOWPOWERSTATE_SWITCH; -		} else { -			hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]); -			clkdm_wakeup(pwrdm->pwrdm_clkdms[0]); -			sleep_switch = FORCEWAKEUP_SWITCH; -		} -	} - -	ret = pwrdm_set_next_pwrst(pwrdm, pwrst); -	if (ret) -		pr_err("%s: unable to set power state of powerdomain: %s\n", -		       __func__, pwrdm->name); - -	switch (sleep_switch) { -	case FORCEWAKEUP_SWITCH: -		if (hwsup) -			clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]); -		else -			clkdm_sleep(pwrdm->pwrdm_clkdms[0]); -		break; -	case LOWPOWERSTATE_SWITCH: -		pwrdm_set_lowpwrstchange(pwrdm); -		pwrdm_wait_transition(pwrdm); -		pwrdm_state_switch(pwrdm); -		break; -	} - -	return ret; -} - - - -/*   * This API is to be called during init to set the various voltage   * domains to the voltage as per the opp table. Typically we boot up   * at the nominal voltage. So this function finds out the rate of diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index c22503b17ab..7bdd22afce6 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h @@ -33,7 +33,6 @@ static inline int omap4_idle_init(void)  extern void *omap3_secure_ram_storage;  extern void omap3_pm_off_mode_enable(int);  extern void omap_sram_idle(void); -extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);  extern int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused);  extern int (*omap_pm_suspend)(void); diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index c333fa6dffa..b59d9390834 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -54,7 +54,6 @@  #include "powerdomain.h"  #include "clockdomain.h" -static void (*omap2_sram_idle)(void);  static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl,  				  void __iomem *sdrc_power); @@ -90,11 +89,7 @@ static int omap2_enter_full_retention(void)  	omap2_prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2);  	omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); -	/* -	 * Set MPU powerdomain's next power state to RETENTION; -	 * preserve logic state during retention -	 */ -	pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); +	pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET);  	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);  	/* Workaround to kill USB */ @@ -137,15 +132,10 @@ no_sleep:  	/* Mask future PRCM-to-MPU interrupts */  	omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET); -	return 0; -} - -static int omap2_i2c_active(void) -{ -	u32 l; +	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON); +	pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_ON); -	l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); -	return l & (OMAP2420_EN_I2C2_MASK | OMAP2420_EN_I2C1_MASK); +	return 0;  }  static int sti_console_enabled; @@ -172,10 +162,7 @@ static int omap2_allow_mpu_retention(void)  static void omap2_enter_mpu_retention(void)  { -	/* Putting MPU into the WFI state while a transfer is active -	 * seems to cause the I2C block to timeout. Why? Good question. */ -	if (omap2_i2c_active()) -		return; +	const int zero = 0;  	/* The peripherals seem not to be able to wake up the MPU when  	 * it is in retention mode. */ @@ -186,17 +173,17 @@ static void omap2_enter_mpu_retention(void)  		omap2_prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST);  		/* Try to enter MPU retention */ -		omap2_prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) | -				  OMAP_LOGICRETSTATE_MASK, -				  MPU_MOD, OMAP2_PM_PWSTCTRL); +		pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); +  	} else {  		/* Block MPU retention */ - -		omap2_prm_write_mod_reg(OMAP_LOGICRETSTATE_MASK, MPU_MOD, -						 OMAP2_PM_PWSTCTRL); +		pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);  	} -	omap2_sram_idle(); +	/* WFI */ +	asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (zero) : "memory", "cc"); + +	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);  }  static int omap2_can_sleep(void) @@ -251,25 +238,17 @@ static void __init prcm_setup_regs(void)  	for (i = 0; i < num_mem_banks; i++)  		pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET); -	/* Set CORE powerdomain's next power state to RETENTION */ -	pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET); +	pwrdm_set_logic_retst(core_pwrdm, PWRDM_POWER_RET); -	/* -	 * Set MPU powerdomain's next power state to RETENTION; -	 * preserve logic state during retention -	 */  	pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); -	pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET);  	/* Force-power down DSP, GFX powerdomains */  	pwrdm = clkdm_get_pwrdm(dsp_clkdm);  	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); -	clkdm_sleep(dsp_clkdm);  	pwrdm = clkdm_get_pwrdm(gfx_clkdm);  	pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); -	clkdm_sleep(gfx_clkdm);  	/* Enable hardware-supervised idle for all clkdms */  	clkdm_for_each(omap_pm_clkdms_setup, NULL); @@ -356,11 +335,9 @@ int __init omap2_pm_init(void)  	/*  	 * We copy the assembler sleep/wakeup routines to SRAM.  	 * These routines need to be in SRAM as that's the only -	 * memory the MPU can see when it wakes up. +	 * memory the MPU can see when it wakes up after the entire +	 * chip enters idle.  	 */ -	omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend, -					 omap24xx_idle_loop_suspend_sz); -  	omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend,  					    omap24xx_cpu_suspend_sz); diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c index eb78ae7a346..0ef4d6aa758 100644 --- a/arch/arm/mach-omap2/pmu.c +++ b/arch/arm/mach-omap2/pmu.c @@ -48,8 +48,7 @@ static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[])  		}  	} -	omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0, -					    NULL, 0, 0); +	omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0);  	WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n",  	     dev_name); diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index dea62a9aad0..8e61d80bf6b 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -19,6 +19,7 @@  #include <linux/list.h>  #include <linux/errno.h>  #include <linux/string.h> +#include <linux/spinlock.h>  #include <trace/events/power.h>  #include "cm2xxx_3xxx.h" @@ -42,6 +43,16 @@ enum {  	PWRDM_STATE_PREV,  }; +/* + * Types of sleep_switch used internally in omap_set_pwrdm_state() + * and its associated static functions + * + * XXX Better documentation is needed here + */ +#define ALREADYACTIVE_SWITCH		0 +#define FORCEWAKEUP_SWITCH		1 +#define LOWPOWERSTATE_SWITCH		2 +#define ERROR_SWITCH			3  /* pwrdm_list contains all registered struct powerdomains */  static LIST_HEAD(pwrdm_list); @@ -101,6 +112,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)  	pwrdm->voltdm.ptr = voltdm;  	INIT_LIST_HEAD(&pwrdm->voltdm_node);  	voltdm_add_pwrdm(voltdm, pwrdm); +	spin_lock_init(&pwrdm->_lock);  	list_add(&pwrdm->node, &pwrdm_list); @@ -112,7 +124,7 @@ static int _pwrdm_register(struct powerdomain *pwrdm)  	for (i = 0; i < pwrdm->banks; i++)  		pwrdm->ret_mem_off_counter[i] = 0; -	pwrdm_wait_transition(pwrdm); +	arch_pwrdm->pwrdm_wait_transition(pwrdm);  	pwrdm->state = pwrdm_read_pwrst(pwrdm);  	pwrdm->state_counter[pwrdm->state] = 1; @@ -143,7 +155,7 @@ static void _update_logic_membank_counters(struct powerdomain *pwrdm)  static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)  { -	int prev, state, trace_state = 0; +	int prev, next, state, trace_state = 0;  	if (pwrdm == NULL)  		return -EINVAL; @@ -164,9 +176,10 @@ static int _pwrdm_state_switch(struct powerdomain *pwrdm, int flag)  		 * If the power domain did not hit the desired state,  		 * generate a trace event with both the desired and hit states  		 */ -		if (state != prev) { +		next = pwrdm_read_next_pwrst(pwrdm); +		if (next != prev) {  			trace_state = (PWRDM_TRACE_STATES_FLAG | -				       ((state & OMAP_POWERSTATE_MASK) << 8) | +				       ((next & OMAP_POWERSTATE_MASK) << 8) |  				       ((prev & OMAP_POWERSTATE_MASK) << 0));  			trace_power_domain_target(pwrdm->name, trace_state,  						  smp_processor_id()); @@ -199,6 +212,80 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)  	return 0;  } +/** + * _pwrdm_save_clkdm_state_and_activate - prepare for power state change + * @pwrdm: struct powerdomain * to operate on + * @curr_pwrst: current power state of @pwrdm + * @pwrst: power state to switch to + * @hwsup: ptr to a bool to return whether the clkdm is hardware-supervised + * + * Determine whether the powerdomain needs to be turned on before + * attempting to switch power states.  Called by + * omap_set_pwrdm_state().  NOTE that if the powerdomain contains + * multiple clockdomains, this code assumes that the first clockdomain + * supports software-supervised wakeup mode - potentially a problem. + * Returns the power state switch mode currently in use (see the + * "Types of sleep_switch" comment above). + */ +static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm, +					       u8 curr_pwrst, u8 pwrst, +					       bool *hwsup) +{ +	u8 sleep_switch; + +	if (curr_pwrst < 0) { +		WARN_ON(1); +		sleep_switch = ERROR_SWITCH; +	} else if (curr_pwrst < PWRDM_POWER_ON) { +		if (curr_pwrst > pwrst && +		    pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE && +		    arch_pwrdm->pwrdm_set_lowpwrstchange) { +			sleep_switch = LOWPOWERSTATE_SWITCH; +		} else { +			*hwsup = clkdm_in_hwsup(pwrdm->pwrdm_clkdms[0]); +			clkdm_wakeup_nolock(pwrdm->pwrdm_clkdms[0]); +			sleep_switch = FORCEWAKEUP_SWITCH; +		} +	} else { +		sleep_switch = ALREADYACTIVE_SWITCH; +	} + +	return sleep_switch; +} + +/** + * _pwrdm_restore_clkdm_state - restore the clkdm hwsup state after pwrst change + * @pwrdm: struct powerdomain * to operate on + * @sleep_switch: return value from _pwrdm_save_clkdm_state_and_activate() + * @hwsup: should @pwrdm's first clockdomain be set to hardware-supervised mode? + * + * Restore the clockdomain state perturbed by + * _pwrdm_save_clkdm_state_and_activate(), and call the power state + * bookkeeping code.  Called by omap_set_pwrdm_state().  NOTE that if + * the powerdomain contains multiple clockdomains, this assumes that + * the first associated clockdomain supports either + * hardware-supervised idle control in the register, or + * software-supervised sleep.  No return value. + */ +static void _pwrdm_restore_clkdm_state(struct powerdomain *pwrdm, +				       u8 sleep_switch, bool hwsup) +{ +	switch (sleep_switch) { +	case FORCEWAKEUP_SWITCH: +		if (hwsup) +			clkdm_allow_idle_nolock(pwrdm->pwrdm_clkdms[0]); +		else +			clkdm_sleep_nolock(pwrdm->pwrdm_clkdms[0]); +		break; +	case LOWPOWERSTATE_SWITCH: +		if (pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE && +		    arch_pwrdm->pwrdm_set_lowpwrstchange) +			arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm); +		pwrdm_state_switch_nolock(pwrdm); +		break; +	} +} +  /* Public functions */  /** @@ -275,6 +362,30 @@ int pwrdm_complete_init(void)  }  /** + * pwrdm_lock - acquire a Linux spinlock on a powerdomain + * @pwrdm: struct powerdomain * to lock + * + * Acquire the powerdomain spinlock on @pwrdm.  No return value. + */ +void pwrdm_lock(struct powerdomain *pwrdm) +	__acquires(&pwrdm->_lock) +{ +	spin_lock_irqsave(&pwrdm->_lock, pwrdm->_lock_flags); +} + +/** + * pwrdm_unlock - release a Linux spinlock on a powerdomain + * @pwrdm: struct powerdomain * to unlock + * + * Release the powerdomain spinlock on @pwrdm.  No return value. + */ +void pwrdm_unlock(struct powerdomain *pwrdm) +	__releases(&pwrdm->_lock) +{ +	spin_unlock_irqrestore(&pwrdm->_lock, pwrdm->_lock_flags); +} + +/**   * pwrdm_lookup - look up a powerdomain by name, return a pointer   * @name: name of powerdomain   * @@ -920,65 +1031,27 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)  	return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;  } -/** - * pwrdm_set_lowpwrstchange - Request a low power state change - * @pwrdm: struct powerdomain * - * - * Allows a powerdomain to transtion to a lower power sleep state - * from an existing sleep state without waking up the powerdomain. - * Returns -EINVAL if the powerdomain pointer is null or if the - * powerdomain does not support LOWPOWERSTATECHANGE, or returns 0 - * upon success. - */ -int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm) -{ -	int ret = -EINVAL; - -	if (!pwrdm) -		return -EINVAL; - -	if (!(pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE)) -		return -EINVAL; - -	pr_debug("powerdomain: %s: setting LOWPOWERSTATECHANGE bit\n", -		 pwrdm->name); - -	if (arch_pwrdm && arch_pwrdm->pwrdm_set_lowpwrstchange) -		ret = arch_pwrdm->pwrdm_set_lowpwrstchange(pwrdm); - -	return ret; -} - -/** - * pwrdm_wait_transition - wait for powerdomain power transition to finish - * @pwrdm: struct powerdomain * to wait for - * - * If the powerdomain @pwrdm is in the process of a state transition, - * spin until it completes the power transition, or until an iteration - * bailout value is reached. Returns -EINVAL if the powerdomain - * pointer is null, -EAGAIN if the bailout value was reached, or - * returns 0 upon success. - */ -int pwrdm_wait_transition(struct powerdomain *pwrdm) +int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)  { -	int ret = -EINVAL; +	int ret; -	if (!pwrdm) +	if (!pwrdm || !arch_pwrdm)  		return -EINVAL; -	if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition) -		ret = arch_pwrdm->pwrdm_wait_transition(pwrdm); +	ret = arch_pwrdm->pwrdm_wait_transition(pwrdm); +	if (!ret) +		ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);  	return ret;  } -int pwrdm_state_switch(struct powerdomain *pwrdm) +int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm)  {  	int ret; -	ret = pwrdm_wait_transition(pwrdm); -	if (!ret) -		ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW); +	pwrdm_lock(pwrdm); +	ret = pwrdm_state_switch_nolock(pwrdm); +	pwrdm_unlock(pwrdm);  	return ret;  } @@ -1004,6 +1077,61 @@ int pwrdm_post_transition(struct powerdomain *pwrdm)  }  /** + * omap_set_pwrdm_state - change a powerdomain's current power state + * @pwrdm: struct powerdomain * to change the power state of + * @pwrst: power state to change to + * + * Change the current hardware power state of the powerdomain + * represented by @pwrdm to the power state represented by @pwrst. + * Returns -EINVAL if @pwrdm is null or invalid or if the + * powerdomain's current power state could not be read, or returns 0 + * upon success or if @pwrdm does not support @pwrst or any + * lower-power state.  XXX Should not return 0 if the @pwrdm does not + * support @pwrst or any lower-power state: this should be an error. + */ +int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst) +{ +	u8 curr_pwrst, next_pwrst, sleep_switch; +	int ret = 0; +	bool hwsup = false; + +	if (!pwrdm || IS_ERR(pwrdm)) +		return -EINVAL; + +	while (!(pwrdm->pwrsts & (1 << pwrst))) { +		if (pwrst == PWRDM_POWER_OFF) +			return ret; +		pwrst--; +	} + +	pwrdm_lock(pwrdm); + +	curr_pwrst = pwrdm_read_pwrst(pwrdm); +	next_pwrst = pwrdm_read_next_pwrst(pwrdm); +	if (curr_pwrst == pwrst && next_pwrst == pwrst) +		goto osps_out; + +	sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst, +							    pwrst, &hwsup); +	if (sleep_switch == ERROR_SWITCH) { +		ret = -EINVAL; +		goto osps_out; +	} + +	ret = pwrdm_set_next_pwrst(pwrdm, pwrst); +	if (ret) +		pr_err("%s: unable to set power state of powerdomain: %s\n", +		       __func__, pwrdm->name); + +	_pwrdm_restore_clkdm_state(pwrdm, sleep_switch, hwsup); + +osps_out: +	pwrdm_unlock(pwrdm); + +	return ret; +} + +/**   * pwrdm_get_context_loss_count - get powerdomain's context loss count   * @pwrdm: struct powerdomain * to wait for   * diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index 5277d56eb37..140c36074fe 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -19,8 +19,7 @@  #include <linux/types.h>  #include <linux/list.h> - -#include <linux/atomic.h> +#include <linux/spinlock.h>  #include "voltage.h" @@ -44,18 +43,20 @@  #define PWRSTS_OFF_RET_ON	(PWRSTS_OFF_RET | PWRSTS_ON) -/* Powerdomain flags */ -#define PWRDM_HAS_HDWR_SAR	(1 << 0) /* hardware save-and-restore support */ -#define PWRDM_HAS_MPU_QUIRK	(1 << 1) /* MPU pwr domain has MEM bank 0 bits -					  * in MEM bank 1 position. This is -					  * true for OMAP3430 -					  */ -#define PWRDM_HAS_LOWPOWERSTATECHANGE	(1 << 2) /* -						  * support to transition from a -						  * sleep state to a lower sleep -						  * state without waking up the -						  * powerdomain -						  */ +/* + * Powerdomain flags (struct powerdomain.flags) + * + * PWRDM_HAS_HDWR_SAR - powerdomain has hardware save-and-restore support + * + * PWRDM_HAS_MPU_QUIRK - MPU pwr domain has MEM bank 0 bits in MEM + * bank 1 position. This is true for OMAP3430 + * + * PWRDM_HAS_LOWPOWERSTATECHANGE - can transition from a sleep state + * to a lower sleep state without waking up the powerdomain + */ +#define PWRDM_HAS_HDWR_SAR		BIT(0) +#define PWRDM_HAS_MPU_QUIRK		BIT(1) +#define PWRDM_HAS_LOWPOWERSTATECHANGE	BIT(2)  /*   * Number of memory banks that are power-controllable.	On OMAP4430, the @@ -103,6 +104,8 @@ struct powerdomain;   * @state_counter:   * @timer:   * @state_timer: + * @_lock: spinlock used to serialize powerdomain and some clockdomain ops + * @_lock_flags: stored flags when @_lock is taken   *   * @prcm_partition possible values are defined in mach-omap2/prcm44xx.h.   */ @@ -127,7 +130,8 @@ struct powerdomain {  	unsigned state_counter[PWRDM_MAX_PWRSTS];  	unsigned ret_logic_off_counter;  	unsigned ret_mem_off_counter[PWRDM_MAX_MEM_BANKS]; - +	spinlock_t _lock; +	unsigned long _lock_flags;  	const u8 pwrstctrl_offs;  	const u8 pwrstst_offs;  	const u32 logicretstate_mask; @@ -162,6 +166,16 @@ struct powerdomain {   * @pwrdm_disable_hdwr_sar: Disable Hardware Save-Restore feature for a pd   * @pwrdm_set_lowpwrstchange: Enable pd transitions from a shallow to deep sleep   * @pwrdm_wait_transition: Wait for a pd state transition to complete + * + * Regarding @pwrdm_set_lowpwrstchange: On the OMAP2 and 3-family + * chips, a powerdomain's power state is not allowed to directly + * transition from one low-power state (e.g., CSWR) to another + * low-power state (e.g., OFF) without first waking up the + * powerdomain.  This wastes energy.  So OMAP4 chips support the + * ability to transition a powerdomain power state directly from one + * low-power state to another.  The function pointed to by + * @pwrdm_set_lowpwrstchange is intended to configure the OMAP4 + * hardware powerdomain state machine to enable this feature.   */  struct pwrdm_ops {  	int	(*pwrdm_set_next_pwrst)(struct powerdomain *pwrdm, u8 pwrst); @@ -225,15 +239,15 @@ int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);  int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);  bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); -int pwrdm_wait_transition(struct powerdomain *pwrdm); - +int pwrdm_state_switch_nolock(struct powerdomain *pwrdm);  int pwrdm_state_switch(struct powerdomain *pwrdm);  int pwrdm_pre_transition(struct powerdomain *pwrdm);  int pwrdm_post_transition(struct powerdomain *pwrdm); -int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);  int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);  bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm); +extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 state); +  extern void omap242x_powerdomains_init(void);  extern void omap243x_powerdomains_init(void);  extern void omap3xxx_powerdomains_init(void); @@ -253,5 +267,7 @@ extern u32 omap2_pwrdm_get_mem_bank_stst_mask(u8 bank);  extern struct powerdomain wkup_omap2_pwrdm;  extern struct powerdomain gfx_omap2_pwrdm; +extern void pwrdm_lock(struct powerdomain *pwrdm); +extern void pwrdm_unlock(struct powerdomain *pwrdm);  #endif diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c index d3a5399091a..7b946f1005b 100644 --- a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c @@ -54,12 +54,12 @@ struct powerdomain gfx_omap2_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  /* MEMONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  struct powerdomain wkup_omap2_pwrdm = {  	.name		= "wkup_pwrdm",  	.prcm_offs	= WKUP_MOD,  	.pwrsts		= PWRSTS_ON, -	.voltdm         = { .name = "wakeup" }, +	.voltdm		= { .name = "wakeup" },  }; diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_data.c index ba520d4f7c7..578eef86fcf 100644 --- a/arch/arm/mach-omap2/powerdomains2xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c @@ -38,7 +38,7 @@ static struct powerdomain dsp_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain mpu_24xx_pwrdm = { @@ -53,13 +53,14 @@ static struct powerdomain mpu_24xx_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain core_24xx_pwrdm = {  	.name		  = "core_pwrdm",  	.prcm_offs	  = CORE_MOD,  	.pwrsts		  = PWRSTS_OFF_RET_ON, +	.pwrsts_logic_ret = PWRSTS_RET,  	.banks		  = 3,  	.pwrsts_mem_ret	  = {  		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */ @@ -71,7 +72,7 @@ static struct powerdomain core_24xx_pwrdm = {  		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */  		[2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  }; @@ -93,7 +94,7 @@ static struct powerdomain mdm_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  /* MEMONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  /* diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c index 8b23d234fb5..f0e14e9efe5 100644 --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c @@ -50,7 +50,7 @@ static struct powerdomain iva2_pwrdm = {  		[2] = PWRSTS_OFF_ON,  		[3] = PWRSTS_ON,  	}, -	.voltdm           = { .name = "mpu_iva" }, +	.voltdm		  = { .name = "mpu_iva" },  };  static struct powerdomain mpu_3xxx_pwrdm = { @@ -66,7 +66,7 @@ static struct powerdomain mpu_3xxx_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_OFF_ON,  	}, -	.voltdm           = { .name = "mpu_iva" }, +	.voltdm		  = { .name = "mpu_iva" },  };  static struct powerdomain mpu_am35x_pwrdm = { @@ -82,7 +82,7 @@ static struct powerdomain mpu_am35x_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  	}, -	.voltdm           = { .name = "mpu_iva" }, +	.voltdm		  = { .name = "mpu_iva" },  };  /* @@ -109,7 +109,7 @@ static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {  		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */  		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain core_3xxx_es3_1_pwrdm = { @@ -131,7 +131,7 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {  		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */  		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain core_am35x_pwrdm = { @@ -148,7 +148,7 @@ static struct powerdomain core_am35x_pwrdm = {  		[0] = PWRSTS_ON, /* MEM1ONSTATE */  		[1] = PWRSTS_ON, /* MEM2ONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain dss_pwrdm = { @@ -163,7 +163,7 @@ static struct powerdomain dss_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  /* MEMONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain dss_am35x_pwrdm = { @@ -178,7 +178,7 @@ static struct powerdomain dss_am35x_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  /* MEMONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  /* @@ -199,7 +199,7 @@ static struct powerdomain sgx_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  /* MEMONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain sgx_am35x_pwrdm = { @@ -214,7 +214,7 @@ static struct powerdomain sgx_am35x_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  /* MEMONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain cam_pwrdm = { @@ -229,7 +229,7 @@ static struct powerdomain cam_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  /* MEMONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain per_pwrdm = { @@ -244,7 +244,7 @@ static struct powerdomain per_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  /* MEMONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain per_am35x_pwrdm = { @@ -259,13 +259,13 @@ static struct powerdomain per_am35x_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  /* MEMONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain emu_pwrdm = {  	.name		= "emu_pwrdm",  	.prcm_offs	= OMAP3430_EMU_MOD, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain neon_pwrdm = { @@ -273,7 +273,7 @@ static struct powerdomain neon_pwrdm = {  	.prcm_offs	  = OMAP3430_NEON_MOD,  	.pwrsts		  = PWRSTS_OFF_RET_ON,  	.pwrsts_logic_ret = PWRSTS_RET, -	.voltdm           = { .name = "mpu_iva" }, +	.voltdm		  = { .name = "mpu_iva" },  };  static struct powerdomain neon_am35x_pwrdm = { @@ -281,7 +281,7 @@ static struct powerdomain neon_am35x_pwrdm = {  	.prcm_offs	  = OMAP3430_NEON_MOD,  	.pwrsts		  = PWRSTS_ON,  	.pwrsts_logic_ret = PWRSTS_ON, -	.voltdm           = { .name = "mpu_iva" }, +	.voltdm		  = { .name = "mpu_iva" },  };  static struct powerdomain usbhost_pwrdm = { @@ -303,37 +303,37 @@ static struct powerdomain usbhost_pwrdm = {  	.pwrsts_mem_on	  = {  		[0] = PWRSTS_ON,  /* MEMONSTATE */  	}, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain dpll1_pwrdm = {  	.name		= "dpll1_pwrdm",  	.prcm_offs	= MPU_MOD, -	.voltdm           = { .name = "mpu_iva" }, +	.voltdm		  = { .name = "mpu_iva" },  };  static struct powerdomain dpll2_pwrdm = {  	.name		= "dpll2_pwrdm",  	.prcm_offs	= OMAP3430_IVA2_MOD, -	.voltdm           = { .name = "mpu_iva" }, +	.voltdm		  = { .name = "mpu_iva" },  };  static struct powerdomain dpll3_pwrdm = {  	.name		= "dpll3_pwrdm",  	.prcm_offs	= PLL_MOD, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain dpll4_pwrdm = {  	.name		= "dpll4_pwrdm",  	.prcm_offs	= PLL_MOD, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  static struct powerdomain dpll5_pwrdm = {  	.name		= "dpll5_pwrdm",  	.prcm_offs	= PLL_MOD, -	.voltdm           = { .name = "core" }, +	.voltdm		  = { .name = "core" },  };  /* As powerdomains are added or removed above, this list must also be changed */ diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index a3e121f94a8..947f6adfed0 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -210,6 +210,7 @@ int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1,  					     PM_WKDEP, (1 << clkdm2->dep_bit));  } +/* XXX Caller must hold the clkdm's powerdomain lock */  int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)  {  	struct clkdm_dep *cd; @@ -221,7 +222,7 @@ int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)  		/* PRM accesses are slow, so minimize them */  		mask |= 1 << cd->clkdm->dep_bit; -		atomic_set(&cd->wkdep_usecount, 0); +		cd->wkdep_usecount = 0;  	}  	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 04fdbc4c499..d01c373cbbe 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -316,8 +316,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata,  	if (WARN_ON(!oh))  		return; -	pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size, -				 NULL, 0, false); +	pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size);  	if (IS_ERR(pdev)) {  		WARN(1, "Could not build omap_device for %s: %s.\n", name,  		     oh->name); diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S index ce0ccd26efb..1d3cb25c962 100644 --- a/arch/arm/mach-omap2/sleep24xx.S +++ b/arch/arm/mach-omap2/sleep24xx.S @@ -37,25 +37,6 @@  	.text  /* - * Forces OMAP into idle state - * - * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI - * for normal idles. - * - * Note: This code get's copied to internal SRAM at boot. When the OMAP - *	 wakes up it continues execution at the point it went to sleep. - */ -	.align	3 -ENTRY(omap24xx_idle_loop_suspend) -	stmfd	sp!, {r0, lr}		@ save registers on stack -	mov	r0, #0			@ clear for mcr setup -	mcr	p15, 0, r0, c7, c0, 4	@ wait for interrupt -	ldmfd	sp!, {r0, pc}		@ restore regs and return - -ENTRY(omap24xx_idle_loop_suspend_sz) -	.word	. - omap24xx_idle_loop_suspend - -/*   * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing   * SDRC shutdown then ARM shutdown.  Upon wake MPU is back on so just restore   * SDRC. diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index b9753fe2723..d7bc33f1534 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -152,8 +152,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)  	sr_data->enable_on_init = sr_enable_on_init; -	pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), -				 NULL, 0, 0); +	pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data));  	if (IS_ERR(pdev))  		pr_warning("%s: Could not build omap_device for %s: %s.\n\n",  			__func__, name, oh->name); diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index b8ad6e632bb..63e5fb017fd 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -702,8 +702,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)  	pdata->timer_errata = omap_dm_timer_get_errata();  	pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; -	pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata), -				 NULL, 0, 0); +	pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata));  	if (IS_ERR(pdev)) {  		pr_err("%s: Can't build omap_device for %s: %s.\n", diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c index 2e44e8a2288..99f04deb4c7 100644 --- a/arch/arm/mach-omap2/usb-host.c +++ b/arch/arm/mach-omap2/usb-host.c @@ -42,14 +42,6 @@ static struct usbtll_omap_platform_data		usbtll_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 @@ -530,9 +522,7 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)  	}  	pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm, -				&usbtll_data, sizeof(usbtll_data), -				omap_uhhtll_latency, -				ARRAY_SIZE(omap_uhhtll_latency), false); +				 &usbtll_data, sizeof(usbtll_data));  	if (IS_ERR(pdev)) {  		pr_err("Could not build hwmod device %s\n",  		       USBHS_TLL_HWMODNAME); @@ -540,9 +530,7 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)  	}  	pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm, -				&usbhs_data, sizeof(usbhs_data), -				omap_uhhtll_latency, -				ARRAY_SIZE(omap_uhhtll_latency), false); +				&usbhs_data, sizeof(usbhs_data));  	if (IS_ERR(pdev)) {  		pr_err("Could not build hwmod devices %s\n",  		       USBHS_UHH_HWMODNAME); diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c index 7b33b375fe7..8c4de2708cf 100644 --- a/arch/arm/mach-omap2/usb-musb.c +++ b/arch/arm/mach-omap2/usb-musb.c @@ -102,7 +102,7 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)                  return;  	pdev = omap_device_build(name, bus_id, oh, &musb_plat, -			       sizeof(musb_plat), NULL, 0, false); +				 sizeof(musb_plat));  	if (IS_ERR(pdev)) {  		pr_err("Could not build omap_device for %s %s\n",  						name, oh_name); diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c index 7c2b4ed38f0..910243f54a0 100644 --- a/arch/arm/mach-omap2/wd_timer.c +++ b/arch/arm/mach-omap2/wd_timer.c @@ -124,8 +124,7 @@ static int __init omap_init_wdt(void)  	pdata.read_reset_sources = prm_read_reset_sources;  	pdev = omap_device_build(dev_name, id, oh, &pdata, -				 sizeof(struct omap_wd_timer_platform_data), -				 NULL, 0, 0); +				 sizeof(struct omap_wd_timer_platform_data));  	WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",  	     dev_name, oh->name);  	return 0;  |