mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
141 lines
3.3 KiB
C
141 lines
3.3 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright (c) 2016 Rockchip Electronics Co. Ltd.
|
|
* Author: Lin Huang <hl@rock-chips.com>
|
|
*/
|
|
|
|
#include <linux/arm-smccc.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/clk-provider.h>
|
|
#include <linux/io.h>
|
|
#include <linux/slab.h>
|
|
#include <soc/rockchip/rockchip_sip.h>
|
|
#include "clk.h"
|
|
|
|
struct rockchip_ddrclk {
|
|
struct clk_hw hw;
|
|
void __iomem *reg_base;
|
|
int mux_offset;
|
|
int mux_shift;
|
|
int mux_width;
|
|
int div_shift;
|
|
int div_width;
|
|
int ddr_flag;
|
|
spinlock_t *lock;
|
|
};
|
|
|
|
#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk, hw)
|
|
|
|
static int rockchip_ddrclk_sip_set_rate(struct clk_hw *hw, unsigned long drate,
|
|
unsigned long prate)
|
|
{
|
|
struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
|
|
unsigned long flags;
|
|
struct arm_smccc_res res;
|
|
|
|
spin_lock_irqsave(ddrclk->lock, flags);
|
|
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, drate, 0,
|
|
ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE,
|
|
0, 0, 0, 0, &res);
|
|
spin_unlock_irqrestore(ddrclk->lock, flags);
|
|
|
|
return res.a0;
|
|
}
|
|
|
|
static unsigned long
|
|
rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw,
|
|
unsigned long parent_rate)
|
|
{
|
|
struct arm_smccc_res res;
|
|
|
|
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
|
|
ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE,
|
|
0, 0, 0, 0, &res);
|
|
|
|
return res.a0;
|
|
}
|
|
|
|
static int rockchip_ddrclk_sip_determine_rate(struct clk_hw *hw,
|
|
struct clk_rate_request *req)
|
|
{
|
|
struct arm_smccc_res res;
|
|
|
|
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, req->rate, 0,
|
|
ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE,
|
|
0, 0, 0, 0, &res);
|
|
|
|
req->rate = res.a0;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw)
|
|
{
|
|
struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
|
|
u32 val;
|
|
|
|
val = readl(ddrclk->reg_base +
|
|
ddrclk->mux_offset) >> ddrclk->mux_shift;
|
|
val &= GENMASK(ddrclk->mux_width - 1, 0);
|
|
|
|
return val;
|
|
}
|
|
|
|
static const struct clk_ops rockchip_ddrclk_sip_ops = {
|
|
.recalc_rate = rockchip_ddrclk_sip_recalc_rate,
|
|
.set_rate = rockchip_ddrclk_sip_set_rate,
|
|
.determine_rate = rockchip_ddrclk_sip_determine_rate,
|
|
.get_parent = rockchip_ddrclk_get_parent,
|
|
};
|
|
|
|
struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
|
|
const char *const *parent_names,
|
|
u8 num_parents, int mux_offset,
|
|
int mux_shift, int mux_width,
|
|
int div_shift, int div_width,
|
|
int ddr_flag, void __iomem *reg_base,
|
|
spinlock_t *lock)
|
|
{
|
|
struct rockchip_ddrclk *ddrclk;
|
|
struct clk_init_data init;
|
|
struct clk *clk;
|
|
|
|
ddrclk = kzalloc_obj(*ddrclk);
|
|
if (!ddrclk)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
init.name = name;
|
|
init.parent_names = parent_names;
|
|
init.num_parents = num_parents;
|
|
|
|
init.flags = flags;
|
|
init.flags |= CLK_SET_RATE_NO_REPARENT;
|
|
|
|
switch (ddr_flag) {
|
|
case ROCKCHIP_DDRCLK_SIP:
|
|
init.ops = &rockchip_ddrclk_sip_ops;
|
|
break;
|
|
default:
|
|
pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag);
|
|
kfree(ddrclk);
|
|
return ERR_PTR(-EINVAL);
|
|
}
|
|
|
|
ddrclk->reg_base = reg_base;
|
|
ddrclk->lock = lock;
|
|
ddrclk->hw.init = &init;
|
|
ddrclk->mux_offset = mux_offset;
|
|
ddrclk->mux_shift = mux_shift;
|
|
ddrclk->mux_width = mux_width;
|
|
ddrclk->div_shift = div_shift;
|
|
ddrclk->div_width = div_width;
|
|
ddrclk->ddr_flag = ddr_flag;
|
|
|
|
clk = clk_register(NULL, &ddrclk->hw);
|
|
if (IS_ERR(clk))
|
|
kfree(ddrclk);
|
|
|
|
return clk;
|
|
}
|
|
EXPORT_SYMBOL_GPL(rockchip_clk_register_ddrclk);
|