Commit 80ade29e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'irq-urgent-2020-04-19' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fixes from Thomas Gleixner:
 "A set of fixes/updates for the interrupt subsystem:

   - Remove setup_irq() and remove_irq(). All users have been converted
     so remove them before new users surface.

   - A set of bugfixes for various interrupt chip drivers

   - Add a few missing static attributes to address sparse warnings"

* tag 'irq-urgent-2020-04-19' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  irqchip/irq-bcm7038-l1: Make bcm7038_l1_of_init() static
  irqchip/irq-mvebu-icu: Make legacy_bindings static
  irqchip/meson-gpio: Fix HARDIRQ-safe -> HARDIRQ-unsafe lock order
  irqchip/sifive-plic: Fix maximum priority threshold value
  irqchip/ti-sci-inta: Fix processing of masked irqs
  irqchip/mbigen: Free msi_desc on device teardown
  irqchip/gic-v4.1: Update effective affinity of virtual SGIs
  irqchip/gic-v4.1: Add support for VPENDBASER's Dirty+Valid signaling
  genirq: Remove setup_irq() and remove_irq()
parents 08dd3872 b5963029
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -416,7 +416,7 @@ static const struct irq_domain_ops bcm7038_l1_domain_ops = {
	.map			= bcm7038_l1_map,
};

int __init bcm7038_l1_of_init(struct device_node *dn,
static int __init bcm7038_l1_of_init(struct device_node *dn,
			      struct device_node *parent)
{
	struct bcm7038_l1_chip *intc;
+20 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/dma-iommu.h>
#include <linux/efi.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/irqdomain.h>
#include <linux/list.h>
#include <linux/log2.h>
@@ -3672,6 +3673,20 @@ out:
	return IRQ_SET_MASK_OK_DONE;
}

static void its_wait_vpt_parse_complete(void)
{
	void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
	u64 val;

	if (!gic_rdists->has_vpend_valid_dirty)
		return;

	WARN_ON_ONCE(readq_relaxed_poll_timeout(vlpi_base + GICR_VPENDBASER,
						val,
						!(val & GICR_VPENDBASER_Dirty),
						10, 500));
}

static void its_vpe_schedule(struct its_vpe *vpe)
{
	void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
@@ -3702,6 +3717,8 @@ static void its_vpe_schedule(struct its_vpe *vpe)
	val |= vpe->idai ? GICR_VPENDBASER_IDAI : 0;
	val |= GICR_VPENDBASER_Valid;
	gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);

	its_wait_vpt_parse_complete();
}

static void its_vpe_deschedule(struct its_vpe *vpe)
@@ -3910,6 +3927,8 @@ static void its_vpe_4_1_schedule(struct its_vpe *vpe,
	val |= FIELD_PREP(GICR_VPENDBASER_4_1_VPEID, vpe->vpe_id);

	gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);

	its_wait_vpt_parse_complete();
}

static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
@@ -4035,6 +4054,7 @@ static int its_sgi_set_affinity(struct irq_data *d,
	 * not on the host (since they can only be targetting a vPE).
	 * Tell the kernel we've done whatever it asked for.
	 */
	irq_data_update_effective_affinity(d, mask_val);
	return IRQ_SET_MASK_OK;
}

