2020-09-28 06:42:42

by Peter Ujfalusi

[permalink] [raw]
Subject: [PATCH 0/2] irqchip/ti-sci-inta: Support for unmapped events

Hi,

The version of INTA within DMSS (in AM64) changed how the events from the DMAs
are handled and how sysfw is presenting these events to be used for interrupts.

The DMA related events are directly mapped within INTA as unmapped events in
contrast to previous devices with NAVSS where the events were tied to their
source devices (UDMAP, ringacc).

This series adds support for handling the new version of INTA by introducing a
new property: ti,unmapped-event-sources which should hold a list of phandles
pointing to the sources of these unmapped events.

Regards,
Peter
---
Peter Ujfalusi (2):
dt-bindings: irqchip: ti,sci-inta: Update for unmapped event handling
irqchip/ti-sci-inta: Add support for unmapped event handling

.../interrupt-controller/ti,sci-inta.yaml | 5 ++
drivers/irqchip/irq-ti-sci-inta.c | 72 +++++++++++++++++--
2 files changed, 73 insertions(+), 4 deletions(-)

--
Peter

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


2020-09-28 06:43:27

by Peter Ujfalusi

[permalink] [raw]
Subject: [PATCH 1/2] dt-bindings: irqchip: ti,sci-inta: Update for unmapped event handling

The new DMA architecture introduced with AM64 introduced new event types:
unampped events.

These events are mapped within INTA in contrast to other K3 devices where
the events with similar function was originating from the UDMAP or ringacc.

The ti,unmapped-event-sources should contain phandle array to the devices
in the system (typically DMA controllers) from where the unmapped events
originate.

Signed-off-by: Peter Ujfalusi <[email protected]>
---
.../bindings/interrupt-controller/ti,sci-inta.yaml | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.yaml b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.yaml
index c7cd05656a3e..2837b90bbb56 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.yaml
@@ -70,6 +70,11 @@ properties:
- description: |
"limit" specifies the limit for translation

+ ti,unmapped-event-sources:
+ $ref: /schemas/types.yaml#definitions/phandle-array
+ description:
+ Array of phandles to DMA controllers where the unmapped events originate.
+
required:
- compatible
- reg
--
Peter

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

2020-09-28 06:43:27

by Peter Ujfalusi

[permalink] [raw]
Subject: [PATCH 2/2] irqchip/ti-sci-inta: Add support for unmapped event handling

The DMA (BCDMA/PKTDMA and their rings/flows) events are under the INTA's
supervision as unmapped events in AM64.

In order to keep the current SW stack working, the INTA driver must replace
the dev_id with it's own when a request comes for BCDMA or PKTDMA
resources.

Implement parsing of the optional "ti,unmapped-event-sources" phandle array
to get the sci-dev-ids of the devices where the unmapped events originate.

