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

Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fixes from Thomas Gleixner:
"This contains:

- a series of fixes for interrupt drivers to prevent a potential race
when installing a chained interrupt handler

- a fix for cpumask pointer misuse

- a fix for using the wrong interrupt number from struct irq_data

- removal of unused code and outdated comments

- a few new helper functions which allow us to cleanup the interrupt
handling code further in 4.3

I decided against doing the cleanup at the end of this merge window
and rather do the preparatory steps for 4.3, so we can run the final
ABI change at the end of the 4.3 merge window with less risk"

* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (26 commits)
ARM/LPC32xx: Use irq not hwirq for __irq_set_handler_locked()
genirq: Implement irq_set_handler_locked()/irq_set_chip_handler_name_locked()
genirq: Introduce helper irq_desc_get_irq()
genirq: Remove irq_node()
genirq: Clean up outdated comments related to include/linux/irqdesc.h
mn10300: Fix incorrect use of irq_data->affinity
MIPS/ralink: Fix race in installing chained IRQ handler
MIPS/pci: Fix race in installing chained IRQ handler
MIPS/ath25: Fix race in installing chained IRQ handler
MIPS/ath25: Fix race in installing chained IRQ handler
m68k/psc: Fix race in installing chained IRQ handler
avr32/at32ap: Fix race in installing chained IRQ handler
sh/intc: Fix race in installing chained IRQ handler
sh/intc: Fix potential race in installing chained IRQ handler
pinctrl/sun4i: Fix race in installing chained IRQ handler
pinctrl/samsung: Fix race in installing chained IRQ handler
pinctrl/samsung: Fix race in installing chained IRQ handler
pinctrl/exynos: Fix race in installing chained IRQ handler
pinctrl/st: Fix race in installing chained IRQ handler
pinctrl/adi2: Fix race in installing chained IRQ handler
...

