All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFCv2 0/2] Representing interrupt affinity in devicetree
@ 2012-12-13 16:49 ` Mark Rutland
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Rutland @ 2012-12-13 16:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: Mark Rutland, Lorenzo.Pieralisi, benh, devicetree-discuss,
	Will.Deacon, rob.herring, grant.likely, tglx

[This is an updated version of my previous RFC, which can be found at
http://lists.infradead.org/pipermail/linux-arm-kernel/2012-October/128205.html]

Current devicetree bindings for devices which use cpu-affine shared interrupts
assume that interrupts are listed in ascending order of physical cpu id
(MPIDR.Aff{2,1,0}). This is problematic for drivers because:

(1) The driver must convert each physical id to a logical id for the purpose of
    managing interrupts.

(2) In multi-cluster systems the physical ids are not necessarily contiguous,
    and drivers cannot simply iterate over ids from 0 to NR_CPUS.

(3) It is not possible to specify sets of interrupts which are wired to a
    subset of cpus (i.e. clusters) not starting at physical id 0, as we can't
    specify which cpu to start from, and can't skip cpus. This makes it
    impossible to represent some devices (e.g. cpu PMUs) which may not exist
    in the first cluster.

(4) Some devices may either be wired with PPIs or SPIs. It is not possible to
    differentiate the two cases in general from the interrupts list (e.g. when
    a device has multiple PPIs wired to all cpus).

To represent the general case, we require a mechanism to describe the cpu
affinity of a device, and a consistent way to map each interrupt to a cpu (or
set of cpus). So far, the only workable mechanism I've been able to come up
with is the following:

In addition to the interrupts list we add an optional 'interrupts-affinity'
list which describes how to map an interrupt to cpu(s). Each interrupt would
have a corresponding element in the interrupts-affinity list.

Each element consists of a pair of cells specifying how to test if a cpu is
affine. This test specification consists of a most significant affinity level
to match, and values for the MPIDR affinity bits down to this level. Each pair
of cells has the form:

    < N 0x00AABBCC >
       \   \ \ \ \__ MPIDR.Aff0
        \   \ \ \___ MPIDR.Aff1
         \   \ \____ MPIDR.Aff2
          \   \_____ [must be zero]
           \________ level-specifier

The level-specifier is in the range [0-3]. When the value is 3, MPIDR affinity
levels 2,1,0 are ignored, and thus all cpus are matched. When the value is 0,
levels 2,1,0 must all be matched for a cpu to be considered affine. Affinity
bits which are not to be matched should be set to zero.

In practice, use of the binding would look something like:

> device@0 {
> 	compatible = "example,example-affine-device";
> 	interrupts = <0 130 4>,
> 	             <0 131 4>,
> 	             <1 12 4>;
> 	interrupts-affinity = <0 0x00000000>,
>	                      <0 0x00000001>,
> 	                      <1 0x00000100>;
> };

To request/free interrupts, drivers would walk over all interrupts, and request
the affine cpu(s), which can be automatically mapped to logical ids by common
code. This fixes issues 1, 2, and 3. 4 is partially solved, in that we know
whether an interrupt is targeted at a single cpu or multiple cpus (i.e.
whether it's an SPI or a PPI), but we can't differentiate multiple interrupts
targeted at the same cpu. We could solve this with an additional
"interrupt-names" property, or something of that sort.

The following patches implement common code that could be used by drivers to
deal with this affinity information, allowing drivers to extract a (logical)
cpumask specifying the affinity of each interrupt, and additional information
specifying whether an interrupt targets multiple cpus.

The patches are based on rmk's for-next branch.

Any thoughts?

Thanks,
Mark.

Mark Rutland (2):
  of: add of_property_read_u32_index
  ARM: add functions to parse irq affinity from dt

 arch/arm/include/asm/dt_irq.h |    9 ++++
 arch/arm/kernel/devtree.c     |   91 +++++++++++++++++++++++++++++++++++++++++
 drivers/of/base.c             |   36 ++++++++++++++++
 include/linux/of.h            |   11 +++++
 4 files changed, 147 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/dt_irq.h

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFCv2 0/2] Representing interrupt affinity in devicetree
@ 2012-12-13 16:49 ` Mark Rutland
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Rutland @ 2012-12-13 16:49 UTC (permalink / raw)
  To: linux-arm-kernel

