root/drivers/clk/imx/clk-gate-exclusive.c

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

DEFINITIONS

This source file includes following definitions.
  1. clk_gate_exclusive_enable
  2. clk_gate_exclusive_disable
  3. clk_gate_exclusive_is_enabled
  4. imx_clk_hw_gate_exclusive

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright 2014 Freescale Semiconductor, Inc.
   4  */
   5 
   6 #include <linux/clk-provider.h>
   7 #include <linux/err.h>
   8 #include <linux/io.h>
   9 #include <linux/slab.h>
  10 #include "clk.h"
  11 
  12 /**
  13  * struct clk_gate_exclusive - i.MX specific gate clock which is mutually
  14  * exclusive with other gate clocks
  15  *
  16  * @gate: the parent class
  17  * @exclusive_mask: mask of gate bits which are mutually exclusive to this
  18  *      gate clock
  19  *
  20  * The imx exclusive gate clock is a subclass of basic clk_gate
  21  * with an addtional mask to indicate which other gate bits in the same
  22  * register is mutually exclusive to this gate clock.
  23  */
  24 struct clk_gate_exclusive {
  25         struct clk_gate gate;
  26         u32 exclusive_mask;
  27 };
  28 
  29 static int clk_gate_exclusive_enable(struct clk_hw *hw)
  30 {
  31         struct clk_gate *gate = to_clk_gate(hw);
  32         struct clk_gate_exclusive *exgate = container_of(gate,
  33                                         struct clk_gate_exclusive, gate);
  34         u32 val = readl(gate->reg);
  35 
  36         if (val & exgate->exclusive_mask)
  37                 return -EBUSY;
  38 
  39         return clk_gate_ops.enable(hw);
  40 }
  41 
  42 static void clk_gate_exclusive_disable(struct clk_hw *hw)
  43 {
  44         clk_gate_ops.disable(hw);
  45 }
  46 
  47 static int clk_gate_exclusive_is_enabled(struct clk_hw *hw)
  48 {
  49         return clk_gate_ops.is_enabled(hw);
  50 }
  51 
  52 static const struct clk_ops clk_gate_exclusive_ops = {
  53         .enable = clk_gate_exclusive_enable,
  54         .disable = clk_gate_exclusive_disable,
  55         .is_enabled = clk_gate_exclusive_is_enabled,
  56 };
  57 
  58 struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent,
  59          void __iomem *reg, u8 shift, u32 exclusive_mask)
  60 {
  61         struct clk_gate_exclusive *exgate;
  62         struct clk_gate *gate;
  63         struct clk_hw *hw;
  64         struct clk_init_data init;
  65         int ret;
  66 
  67         if (exclusive_mask == 0)
  68                 return ERR_PTR(-EINVAL);
  69 
  70         exgate = kzalloc(sizeof(*exgate), GFP_KERNEL);
  71         if (!exgate)
  72                 return ERR_PTR(-ENOMEM);
  73         gate = &exgate->gate;
  74 
  75         init.name = name;
  76         init.ops = &clk_gate_exclusive_ops;
  77         init.flags = CLK_SET_RATE_PARENT;
  78         init.parent_names = parent ? &parent : NULL;
  79         init.num_parents = parent ? 1 : 0;
  80 
  81         gate->reg = reg;
  82         gate->bit_idx = shift;
  83         gate->lock = &imx_ccm_lock;
  84         gate->hw.init = &init;
  85         exgate->exclusive_mask = exclusive_mask;
  86 
  87         hw = &gate->hw;
  88 
  89         ret = clk_hw_register(NULL, hw);
  90         if (ret) {
  91                 kfree(gate);
  92                 return ERR_PTR(ret);
  93         }
  94 
  95         return hw;
  96 }

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