Skip to content

Commit ede4090

Browse files
committed
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner: "This update delivers: - Yet another interrupt chip diver (LPC32xx) - Core functions to handle partitioned per-cpu interrupts - Enhancements to the IPI core - Proper handling of irq type configuration - A large set of ARM GIC enhancements - The usual pile of small fixes, cleanups and enhancements" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (31 commits) irqchip/bcm2836: Use a more generic memory barrier call irqchip/bcm2836: Fix compiler warning on 64-bit build irqchip/bcm2836: Drop smp_set_ops on arm64 builds irqchip/gic: Add helper functions for GIC setup and teardown irqchip/gic: Store GIC configuration parameters irqchip/gic: Pass GIC pointer to save/restore functions irqchip/gic: Return an error if GIC initialisation fails irqchip/gic: Remove static irq_chip definition for eoimode1 irqchip/gic: Don't initialise chip if mapping IO space fails irqchip/gic: WARN if setting the interrupt type for a PPI fails irqchip/gic: Don't unnecessarily write the IRQ configuration irqchip: Mask the non-type/sense bits when translating an IRQ genirq: Ensure IRQ descriptor is valid when setting-up the IRQ irqchip/gic-v3: Configure all interrupts as non-secure Group-1 irqchip/gic-v2m: Add workaround for Broadcom NS2 GICv2m erratum irqchip/irq-alpine-msi: Don't use <asm-generic/msi.h> irqchip/mbigen: Checking for IS_ERR() instead of NULL irqchip/gic-v3: Remove inexistant register definition irqchip/gicv3-its: Don't allow devices whose ID is outside range irqchip: Add LPC32xx interrupt controller driver ...
2 parents 91e8d0c + 0097852 commit ede4090

28 files changed

+1438
-171
lines changed

Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Main node required properties:
1111
- interrupt-controller : Identifies the node as an interrupt controller
1212
- #interrupt-cells : Specifies the number of cells needed to encode an
1313
interrupt source. Must be a single cell with a value of at least 3.
14+
If the system requires describing PPI affinity, then the value must
15+
be at least 4.
1416

1517
The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI
1618
interrupts. Other values are reserved for future use.
@@ -24,7 +26,14 @@ Main node required properties:
2426
1 = edge triggered
2527
4 = level triggered
2628

27-
Cells 4 and beyond are reserved for future use and must have a value
29+
The 4th cell is a phandle to a node describing a set of CPUs this
30+
interrupt is affine to. The interrupt must be a PPI, and the node
31+
pointed must be a subnode of the "ppi-partitions" subnode. For
32+
interrupt types other than PPI or PPIs that are not partitionned,
33+
this cell must be zero. See the "ppi-partitions" node description
34+
below.
35+
36+
Cells 5 and beyond are reserved for future use and must have a value
2837
of 0 if present.
2938

3039
- reg : Specifies base physical address(s) and size of the GIC
@@ -50,6 +59,11 @@ Optional
5059

5160
Sub-nodes:
5261

62+
PPI affinity can be expressed as a single "ppi-partitions" node,
63+
containing a set of sub-nodes, each with the following property:
64+
- affinity: Should be a list of phandles to CPU nodes (as described in
65+
Documentation/devicetree/bindings/arm/cpus.txt).
66+
5367
GICv3 has one or more Interrupt Translation Services (ITS) that are
5468
used to route Message Signalled Interrupts (MSI) to the CPUs.
5569

@@ -91,7 +105,7 @@ Examples:
91105

