summaryrefslogtreecommitdiff
path: root/drivers/clk/tegra
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/tegra')
-rw-r--r--drivers/clk/tegra/clk-dfll.c42
-rw-r--r--drivers/clk/tegra/clk-tegra114.c2
-rw-r--r--drivers/clk/tegra/clk-tegra124.c2
-rw-r--r--drivers/clk/tegra/clk-tegra20.c52
-rw-r--r--drivers/clk/tegra/clk-tegra210.c2
-rw-r--r--drivers/clk/tegra/clk-tegra30.c2
-rw-r--r--drivers/clk/tegra/clk.c5
-rw-r--r--drivers/clk/tegra/clk.h2
8 files changed, 66 insertions, 43 deletions
diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c
index 0a7deee74eea..48ee43734e05 100644
--- a/drivers/clk/tegra/clk-dfll.c
+++ b/drivers/clk/tegra/clk-dfll.c
@@ -1196,42 +1196,24 @@ static const struct file_operations attr_registers_fops = {
.release = single_release,
};
-static int dfll_debug_init(struct tegra_dfll *td)
+static void dfll_debug_init(struct tegra_dfll *td)
{
- int ret;
+ struct dentry *root;
if (!td || (td->mode == DFLL_UNINITIALIZED))
- return 0;
-
- td->debugfs_dir = debugfs_create_dir("tegra_dfll_fcpu", NULL);
- if (!td->debugfs_dir)
- return -ENOMEM;
-
- ret = -ENOMEM;
-
- if (!debugfs_create_file("enable", S_IRUGO | S_IWUSR,
- td->debugfs_dir, td, &enable_fops))
- goto err_out;
-
- if (!debugfs_create_file("lock", S_IRUGO,
- td->debugfs_dir, td, &lock_fops))
- goto err_out;
+ return;
- if (!debugfs_create_file("rate", S_IRUGO,
- td->debugfs_dir, td, &rate_fops))
- goto err_out;
+ root = debugfs_create_dir("tegra_dfll_fcpu", NULL);
+ td->debugfs_dir = root;
- if (!debugfs_create_file("registers", S_IRUGO,
- td->debugfs_dir, td, &attr_registers_fops))
- goto err_out;
-
- return 0;
-
-err_out:
- debugfs_remove_recursive(td->debugfs_dir);
- return ret;
+ debugfs_create_file("enable", S_IRUGO | S_IWUSR, root, td, &enable_fops);
+ debugfs_create_file("lock", S_IRUGO, root, td, &lock_fops);
+ debugfs_create_file("rate", S_IRUGO, root, td, &rate_fops);
+ debugfs_create_file("registers", S_IRUGO, root, td, &attr_registers_fops);
}
+#else
+static void inline dfll_debug_init(struct tegra_dfll *td) { }
#endif /* CONFIG_DEBUG_FS */
/*
@@ -1715,9 +1697,7 @@ int tegra_dfll_register(struct platform_device *pdev,
return ret;
}
-#ifdef CONFIG_DEBUG_FS
dfll_debug_init(td);
-#endif
return 0;
}
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
index 5d5a22d529f5..1824f014202b 100644
--- a/drivers/clk/tegra/clk-tegra114.c
+++ b/drivers/clk/tegra/clk-tegra114.c
@@ -1367,7 +1367,7 @@ static void __init tegra114_clock_init(struct device_node *np)
tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks,
&pll_x_params);
- tegra_add_of_provider(np);
+ tegra_add_of_provider(np, of_clk_src_onecell_get);
tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
tegra_clk_apply_init_table = tegra114_clock_apply_init_table;
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 50088e976611..0c69c7970950 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -1479,7 +1479,7 @@ static void __init tegra124_132_clock_init_post(struct device_node *np)
&pll_x_params);
tegra_init_special_resets(1, tegra124_reset_assert,
tegra124_reset_deassert);
- tegra_add_of_provider(np);
+ tegra_add_of_provider(np, of_clk_src_onecell_get);
clks[TEGRA124_CLK_EMC] = tegra_clk_register_emc(clk_base, np,
&emc_lock);
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 0ee56dd04cec..cc857d4d4a86 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -26,6 +26,8 @@
#include "clk.h"
#include "clk-id.h"
+#define MISC_CLK_ENB 0x48
+
#define OSC_CTRL 0x50
#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
@@ -831,15 +833,25 @@ static void __init tegra20_periph_clk_init(void)
periph_clk_enb_refcnt);
clks[TEGRA20_CLK_PEX] = clk;
+ /* dev1 OSC divider */
+ clk_register_divider(NULL, "dev1_osc_div", "clk_m",
+ 0, clk_base + MISC_CLK_ENB, 22, 2,
+ CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_READ_ONLY,
+ NULL);
+
+ /* dev2 OSC divider */
+ clk_register_divider(NULL, "dev2_osc_div", "clk_m",
+ 0, clk_base + MISC_CLK_ENB, 20, 2,
+ CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_READ_ONLY,
+ NULL);
+
/* cdev1 */
- clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, 0, 26000000);
- clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0,
+ clk = tegra_clk_register_periph_gate("cdev1", "cdev1_mux", 0,
clk_base, 0, 94, periph_clk_enb_refcnt);
clks[TEGRA20_CLK_CDEV1] = clk;
/* cdev2 */
- clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, 0, 26000000);
- clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0,
+ clk = tegra_clk_register_periph_gate("cdev2", "cdev2_mux", 0,
clk_base, 0, 93, periph_clk_enb_refcnt);
clks[TEGRA20_CLK_CDEV2] = clk;
@@ -1077,6 +1089,36 @@ static const struct of_device_id pmc_match[] __initconst = {
{ },
};
+static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
+ void *data)
+{
+ struct clk_hw *parent_hw;
+ struct clk_hw *hw;
+ struct clk *clk;
+
+ clk = of_clk_src_onecell_get(clkspec, data);
+ if (IS_ERR(clk))
+ return clk;
+
+ /*
+ * Tegra20 CDEV1 and CDEV2 clocks are a bit special case, their parent
+ * clock is created by the pinctrl driver. It is possible for clk user
+ * to request these clocks before pinctrl driver got probed and hence
+ * user will get an orphaned clock. That might be undesirable because
+ * user may expect parent clock to be enabled by the child.
+ */
+ if (clkspec->args[0] == TEGRA20_CLK_CDEV1 ||
+ clkspec->args[0] == TEGRA20_CLK_CDEV2) {
+ hw = __clk_get_hw(clk);
+
+ parent_hw = clk_hw_get_parent(hw);
+ if (!parent_hw)
+ return ERR_PTR(-EPROBE_DEFER);
+ }
+
+ return clk;
+}
+
static void __init tegra20_clock_init(struct device_node *np)
{
struct device_node *node;
@@ -1115,7 +1157,7 @@ static void __init tegra20_clock_init(struct device_node *np)
tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX);
- tegra_add_of_provider(np);
+ tegra_add_of_provider(np, tegra20_clk_src_onecell_get);
tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 9fb5d51ccce4..5435d01c636a 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -3567,7 +3567,7 @@ static void __init tegra210_clock_init(struct device_node *np)
tegra_init_special_resets(2, tegra210_reset_assert,
tegra210_reset_deassert);
- tegra_add_of_provider(np);
+ tegra_add_of_provider(np, of_clk_src_onecell_get);
tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
tegra210_mbist_clk_init();
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index b316dfb6f6c7..acfe661b2ae7 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -1349,7 +1349,7 @@ static void __init tegra30_clock_init(struct device_node *np)
tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
- tegra_add_of_provider(np);
+ tegra_add_of_provider(np, of_clk_src_onecell_get);
tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index ba923f0d5953..593d76a114f9 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -298,7 +298,8 @@ static struct reset_controller_dev rst_ctlr = {
.of_reset_n_cells = 1,
};
-void __init tegra_add_of_provider(struct device_node *np)
+void __init tegra_add_of_provider(struct device_node *np,
+ void *clk_src_onecell_get)
{
int i;
@@ -314,7 +315,7 @@ void __init tegra_add_of_provider(struct device_node *np)
clk_data.clks = clks;
clk_data.clk_num = clk_num;
- of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+ of_clk_add_provider(np, clk_src_onecell_get, &clk_data);
rst_ctlr.of_node = np;
rst_ctlr.nr_resets = periph_banks * 32 + num_special_reset;
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index ba7e20e6a82b..e1f88463b600 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -763,7 +763,7 @@ struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks);
struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk);
-void tegra_add_of_provider(struct device_node *np);
+void tegra_add_of_provider(struct device_node *np, void *clk_src_onecell_get);
void tegra_register_devclks(struct tegra_devclk *dev_clks, int num);
void tegra_audio_clk_init(void __iomem *clk_base,