diff mbox series

[07/35] ARM: davinci: aintc: use irq domain

Message ID 20190131133928.17985-8-brgl@bgdev.pl (mailing list archive)
State New, archived
Headers show
Series ARM: davinci: modernize the irq support | expand

Commit Message

Bartosz Golaszewski Jan. 31, 2019, 1:39 p.m. UTC
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>

We need to create an irq domain if we want to select SPARSE_IRQ. The
cp-intc driver already supports it, but aintc doesn't. Use the helpers
provided by the generic irq chip abstraction.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 arch/arm/mach-davinci/irq.c | 38 ++++++++++++++++++++++++++-----------
 1 file changed, 27 insertions(+), 11 deletions(-)

Comments

David Lechner Feb. 4, 2019, 10:42 p.m. UTC | #1
On 1/31/19 7:39 AM, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> 
> We need to create an irq domain if we want to select SPARSE_IRQ. The
> cp-intc driver already supports it, but aintc doesn't. Use the helpers
> provided by the generic irq chip abstraction.
> 
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
>   arch/arm/mach-davinci/irq.c | 38 ++++++++++++++++++++++++++-----------
>   1 file changed, 27 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
> index e539bc65d4ef..c874ea269411 100644
> --- a/arch/arm/mach-davinci/irq.c
> +++ b/arch/arm/mach-davinci/irq.c
> @@ -23,6 +23,7 @@
>   #include <linux/interrupt.h>
>   #include <linux/irq.h>
>   #include <linux/io.h>
> +#include <linux/irqdomain.h>
>   
>   #include <mach/hardware.h>
>   #include <mach/cputype.h>
> @@ -43,6 +44,7 @@
>   #define IRQ_INTPRI7_REG_OFFSET	0x004C
>   
>   static void __iomem *davinci_intc_base;
> +static struct irq_domain *davinci_irq_domain;
>   
>   static inline void davinci_irq_writel(unsigned long value, int offset)
>   {
> @@ -55,17 +57,15 @@ static inline unsigned long davinci_irq_readl(int offset)
>   }
>   
>   static __init void
> -davinci_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
> +davinci_irq_setup_gc(void __iomem *base,
> +		     unsigned int irq_start, unsigned int num)
>   {
>   	struct irq_chip_generic *gc;
>   	struct irq_chip_type *ct;
>   
> -	gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq);
> -	if (!gc) {
> -		pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n",
> -		       __func__, irq_start);
> -		return;
> -	}
> +	gc = irq_get_domain_generic_chip(davinci_irq_domain, irq_start);

check for (gc == NULL) here?
Bartosz Golaszewski Feb. 5, 2019, 4:29 p.m. UTC | #2
pon., 4 lut 2019 o 23:42 David Lechner <david@lechnology.com> napisaƂ(a):
>
> On 1/31/19 7:39 AM, Bartosz Golaszewski wrote:
> > From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> >
> > We need to create an irq domain if we want to select SPARSE_IRQ. The
> > cp-intc driver already supports it, but aintc doesn't. Use the helpers
> > provided by the generic irq chip abstraction.
> >
> > Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> > ---
> >   arch/arm/mach-davinci/irq.c | 38 ++++++++++++++++++++++++++-----------
> >   1 file changed, 27 insertions(+), 11 deletions(-)
> >
> > diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
> > index e539bc65d4ef..c874ea269411 100644
> > --- a/arch/arm/mach-davinci/irq.c
> > +++ b/arch/arm/mach-davinci/irq.c
> > @@ -23,6 +23,7 @@
> >   #include <linux/interrupt.h>
> >   #include <linux/irq.h>
> >   #include <linux/io.h>
> > +#include <linux/irqdomain.h>
> >
> >   #include <mach/hardware.h>
> >   #include <mach/cputype.h>
> > @@ -43,6 +44,7 @@
> >   #define IRQ_INTPRI7_REG_OFFSET      0x004C
> >
> >   static void __iomem *davinci_intc_base;
> > +static struct irq_domain *davinci_irq_domain;
> >
> >   static inline void davinci_irq_writel(unsigned long value, int offset)
> >   {
> > @@ -55,17 +57,15 @@ static inline unsigned long davinci_irq_readl(int offset)
> >   }
> >
> >   static __init void
> > -davinci_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
> > +davinci_irq_setup_gc(void __iomem *base,
> > +                  unsigned int irq_start, unsigned int num)
> >   {
> >       struct irq_chip_generic *gc;
> >       struct irq_chip_type *ct;
> >
> > -     gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq);
> > -     if (!gc) {
> > -             pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n",
> > -                    __func__, irq_start);
> > -             return;
> > -     }
> > +     gc = irq_get_domain_generic_chip(davinci_irq_domain, irq_start);
>
> check for (gc == NULL) here?
>

