diff --git a/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c b/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c
index dbaad5cab8001360ec9a6b311fb7e4942b0407b9..8acc3344f649e9c1d6ea7e453b72fc76946672c5 100644
--- a/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c
+++ b/target/linux/ar71xx/files/arch/mips/ar71xx/irq.c
@@ -93,6 +93,81 @@ static void __init ar71xx_pci_irq_init(void)
 
 	setup_irq(AR71XX_CPU_IRQ_PCI, &ar71xx_pci_irqaction);
 }
+
+static void ar724x_pci_irq_dispatch(void)
+{
+	u32 pending;
+
+	pending = ar724x_pci_rr(AR724X_PCI_REG_INT_STATUS) &
+		  ar724x_pci_rr(AR724X_PCI_REG_INT_MASK);
+
+	if (pending & AR724X_PCI_INT_DEV0)
+		do_IRQ(AR71XX_PCI_IRQ_DEV0);
+
+	else
+		spurious_interrupt();
+}
+
+static void ar724x_pci_irq_unmask(unsigned int irq)
+{
+	switch (irq) {
+	case AR71XX_PCI_IRQ_DEV0:
+		irq -= AR71XX_PCI_IRQ_BASE;
+		ar724x_pci_wr(AR724X_PCI_REG_INT_MASK,
+			      ar724x_pci_rr(AR724X_PCI_REG_INT_MASK) |
+					    AR724X_PCI_INT_DEV0);
+		/* flush write */
+		ar724x_pci_rr(AR724X_PCI_REG_INT_MASK);
+	}
+}
+
+static void ar724x_pci_irq_mask(unsigned int irq)
+{
+	switch (irq) {
+	case AR71XX_PCI_IRQ_DEV0:
+		irq -= AR71XX_PCI_IRQ_BASE;
+		ar724x_pci_wr(AR724X_PCI_REG_INT_MASK,
+			      ar724x_pci_rr(AR724X_PCI_REG_INT_MASK) &
+					    ~AR724X_PCI_INT_DEV0);
+		/* flush write */
+		ar724x_pci_rr(AR724X_PCI_REG_INT_MASK);
+
+		ar724x_pci_wr(AR724X_PCI_REG_INT_STATUS,
+			      ar724x_pci_rr(AR724X_PCI_REG_INT_STATUS) |
+					    AR724X_PCI_INT_DEV0);
+		/* flush write */
+		ar724x_pci_rr(AR724X_PCI_REG_INT_STATUS);
+	}
+}
+
+static struct irq_chip ar724x_pci_irq_chip = {
+	.name		= "AR724X PCI ",
+	.mask		= ar724x_pci_irq_mask,
+	.unmask		= ar724x_pci_irq_unmask,
+	.mask_ack	= ar724x_pci_irq_mask,
+};
+
+static struct irqaction ar724x_pci_irqaction = {
+	.handler	= no_action,
+	.name		= "cascade [AR724X PCI]",
+};
+
+static void __init ar724x_pci_irq_init(void)
+{
+	int i;
+
+	ar724x_pci_wr(AR724X_PCI_REG_INT_MASK, 0);
+	ar724x_pci_wr(AR724X_PCI_REG_INT_STATUS, 0);
+
+	for (i = AR71XX_PCI_IRQ_BASE;
+	     i < AR71XX_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) {
+		irq_desc[i].status = IRQ_DISABLED;
+		set_irq_chip_and_handler(i, &ar724x_pci_irq_chip,
+					 handle_level_irq);
+	}
+
+	setup_irq(AR71XX_CPU_IRQ_PCI, &ar724x_pci_irqaction);
+}
 #endif /* CONFIG_PCI */
 
 static void ar71xx_gpio_irq_dispatch(void)
@@ -306,10 +381,14 @@ void __init arch_init_irq(void)
 	case AR71XX_SOC_AR7130:
 	case AR71XX_SOC_AR7141:
 	case AR71XX_SOC_AR7161:
-	case AR71XX_SOC_AR7240:
 #ifdef CONFIG_PCI
 		ar71xx_pci_irq_init();
 		ar71xx_ip2_irq_handler = ar71xx_pci_irq_dispatch;
+#endif
+	case AR71XX_SOC_AR7240:
+#ifdef CONFIG_PCI
+		ar724x_pci_irq_init();
+		ar71xx_ip2_irq_handler = ar724x_pci_irq_dispatch;
 #endif
 		break;
 	case AR71XX_SOC_AR9130:
diff --git a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/ar71xx.h b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/ar71xx.h
index 0fc0d2066457b884afa0c3beba02c85c87edbe48..7ce34b2cc545935470bc6f8205e6c03effb9a6c4 100644
--- a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/ar71xx.h
+++ b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ar71xx/ar71xx.h
@@ -56,6 +56,13 @@
 #define AR71XX_DMA_SIZE		0x10000
 #define AR71XX_STEREO_BASE	(AR71XX_APB_BASE + 0x000B0000)
 #define AR71XX_STEREO_SIZE	0x10000
+
+#define AR724X_PCI_CRP_BASE	(AR71XX_APB_BASE + 0x000C0000)
+#define AR724X_PCI_CRP_SIZE	0x100
+
+#define AR724X_PCI_CTRL_BASE	(AR71XX_APB_BASE + 0x000F0000)
+#define AR724X_PCI_CTRL_SIZE	0x100
+
 #define AR91XX_WMAC_BASE	(AR71XX_APB_BASE + 0x000C0000)
 #define AR91XX_WMAC_SIZE	0x30000
 
@@ -338,6 +345,34 @@ void ar71xx_ddr_flush(u32 reg);
 
 #define PCI_IDSEL_ADL_START	17
 
+#define AR7240_PCI_CFG_BASE	(AR71XX_PCI_MEM_BASE + PCI_WIN4_OFFS)
+#define AR7240_PCI_CFG_SIZE	0x100
+
+#define AR724X_PCI_REG_INT_STATUS	0x4c
+#define AR724X_PCI_REG_INT_MASK		0x50
+
+#define AR724X_PCI_INT_DEV0		BIT(14)
+
+static inline void ar724x_pci_wr(unsigned reg, u32 val)
+{
+	void __iomem *base;
+
+	base = ioremap_nocache(AR724X_PCI_CTRL_BASE, AR724X_PCI_CTRL_SIZE);
+	__raw_writel(val, base + reg);
+	iounmap(base);
+}
+
+static inline u32 ar724x_pci_rr(unsigned reg)
+{
+	void __iomem *base;
+	u32 ret;
+
+	base = ioremap_nocache(AR724X_PCI_CTRL_BASE, AR724X_PCI_CTRL_SIZE);
+	ret = __raw_readl(base + reg);
+	iounmap(base);
+	return ret;
+}
+
 /*
  * RESET block
  */