diff options
Diffstat (limited to 'drivers/power/reset/nvmem-reboot-mode.c')
-rw-r--r-- | drivers/power/reset/nvmem-reboot-mode.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/drivers/power/reset/nvmem-reboot-mode.c b/drivers/power/reset/nvmem-reboot-mode.c new file mode 100644 index 0000000000..e229308d43 --- /dev/null +++ b/drivers/power/reset/nvmem-reboot-mode.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) Vaisala Oyj. All rights reserved. + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/nvmem-consumer.h> +#include <linux/platform_device.h> +#include <linux/reboot-mode.h> + +struct nvmem_reboot_mode { + struct reboot_mode_driver reboot; + struct nvmem_cell *cell; +}; + +static int nvmem_reboot_mode_write(struct reboot_mode_driver *reboot, + unsigned int magic) +{ + int ret; + struct nvmem_reboot_mode *nvmem_rbm; + + nvmem_rbm = container_of(reboot, struct nvmem_reboot_mode, reboot); + + ret = nvmem_cell_write(nvmem_rbm->cell, &magic, sizeof(magic)); + if (ret < 0) + dev_err(reboot->dev, "update reboot mode bits failed\n"); + + return ret; +} + +static int nvmem_reboot_mode_probe(struct platform_device *pdev) +{ + int ret; + struct nvmem_reboot_mode *nvmem_rbm; + + nvmem_rbm = devm_kzalloc(&pdev->dev, sizeof(*nvmem_rbm), GFP_KERNEL); + if (!nvmem_rbm) + return -ENOMEM; + + nvmem_rbm->reboot.dev = &pdev->dev; + nvmem_rbm->reboot.write = nvmem_reboot_mode_write; + + nvmem_rbm->cell = devm_nvmem_cell_get(&pdev->dev, "reboot-mode"); + if (IS_ERR(nvmem_rbm->cell)) { + dev_err(&pdev->dev, "failed to get the nvmem cell reboot-mode\n"); + return PTR_ERR(nvmem_rbm->cell); + } + + ret = devm_reboot_mode_register(&pdev->dev, &nvmem_rbm->reboot); + if (ret) + dev_err(&pdev->dev, "can't register reboot mode\n"); + + return ret; +} + +static const struct of_device_id nvmem_reboot_mode_of_match[] = { + { .compatible = "nvmem-reboot-mode" }, + {} +}; +MODULE_DEVICE_TABLE(of, nvmem_reboot_mode_of_match); + +static struct platform_driver nvmem_reboot_mode_driver = { + .probe = nvmem_reboot_mode_probe, + .driver = { + .name = "nvmem-reboot-mode", + .of_match_table = nvmem_reboot_mode_of_match, + }, +}; +module_platform_driver(nvmem_reboot_mode_driver); + +MODULE_AUTHOR("Nandor Han <nandor.han@vaisala.com>"); +MODULE_DESCRIPTION("NVMEM reboot mode driver"); +MODULE_LICENSE("GPL"); |