|  | @@ -368,3 +368,168 @@ int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
 | 
	
		
			
				|  |  |  pac_exit:
 | 
	
		
			
				|  |  |  	return ret;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
 | 
	
		
			
				|  |  | + * @pwrdm: struct powerdomain * to add the clockdomain to
 | 
	
		
			
				|  |  | + * @clkdm: struct clockdomain * to associate with a powerdomain
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Dissociate the clockdomain @clkdm from the powerdomain
 | 
	
		
			
				|  |  | + * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT
 | 
	
		
			
				|  |  | + * if @clkdm was not associated with the powerdomain, or 0 upon
 | 
	
		
			
				|  |  | + * success.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int ret = -EINVAL;
 | 
	
		
			
				|  |  | +	int i;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!pwrdm || !clkdm)
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pr_debug("powerdomain: %s: dissociating clockdomain %s\n",
 | 
	
		
			
				|  |  | +		 pwrdm->name, clkdm->name);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
 | 
	
		
			
				|  |  | +		if (pwrdm->pwrdm_clkdms[i] == clkdm)
 | 
	
		
			
				|  |  | +			break;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (i == PWRDM_MAX_CLKDMS) {
 | 
	
		
			
				|  |  | +		pr_debug("powerdomain: %s: clkdm %s not associated?!\n",
 | 
	
		
			
				|  |  | +			 pwrdm->name, clkdm->name);
 | 
	
		
			
				|  |  | +		ret = -ENOENT;
 | 
	
		
			
				|  |  | +		goto pdc_exit;
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pwrdm->pwrdm_clkdms[i] = NULL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	ret = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +pdc_exit:
 | 
	
		
			
				|  |  | +	return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
 | 
	
		
			
				|  |  | + * @pwrdm: struct powerdomain * to iterate over
 | 
	
		
			
				|  |  | + * @fn: callback function *
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Call the supplied function @fn for each clockdomain in the powerdomain
 | 
	
		
			
				|  |  | + * @pwrdm.  The callback function can return anything but 0 to bail
 | 
	
		
			
				|  |  | + * out early from the iterator.  Returns -EINVAL if presented with
 | 
	
		
			
				|  |  | + * invalid pointers; or passes along the last return value of the
 | 
	
		
			
				|  |  | + * callback function, which should be 0 for success or anything else
 | 
	
		
			
				|  |  | + * to indicate failure.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
 | 
	
		
			
				|  |  | +			 int (*fn)(struct powerdomain *pwrdm,
 | 
	
		
			
				|  |  | +				   struct clockdomain *clkdm))
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int ret = 0;
 | 
	
		
			
				|  |  | +	int i;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!fn)
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
 | 
	
		
			
				|  |  | +		ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * pwrdm_get_voltdm - return a ptr to the voltdm that this pwrdm resides in
 | 
	
		
			
				|  |  | + * @pwrdm: struct powerdomain *
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Return a pointer to the struct voltageomain that the specified powerdomain
 | 
	
		
			
				|  |  | + * @pwrdm exists in.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	return pwrdm->voltdm.ptr;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
 | 
	
		
			
				|  |  | + * @pwrdm: struct powerdomain *
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Return the number of controllable memory banks in powerdomain @pwrdm,
 | 
	
		
			
				|  |  | + * starting with 1.  Returns -EINVAL if the powerdomain pointer is null.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	if (!pwrdm)
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return pwrdm->banks;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * pwrdm_set_next_pwrst - set next powerdomain power state
 | 
	
		
			
				|  |  | + * @pwrdm: struct powerdomain * to set
 | 
	
		
			
				|  |  | + * @pwrst: one of the PWRDM_POWER_* macros
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Set the powerdomain @pwrdm's next power state to @pwrst.  The powerdomain
 | 
	
		
			
				|  |  | + * may not enter this state immediately if the preconditions for this state
 | 
	
		
			
				|  |  | + * have not been satisfied.  Returns -EINVAL if the powerdomain pointer is
 | 
	
		
			
				|  |  | + * null or if the power state is invalid for the powerdomin, or returns 0
 | 
	
		
			
				|  |  | + * upon success.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int ret = -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!pwrdm)
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!(pwrdm->pwrsts & (1 << pwrst)))
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	pr_debug("powerdomain: %s: setting next powerstate to %0x\n",
 | 
	
		
			
				|  |  | +		 pwrdm->name, pwrst);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (arch_pwrdm && arch_pwrdm->pwrdm_set_next_pwrst) {
 | 
	
		
			
				|  |  | +		/* Trace the pwrdm desired target state */
 | 
	
		
			
				|  |  | +		trace_power_domain_target(pwrdm->name, pwrst,
 | 
	
		
			
				|  |  | +					  smp_processor_id());
 | 
	
		
			
				|  |  | +		/* Program the pwrdm desired target state */
 | 
	
		
			
				|  |  | +		ret = arch_pwrdm->pwrdm_set_next_pwrst(pwrdm, pwrst);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * pwrdm_read_next_pwrst - get next powerdomain power state
 | 
	
		
			
				|  |  | + * @pwrdm: struct powerdomain * to get power state
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Return the powerdomain @pwrdm's next power state.  Returns -EINVAL
 | 
	
		
			
				|  |  | + * if the powerdomain pointer is null or returns the next power state
 | 
	
		
			
				|  |  | + * upon success.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int ret = -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!pwrdm)
 | 
	
		
			
				|  |  | +		return -EINVAL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (arch_pwrdm && arch_pwrdm->pwrdm_read_next_pwrst)
 | 
	
		
			
				|  |  | +		ret = arch_pwrdm->pwrdm_read_next_pwrst(pwrdm);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return ret;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * pwrdm_read_pwrst - get current powerdomain power state
 | 
	
		
			
				|  |  | + * @pwrdm: struct powerdomain * to get power state
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * Return the powerdomain @pwrdm's current power state.	Returns -EINVAL
 | 
	
		
			
				|  |  | + * if the powerdomain pointer is null or returns the current power state
 | 
	
		
			
				|  |  | + * upon success. Note that if the power domain only supports the ON state
 | 
	
		
			
				|  |  | + * then just return ON as the current state.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +int pwrdm_read_pwrst(struct powerdomain *pwrdm)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int ret = -EINVAL;
 | 
	
		
			
				|  |  | +
 |