[GIT PULL] irqchip updates for 4.7

Marc Zyngier marc.zyngier at arm.com
Wed May 11 03:01:09 PDT 2016


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;
  	}



More information about the linux-arm-kernel mailing list