Skip to content

Commit 9b6a3f3

Browse files
mikel-armbbgregkh
authored andcommitted
coresight: etmv4: Fix CPU power management setup in probe() function
The current probe() function calls a pair of cpuhp_xxx API functions to setup CPU hotplug handling. The hotplug lock is held for the duration of the two calls and other CPU related code using cpus_read_lock() / cpus_read_unlock() calls. The problem is that on error states, goto: statements bypass the cpus_read_unlock() call. This code has increased in complexity as the driver has developed. This patch introduces a pair of helper functions etm4_pm_setup_cpuslocked() and etm4_pm_clear() which correct the issues above and group the PM code a little better. The two functions etm4_cpu_pm_register() and etm4_cpu_pm_unregister() are dropped as these call cpu_pm_register_notifier() / ..unregister_notifier() dependent on CONFIG_CPU_PM - but this define is used to nop these functions out in the pm headers - so the wrapper functions are superfluous. Fixes: f188b5e ("coresight: etm4x: Save/restore state across CPU low power states") Fixes: e9f5d63 ("hwtracing/coresight-etm4x: Use cpuhp_setup_state_nocalls_cpuslocked()") Fixes: 58eb457 ("hwtracing/coresight-etm4x: Convert to hotplug state machine") Signed-off-by: Mike Leach <[email protected]> Cc: stable <[email protected]> Reviewed-by: Mathieu Poirier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 6740de9 commit 9b6a3f3

File tree

1 file changed

+53
-29
lines changed

1 file changed

+53
-29
lines changed

drivers/hwtracing/coresight/coresight-etm4x.c

Lines changed: 53 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,18 +1388,57 @@ static struct notifier_block etm4_cpu_pm_nb = {
13881388
.notifier_call = etm4_cpu_pm_notify,
13891389
};
13901390

1391-
static int etm4_cpu_pm_register(void)
1391+
/* Setup PM. Called with cpus locked. Deals with error conditions and counts */
1392+
static int etm4_pm_setup_cpuslocked(void)
13921393
{
1393-
if (IS_ENABLED(CONFIG_CPU_PM))
1394-
return cpu_pm_register_notifier(&etm4_cpu_pm_nb);
1394+
int ret;
13951395

1396-
return 0;
1396+
if (etm4_count++)
1397+
return 0;
1398+
1399+
ret = cpu_pm_register_notifier(&etm4_cpu_pm_nb);
1400+
if (ret)
1401+
goto reduce_count;
1402+
1403+
ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING,
1404+
"arm/coresight4:starting",
1405+
etm4_starting_cpu, etm4_dying_cpu);
1406+
1407+
if (ret)
1408+
goto unregister_notifier;
1409+
1410+
ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN,
1411+
"arm/coresight4:online",
1412+
etm4_online_cpu, NULL);
1413+
1414+
/* HP dyn state ID returned in ret on success */
1415+
if (ret > 0) {
1416+
hp_online = ret;
1417+
return 0;
1418+
}
1419+
1420+
/* failed dyn state - remove others */
1421+
cpuhp_remove_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING);
1422+
1423+
unregister_notifier:
1424+
cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
1425+
1426+
reduce_count:
1427+
--etm4_count;
1428+
return ret;
13971429
}
13981430

1399-
static void etm4_cpu_pm_unregister(void)
1431+
static void etm4_pm_clear(void)
14001432
{
1401-
if (IS_ENABLED(CONFIG_CPU_PM))
1402-
cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
1433+
if (--etm4_count != 0)
1434+
return;
1435+
1436+
cpu_pm_unregister_notifier(&etm4_cpu_pm_nb);
1437+
cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
1438+
if (hp_online) {
1439+
cpuhp_remove_state_nocalls(hp_online);
1440+
hp_online = 0;
1441+
}
14031442
}
14041443

14051444
static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
@@ -1453,24 +1492,15 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
14531492
etm4_init_arch_data, drvdata, 1))
14541493
dev_err(dev, "ETM arch init failed\n");
14551494

1456-
if (!etm4_count++) {
1457-
cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING,
1458-
"arm/coresight4:starting",
1459-
etm4_starting_cpu, etm4_dying_cpu);
1460-
ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN,
1461-
"arm/coresight4:online",
1462-
etm4_online_cpu, NULL);
1463-
if (ret < 0)
1464-
goto err_arch_supported;
1465-
hp_online = ret;
1495+
ret = etm4_pm_setup_cpuslocked();
1496+
cpus_read_unlock();
14661497

1467-
ret = etm4_cpu_pm_register();
1468-
if (ret)
1469-
goto err_arch_supported;
1498+
/* etm4_pm_setup_cpuslocked() does its own cleanup - exit on error */
1499+
if (ret) {
1500+
etmdrvdata[drvdata->cpu] = NULL;
1501+
return ret;
14701502
}
14711503

1472-
cpus_read_unlock();
1473-
14741504
if (etm4_arch_supported(drvdata->arch) == false) {
14751505
ret = -EINVAL;
14761506
goto err_arch_supported;
@@ -1517,13 +1547,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
15171547

15181548
err_arch_supported:
15191549
etmdrvdata[drvdata->cpu] = NULL;
1520-
if (--etm4_count == 0) {
1521-
etm4_cpu_pm_unregister();
1522-
1523-
cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
1524-
if (hp_online)
1525-
cpuhp_remove_state_nocalls(hp_online);
1526-
}
1550+
etm4_pm_clear();
15271551
return ret;
15281552
}
15291553

0 commit comments

Comments
 (0)