Skip to content

Commit 0097852

Browse files
committed
Merge tag 'irqchip-for-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/core
Pull irqchip updates for Linux 4.7 from Marc Zyngier - Layerscape SCFG MSI controller support - LPC32xx interrupt controller support - RPi irqchip support on arm64 - GICv2 cleanup - GICv2 and GICv3 bug fixes
2 parents 9d9b7ee + a1dcbd1 commit 0097852

File tree

18 files changed

+826
-136
lines changed

18 files changed

+826
-136
lines changed
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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,5 +246,10 @@ config MVEBU_ODMI
246246
bool
247247
select GENERIC_MSI_IRQ_DOMAIN
248248

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+
249254
config PARTITION_PERCPU
250255
bool

drivers/irqchip/Makefile

Lines changed: 2 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
@@ -66,3 +67,4 @@ obj-$(CONFIG_INGENIC_IRQ) += irq-ingenic.o
6667
obj-$(CONFIG_IMX_GPCV2) += irq-imx-gpcv2.o
6768
obj-$(CONFIG_PIC32_EVIC) += irq-pic32-evic.o
6869
obj-$(CONFIG_MVEBU_ODMI) += irq-mvebu-odmi.o
70+
obj-$(CONFIG_LS_SCFG_MSI) += irq-ls-scfg-msi.o

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

drivers/irqchip/irq-gic-v3.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,13 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
367367
if (static_key_true(&supports_deactivate))
368368
gic_write_dir(irqnr);
369369
#ifdef CONFIG_SMP
370+
/*
371+
* Unlike GICv2, we don't need an smp_rmb() here.
372+
* The control dependency from gic_read_iar to
373+
* the ISB in gic_write_eoir is enough to ensure
374+
* that any shared data read by handle_IPI will
375+
* be read after the ACK.
376+
*/
370377
handle_IPI(irqnr, regs);
371378
#else
372379
WARN_ONCE(true, "Unexpected SGI received!\n");
@@ -386,6 +393,15 @@ static void __init gic_dist_init(void)
386393
writel_relaxed(0, base + GICD_CTLR);
387394
gic_dist_wait_for_rwp();
388395

396+
/*
397+
* Configure SPIs as non-secure Group-1. This will only matter
398+
* if the GIC only has a single security state. This will not
399+
* do the right thing if the kernel is running in secure mode,
400+
* but that's not the intended use case anyway.
401+
*/
402+
for (i = 32; i < gic_data.irq_nr; i += 32)
403+
writel_relaxed(~0, base + GICD_IGROUPR + i / 8);
404+
389405
gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp);
390406

391407
/* Enable distributor with ARE, Group1 */
@@ -503,6 +519,9 @@ static void gic_cpu_init(void)
503519

504520
rbase = gic_data_rdist_sgi_base();
505521

522+
/* Configure SGIs/PPIs as non-secure Group-1 */
523+
writel_relaxed(~0, rbase + GICR_IGROUPR0);
524+
506525
gic_cpu_config(rbase, gic_redist_wait_for_rwp);
507526

508527
/* Give LPIs a spin */

0 commit comments

Comments
 (0)