Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 2/4] kernel hacking: new config NO_AUTO_INLINE to disable compiler auto-inline optimizations
From: Steven Rostedt @ 2018-06-08 20:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607091816.GT13775@localhost>

On Thu, 7 Jun 2018 11:18:16 +0200
Johan Hovold <johan@kernel.org> wrote:


> If you want to work around the warning and think you can do it in some
> non-contrived way, then go for it.
> 
> Clearing the request buffer, checking for termination using strnlen, and
> then using memcpy might not be too bad.
> 
> But after all, it is a false positive, so leaving things as they stand
> is fine too.

Not sure how contrived you think this is, but it solves the warning
without adding extra work in the normal case.

-- Steve

diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c
index 71aec14f8181..4fb9f1dff47d 100644
--- a/drivers/staging/greybus/fw-management.c
+++ b/drivers/staging/greybus/fw-management.c
@@ -150,15 +150,18 @@ static int fw_mgmt_load_and_validate_operation(struct fw_mgmt *fw_mgmt,
 	}
 
 	request.load_method = load_method;
-	strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE);
+	strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE - 1);
 
 	/*
 	 * The firmware-tag should be NULL terminated, otherwise throw error and
 	 * fail.
 	 */
-	if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
-		dev_err(fw_mgmt->parent, "load-and-validate: firmware-tag is not NULL terminated\n");
-		return -EINVAL;
+	if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 2] != '\0') {
+		if (tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') {
+			dev_err(fw_mgmt->parent, "load-and-validate: firmware-tag is not NULL terminated\n");
+			return -EINVAL;
+		}
+		request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] = '\0';
 	}
 
 	/* Allocate ids from 1 to 255 (u8-max), 0 is an invalid id */

^ permalink raw reply related

* [PATCH 03/20] coresight: Fix remote endpoint parsing
From: Mathieu Poirier @ 2018-06-08 20:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528235011-30691-4-git-send-email-suzuki.poulose@arm.com>

On Tue, Jun 05, 2018 at 10:43:14PM +0100, Suzuki K Poulose wrote:
> When parsing the remote endpoint of an output port, we do :
>      rport = of_graph_get_remote_port(ep);
>      rparent = of_graph_get_remote_port_parent(ep);
> 
> and then parse the "remote_port" as if it was the remote endpoint,
> which is wrong. The code worked fine because we used endpoint number
> as the port number. Let us fix it and optimise a bit as:
> 
>      remote_ep = of_graph_get_remote_endpoint(ep);
>      if (remote_ep)
>         remote_parent = of_graph_get_port_parent(remote_ep);
> 
> and then, parse the remote_ep for the port/endpoint details.
> 
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
>  drivers/hwtracing/coresight/of_coresight.c | 22 +++++++++++-----------
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index 8a23c63..ada4f07 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -129,7 +129,7 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
>  	int ret = 0;
>  	struct of_endpoint endpoint, rendpoint;
>  	struct device_node *rparent = NULL;
> -	struct device_node *rport = NULL;
> +	struct device_node *rep = NULL;
>  	struct device *rdev = NULL;
>  
>  	do {
> @@ -144,16 +144,16 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
>  		if (of_graph_parse_endpoint(ep, &endpoint))
>  			break;
>  		/*
> -		 * Get a handle on the remote port and parent
> -		 * attached to it.
> +		 * Get a handle on the remote endpoint and the device it is
> +		 * attached to.
>  		 */
> -		rparent = of_graph_get_remote_port_parent(ep);
> +		rep = of_graph_get_remote_endpoint(ep);
> +		if (!rep)
> +			break;
> +		rparent = of_graph_get_port_parent(rep);
>  		if (!rparent)
>  			break;
> -		rport = of_graph_get_remote_port(ep);
> -		if (!rport)
> -			break;
> -		if (of_graph_parse_endpoint(rport, &rendpoint))
> +		if (of_graph_parse_endpoint(rep, &rendpoint))
>  			break;
>  
>  		/* If the remote device is not available, defer probing */
> @@ -165,15 +165,15 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
>  
>  		pdata->outports[*i] = endpoint.port;
>  		pdata->child_names[*i] = dev_name(rdev);
> -		pdata->child_ports[*i] = rendpoint.id;
> +		pdata->child_ports[*i] = rendpoint.port;
>  		/* Move the index */
>  		(*i)++;
>  	} while (0);
>  
>  	if (rparent)
>  		of_node_put(rparent);
> -	if (rport)
> -		of_node_put(rport);
> +	if (rep)
> +		of_node_put(rep);
>  
>  	return ret;
>  }

Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>

(Please add to the next iteration so that I don't have to review again)

> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH 05/20] coresight: platform: Cleanup coresight connection handling
From: Mathieu Poirier @ 2018-06-08 20:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528235011-30691-6-git-send-email-suzuki.poulose@arm.com>

