Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'irq-drivers-2025-09-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq chip driver updates from Thomas Gleixner:

- Use the startup/shutdown callbacks for the PCI/MSI per device
interrupt domains.

This allows us to initialize the RISCV PLIC interrupt hierarchy
correctly and provides a mechanism to decouple the masking and
unmasking during run-time from the expensive PCI mask and unmask when
the underlying MSI provider implementation allows the interrupt to be
masked.

- Initialize the RISCV PLIC MSI interrupt hierarchy correctly so that
the affinity assignment works correctly by switching it over to the
startup/shutdown scheme

- Allow MSI providers to opt out from masking a PCI/MSI interrupt at
the PCI device during operation when the provider can mask the
interrupt at the underlying interrupt chip. This reduces the overhead
in scenarios where disable_irq()/enable_irq() is utilized frequently
by a driver.

The PCI/MSI device level [un]masking is only required on startup and
shutdown in this case.

- Remove the conditional mask/unmask logic in the PCI/MSI layer as this
is now handled unconditionally.

- Replace the hardcoded interrupt routing in the Loongson EIOINTC
interrupt driver to respect the firmware settings and spread them out
to different CPU interrupt inputs so that the demultiplexing handler
only needs to read only a single 64-bit status register instead of
four, which significantly reduces the overhead in VMs as the status
register access causes a VM exit.

- Add support for the new AST2700 SCU interrupt controllers

- Use the legacy interrupt domain setup for the Loongson PCH-LPC
interrupt controller, which resembles the x86 legacy PIC setup and
has the same hardcoded legacy requirements.

- The usual set of cleanups, fixes and improvements all over the place

* tag 'irq-drivers-2025-09-29' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits)
irqchip/loongson-pch-lpc: Use legacy domain for PCH-LPC IRQ controller
PCI/MSI: Remove the conditional parent [un]mask logic
irqchip/msi-lib: Honor the MSI_FLAG_PCI_MSI_MASK_PARENT flag
irqchip/aspeed-scu-ic: Add support for AST2700 SCU interrupt controllers
dt-bindings: interrupt-controller: aspeed: Add AST2700 SCU IC compatibles
dt-bindings: mfd: aspeed: Add AST2700 SCU compatibles
irqchip/aspeed-scu-ic: Refactor driver to support variant-based initialization
irqchip/gic-v5: Fix error handling in gicv5_its_irq_domain_alloc()
irqchip/gic-v5: Fix loop in gicv5_its_create_itt_two_level() cleanup path
irqchip/gic-v5: Delete a stray tab
irqchip/sg2042-msi: Set irq type according to DT configuration
riscv: sophgo: dts: sg2044: Change msi irq type to IRQ_TYPE_EDGE_RISING
riscv: sophgo: dts: sg2042: Change msi irq type to IRQ_TYPE_EDGE_RISING
irqchip/gic-v2m: Handle Multiple MSI base IRQ Alignment
irqchip/renesas-rzg2l: Remove dev_err_probe() if error is -ENOMEM
irqchip: Use int type to store negative error codes
irqchip/gic-v5: Remove the redundant ITS cache invalidation
PCI/MSI: Check MSI_FLAG_PCI_MSI_MASK_PARENT in cond_[startup|shutdown]_parent()
irqchip/loongson-eiointc: Add multiple interrupt pin routing support
irqchip/loongson-eiointc: Route interrupt parsed from bios table
...

