diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c
index 9ecb8f9c4ef5..d4f7dc87042b 100644
--- a/arch/arm/mach-lpc32xx/irq.c
+++ b/arch/arm/mach-lpc32xx/irq.c
@@ -283,25 +283,25 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type)
 	case IRQ_TYPE_EDGE_RISING:
 		/* Rising edge sensitive */
 		__lpc32xx_set_irq_type(d->hwirq, 1, 1);
-		__irq_set_handler_locked(d->hwirq, handle_edge_irq);
+		__irq_set_handler_locked(d->irq, handle_edge_irq);
 		break;
 
 	case IRQ_TYPE_EDGE_FALLING:
 		/* Falling edge sensitive */
 		__lpc32xx_set_irq_type(d->hwirq, 0, 1);
-		__irq_set_handler_locked(d->hwirq, handle_edge_irq);
+		__irq_set_handler_locked(d->irq, handle_edge_irq);
 		break;
 
 	case IRQ_TYPE_LEVEL_LOW:
 		/* Low level sensitive */
 		__lpc32xx_set_irq_type(d->hwirq, 0, 0);
-		__irq_set_handler_locked(d->hwirq, handle_level_irq);
+		__irq_set_handler_locked(d->irq, handle_level_irq);
 		break;
 
 	case IRQ_TYPE_LEVEL_HIGH:
 		/* High level sensitive */
 		__lpc32xx_set_irq_type(d->hwirq, 1, 0);
-		__irq_set_handler_locked(d->hwirq, handle_level_irq);
+		__irq_set_handler_locked(d->irq, handle_level_irq);
 		break;
 
 	/* Other modes are not supported */
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index cfb298d66305..2d48b6a46166 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -231,8 +231,7 @@ static int __init eic_probe(struct platform_device *pdev)
 		irq_set_chip_data(eic->first_irq + i, eic);
 	}
 
-	irq_set_chained_handler(int_irq, demux_eic_irq);
-	irq_set_handler_data(int_irq, eic);
+	irq_set_chained_handler_and_data(int_irq, demux_eic_irq, eic);
 
 	if (pdev->id == 0) {
 		nmi_eic = eic;
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
index 835fa04511c8..272dde481d17 100644
--- a/arch/m68k/mac/psc.c
+++ b/arch/m68k/mac/psc.c
@@ -148,14 +148,10 @@ static void psc_irq(unsigned int irq, struct irq_desc *desc)
 
 void __init psc_register_interrupts(void)
 {
-	irq_set_chained_handler(IRQ_AUTO_3, psc_irq);
-	irq_set_handler_data(IRQ_AUTO_3, (void *)0x30);
-	irq_set_chained_handler(IRQ_AUTO_4, psc_irq);
-	irq_set_handler_data(IRQ_AUTO_4, (void *)0x40);
-	irq_set_chained_handler(IRQ_AUTO_5, psc_irq);
-	irq_set_handler_data(IRQ_AUTO_5, (void *)0x50);
-	irq_set_chained_handler(IRQ_AUTO_6, psc_irq);
-	irq_set_handler_data(IRQ_AUTO_6, (void *)0x60);
+	irq_set_chained_handler_and_data(IRQ_AUTO_3, psc_irq, (void *)0x30);
+	irq_set_chained_handler_and_data(IRQ_AUTO_4, psc_irq, (void *)0x40);
+	irq_set_chained_handler_and_data(IRQ_AUTO_5, psc_irq, (void *)0x50);
+	irq_set_chained_handler_and_data(IRQ_AUTO_6, psc_irq, (void *)0x60);
 }
 
 void psc_irq_enable(int irq) {
diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c
index 8742e1cee492..ec9a371f1e62 100644
--- a/arch/mips/ath25/ar2315.c
+++ b/arch/mips/ath25/ar2315.c
@@ -161,8 +161,8 @@ void __init ar2315_arch_init_irq(void)
 	irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB);
 	setup_irq(irq, &ar2315_ahb_err_interrupt);
 
-	irq_set_chained_handler(AR2315_IRQ_MISC, ar2315_misc_irq_handler);
-	irq_set_handler_data(AR2315_IRQ_MISC, domain);
+	irq_set_chained_handler_and_data(AR2315_IRQ_MISC,
+					 ar2315_misc_irq_handler, domain);
 
 	ar2315_misc_irq_domain = domain;
 }
diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c
index 094b938fd603..e63e38fa4880 100644
--- a/arch/mips/ath25/ar5312.c
+++ b/arch/mips/ath25/ar5312.c
@@ -156,8 +156,8 @@ void __init ar5312_arch_init_irq(void)
 	irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC);
 	setup_irq(irq, &ar5312_ahb_err_interrupt);
 
-	irq_set_chained_handler(AR5312_IRQ_MISC, ar5312_misc_irq_handler);
-	irq_set_handler_data(AR5312_IRQ_MISC, domain);
+	irq_set_chained_handler_and_data(AR5312_IRQ_MISC,
+					 ar5312_misc_irq_handler, domain);
 
 	ar5312_misc_irq_domain = domain;
 }
diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c
index dadb30306a0a..f8d0acb4f973 100644
--- a/arch/mips/pci/pci-ar2315.c
+++ b/arch/mips/pci/pci-ar2315.c
@@ -384,8 +384,8 @@ static void ar2315_pci_irq_init(struct ar2315_pci_ctrl *apc)
 
 	apc->irq_ext = irq_create_mapping(apc->domain, AR2315_PCI_IRQ_EXT);
 
-	irq_set_chained_handler(apc->irq, ar2315_pci_irq_handler);
-	irq_set_handler_data(apc->irq, apc);
+	irq_set_chained_handler_and_data(apc->irq, ar2315_pci_irq_handler,
+					 apc);
 
 	/* Clear any pending Abort or external Interrupts
 	 * and enable interrupt processing */
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c
index da301e0a2f1f..53707aacc0f8 100644
--- a/arch/mips/ralink/irq.c
+++ b/arch/mips/ralink/irq.c
@@ -184,8 +184,7 @@ static int __init intc_of_init(struct device_node *node,
 
 	rt_intc_w32(INTC_INT_GLOBAL, INTC_REG_ENABLE);
 
-	irq_set_chained_handler(irq, ralink_intc_irq_handler);
-	irq_set_handler_data(irq, domain);
+	irq_set_chained_handler_and_data(irq, ralink_intc_irq_handler, domain);
 
 	/* tell the kernel which irq is used for performance monitoring */
 	rt_perfcount_irq = irq_create_mapping(domain, 9);
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index 6ab3b73efcf8..480de70f4059 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -320,11 +320,11 @@ void migrate_irqs(void)
 		if (irqd_is_per_cpu(data))
 			continue;
 
-		if (cpumask_test_cpu(self, &data->affinity) &&
+		if (cpumask_test_cpu(self, data->affinity) &&
 		    !cpumask_intersects(&irq_affinity[irq], cpu_online_mask)) {
 			int cpu_id;
 			cpu_id = cpumask_first(cpu_online_mask);
-			cpumask_set_cpu(cpu_id, &data->affinity);
+			cpumask_set_cpu(cpu_id, data->affinity);
 		}
 		/* We need to operate irq_affinity_online atomically. */
 		arch_local_cli_save(flags);
@@ -335,7 +335,7 @@ void migrate_irqs(void)
 			GxICR(irq) = x & GxICR_LEVEL;
 			tmp = GxICR(irq);
 
-			new = cpumask_any_and(&data->affinity,
+			new = cpumask_any_and(data->affinity,
 					      cpu_online_mask);
 			irq_affinity_online[irq] = new;
 
diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c
index 8333f878919c..40343fa92c7b 100644
--- a/drivers/gpio/gpio-bcm-kona.c
+++ b/drivers/gpio/gpio-bcm-kona.c
@@ -657,8 +657,9 @@ static int bcm_kona_gpio_probe(struct platform_device *pdev)
 	}
 	for (i = 0; i < kona_gpio->num_bank; i++) {
 		bank = &kona_gpio->banks[i];
-		irq_set_chained_handler(bank->irq, bcm_kona_gpio_irq_handler);
-		irq_set_handler_data(bank->irq, bank);
+		irq_set_chained_handler_and_data(bank->irq,
+						 bcm_kona_gpio_irq_handler,
+						 bank);
 	}
 
 	spin_lock_init(&kona_gpio->lock);
diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 58faf04fce5d..55fa9853a7f2 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -348,8 +348,8 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
 	irq_gc->chip_types[1].handler = handle_edge_irq;
 
 	if (!pp->irq_shared) {
-		irq_set_chained_handler(pp->irq, dwapb_irq_handler);
-		irq_set_handler_data(pp->irq, gpio);
+		irq_set_chained_handler_and_data(pp->irq, dwapb_irq_handler,
+						 gpio);
 	} else {
 		/*
 		 * Request a shared IRQ since where MFD would have devices
diff --git a/drivers/gpio/gpio-msic.c b/drivers/gpio/gpio-msic.c
index 01acf0a8cdb1..7bcfb87a5fa6 100644
--- a/drivers/gpio/gpio-msic.c
+++ b/drivers/gpio/gpio-msic.c
@@ -309,8 +309,7 @@ static int platform_msic_gpio_probe(struct platform_device *pdev)
 					 &msic_irqchip,
 					 handle_simple_irq);
 	}
-	irq_set_chained_handler(mg->irq, msic_gpio_irq_handler);
-	irq_set_handler_data(mg->irq, mg);
+	irq_set_chained_handler_and_data(mg->irq, msic_gpio_irq_handler, mg);
 
 	return 0;
 err:
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 977bd3a3eed0..120df5c08741 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -417,9 +417,8 @@ static int __init asic3_irq_probe(struct platform_device *pdev)
 	asic3_write_register(asic, ASIC3_OFFSET(INTR, INT_MASK),
 			     ASIC3_INTMASK_GINTMASK);
 
-	irq_set_chained_handler(asic->irq_nr, asic3_irq_demux);
+	irq_set_chained_handler_and_data(asic->irq_nr, asic3_irq_demux, asic);
 	irq_set_irq_type(asic->irq_nr, IRQ_TYPE_EDGE_RISING);
-	irq_set_handler_data(asic->irq_nr, asic);
 
 	return 0;
 }
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
index b75d684aefcd..734da589cdfb 100644
--- a/drivers/pci/host/pci-keystone.c
+++ b/drivers/pci/host/pci-keystone.c
@@ -221,10 +221,9 @@ static void ks_pcie_setup_interrupts(struct keystone_pcie *ks_pcie)
 	/* MSI IRQ */
 	if (IS_ENABLED(CONFIG_PCI_MSI)) {
 		for (i = 0; i < ks_pcie->num_msi_host_irqs; i++) {
-			irq_set_chained_handler(ks_pcie->msi_host_irqs[i],
-						ks_pcie_msi_irq_handler);
-			irq_set_handler_data(ks_pcie->msi_host_irqs[i],
-					     ks_pcie);
+			irq_set_chained_handler_and_data(ks_pcie->msi_host_irqs[i],
+							 ks_pcie_msi_irq_handler,
+							 ks_pcie);
 		}
 	}
 }
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index c4fc77aa766e..ad1ea1695b4a 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -1351,8 +1351,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
 		set_irq_flags(virq, IRQF_VALID);
 	};
 
-	irq_set_chained_handler(irq, mtk_eint_irq_handler);
-	irq_set_handler_data(irq, pctl);
+	irq_set_chained_handler_and_data(irq, mtk_eint_irq_handler, pctl);
 	set_irq_flags(irq, IRQF_VALID);
 	return 0;
 
diff --git a/drivers/pinctrl/pinctrl-adi2.c b/drivers/pinctrl/pinctrl-adi2.c
index 873433da0f2c..c3c3d2345fc6 100644
--- a/drivers/pinctrl/pinctrl-adi2.c
+++ b/drivers/pinctrl/pinctrl-adi2.c
@@ -865,8 +865,8 @@ static int adi_gpio_pint_probe(struct platform_device *pdev)
 	pint->pint_map_port = adi_pint_map_port;
 	platform_set_drvdata(pdev, pint);
 
-	irq_set_chained_handler(pint->irq, adi_gpio_handle_pint_irq);
-	irq_set_handler_data(pint->irq, pint);
+	irq_set_chained_handler_and_data(pint->irq, adi_gpio_handle_pint_irq,
+					 pint);
 
 	list_add_tail(&pint->node, &adi_pint_list);
 
diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c
index d34ac879af9e..c262e5f35c28 100644
--- a/drivers/pinctrl/pinctrl-st.c
+++ b/drivers/pinctrl/pinctrl-st.c
@@ -1661,8 +1661,8 @@ static int st_pctl_probe_dt(struct platform_device *pdev,
 		if (IS_ERR(info->irqmux_base))
 			return PTR_ERR(info->irqmux_base);
 
-		irq_set_chained_handler(irq, st_gpio_irqmux_handler);
-		irq_set_handler_data(irq, info);
+		irq_set_chained_handler_and_data(irq, st_gpio_irqmux_handler,
+						 info);
 
 	}
 
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 0b7afa50121a..b18dabba03a4 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -563,8 +563,8 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 		return -ENOMEM;
 	}
 
