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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Feb 12, 2023 at 9:53 AM Huacai Chen <chenhuacai@xxxxxxxxxx> wrote:
>
> Hi, Binbin,
>
> On Sat, Feb 11, 2023 at 10:41 AM Binbin Zhou <zhoubinbin@xxxxxxxxxxx> 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 <zhoubinbin@xxxxxxxxxxx>
> > ---
> >  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
> >
> >
>



[Index of Archives]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux