linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chanwoo Choi <cw00.choi@samsung.com>
To: "Artur Świgoń" <a.swigon@samsung.com>,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-pm@vger.kernel.org, dri-devel@lists.freedesktop.org
Cc: myungjoo.ham@samsung.com, inki.dae@samsung.com,
	sw0312.kim@samsung.com, georgi.djakov@linaro.org,
	leonard.crestez@nxp.com, m.szyprowski@samsung.com,
	b.zolnierkie@samsung.com, krzk@kernel.org
Subject: Re: [RFC PATCH v2 09/11] devfreq: exynos-bus: Add interconnect functionality to exynos-bus
Date: Mon, 16 Dec 2019 09:44:48 +0900	[thread overview]
Message-ID: <35053bad-3f08-190a-0ffa-9aacd16da272@samsung.com> (raw)
In-Reply-To: <20190919142236.4071-10-a.swigon@samsung.com>

Hi,

On 9/19/19 11:22 PM, Artur Świgoń wrote:
> From: Artur Świgoń <a.swigon@partner.samsung.com>
> 
> This patch adds interconnect functionality to the exynos-bus devfreq
> driver.
> 
> The SoC topology is a graph (or, more specifically, a tree) and most of
> its edges are taken from the devfreq parent-child hierarchy (cf.
> Documentation/devicetree/bindings/devfreq/exynos-bus.txt). Due to
> unspecified relative probing order, -EPROBE_DEFER may be propagated to
> guarantee that a child is probed before its parent.
> 
> Each bus is now an interconnect provider and an interconnect node as well
> (cf. Documentation/interconnect/interconnect.rst), i.e. every bus registers
> itself as a node. Node IDs are not hardcoded but rather assigned at
> runtime, in probing order (subject to the above-mentioned exception
> regarding relative order). This approach allows for using this driver with
> various Exynos SoCs.
> 
> Frequencies requested via the interconnect API for a given node are
> propagated to devfreq using dev_pm_qos_update_request(). Please note that
> it is not an error when CONFIG_INTERCONNECT is 'n', in which case all
> interconnect API functions are no-op.
> 
> Signed-off-by: Artur Świgoń <a.swigon@partner.samsung.com>
> ---
>  drivers/devfreq/exynos-bus.c | 153 +++++++++++++++++++++++++++++++++++
>  1 file changed, 153 insertions(+)
> 
> diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
> index 8d44810cac69..e0232202720d 100644
> --- a/drivers/devfreq/exynos-bus.c
> +++ b/drivers/devfreq/exynos-bus.c
> @@ -14,14 +14,19 @@
>  #include <linux/devfreq-event.h>
>  #include <linux/device.h>
>  #include <linux/export.h>
> +#include <linux/idr.h>
> +#include <linux/interconnect-provider.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/pm_opp.h>
> +#include <linux/pm_qos.h>
>  #include <linux/platform_device.h>
>  #include <linux/regulator/consumer.h>
>  
>  #define DEFAULT_SATURATION_RATIO	40
>  
> +#define icc_units_to_khz(x) ((x) / 8)

icc_units_to_khz() -> kpbs_to_khz()

> +
>  struct exynos_bus {
>  	struct device *dev;
>  
> @@ -35,6 +40,12 @@ struct exynos_bus {
>  	struct opp_table *opp_table;
>  	struct clk *clk;
>  	unsigned int ratio;
> +
> +	/* One provider per bus, one node per provider */
> +	struct icc_provider provider;
> +	struct icc_node *node;
> +
> +	struct dev_pm_qos_request qos_req;
>  };
>  
>  /*
> @@ -59,6 +70,13 @@ exynos_bus_ops_edev(enable_edev);
>  exynos_bus_ops_edev(disable_edev);
>  exynos_bus_ops_edev(set_event);
>  
> +static int exynos_bus_next_id(void)
> +{
> +	static DEFINE_IDA(exynos_bus_icc_ida);
> +
> +	return ida_alloc(&exynos_bus_icc_ida, GFP_KERNEL);
> +}
> +
>  static int exynos_bus_get_event(struct exynos_bus *bus,
>  				struct devfreq_event_data *edata)
>  {
> @@ -171,6 +189,38 @@ static void exynos_bus_passive_exit(struct device *dev)
>  	clk_disable_unprepare(bus->clk);
>  }
>  
> +static int exynos_bus_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> +	struct exynos_bus *src_bus = src->data, *dst_bus = dst->data;
> +	s32 src_freq = icc_units_to_khz(src->avg_bw);
> +	s32 dst_freq = icc_units_to_khz(dst->avg_bw);
> +
> +	dev_pm_qos_update_request(&src_bus->qos_req, src_freq);

Have to check the return value.
If return error, show the waring with dev_warn.

> +	dev_pm_qos_update_request(&dst_bus->qos_req, dst_freq);

ditto.

> +
> +	return 0;
> +}
> +
> +static int exynos_bus_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
> +				    u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> +{
> +	*agg_avg += avg_bw;
> +	*agg_peak = max(*agg_peak, peak_bw);
> +
> +	return 0;
> +}
> +
> +static struct icc_node *exynos_bus_icc_xlate(struct of_phandle_args *spec,
> +					     void *data)
> +{
> +	struct exynos_bus *bus = data;
> +
> +	if (spec->np != bus->dev->of_node)
> +		return ERR_PTR(-EINVAL);
> +
> +	return bus->node;
> +}
> +
>  static int exynos_bus_parent_parse_of(struct device_node *np,
>  					struct exynos_bus *bus)
>  {
> @@ -366,6 +416,101 @@ static int exynos_bus_profile_init_passive(struct exynos_bus *bus,
>  	return 0;
>  }
>  
> +static int exynos_bus_icc_connect(struct exynos_bus *bus)
> +{
> +	struct device_node *np = bus->dev->of_node;
> +	struct devfreq *parent_devfreq;
> +	struct icc_node *parent_node = NULL;
> +	struct of_phandle_args args;
> +	int ret = 0;
> +
> +	parent_devfreq = devfreq_get_devfreq_by_phandle(bus->dev, 0);
> +	if (!IS_ERR(parent_devfreq)) {
> +		struct exynos_bus *parent_bus;
> +
> +		parent_bus = dev_get_drvdata(parent_devfreq->dev.parent);
> +		parent_node = parent_bus->node;
> +	} else {
> +		/* Look for parent in DT */
> +		int num = of_count_phandle_with_args(np, "parent",
> +						     "#interconnect-cells");
> +		if (num != 1)
> +			goto out; /* 'parent' is optional */
> +
> +		ret = of_parse_phandle_with_args(np, "parent",
> +						 "#interconnect-cells",
> +						 0, &args);


Actually, I agree your approach. I think that it is very useful
and necessary to guarantee the PM QoS requirements between devices.

But,
As I already commented, I'm not sure that the "parent" property 
is proper for only this driver. If possible, you better to get
the parent phandle through other way like OF graph.

If you suggest the standard way to make the tree between
the exynos-bus, I'll agree.

Also, for interconnect path, you have to add the connection
between 'bus_display' and 'bus_leftbus' regardless
of the existing 'devfreq' property.
- bus_display - bus_leftbus - bus_dmc

> +		if (ret < 0)
> +			goto out;
> +
> +		of_node_put(args.np);
> +
> +		parent_node = of_icc_get_from_provider(&args);
> +		if (IS_ERR(parent_node)) {
> +			/* May be -EPROBE_DEFER */
> +			ret = PTR_ERR(parent_node);
> +			goto out;
> +		}
> +	}
> +
> +	ret = icc_link_create(bus->node, parent_node->id);
> +
> +out:
> +	return ret;
> +}
> +
> +static int exynos_bus_icc_init(struct exynos_bus *bus)
> +{
> +	struct device *dev = bus->dev;
> +	struct icc_provider *provider = &bus->provider;
> +	struct icc_node *node;
> +	int id, ret;
> +
> +	/* Initialize the interconnect provider */
> +	provider->set = exynos_bus_icc_set;
> +	provider->aggregate = exynos_bus_icc_aggregate;
> +	provider->xlate = exynos_bus_icc_xlate;
> +	provider->dev = dev;
> +	provider->data = bus;
> +
> +	ret = icc_provider_add(provider);
> +	if (ret < 0)
> +		goto out;

Return error without goto because there is no any requirement
to free the resource before.

> +
> +	ret = id = exynos_bus_next_id();
> +	if (ret < 0)
> +		goto err_node;
> +
> +	node = icc_node_create(id);
> +	if (IS_ERR(node)) {
> +		ret = PTR_ERR(node);
> +		goto err_node;
> +	}
> +
> +	bus->node = node;
> +	node->name = dev->of_node->name;
> +	node->data = bus;
> +	icc_node_add(node, provider);
> +
> +	ret = exynos_bus_icc_connect(bus);
> +	if (ret < 0)
> +		goto err_connect;
> +
> +	ret = dev_pm_qos_add_request(bus->devfreq->dev.parent, &bus->qos_req,

Check whether this line is over 80 char.

> +				     DEV_PM_QOS_MIN_FREQUENCY, 0);

	Check the return value.

> +
> +out:

Remove this goto due to not necessary.

> +	return ret;

	return 0;

> +
> +err_connect:
> +	icc_node_del(node);
> +	icc_node_destroy(id);
> +err_node:
> +	icc_provider_del(provider);
> +
> +	return ret;
> +}
> +
>  static int exynos_bus_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -415,6 +560,14 @@ static int exynos_bus_probe(struct platform_device *pdev)
>  	if (ret < 0)
>  		goto err;
>  
> +	/*
> +	 * Initialize interconnect provider. A return value of -ENOTSUPP means
> +	 * that CONFIG_INTERCONNECT is disabled.
> +	 */
> +	ret = exynos_bus_icc_init(bus);
> +	if (ret < 0 && ret != -ENOTSUPP)
> +		goto err;

Print error message.
	dev_err(dev, "failed to initialize the interconnect provider");

> +
>  	max_state = bus->devfreq->profile->max_state;
>  	min_freq = (bus->devfreq->profile->freq_table[0] / 1000);
>  	max_freq = (bus->devfreq->profile->freq_table[max_state - 1] / 1000);
> 


-- 
Best Regards,
Chanwoo Choi
Samsung Electronics

  parent reply	other threads:[~2019-12-16  0:38 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20190919142321eucas1p164c2591ad402427cb71fd00c348a29ec@eucas1p1.samsung.com>
2019-09-19 14:22 ` [RFC PATCH v2 00/11] Simple QoS for exynos-bus driver using interconnect Artur Świgoń
     [not found]   ` <CGME20190919142322eucas1p24bc477ee6e1bcd65546c305d55af097d@eucas1p2.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 01/11] devfreq: exynos-bus: Extract exynos_bus_profile_init() Artur Świgoń
2019-09-20  2:15       ` Chanwoo Choi
2019-09-25  5:44         ` Artur Świgoń
2019-09-25  6:37           ` Chanwoo Choi
2019-09-25  6:41             ` Artur Świgoń
     [not found]   ` <CGME20190919142322eucas1p1949ad95468af26698c4c5addc060ce00@eucas1p1.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 02/11] devfreq: exynos-bus: Extract exynos_bus_profile_init_passive() Artur Świgoń
     [not found]   ` <CGME20190919142323eucas1p2fc73a765389432f880fa28945fd28975@eucas1p2.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 03/11] devfreq: exynos-bus: Change goto-based logic to if-else logic Artur Świgoń
     [not found]   ` <CGME20190919142324eucas1p1638cec2aafbfcaf03cfdfa7d0189143a@eucas1p1.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 04/11] devfreq: exynos-bus: Clean up code Artur Świgoń
2019-09-20  2:22       ` Chanwoo Choi
2019-10-03  8:10         ` Artur Świgoń
     [not found]   ` <CGME20190919142325eucas1p28102446c22b1e1c61aae0bad46d079b0@eucas1p2.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 05/11] interconnect: Export of_icc_get_from_provider() Artur Świgoń
