root/drivers/clk/rockchip/softrst.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rockchip_softrst_assert
  2. rockchip_softrst_deassert
  3. rockchip_register_softrst

   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 
  13 struct 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 
  22 static 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 
  49 static 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 
  75 static const struct reset_control_ops rockchip_softrst_ops = {
  76         .assert         = rockchip_softrst_assert,
  77         .deassert       = rockchip_softrst_deassert,
  78 };
  79 
  80 void __init 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 };

/* [<][>][^][v][top][bottom][index][help] */