power: regulator: Add support for regulator-force-boot-off
Add support for regulator-force-boot-off DT property. This property can be used by the board/device drivers for turning off regulators on early init stages as pre-requisite for the other components initialization. Signed-off-by: Konstantin Porotchkin <kostap@marvell.com> Signed-off-by: Stefan Roese <sr@denx.de> Cc: Jaehoon Chung <jh80.chung@samsung.com> Cc: Simon Glass <sjg@chromium.org> Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
This commit is contained in:
		
							parent
							
								
									939c4934c8
								
							
						
					
					
						commit
						fec8c900c8
					
				|  | @ -311,6 +311,17 @@ int regulator_autoset(struct udevice *dev) | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int regulator_unset(struct udevice *dev) | ||||||
|  | { | ||||||
|  | 	struct dm_regulator_uclass_plat *uc_pdata; | ||||||
|  | 
 | ||||||
|  | 	uc_pdata = dev_get_uclass_plat(dev); | ||||||
|  | 	if (uc_pdata && uc_pdata->force_off) | ||||||
|  | 		return regulator_set_enable(dev, false); | ||||||
|  | 
 | ||||||
|  | 	return -EMEDIUMTYPE; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void regulator_show(struct udevice *dev, int ret) | static void regulator_show(struct udevice *dev, int ret) | ||||||
| { | { | ||||||
| 	struct dm_regulator_uclass_plat *uc_pdata; | 	struct dm_regulator_uclass_plat *uc_pdata; | ||||||
|  | @ -443,6 +454,7 @@ static int regulator_pre_probe(struct udevice *dev) | ||||||
| 	uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on"); | 	uc_pdata->boot_on = dev_read_bool(dev, "regulator-boot-on"); | ||||||
| 	uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay", | 	uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay", | ||||||
| 						    0); | 						    0); | ||||||
|  | 	uc_pdata->force_off = dev_read_bool(dev, "regulator-force-boot-off"); | ||||||
| 
 | 
 | ||||||
| 	node = dev_read_subnode(dev, "regulator-state-mem"); | 	node = dev_read_subnode(dev, "regulator-state-mem"); | ||||||
| 	if (ofnode_valid(node)) { | 	if (ofnode_valid(node)) { | ||||||
|  | @ -495,6 +507,32 @@ int regulators_enable_boot_on(bool verbose) | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int regulators_enable_boot_off(bool verbose) | ||||||
|  | { | ||||||
|  | 	struct udevice *dev; | ||||||
|  | 	struct uclass *uc; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	ret = uclass_get(UCLASS_REGULATOR, &uc); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 	for (uclass_first_device(UCLASS_REGULATOR, &dev); | ||||||
|  | 	     dev; | ||||||
|  | 	     uclass_next_device(&dev)) { | ||||||
|  | 		ret = regulator_unset(dev); | ||||||
|  | 		if (ret == -EMEDIUMTYPE) { | ||||||
|  | 			ret = 0; | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 		if (verbose) | ||||||
|  | 			regulator_show(dev, ret); | ||||||
|  | 		if (ret == -ENOSYS) | ||||||
|  | 			ret = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| UCLASS_DRIVER(regulator) = { | UCLASS_DRIVER(regulator) = { | ||||||
| 	.id		= UCLASS_REGULATOR, | 	.id		= UCLASS_REGULATOR, | ||||||
| 	.name		= "regulator", | 	.name		= "regulator", | ||||||
|  |  | ||||||
|  | @ -151,6 +151,7 @@ enum regulator_flag { | ||||||
|  * @max_uA*    - maximum amperage (micro Amps) |  * @max_uA*    - maximum amperage (micro Amps) | ||||||
|  * @always_on* - bool type, true or false |  * @always_on* - bool type, true or false | ||||||
|  * @boot_on*   - bool type, true or false |  * @boot_on*   - bool type, true or false | ||||||
|  |  * @force_off* - bool type, true or false | ||||||
|  * TODO(sjg@chromium.org): Consider putting the above two into @flags |  * TODO(sjg@chromium.org): Consider putting the above two into @flags | ||||||
|  * @ramp_delay - Time to settle down after voltage change (unit: uV/us) |  * @ramp_delay - Time to settle down after voltage change (unit: uV/us) | ||||||
|  * @flags:     - flags value (see REGULATOR_FLAG_...) |  * @flags:     - flags value (see REGULATOR_FLAG_...) | ||||||
|  | @ -176,6 +177,7 @@ struct dm_regulator_uclass_plat { | ||||||
| 	unsigned int ramp_delay; | 	unsigned int ramp_delay; | ||||||
| 	bool always_on; | 	bool always_on; | ||||||
| 	bool boot_on; | 	bool boot_on; | ||||||
|  | 	bool force_off; | ||||||
| 	const char *name; | 	const char *name; | ||||||
| 	int flags; | 	int flags; | ||||||
| 	u8 ctrl_reg; | 	u8 ctrl_reg; | ||||||
|  | @ -420,6 +422,15 @@ int regulator_set_mode(struct udevice *dev, int mode_id); | ||||||
|  */ |  */ | ||||||
| int regulators_enable_boot_on(bool verbose); | int regulators_enable_boot_on(bool verbose); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * regulators_enable_boot_off() - disable regulators needed for boot | ||||||
|  |  * | ||||||
|  |  * This disables all regulators which are marked to be off at boot time. | ||||||
|  |  * | ||||||
|  |  * This effectively calls regulator_unset() for every regulator. | ||||||
|  |  */ | ||||||
|  | int regulators_enable_boot_off(bool verbose); | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * regulator_autoset: setup the voltage/current on a regulator |  * regulator_autoset: setup the voltage/current on a regulator | ||||||
|  * |  * | ||||||
|  | @ -439,6 +450,18 @@ int regulators_enable_boot_on(bool verbose); | ||||||
|  */ |  */ | ||||||
| int regulator_autoset(struct udevice *dev); | int regulator_autoset(struct udevice *dev); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * regulator_unset: turn off a regulator | ||||||
|  |  * | ||||||
|  |  * The setup depends on constraints found in device's uclass's platform data | ||||||
|  |  * (struct dm_regulator_uclass_platdata): | ||||||
|  |  * | ||||||
|  |  * - Disable - will set - if  'force_off' is set to true, | ||||||
|  |  * | ||||||
|  |  * The function returns on the first-encountered error. | ||||||
|  |  */ | ||||||
|  | int regulator_unset(struct udevice *dev); | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * regulator_autoset_by_name: setup the regulator given by its uclass's |  * regulator_autoset_by_name: setup the regulator given by its uclass's | ||||||
|  * platform data name field. The setup depends on constraints found in device's |  * platform data name field. The setup depends on constraints found in device's | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue