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-hi655x.c (2858B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Clock driver for Hi655x
      4 *
      5 * Copyright (c) 2017, Linaro Ltd.
      6 *
      7 * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
      8 */
      9#include <linux/clk-provider.h>
     10#include <linux/module.h>
     11#include <linux/platform_device.h>
     12#include <linux/regmap.h>
     13#include <linux/slab.h>
     14#include <linux/mfd/core.h>
     15#include <linux/mfd/hi655x-pmic.h>
     16
     17#define HI655X_CLK_BASE	HI655X_BUS_ADDR(0x1c)
     18#define HI655X_CLK_SET	BIT(6)
     19
     20struct hi655x_clk {
     21	struct hi655x_pmic *hi655x;
     22	struct clk_hw       clk_hw;
     23};
     24
     25static unsigned long hi655x_clk_recalc_rate(struct clk_hw *hw,
     26					    unsigned long parent_rate)
     27{
     28	return 32768;
     29}
     30
     31static int hi655x_clk_enable(struct clk_hw *hw, bool enable)
     32{
     33	struct hi655x_clk *hi655x_clk =
     34		container_of(hw, struct hi655x_clk, clk_hw);
     35
     36	struct hi655x_pmic *hi655x = hi655x_clk->hi655x;
     37
     38	return regmap_update_bits(hi655x->regmap, HI655X_CLK_BASE,
     39				  HI655X_CLK_SET, enable ? HI655X_CLK_SET : 0);
     40}
     41
     42static int hi655x_clk_prepare(struct clk_hw *hw)
     43{
     44	return hi655x_clk_enable(hw, true);
     45}
     46
     47static void hi655x_clk_unprepare(struct clk_hw *hw)
     48{
     49	hi655x_clk_enable(hw, false);
     50}
     51
     52static int hi655x_clk_is_prepared(struct clk_hw *hw)
     53{
     54	struct hi655x_clk *hi655x_clk =
     55		container_of(hw, struct hi655x_clk, clk_hw);
     56	struct hi655x_pmic *hi655x = hi655x_clk->hi655x;
     57	int ret;
     58	uint32_t val;
     59
     60	ret = regmap_read(hi655x->regmap, HI655X_CLK_BASE, &val);
     61	if (ret < 0)
     62		return ret;
     63
     64	return val & HI655X_CLK_BASE;
     65}
     66
     67static const struct clk_ops hi655x_clk_ops = {
     68	.prepare     = hi655x_clk_prepare,
     69	.unprepare   = hi655x_clk_unprepare,
     70	.is_prepared = hi655x_clk_is_prepared,
     71	.recalc_rate = hi655x_clk_recalc_rate,
     72};
     73
     74static int hi655x_clk_probe(struct platform_device *pdev)
     75{
     76	struct device *parent = pdev->dev.parent;
     77	struct hi655x_pmic *hi655x = dev_get_drvdata(parent);
     78	struct hi655x_clk *hi655x_clk;
     79	const char *clk_name = "hi655x-clk";
     80	struct clk_init_data init = {
     81		.name = clk_name,
     82		.ops = &hi655x_clk_ops
     83	};
     84	int ret;
     85
     86	hi655x_clk = devm_kzalloc(&pdev->dev, sizeof(*hi655x_clk), GFP_KERNEL);
     87	if (!hi655x_clk)
     88		return -ENOMEM;
     89
     90	of_property_read_string_index(parent->of_node, "clock-output-names",
     91				      0, &clk_name);
     92
     93	hi655x_clk->clk_hw.init	= &init;
     94	hi655x_clk->hi655x	= hi655x;
     95
     96	platform_set_drvdata(pdev, hi655x_clk);
     97
     98	ret = devm_clk_hw_register(&pdev->dev, &hi655x_clk->clk_hw);
     99	if (ret)
    100		return ret;
    101
    102	return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_simple_get,
    103					   &hi655x_clk->clk_hw);
    104}
    105
    106static struct platform_driver hi655x_clk_driver = {
    107	.probe =  hi655x_clk_probe,
    108	.driver		= {
    109		.name	= "hi655x-clk",
    110	},
    111};
    112
    113module_platform_driver(hi655x_clk_driver);
    114
    115MODULE_DESCRIPTION("Clk driver for the hi655x series PMICs");
    116MODULE_AUTHOR("Daniel Lezcano <daniel.lezcano@linaro.org>");
    117MODULE_LICENSE("GPL");
    118MODULE_ALIAS("platform:hi655x-clk");