Skip to content

Commit 04b6d0a

Browse files
committed
Merge tag 'omap-for-v4.8/soc-pt2-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/soc
Merge "Few more omap SoC changes for v4.8 merge window" from Tony Lindgren: - Fix a make randconfig build error for recent SMP kexec changes - A series of clock related fixes to prepare things for moving device clkctrl register handling to drivers/clk * tag 'omap-for-v4.8/soc-pt2-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: ARM: AM33xx: fix module_wait_ready without clkctrl register ARM: OMAP2+: clockdomain: add usecounting support to autoidle APIs ARM: OMAP2+: timer: change order of hwmod data handling ARM: OMAP2+: hwmod: fetch main_clk based on hwmod name ARM: OMAP2+: omap_device: create clock alias purely from DT data ARM: OMAP2+: Fix build with CONFIG_SMP and CONFIG_PM is not set
2 parents c341376 + 183e207 commit 04b6d0a

File tree

12 files changed

+123
-59
lines changed

12 files changed

+123
-59
lines changed

arch/arm/mach-omap2/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,16 @@ obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
7878
endif
7979

8080
# Power Management
81+
omap-4-5-pm-common = omap-mpuss-lowpower.o
82+
obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common)
83+
obj-$(CONFIG_ARCH_OMAP5) += $(omap-4-5-pm-common)
8184
obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
8285

8386
ifeq ($(CONFIG_PM),y)
8487
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
8588
obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
8689
obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
87-
omap-4-5-pm-common = pm44xx.o omap-mpuss-lowpower.o
90+
omap-4-5-pm-common += pm44xx.o
8891
obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common)
8992
obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-pm-common)
9093
obj-$(CONFIG_SOC_DRA7XX) += $(omap-4-5-pm-common)

arch/arm/mach-omap2/clockdomain.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -465,10 +465,7 @@ int clkdm_complete_init(void)
465465
return -EACCES;
466466

467467
list_for_each_entry(clkdm, &clkdm_list, node) {
468-
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
469-
clkdm_wakeup(clkdm);
470-
else if (clkdm->flags & CLKDM_CAN_DISABLE_AUTO)
471-
clkdm_deny_idle(clkdm);
468+
clkdm_deny_idle(clkdm);
472469

473470
_resolve_clkdm_deps(clkdm, clkdm->wkdep_srcs);
474471
clkdm_clear_all_wkdeps(clkdm);
@@ -925,11 +922,20 @@ void clkdm_allow_idle_nolock(struct clockdomain *clkdm)
925922
if (!clkdm)
926923
return;
927924

928-
if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) {
929-
pr_debug("clock: %s: automatic idle transitions cannot be enabled\n",
930-
clkdm->name);
925+
if (!WARN_ON(!clkdm->forcewake_count))
926+
clkdm->forcewake_count--;
927+
928+
if (clkdm->forcewake_count)
929+
return;
930+
931+
if (!clkdm->usecount && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP))
932+
clkdm_sleep_nolock(clkdm);
933+
934+
if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO))
935+
return;
936+
937+
if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)
931938
return;
932-
}
933939

934940
if (!arch_clkdm || !arch_clkdm->clkdm_allow_idle)
935941
return;
@@ -974,11 +980,17 @@ void clkdm_deny_idle_nolock(struct clockdomain *clkdm)
974980
if (!clkdm)
975981
return;
976982

977-
if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) {
978-
pr_debug("clockdomain: %s: automatic idle transitions cannot be disabled\n",
979-
clkdm->name);
983+
if (clkdm->forcewake_count++)
984+
return;
985+
986+
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
987+
clkdm_wakeup_nolock(clkdm);
988+
989+
if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO))
990+
return;
991+
992+
if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING)
980993
return;
981-
}
982994

983995
if (!arch_clkdm || !arch_clkdm->clkdm_deny_idle)
984996
return;

