Linux-ARM-Kernel Archive on lore.kernel.org
 help / Atom feed
* [PATCH v5 00/10] Add support for TISCI irqchip drivers
@ 2019-02-12  7:42 Lokesh Vutla
  2019-02-12  7:42 ` [PATCH v5 01/10] firmware: ti_sci: Add support to get TISCI handle using of_phandle Lokesh Vutla
                   ` (10 more replies)
  0 siblings, 11 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

TI AM65x SoC based on K3 architecture introduced support for Events
which are message based interrupts with minimal latency. These events
are not compatible with regular interrupts and are valid only through
an event transport lane. An Interrupt Aggregator(INTA) is introduced
to convert these events to interrupts. INTA can also group 64 events
into a single interrupt. Now the SoC has many peripherals and a large
number of event sources (time sync or DMA), the use of events is
completely dependent on a user's specific application, which drives a
need for maximum flexibility in which event sources are used in the
system. It is also completely up to software control as to how the
events are serviced.

Because of the huge flexibility there are certain standard peripherals
(like GPIO etc)where all interrupts cannot be directly corrected to host
interrupt controller. For this purpose, Interrupt Router(INTR) is
introduced in the SoC. INTR just does a classic interrupt redirection.

So the SoC has 3 types of interrupt controllers:
- GIC500
- Interrupt Router
- Interrupt Aggregator

Below is a diagrammatic view of how SoC integration of these interrupt
controllers:(https://pastebin.ubuntu.com/p/9ngV3jdGj2/)

Device Index-x               Device Index-y
           |                         |
           |                         |
                      ....
            \                       /
             \                     /
              \  (global events)  /
          +---------------------------+   +---------+
          |                           |   |         |
          |             INTA          |   |  GPIO   |
          |                           |   |         |
          +---------------------------+   +---------+
                         |   (vint)            |
                         |                     |
                        \|/                    |
          +---------------------------+        |
          |                           |<-------+
          |           INTR            |
          |                           |
          +---------------------------+
                         |
                         |
                        \|/ (gic irq)
          +---------------------------+
          |                           |
          |             GIC           |
          |                           |
          +---------------------------+

While at it, TISCI abstracts the handling of all above IRQ routes where
interrupt sources are not directly connected to host interrupt controller.
That would be configuration of Interrupt Aggregator and Interrupt Router.

This series adds support for:
- TISCI commands needed for IRQ configuration
- Interrupt Router(INTR) and Interrupt Aggregator(INTA) drivers

Changes since v4:
- Mentioned the changes in each patch

Changes since v3:
- Fix documentation for Interrupt Router driver
- Rebased on top of latest next.
- Fully tested with DMA(using out of tree patches)
- Fixed a build error with allmodconfig


Grygorii Strashko (1):
  firmware: ti_sci: Add support to get TISCI handle using of_phandle

Lokesh Vutla (8):
  firmware: ti_sci: Add support for RM core ops
  firmware: ti_sci: Add support for IRQ management
  dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  irqchip: ti-sci-intr: Add support for Interrupt Router driver
  dt-bindings: irqchip: Introduce TISCI Interrupt Aggregator bindings
  irqchip: ti-sci-inta: Add support for Interrupt Aggregator driver
  soc: ti: Add MSI domain support for K3 Interrupt Aggregator
  soc: ti: am6: Enable interrupt controller drivers

Peter Ujfalusi (1):
  firmware: ti_sci: Add RM mapping table for am654

 .../bindings/arm/keystone/ti,sci.txt          |   3 +-
 .../interrupt-controller/ti,sci-inta.txt      |  74 +++
 .../interrupt-controller/ti,sci-intr.txt      |  85 +++
 MAINTAINERS                                   |   6 +
 drivers/firmware/ti_sci.c                     | 536 ++++++++++++++++++
 drivers/firmware/ti_sci.h                     | 102 ++++
 drivers/irqchip/Kconfig                       |  23 +
 drivers/irqchip/Makefile                      |   2 +
 drivers/irqchip/irq-ti-sci-common.c           | 131 +++++
 drivers/irqchip/irq-ti-sci-common.h           |  59 ++
 drivers/irqchip/irq-ti-sci-inta.c             | 531 +++++++++++++++++
 drivers/irqchip/irq-ti-sci-intr.c             | 315 ++++++++++
 drivers/soc/ti/Kconfig                        |  11 +
 drivers/soc/ti/Makefile                       |   1 +
 drivers/soc/ti/k3_inta_msi.c                  | 143 +++++
 include/linux/irqdomain.h                     |   1 +
 include/linux/msi.h                           |   7 +
 include/linux/soc/ti/k3_inta_msi.h            |  21 +
 include/linux/soc/ti/ti_sci_protocol.h        |  72 +++
 19 files changed, 2122 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
 create mode 100644 drivers/irqchip/irq-ti-sci-common.c
 create mode 100644 drivers/irqchip/irq-ti-sci-common.h
 create mode 100644 drivers/irqchip/irq-ti-sci-inta.c
 create mode 100644 drivers/irqchip/irq-ti-sci-intr.c
 create mode 100644 drivers/soc/ti/k3_inta_msi.c
 create mode 100644 include/linux/soc/ti/k3_inta_msi.h

-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 01/10] firmware: ti_sci: Add support to get TISCI handle using of_phandle
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
@ 2019-02-12  7:42 ` Lokesh Vutla
  2019-02-12  7:42 ` [PATCH v5 02/10] firmware: ti_sci: Add support for RM core ops Lokesh Vutla
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

From: Grygorii Strashko <grygorii.strashko@ti.com>

TISCI has been updated to have support for Resource management(likes
interrupts etc..). And there can be multiple device instances of a
resource type in a SoC. So every driver corresponding to a resource type
should get a TISCI handle so that it can make TISCI calls. And each
DT node corresponding to a device should exist under its corresponding
bus node as per the SoC architecture.

But existing apis in TISCI library assumes that all TISCI users are
child nodes of TISCI. Which is not true in the above case. So introduce
(devm_)ti_sci_get_by_phandle() apis that can be used by TISCI users
to get TISCI handle using of phandle property.

Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
Changes since v4:
- None

 drivers/firmware/ti_sci.c              | 83 ++++++++++++++++++++++++++
 include/linux/soc/ti/ti_sci_protocol.h | 17 ++++++
 2 files changed, 100 insertions(+)

diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 69ed1464175c..f0cafa8a2ee9 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -1781,6 +1781,89 @@ const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(devm_ti_sci_get_handle);
 
+/**
+ * ti_sci_get_by_phandle() - Get the TI SCI handle using DT phandle
+ * @np:		device node
+ * @propname:	property name containing phandle on TISCI node
+ *
+ * NOTE: The function does not track individual clients of the framework
+ * and is expected to be maintained by caller of TI SCI protocol library.
+ * ti_sci_put_handle must be balanced with successful ti_sci_get_by_phandle
+ * Return: pointer to handle if successful, else:
+ * -EPROBE_DEFER if the instance is not ready
+ * -ENODEV if the required node handler is missing
+ * -EINVAL if invalid conditions are encountered.
+ */
+const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
+						  const char *property)
+{
+	struct ti_sci_handle *handle = NULL;
+	struct device_node *ti_sci_np;
+	struct ti_sci_info *info;
+	struct list_head *p;
+
+	if (!np) {
+		pr_err("I need a device pointer\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	ti_sci_np = of_parse_phandle(np, property, 0);
+	if (!ti_sci_np)
+		return ERR_PTR(-ENODEV);
+
+	mutex_lock(&ti_sci_list_mutex);
+	list_for_each(p, &ti_sci_list) {
+		info = list_entry(p, struct ti_sci_info, node);
+		if (ti_sci_np == info->dev->of_node) {
+			handle = &info->handle;
+			info->users++;
+			break;
+		}
+	}
+	mutex_unlock(&ti_sci_list_mutex);
+	of_node_put(ti_sci_np);
+
+	if (!handle)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return handle;
+}
+EXPORT_SYMBOL_GPL(ti_sci_get_by_phandle);
+
+/**
+ * devm_ti_sci_get_by_phandle() - Managed get handle using phandle
+ * @dev:	Device pointer requesting TISCI handle
+ * @propname:	property name containing phandle on TISCI node
+ *
+ * NOTE: This releases the handle once the device resources are
+ * no longer needed. MUST NOT BE released with ti_sci_put_handle.
+ * The function does not track individual clients of the framework
+ * and is expected to be maintained by caller of TI SCI protocol library.
+ *
+ * Return: 0 if all went fine, else corresponding error.
+ */
+const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev,
+						       const char *property)
+{
+	const struct ti_sci_handle *handle;
+	const struct ti_sci_handle **ptr;
+
+	ptr = devres_alloc(devm_ti_sci_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+	handle = ti_sci_get_by_phandle(dev_of_node(dev), property);
+
+	if (!IS_ERR(handle)) {
+		*ptr = handle;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return handle;
+}
+EXPORT_SYMBOL_GPL(devm_ti_sci_get_by_phandle);
+
 static int tisci_reboot_handler(struct notifier_block *nb, unsigned long mode,
 				void *cmd)
 {
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index 18435e5c6364..515587e9d373 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -217,6 +217,10 @@ struct ti_sci_handle {
 const struct ti_sci_handle *ti_sci_get_handle(struct device *dev);
 int ti_sci_put_handle(const struct ti_sci_handle *handle);
 const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev);
+const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
+						  const char *property);
+const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev,
+						       const char *property);
 
 #else	/* CONFIG_TI_SCI_PROTOCOL */
 
@@ -236,6 +240,19 @@ const struct ti_sci_handle *devm_ti_sci_get_handle(struct device *dev)
 	return ERR_PTR(-EINVAL);
 }
 
+static inline
+const struct ti_sci_handle *ti_sci_get_by_phandle(struct device_node *np,
+						  const char *property)
+{
+	return ERR_PTR(-EINVAL);
+}
+
+static inline
+const struct ti_sci_handle *devm_ti_sci_get_by_phandle(struct device *dev,
+						       const char *property)
+{
+	return ERR_PTR(-EINVAL);
+}
 #endif	/* CONFIG_TI_SCI_PROTOCOL */
 
 #endif	/* __TISCI_PROTOCOL_H */
-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 02/10] firmware: ti_sci: Add support for RM core ops
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
  2019-02-12  7:42 ` [PATCH v5 01/10] firmware: ti_sci: Add support to get TISCI handle using of_phandle Lokesh Vutla
@ 2019-02-12  7:42 ` Lokesh Vutla
  2019-02-12  7:42 ` [PATCH v5 03/10] firmware: ti_sci: Add support for IRQ management Lokesh Vutla
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

TISCI provides support for getting the resources(IRQ, RING etc..)
assigned to a specific device. These resources can be handled by
the client and in turn sends TISCI cmd to configure the resources.

It is very important that client should keep track on usage of these
resources.

Add support for TISCI commands to get resource ranges.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
Changes since v4:
- None

 drivers/firmware/ti_sci.c              | 170 +++++++++++++++++++++++++
 drivers/firmware/ti_sci.h              |  42 ++++++
 include/linux/soc/ti/ti_sci_protocol.h |  27 ++++
 3 files changed, 239 insertions(+)

diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index f0cafa8a2ee9..a2a099b8f62a 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -64,6 +64,22 @@ struct ti_sci_xfers_info {
 	spinlock_t xfer_lock;
 };
 
+/**
+ * struct ti_sci_rm_type_map - Structure representing TISCI Resource
+ *				management representation of dev_ids.
+ * @dev_id:	TISCI device ID
+ * @type:	Corresponding id as identified by TISCI RM.
+ *
+ * Note: This is used only as a work around for using RM range apis
+ *	for AM654 SoC. For future SoCs dev_id will be used as type
+ *	for RM range APIs. In order to maintain ABI backward compatibility
+ *	type is not being changed for AM654 SoC.
+ */
+struct ti_sci_rm_type_map {
+	u32 dev_id;
+	u16 type;
+};
+
 /**
  * struct ti_sci_desc - Description of SoC integration
  * @default_host_id:	Host identifier representing the compute entity
@@ -71,12 +87,14 @@ struct ti_sci_xfers_info {
  * @max_msgs: Maximum number of messages that can be pending
  *		  simultaneously in the system
  * @max_msg_size: Maximum size of data per message that can be handled.
+ * @rm_type_map: RM resource type mapping structure.
  */
 struct ti_sci_desc {
 	u8 default_host_id;
 	int max_rx_timeout_ms;
 	int max_msgs;
 	int max_msg_size;
+	struct ti_sci_rm_type_map *rm_type_map;
 };
 
 /**
@@ -1617,6 +1635,153 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle)
 	return ret;
 }
 
+static int ti_sci_get_resource_type(struct ti_sci_info *info, u16 dev_id,
+				    u16 *type)
+{
+	struct ti_sci_rm_type_map *rm_type_map = info->desc->rm_type_map;
+	bool found = false;
+	int i;
+
+	/* If map is not provided then assume dev_id is used as type */
+	if (!rm_type_map) {
+		*type = dev_id;
+		return 0;
+	}
+
+	for (i = 0; rm_type_map[i].dev_id; i++) {
+		if (rm_type_map[i].dev_id == dev_id) {
+			*type = rm_type_map[i].type;
+			found = true;
+			break;
+		}
+	}
+
+	if (!found)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * ti_sci_get_resource_range - Helper to get a range of resources assigned
+ *			       to a host. Resource is uniquely identified by
+ *			       type and subtype.
+ * @handle:		Pointer to TISCI handle.
+ * @dev_id:		TISCI device ID.
+ * @subtype:		Resource assignment subtype that is being requested
+ *			from the given device.
+ * @s_host:		Host processor ID to which the resources are allocated
+ * @range_start:	Start index of the resource range
+ * @range_num:		Number of resources in the range
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_get_resource_range(const struct ti_sci_handle *handle,
+				     u32 dev_id, u8 subtype, u8 s_host,
+				     u16 *range_start, u16 *range_num)
+{
+	struct ti_sci_msg_resp_get_resource_range *resp;
+	struct ti_sci_msg_req_get_resource_range *req;
+	struct ti_sci_xfer *xfer;
+	struct ti_sci_info *info;
+	struct device *dev;
+	u16 type;
+	int ret = 0;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	info = handle_to_ti_sci_info(handle);
+	dev = info->dev;
+
+	xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_GET_RESOURCE_RANGE,
+				   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+				   sizeof(*req), sizeof(*resp));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+
+	ret = ti_sci_get_resource_type(info, dev_id, &type);
+	if (ret) {
+		dev_err(dev, "rm type lookup failed for %u\n", dev_id);
+		goto fail;
+	}
+
+	req = (struct ti_sci_msg_req_get_resource_range *)xfer->xfer_buf;
+	req->secondary_host = s_host;
+	req->type = type & MSG_RM_RESOURCE_TYPE_MASK;
+	req->subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK;
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+	resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->xfer_buf;
+
+	if (!ti_sci_is_response_ack(resp)) {
+		ret = -ENODEV;
+	} else if (!resp->range_start && !resp->range_num) {
+		ret = -ENODEV;
+	} else {
+		*range_start = resp->range_start;
+		*range_num = resp->range_num;
+	};
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
+/**
+ * ti_sci_cmd_get_resource_range - Get a range of resources assigned to host
+ *				   that is same as ti sci interface host.
+ * @handle:		Pointer to TISCI handle.
+ * @dev_id:		TISCI device ID.
+ * @subtype:		Resource assignment subtype that is being requested
+ *			from the given device.
+ * @range_start:	Start index of the resource range
+ * @range_num:		Number of resources in the range
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_get_resource_range(const struct ti_sci_handle *handle,
+					 u32 dev_id, u8 subtype,
+					 u16 *range_start, u16 *range_num)
+{
+	return ti_sci_get_resource_range(handle, dev_id, subtype,
+					 TI_SCI_IRQ_SECONDARY_HOST_INVALID,
+					 range_start, range_num);
+}
+
+/**
+ * ti_sci_cmd_get_resource_range_from_shost - Get a range of resources
+ *					      assigned to a specified host.
+ * @handle:		Pointer to TISCI handle.
+ * @dev_id:		TISCI device ID.
+ * @subtype:		Resource assignment subtype that is being requested
+ *			from the given device.
+ * @s_host:		Host processor ID to which the resources are allocated
+ * @range_start:	Start index of the resource range
+ * @range_num:		Number of resources in the range
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static
+int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
+					     u32 dev_id, u8 subtype, u8 s_host,
+					     u16 *range_start, u16 *range_num)
+{
+	return ti_sci_get_resource_range(handle, dev_id, subtype, s_host,
+					 range_start, range_num);
+}
+
 /*
  * ti_sci_setup_ops() - Setup the operations structures
  * @info:	pointer to TISCI pointer
@@ -1627,6 +1792,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
 	struct ti_sci_core_ops *core_ops = &ops->core_ops;
 	struct ti_sci_dev_ops *dops = &ops->dev_ops;
 	struct ti_sci_clk_ops *cops = &ops->clk_ops;
+	struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
 
 	core_ops->reboot_device = ti_sci_cmd_core_reboot;
 
@@ -1657,6 +1823,10 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
 	cops->get_best_match_freq = ti_sci_cmd_clk_get_match_freq;
 	cops->set_freq = ti_sci_cmd_clk_set_freq;
 	cops->get_freq = ti_sci_cmd_clk_get_freq;
+
+	rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
+	rm_core_ops->get_range_from_shost =
+				ti_sci_cmd_get_resource_range_from_shost;
 }
 
 /**
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
index 12bf316b68df..a043c4762791 100644
--- a/drivers/firmware/ti_sci.h
+++ b/drivers/firmware/ti_sci.h
@@ -35,6 +35,9 @@
 #define TI_SCI_MSG_QUERY_CLOCK_FREQ	0x010d
 #define TI_SCI_MSG_GET_CLOCK_FREQ	0x010e
 
+/* Resource Management Requests */
+#define TI_SCI_MSG_GET_RESOURCE_RANGE	0x1500
+
 /**
  * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
  * @type:	Type of messages: One of TI_SCI_MSG* values
@@ -461,4 +464,43 @@ struct ti_sci_msg_resp_get_clock_freq {
 	u64 freq_hz;
 } __packed;
 
+#define TI_SCI_IRQ_SECONDARY_HOST_INVALID	0xff
+
+/**
+ * struct ti_sci_msg_req_get_resource_range - Request to get a host's assigned
+ *					      range of resources.
+ * @hdr:		Generic Header
+ * @type:		Unique resource assignment type
+ * @subtype:		Resource assignment subtype within the resource type.
+ * @secondary_host:	Host processing entity to which the resources are
+ *			allocated. This is required only when the destination
+ *			host id id different from ti sci interface host id,
+ *			else TI_SCI_IRQ_SECONDARY_HOST_INVALID can be passed.
+ *
+ * Request type is TI_SCI_MSG_GET_RESOURCE_RANGE. Responded with requested
+ * resource range which is of type TI_SCI_MSG_GET_RESOURCE_RANGE.
+ */
+struct ti_sci_msg_req_get_resource_range {
+	struct ti_sci_msg_hdr hdr;
+#define MSG_RM_RESOURCE_TYPE_MASK	GENMASK(9, 0)
+#define MSG_RM_RESOURCE_SUBTYPE_MASK	GENMASK(5, 0)
+	u16 type;
+	u8 subtype;
+	u8 secondary_host;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_resource_range - Response to resource get range.
+ * @hdr:		Generic Header
+ * @range_start:	Start index of the resource range.
+ * @range_num:		Number of resources in the range.
+ *
+ * Response to request TI_SCI_MSG_GET_RESOURCE_RANGE.
+ */
+struct ti_sci_msg_resp_get_resource_range {
+	struct ti_sci_msg_hdr hdr;
+	u16 range_start;
+	u16 range_num;
+} __packed;
+
 #endif /* __TI_SCI_H */
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index 515587e9d373..0c92a922db6a 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -192,15 +192,42 @@ struct ti_sci_clk_ops {
 			u64 *current_freq);
 };
 
+/**
+ * struct ti_sci_rm_core_ops - Resource management core operations
+ * @get_range:		Get a range of resources belonging to ti sci host.
+ * @get_rage_from_shost:	Get a range of resources belonging to
+ *				specified host id.
+ *			- s_host: Host processing entity to which the
+ *				  resources are allocated
+ *
+ * NOTE: for these functions, all the parameters are consolidated and defined
+ * as below:
+ * - handle:	Pointer to TISCI handle as retrieved by *ti_sci_get_handle
+ * - dev_id:	TISCI device ID.
+ * - subtype:	Resource assignment subtype that is being requested
+ *		from the given device.
+ * - range_start:	Start index of the resource range
+ * - range_end:		Number of resources in the range
+ */
+struct ti_sci_rm_core_ops {
+	int (*get_range)(const struct ti_sci_handle *handle, u32 dev_id,
+			 u8 subtype, u16 *range_start, u16 *range_num);
+	int (*get_range_from_shost)(const struct ti_sci_handle *handle,
+				    u32 dev_id, u8 subtype, u8 s_host,
+				    u16 *range_start, u16 *range_num);
+};
+
 /**
  * struct ti_sci_ops - Function support for TI SCI
  * @dev_ops:	Device specific operations
  * @clk_ops:	Clock specific operations
+ * @rm_core_ops:	Resource management core operations.
  */
 struct ti_sci_ops {
 	struct ti_sci_core_ops core_ops;
 	struct ti_sci_dev_ops dev_ops;
 	struct ti_sci_clk_ops clk_ops;
+	struct ti_sci_rm_core_ops rm_core_ops;
 };
 
 /**
-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 03/10] firmware: ti_sci: Add support for IRQ management
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
  2019-02-12  7:42 ` [PATCH v5 01/10] firmware: ti_sci: Add support to get TISCI handle using of_phandle Lokesh Vutla
  2019-02-12  7:42 ` [PATCH v5 02/10] firmware: ti_sci: Add support for RM core ops Lokesh Vutla
@ 2019-02-12  7:42 ` Lokesh Vutla
  2019-02-12  7:42 ` [PATCH v5 04/10] firmware: ti_sci: Add RM mapping table for am654 Lokesh Vutla
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

TISCI abstracts the handling of IRQ routes where interrupt sources
are not directly connected to host interrupt controller. Add support
for the set of TISCI commands for requesting and releasing IRQs.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
Changes since v4:
- Updated to the latest sysfw APIs where event irq configuration is broken
  down in two parts. One for event to vint map and other for vint to gic map.
- Dropped support for configuring irqs for secondary host to avoid confusion.
  This can be added later once the support is required.

 drivers/firmware/ti_sci.c              | 260 +++++++++++++++++++++++++
 drivers/firmware/ti_sci.h              |  60 ++++++
 include/linux/soc/ti/ti_sci_protocol.h |  28 +++
 3 files changed, 348 insertions(+)

diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index a2a099b8f62a..729fef77379e 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -1782,6 +1782,260 @@ int ti_sci_cmd_get_resource_range_from_shost(const struct ti_sci_handle *handle,
 					 range_start, range_num);
 }
 
+/**
+ * ti_sci_manage_irq() - Helper api to configure/release the irq route between
+ *			 the requested source and destination
+ * @handle:		Pointer to TISCI handle.
+ * @valid_params:	Bit fields defining the validity of certain params
+ * @src_id:		Device ID of the IRQ source
+ * @src_index:		IRQ source index within the source device
+ * @dst_id:		Device ID of the IRQ destination
+ * @dt_host_irq:	IRQ number of the destination device
+ * @ia_id:		Device ID of the IA, if the IRQ flows through this IA
+ * @vint:		Virtual interrupt to be used within the IA
+ * @global_event:	Global event number to be used for the requesting event
+ * @vint_status_bit:	Virtual interrupt status bit to be used for the event
+ * @s_host:		Secondary host ID to which the irq/event is being
+ *			requested for.
+ * @type:		Request type irq set or release.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_manage_irq(const struct ti_sci_handle *handle,
+			     u32 valid_params, u16 src_id, u16 src_index,
+			     u16 dst_id, u16 dst_host_irq, u16 ia_id, u16 vint,
+			     u16 global_event, u8 vint_status_bit, u8 s_host,
+			     u16 type)
+{
+	struct ti_sci_msg_req_manage_irq *req;
+	struct ti_sci_msg_hdr *resp;
+	struct ti_sci_xfer *xfer;
+	struct ti_sci_info *info;
+	struct device *dev;
+	int ret = 0;
+
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+	if (!handle)
+		return -EINVAL;
+
+	info = handle_to_ti_sci_info(handle);
+	dev = info->dev;
+
+	xfer = ti_sci_get_one_xfer(info, type, TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+				   sizeof(*req), sizeof(*resp));
+	if (IS_ERR(xfer)) {
+		ret = PTR_ERR(xfer);
+		dev_err(dev, "Message alloc failed(%d)\n", ret);
+		return ret;
+	}
+	req = (struct ti_sci_msg_req_manage_irq *)xfer->xfer_buf;
+	req->valid_params = valid_params;
+	req->src_id = src_id;
+	req->src_index = src_index;
+	req->dst_id = dst_id;
+	req->dst_host_irq = dst_host_irq;
+	req->ia_id = ia_id;
+	req->vint = vint;
+	req->global_event = global_event;
+	req->vint_status_bit = vint_status_bit;
+	req->secondary_host = s_host;
+
+	ret = ti_sci_do_xfer(info, xfer);
+	if (ret) {
+		dev_err(dev, "Mbox send fail %d\n", ret);
+		goto fail;
+	}
+
+	resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf;
+
+	ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV;
+
+fail:
+	ti_sci_put_one_xfer(&info->minfo, xfer);
+
+	return ret;
+}
+
+/**
+ * ti_sci_set_irq() - Helper api to configure the irq route between the
+ *		      requested source and destination
+ * @handle:		Pointer to TISCI handle.
+ * @valid_params:	Bit fields defining the validity of certain params
+ * @src_id:		Device ID of the IRQ source
+ * @src_index:		IRQ source index within the source device
+ * @dst_id:		Device ID of the IRQ destination
+ * @dt_host_irq:	IRQ number of the destination device
+ * @ia_id:		Device ID of the IA, if the IRQ flows through this IA
+ * @vint:		Virtual interrupt to be used within the IA
+ * @global_event:	Global event number to be used for the requesting event
+ * @vint_status_bit:	Virtual interrupt status bit to be used for the event
+ * @s_host:		Secondary host ID to which the irq/event is being
+ *			requested for.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_set_irq(const struct ti_sci_handle *handle, u32 valid_params,
+			  u16 src_id, u16 src_index, u16 dst_id,
+			  u16 dst_host_irq, u16 ia_id, u16 vint,
+			  u16 global_event, u8 vint_status_bit, u8 s_host)
+{
+	pr_debug("%s: IRQ set with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
+		 __func__, valid_params, src_id, src_index,
+		 dst_id, dst_host_irq, ia_id, vint, global_event,
+		 vint_status_bit);
+
+	return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
+				 dst_id, dst_host_irq, ia_id, vint,
+				 global_event, vint_status_bit, s_host,
+				 TI_SCI_MSG_SET_IRQ);
+}
+
+/**
+ * ti_sci_free_irq() - Helper api to free the irq route between the
+ *			   requested source and destination
+ * @handle:		Pointer to TISCI handle.
+ * @valid_params:	Bit fields defining the validity of certain params
+ * @src_id:		Device ID of the IRQ source
+ * @src_index:		IRQ source index within the source device
+ * @dst_id:		Device ID of the IRQ destination
+ * @dt_host_irq:	IRQ number of the destination device
+ * @ia_id:		Device ID of the IA, if the IRQ flows through this IA
+ * @vint:		Virtual interrupt to be used within the IA
+ * @global_event:	Global event number to be used for the requesting event
+ * @vint_status_bit:	Virtual interrupt status bit to be used for the event
+ * @s_host:		Secondary host ID to which the irq/event is being
+ *			requested for.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_free_irq(const struct ti_sci_handle *handle, u32 valid_params,
+			   u16 src_id, u16 src_index, u16 dst_id,
+			   u16 dst_host_irq, u16 ia_id, u16 vint,
+			   u16 global_event, u8 vint_status_bit, u8 s_host)
+{
+	pr_debug("%s: IRQ release with valid_params = 0x%x from src = %d, index = %d, to dst = %d, irq = %d,via ia_id = %d, vint = %d, global event = %d,status_bit = %d\n",
+		 __func__, valid_params, src_id, src_index,
+		 dst_id, dst_host_irq, ia_id, vint, global_event,
+		 vint_status_bit);
+
+	return ti_sci_manage_irq(handle, valid_params, src_id, src_index,
+				 dst_id, dst_host_irq, ia_id, vint,
+				 global_event, vint_status_bit, s_host,
+				 TI_SCI_MSG_FREE_IRQ);
+}
+
+/**
+ * ti_sci_cmd_set_irq() - Configure a host irq route between the requested
+ *			  source and destination.
+ * @handle:		Pointer to TISCI handle.
+ * @src_id:		Device ID of the IRQ source
+ * @src_index:		IRQ source index within the source device
+ * @dst_id:		Device ID of the IRQ destination
+ * @dt_host_irq:	IRQ number of the destination device
+ * @vint_irq:		Boolean specifying if this interrupt belongs to
+ *			Interrupt Aggregator.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_set_irq(const struct ti_sci_handle *handle, u16 src_id,
+			      u16 src_index, u16 dst_id, u16 dst_host_irq,
+			      bool vint_irq)
+{
+	u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
+
+	if (vint_irq) {
+		valid_params |= MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID;
+		return ti_sci_set_irq(handle, valid_params, 0, 0, dst_id,
+				      dst_host_irq, src_id, src_index, 0, 0, 0);
+	} else {
+		return ti_sci_set_irq(handle, valid_params, src_id, src_index,
+				      dst_id, dst_host_irq, 0, 0, 0, 0, 0);
+	}
+}
+
+/**
+ * ti_sci_cmd_set_event_map() - Configure an event based irq route between the
+ *				requested source and Interrupt Aggregator.
+ * @handle:		Pointer to TISCI handle.
+ * @src_id:		Device ID of the IRQ source
+ * @src_index:		IRQ source index within the source device
+ * @ia_id:		Device ID of the IA, if the IRQ flows through this IA
+ * @vint:		Virtual interrupt to be used within the IA
+ * @global_event:	Global event number to be used for the requesting event
+ * @vint_status_bit:	Virtual interrupt status bit to be used for the event
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_set_event_map(const struct ti_sci_handle *handle,
+				    u16 src_id, u16 src_index, u16 ia_id,
+				    u16 vint, u16 global_event,
+				    u8 vint_status_bit)
+{
+	u32 valid_params = MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID |
+			   MSG_FLAG_GLB_EVNT_VALID |
+			   MSG_FLAG_VINT_STS_BIT_VALID;
+
+	return ti_sci_set_irq(handle, valid_params, src_id, src_index, 0, 0,
+			      ia_id, vint, global_event, vint_status_bit, 0);
+}
+
+/**
+ * ti_sci_cmd_free_irq() - Free a host irq route between the between the
+ *			   requested source and destination.
+ * @handle:		Pointer to TISCI handle.
+ * @src_id:		Device ID of the IRQ source
+ * @src_index:		IRQ source index within the source device
+ * @dst_id:		Device ID of the IRQ destination
+ * @dt_host_irq:	IRQ number of the destination device
+ * @vint_irq:		Boolean specifying if this interrupt belongs to
+ *			Interrupt Aggregator.
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_free_irq(const struct ti_sci_handle *handle, u16 src_id,
+			       u16 src_index, u16 dst_id, u16 dst_host_irq,
+			       bool vint_irq)
+{
+	u32 valid_params = MSG_FLAG_DST_ID_VALID | MSG_FLAG_DST_HOST_IRQ_VALID;
+
+	if (vint_irq) {
+		valid_params |= MSG_FLAG_IA_ID_VALID | MSG_FLAG_VINT_VALID;
+		return ti_sci_free_irq(handle, valid_params, 0, 0, dst_id,
+				       dst_host_irq, src_id, src_index, 0, 0,
+				       0);
+	} else {
+		return ti_sci_free_irq(handle, valid_params, src_id, src_index,
+				       dst_id, dst_host_irq, 0, 0, 0, 0, 0);
+	}
+}
+
+/**
+ * ti_sci_cmd_free_event_map() - Free an event map between the requested source
+ *				 and Interrupt Aggregator.
+ * @handle:		Pointer to TISCI handle.
+ * @src_id:		Device ID of the IRQ source
+ * @src_index:		IRQ source index within the source device
+ * @ia_id:		Device ID of the IA, if the IRQ flows through this IA
+ * @vint:		Virtual interrupt to be used within the IA
+ * @global_event:	Global event number to be used for the requesting event
+ * @vint_status_bit:	Virtual interrupt status bit to be used for the event
+ *
+ * Return: 0 if all went fine, else return appropriate error.
+ */
+static int ti_sci_cmd_free_event_map(const struct ti_sci_handle *handle,
+				     u16 src_id, u16 src_index, u16 ia_id,
+				     u16 vint, u16 global_event,
+				     u8 vint_status_bit)
+{
+	u32 valid_params = MSG_FLAG_IA_ID_VALID |
+			   MSG_FLAG_VINT_VALID | MSG_FLAG_GLB_EVNT_VALID |
+			   MSG_FLAG_VINT_STS_BIT_VALID;
+
+	return ti_sci_free_irq(handle, valid_params, src_id, src_index, 0, 0,
+			       ia_id, vint, global_event, vint_status_bit, 0);
+}
+
 /*
  * ti_sci_setup_ops() - Setup the operations structures
  * @info:	pointer to TISCI pointer
@@ -1793,6 +2047,7 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
 	struct ti_sci_dev_ops *dops = &ops->dev_ops;
 	struct ti_sci_clk_ops *cops = &ops->clk_ops;
 	struct ti_sci_rm_core_ops *rm_core_ops = &ops->rm_core_ops;
+	struct ti_sci_rm_irq_ops *iops = &ops->rm_irq_ops;
 
 	core_ops->reboot_device = ti_sci_cmd_core_reboot;
 
@@ -1827,6 +2082,11 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
 	rm_core_ops->get_range = ti_sci_cmd_get_resource_range;
 	rm_core_ops->get_range_from_shost =
 				ti_sci_cmd_get_resource_range_from_shost;
+
+	iops->set_irq = ti_sci_cmd_set_irq;
+	iops->set_event_map = ti_sci_cmd_set_event_map;
+	iops->free_irq = ti_sci_cmd_free_irq;
+	iops->free_event_map = ti_sci_cmd_free_event_map;
 }
 
 /**
diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h
index a043c4762791..4983827151bf 100644
--- a/drivers/firmware/ti_sci.h
+++ b/drivers/firmware/ti_sci.h
@@ -38,6 +38,10 @@
 /* Resource Management Requests */
 #define TI_SCI_MSG_GET_RESOURCE_RANGE	0x1500
 
+/* IRQ requests */
+#define TI_SCI_MSG_SET_IRQ		0x1000
+#define TI_SCI_MSG_FREE_IRQ		0x1001
+
 /**
  * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
  * @type:	Type of messages: One of TI_SCI_MSG* values
@@ -503,4 +507,60 @@ struct ti_sci_msg_resp_get_resource_range {
 	u16 range_num;
 } __packed;
 
+/**
+ * struct ti_sci_msg_req_manage_irq - Request to configure/release the route
+ *					between the dev and the host.
+ * @hdr:		Generic Header
+ * @valid_params:	Bit fields defining the validity of interrupt source
+ *			parameters. If a bit is not set, then corresponding
+ *			field is not valid and will not be used for route set.
+ *			Bit field definitions:
+ *			0 - Valid bit for @dst_id
+ *			1 - Valid bit for @dst_host_irq
+ *			2 - Valid bit for @ia_id
+ *			3 - Valid bit for @vint
+ *			4 - Valid bit for @global_event
+ *			5 - Valid bit for @vint_status_bit_index
+ *			31 - Valid bit for @secondary_host
+ * @src_id:		IRQ source peripheral ID.
+ * @src_index:		IRQ source index within the peripheral
+ * @dst_id:		IRQ Destination ID. Based on the architecture it can be
+ *			IRQ controller or host processor ID.
+ * @dst_host_irq:	IRQ number of the destination host IRQ controller
+ * @ia_id:		Device ID of the interrupt aggregator in which the
+ *			vint resides.
+ * @vint:		Virtual interrupt number if the interrupt route
+ *			is through an interrupt aggregator.
+ * @global_event:	Global event that is to be mapped to interrupt
+ *			aggregator virtual interrupt status bit.
+ * @vint_status_bit:	Virtual interrupt status bit if the interrupt route
+ *			utilizes an interrupt aggregator status bit.
+ * @secondary_host:	Host ID of the IRQ destination computing entity. This is
+ *			required only when destination host id is different
+ *			from ti sci interface host id.
+ *
+ * Request type is TI_SCI_MSG_SET/RELEASE_IRQ.
+ * Response is generic ACK / NACK message.
+ */
+struct ti_sci_msg_req_manage_irq {
+	struct ti_sci_msg_hdr hdr;
+#define MSG_FLAG_DST_ID_VALID			TI_SCI_MSG_FLAG(0)
+#define MSG_FLAG_DST_HOST_IRQ_VALID		TI_SCI_MSG_FLAG(1)
+#define MSG_FLAG_IA_ID_VALID			TI_SCI_MSG_FLAG(2)
+#define MSG_FLAG_VINT_VALID			TI_SCI_MSG_FLAG(3)
+#define MSG_FLAG_GLB_EVNT_VALID			TI_SCI_MSG_FLAG(4)
+#define MSG_FLAG_VINT_STS_BIT_VALID		TI_SCI_MSG_FLAG(5)
+#define MSG_FLAG_SHOST_VALID			TI_SCI_MSG_FLAG(31)
+	u32 valid_params;
+	u16 src_id;
+	u16 src_index;
+	u16 dst_id;
+	u16 dst_host_irq;
+	u16 ia_id;
+	u16 vint;
+	u16 global_event;
+	u8 vint_status_bit;
+	u8 secondary_host;
+} __packed;
+
 #endif /* __TI_SCI_H */
diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h
index 0c92a922db6a..a0216c947acd 100644
--- a/include/linux/soc/ti/ti_sci_protocol.h
+++ b/include/linux/soc/ti/ti_sci_protocol.h
@@ -217,17 +217,45 @@ struct ti_sci_rm_core_ops {
 				    u16 *range_start, u16 *range_num);
 };
 
+/**
+ * struct ti_sci_rm_irq_ops: IRQ management operations
+ * @set_irq:		Set an IRQ route between the requested source
+ *			and destination
+ * @set_event_map:	Set an Event based peripheral irq to Interrupt
+ *			Aggregator.
+ * @free_irq:		Free an an IRQ route between the requested source
+ *			destination.
+ * @free_event_map:	Free an event based peripheral irq to Interrupt
+ *			Aggregator.
+ */
+struct ti_sci_rm_irq_ops {
+	int (*set_irq)(const struct ti_sci_handle *handle, u16 src_id,
+		       u16 src_index, u16 dst_id, u16 dst_host_irq,
+		       bool vint_irq);
+	int (*set_event_map)(const struct ti_sci_handle *handle, u16 src_id,
+			     u16 src_index, u16 ia_id, u16 vint,
+			     u16 global_event, u8 vint_status_bit);
+	int (*free_irq)(const struct ti_sci_handle *handle, u16 src_id,
+			u16 src_index, u16 dst_id, u16 dst_host_irq,
+			bool vint_irq);
+	int (*free_event_map)(const struct ti_sci_handle *handle, u16 src_id,
+			      u16 src_index, u16 ia_id, u16 vint,
+			      u16 global_event, u8 vint_status_bit);
+};
+
 /**
  * struct ti_sci_ops - Function support for TI SCI
  * @dev_ops:	Device specific operations
  * @clk_ops:	Clock specific operations
  * @rm_core_ops:	Resource management core operations.
+ * @rm_irq_ops:		IRQ management specific operations
  */
 struct ti_sci_ops {
 	struct ti_sci_core_ops core_ops;
 	struct ti_sci_dev_ops dev_ops;
 	struct ti_sci_clk_ops clk_ops;
 	struct ti_sci_rm_core_ops rm_core_ops;
+	struct ti_sci_rm_irq_ops rm_irq_ops;
 };
 
 /**
-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 04/10] firmware: ti_sci: Add RM mapping table for am654
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
                   ` (2 preceding siblings ...)
  2019-02-12  7:42 ` [PATCH v5 03/10] firmware: ti_sci: Add support for IRQ management Lokesh Vutla
@ 2019-02-12  7:42 ` Lokesh Vutla
  2019-02-12  7:42 ` [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings Lokesh Vutla
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

From: Peter Ujfalusi <peter.ujfalusi@ti.com>

Add the resource mapping table for AM654 SoC as defined
in http://downloads.ti.com/tisci/esd/latest/5_soc_doc/am6x/resasg_types.html
Introduce a new compatible for AM654 "ti,am654-sci" for using
this resource map table.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
Changes since v4:
- None

 .../bindings/arm/keystone/ti,sci.txt          |  3 ++-
 drivers/firmware/ti_sci.c                     | 23 +++++++++++++++++++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt b/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
index b56a02c10ae6..6f0cd31c1520 100644
--- a/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+++ b/Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
@@ -24,7 +24,8 @@ relationship between the TI-SCI parent node to the child node.
 
 Required properties:
 -------------------
-- compatible: should be "ti,k2g-sci"
+- compatible:	should be "ti,k2g-sci" for TI 66AK2G SoC
+		should be "ti,am654-sci" for for TI AM654 SoC
 - mbox-names:
 	"rx" - Mailbox corresponding to receive path
 	"tx" - Mailbox corresponding to transmit path
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index 729fef77379e..7f6fed374973 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -2314,10 +2314,33 @@ static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = {
 	/* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
 	.max_msgs = 20,
 	.max_msg_size = 64,
+	.rm_type_map = NULL,
+};
+
+static struct ti_sci_rm_type_map ti_sci_am654_rm_type_map[] = {
+	{.dev_id = 56, .type = 0x00b}, /* GIC_IRQ */
+	{.dev_id = 179, .type = 0x000}, /* MAIN_NAV_UDMASS_IA0 */
+	{.dev_id = 187, .type = 0x009}, /* MAIN_NAV_RA */
+	{.dev_id = 188, .type = 0x006}, /* MAIN_NAV_UDMAP */
+	{.dev_id = 194, .type = 0x007}, /* MCU_NAV_UDMAP */
+	{.dev_id = 195, .type = 0x00a}, /* MCU_NAV_RA */
+	{.dev_id = 0, .type = 0x000}, /* end of table */
+};
+
+/* Description for AM654 */
+static const struct ti_sci_desc ti_sci_pmmc_am654_desc = {
+	.default_host_id = 12,
+	/* Conservative duration */
+	.max_rx_timeout_ms = 10000,
+	/* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */
+	.max_msgs = 20,
+	.max_msg_size = 60,
+	.rm_type_map = ti_sci_am654_rm_type_map,
 };
 
 static const struct of_device_id ti_sci_of_match[] = {
 	{.compatible = "ti,k2g-sci", .data = &ti_sci_pmmc_k2g_desc},
+	{.compatible = "ti,am654-sci", .data = &ti_sci_pmmc_am654_desc},
 	{ /* Sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, ti_sci_of_match);
-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
                   ` (3 preceding siblings ...)
  2019-02-12  7:42 ` [PATCH v5 04/10] firmware: ti_sci: Add RM mapping table for am654 Lokesh Vutla
@ 2019-02-12  7:42 ` Lokesh Vutla
  2019-02-12 16:22   ` Tony Lindgren
                     ` (3 more replies)
  2019-02-12  7:42 ` [PATCH v5 06/10] irqchip: ti-sci-intr: Add support for Interrupt Router driver Lokesh Vutla
                   ` (5 subsequent siblings)
  10 siblings, 4 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