On Tue, Jun 05, 2018 at 10:43:16PM +0100, Suzuki K Poulose wrote:
> The platform code parses the component connections and populates
> a platform-description of the output connections in arrays of fields
> (which is never freed). This is later copied in the coresight_register
> to a newly allocated area, represented by coresight_connection(s).
> 
> This patch cleans up the code dealing with connections by making
> use of the "coresight_connection" structure right at the platform
> code and lets the generic driver simply re-use information provided
> by the platform.
> 
> Thus making it reader friendly as well as avoiding the wastage of
> unused memory.
> 
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
>  drivers/hwtracing/coresight/coresight.c    | 21 +-----------
>  drivers/hwtracing/coresight/of_coresight.c | 51 ++++++++++++------------------
>  include/linux/coresight.h                  |  9 ++----
>  3 files changed, 23 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
> index 2893cfe..69e9136 100644
> --- a/drivers/hwtracing/coresight/coresight.c
> +++ b/drivers/hwtracing/coresight/coresight.c
> @@ -953,13 +953,11 @@ postcore_initcall(coresight_init);
>  
>  struct coresight_device *coresight_register(struct coresight_desc *desc)
>  {
> -	int i;
>  	int ret;
>  	int link_subtype;
>  	int nr_refcnts = 1;
>  	atomic_t *refcnts = NULL;
>  	struct coresight_device *csdev;
> -	struct coresight_connection *conns = NULL;
>  
>  	csdev = kzalloc(sizeof(*csdev), GFP_KERNEL);
>  	if (!csdev) {
> @@ -988,22 +986,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
>  	csdev->nr_inport = desc->pdata->nr_inport;
>  	csdev->nr_outport = desc->pdata->nr_outport;
>  
> -	/* Initialise connections if there is at least one outport */
> -	if (csdev->nr_outport) {
> -		conns = kcalloc(csdev->nr_outport, sizeof(*conns), GFP_KERNEL);
> -		if (!conns) {
> -			ret = -ENOMEM;
> -			goto err_kzalloc_conns;
> -		}
> -
> -		for (i = 0; i < csdev->nr_outport; i++) {
> -			conns[i].outport = desc->pdata->outports[i];
> -			conns[i].child_name = desc->pdata->child_names[i];
> -			conns[i].child_port = desc->pdata->child_ports[i];
> -		}
> -	}
> -
> -	csdev->conns = conns;
> +	csdev->conns = desc->pdata->conns;
>  
>  	csdev->type = desc->type;
>  	csdev->subtype = desc->subtype;
> @@ -1032,8 +1015,6 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
>  
>  	return csdev;
>  
> -err_kzalloc_conns:
> -	kfree(refcnts);
>  err_kzalloc_refcnts:
>  	kfree(csdev);
>  err_kzalloc_csdev:
> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index ada4f07..d01a9ce 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -70,26 +70,13 @@ static void of_coresight_get_ports(const struct device_node *node,
>  static int of_coresight_alloc_memory(struct device *dev,
>  			struct coresight_platform_data *pdata)
>  {
> -	/* List of output port on this component */
> -	pdata->outports = devm_kzalloc(dev, pdata->nr_outport *
> -				       sizeof(*pdata->outports),
> -				       GFP_KERNEL);
> -	if (!pdata->outports)
> -		return -ENOMEM;
> -
> -	/* Children connected to this component via @outports */
> -	pdata->child_names = devm_kzalloc(dev, pdata->nr_outport *
> -					  sizeof(*pdata->child_names),
> -					  GFP_KERNEL);
> -	if (!pdata->child_names)
> -		return -ENOMEM;
> -
> -	/* Port number on the child this component is connected to */
> -	pdata->child_ports = devm_kzalloc(dev, pdata->nr_outport *
> -					  sizeof(*pdata->child_ports),
> -					  GFP_KERNEL);
> -	if (!pdata->child_ports)
> -		return -ENOMEM;
> +	if (pdata->nr_outport) {
> +		pdata->conns = devm_kzalloc(dev, pdata->nr_outport *
> +					    sizeof(*pdata->conns),
> +					    GFP_KERNEL);
> +		if (!pdata->conns)
> +			return -ENOMEM;
> +	}
>  
>  	return 0;
>  }
> @@ -113,24 +100,24 @@ EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
>  
>  /*
>   * of_coresight_parse_endpoint : Parse the given output endpoint @ep
> - * and fill the connection information in @pdata[*@i].
> + * and fill the connection information in *@pconn.
>   *
>   * Parses the local port, remote device name and the remote port. Also
> - * updates *@i to point to the next index, when an entry is added.
> + * updates *@pconn to point to the next record, when an entry is added.
>   *
>   * Returns :
>   *	 0	- If the parsing completed without any fatal errors.
>   *	-Errno	- Fatal error, abort the scanning.
>   */
>  static int of_coresight_parse_endpoint(struct device_node *ep,
> -				       struct coresight_platform_data *pdata,
> -				       int *i)
> +				       struct coresight_connection **pconn)
>  {
>  	int ret = 0;
>  	struct of_endpoint endpoint, rendpoint;
>  	struct device_node *rparent = NULL;
>  	struct device_node *rep = NULL;
>  	struct device *rdev = NULL;
> +	struct coresight_connection *conn = *pconn;
>  
>  	do {
>  		/*
> @@ -163,11 +150,11 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
>  			break;
>  		}
>  
> -		pdata->outports[*i] = endpoint.port;
> -		pdata->child_names[*i] = dev_name(rdev);
> -		pdata->child_ports[*i] = rendpoint.port;
> -		/* Move the index */
> -		(*i)++;
> +		conn->outport = endpoint.port;
> +		conn->child_name = dev_name(rdev);
> +		conn->child_port = rendpoint.port;
> +		/* Move the connection record */
> +		(*pconn)++;
>  	} while (0);
>  
>  	if (rparent)
> @@ -182,8 +169,9 @@ struct coresight_platform_data *
>  of_get_coresight_platform_data(struct device *dev,
>  			       const struct device_node *node)
>  {
> -	int i = 0, ret = 0;
> +	int ret = 0;
>  	struct coresight_platform_data *pdata;
> +	struct coresight_connection *conn;
>  	struct device_node *ep = NULL;
>  
>  	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
> @@ -205,13 +193,14 @@ of_get_coresight_platform_data(struct device *dev,
>  	if (ret)
>  		return ERR_PTR(ret);
>  
> +	conn = pdata->conns;
>  	/* Iterate through each port to discover topology */
>  	do {
>  		/* Get a handle on a port */
>  		ep = of_graph_get_next_endpoint(node, ep);
>  		if (!ep)
>  			break;
> -		ret = of_coresight_parse_endpoint(ep, pdata, &i);
> +		ret = of_coresight_parse_endpoint(ep, &conn);
>  		if (ret)
>  			return ERR_PTR(ret);
>  	} while (ep);
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 69a5c9f..2a75a15 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -82,20 +82,15 @@ struct coresight_dev_subtype {
>   * @cpu:	the CPU a source belongs to. Only applicable for ETM/PTMs.
>   * @name:	name of the component as shown under sysfs.
>   * @nr_inport:	number of input ports for this component.
> - * @outports:	list of remote endpoint port number.
> - * @child_names:name of all child components connected to this device.
> - * @child_ports:child component port number the current component is
> -		connected  to.
>   * @nr_outport:	number of output ports for this component.
> + * @conns:	Array of nr_outport connections from this component
>   */
>  struct coresight_platform_data {
>  	int cpu;
>  	const char *name;
>  	int nr_inport;
> -	int *outports;
> -	const char **child_names;
> -	int *child_ports;
>  	int nr_outport;
> +	struct coresight_connection *conns;
>  };

Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>

>  
>  /**
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH 06/20] coresight: Handle errors in finding input/output ports
From: Mathieu Poirier @ 2018-06-08 20:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528235011-30691-7-git-send-email-suzuki.poulose@arm.com>

On Tue, Jun 05, 2018 at 10:43:17PM +0100, Suzuki K Poulose wrote:
> If we fail to find the input / output port for a LINK component
> while enabling a path, we should fail gracefully rather than
> assuming port "0".
> 
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
>  drivers/hwtracing/coresight/coresight.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
> index 69e9136..3c1c058 100644
> --- a/drivers/hwtracing/coresight/coresight.c
> +++ b/drivers/hwtracing/coresight/coresight.c
> @@ -107,7 +107,7 @@ static int coresight_find_link_inport(struct coresight_device *csdev,
>  	dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n",
>  		dev_name(&parent->dev), dev_name(&csdev->dev));
>  
> -	return 0;
> +	return -ENODEV;
>  }
>  
>  static int coresight_find_link_outport(struct coresight_device *csdev,
> @@ -125,7 +125,7 @@ static int coresight_find_link_outport(struct coresight_device *csdev,
>  	dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n",
>  		dev_name(&csdev->dev), dev_name(&child->dev));
>  
> -	return 0;
> +	return -ENODEV;
>  }
>  
>  static int coresight_enable_sink(struct coresight_device *csdev, u32 mode)
> @@ -178,6 +178,9 @@ static int coresight_enable_link(struct coresight_device *csdev,
>  	else
>  		refport = 0;
>  
> +	if (refport < 0)
> +		return refport;
> +
>  	if (atomic_inc_return(&csdev->refcnt[refport]) == 1) {
>  		if (link_ops(csdev)->enable) {
>  			ret = link_ops(csdev)->enable(csdev, inport, outport);

Queued for the next rc - no need to resend.

Thanks,
Mathieu

> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH 07/20] coresight: dts: Document usage of graph bindings
From: Mathieu Poirier @ 2018-06-08 20:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528235011-30691-8-git-send-email-suzuki.poulose@arm.com>

On Tue, Jun 05, 2018 at 10:43:18PM +0100, Suzuki K Poulose wrote:
> Before we update the bindings, document the current graph bindings
> and usage of additional properties.
> 
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>

Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>

> ---
>  .../devicetree/bindings/arm/coresight.txt          | 31 +++++++++++++++++++---
>  1 file changed, 27 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> index 9aa30a1..ed6b555 100644
> --- a/Documentation/devicetree/bindings/arm/coresight.txt
> +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> @@ -52,9 +52,7 @@ its hardware characteristcs.
>  	  clocks the core of that coresight component. The latter clock
>  	  is optional.
>  
> -	* port or ports: The representation of the component's port
> -	  layout using the generic DT graph presentation found in
> -	  "bindings/graph.txt".
> +	* port or ports: see "Graph bindings for Coresight" below.
>  
>  * Additional required properties for System Trace Macrocells (STM):
>  	* reg: along with the physical base address and length of the register
> @@ -71,7 +69,7 @@ its hardware characteristcs.
>  	  AMBA markee):
>  		- "arm,coresight-replicator"
>  
> -	* port or ports: same as above.
> +	* port or ports: see "Graph bindings for Coresight" below.
>  
>  * Optional properties for ETM/PTMs:
>  
> @@ -90,6 +88,31 @@ its hardware characteristcs.
>  	* arm,scatter-gather: boolean. Indicates that the TMC-ETR can safely
>  	  use the SG mode on this system.
>  
> +Graph bindings for Coresight
> +-------------------------------
> +
> +Coresight components are interconnected to create a data path for the flow of
> +trace data generated from the "sources" to their collection points "sink".
> +Each coresight component must describe the "input" and "output" connections.
> +The connections must be described via generic DT graph bindings as described
> +by the "bindings/graph.txt", where each "port" along with an "endpoint"
> +component represents a hardware port and the connection.
> +
> +Since it is possible to have multiple connections for any coresight component
> +with a specific direction of data flow, each connection must define the
> +following properties to uniquely identify the connection details.
> +
> + * Direction of the data flow w.r.t the component :
> +   Each input port must have the following property defined at the "endpoint"
> +   for the port.
> +	"slave-mode"
> +
> + * Hardware Port number at the component:
> +     -  The hardware port number is assumed to be the address of the "port"
> +         component.
> +
> +
> +
>  Example:
>  
>  1. Sinks
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH v4 2/3] arm: shmobile: Add the R9A06G032 SMP enabler driver
From: Rob Herring @ 2018-06-08 20:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAMuHMdUOqLhmb8kXOxriQ5mt_4rDQJbUqGsQiJBSkq5J5FWG7w@mail.gmail.com>

On Fri, Jun 8, 2018 at 2:47 AM, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
> On Fri, Jun 8, 2018 at 8:50 AM, Michel Pollet
> <michel.pollet@bp.renesas.com> wrote:
>> On 07 June 2018 16:55, Rob wrote:
>>> On Thu, Jun 7, 2018 at 1:59 AM, Michel Pollet
>>> <michel.pollet@bp.renesas.com> wrote:
>>> > On 06 June 2018 22:53, Frank wrote:
>>> >> On 06/06/18 14:48, Frank Rowand wrote:
>>> >> > On 06/05/18 23:36, Michel Pollet wrote:
>>> >> >> On 05 June 2018 18:34, Frank wrote:
>>> >> >>> On 06/05/18 04:28, Michel Pollet wrote:
>>> >> >>>> The Renesas R9A06G032 second CA7 is parked in a ROM pen at boot
>>> >> >>>> time, it requires a special enable method to get it started.
>>>
>>> [...]
>>>
>>> >> >>>> + * The second CPU is parked in ROM at boot time. It requires
>>> >> >>>> +waking it after
>>> >> >>>> + * writing an address into the BOOTADDR register of sysctrl.
>>> >> >>>> + *
>>> >> >>>> + * So the default value of the "cpu-release-addr" corresponds
>>> >> >>>> +to
>>> >> >>> BOOTADDR...
>>> >> >>>> + *
>>> >> >>>> + * *However* the BOOTADDR register is not available when the
>>> >> >>>> +kernel
>>> >> >>>> + * starts in NONSEC mode.
>>> >> >>>> + *
>>> >> >>>> + * So for NONSEC mode, the bootloader re-parks the second CPU
>>> >> >>>> +into a pen
>>> >> >>>> + * in SRAM, and changes the "cpu-release-addr" of linux's DT to
>>> >> >>>> +a SRAM address,
>>> >> >>>> + * which is not restricted.
>>> >> >>>
>>> >> >>> The binding document for cpu-release-addr does not have a
>>> >> >>> definition for 32 bit arm.  The existing definition is only 64
>>> >> >>> bit arm.  Please add the definition for 32 bit arm to patch 1.
>>> >> >>
>>> >> >> Hmmm I do find a definition in
>>> >> >> Documentation/devicetree/bindings/arm/cpus.txt -- just under where
>>> >> >> I added my 'enable-method' -- And it is already used as 32 bits in
>>> >> >> at least arch/arm/boot/dts/stih407-family.dtsi.
>>> >> >
>>> >> > If the correct answer is for cpu-release-addr to be 64 bits in
>>> >> > certain cases (that discussion is ongoing further downthread) then
>>> >> > one approach to maintain compatibility _and_ to fix the devicetree
>>> >> > source files is to change the source code that currently gets
>>> >> > cpu-release-addr as a
>>> >> > 32 bit object to check the size of the property and get it as
>>> >> > either a
>>> >> > 32 bit or 64 bit object, based on the actual size of the property
>>> >> > in the device tree and then change the value in the devicetree
>>> >> > source files to be two cells.  BUT this does not consider the
>>> >> > bootloader complication.  arch/arm/boot/dts/axm5516-cpus.dtsi has a
>>> >> > note "// Fixed by the boot loader", so the boot loader also has to
>>> >> > be modified to be able to handle the possibility that the property
>>> >> > could be either
>>> >> > 32 bits or 64 bits.  I don't know how to maintain compatibility
>>> >> > with the boot loader since we can't force it to change
>>> >> > synchronously with changes in the kernel.
>>> >> >
>>> >> > You can consider this comment to be a drive-by observation.  I
>>> >> > think Rob and Geert and people like that are likely to be more
>>> >> > helpful with what to actually do, and you can treat my comment more
>>> >> > as pointing out the issue than as providing the perfect solution.
>>> >>
>>> >> Darn it, hit <send> too quickly.
>>> >>
>>> >> I meant to mention that there are several devicetree source files
>>> >> that have a single cell value for cpu-release-addr, and thus
>>> >> potentially face the same situation, depending on what the final
>>> >> decision is on the proper size for cpu- release-addr. As of v4.17, a git grep
>>> shows one cell values in:
>>> >>
>>> >>   arch/arm/boot/dts/axm5516-cpus.dtsi
>>> >>   arch/arm/boot/dts/stih407-family.dtsi
>>> >>   arch/arm/boot/dts/stih418.dtsi
>>> >
>>> > Yes, I had grepped before I used 32 bits on mine...
>>> >
>>> > Now, what is the decision here? Our bootloader is already modified to
>>> > set it to 32 bits, so I propose that
>>>
>>> And too late to fix the bootloader?
>>
>>
>> Well not too late, but read further on...
>>
>>>
>>> >
>>> > + I change the driver to handle 32 and 64 bits properties
>>>
>>> That's fine if you can't fix the bootloader.
>>>
>>> > + I add this to the cpu.txt, as a separate patch:
>>> > # On other systems, the property can be either
>>> >   32 bits or 64 bits, it is the driver's responsibility
>>> >   to deal with either sizes.
>>>
>>> That is definitely not what we want to say. Use of 32-bit should be
>>> considered out of spec. Yes, we have a few platforms in that category, but
>>> they already handle that themselves. Would be nice to fix them, but at least
>>> the STi platforms don't seem too active.
>>>
>>> IMO, we should delete whatever text we can here and at most just refer to
>>> the spec.
>>
>> So actually I didn't use 32 bits by plain chance, I read the cpu.txt file which says
>> that 64 bits systems use 64 bits property, concluded that in my case I ought to
>> use 32 bits, then grepped around and found other systems using 32 bits, therefore
>> I went forward and used it..
>>
>> Nothing said here that it should be 64 bits everywhere -- So the documentation
>> needs fixing somehow. Right now it certainly led me wrong.
>
> Perhaps we should add to Documentation/devicetree/bindings/ the standard
> bindings from ePAPR and successors, too?

I hope you mean *reference* here, not duplicate the bindings here. We
want to move in the other direction and move the common bindings out
of the kernel and into the spec.

The real solution here is validation which I'm working on. I had
already converted cpus.txt. Here's an example of the results of the
validation:

arch/arm/boot/dts/stih410-b2120.dt.yaml:1962:7: cpu at 0: 'enable-method'
is a dependency of 'cpu-release-addr'
arch/arm/boot/dts/stih410-b2120.dt.yaml:1965:26:
cpu at 0:cpu-release-addr: [155254948] is too short

The schema is up on my yaml-bindings branch. Will send out more details soon.

Rob

^ permalink raw reply

* [PATCH 08/20] coresight: dts: Cleanup device tree graph bindings
From: Mathieu Poirier @ 2018-06-08 21:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528235011-30691-9-git-send-email-suzuki.poulose@arm.com>

On Tue, Jun 05, 2018 at 10:43:19PM +0100, Suzuki K Poulose wrote:
> The coresight drivers relied on default bindings for graph
> in DT, while reusing the "reg" field of the "ports" to indicate
> the actual hardware port number for the connections. However,
> with the rules getting stricter w.r.t to the address mismatch
> with the label, it is no longer possible to use the port address
> field for the hardware port number. Hence, we add an explicit
> property to denote the hardware port number, "coresight,hwid"
> which must be specified for each "endpoint".
> 
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Rob Herring <robh@kernel.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
>  .../devicetree/bindings/arm/coresight.txt          | 29 ++++++++++---
>  drivers/hwtracing/coresight/of_coresight.c         | 49 +++++++++++++++++-----
>  2 files changed, 62 insertions(+), 16 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> index ed6b555..bf75ab3 100644
> --- a/Documentation/devicetree/bindings/arm/coresight.txt
> +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> @@ -108,8 +108,13 @@ following properties to uniquely identify the connection details.
>  	"slave-mode"
>  
>   * Hardware Port number at the component:
> -     -  The hardware port number is assumed to be the address of the "port"
> -         component.
> +     - Each "endpoint" must define the hardware port of the local end of the
> +       connection using the following property :
> +
> +	"coresight,hwid" - 32bit integer, local hardware port.
> +
> +     - [ ** Obsolete ** ] The hardware port number is assumed to be the address
> +       of the "port" component.
>  
>  
>  
> @@ -126,6 +131,7 @@ Example:
>  			etb_in_port: endpoint at 0 {
>  				slave-mode;
>  				remote-endpoint = <&replicator_out_port0>;
> +				coresight,hwid = <0>;
>  			};
>  		};
>  	};
> @@ -140,6 +146,7 @@ Example:
>  			tpiu_in_port: endpoint at 0 {
>  				slave-mode;
>  				remote-endpoint = <&replicator_out_port1>;
> +				coresight,hwid = <0>;
>  			};
>  		};
>  	};
> @@ -160,6 +167,7 @@ Example:
>  				reg = <0>;
>  				replicator_out_port0: endpoint {
>  					remote-endpoint = <&etb_in_port>;
> +					coresight,hwid = <0>;
>  				};
>  			};
>  
> @@ -167,15 +175,17 @@ Example:
>  				reg = <1>;
>  				replicator_out_port1: endpoint {
>  					remote-endpoint = <&tpiu_in_port>;
> +					coresight,hwid = <1>;
>  				};
>  			};
>  
>  			/* replicator input port */
>  			port at 2 {
> -				reg = <0>;
> +				reg = <1>;
>  				replicator_in_port0: endpoint {
>  					slave-mode;
>  					remote-endpoint = <&funnel_out_port0>;
> +					coresight,hwid = <0>;
>  				};
>  			};
>  		};
> @@ -197,31 +207,35 @@ Example:
>  				funnel_out_port0: endpoint {
>  					remote-endpoint =
>  							<&replicator_in_port0>;
> +					coresight,hwid = <0>;
>  				};
>  			};
>  
>  			/* funnel input ports */
>  			port at 1 {
> -				reg = <0>;
> +				reg = <1>;
>  				funnel_in_port0: endpoint {
>  					slave-mode;
>  					remote-endpoint = <&ptm0_out_port>;
> +					coresight,hwid = <0>;
>  				};
>  			};
>  
>  			port at 2 {
> -				reg = <1>;
> +				reg = <2>;
>  				funnel_in_port1: endpoint {
>  					slave-mode;
>  					remote-endpoint = <&ptm1_out_port>;
> +					coresight,hwid = <1>;
>  				};
>  			};
>  
>  			port at 3 {
> -				reg = <2>;
> +				reg = <3>;
>  				funnel_in_port2: endpoint {
>  					slave-mode;
>  					remote-endpoint = <&etm0_out_port>;
> +					coresight,hwid = <2>;
>  				};
>  			};
>  
> @@ -239,6 +253,7 @@ Example:
>  		port {
>  			ptm0_out_port: endpoint {
>  				remote-endpoint = <&funnel_in_port0>;
> +				coresight,hwid = <0>;
>  			};
>  		};
>  	};
> @@ -253,6 +268,7 @@ Example:
>  		port {
>  			ptm1_out_port: endpoint {
>  				remote-endpoint = <&funnel_in_port1>;
> +				coresight,hwid = <0>;
>  			};
>  		};
>  	};
> @@ -269,6 +285,7 @@ Example:
>  		port {
>  			stm_out_port: endpoint {
>  				remote-endpoint = <&main_funnel_in_port2>;
> +				coresight,hwid = <0>;
>  			};
>  		};
>  	};

For the binding part:
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>

> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index d01a9ce..d23d7dd 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -99,6 +99,31 @@ int of_coresight_get_cpu(const struct device_node *node)
>  EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
>  
>  /*
> + * of_coresight_endpoint_get_port_id : Get the hardware port number for the
> + * given endpoint device node. Prefer the explicit "coresight,hwid" property
> + * over the endpoint register id (obsolete bindings).
> + */
> +static int of_coresight_endpoint_get_port_id(struct device *dev,
> +					     struct device_node *ep_node)
> +{
> +	struct of_endpoint ep;
> +	int rc, port_id;
> +
> +
> +	if (!of_property_read_u32(ep_node, "coresight,hwid", &port_id))
> +		return port_id;
> +
> +	rc = of_graph_parse_endpoint(ep_node, &ep);
> +	if (rc)
> +		return rc;
> +	dev_warn_once(dev,
> +		      "ep%d: Mandatory \"coresight,hwid\" property missing.\n",
> +		      ep.port);
> +	dev_warn_once(dev, "DT uses obsolete coresight bindings\n");
> +	return ep.port;
> +}
> +
> +/*
>   * of_coresight_parse_endpoint : Parse the given output endpoint @ep
>   * and fill the connection information in *@pconn.
>   *
> @@ -109,11 +134,11 @@ EXPORT_SYMBOL_GPL(of_coresight_get_cpu);
>   *	 0	- If the parsing completed without any fatal errors.
>   *	-Errno	- Fatal error, abort the scanning.
>   */
> -static int of_coresight_parse_endpoint(struct device_node *ep,
> +static int of_coresight_parse_endpoint(struct device *dev,
> +				       struct device_node *ep,
>  				       struct coresight_connection **pconn)
>  {
> -	int ret = 0;
> -	struct of_endpoint endpoint, rendpoint;
> +	int ret = 0, local_port, child_port;
>  	struct device_node *rparent = NULL;
>  	struct device_node *rep = NULL;
>  	struct device *rdev = NULL;
> @@ -128,7 +153,8 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
>  			break;
>  
>  		/* Parse the local port details */
> -		if (of_graph_parse_endpoint(ep, &endpoint))
> +		local_port = of_coresight_endpoint_get_port_id(dev, ep);
> +		if (local_port < 0)
>  			break;
>  		/*
>  		 * Get a handle on the remote endpoint and the device it is
> @@ -140,9 +166,6 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
>  		rparent = of_graph_get_port_parent(rep);
>  		if (!rparent)
>  			break;
> -		if (of_graph_parse_endpoint(rep, &rendpoint))
> -			break;
> -
>  		/* If the remote device is not available, defer probing */
>  		rdev = of_coresight_get_endpoint_device(rparent);
>  		if (!rdev) {
> @@ -150,9 +173,15 @@ static int of_coresight_parse_endpoint(struct device_node *ep,
>  			break;
>  		}
>  
> -		conn->outport = endpoint.port;
> +		child_port = of_coresight_endpoint_get_port_id(rdev, rep);
> +		if (child_port < 0) {
> +			ret = 0;

Why returning '0' on an error condition?  Same for 'local_port' above.

> +			break;
> +		}
> +
> +		conn->outport = local_port;
>  		conn->child_name = dev_name(rdev);
> -		conn->child_port = rendpoint.port;
> +		conn->child_port = child_port;
>  		/* Move the connection record */
>  		(*pconn)++;
>  	} while (0);
> @@ -200,7 +229,7 @@ of_get_coresight_platform_data(struct device *dev,
>  		ep = of_graph_get_next_endpoint(node, ep);
>  		if (!ep)
>  			break;
> -		ret = of_coresight_parse_endpoint(ep, &conn);
> +		ret = of_coresight_parse_endpoint(dev, ep, &conn);
>  		if (ret)
>  			return ERR_PTR(ret);
>  	} while (ep);
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH 09/20] coresight: dts: Define new bindings for direction of data flow
From: Mathieu Poirier @ 2018-06-08 21:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528235011-30691-10-git-send-email-suzuki.poulose@arm.com>

On Tue, Jun 05, 2018 at 10:43:20PM +0100, Suzuki K Poulose wrote:
> So far we have relied on an undocumented property "slave-mode",
> to indicate if the given port is input or not. Since we are
> redefining the coresight bindings, define new property for the
> "direction" of data flow for a given connection endpoint in the
> device.
> 
> Each endpoint must define the following property.
> 
>  - "direction" : 0 => Port is input
> 		 1 => Port is output
> 
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
>  .../devicetree/bindings/arm/coresight.txt          | 24 ++++++++++++++--------
>  drivers/hwtracing/coresight/of_coresight.c         | 22 ++++++++++++++++----
>  2 files changed, 34 insertions(+), 12 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
> index bf75ab3..ff382bc 100644
> --- a/Documentation/devicetree/bindings/arm/coresight.txt
> +++ b/Documentation/devicetree/bindings/arm/coresight.txt
> @@ -103,9 +103,11 @@ with a specific direction of data flow, each connection must define the
>  following properties to uniquely identify the connection details.
>  
>   * Direction of the data flow w.r.t the component :
> -   Each input port must have the following property defined at the "endpoint"
> +   Each hardware port must have the following property defined at the "endpoint"
>     for the port.
> -	"slave-mode"
> +	"direction" - 32bit integer, whose values are defined as follows :
> +		0 => the endpoint is an Input port
> +		1 => the endpoint is an Output port.
>  
>   * Hardware Port number at the component:
>       - Each "endpoint" must define the hardware port of the local end of the
> @@ -129,7 +131,7 @@ Example:
>  		clock-names = "apb_pclk";
>  		port {
>  			etb_in_port: endpoint at 0 {
> -				slave-mode;
> +				direction = <0>;
>  				remote-endpoint = <&replicator_out_port0>;
>  				coresight,hwid = <0>;
>  			};
> @@ -144,7 +146,7 @@ Example:
>  		clock-names = "apb_pclk";
>  		port {
>  			tpiu_in_port: endpoint at 0 {
> -				slave-mode;
> +				direction = <0>;
>  				remote-endpoint = <&replicator_out_port1>;
>  				coresight,hwid = <0>;
>  			};
> @@ -166,6 +168,7 @@ Example:
>  			port at 0 {
>  				reg = <0>;
>  				replicator_out_port0: endpoint {
> +					direction = <1>;
>  					remote-endpoint = <&etb_in_port>;
>  					coresight,hwid = <0>;
>  				};
> @@ -174,6 +177,7 @@ Example:
>  			port at 1 {
>  				reg = <1>;
>  				replicator_out_port1: endpoint {
> +					direction = <1>;
>  					remote-endpoint = <&tpiu_in_port>;
>  					coresight,hwid = <1>;
>  				};
> @@ -183,7 +187,7 @@ Example:
>  			port at 2 {
>  				reg = <1>;
>  				replicator_in_port0: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&funnel_out_port0>;
>  					coresight,hwid = <0>;
>  				};
> @@ -205,6 +209,7 @@ Example:
>  			port at 0 {
>  				reg = <0>;
>  				funnel_out_port0: endpoint {
> +					direction = <1>;
>  					remote-endpoint =
>  							<&replicator_in_port0>;
>  					coresight,hwid = <0>;
> @@ -215,7 +220,7 @@ Example:
>  			port at 1 {
>  				reg = <1>;
>  				funnel_in_port0: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&ptm0_out_port>;
>  					coresight,hwid = <0>;
>  				};
> @@ -224,7 +229,7 @@ Example:
>  			port at 2 {
>  				reg = <2>;
>  				funnel_in_port1: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&ptm1_out_port>;
>  					coresight,hwid = <1>;
>  				};
> @@ -233,7 +238,7 @@ Example:
>  			port at 3 {
>  				reg = <3>;
>  				funnel_in_port2: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&etm0_out_port>;
>  					coresight,hwid = <2>;
>  				};
> @@ -252,6 +257,7 @@ Example:
>  		clock-names = "apb_pclk";
>  		port {
>  			ptm0_out_port: endpoint {
> +				direction = <1>;
>  				remote-endpoint = <&funnel_in_port0>;
>  				coresight,hwid = <0>;
>  			};
> @@ -267,6 +273,7 @@ Example:
>  		clock-names = "apb_pclk";
>  		port {
>  			ptm1_out_port: endpoint {
> +				direction = <1>;
>  				remote-endpoint = <&funnel_in_port1>;
>  				coresight,hwid = <0>;
>  			};
> @@ -284,6 +291,7 @@ Example:
>  		clock-names = "apb_pclk";
>  		port {
>  			stm_out_port: endpoint {
> +				direction = <1>;
>  				remote-endpoint = <&main_funnel_in_port2>;
>  				coresight,hwid = <0>;
>  			};
> diff --git a/drivers/hwtracing/coresight/of_coresight.c b/drivers/hwtracing/coresight/of_coresight.c
> index d23d7dd..0d6e6a9 100644
> --- a/drivers/hwtracing/coresight/of_coresight.c
> +++ b/drivers/hwtracing/coresight/of_coresight.c
> @@ -45,7 +45,20 @@ of_coresight_get_endpoint_device(struct device_node *endpoint)
>  			       endpoint, of_dev_node_match);
>  }
>  
> -static void of_coresight_get_ports(const struct device_node *node,
> +static bool of_coresight_endpoint_is_input(struct device *dev,
> +					   struct device_node *ep_node)
> +{
> +	u32 dir;
> +
> +	if (!of_property_read_u32(ep_node, "direction", &dir))
> +		return dir == 0;
> +
> +	dev_warn_once(dev, "Missing mandatory \"direction\" property!\n");
> +	return of_property_read_bool(ep_node, "slave-mode");
> +}
> +
> +static void of_coresight_get_ports(struct device *dev,
> +				   const struct device_node *node,
>  				   int *nr_inport, int *nr_outport)
>  {
>  	struct device_node *ep = NULL;
> @@ -56,7 +69,7 @@ static void of_coresight_get_ports(const struct device_node *node,
>  		if (!ep)
>  			break;
>  
> -		if (of_property_read_bool(ep, "slave-mode"))
> +		if (of_coresight_endpoint_is_input(dev, ep))
>  			in++;
>  		else
>  			out++;
> @@ -149,7 +162,7 @@ static int of_coresight_parse_endpoint(struct device *dev,
>  		 * No need to deal with input ports, processing for as
>  		 * processing for output ports will deal with them.
>  		 */
> -		if (of_find_property(ep, "slave-mode", NULL))
> +		if (of_coresight_endpoint_is_input(dev, ep))
>  			break;
>  
>  		/* Parse the local port details */
> @@ -212,7 +225,8 @@ of_get_coresight_platform_data(struct device *dev,
>  	pdata->cpu = of_coresight_get_cpu(node);
>  
>  	/* Get the number of input and output port for this component */
> -	of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
> +	of_coresight_get_ports(dev, node,
> +			       &pdata->nr_inport, &pdata->nr_outport);
>  
>  	/* If there are not output connections, we are done */
>  	if (!pdata->nr_outport)

For both the binding and the code:
Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>

> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH 10/20] dts: juno: Update coresight bindings for hw port
From: Mathieu Poirier @ 2018-06-08 21:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1528235011-30691-11-git-send-email-suzuki.poulose@arm.com>

On Tue, Jun 05, 2018 at 10:43:21PM +0100, Suzuki K Poulose wrote:
> Switch to updated coresight bindings for hw ports.
> 
> Cc: Sudeep Holla <sudeep.holla@arm.com>
> Cc: Liviu Dudau <liviu.dudau@arm.com>
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> Changes since V1:
>   - Add support Juno for r1 & r2.
> ---

Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>

>  arch/arm64/boot/dts/arm/juno-base.dtsi    | 82 ++++++++++++++++++++++---------
>  arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi | 26 +++++++---
>  arch/arm64/boot/dts/arm/juno.dts          |  5 +-
>  3 files changed, 81 insertions(+), 32 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
> index eb749c5..33b41ba 100644
> --- a/arch/arm64/boot/dts/arm/juno-base.dtsi
> +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
> @@ -122,15 +122,18 @@
>  			port at 0 {
>  				reg = <0>;
>  				etf0_in_port: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&main_funnel_out_port>;
> +					coresight,hwid = <0>;
>  				};
>  			};
>  
>  			/* output port */
>  			port at 1 {
> -				reg = <0>;
> +				reg = <1>;
>  				etf0_out_port: endpoint {
> +					coresight,hwid = <0>;
> +					direction = <1>;
>  				};
>  			};
>  		};
> @@ -145,8 +148,9 @@
>  		power-domains = <&scpi_devpd 0>;
>  		port {
>  			tpiu_in_port: endpoint {
> -				slave-mode;
> +				direction = <0>;
>  				remote-endpoint = <&replicator_out_port0>;
> +				coresight,hwid = <0>;
>  			};
>  		};
>  	};
> @@ -168,23 +172,27 @@
>  				reg = <0>;
>  				main_funnel_out_port: endpoint {
>  					remote-endpoint = <&etf0_in_port>;
> +					coresight,hwid = <0>;
> +					direction = <1>;
>  				};
>  			};
>  
>  			/* input ports */
>  			port at 1 {
> -				reg = <0>;
> +				reg = <1>;
>  				main_funnel_in_port0: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&cluster0_funnel_out_port>;
> +					coresight,hwid = <0>;
>  				};
>  			};
>  
>  			port at 2 {
> -				reg = <1>;
> +				reg = <2>;
>  				main_funnel_in_port1: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&cluster1_funnel_out_port>;
> +					coresight,hwid = <1>;
>  				};
>  			};
>  		};
> @@ -200,8 +208,9 @@
>  		power-domains = <&scpi_devpd 0>;
>  		port {
>  			etr_in_port: endpoint {
> -				slave-mode;
> +				direction = <0>;
>  				remote-endpoint = <&replicator_out_port1>;
> +				coresight,hwid = <0>;
>  			};
>  		};
>  	};
> @@ -217,6 +226,8 @@
>  		power-domains = <&scpi_devpd 0>;
>  		port {
>  			stm_out_port: endpoint {
> +				coresight,hwid = <0>;
> +				direction = <1>;
>  			};
>  		};
>  	};
> @@ -240,6 +251,8 @@
>  		port {
>  			cluster0_etm0_out_port: endpoint {
>  				remote-endpoint = <&cluster0_funnel_in_port0>;
> +				coresight,hwid = <0>;
> +				direction = <1>;
>  			};
>  		};
>  	};
> @@ -259,22 +272,26 @@
>  				reg = <0>;
>  				cluster0_funnel_out_port: endpoint {
>  					remote-endpoint = <&main_funnel_in_port0>;
> +					coresight,hwid = <0>;
> +					direction = <1>;
>  				};
>  			};
>  
>  			port at 1 {
> -				reg = <0>;
> +				reg = <1>;
>  				cluster0_funnel_in_port0: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&cluster0_etm0_out_port>;
> +					coresight,hwid = <0>;
>  				};
>  			};
>  
>  			port at 2 {
> -				reg = <1>;
> +				reg = <2>;
>  				cluster0_funnel_in_port1: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&cluster0_etm1_out_port>;
> +					coresight,hwid = <1>;
>  				};
>  			};
>  		};
> @@ -299,6 +316,8 @@
>  		port {
>  			cluster0_etm1_out_port: endpoint {
>  				remote-endpoint = <&cluster0_funnel_in_port1>;
> +				coresight,hwid = <0>;
> +				direction = <1>;
>  			};
>  		};
>  	};
> @@ -322,6 +341,8 @@
>  		port {
>  			cluster1_etm0_out_port: endpoint {
>  				remote-endpoint = <&cluster1_funnel_in_port0>;
> +				coresight,hwid = <0>;
> +				direction = <1>;
>  			};
>  		};
>  	};
> @@ -341,36 +362,42 @@
>  				reg = <0>;
>  				cluster1_funnel_out_port: endpoint {
>  					remote-endpoint = <&main_funnel_in_port1>;
> +					coresight,hwid = <0>;
> +					direction = <1>;
>  				};
>  			};
>  
>  			port at 1 {
> -				reg = <0>;
> +				reg = <1>;
>  				cluster1_funnel_in_port0: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&cluster1_etm0_out_port>;
> +					coresight,hwid = <0>;
>  				};
>  			};
>  
>  			port at 2 {
> -				reg = <1>;
> +				reg = <2>;
>  				cluster1_funnel_in_port1: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&cluster1_etm1_out_port>;
> +					coresight,hwid = <1>;
>  				};
>  			};
>  			port at 3 {
> -				reg = <2>;
> +				reg = <3>;
>  				cluster1_funnel_in_port2: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&cluster1_etm2_out_port>;
> +					coresight,hwid = <2>;
>  				};
>  			};
>  			port at 4 {
> -				reg = <3>;
> +				reg = <4>;
>  				cluster1_funnel_in_port3: endpoint {
> -					slave-mode;
> +					direction = <0>;
>  					remote-endpoint = <&cluster1_etm3_out_port>;
> +					coresight,hwid = <3>;
>  				};
>  			};
>  		};
> @@ -395,6 +422,8 @@
>  		port {
>  			cluster1_etm1_out_port: endpoint {
>  				remote-endpoint = <&cluster1_funnel_in_port1>;
> +				coresight,hwid = <0>;
> +				direction = <1>;
>  			};
>  		};
>  	};
> @@ -418,6 +447,8 @@
>  		port {
>  			cluster1_etm2_out_port: endpoint {
>  				remote-endpoint = <&cluster1_funnel_in_port2>;
> +				coresight,hwid = <0>;
> +				direction = <1>;
>  			};
>  		};
>  	};
> @@ -441,6 +472,8 @@
>  		port {
>  			cluster1_etm3_out_port: endpoint {
>  				remote-endpoint = <&cluster1_funnel_in_port3>;
> +				coresight,hwid = <0>;
> +				direction = <1>;
>  			};
>  		};
>  	};
> @@ -462,6 +495,8 @@
>  				reg = <0>;
>  				replicator_out_port0: endpoint {
>  					remote-endpoint = <&tpiu_in_port>;
> +					coresight,hwid = <0>;
> +					direction = <1>;
>  				};
>  			};
>  
> @@ -469,14 +504,17 @@
>  				reg = <1>;
>  				replicator_out_port1: endpoint {
>  					remote-endpoint = <&etr_in_port>;
> +					coresight,hwid = <1>;
> +					direction = <1>;
>  				};
>  			};
>  
>  			/* replicator input port */
>  			port at 2 {
> -				reg = <0>;
> +				reg = <2>;
>  				replicator_in_port0: endpoint {
> -					slave-mode;
> +					direction = <0>;
> +					coresight,hwid = <0>;
>  				};
>  			};
>  		};
> diff --git a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
> index 0c43fb3..146a5d9 100644
> --- a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
> +++ b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
> @@ -15,15 +15,18 @@
>  			port at 0 {
>  				reg = <0>;
>  				csys1_funnel_out_port: endpoint {
> +					coresight,hwid = <0>;
> +					direction = <1>;
>  					remote-endpoint = <&etf1_in_port>;
>  				};
>  			};
>  
>  			/* input port */
>  			port at 1 {
> -				reg = <0>;
> +				reg = <1>;
>  				csys1_funnel_in_port0: endpoint {
> -					slave-mode;
> +					coresight,hwid = <0>;
> +					direction = <0>;
>  				};
>  			};
>  
> @@ -45,15 +48,18 @@
>  			port at 0 {
>  				reg = <0>;
>  				etf1_in_port: endpoint {
> -					slave-mode;
> +					direction = <0>;
> +					coresight,hwid = <0>;
>  					remote-endpoint = <&csys1_funnel_out_port>;
>  				};
>  			};
>  
>  			/* output port */
>  			port at 1 {
> -				reg = <0>;
> +				reg = <1>;
>  				etf1_out_port: endpoint {
> +					coresight,hwid = <0>;
> +					direction = <1>;
>  					remote-endpoint = <&csys2_funnel_in_port1>;
>  				};
>  			};
> @@ -75,23 +81,27 @@
>  			port at 0 {
>  				reg = <0>;
>  				csys2_funnel_out_port: endpoint {
> +					coresight,hwid = <0>;
> +					direction = <1>;
>  					remote-endpoint = <&replicator_in_port0>;
>  				};
>  			};
>  
>  			/* input ports */
>  			port at 1 {
> -				reg = <0>;
> +				reg = <1>;
>  				csys2_funnel_in_port0: endpoint {
> -					slave-mode;
> +					direction = <0>;
> +					coresight,hwid = <0>;
>  					remote-endpoint = <&etf0_out_port>;
>  				};
>  			};
>  
>  			port at 2 {
> -				reg = <1>;
> +				reg = <2>;
>  				csys2_funnel_in_port1: endpoint {
> -					slave-mode;
> +					direction = <0>;
> +					coresight,hwid = <1>;
>  					remote-endpoint = <&etf1_out_port>;
>  				};
>  			};
> diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
> index c9236c4..27b8036 100644
> --- a/arch/arm64/boot/dts/arm/juno.dts
> +++ b/arch/arm64/boot/dts/arm/juno.dts
> @@ -260,10 +260,11 @@
>  &main_funnel {
>  	ports {
>  		port at 3 {
> -			reg = <2>;
> +			reg = <3>;
>  			main_funnel_in_port2: endpoint {
> -				slave-mode;
> +				direction = <0>;
>  				remote-endpoint = <&stm_out_port>;
> +				coresight,hwid = <2>;
>  			};
>  		};
>  	};
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH 10/20] dts: juno: Update coresight bindings for hw port
From: Mathieu Poirier @ 2018-06-08 21:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180608214946.GI30587@xps15>

