diff options
Diffstat (limited to 'arch/arm/mach-omap2/clockdomain.c')
| -rw-r--r-- | arch/arm/mach-omap2/clockdomain.c | 76 | 
1 files changed, 41 insertions, 35 deletions
| diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index 4c3ce9cfd948..0e7d501865b6 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -22,6 +22,7 @@  #include <linux/delay.h>  #include <linux/clk.h>  #include <linux/limits.h> +#include <linux/err.h>  #include <linux/io.h> @@ -71,16 +72,13 @@ static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep)  	if (!omap_chip_is(autodep->omap_chip))  		return; -	pwrdm = pwrdm_lookup(autodep->pwrdm_name); +	pwrdm = pwrdm_lookup(autodep->pwrdm.name);  	if (!pwrdm) { -		pr_debug("clockdomain: _autodep_lookup: powerdomain %s " -			 "does not exist\n", autodep->pwrdm_name); -		WARN_ON(1); -		return; +		pr_err("clockdomain: autodeps: powerdomain %s does not exist\n", +			 autodep->pwrdm.name); +		pwrdm = ERR_PTR(-ENOENT);  	} -	autodep->pwrdm = pwrdm; - -	return; +	autodep->pwrdm.ptr = pwrdm;  }  /* @@ -95,16 +93,19 @@ static void _clkdm_add_autodeps(struct clockdomain *clkdm)  {  	struct clkdm_pwrdm_autodep *autodep; -	for (autodep = autodeps; autodep->pwrdm_name; autodep++) { -		if (!autodep->pwrdm) +	for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) { +		if (IS_ERR(autodep->pwrdm.ptr)) +			continue; + +		if (!omap_chip_is(autodep->omap_chip))  			continue;  		pr_debug("clockdomain: adding %s sleepdep/wkdep for " -			 "pwrdm %s\n", autodep->pwrdm_name, -			 clkdm->pwrdm->name); +			 "pwrdm %s\n", autodep->pwrdm.ptr->name, +			 clkdm->pwrdm.ptr->name); -		pwrdm_add_sleepdep(clkdm->pwrdm, autodep->pwrdm); -		pwrdm_add_wkdep(clkdm->pwrdm, autodep->pwrdm); +		pwrdm_add_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr); +		pwrdm_add_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);  	}  } @@ -120,16 +121,19 @@ static void _clkdm_del_autodeps(struct clockdomain *clkdm)  {  	struct clkdm_pwrdm_autodep *autodep; -	for (autodep = autodeps; autodep->pwrdm_name; autodep++) { -		if (!autodep->pwrdm) +	for (autodep = autodeps; autodep->pwrdm.ptr; autodep++) { +		if (IS_ERR(autodep->pwrdm.ptr)) +			continue; + +		if (!omap_chip_is(autodep->omap_chip))  			continue;  		pr_debug("clockdomain: removing %s sleepdep/wkdep for " -			 "pwrdm %s\n", autodep->pwrdm_name, -			 clkdm->pwrdm->name); +			 "pwrdm %s\n", autodep->pwrdm.ptr->name, +			 clkdm->pwrdm.ptr->name); -		pwrdm_del_sleepdep(clkdm->pwrdm, autodep->pwrdm); -		pwrdm_del_wkdep(clkdm->pwrdm, autodep->pwrdm); +		pwrdm_del_sleepdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr); +		pwrdm_del_wkdep(clkdm->pwrdm.ptr, autodep->pwrdm.ptr);  	}  } @@ -179,7 +183,7 @@ void clkdm_init(struct clockdomain **clkdms,  	autodeps = init_autodeps;  	if (autodeps) -		for (autodep = autodeps; autodep->pwrdm_name; autodep++) +		for (autodep = autodeps; autodep->pwrdm.ptr; autodep++)  			_autodep_lookup(autodep);  } @@ -202,20 +206,20 @@ int clkdm_register(struct clockdomain *clkdm)  	if (!omap_chip_is(clkdm->omap_chip))  		return -EINVAL; -	pwrdm = pwrdm_lookup(clkdm->pwrdm_name); +	pwrdm = pwrdm_lookup(clkdm->pwrdm.name);  	if (!pwrdm) { -		pr_debug("clockdomain: clkdm_register %s: powerdomain %s " -			 "does not exist\n", clkdm->name, clkdm->pwrdm_name); +		pr_err("clockdomain: %s: powerdomain %s does not exist\n", +			clkdm->name, clkdm->pwrdm.name);  		return -EINVAL;  	} -	clkdm->pwrdm = pwrdm; +	clkdm->pwrdm.ptr = pwrdm;  	mutex_lock(&clkdm_mutex);  	/* Verify that the clockdomain is not already registered */  	if (_clkdm_lookup(clkdm->name)) {  		ret = -EEXIST;  		goto cr_unlock; -	}; +	}  	list_add(&clkdm->node, &clkdm_list); @@ -242,7 +246,7 @@ int clkdm_unregister(struct clockdomain *clkdm)  	if (!clkdm)  		return -EINVAL; -	pwrdm_del_clkdm(clkdm->pwrdm, clkdm); +	pwrdm_del_clkdm(clkdm->pwrdm.ptr, clkdm);  	mutex_lock(&clkdm_mutex);  	list_del(&clkdm->node); @@ -327,7 +331,7 @@ struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)  	if (!clkdm)  		return NULL; -	return clkdm->pwrdm; +	return clkdm->pwrdm.ptr;  } @@ -348,7 +352,7 @@ static int omap2_clkdm_clktrctrl_read(struct clockdomain *clkdm)  	if (!clkdm)  		return -EINVAL; -	v = cm_read_mod_reg(clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); +	v = cm_read_mod_reg(clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);  	v &= clkdm->clktrctrl_mask;  	v >>= __ffs(clkdm->clktrctrl_mask); @@ -380,7 +384,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)  	if (cpu_is_omap24xx()) {  		cm_set_mod_reg_bits(OMAP24XX_FORCESTATE, -				    clkdm->pwrdm->prcm_offs, PM_PWSTCTRL); +				    clkdm->pwrdm.ptr->prcm_offs, PM_PWSTCTRL);  	} else if (cpu_is_omap34xx()) { @@ -388,7 +392,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)  			 __ffs(clkdm->clktrctrl_mask));  		cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v, -				    clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); +				    clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);  	} else {  		BUG(); @@ -422,7 +426,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)  	if (cpu_is_omap24xx()) {  		cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE, -				      clkdm->pwrdm->prcm_offs, PM_PWSTCTRL); +				      clkdm->pwrdm.ptr->prcm_offs, PM_PWSTCTRL);  	} else if (cpu_is_omap34xx()) { @@ -430,7 +434,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)  			 __ffs(clkdm->clktrctrl_mask));  		cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v, -				    clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); +				    clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);  	} else {  		BUG(); @@ -478,7 +482,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)  	cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,  			    v << __ffs(clkdm->clktrctrl_mask), -			    clkdm->pwrdm->prcm_offs, +			    clkdm->pwrdm.ptr->prcm_offs,  			    CM_CLKSTCTRL);  } @@ -516,7 +520,7 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)  	cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,  			    v << __ffs(clkdm->clktrctrl_mask), -			    clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL); +			    clkdm->pwrdm.ptr->prcm_offs, CM_CLKSTCTRL);  	if (atomic_read(&clkdm->usecount) > 0)  		_clkdm_del_autodeps(clkdm); @@ -567,6 +571,8 @@ int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)  	else  		omap2_clkdm_wakeup(clkdm); +	pwrdm_wait_transition(clkdm->pwrdm.ptr); +  	return 0;  } |