cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

syscon-reboot-mode.c (2236B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
      4 */
      5
      6#include <linux/init.h>
      7#include <linux/module.h>
      8#include <linux/kernel.h>
      9#include <linux/of.h>
     10#include <linux/platform_device.h>
     11#include <linux/reboot.h>
     12#include <linux/regmap.h>
     13#include <linux/mfd/syscon.h>
     14#include <linux/reboot-mode.h>
     15
     16struct syscon_reboot_mode {
     17	struct regmap *map;
     18	struct reboot_mode_driver reboot;
     19	u32 offset;
     20	u32 mask;
     21};
     22
     23static int syscon_reboot_mode_write(struct reboot_mode_driver *reboot,
     24				    unsigned int magic)
     25{
     26	struct syscon_reboot_mode *syscon_rbm;
     27	int ret;
     28
     29	syscon_rbm = container_of(reboot, struct syscon_reboot_mode, reboot);
     30
     31	ret = regmap_update_bits(syscon_rbm->map, syscon_rbm->offset,
     32				 syscon_rbm->mask, magic);
     33	if (ret < 0)
     34		dev_err(reboot->dev, "update reboot mode bits failed\n");
     35
     36	return ret;
     37}
     38
     39static int syscon_reboot_mode_probe(struct platform_device *pdev)
     40{
     41	int ret;
     42	struct syscon_reboot_mode *syscon_rbm;
     43
     44	syscon_rbm = devm_kzalloc(&pdev->dev, sizeof(*syscon_rbm), GFP_KERNEL);
     45	if (!syscon_rbm)
     46		return -ENOMEM;
     47
     48	syscon_rbm->reboot.dev = &pdev->dev;
     49	syscon_rbm->reboot.write = syscon_reboot_mode_write;
     50	syscon_rbm->mask = 0xffffffff;
     51
     52	syscon_rbm->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
     53	if (IS_ERR(syscon_rbm->map))
     54		return PTR_ERR(syscon_rbm->map);
     55
     56	if (of_property_read_u32(pdev->dev.of_node, "offset",
     57	    &syscon_rbm->offset))
     58		return -EINVAL;
     59
     60	of_property_read_u32(pdev->dev.of_node, "mask", &syscon_rbm->mask);
     61
     62	ret = devm_reboot_mode_register(&pdev->dev, &syscon_rbm->reboot);
     63	if (ret)
     64		dev_err(&pdev->dev, "can't register reboot mode\n");
     65
     66	return ret;
     67}
     68
     69static const struct of_device_id syscon_reboot_mode_of_match[] = {
     70	{ .compatible = "syscon-reboot-mode" },
     71	{}
     72};
     73MODULE_DEVICE_TABLE(of, syscon_reboot_mode_of_match);
     74
     75static struct platform_driver syscon_reboot_mode_driver = {
     76	.probe = syscon_reboot_mode_probe,
     77	.driver = {
     78		.name = "syscon-reboot-mode",
     79		.of_match_table = syscon_reboot_mode_of_match,
     80	},
     81};
     82module_platform_driver(syscon_reboot_mode_driver);
     83
     84MODULE_AUTHOR("Andy Yan <andy.yan@rock-chips.com");
     85MODULE_DESCRIPTION("SYSCON reboot mode driver");
     86MODULE_LICENSE("GPL v2");