On 8 June 2018 at 15:49, Mathieu Poirier <mathieu.poirier@linaro.org> wrote:
> On Tue, Jun 05, 2018 at 10:43:21PM +0100, Suzuki K Poulose wrote:
>> Switch to updated coresight bindings for hw ports.
>>
>> Cc: Sudeep Holla <sudeep.holla@arm.com>
>> Cc: Liviu Dudau <liviu.dudau@arm.com>
>> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>> ---
>> Changes since V1:
>>   - Add support Juno for r1 & r2.
>> ---
>
> Reviewed-by: Mathieu Poirier <mathieu.poirier@linaro.org>

Sudeep please hold on before applying this as there is more work to be
done on this set.

>
>>  arch/arm64/boot/dts/arm/juno-base.dtsi    | 82 ++++++++++++++++++++++---------
>>  arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi | 26 +++++++---
>>  arch/arm64/boot/dts/arm/juno.dts          |  5 +-
>>  3 files changed, 81 insertions(+), 32 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
>> index eb749c5..33b41ba 100644
>> --- a/arch/arm64/boot/dts/arm/juno-base.dtsi
>> +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
>> @@ -122,15 +122,18 @@
>>                       port at 0 {
>>                               reg = <0>;
>>                               etf0_in_port: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>>                                       remote-endpoint = <&main_funnel_out_port>;
>> +                                     coresight,hwid = <0>;
>>                               };
>>                       };
>>
>>                       /* output port */
>>                       port at 1 {
>> -                             reg = <0>;
>> +                             reg = <1>;
>>                               etf0_out_port: endpoint {
>> +                                     coresight,hwid = <0>;
>> +                                     direction = <1>;
>>                               };
>>                       };
>>               };
>> @@ -145,8 +148,9 @@
>>               power-domains = <&scpi_devpd 0>;
>>               port {
>>                       tpiu_in_port: endpoint {
>> -                             slave-mode;
>> +                             direction = <0>;
>>                               remote-endpoint = <&replicator_out_port0>;
>> +                             coresight,hwid = <0>;
>>                       };
>>               };
>>       };
>> @@ -168,23 +172,27 @@
>>                               reg = <0>;
>>                               main_funnel_out_port: endpoint {
>>                                       remote-endpoint = <&etf0_in_port>;
>> +                                     coresight,hwid = <0>;
>> +                                     direction = <1>;
>>                               };
>>                       };
>>
>>                       /* input ports */
>>                       port at 1 {
>> -                             reg = <0>;
>> +                             reg = <1>;
>>                               main_funnel_in_port0: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>>                                       remote-endpoint = <&cluster0_funnel_out_port>;
>> +                                     coresight,hwid = <0>;
>>                               };
>>                       };
>>
>>                       port at 2 {
>> -                             reg = <1>;
>> +                             reg = <2>;
>>                               main_funnel_in_port1: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>>                                       remote-endpoint = <&cluster1_funnel_out_port>;
>> +                                     coresight,hwid = <1>;
>>                               };
>>                       };
>>               };
>> @@ -200,8 +208,9 @@
>>               power-domains = <&scpi_devpd 0>;
>>               port {
>>                       etr_in_port: endpoint {
>> -                             slave-mode;
>> +                             direction = <0>;
>>                               remote-endpoint = <&replicator_out_port1>;
>> +                             coresight,hwid = <0>;
>>                       };
>>               };
>>       };
>> @@ -217,6 +226,8 @@
>>               power-domains = <&scpi_devpd 0>;
>>               port {
>>                       stm_out_port: endpoint {
>> +                             coresight,hwid = <0>;
>> +                             direction = <1>;
>>                       };
>>               };
>>       };
>> @@ -240,6 +251,8 @@
>>               port {
>>                       cluster0_etm0_out_port: endpoint {
>>                               remote-endpoint = <&cluster0_funnel_in_port0>;
>> +                             coresight,hwid = <0>;
>> +                             direction = <1>;
>>                       };
>>               };
>>       };
>> @@ -259,22 +272,26 @@
>>                               reg = <0>;
>>                               cluster0_funnel_out_port: endpoint {
>>                                       remote-endpoint = <&main_funnel_in_port0>;
>> +                                     coresight,hwid = <0>;
>> +                                     direction = <1>;
>>                               };
>>                       };
>>
>>                       port at 1 {
>> -                             reg = <0>;
>> +                             reg = <1>;
>>                               cluster0_funnel_in_port0: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>>                                       remote-endpoint = <&cluster0_etm0_out_port>;
>> +                                     coresight,hwid = <0>;
>>                               };
>>                       };
>>
>>                       port at 2 {
>> -                             reg = <1>;
>> +                             reg = <2>;
>>                               cluster0_funnel_in_port1: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>>                                       remote-endpoint = <&cluster0_etm1_out_port>;
>> +                                     coresight,hwid = <1>;
>>                               };
>>                       };
>>               };
>> @@ -299,6 +316,8 @@
>>               port {
>>                       cluster0_etm1_out_port: endpoint {
>>                               remote-endpoint = <&cluster0_funnel_in_port1>;
>> +                             coresight,hwid = <0>;
>> +                             direction = <1>;
>>                       };
>>               };
>>       };
>> @@ -322,6 +341,8 @@
>>               port {
>>                       cluster1_etm0_out_port: endpoint {
>>                               remote-endpoint = <&cluster1_funnel_in_port0>;
>> +                             coresight,hwid = <0>;
>> +                             direction = <1>;
>>                       };
>>               };
>>       };
>> @@ -341,36 +362,42 @@
>>                               reg = <0>;
>>                               cluster1_funnel_out_port: endpoint {
>>                                       remote-endpoint = <&main_funnel_in_port1>;
>> +                                     coresight,hwid = <0>;
>> +                                     direction = <1>;
>>                               };
>>                       };
>>
>>                       port at 1 {
>> -                             reg = <0>;
>> +                             reg = <1>;
>>                               cluster1_funnel_in_port0: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>>                                       remote-endpoint = <&cluster1_etm0_out_port>;
>> +                                     coresight,hwid = <0>;
>>                               };
>>                       };
>>
>>                       port at 2 {
>> -                             reg = <1>;
>> +                             reg = <2>;
>>                               cluster1_funnel_in_port1: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>>                                       remote-endpoint = <&cluster1_etm1_out_port>;
>> +                                     coresight,hwid = <1>;
>>                               };
>>                       };
>>                       port at 3 {
>> -                             reg = <2>;
>> +                             reg = <3>;
>>                               cluster1_funnel_in_port2: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>>                                       remote-endpoint = <&cluster1_etm2_out_port>;
>> +                                     coresight,hwid = <2>;
>>                               };
>>                       };
>>                       port at 4 {
>> -                             reg = <3>;
>> +                             reg = <4>;
>>                               cluster1_funnel_in_port3: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>>                                       remote-endpoint = <&cluster1_etm3_out_port>;
>> +                                     coresight,hwid = <3>;
>>                               };
>>                       };
>>               };
>> @@ -395,6 +422,8 @@
>>               port {
>>                       cluster1_etm1_out_port: endpoint {
>>                               remote-endpoint = <&cluster1_funnel_in_port1>;
>> +                             coresight,hwid = <0>;
>> +                             direction = <1>;
>>                       };
>>               };
>>       };
>> @@ -418,6 +447,8 @@
>>               port {
>>                       cluster1_etm2_out_port: endpoint {
>>                               remote-endpoint = <&cluster1_funnel_in_port2>;
>> +                             coresight,hwid = <0>;
>> +                             direction = <1>;
>>                       };
>>               };
>>       };
>> @@ -441,6 +472,8 @@
>>               port {
>>                       cluster1_etm3_out_port: endpoint {
>>                               remote-endpoint = <&cluster1_funnel_in_port3>;
>> +                             coresight,hwid = <0>;
>> +                             direction = <1>;
>>                       };
>>               };
>>       };
>> @@ -462,6 +495,8 @@
>>                               reg = <0>;
>>                               replicator_out_port0: endpoint {
>>                                       remote-endpoint = <&tpiu_in_port>;
>> +                                     coresight,hwid = <0>;
>> +                                     direction = <1>;
>>                               };
>>                       };
>>
>> @@ -469,14 +504,17 @@
>>                               reg = <1>;
>>                               replicator_out_port1: endpoint {
>>                                       remote-endpoint = <&etr_in_port>;
>> +                                     coresight,hwid = <1>;
>> +                                     direction = <1>;
>>                               };
>>                       };
>>
>>                       /* replicator input port */
>>                       port at 2 {
>> -                             reg = <0>;
>> +                             reg = <2>;
>>                               replicator_in_port0: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>> +                                     coresight,hwid = <0>;
>>                               };
>>                       };
>>               };
>> diff --git a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
>> index 0c43fb3..146a5d9 100644
>> --- a/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
>> +++ b/arch/arm64/boot/dts/arm/juno-cs-r1r2.dtsi
>> @@ -15,15 +15,18 @@
>>                       port at 0 {
>>                               reg = <0>;
>>                               csys1_funnel_out_port: endpoint {
>> +                                     coresight,hwid = <0>;
>> +                                     direction = <1>;
>>                                       remote-endpoint = <&etf1_in_port>;
>>                               };
>>                       };
>>
>>                       /* input port */
>>                       port at 1 {
>> -                             reg = <0>;
>> +                             reg = <1>;
>>                               csys1_funnel_in_port0: endpoint {
>> -                                     slave-mode;
>> +                                     coresight,hwid = <0>;
>> +                                     direction = <0>;
>>                               };
>>                       };
>>
>> @@ -45,15 +48,18 @@
>>                       port at 0 {
>>                               reg = <0>;
>>                               etf1_in_port: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>> +                                     coresight,hwid = <0>;
>>                                       remote-endpoint = <&csys1_funnel_out_port>;
>>                               };
>>                       };
>>
>>                       /* output port */
>>                       port at 1 {
>> -                             reg = <0>;
>> +                             reg = <1>;
>>                               etf1_out_port: endpoint {
>> +                                     coresight,hwid = <0>;
>> +                                     direction = <1>;
>>                                       remote-endpoint = <&csys2_funnel_in_port1>;
>>                               };
>>                       };
>> @@ -75,23 +81,27 @@
>>                       port at 0 {
>>                               reg = <0>;
>>                               csys2_funnel_out_port: endpoint {
>> +                                     coresight,hwid = <0>;
>> +                                     direction = <1>;
>>                                       remote-endpoint = <&replicator_in_port0>;
>>                               };
>>                       };
>>
>>                       /* input ports */
>>                       port at 1 {
>> -                             reg = <0>;
>> +                             reg = <1>;
>>                               csys2_funnel_in_port0: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>> +                                     coresight,hwid = <0>;
>>                                       remote-endpoint = <&etf0_out_port>;
>>                               };
>>                       };
>>
>>                       port at 2 {
>> -                             reg = <1>;
>> +                             reg = <2>;
>>                               csys2_funnel_in_port1: endpoint {
>> -                                     slave-mode;
>> +                                     direction = <0>;
>> +                                     coresight,hwid = <1>;
>>                                       remote-endpoint = <&etf1_out_port>;
>>                               };
>>                       };
>> diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
>> index c9236c4..27b8036 100644
>> --- a/arch/arm64/boot/dts/arm/juno.dts
>> +++ b/arch/arm64/boot/dts/arm/juno.dts
>> @@ -260,10 +260,11 @@
>>  &main_funnel {
>>       ports {
>>               port at 3 {
>> -                     reg = <2>;
>> +                     reg = <3>;
>>                       main_funnel_in_port2: endpoint {
>> -                             slave-mode;
>> +                             direction = <0>;
>>                               remote-endpoint = <&stm_out_port>;
>> +                             coresight,hwid = <2>;
>>                       };
>>               };
>>       };
>> --
>> 2.7.4
>>

^ permalink raw reply

* [PATCH 04/24] 32-bit userspace ABI: introduce ARCH_32BIT_OFF_T config option
From: Palmer Dabbelt @ 2018-06-08 22:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180608173207.nwoi25jee52gpdwy@armageddon.cambridge.arm.com>

On Fri, 08 Jun 2018 10:32:07 PDT (-0700), catalin.marinas at arm.com wrote:
> On Wed, May 16, 2018 at 11:18:49AM +0300, Yury Norov wrote:
>> diff --git a/arch/Kconfig b/arch/Kconfig
>> index 76c0b54443b1..ee079244dc3c 100644
>> --- a/arch/Kconfig
>> +++ b/arch/Kconfig
>> @@ -264,6 +264,21 @@ config ARCH_THREAD_STACK_ALLOCATOR
>>  config ARCH_WANTS_DYNAMIC_TASK_STRUCT
>>  	bool
>>
>> +config ARCH_32BIT_OFF_T
>> +	bool
>> +	depends on !64BIT
>> +	help
>> +	  All new 32-bit architectures should have 64-bit off_t type on
>> +	  userspace side which corresponds to the loff_t kernel type. This
>> +	  is the requirement for modern ABIs. Some existing architectures
>> +	  already have 32-bit off_t. This option is enabled for all such
>> +	  architectures explicitly. Namely: arc, arm, blackfin, cris, frv,
>> +	  h8300, hexagon, m32r, m68k, metag, microblaze, mips32, mn10300,
>> +	  nios2, openrisc, parisc32, powerpc32, score, sh, sparc, tile32,
>> +	  unicore32, x86_32 and xtensa. This is the complete list. Any
>> +	  new 32-bit architecture should declare 64-bit off_t type on user
>> +	  side and so should not enable this option.
>
> Do you know if this is the case for riscv and nds32, merged in the
> meantime? If not, I suggest you drop this patch altogether and just
> define force_o_largefile() for arm64/ilp32 as we don't seem to stick to
> "all new 32-bit architectures should have 64-bit off_t".

We (RISC-V) don't have support for rv32i in glibc yet, so there really isn't a 
fixed ABI there yet.  From my understanding the rv32i port as it currently 
stands has a 32-bit off_t (via __kernel_off_t being defined as long), so this 
change would technically be a kernel ABI break.

Since we don't have rv32i glibc yet I'm not fundamentally opposed to an ABI 
break.  Is there a concrete advantage to this?

^ permalink raw reply

* [PATCH v7 0/2] regulator: add QCOM RPMh regulator driver
From: David Collins @ 2018-06-08 23:44 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series adds a driver and device tree binding documentation for
PMIC regulator control via Resource Power Manager-hardened (RPMh) on some
Qualcomm Technologies, Inc. SoCs such as SDM845.  RPMh is a hardware block
which contains several accelerators which are used to manage various
hardware resources that are shared between the processors of the SoC.  The
final hardware state of a regulator is determined within RPMh by performing
max aggregation of the requests made by all of the processors.

The RPMh regulator driver depends upon the RPMh driver [1] and command DB
driver [2] which are both still undergoing review.  It also depends upon
three recent regulator changes: [3], [4], and [5].

Changes since v6 [6]:
 - Removed 'count' parameter from rpmh_regulator_send_request() since
   it is always 1
 - Fixed _rpmh_regulator_vrm_set_voltage_sel() return value
 - Added a helper function to capture common code between
   rpmh_regulator_enable() and rpmh_regulator_disable()
 - Added an iterator for pmic_rpmh_data in rpmh_regulator_init_vreg()
 - Added Reviewed-by tag for both patches

Changes since v5 [7]:
 - Removed unused constants
 - Added Reviewed-by tag for DT patch 1/2

Changes since v4 [8]:
 - Removed support for DT properties qcom,regulator-drms-modes and
   qcom,drms-mode-max-microamps
 - Specified fixed DRMS high power mode minimum limits for LDO type
   regulators
 - Removed DRMS support for SMPS and BOB type regulators
 - Simplified voltage caching logic

Changes since v3 [9]:
 - Removed support for DT properties qcom,regulator-initial-microvolt
   and qcom,headroom-microvolt
 - Renamed DT property qcom,allowed-drms-modes to be
   qcom,regulator-drms-modes
 - Updated DT binding documentation to mention which common regulator
   bindings can be used for qcom-rpmh-regulator devices
 - Added voltage caching so that voltage requests are only sent to RPMh
   after the regulator has been enabled at least once
 - Changed 'voltage_selector' default value to be -ENOTRECOVERABLE to
   interact with [5]
 - Initialized 'enabled' to -EINVAL so that unused regulators are
   disabled by regulator_late_cleanup()
 - Removed rpmh_regulator_load_default_parameters() as it is no longer
   needed
 - Updated the mode usage description in qcom,rpmh-regulator.h

Changes since v2 [10]:
 - Replaced '_' with '-' in device tree supply property names
 - Renamed qcom_rpmh-regulator.c to be qcom-rpmh-regulator.c
 - Updated various DT property names to use "microvolt" and "microamp"
 - Moved allowed modes constraint specification out of the driver [4]
 - Replaced rpmh_client with device pointer to match new RPMh API [1]
 - Corrected drms mode threshold checking
 - Initialized voltage_selector to -EINVAL when not specified in DT
 - Added constants for PMIC regulator hardware modes
 - Corrected type sign of mode mapping tables
 - Made variable names for mode arrays plural
 - Simplified Kconfig depends on
 - Removed unnecessary constants and struct fields
 - Added some descriptive comments

Changes since v1 [11]:
 - Addressed review feedback from Doug, Mark, and Stephen
 - Replaced set_voltage()/get_voltage() callbacks with set_voltage_sel()/
   get_voltage_sel()
 - Added set_bypass()/get_bypass() callbacks for BOB pass-through mode
   control
 - Removed top-level PMIC data structures
 - Removed initialization variables from structs and passed them as
   function parameters
 - Removed various comments and error messages
 - Simplified mode handling
 - Refactored per-PMIC rpmh-regulator data specification
 - Simplified probe function
 - Moved header into DT patch
 - Removed redundant property listings from DT binding documentation

[1]: https://lkml.org/lkml/2018/5/9/729
[2]: https://lkml.org/lkml/2018/4/10/714
[3]: https://lkml.org/lkml/2018/4/18/556
[4]: https://lkml.org/lkml/2018/5/11/696
[5]: https://lkml.org/lkml/2018/5/15/1005
[6]: https://lkml.org/lkml/2018/6/4/879
[7]: https://lkml.org/lkml/2018/6/1/895
[8]: https://lkml.org/lkml/2018/5/22/1168
[9]: https://lkml.org/lkml/2018/5/11/701
[10]: https://lkml.org/lkml/2018/4/13/687
[11]: https://lkml.org/lkml/2018/3/16/1431

David Collins (2):
  regulator: dt-bindings: add QCOM RPMh regulator bindings
  regulator: add QCOM RPMh regulator driver

 .../bindings/regulator/qcom,rpmh-regulator.txt     | 160 +++++
 drivers/regulator/Kconfig                          |   9 +
 drivers/regulator/Makefile                         |   1 +
 drivers/regulator/qcom-rpmh-regulator.c            | 753 +++++++++++++++++++++
 .../dt-bindings/regulator/qcom,rpmh-regulator.h    |  36 +
 5 files changed, 959 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
 create mode 100644 drivers/regulator/qcom-rpmh-regulator.c
 create mode 100644 include/dt-bindings/regulator/qcom,rpmh-regulator.h

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

^ permalink raw reply

* [PATCH v7 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: David Collins @ 2018-06-08 23:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1528498807.git.collinsd@codeaurora.org>

Introduce bindings for RPMh regulator devices found on some
Qualcomm Technlogies, Inc. SoCs.  These devices allow a given
processor within the SoC to make PMIC regulator requests which
are aggregated within the RPMh hardware block along with requests
from other processors in the SoC to determine the final PMIC
regulator hardware state.

Signed-off-by: David Collins <collinsd@codeaurora.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
---
 .../bindings/regulator/qcom,rpmh-regulator.txt     | 160 +++++++++++++++++++++
 .../dt-bindings/regulator/qcom,rpmh-regulator.h    |  36 +++++
 2 files changed, 196 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
 create mode 100644 include/dt-bindings/regulator/qcom,rpmh-regulator.h

diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
new file mode 100644
index 0000000..7ef2dbe
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
@@ -0,0 +1,160 @@
+Qualcomm Technologies, Inc. RPMh Regulators
+
+rpmh-regulator devices support PMIC regulator management via the Voltage
+Regulator Manager (VRM) and Oscillator Buffer (XOB) RPMh accelerators.  The APPS
+processor communicates with these hardware blocks via a Resource State
+Coordinator (RSC) using command packets.  The VRM allows changing three
+parameters for a given regulator: enable state, output voltage, and operating
+mode.  The XOB allows changing only a single parameter for a given regulator:
+its enable state.  Despite its name, the XOB is capable of controlling the
+enable state of any PMIC peripheral.  It is used for clock buffers, low-voltage
+switches, and LDO/SMPS regulators which have a fixed voltage and mode.
+
+=======================
+Required Node Structure
+=======================
+
+RPMh regulators must be described in two levels of device nodes.  The first
+level describes the PMIC containing the regulators and must reside within an
+RPMh device node.  The second level describes each regulator within the PMIC
+which is to be used on the board.  Each of these regulators maps to a single
+RPMh resource.
+
+The names used for regulator nodes must match those supported by a given PMIC.
+Supported regulator node names:
+	PM8998:		smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2
+	PMI8998:	bob
+	PM8005:		smps1 - smps4
+
+========================
+First Level Nodes - PMIC
+========================
+
+- compatible
+	Usage:      required
+	Value type: <string>
+	Definition: Must be one of: "qcom,pm8998-rpmh-regulators",
+		    "qcom,pmi8998-rpmh-regulators" or
+		    "qcom,pm8005-rpmh-regulators".
+
+- qcom,pmic-id
+	Usage:      required
+	Value type: <string>
+	Definition: RPMh resource name suffix used for the regulators found on
+		    this PMIC.  Typical values: "a", "b", "c", "d", "e", "f".
+
+- vdd-s1-supply
+- vdd-s2-supply
+- vdd-s3-supply
+- vdd-s4-supply
+	Usage:      optional (PM8998 and PM8005 only)
+	Value type: <phandle>
+	Definition: phandle of the parent supply regulator of one or more of the
+		    regulators for this PMIC.
+
+- vdd-s5-supply
+- vdd-s6-supply
+- vdd-s7-supply
+- vdd-s8-supply
+- vdd-s9-supply
+- vdd-s10-supply
+- vdd-s11-supply
+- vdd-s12-supply
+- vdd-s13-supply
+- vdd-l1-l27-supply
+- vdd-l2-l8-l17-supply
+- vdd-l3-l11-supply
+- vdd-l4-l5-supply
+- vdd-l6-supply
+- vdd-l7-l12-l14-l15-supply
+- vdd-l9-supply
+- vdd-l10-l23-l25-supply
+- vdd-l13-l19-l21-supply
+- vdd-l16-l28-supply
+- vdd-l18-l22-supply
+- vdd-l20-l24-supply
+- vdd-l26-supply
+- vin-lvs-1-2-supply
+	Usage:      optional (PM8998 only)
+	Value type: <phandle>
+	Definition: phandle of the parent supply regulator of one or more of the
+		    regulators for this PMIC.
+
+- vdd-bob-supply
+	Usage:      optional (PMI8998 only)
+	Value type: <phandle>
+	Definition: BOB regulator parent supply phandle
+
+===============================
+Second Level Nodes - Regulators
+===============================
+
+- qcom,always-wait-for-ack
+	Usage:      optional
+	Value type: <empty>
+	Definition: Boolean flag which indicates that the application processor
+		    must wait for an ACK or a NACK from RPMh for every request
+		    sent for this regulator including those which are for a
+		    strictly lower power state.
+
+Other properties defined in Documentation/devicetree/bindings/regulator.txt
+may also be used.  regulator-initial-mode and regulator-allowed-modes may be
+specified for VRM regulators using mode values from
+include/dt-bindings/regulator/qcom,rpmh-regulator.h.  regulator-allow-bypass
+may be specified for BOB type regulators managed via VRM.
+regulator-allow-set-load may be specified for LDO type regulators managed via
+VRM.
+
+========
+Examples
+========
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+&apps_rsc {
+	pm8998-rpmh-regulators {
+		compatible = "qcom,pm8998-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vdd-l7-l12-l14-l15-supply = <&pm8998_s5>;
+
+		smps2 {
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1100000>;
+		};
+
+		pm8998_s5: smps5 {
+			regulator-min-microvolt = <1904000>;
+			regulator-max-microvolt = <2040000>;
+		};
+
+		ldo7 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allowed-modes =
+				<RPMH_REGULATOR_MODE_LPM
+				 RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+		};
+
+		lvs1 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+	};
+
+	pmi8998-rpmh-regulators {
+		compatible = "qcom,pmi8998-rpmh-regulators";
+		qcom,pmic-id = "b";
+
+		bob {
+			regulator-min-microvolt = <3312000>;
+			regulator-max-microvolt = <3600000>;
+			regulator-allowed-modes =
+				<RPMH_REGULATOR_MODE_AUTO
+				 RPMH_REGULATOR_MODE_HPM>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+		};
+	};
+};
diff --git a/include/dt-bindings/regulator/qcom,rpmh-regulator.h b/include/dt-bindings/regulator/qcom,rpmh-regulator.h
new file mode 100644
index 0000000..86713dc
--- /dev/null
+++ b/include/dt-bindings/regulator/qcom,rpmh-regulator.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */
+
+#ifndef __QCOM_RPMH_REGULATOR_H
+#define __QCOM_RPMH_REGULATOR_H
+
+/*
+ * These mode constants may be used to specify modes for various RPMh regulator
+ * device tree properties (e.g. regulator-initial-mode).  Each type of regulator
+ * supports a subset of the possible modes.
+ *
+ * %RPMH_REGULATOR_MODE_RET:	Retention mode in which only an extremely small
+ *				load current is allowed.  This mode is supported
+ *				by LDO and SMPS type regulators.
+ * %RPMH_REGULATOR_MODE_LPM:	Low power mode in which a small load current is
+ *				allowed.  This mode corresponds to PFM for SMPS
+ *				and BOB type regulators.  This mode is supported
+ *				by LDO, HFSMPS, BOB, and PMIC4 FTSMPS type
+ *				regulators.
+ * %RPMH_REGULATOR_MODE_AUTO:	Auto mode in which the regulator hardware
+ *				automatically switches between LPM and HPM based
+ *				upon the real-time load current.  This mode is
+ *				supported by HFSMPS, BOB, and PMIC4 FTSMPS type
+ *				regulators.
+ * %RPMH_REGULATOR_MODE_HPM:	High power mode in which the full rated current
+ *				of the regulator is allowed.  This mode
+ *				corresponds to PWM for SMPS and BOB type
+ *				regulators.  This mode is supported by all types
+ *				of regulators.
+ */
+#define RPMH_REGULATOR_MODE_RET		0
+#define RPMH_REGULATOR_MODE_LPM		1
+#define RPMH_REGULATOR_MODE_AUTO	2
+#define RPMH_REGULATOR_MODE_HPM		3
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH v7 2/2] regulator: add QCOM RPMh regulator driver
From: David Collins @ 2018-06-08 23:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1528498807.git.collinsd@codeaurora.org>