Add the DT binding documentation for Interrupt router driver.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
Changes since v4:
- None

 .../interrupt-controller/ti,sci-intr.txt      | 85 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 86 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
new file mode 100644
index 000000000000..4b0ca797fda1
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
@@ -0,0 +1,85 @@
+Texas Instruments K3 Interrupt Router
+=====================================
+
+The Interrupt Router (INTR) module provides a mechanism to route M
+interrupt inputs to N interrupt outputs, where all M inputs are selectable
+to be driven per N output. There is one register per output (MUXCNTL_N) that
+controls the selection.
+
+
+                                 Interrupt Router
+                             +----------------------+
+                             |  Inputs     Outputs  |
+        +-------+            | +------+             |
+        | GPIO  |----------->| | irq0 |             |       Host IRQ
+        +-------+            | +------+             |      controller
+                             |    .        +-----+  |      +-------+
+        +-------+            |    .        |  0  |  |----->|  IRQ  |
+        | INTA  |----------->|    .        +-----+  |      +-------+
+        +-------+            |    .          .      |
+                             | +------+      .      |
+                             | | irqM |    +-----+  |
+                             | +------+    |  N  |  |
+                             |             +-----+  |
+                             +----------------------+
+
+Configuration of these MUXCNTL_N registers is done by a system controller
+(like the Device Memory and Security Controller on K3 AM654 SoC). System
+controller will keep track of the used and unused registers within the Router.
+Driver should request the system controller to get the range of GIC IRQs
+assigned to the requesting hosts. It is the drivers responsibility to keep
+track of Host IRQs.
+
+Communication between the host processor running an OS and the system
+controller happens through a protocol called TI System Control Interface
+(TISCI protocol). For more details refer:
+Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+
+TISCI Interrupt Router Node:
+----------------------------
+- compatible:		Must be "ti,sci-intr".
+- interrupt-controller:	Identifies the node as an interrupt controller
+- #interrupt-cells:	Specifies the number of cells needed to encode an
+			interrupt source. The value should be 4.
+			First cell should contain the TISCI device ID of source
+			Second cell should contain the interrupt source offset
+			within the device
+			Third cell specifies the trigger type as defined
+			in interrupts.txt in this directory.
+			Fourth cell should be 1 if the irq is coming from
+			interrupt aggregator else 0.
+- ti,sci:		Phandle to TI-SCI compatible System controller node.
+- ti,sci-dst-id:	TISCI device ID of the destination IRQ controller.
+- ti,sci-rm-range-girq:	Array of TISCI subtype ids representing the host irqs
+			assigned to this interrupt router. Each subtype id
+			corresponds to a range of host irqs.
+
+For more details on TISCI IRQ resource management refer:
+http://downloads.ti.com/tisci/esd/latest/2_tisci_msgs/rm/rm_irq.html
+
+Example:
+--------
+The following example demonstrates both interrupt router node and the consumer
+node(main gpio) on the AM654 SoC:
+
+main_intr: interrupt-controller0 {
+	compatible = "ti,sci-intr";
+	interrupt-controller;
+	interrupt-parent = <&gic500>;
+	#interrupt-cells = <4>;
+	ti,sci = <&dmsc>;
+	ti,sci-dst-id = <56>;
+	ti,sci-rm-range-girq = <0x1>;
+};
+
+main_gpio0: gpio@600000 {
+	...
+	interrupt-parent = <&main_intr>;
+	interrupts = <57 256 IRQ_TYPE_EDGE_RISING 0>,
+			<57 257 IRQ_TYPE_EDGE_RISING 0>,
+			<57 258 IRQ_TYPE_EDGE_RISING 0>,
+			<57 259 IRQ_TYPE_EDGE_RISING 0>,
+			<57 260 IRQ_TYPE_EDGE_RISING 0>,
+			<57 261 IRQ_TYPE_EDGE_RISING 0>;
+	...
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 8c68de3cfd80..c918d9b2ee18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15064,6 +15064,7 @@ F:	Documentation/devicetree/bindings/reset/ti,sci-reset.txt
 F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 F:	drivers/clk/keystone/sci-clk.c
 F:	drivers/reset/reset-ti-sci.c
+F:	Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
 
 Texas Instruments ASoC drivers
 M:	Peter Ujfalusi <peter.ujfalusi@ti.com>
-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 06/10] irqchip: ti-sci-intr: Add support for Interrupt Router driver
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
                   ` (4 preceding siblings ...)
  2019-02-12  7:42 ` [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings Lokesh Vutla
@ 2019-02-12  7:42 ` Lokesh Vutla
  2019-02-18 15:52   ` Marc Zyngier
  2019-02-12  7:42 ` [PATCH v5 07/10] dt-bindings: irqchip: Introduce TISCI Interrupt Aggregator bindings Lokesh Vutla
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

Texas Instruments' K3 generation SoCs has an IP Interrupt Router
that does allows for redirection of input interrupts to host
interrupt controller. Interrupt Router inputs are either from a
peripheral or from an Interrupt Aggregator which is another
interrupt controller.

Configuration of the interrupt router registers can only be done by
a system co-processor and the driver needs to send a message to this
co processor over TISCI protocol.

Add support for Interrupt Router driver over TISCI protocol.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
Changes since v4:
- Moved the ti_sci irq resource handling to ti-sci-common.c from ti_sci.c.
  Firmware maintainer rejected the idea of having this in firmware driver as
  the resource handling is specific to the client.
- Obtain the number of peripheral interrupts attached to INTR by parsing DT.
  Using this information store the max irqs that can be allocated to INTA.
  This is done for pre allocating the INTA irqs(vints) during inta driver
  probe.
  This will not work for cases where there are more that 1 INTAs attached to
  INTR, but wanted to show this approach as suggested by Marc.

 MAINTAINERS                         |   3 +
 drivers/irqchip/Kconfig             |  11 +
 drivers/irqchip/Makefile            |   1 +
 drivers/irqchip/irq-ti-sci-common.c | 131 ++++++++++++
 drivers/irqchip/irq-ti-sci-common.h |  59 ++++++
 drivers/irqchip/irq-ti-sci-intr.c   | 315 ++++++++++++++++++++++++++++
 6 files changed, 520 insertions(+)
 create mode 100644 drivers/irqchip/irq-ti-sci-common.c
 create mode 100644 drivers/irqchip/irq-ti-sci-common.h
 create mode 100644 drivers/irqchip/irq-ti-sci-intr.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c918d9b2ee18..823eeb672cf0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15065,6 +15065,9 @@ F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 F:	drivers/clk/keystone/sci-clk.c
 F:	drivers/reset/reset-ti-sci.c
 F:	Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
+F:	drivers/irqchip/irq-ti-sci-intr.c
+F:	drivers/irqchip/irq-ti-sci-common.c
+F:	drivers/irqchip/irq-ti-sci-common.h
 
 Texas Instruments ASoC drivers
 M:	Peter Ujfalusi <peter.ujfalusi@ti.com>
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3d1e60779078..a8d9bed0254b 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -406,6 +406,17 @@ config IMX_IRQSTEER
 	help
 	  Support for the i.MX IRQSTEER interrupt multiplexer/remapper.
 
+config TI_SCI_INTR_IRQCHIP
+	bool
+	depends on TI_SCI_PROTOCOL && ARCH_K3
+	select IRQ_DOMAIN
+	select IRQ_DOMAIN_HIERARCHY
+	help
+	  This enables the irqchip driver support for K3 Interrupt router
+	  over TI System Control Interface available on some new TI's SoCs.
+	  If you wish to use interrupt router irq resources managed by the
+	  TI System Controller, say Y here. Otherwise, say N.
+
 endmenu
 
 config SIFIVE_PLIC
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c93713d24b86..0499fae148a9 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -94,3 +94,4 @@ obj-$(CONFIG_CSKY_APB_INTC)		+= irq-csky-apb-intc.o
 obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
 obj-$(CONFIG_MADERA_IRQ)		+= irq-madera.o
+obj-$(CONFIG_TI_SCI_INTR_IRQCHIP)	+= irq-ti-sci-intr.o irq-ti-sci-common.o
diff --git a/drivers/irqchip/irq-ti-sci-common.c b/drivers/irqchip/irq-ti-sci-common.c
new file mode 100644
index 000000000000..79d9c4e8ea14
--- /dev/null
+++ b/drivers/irqchip/irq-ti-sci-common.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Common Code for TISCI IRQCHIP drivers
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *	Lokesh Vutla <lokeshvutla@ti.com>
+ */
+
+#include <linux/of.h>
+#include <linux/bitmap.h>
+#include <linux/device.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+#include "irq-ti-sci-common.h"
+
+/**
+ * ti_sci_get_free_resource() - Get a free resource from TISCI resource.
+ * @res:	Pointer to the TISCI resource
+ *
+ * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL.
+ */
+u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
+{
+	u16 set, free_bit;
+
+	mutex_lock(&res->request_mutex);
+	for (set = 0; set < res->sets; set++) {
+		free_bit = find_first_zero_bit(res->desc[set].res_map,
+					       res->desc[set].num);
+		if (free_bit != res->desc[set].num) {
+			set_bit(free_bit, res->desc[set].res_map);
+			mutex_unlock(&res->request_mutex);
+			return res->desc[set].start + free_bit;
+		}
+	}
+	mutex_unlock(&res->request_mutex);
+
+	return TI_SCI_RESOURCE_NULL;
+}
+
+/**
+ * ti_sci_release_resource() - Release a resource from TISCI resource.
+ * @res:	Pointer to the TISCI resource
+ * @id:		Resource id to be released.
+ */
+void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
+{
+	u16 set;
+
+	mutex_lock(&res->request_mutex);
+	for (set = 0; set < res->sets; set++) {
+		if (res->desc[set].start <= id &&
+		    (res->desc[set].num + res->desc[set].start) > id)
+			clear_bit(id - res->desc[set].start,
+				  res->desc[set].res_map);
+	}
+	mutex_unlock(&res->request_mutex);
+}
+
+u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
+{
+	u32 count = 0, set;
+
+	for (set = 0; set < res->sets; set++)
+		count += res->desc[set].num;
+
+	return count;
+}
+
+/**
+ * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to a device
+ * @handle:	TISCI handle
+ * @dev:	Device pointer to which the resource is assigned
+ * @of_prop:	property name by which the resource are represented
+ *
+ * Return: Pointer to ti_sci_resource if all went well else appropriate
+ *	   error pointer.
+ */
+struct ti_sci_resource *
+devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
+			    struct device *dev, u32 dev_id, char *of_prop)
+{
+	struct ti_sci_resource *res;
+	u32 resource_subtype;
+	int i, ret;
+
+	res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
+	if (!res)
+		return ERR_PTR(-ENOMEM);
+
+	res->sets = of_property_count_elems_of_size(dev_of_node(dev), of_prop,
+						    sizeof(u32));
+	if (res->sets < 0) {
+		dev_err(dev, "%s resource type ids not available\n", of_prop);
+		return ERR_PTR(res->sets);
+	}
+
+	res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
+				 GFP_KERNEL);
+	if (!res->desc)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < res->sets; i++) {
+		ret = of_property_read_u32_index(dev_of_node(dev), of_prop, i,
+						 &resource_subtype);
+		if (ret)
+			return ERR_PTR(-EINVAL);
+
+		ret = handle->ops.rm_core_ops.get_range(handle, dev_id,
+							resource_subtype,
+							&res->desc[i].start,
+							&res->desc[i].num);
+		if (ret) {
+			dev_err(dev, "dev = %d subtype %d not allocated for this host\n",
+				dev_id, resource_subtype);
+			return ERR_PTR(ret);
+		}
+
+		dev_dbg(dev, "dev = %d, subtype = %d, start = %d, num = %d\n",
+			dev_id, resource_subtype, res->desc[i].start,
+			res->desc[i].num);
+
+		res->desc[i].res_map =
+			devm_kzalloc(dev, BITS_TO_LONGS(res->desc[i].num) *
+				     sizeof(*res->desc[i].res_map), GFP_KERNEL);
+		if (!res->desc[i].res_map)
+			return ERR_PTR(-ENOMEM);
+	}
+	mutex_init(&res->request_mutex);
+
+	return res;
+}
diff --git a/drivers/irqchip/irq-ti-sci-common.h b/drivers/irqchip/irq-ti-sci-common.h
new file mode 100644
index 000000000000..60c4b28bebab
--- /dev/null
+++ b/drivers/irqchip/irq-ti-sci-common.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Common header file for TISCI IRQCHIP drivers
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *	Lokesh Vutla <lokeshvutla@ti.com>
+ */
+
+#ifndef __TI_SCI_COMMON_IRQCHIP_H
+#define __TI_SCI_COMMON_IRQCHIP_H
+
+#include <linux/mutex.h>
+
+#define TI_SCI_RESOURCE_NULL	0xffff
+#define TI_SCI_DEV_ID_MASK	0xffff
+#define TI_SCI_DEV_ID_SHIFT	16
+#define TI_SCI_IRQ_ID_MASK	0xffff
+#define TI_SCI_IRQ_ID_SHIFT	0
+#define TI_SCI_VINT_IRQ		BIT(0)
+#define HWIRQ_TO_DEVID(hwirq)	(((hwirq) >> (TI_SCI_DEV_ID_SHIFT)) & \
+				 (TI_SCI_DEV_ID_MASK))
+#define HWIRQ_TO_IRQID(hwirq)	((hwirq) & (TI_SCI_IRQ_ID_MASK))
+#define TO_HWIRQ(dev, index)	((((dev) & TI_SCI_DEV_ID_MASK) << \
+				 TI_SCI_DEV_ID_SHIFT) | \
+				((index) & TI_SCI_IRQ_ID_MASK))
+
+/**
+ * struct ti_sci_resource_desc - Description of TI SCI resource instance range.
+ * @start:	Start index of the resource.
+ * @num:	Number of resources.
+ * @res_map:	Bitmap to manage the allocation of these resources.
+ */
+struct ti_sci_resource_desc {
+	u16 start;
+	u16 num;
+	unsigned long *res_map;
+};
+
+/**
+ * struct ti_sci_resource - Structure representing a resource assigned
+ *			    to a device.
+ * @sets:		Number of sets available from this resource type
+ * @request_mutex:	mutex to protect request and release of resources.
+ * @desc:		Array of resource descriptors.
+ */
+struct ti_sci_resource {
+	u16 sets;
+	/* Mutex to protect request and release of resources */
+	struct mutex request_mutex;
+	struct ti_sci_resource_desc *desc;
+};
+
+u16 ti_sci_get_free_resource(struct ti_sci_resource *res);
+void ti_sci_release_resource(struct ti_sci_resource *res, u16 id);
+u32 ti_sci_get_num_resources(struct ti_sci_resource *res);
+struct ti_sci_resource *
+devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
+			    struct device *dev, u32 dev_id, char *of_prop);
+#endif /*__TI_SCI_COMMON_IRQCHIP_H */
diff --git a/drivers/irqchip/irq-ti-sci-intr.c b/drivers/irqchip/irq-ti-sci-intr.c
new file mode 100644
index 000000000000..7e224552a735
--- /dev/null
+++ b/drivers/irqchip/irq-ti-sci-intr.c
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Texas Instruments' K3 Interrupt Router irqchip driver
+ *
+ * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
+ *	Lokesh Vutla <lokeshvutla@ti.com>
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/irqdomain.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+#include "irq-ti-sci-common.h"
+
+/**
+ * struct ti_sci_intr_irq_domain - Structure representing a TISCI based
+ *				   Interrupt Router IRQ domain.
+ * @sci:	Pointer to TISCI handle
+ * @dst_irq:	TISCI resource pointer representing GIC irq controller.
+ * @vint_irqs:	Number of GIC irqs that can be allocated to INTA.
+ * @dst_id:	TISCI device ID of the GIC irq controller.
+ */
+struct ti_sci_intr_irq_domain {
+	const struct ti_sci_handle *sci;
+	struct ti_sci_resource *dst_irq;
+	u32 vint_irqs;
+	u16 dst_id;
+};
+
+static struct irq_chip ti_sci_intr_irq_chip = {
+	.name			= "INTR",
+	.irq_eoi		= irq_chip_eoi_parent,
+	.irq_mask		= irq_chip_mask_parent,
+	.irq_unmask		= irq_chip_unmask_parent,
+	.irq_retrigger		= irq_chip_retrigger_hierarchy,
+	.irq_set_type		= irq_chip_set_type_parent,
+	.irq_set_affinity	= irq_chip_set_affinity_parent,
+};
+
+/**
+ * ti_sci_intr_irq_domain_translate() - Retrieve hwirq and type from
+ *					IRQ firmware specific handler.
+ * @domain:	Pointer to IRQ domain
+ * @fwspec:	Pointer to IRQ specific firmware structure
+ * @hwirq:	IRQ number identified by hardware
+ * @type:	IRQ type
+ *
+ * Return 0 if all went ok else appropriate error.
+ */
+static int ti_sci_intr_irq_domain_translate(struct irq_domain *domain,
+					    struct irq_fwspec *fwspec,
+					    unsigned long *hwirq,
+					    unsigned int *type)
+{
+	struct ti_sci_intr_irq_domain *intr = domain->host_data;
+
+	if (fwspec->param_count != 4)
+		return -EINVAL;
+
+	*hwirq = TO_HWIRQ(fwspec->param[0], fwspec->param[1]);
+	*type = fwspec->param[2];
+
+	if (fwspec->param[3] != 0 && fwspec->param[3] != 1)
+		return -EINVAL;
+
+	if (fwspec->param[3] && intr->vint_irqs <= 0)
+		return -ERANGE;
+
+	return 0;
+}
+
+static inline void ti_sci_intr_free_gic_irq(struct ti_sci_intr_irq_domain *intr,
+					    u32 hwirq, u16 dst_irq, u8 vint_irq)
+{
+	u16 src_id, src_index;
+
+	src_id = HWIRQ_TO_DEVID(hwirq);
+	src_index = HWIRQ_TO_IRQID(hwirq);
+	intr->sci->ops.rm_irq_ops.free_irq(intr->sci, src_id, src_index,
+					   intr->dst_id, dst_irq, vint_irq);
+	ti_sci_release_resource(intr->dst_irq, dst_irq);
+	if (vint_irq == TI_SCI_VINT_IRQ)
+		intr->vint_irqs++;
+}
+
+/**
+ * ti_sci_intr_irq_domain_free() - Free the specified IRQs from the domain.
+ * @domain:	Domain to which the irqs belong
+ * @virq:	Linux virtual IRQ to be freed.
+ * @nr_irqs:	Number of continuous irqs to be freed
+ */
+static void ti_sci_intr_irq_domain_free(struct irq_domain *domain,
+					unsigned int virq, unsigned int nr_irqs)
+{
+	struct ti_sci_intr_irq_domain *intr = domain->host_data;
+	struct irq_data *data, *parent_data;
+	phys_addr_t vint_irq;
+
+	data = irq_domain_get_irq_data(domain, virq);
+	vint_irq = (phys_addr_t)irq_data_get_irq_chip_data(data);
+	parent_data = irq_domain_get_irq_data(domain->parent, virq);
+
+	ti_sci_intr_free_gic_irq(intr, data->hwirq, parent_data->hwirq,
+				 vint_irq);
+	irq_domain_free_irqs_parent(domain, virq, 1);
+	irq_domain_reset_irq_data(data);
+}
+
+/**
+ * ti_sci_intr_alloc_gic_irq() - Allocate GIC specific IRQ
+ * @domain:	Point to the interrupt router IRQ domain
+ * @virq:	Corresponding Linux virtual IRQ number
+ * @dev:	TISCI device IRQ generating the IRQ
+ * @irq:	IRQ offset within the device
+ * @flags:	Corresponding flags to the IRQ
+ * @vint_irq:	Flag to tell if requested irq is from interrupt aggregator.
+ *
+ * Returns 0 if all went well else appropriate error pointer.
+ */
+static int ti_sci_intr_alloc_gic_irq(struct irq_domain *domain,
+				     unsigned int virq, u32 hwirq, u32 flags,
+				     u8 vint_irq)
+{
+	struct ti_sci_intr_irq_domain *intr = domain->host_data;
+	struct irq_fwspec fwspec;
+	u16 src_id, src_index;
+	u16 dst_irq;
+	int err;
+
+	src_id = HWIRQ_TO_DEVID(hwirq);
+	src_index = HWIRQ_TO_IRQID(hwirq);
+
+	dst_irq = ti_sci_get_free_resource(intr->dst_irq);
+	if (dst_irq == TI_SCI_RESOURCE_NULL)
+		return -EINVAL;
+
+	fwspec.fwnode = domain->parent->fwnode;
+	fwspec.param_count = 3;
+	fwspec.param[0] = 0;	/* SPI */
+	fwspec.param[1] = dst_irq - 32; /* SPI offset */
+	fwspec.param[2] = flags & IRQ_TYPE_SENSE_MASK;
+
+	err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
+	if (err)
+		goto err_irqs;
+
+	err = intr->sci->ops.rm_irq_ops.set_irq(intr->sci, src_id, src_index,
+						intr->dst_id, dst_irq,
+						vint_irq);
+	if (err)
+		goto err_msg;
+
+	if (vint_irq == TI_SCI_VINT_IRQ)
+		intr->vint_irqs--;
+
+	return 0;
+
+err_msg:
+	irq_domain_free_irqs_parent(domain, virq, 1);
+err_irqs:
+	ti_sci_release_resource(intr->dst_irq, dst_irq);
+	return err;
+}
+
+/**
+ * ti_sci_intr_irq_domain_alloc() - Allocate Interrupt router IRQs
+ * @domain:	Point to the interrupt router IRQ domain
+ * @virq:	Corresponding Linux virtual IRQ number
+ * @nr_irqs:	Continuous irqs to be allocated
+ * @data:	Pointer to firmware specifier
+ *
+ * Return 0 if all went well else appropriate error value.
+ */
+static int ti_sci_intr_irq_domain_alloc(struct irq_domain *domain,
+					unsigned int virq, unsigned int nr_irqs,
+					void *data)
+{
+	struct irq_fwspec *fwspec = data;
+	phys_addr_t vint_irq;
+	unsigned long hwirq;
+	u32 type;
+	int err;
+
+	err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &type);
+	if (err)
+		return err;
+
+	vint_irq = fwspec->param[3] & TI_SCI_VINT_IRQ;
+
+	err = ti_sci_intr_alloc_gic_irq(domain, virq, hwirq, type, vint_irq);
+	if (err)
+		return err;
+
+	err = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
+					    &ti_sci_intr_irq_chip,
+					    (void *)vint_irq);
+	if (err) {
+		ti_sci_intr_irq_domain_free(domain, virq, 1);
+		return err;
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops ti_sci_intr_irq_domain_ops = {
+	.alloc		= ti_sci_intr_irq_domain_alloc,
+	.free		= ti_sci_intr_irq_domain_free,
+	.translate	= ti_sci_intr_irq_domain_translate,
+};
+
+static int ti_sci_intr_irq_domain_probe(struct platform_device *pdev)
+{
+	struct irq_domain *parent_domain, *domain;
+	struct device_node *parent_node, *dn;
+	struct ti_sci_intr_irq_domain *intr;
+	struct device *dev = &pdev->dev;
+	struct of_phandle_iterator it;
+	int ret, count, intsize;
+
+	parent_node = of_irq_find_parent(dev_of_node(dev));
+	if (!parent_node) {
+		dev_err(dev, "Failed to get IRQ parent node\n");
+		return -ENODEV;
+	}
+
+	parent_domain = irq_find_host(parent_node);
+	if (!parent_domain) {
+		dev_err(dev, "Failed to find IRQ parent domain\n");
+		return -ENODEV;
+	}
+
+	intr = devm_kzalloc(dev, sizeof(*intr), GFP_KERNEL);
+	if (!intr)
+		return -ENOMEM;
+
+	intr->sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
+	if (IS_ERR(intr->sci)) {
+		ret = PTR_ERR(intr->sci);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "ti,sci read fail %d\n", ret);
+		intr->sci = NULL;
+		return ret;
+	}
+
+	ret = of_property_read_u32(dev_of_node(dev), "ti,sci-dst-id",
+				   (u32 *)&intr->dst_id);
+	if (ret) {
+		dev_err(dev, "missing 'ti,sci-dst-id' property\n");
+		return -EINVAL;
+	}
+
+	intr->dst_irq = devm_ti_sci_get_of_resource(intr->sci, dev,
+						    intr->dst_id,
+						    "ti,sci-rm-range-girq");
+	if (IS_ERR(intr->dst_irq)) {
+		dev_err(dev, "Destination irq resource allocation failed\n");
+		return PTR_ERR(intr->dst_irq);
+	}
+
+	domain = irq_domain_add_hierarchy(parent_domain, 0, 0, dev_of_node(dev),
+					  &ti_sci_intr_irq_domain_ops, intr);
+	if (!domain) {
+		dev_err(dev, "Failed to allocate IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	if (of_property_read_u32(dev_of_node(dev), "#interrupt-cells",
+				 &intsize))
+		return -EINVAL;
+
+	count = 0;
+	for_each_node_with_property(dn, "interrupts") {
+		if (of_irq_find_parent(dn) != dev_of_node(dev))
+			continue;
+		count += of_property_count_elems_of_size(dn, "interrupts",
+							 sizeof(u32) * intsize);
+	}
+
+	for_each_node_with_property(dn, "interrupts-extended") {
+		of_for_each_phandle(&it, ret, dn, "interrupts-extended",
+				    "#interrupt-cells", 0) {
+			if (it.node == dev_of_node(dev))
+				count++;
+		}
+	}
+
+	intr->vint_irqs = ti_sci_get_num_resources(intr->dst_irq) - count;
+
+	return 0;
+}
+
+static const struct of_device_id ti_sci_intr_irq_domain_of_match[] = {
+	{ .compatible = "ti,sci-intr", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ti_sci_intr_irq_domain_of_match);
+
+static struct platform_driver ti_sci_intr_irq_domain_driver = {
+	.probe = ti_sci_intr_irq_domain_probe,
+	.driver = {
+		.name = "ti-sci-intr",
+		.of_match_table = ti_sci_intr_irq_domain_of_match,
+	},
+};
+module_platform_driver(ti_sci_intr_irq_domain_driver);
+
+MODULE_AUTHOR("Lokesh Vutla <lokeshvutla@ticom>");
+MODULE_DESCRIPTION("K3 Interrupt Router driver over TI SCI protocol");
+MODULE_LICENSE("GPL v2");
-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 07/10] dt-bindings: irqchip: Introduce TISCI Interrupt Aggregator bindings
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
                   ` (5 preceding siblings ...)
  2019-02-12  7:42 ` [PATCH v5 06/10] irqchip: ti-sci-intr: Add support for Interrupt Router driver Lokesh Vutla
@ 2019-02-12  7:42 ` Lokesh Vutla
  2019-02-12  7:42 ` [PATCH v5 08/10] irqchip: ti-sci-inta: Add support for Interrupt Aggregator driver Lokesh Vutla
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

Add the DT binding documentation for Interrupt Aggregator driver.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
Changes sine v4:
- None

 .../interrupt-controller/ti,sci-inta.txt      | 74 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 75 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt
new file mode 100644
index 000000000000..17b1fbd90312
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt
@@ -0,0 +1,74 @@
+Texas Instruments K3 Interrupt Aggregator
+=========================================
+
+The Interrupt Aggregator (INTA) provides a centralized machine
+which handles the termination of system events to that they can
+be coherently processed by the host(s) in the system. A maximum
+of 64 events can be mapped to a single interrupt.
+
+
+                              Interrupt Aggregator
+                     +-----------------------------------------+
+                     |      Intmap            VINT             |
+                     | +--------------+  +------------+        |
+            m ------>| | vint  | bit  |  | 0 |.....|63| vint0  |
+               .     | +--------------+  +------------+        |       +------+
+               .     |         .               .               |       | HOST |
+Globalevents  ------>|         .               .               |------>| IRQ  |
+               .     |         .               .               |       | CTRL |
+               .     |         .               .               |       +------+
+            n ------>| +--------------+  +------------+        |
+                     | | vint  | bit  |  | 0 |.....|63| vintx  |
+                     | +--------------+  +------------+        |
+                     |                                         |
+                     +-----------------------------------------+
+
+Configuration of these Intmap registers that maps global events to vint is done
+by a system controller (like the Device Memory and Security Controller on K3
+AM654 SoC). Driver should request the system controller to get the range
+of global events and vints assigned to the requesting host. Management
+of these requested resources should be handled by driver and requests
+system controller to map specific global event to vint, bit pair.
+
+Communication between the host processor running an OS and the system
+controller happens through a protocol called TI System Control Interface
+(TISCI protocol). For more details refer:
+Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+
+TISCI Interrupt Aggregator Node:
+-------------------------------
+- compatible:		Must be "ti,sci-inta".
+- reg:			Should contain registers location and length.
+- interrupt-controller:	Identifies the node as an interrupt controller
+- #interrupt-cells:	Specifies the number of cells needed to encode an
+			interrupt source. The value should be 4.
+			First cell should contain the TISCI device ID of source
+			Second cell should contain the event source offset
+			within the device
+			Third cell specified the interrupt number(vint)
+			reaching Interrupt aggregator.
+			Fourth cell specifies the trigger type as defined
+			in interrupts.txt in this directory.
+- interrupt-parent:	phandle of irq parent for TISCI intr.
+- ti,sci:		Phandle to TI-SCI compatible System controller node.
+- ti,sci-dev-id:	TISCI device ID of the Interrupt Aggregator.
+- ti,sci-rm-range-vint:	TISCI subtype id representing the virtual interrupts
+			(vints) range within this IA, assigned to the
+			requesting host context.
+- ti,sci-rm-range-global-event:	TISCI subtype id representing the global
+			events range reaching this IA and are assigned
+			to the requesting host context.
+
+Example:
+--------
+main_udmass_inta: interrupt-controller@33d00000 {
+	compatible = "ti,sci-inta";
+	reg = <0x0 0x33d00000 0x0 0x100000>;
+	interrupt-controller;
+	interrupt-parent = <&main_navss_intr>;
+	#interrupt-cells = <4>;
+	ti,sci = <&dmsc>;
+	ti,sci-dev-id = <179>;
+	ti,sci-rm-range-vint = <0x0>;
+	ti,sci-rm-range-global-event = <0x1>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 823eeb672cf0..970c732b7158 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15065,6 +15065,7 @@ F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 F:	drivers/clk/keystone/sci-clk.c
 F:	drivers/reset/reset-ti-sci.c
 F:	Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
+F:	Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt
 F:	drivers/irqchip/irq-ti-sci-intr.c
 F:	drivers/irqchip/irq-ti-sci-common.c
 F:	drivers/irqchip/irq-ti-sci-common.h
-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 08/10] irqchip: ti-sci-inta: Add support for Interrupt Aggregator driver
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
                   ` (6 preceding siblings ...)
  2019-02-12  7:42 ` [PATCH v5 07/10] dt-bindings: irqchip: Introduce TISCI Interrupt Aggregator bindings Lokesh Vutla
@ 2019-02-12  7:42 ` Lokesh Vutla
  2019-02-12  7:42 ` [PATCH v5 09/10] soc: ti: Add MSI domain support for K3 Interrupt Aggregator Lokesh Vutla
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

Texas Instruments' K3 generation SoCs has an IP Interrupt Aggregator
which is an interrupt controller that does the following:
- Converts events to interrupts that can be understood by
  an interrupt router.
- Allows for multiplexing of events to interrupts.

Configuration of the interrupt aggregator registers can only be done by
a system co-processor and the driver needs to send a message to this
co processor over TISCI protocol.

Add support for Interrupt Aggregator driver with 2 IRQ Domains:
- INTA MSI domain that interfaces the devices using which interrupts can be
  allocated dynamically.
- INTA domain that is parent to the MSI domain that manages the interrupt
  resources.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
Changes since v4:
- Allocate the INTA output interrupts during probe.

 MAINTAINERS                       |   1 +
 drivers/irqchip/Kconfig           |  12 +
 drivers/irqchip/Makefile          |   1 +
 drivers/irqchip/irq-ti-sci-inta.c | 531 ++++++++++++++++++++++++++++++
 4 files changed, 545 insertions(+)
 create mode 100644 drivers/irqchip/irq-ti-sci-inta.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 970c732b7158..44a3392239d9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15069,6 +15069,7 @@ F:	Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt
 F:	drivers/irqchip/irq-ti-sci-intr.c
 F:	drivers/irqchip/irq-ti-sci-common.c
 F:	drivers/irqchip/irq-ti-sci-common.h
+F:	drivers/irqchip/irq-ti-sci-inta.c
 
 Texas Instruments ASoC drivers
 M:	Peter Ujfalusi <peter.ujfalusi@ti.com>
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index a8d9bed0254b..d16fd39408ad 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -417,6 +417,18 @@ config TI_SCI_INTR_IRQCHIP
 	  If you wish to use interrupt router irq resources managed by the
 	  TI System Controller, say Y here. Otherwise, say N.
 
+config TI_SCI_INTA_IRQCHIP
+	bool
+	depends on TI_SCI_PROTOCOL && ARCH_K3
+	select IRQ_DOMAIN
+	select IRQ_DOMAIN_HIERARCHY
+	select K3_INTA_MSI_DOMAIN
+	help
+	  This enables the irqchip driver support for K3 Interrupt aggregator
+	  over TI System Control Interface available on some new TI's SoCs.
+	  If you wish to use interrupt aggregator irq resources managed by the
+	  TI System Controller, say Y here. Otherwise, say N.
+
 endmenu
 
 config SIFIVE_PLIC
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 0499fae148a9..caf6d084e0d4 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -95,3 +95,4 @@ obj-$(CONFIG_SIFIVE_PLIC)		+= irq-sifive-plic.o
 obj-$(CONFIG_IMX_IRQSTEER)		+= irq-imx-irqsteer.o
 obj-$(CONFIG_MADERA_IRQ)		+= irq-madera.o
 obj-$(CONFIG_TI_SCI_INTR_IRQCHIP)	+= irq-ti-sci-intr.o irq-ti-sci-common.o
+obj-$(CONFIG_TI_SCI_INTA_IRQCHIP)	+= irq-ti-sci-inta.o irq-ti-sci-common.o
diff --git a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c
new file mode 100644
index 000000000000..131944fec6fe
--- /dev/null
+++ b/drivers/irqchip/irq-ti-sci-inta.c
@@ -0,0 +1,531 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Texas Instruments' K3 Interrupt Aggregator irqchip driver
+ *
+ * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
+ *	Lokesh Vutla <lokeshvutla@ti.com>
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/msi.h>
+#include <linux/irqchip.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/irqdomain.h>
+#include <linux/interrupt.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+#include <linux/soc/ti/k3_inta_msi.h>
+#include <linux/irqchip/chained_irq.h>
+#include <asm-generic/msi.h>
+#include "irq-ti-sci-common.h"
+
+#define MAX_EVENTS_PER_VINT	64
+
+#define VINT_ENABLE_SET_OFFSET	0x0
+#define VINT_ENABLE_CLR_OFFSET	0x8
+#define VINT_STATUS_OFFSET	0x18
+
+/**
+ * struct ti_sci_inta_event_desc - Description of an event coming to
+ *				   Interrupt Aggregator.
+ * @global_event:	Global event number corresponding to this event
+ * @src_id:		TISCI device ID of the event source
+ * @src_index:		Event source index within the device.
+ */
+struct ti_sci_inta_event_desc {
+	u16 global_event;
+	u16 src_id;
+	u16 src_index;
+};
+
+/**
+ * struct ti_sci_inta_vint_desc - Description of a virtual interrupt coming out
+ *				  of Interrupt Aggregator.
+ * @domain:		Pointer to IRQ domain to which this vint belongs.
+ * @list:		List entry for the vint list
+ * @event_lock:		lock to guard the event map
+ * @event_map:		Bitmap to manage the allocation of events to vint.
+ * @events:		Array of event descriptors assigned to this vint.
+ * @parent_virq:	Linux IRQ number that gets attached to parent
+ * @vint_id:		TISCI vint ID
+ */
+struct ti_sci_inta_vint_desc {
+	struct irq_domain *domain;
+	struct list_head list;
+	struct mutex event_lock;
+	unsigned long *event_map;
+	struct ti_sci_inta_event_desc events[MAX_EVENTS_PER_VINT];
+	unsigned int parent_virq;
+	u16 vint_id;
+};
+
+/**
+ * struct ti_sci_inta_irq_domain - Structure representing a TISCI based
+ *				   Interrupt Aggregator IRQ domain.
+ * @sci:		Pointer to TISCI handle
+ * @vint:		TISCI resource pointer representing IA inerrupts.
+ * @global_event:	TISCI resource pointer representing global events.
+ * @vint_list:		List of the vints active in the system
+ * @base:		Base address of the memory mapped IO registers
+ * @ia_id:		TISCI device ID of this Interrupt Aggregator.
+ */
+struct ti_sci_inta_irq_domain {
+	const struct ti_sci_handle *sci;
+	struct ti_sci_resource *vint;
+	struct ti_sci_resource *global_event;
+	struct list_head vint_list;
+	void __iomem *base;
+	u16 ia_id;
+};
+
+static int __get_event_index(struct ti_sci_inta_vint_desc *vint_desc,
+			     int global_event)
+{
+	int event_index = -ENODEV, i;
+
+	for (i = 0; i < MAX_EVENTS_PER_VINT; i++) {
+		if (vint_desc->events[i].global_event == global_event) {
+			event_index = i;
+			break;
+		}
+	}
+
+	return event_index;
+}
+
+static void __ti_sci_inta_manage_event(struct irq_data *data, u32 offset)
+{
+	struct ti_sci_inta_vint_desc *vint_desc;
+	struct ti_sci_inta_irq_domain *inta;
+	int global_event, event_index;
+
+	vint_desc = irq_data_get_irq_chip_data(data);
+	global_event = data->hwirq;
+	event_index = __get_event_index(vint_desc, global_event);
+	inta = vint_desc->domain->host_data;
+
+	if (event_index < 0)
+		return;
+
+	writeq_relaxed(BIT(event_index), inta->base +
+		       vint_desc->vint_id * 0x1000 + offset);
+}
+
+static void ti_sci_inta_mask_irq(struct irq_data *data)
+{
+	__ti_sci_inta_manage_event(data, VINT_ENABLE_CLR_OFFSET);
+}
+
+static void ti_sci_inta_unmask_irq(struct irq_data *data)
+{
+	__ti_sci_inta_manage_event(data, VINT_ENABLE_SET_OFFSET);
+}
+
+static int ti_sci_inta_set_affinity(struct irq_data *d,
+				    const struct cpumask *mask_val, bool force)
+{
+	struct ti_sci_inta_vint_desc *vint_desc = irq_data_get_irq_chip_data(d);
+	struct irq_chip *chip = irq_get_chip(vint_desc->parent_virq);
+	struct irq_data *data = irq_get_irq_data(vint_desc->parent_virq);
+
+	if (chip && chip->irq_set_affinity)
+		return chip->irq_set_affinity(data, mask_val, force);
+	else
+		return -EINVAL;
+}
+
+static struct irq_chip ti_sci_inta_irq_chip = {
+	.name			= "INTA",
+	.irq_mask		= ti_sci_inta_mask_irq,
+	.irq_unmask		= ti_sci_inta_unmask_irq,
+	.irq_set_affinity	= ti_sci_inta_set_affinity,
+};
+
+/**
+ * ti_sci_free_event_irq() - Free an event from vint
+ * @domain:	Pointer to Interrupt Aggregator IRQ domain
+ * @vint_desc:	Virtual interrupt descriptor containing the event.
+ * @global_event: Global event id to be freed.
+ */
+static void ti_sci_free_event_irq(struct irq_domain *domain,
+				  struct ti_sci_inta_vint_desc *vint_desc,
+				  u16 global_event)
+{
+	struct ti_sci_inta_irq_domain *inta = domain->host_data;
+	struct ti_sci_inta_event_desc *event_desc;
+	int event_index = 0;
+
+	event_index = __get_event_index(vint_desc, global_event);
+	event_desc = &vint_desc->events[event_index];
+	inta->sci->ops.rm_irq_ops.free_event_map(inta->sci,
+						 event_desc->src_id,
+						 event_desc->src_index,
+						 inta->ia_id,
+						 vint_desc->vint_id,
+						 event_desc->global_event,
+						 event_index);
+
+	clear_bit(event_index, vint_desc->event_map);
+
+	ti_sci_release_resource(inta->global_event, event_desc->global_event);
+}
+
+static void ti_sci_inta_free_vint(struct ti_sci_inta_irq_domain *inta,
+				  struct ti_sci_inta_vint_desc *vint_desc)
+{
+	/* If all events are cleared, release vint */
+	if (find_first_bit(vint_desc->event_map, MAX_EVENTS_PER_VINT) ==
+	    MAX_EVENTS_PER_VINT)
+		ti_sci_release_resource(inta->vint, vint_desc->vint_id);
+}
+
+/**
+ * ti_sci_inta_irq_domain_free() - Free an IRQ from the IRQ domain
+ * @domain:	Domain to which the irqs belong
+ * @virq:	base linux virtual IRQ to be freed.
+ * @nr_irqs:	Number of continuous irqs to be freed
+ */
+static void ti_sci_inta_irq_domain_free(struct irq_domain *domain,
+					unsigned int virq, unsigned int nr_irqs)
+{
+	struct ti_sci_inta_vint_desc *vint_desc;
+	struct irq_data *data;
+
+	data = irq_domain_get_irq_data(domain, virq);
+	vint_desc = irq_data_get_irq_chip_data(data);
+
+	ti_sci_free_event_irq(domain, vint_desc, data->hwirq);
+	ti_sci_inta_free_vint(domain->host_data, vint_desc);
+	irq_domain_reset_irq_data(data);
+}
+
+/**
+ * ti_sci_allocate_event_irq() - Allocate an event to a IA vint.
+ *
+ * Return global_event if all went ok else appropriate error value.
+ */
+static
+int ti_sci_allocate_event_irq(struct irq_domain *domain, msi_alloc_info_t *arg)
+{
+	struct ti_sci_inta_irq_domain *inta = domain->host_data;
+	struct ti_sci_inta_event_desc *event_desc;
+	struct ti_sci_inta_vint_desc *vint_desc;
+	u16 free_bit, src_id, src_index;
+	int err;
+
+	src_id = HWIRQ_TO_DEVID(arg->hwirq);
+	src_index = HWIRQ_TO_IRQID(arg->hwirq);
+	vint_desc = arg->scratchpad[0].ptr;
+
+	mutex_lock(&vint_desc->event_lock);
+	free_bit = find_first_zero_bit(vint_desc->event_map,
+				       MAX_EVENTS_PER_VINT);
+	if (free_bit != MAX_EVENTS_PER_VINT)
+		set_bit(free_bit, vint_desc->event_map);
+	mutex_unlock(&vint_desc->event_lock);
+
+	event_desc = &vint_desc->events[free_bit];
+
+	event_desc->src_id = src_id;
+	event_desc->src_index = src_index;
+	event_desc->global_event = ti_sci_get_free_resource(inta->global_event);
+	if (event_desc->global_event == TI_SCI_RESOURCE_NULL) {
+		err = -EINVAL;
+		goto free_event;
+	}
+
+	err = inta->sci->ops.rm_irq_ops.set_event_map(inta->sci,
+						      src_id, src_index,
+						      inta->ia_id,
+						      vint_desc->vint_id,
+						      event_desc->global_event,
+						      free_bit);
+	if (err)
+		goto free_global_event;
+
+	return event_desc->global_event;
+free_global_event:
+	ti_sci_release_resource(inta->global_event, event_desc->global_event);
+free_event:
+	clear_bit(free_bit, vint_desc->event_map);
+	return err;
+}
+
+struct ti_sci_inta_vint_desc *
+ti_sci_inta_get_vint(struct ti_sci_inta_irq_domain *inta, u16 vint)
+{
+	struct ti_sci_inta_vint_desc *vint_desc;
+
+	list_for_each_entry(vint_desc, &inta->vint_list, list)
+		if (vint_desc->vint_id == vint)
+			return vint_desc;
+	return NULL;
+}
+
+/**
+ * ti_sci_inta_irq_domain_alloc() - Allocate Interrupt aggregator IRQs
+ * @domain:	Point to the interrupt aggregator IRQ domain
+ * @virq:	Corresponding Linux virtual IRQ number
+ * @nr_irqs:	Continuous irqs to be allocated
+ * @data:	Pointer to firmware specifier
+ *
+ * Return 0 if all went well else appropriate error value.
+ */
+static int ti_sci_inta_irq_domain_alloc(struct irq_domain *domain,
+					unsigned int virq, unsigned int nr_irqs,
+					void *data)
+{
+	struct ti_sci_inta_irq_domain *inta = domain->host_data;
+	msi_alloc_info_t *arg = data;
+	int hwirq;
+	u16 vint;
+
+	if (arg->desc->inta.share) {
+		if (!arg->scratchpad[0].ptr) {
+			vint = ti_sci_get_free_resource(inta->vint);
+			arg->scratchpad[0].ptr = ti_sci_inta_get_vint(inta,
+								      vint);
+		}
+	} else {
+		vint = ti_sci_get_free_resource(inta->vint);
+		arg->scratchpad[0].ptr = ti_sci_inta_get_vint(inta, vint);
+	}
+
+	hwirq = ti_sci_allocate_event_irq(domain, arg);
+	if (hwirq < 0)
+		return hwirq;
+
+	irq_domain_set_info(domain, virq, hwirq, &ti_sci_inta_irq_chip,
+			    arg->scratchpad[0].ptr, handle_simple_irq,
+			    NULL, NULL);
+
+	return 0;
+}
+
+static const struct irq_domain_ops ti_sci_inta_irq_domain_ops = {
+	.alloc		= ti_sci_inta_irq_domain_alloc,
+	.free		= ti_sci_inta_irq_domain_free,
+};
+
+static struct irq_chip inta_msi_irq_chip = {
+	.name		= "MSI-INTA",
+};
+
+static void inta_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+{
+	arg->desc = desc;
+	arg->hwirq = TO_HWIRQ(desc->inta.dev_id, desc->inta.index);
+}
+
+static struct msi_domain_ops inta_msi_ops = {
+	.set_desc	= inta_msi_set_desc,
+};
+
+static struct msi_domain_info inta_msi_domain_info = {
+	.flags	= (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
+	.ops	= &inta_msi_ops,
+	.chip	= &inta_msi_irq_chip,
+};
+
+static void inta_msi_irq_handler(struct irq_desc *desc)
+{
+	struct ti_sci_inta_vint_desc *vint_desc;
+	struct ti_sci_inta_irq_domain *inta;
+	struct irq_domain *domain;
+	struct irq_data *irq_data;
+	u32 hwirq, bit, virq;
+	u64 val;
+
+	vint_desc = irq_desc_get_handler_data(desc);
+	domain = vint_desc->domain;
+	inta = domain->host_data;
+
+	chained_irq_enter(irq_desc_get_chip(desc), desc);
+
+	val = readq_relaxed(inta->base + vint_desc->vint_id * 0x1000 +
+			    VINT_STATUS_OFFSET);
+
+	for (bit = 0; bit < MAX_EVENTS_PER_VINT; bit++) {
+		if (BIT(bit) & val) {
+			hwirq = vint_desc->events[bit].global_event;
+			virq = irq_find_mapping(domain, hwirq);
+			irq_data = irq_get_irq_data(virq);
+			if (irqd_get_trigger_type(irq_data) ==
+			    IRQF_TRIGGER_HIGH)
+				writeq_relaxed(BIT(bit),
+					       inta->base + vint_desc->vint_id *
+					       0x1000 + VINT_STATUS_OFFSET);
+
+			if (virq)
+				generic_handle_irq(virq);
+		}
+	}
+
+	chained_irq_exit(irq_desc_get_chip(desc), desc);
+}
+
+/**
+ * ti_sci_inta_alloc_parent_irq() - Allocate parent irq to Interrupt aggregator
+ * @domain:	IRQ domain corresponding to Interrupt Aggregator
+ * @virq:	Linux virtual IRQ number
+ *
+ * Return 0 if all went well else corresponding error value.
+ */
+static int ti_sci_inta_alloc_parent_irq(struct irq_domain *domain, u16 vint_id)
+{
+	struct ti_sci_inta_irq_domain *inta = domain->host_data;
+	struct ti_sci_inta_vint_desc *vint_desc;
+	struct irq_fwspec parent_fwspec;
+	unsigned int virq;
+
+	vint_desc = kzalloc(sizeof(*vint_desc), GFP_KERNEL);
+	if (!vint_desc)
+		return -ENOMEM;
+
+	vint_desc->event_map = kcalloc(BITS_TO_LONGS(MAX_EVENTS_PER_VINT),
+				       sizeof(*vint_desc->event_map),
+				       GFP_KERNEL);
+	if (!vint_desc->event_map) {
+		kfree(vint_desc);
+		return -ENOMEM;
+	}
+
+	vint_desc->domain = domain;
+	vint_desc->vint_id = vint_id;
+	INIT_LIST_HEAD(&vint_desc->list);
+	list_add_tail(&vint_desc->list, &inta->vint_list);
+
+	parent_fwspec.fwnode = domain->parent->fwnode;
+	parent_fwspec.param_count = 4;
+	/* Interrupt parent is Interrupt Router */
+	parent_fwspec.param[0] = inta->ia_id;
+	parent_fwspec.param[1] = vint_desc->vint_id;
+	parent_fwspec.param[2] = IRQF_TRIGGER_HIGH;
+	parent_fwspec.param[3] = 1;
+
+	virq = irq_create_fwspec_mapping(&parent_fwspec);
+	if (virq <= 0) {
+		kfree(vint_desc->event_map);
+		kfree(vint_desc);
+		return -ERANGE;
+	}
+
+	irq_set_chained_handler_and_data(virq, inta_msi_irq_handler, vint_desc);
+
+	mutex_init(&vint_desc->event_lock);
+
+	return 0;
+}
+
+static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
+{
+	struct irq_domain *parent_domain, *domain, *msi_domain;
+	struct device_node *parent_node, *node;
+	struct ti_sci_inta_irq_domain *inta;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	int ret, set, i;
+
+	node = dev_of_node(dev);
+	parent_node = of_irq_find_parent(node);
+	if (!parent_node) {
+		dev_err(dev, "Failed to get IRQ parent node\n");
+		return -ENODEV;
+	}
+
+	parent_domain = irq_find_host(parent_node);
+	if (!parent_domain)
+		return -EPROBE_DEFER;
+
+	inta = devm_kzalloc(dev, sizeof(*inta), GFP_KERNEL);
+	if (!inta)
+		return -ENOMEM;
+
+	inta->sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
+	if (IS_ERR(inta->sci)) {
+		ret = PTR_ERR(inta->sci);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "ti,sci read fail %d\n", ret);
+		inta->sci = NULL;
+		return ret;
+	}
+
+	ret = of_property_read_u32(dev->of_node, "ti,sci-dev-id",
+				   (u32 *)&inta->ia_id);
+	if (ret) {
+		dev_err(dev, "missing 'ti,sci-dev-id' property\n");
+		return -EINVAL;
+	}
+
+	inta->vint = devm_ti_sci_get_of_resource(inta->sci, dev,
+						 inta->ia_id,
+						 "ti,sci-rm-range-vint");
+	if (IS_ERR(inta->vint)) {
+		dev_err(dev, "VINT resource allocation failed\n");
+		return PTR_ERR(inta->vint);
+	}
+
+	inta->global_event =
+		devm_ti_sci_get_of_resource(inta->sci, dev,
+					    inta->ia_id,
+					    "ti,sci-rm-range-global-event");
+	if (IS_ERR(inta->global_event)) {
+		dev_err(dev, "Global event resource allocation failed\n");
+		return PTR_ERR(inta->global_event);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	inta->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(inta->base))
+		return -ENODEV;
+
+	domain = irq_domain_add_hierarchy(parent_domain, 0, 0, dev_of_node(dev),
+					  &ti_sci_inta_irq_domain_ops, inta);
+	if (!domain) {
+		dev_err(dev, "Failed to allocate IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	msi_domain = inta_msi_create_irq_domain(of_node_to_fwnode(node),
+						&inta_msi_domain_info,
+						domain);
+	if (!msi_domain) {
+		irq_domain_remove(domain);
+		dev_err(dev, "Failed to allocate msi domain\n");
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&inta->vint_list);
+	for (set = 0; set < inta->vint->sets; set++) {
+		for (i = 0; i < inta->vint->desc[set].num; i++) {
+			if (ti_sci_inta_alloc_parent_irq(domain,
+					inta->vint->desc[set].start + i))
+				break;
+		}
+	}
+
+	return 0;
+}
+
+static const struct of_device_id ti_sci_inta_irq_domain_of_match[] = {
+	{ .compatible = "ti,sci-inta", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ti_sci_inta_irq_domain_of_match);
+
+static struct platform_driver ti_sci_inta_irq_domain_driver = {
+	.probe = ti_sci_inta_irq_domain_probe,
+	.driver = {
+		.name = "ti-sci-inta",
+		.of_match_table = ti_sci_inta_irq_domain_of_match,
+	},
+};
+module_platform_driver(ti_sci_inta_irq_domain_driver);
+
+MODULE_AUTHOR("Lokesh Vutla <lokeshvutla@ticom>");
+MODULE_DESCRIPTION("K3 Interrupt Aggregator driver over TI SCI protocol");
+MODULE_LICENSE("GPL v2");
-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 09/10] soc: ti: Add MSI domain support for K3 Interrupt Aggregator
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
                   ` (7 preceding siblings ...)
  2019-02-12  7:42 ` [PATCH v5 08/10] irqchip: ti-sci-inta: Add support for Interrupt Aggregator driver Lokesh Vutla
@ 2019-02-12  7:42 ` Lokesh Vutla
  2019-02-13 16:41   ` Tony Lindgren
  2019-02-12  7:42 ` [PATCH v5 10/10] soc: ti: am6: Enable interrupt controller drivers Lokesh Vutla
  2019-02-16  3:37 ` [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
  10 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

With the system coprocessor managing the range allocation of the
inputs to Interrupt Aggregator, it is difficult to represent
the device IRQs from DT.

The suggestion is to use MSI in such cases where devices wants
to allocate and group interrupts dynamically.

Create a MSI domain bus layer that allocates and frees MSIs for
a device.

APIs that are implemented are:
- inta_msi_create_irq_domain() that creates a MSI domain
- inta_msi_domain_alloc_irqs() that creates MSIs for the
  specified device and source indexes.
- inta_msi_domain_free_irqs() frees the grouped irqs.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
Changes since v4:
- Dropped support for creating allocation of single MSI.
- Use the existing MSI apis for allocating IRQs

 drivers/soc/ti/Kconfig             |   6 ++
 drivers/soc/ti/Makefile            |   1 +
 drivers/soc/ti/k3_inta_msi.c       | 143 +++++++++++++++++++++++++++++
 include/linux/irqdomain.h          |   1 +
 include/linux/msi.h                |   7 ++
 include/linux/soc/ti/k3_inta_msi.h |  21 +++++
 6 files changed, 179 insertions(+)
 create mode 100644 drivers/soc/ti/k3_inta_msi.c
 create mode 100644 include/linux/soc/ti/k3_inta_msi.h

diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
index be4570baad96..7640490c2a6a 100644
--- a/drivers/soc/ti/Kconfig
+++ b/drivers/soc/ti/Kconfig
@@ -73,4 +73,10 @@ config TI_SCI_PM_DOMAINS
 	  called ti_sci_pm_domains. Note this is needed early in boot before
 	  rootfs may be available.
 
+config K3_INTA_MSI_DOMAIN
+	bool
+	select GENERIC_MSI_IRQ_DOMAIN
+	help
+	  Driver to enable Interrupt Aggregator specific MSI Domain.
+
 endif # SOC_TI
diff --git a/drivers/soc/ti/Makefile b/drivers/soc/ti/Makefile
index a22edc0b258a..152b195273ee 100644
--- a/drivers/soc/ti/Makefile
+++ b/drivers/soc/ti/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA)	+= knav_dma.o
 obj-$(CONFIG_AMX3_PM)			+= pm33xx.o
 obj-$(CONFIG_WKUP_M3_IPC)		+= wkup_m3_ipc.o
 obj-$(CONFIG_TI_SCI_PM_DOMAINS)		+= ti_sci_pm_domains.o
+obj-$(CONFIG_K3_INTA_MSI_DOMAIN)	+= k3_inta_msi.o
diff --git a/drivers/soc/ti/k3_inta_msi.c b/drivers/soc/ti/k3_inta_msi.c
new file mode 100644
index 000000000000..ffce1a7541e2
--- /dev/null
+++ b/drivers/soc/ti/k3_inta_msi.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Texas Instruments' K3 Interrupt Aggregator MSI bus
+ *
+ * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
+ *	Lokesh Vutla <lokeshvutla@ti.com>
+ */
+
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/msi.h>
+#include <linux/soc/ti/k3_inta_msi.h>
+
+static void inta_msi_write_msg(struct irq_data *data, struct msi_msg *msg)
+{
+	/* Nothing to do */
+}
+
+static void inta_msi_compose_msi_msg(struct irq_data *data,
+				     struct msi_msg *msg)
+{
+	/* Nothing to do */
+}
+
+static void inta_msi_update_chip_ops(struct msi_domain_info *info)
+{
+	struct irq_chip *chip = info->chip;
+
+	BUG_ON(!chip);
+	if (!chip->irq_mask)
+		chip->irq_mask = irq_chip_mask_parent;
+	if (!chip->irq_unmask)
+		chip->irq_unmask = irq_chip_unmask_parent;
+	if (!chip->irq_eoi)
+		chip->irq_eoi = irq_chip_eoi_parent;
+	if (!chip->irq_write_msi_msg)
+		chip->irq_write_msi_msg = inta_msi_write_msg;
+	if (!chip->irq_compose_msi_msg)
+		chip->irq_compose_msi_msg = inta_msi_compose_msi_msg;
+}
+
+struct irq_domain *inta_msi_create_irq_domain(struct fwnode_handle *fwnode,
+					      struct msi_domain_info *info,
+					      struct irq_domain *parent)
+{
+	struct irq_domain *domain;
+
+	if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
+		inta_msi_update_chip_ops(info);
+
+	domain = msi_create_irq_domain(fwnode, info, parent);
+	if (domain)
+		irq_domain_update_bus_token(domain, DOMAIN_BUS_K3_INTA_MSI);
+
+	return domain;
+}
+EXPORT_SYMBOL_GPL(inta_msi_create_irq_domain);
+
+static void inta_msi_free_descs(struct device *dev)
+{
+	struct msi_desc *desc, *tmp;
+
+	list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
+		list_del(&desc->list);
+		free_msi_entry(desc);
+	}
+}
+
+static int inta_msi_alloc_descs(struct device *dev, u32 dev_id, int nvec,
+				u32 *arr_index, bool share)
+{
+	struct msi_desc *msi_desc;
+	int i;
+
+	for (i = 0; i < nvec; i++) {
+		msi_desc = alloc_msi_entry(dev, 1, NULL);
+		if (!msi_desc)
+			break;
+
+		msi_desc->inta.index = arr_index[i];
+		msi_desc->inta.dev_id = dev_id;
+		msi_desc->inta.share = share;
+		INIT_LIST_HEAD(&msi_desc->list);
+		list_add_tail(&msi_desc->list, dev_to_msi_list(dev));
+	};
+
+	if (i != nvec) {
+		inta_msi_free_descs(dev);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+int inta_msi_domain_alloc_irqs(struct device *dev, u32 dev_id, int nvec,
+			       u32 *arr_index, bool share)
+{
+	struct irq_domain *msi_domain;
+	int ret;
+
+	msi_domain = dev_get_msi_domain(dev);
+	if (!msi_domain)
+		return -EINVAL;
+
+	ret = inta_msi_alloc_descs(dev, dev_id, nvec, arr_index, share);
+	if (ret)
+		return ret;
+
+	ret = msi_domain_alloc_irqs(msi_domain, dev, nvec);
+	if (ret) {
+		dev_err(dev, "Failed to allocate IRQs\n");
+		goto cleanup;
+	}
+
+	return 0;
+
+cleanup:
+	inta_msi_free_descs(dev);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(inta_msi_domain_alloc_irqs);
+
+void inta_msi_domain_free_irqs(struct device *dev)
+{
+	msi_domain_free_irqs(dev->msi_domain, dev);
+	inta_msi_free_descs(dev);
+}
+EXPORT_SYMBOL_GPL(inta_msi_domain_free_irqs);
+
+unsigned int inta_msi_get_virq(struct device *dev, u32 dev_id, u32 index)
+{
+	struct msi_desc *desc;
+
+	for_each_msi_entry(desc, dev)
+		if (desc->inta.index == index && desc->inta.dev_id == dev_id)
+			return desc->irq;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(inta_msi_get_virq);
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 35965f41d7be..05afb25062cf 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -82,6 +82,7 @@ enum irq_domain_bus_token {
 	DOMAIN_BUS_NEXUS,
 	DOMAIN_BUS_IPI,
 	DOMAIN_BUS_FSL_MC_MSI,
+	DOMAIN_BUS_K3_INTA_MSI,
 };
 
 /**
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 784fb52b9900..7e8a8786308e 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -47,6 +47,12 @@ struct fsl_mc_msi_desc {
 	u16				msi_index;
 };
 
+struct inta_msi_desc {
+	u16	dev_id;
+	u16	index;
+	bool share;
+};
+
 /**
  * struct msi_desc - Descriptor structure for MSI based interrupts
  * @list:	List head for management
@@ -106,6 +112,7 @@ struct msi_desc {
 		 */
 		struct platform_msi_desc platform;
 		struct fsl_mc_msi_desc fsl_mc;
+		struct inta_msi_desc inta;
 	};
 };
 
diff --git a/include/linux/soc/ti/k3_inta_msi.h b/include/linux/soc/ti/k3_inta_msi.h
new file mode 100644
index 000000000000..7fc8c9946cdc
--- /dev/null
+++ b/include/linux/soc/ti/k3_inta_msi.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Texas Instruments' K3 INTA MSI helper
+ *
+ * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
+ *	Lokesh Vutla <lokeshvutla@ti.com>
+ */
+
+#ifndef __INCLUDE_LINUX_K3_INTA_MSI_H
+#define __INCLUDE_LINUX_K3_INTA_MSI_H
+
+#include <linux/msi.h>
+
+struct irq_domain *inta_msi_create_irq_domain(struct fwnode_handle *fwnode,
+					      struct msi_domain_info *info,
+					      struct irq_domain *parent);
+int inta_msi_domain_alloc_irqs(struct device *dev, u32 dev_id, int nvec,
+			       u32 *arr_index, bool share);
+void inta_msi_domain_free_irqs(struct device *dev);
+unsigned int inta_msi_get_virq(struct device *dev, u32 dev_id, u32 index);
+#endif /* __INCLUDE_LINUX_IRQCHIP_TI_SCI_INTA_H */
-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v5 10/10] soc: ti: am6: Enable interrupt controller drivers
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
                   ` (8 preceding siblings ...)
  2019-02-12  7:42 ` [PATCH v5 09/10] soc: ti: Add MSI domain support for K3 Interrupt Aggregator Lokesh Vutla
@ 2019-02-12  7:42 ` Lokesh Vutla
  2019-02-16  3:37 ` [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
  10 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-12  7:42 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Lokesh Vutla,
	Sekhar Nori, linux-kernel, Tero Kristo, Linux ARM Mailing List

Select all the TISCI dependent interrupt controller drivers
for AM6 SoC.

Suggested-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
---
Changes since v4:
- None
 drivers/soc/ti/Kconfig | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig
index 7640490c2a6a..145b701a3d96 100644
--- a/drivers/soc/ti/Kconfig
+++ b/drivers/soc/ti/Kconfig
@@ -5,6 +5,11 @@ if ARCH_K3
 
 config ARCH_K3_AM6_SOC
 	bool "K3 AM6 SoC"
+	select MAILBOX
+	select TI_MESSAGE_MANAGER
+	select TI_SCI_PROTOCOL
+	select TI_SCI_INTR_IRQCHIP
+	select TI_SCI_INTA_IRQCHIP
 	help
 	  Enable support for TI's AM6 SoC Family support
 
-- 
2.19.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-12  7:42 ` [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings Lokesh Vutla
@ 2019-02-12 16:22   ` Tony Lindgren
  2019-02-13  4:25     ` Lokesh Vutla
  2019-02-12 16:30   ` Tony Lindgren
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-12 16:22 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi,

* Lokesh Vutla <lokeshvutla@ti.com> [190212 07:43]:
> +Example:
> +--------
> +The following example demonstrates both interrupt router node and the consumer
> +node(main gpio) on the AM654 SoC:
> +
> +main_intr: interrupt-controller0 {
> +	compatible = "ti,sci-intr";
> +	interrupt-controller;
> +	interrupt-parent = <&gic500>;
> +	#interrupt-cells = <4>;
> +	ti,sci = <&dmsc>;
> +	ti,sci-dst-id = <56>;
> +	ti,sci-rm-range-girq = <0x1>;
> +};

Can you describe a bit what the "ti,sci-dst-id" is above?

These IDs seem to be listed at at [0] below, but is it really a property
of the hardware? Or is it some enumeration of SoC devices in the firmware?

Regards,

Tony


[0] http://downloads.ti.com/tisci/esd/latest/5_soc_doc/am6x/irq_dsts.html

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-12  7:42 ` [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings Lokesh Vutla
  2019-02-12 16:22   ` Tony Lindgren
@ 2019-02-12 16:30   ` Tony Lindgren
  2019-02-13  4:22     ` Lokesh Vutla
  2019-02-16  3:30   ` Lokesh Vutla
  2019-02-18 15:12   ` Marc Zyngier
  3 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-12 16:30 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi,

* Lokesh Vutla <lokeshvutla@ti.com> [190212 07:43]:
> +The Interrupt Router (INTR) module provides a mechanism to route M
> +interrupt inputs to N interrupt outputs, where all M inputs are selectable
> +to be driven per N output. There is one register per output (MUXCNTL_N) that
> +controls the selection.
> +
> +
> +                                 Interrupt Router
> +                             +----------------------+
> +                             |  Inputs     Outputs  |
> +        +-------+            | +------+             |
> +        | GPIO  |----------->| | irq0 |             |       Host IRQ
> +        +-------+            | +------+             |      controller
> +                             |    .        +-----+  |      +-------+
> +        +-------+            |    .        |  0  |  |----->|  IRQ  |
> +        | INTA  |----------->|    .        +-----+  |      +-------+
> +        +-------+            |    .          .      |
> +                             | +------+      .      |
> +                             | | irqM |    +-----+  |
> +                             | +------+    |  N  |  |
> +                             |             +-----+  |
> +                             +----------------------+

Is this always one-to-one mapping or can the same interrupt be routed to
multiple targets like to the SoC and some coprocessor?

> +Configuration of these MUXCNTL_N registers is done by a system controller
> +(like the Device Memory and Security Controller on K3 AM654 SoC). System
> +controller will keep track of the used and unused registers within the Router.
> +Driver should request the system controller to get the range of GIC IRQs
> +assigned to the requesting hosts. It is the drivers responsibility to keep
> +track of Host IRQs.
> +
> +Communication between the host processor running an OS and the system
> +controller happens through a protocol called TI System Control Interface
> +(TISCI protocol). For more details refer:
> +Documentation/devicetree/bindings/arm/keystone/ti,sci.txt

Care to describe a bit why the interrupts need to be routed by a system
controller?

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-12 16:30   ` Tony Lindgren
@ 2019-02-13  4:22     ` Lokesh Vutla
  2019-02-13 15:32       ` Tony Lindgren
  0 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-13  4:22 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Tony,

On 12/02/19 10:00 PM, Tony Lindgren wrote:
> Hi,
> 
> * Lokesh Vutla <lokeshvutla@ti.com> [190212 07:43]:
>> +The Interrupt Router (INTR) module provides a mechanism to route M
>> +interrupt inputs to N interrupt outputs, where all M inputs are selectable
>> +to be driven per N output. There is one register per output (MUXCNTL_N) that
>> +controls the selection.
>> +
>> +
>> +                                 Interrupt Router
>> +                             +----------------------+
>> +                             |  Inputs     Outputs  |
>> +        +-------+            | +------+             |
>> +        | GPIO  |----------->| | irq0 |             |       Host IRQ
>> +        +-------+            | +------+             |      controller
>> +                             |    .        +-----+  |      +-------+
>> +        +-------+            |    .        |  0  |  |----->|  IRQ  |
>> +        | INTA  |----------->|    .        +-----+  |      +-------+
>> +        +-------+            |    .          .      |
>> +                             | +------+      .      |
>> +                             | | irqM |    +-----+  |
>> +                             | +------+    |  N  |  |
>> +                             |             +-----+  |
>> +                             +----------------------+
> 
> Is this always one-to-one mapping or can the same interrupt be routed to
> multiple targets like to the SoC and some coprocessor?

Yes, it is always one-to-one. Output of INTR can only be attached to one of the
processor.

> 
>> +Configuration of these MUXCNTL_N registers is done by a system controller
>> +(like the Device Memory and Security Controller on K3 AM654 SoC). System
>> +controller will keep track of the used and unused registers within the Router.
>> +Driver should request the system controller to get the range of GIC IRQs
>> +assigned to the requesting hosts. It is the drivers responsibility to keep
>> +track of Host IRQs.
>> +
>> +Communication between the host processor running an OS and the system
>> +controller happens through a protocol called TI System Control Interface
>> +(TISCI protocol). For more details refer:
>> +Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
> 
> Care to describe a bit why the interrupts need to be routed by a system
> controller?

K3 architecture defines a heterogeneous system where multiple heterogeneous
cores are serving its own usecases. Given that there are multiple ways in which
a device IRQ can be routed using INTR, like either it can be routed to HLOS
core(A53 int this case) or it can be routed to any other coprocessor available
in the system(like R5). If every sw running in each co-processor is allowed to
program this INTR then there is a high probability that one sw executing on one
core can damage other heterogeneous core.  Mainly to avoid this damage the
configuration of all the INTRs and INTAs are done in a centralized place(sysfw).
Any user for programming its IRQ route should send a message to sysfw with the
parameters. These parameters are policed by sysfw and does the configuration.


Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-12 16:22   ` Tony Lindgren
@ 2019-02-13  4:25     ` Lokesh Vutla
  2019-02-13 15:26       ` Tony Lindgren
  0 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-13  4:25 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Tony,

On 12/02/19 9:52 PM, Tony Lindgren wrote:
> Hi,
> 
> * Lokesh Vutla <lokeshvutla@ti.com> [190212 07:43]:
>> +Example:
>> +--------
>> +The following example demonstrates both interrupt router node and the consumer
>> +node(main gpio) on the AM654 SoC:
>> +
>> +main_intr: interrupt-controller0 {
>> +	compatible = "ti,sci-intr";
>> +	interrupt-controller;
>> +	interrupt-parent = <&gic500>;
>> +	#interrupt-cells = <4>;
>> +	ti,sci = <&dmsc>;
>> +	ti,sci-dst-id = <56>;
>> +	ti,sci-rm-range-girq = <0x1>;
>> +};
> 
> Can you describe a bit what the "ti,sci-dst-id" is above?
> 
> These IDs seem to be listed at at [0] below, but is it really a property
> of the hardware? Or is it some enumeration of SoC devices in the firmware?

This is the way that sysfw describes the hardware. In this case it is GIC and it
is identified by this ID.

Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-13  4:25     ` Lokesh Vutla
@ 2019-02-13 15:26       ` Tony Lindgren
  2019-02-13 20:40         ` Rob Herring
  2019-02-14  8:38         ` Lokesh Vutla
  0 siblings, 2 replies; 46+ messages in thread
From: Tony Lindgren @ 2019-02-13 15:26 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Lokesh Vutla <lokeshvutla@ti.com> [190213 04:26]:
> Hi Tony,
> 
> On 12/02/19 9:52 PM, Tony Lindgren wrote:
> > Hi,
> > 
> > * Lokesh Vutla <lokeshvutla@ti.com> [190212 07:43]:
> >> +Example:
> >> +--------
> >> +The following example demonstrates both interrupt router node and the consumer
> >> +node(main gpio) on the AM654 SoC:
> >> +
> >> +main_intr: interrupt-controller0 {
> >> +	compatible = "ti,sci-intr";
> >> +	interrupt-controller;
> >> +	interrupt-parent = <&gic500>;
> >> +	#interrupt-cells = <4>;
> >> +	ti,sci = <&dmsc>;
> >> +	ti,sci-dst-id = <56>;
> >> +	ti,sci-rm-range-girq = <0x1>;
> >> +};
> > 
> > Can you describe a bit what the "ti,sci-dst-id" is above?
> > 
> > These IDs seem to be listed at at [0] below, but is it really a property
> > of the hardware? Or is it some enumeration of SoC devices in the firmware?
> 
> This is the way that sysfw describes the hardware. In this case it is GIC and it
> is identified by this ID.

If this ID is an enumeration in the sysfw rather than an actual
hardware property it should not be in the device tree. If so,
the device driver should request the id from the sysfw based
on a name. That is, if no struct device or device phandle can
be used.

The problem with using enumeration in the dts is that it
requires maintaining the dts, driver(s) and possibly firmware
in sync. And that might change between SoCs variants when new
devices get added and removed.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-13  4:22     ` Lokesh Vutla
@ 2019-02-13 15:32       ` Tony Lindgren
  2019-02-14  8:40         ` Lokesh Vutla
  0 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-13 15:32 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Lokesh Vutla <lokeshvutla@ti.com> [190213 04:23]:
> Hi Tony,
> 
> On 12/02/19 10:00 PM, Tony Lindgren wrote:
> > Hi,
> > 
> > * Lokesh Vutla <lokeshvutla@ti.com> [190212 07:43]:
> >> +The Interrupt Router (INTR) module provides a mechanism to route M
> >> +interrupt inputs to N interrupt outputs, where all M inputs are selectable
> >> +to be driven per N output. There is one register per output (MUXCNTL_N) that
> >> +controls the selection.
> >> +
> >> +
> >> +                                 Interrupt Router
> >> +                             +----------------------+
> >> +                             |  Inputs     Outputs  |
> >> +        +-------+            | +------+             |
> >> +        | GPIO  |----------->| | irq0 |             |       Host IRQ
> >> +        +-------+            | +------+             |      controller
> >> +                             |    .        +-----+  |      +-------+
> >> +        +-------+            |    .        |  0  |  |----->|  IRQ  |
> >> +        | INTA  |----------->|    .        +-----+  |      +-------+
> >> +        +-------+            |    .          .      |
> >> +                             | +------+      .      |
> >> +                             | | irqM |    +-----+  |
> >> +                             | +------+    |  N  |  |
> >> +                             |             +-----+  |
> >> +                             +----------------------+
> > 
> > Is this always one-to-one mapping or can the same interrupt be routed to
> > multiple targets like to the SoC and some coprocessor?
> 
> Yes, it is always one-to-one. Output of INTR can only be attached to one of the
> processor.

OK

> >> +Configuration of these MUXCNTL_N registers is done by a system controller
> >> +(like the Device Memory and Security Controller on K3 AM654 SoC). System
> >> +controller will keep track of the used and unused registers within the Router.
> >> +Driver should request the system controller to get the range of GIC IRQs
> >> +assigned to the requesting hosts. It is the drivers responsibility to keep
> >> +track of Host IRQs.
> >> +
> >> +Communication between the host processor running an OS and the system
> >> +controller happens through a protocol called TI System Control Interface
> >> +(TISCI protocol). For more details refer:
> >> +Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
> > 
> > Care to describe a bit why the interrupts need to be routed by a system
> > controller?
> 
> K3 architecture defines a heterogeneous system where multiple heterogeneous
> cores are serving its own usecases. Given that there are multiple ways in which
> a device IRQ can be routed using INTR, like either it can be routed to HLOS
> core(A53 int this case) or it can be routed to any other coprocessor available
> in the system(like R5). If every sw running in each co-processor is allowed to
> program this INTR then there is a high probability that one sw executing on one
> core can damage other heterogeneous core.  Mainly to avoid this damage the
> configuration of all the INTRs and INTAs are done in a centralized place(sysfw).
> Any user for programming its IRQ route should send a message to sysfw with the
> parameters. These parameters are policed by sysfw and does the configuration.

OK so maybe update the description along those lines saying it's
a shared piece of hardware between various independent SoC
clusters which may or may not be running Linux.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 09/10] soc: ti: Add MSI domain support for K3 Interrupt Aggregator
  2019-02-12  7:42 ` [PATCH v5 09/10] soc: ti: Add MSI domain support for K3 Interrupt Aggregator Lokesh Vutla
@ 2019-02-13 16:41   ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2019-02-13 16:41 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Lokesh Vutla <lokeshvutla@ti.com> [190212 07:43]:
> With the system coprocessor managing the range allocation of the
> inputs to Interrupt Aggregator, it is difficult to represent
> the device IRQs from DT.
> 
> The suggestion is to use MSI in such cases where devices wants
> to allocate and group interrupts dynamically.
> 
> Create a MSI domain bus layer that allocates and frees MSIs for
> a device.
> 
> APIs that are implemented are:
> - inta_msi_create_irq_domain() that creates a MSI domain
> - inta_msi_domain_alloc_irqs() that creates MSIs for the
>   specified device and source indexes.
> - inta_msi_domain_free_irqs() frees the grouped irqs.

Can you please describe what all code will be calling these
functions?

If the callers are limited to drivers/soc/ti, then you
can can maybe make it local and get rid of the exported
custom functions as it's all built-in anyways.

Or does the dma ring accelerator for example need to call
these?

If various subsystems will be calling these I'd assume
we'd have some generic API.. Marc, any comments on that?

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-13 15:26       ` Tony Lindgren
@ 2019-02-13 20:40         ` Rob Herring
  2019-02-14  8:38         ` Lokesh Vutla
  1 sibling, 0 replies; 46+ messages in thread
From: Rob Herring @ 2019-02-13 20:40 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	Lokesh Vutla, Sekhar Nori, linux-kernel, Tero Kristo,
	marc.zyngier, Santosh Shilimkar, tglx, Linux ARM Mailing List

On Wed, Feb 13, 2019 at 07:26:20AM -0800, Tony Lindgren wrote:
> * Lokesh Vutla <lokeshvutla@ti.com> [190213 04:26]:
> > Hi Tony,
> > 
> > On 12/02/19 9:52 PM, Tony Lindgren wrote:
> > > Hi,
> > > 
> > > * Lokesh Vutla <lokeshvutla@ti.com> [190212 07:43]:
> > >> +Example:
> > >> +--------
> > >> +The following example demonstrates both interrupt router node and the consumer
> > >> +node(main gpio) on the AM654 SoC:
> > >> +
> > >> +main_intr: interrupt-controller0 {
> > >> +	compatible = "ti,sci-intr";
> > >> +	interrupt-controller;
> > >> +	interrupt-parent = <&gic500>;
> > >> +	#interrupt-cells = <4>;
> > >> +	ti,sci = <&dmsc>;
> > >> +	ti,sci-dst-id = <56>;
> > >> +	ti,sci-rm-range-girq = <0x1>;
> > >> +};
> > > 
> > > Can you describe a bit what the "ti,sci-dst-id" is above?
> > > 
> > > These IDs seem to be listed at at [0] below, but is it really a property
> > > of the hardware? Or is it some enumeration of SoC devices in the firmware?
> > 
> > This is the way that sysfw describes the hardware. In this case it is GIC and it
> > is identified by this ID.
> 
> If this ID is an enumeration in the sysfw rather than an actual
> hardware property it should not be in the device tree. If so,
> the device driver should request the id from the sysfw based
> on a name. That is, if no struct device or device phandle can
> be used.
> 
> The problem with using enumeration in the dts is that it
> requires maintaining the dts, driver(s) and possibly firmware
> in sync. And that might change between SoCs variants when new
> devices get added and removed.

IOW, don't repeat h/w designers mistakes and make your firmware 
discoverable. We have DT only for what is not discoverable.

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-13 15:26       ` Tony Lindgren
  2019-02-13 20:40         ` Rob Herring
@ 2019-02-14  8:38         ` Lokesh Vutla
  2019-02-14 15:41           ` Tony Lindgren
  1 sibling, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-14  8:38 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Tony,

On 13/02/19 8:56 PM, Tony Lindgren wrote:
> * Lokesh Vutla <lokeshvutla@ti.com> [190213 04:26]:
>> Hi Tony,
>> 
>> On 12/02/19 9:52 PM, Tony Lindgren wrote:
>>> Hi,
>>> 
>>> * Lokesh Vutla <lokeshvutla@ti.com> [190212 07:43]:
>>>> +Example: +-------- +The following example demonstrates both interrupt 
>>>> router node and the consumer +node(main gpio) on the AM654 SoC: + 
>>>> +main_intr: interrupt-controller0 { +	compatible = "ti,sci-intr"; + 
>>>> interrupt-controller; +	interrupt-parent = <&gic500>; + 
>>>> #interrupt-cells = <4>; +	ti,sci = <&dmsc>; +	ti,sci-dst-id = <56>; + 
>>>> ti,sci-rm-range-girq = <0x1>; +};
>>> 
>>> Can you describe a bit what the "ti,sci-dst-id" is above?
>>> 
>>> These IDs seem to be listed at at [0] below, but is it really a property
>>>  of the hardware? Or is it some enumeration of SoC devices in the 
>>> firmware?
>> 
>> This is the way that sysfw describes the hardware. In this case it is GIC 
>> and it is identified by this ID.
> 
> If this ID is an enumeration in the sysfw rather than an actual hardware 
> property it should not be in the device tree. If so,

Devicetree-specification-v0.2[1] "Section 1.1 Purpose and Scope" mentions that
devicetree specification provides a complete boot program to client program
interface definition. Where boot program here is the sysfw and client program is
Linux. In this case we are describing the id which is the destination interrupt
controller to which the irqs are supposed to be attached.

> the device driver should request the id from the sysfw based on a name. That 
> is, if no struct device or device phandle can

From a scalability perspective using a name to get a device id might worsen
things.  There are hundreds of devices within the SoC and standardizing a name
for each device and making sure using the same name across all future SoCs might
be a bit pain. If there are more than one instance of the same device then name
that should be requested is different with in the same driver.

IMHO, device ids are something which can be used in DT. There are many other
things like the interrupt ranges etc.. which are discoverable from sysfw and we
are implementing it.

> be used.
> > The problem with using enumeration in the dts is that it requires
> maintaining the dts, driver(s) and possibly firmware in sync. And that might

The idea here is device ids are not going to change for a SoC. For new SoCs
within the same architecture ids will change and we will have new dts or this
new SoC.

> change between SoCs variants when new devices get added and removed.
> 

[1]
https://github.com/devicetree-org/devicetree-specification/releases/download/v0.2/devicetree-specification-v0.2.pdf

Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-13 15:32       ` Tony Lindgren
@ 2019-02-14  8:40         ` Lokesh Vutla
  2019-02-14 15:42           ` Tony Lindgren
  0 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-14  8:40 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List



On 13/02/19 9:02 PM, Tony Lindgren wrote:
> * Lokesh Vutla <lokeshvutla@ti.com> [190213 04:23]:
>> Hi Tony,
>>
>> On 12/02/19 10:00 PM, Tony Lindgren wrote:
>>> Hi,
>>>
>>> * Lokesh Vutla <lokeshvutla@ti.com> [190212 07:43]:
>>>> +The Interrupt Router (INTR) module provides a mechanism to route M
>>>> +interrupt inputs to N interrupt outputs, where all M inputs are selectable
>>>> +to be driven per N output. There is one register per output (MUXCNTL_N) that
>>>> +controls the selection.
>>>> +
>>>> +
>>>> +                                 Interrupt Router
>>>> +                             +----------------------+
>>>> +                             |  Inputs     Outputs  |
>>>> +        +-------+            | +------+             |
>>>> +        | GPIO  |----------->| | irq0 |             |       Host IRQ
>>>> +        +-------+            | +------+             |      controller
>>>> +                             |    .        +-----+  |      +-------+
>>>> +        +-------+            |    .        |  0  |  |----->|  IRQ  |
>>>> +        | INTA  |----------->|    .        +-----+  |      +-------+
>>>> +        +-------+            |    .          .      |
>>>> +                             | +------+      .      |
>>>> +                             | | irqM |    +-----+  |
>>>> +                             | +------+    |  N  |  |
>>>> +                             |             +-----+  |
>>>> +                             +----------------------+
>>>
>>> Is this always one-to-one mapping or can the same interrupt be routed to
>>> multiple targets like to the SoC and some coprocessor?
>>
>> Yes, it is always one-to-one. Output of INTR can only be attached to one of the
>> processor.
> 
> OK
> 
>>>> +Configuration of these MUXCNTL_N registers is done by a system controller
>>>> +(like the Device Memory and Security Controller on K3 AM654 SoC). System
>>>> +controller will keep track of the used and unused registers within the Router.
>>>> +Driver should request the system controller to get the range of GIC IRQs
>>>> +assigned to the requesting hosts. It is the drivers responsibility to keep
>>>> +track of Host IRQs.
>>>> +
>>>> +Communication between the host processor running an OS and the system
>>>> +controller happens through a protocol called TI System Control Interface
>>>> +(TISCI protocol). For more details refer:
>>>> +Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>>>
>>> Care to describe a bit why the interrupts need to be routed by a system
>>> controller?
>>
>> K3 architecture defines a heterogeneous system where multiple heterogeneous
>> cores are serving its own usecases. Given that there are multiple ways in which
>> a device IRQ can be routed using INTR, like either it can be routed to HLOS
>> core(A53 int this case) or it can be routed to any other coprocessor available
>> in the system(like R5). If every sw running in each co-processor is allowed to
>> program this INTR then there is a high probability that one sw executing on one
>> core can damage other heterogeneous core.  Mainly to avoid this damage the
>> configuration of all the INTRs and INTAs are done in a centralized place(sysfw).
>> Any user for programming its IRQ route should send a message to sysfw with the
>> parameters. These parameters are policed by sysfw and does the configuration.
> 
> OK so maybe update the description along those lines saying it's
> a shared piece of hardware between various independent SoC
> clusters which may or may not be running Linux.

IMHO, SoC integration is out of scope of this document. If you insist I can add
the details.

Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-14  8:38         ` Lokesh Vutla
@ 2019-02-14 15:41           ` Tony Lindgren
  2019-02-14 17:32             ` Lokesh Vutla
  0 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-14 15:41 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Lokesh Vutla <lokeshvutla@ti.com> [190214 08:39]:
> IMHO, device ids are something which can be used in DT. There are many other
> things like the interrupt ranges etc.. which are discoverable from sysfw and we
> are implementing it.

We need to describe hardware in the device tree, not firmware.

If you have something discoverable from the firmware, you should
have the device driver query it from sysfw based on a hardware
property, not based on some invented enumeration in the firmware.
If there is some device to firmware translation needed, hide that
into the device driver and keep it out of the device tree.

For example, look at the interrupt binding where the interrupt
is phandle to the controller and the bit offset from the interrupt
controller instance.

You need to use device IO address + bit offset (or register
offset) type indexing for device tree here. Something out of
the TRM that makes sense to developers.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-14  8:40         ` Lokesh Vutla
@ 2019-02-14 15:42           ` Tony Lindgren
  0 siblings, 0 replies; 46+ messages in thread
From: Tony Lindgren @ 2019-02-14 15:42 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Lokesh Vutla <lokeshvutla@ti.com> [190214 08:40]:
> On 13/02/19 9:02 PM, Tony Lindgren wrote:
> > OK so maybe update the description along those lines saying it's
> > a shared piece of hardware between various independent SoC
> > clusters which may or may not be running Linux.
> 
> IMHO, SoC integration is out of scope of this document. If you insist I can add
> the details.

Certainly you need to justify how come such a critical piece
of information as interrupt line routing is out of control
of Linux here.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-14 15:41           ` Tony Lindgren
@ 2019-02-14 17:32             ` Lokesh Vutla
  2019-02-14 17:46               ` Tony Lindgren
  0 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-14 17:32 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Tony,
	Please do not snip the on going discussion.

On 2/14/2019 9:11 PM, Tony Lindgren wrote:
> * Lokesh Vutla <lokeshvutla@ti.com> [190214 08:39]:
>> IMHO, device ids are something which can be used in DT. There are many other
>> things like the interrupt ranges etc.. which are discoverable from sysfw and we
>> are implementing it.
> 
> We need to describe hardware in the device tree, not firmware.
> 
> If you have something discoverable from the firmware, you should
> have the device driver query it from sysfw based on a hardware
> property, not based on some invented enumeration in the firmware.

Yes we are already querying sysfw for all the irq ranges that can be
discoverable. The topic of discussion here is about the parent interrupt
controller id. I am not sure how you are expecting an id be discoverable
from system firmware especially with a name.

> If there is some device to firmware translation needed, hide that
> into the device driver and keep it out of the device tree.

If preferred this can be moved to of_match_data attached to each
compatible property. Then for each SoC a new compatible needs to be created.

> 
> For example, look at the interrupt binding where the interrupt
> is phandle to the controller and the bit offset from the interrupt
> controller instance.
> 
> You need to use device IO address + bit offset (or register
> offset) type indexing for device tree here. Something out of
> the TRM that makes sense to developers.
> 


[1]
https://github.com/devicetree-org/devicetree-specification/releases/download/v0.2/devicetree-specification-v0.2.pdf

Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-14 17:32             ` Lokesh Vutla
@ 2019-02-14 17:46               ` Tony Lindgren
  2019-02-14 18:02                 ` Lokesh Vutla
  0 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-14 17:46 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Lokesh Vutla <lokeshvutla@ti.com> [190214 17:32]:
> Hi Tony,
> 	Please do not snip the on going discussion.
> 
> On 2/14/2019 9:11 PM, Tony Lindgren wrote:
> > * Lokesh Vutla <lokeshvutla@ti.com> [190214 08:39]:
> >> IMHO, device ids are something which can be used in DT. There are many other
> >> things like the interrupt ranges etc.. which are discoverable from sysfw and we
> >> are implementing it.
> > 
> > We need to describe hardware in the device tree, not firmware.
> > 
> > If you have something discoverable from the firmware, you should
> > have the device driver query it from sysfw based on a hardware
> > property, not based on some invented enumeration in the firmware.
> 
> Yes we are already querying sysfw for all the irq ranges that can be
> discoverable. The topic of discussion here is about the parent interrupt
> controller id. I am not sure how you are expecting an id be discoverable
> from system firmware especially with a name.

Well names are quite standard in dts (but should be used with
the phandle + offset). Think for example interrupt-names and
reg-names :)

> > If there is some device to firmware translation needed, hide that
> > into the device driver and keep it out of the device tree.
> 
> If preferred this can be moved to of_match_data attached to each
> compatible property. Then for each SoC a new compatible needs to be created.

Hiding the ID into the device driver and compatible property
makes sense to me if the id is based on SoC + firmware.

But I'd rather have a proper hardware based phandle + index
type mapping in the dts if possible though.

What does this id really consist of?

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-14 17:46               ` Tony Lindgren
@ 2019-02-14 18:02                 ` Lokesh Vutla
  2019-02-15 16:16                   ` Tony Lindgren
  0 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-14 18:02 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Tony,

On 2/14/2019 11:16 PM, Tony Lindgren wrote:
> * Lokesh Vutla <lokeshvutla@ti.com> [190214 17:32]:
>> Hi Tony,
>> 	Please do not snip the on going discussion.
>>
>> On 2/14/2019 9:11 PM, Tony Lindgren wrote:
>>> * Lokesh Vutla <lokeshvutla@ti.com> [190214 08:39]:
>>>> IMHO, device ids are something which can be used in DT. There are many other
>>>> things like the interrupt ranges etc.. which are discoverable from sysfw and we
>>>> are implementing it.
>>>
>>> We need to describe hardware in the device tree, not firmware.
>>>
>>> If you have something discoverable from the firmware, you should
>>> have the device driver query it from sysfw based on a hardware
>>> property, not based on some invented enumeration in the firmware.
>>
>> Yes we are already querying sysfw for all the irq ranges that can be
>> discoverable. The topic of discussion here is about the parent interrupt
>> controller id. I am not sure how you are expecting an id be discoverable
>> from system firmware especially with a name.
> 
> Well names are quite standard in dts (but should be used with
> the phandle + offset). Think for example interrupt-names and
> reg-names :)
> 
>>> If there is some device to firmware translation needed, hide that
>>> into the device driver and keep it out of the device tree.
>>
>> If preferred this can be moved to of_match_data attached to each
>> compatible property. Then for each SoC a new compatible needs to be created.
> 
> Hiding the ID into the device driver and compatible property
> makes sense to me if the id is based on SoC + firmware.
> 
> But I'd rather have a proper hardware based phandle + index
> type mapping in the dts if possible though.

The idea about sysfw here is that Linux is not aware of anything about
this device(Interrupt Router). It cannot even access any of its
registers. As a user Linux should know who is the parent to which the
Interrut router output should be configured. Then query sysfw about the
range of gic irqs allocated to it. Now for configuration, Linux should
pass the the input to interrupt router, gic irq no, and gic id(by which
sysfw uniquely identifies GIC interrupt controller with the SoC).  Based
on these parameters Interrupt Router registers gets configured.

So for the above configuration we need the gic_id for which the dt
property "ti,sci-dst-id" is used.

Thanks and regards,
Lokesh

> 
> What does this id really consist of?
> 
> Regards,
> 
> Tony
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-14 18:02                 ` Lokesh Vutla
@ 2019-02-15 16:16                   ` Tony Lindgren
  2019-02-16  3:29                     ` Lokesh Vutla
  0 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-15 16:16 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi,

* Lokesh Vutla <lokeshvutla@ti.com> [190214 18:03]:
> On 2/14/2019 11:16 PM, Tony Lindgren wrote:
> > But I'd rather have a proper hardware based phandle + index
> > type mapping in the dts if possible though.
> 
> The idea about sysfw here is that Linux is not aware of anything about
> this device(Interrupt Router). It cannot even access any of its
> registers. As a user Linux should know who is the parent to which the
> Interrut router output should be configured. Then query sysfw about the
> range of gic irqs allocated to it. Now for configuration, Linux should
> pass the the input to interrupt router, gic irq no, and gic id(by which
> sysfw uniquely identifies GIC interrupt controller with the SoC).  Based
> on these parameters Interrupt Router registers gets configured.

If the interrupt router hardawre is hidden away from Linux,
just leave it out of the device tree completely and have the
interrupt controller driver request the routing.

The dts node for the interrupt controller should describe a
proper Linux device, that is with reg entries and so on.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-15 16:16                   ` Tony Lindgren
@ 2019-02-16  3:29                     ` Lokesh Vutla
  2019-02-18 14:32                       ` Tony Lindgren
  0 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-16  3:29 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Tony,

On 2/15/2019 9:46 PM, Tony Lindgren wrote:
> Hi,
> 
> * Lokesh Vutla <lokeshvutla@ti.com> [190214 18:03]:
>> On 2/14/2019 11:16 PM, Tony Lindgren wrote:
>>> But I'd rather have a proper hardware based phandle + index
>>> type mapping in the dts if possible though.
>>
>> The idea about sysfw here is that Linux is not aware of anything about
>> this device(Interrupt Router). It cannot even access any of its
>> registers. As a user Linux should know who is the parent to which the
>> Interrut router output should be configured. Then query sysfw about the
>> range of gic irqs allocated to it. Now for configuration, Linux should
>> pass the the input to interrupt router, gic irq no, and gic id(by which
>> sysfw uniquely identifies GIC interrupt controller with the SoC).  Based
>> on these parameters Interrupt Router registers gets configured.
> 
> If the interrupt router hardawre is hidden away from Linux,
> just leave it out of the device tree completely and have the
> interrupt controller driver request the routing.

Yes while requesting you should at-least specify which is your
destination interrupt-controller Else how does the sysfw even know to
whom the requester wants the routing to happen to. You do know that we
are dealing with a heterogeneous system where there are more the one
destination interrupt controllers(GIC, R5 VIM  etc etc..). This is what
the DT property is specifying and we cannot query a device based on a name.

> 
> The dts node for the interrupt controller should describe a
> proper Linux device, that is with reg entries and so on.

You are asking to just keep the compatible property :)

I am no where denying that. But the cases where the firmware does the
configuration DT spec[1] clearly mentions about the interface.

Please take a look at arm-psci devicetree binding documentation where
the function ids are represented using which each psci function is invoked.

[1]
https://github.com/devicetree-org/devicetree-specification/releases/download/v0.2/devicetree-specification-v0.2.pdf

Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-12  7:42 ` [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings Lokesh Vutla
  2019-02-12 16:22   ` Tony Lindgren
  2019-02-12 16:30   ` Tony Lindgren
@ 2019-02-16  3:30   ` Lokesh Vutla
  2019-02-18 14:35     ` Tony Lindgren
  2019-02-18 15:12   ` Marc Zyngier
  3 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-16  3:30 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Sekhar Nori,
	linux-kernel, Tero Kristo, Linux ARM Mailing List

Hi Rob,

On 2/12/2019 1:12 PM, Lokesh Vutla wrote:
> Add the DT binding documentation for Interrupt router driver.
> 
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> ---
> Changes since v4:
> - None
> 
>  .../interrupt-controller/ti,sci-intr.txt      | 85 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 86 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
> new file mode 100644
> index 000000000000..4b0ca797fda1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
> @@ -0,0 +1,85 @@
> +Texas Instruments K3 Interrupt Router
> +=====================================
> +
> +The Interrupt Router (INTR) module provides a mechanism to route M
> +interrupt inputs to N interrupt outputs, where all M inputs are selectable
> +to be driven per N output. There is one register per output (MUXCNTL_N) that
> +controls the selection.
> +
> +
> +                                 Interrupt Router
> +                             +----------------------+
> +                             |  Inputs     Outputs  |
> +        +-------+            | +------+             |
> +        | GPIO  |----------->| | irq0 |             |       Host IRQ
> +        +-------+            | +------+             |      controller
> +                             |    .        +-----+  |      +-------+
> +        +-------+            |    .        |  0  |  |----->|  IRQ  |
> +        | INTA  |----------->|    .        +-----+  |      +-------+
> +        +-------+            |    .          .      |
> +                             | +------+      .      |
> +                             | | irqM |    +-----+  |
> +                             | +------+    |  N  |  |
> +                             |             +-----+  |
> +                             +----------------------+
> +
> +Configuration of these MUXCNTL_N registers is done by a system controller
> +(like the Device Memory and Security Controller on K3 AM654 SoC). System
> +controller will keep track of the used and unused registers within the Router.
> +Driver should request the system controller to get the range of GIC IRQs
> +assigned to the requesting hosts. It is the drivers responsibility to keep
> +track of Host IRQs.
> +
> +Communication between the host processor running an OS and the system
> +controller happens through a protocol called TI System Control Interface
> +(TISCI protocol). For more details refer:
> +Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
> +
> +TISCI Interrupt Router Node:
> +----------------------------
> +- compatible:		Must be "ti,sci-intr".
> +- interrupt-controller:	Identifies the node as an interrupt controller
> +- #interrupt-cells:	Specifies the number of cells needed to encode an
> +			interrupt source. The value should be 4.
> +			First cell should contain the TISCI device ID of source
> +			Second cell should contain the interrupt source offset
> +			within the device
> +			Third cell specifies the trigger type as defined
> +			in interrupts.txt in this directory.
> +			Fourth cell should be 1 if the irq is coming from
> +			interrupt aggregator else 0.
> +- ti,sci:		Phandle to TI-SCI compatible System controller node.
> +- ti,sci-dst-id:	TISCI device ID of the destination IRQ controller.

Please help me here. As said this is the TISCI device id for the host
interrupt controller. While sending message to the system co-processor
this ID needs to be specified so that the irq route gets discovered and
configured. Atleast with the current design device Ids are not
discoverable. Can you mention what can be improved here? Is there any
such example where a firmware supports querying the deivce ids?

Also do you have any further comments on this patch?

Thanks and regards,
Lokesh

> +- ti,sci-rm-range-girq:	Array of TISCI subtype ids representing the host irqs
> +			assigned to this interrupt router. Each subtype id
> +			corresponds to a range of host irqs.
> +
> +For more details on TISCI IRQ resource management refer:
> +http://downloads.ti.com/tisci/esd/latest/2_tisci_msgs/rm/rm_irq.html
> +
> +Example:
> +--------
> +The following example demonstrates both interrupt router node and the consumer
> +node(main gpio) on the AM654 SoC:
> +
> +main_intr: interrupt-controller0 {
> +	compatible = "ti,sci-intr";
> +	interrupt-controller;
> +	interrupt-parent = <&gic500>;
> +	#interrupt-cells = <4>;
> +	ti,sci = <&dmsc>;
> +	ti,sci-dst-id = <56>;
> +	ti,sci-rm-range-girq = <0x1>;
> +};
> +
> +main_gpio0: gpio@600000 {
> +	...
> +	interrupt-parent = <&main_intr>;
> +	interrupts = <57 256 IRQ_TYPE_EDGE_RISING 0>,
> +			<57 257 IRQ_TYPE_EDGE_RISING 0>,
> +			<57 258 IRQ_TYPE_EDGE_RISING 0>,
> +			<57 259 IRQ_TYPE_EDGE_RISING 0>,
> +			<57 260 IRQ_TYPE_EDGE_RISING 0>,
> +			<57 261 IRQ_TYPE_EDGE_RISING 0>;
> +	...
> +};
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 8c68de3cfd80..c918d9b2ee18 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -15064,6 +15064,7 @@ F:	Documentation/devicetree/bindings/reset/ti,sci-reset.txt
>  F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>  F:	drivers/clk/keystone/sci-clk.c
>  F:	drivers/reset/reset-ti-sci.c
> +F:	Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
>  
>  Texas Instruments ASoC drivers
>  M:	Peter Ujfalusi <peter.ujfalusi@ti.com>
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 00/10] Add support for TISCI irqchip drivers
  2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
                   ` (9 preceding siblings ...)
  2019-02-12  7:42 ` [PATCH v5 10/10] soc: ti: am6: Enable interrupt controller drivers Lokesh Vutla
@ 2019-02-16  3:37 ` Lokesh Vutla
  10 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-16  3:37 UTC (permalink / raw)
  To: marc.zyngier, Tony Lindgren, Nishanth Menon, Santosh Shilimkar,
	Rob Herring, tglx, jason
  Cc: Device Tree Mailing List, Peter Ujfalusi, Sekhar Nori,
	linux-kernel, Tero Kristo, Linux ARM Mailing List

Hi Marc,

On 2/12/2019 1:12 PM, Lokesh Vutla wrote:
> TI AM65x SoC based on K3 architecture introduced support for Events
> which are message based interrupts with minimal latency. These events
> are not compatible with regular interrupts and are valid only through
> an event transport lane. An Interrupt Aggregator(INTA) is introduced
> to convert these events to interrupts. INTA can also group 64 events
> into a single interrupt. Now the SoC has many peripherals and a large
> number of event sources (time sync or DMA), the use of events is
> completely dependent on a user's specific application, which drives a
> need for maximum flexibility in which event sources are used in the
> system. It is also completely up to software control as to how the
> events are serviced.
> 
> Because of the huge flexibility there are certain standard peripherals
> (like GPIO etc)where all interrupts cannot be directly corrected to host
> interrupt controller. For this purpose, Interrupt Router(INTR) is
> introduced in the SoC. INTR just does a classic interrupt redirection.
> 
> So the SoC has 3 types of interrupt controllers:
> - GIC500
> - Interrupt Router
> - Interrupt Aggregator
> 
> Below is a diagrammatic view of how SoC integration of these interrupt
> controllers:(https://pastebin.ubuntu.com/p/9ngV3jdGj2/)
> 
> Device Index-x               Device Index-y
>            |                         |
>            |                         |
>                       ....
>             \                       /
>              \                     /
>               \  (global events)  /
>           +---------------------------+   +---------+
>           |                           |   |         |
>           |             INTA          |   |  GPIO   |
>           |                           |   |         |
>           +---------------------------+   +---------+
>                          |   (vint)            |
>                          |                     |
>                         \|/                    |
>           +---------------------------+        |
>           |                           |<-------+
>           |           INTR            |
>           |                           |
>           +---------------------------+
>                          |
>                          |
>                         \|/ (gic irq)
>           +---------------------------+
>           |                           |
>           |             GIC           |
>           |                           |
>           +---------------------------+
> 
> While at it, TISCI abstracts the handling of all above IRQ routes where
> interrupt sources are not directly connected to host interrupt controller.
> That would be configuration of Interrupt Aggregator and Interrupt Router.
> 
> This series adds support for:
> - TISCI commands needed for IRQ configuration
> - Interrupt Router(INTR) and Interrupt Aggregator(INTA) drivers

Sorry to bother you again. Any chance you can take a quick look at the
series?

Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-16  3:29                     ` Lokesh Vutla
@ 2019-02-18 14:32                       ` Tony Lindgren
  2019-02-19  8:51                         ` Lokesh Vutla
  0 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-18 14:32 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Lokesh Vutla <lokeshvutla@ti.com> [190216 03:30]:
> On 2/15/2019 9:46 PM, Tony Lindgren wrote:
> > The dts node for the interrupt controller should describe a
> > proper Linux device, that is with reg entries and so on.
> 
> You are asking to just keep the compatible property :)

Right, and then I realized this node is missing the standard
reg entry too. And you're saying the registers are not even
accissible from Linux.

So based on that IMO you should not even have a device tree
node for it at all. You should just have the interrupt
controller driver do the muxing on request_irq() using tisci
calls.

If that's not true, and these mux registers are accessible
from Linux, then set up proper dts node with reg entries.
And have the driver deal with the firmware based on the
compatible node.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-16  3:30   ` Lokesh Vutla
@ 2019-02-18 14:35     ` Tony Lindgren
  2019-02-22 10:10       ` Peter Ujfalusi
  0 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-18 14:35 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Lokesh Vutla <lokeshvutla@ti.com> [190216 03:30]:
> On 2/12/2019 1:12 PM, Lokesh Vutla wrote:
> > +TISCI Interrupt Router Node:
> > +----------------------------
> > +- compatible:		Must be "ti,sci-intr".
> > +- interrupt-controller:	Identifies the node as an interrupt controller
> > +- #interrupt-cells:	Specifies the number of cells needed to encode an
> > +			interrupt source. The value should be 4.
> > +			First cell should contain the TISCI device ID of source
> > +			Second cell should contain the interrupt source offset
> > +			within the device
> > +			Third cell specifies the trigger type as defined
> > +			in interrupts.txt in this directory.
> > +			Fourth cell should be 1 if the irq is coming from
> > +			interrupt aggregator else 0.
> > +- ti,sci:		Phandle to TI-SCI compatible System controller node.
> > +- ti,sci-dst-id:	TISCI device ID of the destination IRQ controller.
>
> Please help me here. As said this is the TISCI device id for the host
> interrupt controller. While sending message to the system co-processor
> this ID needs to be specified so that the irq route gets discovered and
> configured. Atleast with the current design device Ids are not
> discoverable. Can you mention what can be improved here? Is there any
> such example where a firmware supports querying the deivce ids?
> 
> Also do you have any further comments on this patch?

No reg property above. So if the interrupt router is not accessible
by Linux like you're saying, you should not set up a dts node for
it at all.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-12  7:42 ` [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings Lokesh Vutla
                     ` (2 preceding siblings ...)
  2019-02-16  3:30   ` Lokesh Vutla
@ 2019-02-18 15:12   ` Marc Zyngier
  2019-02-18 15:27     ` Lokesh Vutla
  3 siblings, 1 reply; 46+ messages in thread
From: Marc Zyngier @ 2019-02-18 15:12 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	Tony Lindgren, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

On Tue, 12 Feb 2019 13:12:32 +0530
Lokesh Vutla <lokeshvutla@ti.com> wrote:

> Add the DT binding documentation for Interrupt router driver.
> 
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> ---
> Changes since v4:
> - None
> 
>  .../interrupt-controller/ti,sci-intr.txt      | 85 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 86 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
> new file mode 100644
> index 000000000000..4b0ca797fda1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
> @@ -0,0 +1,85 @@
> +Texas Instruments K3 Interrupt Router
> +=====================================
> +
> +The Interrupt Router (INTR) module provides a mechanism to route M
> +interrupt inputs to N interrupt outputs, where all M inputs are selectable
> +to be driven per N output. There is one register per output (MUXCNTL_N) that
> +controls the selection.
> +
> +
> +                                 Interrupt Router
> +                             +----------------------+
> +                             |  Inputs     Outputs  |
> +        +-------+            | +------+             |
> +        | GPIO  |----------->| | irq0 |             |       Host IRQ
> +        +-------+            | +------+             |      controller
> +                             |    .        +-----+  |      +-------+
> +        +-------+            |    .        |  0  |  |----->|  IRQ  |
> +        | INTA  |----------->|    .        +-----+  |      +-------+
> +        +-------+            |    .          .      |
> +                             | +------+      .      |
> +                             | | irqM |    +-----+  |
> +                             | +------+    |  N  |  |
> +                             |             +-----+  |
> +                             +----------------------+
> +
> +Configuration of these MUXCNTL_N registers is done by a system controller
> +(like the Device Memory and Security Controller on K3 AM654 SoC). System
> +controller will keep track of the used and unused registers within the Router.
> +Driver should request the system controller to get the range of GIC IRQs
> +assigned to the requesting hosts. It is the drivers responsibility to keep
> +track of Host IRQs.
> +
> +Communication between the host processor running an OS and the system
> +controller happens through a protocol called TI System Control Interface
> +(TISCI protocol). For more details refer:
> +Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
> +
> +TISCI Interrupt Router Node:
> +----------------------------
> +- compatible:		Must be "ti,sci-intr".
> +- interrupt-controller:	Identifies the node as an interrupt controller
> +- #interrupt-cells:	Specifies the number of cells needed to encode an
> +			interrupt source. The value should be 4.
> +			First cell should contain the TISCI device ID of source
> +			Second cell should contain the interrupt source offset
> +			within the device
> +			Third cell specifies the trigger type as defined
> +			in interrupts.txt in this directory.
> +			Fourth cell should be 1 if the irq is coming from
> +			interrupt aggregator else 0.

This is odd. Doesn't the aggregator have a device ID too, which could
be used to discriminate between the two?

Thanks,

	M.
-- 
Without deviation from the norm, progress is not possible.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-18 15:12   ` Marc Zyngier
@ 2019-02-18 15:27     ` Lokesh Vutla
  0 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-18 15:27 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	Tony Lindgren, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Marc,

On 18/02/19 8:42 PM, Marc Zyngier wrote:
> On Tue, 12 Feb 2019 13:12:32 +0530
> Lokesh Vutla <lokeshvutla@ti.com> wrote:
> 
>> Add the DT binding documentation for Interrupt router driver.
>>
>> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
>> ---
>> Changes since v4:
>> - None
>>
>>  .../interrupt-controller/ti,sci-intr.txt      | 85 +++++++++++++++++++
>>  MAINTAINERS                                   |  1 +
>>  2 files changed, 86 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
>>
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
>> new file mode 100644
>> index 000000000000..4b0ca797fda1
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
>> @@ -0,0 +1,85 @@
>> +Texas Instruments K3 Interrupt Router
>> +=====================================
>> +
>> +The Interrupt Router (INTR) module provides a mechanism to route M
>> +interrupt inputs to N interrupt outputs, where all M inputs are selectable
>> +to be driven per N output. There is one register per output (MUXCNTL_N) that
>> +controls the selection.
>> +
>> +
>> +                                 Interrupt Router
>> +                             +----------------------+
>> +                             |  Inputs     Outputs  |
>> +        +-------+            | +------+             |
>> +        | GPIO  |----------->| | irq0 |             |       Host IRQ
>> +        +-------+            | +------+             |      controller
>> +                             |    .        +-----+  |      +-------+
>> +        +-------+            |    .        |  0  |  |----->|  IRQ  |
>> +        | INTA  |----------->|    .        +-----+  |      +-------+
>> +        +-------+            |    .          .      |
>> +                             | +------+      .      |
>> +                             | | irqM |    +-----+  |
>> +                             | +------+    |  N  |  |
>> +                             |             +-----+  |
>> +                             +----------------------+
>> +
>> +Configuration of these MUXCNTL_N registers is done by a system controller
>> +(like the Device Memory and Security Controller on K3 AM654 SoC). System
>> +controller will keep track of the used and unused registers within the Router.
>> +Driver should request the system controller to get the range of GIC IRQs
>> +assigned to the requesting hosts. It is the drivers responsibility to keep
>> +track of Host IRQs.
>> +
>> +Communication between the host processor running an OS and the system
>> +controller happens through a protocol called TI System Control Interface
>> +(TISCI protocol). For more details refer:
>> +Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>> +
>> +TISCI Interrupt Router Node:
>> +----------------------------
>> +- compatible:		Must be "ti,sci-intr".
>> +- interrupt-controller:	Identifies the node as an interrupt controller
>> +- #interrupt-cells:	Specifies the number of cells needed to encode an
>> +			interrupt source. The value should be 4.
>> +			First cell should contain the TISCI device ID of source
>> +			Second cell should contain the interrupt source offset
>> +			within the device
>> +			Third cell specifies the trigger type as defined
>> +			in interrupts.txt in this directory.
>> +			Fourth cell should be 1 if the irq is coming from
>> +			interrupt aggregator else 0.
> 
> This is odd. Doesn't the aggregator have a device ID too, which could
> be used to discriminate between the two?

For that we have to store the list of INTA device IDs connected to the INTR in
the router driver. Again we have to get this list from DT. I felt this is easier
to differentiate the INTA interrupts. If you prefer to get the list of ids and
store it in INTR driver, I can change that by adding an extra DT property.

I guess you assumed that there is a single INTA attached to an INTR. There are
cases where there are more than one INTA connected to INTR. We will have to
handle that as well.

Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 06/10] irqchip: ti-sci-intr: Add support for Interrupt Router driver
  2019-02-12  7:42 ` [PATCH v5 06/10] irqchip: ti-sci-intr: Add support for Interrupt Router driver Lokesh Vutla
@ 2019-02-18 15:52   ` Marc Zyngier
  2019-02-20 13:17     ` Lokesh Vutla
  0 siblings, 1 reply; 46+ messages in thread
From: Marc Zyngier @ 2019-02-18 15:52 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	Tony Lindgren, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

On Tue, 12 Feb 2019 13:12:33 +0530
Lokesh Vutla <lokeshvutla@ti.com> wrote:

> Texas Instruments' K3 generation SoCs has an IP Interrupt Router
> that does allows for redirection of input interrupts to host
> interrupt controller. Interrupt Router inputs are either from a
> peripheral or from an Interrupt Aggregator which is another
> interrupt controller.
> 
> Configuration of the interrupt router registers can only be done by
> a system co-processor and the driver needs to send a message to this
> co processor over TISCI protocol.
> 
> Add support for Interrupt Router driver over TISCI protocol.
> 
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> ---
> Changes since v4:
> - Moved the ti_sci irq resource handling to ti-sci-common.c from ti_sci.c.
>   Firmware maintainer rejected the idea of having this in firmware
> driver as the resource handling is specific to the client.
> - Obtain the number of peripheral interrupts attached to INTR by
> parsing DT. Using this information store the max irqs that can be
> allocated to INTA. This is done for pre allocating the INTA
> irqs(vints) during inta driver probe.
>   This will not work for cases where there are more that 1 INTAs
> attached to INTR, but wanted to show this approach as suggested by
> Marc.

Or not.

> 
>  MAINTAINERS                         |   3 +
>  drivers/irqchip/Kconfig             |  11 +
>  drivers/irqchip/Makefile            |   1 +
>  drivers/irqchip/irq-ti-sci-common.c | 131 ++++++++++++
>  drivers/irqchip/irq-ti-sci-common.h |  59 ++++++
>  drivers/irqchip/irq-ti-sci-intr.c   | 315
> ++++++++++++++++++++++++++++ 6 files changed, 520 insertions(+)
>  create mode 100644 drivers/irqchip/irq-ti-sci-common.c
>  create mode 100644 drivers/irqchip/irq-ti-sci-common.h
>  create mode 100644 drivers/irqchip/irq-ti-sci-intr.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c918d9b2ee18..823eeb672cf0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -15065,6 +15065,9 @@ F:
> Documentation/devicetree/bindings/clock/ti,sci-clk.txt F:
> drivers/clk/keystone/sci-clk.c F:	drivers/reset/reset-ti-sci.c
>  F:
> Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
> +F:	drivers/irqchip/irq-ti-sci-intr.c +F:
> drivers/irqchip/irq-ti-sci-common.c +F:
> drivers/irqchip/irq-ti-sci-common.h 
>  Texas Instruments ASoC drivers
>  M:	Peter Ujfalusi <peter.ujfalusi@ti.com>
> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
> index 3d1e60779078..a8d9bed0254b 100644
> --- a/drivers/irqchip/Kconfig
> +++ b/drivers/irqchip/Kconfig
> @@ -406,6 +406,17 @@ config IMX_IRQSTEER
>  	help
>  	  Support for the i.MX IRQSTEER interrupt
> multiplexer/remapper. 
> +config TI_SCI_INTR_IRQCHIP
> +	bool
> +	depends on TI_SCI_PROTOCOL && ARCH_K3
> +	select IRQ_DOMAIN
> +	select IRQ_DOMAIN_HIERARCHY
> +	help
> +	  This enables the irqchip driver support for K3 Interrupt
> router
> +	  over TI System Control Interface available on some new
> TI's SoCs.
> +	  If you wish to use interrupt router irq resources managed
> by the
> +	  TI System Controller, say Y here. Otherwise, say N.
> +
>  endmenu
>  
>  config SIFIVE_PLIC
> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
> index c93713d24b86..0499fae148a9 100644
> --- a/drivers/irqchip/Makefile
> +++ b/drivers/irqchip/Makefile
> @@ -94,3 +94,4 @@ obj-$(CONFIG_CSKY_APB_INTC)		+=
> irq-csky-apb-intc.o obj-$(CONFIG_SIFIVE_PLIC)		+=
> irq-sifive-plic.o obj-$(CONFIG_IMX_IRQSTEER)		+=
> irq-imx-irqsteer.o obj-$(CONFIG_MADERA_IRQ)		+=
> irq-madera.o +obj-$(CONFIG_TI_SCI_INTR_IRQCHIP)	+=
> irq-ti-sci-intr.o irq-ti-sci-common.o diff --git
> a/drivers/irqchip/irq-ti-sci-common.c
> b/drivers/irqchip/irq-ti-sci-common.c new file mode 100644 index
> 000000000000..79d9c4e8ea14 --- /dev/null
> +++ b/drivers/irqchip/irq-ti-sci-common.c
> @@ -0,0 +1,131 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Common Code for TISCI IRQCHIP drivers
> + *
> + * Copyright (C) 2019 Texas Instruments Incorporated -
> http://www.ti.com/
> + *	Lokesh Vutla <lokeshvutla@ti.com>
> + */
> +
> +#include <linux/of.h>
> +#include <linux/bitmap.h>
> +#include <linux/device.h>
> +#include <linux/soc/ti/ti_sci_protocol.h>
> +#include "irq-ti-sci-common.h"
> +
> +/**
> + * ti_sci_get_free_resource() - Get a free resource from TISCI
> resource.
> + * @res:	Pointer to the TISCI resource
> + *
> + * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL.
> + */
> +u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
> +{
> +	u16 set, free_bit;
> +
> +	mutex_lock(&res->request_mutex);
> +	for (set = 0; set < res->sets; set++) {
> +		free_bit =
> find_first_zero_bit(res->desc[set].res_map,
> +					       res->desc[set].num);
> +		if (free_bit != res->desc[set].num) {
> +			set_bit(free_bit, res->desc[set].res_map);
> +			mutex_unlock(&res->request_mutex);
> +			return res->desc[set].start + free_bit;
> +		}
> +	}
> +	mutex_unlock(&res->request_mutex);
> +
> +	return TI_SCI_RESOURCE_NULL;
> +}
> +
> +/**
> + * ti_sci_release_resource() - Release a resource from TISCI
> resource.
> + * @res:	Pointer to the TISCI resource
> + * @id:		Resource id to be released.
> + */
> +void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
> +{
> +	u16 set;
> +
> +	mutex_lock(&res->request_mutex);
> +	for (set = 0; set < res->sets; set++) {
> +		if (res->desc[set].start <= id &&
> +		    (res->desc[set].num + res->desc[set].start) > id)
> +			clear_bit(id - res->desc[set].start,
> +				  res->desc[set].res_map);
> +	}
> +	mutex_unlock(&res->request_mutex);
> +}
> +
> +u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
> +{
> +	u32 count = 0, set;
> +
> +	for (set = 0; set < res->sets; set++)
> +		count += res->desc[set].num;
> +
> +	return count;
> +}
> +
> +/**
> + * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to
> a device
> + * @handle:	TISCI handle
> + * @dev:	Device pointer to which the resource is assigned
> + * @of_prop:	property name by which the resource are
> represented
> + *
> + * Return: Pointer to ti_sci_resource if all went well else
> appropriate
> + *	   error pointer.
> + */
> +struct ti_sci_resource *
> +devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
> +			    struct device *dev, u32 dev_id, char
> *of_prop) +{
> +	struct ti_sci_resource *res;
> +	u32 resource_subtype;
> +	int i, ret;
> +
> +	res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
> +	if (!res)
> +		return ERR_PTR(-ENOMEM);
> +
> +	res->sets =
> of_property_count_elems_of_size(dev_of_node(dev), of_prop,
> +						    sizeof(u32));
> +	if (res->sets < 0) {
> +		dev_err(dev, "%s resource type ids not available\n",
> of_prop);
> +		return ERR_PTR(res->sets);
> +	}
> +
> +	res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
> +				 GFP_KERNEL);
> +	if (!res->desc)
> +		return ERR_PTR(-ENOMEM);
> +
> +	for (i = 0; i < res->sets; i++) {
> +		ret = of_property_read_u32_index(dev_of_node(dev),
> of_prop, i,
> +						 &resource_subtype);
> +		if (ret)
> +			return ERR_PTR(-EINVAL);
> +
> +		ret = handle->ops.rm_core_ops.get_range(handle,
> dev_id,
> +
> resource_subtype,
> +
> &res->desc[i].start,
> +
> &res->desc[i].num);
> +		if (ret) {
> +			dev_err(dev, "dev = %d subtype %d not
> allocated for this host\n",
> +				dev_id, resource_subtype);
> +			return ERR_PTR(ret);
> +		}
> +
> +		dev_dbg(dev, "dev = %d, subtype = %d, start = %d,
> num = %d\n",
> +			dev_id, resource_subtype, res->desc[i].start,
> +			res->desc[i].num);
> +
> +		res->desc[i].res_map =
> +			devm_kzalloc(dev,
> BITS_TO_LONGS(res->desc[i].num) *
> +				     sizeof(*res->desc[i].res_map),
> GFP_KERNEL);
> +		if (!res->desc[i].res_map)
> +			return ERR_PTR(-ENOMEM);
> +	}
> +	mutex_init(&res->request_mutex);
> +
> +	return res;
> +}
> diff --git a/drivers/irqchip/irq-ti-sci-common.h
> b/drivers/irqchip/irq-ti-sci-common.h new file mode 100644
> index 000000000000..60c4b28bebab
> --- /dev/null
> +++ b/drivers/irqchip/irq-ti-sci-common.h
> @@ -0,0 +1,59 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Common header file for TISCI IRQCHIP drivers
> + *
> + * Copyright (C) 2019 Texas Instruments Incorporated -
> http://www.ti.com/
> + *	Lokesh Vutla <lokeshvutla@ti.com>
> + */
> +
> +#ifndef __TI_SCI_COMMON_IRQCHIP_H
> +#define __TI_SCI_COMMON_IRQCHIP_H
> +
> +#include <linux/mutex.h>
> +
> +#define TI_SCI_RESOURCE_NULL	0xffff
> +#define TI_SCI_DEV_ID_MASK	0xffff
> +#define TI_SCI_DEV_ID_SHIFT	16
> +#define TI_SCI_IRQ_ID_MASK	0xffff
> +#define TI_SCI_IRQ_ID_SHIFT	0
> +#define TI_SCI_VINT_IRQ		BIT(0)
> +#define HWIRQ_TO_DEVID(hwirq)	(((hwirq) >>
> (TI_SCI_DEV_ID_SHIFT)) & \
> +				 (TI_SCI_DEV_ID_MASK))
> +#define HWIRQ_TO_IRQID(hwirq)	((hwirq) & (TI_SCI_IRQ_ID_MASK))
> +#define TO_HWIRQ(dev, index)	((((dev) & TI_SCI_DEV_ID_MASK)
> << \
> +				 TI_SCI_DEV_ID_SHIFT) | \
> +				((index) & TI_SCI_IRQ_ID_MASK))
> +
> +/**
> + * struct ti_sci_resource_desc - Description of TI SCI resource
> instance range.
> + * @start:	Start index of the resource.
> + * @num:	Number of resources.
> + * @res_map:	Bitmap to manage the allocation of these
> resources.
> + */
> +struct ti_sci_resource_desc {
> +	u16 start;
> +	u16 num;
> +	unsigned long *res_map;
> +};
> +
> +/**
> + * struct ti_sci_resource - Structure representing a resource
> assigned
> + *			    to a device.
> + * @sets:		Number of sets available from this resource
> type
> + * @request_mutex:	mutex to protect request and release of
> resources.
> + * @desc:		Array of resource descriptors.
> + */
> +struct ti_sci_resource {
> +	u16 sets;
> +	/* Mutex to protect request and release of resources */
> +	struct mutex request_mutex;
> +	struct ti_sci_resource_desc *desc;
> +};
> +
> +u16 ti_sci_get_free_resource(struct ti_sci_resource *res);
> +void ti_sci_release_resource(struct ti_sci_resource *res, u16 id);
> +u32 ti_sci_get_num_resources(struct ti_sci_resource *res);
> +struct ti_sci_resource *
> +devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
> +			    struct device *dev, u32 dev_id, char
> *of_prop); +#endif /*__TI_SCI_COMMON_IRQCHIP_H */

