Merge tag 'docs-5.3' of git://git.lwn.net/linux
[linux-2.6-microblaze.git] / drivers / regulator / core.c
index c5d8996..e0c0cf4 100644 (file)
@@ -1,12 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * core.c  --  Voltage/Current Regulator framework.
- *
- * Copyright 2007, 2008 Wolfson Microelectronics PLC.
- * Copyright 2008 SlimLogic Ltd.
- *
- * Author: Liam Girdwood <lrg@slimlogic.co.uk>
- */
+//
+// core.c  --  Voltage/Current Regulator framework.
+//
+// Copyright 2007, 2008 Wolfson Microelectronics PLC.
+// Copyright 2008 SlimLogic Ltd.
+//
+// Author: Liam Girdwood <lrg@slimlogic.co.uk>
 
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -23,6 +22,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/consumer.h>
+#include <linux/regulator/coupler.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
 #include <linux/module.h>
@@ -50,6 +50,7 @@ static DEFINE_MUTEX(regulator_list_mutex);
 static LIST_HEAD(regulator_map_list);
 static LIST_HEAD(regulator_ena_gpio_list);
 static LIST_HEAD(regulator_supply_alias_list);
+static LIST_HEAD(regulator_coupler_list);
 static bool has_full_constraints;
 
 static struct dentry *debugfs_root;
