This patch set adds support for the clocks having their own register set. Other
clocks are available but they are sharing a common register in addition of their
own registers. They will be supported in a following series.
Also, I realized that when moving the pll nodes out of the clocks container,
they didn't get reorder.
Alexandre Belloni (5):
clk: berlin: add support for clocks
clk: berlin: add berlin clocks DT bindings documentation
ARM: berlin/dt: add sdio clocks to BG2
ARM: berlin/dt: add sdio clocks to BG2CD
ARM: berlin/dt: add sdio clocks to BG2Q
.../devicetree/bindings/clock/berlin-clock.txt | 9 +-
arch/arm/boot/dts/berlin2.dtsi | 42 ++++---
arch/arm/boot/dts/berlin2cd.dtsi | 42 ++++---
arch/arm/boot/dts/berlin2q.dtsi | 28 +++--
drivers/clk/berlin/Makefile | 2 +-
drivers/clk/berlin/clk.c | 132 +++++++++++++++++++++
6 files changed, 218 insertions(+), 37 deletions(-)
create mode 100644 drivers/clk/berlin/clk.c
--
1.9.1
Add support for clocks having their own register set.
Signed-off-by: Alexandre Belloni <[email protected]>
---
drivers/clk/berlin/Makefile | 2 +-
drivers/clk/berlin/clk.c | 132 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 133 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/berlin/clk.c
diff --git a/drivers/clk/berlin/Makefile b/drivers/clk/berlin/Makefile
index 94859513de90..9bfa58eaf25a 100644
--- a/drivers/clk/berlin/Makefile
+++ b/drivers/clk/berlin/Makefile
@@ -1,4 +1,4 @@
-obj-y += pll.o
+obj-y += pll.o clk.o
obj-$(CONFIG_MACH_BERLIN_BG2) += pll-berlin2.o
obj-$(CONFIG_MACH_BERLIN_BG2CD) += pll-berlin2.o
obj-$(CONFIG_MACH_BERLIN_BG2Q) += pll-berlin2q.o
diff --git a/drivers/clk/berlin/clk.c b/drivers/clk/berlin/clk.c
new file mode 100644
index 000000000000..a0e688e5bead
--- /dev/null
+++ b/drivers/clk/berlin/clk.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2014 Marvell Technology Group Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#include "common.h"
+
+#define CLKEN (1 << 0)
+#define CLKPLLSEL_MASK 7
+#define CLKPLLSEL_SHIFT 1
+#define CLKPLLSWITCH (1 << 4)
+#define CLKSWITCH (1 << 5)
+#define CLKD3SWITCH (1 << 6)
+#define CLKSEL_MASK 7
+#define CLKSEL_SHIFT 7
+
+struct berlin_clk {
+ struct clk_hw hw;
+ void __iomem *base;
+};
+
+#define to_berlin_clk(hw) container_of(hw, struct berlin_clk, hw)
+
+static u8 clk_div[] = {1, 2, 4, 6, 8, 12, 1, 1};
+
+static unsigned long berlin_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ u32 val, divider;
+ struct berlin_clk *clk = to_berlin_clk(hw);
+
+ val = readl_relaxed(clk->base);
+ if (val & CLKD3SWITCH)
+ divider = 3;
+ else {
+ if (val & CLKSWITCH) {
+ val >>= CLKSEL_SHIFT;
+ val &= CLKSEL_MASK;
+ divider = clk_div[val];
+ } else
+ divider = 1;
+ }
+
+ return parent_rate / divider;
+}
+
+static u8 berlin_clk_get_parent(struct clk_hw *hw)
+{
+ u32 val;
+ struct berlin_clk *clk = to_berlin_clk(hw);
+
+ val = readl_relaxed(clk->base);
+ if (val & CLKPLLSWITCH) {
+ val >>= CLKPLLSEL_SHIFT;
+ val &= CLKPLLSEL_MASK;
+ return val;
+ }
+
+ return 0;
+}
+
+static const struct clk_ops berlin_clk_ops = {
+ .recalc_rate = berlin_clk_recalc_rate,
+ .get_parent = berlin_clk_get_parent,
+};
+
+static void __init berlin_clk_setup(struct device_node *np)
+{
+ struct clk_init_data init;
+ struct berlin_clk *bclk;
+ struct clk *clk;
+ const char **parent_names;
+ int nparents, i, ret;
+
+ bclk = kzalloc(sizeof(*bclk), GFP_KERNEL);
+ if (WARN_ON(!bclk))
+ return;
+
+ bclk->base = of_iomap(np, 0);
+ if (WARN_ON(!bclk->base))
+ goto exit;
+
+ nparents = of_clk_get_parent_count(np);
+ if (WARN_ON(!nparents))
+ goto exit;
+
+ parent_names = kzalloc((sizeof(char *) * nparents), GFP_KERNEL);
+ if (WARN_ON(!parent_names))
+ goto exit;
+
+ init.name = np->name;
+ init.ops = &berlin_clk_ops;
+ for (i = 0; i < nparents; i++) {
+ parent_names[i] = of_clk_get_parent_name(np, i);
+ if (!parent_names[i])
+ break;
+ }
+ init.parent_names = parent_names;
+ init.num_parents = i;
+
+ bclk->hw.init = &init;
+
+ clk = clk_register(NULL, &bclk->hw);
+ kfree(parent_names);
+ if (WARN_ON(IS_ERR(clk)))
+ goto exit;
+
+ ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
+ WARN_ON(ret);
+
+ return;
+exit:
+ kfree(bclk);
+}
+
+CLK_OF_DECLARE(berlin_clk, "marvell,berlin-clk", berlin_clk_setup);
--
1.9.1
Add sdio clocks to the berlin2.dtsi
Also reorder the PLLs nodes by address
Signed-off-by: Alexandre Belloni <[email protected]>
---
arch/arm/boot/dts/berlin2.dtsi | 42 ++++++++++++++++++++++++++++--------------
1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
index 6c080eb6242a..707fffd7277d 100644
--- a/arch/arm/boot/dts/berlin2.dtsi
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -86,20 +86,6 @@
clocks = <&twdclk>;
};
- syspll: syspll@ea0014 {
- compatible = "marvell,berlin2-pll";
- clocks = <&smclk>;
- #clock-cells = <0>;
- reg = <0xea0014 8>;
- };
-
- cpupll: cpupll@ea003c {
- compatible = "marvell,berlin2-pll";
- clocks = <&smclk>;
- #clock-cells = <0>;
- reg = <0xea003c 8>;
- };
-
apb@e80000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -190,6 +176,34 @@
};
};
+ syspll: syspll@ea0014 {
+ compatible = "marvell,berlin2-pll";
+ clocks = <&smclk>;
+ #clock-cells = <0>;
+ reg = <0xea0014 8>;
+ };
+
+ cpupll: cpupll@ea003c {
+ compatible = "marvell,berlin2-pll";
+ clocks = <&smclk>;
+ #clock-cells = <0>;
+ reg = <0xea003c 8>;
+ };
+
+ sdio0xinclk: sdio0xinclk@ea023c {
+ compatible = "marvell,berlin-clk";
+ clocks = <&syspll>;
+ #clock-cells = <0>;
+ reg = <0xea023c 4>;
+ };
+
+ sdio1xinclk: sdio1xinclk@ea0240 {
+ compatible = "marvell,berlin-clk";
+ clocks = <&syspll>;
+ #clock-cells = <0>;
+ reg = <0xea0240 4>;
+ };
+
apb@fc0000 {
compatible = "simple-bus";
#address-cells = <1>;
--
1.9.1
Add sdio clocks to the berlin2cd.dtsi
Also reorder the PLLs nodes by address
Signed-off-by: Alexandre Belloni <[email protected]>
---
arch/arm/boot/dts/berlin2cd.dtsi | 42 ++++++++++++++++++++++++++--------------
1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
index bd4e9dd4867e..9b3faeee0728 100644
--- a/arch/arm/boot/dts/berlin2cd.dtsi
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -79,20 +79,6 @@
clocks = <&twdclk>;
};
- syspll: syspll@ea0014 {
- compatible = "marvell,berlin2-pll";
- clocks = <&smclk>;
- #clock-cells = <0>;
- reg = <0xf7ea0014 8>;
- };
-
- cpupll: cpupll@ea003c {
- compatible = "marvell,berlin2-pll";
- clocks = <&smclk>;
- #clock-cells = <0>;
- reg = <0xf7ea003c 8>;
- };
-
apb@e80000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -183,6 +169,34 @@
};
};
+ syspll: syspll@ea0014 {
+ compatible = "marvell,berlin2-pll";
+ clocks = <&smclk>;
+ #clock-cells = <0>;
+ reg = <0xf7ea0014 8>;
+ };
+
+ cpupll: cpupll@ea003c {
+ compatible = "marvell,berlin2-pll";
+ clocks = <&smclk>;
+ #clock-cells = <0>;
+ reg = <0xf7ea003c 8>;
+ };
+
+ sdio0xinclk: sdio0xinclk@ea023c {
+ compatible = "marvell,berlin-clk";
+ clocks = <&syspll>;
+ #clock-cells = <0>;
+ reg = <0xea023c 4>;
+ };
+
+ sdio1xinclk: sdio1xinclk@ea0240 {
+ compatible = "marvell,berlin-clk";
+ clocks = <&syspll>;
+ #clock-cells = <0>;
+ reg = <0xea0240 4>;
+ };
+
apb@fc0000 {
compatible = "simple-bus";
#address-cells = <1>;
--
1.9.1
Document the newly added berlin clock driver
Signed-off-by: Alexandre Belloni <[email protected]>
---
Cc: [email protected]
Documentation/devicetree/bindings/clock/berlin-clock.txt | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/clock/berlin-clock.txt b/Documentation/devicetree/bindings/clock/berlin-clock.txt
index 49b7860bffb8..00f0053ef587 100644
--- a/Documentation/devicetree/bindings/clock/berlin-clock.txt
+++ b/Documentation/devicetree/bindings/clock/berlin-clock.txt
@@ -9,6 +9,8 @@ Required properties:
"marvell,berlin2-pll",
"marvell,berlin2q-pll":
CPU PLL and System PLL
+ "marvell,berlin2-clk":
+ simple clocks
- reg: Address and length of the clock register set.
- #clock-cells: from common clock binding; shall be set to 0.
- clocks: from common clock binding
@@ -26,4 +28,9 @@ cpupll: cpupll@ea003c {
reg = <0xea003c 0x8>;
};
-
+sdio0xinclk: sdio0xinclk@ea023c {
+ compatible = "marvell,berlin-clk";
+ clocks = <&syspll>;
+ #clock-cells = <0>;
+ reg = <0xea023c 4>;
+};
--
1.9.1
Add sdio clocks to the berlin2q.dtsi
Also reorder the syspll node
Signed-off-by: Alexandre Belloni <[email protected]>
---
arch/arm/boot/dts/berlin2q.dtsi | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index 5925e6a16749..0fc826305614 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -102,13 +102,6 @@
reg = <0xdd0170 0x8>;
};
- syspll: syspll@ea0030 {
- compatible = "marvell,berlin2q-pll";
- clocks = <&smclk>;
- #clock-cells = <0>;
- reg = <0xea0030 0x8>;
- };
-
apb@e80000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -191,6 +184,27 @@
};
};
+ syspll: syspll@ea0030 {
+ compatible = "marvell,berlin2q-pll";
+ clocks = <&smclk>;
+ #clock-cells = <0>;
+ reg = <0xea0030 0x8>;
+ };
+
+ sdio0xinclk: sdio0xinclk@ea0158 {
+ compatible = "marvell,berlin-clk";
+ clocks = <&syspll>;
+ #clock-cells = <0>;
+ reg = <0xea0158 4>;
+ };
+
+ sdio1xinclk: sdio1xinclk@ea015c {
+ compatible = "marvell,berlin-clk";
+ clocks = <&syspll>;
+ #clock-cells = <0>;
+ reg = <0xea015c 4>;
+ };
+
apb@fc0000 {
compatible = "simple-bus";
#address-cells = <1>;
--
1.9.1
On 04/23/2014 04:01 PM, Alexandre Belloni wrote:
> Add support for clocks having their own register set.
>
> Signed-off-by: Alexandre Belloni <[email protected]>
> ---
> drivers/clk/berlin/Makefile | 2 +-
> drivers/clk/berlin/clk.c | 132 ++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 133 insertions(+), 1 deletion(-)
> create mode 100644 drivers/clk/berlin/clk.c
>
> diff --git a/drivers/clk/berlin/Makefile b/drivers/clk/berlin/Makefile
> index 94859513de90..9bfa58eaf25a 100644
> --- a/drivers/clk/berlin/Makefile
> +++ b/drivers/clk/berlin/Makefile
> @@ -1,4 +1,4 @@
> -obj-y += pll.o
> +obj-y += pll.o clk.o
> obj-$(CONFIG_MACH_BERLIN_BG2) += pll-berlin2.o
> obj-$(CONFIG_MACH_BERLIN_BG2CD) += pll-berlin2.o
> obj-$(CONFIG_MACH_BERLIN_BG2Q) += pll-berlin2q.o
> diff --git a/drivers/clk/berlin/clk.c b/drivers/clk/berlin/clk.c
> new file mode 100644
> index 000000000000..a0e688e5bead
> --- /dev/null
> +++ b/drivers/clk/berlin/clk.c
> @@ -0,0 +1,132 @@
> +/*
> + * Copyright (c) 2014 Marvell Technology Group Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +#include <linux/bitops.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/slab.h>
> +
> +#include "common.h"
> +
> +#define CLKEN (1 << 0)
Alexandre,
please use BIT(n) instead of (1 << n).
> +#define CLKPLLSEL_MASK 7
> +#define CLKPLLSEL_SHIFT 1
> +#define CLKPLLSWITCH (1 << 4)
> +#define CLKSWITCH (1 << 5)
> +#define CLKD3SWITCH (1 << 6)
> +#define CLKSEL_MASK 7
> +#define CLKSEL_SHIFT 7
In general, I would change the above defines to CLK_SEL_MASK, i.e.
add a _ after CLK. While at it (as it can be seen from the code
below), also rename CLK_D3SWITCH to CLK_DIV3_SWITCH.
> +
> +struct berlin_clk {
> + struct clk_hw hw;
> + void __iomem *base;
> +};
> +
> +#define to_berlin_clk(hw) container_of(hw, struct berlin_clk, hw)
> +
> +static u8 clk_div[] = {1, 2, 4, 6, 8, 12, 1, 1};
> +
> +static unsigned long berlin_clk_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + u32 val, divider;
> + struct berlin_clk *clk = to_berlin_clk(hw);
> +
> + val = readl_relaxed(clk->base);
> + if (val & CLKD3SWITCH)
> + divider = 3;
> + else {
> + if (val & CLKSWITCH) {
> + val >>= CLKSEL_SHIFT;
> + val &= CLKSEL_MASK;
> + divider = clk_div[val];
> + } else
> + divider = 1;
> + }
> +
There are stylistic issues:
if-else with one part being enclosed in {} requires both parts
to be enclosed in those curly brackets, i.e.
if (foo)
bar;
else {
foobar;
barfoo;
}
has to become
if (foo) {
bar;
} else {
foobar;
barfoo;
}
How about writing the above
> + val = readl_relaxed(clk->base);
> + if (val & CLKD3SWITCH)
> + divider = 3;
> + else {
> + if (val & CLKSWITCH) {
> + val >>= CLKSEL_SHIFT;
> + val &= CLKSEL_MASK;
> + divider = clk_div[val];
> + } else
> + divider = 1;
> + }
> + return parent_rate / divider;
> +}
> +
> +static u8 berlin_clk_get_parent(struct clk_hw *hw)
> +{
> + u32 val;
> + struct berlin_clk *clk = to_berlin_clk(hw);
> +
> + val = readl_relaxed(clk->base);
> + if (val & CLKPLLSWITCH) {
> + val >>= CLKPLLSEL_SHIFT;
> + val &= CLKPLLSEL_MASK;
> + return val;
> + }
> +
> + return 0;
> +}
> +
> +static const struct clk_ops berlin_clk_ops = {
> + .recalc_rate = berlin_clk_recalc_rate,
> + .get_parent = berlin_clk_get_parent,
> +};
> +
> +static void __init berlin_clk_setup(struct device_node *np)
> +{
> + struct clk_init_data init;
> + struct berlin_clk *bclk;
> + struct clk *clk;
> + const char **parent_names;
> + int nparents, i, ret;
> +
> + bclk = kzalloc(sizeof(*bclk), GFP_KERNEL);
> + if (WARN_ON(!bclk))
> + return;
> +
> + bclk->base = of_iomap(np, 0);
> + if (WARN_ON(!bclk->base))
> + goto exit;
> +
> + nparents = of_clk_get_parent_count(np);
> + if (WARN_ON(!nparents))
> + goto exit;
> +
> + parent_names = kzalloc((sizeof(char *) * nparents), GFP_KERNEL);
> + if (WARN_ON(!parent_names))
> + goto exit;
> +
> + init.name = np->name;
> + init.ops = &berlin_clk_ops;
> + for (i = 0; i < nparents; i++) {
> + parent_names[i] = of_clk_get_parent_name(np, i);
> + if (!parent_names[i])
> + break;
> + }
> + init.parent_names = parent_names;
> + init.num_parents = i;
> +
> + bclk->hw.init = &init;
> +
> + clk = clk_register(NULL, &bclk->hw);
> + kfree(parent_names);
> + if (WARN_ON(IS_ERR(clk)))
> + goto exit;
> +
> + ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
> + WARN_ON(ret);
> +
> + return;
> +exit:
> + kfree(bclk);
> +}
> +
> +CLK_OF_DECLARE(berlin_clk, "marvell,berlin-clk", berlin_clk_setup);
>
On 04/23/2014 07:03 PM, Sebastian Hesselbarth wrote:
> On 04/23/2014 04:01 PM, Alexandre Belloni wrote:
>> Add support for clocks having their own register set.
>>
>> Signed-off-by: Alexandre Belloni <[email protected]>
>> ---
>> drivers/clk/berlin/Makefile | 2 +-
>> drivers/clk/berlin/clk.c | 132 ++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 133 insertions(+), 1 deletion(-)
>> create mode 100644 drivers/clk/berlin/clk.c
>>
>> diff --git a/drivers/clk/berlin/Makefile b/drivers/clk/berlin/Makefile
>> index 94859513de90..9bfa58eaf25a 100644
>> --- a/drivers/clk/berlin/Makefile
>> +++ b/drivers/clk/berlin/Makefile
>> @@ -1,4 +1,4 @@
>> -obj-y += pll.o
>> +obj-y += pll.o clk.o
>> obj-$(CONFIG_MACH_BERLIN_BG2) += pll-berlin2.o
>> obj-$(CONFIG_MACH_BERLIN_BG2CD) += pll-berlin2.o
>> obj-$(CONFIG_MACH_BERLIN_BG2Q) += pll-berlin2q.o
>> diff --git a/drivers/clk/berlin/clk.c b/drivers/clk/berlin/clk.c
>> new file mode 100644
>> index 000000000000..a0e688e5bead
>> --- /dev/null
>> +++ b/drivers/clk/berlin/clk.c
>> @@ -0,0 +1,132 @@
>> +/*
>> + * Copyright (c) 2014 Marvell Technology Group Ltd.
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
>> + * more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program. If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +#include <linux/bitops.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/slab.h>
>> +
>> +#include "common.h"
>> +
>> +#define CLKEN (1 << 0)
>
> Alexandre,
>
> please use BIT(n) instead of (1 << n).
>
>> +#define CLKPLLSEL_MASK 7
>> +#define CLKPLLSEL_SHIFT 1
>> +#define CLKPLLSWITCH (1 << 4)
>> +#define CLKSWITCH (1 << 5)
>> +#define CLKD3SWITCH (1 << 6)
>> +#define CLKSEL_MASK 7
>> +#define CLKSEL_SHIFT 7
>
> In general, I would change the above defines to CLK_SEL_MASK, i.e.
> add a _ after CLK. While at it (as it can be seen from the code
> below), also rename CLK_D3SWITCH to CLK_DIV3_SWITCH.
>
>> +
>> +struct berlin_clk {
>> + struct clk_hw hw;
>> + void __iomem *base;
>> +};
>> +
>> +#define to_berlin_clk(hw) container_of(hw, struct berlin_clk, hw)
>> +
>> +static u8 clk_div[] = {1, 2, 4, 6, 8, 12, 1, 1};
>> +
>> +static unsigned long berlin_clk_recalc_rate(struct clk_hw *hw,
>> + unsigned long parent_rate)
>> +{
>> + u32 val, divider;
>> + struct berlin_clk *clk = to_berlin_clk(hw);
>> +
>> + val = readl_relaxed(clk->base);
>> + if (val & CLKD3SWITCH)
>> + divider = 3;
>> + else {
>> + if (val & CLKSWITCH) {
>> + val >>= CLKSEL_SHIFT;
>> + val &= CLKSEL_MASK;
>> + divider = clk_div[val];
>> + } else
>> + divider = 1;
>> + }
>> +
>
> There are stylistic issues:
>
> if-else with one part being enclosed in {} requires both parts
> to be enclosed in those curly brackets, i.e.
>
> if (foo)
> bar;
> else {
> foobar;
> barfoo;
> }
>
> has to become
>
> if (foo) {
> bar;
> } else {
> foobar;
> barfoo;
> }
>
> How about writing the above
Grr, I wasn't done with my review but who the f*ck puts
"Send now" on ^D ?
So, how about writing the above
val = readl_relaxed(clk->base);
divider = 1;
if (val & CLKD3SWITCH) {
divider = 3;
} else if (val & CLKSWITCH) {
val >>= CLKSEL_SHIFT;
val &= CLKSEL_MASK;
divider = clk_div[val];
}
>> + return parent_rate / divider;
>> +}
>> +
>> +static u8 berlin_clk_get_parent(struct clk_hw *hw)
>> +{
>> + u32 val;
>> + struct berlin_clk *clk = to_berlin_clk(hw);
>> +
>> + val = readl_relaxed(clk->base);
>> + if (val & CLKPLLSWITCH) {
>> + val >>= CLKPLLSEL_SHIFT;
>> + val &= CLKPLLSEL_MASK;
>> + return val;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static const struct clk_ops berlin_clk_ops = {
>> + .recalc_rate = berlin_clk_recalc_rate,
>> + .get_parent = berlin_clk_get_parent,
>> +};
>> +
>> +static void __init berlin_clk_setup(struct device_node *np)
>> +{
>> + struct clk_init_data init;
>> + struct berlin_clk *bclk;
>> + struct clk *clk;
>> + const char **parent_names;
>> + int nparents, i, ret;
>> +
>> + bclk = kzalloc(sizeof(*bclk), GFP_KERNEL);
>> + if (WARN_ON(!bclk))
>> + return;
>> +
>> + bclk->base = of_iomap(np, 0);
>> + if (WARN_ON(!bclk->base))
>> + goto exit;
>> +
>> + nparents = of_clk_get_parent_count(np);
>> + if (WARN_ON(!nparents))
>> + goto exit;
>> +
>> + parent_names = kzalloc((sizeof(char *) * nparents), GFP_KERNEL);
No need to put () around the calculation above. Also, if you put
nparents in front it may be more readable.
Sebastian
>> + if (WARN_ON(!parent_names))
>> + goto exit;
>> +
>> + init.name = np->name;
>> + init.ops = &berlin_clk_ops;
>> + for (i = 0; i < nparents; i++) {
>> + parent_names[i] = of_clk_get_parent_name(np, i);
>> + if (!parent_names[i])
>> + break;
>> + }
>> + init.parent_names = parent_names;
>> + init.num_parents = i;
>> +
>> + bclk->hw.init = &init;
>> +
>> + clk = clk_register(NULL, &bclk->hw);
>> + kfree(parent_names);
>> + if (WARN_ON(IS_ERR(clk)))
>> + goto exit;
>> +
>> + ret = of_clk_add_provider(np, of_clk_src_simple_get, clk);
>> + WARN_ON(ret);
>> +
>> + return;
>> +exit:
>> + kfree(bclk);
>> +}
>> +
>> +CLK_OF_DECLARE(berlin_clk, "marvell,berlin-clk", berlin_clk_setup);
>>
>
On 04/23/2014 04:01 PM, Alexandre Belloni wrote:
> Document the newly added berlin clock driver
>
> Signed-off-by: Alexandre Belloni <[email protected]>
> ---
> Cc: [email protected]
> Documentation/devicetree/bindings/clock/berlin-clock.txt | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/clock/berlin-clock.txt b/Documentation/devicetree/bindings/clock/berlin-clock.txt
> index 49b7860bffb8..00f0053ef587 100644
> --- a/Documentation/devicetree/bindings/clock/berlin-clock.txt
> +++ b/Documentation/devicetree/bindings/clock/berlin-clock.txt
> @@ -9,6 +9,8 @@ Required properties:
> "marvell,berlin2-pll",
> "marvell,berlin2q-pll":
> CPU PLL and System PLL
> + "marvell,berlin2-clk":
> + simple clocks
> - reg: Address and length of the clock register set.
> - #clock-cells: from common clock binding; shall be set to 0.
> - clocks: from common clock binding
> @@ -26,4 +28,9 @@ cpupll: cpupll@ea003c {
> reg = <0xea003c 0x8>;
> };
>
> -
> +sdio0xinclk: sdio0xinclk@ea023c {
Yuck! ;)
Can't we just simply use "clock@<addr>" for the node name and
have the driver compute the name like simple-bus does?
Sebastian
> + compatible = "marvell,berlin-clk";
> + clocks = <&syspll>;
> + #clock-cells = <0>;
> + reg = <0xea023c 4>;
> +};
>
Alexandre,
On Wed, Apr 23, 2014 at 04:01:07PM +0200, Alexandre Belloni wrote:
> Add sdio clocks to the berlin2q.dtsi
> Also reorder the syspll node
>
> Signed-off-by: Alexandre Belloni <[email protected]>
> ---
> arch/arm/boot/dts/berlin2q.dtsi | 28 +++++++++++++++++++++-------
> 1 file changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
> index 5925e6a16749..0fc826305614 100644
> --- a/arch/arm/boot/dts/berlin2q.dtsi
> +++ b/arch/arm/boot/dts/berlin2q.dtsi
> @@ -102,13 +102,6 @@
> reg = <0xdd0170 0x8>;
> };
>
> - syspll: syspll@ea0030 {
> - compatible = "marvell,berlin2q-pll";
> - clocks = <&smclk>;
> - #clock-cells = <0>;
> - reg = <0xea0030 0x8>;
> - };
> -
> apb@e80000 {
> compatible = "simple-bus";
> #address-cells = <1>;
> @@ -191,6 +184,27 @@
> };
> };
>
> + syspll: syspll@ea0030 {
> + compatible = "marvell,berlin2q-pll";
> + clocks = <&smclk>;
> + #clock-cells = <0>;
> + reg = <0xea0030 0x8>;
> + };
> +
> + sdio0xinclk: sdio0xinclk@ea0158 {
> + compatible = "marvell,berlin-clk";
> + clocks = <&syspll>;
> + #clock-cells = <0>;
> + reg = <0xea0158 4>;
I believe you can use
reg = <0xea0158 0x4>;
since you used an hex value in the previous node. Plus we tend to use
hex values elsewhere too.
> + };
> +
> + sdio1xinclk: sdio1xinclk@ea015c {
> + compatible = "marvell,berlin-clk";
> + clocks = <&syspll>;
> + #clock-cells = <0>;
> + reg = <0xea015c 4>;
Ditto. This also applies to BG2/BG2CD and the documentation patches.
Thanks!
Antoine
> + };
> +
> apb@fc0000 {
> compatible = "simple-bus";
> #address-cells = <1>;
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Antoine T?nart, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
Alexandre,
On Wed, Apr 23, 2014 at 04:01:06PM +0200, Alexandre Belloni wrote:
> Add sdio clocks to the berlin2cd.dtsi
> Also reorder the PLLs nodes by address
>
> Signed-off-by: Alexandre Belloni <[email protected]>
> ---
> arch/arm/boot/dts/berlin2cd.dtsi | 42 ++++++++++++++++++++++++++--------------
> 1 file changed, 28 insertions(+), 14 deletions(-)
>
> diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
> index bd4e9dd4867e..9b3faeee0728 100644
> --- a/arch/arm/boot/dts/berlin2cd.dtsi
> +++ b/arch/arm/boot/dts/berlin2cd.dtsi
> @@ -79,20 +79,6 @@
> clocks = <&twdclk>;
> };
>
> - syspll: syspll@ea0014 {
> - compatible = "marvell,berlin2-pll";
> - clocks = <&smclk>;
> - #clock-cells = <0>;
> - reg = <0xf7ea0014 8>;
> - };
> -
> - cpupll: cpupll@ea003c {
> - compatible = "marvell,berlin2-pll";
> - clocks = <&smclk>;
> - #clock-cells = <0>;
> - reg = <0xf7ea003c 8>;
> - };
> -
> apb@e80000 {
> compatible = "simple-bus";
> #address-cells = <1>;
> @@ -183,6 +169,34 @@
> };
> };
>
> + syspll: syspll@ea0014 {
> + compatible = "marvell,berlin2-pll";
> + clocks = <&smclk>;
> + #clock-cells = <0>;
> + reg = <0xf7ea0014 8>;
You can drop the 'f7' here
> + };
> +
> + cpupll: cpupll@ea003c {
> + compatible = "marvell,berlin2-pll";
> + clocks = <&smclk>;
> + #clock-cells = <0>;
> + reg = <0xf7ea003c 8>;
and here.
Thanks!
Antoine
> + };
> +
> + sdio0xinclk: sdio0xinclk@ea023c {
> + compatible = "marvell,berlin-clk";
> + clocks = <&syspll>;
> + #clock-cells = <0>;
> + reg = <0xea023c 4>;
> + };
> +
> + sdio1xinclk: sdio1xinclk@ea0240 {
> + compatible = "marvell,berlin-clk";
> + clocks = <&syspll>;
> + #clock-cells = <0>;
> + reg = <0xea0240 4>;
> + };
> +
> apb@fc0000 {
> compatible = "simple-bus";
> #address-cells = <1>;
> --
> 1.9.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
Antoine T?nart, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com