root/drivers/clk/hisilicon/clkgate-separated.c

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

DEFINITIONS

This source file includes following definitions.
  1. clkgate_separated_enable
  2. clkgate_separated_disable
  3. clkgate_separated_is_enabled
  4. hisi_register_clkgate_sep

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Hisilicon clock separated gate driver
   4  *
   5  * Copyright (c) 2012-2013 Hisilicon Limited.
   6  * Copyright (c) 2012-2013 Linaro Limited.
   7  *
   8  * Author: Haojian Zhuang <haojian.zhuang@linaro.org>
   9  *         Xin Li <li.xin@linaro.org>
  10  */
  11 
  12 #include <linux/kernel.h>
  13 #include <linux/clk-provider.h>
  14 #include <linux/io.h>
  15 #include <linux/slab.h>
  16 
  17 #include "clk.h"
  18 
  19 /* clock separated gate register offset */
  20 #define CLKGATE_SEPERATED_ENABLE                0x0
  21 #define CLKGATE_SEPERATED_DISABLE               0x4
  22 #define CLKGATE_SEPERATED_STATUS                0x8
  23 
  24 struct clkgate_separated {
  25         struct clk_hw   hw;
  26         void __iomem    *enable;        /* enable register */
  27         u8              bit_idx;        /* bits in enable/disable register */
  28         u8              flags;
  29         spinlock_t      *lock;
  30 };
  31 
  32 static int clkgate_separated_enable(struct clk_hw *hw)
  33 {
  34         struct clkgate_separated *sclk;
  35         unsigned long flags = 0;
  36         u32 reg;
  37 
  38         sclk = container_of(hw, struct clkgate_separated, hw);
  39         if (sclk->lock)
  40                 spin_lock_irqsave(sclk->lock, flags);
  41         reg = BIT(sclk->bit_idx);
  42         writel_relaxed(reg, sclk->enable);
  43         readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
  44         if (sclk->lock)
  45                 spin_unlock_irqrestore(sclk->lock, flags);
  46         return 0;
  47 }
  48 
  49 static void clkgate_separated_disable(struct clk_hw *hw)
  50 {
  51         struct clkgate_separated *sclk;
  52         unsigned long flags = 0;
  53         u32 reg;
  54 
  55         sclk = container_of(hw, struct clkgate_separated, hw);
  56         if (sclk->lock)
  57                 spin_lock_irqsave(sclk->lock, flags);
  58         reg = BIT(sclk->bit_idx);
  59         writel_relaxed(reg, sclk->enable + CLKGATE_SEPERATED_DISABLE);
  60         readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
  61         if (sclk->lock)
  62                 spin_unlock_irqrestore(sclk->lock, flags);
  63 }
  64 
  65 static int clkgate_separated_is_enabled(struct clk_hw *hw)
  66 {
  67         struct clkgate_separated *sclk;
  68         u32 reg;
  69 
  70         sclk = container_of(hw, struct clkgate_separated, hw);
  71         reg = readl_relaxed(sclk->enable + CLKGATE_SEPERATED_STATUS);
  72         reg &= BIT(sclk->bit_idx);
  73 
  74         return reg ? 1 : 0;
  75 }
  76 
  77 static const struct clk_ops clkgate_separated_ops = {
  78         .enable         = clkgate_separated_enable,
  79         .disable        = clkgate_separated_disable,
  80         .is_enabled     = clkgate_separated_is_enabled,
  81 };
  82 
  83 struct clk *hisi_register_clkgate_sep(struct device *dev, const char *name,
  84                                       const char *parent_name,
  85                                       unsigned long flags,
  86                                       void __iomem *reg, u8 bit_idx,
  87                                       u8 clk_gate_flags, spinlock_t *lock)
  88 {
  89         struct clkgate_separated *sclk;
  90         struct clk *clk;
  91         struct clk_init_data init;
  92 
  93         sclk = kzalloc(sizeof(*sclk), GFP_KERNEL);
  94         if (!sclk)
  95                 return ERR_PTR(-ENOMEM);
  96 
  97         init.name = name;
  98         init.ops = &clkgate_separated_ops;
  99         init.flags = flags;
 100         init.parent_names = (parent_name ? &parent_name : NULL);
 101         init.num_parents = (parent_name ? 1 : 0);
 102 
 103         sclk->enable = reg + CLKGATE_SEPERATED_ENABLE;
 104         sclk->bit_idx = bit_idx;
 105         sclk->flags = clk_gate_flags;
 106         sclk->hw.init = &init;
 107         sclk->lock = lock;
 108 
 109         clk = clk_register(dev, &sclk->hw);
 110         if (IS_ERR(clk))
 111                 kfree(sclk);
 112         return clk;
 113 }

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