Skip to content

Commit

Permalink
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/tip/tip

Pull irq updates from Thomas Gleixner:
 "The irq department delivers:

   - Expand the generic infrastructure handling the irq migration on CPU
     hotplug and convert X86 over to it. (Thomas Gleixner)

     Aside of consolidating code this is a preparatory change for:

   - Finalizing the affinity management for multi-queue devices. The
     main change here is to shut down interrupts which are affine to a
     outgoing CPU and reenabling them when the CPU comes online again.
     That avoids moving interrupts pointlessly around and breaking and
     reestablishing affinities for no value. (Christoph Hellwig)

     Note: This contains also the BLOCK-MQ and NVME changes which depend
     on the rework of the irq core infrastructure. Jens acked them and
     agreed that they should go with the irq changes.

   - Consolidation of irq domain code (Marc Zyngier)

   - State tracking consolidation in the core code (Jeffy Chen)

   - Add debug infrastructure for hierarchical irq domains (Thomas
     Gleixner)

   - Infrastructure enhancement for managing generic interrupt chips via
     devmem (Bartosz Golaszewski)

   - Constification work all over the place (Tobias Klauser)

   - Two new interrupt controller drivers for MVEBU (Thomas Petazzoni)

   - The usual set of fixes, updates and enhancements all over the
     place"

* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (112 commits)
  irqchip/or1k-pic: Fix interrupt acknowledgement
  irqchip/irq-mvebu-gicp: Allocate enough memory for spi_bitmap
  irqchip/gic-v3: Fix out-of-bound access in gic_set_affinity
  nvme: Allocate queues for all possible CPUs
  blk-mq: Create hctx for each present CPU
  blk-mq: Include all present CPUs in the default queue mapping
  genirq: Avoid unnecessary low level irq function calls
  genirq: Set irq masked state when initializing irq_desc
  genirq/timings: Add infrastructure for estimating the next interrupt arrival time
  genirq/timings: Add infrastructure to track the interrupt timings
  genirq/debugfs: Remove pointless NULL pointer check
  irqchip/gic-v3-its: Don't assume GICv3 hardware supports 16bit INTID
  irqchip/gic-v3-its: Add ACPI NUMA node mapping
  irqchip/gic-v3-its-platform-msi: Make of_device_ids const
  irqchip/gic-v3-its: Make of_device_ids const
  irqchip/irq-mvebu-icu: Add new driver for Marvell ICU
  irqchip/irq-mvebu-gicp: Add new driver for Marvell GICP
  dt-bindings/interrupt-controller: Add DT binding for the Marvell ICU
  genirq/irqdomain: Remove auto-recursive hierarchy support
  irqchip/MSI: Use irq_domain_update_bus_token instead of an open coded access
  ...
  • Loading branch information
torvalds committed Jul 3, 2017
2 parents 1b044f1 + f9632de commit 03ffbcd
Show file tree
Hide file tree
Showing 86 changed files with 3,342 additions and 709 deletions.
41 changes: 39 additions & 2 deletions Documentation/IRQ-domain.txt
Original file line number Diff line number Diff line change
Expand Up @@ -231,5 +231,42 @@ needs to:
4) No need to implement irq_domain_ops.map and irq_domain_ops.unmap,
they are unused with hierarchy irq_domain.

Hierarchy irq_domain may also be used to support other architectures,
such as ARM, ARM64 etc.
Hierarchy irq_domain is in no way x86 specific, and is heavily used to
support other architectures, such as ARM, ARM64 etc.

=== Debugging ===

If you switch on CONFIG_IRQ_DOMAIN_DEBUG (which depends on
CONFIG_IRQ_DOMAIN and CONFIG_DEBUG_FS), you will find a new file in
your debugfs mount point, called irq_domain_mapping. This file
contains a live snapshot of all the IRQ domains in the system:

name mapped linear-max direct-max devtree-node
pl061 8 8 0 /smb/gpio@e0080000
pl061 8 8 0 /smb/gpio@e1050000
pMSI 0 0 0 /interrupt-controller@e1101000/v2m@e0080000
MSI 37 0 0 /interrupt-controller@e1101000/v2m@e0080000
GICv2m 37 0 0 /interrupt-controller@e1101000/v2m@e0080000
GICv2 448 448 0 /interrupt-controller@e1101000

it also iterates over the interrupts to display their mapping in the
domains, and makes the domain stacking visible:


