In order to ease transitions with drivers are boards start using regulators
provide an option to cause all regulator_get() calls to succeed, with a
dummy always on regulator being supplied where one has not been configured.
A warning is printed whenever the dummy regulator is used to aid system
development.
This regulator does not implement any regulator operations but will allow
simple consumers which only do enable() and disable() calls to run. It
is kept separate from the fixed voltage regulator to avoid Kconfig
confusion on the part of users when it is extended to allow boards to
explicitly use the dummy regulator to simplify cases where the majority
of supplies are from fixed regulators without software control.
This option is currently only effective for systems which do not specify
full constriants. If required an override could also be provided to allow
these systems to use the dummy regulator, though it is likely that
unconfigured supplies on such systems will lead to error due to
regulators being powered down more aggressively when not in use.
Signed-off-by: Mark Brown <[email protected]>
---
drivers/regulator/Kconfig | 11 +++++++
drivers/regulator/Makefile | 1 +
drivers/regulator/core.c | 27 ++++++++++++++++-
drivers/regulator/dummy.c | 71 ++++++++++++++++++++++++++++++++++++++++++++
drivers/regulator/dummy.h | 31 +++++++++++++++++++
5 files changed, 140 insertions(+), 1 deletions(-)
create mode 100644 drivers/regulator/dummy.c
create mode 100644 drivers/regulator/dummy.h
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 3c07169..834b484 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -27,6 +27,17 @@ config REGULATOR_DEBUG
help
Say yes here to enable debugging support.
+config REGULATOR_DUMMY
+ bool "Provide a dummy regulator if regulator lookups fail"
+ help
+ If this option is enabled then when a regulator lookup fails
+ and the board has not specified that it has provided full
+ constraints then the regulator core will provide an always
+ enabled dummy regulator will be provided, allowing consumer
+ drivers to continue.
+
+ A warning will be generated when this substitution is done.
+
config REGULATOR_FIXED_VOLTAGE
tristate "Fixed voltage regulator support"
help
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 7c59bcb..e845b66 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_DUMMY) += dummy.o
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 75a26f7..c7bbe30 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -24,6 +24,8 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
+#include "dummy.h"
+
#define REGULATOR_VERSION "0.5"
static DEFINE_MUTEX(regulator_list_mutex);
@@ -1123,6 +1125,22 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
goto found;
}
}
+
+#ifdef CONFIG_REGULATOR_DUMMY
+ if (!devname)
+ devname = "deviceless";
+
+ /* If the board didn't flag that it was fully constrained then
+ * substitute in a dummy regulator so consumers can continue.
+ */
+ if (!has_full_constraints) {
+ pr_warning("%s supply %s not found, using dummy regulator\n",
+ devname, id);
+ rdev = dummy_regulator_rdev;
+ goto found;
+ }
+#endif
+
mutex_unlock(®ulator_list_mutex);
return regulator;
@@ -2483,8 +2501,15 @@ EXPORT_SYMBOL_GPL(regulator_get_init_drvdata);
static int __init regulator_init(void)
{
+ int ret;
+
printk(KERN_INFO "regulator: core version %s\n", REGULATOR_VERSION);
- return class_register(®ulator_class);
+
+ ret = class_register(®ulator_class);
+
+ regulator_dummy_init();
+
+ return ret;
}
/* init early to allow our consumers to complete system booting */
diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c
new file mode 100644
index 0000000..a41c733
--- /dev/null
+++ b/drivers/regulator/dummy.c
@@ -0,0 +1,71 @@
+/*
+ * dummy.c
+ *
+ * Copyright 2010 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This is useful for systems with mixed controllable and
+ * non-controllable regulators, as well as for allowing testing on
+ * systems with no controllable regulators.
+ */
+
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#include "dummy.h"
+
+struct regulator_dev *dummy_regulator_rdev;
+
+static struct regulator_init_data dummy_initdata;
+
+static struct regulator_ops dummy_ops;
+
+static struct regulator_desc dummy_desc = {
+ .name = "dummy",
+ .id = -1,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .ops = &dummy_ops,
+};
+
+static struct platform_device *dummy_pdev;
+
+void __init regulator_dummy_init(void)
+{
+ int ret;
+
+ dummy_pdev = platform_device_alloc("reg-dummy", -1);
+ if (!dummy_pdev) {
+ pr_err("Failed to allocate dummy regulator device\n");
+ return -ENODEV;
+ }
+
+ ret = platform_device_add(dummy_pdev);
+ if (ret != 0) {
+ pr_err("Failed to register dummy regulator device: %d\n", ret);
+ goto err;
+ }
+
+ dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
+ &dummy_initdata, NULL);
+ if (IS_ERR(dummy_regulator_rdev)) {
+ ret = PTR_ERR(dummy_regulator_rdev);
+ pr_err("Failed to register regulator: %d\n", ret);
+ platform_device_unregister(dummy_pdev);
+ return ret;
+ }
+
+ return 0;
+
+err:
+ platform_device_put(dummy_pdev);
+ return ret;
+}
diff --git a/drivers/regulator/dummy.h b/drivers/regulator/dummy.h
new file mode 100644
index 0000000..3921c0e
--- /dev/null
+++ b/drivers/regulator/dummy.h
@@ -0,0 +1,31 @@
+/*
+ * dummy.h
+ *
+ * Copyright 2010 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This is useful for systems with mixed controllable and
+ * non-controllable regulators, as well as for allowing testing on
+ * systems with no controllable regulators.
+ */
+
+#ifndef _DUMMY_H
+#define _DUMMY_H
+
+struct regulator_dev;
+
+extern struct regulator_dev *dummy_regulator_rdev;
+
+#ifdef CONFIG_REGULATOR_DUMMY
+void __init regulator_dummy_init(void);
+#else
+static inline void regulator_dummy_init(void) { }
+#endif
+
+#endif
--
1.6.6.1
In order to ease transitions with drivers are boards start using regulators
provide an option to cause all regulator_get() calls to succeed, with a
dummy always on regulator being supplied where one has not been configured.
A warning is printed whenever the dummy regulator is used to aid system
development.
This regulator does not implement any regulator operations but will allow
simple consumers which only do enable() and disable() calls to run. It
is kept separate from the fixed voltage regulator to avoid Kconfig
confusion on the part of users when it is extended to allow boards to
explicitly use the dummy regulator to simplify cases where the majority
of supplies are from fixed regulators without software control.
This option is currently only effective for systems which do not specify
full constriants. If required an override could also be provided to allow
these systems to use the dummy regulator, though it is likely that
unconfigured supplies on such systems will lead to error due to
regulators being powered down more aggressively when not in use.
Signed-off-by: Mark Brown <[email protected]>
---
And if we remember that git doesn't overwrite the patch file before
sending...
drivers/regulator/Kconfig | 11 +++++++
drivers/regulator/Makefile | 1 +
drivers/regulator/core.c | 27 +++++++++++++++++-
drivers/regulator/dummy.c | 66 ++++++++++++++++++++++++++++++++++++++++++++
drivers/regulator/dummy.h | 31 ++++++++++++++++++++
5 files changed, 135 insertions(+), 1 deletions(-)
create mode 100644 drivers/regulator/dummy.c
create mode 100644 drivers/regulator/dummy.h
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 3c07169..834b484 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -27,6 +27,17 @@ config REGULATOR_DEBUG
help
Say yes here to enable debugging support.
+config REGULATOR_DUMMY
+ bool "Provide a dummy regulator if regulator lookups fail"
+ help
+ If this option is enabled then when a regulator lookup fails
+ and the board has not specified that it has provided full
+ constraints then the regulator core will provide an always
+ enabled dummy regulator will be provided, allowing consumer
+ drivers to continue.
+
+ A warning will be generated when this substitution is done.
+
config REGULATOR_FIXED_VOLTAGE
tristate "Fixed voltage regulator support"
help
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 7c59bcb..e845b66 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_DUMMY) += dummy.o
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 75a26f7..c7bbe30 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -24,6 +24,8 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
+#include "dummy.h"
+
#define REGULATOR_VERSION "0.5"
static DEFINE_MUTEX(regulator_list_mutex);
@@ -1123,6 +1125,22 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
goto found;
}
}
+
+#ifdef CONFIG_REGULATOR_DUMMY
+ if (!devname)
+ devname = "deviceless";
+
+ /* If the board didn't flag that it was fully constrained then
+ * substitute in a dummy regulator so consumers can continue.
+ */
+ if (!has_full_constraints) {
+ pr_warning("%s supply %s not found, using dummy regulator\n",
+ devname, id);
+ rdev = dummy_regulator_rdev;
+ goto found;
+ }
+#endif
+
mutex_unlock(®ulator_list_mutex);
return regulator;
@@ -2483,8 +2501,15 @@ EXPORT_SYMBOL_GPL(regulator_get_init_drvdata);
static int __init regulator_init(void)
{
+ int ret;
+
printk(KERN_INFO "regulator: core version %s\n", REGULATOR_VERSION);
- return class_register(®ulator_class);
+
+ ret = class_register(®ulator_class);
+
+ regulator_dummy_init();
+
+ return ret;
}
/* init early to allow our consumers to complete system booting */
diff --git a/drivers/regulator/dummy.c b/drivers/regulator/dummy.c
new file mode 100644
index 0000000..c7410bd
--- /dev/null
+++ b/drivers/regulator/dummy.c
@@ -0,0 +1,66 @@
+/*
+ * dummy.c
+ *
+ * Copyright 2010 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This is useful for systems with mixed controllable and
+ * non-controllable regulators, as well as for allowing testing on
+ * systems with no controllable regulators.
+ */
+
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+
+#include "dummy.h"
+
+struct regulator_dev *dummy_regulator_rdev;
+
+static struct regulator_init_data dummy_initdata;
+
+static struct regulator_ops dummy_ops;
+
+static struct regulator_desc dummy_desc = {
+ .name = "dummy",
+ .id = -1,
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .ops = &dummy_ops,
+};
+
+static struct platform_device *dummy_pdev;
+
+void __init regulator_dummy_init(void)
+{
+ int ret;
+
+ dummy_pdev = platform_device_alloc("reg-dummy", -1);
+ if (!dummy_pdev) {
+ pr_err("Failed to allocate dummy regulator device\n");
+ return;
+ }
+
+ ret = platform_device_add(dummy_pdev);
+ if (ret != 0) {
+ pr_err("Failed to register dummy regulator device: %d\n", ret);
+ platform_device_put(dummy_pdev);
+ return;
+ }
+
+ dummy_regulator_rdev = regulator_register(&dummy_desc, NULL,
+ &dummy_initdata, NULL);
+ if (IS_ERR(dummy_regulator_rdev)) {
+ ret = PTR_ERR(dummy_regulator_rdev);
+ pr_err("Failed to register regulator: %d\n", ret);
+ platform_device_unregister(dummy_pdev);
+ return;
+ }
+}
diff --git a/drivers/regulator/dummy.h b/drivers/regulator/dummy.h
new file mode 100644
index 0000000..3921c0e
--- /dev/null
+++ b/drivers/regulator/dummy.h
@@ -0,0 +1,31 @@
+/*
+ * dummy.h
+ *
+ * Copyright 2010 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This is useful for systems with mixed controllable and
+ * non-controllable regulators, as well as for allowing testing on
+ * systems with no controllable regulators.
+ */
+
+#ifndef _DUMMY_H
+#define _DUMMY_H
+
+struct regulator_dev;
+
+extern struct regulator_dev *dummy_regulator_rdev;
+
+#ifdef CONFIG_REGULATOR_DUMMY
+void __init regulator_dummy_init(void);
+#else
+static inline void regulator_dummy_init(void) { }
+#endif
+
+#endif
--
1.6.6.1
On Fri, 2010-02-12 at 10:18 +0000, Mark Brown wrote:
> In order to ease transitions with drivers are boards start using regulators
> provide an option to cause all regulator_get() calls to succeed, with a
> dummy always on regulator being supplied where one has not been configured.
> A warning is printed whenever the dummy regulator is used to aid system
> development.
>
> This regulator does not implement any regulator operations but will allow
> simple consumers which only do enable() and disable() calls to run. It
> is kept separate from the fixed voltage regulator to avoid Kconfig
> confusion on the part of users when it is extended to allow boards to
> explicitly use the dummy regulator to simplify cases where the majority
> of supplies are from fixed regulators without software control.
>
> This option is currently only effective for systems which do not specify
> full constriants. If required an override could also be provided to allow
> these systems to use the dummy regulator, though it is likely that
> unconfigured supplies on such systems will lead to error due to
> regulators being powered down more aggressively when not in use.
>
> Signed-off-by: Mark Brown <[email protected]>
> ---
>
Applied.
Thanks
Liam
--
Freelance Developer, SlimLogic Ltd
ASoC and Voltage Regulator Maintainer.
http://www.slimlogic.co.uk
On Fri, Feb 12, 2010 at 12:18 PM, Mark Brown
<[email protected]> wrote:
> In order to ease transitions with drivers are boards start using regulators
> provide an option to cause all regulator_get() calls to succeed, with a
> dummy always on regulator being supplied where one has not been configured.
> A warning is printed whenever the dummy regulator is used to aid system
> development.
>
> This regulator does not implement any regulator operations but will allow
> simple consumers which only do enable() and disable() calls to run. It
> is kept separate from the fixed voltage regulator to avoid Kconfig
> confusion on the part of users when it is extended to allow boards to
> explicitly use the dummy regulator to simplify cases where the majority
> of supplies are from fixed regulators without software control.
>
> This option is currently only effective for systems which do not specify
> full constriants. If required an override could also be provided to allow
> these systems to use the dummy regulator, though it is likely that
> unconfigured supplies on such systems will lead to error due to
> regulators being powered down more aggressively when not in use.
>
> Signed-off-by: Mark Brown <[email protected]>
> ---
>
hm, tried intentionally nuking regulator setup on my board to test
dummy and drivers started failing on regulator_enable() with -1
(EPERM?). Looks like dummy doesn't have constraints defined, so not
much use of this if _enable() is failing anyway.
BTW, drivers/mmc/host/omap_hsmmc.c has quite a lot of logic related to
vcc_aux being available or not (vcc_aux is typically used to power
some MMC pins and is unused on devices with SD cards, like pandora). I
wonder if it may cause some functionality change there.
On 12 Feb 2010, at 23:01, Grazvydas Ignotas <[email protected]> wrote:
> On Fri, Feb 12, 2010 at 12:18 PM, Mark Brown
> <[email protected]> wrote:
>> In order to ease transitions with drivers are boards start using
>> regulators
>> provide an option to cause all regulator_get() calls to succeed,
>> with a
>> dummy always on regulator being supplied where one has not been
>> configured.
>> A warning is printed whenever the dummy regulator is used to aid
>> system
>> development.
>>
>> This regulator does not implement any regulator operations but will
>> allow
>> simple consumers which only do enable() and disable() calls to run.
>> It
>> is kept separate from the fixed voltage regulator to avoid Kconfig
>> confusion on the part of users when it is extended to allow boards to
>> explicitly use the dummy regulator to simplify cases where the
>> majority
>> of supplies are from fixed regulators without software control.
>>
>> This option is currently only effective for systems which do not
>> specify
>> full constriants. If required an override could also be provided to
>> allow
>> these systems to use the dummy regulator, though it is likely that
>> unconfigured supplies on such systems will lead to error due to
>> regulators being powered down more aggressively when not in use.
>>
>> Signed-off-by: Mark Brown <[email protected]>
>> ---
>>
>
> hm, tried intentionally nuking regulator setup on my board to test
> dummy and drivers started failing on regulator_enable() with -1
> (EPERM?). Looks like dummy doesn't have constraints defined, so not
> much use of this if _enable() is failing anyway.
Hrmpf. That was working for me - are you running the latest regulator
code? There was a bug where it was requiring CHANGE_STATUS even if the
regulator is always on, which isn't sensible since there is no
possibility of actually changing the status. It should now only be
checking for permission to change status if it would actually do so.
There was also a patch yesterday to make regulators that don't define
an is_enabled() report as enabled.
> BTW, drivers/mmc/host/omap_hsmmc.c has quite a lot of logic related to
> vcc_aux being available or not (vcc_aux is typically used to power
> some MMC pins and is unused on devices with SD cards, like pandora). I
> wonder if it may cause some functionality change there.
Yeah, quite possibly. This sort of stuff is one of the reasons it's
much nicer to specify full constraints where possible; it allows
drivers that can have missing supplies to handle that.
On Sat, Feb 13, 2010 at 1:26 AM, Mark Brown
<[email protected]> wrote:
> On 12 Feb 2010, at 23:01, Grazvydas Ignotas <[email protected]> wrote:
>
>> On Fri, Feb 12, 2010 at 12:18 PM, Mark Brown
>> <[email protected]> wrote:
>>>
>>> In order to ease transitions with drivers are boards start using
>>> regulators
>>> provide an option to cause all regulator_get() calls to succeed, with a
>>> dummy always on regulator being supplied where one has not been
>>> configured.
>>> A warning is printed whenever the dummy regulator is used to aid system
>>> development.
>>>
>>> This regulator does not implement any regulator operations but will allow
>>> simple consumers which only do enable() and disable() calls to run. It
>>> is kept separate from the fixed voltage regulator to avoid Kconfig
>>> confusion on the part of users when it is extended to allow boards to
>>> explicitly use the dummy regulator to simplify cases where the majority
>>> of supplies are from fixed regulators without software control.
>>>
>>> This option is currently only effective for systems which do not specify
>>> full constriants. If required an override could also be provided to allow
>>> these systems to use the dummy regulator, though it is likely that
>>> unconfigured supplies on such systems will lead to error due to
>>> regulators being powered down more aggressively when not in use.
>>>
>>> Signed-off-by: Mark Brown <[email protected]>
>>> ---
>>>
>>
>> hm, tried intentionally nuking regulator setup on my board to test
>> dummy and drivers started failing on regulator_enable() with -1
>> (EPERM?). Looks like dummy doesn't have constraints defined, so not
>> much use of this if _enable() is failing anyway.
>
> Hrmpf. That was working for me - are you running the latest regulator code?
> There was a bug where it was requiring CHANGE_STATUS even if the regulator
> is always on, which isn't sensible since there is no possibility of actually
> changing the status. It should now only be checking for permission to change
> status if it would actually do so. There was also a patch yesterday to make
> regulators that don't define an is_enabled() report as enabled.
Oh, it appears I was missing those patches (they were not in last
linux-lest yet), now everything works as expected, thanks.
>
>> BTW, drivers/mmc/host/omap_hsmmc.c has quite a lot of logic related to
>> vcc_aux being available or not (vcc_aux is typically used to power
>> some MMC pins and is unused on devices with SD cards, like pandora). I
>> wonder if it may cause some functionality change there.
>
> Yeah, quite possibly. This sort of stuff is one of the reasons it's much
> nicer to specify full constraints where possible; it allows drivers that can
> have missing supplies to handle that.