I can add it, but it's not really needed. We know we pass correct
parameters to this routine and if it fails, the system won't boot
anyway.

Bart
Sekhar Nori Feb. 6, 2019, 3:08 p.m. UTC | #3
On 31/01/19 7:09 PM, Bartosz Golaszewski wrote:
> @@ -82,13 +82,11 @@ static asmlinkage void __exception_irq_entry
>  davinci_handle_irq(struct pt_regs *regs)
>  {
>  	int irqnr = davinci_irq_readl(IRQ_IRQENTRY_OFFSET);
> -	struct pt_regs *old_regs = set_irq_regs(regs);
>  
>  	irqnr >>= 2;
>  	irqnr -= 1;
>  
> -	generic_handle_irq(irqnr);
> -	set_irq_regs(old_regs);
> +	handle_domain_irq(davinci_irq_domain, irqnr, regs);
>  }

Is it possible to bring 2/35 after this patch so you dont end up
removing code added there?

Thanks,
Sekhar
diff mbox series

Patch

diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
index e539bc65d4ef..c874ea269411 100644
--- a/arch/arm/mach-davinci/irq.c
+++ b/arch/arm/mach-davinci/irq.c
@@ -23,6 +23,7 @@ 
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/irqdomain.h>
 
 #include <mach/hardware.h>
 #include <mach/cputype.h>
@@ -43,6 +44,7 @@ 
 #define IRQ_INTPRI7_REG_OFFSET	0x004C
 
 static void __iomem *davinci_intc_base;
+static struct irq_domain *davinci_irq_domain;
 
 static inline void davinci_irq_writel(unsigned long value, int offset)
 {
@@ -55,17 +57,15 @@  static inline unsigned long davinci_irq_readl(int offset)
 }
 
 static __init void
-davinci_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
+davinci_irq_setup_gc(void __iomem *base,
+		     unsigned int irq_start, unsigned int num)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 
-	gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq);
-	if (!gc) {
-		pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n",
-		       __func__, irq_start);
-		return;
-	}
+	gc = irq_get_domain_generic_chip(davinci_irq_domain, irq_start);
+	gc->reg_base = base;
+	gc->irq_base = irq_start;
 
 	ct = gc->chip_types;
 	ct->chip.irq_ack = irq_gc_ack_set_bit;
@@ -82,13 +82,11 @@  static asmlinkage void __exception_irq_entry
 davinci_handle_irq(struct pt_regs *regs)
 {
 	int irqnr = davinci_irq_readl(IRQ_IRQENTRY_OFFSET);
-	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	irqnr >>= 2;
 	irqnr -= 1;
 
-	generic_handle_irq(irqnr);
-	set_irq_regs(old_regs);
+	handle_domain_irq(davinci_irq_domain, irqnr, regs);
 }
 
 /* ARM Interrupt Controller Initialization */
@@ -96,6 +94,7 @@  void __init davinci_irq_init(void)
 {
 	unsigned i, j;
 	const u8 *davinci_def_priorities = davinci_soc_info.intc_irq_prios;
+	int rv, irq_base;
 
 	davinci_intc_base = ioremap(davinci_soc_info.intc_base, SZ_4K);
 	if (WARN_ON(!davinci_intc_base))
@@ -131,8 +130,25 @@  void __init davinci_irq_init(void)
 		davinci_irq_writel(pri, i);
 	}
 
+	irq_base = irq_alloc_descs(-1, 0, davinci_soc_info.intc_irq_num, 0);
+	if (WARN_ON(irq_base < 0))
+		return;
+
+	davinci_irq_domain = irq_domain_add_legacy(NULL,
+					davinci_soc_info.intc_irq_num,
+					irq_base, 0, &irq_domain_simple_ops,
+					NULL);
+	if (WARN_ON(!davinci_irq_domain))
+		return;
+
+	rv = irq_alloc_domain_generic_chips(davinci_irq_domain, 32, 1,
+					    "AINTC", handle_edge_irq,
+					    IRQ_NOREQUEST | IRQ_NOPROBE, 0, 0);
+	if (WARN_ON(rv))
+		return;
+
 	for (i = 0, j = 0; i < davinci_soc_info.intc_irq_num; i += 32, j += 0x04)
-		davinci_alloc_gc(davinci_intc_base + j, i, 32);
+		davinci_irq_setup_gc(davinci_intc_base + j, irq_base + i, 32);
 
 	irq_set_handler(IRQ_TINT1_TINT34, handle_level_irq);
 	set_handle_irq(davinci_handle_irq);