Most the above "common" should be a separate patch, really. Also, why
isn't the whole resource management part of the firmware interface? I
see that "Firmware maintainer rejected the idea", but I don't really
buy the rational. I don't see anything irq specific to the whole
devm_ti_sci_get_of_resource and co, to be honest.

> diff --git a/drivers/irqchip/irq-ti-sci-intr.c b/drivers/irqchip/irq-ti-sci-intr.c
> new file mode 100644
> index 000000000000..7e224552a735
> --- /dev/null
> +++ b/drivers/irqchip/irq-ti-sci-intr.c
> @@ -0,0 +1,315 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Texas Instruments' K3 Interrupt Router irqchip driver
> + *
> + * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
> + *	Lokesh Vutla <lokeshvutla@ti.com>
> + */
> +
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/irqchip.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/irqdomain.h>
> +#include <linux/soc/ti/ti_sci_protocol.h>
> +#include "irq-ti-sci-common.h"
> +
> +/**
> + * struct ti_sci_intr_irq_domain - Structure representing a TISCI based
> + *				   Interrupt Router IRQ domain.
> + * @sci:	Pointer to TISCI handle
> + * @dst_irq:	TISCI resource pointer representing GIC irq controller.
> + * @:	Number of GIC irqs that can be allocated to INTA.
> + * @dst_id:	TISCI device ID of the GIC irq controller.
> + */
> +struct ti_sci_intr_irq_domain {
> +	const struct ti_sci_handle *sci;
> +	struct ti_sci_resource *dst_irq;
> +	u32 vint_irqs;
> +	u16 dst_id;
> +};
> +
> +static struct irq_chip ti_sci_intr_irq_chip = {
> +	.name			= "INTR",
> +	.irq_eoi		= irq_chip_eoi_parent,
> +	.irq_mask		= irq_chip_mask_parent,
> +	.irq_unmask		= irq_chip_unmask_parent,
> +	.irq_retrigger		= irq_chip_retrigger_hierarchy,
> +	.irq_set_type		= irq_chip_set_type_parent,

The DT seems to be able to express settings that are not necessarily
compatible with the underlying interrupt controller (GIC500). So either
you're missing the code that will turn configure this controller to
change levels/edges, or you need to change the DT.

> +	.irq_set_affinity	= irq_chip_set_affinity_parent,
> +};
> +
> +/**
> + * ti_sci_intr_irq_domain_translate() - Retrieve hwirq and type from
> + *					IRQ firmware specific handler.
> + * @domain:	Pointer to IRQ domain
> + * @fwspec:	Pointer to IRQ specific firmware structure
> + * @hwirq:	IRQ number identified by hardware
> + * @type:	IRQ type
> + *
> + * Return 0 if all went ok else appropriate error.
> + */
> +static int ti_sci_intr_irq_domain_translate(struct irq_domain *domain,
> +					    struct irq_fwspec *fwspec,
> +					    unsigned long *hwirq,
> +					    unsigned int *type)
> +{
> +	struct ti_sci_intr_irq_domain *intr = domain->host_data;
> +
> +	if (fwspec->param_count != 4)
> +		return -EINVAL;
> +
> +	*hwirq = TO_HWIRQ(fwspec->param[0], fwspec->param[1]);
> +	*type = fwspec->param[2];
> +
> +	if (fwspec->param[3] != 0 && fwspec->param[3] != 1)
> +		return -EINVAL;
> +
> +	if (fwspec->param[3] && intr->vint_irqs <= 0)

How can vint_irqs be negative?

> +		return -ERANGE;
> +
> +	return 0;
> +}
> +
> +static inline void ti_sci_intr_free_gic_irq(struct ti_sci_intr_irq_domain *intr,

Why the inline?

> +					    u32 hwirq, u16 dst_irq, u8 vint_irq)
> +{
> +	u16 src_id, src_index;
> +
> +	src_id = HWIRQ_TO_DEVID(hwirq);
> +	src_index = HWIRQ_TO_IRQID(hwirq);
> +	intr->sci->ops.rm_irq_ops.free_irq(intr->sci, src_id, src_index,
> +					   intr->dst_id, dst_irq, vint_irq);
> +	ti_sci_release_resource(intr->dst_irq, dst_irq);
> +	if (vint_irq == TI_SCI_VINT_IRQ)
> +		intr->vint_irqs++;

What ensures that an alloc/free happening in parallel on the same data
structure will not corrupt the state?

> +}
> +
> +/**
> + * ti_sci_intr_irq_domain_free() - Free the specified IRQs from the domain.
> + * @domain:	Domain to which the irqs belong
> + * @virq:	Linux virtual IRQ to be freed.
> + * @nr_irqs:	Number of continuous irqs to be freed
> + */
> +static void ti_sci_intr_irq_domain_free(struct irq_domain *domain,
> +					unsigned int virq, unsigned int nr_irqs)
> +{
> +	struct ti_sci_intr_irq_domain *intr = domain->host_data;
> +	struct irq_data *data, *parent_data;
> +	phys_addr_t vint_irq;

What???? phys_addr_t???

> +
> +	data = irq_domain_get_irq_data(domain, virq);
> +	vint_irq = (phys_addr_t)irq_data_get_irq_chip_data(data);
> +	parent_data = irq_domain_get_irq_data(domain->parent, virq);
> +
> +	ti_sci_intr_free_gic_irq(intr, data->hwirq, parent_data->hwirq,
> +				 vint_irq);

Err... Isn't vint_irq supposed to be a u8? But on the other side,
intr->vint_irqs is a u32. I'm sorry, but none of that makes any sense.
Please explain what is what.

> +	irq_domain_free_irqs_parent(domain, virq, 1);
> +	irq_domain_reset_irq_data(data);
> +}
> +
> +/**
> + * ti_sci_intr_alloc_gic_irq() - Allocate GIC specific IRQ
> + * @domain:	Point to the interrupt router IRQ domain
> + * @virq:	Corresponding Linux virtual IRQ number
> + * @dev:	TISCI device IRQ generating the IRQ
> + * @irq:	IRQ offset within the device
> + * @flags:	Corresponding flags to the IRQ
> + * @vint_irq:	Flag to tell if requested irq is from interrupt aggregator.
> + *
> + * Returns 0 if all went well else appropriate error pointer.
> + */
> +static int ti_sci_intr_alloc_gic_irq(struct irq_domain *domain,
> +				     unsigned int virq, u32 hwirq, u32 flags,
> +				     u8 vint_irq)
> +{
> +	struct ti_sci_intr_irq_domain *intr = domain->host_data;
> +	struct irq_fwspec fwspec;
> +	u16 src_id, src_index;
> +	u16 dst_irq;
> +	int err;
> +
> +	src_id = HWIRQ_TO_DEVID(hwirq);
> +	src_index = HWIRQ_TO_IRQID(hwirq);
> +
> +	dst_irq = ti_sci_get_free_resource(intr->dst_irq);
> +	if (dst_irq == TI_SCI_RESOURCE_NULL)
> +		return -EINVAL;
> +
> +	fwspec.fwnode = domain->parent->fwnode;
> +	fwspec.param_count = 3;
> +	fwspec.param[0] = 0;	/* SPI */
> +	fwspec.param[1] = dst_irq - 32; /* SPI offset */
> +	fwspec.param[2] = flags & IRQ_TYPE_SENSE_MASK;
> +
> +	err = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec);
> +	if (err)
> +		goto err_irqs;
> +
> +	err = intr->sci->ops.rm_irq_ops.set_irq(intr->sci, src_id, src_index,
> +						intr->dst_id, dst_irq,
> +						vint_irq);
> +	if (err)
> +		goto err_msg;
> +
> +	if (vint_irq == TI_SCI_VINT_IRQ)
> +		intr->vint_irqs--;

