]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge branch 'for-v3.18/ti-clk-driver' of github.com:t-kristo/linux-pm into clk-next
authorMike Turquette <mturquette@linaro.org>
Tue, 30 Sep 2014 06:38:59 +0000 (23:38 -0700)
committerMike Turquette <mturquette@linaro.org>
Tue, 30 Sep 2014 06:38:59 +0000 (23:38 -0700)
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/prm_common.c
drivers/clk/ti/clk-dra7-atl.c
drivers/clk/ti/clk.c
drivers/clk/ti/clockdomain.c
drivers/clk/ti/divider.c
include/linux/clk/ti.h

index 5d0667c119f6e6866e23d25d344eb47ddb34472a..a1b82a994842b51c20e4dfccdac7f752c4d740c1 100644 (file)
@@ -734,8 +734,16 @@ int __init omap_clk_init(void)
        ti_clk_init_features();
 
        ret = of_prcm_init();
-       if (!ret)
-               ret = omap_clk_soc_init();
+       if (ret)
+               return ret;
+
+       of_clk_init(NULL);
+
+       ti_dt_clk_init_retry_clks();
+
+       ti_dt_clockdomains_setup();
+
+       ret = omap_clk_soc_init();
 
        return ret;
 }
index 76ca320f007c2158cae69eb494b6215f98acbcbd..3b890807f5e6bcc77d0c72f7168c2bb2fd1c55b1 100644 (file)
@@ -525,8 +525,6 @@ int __init of_prcm_init(void)
                memmap_index++;
        }
 
-       ti_dt_clockdomains_setup();
-
        return 0;
 }
 
index 990e1d9edc01a074d746ab46de149915942ff4e1..59bb4b39d12e799f6d32d8f5a3d898e4dc9d1c46 100644 (file)
@@ -203,6 +203,7 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node)
 
        if (!IS_ERR(clk)) {
                of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               kfree(parent_names);
                return;
        }
 cleanup:
@@ -228,6 +229,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
        cinfo->iobase = of_iomap(node, 0);
        cinfo->dev = &pdev->dev;
        pm_runtime_enable(cinfo->dev);
+       pm_runtime_irq_safe(cinfo->dev);
 
        pm_runtime_get_sync(cinfo->dev);
        atl_write(cinfo, DRA7_ATL_PCLKMUX_REG(0), DRA7_ATL_PCLKMUX);
index b1a6f7144f3fcb10e96608b5247b36f227f04600..337abe5909e1f272cdcdca85e5ae0fb3fe1f4729 100644 (file)
@@ -25,8 +25,8 @@
 #undef pr_fmt
 #define pr_fmt(fmt) "%s: " fmt, __func__
 
-static int ti_dt_clk_memmap_index;
 struct ti_clk_ll_ops *ti_clk_ll_ops;
+static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS];
 
 /**
  * ti_dt_clocks_register - register DT alias clocks during boot
@@ -108,9 +108,21 @@ void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
        struct clk_omap_reg *reg;
        u32 val;
        u32 tmp;
+       int i;
 
        reg = (struct clk_omap_reg *)&tmp;
-       reg->index = ti_dt_clk_memmap_index;
+
+       for (i = 0; i < CLK_MAX_MEMMAPS; i++) {
+               if (clocks_node_ptr[i] == node->parent)
+                       break;
+       }
+
+       if (i == CLK_MAX_MEMMAPS) {
+               pr_err("clk-provider not found for %s!\n", node->name);
+               return NULL;
+       }
+
+       reg->index = i;
 
        if (of_property_read_u32_index(node, "reg", index, &val)) {
                pr_err("%s must have reg[%d]!\n", node->name, index);
@@ -127,20 +139,14 @@ void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
  * @parent: master node
  * @index: internal index for clk_reg_ops
  *
- * Initializes a master clock IP block and its child clock nodes.
- * Regmap is provided for accessing the register space for the
- * IP block and all the clocks under it.
+ * Initializes a master clock IP block. This basically sets up the
+ * mapping from clocks node to the memory map index. All the clocks
+ * are then initialized through the common of_clk_init call, and the
+ * clocks will access their memory maps based on the node layout.
  */
 void ti_dt_clk_init_provider(struct device_node *parent, int index)
 {
-       const struct of_device_id *match;
-       struct device_node *np;
        struct device_node *clocks;
-       of_clk_init_cb_t clk_init_cb;
-       struct clk_init_item *retry;
-       struct clk_init_item *tmp;
-
-       ti_dt_clk_memmap_index = index;
 
        /* get clocks for this parent */
        clocks = of_get_child_by_name(parent, "clocks");
@@ -149,19 +155,31 @@ void ti_dt_clk_init_provider(struct device_node *parent, int index)
                return;
        }
 
