]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
clk: at91: move slow clock controller clocks to sckc.c
authorAlexandre Belloni <alexandre.belloni@free-electrons.com>
Tue, 20 Sep 2016 20:58:29 +0000 (22:58 +0200)
committerStephen Boyd <sboyd@codeaurora.org>
Wed, 21 Sep 2016 00:02:38 +0000 (17:02 -0700)
Move all clocks related to the slow clock controller to sckc.c. This avoids
extern definitions and allows to remove sckc.h

Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
[sboyd@codeaurora.org: Mark some functions static]
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
drivers/clk/at91/clk-slow.c
drivers/clk/at91/sckc.c
drivers/clk/at91/sckc.h [deleted file]

index cd831e19ba72905c4b0ea43da7524e5c980bd938..560a8b9abf9312bd921311bcf88d121727750c83 100644 (file)
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/clk/at91_pmc.h>
-#include <linux/delay.h>
 #include <linux/of.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 
 #include "pmc.h"
-#include "sckc.h"
-
-#define SLOW_CLOCK_FREQ                32768
-#define SLOWCK_SW_CYCLES       5
-#define SLOWCK_SW_TIME_USEC    ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
-                                SLOW_CLOCK_FREQ)
-
-#define        AT91_SCKC_CR                    0x00
-#define                AT91_SCKC_RCEN          (1 << 0)
-#define                AT91_SCKC_OSC32EN       (1 << 1)
-#define                AT91_SCKC_OSC32BYP      (1 << 2)
-#define                AT91_SCKC_OSCSEL        (1 << 3)
-
-struct clk_slow_osc {
-       struct clk_hw hw;
-       void __iomem *sckcr;
-       unsigned long startup_usec;
-};
-
-#define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)
-
-struct clk_slow_rc_osc {
-       struct clk_hw hw;
-       void __iomem *sckcr;
-       unsigned long frequency;
-       unsigned long accuracy;
-       unsigned long startup_usec;
-};
-
-#define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)
 
 struct clk_sam9260_slow {
        struct clk_hw hw;
@@ -57,340 +26,6 @@ struct clk_sam9260_slow {
 
 #define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw)
 
-struct clk_sam9x5_slow {
-       struct clk_hw hw;
-       void __iomem *sckcr;
-       u8 parent;
-};
-
-#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
-
-static int clk_slow_osc_prepare(struct clk_hw *hw)
-{
-       struct clk_slow_osc *osc = to_clk_slow_osc(hw);
-       void __iomem *sckcr = osc->sckcr;
-       u32 tmp = readl(sckcr);
-
-       if (tmp & AT91_SCKC_OSC32BYP)
-               return 0;
-
-       writel(tmp | AT91_SCKC_OSC32EN, sckcr);
-
-       usleep_range(osc->startup_usec, osc->startup_usec + 1);
-
-       return 0;
-}
-
-static void clk_slow_osc_unprepare(struct clk_hw *hw)
-{
-       struct clk_slow_osc *osc = to_clk_slow_osc(hw);
-       void __iomem *sckcr = osc->sckcr;
-       u32 tmp = readl(sckcr);
-
-       if (tmp & AT91_SCKC_OSC32BYP)
-               return;
-
-       writel(tmp & ~AT91_SCKC_OSC32EN, sckcr);
-}
-
-static int clk_slow_osc_is_prepared(struct clk_hw *hw)
-{
-       struct clk_slow_osc *osc = to_clk_slow_osc(hw);
-       void __iomem *sckcr = osc->sckcr;
-       u32 tmp = readl(sckcr);
-
-       if (tmp & AT91_SCKC_OSC32BYP)
-               return 1;
-
-       return !!(tmp & AT91_SCKC_OSC32EN);
-}
-
-static const struct clk_ops slow_osc_ops = {
-       .prepare = clk_slow_osc_prepare,
-       .unprepare = clk_slow_osc_unprepare,
-       .is_prepared = clk_slow_osc_is_prepared,
-};
-
-static struct clk_hw * __init
-at91_clk_register_slow_osc(void __iomem *sckcr,
-                          const char *name,
-                          const char *parent_name,
-                          unsigned long startup,
-                          bool bypass)
-{
-       struct clk_slow_osc *osc;
-       struct clk_hw *hw;
-       struct clk_init_data init;
-       int ret;
-
-       if (!sckcr || !name || !parent_name)
-               return ERR_PTR(-EINVAL);
-
-       osc = kzalloc(sizeof(*osc), GFP_KERNEL);
-       if (!osc)
-               return ERR_PTR(-ENOMEM);
-
-       init.name = name;
-       init.ops = &slow_osc_ops;
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
-       init.flags = CLK_IGNORE_UNUSED;
-
-       osc->hw.init = &init;
-       osc->sckcr = sckcr;
-       osc->startup_usec = startup;
-
-       if (bypass)
-               writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP,
-                      sckcr);
-
-       hw = &osc->hw;
-       ret = clk_hw_register(NULL, &osc->hw);
-       if (ret) {
-               kfree(osc);
-               hw = ERR_PTR(ret);
-       }
-
-       return hw;
-}
-
-void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np,
-                                            void __iomem *sckcr)
-{
-       struct clk_hw *hw;
-       const char *parent_name;
-       const char *name = np->name;
-       u32 startup;
-       bool bypass;
-
-       parent_name = of_clk_get_parent_name(np, 0);
-       of_property_read_string(np, "clock-output-names", &name);
-       of_property_read_u32(np, "atmel,startup-time-usec", &startup);
-       bypass = of_property_read_bool(np, "atmel,osc-bypass");
-
-       hw = at91_clk_register_slow_osc(sckcr, name, parent_name, startup,
-                                        bypass);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-
-static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
-                                                unsigned long parent_rate)
-{
-       struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
-
-       return osc->frequency;
-}
-
-static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw,
-                                                    unsigned long parent_acc)
-{
-       struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
-
-       return osc->accuracy;
-}
-
-static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
-{
-       struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
-       void __iomem *sckcr = osc->sckcr;
-
-       writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr);
-
-       usleep_range(osc->startup_usec, osc->startup_usec + 1);
-
-       return 0;
-}
-
-static void clk_slow_rc_osc_unprepare(struct clk_hw *hw)
-{
-       struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
-       void __iomem *sckcr = osc->sckcr;
-
-       writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr);
-}
-
-static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw)
-{
-       struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
-
-       return !!(readl(osc->sckcr) & AT91_SCKC_RCEN);
-}
-
-static const struct clk_ops slow_rc_osc_ops = {
-       .prepare = clk_slow_rc_osc_prepare,
-       .unprepare = clk_slow_rc_osc_unprepare,
-       .is_prepared = clk_slow_rc_osc_is_prepared,
-       .recalc_rate = clk_slow_rc_osc_recalc_rate,
-       .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
-};
-
-static struct clk_hw * __init
-at91_clk_register_slow_rc_osc(void __iomem *sckcr,
-                             const char *name,
-                             unsigned long frequency,
-                             unsigned long accuracy,
-                             unsigned long startup)
-{
-       struct clk_slow_rc_osc *osc;
-       struct clk_hw *hw;
-       struct clk_init_data init;
-       int ret;
-
-       if (!sckcr || !name)
-               return ERR_PTR(-EINVAL);
-
-       osc = kzalloc(sizeof(*osc), GFP_KERNEL);
-       if (!osc)
-               return ERR_PTR(-ENOMEM);
-
-       init.name = name;
-       init.ops = &slow_rc_osc_ops;
-       init.parent_names = NULL;
-       init.num_parents = 0;
-       init.flags = CLK_IGNORE_UNUSED;
-
-       osc->hw.init = &init;
-       osc->sckcr = sckcr;
-       osc->frequency = frequency;
-       osc->accuracy = accuracy;
-       osc->startup_usec = startup;
-
-       hw = &osc->hw;
-       ret = clk_hw_register(NULL, &osc->hw);
-       if (ret) {
-               kfree(osc);
-               hw = ERR_PTR(ret);
-       }
-
-       return hw;
-}
-
-void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np,
-                                               void __iomem *sckcr)
-{
-       struct clk_hw *hw;
-       u32 frequency = 0;
-       u32 accuracy = 0;
-       u32 startup = 0;
-       const char *name = np->name;
-
-       of_property_read_string(np, "clock-output-names", &name);
-       of_property_read_u32(np, "clock-frequency", &frequency);
-       of_property_read_u32(np, "clock-accuracy", &accuracy);
-       of_property_read_u32(np, "atmel,startup-time-usec", &startup);
-
-       hw = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy,
-                                           startup);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-
-static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
-{
-       struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
-       void __iomem *sckcr = slowck->sckcr;
-       u32 tmp;
-
-       if (index > 1)
-               return -EINVAL;
-
-       tmp = readl(sckcr);
-
-       if ((!index && !(tmp & AT91_SCKC_OSCSEL)) ||
-           (index && (tmp & AT91_SCKC_OSCSEL)))
-               return 0;
-
-       if (index)
-               tmp |= AT91_SCKC_OSCSEL;
-       else
-               tmp &= ~AT91_SCKC_OSCSEL;
-
-       writel(tmp, sckcr);
-
-       usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
-
-       return 0;
-}
-
-static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
-{
-       struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
-
-       return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL);
-}
-
-static const struct clk_ops sam9x5_slow_ops = {
-       .set_parent = clk_sam9x5_slow_set_parent,
-       .get_parent = clk_sam9x5_slow_get_parent,
-};
-
-static struct clk_hw * __init
-at91_clk_register_sam9x5_slow(void __iomem *sckcr,
-                             const char *name,
-                             const char **parent_names,
-                             int num_parents)
-{
-       struct clk_sam9x5_slow *slowck;
-       struct clk_hw *hw;
-       struct clk_init_data init;
-       int ret;
-
-       if (!sckcr || !name || !parent_names || !num_parents)
-               return ERR_PTR(-EINVAL);
-
-       slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
-       if (!slowck)
-               return ERR_PTR(-ENOMEM);
-
-       init.name = name;
-       init.ops = &sam9x5_slow_ops;
-       init.parent_names = parent_names;
-       init.num_parents = num_parents;
-       init.flags = 0;
-
-       slowck->hw.init = &init;
-       slowck->sckcr = sckcr;
-       slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL);
-
-       hw = &slowck->hw;
-       ret = clk_hw_register(NULL, &slowck->hw);
-       if (ret) {
-               kfree(slowck);
-               hw = ERR_PTR(ret);
-       }
-
-       return hw;
-}
-
-void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
-                                        void __iomem *sckcr)
-{
-       struct clk_hw *hw;
-       const char *parent_names[2];
-       unsigned int num_parents;
-       const char *name = np->name;
-
-       num_parents = of_clk_get_parent_count(np);
-       if (num_parents == 0 || num_parents > 2)
-               return;
-
-       of_clk_parent_fill(np, parent_names, num_parents);
-
-       of_property_read_string(np, "clock-output-names", &name);
-
-       hw = at91_clk_register_sam9x5_slow(sckcr, name, parent_names,
-                                           num_parents);
-       if (IS_ERR(hw))
-               return;
-
-       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
-}
-
 static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw)
 {
        struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw);
