diff options
Diffstat (limited to 'drivers/clk/clk-ppc-corenet.c')
| -rw-r--r-- | drivers/clk/clk-ppc-corenet.c | 71 | 
1 files changed, 49 insertions, 22 deletions
diff --git a/drivers/clk/clk-ppc-corenet.c b/drivers/clk/clk-ppc-corenet.c index e9587073bd3..8b284be4efa 100644 --- a/drivers/clk/clk-ppc-corenet.c +++ b/drivers/clk/clk-ppc-corenet.c @@ -11,6 +11,7 @@  #include <linux/io.h>  #include <linux/kernel.h>  #include <linux/module.h> +#include <linux/of_address.h>  #include <linux/of_platform.h>  #include <linux/of.h>  #include <linux/slab.h> @@ -26,7 +27,6 @@ struct cmux_clk {  #define CLKSEL_ADJUST		BIT(0)  #define to_cmux_clk(p)		container_of(p, struct cmux_clk, hw) -static void __iomem *base;  static unsigned int clocks_per_pll;  static int cmux_set_parent(struct clk_hw *hw, u8 idx) @@ -99,7 +99,11 @@ static void __init core_mux_init(struct device_node *np)  		pr_err("%s: could not allocate cmux_clk\n", __func__);  		goto err_name;  	} -	cmux_clk->reg = base + offset; +	cmux_clk->reg = of_iomap(np, 0); +	if (!cmux_clk->reg) { +		pr_err("%s: could not map register\n", __func__); +		goto err_clk; +	}  	node = of_find_compatible_node(NULL, NULL, "fsl,p4080-clockgen");  	if (node && (offset >= 0x80)) @@ -142,38 +146,39 @@ err_name:  static void __init core_pll_init(struct device_node *np)  { -	u32 offset, mult; +	u32 mult;  	int i, rc, count;  	const char *clk_name, *parent_name;  	struct clk_onecell_data *onecell_data;  	struct clk      **subclks; +	void __iomem *base; -	rc = of_property_read_u32(np, "reg", &offset); -	if (rc) { -		pr_err("%s: could not get reg property\n", np->name); +	base = of_iomap(np, 0); +	if (!base) { +		pr_err("clk-ppc: iomap error\n");  		return;  	}  	/* get the multiple of PLL */ -	mult = ioread32be(base + offset); +	mult = ioread32be(base);  	/* check if this PLL is disabled */  	if (mult & PLL_KILL) {  		pr_debug("PLL:%s is disabled\n", np->name); -		return; +		goto err_map;  	}  	mult = (mult >> 1) & 0x3f;  	parent_name = of_clk_get_parent_name(np, 0);  	if (!parent_name) {  		pr_err("PLL: %s must have a parent\n", np->name); -		return; +		goto err_map;  	}  	count = of_property_count_strings(np, "clock-output-names");  	if (count < 0 || count > 4) {  		pr_err("%s: clock is not supported\n", np->name); -		return; +		goto err_map;  	}  	/* output clock number per PLL */ @@ -182,7 +187,7 @@ static void __init core_pll_init(struct device_node *np)  	subclks = kzalloc(sizeof(struct clk *) * count, GFP_KERNEL);  	if (!subclks) {  		pr_err("%s: could not allocate subclks\n", __func__); -		return; +		goto err_map;  	}  	onecell_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); @@ -229,30 +234,52 @@ static void __init core_pll_init(struct device_node *np)  		goto err_cell;  	} +	iounmap(base);  	return;  err_cell:  	kfree(onecell_data);  err_clks:  	kfree(subclks); +err_map: +	iounmap(base); +} + +static void __init sysclk_init(struct device_node *node) +{ +	struct clk *clk; +	const char *clk_name = node->name; +	struct device_node *np = of_get_parent(node); +	u32 rate; + +	if (!np) { +		pr_err("ppc-clk: could not get parent node\n"); +		return; +	} + +	if (of_property_read_u32(np, "clock-frequency", &rate)) { +		of_node_put(node); +		return; +	} + +	of_property_read_string(np, "clock-output-names", &clk_name); + +	clk = clk_register_fixed_rate(NULL, clk_name, NULL, CLK_IS_ROOT, rate); +	if (!IS_ERR(clk)) +		of_clk_add_provider(np, of_clk_src_simple_get, clk);  }  static const struct of_device_id clk_match[] __initconst = { -	{ .compatible = "fixed-clock", .data = of_fixed_clk_setup, }, -	{ .compatible = "fsl,core-pll-clock", .data = core_pll_init, }, -	{ .compatible = "fsl,core-mux-clock", .data = core_mux_init, }, +	{ .compatible = "fsl,qoriq-sysclk-1.0", .data = sysclk_init, }, +	{ .compatible = "fsl,qoriq-sysclk-2.0", .data = sysclk_init, }, +	{ .compatible = "fsl,qoriq-core-pll-1.0", .data = core_pll_init, }, +	{ .compatible = "fsl,qoriq-core-pll-2.0", .data = core_pll_init, }, +	{ .compatible = "fsl,qoriq-core-mux-1.0", .data = core_mux_init, }, +	{ .compatible = "fsl,qoriq-core-mux-2.0", .data = core_mux_init, },  	{}  };  static int __init ppc_corenet_clk_probe(struct platform_device *pdev)  { -	struct device_node *np; - -	np = pdev->dev.of_node; -	base = of_iomap(np, 0); -	if (!base) { -		dev_err(&pdev->dev, "iomap error\n"); -		return -ENOMEM; -	}  	of_clk_init(clk_match);  	return 0;  | 