2019-12-16  0:57       ` Chanwoo Choi
     [not found]   ` <CGME20190919142326eucas1p204819014fe85716b47e2de4af9102cd5@eucas1p2.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 06/11] interconnect: Relax requirement in of_icc_get_from_provider() Artur Świgoń
     [not found]   ` <CGME20190919142327eucas1p183470eede07b50c1e3acda58f2af1eba@eucas1p1.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 07/11] interconnect: Relax condition in apply_constraints() Artur Świgoń
     [not found]   ` <CGME20190919142329eucas1p299762f99dd55a5d625633ceec84219f9@eucas1p2.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 08/11] arm: dts: exynos: Add parents and #interconnect-cells to Exynos4412 Artur Świgoń
2019-12-16  0:51       ` Chanwoo Choi
2019-12-16  2:59         ` Chanwoo Choi
2019-12-18 10:17           ` Artur Świgoń
2019-12-18 10:29             ` Chanwoo Choi
2019-12-18 10:41               ` Artur Świgoń
2019-12-16  0:55       ` Chanwoo Choi
2019-12-16  0:57         ` Chanwoo Choi
     [not found]   ` <CGME20190919142329eucas1p2e53992eab9ec6b404f716f955b3c228e@eucas1p2.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 09/11] devfreq: exynos-bus: Add interconnect functionality to exynos-bus Artur Świgoń
2019-09-25  7:03       ` Chanwoo Choi
2019-09-25  7:12         ` Artur Świgoń
2019-12-02 17:05         ` Artur Świgoń
2019-12-05  2:36           ` Chanwoo Choi
2019-12-16  0:44       ` Chanwoo Choi [this message]
2019-12-18 10:18         ` Artur Świgoń
2019-12-18 10:39           ` Chanwoo Choi
2019-12-18 10:48             ` Artur Świgoń
2019-12-18 11:08               ` Chanwoo Choi
     [not found]   ` <CGME20190919142330eucas1p1eceae78b148a03f2af71657b7cdd6694@eucas1p1.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 10/11] arm: dts: exynos: Add interconnects to Exynos4412 mixer Artur Świgoń
     [not found]   ` <CGME20190919142331eucas1p2107a7cb9ce8b3817ed171c21a8ad5b00@eucas1p2.samsung.com>
2019-09-19 14:22     ` [RFC PATCH v2 11/11] drm: exynos: mixer: Add interconnect support Artur Świgoń
2019-09-20  1:07   ` [RFC PATCH v2 00/11] Simple QoS for exynos-bus driver using interconnect Chanwoo Choi
2019-09-20  2:14     ` Chanwoo Choi
2019-09-25  5:47       ` Artur Świgoń
2019-09-25  6:12         ` Chanwoo Choi
2019-09-25  6:37           ` Artur Świgoń
2019-09-25  6:48             ` Chanwoo Choi

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=35053bad-3f08-190a-0ffa-9aacd16da272@samsung.com \
    --to=cw00.choi@samsung.com \
    --cc=a.swigon@samsung.com \
    --cc=b.zolnierkie@samsung.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=georgi.djakov@linaro.org \
    --cc=inki.dae@samsung.com \
    --cc=krzk@kernel.org \
    --cc=leonard.crestez@nxp.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=myungjoo.ham@samsung.com \
    --cc=sw0312.kim@samsung.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).