Same RMW problem.

> +
> +	return 0;
> +
> +err_msg:
> +	irq_domain_free_irqs_parent(domain, virq, 1);
> +err_irqs:
> +	ti_sci_release_resource(intr->dst_irq, dst_irq);
> +	return err;
> +}
> +
> +/**
> + * ti_sci_intr_irq_domain_alloc() - Allocate Interrupt router IRQs
> + * @domain:	Point to the interrupt router IRQ domain
> + * @virq:	Corresponding Linux virtual IRQ number
> + * @nr_irqs:	Continuous irqs to be allocated
> + * @data:	Pointer to firmware specifier
> + *
> + * Return 0 if all went well else appropriate error value.
> + */
> +static int ti_sci_intr_irq_domain_alloc(struct irq_domain *domain,
> +					unsigned int virq, unsigned int nr_irqs,
> +					void *data)
> +{
> +	struct irq_fwspec *fwspec = data;
> +	phys_addr_t vint_irq;

This is sad.

> +	unsigned long hwirq;
> +	u32 type;
> +	int err;
> +
> +	err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &type);
> +	if (err)
> +		return err;
> +
> +	vint_irq = fwspec->param[3] & TI_SCI_VINT_IRQ;
> +
> +	err = ti_sci_intr_alloc_gic_irq(domain, virq, hwirq, type, vint_irq);
> +	if (err)
> +		return err;
> +
> +	err = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
> +					    &ti_sci_intr_irq_chip,
> +					    (void *)vint_irq);

