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

reset-hi3660.c (3209B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (c) 2016-2017 Linaro Ltd.
      4 * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
      5 */
      6#include <linux/kernel.h>
      7#include <linux/mfd/syscon.h>
      8#include <linux/module.h>
      9#include <linux/of_device.h>
     10#include <linux/platform_device.h>
     11#include <linux/regmap.h>
     12#include <linux/reset-controller.h>
     13
     14struct hi3660_reset_controller {
     15	struct reset_controller_dev rst;
     16	struct regmap *map;
     17};
     18
     19#define to_hi3660_reset_controller(_rst) \
     20	container_of(_rst, struct hi3660_reset_controller, rst)
     21
     22static int hi3660_reset_program_hw(struct reset_controller_dev *rcdev,
     23				   unsigned long idx, bool assert)
     24{
     25	struct hi3660_reset_controller *rc = to_hi3660_reset_controller(rcdev);
     26	unsigned int offset = idx >> 8;
     27	unsigned int mask = BIT(idx & 0x1f);
     28
     29	if (assert)
     30		return regmap_write(rc->map, offset, mask);
     31	else
     32		return regmap_write(rc->map, offset + 4, mask);
     33}
     34
     35static int hi3660_reset_assert(struct reset_controller_dev *rcdev,
     36			       unsigned long idx)
     37{
     38	return hi3660_reset_program_hw(rcdev, idx, true);
     39}
     40
     41static int hi3660_reset_deassert(struct reset_controller_dev *rcdev,
     42				 unsigned long idx)
     43{
     44	return hi3660_reset_program_hw(rcdev, idx, false);
     45}
     46
     47static int hi3660_reset_dev(struct reset_controller_dev *rcdev,
     48			    unsigned long idx)
     49{
     50	int err;
     51
     52	err = hi3660_reset_assert(rcdev, idx);
     53	if (err)
     54		return err;
     55
     56	return hi3660_reset_deassert(rcdev, idx);
     57}
     58
     59static const struct reset_control_ops hi3660_reset_ops = {
     60	.reset    = hi3660_reset_dev,
     61	.assert   = hi3660_reset_assert,
     62	.deassert = hi3660_reset_deassert,
     63};
     64
     65static int hi3660_reset_xlate(struct reset_controller_dev *rcdev,
     66			      const struct of_phandle_args *reset_spec)
     67{
     68	unsigned int offset, bit;
     69
     70	offset = reset_spec->args[0];
     71	bit = reset_spec->args[1];
     72
     73	return (offset << 8) | bit;
     74}
     75
     76static int hi3660_reset_probe(struct platform_device *pdev)
     77{
     78	struct hi3660_reset_controller *rc;
     79	struct device_node *np = pdev->dev.of_node;
     80	struct device *dev = &pdev->dev;
     81
     82	rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL);
     83	if (!rc)
     84		return -ENOMEM;
     85
     86	rc->map = syscon_regmap_lookup_by_phandle(np, "hisilicon,rst-syscon");
     87	if (rc->map == ERR_PTR(-ENODEV)) {
     88		/* fall back to the deprecated compatible */
     89		rc->map = syscon_regmap_lookup_by_phandle(np,
     90							  "hisi,rst-syscon");
     91	}
     92	if (IS_ERR(rc->map)) {
     93		dev_err(dev, "failed to get hisilicon,rst-syscon\n");
     94		return PTR_ERR(rc->map);
     95	}
     96
     97	rc->rst.ops = &hi3660_reset_ops,
     98	rc->rst.of_node = np;
     99	rc->rst.of_reset_n_cells = 2;
    100	rc->rst.of_xlate = hi3660_reset_xlate;
    101
    102	return reset_controller_register(&rc->rst);
    103}
    104
    105static const struct of_device_id hi3660_reset_match[] = {
    106	{ .compatible = "hisilicon,hi3660-reset", },
    107	{},
    108};
    109MODULE_DEVICE_TABLE(of, hi3660_reset_match);
    110
    111static struct platform_driver hi3660_reset_driver = {
    112	.probe = hi3660_reset_probe,
    113	.driver = {
    114		.name = "hi3660-reset",
    115		.of_match_table = hi3660_reset_match,
    116	},
    117};
    118
    119static int __init hi3660_reset_init(void)
    120{
    121	return platform_driver_register(&hi3660_reset_driver);
    122}
    123arch_initcall(hi3660_reset_init);
    124
    125MODULE_LICENSE("GPL");
    126MODULE_ALIAS("platform:hi3660-reset");
    127MODULE_DESCRIPTION("HiSilicon Hi3660 Reset Driver");