[This is an updated version of my previous RFC, which can be found at
http://lists.infradead.org/pipermail/linux-arm-kernel/2012-October/128205.html]

Current devicetree bindings for devices which use cpu-affine shared interrupts
assume that interrupts are listed in ascending order of physical cpu id
(MPIDR.Aff{2,1,0}). This is problematic for drivers because:

(1) The driver must convert each physical id to a logical id for the purpose of
    managing interrupts.

(2) In multi-cluster systems the physical ids are not necessarily contiguous,
    and drivers cannot simply iterate over ids from 0 to NR_CPUS.

(3) It is not possible to specify sets of interrupts which are wired to a
    subset of cpus (i.e. clusters) not starting at physical id 0, as we can't
    specify which cpu to start from, and can't skip cpus. This makes it
    impossible to represent some devices (e.g. cpu PMUs) which may not exist
    in the first cluster.

(4) Some devices may either be wired with PPIs or SPIs. It is not possible to
    differentiate the two cases in general from the interrupts list (e.g. when
    a device has multiple PPIs wired to all cpus).

To represent the general case, we require a mechanism to describe the cpu
affinity of a device, and a consistent way to map each interrupt to a cpu (or
set of cpus). So far, the only workable mechanism I've been able to come up
with is the following:

In addition to the interrupts list we add an optional 'interrupts-affinity'
list which describes how to map an interrupt to cpu(s). Each interrupt would
have a corresponding element in the interrupts-affinity list.

Each element consists of a pair of cells specifying how to test if a cpu is
affine. This test specification consists of a most significant affinity level
to match, and values for the MPIDR affinity bits down to this level. Each pair
of cells has the form:

    < N 0x00AABBCC >
       \   \ \ \ \__ MPIDR.Aff0
        \   \ \ \___ MPIDR.Aff1
         \   \ \____ MPIDR.Aff2
          \   \_____ [must be zero]
           \________ level-specifier

The level-specifier is in the range [0-3]. When the value is 3, MPIDR affinity
levels 2,1,0 are ignored, and thus all cpus are matched. When the value is 0,
levels 2,1,0 must all be matched for a cpu to be considered affine. Affinity
bits which are not to be matched should be set to zero.

In practice, use of the binding would look something like:

> device at 0 {
> 	compatible = "example,example-affine-device";
> 	interrupts = <0 130 4>,
> 	             <0 131 4>,
> 	             <1 12 4>;
> 	interrupts-affinity = <0 0x00000000>,
>	                      <0 0x00000001>,
> 	                      <1 0x00000100>;
> };

To request/free interrupts, drivers would walk over all interrupts, and request
the affine cpu(s), which can be automatically mapped to logical ids by common
code. This fixes issues 1, 2, and 3. 4 is partially solved, in that we know
whether an interrupt is targeted at a single cpu or multiple cpus (i.e.
whether it's an SPI or a PPI), but we can't differentiate multiple interrupts
targeted at the same cpu. We could solve this with an additional
"interrupt-names" property, or something of that sort.

The following patches implement common code that could be used by drivers to
deal with this affinity information, allowing drivers to extract a (logical)
cpumask specifying the affinity of each interrupt, and additional information
specifying whether an interrupt targets multiple cpus.

The patches are based on rmk's for-next branch.

Any thoughts?

Thanks,
Mark.

Mark Rutland (2):
  of: add of_property_read_u32_index
  ARM: add functions to parse irq affinity from dt

 arch/arm/include/asm/dt_irq.h |    9 ++++
 arch/arm/kernel/devtree.c     |   91 +++++++++++++++++++++++++++++++++++++++++
 drivers/of/base.c             |   36 ++++++++++++++++
 include/linux/of.h            |   11 +++++
 4 files changed, 147 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/dt_irq.h

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFCv2 1/2] of: add of_property_read_u32_index
  2012-12-13 16:49 ` Mark Rutland
@ 2012-12-13 16:49     ` Mark Rutland
  -1 siblings, 0 replies; 14+ messages in thread
From: Mark Rutland @ 2012-12-13 16:49 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Will.Deacon-5wv7dgnIgG8, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ

Currently, we have to pre-allocate an array when reading multiple u32
values from a property using of_property_read_u32_array. This isn't very
good for times when we want to iterate over elements of a list of
arbitrary size.

This patch adds a function to read a single u32 value from an arbitrary
index in a list, making this case easier.

Signed-off-by: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
---
 drivers/of/base.c  |   36 ++++++++++++++++++++++++++++++++++++
 include/linux/of.h |   11 +++++++++++
 2 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index af3b22a..5ad6830 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -707,6 +707,42 @@ int of_property_read_u32_array(const struct device_node *np,
 EXPORT_SYMBOL_GPL(of_property_read_u32_array);
 
 /**
+ * of_property_read_u32_index - Find and read a 32 bit integer from a multiple
+ * integer property.
+ *
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @out_value:	pointer to return value, modified only if return value is 0.
+ * @index:	index of the integer in the list of integers.
+ *
+ * Search for a property in a device node and read a 32-bit value from
+ * it. Returns 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * index is beyond the range of data.
+ *
+ * The out_value is modified only if a valid u32 value can be decoded.
+ */
+int of_property_read_u32_index(const struct device_node *np,
+			       const char *propname, u32 *out_value,
+			       int idx)
+{
+	struct property *prop = of_find_property(np, propname, NULL);
+	const __be32 *val;
+
+	if (!prop)
+		return -EINVAL;
+	if (!prop->value)
+		return -ENODATA;
+	if ((idx+1) * sizeof(*out_value) > prop->length)
+		return -EOVERFLOW;
+
+	val = prop->value;
+	*out_value = be32_to_cpup(val + idx);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_property_read_u32_index);
+
+/**
  * of_property_read_u64 - Find and read a 64 bit integer from a property
  * @np:		device node from which the property value is to be read.
  * @propname:	name of the property to be searched.
diff --git a/include/linux/of.h b/include/linux/of.h
index b4e50d5..37f6f67 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -227,6 +227,10 @@ extern int of_property_read_u32_array(const struct device_node *np,
 				      const char *propname,
 				      u32 *out_values,
 				      size_t sz);
+extern int of_property_read_u32_index(const struct device_node *np,
+				      const char *propname,
+				      u32 *out_value,
+				      int idx);
 extern int of_property_read_u64(const struct device_node *np,
 				const char *propname, u64 *out_value);
 
@@ -371,6 +375,13 @@ static inline int of_property_read_u32_array(const struct device_node *np,
 	return -ENOSYS;
 }
 
+static inline int of_property_read_u32_index(const struct device_node *np,
+					     const char *propname,
+					     u32 *out_value, int idx)
+{
+	return -ENOSYS;
+}
+
 static inline int of_property_read_string(struct device_node *np,
 					  const char *propname,
 					  const char **out_string)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFCv2 1/2] of: add of_property_read_u32_index
@ 2012-12-13 16:49     ` Mark Rutland
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Rutland @ 2012-12-13 16:49 UTC (permalink / raw)
  To: linux-arm-kernel

Currently, we have to pre-allocate an array when reading multiple u32
values from a property using of_property_read_u32_array. This isn't very
good for times when we want to iterate over elements of a list of
arbitrary size.

This patch adds a function to read a single u32 value from an arbitrary
index in a list, making this case easier.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
 drivers/of/base.c  |   36 ++++++++++++++++++++++++++++++++++++
 include/linux/of.h |   11 +++++++++++
 2 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index af3b22a..5ad6830 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -707,6 +707,42 @@ int of_property_read_u32_array(const struct device_node *np,
 EXPORT_SYMBOL_GPL(of_property_read_u32_array);
 
 /**
+ * of_property_read_u32_index - Find and read a 32 bit integer from a multiple
+ * integer property.
+ *
+ * @np:		device node from which the property value is to be read.
+ * @propname:	name of the property to be searched.
+ * @out_value:	pointer to return value, modified only if return value is 0.
+ * @index:	index of the integer in the list of integers.
+ *
+ * Search for a property in a device node and read a 32-bit value from
+ * it. Returns 0 on success, -EINVAL if the property does not exist,
+ * -ENODATA if property does not have a value, and -EOVERFLOW if the
+ * index is beyond the range of data.
+ *
+ * The out_value is modified only if a valid u32 value can be decoded.
+ */
+int of_property_read_u32_index(const struct device_node *np,
+			       const char *propname, u32 *out_value,
+			       int idx)
+{
+	struct property *prop = of_find_property(np, propname, NULL);
+	const __be32 *val;
+
+	if (!prop)
+		return -EINVAL;
+	if (!prop->value)
+		return -ENODATA;
+	if ((idx+1) * sizeof(*out_value) > prop->length)
+		return -EOVERFLOW;
+
+	val = prop->value;
+	*out_value = be32_to_cpup(val + idx);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_property_read_u32_index);
+
+/**
  * of_property_read_u64 - Find and read a 64 bit integer from a property
  * @np:		device node from which the property value is to be read.
  * @propname:	name of the property to be searched.
diff --git a/include/linux/of.h b/include/linux/of.h
index b4e50d5..37f6f67 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -227,6 +227,10 @@ extern int of_property_read_u32_array(const struct device_node *np,
 				      const char *propname,
 				      u32 *out_values,
 				      size_t sz);
+extern int of_property_read_u32_index(const struct device_node *np,
+				      const char *propname,
+				      u32 *out_value,
+				      int idx);
 extern int of_property_read_u64(const struct device_node *np,
 				const char *propname, u64 *out_value);
 
@@ -371,6 +375,13 @@ static inline int of_property_read_u32_array(const struct device_node *np,
 	return -ENOSYS;
 }
 
+static inline int of_property_read_u32_index(const struct device_node *np,
+					     const char *propname,
+					     u32 *out_value, int idx)
+{
+	return -ENOSYS;
+}
+
 static inline int of_property_read_string(struct device_node *np,
 					  const char *propname,
 					  const char **out_string)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFCv2 2/2] ARM: add functions to parse irq affinity from dt
  2012-12-13 16:49 ` Mark Rutland
@ 2012-12-13 16:49     ` Mark Rutland
  -1 siblings, 0 replies; 14+ messages in thread
From: Mark Rutland @ 2012-12-13 16:49 UTC (permalink / raw)
  To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Will.Deacon-5wv7dgnIgG8, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ

This patch adds functions to handle parsing the CPU affinity of
interrupts from devicetree, based on an "interrupts-affinity" parameter
list. It is assumed that drivers which may optionally use this parameter
implement their own fallback behaviour.

The patch adds:
* arm_dt_has_irq_affinity : returns whether or not a device_node has
  interrupts-affinity information
* arm_dt_affine_irq_is_single : returns whether an interrupt targets a single
  CPU (i.e. is an SPI) or multiple CPUs (i.e. is a PPI). This test is
  independent of the number of affine CPUs we can logically map.
* arm_dt_irq_get_affinity : fills a cpumask with the CPUs an interrupt is
  affine to.

The "interrupts-affinity" property consists of a list of pairs of cells
specifying how to test if a CPU is affine. This test specification consists of
a most significant affinity level to match, and values for the MPIDR affinity
bits down to this level. Each pair of cells has the form:

	< N 0x00AABBCC >
	   \   \ \ \ \__ MPIDR.Aff0
	    \   \ \ \___ MPIDR.Aff1
	     \   \ \____ MPIDR.Aff2
	      \   \_____ [must be zero]
	       \________ level-specifier

The level-specifier is in the range [0-3]. When the value is 3, MPIDR
affinity levels 2,1,0 are ignored, and all CPUs are matched. Affinity
bits which are not to be matched should be set to zero.

Signed-off-by: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>
---
 arch/arm/include/asm/dt_irq.h |    9 ++++
 arch/arm/kernel/devtree.c     |   91 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/dt_irq.h

diff --git a/arch/arm/include/asm/dt_irq.h b/arch/arm/include/asm/dt_irq.h
new file mode 100644
index 0000000..431eeda
--- /dev/null
+++ b/arch/arm/include/asm/dt_irq.h
@@ -0,0 +1,9 @@
+#ifndef ARM_ASM_DT_IRQ_H
+#define ARM_ASM_DT_IRQ_H
+
+bool arm_dt_has_irq_affinity(struct device_node *node);
+bool arm_dt_affine_irq_is_single(struct device_node *node, int idx);
+int arm_dt_irq_get_affinity(struct device_node *node, int idx,
+			    cpumask_t *mask);
+
+#endif /* ARM_ASM_DT_IRQ_H */
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index 70f1bde..65d5052 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -20,6 +20,7 @@
 #include <linux/of_platform.h>
 
 #include <asm/cputype.h>
+#include <asm/dt_irq.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 #include <asm/smp_plat.h>
@@ -165,6 +166,96 @@ void __init arm_dt_init_cpu_maps(void)
 	}
 }
 
