Skip to content

Commit 147cc58

Browse files
committed
Merge tag 'irq-core-2022-01-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner: "Updates for the interrupt subsystem: Core: - Provide a new interface for affinity hints to provide a separation between hint and actual affinity change which has become a hidden property of the current interface - Fix up the in tree usage of the affinity hint interfaces Drivers: - No new irqchip drivers! - Fix GICv3 redistributor table reservation with RT across kexec - Fix GICv4.1 redistributor view of the VPE table across kexec - Add support for extra interrupts on spear-shirq - Make obtaining some interrupts optional for the Renesas drivers - Various cleanups and bug fixes" * tag 'irq-core-2022-01-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits) irqchip/renesas-intc-irqpin: Use platform_get_irq_optional() to get the interrupt irqchip/renesas-irqc: Use platform_get_irq_optional() to get the interrupt irqchip/gic-v4: Disable redistributors' view of the VPE table at boot time irqchip/ingenic-tcu: Use correctly sized arguments for bit field irqchip/gic-v2m: Add const to of_device_id irqchip/imx-gpcv2: Mark imx_gpcv2_instance with __ro_after_init irqchip/spear-shirq: Add support for IRQ 0..6 irqchip/gic-v3-its: Limit memreserve cpuhp state lifetime irqchip/gic-v3-its: Postpone LPI pending table freeing and memreserve irqchip/gic-v3-its: Give the percpu rdist struct its own flags field net/mlx4: Use irq_update_affinity_hint() net/mlx5: Use irq_set_affinity_and_hint() hinic: Use irq_set_affinity_and_hint() scsi: lpfc: Use irq_set_affinity() mailbox: Use irq_update_affinity_hint() ixgbe: Use irq_update_affinity_hint() be2net: Use irq_update_affinity_hint() enic: Use irq_update_affinity_hint() RDMA/irdma: Use irq_update_affinity_hint() scsi: mpt3sas: Use irq_set_affinity_and_hint() ...
2 parents 455e73a + 67d50b5 commit 147cc58

File tree

26 files changed

+228
-86
lines changed

26 files changed

+228
-86
lines changed

drivers/infiniband/hw/irdma/hw.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ static void irdma_destroy_irq(struct irdma_pci_f *rf,
550550
struct irdma_sc_dev *dev = &rf->sc_dev;
551551

552552
dev->irq_ops->irdma_dis_irq(dev, msix_vec->idx);
553-
irq_set_affinity_hint(msix_vec->irq, NULL);
553+
irq_update_affinity_hint(msix_vec->irq, NULL);
554554
free_irq(msix_vec->irq, dev_id);
555555
}
556556

@@ -1100,7 +1100,7 @@ irdma_cfg_ceq_vector(struct irdma_pci_f *rf, struct irdma_ceq *iwceq,
11001100
}
11011101
cpumask_clear(&msix_vec->mask);
11021102
cpumask_set_cpu(msix_vec->cpu_affinity, &msix_vec->mask);
1103-
irq_set_affinity_hint(msix_vec->irq, &msix_vec->mask);
1103+
irq_update_affinity_hint(msix_vec->irq, &msix_vec->mask);
11041104
if (status) {
11051105
ibdev_dbg(&rf->iwdev->ibdev, "ERR: ceq irq config fail\n");
11061106
return IRDMA_ERR_CFG;

drivers/irqchip/irq-gic-v2m.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
405405
return ret;
406406
}
407407

