summaryrefslogtreecommitdiff
path: root/drivers/regulator/virtual.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/virtual.c')
-rw-r--r--drivers/regulator/virtual.c52
1 files changed, 38 insertions, 14 deletions
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index a6f1c7a9914f..218a0d66a152 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* reg-virtual-consumer.c
*
* Copyright 2008 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.
*/
#include <linux/err.h>
@@ -17,6 +13,7 @@
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/module.h>
+#include <linux/of.h>
struct virtual_consumer_data {
struct mutex lock;
@@ -285,26 +282,53 @@ static const struct attribute_group regulator_virtual_attr_group = {
.attrs = regulator_virtual_attributes,
};
+#ifdef CONFIG_OF
+static const struct of_device_id regulator_virtual_consumer_of_match[] = {
+ { .compatible = "regulator-virtual-consumer" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, regulator_virtual_consumer_of_match);
+#endif
+
static int regulator_virtual_probe(struct platform_device *pdev)
{
char *reg_id = dev_get_platdata(&pdev->dev);
struct virtual_consumer_data *drvdata;
+ static bool warned;
int ret;
+ if (!warned) {
+ warned = true;
+ pr_warn("**********************************************************\n");
+ pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
+ pr_warn("** **\n");
+ pr_warn("** regulator-virtual-consumer is only for testing and **\n");
+ pr_warn("** debugging. Do not use it in a production kernel. **\n");
+ pr_warn("** **\n");
+ pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n");
+ pr_warn("**********************************************************\n");
+ }
+
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct virtual_consumer_data),
GFP_KERNEL);
if (drvdata == NULL)
return -ENOMEM;
+ /*
+ * This virtual consumer does not have any hardware-defined supply
+ * name, so just allow the regulator to be specified in a property
+ * named "default-supply" when we're being probed from devicetree.
+ */
+ if (!reg_id && pdev->dev.of_node)
+ reg_id = "default";
+
mutex_init(&drvdata->lock);
drvdata->regulator = devm_regulator_get(&pdev->dev, reg_id);
- if (IS_ERR(drvdata->regulator)) {
- ret = PTR_ERR(drvdata->regulator);
- dev_err(&pdev->dev, "Failed to obtain supply '%s': %d\n",
- reg_id, ret);
- return ret;
- }
+ if (IS_ERR(drvdata->regulator))
+ return dev_err_probe(&pdev->dev, PTR_ERR(drvdata->regulator),
+ "Failed to obtain supply '%s'\n",
+ reg_id);
ret = sysfs_create_group(&pdev->dev.kobj,
&regulator_virtual_attr_group);
@@ -321,7 +345,7 @@ static int regulator_virtual_probe(struct platform_device *pdev)
return 0;
}
-static int regulator_virtual_remove(struct platform_device *pdev)
+static void regulator_virtual_remove(struct platform_device *pdev)
{
struct virtual_consumer_data *drvdata = platform_get_drvdata(pdev);
@@ -329,8 +353,6 @@ static int regulator_virtual_remove(struct platform_device *pdev)
if (drvdata->enabled)
regulator_disable(drvdata->regulator);
-
- return 0;
}
static struct platform_driver regulator_virtual_consumer_driver = {
@@ -338,6 +360,8 @@ static struct platform_driver regulator_virtual_consumer_driver = {
.remove = regulator_virtual_remove,
.driver = {
.name = "reg-virt-consumer",
+ .probe_type = PROBE_PREFER_ASYNCHRONOUS,
+ .of_match_table = of_match_ptr(regulator_virtual_consumer_of_match),
},
};