diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/arm/mach-omap2/io.c | 3 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/omap_twl.c | 10 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/pm.c | 2 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/sr_device.c | 2 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/voltage.c | 257 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/voltage.h | 27 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/voltagedomains3xxx_data.c | 34 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/voltagedomains44xx_data.c | 44 | 
8 files changed, 207 insertions, 172 deletions
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 40b6d47fdbd..7c36fde5dd6 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -38,6 +38,7 @@  #include "io.h"  #include <plat/omap-pm.h> +#include "voltage.h"  #include "powerdomain.h"  #include "clockdomain.h" @@ -349,10 +350,12 @@ void __init omap2_init_common_infrastructure(void)  		omap243x_clockdomains_init();  		omap2430_hwmod_init();  	} else if (cpu_is_omap34xx()) { +		omap3xxx_voltagedomains_init();  		omap3xxx_powerdomains_init();  		omap3xxx_clockdomains_init();  		omap3xxx_hwmod_init();  	} else if (cpu_is_omap44xx()) { +		omap44xx_voltagedomains_init();  		omap44xx_powerdomains_init();  		omap44xx_clockdomains_init();  		omap44xx_hwmod_init(); diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c index 07d6140baa9..fcd2f62fbdc 100644 --- a/arch/arm/mach-omap2/omap_twl.c +++ b/arch/arm/mach-omap2/omap_twl.c @@ -250,13 +250,13 @@ int __init omap4_twl_init(void)  	if (!cpu_is_omap44xx())  		return -ENODEV; -	voltdm = omap_voltage_domain_lookup("mpu"); +	voltdm = voltdm_lookup("mpu");  	omap_voltage_register_pmic(voltdm, &omap4_mpu_volt_info); -	voltdm = omap_voltage_domain_lookup("iva"); +	voltdm = voltdm_lookup("iva");  	omap_voltage_register_pmic(voltdm, &omap4_iva_volt_info); -	voltdm = omap_voltage_domain_lookup("core"); +	voltdm = voltdm_lookup("core");  	omap_voltage_register_pmic(voltdm, &omap4_core_volt_info);  	return 0; @@ -288,10 +288,10 @@ int __init omap3_twl_init(void)  	if (!twl_sr_enable_autoinit)  		omap3_twl_set_sr_bit(true); -	voltdm = omap_voltage_domain_lookup("mpu"); +	voltdm = voltdm_lookup("mpu");  	omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info); -	voltdm = omap_voltage_domain_lookup("core"); +	voltdm = voltdm_lookup("core");  	omap_voltage_register_pmic(voltdm, &omap3_core_volt_info);  	return 0; diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 472bf22d5e8..c10f8f6ae6f 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -181,7 +181,7 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,  		goto exit;  	} -	voltdm = omap_voltage_domain_lookup(vdd_name); +	voltdm = voltdm_lookup(vdd_name);  	if (IS_ERR(voltdm)) {  		printk(KERN_ERR "%s: Unable to get vdd pointer for vdd_%s\n",  			__func__, vdd_name); diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index 10d3c5ee801..2782d3f604c 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -102,7 +102,7 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)  	sr_data->senn_mod = 0x1;  	sr_data->senp_mod = 0x1; -	sr_data->voltdm = omap_voltage_domain_lookup(oh->vdd_name); +	sr_data->voltdm = voltdm_lookup(oh->vdd_name);  	if (IS_ERR(sr_data->voltdm)) {  		pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",  			__func__, oh->vdd_name); diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c index a366a6b30a6..4f0361a23ff 100644 --- a/arch/arm/mach-omap2/voltage.c +++ b/arch/arm/mach-omap2/voltage.c @@ -40,20 +40,13 @@  #include "vc.h"  #include "vp.h" -#define VOLTAGE_DIR_SIZE	16 - - -static struct omap_vdd_info **vdd_info; - -/* - * Number of scalable voltage domains. - */ -static int nr_scalable_vdd; +static LIST_HEAD(voltdm_list); +#define VOLTAGE_DIR_SIZE	16  static struct dentry *voltage_dir;  /* Init function pointers */ -static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd, +static int vp_forceupdate_scale_voltage(struct voltagedomain *voltdm,  					unsigned long target_volt);  static u32 omap3_voltage_read_reg(u16 mod, u8 offset) @@ -77,11 +70,12 @@ static void omap4_voltage_write_reg(u32 val, u16 mod, u8 offset)  	omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, mod, offset);  } -static int __init _config_common_vdd_data(struct omap_vdd_info *vdd) +static int __init _config_common_vdd_data(struct voltagedomain *voltdm)  {  	char *sys_ck_name;  	struct clk *sys_ck;  	u32 sys_clk_speed, timeout_val, waittime; +	struct omap_vdd_info *vdd = voltdm->vdd;  	/*  	 * XXX Clockfw should handle this, or this should be in a @@ -101,7 +95,7 @@ static int __init _config_common_vdd_data(struct omap_vdd_info *vdd)  	sys_ck = clk_get(NULL, sys_ck_name);  	if (IS_ERR(sys_ck)) {  		pr_warning("%s: Could not get the sys clk to calculate" -			"various vdd_%s params\n", __func__, vdd->voltdm.name); +			"various vdd_%s params\n", __func__, voltdm->name);  		return -EINVAL;  	}  	sys_clk_speed = clk_get_rate(sys_ck); @@ -135,7 +129,8 @@ static int __init _config_common_vdd_data(struct omap_vdd_info *vdd)  /* Voltage debugfs support */  static int vp_volt_debug_get(void *data, u64 *val)  { -	struct omap_vdd_info *vdd = (struct omap_vdd_info *) data; +	struct voltagedomain *voltdm = (struct voltagedomain *)data; +	struct omap_vdd_info *vdd = voltdm->vdd;  	u8 vsel;  	if (!vdd) { @@ -157,14 +152,14 @@ static int vp_volt_debug_get(void *data, u64 *val)  static int nom_volt_debug_get(void *data, u64 *val)  { -	struct omap_vdd_info *vdd = (struct omap_vdd_info *) data; +	struct voltagedomain *voltdm = (struct voltagedomain *)data; -	if (!vdd) { +	if (!voltdm) {  		pr_warning("Wrong paramater passed\n");  		return -EINVAL;  	} -	*val = omap_voltage_get_nom_volt(&vdd->voltdm); +	*val = omap_voltage_get_nom_volt(voltdm);  	return 0;  } @@ -172,16 +167,17 @@ static int nom_volt_debug_get(void *data, u64 *val)  DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n");  DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,  								"%llu\n"); -static void vp_latch_vsel(struct omap_vdd_info *vdd) +static void vp_latch_vsel(struct voltagedomain *voltdm)  {  	u32 vpconfig;  	unsigned long uvdc;  	char vsel; +	struct omap_vdd_info *vdd = voltdm->vdd; -	uvdc = omap_voltage_get_nom_volt(&vdd->voltdm); +	uvdc = omap_voltage_get_nom_volt(voltdm);  	if (!uvdc) {  		pr_warning("%s: unable to find current voltage for vdd_%s\n", -			__func__, vdd->voltdm.name); +			__func__, voltdm->name);  		return;  	} @@ -209,13 +205,14 @@ static void vp_latch_vsel(struct omap_vdd_info *vdd)  }  /* Generic voltage init functions */ -static void __init vp_init(struct omap_vdd_info *vdd) +static void __init vp_init(struct voltagedomain *voltdm)  { +	struct omap_vdd_info *vdd = voltdm->vdd;  	u32 vp_val;  	if (!vdd->read_reg || !vdd->write_reg) {  		pr_err("%s: No read/write API for accessing vdd_%s regs\n", -			__func__, vdd->voltdm.name); +			__func__, voltdm->name);  		return;  	} @@ -246,25 +243,26 @@ static void __init vp_init(struct omap_vdd_info *vdd)  	vdd->write_reg(vp_val, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vlimitto);  } -static void __init vdd_debugfs_init(struct omap_vdd_info *vdd) +static void __init vdd_debugfs_init(struct voltagedomain *voltdm)  {  	char *name; +	struct omap_vdd_info *vdd = voltdm->vdd;  	name = kzalloc(VOLTAGE_DIR_SIZE, GFP_KERNEL);  	if (!name) {  		pr_warning("%s: Unable to allocate memory for debugfs"  			" directory name for vdd_%s", -			__func__, vdd->voltdm.name); +			__func__, voltdm->name);  		return;  	}  	strcpy(name, "vdd_"); -	strcat(name, vdd->voltdm.name); +	strcat(name, voltdm->name);  	vdd->debug_dir = debugfs_create_dir(name, voltage_dir);  	kfree(name);  	if (IS_ERR(vdd->debug_dir)) {  		pr_warning("%s: Unable to create debugfs directory for" -			" vdd_%s\n", __func__, vdd->voltdm.name); +			" vdd_%s\n", __func__, voltdm->name);  		vdd->debug_dir = NULL;  		return;  	} @@ -288,16 +286,17 @@ static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)  	(void) debugfs_create_x16("vp_timeout", S_IRUGO, vdd->debug_dir,  				&(vdd->vp_rt_data.vlimitto_timeout));  	(void) debugfs_create_file("curr_vp_volt", S_IRUGO, vdd->debug_dir, -				(void *) vdd, &vp_volt_debug_fops); +				(void *) voltdm, &vp_volt_debug_fops);  	(void) debugfs_create_file("curr_nominal_volt", S_IRUGO, -				vdd->debug_dir, (void *) vdd, +				vdd->debug_dir, (void *) voltdm,  				&nom_volt_debug_fops);  }  /* Voltage scale and accessory APIs */ -static int _pre_volt_scale(struct omap_vdd_info *vdd, +static int _pre_volt_scale(struct voltagedomain *voltdm,  		unsigned long target_volt, u8 *target_vsel, u8 *current_vsel)  { +	struct omap_vdd_info *vdd = voltdm->vdd;  	struct omap_volt_data *volt_data;  	const struct omap_vc_common_data *vc_common;  	const struct omap_vp_common_data *vp_common; @@ -309,25 +308,25 @@ static int _pre_volt_scale(struct omap_vdd_info *vdd,  	/* Check if suffiecient pmic info is available for this vdd */  	if (!vdd->pmic_info) {  		pr_err("%s: Insufficient pmic info to scale the vdd_%s\n", -			__func__, vdd->voltdm.name); +			__func__, voltdm->name);  		return -EINVAL;  	}  	if (!vdd->pmic_info->uv_to_vsel) {  		pr_err("%s: PMIC function to convert voltage in uV to"  			"vsel not registered. Hence unable to scale voltage" -			"for vdd_%s\n", __func__, vdd->voltdm.name); +			"for vdd_%s\n", __func__, voltdm->name);  		return -ENODATA;  	}  	if (!vdd->read_reg || !vdd->write_reg) {  		pr_err("%s: No read/write API for accessing vdd_%s regs\n", -			__func__, vdd->voltdm.name); +			__func__, voltdm->name);  		return -EINVAL;  	}  	/* Get volt_data corresponding to target_volt */ -	volt_data = omap_voltage_get_voltdata(&vdd->voltdm, target_volt); +	volt_data = omap_voltage_get_voltdata(voltdm, target_volt);  	if (IS_ERR(volt_data))  		volt_data = NULL; @@ -355,9 +354,10 @@ static int _pre_volt_scale(struct omap_vdd_info *vdd,  	return 0;  } -static void _post_volt_scale(struct omap_vdd_info *vdd, +static void _post_volt_scale(struct voltagedomain *voltdm,  		unsigned long target_volt, u8 target_vsel, u8 current_vsel)  { +	struct omap_vdd_info *vdd = voltdm->vdd;  	u32 smps_steps = 0, smps_delay = 0;  	smps_steps = abs(target_vsel - current_vsel); @@ -370,15 +370,16 @@ static void _post_volt_scale(struct omap_vdd_info *vdd,  }  /* vc_bypass_scale_voltage - VC bypass method of voltage scaling */ -static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd, +static int vc_bypass_scale_voltage(struct voltagedomain *voltdm,  		unsigned long target_volt)  { +	struct omap_vdd_info *vdd = voltdm->vdd;  	u32 loop_cnt = 0, retries_cnt = 0;  	u32 vc_valid, vc_bypass_val_reg, vc_bypass_value;  	u8 target_vsel, current_vsel;  	int ret; -	ret = _pre_volt_scale(vdd, target_volt, &target_vsel, ¤t_vsel); +	ret = _pre_volt_scale(voltdm, target_volt, &target_vsel, ¤t_vsel);  	if (ret)  		return ret; @@ -417,19 +418,20 @@ static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,  						vc_bypass_val_reg);  	} -	_post_volt_scale(vdd, target_volt, target_vsel, current_vsel); +	_post_volt_scale(voltdm, target_volt, target_vsel, current_vsel);  	return 0;  }  /* VP force update method of voltage scaling */ -static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd, +static int vp_forceupdate_scale_voltage(struct voltagedomain *voltdm,  		unsigned long target_volt)  { +	struct omap_vdd_info *vdd = voltdm->vdd;  	u32 vpconfig;  	u8 target_vsel, current_vsel;  	int ret, timeout = 0; -	ret = _pre_volt_scale(vdd, target_volt, &target_vsel, ¤t_vsel); +	ret = _pre_volt_scale(voltdm, target_volt, &target_vsel, ¤t_vsel);  	if (ret)  		return ret; @@ -447,7 +449,7 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,  	}  	if (timeout >= VP_TRANXDONE_TIMEOUT) {  		pr_warning("%s: vdd_%s TRANXDONE timeout exceeded." -			"Voltage change aborted", __func__, vdd->voltdm.name); +			"Voltage change aborted", __func__, voltdm->name);  		return -ETIMEDOUT;  	} @@ -480,9 +482,9 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,  	if (timeout >= VP_TRANXDONE_TIMEOUT)  		pr_err("%s: vdd_%s TRANXDONE timeout exceeded."  			"TRANXDONE never got set after the voltage update\n", -			__func__, vdd->voltdm.name); +			__func__, voltdm->name); -	_post_volt_scale(vdd, target_volt, target_vsel, current_vsel); +	_post_volt_scale(voltdm, target_volt, target_vsel, current_vsel);  	/*  	 * Disable TransactionDone interrupt , clear all status, clear @@ -501,7 +503,7 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,  	if (timeout >= VP_TRANXDONE_TIMEOUT)  		pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"  			"to clear the TRANXDONE status\n", -			__func__, vdd->voltdm.name); +			__func__, voltdm->name);  	vpconfig = vdd->read_reg(vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);  	/* Clear initVDD copy trigger bit */ @@ -514,8 +516,10 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,  	return 0;  } -static void __init omap3_vfsm_init(struct omap_vdd_info *vdd) +static void __init omap3_vfsm_init(struct voltagedomain *voltdm)  { +	struct omap_vdd_info *vdd = voltdm->vdd; +  	/*  	 * Voltage Manager FSM parameters init  	 * XXX This data should be passed in from the board file @@ -527,8 +531,9 @@ static void __init omap3_vfsm_init(struct omap_vdd_info *vdd)  		       OMAP3_PRM_VOLTSETUP2_OFFSET);  } -static void __init omap3_vc_init(struct omap_vdd_info *vdd) +static void __init omap3_vc_init(struct voltagedomain *voltdm)  { +	struct omap_vdd_info *vdd = voltdm->vdd;  	static bool is_initialized;  	u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;  	u32 vc_val; @@ -556,15 +561,16 @@ static void __init omap3_vc_init(struct omap_vdd_info *vdd)  	vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, vdd->vc_data->vc_common->prm_mod,  			OMAP3_PRM_VC_I2C_CFG_OFFSET); -	omap3_vfsm_init(vdd); +	omap3_vfsm_init(voltdm);  	is_initialized = true;  }  /* OMAP4 specific voltage init functions */ -static void __init omap4_vc_init(struct omap_vdd_info *vdd) +static void __init omap4_vc_init(struct voltagedomain *voltdm)  { +	struct omap_vdd_info *vdd = voltdm->vdd;  	static bool is_initialized;  	u32 vc_val; @@ -589,20 +595,21 @@ static void __init omap4_vc_init(struct omap_vdd_info *vdd)  	is_initialized = true;  } -static void __init omap_vc_init(struct omap_vdd_info *vdd) +static void __init omap_vc_init(struct voltagedomain *voltdm)  { +	struct omap_vdd_info *vdd = voltdm->vdd;  	u32 vc_val;  	if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {  		pr_err("%s: PMIC info requried to configure vc for"  			"vdd_%s not populated.Hence cannot initialize vc\n", -			__func__, vdd->voltdm.name); +			__func__, voltdm->name);  		return;  	}  	if (!vdd->read_reg || !vdd->write_reg) {  		pr_err("%s: No read/write API for accessing vdd_%s regs\n", -			__func__, vdd->voltdm.name); +			__func__, voltdm->name);  		return;  	} @@ -630,23 +637,24 @@ static void __init omap_vc_init(struct omap_vdd_info *vdd)  	vdd->write_reg(vc_val, vdd->vc_data->vc_common->prm_mod, vdd->vfsm->voltsetup_reg);  	if (cpu_is_omap34xx()) -		omap3_vc_init(vdd); +		omap3_vc_init(voltdm);  	else if (cpu_is_omap44xx()) -		omap4_vc_init(vdd); +		omap4_vc_init(voltdm);  } -static int __init omap_vdd_data_configure(struct omap_vdd_info *vdd) +static int __init omap_vdd_data_configure(struct voltagedomain *voltdm)  { +	struct omap_vdd_info *vdd = voltdm->vdd;  	int ret = -EINVAL;  	if (!vdd->pmic_info) {  		pr_err("%s: PMIC info requried to configure vdd_%s not"  			"populated.Hence cannot initialize vdd_%s\n", -			__func__, vdd->voltdm.name, vdd->voltdm.name); +			__func__, voltdm->name, voltdm->name);  		goto ovdc_out;  	} -	if (IS_ERR_VALUE(_config_common_vdd_data(vdd))) +	if (IS_ERR_VALUE(_config_common_vdd_data(voltdm)))  		goto ovdc_out;  	if (cpu_is_omap34xx()) { @@ -680,7 +688,7 @@ unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm)  		return 0;  	} -	vdd = container_of(voltdm, struct omap_vdd_info, voltdm); +	vdd = voltdm->vdd;  	return vdd->curr_volt;  } @@ -701,7 +709,7 @@ unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)  		return 0;  	} -	vdd = container_of(voltdm, struct omap_vdd_info, voltdm); +	vdd = voltdm->vdd;  	if (!vdd->read_reg) {  		pr_err("%s: No read API for reading vdd_%s regs\n",  			__func__, voltdm->name); @@ -736,7 +744,7 @@ void omap_vp_enable(struct voltagedomain *voltdm)  		return;  	} -	vdd = container_of(voltdm, struct omap_vdd_info, voltdm); +	vdd = voltdm->vdd;  	if (!vdd->read_reg || !vdd->write_reg) {  		pr_err("%s: No read/write API for accessing vdd_%s regs\n",  			__func__, voltdm->name); @@ -747,7 +755,7 @@ void omap_vp_enable(struct voltagedomain *voltdm)  	if (vdd->vp_enabled)  		return; -	vp_latch_vsel(vdd); +	vp_latch_vsel(voltdm);  	/* Enable VP */  	vpconfig = vdd->read_reg(vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig); @@ -774,7 +782,7 @@ void omap_vp_disable(struct voltagedomain *voltdm)  		return;  	} -	vdd = container_of(voltdm, struct omap_vdd_info, voltdm); +	vdd = voltdm->vdd;  	if (!vdd->read_reg || !vdd->write_reg) {  		pr_err("%s: No read/write API for accessing vdd_%s regs\n",  			__func__, voltdm->name); @@ -827,7 +835,7 @@ int omap_voltage_scale_vdd(struct voltagedomain *voltdm,  		return -EINVAL;  	} -	vdd = container_of(voltdm, struct omap_vdd_info, voltdm); +	vdd = voltdm->vdd;  	if (!vdd->volt_scale) {  		pr_err("%s: No voltage scale API registered for vdd_%s\n", @@ -835,7 +843,7 @@ int omap_voltage_scale_vdd(struct voltagedomain *voltdm,  		return -ENODATA;  	} -	return vdd->volt_scale(vdd, target_volt); +	return vdd->volt_scale(voltdm, target_volt);  }  /** @@ -888,7 +896,7 @@ void omap_voltage_get_volttable(struct voltagedomain *voltdm,  		return;  	} -	vdd = container_of(voltdm, struct omap_vdd_info, voltdm); +	vdd = voltdm->vdd;  	*volt_data = vdd->volt_data;  } @@ -919,7 +927,7 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,  		return ERR_PTR(-EINVAL);  	} -	vdd = container_of(voltdm, struct omap_vdd_info, voltdm); +	vdd = voltdm->vdd;  	if (!vdd->volt_data) {  		pr_warning("%s: voltage table does not exist for vdd_%s\n", @@ -957,7 +965,7 @@ int omap_voltage_register_pmic(struct voltagedomain *voltdm,  		return -EINVAL;  	} -	vdd = container_of(voltdm, struct omap_vdd_info, voltdm); +	vdd = voltdm->vdd;  	vdd->pmic_info = pmic_info; @@ -984,7 +992,7 @@ struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)  		return NULL;  	} -	vdd = container_of(voltdm, struct omap_vdd_info, voltdm); +	vdd = voltdm->vdd;  	return vdd->debug_dir;  } @@ -1009,7 +1017,7 @@ void omap_change_voltscale_method(struct voltagedomain *voltdm,  		return;  	} -	vdd = container_of(voltdm, struct omap_vdd_info, voltdm); +	vdd = voltdm->vdd;  	switch (voltscale_method) {  	case VOLTSCALE_VPFORCEUPDATE: @@ -1025,38 +1033,6 @@ void omap_change_voltscale_method(struct voltagedomain *voltdm,  }  /** - * omap_voltage_domain_lookup() - API to get the voltage domain pointer - * @name:	Name of the voltage domain - * - * This API looks up in the global vdd_info struct for the - * existence of voltage domain <name>. If it exists, the API returns - * a pointer to the voltage domain structure corresponding to the - * VDD<name>. Else retuns error pointer. - */ -struct voltagedomain *omap_voltage_domain_lookup(char *name) -{ -	int i; - -	if (!vdd_info) { -		pr_err("%s: Voltage driver init not yet happened.Faulting!\n", -			__func__); -		return ERR_PTR(-EINVAL); -	} - -	if (!name) { -		pr_err("%s: No name to get the votage domain!\n", __func__); -		return ERR_PTR(-EINVAL); -	} - -	for (i = 0; i < nr_scalable_vdd; i++) { -		if (!(strcmp(name, vdd_info[i]->voltdm.name))) -			return &vdd_info[i]->voltdm; -	} - -	return ERR_PTR(-EINVAL); -} - -/**   * omap_voltage_late_init() - Init the various voltage parameters   *   * This API is to be called in the later stages of the @@ -1065,9 +1041,9 @@ struct voltagedomain *omap_voltage_domain_lookup(char *name)   */  int __init omap_voltage_late_init(void)  { -	int i; +	struct voltagedomain *voltdm; -	if (!vdd_info) { +	if (list_empty(&voltdm_list)) {  		pr_err("%s: Voltage driver support not added\n",  			__func__);  		return -EINVAL; @@ -1077,22 +1053,81 @@ int __init omap_voltage_late_init(void)  	if (IS_ERR(voltage_dir))  		pr_err("%s: Unable to create voltage debugfs main dir\n",  			__func__); -	for (i = 0; i < nr_scalable_vdd; i++) { -		if (omap_vdd_data_configure(vdd_info[i])) -			continue; -		omap_vc_init(vdd_info[i]); -		vp_init(vdd_info[i]); -		vdd_debugfs_init(vdd_info[i]); +	list_for_each_entry(voltdm, &voltdm_list, node) { +		if (voltdm->vdd) { +			if (omap_vdd_data_configure(voltdm)) +				continue; +			omap_vc_init(voltdm); +			vp_init(voltdm); +			vdd_debugfs_init(voltdm); +		}  	}  	return 0;  } -/* XXX document */ -int __init omap_voltage_early_init(struct omap_vdd_info *omap_vdd_array[], -				   u8 omap_vdd_count) +static struct voltagedomain *_voltdm_lookup(const char *name)  { -	vdd_info = omap_vdd_array; -	nr_scalable_vdd = omap_vdd_count; +	struct voltagedomain *voltdm, *temp_voltdm; + +	voltdm = NULL; + +	list_for_each_entry(temp_voltdm, &voltdm_list, node) { +		if (!strcmp(name, temp_voltdm->name)) { +			voltdm = temp_voltdm; +			break; +		} +	} + +	return voltdm; +} + +static int _voltdm_register(struct voltagedomain *voltdm) +{ +	if (!voltdm || !voltdm->name) +		return -EINVAL; + +	list_add(&voltdm->node, &voltdm_list); + +	pr_debug("voltagedomain: registered %s\n", voltdm->name); +  	return 0;  } + +/** + * voltdm_lookup - look up a voltagedomain by name, return a pointer + * @name: name of voltagedomain + * + * Find a registered voltagedomain by its name @name.  Returns a pointer + * to the struct voltagedomain if found, or NULL otherwise. + */ +struct voltagedomain *voltdm_lookup(const char *name) +{ +	struct voltagedomain *voltdm ; + +	if (!name) +		return NULL; + +	voltdm = _voltdm_lookup(name); + +	return voltdm; +} + +/** + * voltdm_init - set up the voltagedomain layer + * @voltdm_list: array of struct voltagedomain pointers to register + * + * Loop through the array of voltagedomains @voltdm_list, registering all + * that are available on the current CPU. If voltdm_list is supplied + * and not null, all of the referenced voltagedomains will be + * registered.  No return value. + */ +void voltdm_init(struct voltagedomain **voltdms) +{ +	struct voltagedomain **v; + +	if (voltdms) { +		for (v = voltdms; *v; v++) +			_voltdm_register(*v); +	} +} diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h index db23d493f66..54402989626 100644 --- a/arch/arm/mach-omap2/voltage.h +++ b/arch/arm/mach-omap2/voltage.h @@ -31,6 +31,8 @@  #define OMAP3_VOLTOFFSET	0xff  #define OMAP3_VOLTSETUP2	0xff +struct omap_vdd_info; +  /**   * struct omap_vfsm_instance_data - per-voltage manager FSM register/bitfield   * data @@ -50,11 +52,14 @@ struct omap_vfsm_instance_data {  /**   * struct voltagedomain - omap voltage domain global structure. - * @name:	Name of the voltage domain which can be used as a unique - *		identifier. + * @name: Name of the voltage domain which can be used as a unique identifier. + * @node: list_head linking all voltage domains + * @vdd: to be removed   */  struct voltagedomain {  	char *name; +	struct list_head node; +	struct omap_vdd_info *vdd;  };  /** @@ -116,7 +121,6 @@ struct omap_volt_pmic_info {   * @vc_data		: structure containing various various vc registers,   *			  shifts, masks etc.   * @vfsm                : voltage manager FSM data - * @voltdm		: pointer to the voltage domain structure   * @debug_dir		: debug directory for this voltage domain.   * @curr_volt		: current voltage for this vdd.   * @prm_irqst_mod       : PRM module id used for PRM IRQ status register access @@ -130,7 +134,6 @@ struct omap_vdd_info {  	struct omap_vp_runtime_data vp_rt_data;  	struct omap_vc_instance_data *vc_data;  	const struct omap_vfsm_instance_data *vfsm; -	struct voltagedomain voltdm;  	struct dentry *debug_dir;  	u32 curr_volt;  	bool vp_enabled; @@ -139,7 +142,7 @@ struct omap_vdd_info {  	u8 prm_irqst_reg;  	u32 (*read_reg) (u16 mod, u8 offset);  	void (*write_reg) (u32 val, u16 mod, u8 offset); -	int (*volt_scale) (struct omap_vdd_info *vdd, +	int (*volt_scale) (struct voltagedomain *voltdm,  		unsigned long target_volt);  }; @@ -155,16 +158,11 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,  		unsigned long volt);  unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);  struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm); -int __init omap_voltage_early_init(struct omap_vdd_info *omap_vdd_array[], -				   u8 omap_vdd_count);  #ifdef CONFIG_PM  int omap_voltage_register_pmic(struct voltagedomain *voltdm,  		struct omap_volt_pmic_info *pmic_info);  void omap_change_voltscale_method(struct voltagedomain *voltdm,  		int voltscale_method); -/* API to get the voltagedomain pointer */ -struct voltagedomain *omap_voltage_domain_lookup(char *name); -  int omap_voltage_late_init(void);  #else  static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm, @@ -178,10 +176,11 @@ static inline int omap_voltage_late_init(void)  {  	return -EINVAL;  } -static inline struct voltagedomain *omap_voltage_domain_lookup(char *name) -{ -	return ERR_PTR(-EINVAL); -}  #endif +extern void omap3xxx_voltagedomains_init(void); +extern void omap44xx_voltagedomains_init(void); + +struct voltagedomain *voltdm_lookup(const char *name); +void voltdm_init(struct voltagedomain **voltdm_list);  #endif diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c index f831f9adc88..4bee412b673 100644 --- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c +++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c @@ -43,9 +43,6 @@ static struct omap_vdd_info omap3_vdd1_info = {  	.vp_data = &omap3_vp1_data,  	.vc_data = &omap3_vc1_data,  	.vfsm = &omap3_vdd1_vfsm_data, -	.voltdm = { -		.name = "mpu", -	},  };  static const struct omap_vfsm_instance_data omap3_vdd2_vfsm_data = { @@ -60,23 +57,26 @@ static struct omap_vdd_info omap3_vdd2_info = {  	.vp_data = &omap3_vp2_data,  	.vc_data = &omap3_vc2_data,  	.vfsm = &omap3_vdd2_vfsm_data, -	.voltdm = { -		.name = "core", -	},  }; -/* OMAP3 VDD structures */ -static struct omap_vdd_info *omap3_vdd_info[] = { -	&omap3_vdd1_info, -	&omap3_vdd2_info, +static struct voltagedomain omap3_voltdm_mpu = { +	.name = "mpu", +	.vdd = &omap3_vdd1_info,  }; -/* OMAP3 specific voltage init functions */ -static int __init omap3xxx_voltage_early_init(void) -{ -	if (!cpu_is_omap34xx()) -		return 0; +static struct voltagedomain omap3_voltdm_core = { +	.name = "core", +	.vdd = &omap3_vdd2_info, +}; +static struct voltagedomain *voltagedomains_omap3[] __initdata = { +	&omap3_voltdm_mpu, +	&omap3_voltdm_core, +	NULL, +}; + +void __init omap3xxx_voltagedomains_init(void) +{  	/*  	 * XXX Will depend on the process, validation, and binning  	 * for the currently-running IC @@ -89,7 +89,5 @@ static int __init omap3xxx_voltage_early_init(void)  		omap3_vdd2_info.volt_data = omap34xx_vddcore_volt_data;  	} -	return omap_voltage_early_init(omap3_vdd_info, -				       ARRAY_SIZE(omap3_vdd_info)); +	voltdm_init(voltagedomains_omap3);  }; -core_initcall(omap3xxx_voltage_early_init); diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c index 64dc265aa2a..245fdf9cb4a 100644 --- a/arch/arm/mach-omap2/voltagedomains44xx_data.c +++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c @@ -42,9 +42,6 @@ static struct omap_vdd_info omap4_vdd_mpu_info = {  	.vp_data = &omap4_vp_mpu_data,  	.vc_data = &omap4_vc_mpu_data,  	.vfsm = &omap4_vdd_mpu_vfsm_data, -	.voltdm = { -		.name = "mpu", -	},  };  static const struct omap_vfsm_instance_data omap4_vdd_iva_vfsm_data = { @@ -57,9 +54,6 @@ static struct omap_vdd_info omap4_vdd_iva_info = {  	.vp_data = &omap4_vp_iva_data,  	.vc_data = &omap4_vc_iva_data,  	.vfsm = &omap4_vdd_iva_vfsm_data, -	.voltdm = { -		.name = "iva", -	},  };  static const struct omap_vfsm_instance_data omap4_vdd_core_vfsm_data = { @@ -72,24 +66,32 @@ static struct omap_vdd_info omap4_vdd_core_info = {  	.vp_data = &omap4_vp_core_data,  	.vc_data = &omap4_vc_core_data,  	.vfsm = &omap4_vdd_core_vfsm_data, -	.voltdm = { -		.name = "core", -	},  }; -/* OMAP4 VDD structures */ -static struct omap_vdd_info *omap4_vdd_info[] = { -	&omap4_vdd_mpu_info, -	&omap4_vdd_iva_info, -	&omap4_vdd_core_info, +static struct voltagedomain omap4_voltdm_mpu = { +	.name = "mpu", +	.vdd = &omap4_vdd_mpu_info,  }; -/* OMAP4 specific voltage init functions */ -static int __init omap44xx_voltage_early_init(void) -{ -	if (!cpu_is_omap44xx()) -		return 0; +static struct voltagedomain omap4_voltdm_iva = { +	.name = "iva", +	.vdd = &omap4_vdd_iva_info, +}; + +static struct voltagedomain omap4_voltdm_core = { +	.name = "core", +	.vdd = &omap4_vdd_core_info, +}; +static struct voltagedomain *voltagedomains_omap4[] __initdata = { +	&omap4_voltdm_mpu, +	&omap4_voltdm_iva, +	&omap4_voltdm_core, +	NULL, +}; + +void __init omap44xx_voltagedomains_init(void) +{  	/*  	 * XXX Will depend on the process, validation, and binning  	 * for the currently-running IC @@ -98,7 +100,5 @@ static int __init omap44xx_voltage_early_init(void)  	omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;  	omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data; -	return omap_voltage_early_init(omap4_vdd_info, -				       ARRAY_SIZE(omap4_vdd_info)); +	voltdm_init(voltagedomains_omap4);  }; -core_initcall(omap44xx_voltage_early_init);  |