Re: [PATCH v11 11/19] irqchip: vic: Add support for FIQ management

2014-09-02 Thread Russell King - ARM Linux
On Tue, Sep 02, 2014 at 02:00:45PM +0100, Daniel Thompson wrote:
> diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> index bda5a91..8821160 100644
> --- a/drivers/irqchip/irq-gic.c
> +++ b/drivers/irqchip/irq-gic.c
> @@ -502,13 +502,17 @@ static void __init gic_init_fiq(struct gic_chip_data 
> *gic,
>  /*
>   * Fully acknowledge (both ack and eoi) a FIQ-based IPI
>   */
> -static int gic_handle_fiq_ipi(struct notifier_block *nb, unsigned long regs,
> -void *data)
> +void gic_handle_fiq_ipi(void)
>  {
>   struct gic_chip_data *gic = _data[0];
> - void __iomem *cpu_base = gic_data_cpu_base(gic);
> + void __iomem *cpu_base;
>   unsigned long irqstat, irqnr;
>  
> + if (!gic || !gic->fiq_enable)
> + return;
> +
> + cpu_base = gic_data_cpu_base(gic);
> +
>   if (WARN_ON(!in_nmi()))
>   return NOTIFY_BAD;
>  
> @@ -525,13 +529,6 @@ static int gic_handle_fiq_ipi(struct notifier_block *nb, 
> unsigned long regs,
>  
>   return NOTIFY_OK;
>  }
> -
> -/*
> - * Notifier to ensure IPI FIQ is acknowledged correctly.
> - */
> -static struct notifier_block gic_fiq_ipi_notifier = {
> - .notifier_call = gic_handle_fiq_ipi,
> -};
>  #else /* CONFIG_FIQ */
>  static inline void gic_set_group_irq(void __iomem *base, unsigned int hwirq,
>int group) {}
> @@ -1250,10 +1247,6 @@ void __init gic_init_bases(unsigned int gic_nr, int 
> irq_start,
>  #ifdef CONFIG_SMP
>   set_smp_cross_call(gic_raise_softirq);
>   register_cpu_notifier(_cpu_notifier);
> -#ifdef CONFIG_FIQ
> - if (gic_data_fiq_enable(gic))
> - register_fiq_nmi_notifier(_fiq_ipi_notifier);
> -#endif
>  #endif
>   set_handle_irq(gic_handle_irq);
>   }

Shouldn't this be merged into some other patch?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v11 11/19] irqchip: vic: Add support for FIQ management

2014-09-02 Thread Daniel Thompson
This patch introduces callbacks to route interrupts to or away
from the FIQ signal. It also causes these callbacks to be registered
with the FIQ infrastructure.

This patch enable FIQ support for mach-versatile whilst mach-ep93xx,
mach-netx, mach-s3c64xx and plat-samsung are unmodified (and can therefore
continue to use init_FIQ() as before).

Signed-off-by: Daniel Thompson 
Cc: Hartley Sweeten 
Cc: Ryan Mallon 
Cc: Russell King 
Cc: Ben Dooks 
Cc: Kukjin Kim 
Cc: Thomas Gleixner 
Cc: Jason Cooper 
Cc: linux-samsung-...@vger.kernel.org
---
 arch/arm/mach-versatile/core.c  |  2 +-
 drivers/irqchip/irq-gic.c   | 21 --
 drivers/irqchip/irq-vic.c   | 92 -
 include/linux/irqchip/arm-gic.h |  3 ++
 include/linux/irqchip/arm-vic.h |  6 ++-
 5 files changed, 88 insertions(+), 36 deletions(-)

diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 08fb8c8..bad1d30 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -108,7 +108,7 @@ void __init versatile_init_irq(void)
 
np = of_find_matching_node_by_address(NULL, vic_of_match,
  VERSATILE_VIC_BASE);
-   __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np);
+   __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np ? false : true, np);
 
writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index bda5a91..8821160 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -502,13 +502,17 @@ static void __init gic_init_fiq(struct gic_chip_data *gic,
 /*
  * Fully acknowledge (both ack and eoi) a FIQ-based IPI
  */
-static int gic_handle_fiq_ipi(struct notifier_block *nb, unsigned long regs,
-  void *data)
+void gic_handle_fiq_ipi(void)
 {
struct gic_chip_data *gic = _data[0];
-   void __iomem *cpu_base = gic_data_cpu_base(gic);
+   void __iomem *cpu_base;
unsigned long irqstat, irqnr;
 
+   if (!gic || !gic->fiq_enable)
+   return;
+
+   cpu_base = gic_data_cpu_base(gic);
+
if (WARN_ON(!in_nmi()))
return NOTIFY_BAD;
 
@@ -525,13 +529,6 @@ static int gic_handle_fiq_ipi(struct notifier_block *nb, 
unsigned long regs,
 
return NOTIFY_OK;
 }
-
-/*
- * Notifier to ensure IPI FIQ is acknowledged correctly.
- */
-static struct notifier_block gic_fiq_ipi_notifier = {
-   .notifier_call = gic_handle_fiq_ipi,
-};
 #else /* CONFIG_FIQ */
 static inline void gic_set_group_irq(void __iomem *base, unsigned int hwirq,
 int group) {}
@@ -1250,10 +1247,6 @@ void __init gic_init_bases(unsigned int gic_nr, int 
irq_start,
 #ifdef CONFIG_SMP
set_smp_cross_call(gic_raise_softirq);
register_cpu_notifier(_cpu_notifier);
-#ifdef CONFIG_FIQ
-   if (gic_data_fiq_enable(gic))
-   register_fiq_nmi_notifier(_fiq_ipi_notifier);
-#endif
 #endif
set_handle_irq(gic_handle_irq);
}
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
index 7d35287..22aa126 100644
--- a/drivers/irqchip/irq-vic.c
+++ b/drivers/irqchip/irq-vic.c
@@ -36,6 +36,9 @@
 
 #include 
 #include 
+#ifdef CONFIG_FIQ
+#include 
+#endif
 
 #include "irqchip.h"
 
@@ -261,11 +264,53 @@ static struct irq_domain_ops vic_irqdomain_ops = {
.xlate = irq_domain_xlate_onetwocell,
 };
 
+#ifdef CONFIG_FIQ
+static DEFINE_RAW_SPINLOCK(irq_controller_lock);
+
+static void vic_set_fiq(struct irq_data *d, bool enable)
+{
+   void __iomem *base = irq_data_get_irq_chip_data(d);
+   unsigned int irq = d->hwirq;
+   u32 val;
+
+   raw_spin_lock(_controller_lock);
+   val = readl(base + VIC_INT_SELECT);
+   if (enable)
+   val |= 1 << irq;
+   else
+   val &= ~(1 << irq);
+   writel(val, base + VIC_INT_SELECT);
+   raw_spin_unlock(_controller_lock);
+}
+
+static void vic_enable_fiq(struct irq_data *d)
+{
+   vic_set_fiq(d, true);
+}
+
+static void vic_disable_fiq(struct irq_data *d)
+{
+   vic_set_fiq(d, false);
+}
+
+struct fiq_chip vic_fiq = {
+   .fiq_enable = vic_enable_fiq,
+   .fiq_disable = vic_disable_fiq,
+};
+
+static void vic_register_fiq(int irq)
+{
+   fiq_register_mapping(irq, _fiq);
+}
+#else /* CONFIG_FIQ */
+static inline void vic_register_fiq(int irq) {}
+#endif /* CONFIG_FIQ */
+
 /**
  * vic_register() - Register a VIC.
  * @base: The base address of the VIC.
  * @parent_irq: The parent IRQ if cascaded, else 0.
- * @irq: The base IRQ for the VIC.
+ * @irq_start: The base IRQ for the VIC.
  * @valid_sources: bitmask of valid interrupts
  * @resume_sources: bitmask of interrupts allowed for resume sources.
  * @node: The device tree node associated with the VIC.
@@ -277,12 +322,13 @@ static struct irq_domain_ops vic_irqdomain_ops = {
  * This also configures 

[PATCH v11 11/19] irqchip: vic: Add support for FIQ management

2014-09-02 Thread Daniel Thompson
This patch introduces callbacks to route interrupts to or away
from the FIQ signal. It also causes these callbacks to be registered
with the FIQ infrastructure.

This patch enable FIQ support for mach-versatile whilst mach-ep93xx,
mach-netx, mach-s3c64xx and plat-samsung are unmodified (and can therefore
continue to use init_FIQ() as before).

Signed-off-by: Daniel Thompson daniel.thomp...@linaro.org
Cc: Hartley Sweeten hswee...@visionengravers.com
Cc: Ryan Mallon rmal...@gmail.com
Cc: Russell King li...@arm.linux.org.uk
Cc: Ben Dooks ben-li...@fluff.org
Cc: Kukjin Kim kgene@samsung.com
Cc: Thomas Gleixner t...@linutronix.de
Cc: Jason Cooper ja...@lakedaemon.net
Cc: linux-samsung-...@vger.kernel.org
---
 arch/arm/mach-versatile/core.c  |  2 +-
 drivers/irqchip/irq-gic.c   | 21 --
 drivers/irqchip/irq-vic.c   | 92 -
 include/linux/irqchip/arm-gic.h |  3 ++
 include/linux/irqchip/arm-vic.h |  6 ++-
 5 files changed, 88 insertions(+), 36 deletions(-)

diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 08fb8c8..bad1d30 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -108,7 +108,7 @@ void __init versatile_init_irq(void)
 
np = of_find_matching_node_by_address(NULL, vic_of_match,
  VERSATILE_VIC_BASE);
-   __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np);
+   __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np ? false : true, np);
 
writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
 
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index bda5a91..8821160 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -502,13 +502,17 @@ static void __init gic_init_fiq(struct gic_chip_data *gic,
 /*
  * Fully acknowledge (both ack and eoi) a FIQ-based IPI
  */
-static int gic_handle_fiq_ipi(struct notifier_block *nb, unsigned long regs,
-  void *data)
+void gic_handle_fiq_ipi(void)
 {
struct gic_chip_data *gic = gic_data[0];
-   void __iomem *cpu_base = gic_data_cpu_base(gic);
+   void __iomem *cpu_base;
unsigned long irqstat, irqnr;
 
+   if (!gic || !gic-fiq_enable)
+   return;
+
+   cpu_base = gic_data_cpu_base(gic);
+
if (WARN_ON(!in_nmi()))
return NOTIFY_BAD;
 
@@ -525,13 +529,6 @@ static int gic_handle_fiq_ipi(struct notifier_block *nb, 
unsigned long regs,
 
return NOTIFY_OK;
 }
-
-/*
- * Notifier to ensure IPI FIQ is acknowledged correctly.
- */
-static struct notifier_block gic_fiq_ipi_notifier = {
-   .notifier_call = gic_handle_fiq_ipi,
-};
 #else /* CONFIG_FIQ */
 static inline void gic_set_group_irq(void __iomem *base, unsigned int hwirq,
 int group) {}
@@ -1250,10 +1247,6 @@ void __init gic_init_bases(unsigned int gic_nr, int 
irq_start,
 #ifdef CONFIG_SMP
set_smp_cross_call(gic_raise_softirq);
register_cpu_notifier(gic_cpu_notifier);
-#ifdef CONFIG_FIQ
-   if (gic_data_fiq_enable(gic))
-   register_fiq_nmi_notifier(gic_fiq_ipi_notifier);
-#endif
 #endif
set_handle_irq(gic_handle_irq);
}
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
index 7d35287..22aa126 100644
--- a/drivers/irqchip/irq-vic.c
+++ b/drivers/irqchip/irq-vic.c
@@ -36,6 +36,9 @@
 
 #include asm/exception.h
 #include asm/irq.h
+#ifdef CONFIG_FIQ
+#include asm/fiq.h
+#endif
 
 #include irqchip.h
 
@@ -261,11 +264,53 @@ static struct irq_domain_ops vic_irqdomain_ops = {
.xlate = irq_domain_xlate_onetwocell,
 };
 
+#ifdef CONFIG_FIQ
+static DEFINE_RAW_SPINLOCK(irq_controller_lock);
+
+static void vic_set_fiq(struct irq_data *d, bool enable)
+{
+   void __iomem *base = irq_data_get_irq_chip_data(d);
+   unsigned int irq = d-hwirq;
+   u32 val;
+
+   raw_spin_lock(irq_controller_lock);
+   val = readl(base + VIC_INT_SELECT);
+   if (enable)
+   val |= 1  irq;
+   else
+   val = ~(1  irq);
+   writel(val, base + VIC_INT_SELECT);
+   raw_spin_unlock(irq_controller_lock);
+}
+
+static void vic_enable_fiq(struct irq_data *d)
+{
+   vic_set_fiq(d, true);
+}
+
+static void vic_disable_fiq(struct irq_data *d)
+{
+   vic_set_fiq(d, false);
+}
+
+struct fiq_chip vic_fiq = {
+   .fiq_enable = vic_enable_fiq,
+   .fiq_disable = vic_disable_fiq,
+};
+
+static void vic_register_fiq(int irq)
+{
+   fiq_register_mapping(irq, vic_fiq);
+}
+#else /* CONFIG_FIQ */
+static inline void vic_register_fiq(int irq) {}
+#endif /* CONFIG_FIQ */
+
 /**
  * vic_register() - Register a VIC.
  * @base: The base address of the VIC.
  * @parent_irq: The parent IRQ if cascaded, else 0.
- * @irq: The base IRQ for the VIC.
+ * @irq_start: The base IRQ for the VIC.
  * @valid_sources: bitmask of valid interrupts
  * 

Re: [PATCH v11 11/19] irqchip: vic: Add support for FIQ management

2014-09-02 Thread Russell King - ARM Linux
On Tue, Sep 02, 2014 at 02:00:45PM +0100, Daniel Thompson wrote:
 diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
 index bda5a91..8821160 100644
 --- a/drivers/irqchip/irq-gic.c
 +++ b/drivers/irqchip/irq-gic.c
 @@ -502,13 +502,17 @@ static void __init gic_init_fiq(struct gic_chip_data 
 *gic,
  /*
   * Fully acknowledge (both ack and eoi) a FIQ-based IPI
   */
 -static int gic_handle_fiq_ipi(struct notifier_block *nb, unsigned long regs,
 -void *data)
 +void gic_handle_fiq_ipi(void)
  {
   struct gic_chip_data *gic = gic_data[0];
 - void __iomem *cpu_base = gic_data_cpu_base(gic);
 + void __iomem *cpu_base;
   unsigned long irqstat, irqnr;
  
 + if (!gic || !gic-fiq_enable)
 + return;
 +
 + cpu_base = gic_data_cpu_base(gic);
 +
   if (WARN_ON(!in_nmi()))
   return NOTIFY_BAD;
  
 @@ -525,13 +529,6 @@ static int gic_handle_fiq_ipi(struct notifier_block *nb, 
 unsigned long regs,
  
   return NOTIFY_OK;
  }
 -
 -/*
 - * Notifier to ensure IPI FIQ is acknowledged correctly.
 - */
 -static struct notifier_block gic_fiq_ipi_notifier = {
 - .notifier_call = gic_handle_fiq_ipi,
 -};
  #else /* CONFIG_FIQ */
  static inline void gic_set_group_irq(void __iomem *base, unsigned int hwirq,
int group) {}
 @@ -1250,10 +1247,6 @@ void __init gic_init_bases(unsigned int gic_nr, int 
 irq_start,
  #ifdef CONFIG_SMP
   set_smp_cross_call(gic_raise_softirq);
   register_cpu_notifier(gic_cpu_notifier);
 -#ifdef CONFIG_FIQ
 - if (gic_data_fiq_enable(gic))
 - register_fiq_nmi_notifier(gic_fiq_ipi_notifier);
 -#endif
  #endif
   set_handle_irq(gic_handle_irq);
   }

Shouldn't this be merged into some other patch?

-- 
FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/