Skip to content

Commit

Permalink
ARM: at91: pm: do not panic if ram controllers are not enabled
Browse files Browse the repository at this point in the history
[ Upstream commit 1605de1 ]

In case PM is enabled but there is no RAM controller information
in DT the code will panic. Avoid such scenarios by not initializing
platform specific PM code in case RAM controller is not provided
via DT.

Reported-by: Eugen Hristev <eugen.hristev@microchip.com>
Fixes: 827de1f ("ARM: at91: remove at91_dt_initialize and machine init_early()")
Fixes: 892e1f4 ("ARM: at91: pm: add sama7g5 ddr phy controller")
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Link: https://lore.kernel.org/r/20210823131915.23857-2-claudiu.beznea@microchip.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
claudiubeznea authored and gregkh committed Oct 13, 2021
1 parent 55f37cc commit 306b7fe
Showing 1 changed file with 47 additions and 11 deletions.
58 changes: 47 additions & 11 deletions arch/arm/mach-at91/pm.c
Expand Up @@ -514,18 +514,22 @@ static const struct of_device_id ramc_ids[] __initconst = {
{ /*sentinel*/ }
};

static __init void at91_dt_ramc(void)
static __init int at91_dt_ramc(void)
{
struct device_node *np;
const struct of_device_id *of_id;
int idx = 0;
void *standby = NULL;
const struct ramc_info *ramc;
int ret;

for_each_matching_node_and_match(np, ramc_ids, &of_id) {
soc_pm.data.ramc[idx] = of_iomap(np, 0);
if (!soc_pm.data.ramc[idx])
panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
if (!soc_pm.data.ramc[idx]) {
pr_err("unable to map ramc[%d] cpu registers\n", idx);
ret = -ENOMEM;
goto unmap_ramc;
}

ramc = of_id->data;
if (!standby)
Expand All @@ -535,15 +539,26 @@ static __init void at91_dt_ramc(void)
idx++;
}

if (!idx)
panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
if (!idx) {
pr_err("unable to find compatible ram controller node in dtb\n");
ret = -ENODEV;
goto unmap_ramc;
}

if (!standby) {
pr_warn("ramc no standby function available\n");
return;
return 0;
}

at91_cpuidle_device.dev.platform_data = standby;

return 0;

unmap_ramc:
while (idx)
iounmap(soc_pm.data.ramc[--idx]);

return ret;
}

static void at91rm9200_idle(void)
Expand Down Expand Up @@ -866,6 +881,8 @@ static void __init at91_pm_init(void (*pm_idle)(void))

void __init at91rm9200_pm_init(void)
{
int ret;

if (!IS_ENABLED(CONFIG_SOC_AT91RM9200))
return;

Expand All @@ -877,7 +894,9 @@ void __init at91rm9200_pm_init(void)
soc_pm.data.standby_mode = AT91_PM_STANDBY;
soc_pm.data.suspend_mode = AT91_PM_ULP0;

at91_dt_ramc();
ret = at91_dt_ramc();
if (ret)
return;

/*
* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh.
Expand All @@ -892,13 +911,17 @@ void __init sam9x60_pm_init(void)
static const int modes[] __initconst = {
AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
};
int ret;

if (!IS_ENABLED(CONFIG_SOC_SAM9X60))
return;

at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
at91_pm_modes_init();
at91_dt_ramc();
ret = at91_dt_ramc();
if (ret)
return;

at91_pm_init(NULL);

soc_pm.ws_ids = sam9x60_ws_ids;
Expand All @@ -907,6 +930,8 @@ void __init sam9x60_pm_init(void)

void __init at91sam9_pm_init(void)
{
int ret;

if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
return;

Expand All @@ -918,7 +943,10 @@ void __init at91sam9_pm_init(void)
soc_pm.data.standby_mode = AT91_PM_STANDBY;
soc_pm.data.suspend_mode = AT91_PM_ULP0;

at91_dt_ramc();
ret = at91_dt_ramc();
if (ret)
return;

at91_pm_init(at91sam9_idle);
}

Expand All @@ -927,12 +955,16 @@ void __init sama5_pm_init(void)
static const int modes[] __initconst = {
AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST,
};
int ret;

if (!IS_ENABLED(CONFIG_SOC_SAMA5))
return;

at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
at91_dt_ramc();
ret = at91_dt_ramc();
if (ret)
return;

at91_pm_init(NULL);
}

Expand All @@ -942,13 +974,17 @@ void __init sama5d2_pm_init(void)
AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
AT91_PM_BACKUP,
};
int ret;

if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
return;

at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
at91_pm_modes_init();
at91_dt_ramc();
ret = at91_dt_ramc();
if (ret)
return;

at91_pm_init(NULL);

soc_pm.ws_ids = sama5d2_ws_ids;
Expand Down

0 comments on commit 306b7fe

Please sign in to comment.