irq hwirq chip name chip data active type domain
1 0x00019 GICv2 0xffff00000916bfd8 * LINEAR GICv2
2 0x0001d GICv2 0xffff00000916bfd8 LINEAR GICv2
3 0x0001e GICv2 0xffff00000916bfd8 * LINEAR GICv2
4 0x0001b GICv2 0xffff00000916bfd8 * LINEAR GICv2
5 0x0001a GICv2 0xffff00000916bfd8 LINEAR GICv2
[...]
96 0x81808 MSI 0x (null) RADIX MSI
96+ 0x00063 GICv2m 0xffff8003ee116980 RADIX GICv2m
96+ 0x00063 GICv2 0xffff00000916bfd8 LINEAR GICv2
97 0x08800 MSI 0x (null) * RADIX MSI
97+ 0x00064 GICv2m 0xffff8003ee116980 * RADIX GICv2m
97+ 0x00064 GICv2 0xffff00000916bfd8 * LINEAR GICv2

Here, interrupts 1-5 are only using a single domain, while 96 and 97
are build out of a stack of three domain, each level performing a
particular function.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ Allwinner Sunxi NMI Controller

Required properties:

- compatible : should be "allwinner,sun7i-a20-sc-nmi" or
"allwinner,sun6i-a31-sc-nmi" or "allwinner,sun9i-a80-nmi"
- compatible : should be one of the following:
- "allwinner,sun7i-a20-sc-nmi"
- "allwinner,sun6i-a31-sc-nmi" (deprecated)
- "allwinner,sun6i-a31-r-intc"
- "allwinner,sun9i-a80-nmi"
- reg : Specifies base physical address and size of the registers.
- interrupt-controller : Identifies the node as an interrupt controller
- #interrupt-cells : Specifies the number of cells needed to encode an
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Device tree configuration for the I2C Interrupt Controller on the AST24XX and
AST25XX SoCs.

Required Properties:
- #address-cells : should be 1
- #size-cells : should be 1
- #interrupt-cells : should be 1
- compatible : should be "aspeed,ast2400-i2c-ic"
or "aspeed,ast2500-i2c-ic"
- reg : address start and range of controller
- interrupts : interrupt number
- interrupt-controller : denotes that the controller receives and fires
new interrupts for child busses

Example:

i2c_ic: interrupt-controller@0 {
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <1>;
compatible = "aspeed,ast2400-i2c-ic";
reg = <0x0 0x40>;
interrupts = <12>;
interrupt-controller;
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
Aspeed Vectored Interrupt Controller

These bindings are for the Aspeed AST2400 interrupt controller register layout.
The SoC has an legacy register layout, but this driver does not support that
mode of operation.
These bindings are for the Aspeed interrupt controller. The AST2400 and
AST2500 SoC families include a legacy register layout before a re-designed
layout, but the bindings do not prescribe the use of one or the other.

Required properties:

- compatible : should be "aspeed,ast2400-vic".
- compatible : "aspeed,ast2400-vic"
"aspeed,ast2500-vic"

- interrupt-controller : Identifies the node as an interrupt controller
- #interrupt-cells : Specifies the number of cells needed to encode an
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Marvell GICP Controller
-----------------------

GICP is a Marvell extension of the GIC that allows to trigger GIC SPI
interrupts by doing a memory transaction. It is used by the ICU
located in the Marvell CP110 to turn wired interrupts inside the CP
into GIC SPI interrupts.

Required properties:

- compatible: Must be "marvell,ap806-gicp"

- reg: Must be the address and size of the GICP SPI registers

- marvell,spi-ranges: tuples of GIC SPI interrupts ranges available
for this GICP

- msi-controller: indicates that this is an MSI controller

Example:

gicp_spi: gicp-spi@3f0040 {
compatible = "marvell,ap806-gicp";
reg = <0x3f0040 0x10>;
marvell,spi-ranges = <64 64>, <288 64>;
msi-controller;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Marvell ICU Interrupt Controller
--------------------------------

The Marvell ICU (Interrupt Consolidation Unit) controller is
responsible for collecting all wired-interrupt sources in the CP and
communicating them to the GIC in the AP, the unit translates interrupt
requests on input wires to MSG memory mapped transactions to the GIC.

Required properties:

- compatible: Should be "marvell,cp110-icu"

- reg: Should contain ICU registers location and length.

- #interrupt-cells: Specifies the number of cells needed to encode an
interrupt source. The value shall be 3.

The 1st cell is the group type of the ICU interrupt. Possible group
types are:

ICU_GRP_NSR (0x0) : Shared peripheral interrupt, non-secure
ICU_GRP_SR (0x1) : Shared peripheral interrupt, secure
ICU_GRP_SEI (0x4) : System error interrupt
ICU_GRP_REI (0x5) : RAM error interrupt

The 2nd cell is the index of the interrupt in the ICU unit.

The 3rd cell is the type of the interrupt. See arm,gic.txt for
details.

- interrupt-controller: Identifies the node as an interrupt
controller.

- msi-parent: Should point to the GICP controller, the GIC extension
that allows to trigger interrupts using MSG memory mapped
transactions.

Example:

icu: interrupt-controller@1e0000 {
compatible = "marvell,cp110-icu";
reg = <0x1e0000 0x10>;
#interrupt-cells = <3>;
interrupt-controller;
msi-parent = <&gicp>;
};

usb3h0: usb3@500000 {
interrupt-parent = <&icu>;
interrupts = <ICU_GRP_NSR 106 IRQ_TYPE_LEVEL_HIGH>;
};
2 changes: 2 additions & 0 deletions Documentation/driver-model/devres.txt
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ IRQ
devm_irq_alloc_desc_at()
devm_irq_alloc_desc_from()
devm_irq_alloc_descs_from()
devm_irq_alloc_generic_chip()
devm_irq_setup_generic_chip()

LED
devm_led_classdev_register()
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ config X86
select GENERIC_EARLY_IOREMAP
select GENERIC_FIND_FIRST_BIT
select GENERIC_IOMAP
select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
select GENERIC_IRQ_MIGRATION if SMP
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_PENDING_IRQ if SMP
Expand Down
36 changes: 11 additions & 25 deletions arch/x86/include/asm/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ static inline int x2apic_enabled(void) { return 0; }
#define x2apic_supported() (0)
#endif /* !CONFIG_X86_X2APIC */

struct irq_data;

/*
* Copyright 2004 James Cleverdon, IBM.
* Subject to the GNU Public License, v.2
Expand Down Expand Up @@ -296,9 +298,9 @@ struct apic {
/* Can't be NULL on 64-bit */
unsigned long (*set_apic_id)(unsigned int id);

int (*cpu_mask_to_apicid_and)(const struct cpumask *cpumask,
const struct cpumask *andmask,
unsigned int *apicid);
int (*cpu_mask_to_apicid)(const struct cpumask *cpumask,
struct irq_data *irqdata,
unsigned int *apicid);

/* ipi */
void (*send_IPI)(int cpu, int vector);
Expand Down Expand Up @@ -540,28 +542,12 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)

#endif

static inline int
flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
const struct cpumask *andmask,
unsigned int *apicid)
{
unsigned long cpu_mask = cpumask_bits(cpumask)[0] &
cpumask_bits(andmask)[0] &
cpumask_bits(cpu_online_mask)[0] &
APIC_ALL_CPUS;

if (likely(cpu_mask)) {
*apicid = (unsigned int)cpu_mask;
return 0;
} else {
return -EINVAL;
}
}

extern int
default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
const struct cpumask *andmask,
unsigned int *apicid);
extern int flat_cpu_mask_to_apicid(const struct cpumask *cpumask,
struct irq_data *irqdata,
unsigned int *apicid);
extern int default_cpu_mask_to_apicid(const struct cpumask *cpumask,
struct irq_data *irqdata,
unsigned int *apicid);

static inline void
flat_vector_allocation_domain(int cpu, struct cpumask *retmask,
Expand Down
1 change: 0 additions & 1 deletion arch/x86/include/asm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ struct irq_desc;
#include <linux/cpumask.h>
extern int check_irq_vectors_for_cpu_disable(void);
extern void fixup_irqs(void);
extern void irq_force_complete_move(struct irq_desc *desc);
#endif

#ifdef CONFIG_HAVE_KVM
Expand Down
3 changes: 2 additions & 1 deletion arch/x86/include/asm/irq_remapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ extern struct irq_domain *
irq_remapping_get_irq_domain(struct irq_alloc_info *info);

/* Create PCI MSI/MSIx irqdomain, use @parent as the parent irqdomain. */
extern struct irq_domain *arch_create_msi_irq_domain(struct irq_domain *parent);
extern struct irq_domain *
arch_create_remap_msi_irq_domain(struct irq_domain *par, const char *n, int id);

/* Get parent irqdomain for interrupt remapping irqdomain */
static inline struct irq_domain *arch_get_ir_parent_domain(void)
Expand Down
35 changes: 22 additions & 13 deletions arch/x86/kernel/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -2201,23 +2201,32 @@ void default_init_apic_ldr(void)
apic_write(APIC_LDR, val);
}