+#define PROP_IRQ_AFFINITY	"interrupts-affinity"
+#define AFFINE_LEVEL_IDX(i)	(2*(i))
+#define AFFINE_MPIDR_IDX(i)	(2*(i) + 1)
+
+/*
+ * Check whether the device has irq affinity information.
+ * Allows drivers to fall back to current behaviour with a single check.
+ */
+bool arm_dt_has_irq_affinity(struct device_node *node)
+{
+	return of_find_property(node, PROP_IRQ_AFFINITY, NULL) != NULL;
+}
+
+/*
+ * Check whether an irq with affinity information is a single cpu
+ * interrupt (rather than percpu). The node paramenter should be
+ * checked with arm_dt_has_irq_affinity first.
+ */
+bool arm_dt_affine_irq_is_single(struct device_node *node, int idx)
+{
+	u32 level;
+	of_property_read_u32_index(node, PROP_IRQ_AFFINITY, &level,
+				   AFFINE_LEVEL_IDX(idx));
+	return level == 0;
+}
+
+struct affine_match_spec {
+	u32 level;
+	u32 aff;
+};
+
+static bool arm_dt_affine_mpidr_match(u32 mpidr, struct affine_match_spec *match)
+{
+	u32 mask = 0xFFFFFFFF << (8*(match->level));
+	return (mpidr & mask) == (match->aff & mask);
+}
+
+static int arm_dt_irq_read_match(struct device_node *node, int idx,
+				 struct affine_match_spec *match)
+{
+	int ret;
+	if (!node)
+		return -EINVAL;
+
+	ret = of_property_read_u32_index(node, PROP_IRQ_AFFINITY, &match->aff,
+					 AFFINE_MPIDR_IDX(idx));
+	if (ret)
+		return ret;
+
+	ret = of_property_read_u32_index(node, PROP_IRQ_AFFINITY, &match->level,
+					 AFFINE_LEVEL_IDX(idx));
+	if (ret)
+		return ret;
+
+	/*
+	 * To match all cpus regardless of Aff{2,1,0}, we match at the
+	 * nonexistent Aff3.
+	 */
+	if (match->level > 3)
+		return -EINVAL;
+
+	return ret;
+
+}
+
+/*
+ * Get the set of possible cpus that an interrupt at idx is affine to.
+ */
+int arm_dt_irq_get_affinity(struct device_node *node, int idx,
+			    cpumask_t *mask)
+{
+	int i, ret;
+	struct affine_match_spec match;
+	u32 mpidr;
+
+	ret = arm_dt_irq_read_match(node, idx, &match);
+	if (ret)
+		return ret;
+
+	cpumask_clear(mask);
+
+	for_each_possible_cpu(i) {
+		mpidr = cpu_logical_map(i);
+		if (arm_dt_affine_mpidr_match(mpidr, &match))
+			cpumask_set_cpu(i, mask);
+	}
+
+	return 0;
+}
+
 /**
  * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
  * @dt_phys: physical address of dt blob
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFCv2 2/2] ARM: add functions to parse irq affinity from dt
@ 2012-12-13 16:49     ` Mark Rutland
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Rutland @ 2012-12-13 16:49 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds functions to handle parsing the CPU affinity of
interrupts from devicetree, based on an "interrupts-affinity" parameter
list. It is assumed that drivers which may optionally use this parameter
implement their own fallback behaviour.

The patch adds:
* arm_dt_has_irq_affinity : returns whether or not a device_node has
  interrupts-affinity information
* arm_dt_affine_irq_is_single : returns whether an interrupt targets a single
  CPU (i.e. is an SPI) or multiple CPUs (i.e. is a PPI). This test is
  independent of the number of affine CPUs we can logically map.
* arm_dt_irq_get_affinity : fills a cpumask with the CPUs an interrupt is
  affine to.

The "interrupts-affinity" property consists of a list of pairs of cells
specifying how to test if a CPU is affine. This test specification consists of
a most significant affinity level to match, and values for the MPIDR affinity
bits down to this level. Each pair of cells has the form:

	< N 0x00AABBCC >
	   \   \ \ \ \__ MPIDR.Aff0
	    \   \ \ \___ MPIDR.Aff1
	     \   \ \____ MPIDR.Aff2
	      \   \_____ [must be zero]
	       \________ level-specifier

The level-specifier is in the range [0-3]. When the value is 3, MPIDR
affinity levels 2,1,0 are ignored, and all CPUs are matched. Affinity
bits which are not to be matched should be set to zero.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
---
 arch/arm/include/asm/dt_irq.h |    9 ++++
 arch/arm/kernel/devtree.c     |   91 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/dt_irq.h

diff --git a/arch/arm/include/asm/dt_irq.h b/arch/arm/include/asm/dt_irq.h
new file mode 100644
index 0000000..431eeda
--- /dev/null
+++ b/arch/arm/include/asm/dt_irq.h
@@ -0,0 +1,9 @@
+#ifndef ARM_ASM_DT_IRQ_H
+#define ARM_ASM_DT_IRQ_H
+
+bool arm_dt_has_irq_affinity(struct device_node *node);
+bool arm_dt_affine_irq_is_single(struct device_node *node, int idx);
+int arm_dt_irq_get_affinity(struct device_node *node, int idx,
+			    cpumask_t *mask);
+
+#endif /* ARM_ASM_DT_IRQ_H */
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
index 70f1bde..65d5052 100644
--- a/arch/arm/kernel/devtree.c
+++ b/arch/arm/kernel/devtree.c
@@ -20,6 +20,7 @@
 #include <linux/of_platform.h>
 
 #include <asm/cputype.h>
