1 // SPDX-License-Identifier: GPL-2.0-only
3 * Force-disables a regulator to power down a device
5 * Michael Klein <michael@fossekall.de>
7 * Copyright (C) 2020 Michael Klein
9 * Based on the gpio-poweroff driver.
11 #include <linux/delay.h>
12 #include <linux/module.h>
14 #include <linux/platform_device.h>
16 #include <linux/regulator/consumer.h>
18 #define TIMEOUT_MS 3000
21 * Hold configuration here, cannot be more than one instance of the driver
22 * since pm_power_off itself is global.
24 static struct regulator
*cpu_regulator
;
26 static void regulator_poweroff_do_poweroff(void)
28 if (cpu_regulator
&& regulator_is_enabled(cpu_regulator
))
29 regulator_force_disable(cpu_regulator
);
31 /* give it some time */
37 static int regulator_poweroff_probe(struct platform_device
*pdev
)
39 /* If a pm_power_off function has already been added, leave it alone */
40 if (pm_power_off
!= NULL
) {
42 "%s: pm_power_off function already registered\n",
47 cpu_regulator
= devm_regulator_get(&pdev
->dev
, "cpu");
48 if (IS_ERR(cpu_regulator
))
49 return PTR_ERR(cpu_regulator
);
51 pm_power_off
= ®ulator_poweroff_do_poweroff
;
55 static int regulator_poweroff_remove(__maybe_unused
struct platform_device
*pdev
)
57 if (pm_power_off
== ®ulator_poweroff_do_poweroff
)
63 static const struct of_device_id of_regulator_poweroff_match
[] = {
64 { .compatible
= "regulator-poweroff", },
68 static struct platform_driver regulator_poweroff_driver
= {
69 .probe
= regulator_poweroff_probe
,
70 .remove
= regulator_poweroff_remove
,
72 .name
= "poweroff-regulator",
73 .of_match_table
= of_regulator_poweroff_match
,
77 module_platform_driver(regulator_poweroff_driver
);
79 MODULE_AUTHOR("Michael Klein <michael@fossekall.de>");
80 MODULE_DESCRIPTION("Regulator poweroff driver");
81 MODULE_LICENSE("GPL v2");
82 MODULE_ALIAS("platform:poweroff-regulator");