313 lines
7.2 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018 MediaTek Inc.
* Author: Owen Chen <owen.chen@mediatek.com>
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/compiler_types.h>
#include <linux/container_of.h>
#include <linux/err.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include "clk-mux.h"
struct mtk_clk_mux {
struct clk_hw hw;
struct regmap *regmap;
const struct mtk_mux *data;
spinlock_t *lock;
bool reparent;
};
static inline struct mtk_clk_mux *to_mtk_clk_mux(struct clk_hw *hw)
{
return container_of(hw, struct mtk_clk_mux, hw);
}
static int mtk_clk_mux_enable_setclr(struct clk_hw *hw)
{
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
unsigned long flags = 0;
if (mux->lock)
spin_lock_irqsave(mux->lock, flags);
else
__acquire(mux->lock);
regmap_write(mux->regmap, mux->data->clr_ofs,
BIT(mux->data->gate_shift));
/*
* If the parent has been changed when the clock was disabled, it will
* not be effective yet. Set the update bit to ensure the mux gets
* updated.
*/
if (mux->reparent && mux->data->upd_shift >= 0) {
regmap_write(mux->regmap, mux->data->upd_ofs,
BIT(mux->data->upd_shift));
mux->reparent = false;
}
if (mux->lock)
spin_unlock_irqrestore(mux->lock, flags);
else
__release(mux->lock);
return 0;
}
static void mtk_clk_mux_disable_setclr(struct clk_hw *hw)
{
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
regmap_write(mux->regmap, mux->data->set_ofs,
BIT(mux->data->gate_shift));
}
static int mtk_clk_mux_is_enabled(struct clk_hw *hw)
{
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
u32 val;
regmap_read(mux->regmap, mux->data->mux_ofs, &val);
return (val & BIT(mux->data->gate_shift)) == 0;
}
static u8 mtk_clk_mux_get_parent(struct clk_hw *hw)
{
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
u32 mask = GENMASK(mux->data->mux_width - 1, 0);
u32 val;
regmap_read(mux->regmap, mux->data->mux_ofs, &val);
val = (val >> mux->data->mux_shift) & mask;
return val;
}
static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index)
{
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
u32 mask = GENMASK(mux->data->mux_width - 1, 0);
u32 val, orig;
unsigned long flags = 0;
if (mux->lock)
spin_lock_irqsave(mux->lock, flags);
else
__acquire(mux->lock);
regmap_read(mux->regmap, mux->data->mux_ofs, &orig);
val = (orig & ~(mask << mux->data->mux_shift))
| (index << mux->data->mux_shift);
if (val != orig) {
regmap_write(mux->regmap, mux->data->clr_ofs,
mask << mux->data->mux_shift);
regmap_write(mux->regmap, mux->data->set_ofs,
index << mux->data->mux_shift);
if (mux->data->upd_shift >= 0) {
regmap_write(mux->regmap, mux->data->upd_ofs,
BIT(mux->data->upd_shift));
mux->reparent = true;
}
}
if (mux->lock)
spin_unlock_irqrestore(mux->lock, flags);
else
__release(mux->lock);
return 0;
}
clk: mediatek: clk-mux: Add .determine_rate() callback Since commit 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent"), the clk_rate_request is .. as the title says, not forwarded anymore to the parent: this produces an issue with the MediaTek clock MUX driver during GPU DVFS on MT8195, but not on MT8192 or others. This is because, differently from others, like MT8192 where all of the clocks in the MFG parents tree are of mtk_mux type, but in the parent tree of MT8195's MFG clock, we have one mtk_mux clock and one (clk framework generic) mux clock, like so: names: mfg_bg3d -> mfg_ck_fast_ref -> top_mfg_core_tmp (or) mfgpll types: mtk_gate -> mux -> mtk_mux (or) mtk_pll To solve this issue and also keep the GPU DVFS clocks code working as expected, wire up a .determine_rate() callback for the mtk_mux ops; for that, the standard clk_mux_determine_rate_flags() was used as it was possible to. This commit was successfully tested on MT6795 Xperia M5, MT8173 Elm, MT8192 Spherion and MT8195 Tomato; no regressions were seen. For the sake of some more documentation about this issue here's the trace of it: [ 12.211587] ------------[ cut here ]------------ [ 12.211589] WARNING: CPU: 6 PID: 78 at drivers/clk/clk.c:1462 clk_core_init_rate_req+0x84/0x90 [ 12.211593] Modules linked in: stp crct10dif_ce mtk_adsp_common llc rfkill snd_sof_xtensa_dsp panfrost(+) sbs_battery cros_ec_lid_angle cros_ec_sensors snd_sof_of cros_ec_sensors_core hid_multitouch cros_usbpd_logger snd_sof gpu_sched snd_sof_utils fuse ipv6 [ 12.211614] CPU: 6 PID: 78 Comm: kworker/u16:2 Tainted: G W 6.0.0-next-20221011+ #58 [ 12.211616] Hardware name: Acer Tomato (rev2) board (DT) [ 12.211617] Workqueue: devfreq_wq devfreq_monitor [ 12.211620] pstate: 40400009 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 12.211622] pc : clk_core_init_rate_req+0x84/0x90 [ 12.211625] lr : clk_core_forward_rate_req+0xa4/0xe4 [ 12.211627] sp : ffff80000893b8e0 [ 12.211628] x29: ffff80000893b8e0 x28: ffffdddf92f9b000 x27: ffff46a2c0e8bc05 [ 12.211632] x26: ffff46a2c1041200 x25: 0000000000000000 x24: 00000000173eed80 [ 12.211636] x23: ffff80000893b9c0 x22: ffff80000893b940 x21: 0000000000000000 [ 12.211641] x20: ffff46a2c1039f00 x19: ffff46a2c1039f00 x18: 0000000000000000 [ 12.211645] x17: 0000000000000038 x16: 000000000000d904 x15: 0000000000000003 [ 12.211649] x14: ffffdddf9357ce48 x13: ffffdddf935e71c8 x12: 000000000004803c [ 12.211653] x11: 00000000a867d7ad x10: 00000000a867d7ad x9 : ffffdddf90c28df4 [ 12.211657] x8 : ffffdddf9357a980 x7 : 0000000000000000 x6 : 0000000000000004 [ 12.211661] x5 : ffffffffffffffc8 x4 : 00000000173eed80 x3 : ffff80000893b940 [ 12.211665] x2 : 00000000173eed80 x1 : ffff80000893b940 x0 : 0000000000000000 [ 12.211669] Call trace: [ 12.211670] clk_core_init_rate_req+0x84/0x90 [ 12.211673] clk_core_round_rate_nolock+0xe8/0x10c [ 12.211675] clk_mux_determine_rate_flags+0x174/0x1f0 [ 12.211677] clk_mux_determine_rate+0x1c/0x30 [ 12.211680] clk_core_determine_round_nolock+0x74/0x130 [ 12.211682] clk_core_round_rate_nolock+0x58/0x10c [ 12.211684] clk_core_round_rate_nolock+0xf4/0x10c [ 12.211686] clk_core_set_rate_nolock+0x194/0x2ac [ 12.211688] clk_set_rate+0x40/0x94 [ 12.211691] _opp_config_clk_single+0x38/0xa0 [ 12.211693] _set_opp+0x1b0/0x500 [ 12.211695] dev_pm_opp_set_rate+0x120/0x290 [ 12.211697] panfrost_devfreq_target+0x3c/0x50 [panfrost] [ 12.211705] devfreq_set_target+0x8c/0x2d0 [ 12.211707] devfreq_update_target+0xcc/0xf4 [ 12.211708] devfreq_monitor+0x40/0x1d0 [ 12.211710] process_one_work+0x294/0x664 [ 12.211712] worker_thread+0x7c/0x45c [ 12.211713] kthread+0x104/0x110 [ 12.211716] ret_from_fork+0x10/0x20 [ 12.211718] irq event stamp: 7102 [ 12.211719] hardirqs last enabled at (7101): [<ffffdddf904ea5a0>] finish_task_switch.isra.0+0xec/0x2f0 [ 12.211723] hardirqs last disabled at (7102): [<ffffdddf91794b74>] el1_dbg+0x24/0x90 [ 12.211726] softirqs last enabled at (6716): [<ffffdddf90410be4>] __do_softirq+0x414/0x588 [ 12.211728] softirqs last disabled at (6507): [<ffffdddf904171d8>] ____do_softirq+0x18/0x24 [ 12.211730] ---[ end trace 0000000000000000 ]--- Fixes: 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent") Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://lore.kernel.org/r/20221011135548.318323-1-angelogioacchino.delregno@collabora.com Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-10-11 15:55:48 +02:00
static int mtk_clk_mux_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct mtk_clk_mux *mux = to_mtk_clk_mux(hw);
return clk_mux_determine_rate_flags(hw, req, mux->data->flags);
}
const struct clk_ops mtk_mux_clr_set_upd_ops = {
.get_parent = mtk_clk_mux_get_parent,
.set_parent = mtk_clk_mux_set_parent_setclr_lock,
clk: mediatek: clk-mux: Add .determine_rate() callback Since commit 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent"), the clk_rate_request is .. as the title says, not forwarded anymore to the parent: this produces an issue with the MediaTek clock MUX driver during GPU DVFS on MT8195, but not on MT8192 or others. This is because, differently from others, like MT8192 where all of the clocks in the MFG parents tree are of mtk_mux type, but in the parent tree of MT8195's MFG clock, we have one mtk_mux clock and one (clk framework generic) mux clock, like so: names: mfg_bg3d -> mfg_ck_fast_ref -> top_mfg_core_tmp (or) mfgpll types: mtk_gate -> mux -> mtk_mux (or) mtk_pll To solve this issue and also keep the GPU DVFS clocks code working as expected, wire up a .determine_rate() callback for the mtk_mux ops; for that, the standard clk_mux_determine_rate_flags() was used as it was possible to. This commit was successfully tested on MT6795 Xperia M5, MT8173 Elm, MT8192 Spherion and MT8195 Tomato; no regressions were seen. For the sake of some more documentation about this issue here's the trace of it: [ 12.211587] ------------[ cut here ]------------ [ 12.211589] WARNING: CPU: 6 PID: 78 at drivers/clk/clk.c:1462 clk_core_init_rate_req+0x84/0x90 [ 12.211593] Modules linked in: stp crct10dif_ce mtk_adsp_common llc rfkill snd_sof_xtensa_dsp panfrost(+) sbs_battery cros_ec_lid_angle cros_ec_sensors snd_sof_of cros_ec_sensors_core hid_multitouch cros_usbpd_logger snd_sof gpu_sched snd_sof_utils fuse ipv6 [ 12.211614] CPU: 6 PID: 78 Comm: kworker/u16:2 Tainted: G W 6.0.0-next-20221011+ #58 [ 12.211616] Hardware name: Acer Tomato (rev2) board (DT) [ 12.211617] Workqueue: devfreq_wq devfreq_monitor [ 12.211620] pstate: 40400009 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 12.211622] pc : clk_core_init_rate_req+0x84/0x90 [ 12.211625] lr : clk_core_forward_rate_req+0xa4/0xe4 [ 12.211627] sp : ffff80000893b8e0 [ 12.211628] x29: ffff80000893b8e0 x28: ffffdddf92f9b000 x27: ffff46a2c0e8bc05 [ 12.211632] x26: ffff46a2c1041200 x25: 0000000000000000 x24: 00000000173eed80 [ 12.211636] x23: ffff80000893b9c0 x22: ffff80000893b940 x21: 0000000000000000 [ 12.211641] x20: ffff46a2c1039f00 x19: ffff46a2c1039f00 x18: 0000000000000000 [ 12.211645] x17: 0000000000000038 x16: 000000000000d904 x15: 0000000000000003 [ 12.211649] x14: ffffdddf9357ce48 x13: ffffdddf935e71c8 x12: 000000000004803c [ 12.211653] x11: 00000000a867d7ad x10: 00000000a867d7ad x9 : ffffdddf90c28df4 [ 12.211657] x8 : ffffdddf9357a980 x7 : 0000000000000000 x6 : 0000000000000004 [ 12.211661] x5 : ffffffffffffffc8 x4 : 00000000173eed80 x3 : ffff80000893b940 [ 12.211665] x2 : 00000000173eed80 x1 : ffff80000893b940 x0 : 0000000000000000 [ 12.211669] Call trace: [ 12.211670] clk_core_init_rate_req+0x84/0x90 [ 12.211673] clk_core_round_rate_nolock+0xe8/0x10c [ 12.211675] clk_mux_determine_rate_flags+0x174/0x1f0 [ 12.211677] clk_mux_determine_rate+0x1c/0x30 [ 12.211680] clk_core_determine_round_nolock+0x74/0x130 [ 12.211682] clk_core_round_rate_nolock+0x58/0x10c [ 12.211684] clk_core_round_rate_nolock+0xf4/0x10c [ 12.211686] clk_core_set_rate_nolock+0x194/0x2ac [ 12.211688] clk_set_rate+0x40/0x94 [ 12.211691] _opp_config_clk_single+0x38/0xa0 [ 12.211693] _set_opp+0x1b0/0x500 [ 12.211695] dev_pm_opp_set_rate+0x120/0x290 [ 12.211697] panfrost_devfreq_target+0x3c/0x50 [panfrost] [ 12.211705] devfreq_set_target+0x8c/0x2d0 [ 12.211707] devfreq_update_target+0xcc/0xf4 [ 12.211708] devfreq_monitor+0x40/0x1d0 [ 12.211710] process_one_work+0x294/0x664 [ 12.211712] worker_thread+0x7c/0x45c [ 12.211713] kthread+0x104/0x110 [ 12.211716] ret_from_fork+0x10/0x20 [ 12.211718] irq event stamp: 7102 [ 12.211719] hardirqs last enabled at (7101): [<ffffdddf904ea5a0>] finish_task_switch.isra.0+0xec/0x2f0 [ 12.211723] hardirqs last disabled at (7102): [<ffffdddf91794b74>] el1_dbg+0x24/0x90 [ 12.211726] softirqs last enabled at (6716): [<ffffdddf90410be4>] __do_softirq+0x414/0x588 [ 12.211728] softirqs last disabled at (6507): [<ffffdddf904171d8>] ____do_softirq+0x18/0x24 [ 12.211730] ---[ end trace 0000000000000000 ]--- Fixes: 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent") Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://lore.kernel.org/r/20221011135548.318323-1-angelogioacchino.delregno@collabora.com Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-10-11 15:55:48 +02:00
.determine_rate = mtk_clk_mux_determine_rate,
};
EXPORT_SYMBOL_GPL(mtk_mux_clr_set_upd_ops);
const struct clk_ops mtk_mux_gate_clr_set_upd_ops = {
.enable = mtk_clk_mux_enable_setclr,
.disable = mtk_clk_mux_disable_setclr,
.is_enabled = mtk_clk_mux_is_enabled,
.get_parent = mtk_clk_mux_get_parent,
.set_parent = mtk_clk_mux_set_parent_setclr_lock,
clk: mediatek: clk-mux: Add .determine_rate() callback Since commit 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent"), the clk_rate_request is .. as the title says, not forwarded anymore to the parent: this produces an issue with the MediaTek clock MUX driver during GPU DVFS on MT8195, but not on MT8192 or others. This is because, differently from others, like MT8192 where all of the clocks in the MFG parents tree are of mtk_mux type, but in the parent tree of MT8195's MFG clock, we have one mtk_mux clock and one (clk framework generic) mux clock, like so: names: mfg_bg3d -> mfg_ck_fast_ref -> top_mfg_core_tmp (or) mfgpll types: mtk_gate -> mux -> mtk_mux (or) mtk_pll To solve this issue and also keep the GPU DVFS clocks code working as expected, wire up a .determine_rate() callback for the mtk_mux ops; for that, the standard clk_mux_determine_rate_flags() was used as it was possible to. This commit was successfully tested on MT6795 Xperia M5, MT8173 Elm, MT8192 Spherion and MT8195 Tomato; no regressions were seen. For the sake of some more documentation about this issue here's the trace of it: [ 12.211587] ------------[ cut here ]------------ [ 12.211589] WARNING: CPU: 6 PID: 78 at drivers/clk/clk.c:1462 clk_core_init_rate_req+0x84/0x90 [ 12.211593] Modules linked in: stp crct10dif_ce mtk_adsp_common llc rfkill snd_sof_xtensa_dsp panfrost(+) sbs_battery cros_ec_lid_angle cros_ec_sensors snd_sof_of cros_ec_sensors_core hid_multitouch cros_usbpd_logger snd_sof gpu_sched snd_sof_utils fuse ipv6 [ 12.211614] CPU: 6 PID: 78 Comm: kworker/u16:2 Tainted: G W 6.0.0-next-20221011+ #58 [ 12.211616] Hardware name: Acer Tomato (rev2) board (DT) [ 12.211617] Workqueue: devfreq_wq devfreq_monitor [ 12.211620] pstate: 40400009 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 12.211622] pc : clk_core_init_rate_req+0x84/0x90 [ 12.211625] lr : clk_core_forward_rate_req+0xa4/0xe4 [ 12.211627] sp : ffff80000893b8e0 [ 12.211628] x29: ffff80000893b8e0 x28: ffffdddf92f9b000 x27: ffff46a2c0e8bc05 [ 12.211632] x26: ffff46a2c1041200 x25: 0000000000000000 x24: 00000000173eed80 [ 12.211636] x23: ffff80000893b9c0 x22: ffff80000893b940 x21: 0000000000000000 [ 12.211641] x20: ffff46a2c1039f00 x19: ffff46a2c1039f00 x18: 0000000000000000 [ 12.211645] x17: 0000000000000038 x16: 000000000000d904 x15: 0000000000000003 [ 12.211649] x14: ffffdddf9357ce48 x13: ffffdddf935e71c8 x12: 000000000004803c [ 12.211653] x11: 00000000a867d7ad x10: 00000000a867d7ad x9 : ffffdddf90c28df4 [ 12.211657] x8 : ffffdddf9357a980 x7 : 0000000000000000 x6 : 0000000000000004 [ 12.211661] x5 : ffffffffffffffc8 x4 : 00000000173eed80 x3 : ffff80000893b940 [ 12.211665] x2 : 00000000173eed80 x1 : ffff80000893b940 x0 : 0000000000000000 [ 12.211669] Call trace: [ 12.211670] clk_core_init_rate_req+0x84/0x90 [ 12.211673] clk_core_round_rate_nolock+0xe8/0x10c [ 12.211675] clk_mux_determine_rate_flags+0x174/0x1f0 [ 12.211677] clk_mux_determine_rate+0x1c/0x30 [ 12.211680] clk_core_determine_round_nolock+0x74/0x130 [ 12.211682] clk_core_round_rate_nolock+0x58/0x10c [ 12.211684] clk_core_round_rate_nolock+0xf4/0x10c [ 12.211686] clk_core_set_rate_nolock+0x194/0x2ac [ 12.211688] clk_set_rate+0x40/0x94 [ 12.211691] _opp_config_clk_single+0x38/0xa0 [ 12.211693] _set_opp+0x1b0/0x500 [ 12.211695] dev_pm_opp_set_rate+0x120/0x290 [ 12.211697] panfrost_devfreq_target+0x3c/0x50 [panfrost] [ 12.211705] devfreq_set_target+0x8c/0x2d0 [ 12.211707] devfreq_update_target+0xcc/0xf4 [ 12.211708] devfreq_monitor+0x40/0x1d0 [ 12.211710] process_one_work+0x294/0x664 [ 12.211712] worker_thread+0x7c/0x45c [ 12.211713] kthread+0x104/0x110 [ 12.211716] ret_from_fork+0x10/0x20 [ 12.211718] irq event stamp: 7102 [ 12.211719] hardirqs last enabled at (7101): [<ffffdddf904ea5a0>] finish_task_switch.isra.0+0xec/0x2f0 [ 12.211723] hardirqs last disabled at (7102): [<ffffdddf91794b74>] el1_dbg+0x24/0x90 [ 12.211726] softirqs last enabled at (6716): [<ffffdddf90410be4>] __do_softirq+0x414/0x588 [ 12.211728] softirqs last disabled at (6507): [<ffffdddf904171d8>] ____do_softirq+0x18/0x24 [ 12.211730] ---[ end trace 0000000000000000 ]--- Fixes: 262ca38f4b6e ("clk: Stop forwarding clk_rate_requests to the parent") Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://lore.kernel.org/r/20221011135548.318323-1-angelogioacchino.delregno@collabora.com Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-10-11 15:55:48 +02:00
.determine_rate = mtk_clk_mux_determine_rate,
};
EXPORT_SYMBOL_GPL(mtk_mux_gate_clr_set_upd_ops);
static struct clk_hw *mtk_clk_register_mux(struct device *dev,
const struct mtk_mux *mux,
struct regmap *regmap,
spinlock_t *lock)
{
struct mtk_clk_mux *clk_mux;
struct clk_init_data init = {};
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
int ret;
clk_mux = kzalloc(sizeof(*clk_mux), GFP_KERNEL);
if (!clk_mux)
return ERR_PTR(-ENOMEM);
init.name = mux->name;
init.flags = mux->flags | CLK_SET_RATE_PARENT;
init.parent_names = mux->parent_names;
init.num_parents = mux->num_parents;
init.ops = mux->ops;
clk_mux->regmap = regmap;
clk_mux->data = mux;
clk_mux->lock = lock;
clk_mux->hw.init = &init;
ret = clk_hw_register(dev, &clk_mux->hw);
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
if (ret) {
kfree(clk_mux);
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
return ERR_PTR(ret);
}
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
return &clk_mux->hw;
}
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
static void mtk_clk_unregister_mux(struct clk_hw *hw)
{
struct mtk_clk_mux *mux;
if (!hw)
return;
mux = to_mtk_clk_mux(hw);
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
clk_hw_unregister(hw);
kfree(mux);
}
int mtk_clk_register_muxes(struct device *dev,
const struct mtk_mux *muxes,
int num, struct device_node *node,
spinlock_t *lock,
clk: mediatek: Replace 'struct clk' with 'struct clk_hw' As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. Instead of adding new APIs to the MediaTek clk driver library mirroring the existing ones, moving all drivers to the new APIs, and then removing the old ones, just migrate everything at the same time. This involves replacing 'struct clk' with 'struct clk_hw', and 'struct clk_onecell_data' with 'struct clk_hw_onecell_data', and fixing up all usages. For now, the clk_register() and co. usage is retained, with __clk_get_hw() and (struct clk_hw *)->clk used to bridge the difference between the APIs. These will be replaced in subsequent patches. Fix up mtk_{alloc,free}_clk_data to use 'struct clk_hw' by hand. Fix up all other affected call sites with the following coccinelle script. // Replace type @@ @@ - struct clk_onecell_data + struct clk_hw_onecell_data // Replace of_clk_add_provider() & of_clk_src_simple_get() @@ expression NP, DATA; symbol of_clk_src_onecell_get; @@ - of_clk_add_provider( + of_clk_add_hw_provider( NP, - of_clk_src_onecell_get, + of_clk_hw_onecell_get, DATA ) // Fix register/unregister @@ identifier CD; expression E; identifier fn =~ "unregister"; @@ fn(..., - CD->clks[E] + CD->hws[E]->clk ,... ); // Fix calls to clk_prepare_enable() @@ identifier CD; expression E; @@ clk_prepare_enable( - CD->clks[E] + CD->hws[E]->clk ); // Fix pointer assignment @@ identifier CD; identifier CLK; expression E; @@ - CD->clks[E] + CD->hws[E] = ( - CLK + __clk_get_hw(CLK) | ERR_PTR(...) ) ; // Fix pointer usage @@ identifier CD; expression E; @@ - CD->clks[E] + CD->hws[E] // Fix mtk_clk_pll_get_base() @@ symbol clk, hw, data; @@ mtk_clk_pll_get_base( - struct clk *clk, + struct clk_hw *hw, const struct mtk_pll_data *data ) { - struct clk_hw *hw = __clk_get_hw(clk); ... } // Fix mtk_clk_pll_get_base() usage @@ identifier CD; expression E; @@ mtk_clk_pll_get_base( - CD->clks[E] + CD->hws[E]->clk ,... ); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-4-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:08 +08:00
struct clk_hw_onecell_data *clk_data)
{
struct regmap *regmap;
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
struct clk_hw *hw;
int i;
regmap = device_node_to_regmap(node);
if (IS_ERR(regmap)) {
pr_err("Cannot find regmap for %pOF: %pe\n", node, regmap);
return PTR_ERR(regmap);
}
for (i = 0; i < num; i++) {
const struct mtk_mux *mux = &muxes[i];
clk: mediatek: Replace 'struct clk' with 'struct clk_hw' As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. Instead of adding new APIs to the MediaTek clk driver library mirroring the existing ones, moving all drivers to the new APIs, and then removing the old ones, just migrate everything at the same time. This involves replacing 'struct clk' with 'struct clk_hw', and 'struct clk_onecell_data' with 'struct clk_hw_onecell_data', and fixing up all usages. For now, the clk_register() and co. usage is retained, with __clk_get_hw() and (struct clk_hw *)->clk used to bridge the difference between the APIs. These will be replaced in subsequent patches. Fix up mtk_{alloc,free}_clk_data to use 'struct clk_hw' by hand. Fix up all other affected call sites with the following coccinelle script. // Replace type @@ @@ - struct clk_onecell_data + struct clk_hw_onecell_data // Replace of_clk_add_provider() & of_clk_src_simple_get() @@ expression NP, DATA; symbol of_clk_src_onecell_get; @@ - of_clk_add_provider( + of_clk_add_hw_provider( NP, - of_clk_src_onecell_get, + of_clk_hw_onecell_get, DATA ) // Fix register/unregister @@ identifier CD; expression E; identifier fn =~ "unregister"; @@ fn(..., - CD->clks[E] + CD->hws[E]->clk ,... ); // Fix calls to clk_prepare_enable() @@ identifier CD; expression E; @@ clk_prepare_enable( - CD->clks[E] + CD->hws[E]->clk ); // Fix pointer assignment @@ identifier CD; identifier CLK; expression E; @@ - CD->clks[E] + CD->hws[E] = ( - CLK + __clk_get_hw(CLK) | ERR_PTR(...) ) ; // Fix pointer usage @@ identifier CD; expression E; @@ - CD->clks[E] + CD->hws[E] // Fix mtk_clk_pll_get_base() @@ symbol clk, hw, data; @@ mtk_clk_pll_get_base( - struct clk *clk, + struct clk_hw *hw, const struct mtk_pll_data *data ) { - struct clk_hw *hw = __clk_get_hw(clk); ... } // Fix mtk_clk_pll_get_base() usage @@ identifier CD; expression E; @@ mtk_clk_pll_get_base( - CD->clks[E] + CD->hws[E]->clk ,... ); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-4-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:08 +08:00
if (!IS_ERR_OR_NULL(clk_data->hws[mux->id])) {
pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
node, mux->id);
continue;
}
hw = mtk_clk_register_mux(dev, mux, regmap, lock);
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
if (IS_ERR(hw)) {
pr_err("Failed to register clk %s: %pe\n", mux->name,
hw);
goto err;
}
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
clk_data->hws[mux->id] = hw;
}
return 0;
err:
while (--i >= 0) {
const struct mtk_mux *mux = &muxes[i];
clk: mediatek: Replace 'struct clk' with 'struct clk_hw' As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. Instead of adding new APIs to the MediaTek clk driver library mirroring the existing ones, moving all drivers to the new APIs, and then removing the old ones, just migrate everything at the same time. This involves replacing 'struct clk' with 'struct clk_hw', and 'struct clk_onecell_data' with 'struct clk_hw_onecell_data', and fixing up all usages. For now, the clk_register() and co. usage is retained, with __clk_get_hw() and (struct clk_hw *)->clk used to bridge the difference between the APIs. These will be replaced in subsequent patches. Fix up mtk_{alloc,free}_clk_data to use 'struct clk_hw' by hand. Fix up all other affected call sites with the following coccinelle script. // Replace type @@ @@ - struct clk_onecell_data + struct clk_hw_onecell_data // Replace of_clk_add_provider() & of_clk_src_simple_get() @@ expression NP, DATA; symbol of_clk_src_onecell_get; @@ - of_clk_add_provider( + of_clk_add_hw_provider( NP, - of_clk_src_onecell_get, + of_clk_hw_onecell_get, DATA ) // Fix register/unregister @@ identifier CD; expression E; identifier fn =~ "unregister"; @@ fn(..., - CD->clks[E] + CD->hws[E]->clk ,... ); // Fix calls to clk_prepare_enable() @@ identifier CD; expression E; @@ clk_prepare_enable( - CD->clks[E] + CD->hws[E]->clk ); // Fix pointer assignment @@ identifier CD; identifier CLK; expression E; @@ - CD->clks[E] + CD->hws[E] = ( - CLK + __clk_get_hw(CLK) | ERR_PTR(...) ) ; // Fix pointer usage @@ identifier CD; expression E; @@ - CD->clks[E] + CD->hws[E] // Fix mtk_clk_pll_get_base() @@ symbol clk, hw, data; @@ mtk_clk_pll_get_base( - struct clk *clk, + struct clk_hw *hw, const struct mtk_pll_data *data ) { - struct clk_hw *hw = __clk_get_hw(clk); ... } // Fix mtk_clk_pll_get_base() usage @@ identifier CD; expression E; @@ mtk_clk_pll_get_base( - CD->clks[E] + CD->hws[E]->clk ,... ); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-4-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:08 +08:00
if (IS_ERR_OR_NULL(clk_data->hws[mux->id]))
continue;
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
mtk_clk_unregister_mux(clk_data->hws[mux->id]);
clk: mediatek: Replace 'struct clk' with 'struct clk_hw' As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. Instead of adding new APIs to the MediaTek clk driver library mirroring the existing ones, moving all drivers to the new APIs, and then removing the old ones, just migrate everything at the same time. This involves replacing 'struct clk' with 'struct clk_hw', and 'struct clk_onecell_data' with 'struct clk_hw_onecell_data', and fixing up all usages. For now, the clk_register() and co. usage is retained, with __clk_get_hw() and (struct clk_hw *)->clk used to bridge the difference between the APIs. These will be replaced in subsequent patches. Fix up mtk_{alloc,free}_clk_data to use 'struct clk_hw' by hand. Fix up all other affected call sites with the following coccinelle script. // Replace type @@ @@ - struct clk_onecell_data + struct clk_hw_onecell_data // Replace of_clk_add_provider() & of_clk_src_simple_get() @@ expression NP, DATA; symbol of_clk_src_onecell_get; @@ - of_clk_add_provider( + of_clk_add_hw_provider( NP, - of_clk_src_onecell_get, + of_clk_hw_onecell_get, DATA ) // Fix register/unregister @@ identifier CD; expression E; identifier fn =~ "unregister"; @@ fn(..., - CD->clks[E] + CD->hws[E]->clk ,... ); // Fix calls to clk_prepare_enable() @@ identifier CD; expression E; @@ clk_prepare_enable( - CD->clks[E] + CD->hws[E]->clk ); // Fix pointer assignment @@ identifier CD; identifier CLK; expression E; @@ - CD->clks[E] + CD->hws[E] = ( - CLK + __clk_get_hw(CLK) | ERR_PTR(...) ) ; // Fix pointer usage @@ identifier CD; expression E; @@ - CD->clks[E] + CD->hws[E] // Fix mtk_clk_pll_get_base() @@ symbol clk, hw, data; @@ mtk_clk_pll_get_base( - struct clk *clk, + struct clk_hw *hw, const struct mtk_pll_data *data ) { - struct clk_hw *hw = __clk_get_hw(clk); ... } // Fix mtk_clk_pll_get_base() usage @@ identifier CD; expression E; @@ mtk_clk_pll_get_base( - CD->clks[E] + CD->hws[E]->clk ,... ); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-4-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:08 +08:00
clk_data->hws[mux->id] = ERR_PTR(-ENOENT);
}
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
return PTR_ERR(hw);
}
EXPORT_SYMBOL_GPL(mtk_clk_register_muxes);
void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
clk: mediatek: Replace 'struct clk' with 'struct clk_hw' As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. Instead of adding new APIs to the MediaTek clk driver library mirroring the existing ones, moving all drivers to the new APIs, and then removing the old ones, just migrate everything at the same time. This involves replacing 'struct clk' with 'struct clk_hw', and 'struct clk_onecell_data' with 'struct clk_hw_onecell_data', and fixing up all usages. For now, the clk_register() and co. usage is retained, with __clk_get_hw() and (struct clk_hw *)->clk used to bridge the difference between the APIs. These will be replaced in subsequent patches. Fix up mtk_{alloc,free}_clk_data to use 'struct clk_hw' by hand. Fix up all other affected call sites with the following coccinelle script. // Replace type @@ @@ - struct clk_onecell_data + struct clk_hw_onecell_data // Replace of_clk_add_provider() & of_clk_src_simple_get() @@ expression NP, DATA; symbol of_clk_src_onecell_get; @@ - of_clk_add_provider( + of_clk_add_hw_provider( NP, - of_clk_src_onecell_get, + of_clk_hw_onecell_get, DATA ) // Fix register/unregister @@ identifier CD; expression E; identifier fn =~ "unregister"; @@ fn(..., - CD->clks[E] + CD->hws[E]->clk ,... ); // Fix calls to clk_prepare_enable() @@ identifier CD; expression E; @@ clk_prepare_enable( - CD->clks[E] + CD->hws[E]->clk ); // Fix pointer assignment @@ identifier CD; identifier CLK; expression E; @@ - CD->clks[E] + CD->hws[E] = ( - CLK + __clk_get_hw(CLK) | ERR_PTR(...) ) ; // Fix pointer usage @@ identifier CD; expression E; @@ - CD->clks[E] + CD->hws[E] // Fix mtk_clk_pll_get_base() @@ symbol clk, hw, data; @@ mtk_clk_pll_get_base( - struct clk *clk, + struct clk_hw *hw, const struct mtk_pll_data *data ) { - struct clk_hw *hw = __clk_get_hw(clk); ... } // Fix mtk_clk_pll_get_base() usage @@ identifier CD; expression E; @@ mtk_clk_pll_get_base( - CD->clks[E] + CD->hws[E]->clk ,... ); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-4-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:08 +08:00
struct clk_hw_onecell_data *clk_data)
{
int i;
if (!clk_data)
return;
for (i = num; i > 0; i--) {
const struct mtk_mux *mux = &muxes[i - 1];
clk: mediatek: Replace 'struct clk' with 'struct clk_hw' As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. Instead of adding new APIs to the MediaTek clk driver library mirroring the existing ones, moving all drivers to the new APIs, and then removing the old ones, just migrate everything at the same time. This involves replacing 'struct clk' with 'struct clk_hw', and 'struct clk_onecell_data' with 'struct clk_hw_onecell_data', and fixing up all usages. For now, the clk_register() and co. usage is retained, with __clk_get_hw() and (struct clk_hw *)->clk used to bridge the difference between the APIs. These will be replaced in subsequent patches. Fix up mtk_{alloc,free}_clk_data to use 'struct clk_hw' by hand. Fix up all other affected call sites with the following coccinelle script. // Replace type @@ @@ - struct clk_onecell_data + struct clk_hw_onecell_data // Replace of_clk_add_provider() & of_clk_src_simple_get() @@ expression NP, DATA; symbol of_clk_src_onecell_get; @@ - of_clk_add_provider( + of_clk_add_hw_provider( NP, - of_clk_src_onecell_get, + of_clk_hw_onecell_get, DATA ) // Fix register/unregister @@ identifier CD; expression E; identifier fn =~ "unregister"; @@ fn(..., - CD->clks[E] + CD->hws[E]->clk ,... ); // Fix calls to clk_prepare_enable() @@ identifier CD; expression E; @@ clk_prepare_enable( - CD->clks[E] + CD->hws[E]->clk ); // Fix pointer assignment @@ identifier CD; identifier CLK; expression E; @@ - CD->clks[E] + CD->hws[E] = ( - CLK + __clk_get_hw(CLK) | ERR_PTR(...) ) ; // Fix pointer usage @@ identifier CD; expression E; @@ - CD->clks[E] + CD->hws[E] // Fix mtk_clk_pll_get_base() @@ symbol clk, hw, data; @@ mtk_clk_pll_get_base( - struct clk *clk, + struct clk_hw *hw, const struct mtk_pll_data *data ) { - struct clk_hw *hw = __clk_get_hw(clk); ... } // Fix mtk_clk_pll_get_base() usage @@ identifier CD; expression E; @@ mtk_clk_pll_get_base( - CD->clks[E] + CD->hws[E]->clk ,... ); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-4-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:08 +08:00
if (IS_ERR_OR_NULL(clk_data->hws[mux->id]))
continue;
clk: mediatek: Switch to clk_hw provider APIs As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. In a previous patch, 'struct clk_onecell_data' was replaced with 'struct clk_hw_onecell_data', with (struct clk_hw *)->clk and __clk_get_hw() bridging the new data structures and old code. Now switch from the old 'clk_(un)?register*()' APIs to the new 'clk_hw_(un)?register*()' ones. This is done with the coccinelle script below. Unfortunately this also leaves clk-mt8173.c with a compile error that would need a coccinelle script longer than the actual diff to fix. This last part is fixed up by hand. // Fix prototypes @@ identifier F =~ "^mtk_clk_register_"; @@ - struct clk * + struct clk_hw * F(...); // Fix calls to mtk_clk_register_<singular> @ reg @ identifier F =~ "^mtk_clk_register_"; identifier FS =~ "^mtk_clk_register_[a-z_]*s"; identifier I; expression clk_data; expression E; @@ FS(...) { ... - struct clk *I; + struct clk_hw *hw; ... for (...;...;...) { ... ( - I + hw = - clk_register_fixed_rate( + clk_hw_register_fixed_rate( ... ); | - I + hw = - clk_register_fixed_factor( + clk_hw_register_fixed_factor( ... ); | - I + hw = - clk_register_divider( + clk_hw_register_divider( ... ); | - I + hw = F(...); ) ... if ( - IS_ERR(I) + IS_ERR(hw) ) { pr_err(..., - I + hw ,...); ... } - clk_data->hws[E] = __clk_get_hw(I); + clk_data->hws[E] = hw; } ... } @ depends on reg @ identifier reg.I; @@ return PTR_ERR( - I + hw ); // Fix mtk_clk_register_composite to return clk_hw instead of clk @@ identifier I, R; expression E; @@ - struct clk * + struct clk_hw * mtk_clk_register_composite(...) { ... - struct clk *I; + struct clk_hw *hw; ... - I = clk_register_composite( + hw = clk_hw_register_composite( ...); if (IS_ERR( - I + hw )) { ... R = PTR_ERR( - I + hw ); ... } return - I + hw ; ... } // Fix other mtk_clk_register_<singular> to return clk_hw instead of clk @@ identifier F =~ "^mtk_clk_register_"; identifier I, D, C; expression E; @@ - struct clk * + struct clk_hw * F(...) { ... - struct clk *I; + int ret; ... - I = clk_register(D, E); + ret = clk_hw_register(D, E); ... ( - if (IS_ERR(I)) + if (ret) { kfree(C); + return ERR_PTR(ret); + } | - if (IS_ERR(I)) + if (ret) { kfree(C); - return I; + return ERR_PTR(ret); } ) - return I; + return E; } // Fix mtk_clk_unregister_<singular> to take clk_hw instead of clk @@ identifier F =~ "^mtk_clk_unregister_"; identifier I, I2; @@ static void F( - struct clk *I + struct clk_hw *I2 ) { ... - struct clk_hw *I2; ... - I2 = __clk_get_hw(I); ... ( - clk_unregister(I); + clk_hw_unregister(I2); | - clk_unregister_composite(I); + clk_hw_unregister_composite(I2); ) ... } // Fix calls to mtk_clk_unregister_*() @@ identifier F =~ "^mtk_clk_unregister_"; expression I; expression E; @@ - F(I->hws[E]->clk); + F(I->hws[E]); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-5-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:09 +08:00
mtk_clk_unregister_mux(clk_data->hws[mux->id]);
clk: mediatek: Replace 'struct clk' with 'struct clk_hw' As part of the effort to improve the MediaTek clk drivers, the next step is to switch from the old 'struct clk' clk prodivder APIs to the new 'struct clk_hw' ones. Instead of adding new APIs to the MediaTek clk driver library mirroring the existing ones, moving all drivers to the new APIs, and then removing the old ones, just migrate everything at the same time. This involves replacing 'struct clk' with 'struct clk_hw', and 'struct clk_onecell_data' with 'struct clk_hw_onecell_data', and fixing up all usages. For now, the clk_register() and co. usage is retained, with __clk_get_hw() and (struct clk_hw *)->clk used to bridge the difference between the APIs. These will be replaced in subsequent patches. Fix up mtk_{alloc,free}_clk_data to use 'struct clk_hw' by hand. Fix up all other affected call sites with the following coccinelle script. // Replace type @@ @@ - struct clk_onecell_data + struct clk_hw_onecell_data // Replace of_clk_add_provider() & of_clk_src_simple_get() @@ expression NP, DATA; symbol of_clk_src_onecell_get; @@ - of_clk_add_provider( + of_clk_add_hw_provider( NP, - of_clk_src_onecell_get, + of_clk_hw_onecell_get, DATA ) // Fix register/unregister @@ identifier CD; expression E; identifier fn =~ "unregister"; @@ fn(..., - CD->clks[E] + CD->hws[E]->clk ,... ); // Fix calls to clk_prepare_enable() @@ identifier CD; expression E; @@ clk_prepare_enable( - CD->clks[E] + CD->hws[E]->clk ); // Fix pointer assignment @@ identifier CD; identifier CLK; expression E; @@ - CD->clks[E] + CD->hws[E] = ( - CLK + __clk_get_hw(CLK) | ERR_PTR(...) ) ; // Fix pointer usage @@ identifier CD; expression E; @@ - CD->clks[E] + CD->hws[E] // Fix mtk_clk_pll_get_base() @@ symbol clk, hw, data; @@ mtk_clk_pll_get_base( - struct clk *clk, + struct clk_hw *hw, const struct mtk_pll_data *data ) { - struct clk_hw *hw = __clk_get_hw(clk); ... } // Fix mtk_clk_pll_get_base() usage @@ identifier CD; expression E; @@ mtk_clk_pll_get_base( - CD->clks[E] + CD->hws[E]->clk ,... ); Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Tested-by: Miles Chen <miles.chen@mediatek.com> Link: https://lore.kernel.org/r/20220519071610.423372-4-wenst@chromium.org Signed-off-by: Stephen Boyd <sboyd@kernel.org>
2022-05-19 15:16:08 +08:00
clk_data->hws[mux->id] = ERR_PTR(-ENOENT);
}
}
EXPORT_SYMBOL_GPL(mtk_clk_unregister_muxes);
/*
* This clock notifier is called when the frequency of the parent
* PLL clock is to be changed. The idea is to switch the parent to a
* stable clock, such as the main oscillator, while the PLL frequency
* stabilizes.
*/
static int mtk_clk_mux_notifier_cb(struct notifier_block *nb,
unsigned long event, void *_data)
{
struct clk_notifier_data *data = _data;
struct clk_hw *hw = __clk_get_hw(data->clk);
struct mtk_mux_nb *mux_nb = to_mtk_mux_nb(nb);
int ret = 0;
switch (event) {
case PRE_RATE_CHANGE:
mux_nb->original_index = mux_nb->ops->get_parent(hw);
ret = mux_nb->ops->set_parent(hw, mux_nb->bypass_index);
break;
case POST_RATE_CHANGE:
case ABORT_RATE_CHANGE:
ret = mux_nb->ops->set_parent(hw, mux_nb->original_index);
break;
}
return notifier_from_errno(ret);
}
int devm_mtk_clk_mux_notifier_register(struct device *dev, struct clk *clk,
struct mtk_mux_nb *mux_nb)
{
mux_nb->nb.notifier_call = mtk_clk_mux_notifier_cb;
return devm_clk_notifier_register(dev, clk, &mux_nb->nb);
}
EXPORT_SYMBOL_GPL(devm_mtk_clk_mux_notifier_register);
MODULE_LICENSE("GPL");