index 1184d76a7ab737d87f838a25d68b8f4ca73da5fd..311956abf4aa05fc6bd9f1f4d799cb33b5363394 100644 (file)
 
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
+#include <linux/delay.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/io.h>
 
-#include "sckc.h"
+#define SLOW_CLOCK_FREQ                32768
+#define SLOWCK_SW_CYCLES       5
+#define SLOWCK_SW_TIME_USEC    ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
+                                SLOW_CLOCK_FREQ)
+
+#define        AT91_SCKC_CR                    0x00
+#define                AT91_SCKC_RCEN          (1 << 0)
+#define                AT91_SCKC_OSC32EN       (1 << 1)
+#define                AT91_SCKC_OSC32BYP      (1 << 2)
+#define                AT91_SCKC_OSCSEL        (1 << 3)
+
+struct clk_slow_osc {
+       struct clk_hw hw;
+       void __iomem *sckcr;
+       unsigned long startup_usec;
+};
+
+#define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)
+
+struct clk_slow_rc_osc {
+       struct clk_hw hw;
+       void __iomem *sckcr;
+       unsigned long frequency;
+       unsigned long accuracy;
+       unsigned long startup_usec;
+};
+
+#define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)
+
+struct clk_sam9x5_slow {
+       struct clk_hw hw;
+       void __iomem *sckcr;
+       u8 parent;
+};
+
+#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
+
+static int clk_slow_osc_prepare(struct clk_hw *hw)
+{
+       struct clk_slow_osc *osc = to_clk_slow_osc(hw);
+       void __iomem *sckcr = osc->sckcr;
+       u32 tmp = readl(sckcr);
+
+       if (tmp & AT91_SCKC_OSC32BYP)
+               return 0;
+
+       writel(tmp | AT91_SCKC_OSC32EN, sckcr);
+
+       usleep_range(osc->startup_usec, osc->startup_usec + 1);
+
+       return 0;
+}
+
+static void clk_slow_osc_unprepare(struct clk_hw *hw)
+{
+       struct clk_slow_osc *osc = to_clk_slow_osc(hw);
+       void __iomem *sckcr = osc->sckcr;
+       u32 tmp = readl(sckcr);
+
+       if (tmp & AT91_SCKC_OSC32BYP)
+               return;
+
+       writel(tmp & ~AT91_SCKC_OSC32EN, sckcr);
+}
+
+static int clk_slow_osc_is_prepared(struct clk_hw *hw)
+{
+       struct clk_slow_osc *osc = to_clk_slow_osc(hw);
+       void __iomem *sckcr = osc->sckcr;
+       u32 tmp = readl(sckcr);
+
+       if (tmp & AT91_SCKC_OSC32BYP)
+               return 1;
+
+       return !!(tmp & AT91_SCKC_OSC32EN);
+}
+
+static const struct clk_ops slow_osc_ops = {
+       .prepare = clk_slow_osc_prepare,
+       .unprepare = clk_slow_osc_unprepare,
+       .is_prepared = clk_slow_osc_is_prepared,
+};
+
+static struct clk_hw * __init
+at91_clk_register_slow_osc(void __iomem *sckcr,
+                          const char *name,
+                          const char *parent_name,
+                          unsigned long startup,
+                          bool bypass)
+{
+       struct clk_slow_osc *osc;
+       struct clk_hw *hw;
+       struct clk_init_data init;
+       int ret;
+
+       if (!sckcr || !name || !parent_name)
+               return ERR_PTR(-EINVAL);
+
+       osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+       if (!osc)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &slow_osc_ops;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+       init.flags = CLK_IGNORE_UNUSED;
+
+       osc->hw.init = &init;
+       osc->sckcr = sckcr;
+       osc->startup_usec = startup;
+
+       if (bypass)
+               writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP,
+                      sckcr);
+
+       hw = &osc->hw;
+       ret = clk_hw_register(NULL, &osc->hw);
+       if (ret) {
+               kfree(osc);
+               hw = ERR_PTR(ret);
+       }
+
+       return hw;
+}
+
+static void __init
+of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, void __iomem *sckcr)
+{
+       struct clk_hw *hw;
+       const char *parent_name;
+       const char *name = np->name;
+       u32 startup;
+       bool bypass;
+
+       parent_name = of_clk_get_parent_name(np, 0);
+       of_property_read_string(np, "clock-output-names", &name);
+       of_property_read_u32(np, "atmel,startup-time-usec", &startup);
+       bypass = of_property_read_bool(np, "atmel,osc-bypass");
+
+       hw = at91_clk_register_slow_osc(sckcr, name, parent_name, startup,
+                                        bypass);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+
+static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw,
+                                                unsigned long parent_rate)
+{
+       struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
+
+       return osc->frequency;
+}
+
+static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw,
+                                                    unsigned long parent_acc)
+{
+       struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
+
+       return osc->accuracy;
+}
+
+static int clk_slow_rc_osc_prepare(struct clk_hw *hw)
+{
+       struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
+       void __iomem *sckcr = osc->sckcr;
+
+       writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr);
+
+       usleep_range(osc->startup_usec, osc->startup_usec + 1);
+
+       return 0;
+}
+
+static void clk_slow_rc_osc_unprepare(struct clk_hw *hw)
+{
+       struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
+       void __iomem *sckcr = osc->sckcr;
+
+       writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr);
+}
+
+static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw)
+{
+       struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw);
+
+       return !!(readl(osc->sckcr) & AT91_SCKC_RCEN);
+}
+
+static const struct clk_ops slow_rc_osc_ops = {
+       .prepare = clk_slow_rc_osc_prepare,
+       .unprepare = clk_slow_rc_osc_unprepare,
+       .is_prepared = clk_slow_rc_osc_is_prepared,
+       .recalc_rate = clk_slow_rc_osc_recalc_rate,
+       .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy,
+};
+
+static struct clk_hw * __init
+at91_clk_register_slow_rc_osc(void __iomem *sckcr,
+                             const char *name,
+                             unsigned long frequency,
+                             unsigned long accuracy,
+                             unsigned long startup)
+{
+       struct clk_slow_rc_osc *osc;
+       struct clk_hw *hw;
+       struct clk_init_data init;
+       int ret;
+
+       if (!sckcr || !name)
+               return ERR_PTR(-EINVAL);
+
+       osc = kzalloc(sizeof(*osc), GFP_KERNEL);
+       if (!osc)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &slow_rc_osc_ops;
+       init.parent_names = NULL;
+       init.num_parents = 0;
+       init.flags = CLK_IGNORE_UNUSED;
+
+       osc->hw.init = &init;
+       osc->sckcr = sckcr;
+       osc->frequency = frequency;
+       osc->accuracy = accuracy;
+       osc->startup_usec = startup;
+
+       hw = &osc->hw;
+       ret = clk_hw_register(NULL, &osc->hw);
+       if (ret) {
+               kfree(osc);
+               hw = ERR_PTR(ret);
+       }
+
+       return hw;
+}
+
+static void __init
+of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, void __iomem *sckcr)
+{
+       struct clk_hw *hw;
+       u32 frequency = 0;
+       u32 accuracy = 0;
+       u32 startup = 0;
+       const char *name = np->name;
+
+       of_property_read_string(np, "clock-output-names", &name);
+       of_property_read_u32(np, "clock-frequency", &frequency);
+       of_property_read_u32(np, "clock-accuracy", &accuracy);
+       of_property_read_u32(np, "atmel,startup-time-usec", &startup);
+
+       hw = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy,
+                                           startup);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
+
+static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
+       void __iomem *sckcr = slowck->sckcr;
+       u32 tmp;
+
+       if (index > 1)
+               return -EINVAL;
+
+       tmp = readl(sckcr);
+
+       if ((!index && !(tmp & AT91_SCKC_OSCSEL)) ||
+           (index && (tmp & AT91_SCKC_OSCSEL)))
+               return 0;
+
+       if (index)
+               tmp |= AT91_SCKC_OSCSEL;
+       else
+               tmp &= ~AT91_SCKC_OSCSEL;
+
+       writel(tmp, sckcr);
+
+       usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1);
+
+       return 0;
+}
+
+static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw)
+{
+       struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw);
+
+       return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL);
+}
+
+static const struct clk_ops sam9x5_slow_ops = {
+       .set_parent = clk_sam9x5_slow_set_parent,
+       .get_parent = clk_sam9x5_slow_get_parent,
+};
+
+static struct clk_hw * __init
+at91_clk_register_sam9x5_slow(void __iomem *sckcr,
+                             const char *name,
+                             const char **parent_names,
+                             int num_parents)
+{
+       struct clk_sam9x5_slow *slowck;
+       struct clk_hw *hw;
+       struct clk_init_data init;
+       int ret;
+
+       if (!sckcr || !name || !parent_names || !num_parents)
+               return ERR_PTR(-EINVAL);
+
+       slowck = kzalloc(sizeof(*slowck), GFP_KERNEL);
+       if (!slowck)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &sam9x5_slow_ops;
+       init.parent_names = parent_names;
+       init.num_parents = num_parents;
+       init.flags = 0;
+
+       slowck->hw.init = &init;
+       slowck->sckcr = sckcr;
+       slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL);
+
+       hw = &slowck->hw;
+       ret = clk_hw_register(NULL, &slowck->hw);
+       if (ret) {
+               kfree(slowck);
+               hw = ERR_PTR(ret);
+       }
+
+       return hw;
+}
+
+static void __init
+of_at91sam9x5_clk_slow_setup(struct device_node *np, void __iomem *sckcr)
+{
+       struct clk_hw *hw;
+       const char *parent_names[2];
+       unsigned int num_parents;
+       const char *name = np->name;
+
+       num_parents = of_clk_get_parent_count(np);
+       if (num_parents == 0 || num_parents > 2)
+               return;
+
+       of_clk_parent_fill(np, parent_names, num_parents);
+
+       of_property_read_string(np, "clock-output-names", &name);
+
+       hw = at91_clk_register_sam9x5_slow(sckcr, name, parent_names,
+                                           num_parents);
+       if (IS_ERR(hw))
+               return;
+
+       of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
+}
 
 static const struct of_device_id sckc_clk_ids[] __initconst = {
        /* Slow clock */
diff --git a/drivers/clk/at91/sckc.h b/drivers/clk/at91/sckc.h
deleted file mode 100644 (file)
index 836fcf5..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * drivers/clk/at91/sckc.h
- *
- *  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.
- */
-
-#ifndef __AT91_SCKC_H_
-#define __AT91_SCKC_H_
-
-extern void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np,
-                                                   void __iomem *sckcr);
-extern void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np,
-                                                      void __iomem *sckcr);
-extern void __init of_at91sam9x5_clk_slow_setup(struct device_node *np,
-                                               void __iomem *sckcr);
-
-#endif /* __AT91_SCKC_H_ */