408-
static struct of_device_id gicv2m_device_id[] = {
408+
static const struct of_device_id gicv2m_device_id[] = {
409409
{ .compatible = "arm,gic-v2m-frame", },
410410
{},
411411
};

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

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
#define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0)
4747
#define RDIST_FLAGS_RD_TABLES_PREALLOCATED (1 << 1)
4848

49+
#define RD_LOCAL_LPI_ENABLED BIT(0)
50+
#define RD_LOCAL_PENDTABLE_PREALLOCATED BIT(1)
51+
#define RD_LOCAL_MEMRESERVE_DONE BIT(2)
52+
4953
static u32 lpi_id_bits;
5054

5155
/*
@@ -3044,7 +3048,7 @@ static void its_cpu_init_lpis(void)
30443048
phys_addr_t paddr;
30453049
u64 val, tmp;
30463050

3047-
if (gic_data_rdist()->lpi_enabled)
3051+
if (gic_data_rdist()->flags & RD_LOCAL_LPI_ENABLED)
30483052
return;
30493053

30503054
val = readl_relaxed(rbase + GICR_CTLR);
@@ -3063,15 +3067,13 @@ static void its_cpu_init_lpis(void)
30633067
paddr &= GENMASK_ULL(51, 16);
30643068

30653069
WARN_ON(!gic_check_reserved_range(paddr, LPI_PENDBASE_SZ));
3066-
its_free_pending_table(gic_data_rdist()->pend_page);
3067-
gic_data_rdist()->pend_page = NULL;
3070+
gic_data_rdist()->flags |= RD_LOCAL_PENDTABLE_PREALLOCATED;
30683071

30693072
goto out;
30703073
}
30713074

30723075
pend_page = gic_data_rdist()->pend_page;
30733076
paddr = page_to_phys(pend_page);
3074-
WARN_ON(gic_reserve_range(paddr, LPI_PENDBASE_SZ));
30753077

30763078
/* set PROPBASE */
30773079
val = (gic_rdists->prop_table_pa |
@@ -3158,10 +3160,11 @@ static void its_cpu_init_lpis(void)
31583160
/* Make sure the GIC has seen the above */
31593161
dsb(sy);
31603162
out:
3161-
gic_data_rdist()->lpi_enabled = true;
3163+
gic_data_rdist()->flags |= RD_LOCAL_LPI_ENABLED;
31623164
pr_info("GICv3: CPU%d: using %s LPI pending table @%pa\n",
31633165
smp_processor_id(),
3164-
gic_data_rdist()->pend_page ? "allocated" : "reserved",
3166+
gic_data_rdist()->flags & RD_LOCAL_PENDTABLE_PREALLOCATED ?
3167+
"reserved" : "allocated",
31653168
&paddr);
31663169
}
31673170

@@ -5138,7 +5141,7 @@ static int redist_disable_lpis(void)
51385141
*
51395142
* If running with preallocated tables, there is nothing to do.
51405143
*/
5141-
if (gic_data_rdist()->lpi_enabled ||
5144+
if ((gic_data_rdist()->flags & RD_LOCAL_LPI_ENABLED) ||
51425145
(gic_rdists->flags & RDIST_FLAGS_RD_TABLES_PREALLOCATED))
51435146
return 0;
51445147

@@ -5200,6 +5203,51 @@ int its_cpu_init(void)
52005203
return 0;
52015204
}
52025205

5206+
static void rdist_memreserve_cpuhp_cleanup_workfn(struct work_struct *work)
5207+
{
5208+
cpuhp_remove_state_nocalls(gic_rdists->cpuhp_memreserve_state);
5209+
gic_rdists->cpuhp_memreserve_state = CPUHP_INVALID;
5210+
}
5211+
5212+
static DECLARE_WORK(rdist_memreserve_cpuhp_cleanup_work,
5213+
rdist_memreserve_cpuhp_cleanup_workfn);
5214+
5215+
static int its_cpu_memreserve_lpi(unsigned int cpu)
5216+
{
5217+
struct page *pend_page;
5218+
int ret = 0;
5219+
5220+
/* This gets to run exactly once per CPU */
5221+
if (gic_data_rdist()->flags & RD_LOCAL_MEMRESERVE_DONE)
5222+
return 0;
5223+
5224+
pend_page = gic_data_rdist()->pend_page;
5225+
if (WARN_ON(!pend_page)) {
5226+
ret = -ENOMEM;
5227+
goto out;
5228+
}
5229+
/*
5230+
* If the pending table was pre-programmed, free the memory we
5231+
* preemptively allocated. Otherwise, reserve that memory for
5232+
* later kexecs.
5233+
*/
5234+
if (gic_data_rdist()->flags & RD_LOCAL_PENDTABLE_PREALLOCATED) {
5235+
its_free_pending_table(pend_page);
5236+
gic_data_rdist()->pend_page = NULL;
5237+
} else {
5238+
phys_addr_t paddr = page_to_phys(pend_page);
5239+
WARN_ON(gic_reserve_range(paddr, LPI_PENDBASE_SZ));
5240+
}
5241+
5242+
out:
5243+
/* Last CPU being brought up gets to issue the cleanup */
5244+
if (cpumask_equal(&cpus_booted_once_mask, cpu_possible_mask))
5245+
schedule_work(&rdist_memreserve_cpuhp_cleanup_work);
5246+
5247+
gic_data_rdist()->flags |= RD_LOCAL_MEMRESERVE_DONE;
5248+
return ret;
5249+
}
5250+
52035251
static const struct of_device_id its_device_id[] = {
52045252
{ .compatible = "arm,gic-v3-its", },
52055253
{},
@@ -5383,6 +5431,26 @@ static void __init its_acpi_probe(void)
53835431
static void __init its_acpi_probe(void) { }
53845432
#endif
53855433

5434+
int __init its_lpi_memreserve_init(void)
5435+
{
5436+
int state;
5437+
5438+
if (!efi_enabled(EFI_CONFIG_TABLES))
5439+
return 0;
5440+
5441+
gic_rdists->cpuhp_memreserve_state = CPUHP_INVALID;
5442+
state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
5443+
"irqchip/arm/gicv3/memreserve:online",
5444+
its_cpu_memreserve_lpi,
5445+
NULL);
5446+
if (state < 0)
5447+
return state;
5448+
5449+
gic_rdists->cpuhp_memreserve_state = state;
5450+
5451+
return 0;
5452+
}
5453+
53865454
int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
53875455
struct irq_domain *parent_domain)
53885456
{

drivers/irqchip/irq-gic-v3.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,22 @@ static int __gic_update_rdist_properties(struct redist_region *region,
920920
{
921921
u64 typer = gic_read_typer(ptr + GICR_TYPER);
922922

923+
/* Boot-time cleanip */
924+
if ((typer & GICR_TYPER_VLPIS) && (typer & GICR_TYPER_RVPEID)) {
925+
u64 val;
926+
927+
/* Deactivate any present vPE */
928+
val = gicr_read_vpendbaser(ptr + SZ_128K + GICR_VPENDBASER);
929+
if (val & GICR_VPENDBASER_Valid)
930+
gicr_write_vpendbaser(GICR_VPENDBASER_PendingLast,
931+
ptr + SZ_128K + GICR_VPENDBASER);
932+
933+
/* Mark the VPE table as invalid */
934+
val = gicr_read_vpropbaser(ptr + SZ_128K + GICR_VPROPBASER);
935+
val &= ~GICR_VPROPBASER_4_1_VALID;
936+
gicr_write_vpropbaser(val, ptr + SZ_128K + GICR_VPROPBASER);
937+
}
938+
923939
gic_data.rdists.has_vlpis &= !!(typer & GICR_TYPER_VLPIS);
924940

925941
/* RVPEID implies some form of DirectLPI, no matter what the doc says... :-/ */
@@ -1802,6 +1818,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
18021818
if (gic_dist_supports_lpis()) {
18031819
its_init(handle, &gic_data.rdists, gic_data.domain);
18041820
its_cpu_init();
1821+
its_lpi_memreserve_init();
18051822
} else {
18061823
if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
18071824
gicv2m_init(handle, gic_data.domain);

drivers/irqchip/irq-imx-gpcv2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct gpcv2_irqchip_data {
2626
u32 cpu2wakeup;
2727
};
2828

29-
static struct gpcv2_irqchip_data *imx_gpcv2_instance;
29+
static struct gpcv2_irqchip_data *imx_gpcv2_instance __ro_after_init;
3030

3131
static void __iomem *gpcv2_idx_to_reg(struct gpcv2_irqchip_data *cd, int i)
3232
{

drivers/irqchip/irq-ingenic-tcu.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ static void ingenic_tcu_intc_cascade(struct irq_desc *desc)
2828
struct irq_chip_generic *gc = irq_get_domain_generic_chip(domain, 0);
2929
struct regmap *map = gc->private;
3030
uint32_t irq_reg, irq_mask;
31+
unsigned long bits;
3132
unsigned int i;
3233

3334
regmap_read(map, TCU_REG_TFR, &irq_reg);
@@ -36,8 +37,9 @@ static void ingenic_tcu_intc_cascade(struct irq_desc *desc)
3637
chained_irq_enter(irq_chip, desc);
3738

3839
irq_reg &= ~irq_mask;
40+
bits = irq_reg;
3941

40-
for_each_set_bit(i, (unsigned long *)&irq_reg, 32)
42+
for_each_set_bit(i, &bits, 32)
4143
generic_handle_domain_irq(domain, i);
4244

4345
chained_irq_exit(irq_chip, desc);

drivers/irqchip/irq-renesas-intc-irqpin.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,6 @@ static int intc_irqpin_probe(struct platform_device *pdev)
375375
struct intc_irqpin_priv *p;
376376
struct intc_irqpin_iomem *i;
377377
struct resource *io[INTC_IRQPIN_REG_NR];
378-
struct resource *irq;
379378
struct irq_chip *irq_chip;
380379
void (*enable_fn)(struct irq_data *d);
381380
void (*disable_fn)(struct irq_data *d);
@@ -418,12 +417,14 @@ static int intc_irqpin_probe(struct platform_device *pdev)
418417

419418
/* allow any number of IRQs between 1 and INTC_IRQPIN_MAX */
420419
for (k = 0; k < INTC_IRQPIN_MAX; k++) {
421-
irq = platform_get_resource(pdev, IORESOURCE_IRQ, k);
422-
if (!irq)
420+
ret = platform_get_irq_optional(pdev, k);
421+
if (ret == -ENXIO)
423422
break;
423+
if (ret < 0)
424+
goto err0;
424425

425426
p->irq[k].p = p;
426-
p->irq[k].requested_irq = irq->start;
427+
p->irq[k].requested_irq = ret;
427428
}
428429

429430
nirqs = k;

drivers/irqchip/irq-renesas-irqc.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ static int irqc_probe(struct platform_device *pdev)
126126
struct device *dev = &pdev->dev;
127127
const char *name = dev_name(dev);
128128
struct irqc_priv *p;
129-
struct resource *irq;
130129
int ret;
131130
int k;
132131

@@ -142,13 +141,15 @@ static int irqc_probe(struct platform_device *pdev)
142141

143142
/* allow any number of IRQs between 1 and IRQC_IRQ_MAX */
144143
for (k = 0; k < IRQC_IRQ_MAX; k++) {
145-
irq = platform_get_resource(pdev, IORESOURCE_IRQ, k);
146-
if (!irq)
144+
ret = platform_get_irq_optional(pdev, k);
145+
if (ret == -ENXIO)
147146
break;
147+
if (ret < 0)
148+
goto err_runtime_pm_disable;
148149

149150
p->irq[k].p = p;
150151
p->irq[k].hw_irq = k;
151-
p->irq[k].requested_irq = irq->start;
152+
p->irq[k].requested_irq = ret;
152153
}
153154

154155
p->number_of_irqs = k;

drivers/irqchip/spear-shirq.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ static struct spear_shirq spear320_shirq_ras3 = {
149149
.offset = 0,
150150
.nr_irqs = 7,
151151
.mask = ((0x1 << 7) - 1) << 0,
152+
.irq_chip = &dummy_irq_chip,
153+
.status_reg = SPEAR320_INT_STS_MASK_REG,
152154
};
153155

154156
static struct spear_shirq spear320_shirq_ras1 = {

drivers/mailbox/bcm-flexrm-mailbox.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,7 @@ static int flexrm_startup(struct mbox_chan *chan)
12981298
val = (num_online_cpus() < val) ? val / num_online_cpus() : 1;
12991299
cpumask_set_cpu((ring->num / val) % num_online_cpus(),
13001300
&ring->irq_aff_hint);
1301-
ret = irq_set_affinity_hint(ring->irq, &ring->irq_aff_hint);
1301+
ret = irq_update_affinity_hint(ring->irq, &ring->irq_aff_hint);
13021302
if (ret) {
13031303
dev_err(ring->mbox->dev,
13041304
"failed to set IRQ affinity hint for ring%d\n",
@@ -1425,7 +1425,7 @@ static void flexrm_shutdown(struct mbox_chan *chan)
14251425

14261426
/* Release IRQ */
14271427
if (ring->irq_requested) {
1428-
irq_set_affinity_hint(ring->irq, NULL);
1428+
irq_update_affinity_hint(ring->irq, NULL);
14291429
free_irq(ring->irq, ring);
14301430
ring->irq_requested = false;
14311431
}

0 commit comments

Comments
 (0)