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

softrst.c (2793B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (c) 2014 MundoReader S.L.
      4 * Author: Heiko Stuebner <heiko@sntech.de>
      5 */
      6
      7#include <linux/slab.h>
      8#include <linux/io.h>
      9#include <linux/reset-controller.h>
     10#include <linux/spinlock.h>
     11#include "clk.h"
     12
     13struct rockchip_softrst {
     14	struct reset_controller_dev	rcdev;
     15	void __iomem			*reg_base;
     16	int				num_regs;
     17	int				num_per_reg;
     18	u8				flags;
     19	spinlock_t			lock;
     20};
     21
     22static int rockchip_softrst_assert(struct reset_controller_dev *rcdev,
     23			      unsigned long id)
     24{
     25	struct rockchip_softrst *softrst = container_of(rcdev,
     26						     struct rockchip_softrst,
     27						     rcdev);
     28	int bank = id / softrst->num_per_reg;
     29	int offset = id % softrst->num_per_reg;
     30
     31	if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) {
     32		writel(BIT(offset) | (BIT(offset) << 16),
     33		       softrst->reg_base + (bank * 4));
     34	} else {
     35		unsigned long flags;
     36		u32 reg;
     37
     38		spin_lock_irqsave(&softrst->lock, flags);
     39
     40		reg = readl(softrst->reg_base + (bank * 4));
     41		writel(reg | BIT(offset), softrst->reg_base + (bank * 4));
     42
     43		spin_unlock_irqrestore(&softrst->lock, flags);
     44	}
     45
     46	return 0;
     47}
     48
     49static int rockchip_softrst_deassert(struct reset_controller_dev *rcdev,
     50				unsigned long id)
     51{
     52	struct rockchip_softrst *softrst = container_of(rcdev,
     53						     struct rockchip_softrst,
     54						     rcdev);
     55	int bank = id / softrst->num_per_reg;
     56	int offset = id % softrst->num_per_reg;
     57
     58	if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) {
     59		writel((BIT(offset) << 16), softrst->reg_base + (bank * 4));
     60	} else {
     61		unsigned long flags;
     62		u32 reg;
     63
     64		spin_lock_irqsave(&softrst->lock, flags);
     65
     66		reg = readl(softrst->reg_base + (bank * 4));
     67		writel(reg & ~BIT(offset), softrst->reg_base + (bank * 4));
     68
     69		spin_unlock_irqrestore(&softrst->lock, flags);
     70	}
     71
     72	return 0;
     73}
     74
     75static const struct reset_control_ops rockchip_softrst_ops = {
     76	.assert		= rockchip_softrst_assert,
     77	.deassert	= rockchip_softrst_deassert,
     78};
     79
     80void rockchip_register_softrst(struct device_node *np,
     81			       unsigned int num_regs,
     82			       void __iomem *base, u8 flags)
     83{
     84	struct rockchip_softrst *softrst;
     85	int ret;
     86
     87	softrst = kzalloc(sizeof(*softrst), GFP_KERNEL);
     88	if (!softrst)
     89		return;
     90
     91	spin_lock_init(&softrst->lock);
     92
     93	softrst->reg_base = base;
     94	softrst->flags = flags;
     95	softrst->num_regs = num_regs;
     96	softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16
     97								      : 32;
     98
     99	softrst->rcdev.owner = THIS_MODULE;
    100	softrst->rcdev.nr_resets =  num_regs * softrst->num_per_reg;
    101	softrst->rcdev.ops = &rockchip_softrst_ops;
    102	softrst->rcdev.of_node = np;
    103	ret = reset_controller_register(&softrst->rcdev);
    104	if (ret) {
    105		pr_err("%s: could not register reset controller, %d\n",
    106		       __func__, ret);
    107		kfree(softrst);
    108	}
    109};
    110EXPORT_SYMBOL_GPL(rockchip_register_softrst);