Hi Thomas,

This is the pull request for the irqchip updates targeting 4.7: A
couple of new drivers, quite a few cleanups two bug fixes and a
workaround for a Broadcom erratum. Jon's PM support has uncovered
another bug nest, so I'm holding it until this is properly solved.

A word of warning: there is some other GIC stuff queued through the
KVM/ARM tree (ACPI support) and the arm64 tree (feature detection
code), which are already in -next. I'm including the resolution at the
end of this email.

Thanks,

        M.

The following changes since commit 287e9357abcc0ef079bf4e439e098a3bd6246a05:

  DT/arm,gic-v3: Documment PPI partition support (2016-05-02 13:42:51 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git 
tags/irqchip-for-4.7

for you to fetch changes up to a1dcbd11d09be1cb357b2f217c0eaa1461128da0:

  irqchip/bcm2836: Use a more generic memory barrier call (2016-05-11 10:13:00 
+0100)

----------------------------------------------------------------
irqchip updates for Linux 4.7

- Layerscape SCFG MSI controller support
- LPC32xx interrupt controller support
- RPi irqchip support on arm64
- GICv2 cleanup
- GICv2 and GICv3 bug fixes

----------------------------------------------------------------
Christoph Hellwig (1):
      irqchip/irq-alpine-msi: Don't use <asm-generic/msi.h>

Dan Carpenter (1):
      irqchip/mbigen: Checking for IS_ERR() instead of NULL

Eric Anholt (3):
      irqchip/bcm2836: Drop smp_set_ops on arm64 builds
      irqchip/bcm2836: Fix compiler warning on 64-bit build
      irqchip/bcm2836: Use a more generic memory barrier call

Jon Hunter (10):
      genirq: Ensure IRQ descriptor is valid when setting-up the IRQ
      irqchip: Mask the non-type/sense bits when translating an IRQ
      irqchip/gic: Don't unnecessarily write the IRQ configuration
      irqchip/gic: WARN if setting the interrupt type for a PPI fails
      irqchip/gic: Don't initialise chip if mapping IO space fails
      irqchip/gic: Remove static irq_chip definition for eoimode1
      irqchip/gic: Return an error if GIC initialisation fails
      irqchip/gic: Pass GIC pointer to save/restore functions
      irqchip/gic: Store GIC configuration parameters
      irqchip/gic: Add helper functions for GIC setup and teardown

Marc Zyngier (2):
      irqchip/gic-v3: Remove inexistant register definition
      irqchip/gic-v3: Configure all interrupts as non-secure Group-1

Minghuan Lian (2):
      dt/bindings: Add bindings for Layerscape SCFG MSI
      irqchip: Add Layerscape SCFG MSI controller support

Ray Jui (1):
      irqchip/gic-v2m: Add workaround for Broadcom NS2 GICv2m erratum

Shanker Donthineni (1):
      irqchip/gicv3-its: Don't allow devices whose ID is outside range

Vladimir Zapolskiy (1):
      irqchip: Add LPC32xx interrupt controller driver

Will Deacon (1):
      irqchip/gic: Ensure ordering between read of INTACK and shared data

 .../interrupt-controller/fsl,ls-scfg-msi.txt       |  30 ++
 arch/arm/Kconfig                                   |   2 +
 arch/arm/mach-lpc32xx/phy3250.c                    |   1 -
 drivers/irqchip/Kconfig                            |   5 +
 drivers/irqchip/Makefile                           |   2 +
 drivers/irqchip/irq-alpine-msi.c                   |   2 +-
 drivers/irqchip/irq-bcm2836.c                      |  10 +-
 drivers/irqchip/irq-crossbar.c                     |   2 +-
 drivers/irqchip/irq-gic-common.c                   |  20 +-
 drivers/irqchip/irq-gic-v2m.c                      |  19 +-
 drivers/irqchip/irq-gic-v3-its.c                   |  42 ++-
 drivers/irqchip/irq-gic-v3.c                       |  19 ++
 drivers/irqchip/irq-gic.c                          | 322 +++++++++++++--------
 drivers/irqchip/irq-lpc32xx.c                      | 238 +++++++++++++++
 drivers/irqchip/irq-ls-scfg-msi.c                  | 240 +++++++++++++++
 drivers/irqchip/irq-mbigen.c                       |   4 +-
 drivers/irqchip/irq-tegra.c                        |   2 +-
 include/linux/irqchip/arm-gic-v3.h                 |   2 -
 kernel/irq/manage.c                                |   2 +-
 19 files changed, 827 insertions(+), 137 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/interrupt-controller/fsl,ls-scfg-msi.txt
 create mode 100644 drivers/irqchip/irq-lpc32xx.c
 create mode 100644 drivers/irqchip/irq-ls-scfg-msi.c

diff --cc drivers/irqchip/Kconfig
index 81f88ad,2f115be..0000000
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@@ -246,10 -246,11 +246,16 @@@ config MVEBU_ODM
        bool
        select GENERIC_MSI_IRQ_DOMAIN
  
 +config LS_SCFG_MSI
 +      def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE
 +      depends on PCI && PCI_MSI
 +      select PCI_MSI_IRQ_DOMAIN
 +
+ config EZNPS_GIC
+       bool "NPS400 Global Interrupt Manager (GIM)"
+       select IRQ_DOMAIN
+       help
+         Support the EZchip NPS400 global interrupt controller
+ 
  config PARTITION_PERCPU
        bool
diff --cc drivers/irqchip/Makefile
index f828244,f475986..0000000
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@@ -67,4 -66,4 +67,5 @@@ obj-$(CONFIG_INGENIC_IRQ)             += irq-ingen
  obj-$(CONFIG_IMX_GPCV2)                       += irq-imx-gpcv2.o
  obj-$(CONFIG_PIC32_EVIC)              += irq-pic32-evic.o
  obj-$(CONFIG_MVEBU_ODMI)              += irq-mvebu-odmi.o
 +obj-$(CONFIG_LS_SCFG_MSI)             += irq-ls-scfg-msi.o
+ obj-$(CONFIG_EZNPS_GIC)                       += irq-eznps.o
diff --cc drivers/irqchip/irq-gic.c
index 113e2d0,30d05a4..0000000
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@@ -486,9 -491,8 +488,10 @@@ static int gic_cpu_init(struct gic_chip
                /*
                 * Get what the GIC says our CPU mask is.
                 */
 -              BUG_ON(cpu >= NR_GIC_CPU_IF);
 +              if (WARN_ON(cpu >= NR_GIC_CPU_IF))
 +                      return -EINVAL;
 +
+               gic_check_cpu_features();
                cpu_mask = gic_get_cpumask(gic);
                gic_cpu_map[cpu] = cpu_mask;
  
@@@ -1029,28 -1014,24 +1032,26 @@@ static const struct irq_domain_ops gic_
        .unmap = gic_irq_domain_unmap,
  };
  
 -static void __init __gic_init_bases(unsigned int gic_nr, int irq_start,
 -                         void __iomem *dist_base, void __iomem *cpu_base,
 -                         u32 percpu_offset, struct fwnode_handle *handle)
 +static int __init __gic_init_bases(struct gic_chip_data *gic, int irq_start,
 +                                 struct fwnode_handle *handle)
  {
        irq_hw_number_t hwirq_base;
 -      struct gic_chip_data *gic;
 -      int gic_irqs, irq_base, i;
 -
 -      BUG_ON(gic_nr >= CONFIG_ARM_GIC_MAX_NR);
 +      int gic_irqs, irq_base, i, ret;
  
 -      gic = &gic_data[gic_nr];
 +      if (WARN_ON(!gic || gic->domain))
 +              return -EINVAL;
  
-       gic_check_cpu_features();
- 
        /* Initialize irq_chip */
 -      if (static_key_true(&supports_deactivate) && gic_nr == 0) {
 -              gic->chip = gic_eoimode1_chip;
 +      gic->chip = gic_chip;
 +
 +      if (static_key_true(&supports_deactivate) && gic == &gic_data[0]) {
 +              gic->chip.irq_mask = gic_eoimode1_mask_irq;
 +              gic->chip.irq_eoi = gic_eoimode1_eoi_irq;
 +              gic->chip.irq_set_vcpu_affinity = gic_irq_set_vcpu_affinity;
 +              gic->chip.name = kasprintf(GFP_KERNEL, "GICv2");
        } else {
 -              gic->chip = gic_chip;
 -              gic->chip.name = kasprintf(GFP_KERNEL, "GIC-%d", gic_nr);
 +              gic->chip.name = kasprintf(GFP_KERNEL, "GIC-%d",
 +                                         (int)(gic - &gic_data[0]));
        }
  
  #ifdef CONFIG_SMP
@@@ -1249,30 -1190,29 +1250,53 @@@ static bool gic_check_eoimode(struct de
        return true;
  }
  
 +static int gic_of_setup(struct gic_chip_data *gic, struct device_node *node)
 +{
 +      if (!gic || !node)
 +              return -EINVAL;
 +
 +      gic->raw_dist_base = of_iomap(node, 0);
 +      if (WARN(!gic->raw_dist_base, "unable to map gic dist registers\n"))
 +              goto error;
 +
 +      gic->raw_cpu_base = of_iomap(node, 1);
 +      if (WARN(!gic->raw_cpu_base, "unable to map gic cpu registers\n"))
 +              goto error;
 +
 +      if (of_property_read_u32(node, "cpu-offset", &gic->percpu_offset))
 +              gic->percpu_offset = 0;
 +
 +      return 0;
 +
 +error:
 +      gic_teardown(gic);
 +
 +      return -ENOMEM;
 +}
 +
+ static void __init gic_of_setup_kvm_info(struct device_node *node)
+ {
+       int ret;
+       struct resource *vctrl_res = &gic_v2_kvm_info.vctrl;
+       struct resource *vcpu_res = &gic_v2_kvm_info.vcpu;
+ 
+       gic_v2_kvm_info.type = GIC_V2;
+ 
+       gic_v2_kvm_info.maint_irq = irq_of_parse_and_map(node, 0);
+       if (!gic_v2_kvm_info.maint_irq)
+               return;
+ 
+       ret = of_address_to_resource(node, 2, vctrl_res);
+       if (ret)
+               return;
+ 
+       ret = of_address_to_resource(node, 3, vcpu_res);
+       if (ret)
+               return;
+ 
+       gic_set_kvm_info(&gic_v2_kvm_info);
+ }
+ 
  int __init
  gic_of_init(struct device_node *node, struct device_node *parent)
  {
@@@ -1295,17 -1234,18 +1319,19 @@@
         * Disable split EOI/Deactivate if either HYP is not available
         * or the CPU interface is too small.
         */
 -      if (gic_cnt == 0 && !gic_check_eoimode(node, &cpu_base))
 +      if (gic_cnt == 0 && !gic_check_eoimode(node, &gic->raw_cpu_base))
                static_key_slow_dec(&supports_deactivate);
  
 -      if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
 -              percpu_offset = 0;
 +      ret = __gic_init_bases(gic, -1, &node->fwnode);
 +      if (ret) {
 +              gic_teardown(gic);
 +              return ret;
 +      }
  
-       if (!gic_cnt)
 -      __gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset,
 -                       &node->fwnode);
+       if (!gic_cnt) {
                gic_init_physaddr(node);
+               gic_of_setup_kvm_info(node);
+       }
  
        if (parent) {
                irq = irq_of_parse_and_map(node, 0);
@@@ -1402,8 -1390,8 +1476,8 @@@ static int __init gic_v2_acpi_init(stru
                return -EINVAL;
        }
  
-       gic->raw_cpu_base = ioremap(cpu_phy_base, ACPI_GIC_CPU_IF_MEM_SIZE);
 -      cpu_base = ioremap(acpi_data.cpu_phys_base, ACPI_GIC_CPU_IF_MEM_SIZE);
 -      if (!cpu_base) {
++      gic->raw_cpu_base = ioremap(acpi_data.cpu_phys_base, 
ACPI_GIC_CPU_IF_MEM_SIZE);
 +      if (!gic->raw_cpu_base) {
                pr_err("Unable to map GICC registers\n");
                return -ENOMEM;
        }

Reply via email to