I think I see what you're trying to achieve. I suggest you look a
uintptr_t instead of playing with unrelated data types whose semantic
really doesn't apply here.

> +	if (err) {
> +		ti_sci_intr_irq_domain_free(domain, virq, 1);
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops ti_sci_intr_irq_domain_ops = {
> +	.alloc		= ti_sci_intr_irq_domain_alloc,
> +	.free		= ti_sci_intr_irq_domain_free,
> +	.translate	= ti_sci_intr_irq_domain_translate,
> +};
> +
> +static int ti_sci_intr_irq_domain_probe(struct platform_device *pdev)
> +{
> +	struct irq_domain *parent_domain, *domain;
> +	struct device_node *parent_node, *dn;
> +	struct ti_sci_intr_irq_domain *intr;
> +	struct device *dev = &pdev->dev;
> +	struct of_phandle_iterator it;
> +	int ret, count, intsize;
> +
> +	parent_node = of_irq_find_parent(dev_of_node(dev));
> +	if (!parent_node) {
> +		dev_err(dev, "Failed to get IRQ parent node\n");
> +		return -ENODEV;
> +	}
> +
> +	parent_domain = irq_find_host(parent_node);
> +	if (!parent_domain) {
> +		dev_err(dev, "Failed to find IRQ parent domain\n");
> +		return -ENODEV;
> +	}
> +
> +	intr = devm_kzalloc(dev, sizeof(*intr), GFP_KERNEL);
> +	if (!intr)
> +		return -ENOMEM;
> +
> +	intr->sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
> +	if (IS_ERR(intr->sci)) {
> +		ret = PTR_ERR(intr->sci);
> +		if (ret != -EPROBE_DEFER)
> +			dev_err(dev, "ti,sci read fail %d\n", ret);
> +		intr->sci = NULL;
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32(dev_of_node(dev), "ti,sci-dst-id",
> +				   (u32 *)&intr->dst_id);
> +	if (ret) {
> +		dev_err(dev, "missing 'ti,sci-dst-id' property\n");
> +		return -EINVAL;
> +	}
> +
> +	intr->dst_irq = devm_ti_sci_get_of_resource(intr->sci, dev,
> +						    intr->dst_id,
> +						    "ti,sci-rm-range-girq");
> +	if (IS_ERR(intr->dst_irq)) {
> +		dev_err(dev, "Destination irq resource allocation failed\n");
> +		return PTR_ERR(intr->dst_irq);
> +	}
> +
> +	domain = irq_domain_add_hierarchy(parent_domain, 0, 0, dev_of_node(dev),
> +					  &ti_sci_intr_irq_domain_ops, intr);
> +	if (!domain) {
> +		dev_err(dev, "Failed to allocate IRQ domain\n");
> +		return -ENOMEM;
> +	}
> +
> +	if (of_property_read_u32(dev_of_node(dev), "#interrupt-cells",
> +				 &intsize))
> +		return -EINVAL;
> +
> +	count = 0;
> +	for_each_node_with_property(dn, "interrupts") {
> +		if (of_irq_find_parent(dn) != dev_of_node(dev))
> +			continue;
> +		count += of_property_count_elems_of_size(dn, "interrupts",
> +							 sizeof(u32) * intsize);
> +	}
> +
> +	for_each_node_with_property(dn, "interrupts-extended") {
> +		of_for_each_phandle(&it, ret, dn, "interrupts-extended",
> +				    "#interrupt-cells", 0) {
> +			if (it.node == dev_of_node(dev))
> +				count++;
> +		}
> +	}

What is this trying to do? Counting the number of interrupt descriptors
in the whole system? What does this even mean?

What I suggested was to allocate the required number of interrupts
for a given device, based on the requirements of that device. I also
suggested to investigate the x86 two phase allocation mechanism for the
INTA driver.

I never suggested that you'd parse the DT to guess how many interrupts
you'd need to allocate...

	M.

> +
> +	intr->vint_irqs = ti_sci_get_num_resources(intr->dst_irq) - count;
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id ti_sci_intr_irq_domain_of_match[] = {
> +	{ .compatible = "ti,sci-intr", },
> +	{ /* sentinel */ },
> +};
> +MODULE_DEVICE_TABLE(of, ti_sci_intr_irq_domain_of_match);
> +
> +static struct platform_driver ti_sci_intr_irq_domain_driver = {
> +	.probe = ti_sci_intr_irq_domain_probe,
> +	.driver = {
> +		.name = "ti-sci-intr",
> +		.of_match_table = ti_sci_intr_irq_domain_of_match,
> +	},
> +};
> +module_platform_driver(ti_sci_intr_irq_domain_driver);
> +
> +MODULE_AUTHOR("Lokesh Vutla <lokeshvutla@ticom>");
> +MODULE_DESCRIPTION("K3 Interrupt Router driver over TI SCI protocol");
> +MODULE_LICENSE("GPL v2");



-- 
Without deviation from the norm, progress is not possible.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-18 14:32                       ` Tony Lindgren
@ 2019-02-19  8:51                         ` Lokesh Vutla
  2019-02-19 15:35                           ` Tony Lindgren
  0 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-19  8:51 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Tony,

On 18/02/19 8:02 PM, Tony Lindgren wrote:
> * Lokesh Vutla <lokeshvutla@ti.com> [190216 03:30]:
>> On 2/15/2019 9:46 PM, Tony Lindgren wrote:
>>> The dts node for the interrupt controller should describe a
>>> proper Linux device, that is with reg entries and so on.
>>
>> You are asking to just keep the compatible property :)
> 
> Right, and then I realized this node is missing the standard
> reg entry too. And you're saying the registers are not even
> accissible from Linux.
> 
> So based on that IMO you should not even have a device tree
> node for it at all. You should just have the interrupt

Practically lets look at what all I am adding in the DT node. Below is one such
example:

main_intr: interrupt-controller0 {
	compatible = "ti,sci-intr";
	interrupt-controller;
	interrupt-parent = <&gic500>;
	#interrupt-cells = <4>;
	ti,sci = <&dmsc>;
	ti,sci-dst-id = <56>;
	ti,sci-rm-range-girq = <0x1>;
};

The following 4 properties are required at least for probing, to represent the
hierarchy and for  interrupt definition:
	compatible = "ti,sci-intr";
	interrupt-controller;
	interrupt-parent = <&gic500>;
	#interrupt-cells = <4>;

The remaining 3 properties represents the TISCI interface. Let's go step by step:
* ti,sci = <&dmsc> :This is the phandle to the firmware protocol driver using
which the messages are sent
* ti,sci-dst-id = <56> : This is the TISCI device ID for the parent controller
for which your irqs needs to be connected. As I said this cannot be queried from
sysfw and this is the input to the messages that are send to sysfw.
*  ti,sci-rm-range-girq = <0x1>: This define the ids using which the parent-irq
ranges that are allocated to this interrupt router instance can be queried from
sysfw.
If the above 2 properties are to be added as driver phandle then for every
instance of interrupt router in the SoC, a new compatible needs to be created. I
don't think this is a desirable solution.

With this can you tell me how can we not have a device-tree and still support
irq allocation?

Also, this is not the first time a driver based on a firmware is being added.
K2g clock, power and reset drivers are based on this where device ids are being
passed from consumers. Similarly arm scpi based drivers are also available.

Thanks and regards,
Lokesh




_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-19  8:51                         ` Lokesh Vutla
@ 2019-02-19 15:35                           ` Tony Lindgren
  2019-02-19 16:19                             ` Lokesh Vutla
  2019-02-20 16:36                             ` Tony Lindgren
  0 siblings, 2 replies; 46+ messages in thread
From: Tony Lindgren @ 2019-02-19 15:35 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Lokesh Vutla <lokeshvutla@ti.com> [190219 08:51]:
> Hi Tony,
> 
> On 18/02/19 8:02 PM, Tony Lindgren wrote:
> > * Lokesh Vutla <lokeshvutla@ti.com> [190216 03:30]:
> >> On 2/15/2019 9:46 PM, Tony Lindgren wrote:
> >>> The dts node for the interrupt controller should describe a
> >>> proper Linux device, that is with reg entries and so on.
> >>
> >> You are asking to just keep the compatible property :)
> > 
> > Right, and then I realized this node is missing the standard
> > reg entry too. And you're saying the registers are not even
> > accissible from Linux.
> > 
> > So based on that IMO you should not even have a device tree
> > node for it at all. You should just have the interrupt
> 
> Practically lets look at what all I am adding in the DT node. Below is one such
> example:
> 
> main_intr: interrupt-controller0 {
> 	compatible = "ti,sci-intr";
> 	interrupt-controller;
> 	interrupt-parent = <&gic500>;
> 	#interrupt-cells = <4>;
> 	ti,sci = <&dmsc>;
> 	ti,sci-dst-id = <56>;
> 	ti,sci-rm-range-girq = <0x1>;
> };
> 
> The following 4 properties are required at least for probing, to represent the
> hierarchy and for  interrupt definition:
> 	compatible = "ti,sci-intr";
> 	interrupt-controller;
> 	interrupt-parent = <&gic500>;
> 	#interrupt-cells = <4>;
> 
> The remaining 3 properties represents the TISCI interface. Let's go step by step:
> * ti,sci = <&dmsc> :This is the phandle to the firmware protocol driver using
> which the messages are sent
> * ti,sci-dst-id = <56> : This is the TISCI device ID for the parent controller
> for which your irqs needs to be connected. As I said this cannot be queried from
> sysfw and this is the input to the messages that are send to sysfw.

Let's not add anything that does not describe hardware to the device
tree. This is ID is an invented number used by the firmware.

> *  ti,sci-rm-range-girq = <0x1>: This define the ids using which the parent-irq
> ranges that are allocated to this interrupt router instance can be queried from
> sysfw.
> If the above 2 properties are to be added as driver phandle then for every
> instance of interrupt router in the SoC, a new compatible needs to be created. I
> don't think this is a desirable solution.

To me it seems that the interrupt router _must_ have proper IO
configuration registers available to the Linux running SoC.

Are you sure the interrupt route does not have proper IO
configuration registers available for the Linux running SoC?

If the there are not, I'd be surprised how the SoC is designed :)

So assuming it does, you should just use the standard device tree
reg property to differentiate between the various interrupt router
instances. And then you can have the driver talk to the firmware
in a way where the driver instances are separate even if no IO
access to these shared registers is done by the Linux running SoC.

But see also the mux comment below.

> With this can you tell me how can we not have a device-tree and still support
> irq allocation?

Using standard dts reg property to differentiate the interrupt
router instances. And if the interrupt router is a mux, you should
treat it as a mux rather than a chained interrupt controller.

We do have drivers/mux nowadays, not sure if it helps in this case
as at least timer interrupts need to be configured very early.

> Also, this is not the first time a driver based on a firmware is being added.
> K2g clock, power and reset drivers are based on this where device ids are being
> passed from consumers. Similarly arm scpi based drivers are also available.

Having drivers communicate with firmware is quite standard.

However, stuffing firmware specific data to the device tree
does not describe the hardware and must not be done.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-19 15:35                           ` Tony Lindgren
@ 2019-02-19 16:19                             ` Lokesh Vutla
  2019-02-19 17:11                               ` Tony Lindgren
  2019-02-20 16:36                             ` Tony Lindgren
  1 sibling, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-19 16:19 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List



On 2/19/2019 9:05 PM, Tony Lindgren wrote:
> * Lokesh Vutla <lokeshvutla@ti.com> [190219 08:51]:
>> Hi Tony,
>>
>> On 18/02/19 8:02 PM, Tony Lindgren wrote:
>>> * Lokesh Vutla <lokeshvutla@ti.com> [190216 03:30]:
>>>> On 2/15/2019 9:46 PM, Tony Lindgren wrote:
>>>>> The dts node for the interrupt controller should describe a
>>>>> proper Linux device, that is with reg entries and so on.
>>>>
>>>> You are asking to just keep the compatible property :)
>>>
>>> Right, and then I realized this node is missing the standard
>>> reg entry too. And you're saying the registers are not even
>>> accissible from Linux.
>>>
>>> So based on that IMO you should not even have a device tree
>>> node for it at all. You should just have the interrupt
>>
>> Practically lets look at what all I am adding in the DT node. Below is one such
>> example:
>>
>> main_intr: interrupt-controller0 {
>> 	compatible = "ti,sci-intr";
>> 	interrupt-controller;
>> 	interrupt-parent = <&gic500>;
>> 	#interrupt-cells = <4>;
>> 	ti,sci = <&dmsc>;
>> 	ti,sci-dst-id = <56>;
>> 	ti,sci-rm-range-girq = <0x1>;
>> };
>>
>> The following 4 properties are required at least for probing, to represent the
>> hierarchy and for  interrupt definition:
>> 	compatible = "ti,sci-intr";
>> 	interrupt-controller;
>> 	interrupt-parent = <&gic500>;
>> 	#interrupt-cells = <4>;
>>
>> The remaining 3 properties represents the TISCI interface. Let's go step by step:
>> * ti,sci = <&dmsc> :This is the phandle to the firmware protocol driver using
>> which the messages are sent
>> * ti,sci-dst-id = <56> : This is the TISCI device ID for the parent controller
>> for which your irqs needs to be connected. As I said this cannot be queried from
>> sysfw and this is the input to the messages that are send to sysfw.
> 
> Let's not add anything that does not describe hardware to the device
> tree. This is ID is an invented number used by the firmware.
> 
>> *  ti,sci-rm-range-girq = <0x1>: This define the ids using which the parent-irq
>> ranges that are allocated to this interrupt router instance can be queried from
>> sysfw.
>> If the above 2 properties are to be added as driver phandle then for every
>> instance of interrupt router in the SoC, a new compatible needs to be created. I
>> don't think this is a desirable solution.
> 
> To me it seems that the interrupt router _must_ have proper IO
> configuration registers available to the Linux running SoC.
> 
> Are you sure the interrupt route does not have proper IO
> configuration registers available for the Linux running SoC?
> 
> If the there are not, I'd be surprised how the SoC is designed :)
> 
> So assuming it does, you should just use the standard device tree
> reg property to differentiate between the various interrupt router
> instances. And then you can have the driver talk to the firmware
> in a way where the driver instances are separate even if no IO
> access to these shared registers is done by the Linux running SoC.
> 
> But see also the mux comment below.
> 
>> With this can you tell me how can we not have a device-tree and still support
>> irq allocation?
> 
> Using standard dts reg property to differentiate the interrupt
> router instances. And if the interrupt router is a mux, you should
> treat it as a mux rather than a chained interrupt controller.
> 
> We do have drivers/mux nowadays, not sure if it helps in this case
> as at least timer interrupts need to be configured very early.
> 
>> Also, this is not the first time a driver based on a firmware is being added.
>> K2g clock, power and reset drivers are based on this where device ids are being
>> passed from consumers. Similarly arm scpi based drivers are also available.
> 
> Having drivers communicate with firmware is quite standard.

yes. How different is this from any of the above mentioned drivers using
firmware specific ids. Like sci pm domain[1] driver utilizes the same
device id for enabling any device in the system. Similarly clock
driver[2] uses the same device ids and clock ids specified by firmware.
There are more which similarly represents firmware ids from DT.

[1] Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
[2] Documentation/devicetree/bindings/clock/ti,sci-clk.txt

Thanks and regards,
Lokesh

> 
> However, stuffing firmware specific data to the device tree
> does not describe the hardware and must not be done.
> 
> Regards,
> 
> Tony
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-19 16:19                             ` Lokesh Vutla
@ 2019-02-19 17:11                               ` Tony Lindgren
  2019-02-19 17:56                                 ` Tony Lindgren
  0 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-19 17:11 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	marc.zyngier, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Lokesh Vutla <lokeshvutla@ti.com> [190219 16:19]:
> yes. How different is this from any of the above mentioned drivers using
> firmware specific ids. Like sci pm domain[1] driver utilizes the same
> device id for enabling any device in the system. Similarly clock
> driver[2] uses the same device ids and clock ids specified by firmware.
> There are more which similarly represents firmware ids from DT.
> 
> [1] Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
> [2] Documentation/devicetree/bindings/clock/ti,sci-clk.txt

That's horrible. We really must not use any firmware invented
numbers in the device as they do not describe hardware.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-19 17:11                               ` Tony Lindgren
@ 2019-02-19 17:56                                 ` Tony Lindgren
  2019-02-20  5:53                                   ` Lokesh Vutla
  0 siblings, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-19 17:56 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, marc.zyngier,
	Tero Kristo, Sekhar Nori, linux-kernel, Peter Ujfalusi,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

* Tony Lindgren <tony@atomide.com> [190219 17:11]:
> * Lokesh Vutla <lokeshvutla@ti.com> [190219 16:19]:
> > yes. How different is this from any of the above mentioned drivers using
> > firmware specific ids. Like sci pm domain[1] driver utilizes the same
> > device id for enabling any device in the system. Similarly clock
> > driver[2] uses the same device ids and clock ids specified by firmware.
> > There are more which similarly represents firmware ids from DT.
> > 
> > [1] Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
> > [2] Documentation/devicetree/bindings/clock/ti,sci-clk.txt
> 
> That's horrible. We really must not use any firmware invented
> numbers in the device as they do not describe hardware.

No firmware invented numbers in the device tree I mean naturally.
Drivers do whatever they need to do to deal with the firmware.

Regards,

Tony

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-19 17:56                                 ` Tony Lindgren
@ 2019-02-20  5:53                                   ` Lokesh Vutla
  0 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-20  5:53 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, marc.zyngier,
	Tero Kristo, Sekhar Nori, linux-kernel, Peter Ujfalusi,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Tony,

On 19/02/19 11:26 PM, Tony Lindgren wrote:
> * Tony Lindgren <tony@atomide.com> [190219 17:11]:
>> * Lokesh Vutla <lokeshvutla@ti.com> [190219 16:19]:
>>> yes. How different is this from any of the above mentioned drivers using
>>> firmware specific ids. Like sci pm domain[1] driver utilizes the same
>>> device id for enabling any device in the system. Similarly clock
>>> driver[2] uses the same device ids and clock ids specified by firmware.
>>> There are more which similarly represents firmware ids from DT.
>>>
>>> [1] Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
>>> [2] Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>>
>> That's horrible. We really must not use any firmware invented
>> numbers in the device as they do not describe hardware.
> 
> No firmware invented numbers in the device tree I mean naturally.
> Drivers do whatever they need to do to deal with the firmware.

Let's look at these similar other examples available inside Linux:

1: ./Documentation/devicetree/bindings/arm/arm,scmi.txt mentions the following:
- #clock-cells : Should be 1. Contains the Clock ID value used by SCMI commands.
- #power-domain-cells : Should be 1. Contains the device or the power
                                        domain ID value used by SCMI commands.

2: Documentation/devicetree/bindings/arm/arm,scpi.txt mentions the following:
- #power-domain-cells : Should be 1. Contains the device or the power
                             domain ID value used by SCPI commands.

3: Documentation/devicetree/bindings/firmware/nvidia,tegra186-bpmp.txt
the firmware specified identifier are defined in the following header files:
	include/dt-bindings/clock/tegra186-clock.h
	include/dt-bindings/power/tegra186-powergate.h
	include/dt-bindings/reset/tegra186-reset.h

4. Documentation/devicetree/bindings/firmware/xilinx/xlnx,zynqmp-firmware.txt
mentions the following:
"Output clocks are registered based on clock information received
from firmware. Output clocks indexes are mentioned in
include/dt-bindings/clock/xlnx,zynqmp-clk.h."

5. Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt mentions the
following:
 - #power-domain-cells:  Must be 1. Contains the Resource ID used by
                          SCU commands.
                          See detailed Resource ID list from:
                          include/dt-bindings/firmware/imx/rsrc.h
- The clock consumer should specify the desired clock by having the clock
ID in its "clocks" phandle cell.
See the full list of clock IDs from: include/dt-bindings/clock/imx8qxp-clock.

6. Documentation/devicetree/bindings/arm/psci.txt have the following properties:
- cpu_suspend   : Function ID for CPU_SUSPEND operation
- cpu_off       : Function ID for CPU_OFF operation
- cpu_on        : Function ID for CPU_ON operation
- migrate       : Function ID for MIGRATE operation

All the above examples uses the firmware identifiers for devices/clocks or for
other functionalities and use them directly in DT. These are all somewhat
similar to TI sysfw which runs on a micro-controller and tries to abstract
certain functionalities from HLOS. There are many more such examples but I
listed only a few users. The feedback you are providing is not going to work for
any of the above listed firmware interfaces.

Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 06/10] irqchip: ti-sci-intr: Add support for Interrupt Router driver
  2019-02-18 15:52   ` Marc Zyngier
@ 2019-02-20 13:17     ` Lokesh Vutla
  2019-03-19 12:44       ` Lokesh Vutla
  0 siblings, 1 reply; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-20 13:17 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Peter Ujfalusi,
	Tony Lindgren, Sekhar Nori, linux-kernel, Tero Kristo,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Marc,

On 18/02/19 9:22 PM, Marc Zyngier wrote:
> On Tue, 12 Feb 2019 13:12:33 +0530
> Lokesh Vutla <lokeshvutla@ti.com> wrote:
> 
>> Texas Instruments' K3 generation SoCs has an IP Interrupt Router
>> that does allows for redirection of input interrupts to host
>> interrupt controller. Interrupt Router inputs are either from a
>> peripheral or from an Interrupt Aggregator which is another
>> interrupt controller.
>>
>> Configuration of the interrupt router registers can only be done by
>> a system co-processor and the driver needs to send a message to this
>> co processor over TISCI protocol.
>>
>> Add support for Interrupt Router driver over TISCI protocol.
>>
>> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
>> ---
>> Changes since v4:
>> - Moved the ti_sci irq resource handling to ti-sci-common.c from ti_sci.c.
>>   Firmware maintainer rejected the idea of having this in firmware
>> driver as the resource handling is specific to the client.
>> - Obtain the number of peripheral interrupts attached to INTR by
>> parsing DT. Using this information store the max irqs that can be
>> allocated to INTA. This is done for pre allocating the INTA
>> irqs(vints) during inta driver probe.
>>   This will not work for cases where there are more that 1 INTAs
>> attached to INTR, but wanted to show this approach as suggested by
>> Marc.
> 
> Or not.
> 
>>
>>  MAINTAINERS                         |   3 +
>>  drivers/irqchip/Kconfig             |  11 +
>>  drivers/irqchip/Makefile            |   1 +
>>  drivers/irqchip/irq-ti-sci-common.c | 131 ++++++++++++
>>  drivers/irqchip/irq-ti-sci-common.h |  59 ++++++
>>  drivers/irqchip/irq-ti-sci-intr.c   | 315
>> ++++++++++++++++++++++++++++ 6 files changed, 520 insertions(+)
>>  create mode 100644 drivers/irqchip/irq-ti-sci-common.c
>>  create mode 100644 drivers/irqchip/irq-ti-sci-common.h
>>  create mode 100644 drivers/irqchip/irq-ti-sci-intr.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index c918d9b2ee18..823eeb672cf0 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -15065,6 +15065,9 @@ F:
>> Documentation/devicetree/bindings/clock/ti,sci-clk.txt F:
>> drivers/clk/keystone/sci-clk.c F:	drivers/reset/reset-ti-sci.c
>>  F:
>> Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
>> +F:	drivers/irqchip/irq-ti-sci-intr.c +F:
>> drivers/irqchip/irq-ti-sci-common.c +F:
>> drivers/irqchip/irq-ti-sci-common.h 
>>  Texas Instruments ASoC drivers
>>  M:	Peter Ujfalusi <peter.ujfalusi@ti.com>
>> diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
>> index 3d1e60779078..a8d9bed0254b 100644
>> --- a/drivers/irqchip/Kconfig
>> +++ b/drivers/irqchip/Kconfig
>> @@ -406,6 +406,17 @@ config IMX_IRQSTEER
>>  	help
>>  	  Support for the i.MX IRQSTEER interrupt
>> multiplexer/remapper. 
>> +config TI_SCI_INTR_IRQCHIP
>> +	bool
>> +	depends on TI_SCI_PROTOCOL && ARCH_K3
>> +	select IRQ_DOMAIN
>> +	select IRQ_DOMAIN_HIERARCHY
>> +	help
>> +	  This enables the irqchip driver support for K3 Interrupt
>> router
>> +	  over TI System Control Interface available on some new
>> TI's SoCs.
>> +	  If you wish to use interrupt router irq resources managed
>> by the
>> +	  TI System Controller, say Y here. Otherwise, say N.
>> +
>>  endmenu
>>  
>>  config SIFIVE_PLIC
>> diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
>> index c93713d24b86..0499fae148a9 100644
>> --- a/drivers/irqchip/Makefile
>> +++ b/drivers/irqchip/Makefile
>> @@ -94,3 +94,4 @@ obj-$(CONFIG_CSKY_APB_INTC)		+=
>> irq-csky-apb-intc.o obj-$(CONFIG_SIFIVE_PLIC)		+=
>> irq-sifive-plic.o obj-$(CONFIG_IMX_IRQSTEER)		+=
>> irq-imx-irqsteer.o obj-$(CONFIG_MADERA_IRQ)		+=
>> irq-madera.o +obj-$(CONFIG_TI_SCI_INTR_IRQCHIP)	+=
>> irq-ti-sci-intr.o irq-ti-sci-common.o diff --git
>> a/drivers/irqchip/irq-ti-sci-common.c
>> b/drivers/irqchip/irq-ti-sci-common.c new file mode 100644 index
>> 000000000000..79d9c4e8ea14 --- /dev/null
>> +++ b/drivers/irqchip/irq-ti-sci-common.c
>> @@ -0,0 +1,131 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Common Code for TISCI IRQCHIP drivers
>> + *
>> + * Copyright (C) 2019 Texas Instruments Incorporated -
>> http://www.ti.com/
>> + *	Lokesh Vutla <lokeshvutla@ti.com>
>> + */
>> +
>> +#include <linux/of.h>
>> +#include <linux/bitmap.h>
>> +#include <linux/device.h>
>> +#include <linux/soc/ti/ti_sci_protocol.h>
>> +#include "irq-ti-sci-common.h"
>> +
>> +/**
>> + * ti_sci_get_free_resource() - Get a free resource from TISCI
>> resource.
>> + * @res:	Pointer to the TISCI resource
>> + *
>> + * Return: resource num if all went ok else TI_SCI_RESOURCE_NULL.
>> + */
>> +u16 ti_sci_get_free_resource(struct ti_sci_resource *res)
>> +{
>> +	u16 set, free_bit;
>> +
>> +	mutex_lock(&res->request_mutex);
>> +	for (set = 0; set < res->sets; set++) {
>> +		free_bit =
>> find_first_zero_bit(res->desc[set].res_map,
>> +					       res->desc[set].num);
>> +		if (free_bit != res->desc[set].num) {
>> +			set_bit(free_bit, res->desc[set].res_map);
>> +			mutex_unlock(&res->request_mutex);
>> +			return res->desc[set].start + free_bit;
>> +		}
>> +	}
>> +	mutex_unlock(&res->request_mutex);
>> +
>> +	return TI_SCI_RESOURCE_NULL;
>> +}
>> +
>> +/**
>> + * ti_sci_release_resource() - Release a resource from TISCI
>> resource.
>> + * @res:	Pointer to the TISCI resource
>> + * @id:		Resource id to be released.
>> + */
>> +void ti_sci_release_resource(struct ti_sci_resource *res, u16 id)
>> +{
>> +	u16 set;
>> +
>> +	mutex_lock(&res->request_mutex);
>> +	for (set = 0; set < res->sets; set++) {
>> +		if (res->desc[set].start <= id &&
>> +		    (res->desc[set].num + res->desc[set].start) > id)
>> +			clear_bit(id - res->desc[set].start,
>> +				  res->desc[set].res_map);
>> +	}
>> +	mutex_unlock(&res->request_mutex);
>> +}
>> +
>> +u32 ti_sci_get_num_resources(struct ti_sci_resource *res)
>> +{
>> +	u32 count = 0, set;
>> +
>> +	for (set = 0; set < res->sets; set++)
>> +		count += res->desc[set].num;
>> +
>> +	return count;
>> +}
>> +
>> +/**
>> + * devm_ti_sci_get_of_resource() - Get a TISCI resource assigned to
>> a device
>> + * @handle:	TISCI handle
>> + * @dev:	Device pointer to which the resource is assigned
>> + * @of_prop:	property name by which the resource are
>> represented
>> + *
>> + * Return: Pointer to ti_sci_resource if all went well else
>> appropriate
>> + *	   error pointer.
>> + */
>> +struct ti_sci_resource *
>> +devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
>> +			    struct device *dev, u32 dev_id, char
>> *of_prop) +{
>> +	struct ti_sci_resource *res;
>> +	u32 resource_subtype;
>> +	int i, ret;
>> +
>> +	res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
>> +	if (!res)
>> +		return ERR_PTR(-ENOMEM);
>> +
>> +	res->sets =
>> of_property_count_elems_of_size(dev_of_node(dev), of_prop,
>> +						    sizeof(u32));
>> +	if (res->sets < 0) {
>> +		dev_err(dev, "%s resource type ids not available\n",
>> of_prop);
>> +		return ERR_PTR(res->sets);
>> +	}
>> +
>> +	res->desc = devm_kcalloc(dev, res->sets, sizeof(*res->desc),
>> +				 GFP_KERNEL);
>> +	if (!res->desc)
>> +		return ERR_PTR(-ENOMEM);
>> +
>> +	for (i = 0; i < res->sets; i++) {
>> +		ret = of_property_read_u32_index(dev_of_node(dev),
>> of_prop, i,
>> +						 &resource_subtype);
>> +		if (ret)
>> +			return ERR_PTR(-EINVAL);
>> +
>> +		ret = handle->ops.rm_core_ops.get_range(handle,
>> dev_id,
>> +
>> resource_subtype,
>> +
>> &res->desc[i].start,
>> +
>> &res->desc[i].num);
>> +		if (ret) {
>> +			dev_err(dev, "dev = %d subtype %d not
>> allocated for this host\n",
>> +				dev_id, resource_subtype);
>> +			return ERR_PTR(ret);
>> +		}
>> +
>> +		dev_dbg(dev, "dev = %d, subtype = %d, start = %d,
>> num = %d\n",
>> +			dev_id, resource_subtype, res->desc[i].start,
>> +			res->desc[i].num);
>> +
>> +		res->desc[i].res_map =
>> +			devm_kzalloc(dev,
>> BITS_TO_LONGS(res->desc[i].num) *
>> +				     sizeof(*res->desc[i].res_map),
>> GFP_KERNEL);
>> +		if (!res->desc[i].res_map)
>> +			return ERR_PTR(-ENOMEM);
>> +	}
>> +	mutex_init(&res->request_mutex);
>> +
>> +	return res;
>> +}
>> diff --git a/drivers/irqchip/irq-ti-sci-common.h
>> b/drivers/irqchip/irq-ti-sci-common.h new file mode 100644
>> index 000000000000..60c4b28bebab
>> --- /dev/null
>> +++ b/drivers/irqchip/irq-ti-sci-common.h
>> @@ -0,0 +1,59 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Common header file for TISCI IRQCHIP drivers
>> + *
>> + * Copyright (C) 2019 Texas Instruments Incorporated -
>> http://www.ti.com/
>> + *	Lokesh Vutla <lokeshvutla@ti.com>
>> + */
>> +
>> +#ifndef __TI_SCI_COMMON_IRQCHIP_H
>> +#define __TI_SCI_COMMON_IRQCHIP_H
>> +
>> +#include <linux/mutex.h>
>> +
>> +#define TI_SCI_RESOURCE_NULL	0xffff
>> +#define TI_SCI_DEV_ID_MASK	0xffff
>> +#define TI_SCI_DEV_ID_SHIFT	16
>> +#define TI_SCI_IRQ_ID_MASK	0xffff
>> +#define TI_SCI_IRQ_ID_SHIFT	0
>> +#define TI_SCI_VINT_IRQ		BIT(0)
>> +#define HWIRQ_TO_DEVID(hwirq)	(((hwirq) >>
>> (TI_SCI_DEV_ID_SHIFT)) & \
>> +				 (TI_SCI_DEV_ID_MASK))
>> +#define HWIRQ_TO_IRQID(hwirq)	((hwirq) & (TI_SCI_IRQ_ID_MASK))
>> +#define TO_HWIRQ(dev, index)	((((dev) & TI_SCI_DEV_ID_MASK)
>> << \
>> +				 TI_SCI_DEV_ID_SHIFT) | \
>> +				((index) & TI_SCI_IRQ_ID_MASK))
>> +
>> +/**
>> + * struct ti_sci_resource_desc - Description of TI SCI resource
>> instance range.
>> + * @start:	Start index of the resource.
>> + * @num:	Number of resources.
>> + * @res_map:	Bitmap to manage the allocation of these
>> resources.
>> + */
>> +struct ti_sci_resource_desc {
>> +	u16 start;
>> +	u16 num;
>> +	unsigned long *res_map;
>> +};
>> +
>> +/**
>> + * struct ti_sci_resource - Structure representing a resource
>> assigned
>> + *			    to a device.
>> + * @sets:		Number of sets available from this resource
>> type
>> + * @request_mutex:	mutex to protect request and release of
>> resources.
>> + * @desc:		Array of resource descriptors.
>> + */
>> +struct ti_sci_resource {
>> +	u16 sets;
>> +	/* Mutex to protect request and release of resources */
>> +	struct mutex request_mutex;
>> +	struct ti_sci_resource_desc *desc;
>> +};
>> +
>> +u16 ti_sci_get_free_resource(struct ti_sci_resource *res);
>> +void ti_sci_release_resource(struct ti_sci_resource *res, u16 id);
>> +u32 ti_sci_get_num_resources(struct ti_sci_resource *res);
>> +struct ti_sci_resource *
>> +devm_ti_sci_get_of_resource(const struct ti_sci_handle *handle,
>> +			    struct device *dev, u32 dev_id, char
>> *of_prop); +#endif /*__TI_SCI_COMMON_IRQCHIP_H */
> 
> Most the above "common" should be a separate patch, really. Also, why

ok will move this into a separate patch.

> isn't the whole resource management part of the firmware interface? I
> see that "Firmware maintainer rejected the idea", but I don't really
> buy the rational. I don't see anything irq specific to the whole
> devm_ti_sci_get_of_resource and co, to be honest.

I guess the concern is mostly about the way ids are represented from DT. Using
this every tisci client should mandate to have separate DT property for each of
its resource.

> 
>> diff --git a/drivers/irqchip/irq-ti-sci-intr.c b/drivers/irqchip/irq-ti-sci-intr.c
>> new file mode 100644
>> index 000000000000..7e224552a735
>> --- /dev/null
>> +++ b/drivers/irqchip/irq-ti-sci-intr.c
>> @@ -0,0 +1,315 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Texas Instruments' K3 Interrupt Router irqchip driver
>> + *
>> + * Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
>> + *	Lokesh Vutla <lokeshvutla@ti.com>
>> + */

[..snip..]

>> +	err = ti_sci_intr_irq_domain_translate(domain, fwspec, &hwirq, &type);
>> +	if (err)
>> +		return err;
>> +
>> +	vint_irq = fwspec->param[3] & TI_SCI_VINT_IRQ;
>> +
>> +	err = ti_sci_intr_alloc_gic_irq(domain, virq, hwirq, type, vint_irq);
>> +	if (err)
>> +		return err;
>> +
>> +	err = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
>> +					    &ti_sci_intr_irq_chip,
>> +					    (void *)vint_irq);
> 
> I think I see what you're trying to achieve. I suggest you look a
> uintptr_t instead of playing with unrelated data types whose semantic
> really doesn't apply here.

