From ccd805874198c248498b5f269656ec14397eeede Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 Apr 2008 12:58:40 +0900 Subject: sh64: Fixup the nommu build. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh5/entry.S | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S index ba8750176d9..05372ed6c56 100644 --- a/arch/sh/kernel/cpu/sh5/entry.S +++ b/arch/sh/kernel/cpu/sh5/entry.S @@ -143,12 +143,22 @@ resvec_save_area: trap_jtable: .long do_exception_error /* 0x000 */ .long do_exception_error /* 0x020 */ +#ifdef CONFIG_MMU .long tlb_miss_load /* 0x040 */ .long tlb_miss_store /* 0x060 */ +#else + .long do_exception_error + .long do_exception_error +#endif ! ARTIFICIAL pseudo-EXPEVT setting .long do_debug_interrupt /* 0x080 */ +#ifdef CONFIG_MMU .long tlb_miss_load /* 0x0A0 */ .long tlb_miss_store /* 0x0C0 */ +#else + .long do_exception_error + .long do_exception_error +#endif .long do_address_error_load /* 0x0E0 */ .long do_address_error_store /* 0x100 */ #ifdef CONFIG_SH_FPU @@ -185,10 +195,18 @@ trap_jtable: .endr .long do_IRQ /* 0xA00 */ .long do_IRQ /* 0xA20 */ +#ifdef CONFIG_MMU .long itlb_miss_or_IRQ /* 0xA40 */ +#else + .long do_IRQ +#endif .long do_IRQ /* 0xA60 */ .long do_IRQ /* 0xA80 */ +#ifdef CONFIG_MMU .long itlb_miss_or_IRQ /* 0xAA0 */ +#else + .long do_IRQ +#endif .long do_exception_error /* 0xAC0 */ .long do_address_error_exec /* 0xAE0 */ .rept 8 @@ -274,6 +292,7 @@ not_a_tlb_miss: * Instead of '.space 1024-TEXT_SIZE' place the RESVEC * block making sure the final alignment is correct. */ +#ifdef CONFIG_MMU tlb_miss: synco /* TAKum03020 (but probably a good idea anyway.) */ putcon SP, KCR1 @@ -377,6 +396,9 @@ fixup_to_invoke_general_handler: getcon KCR1, SP pta handle_exception, tr0 blink tr0, ZERO +#else /* CONFIG_MMU */ + .balign 256 +#endif /* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE DOES END UP AT VBR+0x600 */ @@ -1103,6 +1125,7 @@ restore_all: * fpu_error_or_IRQ? is a helper to deflect to the right cause. * */ +#ifdef CONFIG_MMU tlb_miss_load: or SP, ZERO, r2 or ZERO, ZERO, r3 /* Read */ @@ -1132,6 +1155,7 @@ call_do_page_fault: movi do_page_fault, r6 ptabs r6, tr0 blink tr0, ZERO +#endif /* CONFIG_MMU */ fpu_error_or_IRQA: pta its_IRQ, tr0 @@ -1481,6 +1505,7 @@ poke_real_address_q: ptabs LINK, tr0 blink tr0, r63 +#ifdef CONFIG_MMU /* * --- User Access Handling Section */ @@ -1604,6 +1629,7 @@ ___clear_user_exit: ptabs LINK, tr0 blink tr0, ZERO +#endif /* CONFIG_MMU */ /* * int __strncpy_from_user(unsigned long __dest, unsigned long __src, @@ -2014,9 +2040,11 @@ sa_default_restorer: .global asm_uaccess_start /* Just a marker */ asm_uaccess_start: +#ifdef CONFIG_MMU .long ___copy_user1, ___copy_user_exit .long ___copy_user2, ___copy_user_exit .long ___clear_user1, ___clear_user_exit +#endif .long ___strncpy_from_user1, ___strncpy_from_user_exit .long ___strnlen_user1, ___strnlen_user_exit .long ___get_user_asm_b1, ___get_user_asm_b_exit -- cgit v1.2.3 From 2a6b8148c050941dd61779cb0b49c5c3ea854ebf Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 Apr 2008 13:05:17 +0900 Subject: sh64: Setup I/D-TLB defaults in SH-5 probe path. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh5/probe.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/sh5/probe.c b/arch/sh/kernel/cpu/sh5/probe.c index 31f8cb0f637..92ad844b5c1 100644 --- a/arch/sh/kernel/cpu/sh5/probe.c +++ b/arch/sh/kernel/cpu/sh5/probe.c @@ -15,6 +15,7 @@ #include #include #include +#include int __init detect_cpu_and_cache_system(void) { @@ -67,5 +68,8 @@ int __init detect_cpu_and_cache_system(void) set_bit(SH_CACHE_MODE_WB, &(boot_cpu_data.dcache.flags)); #endif + /* Setup some I/D TLB defaults */ + sh64_tlb_init(); + return 0; } -- cgit v1.2.3 From a1dc4b59fa4af97ae68ee214d4d72bbd7c7ec1dc Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 25 Apr 2008 16:08:37 +0900 Subject: sh: intc_sh5 depends on cayman board for IRQ priority table. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/intc-sh5.c | 73 ++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 35 deletions(-) (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c index d6e0e2bdaad..de45c6a3e33 100644 --- a/arch/sh/kernel/cpu/irq/intc-sh5.c +++ b/arch/sh/kernel/cpu/irq/intc-sh5.c @@ -184,9 +184,8 @@ int intc_irq_describe(char* p, int irq) void __init plat_irq_setup(void) { - unsigned long long __dummy0, __dummy1=~0x00000000100000f0; + unsigned long long __dummy0, __dummy1=~0x00000000100000f0; unsigned long reg; - unsigned long data; int i; intc_virt = onchip_remap(INTC_BASE, 1024, "INTC"); @@ -196,11 +195,8 @@ void __init plat_irq_setup(void) /* Set default: per-line enable/disable, priority driven ack/eoi */ - for (i = 0; i < NR_INTC_IRQS; i++) { - if (platform_int_priority[i] != NO_PRIORITY) { - irq_desc[i].chip = &intc_irq_type; - } - } + for (i = 0; i < NR_INTC_IRQS; i++) + irq_desc[i].chip = &intc_irq_type; /* Disable all interrupts and set all priorities to 0 to avoid trouble */ @@ -211,35 +207,42 @@ void __init plat_irq_setup(void) ctrl_outl( NO_PRIORITY, reg); - /* Set IRLM */ - /* If all the priorities are set to 'no priority', then - * assume we are using encoded mode. - */ - irlm = platform_int_priority[IRQ_IRL0] + platform_int_priority[IRQ_IRL1] + \ - platform_int_priority[IRQ_IRL2] + platform_int_priority[IRQ_IRL3]; - - if (irlm == NO_PRIORITY) { - /* IRLM = 0 */ - reg = INTC_ICR_CLEAR; - i = IRQ_INTA; - printk("Trying to use encoded IRL0-3. IRLs unsupported.\n"); - } else { - /* IRLM = 1 */ - reg = INTC_ICR_SET; - i = IRQ_IRL0; - } - ctrl_outl(INTC_ICR_IRLM, reg); - - /* Set interrupt priorities according to platform description */ - for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) { - data |= platform_int_priority[i] << ((i % INTC_INTPRI_PPREG) * 4); - if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) { - /* Upon the 7th, set Priority Register */ - ctrl_outl(data, reg); - data = 0; - reg += 8; +#ifdef CONFIG_SH_CAYMAN + { + unsigned long data; + + /* Set IRLM */ + /* If all the priorities are set to 'no priority', then + * assume we are using encoded mode. + */ + irlm = platform_int_priority[IRQ_IRL0] + + platform_int_priority[IRQ_IRL1] + + platform_int_priority[IRQ_IRL2] + + platform_int_priority[IRQ_IRL3]; + if (irlm == NO_PRIORITY) { + /* IRLM = 0 */ + reg = INTC_ICR_CLEAR; + i = IRQ_INTA; + printk("Trying to use encoded IRL0-3. IRLs unsupported.\n"); + } else { + /* IRLM = 1 */ + reg = INTC_ICR_SET; + i = IRQ_IRL0; } - } + ctrl_outl(INTC_ICR_IRLM, reg); + + /* Set interrupt priorities according to platform description */ + for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) { + data |= platform_int_priority[i] << + ((i % INTC_INTPRI_PPREG) * 4); + if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) { + /* Upon the 7th, set Priority Register */ + ctrl_outl(data, reg); + data = 0; + reg += 8; + } + } +#endif /* * And now let interrupts come in. -- cgit v1.2.3 From 65c07d4b3d919ec4a9a95cf576b0685bd382cdf3 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 23 Apr 2008 20:24:52 +0900 Subject: sh: fix sh7705 interrupt vector typo Fix sh7705 interrupt sources for vectors 0xc80 and 0xca0. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index f581534cb73..ba77891ee4e 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -48,7 +48,7 @@ static struct intc_vect vectors[] __initdata = { INTC_VECT(ADC_ADI, 0x980), INTC_VECT(USB_USI0, 0xa20), INTC_VECT(USB_USI1, 0xa40), INTC_VECT(TPU0, 0xc00), INTC_VECT(TPU1, 0xc20), - INTC_VECT(TPU3, 0xc80), INTC_VECT(TPU1, 0xca0), + INTC_VECT(TPU2, 0xc80), INTC_VECT(TPU3, 0xca0), INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460), INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), -- cgit v1.2.3 From a276e588a92737889c21e736f2bbed8aecda25fb Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 24 Apr 2008 21:30:09 +0900 Subject: sh: unify external irq pin code for sh3 This patch unifies the sh3 external irq pin code. It buys us some savings with reduced code redundancy, but the main feature with this change is irq sense selection support for all sh3 processors. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh3/Makefile | 2 +- arch/sh/kernel/cpu/sh3/setup-sh3.c | 64 +++++++++++++++++++++++++++++++++++ arch/sh/kernel/cpu/sh3/setup-sh7705.c | 20 ++--------- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 32 +++--------------- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 20 ++--------- arch/sh/kernel/cpu/sh3/setup-sh7720.c | 31 ++--------------- 6 files changed, 75 insertions(+), 94 deletions(-) create mode 100644 arch/sh/kernel/cpu/sh3/setup-sh3.c (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index 3ae4d9111f1..511de55af83 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux/SuperH SH-3 backends. # -obj-y := ex.o probe.o entry.o +obj-y := ex.o probe.o entry.o setup-sh3.o # CPU subtype setup obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c new file mode 100644 index 00000000000..28e7d655309 --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/setup-sh3.c @@ -0,0 +1,64 @@ +/* + * Shared SH3 Setup code + * + * Copyright (C) 2008 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include + +/* All SH3 devices are equipped with IRQ0->5 (except sh7708) */ + +enum { + UNUSED = 0, + + /* interrupt sources */ + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, +}; + +static struct intc_vect vectors_irq0123[] __initdata = { + INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), + INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), +}; + +static struct intc_vect vectors_irq45[] __initdata = { + INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, + { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, +}; + +static struct intc_sense_reg sense_registers[] __initdata = { + { 0xa4000010, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, +}; + +static DECLARE_INTC_DESC(intc_desc_irq0123, "sh3-irq0123", vectors_irq0123, + NULL, NULL, prio_registers, sense_registers); + +static DECLARE_INTC_DESC(intc_desc_irq45, "sh3-irq45", vectors_irq45, + NULL, NULL, prio_registers, sense_registers); + +#define INTC_ICR1 0xa4000010UL +#define INTC_ICR1_IRQLVL (1<<14) + +void __init plat_irq_setup_pins(int mode) +{ + if (mode == IRQ_MODE_IRQ) { + ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1); + register_intc_controller(&intc_desc_irq0123); + return; + } + BUG(); +} + +void __init plat_irq_setup_sh3(void) +{ + register_intc_controller(&intc_desc_irq45); +} diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index ba77891ee4e..6468ae86b94 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -37,7 +37,7 @@ enum { }; static struct intc_vect vectors[] __initdata = { - INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + /* IRQ0->5 are handled in setup-sh3.c */ INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720), INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860), @@ -81,14 +81,6 @@ static struct intc_prio_reg prio_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups, NULL, prio_registers, NULL); -static struct intc_vect vectors_irq[] __initdata = { - INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), - INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), -}; - -static DECLARE_INTC_DESC(intc_desc_irq, "sh7705-irq", vectors_irq, NULL, - NULL, prio_registers, NULL); - static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xa4410000, @@ -159,16 +151,8 @@ static int __init sh7705_devices_setup(void) } __initcall(sh7705_devices_setup); -void __init plat_irq_setup_pins(int mode) -{ - if (mode == IRQ_MODE_IRQ) { - register_intc_controller(&intc_desc_irq); - return; - } - BUG(); -} - void __init plat_irq_setup(void) { register_intc_controller(&intc_desc); + plat_irq_setup_sh3(); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index d3733b13ea5..93c55e2ed95 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -52,7 +52,7 @@ static struct intc_vect vectors[] __initdata = { #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) - INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + /* IRQ0->5 are handled in setup-sh3.c */ INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860), INTC_VECT(ADC_ADI, 0x980), @@ -104,18 +104,6 @@ static struct intc_prio_reg prio_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups, NULL, prio_registers, NULL); -#if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ - defined(CONFIG_CPU_SUBTYPE_SH7707) || \ - defined(CONFIG_CPU_SUBTYPE_SH7709) -static struct intc_vect vectors_irq[] __initdata = { - INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), - INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), -}; - -static DECLARE_INTC_DESC(intc_desc_irq, "sh770x-irq", vectors_irq, NULL, - NULL, prio_registers, NULL); -#endif - static struct resource rtc_resources[] = { [0] = { .start = 0xfffffec0, @@ -194,24 +182,12 @@ static int __init sh770x_devices_setup(void) } __initcall(sh770x_devices_setup); -#define INTC_ICR1 0xa4000010UL -#define INTC_ICR1_IRQLVL (1<<14) - -void __init plat_irq_setup_pins(int mode) +void __init plat_irq_setup(void) { - if (mode == IRQ_MODE_IRQ) { + register_intc_controller(&intc_desc); #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) - ctrl_outw(ctrl_inw(INTC_ICR1) & ~INTC_ICR1_IRQLVL, INTC_ICR1); - register_intc_controller(&intc_desc_irq); - return; + plat_irq_setup_sh3(); #endif - } - BUG(); -} - -void __init plat_irq_setup(void) -{ - register_intc_controller(&intc_desc); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 7406c9ad925..f353a001fba 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -38,7 +38,7 @@ enum { }; static struct intc_vect vectors[] __initdata = { - INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), + /* IRQ0->5 are handled in setup-sh3.c */ INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860), INTC_VECT(SCIF0_ERI, 0x880), INTC_VECT(SCIF0_RXI, 0x8a0), @@ -91,14 +91,6 @@ static struct intc_prio_reg prio_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups, NULL, prio_registers, NULL); -static struct intc_vect vectors_irq[] __initdata = { - INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), - INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), -}; - -static DECLARE_INTC_DESC(intc_desc_irq, "sh7710-irq", vectors_irq, NULL, - NULL, prio_registers, NULL); - static struct resource rtc_resources[] = { [0] = { .start = 0xa413fec0, @@ -170,16 +162,8 @@ static int __init sh7710_devices_setup(void) } __initcall(sh7710_devices_setup); -void __init plat_irq_setup_pins(int mode) -{ - if (mode == IRQ_MODE_IRQ) { - register_intc_controller(&intc_desc_irq); - return; - } - BUG(); -} - void __init plat_irq_setup(void) { register_intc_controller(&intc_desc); + plat_irq_setup_sh3(); } diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 8028082527c..0e6e66e7b58 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -19,10 +19,6 @@ #include #include -#define INTC_ICR1 0xA4140010UL -#define INTC_ICR_IRLM 0x4000 -#define INTC_ICR_IRQ (~INTC_ICR_IRLM) - static struct resource rtc_resources[] = { [0] = { .start = 0xa413fec0, @@ -170,6 +166,7 @@ enum { }; static struct intc_vect vectors[] __initdata = { + /* IRQ0->5 are handled in setup-sh3.c */ INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), INTC_VECT(TMU2, 0x440), INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), INTC_VECT(RTC_CUI, 0x4c0), @@ -229,32 +226,8 @@ static struct intc_prio_reg prio_registers[] __initdata = { static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups, NULL, prio_registers, NULL); -static struct intc_sense_reg sense_registers[] __initdata = { - { INTC_ICR1, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, -}; - -static struct intc_vect vectors_irq[] __initdata = { - INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), - INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), - INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), -}; - -static DECLARE_INTC_DESC(intc_irq_desc, "sh7720-irq", vectors_irq, - NULL, NULL, prio_registers, sense_registers); - -void __init plat_irq_setup_pins(int mode) -{ - switch (mode) { - case IRQ_MODE_IRQ: - ctrl_outw(ctrl_inw(INTC_ICR1) & INTC_ICR_IRQ, INTC_ICR1); - register_intc_controller(&intc_irq_desc); - break; - default: - BUG(); - } -} - void __init plat_irq_setup(void) { register_intc_controller(&intc_desc); + plat_irq_setup_sh3(); } -- cgit v1.2.3 From d58876e289b0153bf86162aa1a43249e0f0aa03d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 24 Apr 2008 21:36:34 +0900 Subject: sh: add interrupt ack code to sh3 This patch adds interrupt acknowledge code for external interrupt sources on sh3 processors. Only really required for edge triggered interrupts, but we ack regardless of sense configuration. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/intc.c | 79 ++++++++++++++++++++++++++++++++++++-- arch/sh/kernel/cpu/sh3/setup-sh3.c | 15 ++++++-- 2 files changed, 87 insertions(+), 7 deletions(-) (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index 84806b2027f..df3695406d8 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -1,7 +1,7 @@ /* * Shared interrupt handling code for IPR and INTC2 types of IRQs. * - * Copyright (C) 2007 Magnus Damm + * Copyright (C) 2007, 2008 Magnus Damm * * Based on intc2.c and ipr.c * @@ -62,6 +62,9 @@ struct intc_desc_int { #endif static unsigned int intc_prio_level[NR_IRQS]; /* for now */ +#ifdef CONFIG_CPU_SH3 +static unsigned long ack_handle[NR_IRQS]; +#endif static inline struct intc_desc_int *get_intc_desc(unsigned int irq) { @@ -219,6 +222,25 @@ static void intc_disable(unsigned int irq) } } +#ifdef CONFIG_CPU_SH3 +static void intc_mask_ack(unsigned int irq) +{ + struct intc_desc_int *d = get_intc_desc(irq); + unsigned long handle = ack_handle[irq]; + unsigned long addr; + + intc_disable(irq); + + /* read register and write zero only to the assocaited bit */ + + if (handle) { + addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); + ctrl_inb(addr); + ctrl_outb(0x3f ^ set_field(0, 1, handle), addr); + } +} +#endif + static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, unsigned int nr_hp, unsigned int irq) @@ -430,6 +452,40 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc, return 0; } +#ifdef CONFIG_CPU_SH3 +static unsigned int __init intc_ack_data(struct intc_desc *desc, + struct intc_desc_int *d, + intc_enum enum_id) +{ + struct intc_mask_reg *mr = desc->ack_regs; + unsigned int i, j, fn, mode; + unsigned long reg_e, reg_d; + + for (i = 0; mr && enum_id && i < desc->nr_ack_regs; i++) { + mr = desc->ack_regs + i; + + for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { + if (mr->enum_ids[j] != enum_id) + continue; + + fn = REG_FN_MODIFY_BASE; + mode = MODE_ENABLE_REG; + reg_e = mr->set_reg; + reg_d = mr->set_reg; + + fn += (mr->reg_width >> 3) - 1; + return _INTC_MK(fn, mode, + intc_get_reg(d, reg_e), + intc_get_reg(d, reg_d), + 1, + (mr->reg_width - 1) - j); + } + } + + return 0; +} +#endif + static unsigned int __init intc_sense_data(struct intc_desc *desc, struct intc_desc_int *d, intc_enum enum_id) @@ -530,6 +586,11 @@ static void __init intc_register_irq(struct intc_desc *desc, /* irq should be disabled by default */ d->chip.mask(irq); + +#ifdef CONFIG_CPU_SH3 + if (desc->ack_regs) + ack_handle[irq] = intc_ack_data(desc, d, enum_id); +#endif } static unsigned int __init save_reg(struct intc_desc_int *d, @@ -560,6 +621,9 @@ void __init register_intc_controller(struct intc_desc *desc) d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; +#ifdef CONFIG_CPU_SH3 + d->nr_reg += desc->ack_regs ? desc->nr_ack_regs : 0; +#endif d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg)); #ifdef CONFIG_SMP d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp)); @@ -592,14 +656,23 @@ void __init register_intc_controller(struct intc_desc *desc) } } - BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ - d->chip.name = desc->name; d->chip.mask = intc_disable; d->chip.unmask = intc_enable; d->chip.mask_ack = intc_disable; d->chip.set_type = intc_set_sense; +#ifdef CONFIG_CPU_SH3 + if (desc->ack_regs) { + for (i = 0; i < desc->nr_ack_regs; i++) + k += save_reg(d, k, desc->ack_regs[i].set_reg, 0); + + d->chip.mask_ack = intc_mask_ack; + } +#endif + + BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ + for (i = 0; i < desc->nr_vectors; i++) { struct intc_vect *vect = desc->vectors + i; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh3.c b/arch/sh/kernel/cpu/sh3/setup-sh3.c index 28e7d655309..c9884685785 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh3.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh3.c @@ -35,15 +35,22 @@ static struct intc_prio_reg prio_registers[] __initdata = { { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, }; +static struct intc_mask_reg ack_registers[] __initdata = { + { 0xa4000004, 0, 8, /* IRR0 */ + { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, +}; + static struct intc_sense_reg sense_registers[] __initdata = { { 0xa4000010, 16, 2, { 0, 0, IRQ5, IRQ4, IRQ3, IRQ2, IRQ1, IRQ0 } }, }; -static DECLARE_INTC_DESC(intc_desc_irq0123, "sh3-irq0123", vectors_irq0123, - NULL, NULL, prio_registers, sense_registers); +static DECLARE_INTC_DESC_ACK(intc_desc_irq0123, "sh3-irq0123", + vectors_irq0123, NULL, NULL, + prio_registers, sense_registers, ack_registers); -static DECLARE_INTC_DESC(intc_desc_irq45, "sh3-irq45", vectors_irq45, - NULL, NULL, prio_registers, sense_registers); +static DECLARE_INTC_DESC_ACK(intc_desc_irq45, "sh3-irq45", + vectors_irq45, NULL, NULL, + prio_registers, sense_registers, ack_registers); #define INTC_ICR1 0xa4000010UL #define INTC_ICR1_IRQLVL (1<<14) -- cgit v1.2.3 From 995d538a5b09e3c129d8aac559f07a0f5cc3fc3c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 24 Apr 2008 21:41:12 +0900 Subject: sh: clean up sh7710 and sh7720 intc tables Clean up the intc tables by removing unneeded #ifdefs. The vector list is what selects which interrupt sources that should be added, having unsupported bitfields listed is ok as long as the vector is excluded from the list. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 5 +---- arch/sh/kernel/cpu/sh3/setup-sh7720.c | 4 ---- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index f353a001fba..77eee481de4 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -79,10 +79,7 @@ static struct intc_prio_reg prio_registers[] __initdata = { { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC1, SCIF0, SCIF1 } }, - { 0xa4080000, 0, 16, 4, /* IPRF */ { 0, DMAC2 } }, -#ifdef CONFIG_CPU_SUBTYPE_SH7710 - { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC } }, -#endif + { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC, DMAC2 } }, { 0xa4080002, 0, 16, 4, /* IPRG */ { EDMAC0, EDMAC1, EDMAC2 } }, { 0xa4080004, 0, 16, 4, /* IPRH */ { 0, 0, 0, SIOF0 } }, { 0xa4080006, 0, 16, 4, /* IPRI */ { 0, 0, SIOF1 } }, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 0e6e66e7b58..f807a21b066 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -211,11 +211,7 @@ static struct intc_prio_reg prio_registers[] __initdata = { { 0xA414FEE4UL, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, SIM, 0 } }, { 0xA4140016UL, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, { 0xA4140018UL, 0, 16, 4, /* IPRD */ { USBF_SPD, TMU_SUNI, IRQ5, IRQ4 } }, -#if defined(CONFIG_CPU_SUBTYPE_SH7720) { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } }, -#else - { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, 0 } }, -#endif { 0xA4080000UL, 0, 16, 4, /* IPRF */ { ADC, DMAC2, USBFI, CMT } }, { 0xA4080002UL, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, 0, 0 } }, { 0xA4080004UL, 0, 16, 4, /* IPRH */ { PINT07, PINT815, TPU, IIC } }, -- cgit v1.2.3 From 720be99006c5830970d5b62633c92b29e4cef137 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 24 Apr 2008 21:47:15 +0900 Subject: sh: no high level trigger on some sh3 cpus The processor models sh7706, sh7707 and sh7709 don't support high level trigger sense configuration. And the intc code looks like crap these days so what's the difference. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/intc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index df3695406d8..e5a4912d665 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -302,7 +302,12 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { [IRQ_TYPE_EDGE_FALLING] = VALID(0), [IRQ_TYPE_EDGE_RISING] = VALID(1), [IRQ_TYPE_LEVEL_LOW] = VALID(2), + /* SH7706, SH7707 and SH7709 do not support high level triggered */ +#if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \ + !defined(CONFIG_CPU_SUBTYPE_SH7707) && \ + !defined(CONFIG_CPU_SUBTYPE_SH7709) [IRQ_TYPE_LEVEL_HIGH] = VALID(3), +#endif }; static int intc_set_sense(unsigned int irq, unsigned int type) -- cgit v1.2.3 From 4370fe1c06ffa251b63b12a41e2599037a4b7f87 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 24 Apr 2008 21:53:07 +0900 Subject: sh: intc register modify fix Make sure register modifications stay atomic. Fixes processors with shared priority register masking. Dual bitmap masking is unaffected. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/intc.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index e5a4912d665..da5dae78788 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -101,17 +101,26 @@ static void write_32(unsigned long addr, unsigned long h, unsigned long data) static void modify_8(unsigned long addr, unsigned long h, unsigned long data) { + unsigned long flags; + local_irq_save(flags); ctrl_outb(set_field(ctrl_inb(addr), data, h), addr); + local_irq_restore(flags); } static void modify_16(unsigned long addr, unsigned long h, unsigned long data) { + unsigned long flags; + local_irq_save(flags); ctrl_outw(set_field(ctrl_inw(addr), data, h), addr); + local_irq_restore(flags); } static void modify_32(unsigned long addr, unsigned long h, unsigned long data) { + unsigned long flags; + local_irq_save(flags); ctrl_outl(set_field(ctrl_inl(addr), data, h), addr); + local_irq_restore(flags); } enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 }; -- cgit v1.2.3 From 9731e287e08b804592191d8bffaad023154af2aa Mon Sep 17 00:00:00 2001 From: Roel Kluin <12o3l@tiscali.nl> Date: Fri, 9 May 2008 20:05:10 +0900 Subject: SH: catch negative denormal_subf1() retval in denormal_add() 'ix' is unsigned but denormal_subf1() may return a negative int. Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2a/fpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/sh2a/fpu.c b/arch/sh/kernel/cpu/sh2a/fpu.c index 5627c0b3ffa..6df2fb98eb3 100644 --- a/arch/sh/kernel/cpu/sh2a/fpu.c +++ b/arch/sh/kernel/cpu/sh2a/fpu.c @@ -300,7 +300,7 @@ static int denormal_addf(int hx, int hy) iy = hy & 0x7fffffff; if (iy < 0x00800000) { ix = denormal_subf1(ix, iy); - if (ix < 0) { + if ((int) ix < 0) { ix = -ix; sign ^= 0x80000000; } @@ -385,7 +385,7 @@ static long long denormal_addd(long long hx, long long hy) iy = hy & 0x7fffffffffffffffLL; if (iy < 0x0010000000000000LL) { ix = denormal_subd1(ix, iy); - if (ix < 0) { + if ((int) ix < 0) { ix = -ix; sign ^= 0x8000000000000000LL; } -- cgit v1.2.3 From 65b83427c6e5814556855c42bf9b4edeafd66623 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Thu, 15 May 2008 17:44:00 +0900 Subject: sh: fix sh7785 master clock value Signed-off-by: Yoshihiro Shimoda Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/clock-sh7785.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh/kernel/cpu') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c index 805535aa505..27fa81bef6a 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7785.c @@ -26,7 +26,7 @@ static int pfc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 18, static void master_clk_init(struct clk *clk) { - clk->rate *= 36; + clk->rate *= pfc_divisors[ctrl_inl(FRQMR1) & 0x000f]; } static struct clk_ops sh7785_master_clk_ops = { -- cgit v1.2.3