2023-02-11 02:41:58

by Binbin Zhou

[permalink] [raw]
Subject: [PATCH] irqchip/loongson-eiointc: Add DT init support

Add DT support for EIOINTC irqchip, which is needed for the Loongson-2K
series, e.g. Loongson-2K500 soc.

Signed-off-by: Binbin Zhou <[email protected]>
---
drivers/irqchip/irq-loongson-eiointc.c | 119 ++++++++++++++++++-------
1 file changed, 85 insertions(+), 34 deletions(-)

diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
index d15fd38c1756..d5e1ee6aada6 100644
--- a/drivers/irqchip/irq-loongson-eiointc.c
+++ b/drivers/irqchip/irq-loongson-eiointc.c
@@ -39,6 +39,7 @@ static int nr_pics;

struct eiointc_priv {
u32 node;
+ u32 vec_count;
nodemask_t node_map;
cpumask_t cpuspan_map;
struct fwnode_handle *domain_handle;
@@ -156,18 +157,19 @@ static int eiointc_router_init(unsigned int cpu)
if ((cpu_logical_map(cpu) % CORES_PER_EIO_NODE) == 0) {
eiointc_enable();

- for (i = 0; i < VEC_COUNT / 32; i++) {
+ for (i = 0; i < eiointc_priv[0]->vec_count / 32; i++) {
+ pr_info("");
data = (((1 << (i * 2 + 1)) << 16) | (1 << (i * 2)));
iocsr_write32(data, EIOINTC_REG_NODEMAP + i * 4);
}

- for (i = 0; i < VEC_COUNT / 32 / 4; i++) {
+ for (i = 0; i < eiointc_priv[0]->vec_count / 32 / 4; i++) {
bit = BIT(1 + index); /* Route to IP[1 + index] */
data = bit | (bit << 8) | (bit << 16) | (bit << 24);
iocsr_write32(data, EIOINTC_REG_IPMAP + i * 4);
}

- for (i = 0; i < VEC_COUNT / 4; i++) {
+ for (i = 0; i < eiointc_priv[0]->vec_count / 4; i++) {
/* Route to Node-0 Core-0 */
if (index == 0)
bit = BIT(cpu_logical_map(0));
@@ -178,7 +180,7 @@ static int eiointc_router_init(unsigned int cpu)
iocsr_write32(data, EIOINTC_REG_ROUTE + i * 4);
}

- for (i = 0; i < VEC_COUNT / 32; i++) {
+ for (i = 0; i < eiointc_priv[0]->vec_count / 32; i++) {
data = 0xffffffff;
iocsr_write32(data, EIOINTC_REG_ENABLE + i * 4);
iocsr_write32(data, EIOINTC_REG_BOUNCE + i * 4);
@@ -198,7 +200,7 @@ static void eiointc_irq_dispatch(struct irq_desc *desc)

chained_irq_enter(chip, desc);

- for (i = 0; i < VEC_REG_COUNT; i++) {
+ for (i = 0; i < eiointc_priv[0]->vec_count / VEC_COUNT_PER_REG; i++) {
pending = iocsr_read64(EIOINTC_REG_ISR + (i << 3));
iocsr_write64(pending, EIOINTC_REG_ISR + (i << 3));
while (pending) {
@@ -316,7 +318,7 @@ static void eiointc_resume(void)
eiointc_router_init(0);

for (i = 0; i < nr_pics; i++) {
- for (j = 0; j < VEC_COUNT; j++) {
+ for (j = 0; j < eiointc_priv[i]->vec_count; j++) {
desc = irq_resolve_mapping(eiointc_priv[i]->eiointc_domain, j);
if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) {
raw_spin_lock(&desc->lock);
@@ -373,11 +375,44 @@ static int __init acpi_cascade_irqdomain_init(void)
return 0;
}

+static int __init eiointc_init(struct eiointc_priv *priv, int parent_irq,
+ u64 node_map)
+{
+ int i;
+
+ node_map = node_map ? node_map : -1ULL;
+ for_each_possible_cpu(i) {
+ if (node_map & (1ULL << (cpu_to_eio_node(i)))) {
+ node_set(cpu_to_eio_node(i), priv->node_map);
+ cpumask_or(&priv->cpuspan_map, &priv->cpuspan_map,
+ cpumask_of(i));
+ }
+ }
+
+ priv->eiointc_domain = irq_domain_create_linear(priv->domain_handle,
+ priv->vec_count,
+ &eiointc_domain_ops,
+ priv);
+ if (!priv->eiointc_domain) {
+ pr_err("loongson-extioi: cannot add IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ eiointc_priv[nr_pics++] = priv;
+ eiointc_router_init(0);
+ irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, priv);
+ register_syscore_ops(&eiointc_syscore_ops);
+ cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_LOONGARCH_STARTING,
+ "irqchip/loongarch/intc:starting",
+ eiointc_router_init, NULL);
+
+ return 0;
+}
+
int __init eiointc_acpi_init(struct irq_domain *parent,
struct acpi_madt_eio_pic *acpi_eiointc)
{
- int i, ret, parent_irq;
- unsigned long node_map;
+ int parent_irq, ret;
struct eiointc_priv *priv;

priv = kzalloc(sizeof(*priv), GFP_KERNEL);
@@ -391,39 +426,20 @@ int __init eiointc_acpi_init(struct irq_domain *parent,
goto out_free_priv;
}

+ priv->vec_count = VEC_COUNT;
priv->node = acpi_eiointc->node;
- node_map = acpi_eiointc->node_map ? : -1ULL;
-
- for_each_possible_cpu(i) {
- if (node_map & (1ULL << cpu_to_eio_node(i))) {
- node_set(cpu_to_eio_node(i), priv->node_map);
- cpumask_or(&priv->cpuspan_map, &priv->cpuspan_map, cpumask_of(i));
- }
- }
-
- /* Setup IRQ domain */
- priv->eiointc_domain = irq_domain_create_linear(priv->domain_handle, VEC_COUNT,
- &eiointc_domain_ops, priv);
- if (!priv->eiointc_domain) {
- pr_err("loongson-eiointc: cannot add IRQ domain\n");
- goto out_free_handle;
- }
-
- eiointc_priv[nr_pics++] = priv;
-
- eiointc_router_init(0);
-
parent_irq = irq_create_mapping(parent, acpi_eiointc->cascade);
- irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, priv);

- register_syscore_ops(&eiointc_syscore_ops);
- cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_LOONGARCH_STARTING,
- "irqchip/loongarch/intc:starting",
- eiointc_router_init, NULL);
+ ret = eiointc_init(priv, parent_irq, acpi_eiointc->node_map);
+ if (ret < 0)
+ goto out_free_handle;

acpi_set_vec_parent(acpi_eiointc->node, priv->eiointc_domain, pch_group);
acpi_set_vec_parent(acpi_eiointc->node, priv->eiointc_domain, msi_group);
+
ret = acpi_cascade_irqdomain_init();
+ if (ret < 0)
+ goto out_free_handle;

return ret;

@@ -435,3 +451,39 @@ int __init eiointc_acpi_init(struct irq_domain *parent,

return -ENOMEM;
}
+
+static int __init eiointc_of_init(struct device_node *of_node,
+ struct device_node *parent)
+{
+ int parent_irq, ret;
+ struct eiointc_priv *priv;
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ parent_irq = of_irq_get_byname(of_node, "cascade");
+ if (parent_irq <= 0) {
+ ret = -ENODEV;
+ goto out_free_priv;
+ }
+
+ ret = of_property_read_u32(of_node, "vec_count", &priv->vec_count);
+ if (ret < 0)
+ goto out_free_priv;
+
+ priv->node = 0;
+ priv->domain_handle = of_node_to_fwnode(of_node);
+
+ ret = eiointc_init(priv, parent_irq, 0);
+ if (ret < 0)
+ goto out_free_priv;
+
+ return 0;
+
+out_free_priv:
+ kfree(priv);
+ return ret;
+}
+
+IRQCHIP_DECLARE(loongson_eiointc, "loongson,eiointc", eiointc_of_init);
--
2.39.0



2023-02-12 01:53:44

by Huacai Chen

[permalink] [raw]
Subject: Re: [PATCH] irqchip/loongson-eiointc: Add DT init support

Hi, Binbin,

On Sat, Feb 11, 2023 at 10:41 AM Binbin Zhou <[email protected]> wrote:
>
> Add DT support for EIOINTC irqchip, which is needed for the Loongson-2K
> series, e.g. Loongson-2K500 soc.
Use SOC instead of soc.

>
> Signed-off-by: Binbin Zhou <[email protected]>
> ---
> drivers/irqchip/irq-loongson-eiointc.c | 119 ++++++++++++++++++-------
> 1 file changed, 85 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
> index d15fd38c1756..d5e1ee6aada6 100644
> --- a/drivers/irqchip/irq-loongson-eiointc.c
> +++ b/drivers/irqchip/irq-loongson-eiointc.c
> @@ -39,6 +39,7 @@ static int nr_pics;
>
> struct eiointc_priv {
> u32 node;
> + u32 vec_count;
> nodemask_t node_map;
> cpumask_t cpuspan_map;
> struct fwnode_handle *domain_handle;
> @@ -156,18 +157,19 @@ static int eiointc_router_init(unsigned int cpu)
> if ((cpu_logical_map(cpu) % CORES_PER_EIO_NODE) == 0) {
> eiointc_enable();
>
> - for (i = 0; i < VEC_COUNT / 32; i++) {
> + for (i = 0; i < eiointc_priv[0]->vec_count / 32; i++) {
> + pr_info("");
Why print an empty string?

Others look good to me.

Huacai
> data = (((1 << (i * 2 + 1)) << 16) | (1 << (i * 2)));
> iocsr_write32(data, EIOINTC_REG_NODEMAP + i * 4);
> }
>
> - for (i = 0; i < VEC_COUNT / 32 / 4; i++) {
> + for (i = 0; i < eiointc_priv[0]->vec_count / 32 / 4; i++) {
> bit = BIT(1 + index); /* Route to IP[1 + index] */
> data = bit | (bit << 8) | (bit << 16) | (bit << 24);
> iocsr_write32(data, EIOINTC_REG_IPMAP + i * 4);
> }
>
> - for (i = 0; i < VEC_COUNT / 4; i++) {
> + for (i = 0; i < eiointc_priv[0]->vec_count / 4; i++) {
> /* Route to Node-0 Core-0 */
> if (index == 0)
> bit = BIT(cpu_logical_map(0));
> @@ -178,7 +180,7 @@ static int eiointc_router_init(unsigned int cpu)
> iocsr_write32(data, EIOINTC_REG_ROUTE + i * 4);
> }
>
> - for (i = 0; i < VEC_COUNT / 32; i++) {
> + for (i = 0; i < eiointc_priv[0]->vec_count / 32; i++) {
> data = 0xffffffff;
> iocsr_write32(data, EIOINTC_REG_ENABLE + i * 4);
> iocsr_write32(data, EIOINTC_REG_BOUNCE + i * 4);
> @@ -198,7 +200,7 @@ static void eiointc_irq_dispatch(struct irq_desc *desc)
>
> chained_irq_enter(chip, desc);
>
> - for (i = 0; i < VEC_REG_COUNT; i++) {
> + for (i = 0; i < eiointc_priv[0]->vec_count / VEC_COUNT_PER_REG; i++) {
> pending = iocsr_read64(EIOINTC_REG_ISR + (i << 3));
> iocsr_write64(pending, EIOINTC_REG_ISR + (i << 3));
> while (pending) {
> @@ -316,7 +318,7 @@ static void eiointc_resume(void)
> eiointc_router_init(0);
>
> for (i = 0; i < nr_pics; i++) {
> - for (j = 0; j < VEC_COUNT; j++) {
> + for (j = 0; j < eiointc_priv[i]->vec_count; j++) {
> desc = irq_resolve_mapping(eiointc_priv[i]->eiointc_domain, j);
> if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) {
> raw_spin_lock(&desc->lock);
> @@ -373,11 +375,44 @@ static int __init acpi_cascade_irqdomain_init(void)
> return 0;
> }
>
> +static int __init eiointc_init(struct eiointc_priv *priv, int parent_irq,
> + u64 node_map)
> +{
> + int i;
> +
> + node_map = node_map ? node_map : -1ULL;
> + for_each_possible_cpu(i) {
> + if (node_map & (1ULL << (cpu_to_eio_node(i)))) {
> + node_set(cpu_to_eio_node(i), priv->node_map);
> + cpumask_or(&priv->cpuspan_map, &priv->cpuspan_map,
> + cpumask_of(i));
> + }
> + }
> +
> + priv->eiointc_domain = irq_domain_create_linear(priv->domain_handle,
> + priv->vec_count,
> + &eiointc_domain_ops,
> + priv);
> + if (!priv->eiointc_domain) {
> + pr_err("loongson-extioi: cannot add IRQ domain\n");
> + return -ENOMEM;
> + }
> +
> + eiointc_priv[nr_pics++] = priv;
> + eiointc_router_init(0);
> + irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, priv);
> + register_syscore_ops(&eiointc_syscore_ops);
> + cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_LOONGARCH_STARTING,
> + "irqchip/loongarch/intc:starting",
> + eiointc_router_init, NULL);
> +
> + return 0;
> +}
> +
> int __init eiointc_acpi_init(struct irq_domain *parent,
> struct acpi_madt_eio_pic *acpi_eiointc)
> {
> - int i, ret, parent_irq;
> - unsigned long node_map;
> + int parent_irq, ret;
> struct eiointc_priv *priv;
>
> priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> @@ -391,39 +426,20 @@ int __init eiointc_acpi_init(struct irq_domain *parent,
> goto out_free_priv;
> }
>
> + priv->vec_count = VEC_COUNT;
> priv->node = acpi_eiointc->node;
> - node_map = acpi_eiointc->node_map ? : -1ULL;
> -
> - for_each_possible_cpu(i) {
> - if (node_map & (1ULL << cpu_to_eio_node(i))) {
> - node_set(cpu_to_eio_node(i), priv->node_map);
> - cpumask_or(&priv->cpuspan_map, &priv->cpuspan_map, cpumask_of(i));
> - }
> - }
> -
> - /* Setup IRQ domain */
> - priv->eiointc_domain = irq_domain_create_linear(priv->domain_handle, VEC_COUNT,
> - &eiointc_domain_ops, priv);
> - if (!priv->eiointc_domain) {
> - pr_err("loongson-eiointc: cannot add IRQ domain\n");
> - goto out_free_handle;
> - }
> -
> - eiointc_priv[nr_pics++] = priv;
> -
> - eiointc_router_init(0);
> -
> parent_irq = irq_create_mapping(parent, acpi_eiointc->cascade);
> - irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, priv);
>
> - register_syscore_ops(&eiointc_syscore_ops);
> - cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_LOONGARCH_STARTING,
> - "irqchip/loongarch/intc:starting",
> - eiointc_router_init, NULL);
> + ret = eiointc_init(priv, parent_irq, acpi_eiointc->node_map);
> + if (ret < 0)
> + goto out_free_handle;
>
> acpi_set_vec_parent(acpi_eiointc->node, priv->eiointc_domain, pch_group);
> acpi_set_vec_parent(acpi_eiointc->node, priv->eiointc_domain, msi_group);
> +
> ret = acpi_cascade_irqdomain_init();
> + if (ret < 0)
> + goto out_free_handle;
>
> return ret;
>
> @@ -435,3 +451,39 @@ int __init eiointc_acpi_init(struct irq_domain *parent,
>
> return -ENOMEM;
> }
> +
> +static int __init eiointc_of_init(struct device_node *of_node,
> + struct device_node *parent)
> +{
> + int parent_irq, ret;
> + struct eiointc_priv *priv;
> +
> + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + parent_irq = of_irq_get_byname(of_node, "cascade");
> + if (parent_irq <= 0) {
> + ret = -ENODEV;
> + goto out_free_priv;
> + }
> +
> + ret = of_property_read_u32(of_node, "vec_count", &priv->vec_count);
> + if (ret < 0)
> + goto out_free_priv;
> +
> + priv->node = 0;
> + priv->domain_handle = of_node_to_fwnode(of_node);
> +
> + ret = eiointc_init(priv, parent_irq, 0);
> + if (ret < 0)
> + goto out_free_priv;
> +
> + return 0;
> +
> +out_free_priv:
> + kfree(priv);
> + return ret;
> +}
> +
> +IRQCHIP_DECLARE(loongson_eiointc, "loongson,eiointc", eiointc_of_init);
> --
> 2.39.0
>
>

2023-02-12 04:48:47

by Binbin Zhou

[permalink] [raw]
Subject: Re: [PATCH] irqchip/loongson-eiointc: Add DT init support

On Sun, Feb 12, 2023 at 9:53 AM Huacai Chen <[email protected]> wrote:
>
> Hi, Binbin,
>
> On Sat, Feb 11, 2023 at 10:41 AM Binbin Zhou <[email protected]> wrote:
> >
> > Add DT support for EIOINTC irqchip, which is needed for the Loongson-2K
> > series, e.g. Loongson-2K500 soc.
> Use SOC instead of soc.
>
> >
> > Signed-off-by: Binbin Zhou <[email protected]>
> > ---
> > drivers/irqchip/irq-loongson-eiointc.c | 119 ++++++++++++++++++-------
> > 1 file changed, 85 insertions(+), 34 deletions(-)
> >
> > diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c
> > index d15fd38c1756..d5e1ee6aada6 100644
> > --- a/drivers/irqchip/irq-loongson-eiointc.c
> > +++ b/drivers/irqchip/irq-loongson-eiointc.c
> > @@ -39,6 +39,7 @@ static int nr_pics;
> >
> > struct eiointc_priv {
> > u32 node;
> > + u32 vec_count;
> > nodemask_t node_map;
> > cpumask_t cpuspan_map;
> > struct fwnode_handle *domain_handle;
> > @@ -156,18 +157,19 @@ static int eiointc_router_init(unsigned int cpu)
> > if ((cpu_logical_map(cpu) % CORES_PER_EIO_NODE) == 0) {
> > eiointc_enable();
> >
> > - for (i = 0; i < VEC_COUNT / 32; i++) {
> > + for (i = 0; i < eiointc_priv[0]->vec_count / 32; i++) {
> > + pr_info("");
> Why print an empty string?
>
Sorry, I forgot to remove the debug message.
I will fix it.

Thanks.
Binbin

> Others look good to me.
>
> Huacai
> > data = (((1 << (i * 2 + 1)) << 16) | (1 << (i * 2)));
> > iocsr_write32(data, EIOINTC_REG_NODEMAP + i * 4);
> > }
> >
> > - for (i = 0; i < VEC_COUNT / 32 / 4; i++) {
> > + for (i = 0; i < eiointc_priv[0]->vec_count / 32 / 4; i++) {
> > bit = BIT(1 + index); /* Route to IP[1 + index] */
> > data = bit | (bit << 8) | (bit << 16) | (bit << 24);
> > iocsr_write32(data, EIOINTC_REG_IPMAP + i * 4);
> > }
> >
> > - for (i = 0; i < VEC_COUNT / 4; i++) {
> > + for (i = 0; i < eiointc_priv[0]->vec_count / 4; i++) {
> > /* Route to Node-0 Core-0 */
> > if (index == 0)
> > bit = BIT(cpu_logical_map(0));
> > @@ -178,7 +180,7 @@ static int eiointc_router_init(unsigned int cpu)
> > iocsr_write32(data, EIOINTC_REG_ROUTE + i * 4);
> > }
> >
> > - for (i = 0; i < VEC_COUNT / 32; i++) {
> > + for (i = 0; i < eiointc_priv[0]->vec_count / 32; i++) {
> > data = 0xffffffff;
> > iocsr_write32(data, EIOINTC_REG_ENABLE + i * 4);
> > iocsr_write32(data, EIOINTC_REG_BOUNCE + i * 4);
> > @@ -198,7 +200,7 @@ static void eiointc_irq_dispatch(struct irq_desc *desc)
> >
> > chained_irq_enter(chip, desc);
> >
> > - for (i = 0; i < VEC_REG_COUNT; i++) {
> > + for (i = 0; i < eiointc_priv[0]->vec_count / VEC_COUNT_PER_REG; i++) {
> > pending = iocsr_read64(EIOINTC_REG_ISR + (i << 3));
> > iocsr_write64(pending, EIOINTC_REG_ISR + (i << 3));
> > while (pending) {
> > @@ -316,7 +318,7 @@ static void eiointc_resume(void)
> > eiointc_router_init(0);
> >
> > for (i = 0; i < nr_pics; i++) {
> > - for (j = 0; j < VEC_COUNT; j++) {
> > + for (j = 0; j < eiointc_priv[i]->vec_count; j++) {
> > desc = irq_resolve_mapping(eiointc_priv[i]->eiointc_domain, j);
> > if (desc && desc->handle_irq && desc->handle_irq != handle_bad_irq) {
> > raw_spin_lock(&desc->lock);
> > @@ -373,11 +375,44 @@ static int __init acpi_cascade_irqdomain_init(void)
> > return 0;
> > }
> >
> > +static int __init eiointc_init(struct eiointc_priv *priv, int parent_irq,
> > + u64 node_map)
> > +{
> > + int i;
> > +
> > + node_map = node_map ? node_map : -1ULL;
> > + for_each_possible_cpu(i) {
> > + if (node_map & (1ULL << (cpu_to_eio_node(i)))) {
> > + node_set(cpu_to_eio_node(i), priv->node_map);
> > + cpumask_or(&priv->cpuspan_map, &priv->cpuspan_map,
> > + cpumask_of(i));
> > + }
> > + }
> > +
> > + priv->eiointc_domain = irq_domain_create_linear(priv->domain_handle,
> > + priv->vec_count,
> > + &eiointc_domain_ops,
> > + priv);
> > + if (!priv->eiointc_domain) {
> > + pr_err("loongson-extioi: cannot add IRQ domain\n");
> > + return -ENOMEM;
> > + }
> > +
> > + eiointc_priv[nr_pics++] = priv;
> > + eiointc_router_init(0);
> > + irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, priv);
> > + register_syscore_ops(&eiointc_syscore_ops);
> > + cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_LOONGARCH_STARTING,
> > + "irqchip/loongarch/intc:starting",
> > + eiointc_router_init, NULL);
> > +
> > + return 0;
> > +}
> > +
> > int __init eiointc_acpi_init(struct irq_domain *parent,
> > struct acpi_madt_eio_pic *acpi_eiointc)
> > {
> > - int i, ret, parent_irq;
> > - unsigned long node_map;
> > + int parent_irq, ret;
> > struct eiointc_priv *priv;
> >
> > priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> > @@ -391,39 +426,20 @@ int __init eiointc_acpi_init(struct irq_domain *parent,
> > goto out_free_priv;
> > }
> >
> > + priv->vec_count = VEC_COUNT;
> > priv->node = acpi_eiointc->node;
> > - node_map = acpi_eiointc->node_map ? : -1ULL;
> > -
> > - for_each_possible_cpu(i) {
> > - if (node_map & (1ULL << cpu_to_eio_node(i))) {
> > - node_set(cpu_to_eio_node(i), priv->node_map);
> > - cpumask_or(&priv->cpuspan_map, &priv->cpuspan_map, cpumask_of(i));
> > - }
> > - }
> > -
> > - /* Setup IRQ domain */
> > - priv->eiointc_domain = irq_domain_create_linear(priv->domain_handle, VEC_COUNT,
> > - &eiointc_domain_ops, priv);
> > - if (!priv->eiointc_domain) {
> > - pr_err("loongson-eiointc: cannot add IRQ domain\n");
> > - goto out_free_handle;
> > - }
> > -
> > - eiointc_priv[nr_pics++] = priv;
> > -
> > - eiointc_router_init(0);
> > -
> > parent_irq = irq_create_mapping(parent, acpi_eiointc->cascade);
> > - irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, priv);
> >
> > - register_syscore_ops(&eiointc_syscore_ops);
> > - cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_LOONGARCH_STARTING,
> > - "irqchip/loongarch/intc:starting",
> > - eiointc_router_init, NULL);
> > + ret = eiointc_init(priv, parent_irq, acpi_eiointc->node_map);
> > + if (ret < 0)
> > + goto out_free_handle;
> >
> > acpi_set_vec_parent(acpi_eiointc->node, priv->eiointc_domain, pch_group);
> > acpi_set_vec_parent(acpi_eiointc->node, priv->eiointc_domain, msi_group);
> > +
> > ret = acpi_cascade_irqdomain_init();
> > + if (ret < 0)
> > + goto out_free_handle;
> >
> > return ret;
> >
> > @@ -435,3 +451,39 @@ int __init eiointc_acpi_init(struct irq_domain *parent,
> >
> > return -ENOMEM;
> > }
> > +
> > +static int __init eiointc_of_init(struct device_node *of_node,
> > + struct device_node *parent)
> > +{
> > + int parent_irq, ret;
> > + struct eiointc_priv *priv;
> > +
> > + priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> > + if (!priv)
> > + return -ENOMEM;
> > +
> > + parent_irq = of_irq_get_byname(of_node, "cascade");
> > + if (parent_irq <= 0) {
> > + ret = -ENODEV;
> > + goto out_free_priv;
> > + }
> > +
> > + ret = of_property_read_u32(of_node, "vec_count", &priv->vec_count);
> > + if (ret < 0)
> > + goto out_free_priv;
> > +
> > + priv->node = 0;
> > + priv->domain_handle = of_node_to_fwnode(of_node);
> > +
> > + ret = eiointc_init(priv, parent_irq, 0);
> > + if (ret < 0)
> > + goto out_free_priv;
> > +
> > + return 0;
> > +
> > +out_free_priv:
> > + kfree(priv);
> > + return ret;
> > +}
> > +
> > +IRQCHIP_DECLARE(loongson_eiointc, "loongson,eiointc", eiointc_of_init);
> > --
> > 2.39.0
> >
> >
>

2023-02-12 11:49:25

by Marc Zyngier

[permalink] [raw]
Subject: Re: [PATCH] irqchip/loongson-eiointc: Add DT init support

On Sat, 11 Feb 2023 02:41:56 +0000,
Binbin Zhou <[email protected]> wrote:
>
> Add DT support for EIOINTC irqchip, which is needed for the Loongson-2K
> series, e.g. Loongson-2K500 soc.

Where is the binding? I'm pretty sure other drivers need updating.
Where are they?

M.

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

2023-02-13 06:44:06

by Binbin Zhou

[permalink] [raw]
Subject: Re: [PATCH] irqchip/loongson-eiointc: Add DT init support

On Sun, Feb 12, 2023 at 7:49 PM Marc Zyngier <[email protected]> wrote:
>
> On Sat, 11 Feb 2023 02:41:56 +0000,
> Binbin Zhou <[email protected]> wrote:
> >
> > Add DT support for EIOINTC irqchip, which is needed for the Loongson-2K
> > series, e.g. Loongson-2K500 soc.
>
> Where is the binding? I'm pretty sure other drivers need updating.
> Where are they?

Hi Marc:

I will add the binding file in my next version patchset.

Thanks.
Binbin

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