Signed-off-by: Peter Ujfalusi <[email protected]>
---
drivers/irqchip/irq-ti-sci-inta.c | 72 +++++++++++++++++++++++++++++--
1 file changed, 68 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c
index bc863ef7998d..02914d29140b 100644
--- a/drivers/irqchip/irq-ti-sci-inta.c
+++ b/drivers/irqchip/irq-ti-sci-inta.c
@@ -85,6 +85,8 @@ struct ti_sci_inta_vint_desc {
* @base: Base address of the memory mapped IO registers
* @pdev: Pointer to platform device.
* @ti_sci_id: TI-SCI device identifier
+ * @difu_cnt: Number of TI-SCI device identifiers for unmapped events
+ * @dev_ids_for_unmapped: Pointer to an array of TI-SCI device identifiers
*/
struct ti_sci_inta_irq_domain {
const struct ti_sci_handle *sci;
@@ -96,11 +98,33 @@ struct ti_sci_inta_irq_domain {
void __iomem *base;
struct platform_device *pdev;
u32 ti_sci_id;
+
+ int difu_cnt;
+ u32 *dev_ids_for_unmapped;
};

#define to_vint_desc(e, i) container_of(e, struct ti_sci_inta_vint_desc, \
events[i])

+static u16 ti_sci_inta_get_dev_id(struct ti_sci_inta_irq_domain *inta,
+ u32 hwirq)
+{
+ u16 dev_id = HWIRQ_TO_DEVID(hwirq);
+ int i;
+
+ if (inta->difu_cnt == 0)
+ return dev_id;
+
+ for (i = 0; i < inta->difu_cnt; i++) {
+ if (dev_id == inta->dev_ids_for_unmapped[i]) {
+ dev_id = inta->ti_sci_id;
+ break;
+ }
+ }
+
+ return dev_id;
+}
+
/**
* ti_sci_inta_irq_handler() - Chained IRQ handler for the vint irqs
* @desc: Pointer to irq_desc corresponding to the irq
@@ -251,7 +275,7 @@ static struct ti_sci_inta_event_desc *ti_sci_inta_alloc_event(struct ti_sci_inta
u16 dev_id, dev_index;
int err;

- dev_id = HWIRQ_TO_DEVID(hwirq);
+ dev_id = ti_sci_inta_get_dev_id(inta, hwirq);
dev_index = HWIRQ_TO_IRQID(hwirq);

event_desc = &vint_desc->events[free_bit];
@@ -352,14 +376,15 @@ static void ti_sci_inta_free_irq(struct ti_sci_inta_event_desc *event_desc,
{
struct ti_sci_inta_vint_desc *vint_desc;
struct ti_sci_inta_irq_domain *inta;
+ u16 dev_id;

vint_desc = to_vint_desc(event_desc, event_desc->vint_bit);
inta = vint_desc->domain->host_data;
+ dev_id = ti_sci_inta_get_dev_id(inta, hwirq);
/* free event irq */
mutex_lock(&inta->vint_mutex);
inta->sci->ops.rm_irq_ops.free_event_map(inta->sci,
- HWIRQ_TO_DEVID(hwirq),
- HWIRQ_TO_IRQID(hwirq),
+ dev_id, HWIRQ_TO_IRQID(hwirq),
inta->ti_sci_id,
vint_desc->vint_id,
event_desc->global_event,
@@ -562,7 +587,6 @@ static void ti_sci_inta_msi_set_desc(msi_alloc_info_t *arg,
arg->desc = desc;
arg->hwirq = TO_HWIRQ(pdev->id, desc->inta.dev_index);
}
-
static struct msi_domain_ops ti_sci_inta_msi_ops = {
.set_desc = ti_sci_inta_msi_set_desc,
};
@@ -574,6 +598,42 @@ static struct msi_domain_info ti_sci_inta_msi_domain_info = {
.chip = &ti_sci_inta_msi_irq_chip,
};

+static int ti_sci_inta_get_unmapped_sources(struct ti_sci_inta_irq_domain *inta)
+{
+ struct device *dev = &inta->pdev->dev;
+ struct device_node *node = dev_of_node(dev);
+ struct of_phandle_iterator it;
+ int count, err, ret, i;
+
+ count = of_count_phandle_with_args(node, "ti,unmapped-event-sources",
+ NULL);
+ if (count <= 0)
+ return count;
+
+ inta->dev_ids_for_unmapped = devm_kcalloc(dev, count,
+ sizeof(*inta->dev_ids_for_unmapped),
+ GFP_KERNEL);
+ if (!inta->dev_ids_for_unmapped)
+ return -ENOMEM;
+
+ i = 0;
+ of_for_each_phandle(&it, err, node, "ti,unmapped-event-sources",
+ NULL, 0) {
+ ret = of_property_read_u32(it.node, "ti,sci-dev-id",
+ &inta->dev_ids_for_unmapped[i++]);
+ if (ret) {
+ dev_err(dev, "ti,sci-dev-id read failure for %s\n",
+ of_node_full_name(it.node));
+ of_node_put(it.node);
+ return ret;
+ }
+ }
+
+ inta->difu_cnt = count;
+
+ return 0;
+}
+
static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
{
struct irq_domain *parent_domain, *domain, *msi_domain;
@@ -629,6 +689,10 @@ static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
if (IS_ERR(inta->base))
return PTR_ERR(inta->base);

+ ret = ti_sci_inta_get_unmapped_sources(inta);
+ if (ret)
+ return ret;
+
domain = irq_domain_add_linear(dev_of_node(dev),
ti_sci_get_num_resources(inta->vint),
&ti_sci_inta_irq_domain_ops, inta);
--
Peter

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

2020-09-28 07:58:05

by Peter Ujfalusi

[permalink] [raw]
Subject: Re: [PATCH 2/2] irqchip/ti-sci-inta: Add support for unmapped event handling



On 28/09/2020 9.39, Peter Ujfalusi wrote:
> The DMA (BCDMA/PKTDMA and their rings/flows) events are under the INTA's
> supervision as unmapped events in AM64.
>
> In order to keep the current SW stack working, the INTA driver must replace
> the dev_id with it's own when a request comes for BCDMA or PKTDMA
> resources.
>
> Implement parsing of the optional "ti,unmapped-event-sources" phandle array
> to get the sci-dev-ids of the devices where the unmapped events originate.
>
> Signed-off-by: Peter Ujfalusi <[email protected]>
> ---
> drivers/irqchip/irq-ti-sci-inta.c | 72 +++++++++++++++++++++++++++++--
> 1 file changed, 68 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c
> index bc863ef7998d..02914d29140b 100644
> --- a/drivers/irqchip/irq-ti-sci-inta.c
> +++ b/drivers/irqchip/irq-ti-sci-inta.c
> @@ -85,6 +85,8 @@ struct ti_sci_inta_vint_desc {
> * @base: Base address of the memory mapped IO registers
> * @pdev: Pointer to platform device.
> * @ti_sci_id: TI-SCI device identifier
> + * @difu_cnt: Number of TI-SCI device identifiers for unmapped events
> + * @dev_ids_for_unmapped: Pointer to an array of TI-SCI device identifiers
> */
> struct ti_sci_inta_irq_domain {
> const struct ti_sci_handle *sci;
> @@ -96,11 +98,33 @@ struct ti_sci_inta_irq_domain {
> void __iomem *base;
> struct platform_device *pdev;
> u32 ti_sci_id;
> +
> + int difu_cnt;
> + u32 *dev_ids_for_unmapped;
> };
>
> #define to_vint_desc(e, i) container_of(e, struct ti_sci_inta_vint_desc, \
> events[i])
>
> +static u16 ti_sci_inta_get_dev_id(struct ti_sci_inta_irq_domain *inta,
> + u32 hwirq)
> +{
> + u16 dev_id = HWIRQ_TO_DEVID(hwirq);
> + int i;
> +
> + if (inta->difu_cnt == 0)
> + return dev_id;
> +
> + for (i = 0; i < inta->difu_cnt; i++) {
> + if (dev_id == inta->dev_ids_for_unmapped[i]) {
> + dev_id = inta->ti_sci_id;
> + break;
> + }
> + }
> +
> + return dev_id;
> +}
> +
> /**
> * ti_sci_inta_irq_handler() - Chained IRQ handler for the vint irqs
> * @desc: Pointer to irq_desc corresponding to the irq
> @@ -251,7 +275,7 @@ static struct ti_sci_inta_event_desc *ti_sci_inta_alloc_event(struct ti_sci_inta
> u16 dev_id, dev_index;
> int err;
>
> - dev_id = HWIRQ_TO_DEVID(hwirq);
> + dev_id = ti_sci_inta_get_dev_id(inta, hwirq);
> dev_index = HWIRQ_TO_IRQID(hwirq);
>
> event_desc = &vint_desc->events[free_bit];
> @@ -352,14 +376,15 @@ static void ti_sci_inta_free_irq(struct ti_sci_inta_event_desc *event_desc,
> {
> struct ti_sci_inta_vint_desc *vint_desc;
> struct ti_sci_inta_irq_domain *inta;
> + u16 dev_id;
>
> vint_desc = to_vint_desc(event_desc, event_desc->vint_bit);
> inta = vint_desc->domain->host_data;
> + dev_id = ti_sci_inta_get_dev_id(inta, hwirq);
> /* free event irq */
> mutex_lock(&inta->vint_mutex);
> inta->sci->ops.rm_irq_ops.free_event_map(inta->sci,
> - HWIRQ_TO_DEVID(hwirq),
> - HWIRQ_TO_IRQID(hwirq),
> + dev_id, HWIRQ_TO_IRQID(hwirq),
> inta->ti_sci_id,
> vint_desc->vint_id,
> event_desc->global_event,
> @@ -562,7 +587,6 @@ static void ti_sci_inta_msi_set_desc(msi_alloc_info_t *arg,
> arg->desc = desc;
> arg->hwirq = TO_HWIRQ(pdev->id, desc->inta.dev_index);
> }
> -
> static struct msi_domain_ops ti_sci_inta_msi_ops = {
> .set_desc = ti_sci_inta_msi_set_desc,
> };
> @@ -574,6 +598,42 @@ static struct msi_domain_info ti_sci_inta_msi_domain_info = {
> .chip = &ti_sci_inta_msi_irq_chip,
> };
>
> +static int ti_sci_inta_get_unmapped_sources(struct ti_sci_inta_irq_domain *inta)
> +{
> + struct device *dev = &inta->pdev->dev;
> + struct device_node *node = dev_of_node(dev);
> + struct of_phandle_iterator it;
> + int count, err, ret, i;
> +
> + count = of_count_phandle_with_args(node, "ti,unmapped-event-sources",
> + NULL);
> + if (count <= 0)
> + return count;

We should return 0 as the property is optional.
I will wait for other comments and send v2 with this fixed.

> +
> + inta->dev_ids_for_unmapped = devm_kcalloc(dev, count,
> + sizeof(*inta->dev_ids_for_unmapped),
> + GFP_KERNEL);
> + if (!inta->dev_ids_for_unmapped)
> + return -ENOMEM;
> +
> + i = 0;
> + of_for_each_phandle(&it, err, node, "ti,unmapped-event-sources",
> + NULL, 0) {
> + ret = of_property_read_u32(it.node, "ti,sci-dev-id",
> + &inta->dev_ids_for_unmapped[i++]);
> + if (ret) {
> + dev_err(dev, "ti,sci-dev-id read failure for %s\n",
> + of_node_full_name(it.node));
> + of_node_put(it.node);
> + return ret;
> + }
> + }
> +
> + inta->difu_cnt = count;
> +
> + return 0;
> +}
> +
> static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
> {
> struct irq_domain *parent_domain, *domain, *msi_domain;
> @@ -629,6 +689,10 @@ static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
> if (IS_ERR(inta->base))
> return PTR_ERR(inta->base);
>
> + ret = ti_sci_inta_get_unmapped_sources(inta);
> + if (ret)
> + return ret;
> +
> domain = irq_domain_add_linear(dev_of_node(dev),
> ti_sci_get_num_resources(inta->vint),
> &ti_sci_inta_irq_domain_ops, inta);
>

- Péter

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

2020-09-29 19:45:49

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 1/2] dt-bindings: irqchip: ti, sci-inta: Update for unmapped event handling

On Mon, 28 Sep 2020 09:39:29 +0300, Peter Ujfalusi wrote:
> The new DMA architecture introduced with AM64 introduced new event types:
> unampped events.
>
> These events are mapped within INTA in contrast to other K3 devices where
> the events with similar function was originating from the UDMAP or ringacc.
>
> The ti,unmapped-event-sources should contain phandle array to the devices
> in the system (typically DMA controllers) from where the unmapped events
> originate.
>
> Signed-off-by: Peter Ujfalusi <[email protected]>
> ---
> .../bindings/interrupt-controller/ti,sci-inta.yaml | 5 +++++
> 1 file changed, 5 insertions(+)
>

Reviewed-by: Rob Herring <[email protected]>