All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Boyd <sboyd@codeaurora.org>
To: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Rafael Wysocki <rjw@rjwysocki.net>,
	linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org,
	nm@ti.com
Subject: Re: [PATCH 02/17] PM / OPP: Add APIs to set regulator-name
Date: Mon, 11 Jan 2016 17:18:25 -0800	[thread overview]
Message-ID: <20160112011825.GH22188@codeaurora.org> (raw)
In-Reply-To: <30510e48c64f5aef8015e7dae838780e2c2fe86d.1450777582.git.viresh.kumar@linaro.org>

On 12/22, Viresh Kumar wrote:
> This is required mostly for backward compatibility of DT users. The OPP
> layer automatically gets the regulator device currently, but the name of
> the device needs to be same as that of the device. But existing DT

The name of the device needs to be the same as that of the
device? What does that mean? Perhaps this should say the name of
the regulator/supply needs to be the same as that of the device?

The same words are in the kernel doc too.

> entries may not be following that and might have used generic names
> instead. For example, they might have used 'cpu-supply' instead of
> 'cpu0-supply'.
> diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
> index 2e49f5e9daa3..76232ee04cc6 100644
> --- a/drivers/base/power/opp/core.c
> +++ b/drivers/base/power/opp/core.c
> @@ -492,25 +492,11 @@ struct device_list_opp *_add_list_dev(const struct device *dev,
>  	return list_dev;
>  }
>  
> -/**
> - * _add_device_opp() - Find device OPP table or allocate a new one
> - * @dev:	device for which we do this operation
> - *
> - * It tries to find an existing table first, if it couldn't find one, it
> - * allocates a new OPP table and returns that.
> - *
> - * Return: valid device_opp pointer if success, else NULL.
> - */
> -static struct device_opp *_add_device_opp(struct device *dev)
> +static struct device_opp *_add_device_opp_reg(struct device *dev,
> +					      const char *name)
>  {
>  	struct device_opp *dev_opp;
>  	struct device_list_opp *list_dev;
> -	const char *name = dev_name(dev);
> -
> -	/* Check for existing list for 'dev' first */
> -	dev_opp = _find_device_opp(dev);
> -	if (!IS_ERR(dev_opp))
> -		return dev_opp;
>  
>  	/*
>  	 * Allocate a new device OPP table. In the infrequent case where a new
> @@ -542,6 +528,27 @@ static struct device_opp *_add_device_opp(struct device *dev)
>  }
>  
>  /**
> + * _add_device_opp() - Find device OPP table or allocate a new one
> + * @dev:	device for which we do this operation

Why the tab? I know copy/paste, but still.

> + *
> + * It tries to find an existing table first, if it couldn't find one, it
> + * allocates a new OPP table and returns that.
> + *
> + * Return: valid device_opp pointer if success, else NULL.
> + */
> @@ -1091,6 +1101,127 @@ void dev_pm_opp_put_prop_name(struct device *dev)
>  }
>  EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name);
>  
> +/**
> + * dev_pm_opp_set_regulator() - Set regulator name for the device
> + * @dev: Device for which regulator name is being set.
> + * @name: Name of the regulator.
> + *
> + * This is required mostly for backward compatibility of DT users. The OPP layer
> + * automatically gets the regulator device currently, but the name of the device
> + * needs to be same as that of the device. But existing DT entries may not be
> + * following that and might have used generic names instead. For example, they
> + * might have used 'cpu-supply' instead of 'cpu0-supply'.

The new v2 OPP bindings are using cpu-supply instead of
cpu0-supply. This makes it sound like cpu-supply is the old style
and we've added this API to handle it, when in reality, this is
the preferred way to do this and so we've added this API because
we almost always need it.

> + *
> + * This must be called before any OPPs are initialized for the device.
> + *
> + * Locking: The internal device_opp and opp structures are RCU protected.
> + * Hence this function internally uses RCU updater strategy with mutex locks
> + * to keep the integrity of the internal data structures. Callers should ensure
> + * that this function is *NOT* called under RCU protection or in contexts where
> + * mutex cannot be locked.
> + */
> +int dev_pm_opp_set_regulator(struct device *dev, const char *name)
> +{
> +	struct device_opp *dev_opp;
> +	struct regulator *reg;
> +	int ret = 0;
> +
> +	/* Hold our list modification lock here */
> +	mutex_lock(&dev_opp_list_lock);
> +
> +	dev_opp = _find_device_opp(dev);
> +	/* We already have a dev-opp */
> +	if (!IS_ERR(dev_opp)) {
> +		/* This should be called before OPPs are initialized */
> +		if (WARN_ON(!list_empty(&dev_opp->opp_list))) {
> +			ret = -EBUSY;
> +			goto unlock;
> +		}
> +
> +		/* Already have a regulator set? Free it and re-allocate */
> +		if (!IS_ERR(dev_opp->regulator))
> +			regulator_put(dev_opp->regulator);

Is this used in practice? It seems odd that users would be using
one regulator, and then change that to another regulator later.

> +
> +		/* Allocate the regulator */
> +		reg = regulator_get_optional(dev, name);
> +		if (IS_ERR(reg)) {
> +			ret = PTR_ERR(reg);
> +			if (ret != -EPROBE_DEFER)
> +				dev_err(dev, "%s: no regulator (%s) found: %d\n",
> +					__func__, name, ret);
> +		}
> +
> +		dev_opp->regulator = reg;
> +		goto unlock;
> +	}
> +
[...]
> +
> +/**
> + * dev_pm_opp_put_regulator() - Releases resources blocked for regulator
> + * @dev: Device for which regulator was set.
> + *
> + * Locking: The internal device_opp and opp structures are RCU protected.
> + * Hence this function internally uses RCU updater strategy with mutex locks
> + * to keep the integrity of the internal data structures. Callers should ensure
> + * that this function is *NOT* called under RCU protection or in contexts where
> + * mutex cannot be locked.
> + */
> +void dev_pm_opp_put_regulator(struct device *dev)
> +{
> +	struct device_opp *dev_opp;
> +
> +	/* Hold our list modification lock here */

Yeah, that's obvious from the code.

> +	mutex_lock(&dev_opp_list_lock);
> +
> +	/* Check for existing list for 'dev' first */
> +	dev_opp = _find_device_opp(dev);
> +	if (IS_ERR(dev_opp)) {
> +		dev_err(dev, "Failed to find dev_opp: %ld\n", PTR_ERR(dev_opp));
> +		goto unlock;
> +	}
> +
> +	/* Make sure there are no concurrent readers while updating dev_opp */
> +	WARN_ON(!list_empty(&dev_opp->opp_list));
> +
> +	if (!dev_opp->regulator_set) {
> +		dev_err(dev, "%s: Doesn't have regulator set\n", __func__);
> +		goto unlock;
> +	}
> +
> +	dev_opp->regulator_set = false;
> +
> +	/* Try freeing device_opp if this was the last blocking resource */
> +	_remove_device_opp(dev_opp);

It looks like this whole function exists to set the boolean to
false so that _remove_device_opp() can continue. What's the point
of that? From what I can tell all we're getting is symmetry in
the API by having this function, so why have this function at
all?


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

  reply	other threads:[~2016-01-12  1:18 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-22 10:16 [PATCH 00/17] PM / OPP: Introduce APIs to transition OPPs Viresh Kumar
2015-12-22 10:16 ` [PATCH 01/17] PM / OPP: get/put regulators from OPP core Viresh Kumar
2016-01-11 23:21   ` Stephen Boyd
2016-01-12  3:05     ` Viresh Kumar
2016-01-12  5:23       ` Viresh Kumar
2016-01-12 19:32         ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 02/17] PM / OPP: Add APIs to set regulator-name Viresh Kumar
2016-01-12  1:18   ` Stephen Boyd [this message]
2016-01-12  4:43     ` Viresh Kumar
2015-12-22 10:16 ` [PATCH 03/17] PM / OPP: Disable OPPs that aren't supported by the regulator Viresh Kumar
2016-01-12  1:19   ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 04/17] PM / OPP: Introduce dev_pm_opp_get_max_volt_latency() Viresh Kumar
2016-01-12  1:25   ` Stephen Boyd
2016-01-12  5:10     ` Viresh Kumar
2016-01-12 19:45       ` Stephen Boyd
2016-01-13  5:34         ` Viresh Kumar
2016-01-18  7:23           ` Viresh Kumar
2016-01-21  0:20           ` Stephen Boyd
2016-01-21  2:32             ` Viresh Kumar
2016-01-21  2:43               ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 05/17] PM / OPP: Introduce dev_pm_opp_get_max_transition_latency() Viresh Kumar
2016-01-12  2:20   ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 06/17] PM / OPP: Parse clock-latency and voltage-tolerance for v1 bindings Viresh Kumar
2016-01-12  1:29   ` Stephen Boyd
2016-01-12  5:14     ` Viresh Kumar
2016-01-13  0:36       ` Stephen Boyd
2016-01-13  5:35         ` Viresh Kumar
2016-01-15  1:54           ` Stephen Boyd
2016-01-15  1:54   ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 07/17] PM / OPP: Manage device clk Viresh Kumar
2016-01-12  1:32   ` Stephen Boyd
2016-01-12  5:43     ` Viresh Kumar
2016-01-12 19:47       ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 08/17] PM / OPP: Add dev_pm_opp_set_rate() Viresh Kumar
2016-01-12  1:40   ` Stephen Boyd
2016-01-12  6:58     ` Viresh Kumar
2016-01-13  0:49       ` Stephen Boyd
2016-01-13  5:51         ` Viresh Kumar
2015-12-22 10:16 ` [PATCH 10/17] cpufreq: dt: Rename 'need_update' to 'opp_v1' Viresh Kumar
2016-01-12  1:41   ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 11/17] cpufreq: dt: OPP layers handles clock-latency for V1 bindings as well Viresh Kumar
2016-01-12  1:41   ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 12/17] cpufreq: dt: Pass regulator name to the OPP core for V1 bindings Viresh Kumar
2016-01-12  1:53   ` Stephen Boyd
2016-01-12  7:11     ` Viresh Kumar
2016-01-13  0:43       ` Stephen Boyd
2016-01-13  5:47         ` Viresh Kumar
2016-01-13 11:15           ` Mark Brown
2015-12-22 10:16 ` [PATCH 13/17] cpufreq: dt: Unsupported OPPs are already disabled Viresh Kumar
2016-01-12  1:53   ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 14/17] cpufreq: dt: Reuse dev_pm_opp_get_max_transition_latency() Viresh Kumar
2016-01-12  1:54   ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 15/17] cpufreq: dt: Use dev_pm_opp_set_rate() to switch frequency Viresh Kumar
2016-01-12  1:55   ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 16/17] cpufreq: dt: drop references to DT node Viresh Kumar
2016-01-12  1:55   ` Stephen Boyd
2015-12-22 10:16 ` [PATCH 17/17] cpufreq: dt: No need to allocate resources anymore Viresh Kumar
2016-01-12  2:20   ` Stephen Boyd
2016-01-12  7:34     ` Viresh Kumar
2016-01-21  1:18       ` Stephen Boyd
2016-01-21  2:36         ` Viresh Kumar
2016-01-21  2:45           ` Stephen Boyd
2016-01-25 10:33     ` Viresh Kumar
2015-12-22 10:20 ` [PATCH 09/17] cpufreq: dt: Convert few pr_debug/err() calls to dev_dbg/err() Viresh Kumar
2016-01-12  1:40   ` Stephen Boyd
2015-12-23  3:12 ` [PATCH 00/17] PM / OPP: Introduce APIs to transition OPPs Rafael J. Wysocki
2015-12-23  2:46   ` Viresh Kumar
2016-01-11 16:28 ` Viresh Kumar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160112011825.GH22188@codeaurora.org \
    --to=sboyd@codeaurora.org \
    --cc=linaro-kernel@lists.linaro.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=nm@ti.com \
    --cc=rjw@rjwysocki.net \
    --cc=viresh.kumar@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.