aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-spear3xx
diff options
context:
space:
mode:
authorviresh kumar <viresh.kumar@st.com>2010-05-03 09:24:30 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-05-04 16:54:54 +0100
commit4c18e77f718cdda33363132127db4df795eadbd9 (patch)
treebbecdc08f487246049bb6d0c212d338a9056597a /arch/arm/mach-spear3xx
parentff37f6e5910c4fd7ad42063d89c0687def665941 (diff)
downloadkernel_samsung_espresso10-4c18e77f718cdda33363132127db4df795eadbd9.zip
kernel_samsung_espresso10-4c18e77f718cdda33363132127db4df795eadbd9.tar.gz
kernel_samsung_espresso10-4c18e77f718cdda33363132127db4df795eadbd9.tar.bz2
ARM: 6091/1: ST SPEAr: Adding support for shared irq layer
Multiple peripherals in SPEAr share common hardware interrupt lines. This patch adds support for a shared irq layer, which registers hardware irqs by itself and exposes virtual irq numbers to peripherals. Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-spear3xx')
-rw-r--r--arch/arm/mach-spear3xx/include/mach/irqs.h101
-rw-r--r--arch/arm/mach-spear3xx/include/mach/spear300.h16
-rw-r--r--arch/arm/mach-spear3xx/include/mach/spear310.h24
-rw-r--r--arch/arm/mach-spear3xx/include/mach/spear320.h26
-rw-r--r--arch/arm/mach-spear3xx/spear300.c67
-rw-r--r--arch/arm/mach-spear3xx/spear310.c148
-rw-r--r--arch/arm/mach-spear3xx/spear320.c150
7 files changed, 524 insertions, 8 deletions
diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h
index fe980e0..7f940b8 100644
--- a/arch/arm/mach-spear3xx/include/mach/irqs.h
+++ b/arch/arm/mach-spear3xx/include/mach/irqs.h
@@ -14,7 +14,7 @@
#ifndef __MACH_IRQS_H
#define __MACH_IRQS_H
-/* IRQ definitions */
+/* SPEAr3xx IRQ definitions */
#define IRQ_HW_ACCEL_MOD_0 0
#define IRQ_INTRCOMM_RAS_ARM 1
#define IRQ_CPU_GPT1_1 2
@@ -50,16 +50,103 @@
#define IRQ_HW_ACCEL_MOD_1 31
#define IRQ_VIC_END 32
-#define SPEAR_GPIO_INT_BASE IRQ_VIC_END
+#define VIRQ_START IRQ_VIC_END
+/* SPEAr300 Virtual irq definitions */
#ifdef CONFIG_MACH_SPEAR300
-#define SPEAR_GPIO1_INT_BASE (SPEAR_GPIO_INT_BASE + 8)
-#define SPEAR_GPIO_INT_END (SPEAR_GPIO1_INT_BASE + 8)
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define VIRQ_IT_PERS_S (VIRQ_START + 0)
+#define VIRQ_IT_CHANGE_S (VIRQ_START + 1)
+#define VIRQ_I2S (VIRQ_START + 2)
+#define VIRQ_TDM (VIRQ_START + 3)
+#define VIRQ_CAMERA_L (VIRQ_START + 4)
+#define VIRQ_CAMERA_F (VIRQ_START + 5)
+#define VIRQ_CAMERA_V (VIRQ_START + 6)
+#define VIRQ_KEYBOARD (VIRQ_START + 7)
+#define VIRQ_GPIO1 (VIRQ_START + 8)
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define IRQ_CLCD IRQ_GEN_RAS_3
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define IRQ_SDIO IRQ_INTRCOMM_RAS_ARM
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE (VIRQ_START + 9)
+#define SPEAR_GPIO1_INT_BASE (SPEAR_GPIO_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END (SPEAR_GPIO1_INT_BASE + 8)
+
+/* SPEAr310 Virtual irq definitions */
+#elif defined(CONFIG_MACH_SPEAR310)
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define VIRQ_SMII0 (VIRQ_START + 0)
+#define VIRQ_SMII1 (VIRQ_START + 1)
+#define VIRQ_SMII2 (VIRQ_START + 2)
+#define VIRQ_SMII3 (VIRQ_START + 3)
+#define VIRQ_WAKEUP_SMII0 (VIRQ_START + 4)
+#define VIRQ_WAKEUP_SMII1 (VIRQ_START + 5)
+#define VIRQ_WAKEUP_SMII2 (VIRQ_START + 6)
+#define VIRQ_WAKEUP_SMII3 (VIRQ_START + 7)
+
+/* IRQs sharing IRQ_GEN_RAS_2 */
+#define VIRQ_UART1 (VIRQ_START + 8)
+#define VIRQ_UART2 (VIRQ_START + 9)
+#define VIRQ_UART3 (VIRQ_START + 10)
+#define VIRQ_UART4 (VIRQ_START + 11)
+#define VIRQ_UART5 (VIRQ_START + 12)
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define VIRQ_EMI (VIRQ_START + 13)
+#define VIRQ_PLGPIO (VIRQ_START + 14)
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define VIRQ_TDM_HDLC (VIRQ_START + 15)
+#define VIRQ_RS485_0 (VIRQ_START + 16)
+#define VIRQ_RS485_1 (VIRQ_START + 17)
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE (VIRQ_START + 18)
+
+/* SPEAr320 Virtual irq definitions */
#else
-#define SPEAR_GPIO_INT_END (SPEAR_GPIO_INT_BASE + 8)
+/* IRQs sharing IRQ_GEN_RAS_1 */
+#define VIRQ_EMI (VIRQ_START + 0)
+#define VIRQ_CLCD (VIRQ_START + 1)
+#define VIRQ_SPP (VIRQ_START + 2)
+
+/* IRQs sharing IRQ_GEN_RAS_2 */
+#define IRQ_SDIO IRQ_GEN_RAS_2
+
+/* IRQs sharing IRQ_GEN_RAS_3 */
+#define VIRQ_PLGPIO (VIRQ_START + 3)
+#define VIRQ_I2S_PLAY (VIRQ_START + 4)
+#define VIRQ_I2S_REC (VIRQ_START + 5)
+
+/* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
+#define VIRQ_CANU (VIRQ_START + 6)
+#define VIRQ_CANL (VIRQ_START + 7)
+#define VIRQ_UART1 (VIRQ_START + 8)
+#define VIRQ_UART2 (VIRQ_START + 9)
+#define VIRQ_SSP1 (VIRQ_START + 10)
+#define VIRQ_SSP2 (VIRQ_START + 11)
+#define VIRQ_SMII0 (VIRQ_START + 12)
+#define VIRQ_MII1_SMII1 (VIRQ_START + 13)
+#define VIRQ_WAKEUP_SMII0 (VIRQ_START + 14)
+#define VIRQ_WAKEUP_MII1_SMII1 (VIRQ_START + 15)
+#define VIRQ_I2C (VIRQ_START + 16)
+
+/* GPIO pins virtual irqs */
+#define SPEAR_GPIO_INT_BASE (VIRQ_START + 17)
+
+#endif
+
+/* PLGPIO Virtual IRQs */
+#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
+#define SPEAR_PLGPIO_INT_BASE (SPEAR_GPIO_INT_BASE + 8)
+#define SPEAR_GPIO_INT_END (SPEAR_PLGPIO_INT_BASE + 102)
#endif
-#define VIRTUAL_IRQS (SPEAR_GPIO_INT_END - IRQ_VIC_END)
-#define NR_IRQS (IRQ_VIC_END + VIRTUAL_IRQS)
+#define VIRQ_END SPEAR_GPIO_INT_END
+#define NR_IRQS VIRQ_END
#endif /* __MACH_IRQS_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h
index 40c16f3..ccaa765 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear300.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear300.h
@@ -20,6 +20,22 @@
#define SPEAR300_TELECOM_BASE 0x50000000
#define SPEAR300_TELECOM_SIZE 0x10000000
+/* Interrupt registers offsets and masks */
+#define SPEAR300_TELECOM_REG_SIZE 0x00010000
+#define INT_ENB_MASK_REG 0x54
+#define INT_STS_MASK_REG 0x58
+#define IT_PERS_S_IRQ_MASK (1 << 0)
+#define IT_CHANGE_S_IRQ_MASK (1 << 1)
+#define I2S_IRQ_MASK (1 << 2)
+#define TDM_IRQ_MASK (1 << 3)
+#define CAMERA_L_IRQ_MASK (1 << 4)
+#define CAMERA_F_IRQ_MASK (1 << 5)
+#define CAMERA_V_IRQ_MASK (1 << 6)
+#define KEYBOARD_IRQ_MASK (1 << 7)
+#define GPIO1_IRQ_MASK (1 << 8)
+
+#define SHIRQ_RAS1_MASK 0x1FF
+
#define SPEAR300_CLCD_BASE 0x60000000
#define SPEAR300_CLCD_SIZE 0x10000000
diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h
index d4f58d6..b27bb8a 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear310.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear310.h
@@ -40,6 +40,30 @@
#define SPEAR310_SOC_CONFIG_BASE 0xB4000000
#define SPEAR310_SOC_CONFIG_SIZE 0x00000070
+/* Interrupt registers offsets and masks */
+#define INT_STS_MASK_REG 0x04
+#define SMII0_IRQ_MASK (1 << 0)
+#define SMII1_IRQ_MASK (1 << 1)
+#define SMII2_IRQ_MASK (1 << 2)
+#define SMII3_IRQ_MASK (1 << 3)
+#define WAKEUP_SMII0_IRQ_MASK (1 << 4)
+#define WAKEUP_SMII1_IRQ_MASK (1 << 5)
+#define WAKEUP_SMII2_IRQ_MASK (1 << 6)
+#define WAKEUP_SMII3_IRQ_MASK (1 << 7)
+#define UART1_IRQ_MASK (1 << 8)
+#define UART2_IRQ_MASK (1 << 9)
+#define UART3_IRQ_MASK (1 << 10)
+#define UART4_IRQ_MASK (1 << 11)
+#define UART5_IRQ_MASK (1 << 12)
+#define EMI_IRQ_MASK (1 << 13)
+#define TDM_HDLC_IRQ_MASK (1 << 14)
+#define RS485_0_IRQ_MASK (1 << 15)
+#define RS485_1_IRQ_MASK (1 << 16)
+
+#define SHIRQ_RAS1_MASK 0x000FF
+#define SHIRQ_RAS2_MASK 0x01F00
+#define SHIRQ_RAS3_MASK 0x02000
+#define SHIRQ_INTRCOMM_RAS_MASK 0x1C000
#endif /* __MACH_SPEAR310_H */
diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h
index e8ad2ed..cacf17a 100644
--- a/arch/arm/mach-spear3xx/include/mach/spear320.h
+++ b/arch/arm/mach-spear3xx/include/mach/spear320.h
@@ -64,6 +64,32 @@
#define SPEAR320_SOC_CONFIG_BASE 0xB4000000
#define SPEAR320_SOC_CONFIG_SIZE 0x00000070
+/* Interrupt registers offsets and masks */
+#define INT_STS_MASK_REG 0x04
+#define INT_CLR_MASK_REG 0x04
+#define INT_ENB_MASK_REG 0x08
+#define GPIO_IRQ_MASK (1 << 0)
+#define I2S_PLAY_IRQ_MASK (1 << 1)
+#define I2S_REC_IRQ_MASK (1 << 2)
+#define EMI_IRQ_MASK (1 << 7)
+#define CLCD_IRQ_MASK (1 << 8)
+#define SPP_IRQ_MASK (1 << 9)
+#define SDIO_IRQ_MASK (1 << 10)
+#define CAN_U_IRQ_MASK (1 << 11)
+#define CAN_L_IRQ_MASK (1 << 12)
+#define UART1_IRQ_MASK (1 << 13)
+#define UART2_IRQ_MASK (1 << 14)
+#define SSP1_IRQ_MASK (1 << 15)
+#define SSP2_IRQ_MASK (1 << 16)
+#define SMII0_IRQ_MASK (1 << 17)
+#define MII1_SMII1_IRQ_MASK (1 << 18)
+#define WAKEUP_SMII0_IRQ_MASK (1 << 19)
+#define WAKEUP_MII1_SMII1_IRQ_MASK (1 << 20)
+#define I2C1_IRQ_MASK (1 << 21)
+
+#define SHIRQ_RAS1_MASK 0x000380
+#define SHIRQ_RAS3_MASK 0x000007
+#define SHIRQ_INTRCOMM_RAS_MASK 0x3FF800
#endif /* __MACH_SPEAR320_H */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 66e7fcd..3560f8c 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -17,6 +17,7 @@
#include <asm/irq.h>
#include <mach/generic.h>
#include <mach/spear.h>
+#include <plat/shirq.h>
/* pad multiplexing support */
/* muxing registers */
@@ -386,14 +387,78 @@ struct amba_device gpio1_device = {
.end = SPEAR300_GPIO_BASE + SPEAR300_GPIO_SIZE - 1,
.flags = IORESOURCE_MEM,
},
- .irq = {IRQ_GEN_RAS_1, NO_IRQ},
+ .irq = {VIRQ_GPIO1, NO_IRQ},
+};
+
+/* spear3xx shared irq */
+struct shirq_dev_config shirq_ras1_config[] = {
+ {
+ .virq = VIRQ_IT_PERS_S,
+ .enb_mask = IT_PERS_S_IRQ_MASK,
+ .status_mask = IT_PERS_S_IRQ_MASK,
+ }, {
+ .virq = VIRQ_IT_CHANGE_S,
+ .enb_mask = IT_CHANGE_S_IRQ_MASK,
+ .status_mask = IT_CHANGE_S_IRQ_MASK,
+ }, {
+ .virq = VIRQ_I2S,
+ .enb_mask = I2S_IRQ_MASK,
+ .status_mask = I2S_IRQ_MASK,
+ }, {
+ .virq = VIRQ_TDM,
+ .enb_mask = TDM_IRQ_MASK,
+ .status_mask = TDM_IRQ_MASK,
+ }, {
+ .virq = VIRQ_CAMERA_L,
+ .enb_mask = CAMERA_L_IRQ_MASK,
+ .status_mask = CAMERA_L_IRQ_MASK,
+ }, {
+ .virq = VIRQ_CAMERA_F,
+ .enb_mask = CAMERA_F_IRQ_MASK,
+ .status_mask = CAMERA_F_IRQ_MASK,
+ }, {
+ .virq = VIRQ_CAMERA_V,
+ .enb_mask = CAMERA_V_IRQ_MASK,
+ .status_mask = CAMERA_V_IRQ_MASK,
+ }, {
+ .virq = VIRQ_KEYBOARD,
+ .enb_mask = KEYBOARD_IRQ_MASK,
+ .status_mask = KEYBOARD_IRQ_MASK,
+ }, {
+ .virq = VIRQ_GPIO1,
+ .enb_mask = GPIO1_IRQ_MASK,
+ .status_mask = GPIO1_IRQ_MASK,
+ },
+};
+
+struct spear_shirq shirq_ras1 = {
+ .irq = IRQ_GEN_RAS_1,
+ .dev_config = shirq_ras1_config,
+ .dev_count = ARRAY_SIZE(shirq_ras1_config),
+ .regs = {
+ .enb_reg = INT_ENB_MASK_REG,
+ .status_reg = INT_STS_MASK_REG,
+ .status_reg_mask = SHIRQ_RAS1_MASK,
+ .clear_reg = -1,
+ },
};
/* spear300 routines */
void __init spear300_init(void)
{
+ int ret = 0;
+
/* call spear3xx family common init function */
spear3xx_init();
+
+ /* shared irq registeration */
+ shirq_ras1.regs.base =
+ ioremap(SPEAR300_TELECOM_BASE, SPEAR300_TELECOM_REG_SIZE);
+ if (shirq_ras1.regs.base) {
+ ret = spear_shirq_register(&shirq_ras1);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ\n");
+ }
}
void spear300_pmx_init(void)
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index dd5a572..96a1ab8 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -15,6 +15,7 @@
#include <asm/irq.h>
#include <mach/generic.h>
#include <mach/spear.h>
+#include <plat/shirq.h>
/* pad multiplexing support */
/* muxing registers */
@@ -140,11 +141,158 @@ struct pmx_driver pmx_driver = {
/* Add spear310 specific devices here */
+/* spear3xx shared irq */
+struct shirq_dev_config shirq_ras1_config[] = {
+ {
+ .virq = VIRQ_SMII0,
+ .status_mask = SMII0_IRQ_MASK,
+ }, {
+ .virq = VIRQ_SMII1,
+ .status_mask = SMII1_IRQ_MASK,
+ }, {
+ .virq = VIRQ_SMII2,
+ .status_mask = SMII2_IRQ_MASK,
+ }, {
+ .virq = VIRQ_SMII3,
+ .status_mask = SMII3_IRQ_MASK,
+ }, {
+ .virq = VIRQ_WAKEUP_SMII0,
+ .status_mask = WAKEUP_SMII0_IRQ_MASK,
+ }, {
+ .virq = VIRQ_WAKEUP_SMII1,
+ .status_mask = WAKEUP_SMII1_IRQ_MASK,
+ }, {
+ .virq = VIRQ_WAKEUP_SMII2,
+ .status_mask = WAKEUP_SMII2_IRQ_MASK,
+ }, {
+ .virq = VIRQ_WAKEUP_SMII3,
+ .status_mask = WAKEUP_SMII3_IRQ_MASK,
+ },
+};
+
+struct spear_shirq shirq_ras1 = {
+ .irq = IRQ_GEN_RAS_1,
+ .dev_config = shirq_ras1_config,
+ .dev_count = ARRAY_SIZE(shirq_ras1_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = INT_STS_MASK_REG,
+ .status_reg_mask = SHIRQ_RAS1_MASK,
+ .clear_reg = -1,
+ },
+};
+
+struct shirq_dev_config shirq_ras2_config[] = {
+ {
+ .virq = VIRQ_UART1,
+ .status_mask = UART1_IRQ_MASK,
+ }, {
+ .virq = VIRQ_UART2,
+ .status_mask = UART2_IRQ_MASK,
+ }, {
+ .virq = VIRQ_UART3,
+ .status_mask = UART3_IRQ_MASK,
+ }, {
+ .virq = VIRQ_UART4,
+ .status_mask = UART4_IRQ_MASK,
+ }, {
+ .virq = VIRQ_UART5,
+ .status_mask = UART5_IRQ_MASK,
+ },
+};
+
+struct spear_shirq shirq_ras2 = {
+ .irq = IRQ_GEN_RAS_2,
+ .dev_config = shirq_ras2_config,
+ .dev_count = ARRAY_SIZE(shirq_ras2_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = INT_STS_MASK_REG,
+ .status_reg_mask = SHIRQ_RAS2_MASK,
+ .clear_reg = -1,
+ },
+};
+
+struct shirq_dev_config shirq_ras3_config[] = {
+ {
+ .virq = VIRQ_EMI,
+ .status_mask = EMI_IRQ_MASK,
+ },
+};
+
+struct spear_shirq shirq_ras3 = {
+ .irq = IRQ_GEN_RAS_3,
+ .dev_config = shirq_ras3_config,
+ .dev_count = ARRAY_SIZE(shirq_ras3_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = INT_STS_MASK_REG,
+ .status_reg_mask = SHIRQ_RAS3_MASK,
+ .clear_reg = -1,
+ },
+};
+
+struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+ {
+ .virq = VIRQ_TDM_HDLC,
+ .status_mask = TDM_HDLC_IRQ_MASK,
+ }, {
+ .virq = VIRQ_RS485_0,
+ .status_mask = RS485_0_IRQ_MASK,
+ }, {
+ .virq = VIRQ_RS485_1,
+ .status_mask = RS485_1_IRQ_MASK,
+ },
+};
+
+struct spear_shirq shirq_intrcomm_ras = {
+ .irq = IRQ_INTRCOMM_RAS_ARM,
+ .dev_config = shirq_intrcomm_ras_config,
+ .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = INT_STS_MASK_REG,
+ .status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK,
+ .clear_reg = -1,
+ },
+};
+
/* spear310 routines */
void __init spear310_init(void)
{
+ void __iomem *base;
+ int ret = 0;
+
/* call spear3xx family common init function */
spear3xx_init();
+
+ /* shared irq registeration */
+ base = ioremap(SPEAR310_SOC_CONFIG_BASE, SPEAR310_SOC_CONFIG_SIZE);
+ if (base) {
+ /* shirq 1 */
+ shirq_ras1.regs.base = base;
+ ret = spear_shirq_register(&shirq_ras1);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 1\n");
+
+ /* shirq 2 */
+ shirq_ras2.regs.base = base;
+ ret = spear_shirq_register(&shirq_ras2);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 2\n");
+
+ /* shirq 3 */
+ shirq_ras3.regs.base = base;
+ ret = spear_shirq_register(&shirq_ras3);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 3\n");
+
+ /* shirq 4 */
+ shirq_intrcomm_ras.regs.base = base;
+ ret = spear_shirq_register(&shirq_intrcomm_ras);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 4\n");
+ }
}
void spear310_pmx_init(void)
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 2cedf5e..6a12195 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -15,6 +15,7 @@
#include <asm/irq.h>
#include <mach/generic.h>
#include <mach/spear.h>
+#include <plat/shirq.h>
/* pad multiplexing support */
/* muxing registers */
@@ -385,11 +386,160 @@ struct pmx_driver pmx_driver = {
/* Add spear320 specific devices here */
+/* spear3xx shared irq */
+struct shirq_dev_config shirq_ras1_config[] = {
+ {
+ .virq = VIRQ_EMI,
+ .status_mask = EMI_IRQ_MASK,
+ .clear_mask = EMI_IRQ_MASK,
+ }, {
+ .virq = VIRQ_CLCD,
+ .status_mask = CLCD_IRQ_MASK,
+ .clear_mask = CLCD_IRQ_MASK,
+ }, {
+ .virq = VIRQ_SPP,
+ .status_mask = SPP_IRQ_MASK,
+ .clear_mask = SPP_IRQ_MASK,
+ },
+};
+
+struct spear_shirq shirq_ras1 = {
+ .irq = IRQ_GEN_RAS_1,
+ .dev_config = shirq_ras1_config,
+ .dev_count = ARRAY_SIZE(shirq_ras1_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = INT_STS_MASK_REG,
+ .status_reg_mask = SHIRQ_RAS1_MASK,
+ .clear_reg = INT_CLR_MASK_REG,
+ .reset_to_clear = 1,
+ },
+};
+
+struct shirq_dev_config shirq_ras3_config[] = {
+ {
+ .virq = VIRQ_PLGPIO,
+ .enb_mask = GPIO_IRQ_MASK,
+ .status_mask = GPIO_IRQ_MASK,
+ .clear_mask = GPIO_IRQ_MASK,
+ }, {
+ .virq = VIRQ_I2S_PLAY,
+ .enb_mask = I2S_PLAY_IRQ_MASK,
+ .status_mask = I2S_PLAY_IRQ_MASK,
+ .clear_mask = I2S_PLAY_IRQ_MASK,
+ }, {
+ .virq = VIRQ_I2S_REC,
+ .enb_mask = I2S_REC_IRQ_MASK,
+ .status_mask = I2S_REC_IRQ_MASK,
+ .clear_mask = I2S_REC_IRQ_MASK,
+ },
+};
+
+struct spear_shirq shirq_ras3 = {
+ .irq = IRQ_GEN_RAS_3,
+ .dev_config = shirq_ras3_config,
+ .dev_count = ARRAY_SIZE(shirq_ras3_config),
+ .regs = {
+ .enb_reg = INT_ENB_MASK_REG,
+ .reset_to_enb = 1,
+ .status_reg = INT_STS_MASK_REG,
+ .status_reg_mask = SHIRQ_RAS3_MASK,
+ .clear_reg = INT_CLR_MASK_REG,
+ .reset_to_clear = 1,
+ },
+};
+
+struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+ {
+ .virq = VIRQ_CANU,
+ .status_mask = CAN_U_IRQ_MASK,
+ .clear_mask = CAN_U_IRQ_MASK,
+ }, {
+ .virq = VIRQ_CANL,
+ .status_mask = CAN_L_IRQ_MASK,
+ .clear_mask = CAN_L_IRQ_MASK,
+ }, {
+ .virq = VIRQ_UART1,
+ .status_mask = UART1_IRQ_MASK,
+ .clear_mask = UART1_IRQ_MASK,
+ }, {
+ .virq = VIRQ_UART2,
+ .status_mask = UART2_IRQ_MASK,
+ .clear_mask = UART2_IRQ_MASK,
+ }, {
+ .virq = VIRQ_SSP1,
+ .status_mask = SSP1_IRQ_MASK,
+ .clear_mask = SSP1_IRQ_MASK,
+ }, {
+ .virq = VIRQ_SSP2,
+ .status_mask = SSP2_IRQ_MASK,
+ .clear_mask = SSP2_IRQ_MASK,
+ }, {
+ .virq = VIRQ_SMII0,
+ .status_mask = SMII0_IRQ_MASK,
+ .clear_mask = SMII0_IRQ_MASK,
+ }, {
+ .virq = VIRQ_MII1_SMII1,
+ .status_mask = MII1_SMII1_IRQ_MASK,
+ .clear_mask = MII1_SMII1_IRQ_MASK,
+ }, {
+ .virq = VIRQ_WAKEUP_SMII0,
+ .status_mask = WAKEUP_SMII0_IRQ_MASK,
+ .clear_mask = WAKEUP_SMII0_IRQ_MASK,
+ }, {
+ .virq = VIRQ_WAKEUP_MII1_SMII1,
+ .status_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
+ .clear_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
+ }, {
+ .virq = VIRQ_I2C,
+ .status_mask = I2C1_IRQ_MASK,
+ .clear_mask = I2C1_IRQ_MASK,
+ },
+};
+
+struct spear_shirq shirq_intrcomm_ras = {
+ .irq = IRQ_INTRCOMM_RAS_ARM,
+ .dev_config = shirq_intrcomm_ras_config,
+ .dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
+ .regs = {
+ .enb_reg = -1,
+ .status_reg = INT_STS_MASK_REG,
+ .status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK,
+ .clear_reg = INT_CLR_MASK_REG,
+ .reset_to_clear = 1,
+ },
+};
+
/* spear320 routines */
void __init spear320_init(void)
{
+ void __iomem *base;
+ int ret = 0;
+
/* call spear3xx family common init function */
spear3xx_init();
+
+ /* shared irq registeration */
+ base = ioremap(SPEAR320_SOC_CONFIG_BASE, SPEAR320_SOC_CONFIG_SIZE);
+ if (base) {
+ /* shirq 1 */
+ shirq_ras1.regs.base = base;
+ ret = spear_shirq_register(&shirq_ras1);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 1\n");
+
+ /* shirq 3 */
+ shirq_ras3.regs.base = base;
+ ret = spear_shirq_register(&shirq_ras3);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 3\n");
+
+ /* shirq 4 */
+ shirq_intrcomm_ras.regs.base = base;
+ ret = spear_shirq_register(&shirq_intrcomm_ras);
+ if (ret)
+ printk(KERN_ERR "Error registering Shared IRQ 4\n");
+ }
}
void spear320_pmx_init(void)