mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-22 20:58:22 +00:00

Use clock-names property which is accessible via parent clock OF node to look up the parent clock by name instead of depending on unreliable global clock name to perform look up. Signed-off-by: Marek Vasut <marex@denx.de>
86 lines
2 KiB
C
86 lines
2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2019 DENX Software Engineering
|
|
* Lukasz Majewski, DENX Software Engineering, lukma@denx.de
|
|
*
|
|
* Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
|
|
*/
|
|
|
|
#define LOG_CATEGORY UCLASS_CLK
|
|
|
|
#include <clk.h>
|
|
#include <clk-uclass.h>
|
|
#include <div64.h>
|
|
#include <log.h>
|
|
#include <malloc.h>
|
|
#include <dm/device.h>
|
|
#include <dm/devres.h>
|
|
#include <linux/clk-provider.h>
|
|
#include <linux/err.h>
|
|
|
|
#include "clk.h"
|
|
|
|
#define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor"
|
|
|
|
static ulong clk_factor_recalc_rate(struct clk *clk)
|
|
{
|
|
struct clk_fixed_factor *fix = to_clk_fixed_factor(clk);
|
|
unsigned long parent_rate = clk_get_parent_rate(clk);
|
|
unsigned long long int rate;
|
|
|
|
rate = (unsigned long long int)parent_rate * fix->mult;
|
|
do_div(rate, fix->div);
|
|
return (ulong)rate;
|
|
}
|
|
|
|
const struct clk_ops ccf_clk_fixed_factor_ops = {
|
|
.get_rate = clk_factor_recalc_rate,
|
|
};
|
|
|
|
struct clk *clk_hw_register_fixed_factor(struct udevice *dev,
|
|
const char *name, const char *parent_name, unsigned long flags,
|
|
unsigned int mult, unsigned int div)
|
|
{
|
|
struct clk_fixed_factor *fix;
|
|
struct clk *clk;
|
|
int ret;
|
|
|
|
fix = kzalloc(sizeof(*fix), GFP_KERNEL);
|
|
if (!fix)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
/* struct clk_fixed_factor assignments */
|
|
fix->mult = mult;
|
|
fix->div = div;
|
|
clk = &fix->clk;
|
|
clk->flags = flags;
|
|
|
|
ret = clk_register(clk, UBOOT_DM_CLK_IMX_FIXED_FACTOR, name,
|
|
clk_resolve_parent_clk(dev, parent_name));
|
|
if (ret) {
|
|
kfree(fix);
|
|
return ERR_PTR(ret);
|
|
}
|
|
|
|
return clk;
|
|
}
|
|
|
|
struct clk *clk_register_fixed_factor(struct udevice *dev, const char *name,
|
|
const char *parent_name, unsigned long flags,
|
|
unsigned int mult, unsigned int div)
|
|
{
|
|
struct clk *clk;
|
|
|
|
clk = clk_hw_register_fixed_factor(dev, name, parent_name, flags, mult,
|
|
div);
|
|
if (IS_ERR(clk))
|
|
return ERR_CAST(clk);
|
|
return clk;
|
|
}
|
|
|
|
U_BOOT_DRIVER(imx_clk_fixed_factor) = {
|
|
.name = UBOOT_DM_CLK_IMX_FIXED_FACTOR,
|
|
.id = UCLASS_CLK,
|
|
.ops = &ccf_clk_fixed_factor_ops,
|
|
.flags = DM_FLAG_PRE_RELOC,
|
|
};
|