Skip to content

Commit

Permalink
ARM: 6091/1: ST SPEAr: Adding support for shared irq layer
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
viresh kumar authored and Russell King committed May 4, 2010
1 parent ff37f6e commit 4c18e77
Show file tree
Hide file tree
Showing 11 changed files with 718 additions and 8 deletions.
101 changes: 94 additions & 7 deletions arch/arm/mach-spear3xx/include/mach/irqs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 */
16 changes: 16 additions & 0 deletions arch/arm/mach-spear3xx/include/mach/spear300.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
24 changes: 24 additions & 0 deletions arch/arm/mach-spear3xx/include/mach/spear310.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
26 changes: 26 additions & 0 deletions arch/arm/mach-spear3xx/include/mach/spear320.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
67 changes: 66 additions & 1 deletion arch/arm/mach-spear3xx/spear300.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 4c18e77

Please sign in to comment.