clk: bind clk to new parent device
Clock re-parenting is not binding the clock's device to its new parent device, it only calls the clock's ops->set_parent() API. The changes in this commit re-parent the clock device to its new parent so that subsequent operations like clk_get_parent() to point to the proper parent. Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
		
							parent
							
								
									cfecbaf4e7
								
							
						
					
					
						commit
						4d139f3838
					
				|  | @ -14,6 +14,7 @@ | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <log.h> | #include <log.h> | ||||||
| #include <malloc.h> | #include <malloc.h> | ||||||
|  | #include <dm/device-internal.h> | ||||||
| #include <dm/devres.h> | #include <dm/devres.h> | ||||||
| #include <dm/read.h> | #include <dm/read.h> | ||||||
| #include <linux/bug.h> | #include <linux/bug.h> | ||||||
|  | @ -512,6 +513,7 @@ ulong clk_set_rate(struct clk *clk, ulong rate) | ||||||
| int clk_set_parent(struct clk *clk, struct clk *parent) | int clk_set_parent(struct clk *clk, struct clk *parent) | ||||||
| { | { | ||||||
| 	const struct clk_ops *ops; | 	const struct clk_ops *ops; | ||||||
|  | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent); | 	debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent); | ||||||
| 	if (!clk_valid(clk)) | 	if (!clk_valid(clk)) | ||||||
|  | @ -521,7 +523,14 @@ int clk_set_parent(struct clk *clk, struct clk *parent) | ||||||
| 	if (!ops->set_parent) | 	if (!ops->set_parent) | ||||||
| 		return -ENOSYS; | 		return -ENOSYS; | ||||||
| 
 | 
 | ||||||
| 	return ops->set_parent(clk, parent); | 	ret = ops->set_parent(clk, parent); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	if (CONFIG_IS_ENABLED(CLK_CCF)) | ||||||
|  | 		ret = device_reparent(clk->dev, parent->dev); | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int clk_enable(struct clk *clk) | int clk_enable(struct clk *clk) | ||||||
|  |  | ||||||
|  | @ -22,6 +22,10 @@ static int dm_test_clk_ccf(struct unit_test_state *uts) | ||||||
| 	struct udevice *dev; | 	struct udevice *dev; | ||||||
| 	long long rate; | 	long long rate; | ||||||
| 	int ret; | 	int ret; | ||||||
|  | #if CONFIG_IS_ENABLED(CLK_CCF) | ||||||
|  | 	const char *clkname; | ||||||
|  | 	int clkid; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	/* Get the device using the clk device */ | 	/* Get the device using the clk device */ | ||||||
| 	ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-ccf", &dev)); | 	ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-ccf", &dev)); | ||||||
|  | @ -130,6 +134,29 @@ static int dm_test_clk_ccf(struct unit_test_state *uts) | ||||||
| 
 | 
 | ||||||
| 	ret = sandbox_clk_enable_count(pclk); | 	ret = sandbox_clk_enable_count(pclk); | ||||||
| 	ut_asserteq(ret, 0); | 	ut_asserteq(ret, 0); | ||||||
|  | 
 | ||||||
|  | 	/* Test clock re-parenting. */ | ||||||
|  | 	ret = clk_get_by_id(SANDBOX_CLK_USDHC1_SEL, &clk); | ||||||
|  | 	ut_assertok(ret); | ||||||
|  | 	ut_asserteq_str("usdhc1_sel", clk->dev->name); | ||||||
|  | 
 | ||||||
|  | 	pclk = clk_get_parent(clk); | ||||||
|  | 	ut_assertok_ptr(pclk); | ||||||
|  | 	if (!strcmp(pclk->dev->name, "pll3_60m")) { | ||||||
|  | 		clkname = "pll3_80m"; | ||||||
|  | 		clkid = SANDBOX_CLK_PLL3_80M; | ||||||
|  | 	} else { | ||||||
|  | 		clkname = "pll3_60m"; | ||||||
|  | 		clkid = SANDBOX_CLK_PLL3_60M; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret = clk_get_by_id(clkid, &pclk); | ||||||
|  | 	ut_assertok(ret); | ||||||
|  | 	ret = clk_set_parent(clk, pclk); | ||||||
|  | 	ut_assertok(ret); | ||||||
|  | 	pclk = clk_get_parent(clk); | ||||||
|  | 	ut_assertok_ptr(pclk); | ||||||
|  | 	ut_asserteq_str(clkname, pclk->dev->name); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	return 1; | 	return 1; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue