* [PATCH] soc/tegra: pmc: Add reboot notifier
@ 2021-11-15 11:32 Jon Hunter
2021-11-18 19:13 ` Dmitry Osipenko
0 siblings, 1 reply; 4+ messages in thread
From: Jon Hunter @ 2021-11-15 11:32 UTC (permalink / raw)
To: Thierry Reding; +Cc: linux-tegra, Jon Hunter
The Tegra PMC driver implements a restart handler that supports Tegra
specific reboot commands such as placing the device into 'recovery' mode
in order to reprogram the platform. This is accomplished by setting the
appropriate bit in the PMC scratch0 register prior to rebooting the
platform.
For Tegra platforms that support PSCI or EFI, the default Tegra restart
handler is not called and the PSCI or EFI restart handler is called
instead. Hence, for Tegra platforms that support PSCI or EFI, the Tegra
specific reboot commands do not currently work. Fix this by moving the
code that programs the PMC scratch0 register into a separate reboot
notifier that will always be called on reboot.
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
---
drivers/soc/tegra/pmc.c | 50 ++++++++++++++++++++++++++++++++---------
1 file changed, 39 insertions(+), 11 deletions(-)
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 575d6d5b4294..19357ad9f46a 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -1064,27 +1064,47 @@ int tegra_pmc_cpu_remove_clamping(unsigned int cpuid)
return tegra_powergate_remove_clamping(id);
}
-static int tegra_pmc_restart_notify(struct notifier_block *this,
- unsigned long action, void *data)
+static void tegra_pmc_program_reboot_reason(const char *cmd)
{
- const char *cmd = data;
u32 value;
+ if (!cmd)
+ return;
+
value = tegra_pmc_scratch_readl(pmc, pmc->soc->regs->scratch0);
value &= ~PMC_SCRATCH0_MODE_MASK;
- if (cmd) {
- if (strcmp(cmd, "recovery") == 0)
- value |= PMC_SCRATCH0_MODE_RECOVERY;
+ if (strcmp(cmd, "recovery") == 0)
+ value |= PMC_SCRATCH0_MODE_RECOVERY;
- if (strcmp(cmd, "bootloader") == 0)
- value |= PMC_SCRATCH0_MODE_BOOTLOADER;
+ if (strcmp(cmd, "bootloader") == 0)
+ value |= PMC_SCRATCH0_MODE_BOOTLOADER;
- if (strcmp(cmd, "forced-recovery") == 0)
- value |= PMC_SCRATCH0_MODE_RCM;
- }
+ if (strcmp(cmd, "forced-recovery") == 0)
+ value |= PMC_SCRATCH0_MODE_RCM;
tegra_pmc_scratch_writel(pmc, value, pmc->soc->regs->scratch0);
+}
+
+static int tegra_pmc_reboot_notify(struct notifier_block *this,
+ unsigned long action, void *data)
+{
+ if (action == SYS_RESTART)
+ tegra_pmc_program_reboot_reason(data);
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block tegra_pmc_reboot_notifier = {
+ .notifier_call = tegra_pmc_reboot_notify,
+};
+
+static int tegra_pmc_restart_notify(struct notifier_block *this,
+ unsigned long action, void *data)
+{
+ u32 value;
+
+ tegra_pmc_program_reboot_reason(data);
/* reset everything but PMC_SCRATCH0 and PMC_RST_STATUS */
value = tegra_pmc_readl(pmc, PMC_CNTRL);
@@ -2890,6 +2910,14 @@ static int tegra_pmc_probe(struct platform_device *pdev)
goto cleanup_sysfs;
}
+ err = devm_register_reboot_notifier(&pdev->dev,
+ &tegra_pmc_reboot_notifier);
+ if (err) {
+ dev_err(&pdev->dev, "unable to register reboot notifier, %d\n",
+ err);
+ goto cleanup_debugfs;
+ }
+
err = register_restart_handler(&tegra_pmc_restart_handler);
if (err) {
dev_err(&pdev->dev, "unable to register restart handler, %d\n",
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] soc/tegra: pmc: Add reboot notifier
2021-11-15 11:32 [PATCH] soc/tegra: pmc: Add reboot notifier Jon Hunter
@ 2021-11-18 19:13 ` Dmitry Osipenko
2021-11-22 12:12 ` Jon Hunter
0 siblings, 1 reply; 4+ messages in thread
From: Dmitry Osipenko @ 2021-11-18 19:13 UTC (permalink / raw)
To: Jon Hunter, Thierry Reding; +Cc: linux-tegra
15.11.2021 14:32, Jon Hunter пишет:
> -static int tegra_pmc_restart_notify(struct notifier_block *this,
> - unsigned long action, void *data)
> +static void tegra_pmc_program_reboot_reason(const char *cmd)
> {
> - const char *cmd = data;
> u32 value;
>
> + if (!cmd)
> + return;
There is no explanation of this change in the commit message. Previously
scratch register was cleared if command is NULL, now it's not. Why?
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] soc/tegra: pmc: Add reboot notifier
2021-11-18 19:13 ` Dmitry Osipenko
@ 2021-11-22 12:12 ` Jon Hunter
2021-11-22 12:37 ` Dmitry Osipenko
0 siblings, 1 reply; 4+ messages in thread
From: Jon Hunter @ 2021-11-22 12:12 UTC (permalink / raw)
To: Dmitry Osipenko, Thierry Reding; +Cc: linux-tegra
On 18/11/2021 19:13, Dmitry Osipenko wrote:
> 15.11.2021 14:32, Jon Hunter пишет:
>> -static int tegra_pmc_restart_notify(struct notifier_block *this,
>> - unsigned long action, void *data)
>> +static void tegra_pmc_program_reboot_reason(const char *cmd)
>> {
>> - const char *cmd = data;
>> u32 value;
>>
>> + if (!cmd)
>> + return;
>
> There is no explanation of this change in the commit message. Previously
> scratch register was cleared if command is NULL, now it's not. Why?
No reason, just an oversight on my part. I can change this back to keep
the behaviour the same.
Jon
--
nvpublic
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] soc/tegra: pmc: Add reboot notifier
2021-11-22 12:12 ` Jon Hunter
@ 2021-11-22 12:37 ` Dmitry Osipenko
0 siblings, 0 replies; 4+ messages in thread
From: Dmitry Osipenko @ 2021-11-22 12:37 UTC (permalink / raw)
To: Jon Hunter, Thierry Reding; +Cc: linux-tegra
22.11.2021 15:12, Jon Hunter пишет:
>
> On 18/11/2021 19:13, Dmitry Osipenko wrote:
>> 15.11.2021 14:32, Jon Hunter пишет:
>>> -static int tegra_pmc_restart_notify(struct notifier_block *this,
>>> - unsigned long action, void *data)
>>> +static void tegra_pmc_program_reboot_reason(const char *cmd)
>>> {
>>> - const char *cmd = data;
>>> u32 value;
>>> + if (!cmd)
>>> + return;
>>
>> There is no explanation of this change in the commit message. Previously
>> scratch register was cleared if command is NULL, now it's not. Why?
>
>
> No reason, just an oversight on my part. I can change this back to keep
> the behaviour the same.
Alright, I'd expect bootloader to clear the register, although perhaps
there could be a reason why kernel needs to clear it since all
downstream kernels do it.
BTW, this patch is also needed in order to support restarting to
bootloader using PMIC's restart handler, which should become a thing for
some T30 devices soon. Although, will need to double check whether
scratch reg state retains after a full SoC power-cycle, but I assume it
should retain since RTC domain should stay always-on.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-11-22 12:37 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-11-15 11:32 [PATCH] soc/tegra: pmc: Add reboot notifier Jon Hunter
2021-11-18 19:13 ` Dmitry Osipenko
2021-11-22 12:12 ` Jon Hunter
2021-11-22 12:37 ` Dmitry Osipenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox