Commit 47b00dcf authored by Tero Kristo's avatar Tero Kristo
Browse files

clk: ti: clkctrl: support multiple clkctrl nodes under a cm node



Currently, only one clkctrl node can be added under a specific CM node
due to limitation with the implementation. Modify the code to pick-up
clockdomain name from the clkctrl node instead of CM node if provided.
Also, add a new flag to the TI clock driver so that both modes can
be supported simultaneously.

Signed-off-by: default avatarTero Kristo <t-kristo@ti.com>
Tested-by: default avatarTony Lindgren <tony@atomide.com>
parent 8fa45095
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
struct ti_clk_ll_ops *ti_clk_ll_ops;
static struct device_node *clocks_node_ptr[CLK_MAX_MEMMAPS];

static struct ti_clk_features ti_clk_features;
struct ti_clk_features ti_clk_features;

struct clk_iomap {
	struct regmap *regmap;
@@ -140,6 +140,9 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
	int ret;
	static bool clkctrl_nodes_missing;
	static bool has_clkctrl_data;
	static bool compat_mode;

	compat_mode = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT;

	for (c = oclks; c->node_name != NULL; c++) {
		strcpy(buf, c->node_name);
@@ -164,7 +167,7 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
			continue;

		node = of_find_node_by_name(NULL, buf);
		if (num_args) {
		if (num_args && compat_mode) {
			parent = node;
			node = of_get_child_by_name(parent, "clk");
			of_node_put(parent);
+45 −16
Original line number Diff line number Diff line
@@ -259,8 +259,13 @@ _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider,
	struct omap_clkctrl_clk *clkctrl_clk;
	int ret = 0;

	init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", node->parent->name,
			      node->name, offset, bit);
	if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
		init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d",
				      node->parent->name, node->name, offset,
				      bit);
	else
		init.name = kasprintf(GFP_KERNEL, "%s:%04x:%d", node->name,
				      offset, bit);
	clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
	if (!init.name || !clkctrl_clk) {
		ret = -ENOMEM;
@@ -441,6 +446,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
	u32 addr;
	int ret;

	if (!(ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) &&
	    !strcmp(node->name, "clk"))
		ti_clk_features.flags |= TI_CLK_CLKCTRL_COMPAT;

	addrp = of_get_address(node, 0, NULL, NULL);
	addr = (u32)of_translate_address(node, addrp);

@@ -492,6 +501,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)

	provider->base = of_iomap(node, 0);

	if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) {
		provider->clkdm_name = kmalloc(strlen(node->parent->name) + 3,
					       GFP_KERNEL);
		if (!provider->clkdm_name) {
@@ -500,11 +510,26 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
		}

		/*
	 * Create default clkdm name, replace _cm from end of parent node
	 * name with _clkdm
		 * Create default clkdm name, replace _cm from end of parent
		 * node name with _clkdm
		 */
		strcpy(provider->clkdm_name, node->parent->name);
		provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0;
	} else {
		provider->clkdm_name = kmalloc(strlen(node->name), GFP_KERNEL);
		if (!provider->clkdm_name) {
			kfree(provider);
			return;
		}

		/*
		 * Create default clkdm name, replace _clkctrl from end of
		 * node name with _clkdm
		 */
		strcpy(provider->clkdm_name, node->name);
		provider->clkdm_name[strlen(provider->clkdm_name) - 7] = 0;
	}

	strcat(provider->clkdm_name, "clkdm");

	INIT_LIST_HEAD(&provider->clocks);
@@ -539,9 +564,13 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
		init.flags = 0;
		if (reg_data->flags & CLKF_SET_RATE_PARENT)
			init.flags |= CLK_SET_RATE_PARENT;
		if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
			init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d",
					      node->parent->name, node->name,
					      reg_data->offset, 0);
		else
			init.name = kasprintf(GFP_KERNEL, "%s:%04x:%d",
					      node->name, reg_data->offset, 0);
		clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
		if (!init.name || !clkctrl_clk)
			goto cleanup;
+2 −0
Original line number Diff line number Diff line
@@ -233,6 +233,8 @@ extern const struct clk_ops ti_clk_divider_ops;
extern const struct clk_ops ti_clk_mux_ops;
extern const struct clk_ops omap_gate_clk_ops;

extern struct ti_clk_features ti_clk_features;

void omap2_init_clk_clkdm(struct clk_hw *hw);
int omap2_clkops_enable_clkdm(struct clk_hw *hw);
void omap2_clkops_disable_clkdm(struct clk_hw *hw);
+1 −0
Original line number Diff line number Diff line
@@ -290,6 +290,7 @@ struct ti_clk_features {
#define TI_CLK_DPLL4_DENY_REPROGRAM		BIT(1)
#define TI_CLK_DISABLE_CLKDM_CONTROL		BIT(2)
#define TI_CLK_ERRATA_I810			BIT(3)
#define TI_CLK_CLKCTRL_COMPAT			BIT(4)

void ti_clk_setup_features(struct ti_clk_features *features);
const struct ti_clk_features *ti_clk_get_features(void);