From 1dd68f01886a2d5cabbbe90b86e82f70917de89c Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 2 Feb 2009 21:43:31 +0000 Subject: regulator: email - update email address and regulator webpage. Remove deceased email address and update to new address. Also update website details in MAINTAINERS with correct page. Signed-off-by: Liam Girdwood --- include/linux/regulator/machine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/regulator/machine.h') diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 3794773b23d2..5aa00ee36a3d 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -3,7 +3,7 @@ * * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. * - * Author: Liam Girdwood + * Author: Liam Girdwood * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as -- cgit v1.2.3 From a308466c24b4f42bab6945026e938874d22cde50 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 26 Feb 2009 19:24:19 +0000 Subject: regulator: Allow regulators to set the initial operating mode This is useful when wishing to run in a fixed operating mode that isn't the default. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 17 +++++++++++++++++ include/linux/regulator/machine.h | 4 ++++ 2 files changed, 21 insertions(+) (limited to 'include/linux/regulator/machine.h') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index d55a25a6fab2..75abcd85e51b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -724,6 +724,23 @@ static int set_machine_constraints(struct regulator_dev *rdev, } } + if (constraints->initial_mode) { + if (!ops->set_mode) { + printk(KERN_ERR "%s: no set_mode operation for %s\n", + __func__, name); + ret = -EINVAL; + goto out; + } + + ret = ops->set_mode(rdev, constraints->initial_mode); + if (ret < 0) { + printk(KERN_ERR + "%s: failed to set initial mode for %s: %d\n", + __func__, name, ret); + goto out; + } + } + /* if always_on is set then turn the regulator on if it's not * already on. */ if (constraints->always_on && ops->enable && diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 5aa00ee36a3d..1eb861cf4b2c 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -83,6 +83,7 @@ struct regulator_state { * @state_standby: State for regulator when system is suspended in standby * mode. * @initial_state: Suspend state to set by default. + * @initial_mode: Mode to set at startup. */ struct regulation_constraints { @@ -111,6 +112,9 @@ struct regulation_constraints { struct regulator_state state_standby; suspend_state_t initial_state; /* suspend state to set at init */ + /* mode to set on startup */ + unsigned int initial_mode; + /* constriant flags */ unsigned always_on:1; /* regulator never off when system is on */ unsigned boot_on:1; /* bootloader/firmware enabled regulator */ -- cgit v1.2.3 From cacf90f24e80cec9334f98e0377149f943fe9f16 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 2 Mar 2009 16:32:46 +0000 Subject: regulator: Allow boot_on regulators to be disabled by clients Rather than incrementing the reference count for boot_on regulators (which prevents them being disabled later on) simply force the regulator to be enabled when applying the constraints. Previously boot_on was essentially equivalent to always_on. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 13 ++++--------- include/linux/regulator/machine.h | 4 +++- 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'include/linux/regulator/machine.h') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 2ff76349f392..08441e24946e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -776,10 +776,6 @@ static int set_machine_constraints(struct regulator_dev *rdev, } } - /* are we enabled at boot time by firmware / bootloader */ - if (rdev->constraints->boot_on) - rdev->use_count = 1; - /* do we need to setup our suspend state */ if (constraints->initial_state) { ret = suspend_prepare(rdev, constraints->initial_state); @@ -808,11 +804,10 @@ static int set_machine_constraints(struct regulator_dev *rdev, } } - /* if always_on is set then turn the regulator on if it's not - * already on. */ - if (constraints->always_on && ops->enable && - ((ops->is_enabled && !ops->is_enabled(rdev)) || - (!ops->is_enabled && !constraints->boot_on))) { + /* If the constraints say the regulator should be on at this point + * and we have control then make sure it is enabled. + */ + if ((constraints->always_on || constraints->boot_on) && ops->enable) { ret = ops->enable(rdev); if (ret < 0) { printk(KERN_ERR "%s: failed to enable %s\n", diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 1eb861cf4b2c..5de7aa3b02a6 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -73,7 +73,9 @@ struct regulator_state { * * @always_on: Set if the regulator should never be disabled. * @boot_on: Set if the regulator is enabled when the system is initially - * started. + * started. If the regulator is not enabled by the hardware or + * bootloader then it will be enabled when the constraints are + * applied. * @apply_uV: Apply the voltage constraint when initialising. * * @input_uV: Input voltage for regulator when supplied by another regulator. -- cgit v1.2.3 From ca7255614e0861e36480103f4a402a115803d7b5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 16 Mar 2009 19:36:34 +0000 Subject: regulator: Support disabling of unused regulators by machines At present it is not possible for machine constraints to disable regulators which have been left on when the system starts, for example as a result of fixed default configurations in hardware. This means that power may be wasted by these regulators if they are not in use. Provide intial support for this with a late_initcall which will disable any unused regulators if the machine has enabled this feature by calling regulator_has_full_constraints(). If this has not been called then print a warning to encourage users to fully specify their constraints so that we can change this to be the default behaviour in future. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/core.c | 92 +++++++++++++++++++++++++++++++++++++++ include/linux/regulator/machine.h | 2 + 2 files changed, 94 insertions(+) (limited to 'include/linux/regulator/machine.h') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 8588a2490e0a..01f7702a805d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -28,6 +28,7 @@ static DEFINE_MUTEX(regulator_list_mutex); static LIST_HEAD(regulator_list); static LIST_HEAD(regulator_map_list); +static int has_full_constraints; /* * struct regulator_map @@ -2142,6 +2143,23 @@ out: } EXPORT_SYMBOL_GPL(regulator_suspend_prepare); +/** + * regulator_has_full_constraints - the system has fully specified constraints + * + * Calling this function will cause the regulator API to disable all + * regulators which have a zero use count and don't have an always_on + * constraint in a late_initcall. + * + * The intention is that this will become the default behaviour in a + * future kernel release so users are encouraged to use this facility + * now. + */ +void regulator_has_full_constraints(void) +{ + has_full_constraints = 1; +} +EXPORT_SYMBOL_GPL(regulator_has_full_constraints); + /** * rdev_get_drvdata - get rdev regulator driver data * @rdev: regulator @@ -2209,3 +2227,77 @@ static int __init regulator_init(void) /* init early to allow our consumers to complete system booting */ core_initcall(regulator_init); + +static int __init regulator_init_complete(void) +{ + struct regulator_dev *rdev; + struct regulator_ops *ops; + struct regulation_constraints *c; + int enabled, ret; + const char *name; + + mutex_lock(®ulator_list_mutex); + + /* If we have a full configuration then disable any regulators + * which are not in use or always_on. This will become the + * default behaviour in the future. + */ + list_for_each_entry(rdev, ®ulator_list, list) { + ops = rdev->desc->ops; + c = rdev->constraints; + + if (c->name) + name = c->name; + else if (rdev->desc->name) + name = rdev->desc->name; + else + name = "regulator"; + + if (!ops->disable || c->always_on) + continue; + + mutex_lock(&rdev->mutex); + + if (rdev->use_count) + goto unlock; + + /* If we can't read the status assume it's on. */ + if (ops->is_enabled) + enabled = ops->is_enabled(rdev); + else + enabled = 1; + + if (!enabled) + goto unlock; + + if (has_full_constraints) { + /* We log since this may kill the system if it + * goes wrong. */ + printk(KERN_INFO "%s: disabling %s\n", + __func__, name); + ret = ops->disable(rdev); + if (ret != 0) { + printk(KERN_ERR + "%s: couldn't disable %s: %d\n", + __func__, name, ret); + } + } else { + /* The intention is that in future we will + * assume that full constraints are provided + * so warn even if we aren't going to do + * anything here. + */ + printk(KERN_WARNING + "%s: incomplete constraints, leaving %s on\n", + __func__, name); + } + +unlock: + mutex_unlock(&rdev->mutex); + } + + mutex_unlock(®ulator_list_mutex); + + return 0; +} +late_initcall(regulator_init_complete); diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 5de7aa3b02a6..bac64fa390f2 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -166,4 +166,6 @@ struct regulator_init_data { int regulator_suspend_prepare(suspend_state_t state); +void regulator_has_full_constraints(void); + #endif -- cgit v1.2.3