mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register
[ Upstream commit 3d37ca1482c36975255f29911a529f84f1bc34a9 ] In a subsequent patch, the registration callback will need more parameters from cpg_mssr_priv (like another base address with clock controllers with double register block, and also, notifiers and rmw_lock). Instead of adding more parameters, move the needed parameters to a public sub-struct. Instead moving clks to this structure, which would have implied to add an allocation (and cleanup) for it, keep the way the allocation is done and just have a copy of the pointer in the public structure. Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Thierry Bultel <thierry.bultel.yh@bp.renesas.com> Link: https://lore.kernel.org/20250515141828.43444-5-thierry.bultel.yh@bp.renesas.com Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
224a0d7c84
commit
e8c7304992
@@ -159,12 +159,13 @@ static void __init r7s9210_update_clk_table(struct clk *extal_clk,
|
||||
|
||||
static struct clk * __init rza2_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base,
|
||||
struct raw_notifier_head *notifiers)
|
||||
struct cpg_mssr_pub *pub)
|
||||
{
|
||||
struct clk *parent;
|
||||
void __iomem *base = pub->base0;
|
||||
struct clk **clks = pub->clks;
|
||||
unsigned int mult = 1;
|
||||
unsigned int div = 1;
|
||||
struct clk *parent;
|
||||
|
||||
parent = clks[core->parent];
|
||||
if (IS_ERR(parent))
|
||||
|
||||
@@ -222,10 +222,11 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev)
|
||||
|
||||
static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base,
|
||||
struct raw_notifier_head *notifiers)
|
||||
struct cpg_mssr_pub *pub)
|
||||
{
|
||||
const struct clk_div_table *table;
|
||||
void __iomem *base = pub->base0;
|
||||
struct clk **clks = pub->clks;
|
||||
const struct clk *parent;
|
||||
unsigned int shift;
|
||||
|
||||
@@ -239,8 +240,7 @@ static struct clk * __init r8a77970_cpg_clk_register(struct device *dev,
|
||||
shift = 4;
|
||||
break;
|
||||
default:
|
||||
return rcar_gen3_cpg_clk_register(dev, core, info, clks, base,
|
||||
notifiers);
|
||||
return rcar_gen3_cpg_clk_register(dev, core, info, pub);
|
||||
}
|
||||
|
||||
parent = clks[core->parent];
|
||||
|
||||
@@ -274,10 +274,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = {
|
||||
|
||||
struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base,
|
||||
struct raw_notifier_head *notifiers)
|
||||
struct cpg_mssr_pub *pub)
|
||||
{
|
||||
const struct clk_div_table *table = NULL;
|
||||
void __iomem *base = pub->base0;
|
||||
struct clk **clks = pub->clks;
|
||||
const struct clk *parent;
|
||||
const char *parent_name;
|
||||
unsigned int mult = 1;
|
||||
|
||||
@@ -32,8 +32,7 @@ struct rcar_gen2_cpg_pll_config {
|
||||
|
||||
struct clk *rcar_gen2_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base,
|
||||
struct raw_notifier_head *notifiers);
|
||||
struct cpg_mssr_pub *pub);
|
||||
int rcar_gen2_cpg_init(const struct rcar_gen2_cpg_pll_config *config,
|
||||
unsigned int pll0_div, u32 mode);
|
||||
|
||||
|
||||
@@ -346,9 +346,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = {
|
||||
|
||||
struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base,
|
||||
struct raw_notifier_head *notifiers)
|
||||
struct cpg_mssr_pub *pub)
|
||||
{
|
||||
struct raw_notifier_head *notifiers = &pub->notifiers;
|
||||
void __iomem *base = pub->base0;
|
||||
struct clk **clks = pub->clks;
|
||||
const struct clk *parent;
|
||||
unsigned int mult = 1;
|
||||
unsigned int div = 1;
|
||||
|
||||
@@ -81,8 +81,7 @@ struct rcar_gen3_cpg_pll_config {
|
||||
|
||||
struct clk *rcar_gen3_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base,
|
||||
struct raw_notifier_head *notifiers);
|
||||
struct cpg_mssr_pub *pub);
|
||||
int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config,
|
||||
unsigned int clk_extalr, u32 mode);
|
||||
|
||||
|
||||
@@ -330,9 +330,11 @@ static const struct clk_div_table cpg_rpcsrc_div_table[] = {
|
||||
|
||||
struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base,
|
||||
struct raw_notifier_head *notifiers)
|
||||
struct cpg_mssr_pub *pub)
|
||||
{
|
||||
struct raw_notifier_head *notifiers = &pub->notifiers;
|
||||
void __iomem *base = pub->base0;
|
||||
struct clk **clks = pub->clks;
|
||||
const struct clk *parent;
|
||||
unsigned int mult = 1;
|
||||
unsigned int div = 1;
|
||||
|
||||
@@ -72,8 +72,7 @@ struct rcar_gen4_cpg_pll_config {
|
||||
|
||||
struct clk *rcar_gen4_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base,
|
||||
struct raw_notifier_head *notifiers);
|
||||
struct cpg_mssr_pub *pub);
|
||||
int rcar_gen4_cpg_init(const struct rcar_gen4_cpg_pll_config *config,
|
||||
unsigned int clk_extalr, u32 mode);
|
||||
|
||||
|
||||
@@ -127,16 +127,14 @@ static const u16 srstclr_for_gen4[] = {
|
||||
* struct cpg_mssr_priv - Clock Pulse Generator / Module Standby
|
||||
* and Software Reset Private Data
|
||||
*
|
||||
* @pub: Data passed to clock registration callback
|
||||
* @rcdev: Optional reset controller entity
|
||||
* @dev: CPG/MSSR device
|
||||
* @base: CPG/MSSR register block base address
|
||||
* @reg_layout: CPG/MSSR register layout
|
||||
* @rmw_lock: protects RMW register accesses
|
||||
* @np: Device node in DT for this CPG/MSSR module
|
||||
* @num_core_clks: Number of Core Clocks in clks[]
|
||||
* @num_mod_clks: Number of Module Clocks in clks[]
|
||||
* @last_dt_core_clk: ID of the last Core Clock exported to DT
|
||||
* @notifiers: Notifier chain to save/restore clock state for system resume
|
||||
* @status_regs: Pointer to status registers array
|
||||
* @control_regs: Pointer to control registers array
|
||||
* @reset_regs: Pointer to reset registers array
|
||||
@@ -146,20 +144,18 @@ static const u16 srstclr_for_gen4[] = {
|
||||
* @clks: Array containing all Core and Module Clocks
|
||||
*/
|
||||
struct cpg_mssr_priv {
|
||||
struct cpg_mssr_pub pub;
|
||||
#ifdef CONFIG_RESET_CONTROLLER
|
||||
struct reset_controller_dev rcdev;
|
||||
#endif
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
enum clk_reg_layout reg_layout;
|
||||
spinlock_t rmw_lock;
|
||||
struct device_node *np;
|
||||
|
||||
unsigned int num_core_clks;
|
||||
unsigned int num_mod_clks;
|
||||
unsigned int last_dt_core_clk;
|
||||
|
||||
struct raw_notifier_head notifiers;
|
||||
const u16 *status_regs;
|
||||
const u16 *control_regs;
|
||||
const u16 *reset_regs;
|
||||
@@ -202,38 +198,39 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
|
||||
|
||||
dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk,
|
||||
str_on_off(enable));
|
||||
spin_lock_irqsave(&priv->rmw_lock, flags);
|
||||
spin_lock_irqsave(&priv->pub.rmw_lock, flags);
|
||||
|
||||
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
|
||||
value = readb(priv->base + priv->control_regs[reg]);
|
||||
value = readb(priv->pub.base0 + priv->control_regs[reg]);
|
||||
if (enable)
|
||||
value &= ~bitmask;
|
||||
else
|
||||
value |= bitmask;
|
||||
writeb(value, priv->base + priv->control_regs[reg]);
|
||||
writeb(value, priv->pub.base0 + priv->control_regs[reg]);
|
||||
|
||||
/* dummy read to ensure write has completed */
|
||||
readb(priv->base + priv->control_regs[reg]);
|
||||
barrier_data(priv->base + priv->control_regs[reg]);
|
||||
readb(priv->pub.base0 + priv->control_regs[reg]);
|
||||
barrier_data(priv->pub.base0 + priv->control_regs[reg]);
|
||||
|
||||
} else {
|
||||
value = readl(priv->base + priv->control_regs[reg]);
|
||||
value = readl(priv->pub.base0 + priv->control_regs[reg]);
|
||||
if (enable)
|
||||
value &= ~bitmask;
|
||||
else
|
||||
value |= bitmask;
|
||||
writel(value, priv->base + priv->control_regs[reg]);
|
||||
writel(value, priv->pub.base0 + priv->control_regs[reg]);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->rmw_lock, flags);
|
||||
spin_unlock_irqrestore(&priv->pub.rmw_lock, flags);
|
||||
|
||||
if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
|
||||
return 0;
|
||||
|
||||
error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg],
|
||||
error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg],
|
||||
value, !(value & bitmask), 0, 10);
|
||||
if (error)
|
||||
dev_err(dev, "Failed to enable SMSTP %p[%d]\n",
|
||||
priv->base + priv->control_regs[reg], bit);
|
||||
priv->pub.base0 + priv->control_regs[reg], bit);
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -252,12 +249,13 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct mstp_clock *clock = to_mstp_clock(hw);
|
||||
struct cpg_mssr_priv *priv = clock->priv;
|
||||
unsigned int reg = clock->index / 32;
|
||||
u32 value;
|
||||
|
||||
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
|
||||
value = readb(priv->base + priv->control_regs[clock->index / 32]);
|
||||
value = readb(priv->pub.base0 + priv->control_regs[reg]);
|
||||
else
|
||||
value = readl(priv->base + priv->status_regs[clock->index / 32]);
|
||||
value = readl(priv->pub.base0 + priv->status_regs[reg]);
|
||||
|
||||
return !(value & BIT(clock->index % 32));
|
||||
}
|
||||
@@ -349,7 +347,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
|
||||
case CLK_TYPE_DIV6P1:
|
||||
case CLK_TYPE_DIV6_RO:
|
||||
WARN_DEBUG(core->parent >= priv->num_core_clks);
|
||||
parent = priv->clks[core->parent];
|
||||
parent = priv->pub.clks[core->parent];
|
||||
if (IS_ERR(parent)) {
|
||||
clk = parent;
|
||||
goto fail;
|
||||
@@ -359,12 +357,12 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
|
||||
|
||||
if (core->type == CLK_TYPE_DIV6_RO)
|
||||
/* Multiply with the DIV6 register value */
|
||||
div *= (readl(priv->base + core->offset) & 0x3f) + 1;
|
||||
div *= (readl(priv->pub.base0 + core->offset) & 0x3f) + 1;
|
||||
|
||||
if (core->type == CLK_TYPE_DIV6P1) {
|
||||
clk = cpg_div6_register(core->name, 1, &parent_name,
|
||||
priv->base + core->offset,
|
||||
&priv->notifiers);
|
||||
priv->pub.base0 + core->offset,
|
||||
&priv->pub.notifiers);
|
||||
} else {
|
||||
clk = clk_register_fixed_factor(NULL, core->name,
|
||||
parent_name, 0,
|
||||
@@ -380,8 +378,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
|
||||
default:
|
||||
if (info->cpg_clk_register)
|
||||
clk = info->cpg_clk_register(dev, core, info,
|
||||
priv->clks, priv->base,
|
||||
&priv->notifiers);
|
||||
&priv->pub);
|
||||
else
|
||||
dev_err(dev, "%s has unsupported core clock type %u\n",
|
||||
core->name, core->type);
|
||||
@@ -392,7 +389,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
|
||||
goto fail;
|
||||
|
||||
dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
|
||||
priv->clks[id] = clk;
|
||||
priv->pub.clks[id] = clk;
|
||||
return;
|
||||
|
||||
fail:
|
||||
@@ -415,14 +412,14 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod,
|
||||
WARN_DEBUG(id < priv->num_core_clks);
|
||||
WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks);
|
||||
WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks);
|
||||
WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT);
|
||||
WARN_DEBUG(PTR_ERR(priv->pub.clks[id]) != -ENOENT);
|
||||
|
||||
if (!mod->name) {
|
||||
/* Skip NULLified clock */
|
||||
return;
|
||||
}
|
||||
|
||||
parent = priv->clks[mod->parent];
|
||||
parent = priv->pub.clks[mod->parent];
|
||||
if (IS_ERR(parent)) {
|
||||
clk = parent;
|
||||
goto fail;
|
||||
@@ -611,7 +608,7 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
|
||||
dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
|
||||
|
||||
/* Reset module */
|
||||
writel(bitmask, priv->base + priv->reset_regs[reg]);
|
||||
writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]);
|
||||
|
||||
/*
|
||||
* On R-Car Gen4, delay after SRCR has been written is 1ms.
|
||||
@@ -624,7 +621,7 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
|
||||
usleep_range(35, 1000);
|
||||
|
||||
/* Release module from reset state */
|
||||
writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
|
||||
writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -638,7 +635,7 @@ static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
|
||||
dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
|
||||
|
||||
writel(bitmask, priv->base + priv->reset_regs[reg]);
|
||||
writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -652,7 +649,7 @@ static int cpg_mssr_deassert(struct reset_controller_dev *rcdev,
|
||||
|
||||
dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit);
|
||||
|
||||
writel(bitmask, priv->base + priv->reset_clear_regs[reg]);
|
||||
writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -664,7 +661,7 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev,
|
||||
unsigned int bit = id % 32;
|
||||
u32 bitmask = BIT(bit);
|
||||
|
||||
return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask);
|
||||
return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask);
|
||||
}
|
||||
|
||||
static const struct reset_control_ops cpg_mssr_reset_ops = {
|
||||
@@ -885,12 +882,12 @@ static int cpg_mssr_suspend_noirq(struct device *dev)
|
||||
if (priv->smstpcr_saved[reg].mask)
|
||||
priv->smstpcr_saved[reg].val =
|
||||
priv->reg_layout == CLK_REG_LAYOUT_RZ_A ?
|
||||
readb(priv->base + priv->control_regs[reg]) :
|
||||
readl(priv->base + priv->control_regs[reg]);
|
||||
readb(priv->pub.base0 + priv->control_regs[reg]) :
|
||||
readl(priv->pub.base0 + priv->control_regs[reg]);
|
||||
}
|
||||
|
||||
/* Save core clocks */
|
||||
raw_notifier_call_chain(&priv->notifiers, PM_EVENT_SUSPEND, NULL);
|
||||
raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_SUSPEND, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -907,7 +904,7 @@ static int cpg_mssr_resume_noirq(struct device *dev)
|
||||
return 0;
|
||||
|
||||
/* Restore core clocks */
|
||||
raw_notifier_call_chain(&priv->notifiers, PM_EVENT_RESUME, NULL);
|
||||
raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_RESUME, NULL);
|
||||
|
||||
/* Restore module clocks */
|
||||
for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) {
|
||||
@@ -916,29 +913,29 @@ static int cpg_mssr_resume_noirq(struct device *dev)
|
||||
continue;
|
||||
|
||||
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
|
||||
oldval = readb(priv->base + priv->control_regs[reg]);
|
||||
oldval = readb(priv->pub.base0 + priv->control_regs[reg]);
|
||||
else
|
||||
oldval = readl(priv->base + priv->control_regs[reg]);
|
||||
oldval = readl(priv->pub.base0 + priv->control_regs[reg]);
|
||||
newval = oldval & ~mask;
|
||||
newval |= priv->smstpcr_saved[reg].val & mask;
|
||||
if (newval == oldval)
|
||||
continue;
|
||||
|
||||
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) {
|
||||
writeb(newval, priv->base + priv->control_regs[reg]);
|
||||
writeb(newval, priv->pub.base0 + priv->control_regs[reg]);
|
||||
/* dummy read to ensure write has completed */
|
||||
readb(priv->base + priv->control_regs[reg]);
|
||||
barrier_data(priv->base + priv->control_regs[reg]);
|
||||
readb(priv->pub.base0 + priv->control_regs[reg]);
|
||||
barrier_data(priv->pub.base0 + priv->control_regs[reg]);
|
||||
continue;
|
||||
} else
|
||||
writel(newval, priv->base + priv->control_regs[reg]);
|
||||
writel(newval, priv->pub.base0 + priv->control_regs[reg]);
|
||||
|
||||
/* Wait until enabled clocks are really enabled */
|
||||
mask &= ~priv->smstpcr_saved[reg].val;
|
||||
if (!mask)
|
||||
continue;
|
||||
|
||||
error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg],
|
||||
error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg],
|
||||
oldval, !(oldval & mask), 0, 10);
|
||||
if (error)
|
||||
dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg,
|
||||
@@ -976,12 +973,13 @@ static int __init cpg_mssr_common_init(struct device *dev,
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->pub.clks = priv->clks;
|
||||
priv->np = np;
|
||||
priv->dev = dev;
|
||||
spin_lock_init(&priv->rmw_lock);
|
||||
spin_lock_init(&priv->pub.rmw_lock);
|
||||
|
||||
priv->base = of_iomap(np, 0);
|
||||
if (!priv->base) {
|
||||
priv->pub.base0 = of_iomap(np, 0);
|
||||
if (!priv->pub.base0) {
|
||||
error = -ENOMEM;
|
||||
goto out_err;
|
||||
}
|
||||
@@ -989,7 +987,7 @@ static int __init cpg_mssr_common_init(struct device *dev,
|
||||
priv->num_core_clks = info->num_total_core_clks;
|
||||
priv->num_mod_clks = info->num_hw_mod_clks;
|
||||
priv->last_dt_core_clk = info->last_dt_core_clk;
|
||||
RAW_INIT_NOTIFIER_HEAD(&priv->notifiers);
|
||||
RAW_INIT_NOTIFIER_HEAD(&priv->pub.notifiers);
|
||||
priv->reg_layout = info->reg_layout;
|
||||
if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
|
||||
priv->status_regs = mstpsr;
|
||||
@@ -1009,7 +1007,7 @@ static int __init cpg_mssr_common_init(struct device *dev,
|
||||
}
|
||||
|
||||
for (i = 0; i < nclks; i++)
|
||||
priv->clks[i] = ERR_PTR(-ENOENT);
|
||||
priv->pub.clks[i] = ERR_PTR(-ENOENT);
|
||||
|
||||
error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv);
|
||||
if (error)
|
||||
@@ -1020,8 +1018,8 @@ static int __init cpg_mssr_common_init(struct device *dev,
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
if (priv->base)
|
||||
iounmap(priv->base);
|
||||
if (priv->pub.base0)
|
||||
iounmap(priv->pub.base0);
|
||||
kfree(priv);
|
||||
|
||||
return error;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#ifndef __CLK_RENESAS_CPG_MSSR_H__
|
||||
#define __CLK_RENESAS_CPG_MSSR_H__
|
||||
|
||||
#include <linux/notifier.h>
|
||||
|
||||
/*
|
||||
* Definitions of CPG Core Clocks
|
||||
*
|
||||
@@ -29,6 +31,21 @@ struct cpg_core_clk {
|
||||
unsigned int offset;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cpg_mssr_pub - data shared with device-specific clk registration code
|
||||
*
|
||||
* @base0: CPG/MSSR register block base0 address
|
||||
* @notifiers: Notifier chain to save/restore clock state for system resume
|
||||
* @rmw_lock: protects RMW register accesses
|
||||
* @clks: pointer to clocks
|
||||
*/
|
||||
struct cpg_mssr_pub {
|
||||
void __iomem *base0;
|
||||
struct raw_notifier_head notifiers;
|
||||
spinlock_t rmw_lock;
|
||||
struct clk **clks;
|
||||
};
|
||||
|
||||
enum clk_types {
|
||||
/* Generic */
|
||||
CLK_TYPE_IN, /* External Clock Input */
|
||||
@@ -153,8 +170,7 @@ struct cpg_mssr_info {
|
||||
struct clk *(*cpg_clk_register)(struct device *dev,
|
||||
const struct cpg_core_clk *core,
|
||||
const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base,
|
||||
struct raw_notifier_head *notifiers);
|
||||
struct cpg_mssr_pub *pub);
|
||||
};
|
||||
|
||||
extern const struct cpg_mssr_info r7s9210_cpg_mssr_info;
|
||||
|
||||
Reference in New Issue
Block a user