As you commented on the dt-bindings patch to differentiate vints using the INTA
ids, this will not be needed anymore. Will completely drop this.

> 
>> +	if (err) {
>> +		ti_sci_intr_irq_domain_free(domain, virq, 1);
>> +		return err;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct irq_domain_ops ti_sci_intr_irq_domain_ops = {
>> +	.alloc		= ti_sci_intr_irq_domain_alloc,
>> +	.free		= ti_sci_intr_irq_domain_free,
>> +	.translate	= ti_sci_intr_irq_domain_translate,
>> +};
>> +
>> +static int ti_sci_intr_irq_domain_probe(struct platform_device *pdev)
>> +{
>> +	struct irq_domain *parent_domain, *domain;
>> +	struct device_node *parent_node, *dn;
>> +	struct ti_sci_intr_irq_domain *intr;
>> +	struct device *dev = &pdev->dev;
>> +	struct of_phandle_iterator it;
>> +	int ret, count, intsize;
>> +
>> +	parent_node = of_irq_find_parent(dev_of_node(dev));
>> +	if (!parent_node) {
>> +		dev_err(dev, "Failed to get IRQ parent node\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	parent_domain = irq_find_host(parent_node);
>> +	if (!parent_domain) {
>> +		dev_err(dev, "Failed to find IRQ parent domain\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	intr = devm_kzalloc(dev, sizeof(*intr), GFP_KERNEL);
>> +	if (!intr)
>> +		return -ENOMEM;
>> +
>> +	intr->sci = devm_ti_sci_get_by_phandle(dev, "ti,sci");
>> +	if (IS_ERR(intr->sci)) {
>> +		ret = PTR_ERR(intr->sci);
>> +		if (ret != -EPROBE_DEFER)
>> +			dev_err(dev, "ti,sci read fail %d\n", ret);
>> +		intr->sci = NULL;
>> +		return ret;
>> +	}
>> +
>> +	ret = of_property_read_u32(dev_of_node(dev), "ti,sci-dst-id",
>> +				   (u32 *)&intr->dst_id);
>> +	if (ret) {
>> +		dev_err(dev, "missing 'ti,sci-dst-id' property\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	intr->dst_irq = devm_ti_sci_get_of_resource(intr->sci, dev,
>> +						    intr->dst_id,
>> +						    "ti,sci-rm-range-girq");
>> +	if (IS_ERR(intr->dst_irq)) {
>> +		dev_err(dev, "Destination irq resource allocation failed\n");
>> +		return PTR_ERR(intr->dst_irq);
>> +	}
>> +
>> +	domain = irq_domain_add_hierarchy(parent_domain, 0, 0, dev_of_node(dev),
>> +					  &ti_sci_intr_irq_domain_ops, intr);
>> +	if (!domain) {
>> +		dev_err(dev, "Failed to allocate IRQ domain\n");
>> +		return -ENOMEM;
>> +	}
>> +
>> +	if (of_property_read_u32(dev_of_node(dev), "#interrupt-cells",
>> +				 &intsize))
>> +		return -EINVAL;
>> +
>> +	count = 0;
>> +	for_each_node_with_property(dn, "interrupts") {
>> +		if (of_irq_find_parent(dn) != dev_of_node(dev))
>> +			continue;
>> +		count += of_property_count_elems_of_size(dn, "interrupts",
>> +							 sizeof(u32) * intsize);
>> +	}
>> +
>> +	for_each_node_with_property(dn, "interrupts-extended") {
>> +		of_for_each_phandle(&it, ret, dn, "interrupts-extended",
>> +				    "#interrupt-cells", 0) {
>> +			if (it.node == dev_of_node(dev))
>> +				count++;
>> +		}
>> +	}
> 
> What is this trying to do? Counting the number of interrupt descriptors
> in the whole system? What does this even mean?

I am just trying for max utilization of GIC interrupts available for this. Since
inta vints are not represented in DT, total gic available - whatever is in DT
gives the max interrupts that can be used for the child INTA.

> 
> What I suggested was to allocate the required number of interrupts
> for a given device, based on the requirements of that device. I also

okay, then Ill get the number of interrupts needed for INTA from DT.

> suggested to investigate the x86 two phase allocation mechanism for the
> INTA driver.

Sorry, Ill try to explore this path. Any pointers to the doc/code will be really
helpful :)

Thanks and regards,
Lokesh

> 
> I never suggested that you'd parse the DT to guess how many interrupts
> you'd need to allocate...
> 
> 	M.
> 
>> +
>> +	intr->vint_irqs = ti_sci_get_num_resources(intr->dst_irq) - count;
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct of_device_id ti_sci_intr_irq_domain_of_match[] = {
>> +	{ .compatible = "ti,sci-intr", },
>> +	{ /* sentinel */ },
>> +};
>> +MODULE_DEVICE_TABLE(of, ti_sci_intr_irq_domain_of_match);
>> +
>> +static struct platform_driver ti_sci_intr_irq_domain_driver = {
>> +	.probe = ti_sci_intr_irq_domain_probe,
>> +	.driver = {
>> +		.name = "ti-sci-intr",
>> +		.of_match_table = ti_sci_intr_irq_domain_of_match,
>> +	},
>> +};
>> +module_platform_driver(ti_sci_intr_irq_domain_driver);
>> +
>> +MODULE_AUTHOR("Lokesh Vutla <lokeshvutla@ticom>");
>> +MODULE_DESCRIPTION("K3 Interrupt Router driver over TI SCI protocol");
>> +MODULE_LICENSE("GPL v2");
> 
> 
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-19 15:35                           ` Tony Lindgren
  2019-02-19 16:19                             ` Lokesh Vutla
@ 2019-02-20 16:36                             ` Tony Lindgren
  2019-02-20 17:17                               ` Lokesh Vutla
  1 sibling, 1 reply; 46+ messages in thread
From: Tony Lindgren @ 2019-02-20 16:36 UTC (permalink / raw)
  To: Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, marc.zyngier,
	Tero Kristo, Linus Walleij, Sekhar Nori, linux-kernel,
	Peter Ujfalusi, Rob Herring, Santosh Shilimkar, tglx,
	Linux ARM Mailing List

Hi,

Some more info on chained irq vs mux below that might
help.

* Tony Lindgren <tony@atomide.com> [190219 15:36]:
> * Lokesh Vutla <lokeshvutla@ti.com> [190219 08:51]:
> > With this can you tell me how can we not have a device-tree and still support
> > irq allocation?
> 
> Using standard dts reg property to differentiate the interrupt
> router instances. And if the interrupt router is a mux, you should
> treat it as a mux rather than a chained interrupt controller.
> 
> We do have drivers/mux nowadays, not sure if it helps in this case
> as at least timer interrupts need to be configured very early.

Adding Linus Walleij to Cc since he posted a good test to
consider if something should use chained (or nested) irq:

"individual masking and ACKing bits and can all be used at the
 same time" [0]

Not sure if we have that documented somewhere?

But seems like the interrupt router should be set up as
a separate mux driver talking with firmware that the
interrupt controller driver calls on request_irq()?

Cheers,

Tony


[0] https://marc.info/?l=linux-omap&m=155065629529311&w=2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-20 16:36                             ` Tony Lindgren
@ 2019-02-20 17:17                               ` Lokesh Vutla
  0 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-02-20 17:17 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Nishanth Menon, Device Tree Mailing List, jason, marc.zyngier,
	Tero Kristo, Linus Walleij, Sekhar Nori, linux-kernel,
	Peter Ujfalusi, Rob Herring, Santosh Shilimkar, tglx,
	Linux ARM Mailing List

Hi Tony,

On 2/20/2019 10:06 PM, Tony Lindgren wrote:
> Hi,
> 
> Some more info on chained irq vs mux below that might
> help.
> 
> * Tony Lindgren <tony@atomide.com> [190219 15:36]:
>> * Lokesh Vutla <lokeshvutla@ti.com> [190219 08:51]:
>>> With this can you tell me how can we not have a device-tree and still support
>>> irq allocation?
>>
>> Using standard dts reg property to differentiate the interrupt
>> router instances. And if the interrupt router is a mux, you should
>> treat it as a mux rather than a chained interrupt controller.
>>
>> We do have drivers/mux nowadays, not sure if it helps in this case
>> as at least timer interrupts need to be configured very early.
> 
> Adding Linus Walleij to Cc since he posted a good test to
> consider if something should use chained (or nested) irq:
> 
> "individual masking and ACKing bits and can all be used at the
>  same time" [0]

Interrupt Router just routes M inputs to N outputs. One input can only
be mapped to one output. This is a clear case of a hierarchical domain
and the driver is implementing it.

Thanks and regards,
Lokesh

> 
> Not sure if we have that documented somewhere?
> 
> But seems like the interrupt router should be set up as
> a separate mux driver talking with firmware that the
> interrupt controller driver calls on request_irq(>
> Cheers,
> 
> Tony
> 
> 
> [0] https://marc.info/?l=linux-omap&m=155065629529311&w=2
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings
  2019-02-18 14:35     ` Tony Lindgren
@ 2019-02-22 10:10       ` Peter Ujfalusi
  0 siblings, 0 replies; 46+ messages in thread
From: Peter Ujfalusi @ 2019-02-22 10:10 UTC (permalink / raw)
  To: Tony Lindgren, Lokesh Vutla
  Cc: Nishanth Menon, Device Tree Mailing List, jason, marc.zyngier,
	Sekhar Nori, linux-kernel, Tero Kristo, Rob Herring,
	Santosh Shilimkar, tglx, Linux ARM Mailing List



On 18/02/2019 16.35, Tony Lindgren wrote:
> * Lokesh Vutla <lokeshvutla@ti.com> [190216 03:30]:
>> On 2/12/2019 1:12 PM, Lokesh Vutla wrote:
>>> +TISCI Interrupt Router Node:
>>> +----------------------------
>>> +- compatible:		Must be "ti,sci-intr".
>>> +- interrupt-controller:	Identifies the node as an interrupt controller
>>> +- #interrupt-cells:	Specifies the number of cells needed to encode an
>>> +			interrupt source. The value should be 4.
>>> +			First cell should contain the TISCI device ID of source
>>> +			Second cell should contain the interrupt source offset
>>> +			within the device
>>> +			Third cell specifies the trigger type as defined
>>> +			in interrupts.txt in this directory.
>>> +			Fourth cell should be 1 if the irq is coming from
>>> +			interrupt aggregator else 0.
>>> +- ti,sci:		Phandle to TI-SCI compatible System controller node.
>>> +- ti,sci-dst-id:	TISCI device ID of the destination IRQ controller.
>>
>> Please help me here. As said this is the TISCI device id for the host
>> interrupt controller. While sending message to the system co-processor
>> this ID needs to be specified so that the irq route gets discovered and
>> configured. Atleast with the current design device Ids are not
>> discoverable. Can you mention what can be improved here? Is there any
>> such example where a firmware supports querying the deivce ids?
>>
>> Also do you have any further comments on this patch?
> 
> No reg property above. So if the interrupt router is not accessible
> by Linux like you're saying, you should not set up a dts node for
> it at all.

It is accessible via tisci but no direct register access.

> 
> Regards,
> 
> Tony
> 

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v5 06/10] irqchip: ti-sci-intr: Add support for Interrupt Router driver
  2019-02-20 13:17     ` Lokesh Vutla
@ 2019-03-19 12:44       ` Lokesh Vutla
  0 siblings, 0 replies; 46+ messages in thread
From: Lokesh Vutla @ 2019-03-19 12:44 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Nishanth Menon, Device Tree Mailing List, jason, Tony Lindgren,
	Tero Kristo, Sekhar Nori, linux-kernel, Peter Ujfalusi,
	Rob Herring, Santosh Shilimkar, tglx, Linux ARM Mailing List

Hi Marc,

[..snip..]

> 
>> suggested to investigate the x86 two phase allocation mechanism for the
>> INTA driver.
> 
> Sorry, Ill try to explore this path. Any pointers to the doc/code will be really
> helpful :)

I have been trying hard to get some information on this for past few days but I
can't find anything in kernel. Can you point me to some doc/code for the x86 two
phase allocation of irqs?

Thanks and regards,
Lokesh

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, back to index

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-12  7:42 [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla
2019-02-12  7:42 ` [PATCH v5 01/10] firmware: ti_sci: Add support to get TISCI handle using of_phandle Lokesh Vutla
2019-02-12  7:42 ` [PATCH v5 02/10] firmware: ti_sci: Add support for RM core ops Lokesh Vutla
2019-02-12  7:42 ` [PATCH v5 03/10] firmware: ti_sci: Add support for IRQ management Lokesh Vutla
2019-02-12  7:42 ` [PATCH v5 04/10] firmware: ti_sci: Add RM mapping table for am654 Lokesh Vutla
2019-02-12  7:42 ` [PATCH v5 05/10] dt-bindings: irqchip: Introduce TISCI Interrupt router bindings Lokesh Vutla
2019-02-12 16:22   ` Tony Lindgren
2019-02-13  4:25     ` Lokesh Vutla
2019-02-13 15:26       ` Tony Lindgren
2019-02-13 20:40         ` Rob Herring
2019-02-14  8:38         ` Lokesh Vutla
2019-02-14 15:41           ` Tony Lindgren
2019-02-14 17:32             ` Lokesh Vutla
2019-02-14 17:46               ` Tony Lindgren
2019-02-14 18:02                 ` Lokesh Vutla
2019-02-15 16:16                   ` Tony Lindgren
2019-02-16  3:29                     ` Lokesh Vutla
2019-02-18 14:32                       ` Tony Lindgren
2019-02-19  8:51                         ` Lokesh Vutla
2019-02-19 15:35                           ` Tony Lindgren
2019-02-19 16:19                             ` Lokesh Vutla
2019-02-19 17:11                               ` Tony Lindgren
2019-02-19 17:56                                 ` Tony Lindgren
2019-02-20  5:53                                   ` Lokesh Vutla
2019-02-20 16:36                             ` Tony Lindgren
2019-02-20 17:17                               ` Lokesh Vutla
2019-02-12 16:30   ` Tony Lindgren
2019-02-13  4:22     ` Lokesh Vutla
2019-02-13 15:32       ` Tony Lindgren
2019-02-14  8:40         ` Lokesh Vutla
2019-02-14 15:42           ` Tony Lindgren
2019-02-16  3:30   ` Lokesh Vutla
2019-02-18 14:35     ` Tony Lindgren
2019-02-22 10:10       ` Peter Ujfalusi
2019-02-18 15:12   ` Marc Zyngier
2019-02-18 15:27     ` Lokesh Vutla
2019-02-12  7:42 ` [PATCH v5 06/10] irqchip: ti-sci-intr: Add support for Interrupt Router driver Lokesh Vutla
2019-02-18 15:52   ` Marc Zyngier
2019-02-20 13:17     ` Lokesh Vutla
2019-03-19 12:44       ` Lokesh Vutla
2019-02-12  7:42 ` [PATCH v5 07/10] dt-bindings: irqchip: Introduce TISCI Interrupt Aggregator bindings Lokesh Vutla
2019-02-12  7:42 ` [PATCH v5 08/10] irqchip: ti-sci-inta: Add support for Interrupt Aggregator driver Lokesh Vutla
2019-02-12  7:42 ` [PATCH v5 09/10] soc: ti: Add MSI domain support for K3 Interrupt Aggregator Lokesh Vutla
2019-02-13 16:41   ` Tony Lindgren
2019-02-12  7:42 ` [PATCH v5 10/10] soc: ti: am6: Enable interrupt controller drivers Lokesh Vutla
2019-02-16  3:37 ` [PATCH v5 00/10] Add support for TISCI irqchip drivers Lokesh Vutla

Linux-ARM-Kernel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/0 linux-arm-kernel/git/0.git
	git clone --mirror https://lore.kernel.org/linux-arm-kernel/1 linux-arm-kernel/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-arm-kernel linux-arm-kernel/ https://lore.kernel.org/linux-arm-kernel \
		linux-arm-kernel@lists.infradead.org infradead-linux-arm-kernel@archiver.kernel.org
	public-inbox-index linux-arm-kernel


Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.infradead.lists.linux-arm-kernel


AGPL code for this site: git clone https://public-inbox.org/ public-inbox