diff --git a/Documentation/devicetree/bindings/arm/spear/shirq.txt b/Documentation/devicetree/bindings/arm/spear/shirq.txt
new file mode 100644
index 0000000..13fbb88
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/spear/shirq.txt
@@ -0,0 +1,48 @@
+* SPEAr Shared IRQ layer (shirq)
+
+SPEAr3xx architecture includes shared/multiplexed irqs for certain set
+of devices. The multiplexor provides a single interrupt to parent
+interrupt controller (VIC) on behalf of a group of devices.
+
+There can be multiple groups available on SPEAr3xx variants but not
+exceeding 4. The number of devices in a group can differ, further they
+may share same set of status/mask registers spanning across different
+bit masks. Also in some cases the group may not have enable or other
+registers. This makes software little complex.
+
+A single node in the device tree is used to describe the shared
+interrupt multiplexor (one node for all groups). A group in the
+interrupt controller shares config/control registers with other groups.
+For example, a 32-bit interrupt enable/disable config register can
+accommodate upto 4 interrupt groups.
+
+Required properties:
+  - compatible: should be, either of
+     - "st,spear300-shirq"
+     - "st,spear310-shirq"
+     - "st,spear320-shirq"
+  - interrupt-controller: Identifies the node as an interrupt controller.
+  - #interrupt-cells: should be <1> which basically contains the offset
+    (starting from 0) of interrupts for all the groups.
+  - reg: Base address and size of shirq registers.
+  - interrupts: The list of interrupts generated by the groups which are
+    then connected to a parent interrupt controller. Each group is
+    associated with one of the interrupts, hence number of interrupts (to
+    parent) is equal to number of groups. The format of the interrupt
+    specifier depends in the interrupt parent controller.
+
+  Optional properties:
+  - interrupt-parent: pHandle of the parent interrupt controller, if not
+    inherited from the parent node.
+
+Example:
+
+The following is an example from the SPEAr320 SoC dtsi file.
+
+shirq: interrupt-controller@0xb3000000 {
+	compatible = "st,spear320-shirq";
+	reg = <0xb3000000 0x1000>;
+	interrupts = <28 29 30 1>;
+	#interrupt-cells = <1>;
+	interrupt-controller;
+};
diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h
index 803de76..f95e5b2 100644
--- a/arch/arm/mach-spear3xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear3xx/include/mach/irqs.h
@@ -14,14 +14,6 @@
 #ifndef __MACH_IRQS_H
 #define __MACH_IRQS_H
 
-/* FIXME: probe all these from DT */
-#define SPEAR3XX_IRQ_INTRCOMM_RAS_ARM		1
-#define SPEAR3XX_IRQ_GEN_RAS_1			28
-#define SPEAR3XX_IRQ_GEN_RAS_2			29
-#define SPEAR3XX_IRQ_GEN_RAS_3			30
-#define SPEAR3XX_IRQ_VIC_END			32
-#define SPEAR3XX_VIRQ_START			SPEAR3XX_IRQ_VIC_END
-
-#define NR_IRQS			160
+#define NR_IRQS			256
 
 #endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 6ec3005..a69cbfd 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -17,102 +17,9 @@
 #include <linux/of_platform.h>
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
-#include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
 
