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

clk-uniphier-mux.c (2024B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (C) 2016 Socionext Inc.
      4 *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
      5 */
      6
      7#include <linux/clk-provider.h>
      8#include <linux/device.h>
      9#include <linux/regmap.h>
     10
     11#include "clk-uniphier.h"
     12
     13struct uniphier_clk_mux {
     14	struct clk_hw hw;
     15	struct regmap *regmap;
     16	unsigned int reg;
     17	const unsigned int *masks;
     18	const unsigned int *vals;
     19};
     20
     21#define to_uniphier_clk_mux(_hw) container_of(_hw, struct uniphier_clk_mux, hw)
     22
     23static int uniphier_clk_mux_set_parent(struct clk_hw *hw, u8 index)
     24{
     25	struct uniphier_clk_mux *mux = to_uniphier_clk_mux(hw);
     26
     27	return regmap_write_bits(mux->regmap, mux->reg, mux->masks[index],
     28				 mux->vals[index]);
     29}
     30
     31static u8 uniphier_clk_mux_get_parent(struct clk_hw *hw)
     32{
     33	struct uniphier_clk_mux *mux = to_uniphier_clk_mux(hw);
     34	unsigned int num_parents = clk_hw_get_num_parents(hw);
     35	int ret;
     36	unsigned int val;
     37	unsigned int i;
     38
     39	ret = regmap_read(mux->regmap, mux->reg, &val);
     40	if (ret)
     41		return ret;
     42
     43	for (i = 0; i < num_parents; i++)
     44		if ((mux->masks[i] & val) == mux->vals[i])
     45			return i;
     46
     47	return -EINVAL;
     48}
     49
     50static const struct clk_ops uniphier_clk_mux_ops = {
     51	.determine_rate = __clk_mux_determine_rate,
     52	.set_parent = uniphier_clk_mux_set_parent,
     53	.get_parent = uniphier_clk_mux_get_parent,
     54};
     55
     56struct clk_hw *uniphier_clk_register_mux(struct device *dev,
     57					 struct regmap *regmap,
     58					 const char *name,
     59				const struct uniphier_clk_mux_data *data)
     60{
     61	struct uniphier_clk_mux *mux;
     62	struct clk_init_data init;
     63	int ret;
     64
     65	mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
     66	if (!mux)
     67		return ERR_PTR(-ENOMEM);
     68
     69	init.name = name;
     70	init.ops = &uniphier_clk_mux_ops;
     71	init.flags = CLK_SET_RATE_PARENT;
     72	init.parent_names = data->parent_names;
     73	init.num_parents = data->num_parents;
     74
     75	mux->regmap = regmap;
     76	mux->reg = data->reg;
     77	mux->masks = data->masks;
     78	mux->vals = data->vals;
     79	mux->hw.init = &init;
     80
     81	ret = devm_clk_hw_register(dev, &mux->hw);
     82	if (ret)
     83		return ERR_PTR(ret);
     84
     85	return &mux->hw;
     86}