+404 -161
+5 -1
Documentation/devicetree/bindings/interrupt-controller/aspeed,ast2500-scu-ic.yaml
··· 5 5 $id: http://devicetree.org/schemas/interrupt-controller/aspeed,ast2500-scu-ic.yaml# 6 6 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 7 8 - title: Aspeed AST25XX and AST26XX SCU Interrupt Controller 8 + title: Aspeed AST25XX, AST26XX, AST27XX SCU Interrupt Controller 9 9 10 10 maintainers: 11 11 - Eddie James <eajames@linux.ibm.com> ··· 16 16 - aspeed,ast2500-scu-ic 17 17 - aspeed,ast2600-scu-ic0 18 18 - aspeed,ast2600-scu-ic1 19 + - aspeed,ast2700-scu-ic0 20 + - aspeed,ast2700-scu-ic1 21 + - aspeed,ast2700-scu-ic2 22 + - aspeed,ast2700-scu-ic3 19 23 20 24 reg: 21 25 maxItems: 1
+4
Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml
··· 75 75 - aspeed,ast2500-scu-ic 76 76 - aspeed,ast2600-scu-ic0 77 77 - aspeed,ast2600-scu-ic1 78 + - aspeed,ast2700-scu-ic0 79 + - aspeed,ast2700-scu-ic1 80 + - aspeed,ast2700-scu-ic2 81 + - aspeed,ast2700-scu-ic3 78 82 79 83 '^silicon-id@[0-9a-f]+$': 80 84 description: Unique hardware silicon identifiers within the SoC
+1 -1
arch/riscv/boot/dts/sophgo/sg2042.dtsi
··· 190 190 reg-names = "clr", "doorbell"; 191 191 msi-controller; 192 192 #msi-cells = <0>; 193 - msi-ranges = <&intc 64 IRQ_TYPE_LEVEL_HIGH 32>; 193 + msi-ranges = <&intc 64 IRQ_TYPE_EDGE_RISING 32>; 194 194 }; 195 195 196 196 rpgate: clock-controller@7030010368 {
+1 -1
arch/riscv/boot/dts/sophgo/sg2044.dtsi
··· 214 214 reg-names = "clr", "doorbell"; 215 215 #msi-cells = <0>; 216 216 msi-controller; 217 - msi-ranges = <&intc 352 IRQ_TYPE_LEVEL_HIGH 512>; 217 + msi-ranges = <&intc 352 IRQ_TYPE_EDGE_RISING 512>; 218 218 status = "disabled"; 219 219 }; 220 220
+160 -106
drivers/irqchip/irq-aspeed-scu-ic.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* 3 - * Aspeed AST24XX, AST25XX, and AST26XX SCU Interrupt Controller 3 + * Aspeed AST24XX, AST25XX, AST26XX, and AST27XX SCU Interrupt Controller 4 4 * Copyright 2019 IBM Corporation 5 5 * 6 6 * Eddie James <eajames@linux.ibm.com> 7 7 */ 8 8 9 9 #include <linux/bitops.h> 10 + #include <linux/io.h> 10 11 #include <linux/irq.h> 11 12 #include <linux/irqchip.h> 12 13 #include <linux/irqchip/chained_irq.h> 13 14 #include <linux/irqdomain.h> 14 - #include <linux/mfd/syscon.h> 15 + #include <linux/of_address.h> 15 16 #include <linux/of_irq.h> 16 - #include <linux/regmap.h> 17 17 18 - #define ASPEED_SCU_IC_REG 0x018 19 - #define ASPEED_SCU_IC_SHIFT 0 20 - #define ASPEED_SCU_IC_ENABLE GENMASK(15, ASPEED_SCU_IC_SHIFT) 21 - #define ASPEED_SCU_IC_NUM_IRQS 7 22 18 #define ASPEED_SCU_IC_STATUS GENMASK(28, 16) 23 19 #define ASPEED_SCU_IC_STATUS_SHIFT 16 20 + #define AST2700_SCU_IC_STATUS GENMASK(15, 0) 24 21 25 - #define ASPEED_AST2600_SCU_IC0_REG 0x560 26 - #define ASPEED_AST2600_SCU_IC0_SHIFT 0 27 - #define ASPEED_AST2600_SCU_IC0_ENABLE \ 28 - GENMASK(5, ASPEED_AST2600_SCU_IC0_SHIFT) 29 - #define ASPEED_AST2600_SCU_IC0_NUM_IRQS 6 30 - 31 - #define ASPEED_AST2600_SCU_IC1_REG 0x570 32 - #define ASPEED_AST2600_SCU_IC1_SHIFT 4 33 - #define ASPEED_AST2600_SCU_IC1_ENABLE \ 34 - GENMASK(5, ASPEED_AST2600_SCU_IC1_SHIFT) 35 - #define ASPEED_AST2600_SCU_IC1_NUM_IRQS 2 36 - 37 - struct aspeed_scu_ic { 38 - unsigned long irq_enable; 39 - unsigned long irq_shift; 40 - unsigned int num_irqs; 41 - unsigned int reg; 42 - struct regmap *scu; 43 - struct irq_domain *irq_domain; 22 + struct aspeed_scu_ic_variant { 23 + const char *compatible; 24 + unsigned long irq_enable; 25 + unsigned long irq_shift; 26 + unsigned int num_irqs; 27 + unsigned long ier; 28 + unsigned long isr; 44 29 }; 45 30 46 - static void aspeed_scu_ic_irq_handler(struct irq_desc *desc) 31 + #define SCU_VARIANT(_compat, _shift, _enable, _num, _ier, _isr) { \ 32 + .compatible = _compat, \ 33 + .irq_shift = _shift, \ 34 + .irq_enable = _enable, \ 35 + .num_irqs = _num, \ 36 + .ier = _ier, \ 37 + .isr = _isr, \ 38 + } 39 + 40 + static const struct aspeed_scu_ic_variant scu_ic_variants[] __initconst = { 41 + SCU_VARIANT("aspeed,ast2400-scu-ic", 0, GENMASK(15, 0), 7, 0x00, 0x00), 42 + SCU_VARIANT("aspeed,ast2500-scu-ic", 0, GENMASK(15, 0), 7, 0x00, 0x00), 43 + SCU_VARIANT("aspeed,ast2600-scu-ic0", 0, GENMASK(5, 0), 6, 0x00, 0x00), 44 + SCU_VARIANT("aspeed,ast2600-scu-ic1", 4, GENMASK(5, 4), 2, 0x00, 0x00), 45 + SCU_VARIANT("aspeed,ast2700-scu-ic0", 0, GENMASK(3, 0), 4, 0x00, 0x04), 46 + SCU_VARIANT("aspeed,ast2700-scu-ic1", 0, GENMASK(3, 0), 4, 0x00, 0x04), 47 + SCU_VARIANT("aspeed,ast2700-scu-ic2", 0, GENMASK(3, 0), 4, 0x04, 0x00), 48 + SCU_VARIANT("aspeed,ast2700-scu-ic3", 0, GENMASK(1, 0), 2, 0x04, 0x00), 49 + }; 50 + 51 + struct aspeed_scu_ic { 52 + unsigned long irq_enable; 53 + unsigned long irq_shift; 54 + unsigned int num_irqs; 55 + void __iomem *base; 56 + struct irq_domain *irq_domain; 57 + unsigned long ier; 58 + unsigned long isr; 59 + }; 60 + 61 + static inline bool scu_has_split_isr(struct aspeed_scu_ic *scu) 47 62 { 48 - unsigned int sts; 49 - unsigned long bit; 50 - unsigned long enabled; 51 - unsigned long max; 52 - unsigned long status; 63 + return scu->ier != scu->isr; 64 + } 65 + 66 + static void aspeed_scu_ic_irq_handler_combined(struct irq_desc *desc) 67 + { 53 68 struct aspeed_scu_ic *scu_ic = irq_desc_get_handler_data(desc); 54 69 struct irq_chip *chip = irq_desc_get_chip(desc); 55 - unsigned int mask = scu_ic->irq_enable << ASPEED_SCU_IC_STATUS_SHIFT; 70 + unsigned long bit, enabled, max, status; 71 + unsigned int sts, mask; 56 72 57 73 chained_irq_enter(chip, desc); 58 74 75 + mask = scu_ic->irq_enable << ASPEED_SCU_IC_STATUS_SHIFT; 59 76 /* 60 77 * The SCU IC has just one register to control its operation and read 61 78 * status. The interrupt enable bits occupy the lower 16 bits of the ··· 83 66 * shifting the status down to get the mapping and then back up to 84 67 * clear the bit. 85 68 */ 86 - regmap_read(scu_ic->scu, scu_ic->reg, &sts); 69 + sts = readl(scu_ic->base); 87 70 enabled = sts & scu_ic->irq_enable; 88 71 status = (sts >> ASPEED_SCU_IC_STATUS_SHIFT) & enabled; 89 72 ··· 91 74 max = scu_ic->num_irqs + bit; 92 75 93 76 for_each_set_bit_from(bit, &status, max) { 94 - generic_handle_domain_irq(scu_ic->irq_domain, 95 - bit - scu_ic->irq_shift); 96 - 97 - regmap_write_bits(scu_ic->scu, scu_ic->reg, mask, 98 - BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT)); 77 + generic_handle_domain_irq(scu_ic->irq_domain, bit - scu_ic->irq_shift); 78 + writel((readl(scu_ic->base) & ~mask) | BIT(bit + ASPEED_SCU_IC_STATUS_SHIFT), 79 + scu_ic->base); 99 80 } 100 81 101 82 chained_irq_exit(chip, desc); 102 83 } 103 84 104 - static void aspeed_scu_ic_irq_mask(struct irq_data *data) 85 + static void aspeed_scu_ic_irq_handler_split(struct irq_desc *desc) 86 + { 87 + struct aspeed_scu_ic *scu_ic = irq_desc_get_handler_data(desc); 88 + struct irq_chip *chip = irq_desc_get_chip(desc); 89 + unsigned long bit, enabled, max, status; 90 + unsigned int sts, mask; 91 + 92 + chained_irq_enter(chip, desc); 93 + 94 + mask = scu_ic->irq_enable; 95 + sts = readl(scu_ic->base + scu_ic->isr); 96 + enabled = sts & scu_ic->irq_enable; 97 + sts = readl(scu_ic->base + scu_ic->isr); 98 + status = sts & enabled; 99 + 100 + bit = scu_ic->irq_shift; 101 + max = scu_ic->num_irqs + bit; 102 + 103 + for_each_set_bit_from(bit, &status, max) { 104 + generic_handle_domain_irq(scu_ic->irq_domain, bit - scu_ic->irq_shift); 105 + /* Clear interrupt */ 106 + writel(BIT(bit), scu_ic->base + scu_ic->isr); 107 + } 108 + 109 + chained_irq_exit(chip, desc); 110 + } 111 + 112 + static void aspeed_scu_ic_irq_mask_combined(struct irq_data *data) 105 113 { 106 114 struct aspeed_scu_ic *scu_ic = irq_data_get_irq_chip_data(data); 107 - unsigned int mask = BIT(data->hwirq + scu_ic->irq_shift) | 108 - (scu_ic->irq_enable << ASPEED_SCU_IC_STATUS_SHIFT); 115 + unsigned int bit = BIT(data->hwirq + scu_ic->irq_shift); 116 + unsigned int mask = bit | (scu_ic->irq_enable << ASPEED_SCU_IC_STATUS_SHIFT); 109 117 110 118 /* 111 119 * Status bits are cleared by writing 1. In order to prevent the mask 112 120 * operation from clearing the status bits, they should be under the 113 121 * mask and written with 0. 114 122 */ 115 - regmap_update_bits(scu_ic->scu, scu_ic->reg, mask, 0); 123 + writel(readl(scu_ic->base) & ~mask, scu_ic->base); 116 124 } 117 125 118 - static void aspeed_scu_ic_irq_unmask(struct irq_data *data) 126 + static void aspeed_scu_ic_irq_unmask_combined(struct irq_data *data) 119 127 { 120 128 struct aspeed_scu_ic *scu_ic = irq_data_get_irq_chip_data(data); 121 129 unsigned int bit = BIT(data->hwirq + scu_ic->irq_shift); 122 - unsigned int mask = bit | 123 - (scu_ic->irq_enable << ASPEED_SCU_IC_STATUS_SHIFT); 130 + unsigned int mask = bit | (scu_ic->irq_enable << ASPEED_SCU_IC_STATUS_SHIFT); 124 131 125 132 /* 126 133 * Status bits are cleared by writing 1. In order to prevent the unmask 127 134 * operation from clearing the status bits, they should be under the 128 135 * mask and written with 0. 129 136 */ 130 - regmap_update_bits(scu_ic->scu, scu_ic->reg, mask, bit); 137 + writel((readl(scu_ic->base) & ~mask) | bit, scu_ic->base); 138 + } 139 + 140 + static void aspeed_scu_ic_irq_mask_split(struct irq_data *data) 141 + { 142 + struct aspeed_scu_ic *scu_ic = irq_data_get_irq_chip_data(data); 143 + unsigned int mask = BIT(data->hwirq + scu_ic->irq_shift); 144 + 145 + writel(readl(scu_ic->base) & ~mask, scu_ic->base + scu_ic->ier); 146 + } 147 + 148 + static void aspeed_scu_ic_irq_unmask_split(struct irq_data *data) 149 + { 150 + struct aspeed_scu_ic *scu_ic = irq_data_get_irq_chip_data(data); 151 + unsigned int bit = BIT(data->hwirq + scu_ic->irq_shift); 152 + 153 + writel(readl(scu_ic->base) | bit, scu_ic->base + scu_ic->ier); 131 154 } 132 155 133 156 static int aspeed_scu_ic_irq_set_affinity(struct irq_data *data, ··· 177 120 return -EINVAL; 178 121 } 179 122 180 - static struct irq_chip aspeed_scu_ic_chip = { 123 + static struct irq_chip aspeed_scu_ic_chip_combined = { 181 124 .name = "aspeed-scu-ic", 182 - .irq_mask = aspeed_scu_ic_irq_mask, 183 - .irq_unmask = aspeed_scu_ic_irq_unmask, 184 - .irq_set_affinity = aspeed_scu_ic_irq_set_affinity, 125 + .irq_mask = aspeed_scu_ic_irq_mask_combined, 126 + .irq_unmask = aspeed_scu_ic_irq_unmask_combined, 127 + .irq_set_affinity = aspeed_scu_ic_irq_set_affinity, 128 + }; 129 + 130 + static struct irq_chip aspeed_scu_ic_chip_split = { 131 + .name = "ast2700-scu-ic", 132 + .irq_mask = aspeed_scu_ic_irq_mask_split, 133 + .irq_unmask = aspeed_scu_ic_irq_unmask_split, 134 + .irq_set_affinity = aspeed_scu_ic_irq_set_affinity, 185 135 }; 186 136 187 137 static int aspeed_scu_ic_map(struct irq_domain *domain, unsigned int irq, 188 138 irq_hw_number_t hwirq) 189 139 { 190 - irq_set_chip_and_handler(irq, &aspeed_scu_ic_chip, handle_level_irq); 140 + struct aspeed_scu_ic *scu_ic = domain->host_data; 141 + 142 + if (scu_has_split_isr(scu_ic)) 143 + irq_set_chip_and_handler(irq, &aspeed_scu_ic_chip_split, handle_level_irq); 144 + else 145 + irq_set_chip_and_handler(irq, &aspeed_scu_ic_chip_combined, handle_level_irq); 191 146 irq_set_chip_data(irq, domain->host_data); 192 147 193 148 return 0; ··· 212 143 static int aspeed_scu_ic_of_init_common(struct aspeed_scu_ic *scu_ic, 213 144 struct device_node *node) 214 145 { 215 - int irq; 216 - int rc = 0; 146 + int irq, rc = 0; 217 147 218 - if (!node->parent) { 219 - rc = -ENODEV; 148 + scu_ic->base = of_iomap(node, 0); 149 + if (IS_ERR(scu_ic->base)) { 150 + rc = PTR_ERR(scu_ic->base); 220 151 goto err; 221 152 } 222 153 223 - scu_ic->scu = syscon_node_to_regmap(node->parent); 224 - if (IS_ERR(scu_ic->scu)) { 225 - rc = PTR_ERR(scu_ic->scu); 226 - goto err; 154 + if (scu_has_split_isr(scu_ic)) { 155 + writel(AST2700_SCU_IC_STATUS, scu_ic->base + scu_ic->isr); 156 + writel(0, scu_ic->base + scu_ic->ier); 157 + } else { 158 + writel(ASPEED_SCU_IC_STATUS, scu_ic->base); 159 + writel(0, scu_ic->base); 227 160 } 228 - regmap_write_bits(scu_ic->scu, scu_ic->reg, ASPEED_SCU_IC_STATUS, ASPEED_SCU_IC_STATUS); 229 - regmap_write_bits(scu_ic->scu, scu_ic->reg, ASPEED_SCU_IC_ENABLE, 0); 230 161 231 162 irq = irq_of_parse_and_map(node, 0); 232 163 if (!irq) { ··· 235 166 } 236 167 237 168 scu_ic->irq_domain = irq_domain_create_linear(of_fwnode_handle(node), scu_ic->num_irqs, 238 - &aspeed_scu_ic_domain_ops, 239 - scu_ic); 169 + &aspeed_scu_ic_domain_ops, scu_ic); 240 170 if (!scu_ic->irq_domain) { 241 171 rc = -ENOMEM; 242 172 goto err; 243 173 } 244 174 245 - irq_set_chained_handler_and_data(irq, aspeed_scu_ic_irq_handler, 175 + irq_set_chained_handler_and_data(irq, scu_has_split_isr(scu_ic) ? 176 + aspeed_scu_ic_irq_handler_split : 177 + aspeed_scu_ic_irq_handler_combined, 246 178 scu_ic); 247 179 248 180 return 0; 249 181 250 182 err: 251 183 kfree(scu_ic); 252 - 253 184 return rc; 254 185 } 255 186 256 - static int __init aspeed_scu_ic_of_init(struct device_node *node, 257 - struct device_node *parent) 187 + static const struct aspeed_scu_ic_variant *aspeed_scu_ic_find_variant(struct device_node *np) 258 188 { 259 - struct aspeed_scu_ic *scu_ic = kzalloc(sizeof(*scu_ic), GFP_KERNEL); 260 - 261 - if (!scu_ic) 262 - return -ENOMEM; 263 - 264 - scu_ic->irq_enable = ASPEED_SCU_IC_ENABLE; 265 - scu_ic->irq_shift = ASPEED_SCU_IC_SHIFT; 266 - scu_ic->num_irqs = ASPEED_SCU_IC_NUM_IRQS; 267 - scu_ic->reg = ASPEED_SCU_IC_REG; 268 - 269 - return aspeed_scu_ic_of_init_common(scu_ic, node); 189 + for (int i = 0; i < ARRAY_SIZE(scu_ic_variants); i++) { 190 + if (of_device_is_compatible(np, scu_ic_variants[i].compatible)) 191 + return &scu_ic_variants[i]; 192 + } 193 + return NULL; 270 194 } 271 195 272 - static int __init aspeed_ast2600_scu_ic0_of_init(struct device_node *node, 273 - struct device_node *parent) 196 + static int __init aspeed_scu_ic_of_init(struct device_node *node, struct device_node *parent) 274 197 { 275 - struct aspeed_scu_ic *scu_ic = kzalloc(sizeof(*scu_ic), GFP_KERNEL); 198 + const struct aspeed_scu_ic_variant *variant; 199 + struct aspeed_scu_ic *scu_ic; 276 200 201 + variant = aspeed_scu_ic_find_variant(node); 202 + if (!variant) 203 + return -ENODEV; 204 + 205 + scu_ic = kzalloc(sizeof(*scu_ic), GFP_KERNEL); 277 206 if (!scu_ic) 278 207 return -ENOMEM; 279 208 280 - scu_ic->irq_enable = ASPEED_AST2600_SCU_IC0_ENABLE; 281 - scu_ic->irq_shift = ASPEED_AST2600_SCU_IC0_SHIFT; 282 - scu_ic->num_irqs = ASPEED_AST2600_SCU_IC0_NUM_IRQS; 283 - scu_ic->reg = ASPEED_AST2600_SCU_IC0_REG; 284 - 285 - return aspeed_scu_ic_of_init_common(scu_ic, node); 286 - } 287 - 288 - static int __init aspeed_ast2600_scu_ic1_of_init(struct device_node *node, 289 - struct device_node *parent) 290 - { 291 - struct aspeed_scu_ic *scu_ic = kzalloc(sizeof(*scu_ic), GFP_KERNEL); 292 - 293 - if (!scu_ic) 294 - return -ENOMEM; 295 - 296 - scu_ic->irq_enable = ASPEED_AST2600_SCU_IC1_ENABLE; 297 - scu_ic->irq_shift = ASPEED_AST2600_SCU_IC1_SHIFT; 298 - scu_ic->num_irqs = ASPEED_AST2600_SCU_IC1_NUM_IRQS; 299 - scu_ic->reg = ASPEED_AST2600_SCU_IC1_REG; 209 + scu_ic->irq_enable = variant->irq_enable; 210 + scu_ic->irq_shift = variant->irq_shift; 211 + scu_ic->num_irqs = variant->num_irqs; 212 + scu_ic->ier = variant->ier; 213 + scu_ic->isr = variant->isr; 300 214 301 215 return aspeed_scu_ic_of_init_common(scu_ic, node); 302 216 } 303 217 304 218 IRQCHIP_DECLARE(ast2400_scu_ic, "aspeed,ast2400-scu-ic", aspeed_scu_ic_of_init); 305 219 IRQCHIP_DECLARE(ast2500_scu_ic, "aspeed,ast2500-scu-ic", aspeed_scu_ic_of_init); 306 - IRQCHIP_DECLARE(ast2600_scu_ic0, "aspeed,ast2600-scu-ic0", 307 - aspeed_ast2600_scu_ic0_of_init); 308 - IRQCHIP_DECLARE(ast2600_scu_ic1, "aspeed,ast2600-scu-ic1", 309 - aspeed_ast2600_scu_ic1_of_init); 220 + IRQCHIP_DECLARE(ast2600_scu_ic0, "aspeed,ast2600-scu-ic0", aspeed_scu_ic_of_init); 221 + IRQCHIP_DECLARE(ast2600_scu_ic1, "aspeed,ast2600-scu-ic1", aspeed_scu_ic_of_init); 222 + IRQCHIP_DECLARE(ast2700_scu_ic0, "aspeed,ast2700-scu-ic0", aspeed_scu_ic_of_init); 223 + IRQCHIP_DECLARE(ast2700_scu_ic1, "aspeed,ast2700-scu-ic1", aspeed_scu_ic_of_init); 224 + IRQCHIP_DECLARE(ast2700_scu_ic2, "aspeed,ast2700-scu-ic2", aspeed_scu_ic_of_init); 225 + IRQCHIP_DECLARE(ast2700_scu_ic3, "aspeed,ast2700-scu-ic3", aspeed_scu_ic_of_init);
+9 -4
drivers/irqchip/irq-gic-v2m.c
··· 153 153 { 154 154 msi_alloc_info_t *info = args; 155 155 struct v2m_data *v2m = NULL, *tmp; 156 - int hwirq, offset, i, err = 0; 156 + int hwirq, i, err = 0; 157 + unsigned long offset; 158 + unsigned long align_mask = nr_irqs - 1; 157 159 158 160 spin_lock(&v2m_lock); 159 161 list_for_each_entry(tmp, &v2m_nodes, entry) { 160 - offset = bitmap_find_free_region(tmp->bm, tmp->nr_spis, 161 - get_count_order(nr_irqs)); 162 - if (offset >= 0) { 162 + unsigned long align_off = tmp->spi_start - (tmp->spi_start & ~align_mask); 163 + 164 + offset = bitmap_find_next_zero_area_off(tmp->bm, tmp->nr_spis, 0, 165 + nr_irqs, align_mask, align_off); 166 + if (offset < tmp->nr_spis) { 163 167 v2m = tmp; 168 + bitmap_set(v2m->bm, offset, nr_irqs); 164 169 break; 165 170 } 166 171 }
+2 -1
drivers/irqchip/irq-gic-v3.c
··· 1766 1766 struct irq_fwspec *fwspec, 1767 1767 enum irq_domain_bus_token bus_token) 1768 1768 { 1769 - unsigned int type, ret, ppi_idx; 1769 + unsigned int type, ppi_idx; 1770 1770 irq_hw_number_t hwirq; 1771 + int ret; 1771 1772 1772 1773 /* Not for us */ 1773 1774 if (fwspec->fwnode != d->fwnode)
+1 -1
drivers/irqchip/irq-gic-v5-irs.c
··· 571 571 FIELD_PREP(GICV5_IRS_CR1_IST_RA, GICV5_NO_READ_ALLOC) | 572 572 FIELD_PREP(GICV5_IRS_CR1_IC, GICV5_NON_CACHE) | 573 573 FIELD_PREP(GICV5_IRS_CR1_OC, GICV5_NON_CACHE); 574 - irs_data->flags |= IRS_FLAGS_NON_COHERENT; 574 + irs_data->flags |= IRS_FLAGS_NON_COHERENT; 575 575 } else { 576 576 cr1 = FIELD_PREP(GICV5_IRS_CR1_VPED_WA, GICV5_WRITE_ALLOC) | 577 577 FIELD_PREP(GICV5_IRS_CR1_VPED_RA, GICV5_READ_ALLOC) |
+16 -10
drivers/irqchip/irq-gic-v5-its.c
··· 191 191 unsigned int num_events) 192 192 { 193 193 unsigned int l1_bits, l2_bits, span, events_per_l2_table; 194 - unsigned int i, complete_tables, final_span, num_ents; 194 + unsigned int complete_tables, final_span, num_ents; 195 195 __le64 *itt_l1, *itt_l2, **l2ptrs; 196 - int ret; 196 + int i, ret; 197 197 u64 val; 198 198 199 199 ret = gicv5_its_l2sz_to_l2_bits(itt_l2sz); ··· 768 768 goto out_dev_free; 769 769 } 770 770 771 - gicv5_its_device_cache_inv(its, its_dev); 772 - 773 771 its_dev->its_node = its; 774 772 775 773 its_dev->event_map = (unsigned long *)bitmap_zalloc(its_dev->num_events, GFP_KERNEL); ··· 947 949 device_id = its_dev->device_id; 948 950 949 951 for (i = 0; i < nr_irqs; i++) { 950 - lpi = gicv5_alloc_lpi(); 952 + ret = gicv5_alloc_lpi(); 951 953 if (ret < 0) { 952 954 pr_debug("Failed to find free LPI!\n"); 953 - goto out_eventid; 955 + goto out_free_irqs; 954 956 } 957 + lpi = ret; 955 958 956 959 ret = irq_domain_alloc_irqs_parent(domain, virq + i, 1, &lpi); 957 - if (ret) 958 - goto out_free_lpi; 960 + if (ret) { 961 + gicv5_free_lpi(lpi); 962 + goto out_free_irqs; 963 + } 959 964 960 965 /* 961 966 * Store eventid and deviceid into the hwirq for later use. ··· 978 977 979 978 return 0; 980 979 981 - out_free_lpi: 982 - gicv5_free_lpi(lpi); 980 + out_free_irqs: 981 + while (--i >= 0) { 982 + irqd = irq_domain_get_irq_data(domain, virq + i); 983 + gicv5_free_lpi(irqd->parent_data->hwirq); 984 + irq_domain_reset_irq_data(irqd); 985 + irq_domain_free_irqs_parent(domain, virq + i, 1); 986 + } 983 987 out_eventid: 984 988 gicv5_its_free_eventid(its_dev, event_id_base, nr_irqs); 985 989 return ret;
+93 -12
drivers/irqchip/irq-loongson-eiointc.c
··· 46 46 #define EIOINTC_ALL_ENABLE_VEC_MASK(vector) (EIOINTC_ALL_ENABLE & ~BIT(vector & 0x1f)) 47 47 #define EIOINTC_REG_ENABLE_VEC(vector) (EIOINTC_REG_ENABLE + ((vector >> 5) << 2)) 48 48 #define EIOINTC_USE_CPU_ENCODE BIT(0) 49 + #define EIOINTC_ROUTE_MULT_IP BIT(1) 49 50 50 51 #define MAX_EIO_NODES (NR_CPUS / CORES_PER_EIO_NODE) 51 52 ··· 60 59 #define EIOINTC_REG_ROUTE_VEC_MASK(vector) (0xff << EIOINTC_REG_ROUTE_VEC_SHIFT(vector)) 61 60 62 61 static int nr_pics; 62 + struct eiointc_priv; 63 + 64 + struct eiointc_ip_route { 65 + struct eiointc_priv *priv; 66 + /* Offset Routed destination IP */ 67 + int start; 68 + int end; 69 + }; 63 70 64 71 struct eiointc_priv { 65 72 u32 node; ··· 77 68 struct fwnode_handle *domain_handle; 78 69 struct irq_domain *eiointc_domain; 79 70 int flags; 71 + irq_hw_number_t parent_hwirq; 72 + struct eiointc_ip_route route_info[VEC_REG_COUNT]; 80 73 }; 81 74 82 75 static struct eiointc_priv *eiointc_priv[MAX_IO_PICS]; ··· 199 188 { 200 189 int i, bit, cores, index, node; 201 190 unsigned int data; 191 + int hwirq, mask; 202 192 203 193 node = cpu_to_eio_node(cpu); 204 194 index = eiointc_index(node); ··· 208 196 pr_err("Error: invalid nodemap!\n"); 209 197 return -EINVAL; 210 198 } 199 + 200 + /* Enable cpu interrupt pin from eiointc */ 201 + hwirq = eiointc_priv[index]->parent_hwirq; 202 + mask = BIT(hwirq); 203 + if (eiointc_priv[index]->flags & EIOINTC_ROUTE_MULT_IP) 204 + mask |= BIT(hwirq + 1) | BIT(hwirq + 2) | BIT(hwirq + 3); 205 + set_csr_ecfg(mask); 211 206 212 207 if (!(eiointc_priv[index]->flags & EIOINTC_USE_CPU_ENCODE)) 213 208 cores = CORES_PER_EIO_NODE; ··· 230 211 } 231 212 232 213 for (i = 0; i < eiointc_priv[0]->vec_count / 32 / 4; i++) { 233 - bit = BIT(1 + index); /* Route to IP[1 + index] */ 234 - data = bit | (bit << 8) | (bit << 16) | (bit << 24); 214 + /* 215 + * Route to interrupt pin, relative offset used here 216 + * Offset 0 means routing to IP0 and so on 217 + * 218 + * If flags is set with EIOINTC_ROUTE_MULT_IP, 219 + * every 64 vector routes to different consecutive 220 + * IPs, otherwise all vector routes to the same IP 221 + */ 222 + if (eiointc_priv[index]->flags & EIOINTC_ROUTE_MULT_IP) { 223 + /* The first 64 vectors route to hwirq */ 224 + bit = BIT(hwirq++ - INT_HWI0); 225 + data = bit | (bit << 8); 226 + 227 + /* The second 64 vectors route to hwirq + 1 */ 228 + bit = BIT(hwirq++ - INT_HWI0); 229 + data |= (bit << 16) | (bit << 24); 230 + 231 + /* 232 + * Route to hwirq + 2/hwirq + 3 separately 233 + * in next loop 234 + */ 235 + } else { 236 + bit = BIT(hwirq - INT_HWI0); 237 + data = bit | (bit << 8) | (bit << 16) | (bit << 24); 238 + } 235 239 iocsr_write32(data, EIOINTC_REG_IPMAP + i * 4); 236 240 } 237 241 ··· 283 241 284 242 static void eiointc_irq_dispatch(struct irq_desc *desc) 285 243 { 286 - int i; 287 - u64 pending; 288 - bool handled = false; 244 + struct eiointc_ip_route *info = irq_desc_get_handler_data(desc); 289 245 struct irq_chip *chip = irq_desc_get_chip(desc); 290 - struct eiointc_priv *priv = irq_desc_get_handler_data(desc); 246 + bool handled = false; 247 + u64 pending; 248 + int i; 291 249 292 250 chained_irq_enter(chip, desc); 293 251 294 - for (i = 0; i < eiointc_priv[0]->vec_count / VEC_COUNT_PER_REG; i++) { 252 + /* 253 + * If EIOINTC_ROUTE_MULT_IP is set, every 64 interrupt vectors in 254 + * eiointc interrupt controller routes to different cpu interrupt pins 255 + * 256 + * Every cpu interrupt pin has its own irq handler, it is ok to 257 + * read ISR for these 64 interrupt vectors rather than all vectors 258 + */ 259 + for (i = info->start; i < info->end; i++) { 295 260 pending = iocsr_read64(EIOINTC_REG_ISR + (i << 3)); 296 261 297 262 /* Skip handling if pending bitmap is zero */ ··· 311 262 int bit = __ffs(pending); 312 263 int irq = bit + VEC_COUNT_PER_REG * i; 313 264 314 - generic_handle_domain_irq(priv->eiointc_domain, irq); 265 + generic_handle_domain_irq(info->priv->eiointc_domain, irq); 315 266 pending &= ~BIT(bit); 316 267 handled = true; 317 268 } ··· 511 462 } 512 463 513 464 eiointc_priv[nr_pics++] = priv; 465 + /* 466 + * Only the first eiointc device on VM supports routing to 467 + * different CPU interrupt pins. The later eiointc devices use 468 + * generic method if there are multiple eiointc devices in future 469 + */ 470 + if (cpu_has_hypervisor && (nr_pics == 1)) { 471 + priv->flags |= EIOINTC_ROUTE_MULT_IP; 472 + priv->parent_hwirq = INT_HWI0; 473 + } 474 + 475 + if (priv->flags & EIOINTC_ROUTE_MULT_IP) { 476 + for (i = 0; i < priv->vec_count / VEC_COUNT_PER_REG; i++) { 477 + priv->route_info[i].start = priv->parent_hwirq - INT_HWI0 + i; 478 + priv->route_info[i].end = priv->route_info[i].start + 1; 479 + priv->route_info[i].priv = priv; 480 + parent_irq = get_percpu_irq(priv->parent_hwirq + i); 481 + irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, 482 + &priv->route_info[i]); 483 + } 484 + } else { 485 + priv->route_info[0].start = 0; 486 + priv->route_info[0].end = priv->vec_count / VEC_COUNT_PER_REG; 487 + priv->route_info[0].priv = priv; 488 + irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, 489 + &priv->route_info[0]); 490 + } 514 491 eiointc_router_init(0); 515 - irq_set_chained_handler_and_data(parent_irq, eiointc_irq_dispatch, priv); 516 492 517 493 if (nr_pics == 1) { 518 494 register_syscore_ops(&eiointc_syscore_ops); ··· 569 495 570 496 priv->vec_count = VEC_COUNT; 571 497 priv->node = acpi_eiointc->node; 572 - 498 + priv->parent_hwirq = acpi_eiointc->cascade; 573 499 parent_irq = irq_create_mapping(parent, acpi_eiointc->cascade); 574 500 575 501 ret = eiointc_init(priv, parent_irq, acpi_eiointc->node_map); ··· 601 527 static int __init eiointc_of_init(struct device_node *of_node, 602 528 struct device_node *parent) 603 529 { 604 - int parent_irq, ret; 605 530 struct eiointc_priv *priv; 531 + struct irq_data *irq_data; 532 + int parent_irq, ret; 606 533 607 534 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 608 535 if (!priv) ··· 619 544 if (ret < 0) 620 545 goto out_free_priv; 621 546 547 + irq_data = irq_get_irq_data(parent_irq); 548 + if (!irq_data) { 549 + ret = -ENODEV; 550 + goto out_free_priv; 551 + } 552 + 622 553 /* 623 554 * In particular, the number of devices supported by the LS2K0500 624 555 * extended I/O interrupt vector is 128. ··· 633 552 priv->vec_count = 128; 634 553 else 635 554 priv->vec_count = VEC_COUNT; 636 - 555 + priv->parent_hwirq = irqd_to_hwirq(irq_data); 637 556 priv->node = 0; 638 557 priv->domain_handle = of_fwnode_handle(of_node); 639 558
+7 -2
drivers/irqchip/irq-loongson-pch-lpc.c
··· 200 200 goto iounmap_base; 201 201 } 202 202 203 - priv->lpc_domain = irq_domain_create_linear(irq_handle, LPC_COUNT, 204 - &pch_lpc_domain_ops, priv); 203 + /* 204 + * The LPC interrupt controller is a legacy i8259-compatible device, 205 + * which requires a static 1:1 mapping for IRQs 0-15. 206 + * Use irq_domain_create_legacy to establish this static mapping early. 207 + */ 208 + priv->lpc_domain = irq_domain_create_legacy(irq_handle, LPC_COUNT, 0, 0, 209 + &pch_lpc_domain_ops, priv); 205 210 if (!priv->lpc_domain) { 206 211 pr_err("Failed to create IRQ domain\n"); 207 212 goto free_irq_handle;
+14
drivers/irqchip/irq-msi-lib.c
··· 112 112 */ 113 113 if (!chip->irq_set_affinity && !(info->flags & MSI_FLAG_NO_AFFINITY)) 114 114 chip->irq_set_affinity = msi_domain_set_affinity; 115 + 116 + /* 117 + * If the parent domain insists on being in charge of masking, obey 118 + * blindly. The interrupt is un-masked at the PCI level on startup 119 + * and masked on shutdown to prevent rogue interrupts after the 120 + * driver freed the interrupt. Not masking it at the PCI level 121 + * speeds up operation for disable/enable_irq() as it avoids 122 + * getting all the way out to the PCI device. 123 + */ 124 + if (info->flags & MSI_FLAG_PCI_MSI_MASK_PARENT) { 125 + chip->irq_mask = irq_chip_mask_parent; 126 + chip->irq_unmask = irq_chip_unmask_parent; 127 + } 128 + 115 129 return true; 116 130 } 117 131 EXPORT_SYMBOL_GPL(msi_lib_init_dev_msi_info);
+2 -1
drivers/irqchip/irq-nvic.c
··· 73 73 struct device_node *parent) 74 74 { 75 75 unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; 76 - unsigned int irqs, i, ret, numbanks; 76 + unsigned int irqs, i, numbanks; 77 77 void __iomem *nvic_base; 78 + int ret; 78 79 79 80 numbanks = (readl_relaxed(V7M_SCS_ICTR) & 80 81 V7M_SCS_ICTR_INTLINESNUM_MASK) + 1;
+2 -1
drivers/irqchip/irq-renesas-rza1.c
··· 142 142 static int rza1_irqc_parse_map(struct rza1_irqc_priv *priv, 143 143 struct device_node *gic_node) 144 144 { 145 - unsigned int imaplen, i, j, ret; 146 145 struct device *dev = priv->dev; 146 + unsigned int imaplen, i, j; 147 147 struct device_node *ipar; 148 148 const __be32 *imap; 149 149 u32 intsize; 150 + int ret; 150 151 151 152 imap = of_get_property(dev->of_node, "interrupt-map", &imaplen); 152 153 if (!imap)
+1 -1
drivers/irqchip/irq-renesas-rzg2l.c
··· 578 578 &rzg2l_irqc_domain_ops, rzg2l_irqc_data); 579 579 if (!irq_domain) { 580 580 pm_runtime_put(dev); 581 - return dev_err_probe(dev, -ENOMEM, "failed to add irq domain\n"); 581 + return -ENOMEM; 582 582 } 583 583 584 584 register_syscore_ops(&rzg2l_irqc_syscore_ops);
+19 -7
drivers/irqchip/irq-sg2042-msi.c
··· 30 30 * @doorbell_addr: see TRM, 10.1.32, GP_INTR0_SET 31 31 * @irq_first: First vectors number that MSIs starts 32 32 * @num_irqs: Number of vectors for MSIs 33 + * @irq_type: IRQ type for MSIs 33 34 * @msi_map: mapping for allocated MSI vectors. 34 35 * @msi_map_lock: Lock for msi_map 35 36 * @chip_info: chip specific infomations ··· 42 41 43 42 u32 irq_first; 44 43 u32 num_irqs; 44 + unsigned int irq_type; 45 45 46 46 unsigned long *msi_map; 47 47 struct mutex msi_map_lock; ··· 87 85 88 86 static const struct irq_chip sg2042_msi_middle_irq_chip = { 89 87 .name = "SG2042 MSI", 88 + .irq_startup = irq_chip_startup_parent, 89 + .irq_shutdown = irq_chip_shutdown_parent, 90 90 .irq_ack = sg2042_msi_irq_ack, 91 91 .irq_mask = irq_chip_mask_parent, 92 92 .irq_unmask = irq_chip_unmask_parent, ··· 118 114 119 115 static struct irq_chip sg2044_msi_middle_irq_chip = { 120 116 .name = "SG2044 MSI", 117 + .irq_startup = irq_chip_startup_parent, 118 + .irq_shutdown = irq_chip_shutdown_parent, 121 119 .irq_ack = sg2044_msi_irq_ack, 122 120 .irq_mask = irq_chip_mask_parent, 123 121 .irq_unmask = irq_chip_unmask_parent, ··· 139 133 fwspec.fwnode = domain->parent->fwnode; 140 134 fwspec.param_count = 2; 141 135 fwspec.param[0] = data->irq_first + hwirq; 142 - fwspec.param[1] = IRQ_TYPE_EDGE_RISING; 136 + fwspec.param[1] = data->irq_type; 143 137 144 138 ret = irq_domain_alloc_irqs_parent(domain, virq, 1, &fwspec); 145 139 if (ret) 146 140 return ret; 147 141 148 142 d = irq_domain_get_irq_data(domain->parent, virq); 149 - return d->chip->irq_set_type(d, IRQ_TYPE_EDGE_RISING); 143 + return d->chip->irq_set_type(d, data->irq_type); 150 144 } 151 145 152 146 static int sg204x_msi_middle_domain_alloc(struct irq_domain *domain, unsigned int virq, ··· 191 185 .select = msi_lib_irq_domain_select, 192 186 }; 193 187 194 - #define SG2042_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 195 - MSI_FLAG_USE_DEF_CHIP_OPS) 188 + #define SG2042_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 189 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 190 + MSI_FLAG_PCI_MSI_MASK_PARENT | \ 191 + MSI_FLAG_PCI_MSI_STARTUP_PARENT) 196 192 197 193 #define SG2042_MSI_FLAGS_SUPPORTED MSI_GENERIC_FLAGS_MASK 198 194 ··· 208 200 .init_dev_msi_info = msi_lib_init_dev_msi_info, 209 201 }; 210 202 211 - #define SG2044_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 212 - MSI_FLAG_USE_DEF_CHIP_OPS) 203 + #define SG2044_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 204 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 205 + MSI_FLAG_PCI_MSI_MASK_PARENT | \ 206 + MSI_FLAG_PCI_MSI_STARTUP_PARENT) 213 207 214 - #define SG2044_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 208 + #define SG2044_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 209 + MSI_FLAG_MULTI_PCI_MSI | \ 215 210 MSI_FLAG_PCI_MSIX) 216 211 217 212 static const struct msi_parent_ops sg2044_msi_parent_ops = { ··· 300 289 } 301 290 302 291 data->irq_first = (u32)args.args[0]; 292 + data->irq_type = (unsigned int)args.args[1]; 303 293 data->num_irqs = (u32)args.args[args.nargs - 1]; 304 294 305 295 mutex_init(&data->msi_map_lock);
+6 -4
drivers/irqchip/irq-sifive-plic.c
··· 179 179 if (cpu >= nr_cpu_ids) 180 180 return -EINVAL; 181 181 182 - plic_irq_disable(d); 182 + /* Invalidate the original routing entry */ 183 + plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0); 183 184 184 185 irq_data_update_effective_affinity(d, cpumask_of(cpu)); 185 186 187 + /* Setting the new routing entry if irq is enabled */ 186 188 if (!irqd_irq_disabled(d)) 187 - plic_irq_enable(d); 189 + plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1); 188 190 189 191 return IRQ_SET_MASK_OK_DONE; 190 192 } ··· 259 257 readl(priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID)); 260 258 } 261 259 262 - for_each_cpu(cpu, cpu_present_mask) { 260 + for_each_present_cpu(cpu) { 263 261 struct plic_handler *handler = per_cpu_ptr(&plic_handlers, cpu); 264 262 265 263 if (!handler->present) ··· 291 289 priv->regs + PRIORITY_BASE + i * PRIORITY_PER_ID); 292 290 } 293 291 294 - for_each_cpu(cpu, cpu_present_mask) { 292 + for_each_present_cpu(cpu) { 295 293 struct plic_handler *handler = per_cpu_ptr(&plic_handlers, cpu); 296 294 297 295 if (!handler->present)
+45 -8
drivers/pci/msi/irqdomain.c
··· 148 148 arg->hwirq = desc->msi_index; 149 149 } 150 150 151 - static __always_inline void cond_mask_parent(struct irq_data *data) 151 + static void cond_shutdown_parent(struct irq_data *data) 152 152 { 153 153 struct msi_domain_info *info = data->domain->host_data; 154 154 155 - if (unlikely(info->flags & MSI_FLAG_PCI_MSI_MASK_PARENT)) 155 + if (unlikely(info->flags & MSI_FLAG_PCI_MSI_STARTUP_PARENT)) 156 + irq_chip_shutdown_parent(data); 157 + else if (unlikely(info->flags & MSI_FLAG_PCI_MSI_MASK_PARENT)) 156 158 irq_chip_mask_parent(data); 157 159 } 158 160 159 - static __always_inline void cond_unmask_parent(struct irq_data *data) 161 + static unsigned int cond_startup_parent(struct irq_data *data) 160 162 { 161 163 struct msi_domain_info *info = data->domain->host_data; 162 164 163 - if (unlikely(info->flags & MSI_FLAG_PCI_MSI_MASK_PARENT)) 165 + if (unlikely(info->flags & MSI_FLAG_PCI_MSI_STARTUP_PARENT)) 166 + return irq_chip_startup_parent(data); 167 + else if (unlikely(info->flags & MSI_FLAG_PCI_MSI_MASK_PARENT)) 164 168 irq_chip_unmask_parent(data); 169 + 170 + return 0; 171 + } 172 + 173 + static void pci_irq_shutdown_msi(struct irq_data *data) 174 + { 175 + struct msi_desc *desc = irq_data_get_msi_desc(data); 176 + 177 + pci_msi_mask(desc, BIT(data->irq - desc->irq)); 178 + cond_shutdown_parent(data); 179 + } 180 + 181 + static unsigned int pci_irq_startup_msi(struct irq_data *data) 182 + { 183 + struct msi_desc *desc = irq_data_get_msi_desc(data); 184 + unsigned int ret = cond_startup_parent(data); 185 + 186 + pci_msi_unmask(desc, BIT(data->irq - desc->irq)); 187 + return ret; 165 188 } 166 189 167 190 static void pci_irq_mask_msi(struct irq_data *data) ··· 192 169 struct msi_desc *desc = irq_data_get_msi_desc(data); 193 170 194 171 pci_msi_mask(desc, BIT(data->irq - desc->irq)); 195 - cond_mask_parent(data); 196 172 } 197 173 198 174 static void pci_irq_unmask_msi(struct irq_data *data) 199 175 { 200 176 struct msi_desc *desc = irq_data_get_msi_desc(data); 201 177 202 - cond_unmask_parent(data); 203 178 pci_msi_unmask(desc, BIT(data->irq - desc->irq)); 204 179 } 205 180 ··· 215 194 static const struct msi_domain_template pci_msi_template = { 216 195 .chip = { 217 196 .name = "PCI-MSI", 197 + .irq_startup = pci_irq_startup_msi, 198 + .irq_shutdown = pci_irq_shutdown_msi, 218 199 .irq_mask = pci_irq_mask_msi, 219 200 .irq_unmask = pci_irq_unmask_msi, 220 201 .irq_write_msi_msg = pci_msi_domain_write_msg, ··· 233 210 }, 234 211 }; 235 212 213 + static void pci_irq_shutdown_msix(struct irq_data *data) 214 + { 215 + pci_msix_mask(irq_data_get_msi_desc(data)); 216 + cond_shutdown_parent(data); 217 + } 218 + 219 + static unsigned int pci_irq_startup_msix(struct irq_data *data) 220 + { 221 + unsigned int ret = cond_startup_parent(data); 222 + 223 + pci_msix_unmask(irq_data_get_msi_desc(data)); 224 + return ret; 225 + } 226 + 236 227 static void pci_irq_mask_msix(struct irq_data *data) 237 228 { 238 229 pci_msix_mask(irq_data_get_msi_desc(data)); 239 - cond_mask_parent(data); 240 230 } 241 231 242 232 static void pci_irq_unmask_msix(struct irq_data *data) 243 233 { 244 - cond_unmask_parent(data); 245 234 pci_msix_unmask(irq_data_get_msi_desc(data)); 246 235 } 247 236 ··· 269 234 static const struct msi_domain_template pci_msix_template = { 270 235 .chip = { 271 236 .name = "PCI-MSIX", 237 + .irq_startup = pci_irq_startup_msix, 238 + .irq_shutdown = pci_irq_shutdown_msix, 272 239 .irq_mask = pci_irq_mask_msix, 273 240 .irq_unmask = pci_irq_unmask_msix, 274 241 .irq_write_msi_msg = pci_msi_domain_write_msg,
+14
include/dt-bindings/interrupt-controller/aspeed-scu-ic.h
··· 20 20 #define ASPEED_AST2600_SCU_IC1_LPC_RESET_LO_TO_HI 0 21 21 #define ASPEED_AST2600_SCU_IC1_LPC_RESET_HI_TO_LO 1 22 22 23 + #define ASPEED_AST2700_SCU_IC0_PCIE_PERST_LO_TO_HI 3 24 + #define ASPEED_AST2700_SCU_IC0_PCIE_PERST_HI_TO_LO 2 25 + 26 + #define ASPEED_AST2700_SCU_IC1_PCIE_RCRST_LO_TO_HI 3 27 + #define ASPEED_AST2700_SCU_IC1_PCIE_RCRST_HI_TO_LO 2 28 + 29 + #define ASPEED_AST2700_SCU_IC2_PCIE_PERST_LO_TO_HI 3 30 + #define ASPEED_AST2700_SCU_IC2_PCIE_PERST_HI_TO_LO 2 31 + #define ASPEED_AST2700_SCU_IC2_LPC_RESET_LO_TO_HI 1 32 + #define ASPEED_AST2700_SCU_IC2_LPC_RESET_HI_TO_LO 0 33 + 34 + #define ASPEED_AST2700_SCU_IC3_LPC_RESET_LO_TO_HI 1 35 + #define ASPEED_AST2700_SCU_IC3_LPC_RESET_HI_TO_LO 0 36 + 23 37 #endif /* _DT_BINDINGS_INTERRUPT_CONTROLLER_ASPEED_SCU_IC_H_ */
+2
include/linux/msi.h
··· 564 564 MSI_FLAG_PARENT_PM_DEV = (1 << 8), 565 565 /* Support for parent mask/unmask */ 566 566 MSI_FLAG_PCI_MSI_MASK_PARENT = (1 << 9), 567 + /* Support for parent startup/shutdown */ 568 + MSI_FLAG_PCI_MSI_STARTUP_PARENT = (1 << 10), 567 569 568 570 /* Mask for the generic functionality */ 569 571 MSI_GENERIC_FLAGS_MASK = GENMASK(15, 0),