+95 -67
+4 -4
arch/arm/mach-lpc32xx/irq.c
··· 283 283 case IRQ_TYPE_EDGE_RISING: 284 284 /* Rising edge sensitive */ 285 285 __lpc32xx_set_irq_type(d->hwirq, 1, 1); 286 - __irq_set_handler_locked(d->hwirq, handle_edge_irq); 286 + __irq_set_handler_locked(d->irq, handle_edge_irq); 287 287 break; 288 288 289 289 case IRQ_TYPE_EDGE_FALLING: 290 290 /* Falling edge sensitive */ 291 291 __lpc32xx_set_irq_type(d->hwirq, 0, 1); 292 - __irq_set_handler_locked(d->hwirq, handle_edge_irq); 292 + __irq_set_handler_locked(d->irq, handle_edge_irq); 293 293 break; 294 294 295 295 case IRQ_TYPE_LEVEL_LOW: 296 296 /* Low level sensitive */ 297 297 __lpc32xx_set_irq_type(d->hwirq, 0, 0); 298 - __irq_set_handler_locked(d->hwirq, handle_level_irq); 298 + __irq_set_handler_locked(d->irq, handle_level_irq); 299 299 break; 300 300 301 301 case IRQ_TYPE_LEVEL_HIGH: 302 302 /* High level sensitive */ 303 303 __lpc32xx_set_irq_type(d->hwirq, 1, 0); 304 - __irq_set_handler_locked(d->hwirq, handle_level_irq); 304 + __irq_set_handler_locked(d->irq, handle_level_irq); 305 305 break; 306 306 307 307 /* Other modes are not supported */
+1 -2
arch/avr32/mach-at32ap/extint.c
··· 231 231 irq_set_chip_data(eic->first_irq + i, eic); 232 232 } 233 233 234 - irq_set_chained_handler(int_irq, demux_eic_irq); 235 - irq_set_handler_data(int_irq, eic); 234 + irq_set_chained_handler_and_data(int_irq, demux_eic_irq, eic); 236 235 237 236 if (pdev->id == 0) { 238 237 nmi_eic = eic;
+4 -8
arch/m68k/mac/psc.c
··· 148 148 149 149 void __init psc_register_interrupts(void) 150 150 { 151 - irq_set_chained_handler(IRQ_AUTO_3, psc_irq); 152 - irq_set_handler_data(IRQ_AUTO_3, (void *)0x30); 153 - irq_set_chained_handler(IRQ_AUTO_4, psc_irq); 154 - irq_set_handler_data(IRQ_AUTO_4, (void *)0x40); 155 - irq_set_chained_handler(IRQ_AUTO_5, psc_irq); 156 - irq_set_handler_data(IRQ_AUTO_5, (void *)0x50); 157 - irq_set_chained_handler(IRQ_AUTO_6, psc_irq); 158 - irq_set_handler_data(IRQ_AUTO_6, (void *)0x60); 151 + irq_set_chained_handler_and_data(IRQ_AUTO_3, psc_irq, (void *)0x30); 152 + irq_set_chained_handler_and_data(IRQ_AUTO_4, psc_irq, (void *)0x40); 153 + irq_set_chained_handler_and_data(IRQ_AUTO_5, psc_irq, (void *)0x50); 154 + irq_set_chained_handler_and_data(IRQ_AUTO_6, psc_irq, (void *)0x60); 159 155 } 160 156 161 157 void psc_irq_enable(int irq) {
+2 -2
arch/mips/ath25/ar2315.c
··· 161 161 irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB); 162 162 setup_irq(irq, &ar2315_ahb_err_interrupt); 163 163 164 - irq_set_chained_handler(AR2315_IRQ_MISC, ar2315_misc_irq_handler); 165 - irq_set_handler_data(AR2315_IRQ_MISC, domain); 164 + irq_set_chained_handler_and_data(AR2315_IRQ_MISC, 165 + ar2315_misc_irq_handler, domain); 166 166 167 167 ar2315_misc_irq_domain = domain; 168 168 }
+2 -2
arch/mips/ath25/ar5312.c
··· 156 156 irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC); 157 157 setup_irq(irq, &ar5312_ahb_err_interrupt); 158 158 159 - irq_set_chained_handler(AR5312_IRQ_MISC, ar5312_misc_irq_handler); 160 - irq_set_handler_data(AR5312_IRQ_MISC, domain); 159 + irq_set_chained_handler_and_data(AR5312_IRQ_MISC, 160 + ar5312_misc_irq_handler, domain); 161 161 162 162 ar5312_misc_irq_domain = domain; 163 163 }
+2 -2
arch/mips/pci/pci-ar2315.c
··· 384 384 385 385 apc->irq_ext = irq_create_mapping(apc->domain, AR2315_PCI_IRQ_EXT); 386 386 387 - irq_set_chained_handler(apc->irq, ar2315_pci_irq_handler); 388 - irq_set_handler_data(apc->irq, apc); 387 + irq_set_chained_handler_and_data(apc->irq, ar2315_pci_irq_handler, 388 + apc); 389 389 390 390 /* Clear any pending Abort or external Interrupts 391 391 * and enable interrupt processing */
+1 -2
arch/mips/ralink/irq.c
··· 184 184 185 185 rt_intc_w32(INTC_INT_GLOBAL, INTC_REG_ENABLE); 186 186 187 - irq_set_chained_handler(irq, ralink_intc_irq_handler); 188 - irq_set_handler_data(irq, domain); 187 + irq_set_chained_handler_and_data(irq, ralink_intc_irq_handler, domain); 189 188 190 189 /* tell the kernel which irq is used for performance monitoring */ 191 190 rt_perfcount_irq = irq_create_mapping(domain, 9);
+3 -3
arch/mn10300/kernel/irq.c
··· 320 320 if (irqd_is_per_cpu(data)) 321 321 continue; 322 322 323 - if (cpumask_test_cpu(self, &data->affinity) && 323 + if (cpumask_test_cpu(self, data->affinity) && 324 324 !cpumask_intersects(&irq_affinity[irq], cpu_online_mask)) { 325 325 int cpu_id; 326 326 cpu_id = cpumask_first(cpu_online_mask); 327 - cpumask_set_cpu(cpu_id, &data->affinity); 327 + cpumask_set_cpu(cpu_id, data->affinity); 328 328 } 329 329 /* We need to operate irq_affinity_online atomically. */ 330 330 arch_local_cli_save(flags); ··· 335 335 GxICR(irq) = x & GxICR_LEVEL; 336 336 tmp = GxICR(irq); 337 337 338 - new = cpumask_any_and(&data->affinity, 338 + new = cpumask_any_and(data->affinity, 339 339 cpu_online_mask); 340 340 irq_affinity_online[irq] = new; 341 341
+3 -2
drivers/gpio/gpio-bcm-kona.c
··· 657 657 } 658 658 for (i = 0; i < kona_gpio->num_bank; i++) { 659 659 bank = &kona_gpio->banks[i]; 660 - irq_set_chained_handler(bank->irq, bcm_kona_gpio_irq_handler); 661 - irq_set_handler_data(bank->irq, bank); 660 + irq_set_chained_handler_and_data(bank->irq, 661 + bcm_kona_gpio_irq_handler, 662 + bank); 662 663 } 663 664 664 665 spin_lock_init(&kona_gpio->lock);
+2 -2
drivers/gpio/gpio-dwapb.c
··· 348 348 irq_gc->chip_types[1].handler = handle_edge_irq; 349 349 350 350 if (!pp->irq_shared) { 351 - irq_set_chained_handler(pp->irq, dwapb_irq_handler); 352 - irq_set_handler_data(pp->irq, gpio); 351 + irq_set_chained_handler_and_data(pp->irq, dwapb_irq_handler, 352 + gpio); 353 353 } else { 354 354 /* 355 355 * Request a shared IRQ since where MFD would have devices
+1 -2
drivers/gpio/gpio-msic.c
··· 309 309 &msic_irqchip, 310 310 handle_simple_irq); 311 311 } 312 - irq_set_chained_handler(mg->irq, msic_gpio_irq_handler); 313 - irq_set_handler_data(mg->irq, mg); 312 + irq_set_chained_handler_and_data(mg->irq, msic_gpio_irq_handler, mg); 314 313 315 314 return 0; 316 315 err:
+1 -2
drivers/mfd/asic3.c
··· 417 417 asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK), 418 418 ASIC3_INTMASK_GINTMASK); 419 419 420 - irq_set_chained_handler(asic->irq_nr, asic3_irq_demux); 420 + irq_set_chained_handler_and_data(asic->irq_nr, asic3_irq_demux, asic); 421 421 irq_set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING); 422 - irq_set_handler_data(asic->irq_nr, asic); 423 422 424 423 return 0; 425 424 }
+3 -4
drivers/pci/host/pci-keystone.c
··· 221 221 /* MSI IRQ */ 222 222 if (IS_ENABLED(CONFIG_PCI_MSI)) { 223 223 for (i = 0; i < ks_pcie->num_msi_host_irqs; i++) { 224 - irq_set_chained_handler(ks_pcie->msi_host_irqs[i], 225 - ks_pcie_msi_irq_handler); 226 - irq_set_handler_data(ks_pcie->msi_host_irqs[i], 227 - ks_pcie); 224 + irq_set_chained_handler_and_data(ks_pcie->msi_host_irqs[i], 225 + ks_pcie_msi_irq_handler, 226 + ks_pcie); 228 227 } 229 228 } 230 229 }
+1 -2
drivers/pinctrl/mediatek/pinctrl-mtk-common.c
··· 1351 1351 set_irq_flags(virq, IRQF_VALID); 1352 1352 }; 1353 1353 1354 - irq_set_chained_handler(irq, mtk_eint_irq_handler); 1355 - irq_set_handler_data(irq, pctl); 1354 + irq_set_chained_handler_and_data(irq, mtk_eint_irq_handler, pctl); 1356 1355 set_irq_flags(irq, IRQF_VALID); 1357 1356 return 0; 1358 1357
+2 -2
drivers/pinctrl/pinctrl-adi2.c
··· 865 865 pint->pint_map_port = adi_pint_map_port; 866 866 platform_set_drvdata(pdev, pint); 867 867 868 - irq_set_chained_handler(pint->irq, adi_gpio_handle_pint_irq); 869 - irq_set_handler_data(pint->irq, pint); 868 + irq_set_chained_handler_and_data(pint->irq, adi_gpio_handle_pint_irq, 869 + pint); 870 870 871 871 list_add_tail(&pint->node, &adi_pint_list); 872 872
+2 -2
drivers/pinctrl/pinctrl-st.c
··· 1661 1661 if (IS_ERR(info->irqmux_base)) 1662 1662 return PTR_ERR(info->irqmux_base); 1663 1663 1664 - irq_set_chained_handler(irq, st_gpio_irqmux_handler); 1665 - irq_set_handler_data(irq, info); 1664 + irq_set_chained_handler_and_data(irq, st_gpio_irqmux_handler, 1665 + info); 1666 1666 1667 1667 } 1668 1668
+2 -2
drivers/pinctrl/samsung/pinctrl-exynos.c
··· 563 563 return -ENOMEM; 564 564 } 565 565 566 - irq_set_chained_handler(irq, exynos_irq_demux_eint16_31); 567 - irq_set_handler_data(irq, muxed_data); 566 + irq_set_chained_handler_and_data(irq, exynos_irq_demux_eint16_31, 567 + muxed_data); 568 568 569 569 bank = d->pin_banks; 570 570 idx = 0;
+1 -2
drivers/pinctrl/samsung/pinctrl-s3c24xx.c
··· 514 514 } 515 515 516 516 eint_data->parents[i] = irq; 517 - irq_set_chained_handler(irq, handlers[i]); 518 - irq_set_handler_data(irq, eint_data); 517 + irq_set_chained_handler_and_data(irq, handlers[i], eint_data); 519 518 } 520 519 521 520 bank = d->pin_banks;
+4 -4
drivers/pinctrl/samsung/pinctrl-s3c64xx.c
··· 506 506 data->domains[nr_domains++] = bank->irq_domain; 507 507 } 508 508 509 - irq_set_chained_handler(d->irq, s3c64xx_eint_gpio_irq); 510 - irq_set_handler_data(d->irq, data); 509 + irq_set_chained_handler_and_data(d->irq, s3c64xx_eint_gpio_irq, data); 511 510 512 511 return 0; 513 512 } ··· 730 731 return -ENXIO; 731 732 } 732 733 733 - irq_set_chained_handler(irq, s3c64xx_eint0_handlers[i]); 734 - irq_set_handler_data(irq, data); 734 + irq_set_chained_handler_and_data(irq, 735 + s3c64xx_eint0_handlers[i], 736 + data); 735 737 } 736 738 737 739 bank = d->pin_banks;
+3 -3
drivers/pinctrl/sunxi/pinctrl-sunxi.c
··· 1005 1005 writel(0xffffffff, 1006 1006 pctl->membase + sunxi_irq_status_reg_from_bank(i)); 1007 1007 1008 - irq_set_chained_handler(pctl->irq[i], 1009 - sunxi_pinctrl_irq_handler); 1010 - irq_set_handler_data(pctl->irq[i], pctl); 1008 + irq_set_chained_handler_and_data(pctl->irq[i], 1009 + sunxi_pinctrl_irq_handler, 1010 + pctl); 1011 1011 } 1012 1012 1013 1013 dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
+3 -2
drivers/sh/intc/core.c
··· 366 366 367 367 /* redirect this interrupts to the first one */ 368 368 irq_set_chip(irq2, &dummy_irq_chip); 369 - irq_set_chained_handler(irq2, intc_redirect_irq); 370 - irq_set_handler_data(irq2, (void *)irq); 369 + irq_set_chained_handler_and_data(irq2, 370 + intc_redirect_irq, 371 + (void *)irq); 371 372 } 372 373 } 373 374
+2 -1
drivers/sh/intc/virq.c
··· 243 243 */ 244 244 irq_set_nothread(irq); 245 245 246 - irq_set_chained_handler(entry->pirq, intc_virq_handler); 246 + /* Set handler data before installing the handler */ 247 247 add_virq_to_pirq(entry->pirq, irq); 248 + irq_set_chained_handler(entry->pirq, intc_virq_handler); 248 249 249 250 radix_tree_tag_clear(&d->tree, entry->enum_id, 250 251 INTC_TAG_VIRQ_NEEDS_ALLOC);
-1
include/linux/irq.h
··· 407 407 IRQCHIP_EOI_THREADED = (1 << 6), 408 408 }; 409 409 410 - /* This include will go away once we isolated irq_desc usage to core code */ 411 410 #include <linux/irqdesc.h> 412 411 413 412 /*
+46 -3
include/linux/irqdesc.h
··· 3 3 4 4 /* 5 5 * Core internal functions to deal with irq descriptors 6 - * 7 - * This include will move to kernel/irq once we cleaned up the tree. 8 - * For now it's included from <linux/irq.h> 9 6 */ 10 7 11 8 struct irq_affinity_notify; ··· 100 103 #endif 101 104 } 102 105 106 + static inline unsigned int irq_desc_get_irq(struct irq_desc *desc) 107 + { 108 + return desc->irq_data.irq; 109 + } 110 + 103 111 static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc) 104 112 { 105 113 return &desc->irq_data; ··· 188 186 irq_desc_get_irq_data(desc)->chip = chip; 189 187 desc->handle_irq = handler; 190 188 desc->name = name; 189 + } 190 + 191 + /** 192 + * irq_set_handler_locked - Set irq handler from a locked region 193 + * @data: Pointer to the irq_data structure which identifies the irq 194 + * @handler: Flow control handler function for this interrupt 195 + * 196 + * Sets the handler in the irq descriptor associated to @data. 197 + * 198 + * Must be called with irq_desc locked and valid parameters. Typical 199 + * call site is the irq_set_type() callback. 200 + */ 201 + static inline void irq_set_handler_locked(struct irq_data *data, 202 + irq_flow_handler_t handler) 203 + { 204 + struct irq_desc *desc = irq_data_to_desc(data); 205 + 206 + desc->handle_irq = handler; 207 + } 208 + 209 + /** 210 + * irq_set_chip_handler_name_locked - Set chip, handler and name from a locked region 211 + * @data: Pointer to the irq_data structure for which the chip is set 212 + * @chip: Pointer to the new irq chip 213 + * @handler: Flow control handler function for this interrupt 214 + * @name: Name of the interrupt 215 + * 216 + * Replace the irq chip at the proper hierarchy level in @data and 217 + * sets the handler and name in the associated irq descriptor. 218 + * 219 + * Must be called with irq_desc locked and valid parameters. 220 + */ 221 + static inline void 222 + irq_set_chip_handler_name_locked(struct irq_data *data, struct irq_chip *chip, 223 + irq_flow_handler_t handler, const char *name) 224 + { 225 + struct irq_desc *desc = irq_data_to_desc(data); 226 + 227 + desc->handle_irq = handler; 228 + desc->name = name; 229 + data->chip = chip; 191 230 } 192 231 193 232 static inline int irq_balancing_disabled(unsigned int irq)
-6
include/linux/irqnr.h
··· 23 23 ; \ 24 24 else 25 25 26 - #ifdef CONFIG_SMP 27 - #define irq_node(irq) (irq_get_irq_data(irq)->node) 28 - #else 29 - #define irq_node(irq) 0 30 - #endif 31 - 32 26 # define for_each_active_irq(irq) \ 33 27 for (irq = irq_get_next_irq(0); irq < nr_irqs; \ 34 28 irq = irq_get_next_irq(irq + 1))