power: reset: pwr-mlxbf: support graceful reboot instead of emergency reset
authorAsmaa Mnebhi <asmaa@nvidia.com>
Mon, 30 Oct 2023 20:30:58 +0000 (16:30 -0400)
committerSebastian Reichel <sebastian.reichel@collabora.com>
Wed, 15 Nov 2023 22:04:48 +0000 (23:04 +0100)
Replace the soft reset with a graceful reboot.
An acpi event will be triggered by the irq in the pwr-mlxbf.c
to trigger the graceful reboot.

Signed-off-by: Asmaa Mnebhi <asmaa@nvidia.com>
Link: https://lore.kernel.org/r/20231030203058.8056-1-asmaa@nvidia.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
drivers/power/reset/pwr-mlxbf.c

index de35d24bb7ef3edcf22afbdf597ad3436cba0ae5..1775b318d0ef4187cd96031a5a83af3b1e94358a 100644 (file)
 #include <linux/types.h>
 
 struct pwr_mlxbf {
-       struct work_struct send_work;
+       struct work_struct reboot_work;
+       struct work_struct shutdown_work;
        const char *hid;
 };
 
-static void pwr_mlxbf_send_work(struct work_struct *work)
+static void pwr_mlxbf_reboot_work(struct work_struct *work)
+{
+       acpi_bus_generate_netlink_event("button/reboot.*", "Reboot Button", 0x80, 1);
+}
+
+static void pwr_mlxbf_shutdown_work(struct work_struct *work)
 {
        acpi_bus_generate_netlink_event("button/power.*", "Power Button", 0x80, 1);
 }
@@ -33,10 +39,10 @@ static irqreturn_t pwr_mlxbf_irq(int irq, void *ptr)
        struct pwr_mlxbf *priv = ptr;
 
        if (!strncmp(priv->hid, rst_pwr_hid, 8))
-               emergency_restart();
+               schedule_work(&priv->reboot_work);
 
        if (!strncmp(priv->hid, low_pwr_hid, 8))
-               schedule_work(&priv->send_work);
+               schedule_work(&priv->shutdown_work);
 
        return IRQ_HANDLED;
 }
@@ -64,7 +70,11 @@ static int pwr_mlxbf_probe(struct platform_device *pdev)
        if (irq < 0)
                return dev_err_probe(dev, irq, "Error getting %s irq.\n", priv->hid);
 
-       err = devm_work_autocancel(dev, &priv->send_work, pwr_mlxbf_send_work);
+       err = devm_work_autocancel(dev, &priv->shutdown_work, pwr_mlxbf_shutdown_work);
+       if (err)
+               return err;
+
+       err = devm_work_autocancel(dev, &priv->reboot_work, pwr_mlxbf_reboot_work);
        if (err)
                return err;