Skip to content

Commit

Permalink
power: reset: Add TPS65086 restart driver
Browse files Browse the repository at this point in the history
Signed-off-by: Emil Renner Berthing <kernel@esmil.dk>
  • Loading branch information
esmil committed Jun 6, 2021
1 parent 560bb03 commit 66a1c63
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/mfd/tps65086.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
static const struct mfd_cell tps65086_cells[] = {
{ .name = "tps65086-regulator", },
{ .name = "tps65086-gpio", },
{ .name = "tps65086-restart", },
};

static const struct regmap_range tps65086_yes_ranges[] = {
Expand Down
6 changes: 6 additions & 0 deletions drivers/power/reset/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,12 @@ config POWER_RESET_ST
help
Reset support for STMicroelectronics boards.

config POWER_RESET_TPS65086
bool "TPS65086 restart driver"
depends on MFD_TPS65086
help
Reset TPS65086 PMIC on restart.

config POWER_RESET_VERSATILE
bool "ARM Versatile family reboot driver"
depends on ARM
Expand Down
1 change: 1 addition & 0 deletions drivers/power/reset/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
obj-$(CONFIG_POWER_RESET_REGULATOR) += regulator-poweroff.o
obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
obj-$(CONFIG_POWER_RESET_ST) += st-poweroff.o
obj-$(CONFIG_POWER_RESET_TPS65086) += tps65086-restart.o
obj-$(CONFIG_POWER_RESET_VERSATILE) += arm-versatile-reboot.o
obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
obj-$(CONFIG_POWER_RESET_XGENE) += xgene-reboot.o
Expand Down
101 changes: 101 additions & 0 deletions drivers/power/reset/tps65086-restart.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2021 Emil Renner Berthing
*/

#include <linux/reboot.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#include <linux/mfd/tps65086.h>

struct tps65086_restart {
struct notifier_block handler;
struct tps65086 *tps;
struct device *dev;
};

static int tps65086_restart_notify(struct notifier_block *this,
unsigned long mode, void *cmd)
{
struct tps65086_restart *tps65086_restart =
container_of(this, struct tps65086_restart, handler);
int ret;

ret = regmap_write(tps65086_restart->tps->regmap, TPS65086_FORCESHUTDN, 1);
if (ret) {
dev_err(tps65086_restart->dev, "%s: error writing to tps65086 pmic: %d\n",
__func__, ret);
return NOTIFY_DONE;
}

/* give it a little time */
mdelay(200);

WARN_ON(1);

return NOTIFY_DONE;
}

static int tps65086_restart_probe(struct platform_device *pdev)
{
struct tps65086_restart *tps65086_restart;
int ret;

tps65086_restart = devm_kzalloc(&pdev->dev, sizeof(*tps65086_restart), GFP_KERNEL);
if (!tps65086_restart)
return -ENOMEM;

platform_set_drvdata(pdev, tps65086_restart);

tps65086_restart->handler.notifier_call = tps65086_restart_notify;
tps65086_restart->handler.priority = 192;
tps65086_restart->tps = dev_get_drvdata(pdev->dev.parent);
tps65086_restart->dev = &pdev->dev;

ret = register_restart_handler(&tps65086_restart->handler);
if (ret) {
dev_err(&pdev->dev, "%s: cannot register restart handler: %d\n",
__func__, ret);
return -ENODEV;
}

return 0;
}

static int tps65086_restart_remove(struct platform_device *pdev)
{
struct tps65086_restart *tps65086_restart = platform_get_drvdata(pdev);
int ret;

ret = unregister_restart_handler(&tps65086_restart->handler);
if (ret) {
dev_err(&pdev->dev,
"%s: cannot unregister restart handler: %d\n",
__func__, ret);
return -ENODEV;
}

return 0;
}

static const struct platform_device_id tps65086_restart_id_table[] = {
{ "tps65086-restart", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, tps65086_restart_id_table);

static struct platform_driver tps65086_restart_driver = {
.driver = {
.name = "tps65086-restart",
},
.probe = tps65086_restart_probe,
.remove = tps65086_restart_remove,
.id_table = tps65086_restart_id_table,
};
module_platform_driver(tps65086_restart_driver);

MODULE_AUTHOR("Emil Renner Berthing <kernel@esmil.dk>");
MODULE_DESCRIPTION("TPS65086 restart driver");
MODULE_LICENSE("GPL v2");

0 comments on commit 66a1c63

Please sign in to comment.