| 
					
				 | 
			
			
				@@ -154,3 +154,197 @@ int clk_set_rate(struct clk *clk, unsigned long rate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 * the clock may have been made this way by choice. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	WARN_ON(clk->ops == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	WARN_ON(clk->ops && clk->ops->set_rate == NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (clk->ops == NULL || clk->ops->set_rate == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	spin_lock_irqsave(&clocks_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ret = (clk->ops->set_rate)(clk, rate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	spin_unlock_irqrestore(&clocks_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk *clk_get_parent(struct clk *clk) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return clk->parent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int clk_set_parent(struct clk *clk, struct clk *parent) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (IS_ERR_OR_NULL(clk) || IS_ERR_OR_NULL(parent)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	spin_lock_irqsave(&clocks_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (clk->ops && clk->ops->set_parent) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ret = (clk->ops->set_parent)(clk, parent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	spin_unlock_irqrestore(&clocks_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+EXPORT_SYMBOL(clk_enable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+EXPORT_SYMBOL(clk_disable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+EXPORT_SYMBOL(clk_get_rate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+EXPORT_SYMBOL(clk_round_rate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+EXPORT_SYMBOL(clk_set_rate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+EXPORT_SYMBOL(clk_get_parent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+EXPORT_SYMBOL(clk_set_parent); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* base clocks */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int clk_default_setrate(struct clk *clk, unsigned long rate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clk->rate = rate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk_ops clk_ops_def_setrate = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.set_rate	= clk_default_setrate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk clk_xtal = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.name		= "xtal", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.rate		= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.parent		= NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.ctrlbit	= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk clk_ext = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.name		= "ext", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk clk_epll = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.name		= "epll", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk clk_mpll = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.name		= "mpll", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.ops		= &clk_ops_def_setrate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk clk_upll = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.name		= "upll", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.parent		= NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.ctrlbit	= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk clk_f = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.name		= "fclk", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.rate		= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.parent		= &clk_mpll, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.ctrlbit	= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk clk_h = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.name		= "hclk", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.rate		= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.parent		= NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.ctrlbit	= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.ops		= &clk_ops_def_setrate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk clk_p = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.name		= "pclk", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.rate		= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.parent		= NULL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.ctrlbit	= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.ops		= &clk_ops_def_setrate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk clk_usb_bus = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.name		= "usb-bus", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.rate		= 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.parent		= &clk_upll, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+struct clk s3c24xx_uclk = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	.name		= "uclk", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* initialise the clock system */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * s3c24xx_register_clock() - register a clock 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @clk: The clock to register 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Add the specified clock to the list of clocks known by the system. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int s3c24xx_register_clock(struct clk *clk) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (clk->enable == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		clk->enable = clk_null_enable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	/* fill up the clk_lookup structure and register it*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clk->lookup.dev_id = clk->devname; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clk->lookup.con_id = clk->name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clk->lookup.clk = clk; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	clkdev_add(&clk->lookup); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * s3c24xx_register_clocks() - register an array of clock pointers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @clks: Pointer to an array of struct clk pointers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @nr_clks: The number of clocks in the @clks array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Call s3c24xx_register_clock() for all the clock pointers contained 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * in the @clks list. Returns the number of failures. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int s3c24xx_register_clocks(struct clk **clks, int nr_clks) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int fails = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (; nr_clks > 0; nr_clks--, clks++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (s3c24xx_register_clock(*clks) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			struct clk *clk = *clks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			printk(KERN_ERR "%s: failed to register %p: %s\n", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			       __func__, clk, clk->name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			fails++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return fails; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * s3c_register_clocks() - register an array of clocks 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @clkp: Pointer to the first clock in the array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @nr_clks: Number of clocks to register. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Call s3c24xx_register_clock() on the @clkp array given, printing an 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * error if it fails to register the clock (unlikely). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void __init s3c_register_clocks(struct clk *clkp, int nr_clks) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	int ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for (; nr_clks > 0; nr_clks--, clkp++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ret = s3c24xx_register_clock(clkp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			printk(KERN_ERR "Failed to register clock %s (%d)\n", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			       clkp->name, ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * s3c_disable_clocks() - disable an array of clocks 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @clkp: Pointer to the first clock in the array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @nr_clks: Number of clocks to register. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * for internal use only at initialisation time. disable the clocks in the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @clkp array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void __init s3c_disable_clocks(struct clk *clkp, int nr_clks) 
			 |