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.c (3350B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2014 MediaTek Inc.
      4 */
      5
      6#include <linux/mfd/syscon.h>
      7#include <linux/module.h>
      8#include <linux/of.h>
      9#include <linux/platform_device.h>
     10#include <linux/regmap.h>
     11#include <linux/reset-controller.h>
     12#include <linux/slab.h>
     13
     14#include "clk-mtk.h"
     15
     16struct mtk_reset {
     17	struct regmap *regmap;
     18	int regofs;
     19	struct reset_controller_dev rcdev;
     20};
     21
     22static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev,
     23	unsigned long id)
     24{
     25	struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
     26	unsigned int reg = data->regofs + ((id / 32) << 4);
     27
     28	return regmap_write(data->regmap, reg, 1);
     29}
     30
     31static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev,
     32	unsigned long id)
     33{
     34	struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
     35	unsigned int reg = data->regofs + ((id / 32) << 4) + 0x4;
     36
     37	return regmap_write(data->regmap, reg, 1);
     38}
     39
     40static int mtk_reset_assert(struct reset_controller_dev *rcdev,
     41			      unsigned long id)
     42{
     43	struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
     44
     45	return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
     46			BIT(id % 32), ~0);
     47}
     48
     49static int mtk_reset_deassert(struct reset_controller_dev *rcdev,
     50				unsigned long id)
     51{
     52	struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
     53
     54	return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
     55			BIT(id % 32), 0);
     56}
     57
     58static int mtk_reset(struct reset_controller_dev *rcdev,
     59			      unsigned long id)
     60{
     61	int ret;
     62
     63	ret = mtk_reset_assert(rcdev, id);
     64	if (ret)
     65		return ret;
     66
     67	return mtk_reset_deassert(rcdev, id);
     68}
     69
     70static int mtk_reset_set_clr(struct reset_controller_dev *rcdev,
     71	unsigned long id)
     72{
     73	int ret;
     74
     75	ret = mtk_reset_assert_set_clr(rcdev, id);
     76	if (ret)
     77		return ret;
     78	return mtk_reset_deassert_set_clr(rcdev, id);
     79}
     80
     81static const struct reset_control_ops mtk_reset_ops = {
     82	.assert = mtk_reset_assert,
     83	.deassert = mtk_reset_deassert,
     84	.reset = mtk_reset,
     85};
     86
     87static const struct reset_control_ops mtk_reset_ops_set_clr = {
     88	.assert = mtk_reset_assert_set_clr,
     89	.deassert = mtk_reset_deassert_set_clr,
     90	.reset = mtk_reset_set_clr,
     91};
     92
     93static void mtk_register_reset_controller_common(struct device_node *np,
     94			unsigned int num_regs, int regofs,
     95			const struct reset_control_ops *reset_ops)
     96{
     97	struct mtk_reset *data;
     98	int ret;
     99	struct regmap *regmap;
    100
    101	regmap = device_node_to_regmap(np);
    102	if (IS_ERR(regmap)) {
    103		pr_err("Cannot find regmap for %pOF: %pe\n", np, regmap);
    104		return;
    105	}
    106
    107	data = kzalloc(sizeof(*data), GFP_KERNEL);
    108	if (!data)
    109		return;
    110
    111	data->regmap = regmap;
    112	data->regofs = regofs;
    113	data->rcdev.owner = THIS_MODULE;
    114	data->rcdev.nr_resets = num_regs * 32;
    115	data->rcdev.ops = reset_ops;
    116	data->rcdev.of_node = np;
    117
    118	ret = reset_controller_register(&data->rcdev);
    119	if (ret) {
    120		pr_err("could not register reset controller: %d\n", ret);
    121		kfree(data);
    122		return;
    123	}
    124}
    125
    126void mtk_register_reset_controller(struct device_node *np,
    127	unsigned int num_regs, int regofs)
    128{
    129	mtk_register_reset_controller_common(np, num_regs, regofs,
    130		&mtk_reset_ops);
    131}
    132
    133void mtk_register_reset_controller_set_clr(struct device_node *np,
    134	unsigned int num_regs, int regofs)
    135{
    136	mtk_register_reset_controller_common(np, num_regs, regofs,
    137		&mtk_reset_ops_set_clr);
    138}
    139
    140MODULE_LICENSE("GPL");