+7 −4
Original line number Diff line number Diff line
@@ -873,6 +873,7 @@ static int __gic_update_rdist_properties(struct redist_region *region,
	gic_data.rdists.has_rvpeid &= !!(typer & GICR_TYPER_RVPEID);
	gic_data.rdists.has_direct_lpi &= (!!(typer & GICR_TYPER_DirectLPIS) |
					   gic_data.rdists.has_rvpeid);
	gic_data.rdists.has_vpend_valid_dirty &= !!(typer & GICR_TYPER_DIRTY);

	/* Detect non-sensical configurations */
	if (WARN_ON_ONCE(gic_data.rdists.has_rvpeid && !gic_data.rdists.has_vlpis)) {
@@ -893,10 +894,11 @@ static void gic_update_rdist_properties(void)
	if (WARN_ON(gic_data.ppi_nr == UINT_MAX))
		gic_data.ppi_nr = 0;
	pr_info("%d PPIs implemented\n", gic_data.ppi_nr);
	pr_info("%sVLPI support, %sdirect LPI support, %sRVPEID support\n",
		!gic_data.rdists.has_vlpis ? "no " : "",
		!gic_data.rdists.has_direct_lpi ? "no " : "",
		!gic_data.rdists.has_rvpeid ? "no " : "");
	if (gic_data.rdists.has_vlpis)
		pr_info("GICv4 features: %s%s%s\n",
			gic_data.rdists.has_direct_lpi ? "DirectLPI " : "",
			gic_data.rdists.has_rvpeid ? "RVPEID " : "",
			gic_data.rdists.has_vpend_valid_dirty ? "Valid+Dirty " : "");
}

/* Check whether it's single security state view */
@@ -1620,6 +1622,7 @@ static int __init gic_init_bases(void __iomem *dist_base,
	gic_data.rdists.has_rvpeid = true;
	gic_data.rdists.has_vlpis = true;
	gic_data.rdists.has_direct_lpi = true;
	gic_data.rdists.has_vpend_valid_dirty = true;

	if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) {
		err = -ENOMEM;
+7 −1
Original line number Diff line number Diff line
@@ -220,10 +220,16 @@ static int mbigen_irq_domain_alloc(struct irq_domain *domain,
	return 0;
}

static void mbigen_irq_domain_free(struct irq_domain *domain, unsigned int virq,
				   unsigned int nr_irqs)
{
	platform_msi_domain_free(domain, virq, nr_irqs);
}

static const struct irq_domain_ops mbigen_domain_ops = {
	.translate	= mbigen_domain_translate,
	.alloc		= mbigen_irq_domain_alloc,
	.free		= irq_domain_free_irqs_common,
	.free		= mbigen_irq_domain_free,
};

static int mbigen_of_create_domain(struct platform_device *pdev,
+10 −8
Original line number Diff line number Diff line
@@ -144,12 +144,17 @@ struct meson_gpio_irq_controller {
static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
				       unsigned int reg, u32 mask, u32 val)
{
	unsigned long flags;
	u32 tmp;

	spin_lock_irqsave(&ctl->lock, flags);

	tmp = readl_relaxed(ctl->base + reg);
	tmp &= ~mask;
	tmp |= val;
	writel_relaxed(tmp, ctl->base + reg);

	spin_unlock_irqrestore(&ctl->lock, flags);
}

static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl)
@@ -196,14 +201,15 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
			       unsigned long  hwirq,
			       u32 **channel_hwirq)
{
	unsigned long flags;
	unsigned int idx;

	spin_lock(&ctl->lock);
	spin_lock_irqsave(&ctl->lock, flags);

	/* Find a free channel */
	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
	if (idx >= NUM_CHANNEL) {
		spin_unlock(&ctl->lock);
		spin_unlock_irqrestore(&ctl->lock, flags);
		pr_err("No channel available\n");
		return -ENOSPC;
	}
@@ -211,6 +217,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
	/* Mark the channel as used */
	set_bit(idx, ctl->channel_map);

	spin_unlock_irqrestore(&ctl->lock, flags);

	/*
	 * Setup the mux of the channel to route the signal of the pad
	 * to the appropriate input of the GIC
@@ -225,8 +233,6 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
	 */
	*channel_hwirq = &(ctl->channel_irqs[idx]);

	spin_unlock(&ctl->lock);

	pr_debug("hwirq %lu assigned to channel %d - irq %u\n",
		 hwirq, idx, **channel_hwirq);

@@ -287,13 +293,9 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
			val |= REG_EDGE_POL_LOW(params, idx);
	}

	spin_lock(&ctl->lock);

	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
				   REG_EDGE_POL_MASK(params, idx), val);

	spin_unlock(&ctl->lock);

	return 0;
}

Loading