@@ -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
@@ -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
@@ -23,6 +23,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);
@@ -1115,6 +1117,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;
@@ -2451,8 +2469,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 */
new file mode 100644
@@ -0,0 +1,66 @@
+/*
+ * dummy.c
+ *
+ * Copyright 2010 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * 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;
+ }
+}
new file mode 100644
@@ -0,0 +1,31 @@
+/*
+ * dummy.h
+ *
+ * Copyright 2010 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * 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