| From 3386d22d3b3bcb202ef186d699d9dddfa681e13b Mon Sep 17 00:00:00 2001 |
| From: Phil Elwell <phil@raspberrypi.org> |
| Date: Sat, 12 May 2018 21:35:43 +0100 |
| Subject: [PATCH] firmware/raspberrypi: Notify firmware of a reboot |
| |
| Register for reboot notifications, sending RPI_FIRMWARE_NOTIFY_REBOOT |
| over the mailbox interface on reception. |
| |
| Signed-off-by: Phil Elwell <phil@raspberrypi.org> |
| --- |
| drivers/firmware/raspberrypi.c | 40 +++++++++++++++++++++++++++++++++- |
| 1 file changed, 39 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/firmware/raspberrypi.c |
| +++ b/drivers/firmware/raspberrypi.c |
| @@ -12,6 +12,7 @@ |
| #include <linux/of_platform.h> |
| #include <linux/platform_device.h> |
| #include <linux/slab.h> |
| +#include <linux/reboot.h> |
| #include <soc/bcm2835/raspberrypi-firmware.h> |
| |
| #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf)) |
| @@ -177,6 +178,26 @@ int rpi_firmware_property(struct rpi_fir |
| } |
| EXPORT_SYMBOL_GPL(rpi_firmware_property); |
| |
| +static int rpi_firmware_notify_reboot(struct notifier_block *nb, |
| + unsigned long action, |
| + void *data) |
| +{ |
| + struct rpi_firmware *fw; |
| + struct platform_device *pdev = g_pdev; |
| + |
| + if (!pdev) |
| + return 0; |
| + |
| + fw = platform_get_drvdata(pdev); |
| + if (!fw) |
| + return 0; |
| + |
| + (void)rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT, |
| + 0, 0); |
| + |
| + return 0; |
| +} |
| + |
| static void |
| rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) |
| { |
| @@ -307,15 +328,32 @@ static struct platform_driver rpi_firmwa |
| .remove = rpi_firmware_remove, |
| }; |
| |
| +static struct notifier_block rpi_firmware_reboot_notifier = { |
| + .notifier_call = rpi_firmware_notify_reboot, |
| +}; |
| + |
| static int __init rpi_firmware_init(void) |
| { |
| - return platform_driver_register(&rpi_firmware_driver); |
| + int ret = register_reboot_notifier(&rpi_firmware_reboot_notifier); |
| + if (ret) |
| + goto out1; |
| + ret = platform_driver_register(&rpi_firmware_driver); |
| + if (ret) |
| + goto out2; |
| + |
| + return 0; |
| + |
| +out2: |
| + unregister_reboot_notifier(&rpi_firmware_reboot_notifier); |
| +out1: |
| + return ret; |
| } |
| subsys_initcall(rpi_firmware_init); |
| |
| static void __init rpi_firmware_exit(void) |
| { |
| platform_driver_unregister(&rpi_firmware_driver); |
| + unregister_reboot_notifier(&rpi_firmware_reboot_notifier); |
| } |
| module_exit(rpi_firmware_exit); |
| |