@@ -93,7 +94,6 @@ struct regulator_supply_alias {
 
 static int _regulator_is_enabled(struct regulator_dev *rdev);
 static int _regulator_disable(struct regulator *regulator);
-static int _regulator_get_voltage(struct regulator_dev *rdev);
 static int _regulator_get_current_limit(struct regulator_dev *rdev);
 static unsigned int _regulator_get_mode(struct regulator_dev *rdev);
 static int _notifier_call_chain(struct regulator_dev *rdev,
@@ -102,15 +102,12 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                                     int min_uV, int max_uV);
 static int regulator_balance_voltage(struct regulator_dev *rdev,
                                     suspend_state_t state);
-static int regulator_set_voltage_rdev(struct regulator_dev *rdev,
-                                     int min_uV, int max_uV,
-                                     suspend_state_t state);
 static struct regulator *create_regulator(struct regulator_dev *rdev,
                                          struct device *dev,
                                          const char *supply_name);
 static void _regulator_put(struct regulator *regulator);
 
-static const char *rdev_get_name(struct regulator_dev *rdev)
+const char *rdev_get_name(struct regulator_dev *rdev)
 {
        if (rdev->constraints && rdev->constraints->name)
                return rdev->constraints->name;
@@ -424,8 +421,8 @@ static struct device_node *of_get_regulator(struct device *dev, const char *supp
 }
 
 /* Platform voltage constraint check */
-static int regulator_check_voltage(struct regulator_dev *rdev,
-                                  int *min_uV, int *max_uV)
+int regulator_check_voltage(struct regulator_dev *rdev,
+                           int *min_uV, int *max_uV)
 {
        BUG_ON(*min_uV > *max_uV);
 
@@ -457,9 +454,9 @@ static int regulator_check_states(suspend_state_t state)
 /* Make sure we select a voltage that suits the needs of all
  * regulator consumers
  */
-static int regulator_check_consumers(struct regulator_dev *rdev,
-                                    int *min_uV, int *max_uV,
-                                    suspend_state_t state)
+int regulator_check_consumers(struct regulator_dev *rdev,
+                             int *min_uV, int *max_uV,
+                             suspend_state_t state)
 {
        struct regulator *regulator;
        struct regulator_voltage *voltage;
@@ -570,7 +567,7 @@ static ssize_t regulator_uV_show(struct device *dev,
        ssize_t ret;
 
        regulator_lock(rdev);
-       ret = sprintf(buf, "%d\n", _regulator_get_voltage(rdev));
+       ret = sprintf(buf, "%d\n", regulator_get_voltage_rdev(rdev));
        regulator_unlock(rdev);
 
        return ret;
@@ -941,7 +938,7 @@ static int drms_uA_update(struct regulator_dev *rdev)
                        rdev_err(rdev, "failed to set load %d\n", current_uA);
        } else {
                /* get output voltage */
-               output_uV = _regulator_get_voltage(rdev);
+               output_uV = regulator_get_voltage_rdev(rdev);
                if (output_uV <= 0) {
                        rdev_err(rdev, "invalid output voltage found\n");
                        return -EINVAL;
@@ -1054,7 +1051,7 @@ static void print_constraints(struct regulator_dev *rdev)
 
        if (!constraints->min_uV ||
            constraints->min_uV != constraints->max_uV) {
-               ret = _regulator_get_voltage(rdev);
+               ret = regulator_get_voltage_rdev(rdev);
                if (ret > 0)
                        count += scnprintf(buf + count, len - count,
                                           "at %d mV ", ret / 1000);
@@ -1113,7 +1110,7 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
        if (rdev->constraints->apply_uV &&
            rdev->constraints->min_uV && rdev->constraints->max_uV) {
                int target_min, target_max;
-               int current_uV = _regulator_get_voltage(rdev);
+               int current_uV = regulator_get_voltage_rdev(rdev);
 
                if (current_uV == -ENOTRECOVERABLE) {
                        /* This regulator can't be read and must be initialized */
@@ -1123,7 +1120,7 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
                        _regulator_do_set_voltage(rdev,
                                                  rdev->constraints->min_uV,
                                                  rdev->constraints->max_uV);
-                       current_uV = _regulator_get_voltage(rdev);
+                       current_uV = regulator_get_voltage_rdev(rdev);
                }
 
                if (current_uV < 0) {
@@ -1645,9 +1642,9 @@ static int _regulator_get_enable_time(struct regulator_dev *rdev)
 {
        if (rdev->constraints && rdev->constraints->enable_time)
                return rdev->constraints->enable_time;
-       if (!rdev->desc->ops->enable_time)
-               return rdev->desc->enable_time;
-       return rdev->desc->ops->enable_time(rdev);
+       if (rdev->desc->ops->enable_time)
+               return rdev->desc->ops->enable_time(rdev);
+       return rdev->desc->enable_time;
 }
 
 static struct regulator_supply_alias *regulator_find_supply_alias(
@@ -3065,7 +3062,7 @@ static int _regulator_call_set_voltage(struct regulator_dev *rdev,
        struct pre_voltage_change_data data;
        int ret;
 
-       data.old_uV = _regulator_get_voltage(rdev);
+       data.old_uV = regulator_get_voltage_rdev(rdev);
        data.min_uV = min_uV;
        data.max_uV = max_uV;
        ret = _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_VOLTAGE_CHANGE,
@@ -3089,7 +3086,7 @@ static int _regulator_call_set_voltage_sel(struct regulator_dev *rdev,
        struct pre_voltage_change_data data;
        int ret;
 
-       data.old_uV = _regulator_get_voltage(rdev);
+       data.old_uV = regulator_get_voltage_rdev(rdev);
        data.min_uV = uV;
        data.max_uV = uV;
        ret = _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_VOLTAGE_CHANGE,
@@ -3107,6 +3104,66 @@ static int _regulator_call_set_voltage_sel(struct regulator_dev *rdev,
        return ret;
 }
 
+static int _regulator_set_voltage_sel_step(struct regulator_dev *rdev,
+                                          int uV, int new_selector)
+{
+       const struct regulator_ops *ops = rdev->desc->ops;
+       int diff, old_sel, curr_sel, ret;
+
+       /* Stepping is only needed if the regulator is enabled. */
+       if (!_regulator_is_enabled(rdev))
+               goto final_set;
+
+       if (!ops->get_voltage_sel)
+               return -EINVAL;
+
+       old_sel = ops->get_voltage_sel(rdev);
+       if (old_sel < 0)
+               return old_sel;
+
+       diff = new_selector - old_sel;
+       if (diff == 0)
+               return 0; /* No change needed. */
+
+       if (diff > 0) {
+               /* Stepping up. */
+               for (curr_sel = old_sel + rdev->desc->vsel_step;
+                    curr_sel < new_selector;
+                    curr_sel += rdev->desc->vsel_step) {
+                       /*
+                        * Call the callback directly instead of using
+                        * _regulator_call_set_voltage_sel() as we don't
+                        * want to notify anyone yet. Same in the branch
+                        * below.
+                        */
+                       ret = ops->set_voltage_sel(rdev, curr_sel);
+                       if (ret)
+                               goto try_revert;
+               }
+       } else {
+               /* Stepping down. */
+               for (curr_sel = old_sel - rdev->desc->vsel_step;
+                    curr_sel > new_selector;
+                    curr_sel -= rdev->desc->vsel_step) {
+                       ret = ops->set_voltage_sel(rdev, curr_sel);
+                       if (ret)
+                               goto try_revert;
+               }
+       }
+
+final_set:
+       /* The final selector will trigger the notifiers. */
+       return _regulator_call_set_voltage_sel(rdev, uV, new_selector);
+
+try_revert:
+       /*
+        * At least try to return to the previous voltage if setting a new
+        * one failed.
+        */
+       (void)ops->set_voltage_sel(rdev, old_sel);
+       return ret;
+}
+
 static int _regulator_set_voltage_time(struct regulator_dev *rdev,
                                       int old_uV, int new_uV)
 {
@@ -3142,7 +3199,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
        unsigned int selector;
        int old_selector = -1;
        const struct regulator_ops *ops = rdev->desc->ops;
-       int old_uV = _regulator_get_voltage(rdev);
+       int old_uV = regulator_get_voltage_rdev(rdev);
 
        trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
 
@@ -3169,7 +3226,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                                best_val = ops->list_voltage(rdev,
                                                             selector);
                        else
-                               best_val = _regulator_get_voltage(rdev);
+                               best_val = regulator_get_voltage_rdev(rdev);
                }
 
        } else if (ops->set_voltage_sel) {
@@ -3180,6 +3237,9 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
                                selector = ret;
                                if (old_selector == selector)
                                        ret = 0;
+                               else if (rdev->desc->vsel_step)
+                                       ret = _regulator_set_voltage_sel_step(
+                                               rdev, best_val, selector);
                                else
                                        ret = _regulator_call_set_voltage_sel(
                                                rdev, best_val, selector);
@@ -3288,7 +3348,7 @@ static int regulator_set_voltage_unlocked(struct regulator *regulator,
         * changing the voltage.
         */
        if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
-               current_uV = _regulator_get_voltage(rdev);
+               current_uV = regulator_get_voltage_rdev(rdev);
                if (min_uV <= current_uV && current_uV <= max_uV) {
                        voltage->min_uV = min_uV;
                        voltage->max_uV = max_uV;
@@ -3325,8 +3385,8 @@ out:
        return ret;
 }
 
-static int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV,
-                                     int max_uV, suspend_state_t state)
+int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV,
+                              int max_uV, suspend_state_t state)
 {
        int best_supply_uV = 0;
        int supply_change_uV = 0;
@@ -3354,7 +3414,7 @@ static int regulator_set_voltage_rdev(struct regulator_dev *rdev, int min_uV,
 
                best_supply_uV += rdev->desc->min_dropout_uV;
 
-               current_supply_uV = _regulator_get_voltage(rdev->supply->rdev);
+               current_supply_uV = regulator_get_voltage_rdev(rdev->supply->rdev);
                if (current_supply_uV < 0) {
                        ret = current_supply_uV;
                        goto out;
@@ -3405,7 +3465,7 @@ static int regulator_limit_voltage_step(struct regulator_dev *rdev,
                return 1;
 
        if (*current_uV < 0) {
-               *current_uV = _regulator_get_voltage(rdev);
+               *current_uV = regulator_get_voltage_rdev(rdev);
 
                if (*current_uV < 0)
                        return *current_uV;
@@ -3434,11 +3494,10 @@ static int regulator_get_optimal_voltage(struct regulator_dev *rdev,
        struct coupling_desc *c_desc = &rdev->coupling_desc;
        struct regulator_dev **c_rdevs = c_desc->coupled_rdevs;
        struct regulation_constraints *constraints = rdev->constraints;
-       int max_spread = constraints->max_spread;
        int desired_min_uV = 0, desired_max_uV = INT_MAX;
        int max_current_uV = 0, min_current_uV = INT_MAX;
        int highest_min_uV = 0, target_uV, possible_uV;
-       int i, ret;
+       int i, ret, max_spread;
        bool done;
 
        *current_uV = -1;
@@ -3492,6 +3551,8 @@ static int regulator_get_optimal_voltage(struct regulator_dev *rdev,
                }
        }
 
+       max_spread = constraints->max_spread[0];
+
        /*
         * Let target_uV be equal to the desired one if possible.
         * If not, set it to minimum voltage, allowed by other coupled
@@ -3509,7 +3570,7 @@ static int regulator_get_optimal_voltage(struct regulator_dev *rdev,
                if (!_regulator_is_enabled(c_rdevs[i]))
                        continue;
 
-               tmp_act = _regulator_get_voltage(c_rdevs[i]);
+               tmp_act = regulator_get_voltage_rdev(c_rdevs[i]);
                if (tmp_act < 0)
                        return tmp_act;
 
@@ -3551,7 +3612,7 @@ finish:
        if (n_coupled > 1 && *current_uV == -1) {
 
                if (_regulator_is_enabled(rdev)) {
-                       ret = _regulator_get_voltage(rdev);
+                       ret = regulator_get_voltage_rdev(rdev);
                        if (ret < 0)
                                return ret;
 
@@ -3573,9 +3634,11 @@ static int regulator_balance_voltage(struct regulator_dev *rdev,
        struct regulator_dev **c_rdevs;
        struct regulator_dev *best_rdev;
        struct coupling_desc *c_desc = &rdev->coupling_desc;
+       struct regulator_coupler *coupler = c_desc->coupler;
        int i, ret, n_coupled, best_min_uV, best_max_uV, best_c_rdev;
-       bool best_c_rdev_done, c_rdev_done[MAX_COUPLED];
        unsigned int delta, best_delta;
+       unsigned long c_rdev_done = 0;
+       bool best_c_rdev_done;
 
        c_rdevs = c_desc->coupled_rdevs;
        n_coupled = c_desc->n_coupled;
@@ -3592,8 +3655,9 @@ static int regulator_balance_voltage(struct regulator_dev *rdev,
                return -EPERM;
        }
 
-       for (i = 0; i < n_coupled; i++)
-               c_rdev_done[i] = false;
+       /* Invoke custom balancer for customized couplers */
+       if (coupler && coupler->balance_voltage)
+               return coupler->balance_voltage(coupler, rdev, state);
 
        /*
         * Find the best possible voltage change on each loop. Leave the loop
@@ -3620,7 +3684,7 @@ static int regulator_balance_voltage(struct regulator_dev *rdev,
                         */
                        int optimal_uV = 0, optimal_max_uV = 0, current_uV = 0;
 
-                       if (c_rdev_done[i])
+                       if (test_bit(i, &c_rdev_done))
                                continue;
 
                        ret = regulator_get_optimal_voltage(c_rdevs[i],
@@ -3655,7 +3719,8 @@ static int regulator_balance_voltage(struct regulator_dev *rdev,
                if (ret < 0)
                        goto out;
 
-               c_rdev_done[best_c_rdev] = best_c_rdev_done;
+               if (best_c_rdev_done)
+                       set_bit(best_c_rdev, &c_rdev_done);
 
        } while (n_coupled > 1);
 
@@ -3911,7 +3976,7 @@ out:
 }
 EXPORT_SYMBOL_GPL(regulator_sync_voltage);
 
-static int _regulator_get_voltage(struct regulator_dev *rdev)
+int regulator_get_voltage_rdev(struct regulator_dev *rdev)
 {
        int sel, ret;
        bool bypassed;
@@ -3928,7 +3993,7 @@ static int _regulator_get_voltage(struct regulator_dev *rdev)
                                return -EPROBE_DEFER;
                        }
 
-                       return _regulator_get_voltage(rdev->supply->rdev);
+                       return regulator_get_voltage_rdev(rdev->supply->rdev);
                }
        }
 
@@ -3944,7 +4009,7 @@ static int _regulator_get_voltage(struct regulator_dev *rdev)
        } else if (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1)) {
                ret = rdev->desc->fixed_uV;
        } else if (rdev->supply) {
-               ret = _regulator_get_voltage(rdev->supply->rdev);
+               ret = regulator_get_voltage_rdev(rdev->supply->rdev);
        } else {
                return -EINVAL;
        }
@@ -3969,7 +4034,7 @@ int regulator_get_voltage(struct regulator *regulator)
        int ret;
 
        regulator_lock_dependent(regulator->rdev, &ww_ctx);
-       ret = _regulator_get_voltage(regulator->rdev);
+       ret = regulator_get_voltage_rdev(regulator->rdev);
        regulator_unlock_dependent(regulator->rdev, &ww_ctx);
 
        return ret;
@@ -4707,8 +4772,60 @@ static int regulator_register_resolve_supply(struct device *dev, void *data)
        return 0;
 }
 
+int regulator_coupler_register(struct regulator_coupler *coupler)
+{
+       mutex_lock(&regulator_list_mutex);
+       list_add_tail(&coupler->list, &regulator_coupler_list);
+       mutex_unlock(&regulator_list_mutex);
+
+       return 0;
+}
+
+static struct regulator_coupler *
+regulator_find_coupler(struct regulator_dev *rdev)
+{
+       struct regulator_coupler *coupler;
+       int err;
+
+       /*
+        * Note that regulators are appended to the list and the generic
+        * coupler is registered first, hence it will be attached at last
+        * if nobody cared.
+        */
+       list_for_each_entry_reverse(coupler, &regulator_coupler_list, list) {
+               err = coupler->attach_regulator(coupler, rdev);
+               if (!err) {
+                       if (!coupler->balance_voltage &&
+                           rdev->coupling_desc.n_coupled > 2)
+                               goto err_unsupported;
+
+                       return coupler;
+               }
+
+               if (err < 0)
+                       return ERR_PTR(err);
+
+               if (err == 1)
+                       continue;
+
+               break;
+       }
+
+       return ERR_PTR(-EINVAL);
+
+err_unsupported:
+       if (coupler->detach_regulator)
+               coupler->detach_regulator(coupler, rdev);
+
+       rdev_err(rdev,
+               "Voltage balancing for multiple regulator couples is unimplemented\n");
+
+       return ERR_PTR(-EPERM);
+}
+
 static void regulator_resolve_coupling(struct regulator_dev *rdev)
 {
+       struct regulator_coupler *coupler = rdev->coupling_desc.coupler;
        struct coupling_desc *c_desc = &rdev->coupling_desc;
        int n_coupled = c_desc->n_coupled;
        struct regulator_dev *c_rdev;
@@ -4724,6 +4841,12 @@ static void regulator_resolve_coupling(struct regulator_dev *rdev)
                if (!c_rdev)
                        continue;
 
+               if (c_rdev->coupling_desc.coupler != coupler) {
+                       rdev_err(rdev, "coupler mismatch with %s\n",
+                                rdev_get_name(c_rdev));
+                       return;
+               }
+
                regulator_lock(c_rdev);
 
                c_desc->coupled_rdevs[i] = c_rdev;
@@ -4737,10 +4860,12 @@ static void regulator_resolve_coupling(struct regulator_dev *rdev)
 
 static void regulator_remove_coupling(struct regulator_dev *rdev)
 {
+       struct regulator_coupler *coupler = rdev->coupling_desc.coupler;
        struct coupling_desc *__c_desc, *c_desc = &rdev->coupling_desc;
        struct regulator_dev *__c_rdev, *c_rdev;
        unsigned int __n_coupled, n_coupled;
        int i, k;
+       int err;
 
        n_coupled = c_desc->n_coupled;
 
@@ -4770,21 +4895,33 @@ static void regulator_remove_coupling(struct regulator_dev *rdev)
                c_desc->coupled_rdevs[i] = NULL;
                c_desc->n_resolved--;
        }
+
+       if (coupler && coupler->detach_regulator) {
+               err = coupler->detach_regulator(coupler, rdev);
+               if (err)
+                       rdev_err(rdev, "failed to detach from coupler: %d\n",
+                                err);
+       }
+
+       kfree(rdev->coupling_desc.coupled_rdevs);
+       rdev->coupling_desc.coupled_rdevs = NULL;
 }
 
 static int regulator_init_coupling(struct regulator_dev *rdev)
 {
-       int n_phandles;
+       int err, n_phandles;
+       size_t alloc_size;
 
        if (!IS_ENABLED(CONFIG_OF))
                n_phandles = 0;
        else
                n_phandles = of_get_n_coupled(rdev);
 
-       if (n_phandles + 1 > MAX_COUPLED) {
-               rdev_err(rdev, "too many regulators coupled\n");
-               return -EPERM;
-       }
+       alloc_size = sizeof(*rdev) * (n_phandles + 1);
+
+       rdev->coupling_desc.coupled_rdevs = kzalloc(alloc_size, GFP_KERNEL);
+       if (!rdev->coupling_desc.coupled_rdevs)
+               return -ENOMEM;
 
        /*
         * Every regulator should always have coupling descriptor filled with
@@ -4798,23 +4935,35 @@ static int regulator_init_coupling(struct regulator_dev *rdev)
        if (n_phandles == 0)
                return 0;
 
-       /* regulator, which can't change its voltage, can't be coupled */
-       if (!regulator_ops_is_valid(rdev, REGULATOR_CHANGE_VOLTAGE)) {
-               rdev_err(rdev, "voltage operation not allowed\n");
+       if (!of_check_coupling_data(rdev))
                return -EPERM;
-       }
 
-       if (rdev->constraints->max_spread <= 0) {
-               rdev_err(rdev, "wrong max_spread value\n");
-               return -EPERM;
+       rdev->coupling_desc.coupler = regulator_find_coupler(rdev);
+       if (IS_ERR(rdev->coupling_desc.coupler)) {
+               err = PTR_ERR(rdev->coupling_desc.coupler);
+               rdev_err(rdev, "failed to get coupler: %d\n", err);
+               return err;
        }
 
-       if (!of_check_coupling_data(rdev))
+       return 0;
+}
+
+static int generic_coupler_attach(struct regulator_coupler *coupler,
+                                 struct regulator_dev *rdev)
+{
+       if (rdev->coupling_desc.n_coupled > 2) {
+               rdev_err(rdev,
+                        "Voltage balancing for multiple regulator couples is unimplemented\n");
                return -EPERM;
+       }
 
        return 0;
 }
 
+static struct regulator_coupler generic_regulator_coupler = {
+       .attach_regulator = generic_coupler_attach,
+};
+
 /**
  * regulator_register - register regulator
  * @regulator_desc: regulator to register
@@ -4976,7 +5125,9 @@ regulator_register(const struct regulator_desc *regulator_desc,
        if (ret < 0)
                goto wash;
 
+       mutex_lock(&regulator_list_mutex);
        ret = regulator_init_coupling(rdev);
+       mutex_unlock(&regulator_list_mutex);
        if (ret < 0)
                goto wash;
 
@@ -5025,6 +5176,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
 unset_supplies:
        mutex_lock(&regulator_list_mutex);
        unset_regulator_supplies(rdev);
+       regulator_remove_coupling(rdev);
        mutex_unlock(&regulator_list_mutex);
 wash:
        kfree(rdev->constraints);
@@ -5278,7 +5430,7 @@ static void regulator_summary_show_subtree(struct seq_file *s,
                   rdev->use_count, rdev->open_count, rdev->bypass_count,
                   regulator_opmode_to_str(opmode));
 
-       seq_printf(s, "%5dmV ", _regulator_get_voltage(rdev) / 1000);
+       seq_printf(s, "%5dmV ", regulator_get_voltage_rdev(rdev) / 1000);
        seq_printf(s, "%5dmA ",
                   _regulator_get_current_limit_unlocked(rdev) / 1000);
 
@@ -5480,6 +5632,8 @@ static int __init regulator_init(void)
 #endif
        regulator_dummy_init();
 
+       regulator_coupler_register(&generic_regulator_coupler);
+
        return ret;
 }