diff options
author | Mike Turquette <mturquette@linaro.org> | 2014-09-30 06:38:59 (GMT) |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2014-09-30 06:38:59 (GMT) |
commit | 82de1bc86c493ad832db270635fbf4e8c237f02f (patch) | |
tree | f70562cf3ae0a777ff55da734466627e2ab2478c /drivers/clk | |
parent | 6e18ff26c2b529de06207caa2be9e5f1cf520972 (diff) | |
parent | 04ed831f224d4553682f48e1b4a6b68f2622b68e (diff) | |
download | linux-82de1bc86c493ad832db270635fbf4e8c237f02f.tar.xz |
Merge branch 'for-v3.18/ti-clk-driver' of github.com:t-kristo/linux-pm into clk-next
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/ti/clk-dra7-atl.c | 2 | ||||
-rw-r--r-- | drivers/clk/ti/clk.c | 68 | ||||
-rw-r--r-- | drivers/clk/ti/clockdomain.c | 5 | ||||
-rw-r--r-- | drivers/clk/ti/divider.c | 4 |
4 files changed, 52 insertions, 27 deletions
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c index 990e1d9..59bb4b3 100644 --- a/drivers/clk/ti/clk-dra7-atl.c +++ b/drivers/clk/ti/clk-dra7-atl.c @@ -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); diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index b1a6f71..337abe5 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -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--; } } diff --git a/drivers/clk/ti/clockdomain.c b/drivers/clk/ti/clockdomain.c index f1e0038..b4c5fac 100644 --- a/drivers/clk/ti/clockdomain.c +++ b/drivers/clk/ti/clockdomain.c @@ -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)); diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index a837f70..bff2b5b 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -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; |