arch/arm/mach-omap2/clockdomain.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ struct omap_hwmod;
114114
* @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up
115115
* @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact
116116
* @usecount: Usecount tracking
117+
* @forcewake_count: Usecount for forcing the domain active
117118
* @node: list_head to link all clockdomains together
118119
*
119120
* @prcm_partition should be a macro from mach-omap2/prcm44xx.h (OMAP4 only)
@@ -138,6 +139,7 @@ struct clockdomain {
138139
struct clkdm_dep *wkdep_srcs;
139140
struct clkdm_dep *sleepdep_srcs;
140141
int usecount;
142+
int forcewake_count;
141143
struct list_head node;
142144
};
143145

arch/arm/mach-omap2/cm33xx.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ static int am33xx_cm_wait_module_ready(u8 part, s16 inst, u16 clkctrl_offs,
220220
{
221221
int i = 0;
222222

223+
if (!clkctrl_offs)
224+
return 0;
225+
223226
omap_test_timeout(_is_module_ready(inst, clkctrl_offs),
224227
MAX_MODULE_READY_TIME, i);
225228

arch/arm/mach-omap2/cpuidle44xx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
140140
mpuss_can_lose_context)
141141
gic_dist_disable();
142142

143-
clkdm_wakeup(cpu_clkdm[1]);
143+
clkdm_deny_idle(cpu_clkdm[1]);
144144
omap_set_pwrdm_state(cpu_pd[1], PWRDM_POWER_ON);
145145
clkdm_allow_idle(cpu_clkdm[1]);
146146

arch/arm/mach-omap2/omap-mpuss-lowpower.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464

6565
static void __iomem *sar_base;
6666

67-
#ifdef CONFIG_SMP
67+
#if defined(CONFIG_PM) && defined(CONFIG_SMP)
6868

6969
struct omap4_cpu_pm_info {
7070
struct powerdomain *pwrdm;

arch/arm/mach-omap2/omap-smp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
200200
* Ensure that CPU power state is set to ON to avoid CPU
201201
* powerdomain transition on wfi
202202
*/
203-
clkdm_wakeup_nolock(cpu1_clkdm);
203+
clkdm_deny_idle_nolock(cpu1_clkdm);
204204
pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON);
205205
clkdm_allow_idle_nolock(cpu1_clkdm);
206206

arch/arm/mach-omap2/omap_device.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,22 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias,
6363
return;
6464
}
6565

