summaryrefslogtreecommitdiffstats
path: root/drivers/clk/at91/clk-smd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/at91/clk-smd.c')
-rw-r--r--drivers/clk/at91/clk-smd.c82
1 files changed, 39 insertions, 43 deletions
diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c
index e81f0d4d4e..dc1b150750 100644
--- a/drivers/clk/at91/clk-smd.c
+++ b/drivers/clk/at91/clk-smd.c
@@ -1,42 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
*/
-#include <common.h>
-#include <clock.h>
-#include <io.h>
-#include <linux/list.h>
-#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
#include <linux/clk/at91_pmc.h>
+#include <of.h>
#include <mfd/syscon.h>
-#include <regmap.h>
+#include <linux/regmap.h>
#include "pmc.h"
-#define SMD_SOURCE_MAX 2
-
#define SMD_DIV_SHIFT 8
#define SMD_MAX_DIV 0xf
struct at91sam9x5_clk_smd {
- struct clk clk;
+ struct clk_hw hw;
struct regmap *regmap;
- const char *parent_names[SMD_SOURCE_MAX];
};
-#define to_at91sam9x5_clk_smd(clk) \
- container_of(clk, struct at91sam9x5_clk_smd, clk)
+#define to_at91sam9x5_clk_smd(hw) \
+ container_of(hw, struct at91sam9x5_clk_smd, hw)
-static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk *clk,
+static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
- struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(clk);
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
unsigned int smdr;
u8 smddiv;
@@ -46,7 +36,7 @@ static unsigned long at91sam9x5_clk_smd_recalc_rate(struct clk *clk,
return parent_rate / (smddiv + 1);
}
-static long at91sam9x5_clk_smd_round_rate(struct clk *clk, unsigned long rate,
+static long at91sam9x5_clk_smd_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
unsigned long div;
@@ -68,22 +58,22 @@ static long at91sam9x5_clk_smd_round_rate(struct clk *clk, unsigned long rate,
return bestrate;
}
-static int at91sam9x5_clk_smd_set_parent(struct clk *clk, u8 index)
+static int at91sam9x5_clk_smd_set_parent(struct clk_hw *hw, u8 index)
{
- struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(clk);
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
if (index > 1)
return -EINVAL;
- regmap_write_bits(smd->regmap, AT91_PMC_SMD, AT91_PMC_SMDS,
- index ? AT91_PMC_SMDS : 0);
+ regmap_update_bits(smd->regmap, AT91_PMC_SMD, AT91_PMC_SMDS,
+ index ? AT91_PMC_SMDS : 0);
return 0;
}
-static int at91sam9x5_clk_smd_get_parent(struct clk *clk)
+static int at91sam9x5_clk_smd_get_parent(struct clk_hw *hw)
{
- struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(clk);
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
unsigned int smdr;
regmap_read(smd->regmap, AT91_PMC_SMD, &smdr);
@@ -91,17 +81,17 @@ static int at91sam9x5_clk_smd_get_parent(struct clk *clk)
return smdr & AT91_PMC_SMDS;
}
-static int at91sam9x5_clk_smd_set_rate(struct clk *clk, unsigned long rate,
+static int at91sam9x5_clk_smd_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
- struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(clk);
+ struct at91sam9x5_clk_smd *smd = to_at91sam9x5_clk_smd(hw);
unsigned long div = parent_rate / rate;
if (parent_rate % rate || div < 1 || div > (SMD_MAX_DIV + 1))
return -EINVAL;
- regmap_write_bits(smd->regmap, AT91_PMC_SMD, AT91_PMC_SMD_DIV,
- (div - 1) << SMD_DIV_SHIFT);
+ regmap_update_bits(smd->regmap, AT91_PMC_SMD, AT91_PMC_SMD_DIV,
+ (div - 1) << SMD_DIV_SHIFT);
return 0;
}
@@ -114,28 +104,34 @@ static const struct clk_ops at91sam9x5_smd_ops = {
.set_rate = at91sam9x5_clk_smd_set_rate,
};
-struct clk *
+struct clk_hw * __init
at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents)
{
struct at91sam9x5_clk_smd *smd;
+ struct clk_hw *hw;
+ struct clk_init_data init;
int ret;
- smd = xzalloc(sizeof(*smd));
- smd->clk.name = name;
- smd->clk.ops = &at91sam9x5_smd_ops;
- memcpy(smd->parent_names, parent_names,
- num_parents * sizeof(smd->parent_names[0]));
- smd->clk.parent_names = smd->parent_names;
- smd->clk.num_parents = num_parents;
- /* init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; */
+ smd = kzalloc(sizeof(*smd), GFP_KERNEL);
+ if (!smd)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = name;
+ init.ops = &at91sam9x5_smd_ops;
+ init.parent_names = parent_names;
+ init.num_parents = num_parents;
+ init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
+
+ smd->hw.init = &init;
smd->regmap = regmap;
- ret = clk_register(&smd->clk);
+ hw = &smd->hw;
+ ret = clk_hw_register(NULL, &smd->hw);
if (ret) {
kfree(smd);
- return ERR_PTR(ret);
+ hw = ERR_PTR(ret);
}
- return &smd->clk;
+ return hw;
}