浏览代码

ARM: OMAP2: clock: add DT boot support for cpufreq_ck

The clock and clkdev for this are added manually.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Tero Kristo 11 年之前
父节点
当前提交
61f25ca76c
共有 3 个文件被更改,包括 56 次插入0 次删除
  1. 53 0
      arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c
  2. 2 0
      drivers/clk/ti/clk-2xxx.c
  3. 1 0
      include/linux/clk/ti.h

+ 53 - 0
arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c

@@ -208,3 +208,56 @@ void omap2xxx_clkt_vps_late_init(void)
 		clk_put(c);
 		clk_put(c);
 	}
 	}
 }
 }
+
+#ifdef CONFIG_OF
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+
+static const struct clk_ops virt_prcm_set_ops = {
+	.recalc_rate	= &omap2_table_mpu_recalc,
+	.set_rate	= &omap2_select_table_rate,
+	.round_rate	= &omap2_round_to_table_rate,
+};
+
+/**
+ * omap2xxx_clkt_vps_init - initialize virt_prcm_set clock
+ *
+ * Does a manual init for the virtual prcm DVFS clock for OMAP2. This
+ * function is called only from omap2 DT clock init, as the virtual
+ * node is not modelled in the DT clock data.
+ */
+void omap2xxx_clkt_vps_init(void)
+{
+	struct clk_init_data init = { NULL };
+	struct clk_hw_omap *hw = NULL;
+	struct clk *clk;
+	const char *parent_name = "mpu_ck";
+	struct clk_lookup *lookup = NULL;
+
+	omap2xxx_clkt_vps_late_init();
+	omap2xxx_clkt_vps_check_bootloader_rates();
+
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+	lookup = kzalloc(sizeof(*lookup), GFP_KERNEL);
+	if (!hw || !lookup)
+		goto cleanup;
+	init.name = "virt_prcm_set";
+	init.ops = &virt_prcm_set_ops;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	hw->hw.init = &init;
+
+	clk = clk_register(NULL, &hw->hw);
+
+	lookup->dev_id = NULL;
+	lookup->con_id = "cpufreq_ck";
+	lookup->clk = clk;
+
+	clkdev_add(lookup);
+	return;
+cleanup:
+	kfree(hw);
+	kfree(lookup);
+}
+#endif

+ 2 - 0
drivers/clk/ti/clk-2xxx.c

@@ -229,6 +229,8 @@ static int __init omap2xxx_dt_clk_init(int soc_type)
 	else
 	else
 		ti_dt_clocks_register(omap2430_clks);
 		ti_dt_clocks_register(omap2430_clks);
 
 
+	omap2xxx_clkt_vps_init();
+
 	omap2_clk_disable_autoidle_all();
 	omap2_clk_disable_autoidle_all();
 
 
 	omap2_clk_enable_init_clocks(enable_init_clks,
 	omap2_clk_enable_init_clocks(enable_init_clks,

+ 1 - 0
include/linux/clk/ti.h

@@ -283,6 +283,7 @@ unsigned long omap2_dpllcore_recalc(struct clk_hw *hw,
 int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
 int omap2_reprogram_dpllcore(struct clk_hw *clk, unsigned long rate,
 			     unsigned long parent_rate);
 			     unsigned long parent_rate);
 void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
 void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
+void omap2xxx_clkt_vps_init(void);
 
 
 void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index);
 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_clocks_register(struct ti_dt_clk *oclks);