soc/tegra: pmc: Prevent racing with cpuilde driver

Both PMC and cpuidle drivers are probed at the same init level and
cpuidle depends on the PMC suspend mode. Add new default suspend mode
that indicates whether PMC driver has been probed and reset the mode in
a case of deferred probe of the PMC driver.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
Dmitry Osipenko 2021-07-19 00:27:05 +03:00 committed by Thierry Reding
parent 158a9b47a4
commit 9c93ccfc86
5 changed files with 20 additions and 10 deletions

View File

@ -403,7 +403,7 @@ static const struct platform_suspend_ops tegra_suspend_ops = {
.enter = tegra_suspend_enter,
};
void __init tegra_init_suspend(void)
void tegra_pm_init_suspend(void)
{
enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();

View File

@ -25,10 +25,4 @@ void tegra30_sleep_core_init(void);
extern void (*tegra_tear_down_cpu)(void);
#ifdef CONFIG_PM_SLEEP
void tegra_init_suspend(void);
#else
static inline void tegra_init_suspend(void) {}
#endif
#endif /* _MACH_TEGRA_PM_H_ */

View File

@ -84,8 +84,6 @@ static void __init tegra_dt_init(void)
static void __init tegra_dt_init_late(void)
{
tegra_init_suspend();
if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
of_machine_is_compatible("compal,paz00"))
tegra_paz00_wifikill_init();

View File

@ -436,7 +436,7 @@ struct tegra_pmc {
static struct tegra_pmc *pmc = &(struct tegra_pmc) {
.base = NULL,
.suspend_mode = TEGRA_SUSPEND_NONE,
.suspend_mode = TEGRA_SUSPEND_NOT_READY,
};
static inline struct tegra_powergate *
@ -1812,6 +1812,7 @@ static int tegra_pmc_parse_dt(struct tegra_pmc *pmc, struct device_node *np)
u32 value, values[2];
if (of_property_read_u32(np, "nvidia,suspend-mode", &value)) {
pmc->suspend_mode = TEGRA_SUSPEND_NONE;
} else {
switch (value) {
case 0:
@ -2785,6 +2786,11 @@ static int tegra_pmc_regmap_init(struct tegra_pmc *pmc)
return 0;
}
static void tegra_pmc_reset_suspend_mode(void *data)
{
pmc->suspend_mode = TEGRA_SUSPEND_NOT_READY;
}
static int tegra_pmc_probe(struct platform_device *pdev)
{
void __iomem *base;
@ -2803,6 +2809,11 @@ static int tegra_pmc_probe(struct platform_device *pdev)
if (err < 0)
return err;
err = devm_add_action_or_reset(&pdev->dev, tegra_pmc_reset_suspend_mode,
NULL);
if (err)
return err;
/* take over the memory region from the early initialization */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
@ -2909,6 +2920,7 @@ static int tegra_pmc_probe(struct platform_device *pdev)
tegra_pmc_clock_register(pmc, pdev->dev.of_node);
platform_set_drvdata(pdev, pmc);
tegra_pm_init_suspend();
return 0;

View File

@ -14,6 +14,7 @@ enum tegra_suspend_mode {
TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */
TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */
TEGRA_MAX_SUSPEND_MODE,
TEGRA_SUSPEND_NOT_READY,
};
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM)
@ -28,6 +29,7 @@ void tegra_pm_clear_cpu_in_lp2(void);
void tegra_pm_set_cpu_in_lp2(void);
int tegra_pm_enter_lp2(void);
int tegra_pm_park_secondary_cpu(unsigned long cpu);
void tegra_pm_init_suspend(void);
#else
static inline enum tegra_suspend_mode
tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode)
@ -61,6 +63,10 @@ static inline int tegra_pm_park_secondary_cpu(unsigned long cpu)
{
return -ENOTSUPP;
}
static inline void tegra_pm_init_suspend(void)
{
}
#endif /* CONFIG_PM_SLEEP */
#endif /* __SOC_TEGRA_PM_H__ */