-	irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
-	irq_set_handler_data(irq, muxed_data);
+	irq_set_chained_handler_and_data(irq, exynos_irq_demux_eint16_31,
+					 muxed_data);
 
 	bank = d->pin_banks;
 	idx = 0;
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
index f1993f42114c..01b43dbfb795 100644
--- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
@@ -514,8 +514,7 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
 		}
 
 		eint_data->parents[i] = irq;
-		irq_set_chained_handler(irq, handlers[i]);
-		irq_set_handler_data(irq, eint_data);
+		irq_set_chained_handler_and_data(irq, handlers[i], eint_data);
 	}
 
 	bank = d->pin_banks;
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
index 7756c1e9e763..ec8cc3b47621 100644
--- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
@@ -506,8 +506,7 @@ static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 		data->domains[nr_domains++] = bank->irq_domain;
 	}
 
-	irq_set_chained_handler(d->irq, s3c64xx_eint_gpio_irq);
-	irq_set_handler_data(d->irq, data);
+	irq_set_chained_handler_and_data(d->irq, s3c64xx_eint_gpio_irq, data);
 
 	return 0;
 }
@@ -731,8 +730,9 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
 			return -ENXIO;
 		}
 
-		irq_set_chained_handler(irq, s3c64xx_eint0_handlers[i]);
-		irq_set_handler_data(irq, data);
+		irq_set_chained_handler_and_data(irq,
+						 s3c64xx_eint0_handlers[i],
+						 data);
 	}
 
 	bank = d->pin_banks;
diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
index d7857c72e627..f09573e13203 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -1005,9 +1005,9 @@ int sunxi_pinctrl_init(struct platform_device *pdev,
 		writel(0xffffffff,
 			pctl->membase + sunxi_irq_status_reg_from_bank(i));
 
-		irq_set_chained_handler(pctl->irq[i],
-					sunxi_pinctrl_irq_handler);
-		irq_set_handler_data(pctl->irq[i], pctl);
+		irq_set_chained_handler_and_data(pctl->irq[i],
+						 sunxi_pinctrl_irq_handler,
+						 pctl);
 	}
 
 	dev_info(&pdev->dev, "initialized sunXi PIO driver\n");
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
index 81f22980b2de..156b790072b4 100644
--- a/drivers/sh/intc/core.c
+++ b/drivers/sh/intc/core.c
@@ -366,8 +366,9 @@ int __init register_intc_controller(struct intc_desc *desc)
 
 			/* redirect this interrupts to the first one */
 			irq_set_chip(irq2, &dummy_irq_chip);
-			irq_set_chained_handler(irq2, intc_redirect_irq);
-			irq_set_handler_data(irq2, (void *)irq);
+			irq_set_chained_handler_and_data(irq2,
+							 intc_redirect_irq,
+							 (void *)irq);
 		}
 	}
 
diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c
index f30ac9354ff2..f5f1b821241a 100644
--- a/drivers/sh/intc/virq.c
+++ b/drivers/sh/intc/virq.c
@@ -243,8 +243,9 @@ restart:
 		 */
 		irq_set_nothread(irq);
 
-		irq_set_chained_handler(entry->pirq, intc_virq_handler);
+		/* Set handler data before installing the handler */
 		add_virq_to_pirq(entry->pirq, irq);
+		irq_set_chained_handler(entry->pirq, intc_virq_handler);
 
 		radix_tree_tag_clear(&d->tree, entry->enum_id,
 				     INTC_TAG_VIRQ_NEEDS_ALLOC);
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 812149160d3b..92188b0225bb 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -407,7 +407,6 @@ enum {
 	IRQCHIP_EOI_THREADED		= (1 <<  6),
 };
 
-/* This include will go away once we isolated irq_desc usage to core code */
 #include <linux/irqdesc.h>
 
 /*
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index c52d1480f272..624a668e61f1 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -3,9 +3,6 @@
 
 /*
  * Core internal functions to deal with irq descriptors
- *
- * This include will move to kernel/irq once we cleaned up the tree.
- * For now it's included from <linux/irq.h>
  */
 
 struct irq_affinity_notify;
@@ -103,6 +100,11 @@ static inline struct irq_desc *irq_data_to_desc(struct irq_data *data)
 #endif
 }
 
+static inline unsigned int irq_desc_get_irq(struct irq_desc *desc)
+{
+	return desc->irq_data.irq;
+}
+
 static inline struct irq_data *irq_desc_get_irq_data(struct irq_desc *desc)
 {
 	return &desc->irq_data;
@@ -188,6 +190,47 @@ __irq_set_chip_handler_name_locked(unsigned int irq, struct irq_chip *chip,
 	desc->name = name;
 }
 
+/**
+ * irq_set_handler_locked - Set irq handler from a locked region
+ * @data:	Pointer to the irq_data structure which identifies the irq
+ * @handler:	Flow control handler function for this interrupt
+ *
+ * Sets the handler in the irq descriptor associated to @data.
+ *
+ * Must be called with irq_desc locked and valid parameters. Typical
+ * call site is the irq_set_type() callback.
+ */
+static inline void irq_set_handler_locked(struct irq_data *data,
+					  irq_flow_handler_t handler)
+{
+	struct irq_desc *desc = irq_data_to_desc(data);
+
+	desc->handle_irq = handler;
+}
+
+/**
+ * irq_set_chip_handler_name_locked - Set chip, handler and name from a locked region
+ * @data:	Pointer to the irq_data structure for which the chip is set
+ * @chip:	Pointer to the new irq chip
+ * @handler:	Flow control handler function for this interrupt
+ * @name:	Name of the interrupt
+ *
+ * Replace the irq chip at the proper hierarchy level in @data and
+ * sets the handler and name in the associated irq descriptor.
+ *
+ * Must be called with irq_desc locked and valid parameters.
+ */
+static inline void
+irq_set_chip_handler_name_locked(struct irq_data *data, struct irq_chip *chip,
+				 irq_flow_handler_t handler, const char *name)
+{
+	struct irq_desc *desc = irq_data_to_desc(data);
+
+	desc->handle_irq = handler;
+	desc->name = name;
+	data->chip = chip;
+}
+
 static inline int irq_balancing_disabled(unsigned int irq)
 {
 	struct irq_desc *desc;
diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h
index fdd5cc16c9c4..9669bf9d4f48 100644
--- a/include/linux/irqnr.h
+++ b/include/linux/irqnr.h
@@ -23,12 +23,6 @@ unsigned int irq_get_next_irq(unsigned int offset);
 			;						\
 		else
 
-#ifdef CONFIG_SMP
-#define irq_node(irq)	(irq_get_irq_data(irq)->node)
-#else
-#define irq_node(irq)	0
-#endif
-
 # define for_each_active_irq(irq)			\
 	for (irq = irq_get_next_irq(0); irq < nr_irqs;	\
 	     irq = irq_get_next_irq(irq + 1))