Add the QCOM RPMh regulator driver to manage PMIC regulators
which are controlled via RPMh on some Qualcomm Technologies, Inc.
SoCs.  RPMh is a hardware block which contains several
accelerators which are used to manage various hardware resources
that are shared between the processors of the SoC.  The final
hardware state of a regulator is determined within RPMh by
performing max aggregation of the requests made by all of the
processors.

Add support for PMIC regulator control via the voltage regulator
manager (VRM) and oscillator buffer (XOB) RPMh accelerators.
VRM supports manipulation of enable state, voltage, and mode.
XOB supports manipulation of enable state.

Signed-off-by: David Collins <collinsd@codeaurora.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
---
 drivers/regulator/Kconfig               |   9 +
 drivers/regulator/Makefile              |   1 +
 drivers/regulator/qcom-rpmh-regulator.c | 753 ++++++++++++++++++++++++++++++++
 3 files changed, 763 insertions(+)
 create mode 100644 drivers/regulator/qcom-rpmh-regulator.c

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 5dbccf5..96b701f 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -682,6 +682,15 @@ config REGULATOR_QCOM_RPM
 	  Qualcomm RPM as a module. The module will be named
 	  "qcom_rpm-regulator".
 
+config REGULATOR_QCOM_RPMH
+	tristate "Qualcomm Technologies, Inc. RPMh regulator driver"
+	depends on QCOM_RPMH || COMPILE_TEST
+	help
+	  This driver supports control of PMIC regulators via the RPMh hardware
+	  block found on Qualcomm Technologies Inc. SoCs.  RPMh regulator
+	  control allows for voting on regulator state between multiple
+	  processors within the SoC.
+
 config REGULATOR_QCOM_SMD_RPM
 	tristate "Qualcomm SMD based RPM regulator driver"
 	depends on QCOM_SMD_RPM
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index bd818ce..06e76a6 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_REGULATOR_MT6323)	+= mt6323-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380)	+= mt6380-regulator.o
 obj-$(CONFIG_REGULATOR_MT6397)	+= mt6397-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
+obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SMD_RPM) += qcom_smd-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_SPMI) += qcom_spmi-regulator.o
 obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o
diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
new file mode 100644
index 0000000..6f61625
--- /dev/null
+++ b/drivers/regulator/qcom-rpmh-regulator.c
@@ -0,0 +1,753 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved. */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+
+#include <soc/qcom/cmd-db.h>
+#include <soc/qcom/rpmh.h>
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+/**
+ * enum rpmh_regulator_type - supported RPMh accelerator types
+ * %VRM:	RPMh VRM accelerator which supports voting on enable, voltage,
+ *		and mode of LDO, SMPS, and BOB type PMIC regulators.
+ * %XOB:	RPMh XOB accelerator which supports voting on the enable state
+ *		of PMIC regulators.
+ */
+enum rpmh_regulator_type {
+	VRM,
+	XOB,
+};
+
+#define RPMH_REGULATOR_REG_VRM_VOLTAGE		0x0
+#define RPMH_REGULATOR_REG_ENABLE		0x4
+#define RPMH_REGULATOR_REG_VRM_MODE		0x8
+
+#define RPMH_REGULATOR_MODE_COUNT		4
+
+#define PMIC4_LDO_MODE_RETENTION		4
+#define PMIC4_LDO_MODE_LPM			5
+#define PMIC4_LDO_MODE_HPM			7
+
+#define PMIC4_SMPS_MODE_RETENTION		4
+#define PMIC4_SMPS_MODE_PFM			5
+#define PMIC4_SMPS_MODE_AUTO			6
+#define PMIC4_SMPS_MODE_PWM			7
+
+#define PMIC4_BOB_MODE_PASS			0
+#define PMIC4_BOB_MODE_PFM			1
+#define PMIC4_BOB_MODE_AUTO			2
+#define PMIC4_BOB_MODE_PWM			3
+
+/**
+ * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations
+ * @regulator_type:		RPMh accelerator type used to manage this
+ *				regulator
+ * @ops:			Pointer to regulator ops callback structure
+ * @voltage_range:		The single range of voltages supported by this
+ *				PMIC regulator type
+ * @n_voltages:			The number of unique voltage set points defined
+ *				by voltage_range
+ * @hpm_min_load_uA:		Minimum load current in microamps that requires
+ *				high power mode (HPM) operation.  This is used
+ *				for LDO hardware type regulators only.
+ * @pmic_mode_map:		Array indexed by regulator framework mode
+ *				containing PMIC hardware modes.  Must be large
+ *				enough to index all framework modes supported
+ *				by this regulator hardware type.
+ * @of_map_mode:		Maps an RPMH_REGULATOR_MODE_* mode value defined
+ *				in device tree to a regulator framework mode
+ */
+struct rpmh_vreg_hw_data {
+	enum rpmh_regulator_type		regulator_type;
+	const struct regulator_ops		*ops;
+	const struct regulator_linear_range	voltage_range;
+	int					n_voltages;
+	int					hpm_min_load_uA;
+	const int				*pmic_mode_map;
+	unsigned int			      (*of_map_mode)(unsigned int mode);
+};
+
+/**
+ * struct rpmh_vreg - individual RPMh regulator data structure encapsulating a
+ *		single regulator device
+ * @dev:			Device pointer for the top-level PMIC RPMh
+ *				regulator parent device.  This is used as a
+ *				handle in RPMh write requests.
+ * @addr:			Base address of the regulator resource within
+ *				an RPMh accelerator
+ * @rdesc:			Regulator descriptor
+ * @hw_data:			PMIC regulator configuration data for this RPMh
+ *				regulator
+ * @always_wait_for_ack:	Boolean flag indicating if a request must always
+ *				wait for an ACK from RPMh before continuing even
+ *				if it corresponds to a strictly lower power
+ *				state (e.g. enabled --> disabled).
+ * @enabled:			Flag indicating if the regulator is enabled or
+ *				not
+ * @bypassed:			Boolean indicating if the regulator is in
+ *				bypass (pass-through) mode or not.  This is
+ *				only used by BOB rpmh-regulator resources.
+ * @voltage_selector:		Selector used for get_voltage_sel() and
+ *				set_voltage_sel() callbacks
+ * @mode:			RPMh VRM regulator current framework mode
+ */
+struct rpmh_vreg {
+	struct device			*dev;
+	u32				addr;
+	struct regulator_desc		rdesc;
+	const struct rpmh_vreg_hw_data	*hw_data;
+	bool				always_wait_for_ack;
+
+	int				enabled;
+	bool				bypassed;
+	int				voltage_selector;
+	unsigned int			mode;
+};
+
+/**
+ * struct rpmh_vreg_init_data - initialization data for an RPMh regulator
+ * @name:			Name for the regulator which also corresponds
+ *				to the device tree subnode name of the regulator
+ * @resource_name:		RPMh regulator resource name format string.
+ *				This must include exactly one field: '%s' which
+ *				is filled at run-time with the PMIC ID provided
+ *				by device tree property qcom,pmic-id.  Example:
+ *				"ldo%s1" for RPMh resource "ldoa1".
+ * @supply_name:		Parent supply regulator name
+ * @hw_data:			Configuration data for this PMIC regulator type
+ */
+struct rpmh_vreg_init_data {
+	const char			*name;
+	const char			*resource_name;
+	const char			*supply_name;
+	const struct rpmh_vreg_hw_data	*hw_data;
+};
+
+/**
+ * rpmh_regulator_send_request() - send the request to RPMh
+ * @vreg:		Pointer to the RPMh regulator
+ * @cmd:		Pointer to the RPMh command to send
+ * @wait_for_ack:	Boolean indicating if execution must wait until the
+ *			request has been acknowledged as complete
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_send_request(struct rpmh_vreg *vreg,
+			struct tcs_cmd *cmd, bool wait_for_ack)
+{
+	int ret;
+
+	if (wait_for_ack || vreg->always_wait_for_ack)
+		ret = rpmh_write(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd, 1);
+	else
+		ret = rpmh_write_async(vreg->dev, RPMH_ACTIVE_ONLY_STATE, cmd,
+					1);
+
+	return ret;
+}
+
+static int _rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
+				unsigned int selector, bool wait_for_ack)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	struct tcs_cmd cmd = {
+		.addr = vreg->addr + RPMH_REGULATOR_REG_VRM_VOLTAGE,
+	};
+	int ret;
+
+	/* VRM voltage control register is set with voltage in millivolts. */
+	cmd.data = DIV_ROUND_UP(regulator_list_voltage_linear_range(rdev,
+							selector), 1000);
+
+	ret = rpmh_regulator_send_request(vreg, &cmd, wait_for_ack);
+	if (!ret)
+		vreg->voltage_selector = selector;
+
+	return ret;
+}
+
+static int rpmh_regulator_vrm_set_voltage_sel(struct regulator_dev *rdev,
+					unsigned int selector)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+	if (vreg->enabled == -EINVAL) {
+		/*
+		 * Cache the voltage and send it later when the regulator is
+		 * enabled or disabled.
+		 */
+		vreg->voltage_selector = selector;
+		return 0;
+	}
+
+	return _rpmh_regulator_vrm_set_voltage_sel(rdev, selector,
+					selector > vreg->voltage_selector);
+}
+
+static int rpmh_regulator_vrm_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+	return vreg->voltage_selector;
+}
+
+static int rpmh_regulator_is_enabled(struct regulator_dev *rdev)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+	return vreg->enabled;
+}
+
+static int rpmh_regulator_set_enable_state(struct regulator_dev *rdev,
+					bool enable)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	struct tcs_cmd cmd = {
+		.addr = vreg->addr + RPMH_REGULATOR_REG_ENABLE,
+		.data = enable,
+	};
+	int ret;
+
+	if (vreg->enabled == -EINVAL &&
+	    vreg->voltage_selector != -ENOTRECOVERABLE) {
+		ret = _rpmh_regulator_vrm_set_voltage_sel(rdev,
+						vreg->voltage_selector, true);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = rpmh_regulator_send_request(vreg, &cmd, enable);
+	if (!ret)
+		vreg->enabled = enable;
+
+	return ret;
+}
+
+static int rpmh_regulator_enable(struct regulator_dev *rdev)
+{
+	return rpmh_regulator_set_enable_state(rdev, true);
+}
+
+static int rpmh_regulator_disable(struct regulator_dev *rdev)
+{
+	return rpmh_regulator_set_enable_state(rdev, false);
+}
+
+static int rpmh_regulator_vrm_set_mode_bypass(struct rpmh_vreg *vreg,
+					unsigned int mode, bool bypassed)
+{
+	struct tcs_cmd cmd = {
+		.addr = vreg->addr + RPMH_REGULATOR_REG_VRM_MODE,
+	};
+	int pmic_mode;
+
+	if (mode > REGULATOR_MODE_STANDBY)
+		return -EINVAL;
+
+	pmic_mode = vreg->hw_data->pmic_mode_map[mode];
+	if (pmic_mode < 0)
+		return pmic_mode;
+
+	cmd.data = bypassed ? PMIC4_BOB_MODE_PASS : pmic_mode;
+
+	return rpmh_regulator_send_request(vreg, &cmd, true);
+}
+
+static int rpmh_regulator_vrm_set_mode(struct regulator_dev *rdev,
+					unsigned int mode)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	int ret;
+
+	if (mode == vreg->mode)
+		return 0;
+
+	ret = rpmh_regulator_vrm_set_mode_bypass(vreg, mode, vreg->bypassed);
+	if (!ret)
+		vreg->mode = mode;
+
+	return ret;
+}
+
+static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+	return vreg->mode;
+}
+
+/**
+ * rpmh_regulator_vrm_set_load() - set the regulator mode based upon the load
+ *		current requested
+ * @rdev:		Regulator device pointer for the rpmh-regulator
+ * @load_uA:		Aggregated load current in microamps
+ *
+ * This function is used in the regulator_ops for VRM type RPMh regulator
+ * devices.
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_vrm_set_load(struct regulator_dev *rdev, int load_uA)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	unsigned int mode;
+
+	if (load_uA >= vreg->hw_data->hpm_min_load_uA)
+		mode = REGULATOR_MODE_FAST;
+	else
+		mode = REGULATOR_MODE_IDLE;
+
+	return rpmh_regulator_vrm_set_mode(rdev, mode);
+}
+
+static int rpmh_regulator_vrm_set_bypass(struct regulator_dev *rdev,
+				bool enable)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+	int ret;
+
+	if (vreg->bypassed == enable)
+		return 0;
+
+	ret = rpmh_regulator_vrm_set_mode_bypass(vreg, vreg->mode, enable);
+	if (!ret)
+		vreg->bypassed = enable;
+
+	return ret;
+}
+
+static int rpmh_regulator_vrm_get_bypass(struct regulator_dev *rdev,
+				bool *enable)
+{
+	struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
+
+	*enable = vreg->bypassed;
+
+	return 0;
+}
+
+static const struct regulator_ops rpmh_regulator_vrm_ops = {
+	.enable			= rpmh_regulator_enable,
+	.disable		= rpmh_regulator_disable,
+	.is_enabled		= rpmh_regulator_is_enabled,
+	.set_voltage_sel	= rpmh_regulator_vrm_set_voltage_sel,
+	.get_voltage_sel	= rpmh_regulator_vrm_get_voltage_sel,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.set_mode		= rpmh_regulator_vrm_set_mode,
+	.get_mode		= rpmh_regulator_vrm_get_mode,
+};
+
+static const struct regulator_ops rpmh_regulator_vrm_drms_ops = {
+	.enable			= rpmh_regulator_enable,
+	.disable		= rpmh_regulator_disable,
+	.is_enabled		= rpmh_regulator_is_enabled,
+	.set_voltage_sel	= rpmh_regulator_vrm_set_voltage_sel,
+	.get_voltage_sel	= rpmh_regulator_vrm_get_voltage_sel,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.set_mode		= rpmh_regulator_vrm_set_mode,
+	.get_mode		= rpmh_regulator_vrm_get_mode,
+	.set_load		= rpmh_regulator_vrm_set_load,
+};
+
+static const struct regulator_ops rpmh_regulator_vrm_bypass_ops = {
+	.enable			= rpmh_regulator_enable,
+	.disable		= rpmh_regulator_disable,
+	.is_enabled		= rpmh_regulator_is_enabled,
+	.set_voltage_sel	= rpmh_regulator_vrm_set_voltage_sel,
+	.get_voltage_sel	= rpmh_regulator_vrm_get_voltage_sel,
+	.list_voltage		= regulator_list_voltage_linear_range,
+	.set_mode		= rpmh_regulator_vrm_set_mode,
+	.get_mode		= rpmh_regulator_vrm_get_mode,
+	.set_bypass		= rpmh_regulator_vrm_set_bypass,
+	.get_bypass		= rpmh_regulator_vrm_get_bypass,
+};
+
+static const struct regulator_ops rpmh_regulator_xob_ops = {
+	.enable			= rpmh_regulator_enable,
+	.disable		= rpmh_regulator_disable,
+	.is_enabled		= rpmh_regulator_is_enabled,
+};
+
+/**
+ * rpmh_regulator_init_vreg() - initialize all attributes of an rpmh-regulator
+ * vreg:		Pointer to the individual rpmh-regulator resource
+ * dev:			Pointer to the top level rpmh-regulator PMIC device
+ * node:		Pointer to the individual rpmh-regulator resource
+ *			device node
+ * pmic_id:		String used to identify the top level rpmh-regulator
+ *			PMIC device on the board
+ * pmic_rpmh_data:	Pointer to a null-terminated array of rpmh-regulator
+ *			resources defined for the top level PMIC device
+ *
+ * Return: 0 on success, errno on failure
+ */
+static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
+			struct device_node *node, const char *pmic_id,
+			const struct rpmh_vreg_init_data *pmic_rpmh_data)
+{
+	struct regulator_config reg_config = {};
+	char rpmh_resource_name[20] = "";
+	const struct rpmh_vreg_init_data *rpmh_data;
+	struct regulator_init_data *init_data;
+	struct regulator_dev *rdev;
+	int ret;
+
+	vreg->dev = dev;
+
+	for (rpmh_data = pmic_rpmh_data; rpmh_data->name; rpmh_data++)
+		if (!strcmp(rpmh_data->name, node->name))
+			break;
+
+	if (!rpmh_data->name) {
+		dev_err(dev, "Unknown regulator %s\n", node->name);
+		return -EINVAL;
+	}
+
+	scnprintf(rpmh_resource_name, sizeof(rpmh_resource_name),
+		rpmh_data->resource_name, pmic_id);
+
+	vreg->addr = cmd_db_read_addr(rpmh_resource_name);
+	if (!vreg->addr) {
+		dev_err(dev, "%s: could not find RPMh address for resource %s\n",
+			node->name, rpmh_resource_name);
+		return -ENODEV;
+	}
+
+	vreg->rdesc.name = rpmh_data->name;
+	vreg->rdesc.supply_name = rpmh_data->supply_name;
+	vreg->hw_data = rpmh_data->hw_data;
+
+	vreg->enabled = -EINVAL;
+	vreg->voltage_selector = -ENOTRECOVERABLE;
+	vreg->mode = REGULATOR_MODE_INVALID;
+
+	if (rpmh_data->hw_data->n_voltages) {
+		vreg->rdesc.linear_ranges = &rpmh_data->hw_data->voltage_range;
+		vreg->rdesc.n_linear_ranges = 1;
+		vreg->rdesc.n_voltages = rpmh_data->hw_data->n_voltages;
+	}
+
+	vreg->always_wait_for_ack = of_property_read_bool(node,
+						"qcom,always-wait-for-ack");
+
+	vreg->rdesc.owner	= THIS_MODULE;
+	vreg->rdesc.type	= REGULATOR_VOLTAGE;
+	vreg->rdesc.ops		= vreg->hw_data->ops;
+	vreg->rdesc.of_map_mode	= vreg->hw_data->of_map_mode;
+
+	init_data = of_get_regulator_init_data(dev, node, &vreg->rdesc);
+	if (!init_data)
+		return -ENOMEM;
+
+	if (rpmh_data->hw_data->regulator_type == XOB &&
+	    init_data->constraints.min_uV &&
+	    init_data->constraints.min_uV == init_data->constraints.max_uV) {
+		vreg->rdesc.fixed_uV = init_data->constraints.min_uV;
+		vreg->rdesc.n_voltages = 1;
+	}
+
+	reg_config.dev		= dev;
+	reg_config.init_data	= init_data;
+	reg_config.of_node	= node;
+	reg_config.driver_data	= vreg;
+
+	rdev = devm_regulator_register(dev, &vreg->rdesc, &reg_config);
+	if (IS_ERR(rdev)) {
+		ret = PTR_ERR(rdev);
+		dev_err(dev, "%s: devm_regulator_register() failed, ret=%d\n",
+			node->name, ret);
+		return ret;
+	}
+
+	dev_dbg(dev, "%s regulator registered for RPMh resource %s @ 0x%05X\n",
+		node->name, rpmh_resource_name, vreg->addr);
+
+	return 0;
+}
+
+static const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
+	[REGULATOR_MODE_INVALID] = -EINVAL,
+	[REGULATOR_MODE_STANDBY] = PMIC4_LDO_MODE_RETENTION,
+	[REGULATOR_MODE_IDLE]    = PMIC4_LDO_MODE_LPM,
+	[REGULATOR_MODE_NORMAL]  = -EINVAL,
+	[REGULATOR_MODE_FAST]    = PMIC4_LDO_MODE_HPM,
+};
+
+static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int mode)
+{
+	static const unsigned int of_mode_map[RPMH_REGULATOR_MODE_COUNT] = {
+		[RPMH_REGULATOR_MODE_RET]  = REGULATOR_MODE_STANDBY,
+		[RPMH_REGULATOR_MODE_LPM]  = REGULATOR_MODE_IDLE,
+		[RPMH_REGULATOR_MODE_AUTO] = REGULATOR_MODE_INVALID,
+		[RPMH_REGULATOR_MODE_HPM]  = REGULATOR_MODE_FAST,
+	};
+
+	if (mode >= RPMH_REGULATOR_MODE_COUNT)
+		return -EINVAL;
+
+	return of_mode_map[mode];
+}
+
+static const int pmic_mode_map_pmic4_smps[REGULATOR_MODE_STANDBY + 1] = {
+	[REGULATOR_MODE_INVALID] = -EINVAL,
+	[REGULATOR_MODE_STANDBY] = PMIC4_SMPS_MODE_RETENTION,
+	[REGULATOR_MODE_IDLE]    = PMIC4_SMPS_MODE_PFM,
+	[REGULATOR_MODE_NORMAL]  = PMIC4_SMPS_MODE_AUTO,
+	[REGULATOR_MODE_FAST]    = PMIC4_SMPS_MODE_PWM,
+};
+
+static unsigned int rpmh_regulator_pmic4_smps_of_map_mode(unsigned int mode)
+{
+	static const unsigned int of_mode_map[RPMH_REGULATOR_MODE_COUNT] = {
+		[RPMH_REGULATOR_MODE_RET]  = REGULATOR_MODE_STANDBY,
+		[RPMH_REGULATOR_MODE_LPM]  = REGULATOR_MODE_IDLE,
+		[RPMH_REGULATOR_MODE_AUTO] = REGULATOR_MODE_NORMAL,
+		[RPMH_REGULATOR_MODE_HPM]  = REGULATOR_MODE_FAST,
+	};
+
+	if (mode >= RPMH_REGULATOR_MODE_COUNT)
+		return -EINVAL;
+
+	return of_mode_map[mode];
+}
+
+static const int pmic_mode_map_pmic4_bob[REGULATOR_MODE_STANDBY + 1] = {
+	[REGULATOR_MODE_INVALID] = -EINVAL,
+	[REGULATOR_MODE_STANDBY] = -EINVAL,
+	[REGULATOR_MODE_IDLE]    = PMIC4_BOB_MODE_PFM,
+	[REGULATOR_MODE_NORMAL]  = PMIC4_BOB_MODE_AUTO,
+	[REGULATOR_MODE_FAST]    = PMIC4_BOB_MODE_PWM,
+};
+
+static unsigned int rpmh_regulator_pmic4_bob_of_map_mode(unsigned int mode)
+{
+	static const unsigned int of_mode_map[RPMH_REGULATOR_MODE_COUNT] = {
+		[RPMH_REGULATOR_MODE_RET]  = REGULATOR_MODE_INVALID,
+		[RPMH_REGULATOR_MODE_LPM]  = REGULATOR_MODE_IDLE,
+		[RPMH_REGULATOR_MODE_AUTO] = REGULATOR_MODE_NORMAL,
+		[RPMH_REGULATOR_MODE_HPM]  = REGULATOR_MODE_FAST,
+	};
+
+	if (mode >= RPMH_REGULATOR_MODE_COUNT)
+		return -EINVAL;
+
+	return of_mode_map[mode];
+}
+
+static const struct rpmh_vreg_hw_data pmic4_pldo = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_drms_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(1664000, 0, 255, 8000),
+	.n_voltages = 256,
+	.hpm_min_load_uA = 10000,
+	.pmic_mode_map = pmic_mode_map_pmic4_ldo,
+	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_pldo_lv = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_drms_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(1256000, 0, 127, 8000),
+	.n_voltages = 128,
+	.hpm_min_load_uA = 10000,
+	.pmic_mode_map = pmic_mode_map_pmic4_ldo,
+	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_nldo = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_drms_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(312000, 0, 127, 8000),
+	.n_voltages = 128,
+	.hpm_min_load_uA = 30000,
+	.pmic_mode_map = pmic_mode_map_pmic4_ldo,
+	.of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_hfsmps3 = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
+	.n_voltages = 216,
+	.pmic_mode_map = pmic_mode_map_pmic4_smps,
+	.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_ftsmps426 = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 258, 4000),
+	.n_voltages = 259,
+	.pmic_mode_map = pmic_mode_map_pmic4_smps,
+	.of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_bob = {
+	.regulator_type = VRM,
+	.ops = &rpmh_regulator_vrm_bypass_ops,
+	.voltage_range = REGULATOR_LINEAR_RANGE(1824000, 0, 83, 32000),
+	.n_voltages = 84,
+	.pmic_mode_map = pmic_mode_map_pmic4_bob,
+	.of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic4_lvs = {
+	.regulator_type = XOB,
+	.ops = &rpmh_regulator_xob_ops,
+	/* LVS hardware does not support voltage or mode configuration. */
+};
+
+#define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
+{ \
+	.name		= _name, \
+	.resource_name	= _resource_name, \
+	.hw_data	= _hw_data, \
+	.supply_name	= _supply_name, \
+}
+
+static const struct rpmh_vreg_init_data pm8998_vreg_data[] = {
+	RPMH_VREG("smps1",  "smp%s1",  &pmic4_ftsmps426, "vdd-s1"),
+	RPMH_VREG("smps2",  "smp%s2",  &pmic4_ftsmps426, "vdd-s2"),
+	RPMH_VREG("smps3",  "smp%s3",  &pmic4_hfsmps3,   "vdd-s3"),
+	RPMH_VREG("smps4",  "smp%s4",  &pmic4_hfsmps3,   "vdd-s4"),
+	RPMH_VREG("smps5",  "smp%s5",  &pmic4_hfsmps3,   "vdd-s5"),
+	RPMH_VREG("smps6",  "smp%s6",  &pmic4_ftsmps426, "vdd-s6"),
+	RPMH_VREG("smps7",  "smp%s7",  &pmic4_ftsmps426, "vdd-s7"),
+	RPMH_VREG("smps8",  "smp%s8",  &pmic4_ftsmps426, "vdd-s8"),
+	RPMH_VREG("smps9",  "smp%s9",  &pmic4_ftsmps426, "vdd-s9"),
+	RPMH_VREG("smps10", "smp%s10", &pmic4_ftsmps426, "vdd-s10"),
+	RPMH_VREG("smps11", "smp%s11", &pmic4_ftsmps426, "vdd-s11"),
+	RPMH_VREG("smps12", "smp%s12", &pmic4_ftsmps426, "vdd-s12"),
+	RPMH_VREG("smps13", "smp%s13", &pmic4_ftsmps426, "vdd-s13"),
+	RPMH_VREG("ldo1",   "ldo%s1",  &pmic4_nldo,      "vdd-l1-l27"),
+	RPMH_VREG("ldo2",   "ldo%s2",  &pmic4_nldo,      "vdd-l2-l8-l17"),
+	RPMH_VREG("ldo3",   "ldo%s3",  &pmic4_nldo,      "vdd-l3-l11"),
+	RPMH_VREG("ldo4",   "ldo%s4",  &pmic4_nldo,      "vdd-l4-l5"),
+	RPMH_VREG("ldo5",   "ldo%s5",  &pmic4_nldo,      "vdd-l4-l5"),
+	RPMH_VREG("ldo6",   "ldo%s6",  &pmic4_pldo,      "vdd-l6"),
+	RPMH_VREG("ldo7",   "ldo%s7",  &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
+	RPMH_VREG("ldo8",   "ldo%s8",  &pmic4_nldo,      "vdd-l2-l8-l17"),
+	RPMH_VREG("ldo9",   "ldo%s9",  &pmic4_pldo,      "vdd-l9"),
+	RPMH_VREG("ldo10",  "ldo%s10", &pmic4_pldo,      "vdd-l10-l23-l25"),
+	RPMH_VREG("ldo11",  "ldo%s11", &pmic4_nldo,      "vdd-l3-l11"),
+	RPMH_VREG("ldo12",  "ldo%s12", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
+	RPMH_VREG("ldo13",  "ldo%s13", &pmic4_pldo,      "vdd-l13-l19-l21"),
+	RPMH_VREG("ldo14",  "ldo%s14", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
+	RPMH_VREG("ldo15",  "ldo%s15", &pmic4_pldo_lv,   "vdd-l7-l12-l14-l15"),
+	RPMH_VREG("ldo16",  "ldo%s16", &pmic4_pldo,      "vdd-l16-l28"),
+	RPMH_VREG("ldo17",  "ldo%s17", &pmic4_nldo,      "vdd-l2-l8-l17"),
+	RPMH_VREG("ldo18",  "ldo%s18", &pmic4_pldo,      "vdd-l18-l22"),
+	RPMH_VREG("ldo19",  "ldo%s19", &pmic4_pldo,      "vdd-l13-l19-l21"),
+	RPMH_VREG("ldo20",  "ldo%s20", &pmic4_pldo,      "vdd-l20-l24"),
+	RPMH_VREG("ldo21",  "ldo%s21", &pmic4_pldo,      "vdd-l13-l19-l21"),
+	RPMH_VREG("ldo22",  "ldo%s22", &pmic4_pldo,      "vdd-l18-l22"),
+	RPMH_VREG("ldo23",  "ldo%s23", &pmic4_pldo,      "vdd-l10-l23-l25"),
+	RPMH_VREG("ldo24",  "ldo%s24", &pmic4_pldo,      "vdd-l20-l24"),
+	RPMH_VREG("ldo25",  "ldo%s25", &pmic4_pldo,      "vdd-l10-l23-l25"),
+	RPMH_VREG("ldo26",  "ldo%s26", &pmic4_nldo,      "vdd-l26"),
+	RPMH_VREG("ldo27",  "ldo%s27", &pmic4_nldo,      "vdd-l1-l27"),
+	RPMH_VREG("ldo28",  "ldo%s28", &pmic4_pldo,      "vdd-l16-l28"),
+	RPMH_VREG("lvs1",   "vs%s1",   &pmic4_lvs,       "vin-lvs-1-2"),
+	RPMH_VREG("lvs2",   "vs%s2",   &pmic4_lvs,       "vin-lvs-1-2"),
+	{},
+};
+
+static const struct rpmh_vreg_init_data pmi8998_vreg_data[] = {
+	RPMH_VREG("bob",    "bob%s1",  &pmic4_bob,       "vdd-bob"),
+	{},
+};
+
+static const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
+	RPMH_VREG("smps1",  "smp%s1",  &pmic4_ftsmps426, "vdd-s1"),
+	RPMH_VREG("smps2",  "smp%s2",  &pmic4_ftsmps426, "vdd-s2"),
+	RPMH_VREG("smps3",  "smp%s3",  &pmic4_ftsmps426, "vdd-s3"),
+	RPMH_VREG("smps4",  "smp%s4",  &pmic4_ftsmps426, "vdd-s4"),
+	{},
+};
+
+static int rpmh_regulator_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	const struct rpmh_vreg_init_data *vreg_data;
+	struct device_node *node;
+	struct rpmh_vreg *vreg;
+	const char *pmic_id;
+	int ret;
+
+	ret = cmd_db_ready();
+	if (ret < 0) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "Command DB not available, ret=%d\n", ret);
+		return ret;
+	}
+
+	vreg_data = of_device_get_match_data(dev);
+	if (!vreg_data)
+		return -ENODEV;
+
+	ret = of_property_read_string(dev->of_node, "qcom,pmic-id", &pmic_id);
+	if (ret < 0) {
+		dev_err(dev, "qcom,pmic-id missing in DT node\n");
+		return ret;
+	}
+
+	for_each_available_child_of_node(dev->of_node, node) {
+		vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
+		if (!vreg) {
+			of_node_put(node);
+			return -ENOMEM;
+		}
+
+		ret = rpmh_regulator_init_vreg(vreg, dev, node, pmic_id,
+						vreg_data);
+		if (ret < 0) {
+			of_node_put(node);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct of_device_id rpmh_regulator_match_table[] = {
+	{
+		.compatible = "qcom,pm8998-rpmh-regulators",
+		.data = pm8998_vreg_data,
+	},
+	{
+		.compatible = "qcom,pmi8998-rpmh-regulators",
+		.data = pmi8998_vreg_data,
+	},
+	{
+		.compatible = "qcom,pm8005-rpmh-regulators",
+		.data = pm8005_vreg_data,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, rpmh_regulator_match_table);
+
+static struct platform_driver rpmh_regulator_driver = {
+	.driver = {
+		.name = "qcom-rpmh-regulator",
+		.of_match_table	= of_match_ptr(rpmh_regulator_match_table),
+	},
+	.probe = rpmh_regulator_probe,
+};
+module_platform_driver(rpmh_regulator_driver);
+
+MODULE_DESCRIPTION("Qualcomm RPMh regulator driver");
+MODULE_LICENSE("GPL v2");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH] ARM64: dts: meson-gxl-s905x-p212: Add phy-supply for usb0
From: Kevin Hilman @ 2018-06-08 23:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAFBinCCF7v40PrtL3HVf9X-fEVx7P2uOVePa5wQ_y6s7uLKmnw@mail.gmail.com>

Martin Blumenstingl <martin.blumenstingl@googlemail.com> writes:

> On Tue, Jun 5, 2018 at 10:52 AM, Neil Armstrong <narmstrong@baylibre.com> wrote:
>> Like LibreTech-CC, the USB0 needs the 5V regulator to be enabled to power the
>> devices on the P212 Reference Design based boards.
>>
>> Fixes: b9f07cb4f41f ("ARM64: dts: meson-gxl-s905x-p212: enable the USB controller")
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>
> Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>

Applied to v4.18/fixes (will queue for v4.18-rc).

Kevin

^ permalink raw reply

* [PATCH v2] ARM64: dts: meson: fix register ranges for SD/eMMC
From: Kevin Hilman @ 2018-06-08 23:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180605215937.16634-1-khilman@baylibre.com>

Kevin Hilman <khilman@baylibre.com> writes:

> Based on updated information from Amlogic, correct the register range
> for the SD/eMMC blocks to the right size.
>
> Reported-by: Yixun Lan <yixun.lan@amlogic.com>
> Tested-by: Yixun Lan <yixun.lan@amlogic.com>
> Signed-off-by: Kevin Hilman <khilman@baylibre.com>

Applied to v4.18/fixes,

Kevin

^ permalink raw reply

* [PATCH] ARM64: dts: meson-gx: fix ATF reserved memory region
From: Kevin Hilman @ 2018-06-08 23:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180607205514.36631-1-khilman@baylibre.com>

Kevin Hilman <khilman@baylibre.com> writes:

> Vendor firmware/uboot has different reserved regions depending on
> firmware version, but current codebase reserves the same regions on
> GXL and GXBB, so move the additional reserved memory region to common
> .dtsi.
>
> Found when putting a recent vendor u-boot on meson-gxbb-p200.
>
> Recommended-by: Neil Armstrong <narmstrong@baylibre.com>

oops, this should've been the more common "Suggested-by".  Fixed, and
then...

> Signed-off-by: Kevin Hilman <khilman@baylibre.com>

...added a Cc:stable and applied to v4.18/fixes.

Kevin

> ---
>  arch/arm64/boot/dts/amlogic/meson-gx.dtsi  | 6 ++++++
>  arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 8 --------
>  2 files changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> index b003f324ca31..b8dc4dbb391b 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> @@ -35,6 +35,12 @@
>  			no-map;
>  		};
>  
> +		/* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
> +		secmon_reserved_alt: secmon at 5000000 {
> +			reg = <0x0 0x05000000 0x0 0x300000>;
> +			no-map;
> +		};
> +
>  		linux,cma {
>  			compatible = "shared-dma-pool";
>  			reusable;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
> index 27538eea547b..c87a80e9bcc6 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
> @@ -13,14 +13,6 @@
>  / {
>  	compatible = "amlogic,meson-gxl";
>  
> -	reserved-memory {
> -		/* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
> -		secmon_reserved_alt: secmon at 5000000 {
> -			reg = <0x0 0x05000000 0x0 0x300000>;
> -			no-map;
> -		};
> -	};
> -
>  	soc {
>  		usb0: usb at c9000000 {
>  			status = "disabled";

^ permalink raw reply

* [PATCH 04/24] 32-bit userspace ABI: introduce ARCH_32BIT_OFF_T config option
From: Yury Norov @ 2018-06-09  7:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180608173207.nwoi25jee52gpdwy@armageddon.cambridge.arm.com>

On Fri, Jun 08, 2018 at 06:32:07PM +0100, Catalin Marinas wrote:
> On Wed, May 16, 2018 at 11:18:49AM +0300, Yury Norov wrote:
> > diff --git a/arch/Kconfig b/arch/Kconfig
> > index 76c0b54443b1..ee079244dc3c 100644
> > --- a/arch/Kconfig
> > +++ b/arch/Kconfig
> > @@ -264,6 +264,21 @@ config ARCH_THREAD_STACK_ALLOCATOR
> >  config ARCH_WANTS_DYNAMIC_TASK_STRUCT
> >  	bool
> >  
> > +config ARCH_32BIT_OFF_T
> > +	bool
> > +	depends on !64BIT
> > +	help
> > +	  All new 32-bit architectures should have 64-bit off_t type on
> > +	  userspace side which corresponds to the loff_t kernel type. This
> > +	  is the requirement for modern ABIs. Some existing architectures
> > +	  already have 32-bit off_t. This option is enabled for all such
> > +	  architectures explicitly. Namely: arc, arm, blackfin, cris, frv,
> > +	  h8300, hexagon, m32r, m68k, metag, microblaze, mips32, mn10300,
> > +	  nios2, openrisc, parisc32, powerpc32, score, sh, sparc, tile32,
> > +	  unicore32, x86_32 and xtensa. This is the complete list. Any
> > +	  new 32-bit architecture should declare 64-bit off_t type on user
> > +	  side and so should not enable this option.
> 
> Do you know if this is the case for riscv and nds32, merged in the
> meantime? If not, I suggest you drop this patch altogether and just
> define force_o_largefile() for arm64/ilp32 as we don't seem to stick to
> "all new 32-bit architectures should have 64-bit off_t".

I wrote this patch at request of Arnd Bergmann. This is actually his
words that all new 32-bit architectures should have 64-bit off_t. So
I was surprized when riscv was merged with 32-bit off_t (and I didn't
follow nds32).

If this rule is still in force, we'd better add new exceptions to this
patch. Otherwise, we can drop it.

Arnd, could you please comment it?

Yury

^ permalink raw reply

* [PATCH 04/24] 32-bit userspace ABI: introduce ARCH_32BIT_OFF_T config option
From: Yury Norov @ 2018-06-09  7:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <mhng-e1922456-a05b-46f9-8644-d45ad70a55e5@palmer-si-x1c4>

On Fri, Jun 08, 2018 at 03:33:51PM -0700, Palmer Dabbelt wrote:
> On Fri, 08 Jun 2018 10:32:07 PDT (-0700), catalin.marinas at arm.com wrote:
> > On Wed, May 16, 2018 at 11:18:49AM +0300, Yury Norov wrote:
> > > diff --git a/arch/Kconfig b/arch/Kconfig
> > > index 76c0b54443b1..ee079244dc3c 100644
> > > --- a/arch/Kconfig
> > > +++ b/arch/Kconfig
> > > @@ -264,6 +264,21 @@ config ARCH_THREAD_STACK_ALLOCATOR
> > >  config ARCH_WANTS_DYNAMIC_TASK_STRUCT
> > >  	bool
> > > 
> > > +config ARCH_32BIT_OFF_T
> > > +	bool
> > > +	depends on !64BIT
> > > +	help
> > > +	  All new 32-bit architectures should have 64-bit off_t type on
> > > +	  userspace side which corresponds to the loff_t kernel type. This
> > > +	  is the requirement for modern ABIs. Some existing architectures
> > > +	  already have 32-bit off_t. This option is enabled for all such
> > > +	  architectures explicitly. Namely: arc, arm, blackfin, cris, frv,
> > > +	  h8300, hexagon, m32r, m68k, metag, microblaze, mips32, mn10300,
> > > +	  nios2, openrisc, parisc32, powerpc32, score, sh, sparc, tile32,
> > > +	  unicore32, x86_32 and xtensa. This is the complete list. Any
> > > +	  new 32-bit architecture should declare 64-bit off_t type on user
> > > +	  side and so should not enable this option.
> > 
> > Do you know if this is the case for riscv and nds32, merged in the
> > meantime? If not, I suggest you drop this patch altogether and just
> > define force_o_largefile() for arm64/ilp32 as we don't seem to stick to
> > "all new 32-bit architectures should have 64-bit off_t".
> 
> We (RISC-V) don't have support for rv32i in glibc yet, so there really isn't
> a fixed ABI there yet.  From my understanding the rv32i port as it currently
> stands has a 32-bit off_t (via __kernel_off_t being defined as long), so
> this change would technically be a kernel ABI break.
> 
> Since we don't have rv32i glibc yet I'm not fundamentally opposed to an ABI
> break.  Is there a concrete advantage to this?

One obvious advantage is manipulating large files - if file is greater than
2G, you cannot easily mmap(), lseek() etc with 32-bit offset.

Another point is unification of layuots for structures like struct
stat between 32- and 64-bit worlds.

On glibc side it helps to unify 32-bit and 64-bit versions of syscalls.
Refer, for example this commit:
3c7f1f59cd161 (Consolidate lseek/lseek64/llseek implementations).

Yury

^ permalink raw reply

* [PATCH v2 2/6] arm64: KVM: Handle Set/Way CMOs as NOPs if FWB is present
From: Christoffer Dall @ 2018-06-09  9:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-3-marc.zyngier@arm.com>

On Wed, May 30, 2018 at 01:47:02PM +0100, Marc Zyngier wrote:
> Set/Way handling is one of the ugliest corners of KVM. We shouldn't
> have to handle that, but better safe than sorry.
> 
> Thankfully, FWB fixes this for us by not requiering any maintenance
> whatsoever, which means we don't have to emulate S/W CMOs, and don't
> have to track VM ops either.

I tiny bit of rationale here would have been nice.  As I understand it,
if we're presenting the guest with a fully coherent system, there should
never be a need to invalidate anything, because the guest will always
see the most recent value no matter how it sings and dances, right?

> 
> We still have to trap S/W though, if only to prevent the guest from
> doing something bad.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/kvm/sys_regs.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 6e3b969391fd..9a740f159245 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -195,7 +195,13 @@ static bool access_dcsw(struct kvm_vcpu *vcpu,
>  	if (!p->is_write)
>  		return read_from_write_only(vcpu, p, r);
>  
> -	kvm_set_way_flush(vcpu);
> +	/*
> +	 * Only track S/W ops if we don't have FWB. It still indicates
> +	 * that the guest is a bit broken...
> +	 */

Is it strictly true that the guest is broken if it does any form of S/W
ops?  Does the guest actually know that it's running on a fully coherent
system, or is the argument that no software, ever, should do S/W, even
for reboot etc.?

I think this should have slightly more info, or that part of the comment
should just be dropped, to avoid misleading future readers who don't
have the full picture.

> +	if (!cpus_have_const_cap(ARM64_HAS_STAGE2_FWB))
> +		kvm_set_way_flush(vcpu);
> +
>  	return true;
>  }
>  
> -- 
> 2.17.1
> 

Besides the usual nits on commentary:

Reviewed-by: Christoffer Dall <christoffer.dall@arm.com>

^ permalink raw reply

* [PATCH v2 3/6] arm64: KVM: Avoid marking pages as XN in Stage-2 if CTR_EL0.DIC is set
From: Christoffer Dall @ 2018-06-09  9:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-4-marc.zyngier@arm.com>

On Wed, May 30, 2018 at 01:47:03PM +0100, Marc Zyngier wrote:
> On systems where CTR_EL0.DIC is set, we don't need to perform
> icache invalidation to guarantee that we'll fetch the right
> instruction stream.
> 
> This also means that taking a permission fault to invalidate the
> icache is an unnecessary overhead.
> 
> On such systems, we can safely leave the page as being executable.
> 
> Acked-by: Catalin Marinas <catalin.marinas@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@arm.com>

> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/include/asm/pgtable-prot.h | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
> index c66c3047400e..78b942c1bea4 100644
> --- a/arch/arm64/include/asm/pgtable-prot.h
> +++ b/arch/arm64/include/asm/pgtable-prot.h
> @@ -77,8 +77,18 @@
>  		__val;							\
>  	 })
>  
> -#define PAGE_S2			__pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(NORMAL) | PTE_S2_RDONLY | PTE_S2_XN)
> -#define PAGE_S2_DEVICE		__pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(DEVICE_nGnRE) | PTE_S2_RDONLY | PTE_S2_XN)
> +#define PAGE_S2_XN							\
> +	({								\
> +		u64 __val;						\
> +		if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC))		\
> +			__val = 0;					\
> +		else							\
> +			__val = PTE_S2_XN;				\
> +		__val;							\
> +	})
> +
> +#define PAGE_S2			__pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(NORMAL) | PTE_S2_RDONLY | PAGE_S2_XN)
> +#define PAGE_S2_DEVICE		__pgprot(_PROT_DEFAULT | PAGE_S2_MEMATTR(DEVICE_nGnRE) | PTE_S2_RDONLY | PAGE_S2_XN)
>  
>  #define PAGE_NONE		__pgprot(((_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN)
>  #define PAGE_SHARED		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE)
> -- 
> 2.17.1
> 