int default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
const struct cpumask *andmask,
unsigned int *apicid)
int default_cpu_mask_to_apicid(const struct cpumask *mask,
struct irq_data *irqdata,
unsigned int *apicid)
{
unsigned int cpu;
unsigned int cpu = cpumask_first(mask);

for_each_cpu_and(cpu, cpumask, andmask) {
if (cpumask_test_cpu(cpu, cpu_online_mask))
break;
}
if (cpu >= nr_cpu_ids)
return -EINVAL;
*apicid = per_cpu(x86_cpu_to_apicid, cpu);
irq_data_update_effective_affinity(irqdata, cpumask_of(cpu));
return 0;
}

if (likely(cpu < nr_cpu_ids)) {
*apicid = per_cpu(x86_cpu_to_apicid, cpu);
return 0;
}
int flat_cpu_mask_to_apicid(const struct cpumask *mask,
struct irq_data *irqdata,
unsigned int *apicid)

return -EINVAL;
{
struct cpumask *effmsk = irq_data_get_effective_affinity_mask(irqdata);
unsigned long cpu_mask = cpumask_bits(mask)[0] & APIC_ALL_CPUS;

if (!cpu_mask)
return -EINVAL;
*apicid = (unsigned int)cpu_mask;
cpumask_bits(effmsk)[0] = cpu_mask;
return 0;
}

/*
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/apic/apic_flat_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ static struct apic apic_flat __ro_after_init = {
.get_apic_id = flat_get_apic_id,
.set_apic_id = set_apic_id,

.cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and,
.cpu_mask_to_apicid = flat_cpu_mask_to_apicid,

.send_IPI = default_send_IPI_single,
.send_IPI_mask = flat_send_IPI_mask,
Expand Down Expand Up @@ -268,7 +268,7 @@ static struct apic apic_physflat __ro_after_init = {
.get_apic_id = flat_get_apic_id,
.set_apic_id = set_apic_id,

.cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
.cpu_mask_to_apicid = default_cpu_mask_to_apicid,

.send_IPI = default_send_IPI_single_phys,
.send_IPI_mask = default_send_IPI_mask_sequence_phys,
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/apic/apic_noop.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ struct apic apic_noop __ro_after_init = {
.get_apic_id = noop_get_apic_id,
.set_apic_id = NULL,

.cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and,
.cpu_mask_to_apicid = flat_cpu_mask_to_apicid,

.send_IPI = noop_send_IPI,
.send_IPI_mask = noop_send_IPI_mask,
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kernel/apic/apic_numachip.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ static const struct apic apic_numachip1 __refconst = {
.get_apic_id = numachip1_get_apic_id,
.set_apic_id = numachip1_set_apic_id,

.cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
.cpu_mask_to_apicid = default_cpu_mask_to_apicid,

.send_IPI = numachip_send_IPI_one,
.send_IPI_mask = numachip_send_IPI_mask,
Expand Down Expand Up @@ -318,7 +318,7 @@ static const struct apic apic_numachip2 __refconst = {
.get_apic_id = numachip2_get_apic_id,
.set_apic_id = numachip2_set_apic_id,

.cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
.cpu_mask_to_apicid = default_cpu_mask_to_apicid,

.send_IPI = numachip_send_IPI_one,
.send_IPI_mask = numachip_send_IPI_mask,
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/apic/bigsmp_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ static struct apic apic_bigsmp __ro_after_init = {
.get_apic_id = bigsmp_get_apic_id,
.set_apic_id = NULL,

.cpu_mask_to_apicid_and = default_cpu_mask_to_apicid_and,
.cpu_mask_to_apicid = default_cpu_mask_to_apicid,

.send_IPI = default_send_IPI_single_phys,
.send_IPI_mask = default_send_IPI_mask_sequence_phys,
Expand Down
Loading

0 comments on commit 03ffbcd

Please sign in to comment.