-       for_each_child_of_node(clocks, np) {
-               match = of_match_node(&__clk_of_table, np);
-               if (!match)
-                       continue;
-               clk_init_cb = (of_clk_init_cb_t)match->data;
-               pr_debug("%s: initializing: %s\n", __func__, np->name);
-               clk_init_cb(np);
-       }
+       /* add clocks node info */
+       clocks_node_ptr[index] = clocks;
+}
 
-       list_for_each_entry_safe(retry, tmp, &retry_list, link) {
-               pr_debug("retry-init: %s\n", retry->node->name);
-               retry->func(retry->hw, retry->node);
-               list_del(&retry->link);
-               kfree(retry);
+/**
+ * ti_dt_clk_init_retry_clks - init clocks from the retry list
+ *
+ * Initializes any clocks that have failed to initialize before,
+ * reasons being missing parent node(s) during earlier init. This
+ * typically happens only for DPLLs which need to have both of their
+ * parent clocks ready during init.
+ */
+void ti_dt_clk_init_retry_clks(void)
+{
+       struct clk_init_item *retry;
+       struct clk_init_item *tmp;
+       int retries = 5;
+
+       while (!list_empty(&retry_list) && retries) {
+               list_for_each_entry_safe(retry, tmp, &retry_list, link) {
+                       pr_debug("retry-init: %s\n", retry->node->name);
+                       retry->func(retry->hw, retry->node);
+                       list_del(&retry->link);
+                       kfree(retry);
+               }
+               retries--;
        }
 }
index f1e0038d76acd34028764ab52fbfe8d511a4a1ae..b4c5faccaece634c4c9459c6be311f64e4daaf45 100644 (file)
@@ -36,6 +36,11 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
 
        for (i = 0; i < num_clks; i++) {
                clk = of_clk_get(node, i);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: Failed get %s' clock nr %d (%ld)\n",
+                              __func__, node->full_name, i, PTR_ERR(clk));
+                       continue;
+               }
                if (__clk_get_flags(clk) & CLK_IS_BASIC) {
                        pr_warn("can't setup clkdm for basic clk %s\n",
                                __clk_get_name(clk));
index a837f703be658304b7d2a3a0e2743bd17d7077a7..bff2b5b8ff598b2e150496eb3ebc984c651a0ebd 100644 (file)
@@ -300,8 +300,8 @@ static struct clk *_register_divider(struct device *dev, const char *name,
        return clk;
 }
 
-static struct clk_div_table
-__init *ti_clk_get_div_table(struct device_node *node)
+static struct clk_div_table *
+__init ti_clk_get_div_table(struct device_node *node)
 {
        struct clk_div_table *table;
        const __be32 *divspec;
index e8d8a35034a5e81c95e0471d0530f7c87a784db9..f75acbf70e9630631e03bd49e43414d7b3b4b9e3 100644 (file)
@@ -292,6 +292,7 @@ void omap2xxx_clkt_vps_init(void);
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 void ti_dt_clocks_register(struct ti_dt_clk *oclks);
 void ti_dt_clk_init_provider(struct device_node *np, int index);
+void ti_dt_clk_init_retry_clks(void);
 void ti_dt_clockdomains_setup(void);
 int ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
                      ti_of_clk_init_cb_t func);