diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
index fece990af4a7..e7323b3b4a61 100644
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -100,6 +100,13 @@ config POWER_RESET_GPIO_RESTART
 	  If your board needs a GPIO high/low to restart, say Y and
 	  create a binding in your devicetree.
 
+config POWER_RESET_GS101_POWEROFF
+	tristate "GS101 power-off driver"
+	depends on ARCH_EXYNOS || COMPILE_TEST
+	help
+	  This driver supports turning off the Google Tensor Pixel6 GS101 phones.
+	  Select this if you're building a kernel with Google Tensor SoC support.
+
 config POWER_RESET_HISI
 	bool "Hisilicon power-off driver"
 	depends on ARCH_HISI
diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile
index a95d1bd275d1..7065b7e4ce77 100644
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_POWER_RESET_BRCMSTB) += brcmstb-reboot.o
 obj-$(CONFIG_POWER_RESET_GEMINI_POWEROFF) += gemini-poweroff.o
 obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
 obj-$(CONFIG_POWER_RESET_GPIO_RESTART) += gpio-restart.o
+obj-$(CONFIG_POWER_RESET_GS101_POWEROFF) += gs101-poweroff.o
 obj-$(CONFIG_POWER_RESET_HISI) += hisi-reboot.o
 obj-$(CONFIG_POWER_RESET_LINKSTATION) += linkstation-poweroff.o
 obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o
diff --git a/drivers/power/reset/gs101-poweroff.c b/drivers/power/reset/gs101-poweroff.c
new file mode 100644
index 000000000000..2be903de16a1
--- /dev/null
+++ b/drivers/power/reset/gs101-poweroff.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * GS101 Poweroff Driver
+ *
+ * Copyright (c) 2024, Linaro Ltd.
+ * Author: Alexey Klimov <alexey.klimov@linaro.org>
+ */
+
+#include <linux/delay.h>
+#include <linux/devm-helpers.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/keyboard.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/soc/samsung/exynos-pmu.h>
+
+#define shwork_to_poweroff(x)		\
+	container_of(x, struct gs101_poweroff, shutdown_work)
+
+#define keyboard_nb_to_poweroff(x)	\
+	container_of(x, struct gs101_poweroff, keyboard_nb)
+
+struct gs101_poweroff {
+	struct notifier_block keyboard_nb;
+	bool power_key_pressed;
+	struct work_struct shutdown_work;
+	struct regmap *map;
+	u32 offset;
+	u32 mask;
+};
+
+static struct gs101_poweroff *gs101_poweroff_ctx;
+
+static void gs101_shutdown_work_fn(struct work_struct *work)
+{
+	struct gs101_poweroff *gs101 = shwork_to_poweroff(work);
+
+	while (1) {
+		/* wait for power button release */
+		if (!gs101->power_key_pressed) {
+			/* Issue the poweroff */
+			regmap_update_bits(gs101->map,
+					   gs101->offset,
+					   gs101->mask, 0);
+		} else {
+			/*
+			 * if power button is not released,
+			 * wait and check TA again
+			 */
+			pr_info("power key is not released.\n");
+		}
+		mdelay(1000);
+	}
+}
+
+static int gs101_keyboard_notifier_call(struct notifier_block *nb,
+					unsigned long code, void *_param)
+{
+	struct keyboard_notifier_param *param = _param;
+
+	if (param->value == KEY_POWER) {
+		struct gs101_poweroff *gs101 = keyboard_nb_to_poweroff(nb);
+
+		gs101->power_key_pressed = param->down;
+	}
+
+	return NOTIFY_OK;
+}
+
+static void gs101_poweroff(void)
+{
+	schedule_work(&gs101_poweroff_ctx->shutdown_work);
+}
+
+static int gs101_poweroff_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct gs101_poweroff *gs101;
+	int ret;
+
+	gs101 = devm_kzalloc(dev, sizeof(*gs101), GFP_KERNEL);
+	if (!gs101)
+		return -ENOMEM;
+
+	gs101->map = exynos_get_pmu_regmap_by_phandle(dev->of_node,
+						      "samsung,syscon-phandle");
+	if (IS_ERR(gs101->map))
+		return PTR_ERR(gs101->map);
+
+	if (of_property_read_u32(dev->of_node, "offset", &gs101->offset)) {
+		dev_err(dev, "unable to read 'offset' from DT\n");
+		return -EINVAL;
+	}
+
+	if (of_property_read_u32(dev->of_node, "mask", &gs101->mask)) {
+		dev_err(dev, "unable to read 'mask' from DT\n");
+		return -EINVAL;
+	}
+
+	gs101->keyboard_nb.notifier_call = gs101_keyboard_notifier_call;
+	ret = register_keyboard_notifier(&gs101->keyboard_nb);
+	if (ret) {
+		dev_err(dev, "failed to register keyboard notifier: %i\n", ret);
+		return ret;
+	}
+
+	ret = devm_work_autocancel(dev, &gs101->shutdown_work,
+				   gs101_shutdown_work_fn);
+	if (ret) {
+		dev_err(dev, "failed to register gs101 shutdown_work: %i\n", ret);
+		unregister_keyboard_notifier(&gs101->keyboard_nb);
+		return ret;
+	}
+
+	gs101_poweroff_ctx = gs101;
+	platform_set_drvdata(pdev, gs101);
+
+	/*
+	 * At this point there is a chance that psci_sys_poweroff already
+	 * registered as pm_power_off hook but unfortunately it cannot power
+	 * off the gs101 SoC hence we are rewriting it here just as is.
+	 */
+	pm_power_off = gs101_poweroff;
+
+	return 0;
+}
+
+static void gs101_poweroff_remove(struct platform_device *pdev)
+{
+	struct gs101_poweroff *gs101 = platform_get_drvdata(pdev);
+
+	if (pm_power_off == gs101_poweroff)
+		pm_power_off = NULL;
+
+	unregister_keyboard_notifier(&gs101->keyboard_nb);
+}
+
+static const struct of_device_id gs101_poweroff_of_match[] = {
+	{ .compatible = "google,gs101-poweroff" },
+	{}
+};
+
+static struct platform_driver gs101_poweroff_driver = {
+	.probe = gs101_poweroff_probe,
+	.remove_new = gs101_poweroff_remove,
+	.driver = {
+		.name = "gs101-poweroff",
+		.of_match_table = gs101_poweroff_of_match,
+	},
+};
+
+module_platform_driver(gs101_poweroff_driver);
+MODULE_AUTHOR("Alexey Klimov <alexey.klimov@linaro.org>");
+MODULE_DESCRIPTION("Google GS101 poweroff driver");
+MODULE_LICENSE("GPL v2");