^ permalink raw reply

* [PATCH v2 4/6] KVM: arm/arm64: Consolidate page-table accessors
From: Christoffer Dall @ 2018-06-09  9:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-5-marc.zyngier@arm.com>

On Wed, May 30, 2018 at 01:47:04PM +0100, Marc Zyngier wrote:
> The arm and arm64 KVM page tables accessors are pointlessly different
> between the two architectures, and likely both wrong one way or another:
> arm64 lacks a dsb(), and arm doesn't use WRITE_ONCE.
> 
> Let's unify them.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm/include/asm/kvm_mmu.h   | 12 -----------
>  arch/arm64/include/asm/kvm_mmu.h |  3 ---
>  virt/kvm/arm/mmu.c               | 35 ++++++++++++++++++++++++++++----
>  3 files changed, 31 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
> index 707a1f06dc5d..468ff945efa0 100644
> --- a/arch/arm/include/asm/kvm_mmu.h
> +++ b/arch/arm/include/asm/kvm_mmu.h
> @@ -75,18 +75,6 @@ phys_addr_t kvm_get_idmap_vector(void);
>  int kvm_mmu_init(void);
>  void kvm_clear_hyp_idmap(void);
>  
> -static inline void kvm_set_pmd(pmd_t *pmd, pmd_t new_pmd)
> -{
> -	*pmd = new_pmd;
> -	dsb(ishst);
> -}
> -
> -static inline void kvm_set_pte(pte_t *pte, pte_t new_pte)
> -{
> -	*pte = new_pte;
> -	dsb(ishst);
> -}
> -
>  static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
>  {
>  	pte_val(pte) |= L_PTE_S2_RDWR;
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index 9dbca5355029..26c89b63f604 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -170,9 +170,6 @@ phys_addr_t kvm_get_idmap_vector(void);
>  int kvm_mmu_init(void);
>  void kvm_clear_hyp_idmap(void);
>  
> -#define	kvm_set_pte(ptep, pte)		set_pte(ptep, pte)
> -#define	kvm_set_pmd(pmdp, pmd)		set_pmd(pmdp, pmd)
> -
>  static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
>  {
>  	pte_val(pte) |= PTE_S2_RDWR;
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index ba66bf7ae299..c9ed239c0840 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -177,6 +177,33 @@ static void clear_stage2_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr
>  	put_page(virt_to_page(pmd));
>  }
>  
> +static inline void kvm_set_pte(pte_t *ptep, pte_t new_pte)
> +{
> +	WRITE_ONCE(*ptep, new_pte);
> +	dsb(ishst);
> +}
> +
> +static inline void kvm_set_pmd(pmd_t *pmdp, pmd_t new_pmd)
> +{
> +	WRITE_ONCE(*pmdp, new_pmd);
> +	dsb(ishst);
> +}
> +

arm64 set_pte and set_pmd have an isb() in addition to the dsb(), why
can we let go of that here?

> +static inline void kvm_pmd_populate(pmd_t *pmdp, pte_t *ptep)
> +{
> +	pmd_populate_kernel(NULL, pmdp, ptep);
> +}
> +
> +static inline void kvm_pud_populate(pud_t *pudp, pmd_t *pmdp)
> +{
> +	pud_populate(NULL, pudp, pmdp);
> +}
> +
> +static inline void kvm_pgd_populate(pgd_t *pgdp, pud_t *pudp)
> +{
> +	pgd_populate(NULL, pgdp, pudp);
> +}
> +
>  /*
>   * Unmapping vs dcache management:
>   *
> @@ -603,7 +630,7 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
>  				kvm_err("Cannot allocate Hyp pte\n");
>  				return -ENOMEM;
>  			}
> -			pmd_populate_kernel(NULL, pmd, pte);
> +			kvm_pmd_populate(pmd, pte);
>  			get_page(virt_to_page(pmd));
>  			kvm_flush_dcache_to_poc(pmd, sizeof(*pmd));
>  		}
> @@ -636,7 +663,7 @@ static int create_hyp_pud_mappings(pgd_t *pgd, unsigned long start,
>  				kvm_err("Cannot allocate Hyp pmd\n");
>  				return -ENOMEM;
>  			}
> -			pud_populate(NULL, pud, pmd);
> +			kvm_pud_populate(pud, pmd);
>  			get_page(virt_to_page(pud));
>  			kvm_flush_dcache_to_poc(pud, sizeof(*pud));
>  		}
> @@ -673,7 +700,7 @@ static int __create_hyp_mappings(pgd_t *pgdp, unsigned long ptrs_per_pgd,
>  				err = -ENOMEM;
>  				goto out;
>  			}
> -			pgd_populate(NULL, pgd, pud);
> +			kvm_pgd_populate(pgd, pud);
>  			get_page(virt_to_page(pgd));
>  			kvm_flush_dcache_to_poc(pgd, sizeof(*pgd));
>  		}
> @@ -1092,7 +1119,7 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
>  		if (!cache)
>  			return 0; /* ignore calls from kvm_set_spte_hva */
>  		pte = mmu_memory_cache_alloc(cache);
> -		pmd_populate_kernel(NULL, pmd, pte);
> +		kvm_pmd_populate(pmd, pte);
>  		get_page(virt_to_page(pmd));
>  	}
>  
> -- 
> 2.17.1
> 