-/* Base address of various IPs */
-#define SPEAR300_TELECOM_BASE		UL(0x50000000)
-
-/* Interrupt registers offsets and masks */
-#define SPEAR300_INT_ENB_MASK_REG	0x54
-#define SPEAR300_INT_STS_MASK_REG	0x58
-#define SPEAR300_IT_PERS_S_IRQ_MASK	(1 << 0)
-#define SPEAR300_IT_CHANGE_S_IRQ_MASK	(1 << 1)
-#define SPEAR300_I2S_IRQ_MASK		(1 << 2)
-#define SPEAR300_TDM_IRQ_MASK		(1 << 3)
-#define SPEAR300_CAMERA_L_IRQ_MASK	(1 << 4)
-#define SPEAR300_CAMERA_F_IRQ_MASK	(1 << 5)
-#define SPEAR300_CAMERA_V_IRQ_MASK	(1 << 6)
-#define SPEAR300_KEYBOARD_IRQ_MASK	(1 << 7)
-#define SPEAR300_GPIO1_IRQ_MASK		(1 << 8)
-
-#define SPEAR300_SHIRQ_RAS1_MASK	0x1FF
-
-#define SPEAR300_SOC_CONFIG_BASE	UL(0x99000000)
-
-
-/* SPEAr300 Virtual irq definitions */
-/* IRQs sharing IRQ_GEN_RAS_1 */
-#define SPEAR300_VIRQ_IT_PERS_S			(SPEAR3XX_VIRQ_START + 0)
-#define SPEAR300_VIRQ_IT_CHANGE_S		(SPEAR3XX_VIRQ_START + 1)
-#define SPEAR300_VIRQ_I2S			(SPEAR3XX_VIRQ_START + 2)
-#define SPEAR300_VIRQ_TDM			(SPEAR3XX_VIRQ_START + 3)
-#define SPEAR300_VIRQ_CAMERA_L			(SPEAR3XX_VIRQ_START + 4)
-#define SPEAR300_VIRQ_CAMERA_F			(SPEAR3XX_VIRQ_START + 5)
-#define SPEAR300_VIRQ_CAMERA_V			(SPEAR3XX_VIRQ_START + 6)
-#define SPEAR300_VIRQ_KEYBOARD			(SPEAR3XX_VIRQ_START + 7)
-#define SPEAR300_VIRQ_GPIO1			(SPEAR3XX_VIRQ_START + 8)
-
-/* IRQs sharing IRQ_GEN_RAS_3 */
-#define SPEAR300_IRQ_CLCD			SPEAR3XX_IRQ_GEN_RAS_3
-
-/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
-#define SPEAR300_IRQ_SDHCI			SPEAR3XX_IRQ_INTRCOMM_RAS_ARM
-
-/* spear3xx shared irq */
-static struct shirq_dev_config shirq_ras1_config[] = {
-	{
-		.virq = SPEAR300_VIRQ_IT_PERS_S,
-		.enb_mask = SPEAR300_IT_PERS_S_IRQ_MASK,
-		.status_mask = SPEAR300_IT_PERS_S_IRQ_MASK,
-	}, {
-		.virq = SPEAR300_VIRQ_IT_CHANGE_S,
-		.enb_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK,
-		.status_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK,
-	}, {
-		.virq = SPEAR300_VIRQ_I2S,
-		.enb_mask = SPEAR300_I2S_IRQ_MASK,
-		.status_mask = SPEAR300_I2S_IRQ_MASK,
-	}, {
-		.virq = SPEAR300_VIRQ_TDM,
-		.enb_mask = SPEAR300_TDM_IRQ_MASK,
-		.status_mask = SPEAR300_TDM_IRQ_MASK,
-	}, {
-		.virq = SPEAR300_VIRQ_CAMERA_L,
-		.enb_mask = SPEAR300_CAMERA_L_IRQ_MASK,
-		.status_mask = SPEAR300_CAMERA_L_IRQ_MASK,
-	}, {
-		.virq = SPEAR300_VIRQ_CAMERA_F,
-		.enb_mask = SPEAR300_CAMERA_F_IRQ_MASK,
-		.status_mask = SPEAR300_CAMERA_F_IRQ_MASK,
-	}, {
-		.virq = SPEAR300_VIRQ_CAMERA_V,
-		.enb_mask = SPEAR300_CAMERA_V_IRQ_MASK,
-		.status_mask = SPEAR300_CAMERA_V_IRQ_MASK,
-	}, {
-		.virq = SPEAR300_VIRQ_KEYBOARD,
-		.enb_mask = SPEAR300_KEYBOARD_IRQ_MASK,
-		.status_mask = SPEAR300_KEYBOARD_IRQ_MASK,
-	}, {
-		.virq = SPEAR300_VIRQ_GPIO1,
-		.enb_mask = SPEAR300_GPIO1_IRQ_MASK,
-		.status_mask = SPEAR300_GPIO1_IRQ_MASK,
-	},
-};
-
-static struct spear_shirq shirq_ras1 = {
-	.irq = SPEAR3XX_IRQ_GEN_RAS_1,
-	.dev_config = shirq_ras1_config,
-	.dev_count = ARRAY_SIZE(shirq_ras1_config),
-	.regs = {
-		.enb_reg = SPEAR300_INT_ENB_MASK_REG,
-		.status_reg = SPEAR300_INT_STS_MASK_REG,
-		.status_reg_mask = SPEAR300_SHIRQ_RAS1_MASK,
-		.clear_reg = -1,
-	},
-};
-
 /* DMAC platform data's slave info */
 struct pl08x_channel_data spear300_dma_info[] = {
 	{
@@ -285,21 +192,11 @@ static struct of_dev_auxdata spear300_auxdata_lookup[] __initdata = {
 
 static void __init spear300_dt_init(void)
 {
-	int ret;
-
 	pl080_plat_data.slave_channels = spear300_dma_info;
 	pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear300_dma_info);
 
 	of_platform_populate(NULL, of_default_bus_match_table,
 			spear300_auxdata_lookup, NULL);
-
-	/* shared irq registration */
-	shirq_ras1.regs.base = ioremap(SPEAR300_TELECOM_BASE, SZ_4K);
-	if (shirq_ras1.regs.base) {
-		ret = spear_shirq_register(&shirq_ras1);
-		if (ret)
-			pr_err("Error registering Shared IRQ\n");
-	}
 }
 
 static const char * const spear300_dt_board_compat[] = {
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index 1d0e435..b963ebb 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -18,7 +18,6 @@
 #include <linux/of_platform.h>
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
-#include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
 
@@ -27,176 +26,6 @@
 #define SPEAR310_UART3_BASE		UL(0xB2100000)
 #define SPEAR310_UART4_BASE		UL(0xB2180000)
 #define SPEAR310_UART5_BASE		UL(0xB2200000)
-#define SPEAR310_SOC_CONFIG_BASE	UL(0xB4000000)
-
-/* Interrupt registers offsets and masks */
-#define SPEAR310_INT_STS_MASK_REG	0x04
-#define SPEAR310_SMII0_IRQ_MASK		(1 << 0)
-#define SPEAR310_SMII1_IRQ_MASK		(1 << 1)
-#define SPEAR310_SMII2_IRQ_MASK		(1 << 2)
-#define SPEAR310_SMII3_IRQ_MASK		(1 << 3)
-#define SPEAR310_WAKEUP_SMII0_IRQ_MASK	(1 << 4)
-#define SPEAR310_WAKEUP_SMII1_IRQ_MASK	(1 << 5)
-#define SPEAR310_WAKEUP_SMII2_IRQ_MASK	(1 << 6)
-#define SPEAR310_WAKEUP_SMII3_IRQ_MASK	(1 << 7)
-#define SPEAR310_UART1_IRQ_MASK		(1 << 8)
-#define SPEAR310_UART2_IRQ_MASK		(1 << 9)
-#define SPEAR310_UART3_IRQ_MASK		(1 << 10)
-#define SPEAR310_UART4_IRQ_MASK		(1 << 11)
-#define SPEAR310_UART5_IRQ_MASK		(1 << 12)
-#define SPEAR310_EMI_IRQ_MASK		(1 << 13)
-#define SPEAR310_TDM_HDLC_IRQ_MASK	(1 << 14)
-#define SPEAR310_RS485_0_IRQ_MASK	(1 << 15)
-#define SPEAR310_RS485_1_IRQ_MASK	(1 << 16)
-
-#define SPEAR310_SHIRQ_RAS1_MASK	0x000FF
-#define SPEAR310_SHIRQ_RAS2_MASK	0x01F00
-#define SPEAR310_SHIRQ_RAS3_MASK	0x02000
-#define SPEAR310_SHIRQ_INTRCOMM_RAS_MASK	0x1C000
-
-/* SPEAr310 Virtual irq definitions */
-/* IRQs sharing IRQ_GEN_RAS_1 */
-#define SPEAR310_VIRQ_SMII0			(SPEAR3XX_VIRQ_START + 0)
-#define SPEAR310_VIRQ_SMII1			(SPEAR3XX_VIRQ_START + 1)
-#define SPEAR310_VIRQ_SMII2			(SPEAR3XX_VIRQ_START + 2)
-#define SPEAR310_VIRQ_SMII3			(SPEAR3XX_VIRQ_START + 3)
-#define SPEAR310_VIRQ_WAKEUP_SMII0		(SPEAR3XX_VIRQ_START + 4)
-#define SPEAR310_VIRQ_WAKEUP_SMII1		(SPEAR3XX_VIRQ_START + 5)
-#define SPEAR310_VIRQ_WAKEUP_SMII2		(SPEAR3XX_VIRQ_START + 6)
-#define SPEAR310_VIRQ_WAKEUP_SMII3		(SPEAR3XX_VIRQ_START + 7)
-
-/* IRQs sharing IRQ_GEN_RAS_2 */
-#define SPEAR310_VIRQ_UART1			(SPEAR3XX_VIRQ_START + 8)
-#define SPEAR310_VIRQ_UART2			(SPEAR3XX_VIRQ_START + 9)
-#define SPEAR310_VIRQ_UART3			(SPEAR3XX_VIRQ_START + 10)
-#define SPEAR310_VIRQ_UART4			(SPEAR3XX_VIRQ_START + 11)
-#define SPEAR310_VIRQ_UART5			(SPEAR3XX_VIRQ_START + 12)
-
-/* IRQs sharing IRQ_GEN_RAS_3 */
-#define SPEAR310_VIRQ_EMI			(SPEAR3XX_VIRQ_START + 13)
-#define SPEAR310_VIRQ_PLGPIO			(SPEAR3XX_VIRQ_START + 14)
-
-/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
-#define SPEAR310_VIRQ_TDM_HDLC			(SPEAR3XX_VIRQ_START + 15)
-#define SPEAR310_VIRQ_RS485_0			(SPEAR3XX_VIRQ_START + 16)
-#define SPEAR310_VIRQ_RS485_1			(SPEAR3XX_VIRQ_START + 17)
-
-
-/* spear3xx shared irq */
-static struct shirq_dev_config shirq_ras1_config[] = {
-	{
-		.virq = SPEAR310_VIRQ_SMII0,
-		.status_mask = SPEAR310_SMII0_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_SMII1,
-		.status_mask = SPEAR310_SMII1_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_SMII2,
-		.status_mask = SPEAR310_SMII2_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_SMII3,
-		.status_mask = SPEAR310_SMII3_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_WAKEUP_SMII0,
-		.status_mask = SPEAR310_WAKEUP_SMII0_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_WAKEUP_SMII1,
-		.status_mask = SPEAR310_WAKEUP_SMII1_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_WAKEUP_SMII2,
-		.status_mask = SPEAR310_WAKEUP_SMII2_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_WAKEUP_SMII3,
-		.status_mask = SPEAR310_WAKEUP_SMII3_IRQ_MASK,
-	},
-};
-
-static struct spear_shirq shirq_ras1 = {
-	.irq = SPEAR3XX_IRQ_GEN_RAS_1,
-	.dev_config = shirq_ras1_config,
-	.dev_count = ARRAY_SIZE(shirq_ras1_config),
-	.regs = {
-		.enb_reg = -1,
-		.status_reg = SPEAR310_INT_STS_MASK_REG,
-		.status_reg_mask = SPEAR310_SHIRQ_RAS1_MASK,
-		.clear_reg = -1,
-	},
-};
-
-static struct shirq_dev_config shirq_ras2_config[] = {
-	{
-		.virq = SPEAR310_VIRQ_UART1,
-		.status_mask = SPEAR310_UART1_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_UART2,
-		.status_mask = SPEAR310_UART2_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_UART3,
-		.status_mask = SPEAR310_UART3_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_UART4,
-		.status_mask = SPEAR310_UART4_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_UART5,
-		.status_mask = SPEAR310_UART5_IRQ_MASK,
-	},
-};
-
-static struct spear_shirq shirq_ras2 = {
-	.irq = SPEAR3XX_IRQ_GEN_RAS_2,
-	.dev_config = shirq_ras2_config,
-	.dev_count = ARRAY_SIZE(shirq_ras2_config),
-	.regs = {
-		.enb_reg = -1,
-		.status_reg = SPEAR310_INT_STS_MASK_REG,
-		.status_reg_mask = SPEAR310_SHIRQ_RAS2_MASK,
-		.clear_reg = -1,
-	},
-};
-
-static struct shirq_dev_config shirq_ras3_config[] = {
-	{
-		.virq = SPEAR310_VIRQ_EMI,
-		.status_mask = SPEAR310_EMI_IRQ_MASK,
-	},
-};
-
-static struct spear_shirq shirq_ras3 = {
-	.irq = SPEAR3XX_IRQ_GEN_RAS_3,
-	.dev_config = shirq_ras3_config,
-	.dev_count = ARRAY_SIZE(shirq_ras3_config),
-	.regs = {
-		.enb_reg = -1,
-		.status_reg = SPEAR310_INT_STS_MASK_REG,
-		.status_reg_mask = SPEAR310_SHIRQ_RAS3_MASK,
-		.clear_reg = -1,
-	},
-};
-
-static struct shirq_dev_config shirq_intrcomm_ras_config[] = {
-	{
-		.virq = SPEAR310_VIRQ_TDM_HDLC,
-		.status_mask = SPEAR310_TDM_HDLC_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_RS485_0,
-		.status_mask = SPEAR310_RS485_0_IRQ_MASK,
-	}, {
-		.virq = SPEAR310_VIRQ_RS485_1,
-		.status_mask = SPEAR310_RS485_1_IRQ_MASK,
-	},
-};
-
-static struct spear_shirq shirq_intrcomm_ras = {
-	.irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM,
-	.dev_config = shirq_intrcomm_ras_config,
-	.dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
-	.regs = {
-		.enb_reg = -1,
-		.status_reg = SPEAR310_INT_STS_MASK_REG,
-		.status_reg_mask = SPEAR310_SHIRQ_INTRCOMM_RAS_MASK,
-		.clear_reg = -1,
-	},
-};
 
 /* DMAC platform data's slave info */
 struct pl08x_channel_data spear310_dma_info[] = {
@@ -405,42 +234,11 @@ static struct of_dev_auxdata spear310_auxdata_lookup[] __initdata = {
 
 static void __init spear310_dt_init(void)
 {
-	void __iomem *base;
-	int ret;
-
 	pl080_plat_data.slave_channels = spear310_dma_info;
 	pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear310_dma_info);
 
 	of_platform_populate(NULL, of_default_bus_match_table,
 			spear310_auxdata_lookup, NULL);
-
-	/* shared irq registration */
-	base = ioremap(SPEAR310_SOC_CONFIG_BASE, SZ_4K);
-	if (base) {
-		/* shirq 1 */
-		shirq_ras1.regs.base = base;
-		ret = spear_shirq_register(&shirq_ras1);
-		if (ret)
-			pr_err("Error registering Shared IRQ 1\n");
-
-		/* shirq 2 */
-		shirq_ras2.regs.base = base;
-		ret = spear_shirq_register(&shirq_ras2);
-		if (ret)
-			pr_err("Error registering Shared IRQ 2\n");
-
-		/* shirq 3 */
-		shirq_ras3.regs.base = base;
-		ret = spear_shirq_register(&shirq_ras3);
-		if (ret)
-			pr_err("Error registering Shared IRQ 3\n");
-
-		/* shirq 4 */
-		shirq_intrcomm_ras.regs.base = base;
-		ret = spear_shirq_register(&shirq_intrcomm_ras);
-		if (ret)
-			pr_err("Error registering Shared IRQ 4\n");
-	}
 }
 
 static const char * const spear310_dt_board_compat[] = {
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index fd823c6..707504b 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -19,7 +19,6 @@
 #include <linux/of_platform.h>
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
-#include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
 
@@ -28,184 +27,6 @@
 #define SPEAR320_SSP0_BASE		UL(0xA5000000)
 #define SPEAR320_SSP1_BASE		UL(0xA6000000)
 
-/* Interrupt registers offsets and masks */
-#define SPEAR320_INT_STS_MASK_REG		0x04
-#define SPEAR320_INT_CLR_MASK_REG		0x04
-#define SPEAR320_INT_ENB_MASK_REG		0x08
-#define SPEAR320_GPIO_IRQ_MASK			(1 << 0)
-#define SPEAR320_I2S_PLAY_IRQ_MASK		(1 << 1)
-#define SPEAR320_I2S_REC_IRQ_MASK		(1 << 2)
-#define SPEAR320_EMI_IRQ_MASK			(1 << 7)
-#define SPEAR320_CLCD_IRQ_MASK			(1 << 8)
-#define SPEAR320_SPP_IRQ_MASK			(1 << 9)
-#define SPEAR320_SDHCI_IRQ_MASK			(1 << 10)
-#define SPEAR320_CAN_U_IRQ_MASK			(1 << 11)
-#define SPEAR320_CAN_L_IRQ_MASK			(1 << 12)
-#define SPEAR320_UART1_IRQ_MASK			(1 << 13)
-#define SPEAR320_UART2_IRQ_MASK			(1 << 14)
-#define SPEAR320_SSP1_IRQ_MASK			(1 << 15)
-#define SPEAR320_SSP2_IRQ_MASK			(1 << 16)
-#define SPEAR320_SMII0_IRQ_MASK			(1 << 17)
-#define SPEAR320_MII1_SMII1_IRQ_MASK		(1 << 18)
-#define SPEAR320_WAKEUP_SMII0_IRQ_MASK		(1 << 19)
-#define SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK	(1 << 20)
-#define SPEAR320_I2C1_IRQ_MASK			(1 << 21)
-
-#define SPEAR320_SHIRQ_RAS1_MASK		0x000380
-#define SPEAR320_SHIRQ_RAS3_MASK		0x000007
-#define SPEAR320_SHIRQ_INTRCOMM_RAS_MASK	0x3FF800
-
-/* SPEAr320 Virtual irq definitions */
-/* IRQs sharing IRQ_GEN_RAS_1 */
-#define SPEAR320_VIRQ_EMI			(SPEAR3XX_VIRQ_START + 0)
-#define SPEAR320_VIRQ_CLCD			(SPEAR3XX_VIRQ_START + 1)
-#define SPEAR320_VIRQ_SPP			(SPEAR3XX_VIRQ_START + 2)
-
-/* IRQs sharing IRQ_GEN_RAS_2 */
-#define SPEAR320_IRQ_SDHCI			SPEAR3XX_IRQ_GEN_RAS_2
-
-/* IRQs sharing IRQ_GEN_RAS_3 */
-#define SPEAR320_VIRQ_PLGPIO			(SPEAR3XX_VIRQ_START + 3)
-#define SPEAR320_VIRQ_I2S_PLAY			(SPEAR3XX_VIRQ_START + 4)
-#define SPEAR320_VIRQ_I2S_REC			(SPEAR3XX_VIRQ_START + 5)
-
-/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
-#define SPEAR320_VIRQ_CANU			(SPEAR3XX_VIRQ_START + 6)
-#define SPEAR320_VIRQ_CANL			(SPEAR3XX_VIRQ_START + 7)
-#define SPEAR320_VIRQ_UART1			(SPEAR3XX_VIRQ_START + 8)
-#define SPEAR320_VIRQ_UART2			(SPEAR3XX_VIRQ_START + 9)
-#define SPEAR320_VIRQ_SSP1			(SPEAR3XX_VIRQ_START + 10)
-#define SPEAR320_VIRQ_SSP2			(SPEAR3XX_VIRQ_START + 11)
-#define SPEAR320_VIRQ_SMII0			(SPEAR3XX_VIRQ_START + 12)
-#define SPEAR320_VIRQ_MII1_SMII1		(SPEAR3XX_VIRQ_START + 13)
-#define SPEAR320_VIRQ_WAKEUP_SMII0		(SPEAR3XX_VIRQ_START + 14)
-#define SPEAR320_VIRQ_WAKEUP_MII1_SMII1		(SPEAR3XX_VIRQ_START + 15)
-#define SPEAR320_VIRQ_I2C1			(SPEAR3XX_VIRQ_START + 16)
-
-/* spear3xx shared irq */
-static struct shirq_dev_config shirq_ras1_config[] = {
-	{
-		.virq = SPEAR320_VIRQ_EMI,
-		.status_mask = SPEAR320_EMI_IRQ_MASK,
-		.clear_mask = SPEAR320_EMI_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_CLCD,
-		.status_mask = SPEAR320_CLCD_IRQ_MASK,
-		.clear_mask = SPEAR320_CLCD_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_SPP,
-		.status_mask = SPEAR320_SPP_IRQ_MASK,
-		.clear_mask = SPEAR320_SPP_IRQ_MASK,
-	},
-};
-
-static struct spear_shirq shirq_ras1 = {
-	.irq = SPEAR3XX_IRQ_GEN_RAS_1,
-	.dev_config = shirq_ras1_config,
-	.dev_count = ARRAY_SIZE(shirq_ras1_config),
-	.regs = {
-		.enb_reg = -1,
-		.status_reg = SPEAR320_INT_STS_MASK_REG,
-		.status_reg_mask = SPEAR320_SHIRQ_RAS1_MASK,
-		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
-		.reset_to_clear = 1,
-	},
-};
-
-static struct shirq_dev_config shirq_ras3_config[] = {
-	{
-		.virq = SPEAR320_VIRQ_PLGPIO,
-		.enb_mask = SPEAR320_GPIO_IRQ_MASK,
-		.status_mask = SPEAR320_GPIO_IRQ_MASK,
-		.clear_mask = SPEAR320_GPIO_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_I2S_PLAY,
-		.enb_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
-		.status_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
-		.clear_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_I2S_REC,
-		.enb_mask = SPEAR320_I2S_REC_IRQ_MASK,
-		.status_mask = SPEAR320_I2S_REC_IRQ_MASK,
-		.clear_mask = SPEAR320_I2S_REC_IRQ_MASK,
-	},
-};
-
-static struct spear_shirq shirq_ras3 = {
-	.irq = SPEAR3XX_IRQ_GEN_RAS_3,
-	.dev_config = shirq_ras3_config,
-	.dev_count = ARRAY_SIZE(shirq_ras3_config),
-	.regs = {
-		.enb_reg = SPEAR320_INT_ENB_MASK_REG,
-		.reset_to_enb = 1,
-		.status_reg = SPEAR320_INT_STS_MASK_REG,
-		.status_reg_mask = SPEAR320_SHIRQ_RAS3_MASK,
-		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
-		.reset_to_clear = 1,
-	},
-};
-
-static struct shirq_dev_config shirq_intrcomm_ras_config[] = {
-	{
-		.virq = SPEAR320_VIRQ_CANU,
-		.status_mask = SPEAR320_CAN_U_IRQ_MASK,
-		.clear_mask = SPEAR320_CAN_U_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_CANL,
-		.status_mask = SPEAR320_CAN_L_IRQ_MASK,
-		.clear_mask = SPEAR320_CAN_L_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_UART1,
-		.status_mask = SPEAR320_UART1_IRQ_MASK,
-		.clear_mask = SPEAR320_UART1_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_UART2,
-		.status_mask = SPEAR320_UART2_IRQ_MASK,
-		.clear_mask = SPEAR320_UART2_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_SSP1,
-		.status_mask = SPEAR320_SSP1_IRQ_MASK,
-		.clear_mask = SPEAR320_SSP1_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_SSP2,
-		.status_mask = SPEAR320_SSP2_IRQ_MASK,
-		.clear_mask = SPEAR320_SSP2_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_SMII0,
-		.status_mask = SPEAR320_SMII0_IRQ_MASK,
-		.clear_mask = SPEAR320_SMII0_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_MII1_SMII1,
-		.status_mask = SPEAR320_MII1_SMII1_IRQ_MASK,
-		.clear_mask = SPEAR320_MII1_SMII1_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_WAKEUP_SMII0,
-		.status_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK,
-		.clear_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_WAKEUP_MII1_SMII1,
-		.status_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK,
-		.clear_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK,
-	}, {
-		.virq = SPEAR320_VIRQ_I2C1,
-		.status_mask = SPEAR320_I2C1_IRQ_MASK,
-		.clear_mask = SPEAR320_I2C1_IRQ_MASK,
-	},
-};
-
-static struct spear_shirq shirq_intrcomm_ras = {
-	.irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM,
-	.dev_config = shirq_intrcomm_ras_config,
-	.dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
-	.regs = {
-		.enb_reg = -1,
-		.status_reg = SPEAR320_INT_STS_MASK_REG,
-		.status_reg_mask = SPEAR320_SHIRQ_INTRCOMM_RAS_MASK,
-		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
-		.reset_to_clear = 1,
-	},
-};
-
 /* DMAC platform data's slave info */
 struct pl08x_channel_data spear320_dma_info[] = {
 	{
@@ -416,36 +237,11 @@ static struct of_dev_auxdata spear320_auxdata_lookup[] __initdata = {
 
 static void __init spear320_dt_init(void)
 {
-	void __iomem *base;
-	int ret;
-
 	pl080_plat_data.slave_channels = spear320_dma_info;
 	pl080_plat_data.num_slave_channels = ARRAY_SIZE(spear320_dma_info);
 
 	of_platform_populate(NULL, of_default_bus_match_table,
 			spear320_auxdata_lookup, NULL);
-
-	/* shared irq registration */
-	base = ioremap(SPEAR320_SOC_CONFIG_BASE, SZ_4K);
-	if (base) {
-		/* shirq 1 */
-		shirq_ras1.regs.base = base;
-		ret = spear_shirq_register(&shirq_ras1);
-		if (ret)
-			pr_err("Error registering Shared IRQ 1\n");
-
-		/* shirq 3 */
-		shirq_ras3.regs.base = base;
-		ret = spear_shirq_register(&shirq_ras3);
-		if (ret)
-			pr_err("Error registering Shared IRQ 3\n");
-
-		/* shirq 4 */
-		shirq_intrcomm_ras.regs.base = base;
-		ret = spear_shirq_register(&shirq_intrcomm_ras);
-		if (ret)
-			pr_err("Error registering Shared IRQ 4\n");
-	}
 }
 
 static const char * const spear320_dt_board_compat[] = {
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 98144ba..781aec9 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -20,6 +20,7 @@
 #include <asm/hardware/pl080.h>
 #include <asm/hardware/vic.h>
 #include <plat/pl080.h>
+#include <plat/shirq.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
 
@@ -121,6 +122,9 @@ struct sys_timer spear3xx_timer = {
 
 static const struct of_device_id vic_of_match[] __initconst = {
 	{ .compatible = "arm,pl190-vic", .data = vic_of_init, },
+	{ .compatible = "st,spear300-shirq", .data = spear3xx_shirq_of_init, },
+	{ .compatible = "st,spear310-shirq", .data = spear3xx_shirq_of_init, },
+	{ .compatible = "st,spear320-shirq", .data = spear3xx_shirq_of_init, },
 	{ /* Sentinel */ }
 };
 
diff --git a/arch/arm/plat-spear/include/plat/shirq.h b/arch/arm/plat-spear/include/plat/shirq.h
index 88a7fbd..1215afe 100644
--- a/arch/arm/plat-spear/include/plat/shirq.h
+++ b/arch/arm/plat-spear/include/plat/shirq.h
@@ -18,24 +18,8 @@
 #include <linux/types.h>
 
 /*
- * struct shirq_dev_config: shared irq device configuration
- *
- * virq: virtual irq number of device
- * enb_mask: enable mask of device
- * status_mask: status mask of device
- * clear_mask: clear mask of device
- */
-struct shirq_dev_config {
-	u32 virq;
-	u32 enb_mask;
-	u32 status_mask;
-	u32 clear_mask;
-};
-
-/*
  * struct shirq_regs: shared irq register configuration
  *
- * base: base address of shared irq register
  * enb_reg: enable register offset
  * reset_to_enb: val 1 indicates, we need to clear bit for enabling interrupt
  * status_reg: status register offset
@@ -44,11 +28,9 @@ struct shirq_dev_config {
  * reset_to_clear: val 1 indicates, we need to clear bit for clearing interrupt
  */
 struct shirq_regs {
-	void __iomem *base;
 	u32 enb_reg;
 	u32 reset_to_enb;
 	u32 status_reg;
-	u32 status_reg_mask;
 	u32 clear_reg;
 	u32 reset_to_clear;
 };
@@ -57,17 +39,24 @@ struct shirq_regs {
  * struct spear_shirq: shared irq structure
  *
  * irq: hardware irq number
- * dev_config: array of device config structures which are using "irq" line
- * dev_count: size of dev_config array
+ * irq_base: base irq in linux domain
+ * irq_nr: no. of shared interrupts in a particular block
+ * irq_bit_off: starting bit offset in the status register
+ * invalid_irq: irq group is currently disabled
+ * base: base address of shared irq register
  * regs: register configuration for shared irq block
  */
 struct spear_shirq {
 	u32 irq;
-	struct shirq_dev_config *dev_config;
-	u32 dev_count;
+	u32 irq_base;
+	u32 irq_nr;
+	u32 irq_bit_off;
+	int invalid_irq;
+	void __iomem *base;
 	struct shirq_regs regs;
 };
 
-int spear_shirq_register(struct spear_shirq *shirq);
+int __init spear3xx_shirq_of_init(struct device_node *np,
+		struct device_node *parent);
 
 #endif /* __PLAT_SHIRQ_H */
diff --git a/arch/arm/plat-spear/shirq.c b/arch/arm/plat-spear/shirq.c
index 853e891..3912646 100644
--- a/arch/arm/plat-spear/shirq.c
+++ b/arch/arm/plat-spear/shirq.c
@@ -10,56 +10,182 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/err.h>
+#include <linux/export.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/spinlock.h>
 #include <plat/shirq.h>
 
-struct spear_shirq *shirq;
 static DEFINE_SPINLOCK(lock);
 
-static void shirq_irq_mask(struct irq_data *d)
+/* spear300 shared irq registers offsets and masks */
+#define SPEAR300_INT_ENB_MASK_REG	0x54
+#define SPEAR300_INT_STS_MASK_REG	0x58
+
+static struct spear_shirq spear300_shirq_ras1 = {
+	.irq_nr = 9,
+	.irq_bit_off = 0,
+	.regs = {
+		.enb_reg = SPEAR300_INT_ENB_MASK_REG,
+		.status_reg = SPEAR300_INT_STS_MASK_REG,
+		.clear_reg = -1,
+	},
+};
+
+static struct spear_shirq *spear300_shirq_blocks[] = {
+	&spear300_shirq_ras1,
+};
+
+/* spear310 shared irq registers offsets and masks */
+#define SPEAR310_INT_STS_MASK_REG	0x04
+
+static struct spear_shirq spear310_shirq_ras1 = {
+	.irq_nr = 8,
+	.irq_bit_off = 0,
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.clear_reg = -1,
+	},
+};
+
+static struct spear_shirq spear310_shirq_ras2 = {
+	.irq_nr = 5,
+	.irq_bit_off = 8,
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.clear_reg = -1,
+	},
+};
+
+static struct spear_shirq spear310_shirq_ras3 = {
+	.irq_nr = 1,
+	.irq_bit_off = 13,
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.clear_reg = -1,
+	},
+};
+
+static struct spear_shirq spear310_shirq_intrcomm_ras = {
+	.irq_nr = 3,
+	.irq_bit_off = 14,
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.clear_reg = -1,
+	},
+};
+
+static struct spear_shirq *spear310_shirq_blocks[] = {
+	&spear310_shirq_ras1,
+	&spear310_shirq_ras2,
+	&spear310_shirq_ras3,
+	&spear310_shirq_intrcomm_ras,
+};
+
+/* spear320 shared irq registers offsets and masks */
+#define SPEAR320_INT_STS_MASK_REG		0x04
+#define SPEAR320_INT_CLR_MASK_REG		0x04
+#define SPEAR320_INT_ENB_MASK_REG		0x08
+
+static struct spear_shirq spear320_shirq_ras1 = {
+	.irq_nr = 3,
+	.irq_bit_off = 7,
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = SPEAR320_INT_STS_MASK_REG,
+		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
+		.reset_to_clear = 1,
+	},
+};
+
+static struct spear_shirq spear320_shirq_ras2 = {
+	.irq_nr = 1,
+	.irq_bit_off = 10,
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = SPEAR320_INT_STS_MASK_REG,
+		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
+		.reset_to_clear = 1,
+	},
+};
+
+static struct spear_shirq spear320_shirq_ras3 = {
+	.irq_nr = 3,
+	.irq_bit_off = 0,
+	.invalid_irq = 1,
+	.regs = {
+		.enb_reg = SPEAR320_INT_ENB_MASK_REG,
+		.reset_to_enb = 1,
+		.status_reg = SPEAR320_INT_STS_MASK_REG,
+		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
+		.reset_to_clear = 1,
+	},
+};
+
+static struct spear_shirq spear320_shirq_intrcomm_ras = {
+	.irq_nr = 11,
+	.irq_bit_off = 11,
+	.regs = {
+		.enb_reg = -1,
+		.status_reg = SPEAR320_INT_STS_MASK_REG,
+		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
+		.reset_to_clear = 1,
+	},
+};
+
+static struct spear_shirq *spear320_shirq_blocks[] = {
+	&spear320_shirq_ras3,
+	&spear320_shirq_ras1,
+	&spear320_shirq_ras2,
+	&spear320_shirq_intrcomm_ras,
+};
+
+static void shirq_irq_mask_unmask(struct irq_data *d, bool mask)
 {
 	struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
-	u32 val, id = d->irq - shirq->dev_config[0].virq;
+	u32 val, offset = d->irq - shirq->irq_base;
 	unsigned long flags;
 
-	if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1)
+	if (shirq->regs.enb_reg == -1)
 		return;
 
 	spin_lock_irqsave(&lock, flags);
-	val = readl(shirq->regs.base + shirq->regs.enb_reg);
-	if (shirq->regs.reset_to_enb)
-		val |= shirq->dev_config[id].enb_mask;
+	val = readl(shirq->base + shirq->regs.enb_reg);
+
+	if (mask ^ shirq->regs.reset_to_enb)
+		val &= ~(0x1 << shirq->irq_bit_off << offset);
 	else
-		val &= ~(shirq->dev_config[id].enb_mask);
-	writel(val, shirq->regs.base + shirq->regs.enb_reg);
+		val |= 0x1 << shirq->irq_bit_off << offset;
+
+	writel(val, shirq->base + shirq->regs.enb_reg);
 	spin_unlock_irqrestore(&lock, flags);
+
 }
 
-static void shirq_irq_unmask(struct irq_data *d)
+static void shirq_irq_mask(struct irq_data *d)
 {
-	struct spear_shirq *shirq = irq_data_get_irq_chip_data(d);
-	u32 val, id = d->irq - shirq->dev_config[0].virq;
-	unsigned long flags;
-
-	if ((shirq->regs.enb_reg == -1) || shirq->dev_config[id].enb_mask == -1)
-		return;
+	shirq_irq_mask_unmask(d, 1);
+}
 
-	spin_lock_irqsave(&lock, flags);
-	val = readl(shirq->regs.base + shirq->regs.enb_reg);
-	if (shirq->regs.reset_to_enb)
-		val &= ~(shirq->dev_config[id].enb_mask);
-	else
-		val |= shirq->dev_config[id].enb_mask;
-	writel(val, shirq->regs.base + shirq->regs.enb_reg);
-	spin_unlock_irqrestore(&lock, flags);
+static void shirq_irq_unmask(struct irq_data *d)
+{
+	shirq_irq_mask_unmask(d, 0);
 }
 
 static struct irq_chip shirq_chip = {
-	.name		= "spear_shirq",
+	.name		= "spear-shirq",
 	.irq_ack	= shirq_irq_mask,
 	.irq_mask	= shirq_irq_mask,
 	.irq_unmask	= shirq_irq_unmask,
@@ -67,52 +193,131 @@ static struct irq_chip shirq_chip = {
 
 static void shirq_handler(unsigned irq, struct irq_desc *desc)
 {
-	u32 i, val, mask;
+	u32 i, j, val, mask, tmp;
+	struct irq_chip *chip;
 	struct spear_shirq *shirq = irq_get_handler_data(irq);
 
-	desc->irq_data.chip->irq_ack(&desc->irq_data);
-	while ((val = readl(shirq->regs.base + shirq->regs.status_reg) &
-				shirq->regs.status_reg_mask)) {
-		for (i = 0; (i < shirq->dev_count) && val; i++) {
-			if (!(shirq->dev_config[i].status_mask & val))
+	chip = irq_get_chip(irq);
+	chip->irq_ack(&desc->irq_data);
+
+	mask = ((0x1 << shirq->irq_nr) - 1) << shirq->irq_bit_off;
+	while ((val = readl(shirq->base + shirq->regs.status_reg) &
+				mask)) {
+
+		val >>= shirq->irq_bit_off;
+		for (i = 0, j = 1; i < shirq->irq_nr; i++, j <<= 1) {
+
+			if (!(j & val))
 				continue;
 
-			generic_handle_irq(shirq->dev_config[i].virq);
+			generic_handle_irq(shirq->irq_base + i);
 
 			/* clear interrupt */
-			val &= ~shirq->dev_config[i].status_mask;
-			if ((shirq->regs.clear_reg == -1) ||
-					shirq->dev_config[i].clear_mask == -1)
+			if (shirq->regs.clear_reg == -1)
 				continue;
-			mask = readl(shirq->regs.base + shirq->regs.clear_reg);
+
+			tmp = readl(shirq->base + shirq->regs.clear_reg);
 			if (shirq->regs.reset_to_clear)
-				mask &= ~shirq->dev_config[i].clear_mask;
+				tmp &= ~(j << shirq->irq_bit_off);
 			else
-				mask |= shirq->dev_config[i].clear_mask;
-			writel(mask, shirq->regs.base + shirq->regs.clear_reg);
+				tmp |= (j << shirq->irq_bit_off);
+			writel(tmp, shirq->base + shirq->regs.clear_reg);
 		}
 	}
-	desc->irq_data.chip->irq_unmask(&desc->irq_data);
+	chip->irq_unmask(&desc->irq_data);
 }
 
-int spear_shirq_register(struct spear_shirq *shirq)
+static void __init spear_shirq_register(struct spear_shirq *shirq)
 {
 	int i;
 
-	if (!shirq || !shirq->dev_config || !shirq->regs.base)
-		return -EFAULT;
-
-	if (!shirq->dev_count)
-		return -EINVAL;
+	if (shirq->invalid_irq)
+		return;
 
 	irq_set_chained_handler(shirq->irq, shirq_handler);
-	for (i = 0; i < shirq->dev_count; i++) {
-		irq_set_chip_and_handler(shirq->dev_config[i].virq,
+	for (i = 0; i < shirq->irq_nr; i++) {
+		irq_set_chip_and_handler(shirq->irq_base + i,
 					 &shirq_chip, handle_simple_irq);
-		set_irq_flags(shirq->dev_config[i].virq, IRQF_VALID);
-		irq_set_chip_data(shirq->dev_config[i].virq, shirq);
+		set_irq_flags(shirq->irq_base + i, IRQF_VALID);
+		irq_set_chip_data(shirq->irq_base + i, shirq);
 	}
 
 	irq_set_handler_data(shirq->irq, shirq);
+}
+
+static int __init shirq_init(struct spear_shirq **shirq_blocks, int block_nr,
+		void __iomem *base, struct device_node *np)
+{
+	int i, irq_base, hwirq = 0, irq_nr = 0;
+	static struct irq_domain *shirq_domain;
+
+	for (i = 0; i < block_nr; i++)
+		irq_nr += shirq_blocks[i]->irq_nr;
+
+	irq_base = irq_alloc_descs(-1, 0, irq_nr, 0);
+	if (IS_ERR_VALUE(irq_base)) {
+		pr_err("%s: irq desc alloc failed\n", __func__);
+		return -ENXIO;
+	}
+
+	shirq_domain = irq_domain_add_legacy(np, irq_nr, irq_base, 0,
+			&irq_domain_simple_ops, NULL);
+	if (WARN_ON(!shirq_domain)) {
+		pr_warn("%s: irq domain init failed\n", __func__);
+		irq_free_descs(irq_base, irq_nr);
+		return -ENXIO;
+	}
+
+	for (i = 0; i < block_nr; i++) {
+		shirq_blocks[i]->base = base;
+		shirq_blocks[i]->irq_base = irq_find_mapping(shirq_domain,
+				hwirq);
+		shirq_blocks[i]->irq = irq_of_parse_and_map(np, i);
+
+		spear_shirq_register(shirq_blocks[i]);
+		hwirq += shirq_blocks[i]->irq_nr;
+	}
+
 	return 0;
 }
+
+int __init spear3xx_shirq_of_init(struct device_node *np,
+		struct device_node *parent)
+{
+	struct spear_shirq **shirq_blocks;
+	void __iomem *base;
+	int block_nr, ret;
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("%s: failed to map shirq registers\n", __func__);
+		return -ENXIO;
+	}
+
+	if (of_device_is_compatible(np, "st,spear300-shirq")) {
+		shirq_blocks = spear300_shirq_blocks;
+		block_nr = ARRAY_SIZE(spear300_shirq_blocks);
+	} else if (of_device_is_compatible(np, "st,spear310-shirq")) {
+		shirq_blocks = spear310_shirq_blocks;
+		block_nr = ARRAY_SIZE(spear310_shirq_blocks);
+	} else if (of_device_is_compatible(np, "st,spear320-shirq")) {
+		shirq_blocks = spear320_shirq_blocks;
+		block_nr = ARRAY_SIZE(spear320_shirq_blocks);
+	} else {
+		pr_err("%s: unknown platform\n", __func__);
+		ret = -EINVAL;
+		goto unmap;
+	}
+
+	ret = shirq_init(shirq_blocks, block_nr, base, np);
+	if (ret) {
+		pr_err("%s: shirq initialization failed\n", __func__);
+		goto unmap;
+	}
+
+	return ret;
+
+unmap:
+	iounmap(base);
+	return ret;
+}
