Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner: - Consolidation of softirq pending: The softirq mask and its accessors/mutators have many implementations scattered around many architectures. Most do the same things consisting in a field in a per-cpu struct (often irq_cpustat_t) accessed through per-cpu ops. We can provide instead a generic efficient version that most of them can use. In fact s390 is the only exception because the field is stored in lowcore. - Support for level!?! triggered MSI (ARM) Over the past couple of years, we've seen some SoCs coming up with ways of signalling level interrupts using a new flavor of MSIs, where the MSI controller uses two distinct messages: one that raises a virtual line, and one that lowers it. The target MSI controller is in charge of maintaining the state of the line. This allows for a much simplified HW signal routing (no need to have hundreds of discrete lines to signal level interrupts if you already have a memory bus), but results in a departure from the current idea the kernel has of MSIs. - Support for Meson-AXG GPIO irqchip - Large stm32 irqchip rework (suspend/resume, hierarchical domains) - More SPDX conversions * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (36 commits) ARM: dts: stm32: Add exti support to stm32mp157 pinctrl ARM: dts: stm32: Add exti support for stm32mp157c pinctrl/stm32: Add irq_eoi for stm32gpio irqchip irqchip/stm32: Add suspend/resume support for hierarchy domain irqchip/stm32: Add stm32mp1 support with hierarchy domain irqchip/stm32: Prepare common functions irqchip/stm32: Add host and driver data structures irqchip/stm32: Add suspend support irqchip/stm32: Add falling pending register support irqchip/stm32: Checkpatch fix irqchip/stm32: Optimizes and cleans up stm32-exti irq_domain irqchip/meson-gpio: Add support for Meson-AXG SoCs dt-bindings: interrupt-controller: New binding for Meson-AXG SoC dt-bindings: interrupt-controller: Fix the double quotes softirq/s390: Move default mutators of overwritten softirq mask to s390 softirq/x86: Switch to generic local_softirq_pending() implementation softirq/sparc: Switch to generic local_softirq_pending() implementation softirq/powerpc: Switch to generic local_softirq_pending() implementation softirq/parisc: Switch to generic local_softirq_pending() implementation softirq/ia64: Switch to generic local_softirq_pending() implementation ...
This commit is contained in:
@@ -1,11 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2017 Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
* Copyright (C) 2017-2018 Bartosz Golaszewski <brgl@bgdev.pl>
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
@@ -76,6 +76,19 @@ static inline void irq_chip_write_msi_msg(struct irq_data *data,
|
||||
data->chip->irq_write_msi_msg(data, msg);
|
||||
}
|
||||
|
||||
static void msi_check_level(struct irq_domain *domain, struct msi_msg *msg)
|
||||
{
|
||||
struct msi_domain_info *info = domain->host_data;
|
||||
|
||||
/*
|
||||
* If the MSI provider has messed with the second message and
|
||||
* not advertized that it is level-capable, signal the breakage.
|
||||
*/
|
||||
WARN_ON(!((info->flags & MSI_FLAG_LEVEL_CAPABLE) &&
|
||||
(info->chip->flags & IRQCHIP_SUPPORTS_LEVEL_MSI)) &&
|
||||
(msg[1].address_lo || msg[1].address_hi || msg[1].data));
|
||||
}
|
||||
|
||||
/**
|
||||
* msi_domain_set_affinity - Generic affinity setter function for MSI domains
|
||||
* @irq_data: The irq data associated to the interrupt
|
||||
@@ -89,13 +102,14 @@ int msi_domain_set_affinity(struct irq_data *irq_data,
|
||||
const struct cpumask *mask, bool force)
|
||||
{
|
||||
struct irq_data *parent = irq_data->parent_data;
|
||||
struct msi_msg msg;
|
||||
struct msi_msg msg[2] = { [1] = { }, };
|
||||
int ret;
|
||||
|
||||
ret = parent->chip->irq_set_affinity(parent, mask, force);
|
||||
if (ret >= 0 && ret != IRQ_SET_MASK_OK_DONE) {
|
||||
BUG_ON(irq_chip_compose_msi_msg(irq_data, &msg));
|
||||
irq_chip_write_msi_msg(irq_data, &msg);
|
||||
BUG_ON(irq_chip_compose_msi_msg(irq_data, msg));
|
||||
msi_check_level(irq_data->domain, msg);
|
||||
irq_chip_write_msi_msg(irq_data, msg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -104,20 +118,21 @@ int msi_domain_set_affinity(struct irq_data *irq_data,
|
||||
static int msi_domain_activate(struct irq_domain *domain,
|
||||
struct irq_data *irq_data, bool early)
|
||||
{
|
||||
struct msi_msg msg;
|
||||
struct msi_msg msg[2] = { [1] = { }, };
|
||||
|
||||
BUG_ON(irq_chip_compose_msi_msg(irq_data, &msg));
|
||||
irq_chip_write_msi_msg(irq_data, &msg);
|
||||
BUG_ON(irq_chip_compose_msi_msg(irq_data, msg));
|
||||
msi_check_level(irq_data->domain, msg);
|
||||
irq_chip_write_msi_msg(irq_data, msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msi_domain_deactivate(struct irq_domain *domain,
|
||||
struct irq_data *irq_data)
|
||||
{
|
||||
struct msi_msg msg;
|
||||
struct msi_msg msg[2];
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
irq_chip_write_msi_msg(irq_data, &msg);
|
||||
memset(msg, 0, sizeof(msg));
|
||||
irq_chip_write_msi_msg(irq_data, msg);
|
||||
}
|
||||
|
||||
static int msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
|
||||
|
Reference in New Issue
Block a user