66-
rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev), clk_name, NULL);
66+
r = clk_get_sys(NULL, clk_name);
67+
68+
if (IS_ERR(r) && of_have_populated_dt()) {
69+
struct of_phandle_args clkspec;
70+
71+
clkspec.np = of_find_node_by_name(NULL, clk_name);
72+
73+
r = of_clk_get_from_provider(&clkspec);
74+
75+
rc = clk_register_clkdev(r, clk_alias,
76+
dev_name(&od->pdev->dev));
77+
} else {
78+
rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev),
79+
clk_name, NULL);
80+
}
81+
6782
if (rc) {
6883
if (rc == -ENODEV || rc == -ENOMEM)
6984
dev_err(&od->pdev->dev,

arch/arm/mach-omap2/omap_hwmod.c

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@
178178
*/
179179
#define OMAP4_RST_CTRL_ST_OFFSET 4
180180

181+
/*
182+
* Maximum length for module clock handle names
183+
*/
184+
#define MOD_CLK_MAX_NAME_LEN 32
185+
181186
/**
182187
* struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
183188
* @enable_module: function to enable a module (via MODULEMODE)
@@ -200,6 +205,7 @@ struct omap_hwmod_soc_ops {
200205
int (*init_clkdm)(struct omap_hwmod *oh);
201206
void (*update_context_lost)(struct omap_hwmod *oh);
202207
int (*get_context_lost)(struct omap_hwmod *oh);
208+
int (*disable_direct_prcm)(struct omap_hwmod *oh);
203209
};
204210

205211
/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
@@ -776,17 +782,35 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh)
776782
* @oh: struct omap_hwmod *
777783
*
778784
* Called from _init_clocks(). Populates the @oh _clk (main
779-
* functional clock pointer) if a main_clk is present. Returns 0 on
780-
* success or -EINVAL on error.
785+
* functional clock pointer) if a clock matching the hwmod name is found,
786+
* or a main_clk is present. Returns 0 on success or -EINVAL on error.
781787
*/
782788
static int _init_main_clk(struct omap_hwmod *oh)
783789
{
784790
int ret = 0;
791+
char name[MOD_CLK_MAX_NAME_LEN];
792+
struct clk *clk;
785793

786-
if (!oh->main_clk)
787-
return 0;
794+
/* +7 magic comes from '_mod_ck' suffix */
795+
if (strlen(oh->name) + 7 > MOD_CLK_MAX_NAME_LEN)
796+
pr_warn("%s: warning: cropping name for %s\n", __func__,
797+
oh->name);
798+
799+
strncpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - 7);
800+
strcat(name, "_mod_ck");
801+
802+
clk = clk_get(NULL, name);
803+
if (!IS_ERR(clk)) {
804+
oh->_clk = clk;
805+
soc_ops.disable_direct_prcm(oh);
806+
oh->main_clk = kstrdup(name, GFP_KERNEL);
807+
} else {
808+
if (!oh->main_clk)
809+
return 0;
810+
811+
oh->_clk = clk_get(NULL, oh->main_clk);
812+
}
788813

789-
oh->_clk = clk_get(NULL, oh->main_clk);
790814
if (IS_ERR(oh->_clk)) {
791815
pr_warn("omap_hwmod: %s: cannot clk_get main_clk %s\n",
792816
oh->name, oh->main_clk);
@@ -1678,7 +1702,6 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
16781702
{
16791703
struct omap_hwmod_rst_info ohri;
16801704
int ret = -EINVAL;
1681-
int hwsup = 0;
16821705

16831706
if (!oh)
16841707
return -EINVAL;
@@ -1696,7 +1719,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
16961719
* might not be completed. The clockdomain can be set
16971720
* in HW_AUTO only when the module become ready.
16981721
*/
1699-
hwsup = clkdm_in_hwsup(oh->clkdm);
1722+
clkdm_deny_idle(oh->clkdm);
17001723
ret = clkdm_hwmod_enable(oh->clkdm, oh);
17011724
if (ret) {
17021725
WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
@@ -1723,8 +1746,7 @@ static int _deassert_hardreset(struct omap_hwmod *oh, const char *name)
17231746
* Set the clockdomain to HW_AUTO, assuming that the
17241747
* previous state was HW_AUTO.
17251748
*/
1726-
if (hwsup)
1727-
clkdm_allow_idle(oh->clkdm);
1749+
clkdm_allow_idle(oh->clkdm);
17281750

17291751
clkdm_hwmod_disable(oh->clkdm, oh);
17301752
}
@@ -2078,7 +2100,6 @@ static int _enable_preprogram(struct omap_hwmod *oh)
20782100
static int _enable(struct omap_hwmod *oh)
20792101
{
20802102
int r;
2081-
int hwsup = 0;
20822103

20832104
pr_debug("omap_hwmod: %s: enabling\n", oh->name);
20842105

@@ -2138,8 +2159,7 @@ static int _enable(struct omap_hwmod *oh)
21382159
* completely the module. The clockdomain can be set
21392160
* in HW_AUTO only when the module become ready.
21402161
*/
2141-
hwsup = clkdm_in_hwsup(oh->clkdm) &&
2142-
!clkdm_missing_idle_reporting(oh->clkdm);
2162+
clkdm_deny_idle(oh->clkdm);
21432163
r = clkdm_hwmod_enable(oh->clkdm, oh);
21442164
if (r) {
21452165
WARN(1, "omap_hwmod: %s: could not enable clockdomain %s: %d\n",
@@ -2159,14 +2179,10 @@ static int _enable(struct omap_hwmod *oh)
21592179

21602180
r = (soc_ops.wait_target_ready) ? soc_ops.wait_target_ready(oh) :
21612181
-EINVAL;
2162-
if (!r) {
2163-
/*
2164-
* Set the clockdomain to HW_AUTO only if the target is ready,
2165-
* assuming that the previous state was HW_AUTO
2166-
*/
2167-
if (oh->clkdm && hwsup)
2168-
clkdm_allow_idle(oh->clkdm);
2182+
if (oh->clkdm)
2183+
clkdm_allow_idle(oh->clkdm);
21692184

2185+
if (!r) {
21702186
oh->_state = _HWMOD_STATE_ENABLED;
21712187

21722188
/* Access the sysconfig only if the target is ready */
@@ -2220,6 +2236,9 @@ static int _idle(struct omap_hwmod *oh)
22202236
_idle_sysc(oh);
22212237
_del_initiator_dep(oh, mpu_oh);
22222238

2239+
if (oh->clkdm)
2240+
clkdm_deny_idle(oh->clkdm);
2241+
22232242
if (oh->flags & HWMOD_BLOCK_WFI)
22242243
cpu_idle_poll_ctrl(false);
22252244
if (soc_ops.disable_module)
@@ -2232,8 +2251,10 @@ static int _idle(struct omap_hwmod *oh)
22322251
* transition to complete properly.
22332252
*/
22342253
_disable_clocks(oh);
2235-
if (oh->clkdm)
2254+
if (oh->clkdm) {
2255+
clkdm_allow_idle(oh->clkdm);
22362256
clkdm_hwmod_disable(oh->clkdm, oh);
2257+
}
22372258

22382259
/* Mux pins for device idle if populated */
22392260
if (oh->mux && oh->mux->pads_dynamic) {
@@ -3090,6 +3111,25 @@ static int _omap4_is_hardreset_asserted(struct omap_hwmod *oh,
30903111
oh->prcm.omap4.rstctrl_offs);
30913112
}
30923113

3114+
/**
3115+
* _omap4_disable_direct_prcm - disable direct PRCM control for hwmod
3116+
* @oh: struct omap_hwmod * to disable control for
3117+
*
3118+
* Disables direct PRCM clkctrl done by hwmod core. Instead, the hwmod
3119+
* will be using its main_clk to enable/disable the module. Returns
3120+
* 0 if successful.
3121+
*/
3122+
static int _omap4_disable_direct_prcm(struct omap_hwmod *oh)
3123+
{
3124+
if (!oh)
3125+
return -EINVAL;
3126+
3127+
oh->prcm.omap4.clkctrl_offs = 0;
3128+
oh->prcm.omap4.modulemode = 0;
3129+
3130+
return 0;
3131+
}
3132+
30933133
/**
30943134
* _am33xx_deassert_hardreset - call AM33XX PRM hardreset fn with hwmod args
30953135
* @oh: struct omap_hwmod * to deassert hardreset
@@ -3913,6 +3953,7 @@ void __init omap_hwmod_init(void)
39133953
soc_ops.init_clkdm = _init_clkdm;
39143954
soc_ops.update_context_lost = _omap4_update_context_lost;
39153955
soc_ops.get_context_lost = _omap4_get_context_lost;
3956+
soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm;
39163957
} else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() ||
39173958
soc_is_am43xx()) {
39183959
soc_ops.enable_module = _omap4_enable_module;
@@ -3922,6 +3963,7 @@ void __init omap_hwmod_init(void)
39223963
soc_ops.deassert_hardreset = _am33xx_deassert_hardreset;
39233964
soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
39243965
soc_ops.init_clkdm = _init_clkdm;
3966+
soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm;
39253967
} else {
39263968
WARN(1, "omap_hwmod: unknown SoC type\n");
39273969
}

arch/arm/mach-omap2/pm.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,7 @@ static void __init omap2_init_processor_devices(void)
110110

111111
int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused)
112112
{
113-
/* XXX The usecount test is racy */
114-
if ((clkdm->flags & CLKDM_CAN_ENABLE_AUTO) &&
115-
!(clkdm->flags & CLKDM_MISSING_IDLE_REPORTING))
116-
clkdm_allow_idle(clkdm);
117-
else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
118-
clkdm->usecount == 0)
119-
clkdm_sleep(clkdm);
113+
clkdm_allow_idle(clkdm);
120114
return 0;
121115
}
122116

0 commit comments

Comments
 (0)