From 953c8ef250fc6c329d1607cf9cd7fac1d72d7579 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 Sep 2007 12:03:50 +0900 Subject: [PATCH] sh: intc - irl mode update for sh7780 and sh7785 This patch contains the following fixes and improvements: - Fix address typo for INTMSK2 / INTMSKCLR2 registers on sh7780. - Adds IRQ_MODE_IRLnnnn_MASK using intc controller for IRL masking. - Good old IRQ_MODE_IRLnnnn should not register any intc controller. - plat_irq_setup_pins() now selects IRL or IRQ mode. - the holding function is now disabled using ICR0. By default all external pin interrupts are disabled. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 43 ++++++++++++++++++++++-- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 45 +++++++++++++++++++++++++- include/asm-sh/hw_irq.h | 1 + 3 files changed, 85 insertions(+), 4 deletions(-) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index d84c4575fc..e8fd33ff06 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -10,6 +10,7 @@ #include #include #include +#include #include static struct resource rtc_resources[] = { @@ -239,7 +240,7 @@ static struct intc_vect irl_vectors[] __initdata = { }; static struct intc_mask_reg irl3210_mask_registers[] __initdata = { - { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ + { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */ { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, @@ -247,7 +248,7 @@ static struct intc_mask_reg irl3210_mask_registers[] __initdata = { }; static struct intc_mask_reg irl7654_mask_registers[] __initdata = { - { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ + { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, @@ -261,8 +262,28 @@ static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7780-irl7654", irl_vectors, static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7780-irl3210", irl_vectors, NULL, NULL, irl3210_mask_registers, NULL, NULL); +#define INTC_ICR0 0xffd00000 +#define INTC_INTMSK0 0xffd00044 +#define INTC_INTMSK1 0xffd00048 +#define INTC_INTMSK2 0xffd40080 +#define INTC_INTMSKCLR1 0xffd00068 +#define INTC_INTMSKCLR2 0xffd40084 + void __init plat_irq_setup(void) { + /* disable IRQ7-0 */ + ctrl_outl(0xff000000, INTC_INTMSK0); + + /* disable IRL3-0 + IRL7-4 */ + ctrl_outl(0xc0000000, INTC_INTMSK1); + ctrl_outl(0xfffefffe, INTC_INTMSK2); + + /* select IRL mode for IRL3-0 + IRL7-4 */ + ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); + + /* disable holding function, ie enable "SH-4 Mode" */ + ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); + register_intc_controller(&intc_desc); } @@ -270,12 +291,28 @@ void __init plat_irq_setup_pins(int mode) { switch (mode) { case IRQ_MODE_IRQ: + /* select IRQ mode for IRL3-0 + IRL7-4 */ + ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00c00000, INTC_ICR0); register_intc_controller(&intc_irq_desc); break; case IRQ_MODE_IRL7654: - register_intc_controller(&intc_irl7654_desc); + /* enable IRL7-4 but don't provide any masking */ + ctrl_outl(0x40000000, INTC_INTMSKCLR1); + ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL3210: + /* enable IRL0-3 but don't provide any masking */ + ctrl_outl(0x80000000, INTC_INTMSKCLR1); + ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + break; + case IRQ_MODE_IRL7654_MASK: + /* enable IRL7-4 and mask using cpu intc controller */ + ctrl_outl(0x40000000, INTC_INTMSKCLR1); + register_intc_controller(&intc_irl7654_desc); + break; + case IRQ_MODE_IRL3210_MASK: + /* enable IRL0-3 and mask using cpu intc controller */ + ctrl_outl(0x80000000, INTC_INTMSKCLR1); register_intc_controller(&intc_irl3210_desc); break; default: diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index a595203f74..486dabe4d2 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -10,6 +10,7 @@ #include #include #include +#include #include static struct plat_sci_port sci_platform_data[] = { @@ -282,24 +283,66 @@ static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7785-irl0123", vectors_irl0123, static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567, NULL, NULL, mask_registers, NULL, NULL); +#define INTC_ICR0 0xffd00000 +#define INTC_INTMSK0 0xffd00044 +#define INTC_INTMSK1 0xffd00048 +#define INTC_INTMSK2 0xffd40080 +#define INTC_INTMSKCLR1 0xffd00068 +#define INTC_INTMSKCLR2 0xffd40084 + void __init plat_irq_setup(void) { + /* disable IRQ3-0 + IRQ7-4 */ + ctrl_outl(0xff000000, INTC_INTMSK0); + + /* disable IRL3-0 + IRL7-4 */ + ctrl_outl(0xc0000000, INTC_INTMSK1); + ctrl_outl(0xfffefffe, INTC_INTMSK2); + + /* select IRL mode for IRL3-0 + IRL7-4 */ + ctrl_outl(ctrl_inl(INTC_ICR0) & ~0x00c00000, INTC_ICR0); + + /* disable holding function, ie enable "SH-4 Mode" */ + ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00200000, INTC_ICR0); + register_intc_controller(&intc_desc); } void __init plat_irq_setup_pins(int mode) { + ctrl_outl(0xc0000000, INTC_INTMSKCLR1); + ctrl_outl(0xfffefffe, INTC_INTMSKCLR2); + return; + switch (mode) { case IRQ_MODE_IRQ7654: + /* select IRQ mode for IRL7-4 */ + ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00400000, INTC_ICR0); register_intc_controller(&intc_desc_irq4567); break; case IRQ_MODE_IRQ3210: + /* select IRQ mode for IRL3-0 */ + ctrl_outl(ctrl_inl(INTC_ICR0) | 0x00800000, INTC_ICR0); register_intc_controller(&intc_desc_irq0123); break; case IRQ_MODE_IRL7654: - register_intc_controller(&intc_desc_irl4567); + /* enable IRL7-4 but don't provide any masking */ + ctrl_outl(0x40000000, INTC_INTMSKCLR1); + ctrl_outl(0x0000fffe, INTC_INTMSKCLR2); break; case IRQ_MODE_IRL3210: + /* enable IRL0-3 but don't provide any masking */ + ctrl_outl(0x80000000, INTC_INTMSKCLR1); + ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); + break; + case IRQ_MODE_IRL7654_MASK: + /* enable IRL7-4 and mask using cpu intc controller */ + ctrl_outl(0x40000000, INTC_INTMSKCLR1); + register_intc_controller(&intc_desc_irl4567); + break; + case IRQ_MODE_IRL3210_MASK: + /* enable IRL0-3 and mask using cpu intc controller */ + ctrl_outl(0x80000000, INTC_INTMSKCLR1); register_intc_controller(&intc_desc_irl0123); break; default: diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index f9c90670e1..96d9710405 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -95,6 +95,7 @@ int intc_set_priority(unsigned int irq, unsigned int prio); void __init plat_irq_setup(void); enum { IRQ_MODE_IRQ, IRQ_MODE_IRQ7654, IRQ_MODE_IRQ3210, + IRQ_MODE_IRL7654_MASK, IRQ_MODE_IRL3210_MASK, IRQ_MODE_IRL7654, IRQ_MODE_IRL3210 }; void __init plat_irq_setup_pins(int mode); -- 2.39.5