+#include <asm/dt_irq.h>
 #include <asm/setup.h>
 #include <asm/page.h>
 #include <asm/smp_plat.h>
@@ -165,6 +166,96 @@ void __init arm_dt_init_cpu_maps(void)
 	}
 }
 
+#define PROP_IRQ_AFFINITY	"interrupts-affinity"
+#define AFFINE_LEVEL_IDX(i)	(2*(i))
+#define AFFINE_MPIDR_IDX(i)	(2*(i) + 1)
+
+/*
+ * Check whether the device has irq affinity information.
+ * Allows drivers to fall back to current behaviour with a single check.
+ */
+bool arm_dt_has_irq_affinity(struct device_node *node)
+{
+	return of_find_property(node, PROP_IRQ_AFFINITY, NULL) != NULL;
+}
+
+/*
+ * Check whether an irq with affinity information is a single cpu
+ * interrupt (rather than percpu). The node paramenter should be
+ * checked with arm_dt_has_irq_affinity first.
+ */
+bool arm_dt_affine_irq_is_single(struct device_node *node, int idx)
+{
+	u32 level;
+	of_property_read_u32_index(node, PROP_IRQ_AFFINITY, &level,
+				   AFFINE_LEVEL_IDX(idx));
+	return level == 0;
+}
+
+struct affine_match_spec {
+	u32 level;
+	u32 aff;
+};
+
+static bool arm_dt_affine_mpidr_match(u32 mpidr, struct affine_match_spec *match)
+{
+	u32 mask = 0xFFFFFFFF << (8*(match->level));
+	return (mpidr & mask) == (match->aff & mask);
+}
+
+static int arm_dt_irq_read_match(struct device_node *node, int idx,
+				 struct affine_match_spec *match)
+{
+	int ret;
+	if (!node)
+		return -EINVAL;
+
+	ret = of_property_read_u32_index(node, PROP_IRQ_AFFINITY, &match->aff,
+					 AFFINE_MPIDR_IDX(idx));
+	if (ret)
+		return ret;
+
+	ret = of_property_read_u32_index(node, PROP_IRQ_AFFINITY, &match->level,
+					 AFFINE_LEVEL_IDX(idx));
+	if (ret)
+		return ret;
+
+	/*
+	 * To match all cpus regardless of Aff{2,1,0}, we match at the
+	 * nonexistent Aff3.
+	 */
+	if (match->level > 3)
+		return -EINVAL;
+
+	return ret;
+
+}
+
+/*
+ * Get the set of possible cpus that an interrupt at idx is affine to.
+ */
+int arm_dt_irq_get_affinity(struct device_node *node, int idx,
+			    cpumask_t *mask)
+{
+	int i, ret;
+	struct affine_match_spec match;
+	u32 mpidr;
+
+	ret = arm_dt_irq_read_match(node, idx, &match);
+	if (ret)
+		return ret;
+
+	cpumask_clear(mask);
+
+	for_each_possible_cpu(i) {
+		mpidr = cpu_logical_map(i);
+		if (arm_dt_affine_mpidr_match(mpidr, &match))
+			cpumask_set_cpu(i, mask);
+	}
+
+	return 0;
+}
+
 /**
  * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
  * @dt_phys: physical address of dt blob
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [RFCv2 0/2] Representing interrupt affinity in devicetree
  2012-12-13 16:49 ` Mark Rutland
@ 2013-03-04  2:51     ` Grant Likely
  -1 siblings, 0 replies; 14+ messages in thread
From: Grant Likely @ 2013-03-04  2:51 UTC (permalink / raw)
  To: Mark Rutland, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	Will.Deacon-5wv7dgnIgG8, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
	tglx-hfZtesqFncYOwBW4kG4KsQ

On Thu, 13 Dec 2012 16:49:26 +0000, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
> [This is an updated version of my previous RFC, which can be found at
> http://lists.infradead.org/pipermail/linux-arm-kernel/2012-October/128205.html]
> 
> Current devicetree bindings for devices which use cpu-affine shared interrupts
> assume that interrupts are listed in ascending order of physical cpu id
> (MPIDR.Aff{2,1,0}). This is problematic for drivers because:
> 
> (1) The driver must convert each physical id to a logical id for the purpose of
>     managing interrupts.
> 
> (2) In multi-cluster systems the physical ids are not necessarily contiguous,
>     and drivers cannot simply iterate over ids from 0 to NR_CPUS.
> 
> (3) It is not possible to specify sets of interrupts which are wired to a
>     subset of cpus (i.e. clusters) not starting at physical id 0, as we can't
>     specify which cpu to start from, and can't skip cpus. This makes it
>     impossible to represent some devices (e.g. cpu PMUs) which may not exist
>     in the first cluster.
> 
> (4) Some devices may either be wired with PPIs or SPIs. It is not possible to
>     differentiate the two cases in general from the interrupts list (e.g. when
>     a device has multiple PPIs wired to all cpus).
> 
> To represent the general case, we require a mechanism to describe the cpu
> affinity of a device, and a consistent way to map each interrupt to a cpu (or
> set of cpus). So far, the only workable mechanism I've been able to come up
> with is the following:
> 
> In addition to the interrupts list we add an optional 'interrupts-affinity'
> list which describes how to map an interrupt to cpu(s). Each interrupt would
> have a corresponding element in the interrupts-affinity list.
> 
> Each element consists of a pair of cells specifying how to test if a cpu is
> affine. This test specification consists of a most significant affinity level
> to match, and values for the MPIDR affinity bits down to this level. Each pair
> of cells has the form:
> 
>     < N 0x00AABBCC >
>        \   \ \ \ \__ MPIDR.Aff0
>         \   \ \ \___ MPIDR.Aff1
>          \   \ \____ MPIDR.Aff2
>           \   \_____ [must be zero]
>            \________ level-specifier
> 
> The level-specifier is in the range [0-3]. When the value is 3, MPIDR affinity
> levels 2,1,0 are ignored, and thus all cpus are matched. When the value is 0,
> levels 2,1,0 must all be matched for a cpu to be considered affine. Affinity
> bits which are not to be matched should be set to zero.
> 
> In practice, use of the binding would look something like:
> 
> > device@0 {
> > 	compatible = "example,example-affine-device";
> > 	interrupts = <0 130 4>,
> > 	             <0 131 4>,
> > 	             <1 12 4>;
> > 	interrupts-affinity = <0 0x00000000>,
> >	                      <0 0x00000001>,
> > 	                      <1 0x00000100>;
> > };
> 
> To request/free interrupts, drivers would walk over all interrupts, and request
> the affine cpu(s), which can be automatically mapped to logical ids by common
> code. This fixes issues 1, 2, and 3. 4 is partially solved, in that we know
> whether an interrupt is targeted at a single cpu or multiple cpus (i.e.
> whether it's an SPI or a PPI), but we can't differentiate multiple interrupts
> targeted at the same cpu. We could solve this with an additional
> "interrupt-names" property, or something of that sort.
> 
> The following patches implement common code that could be used by drivers to
> deal with this affinity information, allowing drivers to extract a (logical)
> cpumask specifying the affinity of each interrupt, and additional information
> specifying whether an interrupt targets multiple cpus.
> 
> The patches are based on rmk's for-next branch.
> 
> Any thoughts?

Hi Mark,

I could use some more context for how this will be used. Do device
drivers need to be aware of which CPU can handle an interrupt for a
device, or is it the sort of thing that can be done in the background
when an irq is requested? What are some examples of device drivers using
this interface.

Part of the reason why I ask is I see a new function for parsing the
affinity, but no code that links it into the existing irq
infrastructure. Would this need to be called automatically when a DT
interrupt is parsed? Or when the irq is requested? Some guidance would
help me here.

Thanks,
g.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFCv2 0/2] Representing interrupt affinity in devicetree
@ 2013-03-04  2:51     ` Grant Likely
  0 siblings, 0 replies; 14+ messages in thread
From: Grant Likely @ 2013-03-04  2:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 13 Dec 2012 16:49:26 +0000, Mark Rutland <mark.rutland@arm.com> wrote:
> [This is an updated version of my previous RFC, which can be found at
> http://lists.infradead.org/pipermail/linux-arm-kernel/2012-October/128205.html]
> 
> Current devicetree bindings for devices which use cpu-affine shared interrupts
> assume that interrupts are listed in ascending order of physical cpu id
> (MPIDR.Aff{2,1,0}). This is problematic for drivers because:
> 
> (1) The driver must convert each physical id to a logical id for the purpose of
>     managing interrupts.
> 
> (2) In multi-cluster systems the physical ids are not necessarily contiguous,
>     and drivers cannot simply iterate over ids from 0 to NR_CPUS.
> 
> (3) It is not possible to specify sets of interrupts which are wired to a
>     subset of cpus (i.e. clusters) not starting at physical id 0, as we can't
>     specify which cpu to start from, and can't skip cpus. This makes it
>     impossible to represent some devices (e.g. cpu PMUs) which may not exist
>     in the first cluster.
> 
> (4) Some devices may either be wired with PPIs or SPIs. It is not possible to
>     differentiate the two cases in general from the interrupts list (e.g. when
>     a device has multiple PPIs wired to all cpus).
> 
> To represent the general case, we require a mechanism to describe the cpu
> affinity of a device, and a consistent way to map each interrupt to a cpu (or
> set of cpus). So far, the only workable mechanism I've been able to come up
> with is the following:
> 
> In addition to the interrupts list we add an optional 'interrupts-affinity'
> list which describes how to map an interrupt to cpu(s). Each interrupt would
> have a corresponding element in the interrupts-affinity list.
> 
> Each element consists of a pair of cells specifying how to test if a cpu is
> affine. This test specification consists of a most significant affinity level
> to match, and values for the MPIDR affinity bits down to this level. Each pair
> of cells has the form:
> 
>     < N 0x00AABBCC >
>        \   \ \ \ \__ MPIDR.Aff0
>         \   \ \ \___ MPIDR.Aff1
>          \   \ \____ MPIDR.Aff2
>           \   \_____ [must be zero]
>            \________ level-specifier
> 
> The level-specifier is in the range [0-3]. When the value is 3, MPIDR affinity
> levels 2,1,0 are ignored, and thus all cpus are matched. When the value is 0,
> levels 2,1,0 must all be matched for a cpu to be considered affine. Affinity
> bits which are not to be matched should be set to zero.
> 
> In practice, use of the binding would look something like:
> 
> > device at 0 {
> > 	compatible = "example,example-affine-device";
> > 	interrupts = <0 130 4>,
> > 	             <0 131 4>,
> > 	             <1 12 4>;
> > 	interrupts-affinity = <0 0x00000000>,
> >	                      <0 0x00000001>,
> > 	                      <1 0x00000100>;
> > };
> 
> To request/free interrupts, drivers would walk over all interrupts, and request
> the affine cpu(s), which can be automatically mapped to logical ids by common
> code. This fixes issues 1, 2, and 3. 4 is partially solved, in that we know
> whether an interrupt is targeted at a single cpu or multiple cpus (i.e.
> whether it's an SPI or a PPI), but we can't differentiate multiple interrupts
> targeted at the same cpu. We could solve this with an additional
> "interrupt-names" property, or something of that sort.
> 
> The following patches implement common code that could be used by drivers to
> deal with this affinity information, allowing drivers to extract a (logical)
> cpumask specifying the affinity of each interrupt, and additional information
> specifying whether an interrupt targets multiple cpus.
> 
> The patches are based on rmk's for-next branch.
> 
> Any thoughts?

Hi Mark,

I could use some more context for how this will be used. Do device
drivers need to be aware of which CPU can handle an interrupt for a
device, or is it the sort of thing that can be done in the background
when an irq is requested? What are some examples of device drivers using
this interface.

Part of the reason why I ask is I see a new function for parsing the
affinity, but no code that links it into the existing irq
infrastructure. Would this need to be called automatically when a DT
interrupt is parsed? Or when the irq is requested? Some guidance would
help me here.

Thanks,
g.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFCv2 0/2] Representing interrupt affinity in devicetree
  2013-03-04  2:51     ` Grant Likely
@ 2013-03-05  9:28       ` Mark Rutland
  -1 siblings, 0 replies; 14+ messages in thread
From: Mark Rutland @ 2013-03-05  9:28 UTC (permalink / raw)
  To: Grant Likely
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Will Deacon,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ, tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Mon, Mar 04, 2013 at 02:51:14AM +0000, Grant Likely wrote:
> On Thu, 13 Dec 2012 16:49:26 +0000, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
> > [This is an updated version of my previous RFC, which can be found at
> > http://lists.infradead.org/pipermail/linux-arm-kernel/2012-October/128205.html]
> > 
> > Current devicetree bindings for devices which use cpu-affine shared interrupts
> > assume that interrupts are listed in ascending order of physical cpu id
> > (MPIDR.Aff{2,1,0}). This is problematic for drivers because:
> > 
> > (1) The driver must convert each physical id to a logical id for the purpose of
> >     managing interrupts.
> > 
> > (2) In multi-cluster systems the physical ids are not necessarily contiguous,
> >     and drivers cannot simply iterate over ids from 0 to NR_CPUS.
> > 
> > (3) It is not possible to specify sets of interrupts which are wired to a
> >     subset of cpus (i.e. clusters) not starting at physical id 0, as we can't
> >     specify which cpu to start from, and can't skip cpus. This makes it
> >     impossible to represent some devices (e.g. cpu PMUs) which may not exist
> >     in the first cluster.
> > 
> > (4) Some devices may either be wired with PPIs or SPIs. It is not possible to
> >     differentiate the two cases in general from the interrupts list (e.g. when
> >     a device has multiple PPIs wired to all cpus).
> > 
> > To represent the general case, we require a mechanism to describe the cpu
> > affinity of a device, and a consistent way to map each interrupt to a cpu (or
> > set of cpus). So far, the only workable mechanism I've been able to come up
> > with is the following:
> > 
> > In addition to the interrupts list we add an optional 'interrupts-affinity'
> > list which describes how to map an interrupt to cpu(s). Each interrupt would
> > have a corresponding element in the interrupts-affinity list.
> > 
> > Each element consists of a pair of cells specifying how to test if a cpu is
> > affine. This test specification consists of a most significant affinity level
> > to match, and values for the MPIDR affinity bits down to this level. Each pair
> > of cells has the form:
> > 
> >     < N 0x00AABBCC >
> >        \   \ \ \ \__ MPIDR.Aff0
> >         \   \ \ \___ MPIDR.Aff1
> >          \   \ \____ MPIDR.Aff2
> >           \   \_____ [must be zero]
> >            \________ level-specifier
> > 
> > The level-specifier is in the range [0-3]. When the value is 3, MPIDR affinity
> > levels 2,1,0 are ignored, and thus all cpus are matched. When the value is 0,
> > levels 2,1,0 must all be matched for a cpu to be considered affine. Affinity
> > bits which are not to be matched should be set to zero.
> > 
> > In practice, use of the binding would look something like:
> > 
> > > device@0 {
> > > 	compatible = "example,example-affine-device";
> > > 	interrupts = <0 130 4>,
> > > 	             <0 131 4>,
> > > 	             <1 12 4>;
> > > 	interrupts-affinity = <0 0x00000000>,
> > >	                      <0 0x00000001>,
> > > 	                      <1 0x00000100>;
> > > };
> > 
> > To request/free interrupts, drivers would walk over all interrupts, and request
> > the affine cpu(s), which can be automatically mapped to logical ids by common
> > code. This fixes issues 1, 2, and 3. 4 is partially solved, in that we know
> > whether an interrupt is targeted at a single cpu or multiple cpus (i.e.
> > whether it's an SPI or a PPI), but we can't differentiate multiple interrupts
> > targeted at the same cpu. We could solve this with an additional
> > "interrupt-names" property, or something of that sort.
> > 
> > The following patches implement common code that could be used by drivers to
> > deal with this affinity information, allowing drivers to extract a (logical)
> > cpumask specifying the affinity of each interrupt, and additional information
> > specifying whether an interrupt targets multiple cpus.
> > 
> > The patches are based on rmk's for-next branch.
> > 
> > Any thoughts?
> 
> Hi Mark,

Hi,

> 
> I could use some more context for how this will be used. Do device
> drivers need to be aware of which CPU can handle an interrupt for a
> device, or is it the sort of thing that can be done in the background
> when an irq is requested? What are some examples of device drivers using
> this interface.

The main users I can think of for this would be PMUs in multi-cluster systems,
where we may have differing PMUs in each cluster. The driver for each needs to
know the set of CPUs it's handling, and which CPU each interrupt is affine to.

With the above binding scheme, we'd describe the A15x2 A7x3 CoreTile's PMUs
something like:

pmu_a15s {
	compatible = "arm,cortex-a15-pmu";
	interrupts = <0 68 4>,
	             <0 69 4>;
	interrupts-affinity = <0 0x0>,
	                      <0 0x1>;
};

pmu_a7s {
	compatible = arm,cortex-a7-pmu";
	interrupts = <0 128 4>,
	             <0 129 4>,
	             <0 130 4>;
	interrupts-affinity = <0 0x100>,
	                      <0 0x101>,
	                      <0 0x102>;
};

> 
> Part of the reason why I ask is I see a new function for parsing the
> affinity, but no code that links it into the existing irq
> infrastructure. Would this need to be called automatically when a DT
> interrupt is parsed? Or when the irq is requested? Some guidance would
> help me here.

I envisage that each driver that requires this information would request it
manually when parsing the dt, and storing what it needs in an appropriate
datastructure. For PMUs this could be something like:

struct irq_affinity {
	cpumask_t mask;
	int irq;
} interrupt_data[];

When setting up or tearing down interrupts, each CPU can find which
interrupt(s) it needs, and whether it's a PPI or SPI by iterating over the list
and checking against a cpumask, and perform the appropriate steps to setup or
teardown.

Other devices may need affinity information (e.g. which CPUs are connected to
the ACE ports on CCI) and can be handled by a similar binding.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFCv2 0/2] Representing interrupt affinity in devicetree
@ 2013-03-05  9:28       ` Mark Rutland
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Rutland @ 2013-03-05  9:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Mar 04, 2013 at 02:51:14AM +0000, Grant Likely wrote:
> On Thu, 13 Dec 2012 16:49:26 +0000, Mark Rutland <mark.rutland@arm.com> wrote:
> > [This is an updated version of my previous RFC, which can be found at
> > http://lists.infradead.org/pipermail/linux-arm-kernel/2012-October/128205.html]
> > 
> > Current devicetree bindings for devices which use cpu-affine shared interrupts
> > assume that interrupts are listed in ascending order of physical cpu id
> > (MPIDR.Aff{2,1,0}). This is problematic for drivers because:
> > 
> > (1) The driver must convert each physical id to a logical id for the purpose of
> >     managing interrupts.
> > 
> > (2) In multi-cluster systems the physical ids are not necessarily contiguous,
> >     and drivers cannot simply iterate over ids from 0 to NR_CPUS.
> > 
> > (3) It is not possible to specify sets of interrupts which are wired to a
> >     subset of cpus (i.e. clusters) not starting at physical id 0, as we can't
> >     specify which cpu to start from, and can't skip cpus. This makes it
> >     impossible to represent some devices (e.g. cpu PMUs) which may not exist
> >     in the first cluster.
> > 
> > (4) Some devices may either be wired with PPIs or SPIs. It is not possible to
> >     differentiate the two cases in general from the interrupts list (e.g. when
> >     a device has multiple PPIs wired to all cpus).
> > 
> > To represent the general case, we require a mechanism to describe the cpu
> > affinity of a device, and a consistent way to map each interrupt to a cpu (or
> > set of cpus). So far, the only workable mechanism I've been able to come up
> > with is the following:
> > 
> > In addition to the interrupts list we add an optional 'interrupts-affinity'
> > list which describes how to map an interrupt to cpu(s). Each interrupt would
> > have a corresponding element in the interrupts-affinity list.
> > 
> > Each element consists of a pair of cells specifying how to test if a cpu is
> > affine. This test specification consists of a most significant affinity level
> > to match, and values for the MPIDR affinity bits down to this level. Each pair
> > of cells has the form:
> > 
> >     < N 0x00AABBCC >
> >        \   \ \ \ \__ MPIDR.Aff0
> >         \   \ \ \___ MPIDR.Aff1
> >          \   \ \____ MPIDR.Aff2
> >           \   \_____ [must be zero]
> >            \________ level-specifier
> > 
> > The level-specifier is in the range [0-3]. When the value is 3, MPIDR affinity
> > levels 2,1,0 are ignored, and thus all cpus are matched. When the value is 0,
> > levels 2,1,0 must all be matched for a cpu to be considered affine. Affinity
> > bits which are not to be matched should be set to zero.
> > 
> > In practice, use of the binding would look something like:
> > 
> > > device at 0 {
> > > 	compatible = "example,example-affine-device";
> > > 	interrupts = <0 130 4>,
> > > 	             <0 131 4>,
> > > 	             <1 12 4>;
> > > 	interrupts-affinity = <0 0x00000000>,
> > >	                      <0 0x00000001>,
> > > 	                      <1 0x00000100>;
> > > };
> > 
> > To request/free interrupts, drivers would walk over all interrupts, and request
> > the affine cpu(s), which can be automatically mapped to logical ids by common
> > code. This fixes issues 1, 2, and 3. 4 is partially solved, in that we know
> > whether an interrupt is targeted at a single cpu or multiple cpus (i.e.
> > whether it's an SPI or a PPI), but we can't differentiate multiple interrupts
> > targeted at the same cpu. We could solve this with an additional
> > "interrupt-names" property, or something of that sort.
> > 
> > The following patches implement common code that could be used by drivers to
> > deal with this affinity information, allowing drivers to extract a (logical)
> > cpumask specifying the affinity of each interrupt, and additional information
> > specifying whether an interrupt targets multiple cpus.
> > 
> > The patches are based on rmk's for-next branch.
> > 
> > Any thoughts?
> 
> Hi Mark,

Hi,

> 
> I could use some more context for how this will be used. Do device
> drivers need to be aware of which CPU can handle an interrupt for a
> device, or is it the sort of thing that can be done in the background
> when an irq is requested? What are some examples of device drivers using
> this interface.

The main users I can think of for this would be PMUs in multi-cluster systems,
where we may have differing PMUs in each cluster. The driver for each needs to
know the set of CPUs it's handling, and which CPU each interrupt is affine to.

With the above binding scheme, we'd describe the A15x2 A7x3 CoreTile's PMUs
something like:

pmu_a15s {
	compatible = "arm,cortex-a15-pmu";
	interrupts = <0 68 4>,
	             <0 69 4>;
	interrupts-affinity = <0 0x0>,
	                      <0 0x1>;
};

pmu_a7s {
	compatible = arm,cortex-a7-pmu";
	interrupts = <0 128 4>,
	             <0 129 4>,
	             <0 130 4>;
	interrupts-affinity = <0 0x100>,
	                      <0 0x101>,
	                      <0 0x102>;
};

> 
> Part of the reason why I ask is I see a new function for parsing the
> affinity, but no code that links it into the existing irq
> infrastructure. Would this need to be called automatically when a DT
> interrupt is parsed? Or when the irq is requested? Some guidance would
> help me here.

I envisage that each driver that requires this information would request it
manually when parsing the dt, and storing what it needs in an appropriate
datastructure. For PMUs this could be something like:

struct irq_affinity {
	cpumask_t mask;
	int irq;
} interrupt_data[];

When setting up or tearing down interrupts, each CPU can find which
interrupt(s) it needs, and whether it's a PPI or SPI by iterating over the list
and checking against a cpumask, and perform the appropriate steps to setup or
teardown.

Other devices may need affinity information (e.g. which CPUs are connected to
the ACE ports on CCI) and can be handled by a similar binding.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFCv2 0/2] Representing interrupt affinity in devicetree
  2013-03-05  9:28       ` Mark Rutland
@ 2013-04-13 21:33           ` Grant Likely
  -1 siblings, 0 replies; 14+ messages in thread
From: Grant Likely @ 2013-04-13 21:33 UTC (permalink / raw)
  To: Mark Rutland
  Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Will Deacon,
	rob.herring-bsGFqQB8/DxBDgjK7y7TUQ, tglx-hfZtesqFncYOwBW4kG4KsQ,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tue, 5 Mar 2013 09:28:49 +0000, Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> wrote:
> On Mon, Mar 04, 2013 at 02:51:14AM +0000, Grant Likely wrote:
> > I could use some more context for how this will be used. Do device
> > drivers need to be aware of which CPU can handle an interrupt for a
> > device, or is it the sort of thing that can be done in the background
> > when an irq is requested? What are some examples of device drivers using
> > this interface.
> 
> The main users I can think of for this would be PMUs in multi-cluster systems,
> where we may have differing PMUs in each cluster. The driver for each needs to
> know the set of CPUs it's handling, and which CPU each interrupt is affine to.
> 
> With the above binding scheme, we'd describe the A15x2 A7x3 CoreTile's PMUs
> something like:
> 
> pmu_a15s {
> 	compatible = "arm,cortex-a15-pmu";
> 	interrupts = <0 68 4>,
> 	             <0 69 4>;
> 	interrupts-affinity = <0 0x0>,
> 	                      <0 0x1>;
> };
> 
> pmu_a7s {
> 	compatible = arm,cortex-a7-pmu";
> 	interrupts = <0 128 4>,
> 	             <0 129 4>,
> 	             <0 130 4>;
> 	interrupts-affinity = <0 0x100>,
> 	                      <0 0x101>,
> 	                      <0 0x102>;
> };

That does sound an awful lot like what Lorenzo has been trying to solve.
I really do think that you need to coordinate with him.

g.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFCv2 0/2] Representing interrupt affinity in devicetree
@ 2013-04-13 21:33           ` Grant Likely
  0 siblings, 0 replies; 14+ messages in thread
From: Grant Likely @ 2013-04-13 21:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 5 Mar 2013 09:28:49 +0000, Mark Rutland <mark.rutland@arm.com> wrote:
> On Mon, Mar 04, 2013 at 02:51:14AM +0000, Grant Likely wrote:
> > I could use some more context for how this will be used. Do device
> > drivers need to be aware of which CPU can handle an interrupt for a
> > device, or is it the sort of thing that can be done in the background
> > when an irq is requested? What are some examples of device drivers using
> > this interface.
> 
> The main users I can think of for this would be PMUs in multi-cluster systems,
> where we may have differing PMUs in each cluster. The driver for each needs to
> know the set of CPUs it's handling, and which CPU each interrupt is affine to.
> 
> With the above binding scheme, we'd describe the A15x2 A7x3 CoreTile's PMUs
> something like:
> 
> pmu_a15s {
> 	compatible = "arm,cortex-a15-pmu";
> 	interrupts = <0 68 4>,
> 	             <0 69 4>;
> 	interrupts-affinity = <0 0x0>,
> 	                      <0 0x1>;
> };
> 
> pmu_a7s {
> 	compatible = arm,cortex-a7-pmu";
> 	interrupts = <0 128 4>,
> 	             <0 129 4>,
> 	             <0 130 4>;
> 	interrupts-affinity = <0 0x100>,
> 	                      <0 0x101>,
> 	                      <0 0x102>;
> };

That does sound an awful lot like what Lorenzo has been trying to solve.
I really do think that you need to coordinate with him.

g.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFCv2 0/2] Representing interrupt affinity in devicetree
  2013-04-13 21:33           ` Grant Likely
@ 2013-04-15  9:09             ` Mark Rutland
  -1 siblings, 0 replies; 14+ messages in thread
From: Mark Rutland @ 2013-04-15  9:09 UTC (permalink / raw)
  To: Grant Likely
  Cc: Lorenzo Pieralisi, benh, devicetree-discuss, Will Deacon,
	rob.herring, tglx, linux-arm-kernel

On Sat, Apr 13, 2013 at 10:33:22PM +0100, Grant Likely wrote:
> On Tue, 5 Mar 2013 09:28:49 +0000, Mark Rutland <mark.rutland@arm.com> wrote:
> > On Mon, Mar 04, 2013 at 02:51:14AM +0000, Grant Likely wrote:
> > > I could use some more context for how this will be used. Do device
> > > drivers need to be aware of which CPU can handle an interrupt for a
> > > device, or is it the sort of thing that can be done in the background
> > > when an irq is requested? What are some examples of device drivers using
> > > this interface.
> > 
> > The main users I can think of for this would be PMUs in multi-cluster systems,
> > where we may have differing PMUs in each cluster. The driver for each needs to
> > know the set of CPUs it's handling, and which CPU each interrupt is affine to.
> > 
> > With the above binding scheme, we'd describe the A15x2 A7x3 CoreTile's PMUs
> > something like:
> > 
> > pmu_a15s {
> > 	compatible = "arm,cortex-a15-pmu";
> > 	interrupts = <0 68 4>,
> > 	             <0 69 4>;
> > 	interrupts-affinity = <0 0x0>,
> > 	                      <0 0x1>;
> > };
> > 
> > pmu_a7s {
> > 	compatible = arm,cortex-a7-pmu";
> > 	interrupts = <0 128 4>,
> > 	             <0 129 4>,
> > 	             <0 130 4>;
> > 	interrupts-affinity = <0 0x100>,
> > 	                      <0 0x101>,
> > 	                      <0 0x102>;
> > };
> 
> That does sound an awful lot like what Lorenzo has been trying to solve.
> I really do think that you need to coordinate with him.

Indeed it does. Lorenzo and I have been working together on this, and having
realised issues with the above approach, we've put a new series together [1]
which we both believe has a more workable approach.

Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2013-April/162457.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFCv2 0/2] Representing interrupt affinity in devicetree
@ 2013-04-15  9:09             ` Mark Rutland
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Rutland @ 2013-04-15  9:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Apr 13, 2013 at 10:33:22PM +0100, Grant Likely wrote:
> On Tue, 5 Mar 2013 09:28:49 +0000, Mark Rutland <mark.rutland@arm.com> wrote:
> > On Mon, Mar 04, 2013 at 02:51:14AM +0000, Grant Likely wrote:
> > > I could use some more context for how this will be used. Do device
> > > drivers need to be aware of which CPU can handle an interrupt for a
> > > device, or is it the sort of thing that can be done in the background
> > > when an irq is requested? What are some examples of device drivers using
> > > this interface.
> > 
> > The main users I can think of for this would be PMUs in multi-cluster systems,
> > where we may have differing PMUs in each cluster. The driver for each needs to
> > know the set of CPUs it's handling, and which CPU each interrupt is affine to.
> > 
> > With the above binding scheme, we'd describe the A15x2 A7x3 CoreTile's PMUs
> > something like:
> > 
> > pmu_a15s {
> > 	compatible = "arm,cortex-a15-pmu";
> > 	interrupts = <0 68 4>,
> > 	             <0 69 4>;
> > 	interrupts-affinity = <0 0x0>,
> > 	                      <0 0x1>;
> > };
> > 
> > pmu_a7s {
> > 	compatible = arm,cortex-a7-pmu";
> > 	interrupts = <0 128 4>,
> > 	             <0 129 4>,
> > 	             <0 130 4>;
> > 	interrupts-affinity = <0 0x100>,
> > 	                      <0 0x101>,
> > 	                      <0 0x102>;
> > };
> 
> That does sound an awful lot like what Lorenzo has been trying to solve.
> I really do think that you need to coordinate with him.

Indeed it does. Lorenzo and I have been working together on this, and having
realised issues with the above approach, we've put a new series together [1]
which we both believe has a more workable approach.

Mark.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2013-April/162457.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-04-15  9:09 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-13 16:49 [RFCv2 0/2] Representing interrupt affinity in devicetree Mark Rutland
2012-12-13 16:49 ` Mark Rutland
     [not found] ` <1355417368-6861-1-git-send-email-mark.rutland-5wv7dgnIgG8@public.gmane.org>
2012-12-13 16:49   ` [RFCv2 1/2] of: add of_property_read_u32_index Mark Rutland
2012-12-13 16:49     ` Mark Rutland
2012-12-13 16:49   ` [RFCv2 2/2] ARM: add functions to parse irq affinity from dt Mark Rutland
2012-12-13 16:49     ` Mark Rutland
2013-03-04  2:51   ` [RFCv2 0/2] Representing interrupt affinity in devicetree Grant Likely
2013-03-04  2:51     ` Grant Likely
2013-03-05  9:28     ` Mark Rutland
2013-03-05  9:28       ` Mark Rutland
     [not found]       ` <20130305092849.GA15661-NuALmloUBlrZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
2013-04-13 21:33         ` Grant Likely
2013-04-13 21:33           ` Grant Likely
2013-04-15  9:09           ` Mark Rutland
2013-04-15  9:09             ` Mark Rutland

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.