1 // SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause
4 * Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES.
7 #include <linux/acpi.h>
8 #include <linux/device.h>
9 #include <linux/devm-helpers.h>
10 #include <linux/interrupt.h>
11 #include <linux/kernel.h>
12 #include <linux/mod_devicetable.h>
13 #include <linux/module.h>
14 #include <linux/platform_device.h>
16 #include <linux/reboot.h>
17 #include <linux/types.h>
20 struct work_struct reboot_work
;
24 static void pwr_mlxbf_reboot_work(struct work_struct
*work
)
26 acpi_bus_generate_netlink_event("button/reboot.*", "Reboot Button", 0x80, 1);
29 static irqreturn_t
pwr_mlxbf_irq(int irq
, void *ptr
)
31 const char *rst_pwr_hid
= "MLNXBF24";
32 const char *shutdown_hid
= "MLNXBF29";
33 struct pwr_mlxbf
*priv
= ptr
;
35 if (!strncmp(priv
->hid
, rst_pwr_hid
, 8))
36 schedule_work(&priv
->reboot_work
);
38 if (!strncmp(priv
->hid
, shutdown_hid
, 8))
39 orderly_poweroff(true);
44 static int pwr_mlxbf_probe(struct platform_device
*pdev
)
46 struct device
*dev
= &pdev
->dev
;
47 struct acpi_device
*adev
;
48 struct pwr_mlxbf
*priv
;
52 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
56 adev
= ACPI_COMPANION(dev
);
60 hid
= acpi_device_hid(adev
);
63 irq
= acpi_dev_gpio_irq_get(ACPI_COMPANION(dev
), 0);
65 return dev_err_probe(dev
, irq
, "Error getting %s irq.\n", priv
->hid
);
67 err
= devm_work_autocancel(dev
, &priv
->reboot_work
, pwr_mlxbf_reboot_work
);
71 err
= devm_request_irq(dev
, irq
, pwr_mlxbf_irq
, 0, hid
, priv
);
73 dev_err(dev
, "Failed request of %s irq\n", priv
->hid
);
78 static const struct acpi_device_id __maybe_unused pwr_mlxbf_acpi_match
[] = {
83 MODULE_DEVICE_TABLE(acpi
, pwr_mlxbf_acpi_match
);
85 static struct platform_driver pwr_mlxbf_driver
= {
88 .acpi_match_table
= pwr_mlxbf_acpi_match
,
90 .probe
= pwr_mlxbf_probe
,
93 module_platform_driver(pwr_mlxbf_driver
);
95 MODULE_DESCRIPTION("Mellanox BlueField power driver");
96 MODULE_AUTHOR("Asmaa Mnebhi <asmaa@nvidia.com>");
97 MODULE_LICENSE("Dual BSD/GPL");