92106
gic: interrupt-controller@2c010000 {
93107
compatible = "arm,gic-v3";
94-
#interrupt-cells = <3>;
108+
#interrupt-cells = <4>;
95109
#address-cells = <2>;
96110
#size-cells = <2>;
97111
ranges;
@@ -119,4 +133,20 @@ Examples:
119133
#msi-cells = <1>;
120134
reg = <0x0 0x2c400000 0 0x200000>;
121135
};
136+
137+
ppi-partitions {
138+
part0: interrupt-partition-0 {
139+
affinity = <&cpu0 &cpu2>;
140+
};
141+
142+
part1: interrupt-partition-1 {
143+
affinity = <&cpu1 &cpu3>;
144+
};
145+
};
146+
};
147+
148+
149+
device@0 {
150+
reg = <0 0 0 4>;
151+
interrupts = <1 1 4 &part0>;
122152
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
* Freescale Layerscape SCFG PCIe MSI controller
2+
3+
Required properties:
4+
5+
- compatible: should be "fsl,<soc-name>-msi" to identify
6+
Layerscape PCIe MSI controller block such as:
7+
"fsl,1s1021a-msi"
8+
"fsl,1s1043a-msi"
9+
- msi-controller: indicates that this is a PCIe MSI controller node
10+
- reg: physical base address of the controller and length of memory mapped.
11+
- interrupts: an interrupt to the parent interrupt controller.
12+
13+
Optional properties:
14+
- interrupt-parent: the phandle to the parent interrupt controller.
15+
16+
This interrupt controller hardware is a second level interrupt controller that
17+
is hooked to a parent interrupt controller: e.g: ARM GIC for ARM-based
18+
platforms. If interrupt-parent is not provided, the default parent interrupt
19+
controller will be used.
20+
Each PCIe node needs to have property msi-parent that points to
21+
MSI controller node
22+
23+
Examples:
24+
25+
msi1: msi-controller@1571000 {
26+
compatible = "fsl,1s1043a-msi";
27+
reg = <0x0 0x1571000 0x0 0x8>,
28+
msi-controller;
29+
interrupts = <0 116 0x4>;
30+
};

arch/arm/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,8 @@ config ARCH_LPC32XX
531531
select COMMON_CLK
532532
select CPU_ARM926T
533533
select GENERIC_CLOCKEVENTS
534+
select MULTI_IRQ_HANDLER
535+
select SPARSE_IRQ
534536
select USE_OF
535537
help
536538
Support for the NXP LPC32XX family of processors

arch/arm/mach-lpc32xx/phy3250.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ static const char *const lpc32xx_dt_compat[] __initconst = {
206206
DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)")
207207
.atag_offset = 0x100,
208208
.map_io = lpc32xx_map_io,
209-
.init_irq = lpc32xx_init_irq,
210209
.init_machine = lpc3250_machine_init,
211210
.dt_compat = lpc32xx_dt_compat,
212211
MACHINE_END

drivers/irqchip/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ config ARM_GIC_V3
2727
select IRQ_DOMAIN
2828
select MULTI_IRQ_HANDLER
2929
select IRQ_DOMAIN_HIERARCHY
30+
select PARTITION_PERCPU
3031

3132
config ARM_GIC_V3_ITS
3233
bool
@@ -244,3 +245,11 @@ config IRQ_MXS
244245
config MVEBU_ODMI
245246
bool
246247
select GENERIC_MSI_IRQ_DOMAIN
248+
249+
config LS_SCFG_MSI
250+
def_bool y if SOC_LS1021A || ARCH_LAYERSCAPE
251+
depends on PCI && PCI_MSI
252+
select PCI_MSI_IRQ_DOMAIN
253+
254+
config PARTITION_PERCPU
255+
bool

drivers/irqchip/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o
77
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2836.o
88
obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o
99
obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o
10+
obj-$(CONFIG_ARCH_LPC32XX) += irq-lpc32xx.o
1011
obj-$(CONFIG_ARCH_MMP) += irq-mmp.o
1112
obj-$(CONFIG_IRQ_MXS) += irq-mxs.o
1213
obj-$(CONFIG_ARCH_TEGRA) += irq-tegra.o
@@ -27,6 +28,7 @@ obj-$(CONFIG_REALVIEW_DT) += irq-gic-realview.o
2728
obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o
2829
obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o
2930
obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o
31+
obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o
3032
obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o
3133
obj-$(CONFIG_ARM_NVIC) += irq-nvic.o
3234
obj-$(CONFIG_ARM_VIC) += irq-vic.o
@@ -65,3 +67,4 @@ obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o
6567
obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o
6668
obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o
6769
obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o
70+
obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o

drivers/irqchip/irq-alpine-msi.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <linux/slab.h>
2424

2525
#include <asm/irq.h>
26-
#include <asm-generic/msi.h>
26+
#include <asm/msi.h>
2727

2828
/* MSIX message address format: local GIC target */
2929
#define ALPINE_MSIX_SPI_TARGET_CLUSTER0 BIT(16)

drivers/irqchip/irq-bcm2836.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ static void bcm2836_arm_irqchip_send_ipi(const struct cpumask *mask,
195195
* Ensure that stores to normal memory are visible to the
196196
* other CPUs before issuing the IPI.
197197
*/
198-
dsb();
198+
smp_wmb();
199199

200200
for_each_cpu(cpu, mask) {
201201
writel(1 << ipi, mailbox0_base + 16 * cpu);
@@ -223,6 +223,7 @@ static struct notifier_block bcm2836_arm_irqchip_cpu_notifier = {
223223
.priority = 100,
224224
};
225225

226+
#ifdef CONFIG_ARM
226227
int __init bcm2836_smp_boot_secondary(unsigned int cpu,
227228
struct task_struct *idle)
228229
{
@@ -238,7 +239,7 @@ int __init bcm2836_smp_boot_secondary(unsigned int cpu,
238239
static const struct smp_operations bcm2836_smp_ops __initconst = {
239240
.smp_boot_secondary = bcm2836_smp_boot_secondary,
240241
};
241-
242+
#endif
242243
#endif
243244

244245
static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
@@ -252,12 +253,15 @@ bcm2836_arm_irqchip_smp_init(void)
252253
/* Unmask IPIs to the boot CPU. */
253254
bcm2836_arm_irqchip_cpu_notify(&bcm2836_arm_irqchip_cpu_notifier,
254255
CPU_STARTING,
255-
(void *)smp_processor_id());
256+
(void *)(uintptr_t)smp_processor_id());
256257
register_cpu_notifier(&bcm2836_arm_irqchip_cpu_notifier);
257258

258259
set_smp_cross_call(bcm2836_arm_irqchip_send_ipi);
260+
261+
#ifdef CONFIG_ARM
259262
smp_set_ops(&bcm2836_smp_ops);
260263
#endif
264+
#endif
261265
}
262266

263267
/*

drivers/irqchip/irq-crossbar.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ static int crossbar_domain_translate(struct irq_domain *d,
183183
return -EINVAL;
184184

185185
*hwirq = fwspec->param[1];
186-
*type = fwspec->param[2];
186+
*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;
187187
return 0;
188188
}
189189

drivers/irqchip/irq-gic-common.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,26 @@ int gic_configure_irq(unsigned int irq, unsigned int type,
5050
else if (type & IRQ_TYPE_EDGE_BOTH)
5151
val |= confmask;
5252

53+
/* If the current configuration is the same, then we are done */
54+
if (val == oldval)
55+
return 0;
56+
5357
/*
5458
* Write back the new configuration, and possibly re-enable
55-
* the interrupt. If we tried to write a new configuration and failed,
56-
* return an error.
59+
* the interrupt. If we fail to write a new configuration for
60+
* an SPI then WARN and return an error. If we fail to write the
61+
* configuration for a PPI this is most likely because the GIC
62+
* does not allow us to set the configuration or we are in a
63+
* non-secure mode, and hence it may not be catastrophic.
5764
*/
5865
writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
59-
if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val && val != oldval)
60-
ret = -EINVAL;
66+
if (readl_relaxed(base + GIC_DIST_CONFIG + confoff) != val) {
67+
if (WARN_ON(irq >= 32))
68+
ret = -EINVAL;
69+
else
70+
pr_warn("GIC: PPI%d is secure or misconfigured\n",
71+
irq - 16);
72+
}
6173

6274
if (sync_access)
6375
sync_access();

drivers/irqchip/irq-gic-v2m.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
/* APM X-Gene with GICv2m MSI_IIDR register value */
5050
#define XGENE_GICV2M_MSI_IIDR 0x06000170
5151

52+
/* Broadcom NS2 GICv2m MSI_IIDR register value */
53+
#define BCM_NS2_GICV2M_MSI_IIDR 0x0000013f
54+
5255
/* List of flags for specific v2m implementation */
5356
#define GICV2M_NEEDS_SPI_OFFSET 0x00000001
5457

@@ -62,6 +65,7 @@ struct v2m_data {
6265
void __iomem *base; /* GICv2m virt address */
6366
u32 spi_start; /* The SPI number that MSIs start */
6467
u32 nr_spis; /* The number of SPIs for MSIs */
68+
u32 spi_offset; /* offset to be subtracted from SPI number */
6569
unsigned long *bm; /* MSI vector bitmap */
6670
u32 flags; /* v2m flags for specific implementation */
6771
};
@@ -102,7 +106,7 @@ static void gicv2m_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
102106
msg->data = data->hwirq;
103107

104108
if (v2m->flags & GICV2M_NEEDS_SPI_OFFSET)
105-
msg->data -= v2m->spi_start;
109+
msg->data -= v2m->spi_offset;
106110
}
107111

108112
static struct irq_chip gicv2m_irq_chip = {
@@ -340,9 +344,20 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
340344
* different from the standard GICv2m implementation where
341345
* the MSI data is the absolute value within the range from
342346
* spi_start to (spi_start + num_spis).
347+
*
348+
* Broadom NS2 GICv2m implementation has an erratum where the MSI data
349+
* is 'spi_number - 32'
343350
*/
344-
if (readl_relaxed(v2m->base + V2M_MSI_IIDR) == XGENE_GICV2M_MSI_IIDR)
351+
switch (readl_relaxed(v2m->base + V2M_MSI_IIDR)) {
352+
case XGENE_GICV2M_MSI_IIDR:
353+
v2m->flags |= GICV2M_NEEDS_SPI_OFFSET;
354+
v2m->spi_offset = v2m->spi_start;
355+
break;
356+
case BCM_NS2_GICV2M_MSI_IIDR:
345357
v2m->flags |= GICV2M_NEEDS_SPI_OFFSET;
358+
v2m->spi_offset = 32;
359+
break;
360+
}
346361

347362
v2m->bm = kzalloc(sizeof(long) * BITS_TO_LONGS(v2m->nr_spis),
348363
GFP_KERNEL);

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ struct its_collection {
5454
u16 col_id;
5555
};
5656

57+
/*
58+
* The ITS_BASER structure - contains memory information and cached
59+
* value of BASER register configuration.
60+
*/
61+
struct its_baser {
62+
void *base;
63+
u64 val;
64+
u32 order;
65+
};
66+
5767
/*
5868
* The ITS structure - contains most of the infrastructure, with the
5969
* top-level MSI domain, the command queue, the collections, and the
@@ -66,14 +76,12 @@ struct its_node {
6676
unsigned long phys_base;
6777
struct its_cmd_block *cmd_base;
6878
struct its_cmd_block *cmd_write;
69-
struct {
70-
void *base;
71-
u32 order;
72-
} tables[GITS_BASER_NR_REGS];
79+
struct its_baser tables[GITS_BASER_NR_REGS];
7380
struct its_collection *collections;
7481
struct list_head its_device_list;
7582
u64 flags;
7683
u32 ite_size;
84+
u32 device_ids;
7785
};
7886

7987
#define ITS_ITT_ALIGN SZ_256
@@ -838,6 +846,8 @@ static int its_alloc_tables(const char *node_name, struct its_node *its)
838846
ids = GITS_TYPER_DEVBITS(typer);
839847
}
840848

849+
its->device_ids = ids;
850+
841851
for (i = 0; i < GITS_BASER_NR_REGS; i++) {
842852
u64 val = readq_relaxed(its->base + GITS_BASER + i * 8);
843853
u64 type = GITS_BASER_TYPE(val);
@@ -913,6 +923,7 @@ static int its_alloc_tables(const char *node_name, struct its_node *its)
913923
}
914924

915925
val |= alloc_pages - 1;
926+
its->tables[i].val = val;
916927

917928
writeq_relaxed(val, its->base + GITS_BASER + i * 8);
918929
tmp = readq_relaxed(its->base + GITS_BASER + i * 8);
@@ -1138,9 +1149,22 @@ static struct its_device *its_find_device(struct its_node *its, u32 dev_id)
11381149
return its_dev;
11391150
}
11401151

1152+
static struct its_baser *its_get_baser(struct its_node *its, u32 type)
1153+
{
1154+
int i;
1155+
1156+
for (i = 0; i < GITS_BASER_NR_REGS; i++) {
1157+
if (GITS_BASER_TYPE(its->tables[i].val) == type)
1158+
return &its->tables[i];
1159+
}
1160+
1161+
return NULL;
1162+
}
1163+
11411164
static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
11421165
int nvecs)
11431166
{
1167+
struct its_baser *baser;
11441168
struct its_device *dev;
11451169
unsigned long *lpi_map;
11461170
unsigned long flags;
@@ -1151,6 +1175,16 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
11511175
int nr_ites;
11521176
int sz;
11531177

1178+
baser = its_get_baser(its, GITS_BASER_TYPE_DEVICE);
1179+
1180+
/* Don't allow 'dev_id' that exceeds single, flat table limit */
1181+
if (baser) {
1182+
if (dev_id >= (PAGE_ORDER_TO_SIZE(baser->order) /
1183+
GITS_BASER_ENTRY_SIZE(baser->val)))
1184+
return NULL;
1185+
} else if (ilog2(dev_id) >= its->device_ids)
1186+
return NULL;
1187+
11541188
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
11551189
/*
11561190
* At least one bit of EventID is being used, hence a minimum

0 commit comments

Comments
 (0)