Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: core: Support bypass mode

Many regulators support a bypass mode where they simply switch their
input supply to the output. This is mainly used in low power retention
states where power consumption is extremely low so higher voltage or
less clean supplies can be used.

Support this by providing ops for the drivers and a consumer API which
allows the device to be put into bypass mode if all consumers enable it
and the machine enables permission for this.

This is not supported as a mode since the existing modes are rarely used
due to fuzzy definition and mostly redundant with modern hardware which is
able to respond promptly to load changes.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Reviewed-by: Graeme Gregory <gg@slimlogic.co.uk>

+126
+21
Documentation/ABI/testing/sysfs-class-regulator
··· 349 349 350 350 This will be one of the same strings reported by 351 351 the "state" attribute. 352 + 353 + What: /sys/class/regulator/.../bypass 354 + Date: September 2012 355 + KernelVersion: 3.7 356 + Contact: Mark Brown <broonie@opensource.wolfsonmicro.com> 357 + Description: 358 + Some regulator directories will contain a field called 359 + bypass. This indicates if the device is in bypass mode. 360 + 361 + This will be one of the following strings: 362 + 363 + 'enabled' 364 + 'disabled' 365 + 'unknown' 366 + 367 + 'enabled' means the regulator is in bypass mode. 368 + 369 + 'disabled' means that the regulator is regulating. 370 + 371 + 'unknown' means software cannot determine the state, or 372 + the reported state is invalid.
+85
drivers/regulator/core.c
··· 77 77 struct device *dev; 78 78 struct list_head list; 79 79 unsigned int always_on:1; 80 + unsigned int bypass:1; 80 81 int uA_load; 81 82 int min_uV; 82 83 int max_uV; ··· 395 394 case REGULATOR_STATUS_STANDBY: 396 395 label = "standby"; 397 396 break; 397 + case REGULATOR_STATUS_BYPASS: 398 + label = "bypass"; 399 + break; 398 400 case REGULATOR_STATUS_UNDEFINED: 399 401 label = "undefined"; 400 402 break; ··· 589 585 static DEVICE_ATTR(suspend_standby_state, 0444, 590 586 regulator_suspend_standby_state_show, NULL); 591 587 588 + static ssize_t regulator_bypass_show(struct device *dev, 589 + struct device_attribute *attr, char *buf) 590 + { 591 + struct regulator_dev *rdev = dev_get_drvdata(dev); 592 + const char *report; 593 + bool bypass; 594 + int ret; 595 + 596 + ret = rdev->desc->ops->get_bypass(rdev, &bypass); 597 + 598 + if (ret != 0) 599 + report = "unknown"; 600 + else if (bypass) 601 + report = "enabled"; 602 + else 603 + report = "disabled"; 604 + 605 + return sprintf(buf, "%s\n", report); 606 + } 607 + static DEVICE_ATTR(bypass, 0444, 608 + regulator_bypass_show, NULL); 592 609 593 610 /* 594 611 * These are the only attributes are present for all regulators. ··· 2699 2674 EXPORT_SYMBOL_GPL(regulator_set_optimum_mode); 2700 2675 2701 2676 /** 2677 + * regulator_allow_bypass - allow the regulator to go into bypass mode 2678 + * 2679 + * @regulator: Regulator to configure 2680 + * @allow: enable or disable bypass mode 2681 + * 2682 + * Allow the regulator to go into bypass mode if all other consumers 2683 + * for the regulator also enable bypass mode and the machine 2684 + * constraints allow this. Bypass mode means that the regulator is 2685 + * simply passing the input directly to the output with no regulation. 2686 + */ 2687 + int regulator_allow_bypass(struct regulator *regulator, bool enable) 2688 + { 2689 + struct regulator_dev *rdev = regulator->rdev; 2690 + int ret = 0; 2691 + 2692 + if (!rdev->desc->ops->set_bypass) 2693 + return 0; 2694 + 2695 + if (rdev->constraints && 2696 + !(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_BYPASS)) 2697 + return 0; 2698 + 2699 + mutex_lock(&rdev->mutex); 2700 + 2701 + if (enable && !regulator->bypass) { 2702 + rdev->bypass_count++; 2703 + 2704 + if (rdev->bypass_count == rdev->open_count) { 2705 + ret = rdev->desc->ops->set_bypass(rdev, enable); 2706 + if (ret != 0) 2707 + rdev->bypass_count--; 2708 + } 2709 + 2710 + } else if (!enable && regulator->bypass) { 2711 + rdev->bypass_count--; 2712 + 2713 + if (rdev->bypass_count != rdev->open_count) { 2714 + ret = rdev->desc->ops->set_bypass(rdev, enable); 2715 + if (ret != 0) 2716 + rdev->bypass_count++; 2717 + } 2718 + } 2719 + 2720 + if (ret == 0) 2721 + regulator->bypass = enable; 2722 + 2723 + mutex_unlock(&rdev->mutex); 2724 + 2725 + return ret; 2726 + } 2727 + EXPORT_SYMBOL_GPL(regulator_allow_bypass); 2728 + 2729 + /** 2702 2730 * regulator_register_notifier - register regulator event notifier 2703 2731 * @regulator: regulator source 2704 2732 * @nb: notifier block ··· 3114 3036 if (status < 0) 3115 3037 return status; 3116 3038 } 3039 + if (ops->get_bypass) { 3040 + status = device_create_file(dev, &dev_attr_bypass); 3041 + if (status < 0) 3042 + return status; 3043 + } 3117 3044 3118 3045 /* some attributes are type-specific */ 3119 3046 if (rdev->desc->type == REGULATOR_CURRENT) { ··· 3207 3124 &rdev->use_count); 3208 3125 debugfs_create_u32("open_count", 0444, rdev->debugfs, 3209 3126 &rdev->open_count); 3127 + debugfs_create_u32("bypass_count", 0444, rdev->debugfs, 3128 + &rdev->bypass_count); 3210 3129 } 3211 3130 3212 3131 /**
+8
include/linux/regulator/consumer.h
··· 177 177 unsigned int regulator_get_mode(struct regulator *regulator); 178 178 int regulator_set_optimum_mode(struct regulator *regulator, int load_uA); 179 179 180 + int regulator_allow_bypass(struct regulator *regulator, bool allow); 181 + 180 182 /* regulator notifier block */ 181 183 int regulator_register_notifier(struct regulator *regulator, 182 184 struct notifier_block *nb); ··· 328 326 int load_uA) 329 327 { 330 328 return REGULATOR_MODE_NORMAL; 329 + } 330 + 331 + static inline int regulator_allow_bypass(struct regulator *regulator, 332 + bool allow) 333 + { 334 + return 0; 331 335 } 332 336 333 337 static inline int regulator_register_notifier(struct regulator *regulator,
+10
include/linux/regulator/driver.h
··· 32 32 REGULATOR_STATUS_NORMAL, 33 33 REGULATOR_STATUS_IDLE, 34 34 REGULATOR_STATUS_STANDBY, 35 + /* The regulator is enabled but not regulating */ 36 + REGULATOR_STATUS_BYPASS, 35 37 /* in case that any other status doesn't apply */ 36 38 REGULATOR_STATUS_UNDEFINED, 37 39 }; ··· 68 66 * REGULATOR_STATUS value (or negative errno) 69 67 * @get_optimum_mode: Get the most efficient operating mode for the regulator 70 68 * when running with the specified parameters. 69 + * 70 + * @set_bypass: Set the regulator in bypass mode. 71 + * @get_bypass: Get the regulator bypass mode state. 71 72 * 72 73 * @enable_time: Time taken for the regulator voltage output voltage to 73 74 * stabilise after being enabled, in microseconds. ··· 137 132 /* get most efficient regulator operating mode for load */ 138 133 unsigned int (*get_optimum_mode) (struct regulator_dev *, int input_uV, 139 134 int output_uV, int load_uA); 135 + 136 + /* control and report on bypass mode */ 137 + int (*set_bypass)(struct regulator_dev *dev, bool enable); 138 + int (*get_bypass)(struct regulator_dev *dev, bool *enable); 140 139 141 140 /* the operations below are for configuration of regulator state when 142 141 * its parent PMIC enters a global STANDBY/HIBERNATE state */ ··· 262 253 int exclusive; 263 254 u32 use_count; 264 255 u32 open_count; 256 + u32 bypass_count; 265 257 266 258 /* lists we belong to */ 267 259 struct list_head list; /* list of all regulators */
+2
include/linux/regulator/machine.h
··· 32 32 * board/machine. 33 33 * STATUS: Regulator can be enabled and disabled. 34 34 * DRMS: Dynamic Regulator Mode Switching is enabled for this regulator. 35 + * BYPASS: Regulator can be put into bypass mode 35 36 */ 36 37 37 38 #define REGULATOR_CHANGE_VOLTAGE 0x1 ··· 40 39 #define REGULATOR_CHANGE_MODE 0x4 41 40 #define REGULATOR_CHANGE_STATUS 0x8 42 41 #define REGULATOR_CHANGE_DRMS 0x10 42 + #define REGULATOR_CHANGE_BYPASS 0x20 43 43 44 44 /** 45 45 * struct regulator_state - regulator state during low power system states