Merge branches 'regulator-core', 'regulator-dt' and 'regulator-dummy' into regulator...
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Sun, 22 Jul 2012 18:31:41 +0000 (19:31 +0100)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Sun, 22 Jul 2012 18:31:41 +0000 (19:31 +0100)
1  2  3 
drivers/regulator/core.c

diff --combined drivers/regulator/core.c
@@@@ -108,6 -108,28 -108,28 +108,6 @@@@ static const char *rdev_get_name(struc
                return "";
   }
   
 --/* gets the regulator for a given consumer device */
 --static struct regulator *get_device_regulator(struct device *dev)
 --{
 --     struct regulator *regulator = NULL;
 --     struct regulator_dev *rdev;
 --
 --     mutex_lock(&regulator_list_mutex);
 --     list_for_each_entry(rdev, &regulator_list, list) {
 --             mutex_lock(&rdev->mutex);
 --             list_for_each_entry(regulator, &rdev->consumer_list, list) {
 --                     if (regulator->dev == dev) {
 --                             mutex_unlock(&rdev->mutex);
 --                             mutex_unlock(&regulator_list_mutex);
 --                             return regulator;
 --                     }
 --             }
 --             mutex_unlock(&rdev->mutex);
 --     }
 --     mutex_unlock(&regulator_list_mutex);
 --     return NULL;
 --}
 --
   /**
    * of_get_regulator - get a regulator device node based on supply name
    * @dev: Device pointer for the consumer (of regulator) device
@@@@ -281,6 -303,18 -303,18 +281,6 @@@@ static int regulator_check_drms(struct 
        return 0;
   }
   
 --static ssize_t device_requested_uA_show(struct device *dev,
 --                          struct device_attribute *attr, char *buf)
 --{
 --     struct regulator *regulator;
 --
 --     regulator = get_device_regulator(dev);
 --     if (regulator == NULL)
 --             return 0;
 --
 --     return sprintf(buf, "%d\n", regulator->uA_load);
 --}
 --
   static ssize_t regulator_uV_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
   {
@@@@ -393,9 -427,6 -427,6 +393,9 @@@@ static ssize_t regulator_status_show(st
        case REGULATOR_STATUS_STANDBY:
                label = "standby";
                break;
 ++     case REGULATOR_STATUS_UNDEFINED:
 ++             label = "undefined";
 ++             break;
        default:
                return -ERANGE;
        }
@@@@ -1066,29 -1097,48 -1097,48 +1066,29 @@@@ static struct regulator *create_regulat
        list_add(&regulator->list, &rdev->consumer_list);
   
        if (dev) {
 --             /* create a 'requested_microamps_name' sysfs entry */
 --             size = scnprintf(buf, REG_STR_SIZE,
 --                              "microamps_requested_%s-%s",
 --                              dev_name(dev), supply_name);
 --             if (size >= REG_STR_SIZE)
 --                     goto overflow_err;
 --
                regulator->dev = dev;
 --             sysfs_attr_init(&regulator->dev_attr.attr);
 --             regulator->dev_attr.attr.name = kstrdup(buf, GFP_KERNEL);
 --             if (regulator->dev_attr.attr.name == NULL)
 --                     goto attr_name_err;
 --
 --             regulator->dev_attr.attr.mode = 0444;
 --             regulator->dev_attr.show = device_requested_uA_show;
 --             err = device_create_file(dev, &regulator->dev_attr);
 --             if (err < 0) {
 --                     rdev_warn(rdev, "could not add regulator_dev requested microamps sysfs entry\n");
 --                     goto attr_name_err;
 --             }
   
 --             /* also add a link to the device sysfs entry */
 ++             /* Add a link to the device sysfs entry */
                size = scnprintf(buf, REG_STR_SIZE, "%s-%s",
                                 dev->kobj.name, supply_name);
                if (size >= REG_STR_SIZE)
 --                     goto attr_err;
 ++                     goto overflow_err;
   
                regulator->supply_name = kstrdup(buf, GFP_KERNEL);
                if (regulator->supply_name == NULL)
 --                     goto attr_err;
 ++                     goto overflow_err;
   
                err = sysfs_create_link(&rdev->dev.kobj, &dev->kobj,
                                        buf);
                if (err) {
                        rdev_warn(rdev, "could not add device link %s err %d\n",
                                  dev->kobj.name, err);
 --                     goto link_name_err;
 ++                     /* non-fatal */
                }
        } else {
                regulator->supply_name = kstrdup(supply_name, GFP_KERNEL);
                if (regulator->supply_name == NULL)
 --                     goto attr_err;
 ++                     goto overflow_err;
        }
   
        regulator->debugfs = debugfs_create_dir(regulator->supply_name,
   
        mutex_unlock(&rdev->mutex);
        return regulator;
 --link_name_err:
 --     kfree(regulator->supply_name);
 --attr_err:
 --     device_remove_file(regulator->dev, &regulator->dev_attr);
 --attr_name_err:
 --     kfree(regulator->dev_attr.attr.name);
   overflow_err:
        list_del(&regulator->list);
        kfree(regulator);
@@@@ -1364,8 -1420,11 -1420,11 +1364,8 @@@@ void regulator_put(struct regulator *re
        debugfs_remove_recursive(regulator->debugfs);
   
        /* remove any sysfs entries */
 --     if (regulator->dev) {
 ++     if (regulator->dev)
                sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
 --             device_remove_file(regulator->dev, &regulator->dev_attr);
 --             kfree(regulator->dev_attr.attr.name);
 --     }
        kfree(regulator->supply_name);
        list_del(&regulator->list);
        kfree(regulator);
@@@@ -1400,9 -1459,11 -1459,11 +1400,9 @@@@ void devm_regulator_put(struct regulato
   {
        int rc;
   
 --     rc = devres_destroy(regulator->dev, devm_regulator_release,
 ++     rc = devres_release(regulator->dev, devm_regulator_release,
                            devm_regulator_match, regulator);
 --     if (rc == 0)
 --             regulator_put(regulator);
 --     else
 ++     if (rc != 0)
                WARN_ON(rc);
   }
   EXPORT_SYMBOL_GPL(devm_regulator_put);
@@@@ -1821,31 -1882,6 -1882,6 +1821,31 @@@@ int regulator_list_voltage_linear(struc
   }
   EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
   
 ++/**
 ++ * regulator_list_voltage_table - List voltages with table based mapping
 ++ *
 ++ * @rdev: Regulator device
 ++ * @selector: Selector to convert into a voltage
 ++ *
 ++ * Regulators with table based mapping between voltages and
 ++ * selectors can set volt_table in the regulator descriptor
 ++ * and then use this function as their list_voltage() operation.
 ++ */
 ++int regulator_list_voltage_table(struct regulator_dev *rdev,
 ++                              unsigned int selector)
 ++{
 ++     if (!rdev->desc->volt_table) {
 ++             BUG_ON(!rdev->desc->volt_table);
 ++             return -EINVAL;
 ++     }
 ++
 ++     if (selector >= rdev->desc->n_voltages)
 ++             return -EINVAL;
 ++
 ++     return rdev->desc->volt_table[selector];
 ++}
 ++EXPORT_SYMBOL_GPL(regulator_list_voltage_table);
 ++
   /**
    * regulator_list_voltage - enumerate supported voltages
    * @regulator: regulator source
@@@@ -1892,18 -1928,8 -1928,8 +1892,18 @@@@ EXPORT_SYMBOL_GPL(regulator_list_voltag
   int regulator_is_supported_voltage(struct regulator *regulator,
                                   int min_uV, int max_uV)
   {
 ++     struct regulator_dev *rdev = regulator->rdev;
        int i, voltages, ret;
   
 ++     /* If we can't change voltage check the current voltage */
 ++     if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
 ++             ret = regulator_get_voltage(regulator);
 ++             if (ret >= 0)
 ++                     return (min_uV >= ret && ret <= max_uV);
 ++             else
 ++                     return ret;
 ++     }
 ++
        ret = regulator_count_voltages(regulator);
        if (ret < 0)
                return ret;
@@@@ -2024,6 -2050,9 -2050,9 +2024,9 @@@@ int regulator_map_voltage_linear(struc
                return -EINVAL;
        }
   
+       if (min_uV < rdev->desc->min_uV)
+               min_uV = rdev->desc->min_uV;
+  
        ret = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step);
        if (ret < 0)
                return ret;
@@@@ -2042,7 -2071,7 -2071,7 +2045,7 @@@@ static int _regulator_do_set_voltage(st
   {
        int ret;
        int delay = 0;
 --     int best_val;
 ++     int best_val = 0;
        unsigned int selector;
        int old_selector = -1;
   
         * If we can't obtain the old selector there is not enough
         * info to call set_voltage_time_sel().
         */
 --     if (rdev->desc->ops->set_voltage_time_sel &&
 ++     if (_regulator_is_enabled(rdev) &&
 ++         rdev->desc->ops->set_voltage_time_sel &&
            rdev->desc->ops->get_voltage_sel) {
                old_selector = rdev->desc->ops->get_voltage_sel(rdev);
                if (old_selector < 0)
        if (rdev->desc->ops->set_voltage) {
                ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
                                                   &selector);
 ++
 ++             if (ret >= 0) {
 ++                     if (rdev->desc->ops->list_voltage)
 ++                             best_val = rdev->desc->ops->list_voltage(rdev,
 ++                                                                      selector);
 ++                     else
 ++                             best_val = _regulator_get_voltage(rdev);
 ++             }
 ++
        } else if (rdev->desc->ops->set_voltage_sel) {
 --             if (rdev->desc->ops->map_voltage)
 ++             if (rdev->desc->ops->map_voltage) {
                        ret = rdev->desc->ops->map_voltage(rdev, min_uV,
                                                           max_uV);
 --             else
 --                     ret = regulator_map_voltage_iterate(rdev, min_uV,
 --                                                         max_uV);
 ++             } else {
 ++                     if (rdev->desc->ops->list_voltage ==
 ++                         regulator_list_voltage_linear)
 ++                             ret = regulator_map_voltage_linear(rdev,
 ++                                                             min_uV, max_uV);
 ++                     else
 ++                             ret = regulator_map_voltage_iterate(rdev,
 ++                                                             min_uV, max_uV);
 ++             }
   
                if (ret >= 0) {
 --                     selector = ret;
 --                     ret = rdev->desc->ops->set_voltage_sel(rdev, ret);
 ++                     best_val = rdev->desc->ops->list_voltage(rdev, ret);
 ++                     if (min_uV <= best_val && max_uV >= best_val) {
 ++                             selector = ret;
 ++                             ret = rdev->desc->ops->set_voltage_sel(rdev,
 ++                                                                    ret);
 ++                     } else {
 ++                             ret = -EINVAL;
 ++                     }
                }
        } else {
                ret = -EINVAL;
        }
   
 --     if (rdev->desc->ops->list_voltage)
 --             best_val = rdev->desc->ops->list_voltage(rdev, selector);
 --     else
 --             best_val = -1;
 --
        /* Call set_voltage_time_sel if successfully obtained old_selector */
 --     if (ret == 0 && old_selector >= 0 &&
 ++     if (ret == 0 && _regulator_is_enabled(rdev) && old_selector >= 0 &&
            rdev->desc->ops->set_voltage_time_sel) {
   
                delay = rdev->desc->ops->set_voltage_time_sel(rdev,
                                  delay);
                        delay = 0;
                }
 --     }
   
 --     /* Insert any necessary delays */
 --     if (delay >= 1000) {
 --             mdelay(delay / 1000);
 --             udelay(delay % 1000);
 --     } else if (delay) {
 --             udelay(delay);
 ++             /* Insert any necessary delays */
 ++             if (delay >= 1000) {
 ++                     mdelay(delay / 1000);
 ++                     udelay(delay % 1000);
 ++             } else if (delay) {
 ++                     udelay(delay);
 ++             }
        }
   
 --     if (ret == 0)
 ++     if (ret == 0 && best_val >= 0)
                _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
 --                                  NULL);
 ++                                  (void *)best_val);
   
        trace_regulator_set_voltage_complete(rdev_get_name(rdev), best_val);
   
@@@@ -2616,7 -2628,7 -2628,7 +2619,7 @@@@ static void _notifier_call_chain(struc
                                  unsigned long event, void *data)
   {
        /* call rdev chain first */
 --     blocking_notifier_call_chain(&rdev->notifier, event, NULL);
 ++     blocking_notifier_call_chain(&rdev->notifier, event, data);
   }
   
   /**
@@@@ -2897,10 -2909,10 -2909,10 +2900,10 @@@@ int regulator_mode_to_status(unsigned i
                return REGULATOR_STATUS_NORMAL;
        case REGULATOR_MODE_IDLE:
                return REGULATOR_STATUS_IDLE;
 --     case REGULATOR_STATUS_STANDBY:
 ++     case REGULATOR_MODE_STANDBY:
                return REGULATOR_STATUS_STANDBY;
        default:
 --             return 0;
 ++             return REGULATOR_STATUS_UNDEFINED;
        }
   }
   EXPORT_SYMBOL_GPL(regulator_mode_to_status);
@@@@ -3093,10 -3105,7 -3105,7 +3096,10 @@@@ regulator_register(const struct regulat
        rdev->reg_data = config->driver_data;
        rdev->owner = regulator_desc->owner;
        rdev->desc = regulator_desc;
 --     rdev->regmap = config->regmap;
 ++     if (config->regmap)
 ++             rdev->regmap = config->regmap;
 ++     else
 ++             rdev->regmap = dev_get_regmap(dev, NULL);
        INIT_LIST_HEAD(&rdev->consumer_list);
        INIT_LIST_HEAD(&rdev->list);
        BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier);
@@@@ -3463,6 -3472,15 -3472,6 +3466,15 @@@@ static int __init regulator_init_comple
        struct regulation_constraints *c;
        int enabled, ret;
   
+ +     /*
+ +      * Since DT doesn't provide an idiomatic mechanism for
+ +      * enabling full constraints and since it's much more natural
+ +      * with DT to provide them just assume that a DT enabled
+ +      * system has full constraints.
+ +      */
+ +     if (of_have_populated_dt())
+ +             has_full_constraints = true;
+ +
        mutex_lock(&regulator_list_mutex);
   
        /* If we have a full configuration then disable any regulators