77 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * drivers/clk/at91/clk-slow.c4 *5 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>6 */7 8#include <linux/clk-provider.h>9#include <linux/clkdev.h>10#include <linux/clk/at91_pmc.h>11#include <linux/of.h>12#include <linux/mfd/syscon.h>13#include <linux/regmap.h>14 15#include "pmc.h"16 17struct clk_sam9260_slow {18 struct clk_hw hw;19 struct regmap *regmap;20};21 22#define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw)23 24static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw)25{26 struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw);27 unsigned int status;28 29 regmap_read(slowck->regmap, AT91_PMC_SR, &status);30 31 return status & AT91_PMC_OSCSEL ? 1 : 0;32}33 34static const struct clk_ops sam9260_slow_ops = {35 .get_parent = clk_sam9260_slow_get_parent,36};37 38struct clk_hw * __init39at91_clk_register_sam9260_slow(struct regmap *regmap,40 const char *name,41 const char **parent_names,42 int num_parents)43{44 struct clk_sam9260_slow *slowck;45 struct clk_hw *hw;46 struct clk_init_data init;47 int ret;48 49 if (!name)50 return ERR_PTR(-EINVAL);51 52 if (!parent_names || !num_parents)53 return ERR_PTR(-EINVAL);54 55 slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);56 if (!slowck)57 return ERR_PTR(-ENOMEM);58 59 init.name = name;60 init.ops = &sam9260_slow_ops;61 init.parent_names = parent_names;62 init.num_parents = num_parents;63 init.flags = 0;64 65 slowck->hw.init = &init;66 slowck->regmap = regmap;67 68 hw = &slowck->hw;69 ret = clk_hw_register(NULL, &slowck->hw);70 if (ret) {71 kfree(slowck);72 hw = ERR_PTR(ret);73 }74 75 return hw;76}77