OMAP PM related updates via Paul Walmsley <paul@pwsan.com>:
Remove some dead OMAP clock and device integration code and data. Also, clean up the way that the OMAP device integration code blocks WFI/WFE to use a consistent mechanism, controlled by a data flag. Several OMAP2+ power management fixes, optimizations, and cleanup. This series is a prerequisite for the functional powerdomain conversion series. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJRD/2AAAoJEBvUPslcq6VzZ0UP+wdb7Nzn0ZFSMkWpOvjdIRfl XWfdsh2mIOpP97GmitF0iwflI5vx/Jfv9vHxk8elcmHvFOnjrHIuNXU3rTFzYHgS ho0DZsGAuI/RbIekZbq2+UUs5sd5+vpV85c533S/vYuDBM11tUeysb7sx5Vcc6y8 5u2wWfi4ZifgqtcaoEBV/w/cdivz0J3cqDPLJi5En1qsh6toD7fecTnhVHFo51mS 72QGNKDWUvhKUPmKpaNMBf/sS+Xyp0OnezlDfyRo1dj6SUxUt0zhsGZM9aVGOMIB unCiDJNtW7FQsw2TYKEbngrY9i8WPSmw26womRpxGknQSCJRoeNmZsGq3rRQgnfX Bh8VUdYSrjs8covv7pZ7wP6MaMuH1CvS34G7Yy7hKbYPW04RoKswyD7emnIpM3yk 4wtvoB6D85BaDMzGKyTyxOKOCqyamdriI397jXdKsw6jDJl+DVtLkkNADYtkFs+d GzBw81DhnrKmVwYP656yZflDguAKzZvuSoygFBAK7/nwR/qZPLtAN3ZUc1sTbe0u RaqGcUtkYMyRwRuzTSdeFDf+NJAnw7ME7lrlyX01jhKb8oynPRHH1vGROeMOgR22 atF7Z8HQjPWsFR8Zre2Mj85cFmpeuEukFIYKrzN5OWtHjHD0L16dRh4/hLmexOTM A9vnxaD3VbWEjpBVgB21 =Rhql -----END PGP SIGNATURE----- Merge tag 'omap-for-v3.9/pm-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/soc From Tony Lindgren: OMAP PM related updates via Paul Walmsley <paul@pwsan.com>: Remove some dead OMAP clock and device integration code and data. Also, clean up the way that the OMAP device integration code blocks WFI/WFE to use a consistent mechanism, controlled by a data flag. Several OMAP2+ power management fixes, optimizations, and cleanup. This series is a prerequisite for the functional powerdomain conversion series. * tag 'omap-for-v3.9/pm-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: ARM: OMAP2+: powerdomain: fix whitespace, improve flag comments ARM: OMAP2+: clockdomain: convert existing atomic usecounts into spinlock-protected shorts/ints ARM: OMAP2+: clockdomain: work on wkdep/sleepdep functions ARM: OMAP2xxx: CM: remove autodep handling ARM: OMAP2+: powerdomain/clockdomain: add a per-powerdomain spinlock ARM: OMAP2+: PM/powerdomain: move omap_set_pwrdm_state() to powerdomain code ARM: OMAP2: PM/powerdomain: drop unnecessary pwrdm_wait_transition() ARM: OMAP2xxx: PM: clean up some crufty powerstate programming code ARM: OMAP2+: clockdomain: add pwrdm_state_switch() call to clkdm_sleep() ARM: OMAP2+: powerdomain: fix powerdomain trace integration ARM: OMAP4: MPUSS PM: remove unnecessary shim functions for powerdomain control ARM: OMAP3xxx: CPUIdle: optimize __omap3_enter_idle() ARM: OMAP2420: hwmod data/PM: use hwmod to block WFI when I2C active ARM: OMAP2+: hwmod: add support for blocking WFI when a device is active ARM: OMAP3xxx: CPUIdle: simplify the PER next-state code ARM: OMAP2xxx: powerdomain: core powerdomain missing logic retention states ARM: OMAP2xxx: clock data: clean up unused null clocks ARM: OMAP4: clock/hwmod data: remove MODULEMODE entries in mux + gate combos ARM: OMAP4: clock/hwmod data: start to remove some IP block control "clocks" ARM: OMAP2+: omap_device: remove obsolete pm_lats and early_device code
This commit is contained in:
Коммит
d37d79ed8a
|
@ -63,7 +63,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);
|
||||
false);
|
||||
if (IS_ERR(pdev)) {
|
||||
WARN(1, "Can't build omap_device for %s:%s.\n",
|
||||
oh->class->name, oh->name);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
||||
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
|
||||
|
|
|
@ -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,66 +152,6 @@ 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 *
|
||||
*
|
||||
* 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_add_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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _resolve_clkdm_deps() - resolve clkdm_names in @clkdm_deps to clkdms
|
||||
* @clkdm: clockdomain that we are resolving dependencies for
|
||||
|
@ -238,6 +176,184 @@ static void _resolve_clkdm_deps(struct clockdomain *clkdm,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _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)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
static int _clkdm_add_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_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);
|
||||
|
||||
ret = arch_clkdm->clkdm_add_wkdep(clkdm1, clkdm2);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* _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 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)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
static int _clkdm_add_sleepdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
struct clkdm_dep *cd;
|
||||
int ret = 0;
|
||||
|
||||
if (!clkdm1 || !clkdm2)
|
||||
return -EINVAL;
|
||||
|
||||
cd = _clkdm_deps_lookup(clkdm2, clkdm1->sleepdep_srcs);
|
||||
if (IS_ERR(cd))
|
||||
ret = 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* _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)
|
||||
*
|
||||
* 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 int _clkdm_del_sleepdep(struct clockdomain *clkdm1,
|
||||
struct clockdomain *clkdm2)
|
||||
{
|
||||
struct clkdm_dep *cd;
|
||||
int ret = 0;
|
||||
|
||||
if (!clkdm1 || !clkdm2)
|
||||
return -EINVAL;
|
||||
|
||||
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 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_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. Returns -EINVAL if @clkdm is NULL or if the
|
||||
* clockdomain does not support software-controlled wakeup; 0 upon
|
||||
* success.
|
||||
* 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(struct clockdomain *clkdm)
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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, 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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -86,37 +86,6 @@ static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)
|
|||
__raw_writel(addr, pm_info->wkup_sar_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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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_enable_hwmods(od);
|
||||
|
||||
ret = _omap_device_activate(od, IGNORE_WAKEUP_LAT);
|
||||
|
||||
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,49 +734,13 @@ 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;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -1059,86 +796,6 @@ int omap_device_deassert_hardreset(struct platform_device *pdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,79 +106,18 @@ 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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -90,11 +90,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,17 +133,12 @@ no_sleep:
|
|||
/* Mask future PRCM-to-MPU interrupts */
|
||||
omap2_prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRCM_IRQSTATUS_MPU_OFFSET);
|
||||
|
||||
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
|
||||
pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_ON);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap2_i2c_active(void)
|
||||
{
|
||||
u32 l;
|
||||
|
||||
l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
|
||||
return l & (OMAP2420_EN_I2C2_MASK | OMAP2420_EN_I2C1_MASK);
|
||||
}
|
||||
|
||||
static int sti_console_enabled;
|
||||
|
||||
static int omap2_allow_mpu_retention(void)
|
||||
|
@ -172,11 +163,6 @@ 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;
|
||||
|
||||
/* The peripherals seem not to be able to wake up the MPU when
|
||||
* it is in retention mode. */
|
||||
if (omap2_allow_mpu_retention()) {
|
||||
|
@ -186,17 +172,16 @@ 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();
|
||||
|
||||
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
|
||||
}
|
||||
|
||||
static int omap2_can_sleep(void)
|
||||
|
@ -251,25 +236,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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/**
|
||||
|
@ -274,6 +361,30 @@ int pwrdm_complete_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,69 +1031,31 @@ 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 ret = -EINVAL;
|
||||
|
||||
if (!pwrdm)
|
||||
return -EINVAL;
|
||||
|
||||
if (arch_pwrdm && arch_pwrdm->pwrdm_wait_transition)
|
||||
ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pwrdm_state_switch(struct powerdomain *pwrdm)
|
||||
int pwrdm_state_switch_nolock(struct powerdomain *pwrdm)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pwrdm_wait_transition(pwrdm);
|
||||
if (!pwrdm || !arch_pwrdm)
|
||||
return -EINVAL;
|
||||
|
||||
ret = arch_pwrdm->pwrdm_wait_transition(pwrdm);
|
||||
if (!ret)
|
||||
ret = _pwrdm_state_switch(pwrdm, PWRDM_STATE_NOW);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __deprecated pwrdm_state_switch(struct powerdomain *pwrdm)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pwrdm_lock(pwrdm);
|
||||
ret = pwrdm_state_switch_nolock(pwrdm);
|
||||
pwrdm_unlock(pwrdm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int pwrdm_pre_transition(struct powerdomain *pwrdm)
|
||||
{
|
||||
if (pwrdm)
|
||||
|
@ -1003,6 +1076,61 @@ int pwrdm_post_transition(struct powerdomain *pwrdm)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" },
|
||||
};
|
||||
|
|
|
@ -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" },
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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), 0);
|
||||
if (IS_ERR(pdev))
|
||||
pr_warning("%s: Could not build omap_device for %s: %s.\n\n",
|
||||
__func__, name, oh->name);
|
||||
|
|
|
@ -683,8 +683,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",
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче