diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 53cb04cb3743..11d200e3eb7e 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -111,6 +112,8 @@ #define PMC_PWR_DET_VALUE 0xe4 +#define KERNEL_PANIC_MAGIC 0x4E415054 + #define PMC_USB_DEBOUNCE_DEL 0xec #define PMC_USB_AO 0xf0 @@ -419,6 +422,7 @@ struct tegra_pmc_soc { bool has_usb_sleepwalk; bool supports_core_domain; bool has_single_mmio_aperture; + bool has_panic_notifier; }; /** @@ -505,6 +509,7 @@ struct tegra_pmc { unsigned long *wake_cntrl_level_map; struct notifier_block reboot_notifier; + struct notifier_block panic_notifier; struct syscore syscore; /* Pending wake IRQ processing */ @@ -1310,6 +1315,13 @@ static int tegra_pmc_restart_handler(struct sys_off_data *data) return NOTIFY_DONE; } +static int tegra_pmc_panic_handler(struct notifier_block *this, + unsigned long action, void *data) +{ + tegra_pmc_writel(pmc, KERNEL_PANIC_MAGIC, PMC_SCRATCH37); + return NOTIFY_DONE; +} + static int tegra_pmc_power_off_handler(struct sys_off_data *data) { struct tegra_pmc *pmc = data->cb_data; @@ -3199,6 +3211,20 @@ static int tegra_pmc_probe(struct platform_device *pdev) } } + if (pmc->soc->has_panic_notifier) { + pmc->panic_notifier.notifier_call = tegra_pmc_panic_handler; + pmc->panic_notifier.priority = INT_MAX-1; + + err = atomic_notifier_chain_register(&panic_notifier_list, + &pmc->panic_notifier); + if (err) { + dev_err(&pdev->dev, + "unable to register panic notifier, %d\n", + err); + return err; + } + } + err = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, SYS_OFF_PRIO_LOW, @@ -4018,6 +4044,7 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .has_blink_output = true, .has_usb_sleepwalk = true, .has_single_mmio_aperture = true, + .has_panic_notifier = true, }; static const char * const tegra210b01_powergates[] = { @@ -4079,6 +4106,7 @@ static const struct tegra_pmc_soc tegra210b01_pmc_soc = { .has_blink_output = true, .has_usb_sleepwalk = true, .has_single_mmio_aperture = true, + .has_panic_notifier = true, }; static const struct tegra_io_pad_soc tegra186_io_pads[] = {