summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-alpine-msi.c3
-rw-r--r--drivers/irqchip/irq-gic-v2m.c4
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c81
-rw-r--r--drivers/irqchip/irq-gic-v3.c5
-rw-r--r--drivers/irqchip/irq-imgpdc.c2
-rw-r--r--drivers/irqchip/irq-ls-scfg-msi.c10
-rw-r--r--drivers/irqchip/irq-mvebu-gicp.c8
-rw-r--r--drivers/irqchip/irq-partition-percpu.c2
-rw-r--r--drivers/irqchip/irq-s3c24xx.c2
9 files changed, 81 insertions, 36 deletions
diff --git a/drivers/irqchip/irq-alpine-msi.c b/drivers/irqchip/irq-alpine-msi.c
index 63d980995d17..23a3b877f7f1 100644
--- a/drivers/irqchip/irq-alpine-msi.c
+++ b/drivers/irqchip/irq-alpine-msi.c
@@ -268,7 +268,8 @@ static int alpine_msix_init(struct device_node *node,
goto err_priv;
}
- priv->msi_map = kzalloc(sizeof(*priv->msi_map) * BITS_TO_LONGS(priv->num_spis),
+ priv->msi_map = kcalloc(BITS_TO_LONGS(priv->num_spis),
+ sizeof(*priv->msi_map),
GFP_KERNEL);
if (!priv->msi_map) {
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c
index 1ff38aff9f29..f5fe0100f9ff 100644
--- a/drivers/irqchip/irq-gic-v2m.c
+++ b/drivers/irqchip/irq-gic-v2m.c
@@ -199,7 +199,7 @@ static int gicv2m_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
fail:
irq_domain_free_irqs_parent(domain, virq, nr_irqs);
- gicv2m_unalloc_msi(v2m, hwirq, get_count_order(nr_irqs));
+ gicv2m_unalloc_msi(v2m, hwirq, nr_irqs);
return err;
}
@@ -361,7 +361,7 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode,
break;
}
- v2m->bm = kzalloc(sizeof(long) * BITS_TO_LONGS(v2m->nr_spis),
+ v2m->bm = kcalloc(BITS_TO_LONGS(v2m->nr_spis), sizeof(long),
GFP_KERNEL);
if (!v2m->bm) {
ret = -ENOMEM;
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 5416f2b2ac21..d7842d312d3e 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -182,6 +182,22 @@ static struct its_collection *dev_event_to_col(struct its_device *its_dev,
return its->collections + its_dev->event_map.col_map[event];
}
+static struct its_collection *valid_col(struct its_collection *col)
+{
+ if (WARN_ON_ONCE(col->target_address & GENMASK_ULL(0, 15)))
+ return NULL;
+
+ return col;
+}
+
+static struct its_vpe *valid_vpe(struct its_node *its, struct its_vpe *vpe)
+{
+ if (valid_col(its->collections + vpe->col_idx))
+ return vpe;
+
+ return NULL;
+}
+
/*
* ITS command descriptors - parameters to be encoded in a command
* block.
@@ -439,7 +455,7 @@ static struct its_collection *its_build_mapti_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return col;
+ return valid_col(col);
}
static struct its_collection *its_build_movi_cmd(struct its_node *its,
@@ -458,7 +474,7 @@ static struct its_collection *its_build_movi_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return col;
+ return valid_col(col);
}
static struct its_collection *its_build_discard_cmd(struct its_node *its,
@@ -476,7 +492,7 @@ static struct its_collection *its_build_discard_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return col;
+ return valid_col(col);
}
static struct its_collection *its_build_inv_cmd(struct its_node *its,
@@ -494,7 +510,7 @@ static struct its_collection *its_build_inv_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return col;
+ return valid_col(col);
}
static struct its_collection *its_build_int_cmd(struct its_node *its,
@@ -512,7 +528,7 @@ static struct its_collection *its_build_int_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return col;
+ return valid_col(col);
}
static struct its_collection *its_build_clear_cmd(struct its_node *its,
@@ -530,7 +546,7 @@ static struct its_collection *its_build_clear_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return col;
+ return valid_col(col);
}
static struct its_collection *its_build_invall_cmd(struct its_node *its,
@@ -554,7 +570,7 @@ static struct its_vpe *its_build_vinvall_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return desc->its_vinvall_cmd.vpe;
+ return valid_vpe(its, desc->its_vinvall_cmd.vpe);
}
static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
@@ -576,7 +592,7 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return desc->its_vmapp_cmd.vpe;
+ return valid_vpe(its, desc->its_vmapp_cmd.vpe);
}
static struct its_vpe *its_build_vmapti_cmd(struct its_node *its,
@@ -599,7 +615,7 @@ static struct its_vpe *its_build_vmapti_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return desc->its_vmapti_cmd.vpe;
+ return valid_vpe(its, desc->its_vmapti_cmd.vpe);
}
static struct its_vpe *its_build_vmovi_cmd(struct its_node *its,
@@ -622,7 +638,7 @@ static struct its_vpe *its_build_vmovi_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return desc->its_vmovi_cmd.vpe;
+ return valid_vpe(its, desc->its_vmovi_cmd.vpe);
}
static struct its_vpe *its_build_vmovp_cmd(struct its_node *its,
@@ -640,7 +656,7 @@ static struct its_vpe *its_build_vmovp_cmd(struct its_node *its,
its_fixup_cmd(cmd);
- return desc->its_vmovp_cmd.vpe;
+ return valid_vpe(its, desc->its_vmovp_cmd.vpe);
}
static u64 its_cmd_ptr_to_offset(struct its_node *its,
@@ -1239,7 +1255,7 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
if (!its_dev->event_map.vm) {
struct its_vlpi_map *maps;
- maps = kzalloc(sizeof(*maps) * its_dev->event_map.nr_lpis,
+ maps = kcalloc(its_dev->event_map.nr_lpis, sizeof(*maps),
GFP_KERNEL);
if (!maps) {
ret = -ENOMEM;
@@ -1437,7 +1453,7 @@ static int __init its_lpi_init(u32 id_bits)
{
lpi_chunks = its_lpi_to_chunk(1UL << id_bits);
- lpi_bitmap = kzalloc(BITS_TO_LONGS(lpi_chunks) * sizeof(long),
+ lpi_bitmap = kcalloc(BITS_TO_LONGS(lpi_chunks), sizeof(long),
GFP_KERNEL);
if (!lpi_bitmap) {
lpi_chunks = 0;
@@ -1471,7 +1487,8 @@ static unsigned long *its_lpi_alloc_chunks(int nr_irqs, int *base, int *nr_ids)
if (!nr_chunks)
goto out;
- bitmap = kzalloc(BITS_TO_LONGS(nr_chunks * IRQS_PER_CHUNK) * sizeof (long),
+ bitmap = kcalloc(BITS_TO_LONGS(nr_chunks * IRQS_PER_CHUNK),
+ sizeof(long),
GFP_ATOMIC);
if (!bitmap)
goto out;
@@ -1823,11 +1840,16 @@ static int its_alloc_tables(struct its_node *its)
static int its_alloc_collections(struct its_node *its)
{
- its->collections = kzalloc(nr_cpu_ids * sizeof(*its->collections),
+ int i;
+
+ its->collections = kcalloc(nr_cpu_ids, sizeof(*its->collections),
GFP_KERNEL);
if (!its->collections)
return -ENOMEM;
+ for (i = 0; i < nr_cpu_ids; i++)
+ its->collections[i].target_address = ~0ULL;
+
return 0;
}
@@ -2124,10 +2146,10 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id,
if (alloc_lpis) {
lpi_map = its_lpi_alloc_chunks(nvecs, &lpi_base, &nr_lpis);
if (lpi_map)
- col_map = kzalloc(sizeof(*col_map) * nr_lpis,
+ col_map = kcalloc(nr_lpis, sizeof(*col_map),
GFP_KERNEL);
} else {
- col_map = kzalloc(sizeof(*col_map) * nr_ites, GFP_KERNEL);
+ col_map = kcalloc(nr_ites, sizeof(*col_map), GFP_KERNEL);
nr_lpis = 0;
lpi_base = 0;
}
@@ -2309,7 +2331,14 @@ static int its_irq_domain_activate(struct irq_domain *domain,
cpu_mask = cpumask_of_node(its_dev->its->numa_node);
/* Bind the LPI to the first possible CPU */
- cpu = cpumask_first(cpu_mask);
+ cpu = cpumask_first_and(cpu_mask, cpu_online_mask);
+ if (cpu >= nr_cpu_ids) {
+ if (its_dev->its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_23144)
+ return -EINVAL;
+
+ cpu = cpumask_first(cpu_online_mask);
+ }
+
its_dev->event_map.col_map[event] = cpu;
irq_data_update_effective_affinity(d, cpumask_of(cpu));
@@ -3183,7 +3212,7 @@ static int its_init_vpe_domain(void)
its = list_first_entry(&its_nodes, struct its_node, entry);
entries = roundup_pow_of_two(nr_cpu_ids);
- vpe_proxy.vpes = kzalloc(sizeof(*vpe_proxy.vpes) * entries,
+ vpe_proxy.vpes = kcalloc(entries, sizeof(*vpe_proxy.vpes),
GFP_KERNEL);
if (!vpe_proxy.vpes) {
pr_err("ITS: Can't allocate GICv4 proxy device array\n");
@@ -3398,6 +3427,16 @@ static int redist_disable_lpis(void)
u64 timeout = USEC_PER_SEC;
u64 val;
+ /*
+ * If coming via a CPU hotplug event, we don't need to disable
+ * LPIs before trying to re-enable them. They are already
+ * configured and all is well in the world. Detect this case
+ * by checking the allocation of the pending table for the
+ * current CPU.
+ */
+ if (gic_data_rdist()->pend_page)
+ return 0;
+
if (!gic_rdists_supports_plpis()) {
pr_info("CPU%d: LPIs not supported\n", smp_processor_id());
return -ENXIO;
@@ -3567,8 +3606,8 @@ static void __init acpi_table_parse_srat_its(void)
if (count <= 0)
return;
- its_srat_maps = kmalloc(count * sizeof(struct its_srat_map),
- GFP_KERNEL);
+ its_srat_maps = kmalloc_array(count, sizeof(struct its_srat_map),
+ GFP_KERNEL);
if (!its_srat_maps) {
pr_warn("SRAT: Failed to allocate memory for its_srat_maps!\n");
return;
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index 5a67ec084588..76ea56d779a1 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -1167,7 +1167,7 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node)
if (!nr_parts)
goto out_put_node;
- parts = kzalloc(sizeof(*parts) * nr_parts, GFP_KERNEL);
+ parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL);
if (WARN_ON(!parts))
goto out_put_node;
@@ -1289,7 +1289,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
if (of_property_read_u32(node, "#redistributor-regions", &nr_redist_regions))
nr_redist_regions = 1;
- rdist_regs = kzalloc(sizeof(*rdist_regs) * nr_redist_regions, GFP_KERNEL);
+ rdist_regs = kcalloc(nr_redist_regions, sizeof(*rdist_regs),
+ GFP_KERNEL);
if (!rdist_regs) {
err = -ENOMEM;
goto out_unmap_dist;
diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c
index e80263e16c4c..d00489a4b54f 100644
--- a/drivers/irqchip/irq-imgpdc.c
+++ b/drivers/irqchip/irq-imgpdc.c
@@ -354,7 +354,7 @@ static int pdc_intc_probe(struct platform_device *pdev)
priv->nr_syswakes = val;
/* Get peripheral IRQ numbers */
- priv->perip_irqs = devm_kzalloc(&pdev->dev, 4 * priv->nr_perips,
+ priv->perip_irqs = devm_kcalloc(&pdev->dev, 4, priv->nr_perips,
GFP_KERNEL);
if (!priv->perip_irqs) {
dev_err(&pdev->dev, "cannot allocate perip IRQ list\n");
diff --git a/drivers/irqchip/irq-ls-scfg-msi.c b/drivers/irqchip/irq-ls-scfg-msi.c
index 1ec3bfe56693..c671b3212010 100644
--- a/drivers/irqchip/irq-ls-scfg-msi.c
+++ b/drivers/irqchip/irq-ls-scfg-msi.c
@@ -93,8 +93,12 @@ static void ls_scfg_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
msg->address_lo = lower_32_bits(msi_data->msiir_addr);
msg->data = data->hwirq;
- if (msi_affinity_flag)
- msg->data |= cpumask_first(data->common->affinity);
+ if (msi_affinity_flag) {
+ const struct cpumask *mask;
+
+ mask = irq_data_get_effective_affinity_mask(data);
+ msg->data |= cpumask_first(mask);
+ }
iommu_dma_map_msi_msg(data->irq, msg);
}
@@ -121,7 +125,7 @@ static int ls_scfg_msi_set_affinity(struct irq_data *irq_data,
return -EINVAL;
}
- cpumask_copy(irq_data->common->affinity, mask);
+ irq_data_update_effective_affinity(irq_data, cpumask_of(cpu));
return IRQ_SET_MASK_OK;
}
diff --git a/drivers/irqchip/irq-mvebu-gicp.c b/drivers/irqchip/irq-mvebu-gicp.c
index 4e17f7081efc..3be5c5dba1da 100644
--- a/drivers/irqchip/irq-mvebu-gicp.c
+++ b/drivers/irqchip/irq-mvebu-gicp.c
@@ -191,8 +191,8 @@ static int mvebu_gicp_probe(struct platform_device *pdev)
gicp->spi_ranges_cnt = ret / 2;
gicp->spi_ranges =
- devm_kzalloc(&pdev->dev,
- gicp->spi_ranges_cnt *
+ devm_kcalloc(&pdev->dev,
+ gicp->spi_ranges_cnt,
sizeof(struct mvebu_gicp_spi_range),
GFP_KERNEL);
if (!gicp->spi_ranges)
@@ -210,8 +210,8 @@ static int mvebu_gicp_probe(struct platform_device *pdev)
gicp->spi_cnt += gicp->spi_ranges[i].count;
}
- gicp->spi_bitmap = devm_kzalloc(&pdev->dev,
- BITS_TO_LONGS(gicp->spi_cnt) * sizeof(long),
+ gicp->spi_bitmap = devm_kcalloc(&pdev->dev,
+ BITS_TO_LONGS(gicp->spi_cnt), sizeof(long),
GFP_KERNEL);
if (!gicp->spi_bitmap)
return -ENOMEM;
diff --git a/drivers/irqchip/irq-partition-percpu.c b/drivers/irqchip/irq-partition-percpu.c
index ccd72c2cbc23..1f7cc5933cd5 100644
--- a/drivers/irqchip/irq-partition-percpu.c
+++ b/drivers/irqchip/irq-partition-percpu.c
@@ -229,7 +229,7 @@ struct partition_desc *partition_create_desc(struct fwnode_handle *fwnode,
goto out;
desc->domain = d;
- desc->bitmap = kzalloc(sizeof(long) * BITS_TO_LONGS(nr_parts),
+ desc->bitmap = kcalloc(BITS_TO_LONGS(nr_parts), sizeof(long),
GFP_KERNEL);
if (WARN_ON(!desc->bitmap))
goto out;
diff --git a/drivers/irqchip/irq-s3c24xx.c b/drivers/irqchip/irq-s3c24xx.c
index ec0e6a8cdb75..f6fd57ebe6e6 100644
--- a/drivers/irqchip/irq-s3c24xx.c
+++ b/drivers/irqchip/irq-s3c24xx.c
@@ -1261,7 +1261,7 @@ static int __init s3c_init_intc_of(struct device_node *np,
return -ENOMEM;
intc->domain = domain;
- intc->irqs = kzalloc(sizeof(struct s3c_irq_data) * 32,
+ intc->irqs = kcalloc(32, sizeof(struct s3c_irq_data),
GFP_KERNEL);
if (!intc->irqs) {
kfree(intc);
OpenPOWER on IntegriCloud