diff options
Diffstat (limited to 'drivers/regulator/core.c')
-rw-r--r-- | drivers/regulator/core.c | 121 |
1 files changed, 46 insertions, 75 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 1179766811f5..84d48e310aa8 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1959,8 +1959,8 @@ static struct regulator_dev *regulator_dev_lookup(struct device *dev, regulator_supply_alias(&dev, &supply); /* first do a dt based lookup */ - if (dev && dev->of_node) { - r = of_regulator_dev_lookup(dev, supply); + if (dev_of_node(dev)) { + r = of_regulator_dev_lookup(dev, dev_of_node(dev), supply); if (!IS_ERR(r)) return r; if (PTR_ERR(r) == -EPROBE_DEFER) @@ -2643,45 +2643,6 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) } /** - * _regulator_delay_helper - a delay helper function - * @delay: time to delay in microseconds - * - * Delay for the requested amount of time as per the guidelines in: - * - * Documentation/timers/timers-howto.rst - * - * The assumption here is that these regulator operations will never used in - * atomic context and therefore sleeping functions can be used. - */ -static void _regulator_delay_helper(unsigned int delay) -{ - unsigned int ms = delay / 1000; - unsigned int us = delay % 1000; - - if (ms > 0) { - /* - * For small enough values, handle super-millisecond - * delays in the usleep_range() call below. - */ - if (ms < 20) - us += ms * 1000; - else - msleep(ms); - } - - /* - * Give the scheduler some room to coalesce with any other - * wakeup sources. For delays shorter than 10 us, don't even - * bother setting up high-resolution timers and just busy- - * loop. - */ - if (us >= 10) - usleep_range(us, us + 100); - else - udelay(us); -} - -/** * _regulator_check_status_enabled - check if regulator status can be * interpreted as "regulator is enabled" * @rdev: the regulator device to check @@ -2733,7 +2694,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) s64 remaining = ktime_us_delta(end, ktime_get_boottime()); if (remaining > 0) - _regulator_delay_helper(remaining); + fsleep(remaining); } if (rdev->ena_pin) { @@ -2767,7 +2728,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) int time_remaining = delay; while (time_remaining > 0) { - _regulator_delay_helper(rdev->desc->poll_enabled_time); + fsleep(rdev->desc->poll_enabled_time); if (rdev->desc->ops->get_status) { ret = _regulator_check_status_enabled(rdev); @@ -2786,7 +2747,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) return -ETIMEDOUT; } } else { - _regulator_delay_helper(delay); + fsleep(delay); } trace_regulator_enable_complete(rdev_get_name(rdev)); @@ -3730,7 +3691,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, } /* Insert any necessary delays */ - _regulator_delay_helper(delay); + fsleep(delay); if (best_val >= 0) { unsigned long data = best_val; @@ -5681,32 +5642,43 @@ regulator_register(struct device *dev, goto clean; } - init_data = regulator_of_get_init_data(dev, regulator_desc, config, - &rdev->dev.of_node); - - /* - * Sometimes not all resources are probed already so we need to take - * that into account. This happens most the time if the ena_gpiod comes - * from a gpio extender or something else. - */ - if (PTR_ERR(init_data) == -EPROBE_DEFER) { - ret = -EPROBE_DEFER; - goto clean; - } + if (config->init_data) { + /* + * Providing of_match means the framework is expected to parse + * DT to get the init_data. This would conflict with provided + * init_data, if set. Warn if it happens. + */ + if (regulator_desc->of_match) + dev_warn(dev, "Using provided init data - OF match ignored\n"); - /* - * We need to keep track of any GPIO descriptor coming from the - * device tree until we have handled it over to the core. If the - * config that was passed in to this function DOES NOT contain - * a descriptor, and the config after this call DOES contain - * a descriptor, we definitely got one from parsing the device - * tree. - */ - if (!cfg->ena_gpiod && config->ena_gpiod) - dangling_of_gpiod = true; - if (!init_data) { init_data = config->init_data; rdev->dev.of_node = of_node_get(config->of_node); + + } else { + init_data = regulator_of_get_init_data(dev, regulator_desc, + config, + &rdev->dev.of_node); + + /* + * Sometimes not all resources are probed already so we need to + * take that into account. This happens most the time if the + * ena_gpiod comes from a gpio extender or something else. + */ + if (PTR_ERR(init_data) == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto clean; + } + + /* + * We need to keep track of any GPIO descriptor coming from the + * device tree until we have handled it over to the core. If the + * config that was passed in to this function DOES NOT contain a + * descriptor, and the config after this call DOES contain a + * descriptor, we definitely got one from parsing the device + * tree. + */ + if (!cfg->ena_gpiod && config->ena_gpiod) + dangling_of_gpiod = true; } ww_mutex_init(&rdev->mutex, ®ulator_ww_class); @@ -5747,6 +5719,12 @@ regulator_register(struct device *dev, goto wash; } + if (regulator_desc->init_cb) { + ret = regulator_desc->init_cb(rdev, config); + if (ret < 0) + goto wash; + } + if ((rdev->supply_name && !rdev->supply) && (rdev->constraints->always_on || rdev->constraints->boot_on)) { @@ -5758,13 +5736,6 @@ regulator_register(struct device *dev, resolved_early = true; } - /* perform any regulator specific init */ - if (init_data && init_data->regulator_init) { - ret = init_data->regulator_init(rdev->reg_data); - if (ret < 0) - goto wash; - } - if (config->ena_gpiod) { ret = regulator_ena_gpio_request(rdev, config); if (ret != 0) { |