Otherwise:

Acked-by: Christoffer Dall <christoffer.dall@arm.com>

^ permalink raw reply

* [PATCH v2 5/6] KVM: arm/arm64: Stop using {pmd,pud,pgd}_populate
From: Christoffer Dall @ 2018-06-09  9:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-6-marc.zyngier@arm.com>

On Wed, May 30, 2018 at 01:47:05PM +0100, Marc Zyngier wrote:
> The {pmd,pud,pgd}_populate accessors usage in the kernel have always
> been a bit weird in KVM. We don't have a struct mm to pass (and
> neither does the kernel most of the time, but still...), and
> the 32bit code has all kind of cache maintenance that doesn't make
> sense on ARMv7+ when MP extensions are mandatory (which is the
> case when the VEs are present).
> 
> Let's bite the bullet and provide our own implementations. The
> only bit of architectural code left has to do with building the table
> entry itself (arm64 having up to 52bit PA, arm lacking PUD level).
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@arm.com>

> ---
>  arch/arm/include/asm/kvm_mmu.h   | 4 ++++
>  arch/arm64/include/asm/kvm_mmu.h | 7 +++++++
>  virt/kvm/arm/mmu.c               | 8 +++++---
>  3 files changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
> index 468ff945efa0..a94ef9833bd3 100644
> --- a/arch/arm/include/asm/kvm_mmu.h
> +++ b/arch/arm/include/asm/kvm_mmu.h
> @@ -75,6 +75,10 @@ phys_addr_t kvm_get_idmap_vector(void);
>  int kvm_mmu_init(void);
>  void kvm_clear_hyp_idmap(void);
>  
> +#define kvm_mk_pmd(ptep)	__pmd(__pa(ptep) | PMD_TYPE_TABLE)
> +#define kvm_mk_pud(pmdp)	__pud(__pa(pmdp) | PMD_TYPE_TABLE)
> +#define kvm_mk_pgd(pudp)	({ BUILD_BUG(); 0; })
> +
>  static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
>  {
>  	pte_val(pte) |= L_PTE_S2_RDWR;
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index 26c89b63f604..22c9f7cfdf93 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -170,6 +170,13 @@ phys_addr_t kvm_get_idmap_vector(void);
>  int kvm_mmu_init(void);
>  void kvm_clear_hyp_idmap(void);
>  
> +#define kvm_mk_pmd(ptep)					\
> +	__pmd(__phys_to_pmd_val(__pa(ptep) | PMD_TYPE_TABLE))
> +#define kvm_mk_pud(pmdp)					\
> +	__pud(__phys_to_pud_val(__pa(pmdp) | PMD_TYPE_TABLE))
> +#define kvm_mk_pgd(pudp)					\
> +	__pgd(__phys_to_pgd_val(__pa(pudp) | PUD_TYPE_TABLE))
> +
>  static inline pte_t kvm_s2pte_mkwrite(pte_t pte)
>  {
>  	pte_val(pte) |= PTE_S2_RDWR;
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index c9ed239c0840..ad1980d2118a 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -191,17 +191,19 @@ static inline void kvm_set_pmd(pmd_t *pmdp, pmd_t new_pmd)
>  
>  static inline void kvm_pmd_populate(pmd_t *pmdp, pte_t *ptep)
>  {
> -	pmd_populate_kernel(NULL, pmdp, ptep);
> +	kvm_set_pmd(pmdp, kvm_mk_pmd(ptep));
>  }
>  
>  static inline void kvm_pud_populate(pud_t *pudp, pmd_t *pmdp)
>  {
> -	pud_populate(NULL, pudp, pmdp);
> +	WRITE_ONCE(*pudp, kvm_mk_pud(pmdp));
> +	dsb(ishst);
>  }
>  
>  static inline void kvm_pgd_populate(pgd_t *pgdp, pud_t *pudp)
>  {
> -	pgd_populate(NULL, pgdp, pudp);
> +	WRITE_ONCE(*pgdp, kvm_mk_pgd(pudp));
> +	dsb(ishst);
>  }
>  
>  /*
> -- 
> 2.17.1
> 

^ permalink raw reply

* [PATCH v2 6/6] KVM: arm/arm64: Remove unnecessary CMOs when creating HYP page tables
From: Christoffer Dall @ 2018-06-09  9:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180530124706.25284-7-marc.zyngier@arm.com>

On Wed, May 30, 2018 at 01:47:06PM +0100, Marc Zyngier wrote:
> There is no need to perform cache maintenance operations when
> creating the HYP page tables if we have the multiprocessing
> extensions. ARMv7 mandates them with the virtualization support,
> and ARMv8 just mandates them unconditionally.
> 
> Let's remove these operations.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@arm.com>

> ---
>  virt/kvm/arm/mmu.c | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
> index ad1980d2118a..ccdf544d44c0 100644
> --- a/virt/kvm/arm/mmu.c
> +++ b/virt/kvm/arm/mmu.c
> @@ -607,7 +607,6 @@ static void create_hyp_pte_mappings(pmd_t *pmd, unsigned long start,
>  		pte = pte_offset_kernel(pmd, addr);
>  		kvm_set_pte(pte, pfn_pte(pfn, prot));
>  		get_page(virt_to_page(pte));
> -		kvm_flush_dcache_to_poc(pte, sizeof(*pte));
>  		pfn++;
>  	} while (addr += PAGE_SIZE, addr != end);
>  }
> @@ -634,7 +633,6 @@ static int create_hyp_pmd_mappings(pud_t *pud, unsigned long start,
>  			}
>  			kvm_pmd_populate(pmd, pte);
>  			get_page(virt_to_page(pmd));
> -			kvm_flush_dcache_to_poc(pmd, sizeof(*pmd));
>  		}
>  
>  		next = pmd_addr_end(addr, end);
> @@ -667,7 +665,6 @@ static int create_hyp_pud_mappings(pgd_t *pgd, unsigned long start,
>  			}
>  			kvm_pud_populate(pud, pmd);
>  			get_page(virt_to_page(pud));
> -			kvm_flush_dcache_to_poc(pud, sizeof(*pud));
>  		}
>  
>  		next = pud_addr_end(addr, end);
> @@ -704,7 +701,6 @@ static int __create_hyp_mappings(pgd_t *pgdp, unsigned long ptrs_per_pgd,
>  			}
>  			kvm_pgd_populate(pgd, pud);
>  			get_page(virt_to_page(pgd));
> -			kvm_flush_dcache_to_poc(pgd, sizeof(*pgd));
>  		}
>  
>  		next = pgd_addr_end(addr, end);
> -- 
> 2.17.1
> 

^ permalink raw reply

* [PATCH] KVM: arm/arm64: drop resource size check for GICV window
From: Christoffer Dall @ 2018-06-09 10:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180601150628.10111-1-ard.biesheuvel@linaro.org>

On Fri, Jun 01, 2018 at 05:06:28PM +0200, Ard Biesheuvel wrote:
> When booting a 64 KB pages kernel on a ACPI GICv3 system that
> implements support for v2 emulation, the following warning is
> produced
> 
>   GICV size 0x2000 not a multiple of page size 0x10000
> 
> and support for v2 emulation is disabled, preventing GICv2 VMs
> from being able to run on such hosts.
> 
> The reason is that vgic_v3_probe() performs a sanity check on the
> size of the window (it should be a multiple of the page size),
> while the ACPI MADT parsing code hardcodes the size of the window
> to 8 KB. This makes sense, considering that ACPI does not bother
> to describe the size in the first place, under the assumption that
> platforms implementing ACPI will follow the architecture and not
> put anything else in the same 64 KB window.

Does the architecture actually say that anywhere?

> 
> So let's just drop the sanity check altogether, and assume that
> the window is at least 64 KB in size.

This could obviously be dangerous if broken systems actually exist.
Marc may know more about that than me.  An alternative would be to
modify the ACPI code to assume max(8 KB, page size) instead, and/or a
command line parameter to override this check.

That said, I'm not directly opposed to this patch, but I'll let Marc
have a look as well.

Thanks,
-Christoffer

> 
> Fixes: 909777324588 ("KVM: arm/arm64: vgic-new: vgic_init: implement kvm_vgic_hyp_init")
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  virt/kvm/arm/vgic/vgic-v3.c | 5 -----
>  1 file changed, 5 deletions(-)
> 
> diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
> index bdcf8e7a6161..72fc688c3e9d 100644
> --- a/virt/kvm/arm/vgic/vgic-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-v3.c
> @@ -552,11 +552,6 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
>  		pr_warn("GICV physical address 0x%llx not page aligned\n",
>  			(unsigned long long)info->vcpu.start);
>  		kvm_vgic_global_state.vcpu_base = 0;
> -	} else if (!PAGE_ALIGNED(resource_size(&info->vcpu))) {
> -		pr_warn("GICV size 0x%llx not a multiple of page size 0x%lx\n",
> -			(unsigned long long)resource_size(&info->vcpu),
> -			PAGE_SIZE);
> -		kvm_vgic_global_state.vcpu_base = 0;
>  	} else {
>  		kvm_vgic_global_state.vcpu_base = info->vcpu.start;
>  		kvm_vgic_global_state.can_emulate_gicv2 = true;
> -- 
> 2.17.0
> 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox