From e7bd34a15b85655f24d1b45edbe3bdfebf9d027e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 31 Jul 2007 17:07:28 +0900 Subject: sh: Support explicit L1 cache disabling. This reworks the cache mode configuration in Kconfig, and allows for explicit selection of write-back/write-through/off configurations. All of the cache flushing routines are optimized away for the off case. Signed-off-by: Paul Mundt --- include/asm-sh/cacheflush.h | 33 ++++++++++++++++++++++++++++++++- include/asm-sh/page.h | 6 +++--- include/asm-sh/pgtable.h | 3 ++- 3 files changed, 37 insertions(+), 5 deletions(-) (limited to 'include/asm-sh') diff --git a/include/asm-sh/cacheflush.h b/include/asm-sh/cacheflush.h index 07f62ec9ff0..aa558da0847 100644 --- a/include/asm-sh/cacheflush.h +++ b/include/asm-sh/cacheflush.h @@ -1,16 +1,47 @@ #ifndef __ASM_SH_CACHEFLUSH_H #define __ASM_SH_CACHEFLUSH_H + #ifdef __KERNEL__ -#include +#ifdef CONFIG_CACHE_OFF +/* + * Nothing to do when the cache is disabled, initial flush and explicit + * disabling is handled at CPU init time. + * + * See arch/sh/kernel/cpu/init.c:cache_init(). + */ +#define p3_cache_init() do { } while (0) +#define flush_cache_all() do { } while (0) +#define flush_cache_mm(mm) do { } while (0) +#define flush_cache_dup_mm(mm) do { } while (0) +#define flush_cache_range(vma, start, end) do { } while (0) +#define flush_cache_page(vma, vmaddr, pfn) do { } while (0) +#define flush_dcache_page(page) do { } while (0) +#define flush_icache_range(start, end) do { } while (0) +#define flush_icache_page(vma,pg) do { } while (0) +#define flush_dcache_mmap_lock(mapping) do { } while (0) +#define flush_dcache_mmap_unlock(mapping) do { } while (0) +#define flush_cache_sigtramp(vaddr) do { } while (0) +#define flush_icache_user_range(vma,pg,adr,len) do { } while (0) +#define __flush_wback_region(start, size) do { (void)(start); } while (0) +#define __flush_purge_region(start, size) do { (void)(start); } while (0) +#define __flush_invalidate_region(start, size) do { (void)(start); } while (0) +#else #include +/* + * Consistent DMA requires that the __flush_xxx() primitives must be set + * for any of the enabled non-coherent caches (most of the UP CPUs), + * regardless of PIPT or VIPT cache configurations. + */ + /* Flush (write-back only) a region (smaller than a page) */ extern void __flush_wback_region(void *start, int size); /* Flush (write-back & invalidate) a region (smaller than a page) */ extern void __flush_purge_region(void *start, int size); /* Flush (invalidate only) a region (smaller than a page) */ extern void __flush_invalidate_region(void *start, int size); +#endif #define flush_cache_vmap(start, end) flush_cache_all() #define flush_cache_vunmap(start, end) flush_cache_all() diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index 6bc9bba1010..48b718e7455 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -70,14 +70,14 @@ extern void clear_page_nommu(void *to); extern void copy_page_nommu(void *to, void *from); #endif -#if defined(CONFIG_MMU) && (defined(CONFIG_CPU_SH4) || \ - defined(CONFIG_SH7705_CACHE_32KB)) +#if !defined(CONFIG_CACHE_OFF) && defined(CONFIG_MMU) && \ + (defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB)) struct page; extern void clear_user_page(void *to, unsigned long address, struct page *pg); extern void copy_user_page(void *to, void *from, unsigned long address, struct page *pg); extern void __clear_user_page(void *to, void *orig_to); extern void __copy_user_page(void *to, void *from, void *orig_to); -#elif defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH3) || !defined(CONFIG_MMU) +#else #define clear_user_page(page, vaddr, pg) clear_page(page) #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) #endif diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h index e3fae12c0e4..54ad5037fe4 100644 --- a/include/asm-sh/pgtable.h +++ b/include/asm-sh/pgtable.h @@ -563,7 +563,8 @@ struct mm_struct; extern unsigned int kobjsize(const void *objp); #endif /* !CONFIG_MMU */ -#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) +#if !defined(CONFIG_CACHE_OFF) && (defined(CONFIG_CPU_SH4) || \ + defined(CONFIG_SH7705_CACHE_32KB)) #define __HAVE_ARCH_PTEP_GET_AND_CLEAR extern pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); #endif -- cgit v1.2.3-70-g09d2 From a0e23267d4c57cdaa88114c3d88e25c87ee32d84 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 31 Jul 2007 17:11:21 +0900 Subject: sh: intc - add support for SH7785 This patch converts the cpu specific interrupt setup code for sh7785 from intc2 to intc. New vectors are also added to match the information provided by the datasheet. No IRQ/IRL pin vectors are enabled by default. Use plat_irq_setup_pins() to select between IRL and IRQ mode. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 255 ++++++++++++++++++++++++++++----- arch/sh/mm/Kconfig | 2 +- include/asm-sh/hw_irq.h | 3 +- 3 files changed, 225 insertions(+), 35 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index cf047562e43..c49fcb0800c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -72,46 +72,235 @@ static int __init sh7785_devices_setup(void) } __initcall(sh7785_devices_setup); -static struct intc2_data intc2_irq_table[] = { - { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ - - { 40, 8, 24, 0, 2, 3 }, /* SCIF0 ERI */ - { 41, 8, 24, 0, 2, 3 }, /* SCIF0 RXI */ - { 42, 8, 24, 0, 2, 3 }, /* SCIF0 BRI */ - { 43, 8, 24, 0, 2, 3 }, /* SCIF0 TXI */ - - { 44, 8, 16, 0, 3, 3 }, /* SCIF1 ERI */ - { 45, 8, 16, 0, 3, 3 }, /* SCIF1 RXI */ - { 46, 8, 16, 0, 3, 3 }, /* SCIF1 BRI */ - { 47, 8, 16, 0, 3, 3 }, /* SCIF1 TXI */ - - { 64, 0x14, 8, 0, 14, 2 }, /* PCIC0 */ - { 65, 0x14, 0, 0, 15, 2 }, /* PCIC1 */ - { 66, 0x18, 24, 0, 16, 2 }, /* PCIC2 */ - { 67, 0x18, 16, 0, 17, 2 }, /* PCIC3 */ - { 68, 0x18, 8, 0, 18, 2 }, /* PCIC4 */ - - { 60, 8, 8, 0, 4, 3 }, /* SCIF2 ERI, RXI, BRI, TXI */ - { 60, 8, 0, 0, 5, 3 }, /* SCIF3 ERI, RXI, BRI, TXI */ - { 60, 12, 24, 0, 6, 3 }, /* SCIF4 ERI, RXI, BRI, TXI */ - { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */ +enum { + UNUSED = 0, + + /* interrupt sources */ + + IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH, + IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH, + IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH, + IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, + + IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH, + IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH, + IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH, + IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, + + IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, + WDT, + TMU0, TMU1, TMU2, TMU2_TICPI, + HUDI, + DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, + DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE, + SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI, + SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI, + DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, DMAC1_DMINT9, + DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE, + HSPI, + SCIF2, SCIF3, SCIF4, SCIF5, + PCISERR, PCIINTA, PCIINTB, PCIINTC, PCIINTD, + PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0, + SIOF, + MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY, + DU, + GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI, + TMU3, TMU4, TMU5, + SSI0, SSI1, + HAC0, HAC1, + FLCTL_FLSTE, FLCTL_FLEND, FLCTL_FLTRQ0, FLCTL_FLTRQ1, + GPIOI0, GPIOI1, GPIOI2, GPIOI3, + + /* interrupt groups */ + + TMU012, DMAC0, SCIF0, SCIF1, DMAC1, + PCIC5, MMCIF, GDTA, TMU345, FLCTL, GPIO }; -static struct intc2_desc intc2_irq_desc __read_mostly = { - .prio_base = 0xffd40000, - .msk_base = 0xffd40038, - .mskclr_base = 0xffd4003c, +static struct intc_vect vectors[] = { + INTC_VECT(WDT, 0x560), + INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0), + INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0), + INTC_VECT(HUDI, 0x600), + INTC_VECT(DMAC0_DMINT0, 0x620), INTC_VECT(DMAC0_DMINT1, 0x640), + INTC_VECT(DMAC0_DMINT2, 0x660), INTC_VECT(DMAC0_DMINT3, 0x680), + INTC_VECT(DMAC0_DMINT4, 0x6a0), INTC_VECT(DMAC0_DMINT5, 0x6c0), + INTC_VECT(DMAC0_DMAE, 0x6e0), + INTC_VECT(SCIF0_ERI, 0x700), INTC_VECT(SCIF0_RXI, 0x720), + INTC_VECT(SCIF0_BRI, 0x740), INTC_VECT(SCIF0_TXI, 0x760), + INTC_VECT(SCIF1_ERI, 0x780), INTC_VECT(SCIF1_RXI, 0x7a0), + INTC_VECT(SCIF1_BRI, 0x7c0), INTC_VECT(SCIF1_TXI, 0x7e0), + INTC_VECT(DMAC1_DMINT6, 0x880), INTC_VECT(DMAC1_DMINT7, 0x8a0), + INTC_VECT(DMAC1_DMINT8, 0x8c0), INTC_VECT(DMAC1_DMINT9, 0x8e0), + INTC_VECT(DMAC1_DMINT10, 0x900), INTC_VECT(DMAC1_DMINT11, 0x920), + INTC_VECT(DMAC1_DMAE, 0x940), + INTC_VECT(HSPI, 0x960), + INTC_VECT(SCIF2, 0x980), INTC_VECT(SCIF3, 0x9a0), + INTC_VECT(SCIF4, 0x9c0), INTC_VECT(SCIF5, 0x9e0), + INTC_VECT(PCISERR, 0xa00), INTC_VECT(PCIINTA, 0xa20), + INTC_VECT(PCIINTB, 0xa40), INTC_VECT(PCIINTC, 0xa60), + INTC_VECT(PCIINTD, 0xa80), INTC_VECT(PCIERR, 0xaa0), + INTC_VECT(PCIPWD3, 0xac0), INTC_VECT(PCIPWD2, 0xae0), + INTC_VECT(PCIPWD1, 0xb00), INTC_VECT(PCIPWD0, 0xb20), + INTC_VECT(SIOF, 0xc00), + INTC_VECT(MMCIF_FSTAT, 0xd00), INTC_VECT(MMCIF_TRAN, 0xd20), + INTC_VECT(MMCIF_ERR, 0xd40), INTC_VECT(MMCIF_FRDY, 0xd60), + INTC_VECT(DU, 0xd80), + INTC_VECT(GDTA_GACLI, 0xda0), INTC_VECT(GDTA_GAMCI, 0xdc0), + INTC_VECT(GDTA_GAERI, 0xde0), + INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20), + INTC_VECT(TMU5, 0xe40), + INTC_VECT(SSI0, 0xe80), INTC_VECT(SSI1, 0xea0), + INTC_VECT(HAC0, 0xec0), INTC_VECT(HAC1, 0xee0), + INTC_VECT(FLCTL_FLSTE, 0xf00), INTC_VECT(FLCTL_FLEND, 0xf20), + INTC_VECT(FLCTL_FLTRQ0, 0xf40), INTC_VECT(FLCTL_FLTRQ1, 0xf60), + INTC_VECT(GPIOI0, 0xf80), INTC_VECT(GPIOI1, 0xfa0), + INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0), +}; - .intc2_data = intc2_irq_table, - .nr_irqs = ARRAY_SIZE(intc2_irq_table), +static struct intc_group groups[] = { + INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), + INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, + DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE), + INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), + INTC_GROUP(SCIF1, SCIF1_ERI, SCIF1_RXI, SCIF1_BRI, SCIF1_TXI), + INTC_GROUP(DMAC1, DMAC1_DMINT6, DMAC1_DMINT7, DMAC1_DMINT8, + DMAC1_DMINT9, DMAC1_DMINT10, DMAC1_DMINT11, DMAC1_DMAE), + INTC_GROUP(PCIC5, PCIERR, PCIPWD3, PCIPWD2, PCIPWD1, PCIPWD0), + INTC_GROUP(MMCIF, MMCIF_FSTAT, MMCIF_TRAN, MMCIF_ERR, MMCIF_FRDY), + INTC_GROUP(GDTA, GDTA_GACLI, GDTA_GAMCI, GDTA_GAERI), + INTC_GROUP(TMU345, TMU3, TMU4, TMU5), + INTC_GROUP(FLCTL, FLCTL_FLSTE, FLCTL_FLEND, + FLCTL_FLTRQ0, FLCTL_FLTRQ1), + INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), +}; - .chip = { - .name = "INTC2-sh7785", - }, +static struct intc_prio priorities[] = { + INTC_PRIO(SCIF0, 3), + INTC_PRIO(SCIF1, 3), + INTC_PRIO(SCIF2, 3), + INTC_PRIO(SCIF3, 3), + INTC_PRIO(SCIF4, 3), + INTC_PRIO(SCIF5, 3), +}; + +static struct intc_mask_reg mask_registers[] = { + { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ + { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, + + { 0xffd40080, 0xffd40084, 32, /* INTMSK2 / INTMSKCLR2 */ + { IRL0_LLLL, IRL0_LLLH, IRL0_LLHL, IRL0_LLHH, + IRL0_LHLL, IRL0_LHLH, IRL0_LHHL, IRL0_LHHH, + IRL0_HLLL, IRL0_HLLH, IRL0_HLHL, IRL0_HLHH, + IRL0_HHLL, IRL0_HHLH, IRL0_HHHL, 0, + IRL4_LLLL, IRL4_LLLH, IRL4_LLHL, IRL4_LLHH, + IRL4_LHLL, IRL4_LHLH, IRL4_LHHL, IRL4_LHHH, + IRL4_HLLL, IRL4_HLLH, IRL4_HLHL, IRL4_HLHH, + IRL4_HHLL, IRL4_HHLH, IRL4_HHHL, 0, } }, + + { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ + { 0, 0, 0, GDTA, DU, SSI0, SSI1, GPIO, + FLCTL, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB, + PCIINTA, PCISERR, HAC1, HAC0, DMAC1, DMAC0, HUDI, WDT, + SCIF5, SCIF4, SCIF3, SCIF2, SCIF1, SCIF0, TMU345, TMU012 } }, +}; + +static struct intc_prio_reg prio_registers[] = { + { 0xffd00010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, + IRQ4, IRQ5, IRQ6, IRQ7 } }, + { 0xffd40000, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } }, + { 0xffd40004, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, } }, + { 0xffd40008, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, SCIF2, SCIF3 } }, + { 0xffd4000c, 32, 8, /* INT2PRI3 */ { SCIF4, SCIF5, WDT, } }, + { 0xffd40010, 32, 8, /* INT2PRI4 */ { HUDI, DMAC0, DMAC1, } }, + { 0xffd40014, 32, 8, /* INT2PRI5 */ { HAC0, HAC1, PCISERR, PCIINTA } }, + { 0xffd40018, 32, 8, /* INT2PRI6 */ { PCIINTB, PCIINTC, + PCIINTD, PCIC5 } }, + { 0xffd4001c, 32, 8, /* INT2PRI7 */ { SIOF, HSPI, MMCIF, } }, + { 0xffd40020, 32, 8, /* INT2PRI8 */ { FLCTL, GPIO, SSI0, SSI1, } }, + { 0xffd40024, 32, 8, /* INT2PRI9 */ { DU, GDTA, } }, +}; + +static DECLARE_INTC_DESC(intc_desc, "sh7785", vectors, groups, priorities, + mask_registers, prio_registers, NULL); + + +/* Support for external interrupt pins in IRQ mode */ + +static struct intc_vect vectors_irq0123[] = { + INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), + INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), +}; + +static struct intc_vect vectors_irq4567[] = { + INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), + INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), +}; + +static struct intc_sense_reg sense_registers[] = { + { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, + IRQ4, IRQ5, IRQ6, IRQ7 } }, +}; + +static DECLARE_INTC_DESC(intc_desc_irq0123, "sh7785-irq0123", vectors_irq0123, + NULL, NULL, mask_registers, prio_registers, + sense_registers); + +static DECLARE_INTC_DESC(intc_desc_irq4567, "sh7785-irq4567", vectors_irq4567, + NULL, NULL, mask_registers, prio_registers, + sense_registers); + +/* External interrupt pins in IRL mode */ + +static struct intc_vect vectors_irl0123[] = { + INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220), + INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260), + INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0), + INTC_VECT(IRL0_LHHL, 0x2c0), INTC_VECT(IRL0_LHHH, 0x2e0), + INTC_VECT(IRL0_HLLL, 0x300), INTC_VECT(IRL0_HLLH, 0x320), + INTC_VECT(IRL0_HLHL, 0x340), INTC_VECT(IRL0_HLHH, 0x360), + INTC_VECT(IRL0_HHLL, 0x380), INTC_VECT(IRL0_HHLH, 0x3a0), + INTC_VECT(IRL0_HHHL, 0x3c0), }; +static struct intc_vect vectors_irl4567[] = { + INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20), + INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60), + INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0), + INTC_VECT(IRL4_LHHL, 0xbc0), INTC_VECT(IRL4_LHHH, 0xbe0), + INTC_VECT(IRL4_HLLL, 0xc00), INTC_VECT(IRL4_HLLH, 0xc20), + INTC_VECT(IRL4_HLHL, 0xc40), INTC_VECT(IRL4_HLHH, 0xc60), + INTC_VECT(IRL4_HHLL, 0xc80), INTC_VECT(IRL4_HHLH, 0xca0), + INTC_VECT(IRL4_HHHL, 0xcc0), +}; + +static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7785-irl0123", vectors_irl0123, + NULL, NULL, mask_registers, NULL, NULL); + +static DECLARE_INTC_DESC(intc_desc_irl4567, "sh7785-irl4567", vectors_irl4567, + NULL, NULL, mask_registers, NULL, NULL); + void __init plat_irq_setup(void) { - register_intc2_controller(&intc2_irq_desc); + register_intc_controller(&intc_desc); } +void __init plat_irq_setup_pins(int mode) +{ + switch (mode) { + case IRQ_MODE_IRQ7654: + register_intc_controller(&intc_desc_irq4567); + break; + case IRQ_MODE_IRQ3210: + register_intc_controller(&intc_desc_irq0123); + break; + case IRQ_MODE_IRL7654: + register_intc_controller(&intc_desc_irl4567); + break; + case IRQ_MODE_IRL3210: + register_intc_controller(&intc_desc_irl0123); + break; + default: + BUG(); + } +} diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index c2777555003..99aebecc570 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -192,7 +192,7 @@ config CPU_SUBTYPE_SH7785 bool "Support SH7785 processor" select CPU_SH4A select CPU_SHX2 - select CPU_HAS_INTC2_IRQ + select CPU_HAS_INTC_IRQ config CPU_SUBTYPE_SHX3 bool "Support SH-X3 processor" diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 20d42959f52..921ddec6ccf 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -115,7 +115,8 @@ void __init register_intc_controller(struct intc_desc *desc); void __init plat_irq_setup(void); -enum { IRQ_MODE_IRQ, IRQ_MODE_IRL7654, IRQ_MODE_IRL3210 }; +enum { IRQ_MODE_IRQ, IRQ_MODE_IRQ7654, IRQ_MODE_IRQ3210, + IRQ_MODE_IRL7654, IRQ_MODE_IRL3210 }; void __init plat_irq_setup_pins(int mode); #endif /* __ASM_SH_HW_IRQ_H */ -- cgit v1.2.3-70-g09d2 From ad89f87a84040a57c4a78ca2759b364f72f423ab Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 3 Aug 2007 14:19:58 +0900 Subject: rtc: rtc-sh: Support 4-digit year on SH7705/SH7710/SH7712. All SH-4 parts have a 4-digit year, while the SH-3 parts typically only use a 2-digit one. The SH7705, SH7710, and SH7712 SH-3 parts however opted to extend it to 4-digit and still look and act like an SH-3 RTC in all other ways. This adds a capability flag (RTC_CAP_4_DIGIT_YEAR) that these corner-case CPU subtypes can set in their platform data and cleans up some of the ifdef mess in the driver as a result. Reported-by: Markus Brunner Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 12 +++++++-- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 10 ++++++- drivers/rtc/rtc-sh.c | 51 ++++++++++++++++++++++------------- include/asm-sh/rtc.h | 6 +++++ 4 files changed, 58 insertions(+), 21 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 6fc68e77102..568cc08c254 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -1,7 +1,7 @@ /* * SH7705 Setup * - * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2006, 2007 Paul Mundt * Copyright (C) 2007 Nobuhiro Iwamatsu * * This file is subject to the terms and conditions of the GNU General Public @@ -13,8 +13,9 @@ #include #include #include +#include -enum{ +enum { UNUSED = 0, /* interrupt sources */ @@ -138,11 +139,18 @@ static struct resource rtc_resources[] = { }, }; +static struct sh_rtc_platform_info rtc_info = { + .capabilities = RTC_CAP_4_DIGIT_YEAR, +}; + static struct platform_device rtc_device = { .name = "sh-rtc", .id = -1, .num_resources = ARRAY_SIZE(rtc_resources), .resource = rtc_resources, + .dev = { + .platform_data = &rtc_info, + }, }; static struct platform_device *sh7705_devices[] __initdata = { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 07f26ab75d9..eb55ac9dbf7 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -1,7 +1,7 @@ /* * SH3 Setup code for SH7710, SH7712 * - * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2006, 2007 Paul Mundt * Copyright (C) 2007 Nobuhiro Iwamatsu * * This file is subject to the terms and conditions of the GNU General Public @@ -13,6 +13,7 @@ #include #include #include +#include enum { UNUSED = 0, @@ -130,11 +131,18 @@ static struct resource rtc_resources[] = { }, }; +static struct sh_rtc_platform_info rtc_info = { + .capabilities = RTC_CAP_4_DIGIT_YEAR, +}; + static struct platform_device rtc_device = { .name = "sh-rtc", .id = -1, .num_resources = ARRAY_SIZE(rtc_resources), .resource = rtc_resources, + .dev = { + .platform_data = &rtc_info, + }, }; static struct plat_sci_port sci_platform_data[] = { diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 93ee05eeaeb..78277a118b6 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -1,7 +1,7 @@ /* * SuperH On-Chip RTC Support * - * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2006, 2007 Paul Mundt * Copyright (C) 2006 Jamie Lenehan * * Based on the old arch/sh/kernel/cpu/rtc.c by: @@ -23,16 +23,19 @@ #include #include #include +#include #define DRV_NAME "sh-rtc" -#define DRV_VERSION "0.1.2" +#define DRV_VERSION "0.1.3" #ifdef CONFIG_CPU_SH3 #define rtc_reg_size sizeof(u16) #define RTC_BIT_INVERTED 0 /* No bug on SH7708, SH7709A */ +#define RTC_DEF_CAPABILITIES 0UL #elif defined(CONFIG_CPU_SH4) #define rtc_reg_size sizeof(u32) #define RTC_BIT_INVERTED 0x40 /* bug on SH7750, SH7750S */ +#define RTC_DEF_CAPABILITIES RTC_CAP_4_DIGIT_YEAR #endif #define RTC_REG(r) ((r) * rtc_reg_size) @@ -80,6 +83,7 @@ struct sh_rtc { struct rtc_device *rtc_dev; spinlock_t lock; int rearm_aie; + unsigned long capabilities; /* See asm-sh/rtc.h for cap bits */ }; static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id) @@ -319,14 +323,14 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_mday = BCD2BIN(readb(rtc->regbase + RDAYCNT)); tm->tm_mon = BCD2BIN(readb(rtc->regbase + RMONCNT)) - 1; -#if defined(CONFIG_CPU_SH4) - yr = readw(rtc->regbase + RYRCNT); - yr100 = BCD2BIN(yr >> 8); - yr &= 0xff; -#else - yr = readb(rtc->regbase + RYRCNT); - yr100 = BCD2BIN((yr == 0x99) ? 0x19 : 0x20); -#endif + if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { + yr = readw(rtc->regbase + RYRCNT); + yr100 = BCD2BIN(yr >> 8); + yr &= 0xff; + } else { + yr = readb(rtc->regbase + RYRCNT); + yr100 = BCD2BIN((yr == 0x99) ? 0x19 : 0x20); + } tm->tm_year = (yr100 * 100 + BCD2BIN(yr)) - 1900; @@ -375,14 +379,14 @@ static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm) writeb(BIN2BCD(tm->tm_mday), rtc->regbase + RDAYCNT); writeb(BIN2BCD(tm->tm_mon + 1), rtc->regbase + RMONCNT); -#ifdef CONFIG_CPU_SH3 - year = tm->tm_year % 100; - writeb(BIN2BCD(year), rtc->regbase + RYRCNT); -#else - year = (BIN2BCD((tm->tm_year + 1900) / 100) << 8) | - BIN2BCD(tm->tm_year % 100); - writew(year, rtc->regbase + RYRCNT); -#endif + if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) { + year = (BIN2BCD((tm->tm_year + 1900) / 100) << 8) | + BIN2BCD(tm->tm_year % 100); + writew(year, rtc->regbase + RYRCNT); + } else { + year = tm->tm_year % 100; + writeb(BIN2BCD(year), rtc->regbase + RYRCNT); + } /* Start RTC */ tmp = readb(rtc->regbase + RCR2); @@ -589,6 +593,17 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev) goto err_badmap; } + rtc->capabilities = RTC_DEF_CAPABILITIES; + if (pdev->dev.platform_data) { + struct sh_rtc_platform_info *pinfo = pdev->dev.platform_data; + + /* + * Some CPUs have special capabilities in addition to the + * default set. Add those in here. + */ + rtc->capabilities |= pinfo->capabilities; + } + platform_set_drvdata(pdev, rtc); return 0; diff --git a/include/asm-sh/rtc.h b/include/asm-sh/rtc.h index 91aacc96151..858da99d37e 100644 --- a/include/asm-sh/rtc.h +++ b/include/asm-sh/rtc.h @@ -5,4 +5,10 @@ extern void (*board_time_init)(void); extern void (*rtc_sh_get_time)(struct timespec *); extern int (*rtc_sh_set_time)(const time_t); +#define RTC_CAP_4_DIGIT_YEAR (1 << 0) + +struct sh_rtc_platform_info { + unsigned long capabilities; +}; + #endif /* _ASM_RTC_H */ -- cgit v1.2.3-70-g09d2 From d59645d6ba67337ff09369d9da4fc47f7dc361cc Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 3 Aug 2007 14:23:35 +0900 Subject: sh: intc - remove redundant irq code for sh03, snapgear and titan This patch removes redundant board specific interrupt code for boards using sh775x processors and 4 IRQ lines in "Individual Interrupt Mode" aka IRLM. Three boards are affected: sh03, snapgear and titan. The right way to do this is to use cpu specific code provided by intc. A nice side effect is that sh03 now compiles, board not BROKEN any more. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 +- arch/sh/boards/sh03/setup.c | 26 +------------------------- arch/sh/boards/snapgear/setup.c | 30 ++---------------------------- arch/sh/boards/titan/setup.c | 30 +----------------------------- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 14 ++++++++++---- include/asm-sh/hw_irq.h | 5 ----- include/asm-sh/sh03/io.h | 9 --------- include/asm-sh/snapgear.h | 12 ++++-------- 8 files changed, 19 insertions(+), 109 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index ceceb05f9dc..6553325fa43 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -308,7 +308,7 @@ config SH_MPC1211 config SH_SH03 bool "Interface CTP/PCI-SH03" - depends on CPU_SUBTYPE_SH7751 && BROKEN + depends on CPU_SUBTYPE_SH7751 select CPU_HAS_IPR_IRQ select SYS_SUPPORTS_PCI help diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c index 9c031a8c0a1..df96312efd4 100644 --- a/arch/sh/boards/sh03/setup.c +++ b/arch/sh/boards/sh03/setup.c @@ -15,33 +15,9 @@ #include #include -static struct ipr_data ipr_irq_table[] = { - { IRL0_IRQ, 0, IRL0_IPR_POS, IRL0_PRIORITY }, - { IRL1_IRQ, 0, IRL1_IPR_POS, IRL1_PRIORITY }, - { IRL2_IRQ, 0, IRL2_IPR_POS, IRL2_PRIORITY }, - { IRL3_IRQ, 0, IRL3_IPR_POS, IRL3_PRIORITY }, -}; - -static unsigned long ipr_offsets[] = { - INTC_IPRD, -}; - -static struct ipr_desc ipr_irq_desc = { - .ipr_offsets = ipr_offsets, - .nr_offsets = ARRAY_SIZE(ipr_offsets), - - .ipr_data = ipr_irq_table, - .nr_irqs = ARRAY_SIZE(ipr_irq_table), - - .chip = { - .name = "IPR-sh03", - }, -}; - static void __init init_sh03_IRQ(void) { - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); - register_ipr_controller(&ipr_irq_desc); + plat_irq_setup_pins(IRQ_MODE_IRQ); } extern void *cf_io_base; diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c index 84271d85a8d..2b594f60000 100644 --- a/arch/sh/boards/snapgear/setup.c +++ b/arch/sh/boards/snapgear/setup.c @@ -68,37 +68,11 @@ module_init(eraseconfig_init); * IRL3 = crypto */ -static struct ipr_data ipr_irq_table[] = { - { IRL0_IRQ, 0, IRL0_IPR_POS, IRL0_PRIORITY }, - { IRL1_IRQ, 0, IRL1_IPR_POS, IRL1_PRIORITY }, - { IRL2_IRQ, 0, IRL2_IPR_POS, IRL2_PRIORITY }, - { IRL3_IRQ, 0, IRL3_IPR_POS, IRL3_PRIORITY }, -}; - -static unsigned long ipr_offsets[] = { - INTC_IPRD, -}; - -static struct ipr_desc ipr_irq_desc = { - .ipr_offsets = ipr_offsets, - .nr_offsets = ARRAY_SIZE(ipr_offsets), - - .ipr_data = ipr_irq_table, - .nr_irqs = ARRAY_SIZE(ipr_irq_table), - - .chip = { - .name = "IPR-snapgear", - }, -}; - static void __init init_snapgear_IRQ(void) { - /* enable individual interrupt mode for externals */ - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); - printk("Setup SnapGear IRQ/IPR ...\n"); - - register_ipr_controller(&ipr_irq_desc); + /* enable individual interrupt mode for externals */ + plat_irq_setup_pins(IRQ_MODE_IRQ); } /* diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c index 606d25a4b87..5de3b2ad71a 100644 --- a/arch/sh/boards/titan/setup.c +++ b/arch/sh/boards/titan/setup.c @@ -12,38 +12,10 @@ #include #include -static struct ipr_data ipr_irq_table[] = { - /* IRQ, IPR idx, shift, prio */ - { TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */ - { TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */ - { TITAN_IRQ_MPCIA, 3, 4, 8 }, /* mPCI A (top) */ - { TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */ -}; - -static unsigned long ipr_offsets[] = { /* stolen from setup-sh7750.c */ - 0xffd00004UL, /* 0: IPRA */ - 0xffd00008UL, /* 1: IPRB */ - 0xffd0000cUL, /* 2: IPRC */ - 0xffd00010UL, /* 3: IPRD */ -}; - -static struct ipr_desc ipr_irq_desc = { - .ipr_offsets = ipr_offsets, - .nr_offsets = ARRAY_SIZE(ipr_offsets), - - .ipr_data = ipr_irq_table, - .nr_irqs = ARRAY_SIZE(ipr_irq_table), - - .chip = { - .name = "IPR-titan", - }, -}; static void __init init_titan_irq(void) { /* enable individual interrupt mode for externals */ - ipr_irq_enable_irlm(); - /* register ipr irqs */ - register_ipr_controller(&ipr_irq_desc); + plat_irq_setup_pins(IRQ_MODE_IRQ); } static struct sh_machine_vector mv_titan __initmv = { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index f2286de22bd..e313be24984 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -282,13 +282,19 @@ void __init plat_irq_setup(void) #define INTC_ICR 0xffd00000UL #define INTC_ICR_IRLM (1<<7) -/* enable individual interrupt mode for external interupts */ -void __init ipr_irq_enable_irlm(void) +void __init plat_irq_setup_pins(int mode) { #if defined(CONFIG_CPU_SUBTYPE_SH7750) || defined(CONFIG_CPU_SUBTYPE_SH7091) BUG(); /* impossible to mask interrupts on SH7750 and SH7091 */ + return; #endif - register_intc_controller(&intc_desc_irlm); - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); + switch (mode) { + case IRQ_MODE_IRQ: /* individual interrupt mode for IRL3-0 */ + ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); + register_intc_controller(&intc_desc_irlm); + break; + default: + BUG(); + } } diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 921ddec6ccf..8f5bf98d053 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -41,11 +41,6 @@ struct ipr_desc { void register_ipr_controller(struct ipr_desc *); -/* - * Enable individual interrupt mode for external IPR IRQs. - */ -void __init ipr_irq_enable_irlm(void); - typedef unsigned char intc_enum; struct intc_vect { diff --git a/include/asm-sh/sh03/io.h b/include/asm-sh/sh03/io.h index 4ff1eb90030..c39c785bba9 100644 --- a/include/asm-sh/sh03/io.h +++ b/include/asm-sh/sh03/io.h @@ -11,22 +11,13 @@ #include -#define INTC_IPRD 0xffd00010UL - #define IRL0_IRQ 2 -#define IRL0_IPR_POS 3 #define IRL0_PRIORITY 13 - #define IRL1_IRQ 5 -#define IRL1_IPR_POS 2 #define IRL1_PRIORITY 10 - #define IRL2_IRQ 8 -#define IRL2_IPR_POS 1 #define IRL2_PRIORITY 7 - #define IRL3_IRQ 11 -#define IRL3_IPR_POS 0 #define IRL3_PRIORITY 4 void heartbeat_sh03(void); diff --git a/include/asm-sh/snapgear.h b/include/asm-sh/snapgear.h index 3554e3a74e9..042d95f51c4 100644 --- a/include/asm-sh/snapgear.h +++ b/include/asm-sh/snapgear.h @@ -19,20 +19,16 @@ * is the interrupt :-) */ -#define IRL0_IRQ 2 -#define IRL0_IPR_POS 3 +#define IRL0_IRQ 2 #define IRL0_PRIORITY 13 -#define IRL1_IRQ 5 -#define IRL1_IPR_POS 2 +#define IRL1_IRQ 5 #define IRL1_PRIORITY 10 -#define IRL2_IRQ 8 -#define IRL2_IPR_POS 1 +#define IRL2_IRQ 8 #define IRL2_PRIORITY 7 -#define IRL3_IRQ 11 -#define IRL3_IPR_POS 0 +#define IRL3_IRQ 11 #define IRL3_PRIORITY 4 #endif -- cgit v1.2.3-70-g09d2 From 51da64264b8d59a1e5fceebd94a975690b70b086 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 3 Aug 2007 14:25:32 +0900 Subject: sh: intc - add single bitmap register support This patch adds single bitmap register support to intc. The current code only handles 16 and 32 bit registers where a set bit means interrupt enabled, but this is easy to extend in the future. The INTC_IRQ() macro is also added to provide a way to hook in interrupt controllers for FPGAs in boards or companion chips. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/intc.c | 73 ++++++++++++++++++++++++++++++++++++------- include/asm-sh/hw_irq.h | 1 + 2 files changed, 63 insertions(+), 11 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index 9345a7130e9..a25f70dd6ad 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -87,40 +87,71 @@ static void enable_prio_32(struct intc_desc *desc, unsigned int data) ctrl_outl(set_prio_field(desc, ctrl_inl(addr), prio, data), addr); } -static void disable_mask_8(struct intc_desc *desc, unsigned int data) +static void write_set_reg_8(struct intc_desc *desc, unsigned int data) { ctrl_outb(1 << _INTC_BIT(data), _INTC_PTR(desc, mask_regs, data)->set_reg); } -static void enable_mask_8(struct intc_desc *desc, unsigned int data) +static void write_clr_reg_8(struct intc_desc *desc, unsigned int data) { ctrl_outb(1 << _INTC_BIT(data), _INTC_PTR(desc, mask_regs, data)->clr_reg); } -static void disable_mask_32(struct intc_desc *desc, unsigned int data) +static void write_set_reg_32(struct intc_desc *desc, unsigned int data) { ctrl_outl(1 << _INTC_BIT(data), _INTC_PTR(desc, mask_regs, data)->set_reg); } -static void enable_mask_32(struct intc_desc *desc, unsigned int data) +static void write_clr_reg_32(struct intc_desc *desc, unsigned int data) { ctrl_outl(1 << _INTC_BIT(data), _INTC_PTR(desc, mask_regs, data)->clr_reg); } +static void or_set_reg_16(struct intc_desc *desc, unsigned int data) +{ + unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; + + ctrl_outw(ctrl_inw(addr) | 1 << _INTC_BIT(data), addr); +} + +static void and_set_reg_16(struct intc_desc *desc, unsigned int data) +{ + unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; + + ctrl_outw(ctrl_inw(addr) & ~(1 << _INTC_BIT(data)), addr); +} + +static void or_set_reg_32(struct intc_desc *desc, unsigned int data) +{ + unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; + + ctrl_outl(ctrl_inl(addr) | 1 << _INTC_BIT(data), addr); +} + +static void and_set_reg_32(struct intc_desc *desc, unsigned int data) +{ + unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; + + ctrl_outl(ctrl_inl(addr) & ~(1 << _INTC_BIT(data)), addr); +} + enum { REG_FN_ERROR=0, - REG_FN_MASK_8, REG_FN_MASK_32, + REG_FN_DUAL_8, REG_FN_DUAL_32, + REG_FN_ENA_16, REG_FN_ENA_32, REG_FN_PRIO_16, REG_FN_PRIO_32 }; static struct { void (*enable)(struct intc_desc *, unsigned int); void (*disable)(struct intc_desc *, unsigned int); } intc_reg_fns[] = { - [REG_FN_MASK_8] = { enable_mask_8, disable_mask_8 }, - [REG_FN_MASK_32] = { enable_mask_32, disable_mask_32 }, + [REG_FN_DUAL_8] = { write_clr_reg_8, write_set_reg_8 }, + [REG_FN_DUAL_32] = { write_clr_reg_32, write_set_reg_32 }, + [REG_FN_ENA_16] = { or_set_reg_16, and_set_reg_16 }, + [REG_FN_ENA_32] = { or_set_reg_32, and_set_reg_32 }, [REG_FN_PRIO_16] = { enable_prio_16, disable_prio_16 }, [REG_FN_PRIO_32] = { enable_prio_32, disable_prio_32 }, }; @@ -218,13 +249,13 @@ static int intc_set_sense(unsigned int irq, unsigned int type) return -EINVAL; } -static unsigned int __init intc_find_mask_handler(unsigned int width) +static unsigned int __init intc_find_dual_handler(unsigned int width) { switch (width) { case 8: - return REG_FN_MASK_8; + return REG_FN_DUAL_8; case 32: - return REG_FN_MASK_32; + return REG_FN_DUAL_32; } BUG(); @@ -244,6 +275,19 @@ static unsigned int __init intc_find_prio_handler(unsigned int width) return REG_FN_ERROR; } +static unsigned int __init intc_find_ena_handler(unsigned int width) +{ + switch (width) { + case 16: + return REG_FN_ENA_16; + case 32: + return REG_FN_ENA_32; + } + + BUG(); + return REG_FN_ERROR; +} + static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id) { struct intc_group *g = desc->groups; @@ -301,7 +345,14 @@ static unsigned int __init intc_mask_data(struct intc_desc *desc, if (mr->enum_ids[j] != enum_id) continue; - fn = intc_find_mask_handler(mr->reg_width); + switch (mr->clr_reg) { + case 1: /* 1 = enabled interrupt - "enable" register */ + fn = intc_find_ena_handler(mr->reg_width); + break; + default: + fn = intc_find_dual_handler(mr->reg_width); + } + if (fn == REG_FN_ERROR) return 0; diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 8f5bf98d053..9f55c2dc1b5 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -49,6 +49,7 @@ struct intc_vect { }; #define INTC_VECT(enum_id, vect) { enum_id, vect } +#define INTC_IRQ(enum_id, irq) INTC_VECT(enum_id, irq2evt(irq)) struct intc_prio { intc_enum enum_id; -- cgit v1.2.3-70-g09d2 From 48180cab3adf4cb290c28b70e44e958b7fb8a5b0 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 3 Aug 2007 14:27:20 +0900 Subject: sh: intc - convert voyagergx code This patch converts the sh-specific voyagergx interrupt code to make use of intc. A lot of "interesting" old cruft gets replaced with intc tables and some simple demux code. - All interrupt sources in the sm501 data sheet are now in the header. - The number and order of IRQ values are disconnected from register bits. - Interrupt sources now start from IRQ 200. - set_irq_chained_handler() is now used to hook up the demux function. In the future it would probably make sense to move the interrupt demuxer into into the mfd driver, but this is probably a nice step in the right direction until that happens. Tested on a R2D-1 board using the serial port hooked up to the sm501. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/rts7751r2d/irq.c | 6 +- arch/sh/boards/renesas/rts7751r2d/setup.c | 5 +- arch/sh/cchips/voyagergx/irq.c | 188 ++++++++++-------------------- include/asm-sh/voyagergx.h | 39 +++++-- 4 files changed, 95 insertions(+), 143 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c index 0bae9041ace..b97c25de3a4 100644 --- a/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #if defined(CONFIG_RTS7751R2D_REV11) @@ -21,9 +22,6 @@ static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0}; static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0}; #endif -extern int voyagergx_irq_demux(int irq); -extern void setup_voyagergx_irq(void); - static void enable_rts7751r2d_irq(unsigned int irq) { /* Set priority in IPR back to original value */ @@ -39,7 +37,7 @@ static void disable_rts7751r2d_irq(unsigned int irq) int rts7751r2d_irq_demux(int irq) { - return voyagergx_irq_demux(irq); + return irq; } static struct irq_chip rts7751r2d_irq_chip __read_mostly = { diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c index 6f7029d3324..4d1bbd30e52 100644 --- a/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -82,7 +82,7 @@ static struct plat_serial8250_port uart_platform_data[] = { .membase = (void __iomem *)VOYAGER_UART_BASE, .mapbase = VOYAGER_UART_BASE, .iotype = UPIO_MEM, - .irq = VOYAGER_UART0_IRQ, + .irq = IRQ_SM501_U0, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, .regshift = 2, .uartclk = (9600 * 16), @@ -125,7 +125,7 @@ static struct resource sm501_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { - .start = 32, + .start = IRQ_SM501_CV, .flags = IORESOURCE_IRQ, }, }; @@ -187,7 +187,6 @@ static void __init rts7751r2d_setup(char **cmdline_p) static struct sh_machine_vector mv_rts7751r2d __initmv = { .mv_name = "RTS7751R2D", .mv_setup = rts7751r2d_setup, - .mv_nr_irqs = 72, .mv_init_irq = init_rts7751r2d_IRQ, .mv_irq_demux = rts7751r2d_irq_demux, diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c index d70e5c8461b..0ca405a46a5 100644 --- a/arch/sh/cchips/voyagergx/irq.c +++ b/arch/sh/cchips/voyagergx/irq.c @@ -23,149 +23,79 @@ #include #include -static void disable_voyagergx_irq(unsigned int irq) -{ - unsigned long val; - unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); - - pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); - val = readl((void __iomem *)VOYAGER_INT_MASK); - val &= ~mask; - writel(val, (void __iomem *)VOYAGER_INT_MASK); -} - -static void enable_voyagergx_irq(unsigned int irq) -{ - unsigned long val; - unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); - - pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); - val = readl((void __iomem *)VOYAGER_INT_MASK); - val |= mask; - writel(val, (void __iomem *)VOYAGER_INT_MASK); -} - -static void mask_and_ack_voyagergx(unsigned int irq) -{ - disable_voyagergx_irq(irq); -} - -static void end_voyagergx_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_voyagergx_irq(irq); -} - -static unsigned int startup_voyagergx_irq(unsigned int irq) -{ - enable_voyagergx_irq(irq); - return 0; -} - -static void shutdown_voyagergx_irq(unsigned int irq) -{ - disable_voyagergx_irq(irq); -} - -static struct hw_interrupt_type voyagergx_irq_type = { - .typename = "VOYAGERGX-IRQ", - .startup = startup_voyagergx_irq, - .shutdown = shutdown_voyagergx_irq, - .enable = enable_voyagergx_irq, - .disable = disable_voyagergx_irq, - .ack = mask_and_ack_voyagergx, - .end = end_voyagergx_irq, +enum { + UNUSED = 0, + + /* voyager specific interrupt sources */ + UP, G54, G53, G52, G51, G50, G49, G48, + I2C, PW, DMA, PCI, I2S, AC, US, + U1, U0, CV, MC, S1, S0, + UH, TWOD, ZD, PV, CI, }; -static irqreturn_t voyagergx_interrupt(int irq, void *dev_id) -{ - printk(KERN_INFO - "VoyagerGX: spurious interrupt, status: 0x%x\n", - (unsigned int)readl((void __iomem *)INT_STATUS)); - return IRQ_HANDLED; -} - -static struct { - int (*func)(int, void *); - void *dev; -} voyagergx_demux[VOYAGER_IRQ_NUM]; +static struct intc_vect vectors[] = { + INTC_IRQ(UP, IRQ_SM501_UP), INTC_IRQ(G54, IRQ_SM501_G54), + INTC_IRQ(G53, IRQ_SM501_G53), INTC_IRQ(G52, IRQ_SM501_G52), + INTC_IRQ(G51, IRQ_SM501_G51), INTC_IRQ(G50, IRQ_SM501_G50), + INTC_IRQ(G49, IRQ_SM501_G49), INTC_IRQ(G48, IRQ_SM501_G48), + INTC_IRQ(I2C, IRQ_SM501_I2C), INTC_IRQ(PW, IRQ_SM501_PW), + INTC_IRQ(DMA, IRQ_SM501_DMA), INTC_IRQ(PCI, IRQ_SM501_PCI), + INTC_IRQ(I2S, IRQ_SM501_I2S), INTC_IRQ(AC, IRQ_SM501_AC), + INTC_IRQ(US, IRQ_SM501_US), INTC_IRQ(U1, IRQ_SM501_U1), + INTC_IRQ(U0, IRQ_SM501_U0), INTC_IRQ(CV, IRQ_SM501_CV), + INTC_IRQ(MC, IRQ_SM501_MC), INTC_IRQ(S1, IRQ_SM501_S1), + INTC_IRQ(S0, IRQ_SM501_S0), INTC_IRQ(UH, IRQ_SM501_UH), + INTC_IRQ(TWOD, IRQ_SM501_2D), INTC_IRQ(ZD, IRQ_SM501_ZD), + INTC_IRQ(PV, IRQ_SM501_PV), INTC_IRQ(CI, IRQ_SM501_CI), +}; -void voyagergx_register_irq_demux(int irq, - int (*demux)(int irq, void *dev), void *dev) -{ - voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = demux; - voyagergx_demux[irq - VOYAGER_IRQ_BASE].dev = dev; -} +static struct intc_mask_reg mask_registers[] = { + { VOYAGER_INT_MASK, 1, 32, /* "Interrupt Mask", MMIO_base + 0x30 */ + { UP, G54, G53, G52, G51, G50, G49, G48, + I2C, PW, 0, DMA, PCI, I2S, AC, US, + 0, 0, U1, U0, CV, MC, S1, S0, + 0, UH, 0, 0, TWOD, ZD, PV, CI } }, +}; -void voyagergx_unregister_irq_demux(int irq) -{ - voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = 0; -} +static DECLARE_INTC_DESC(intc_desc, "voyagergx", vectors, + NULL, NULL, mask_registers, NULL, NULL); + +static unsigned int voyagergx_stat2irq[32] = { + IRQ_SM501_CI, IRQ_SM501_PV, IRQ_SM501_ZD, IRQ_SM501_2D, + 0, 0, IRQ_SM501_UH, 0, + IRQ_SM501_S0, IRQ_SM501_S1, IRQ_SM501_MC, IRQ_SM501_CV, + IRQ_SM501_U0, IRQ_SM501_U1, 0, 0, + IRQ_SM501_US, IRQ_SM501_AC, IRQ_SM501_I2S, IRQ_SM501_PCI, + IRQ_SM501_DMA, 0, IRQ_SM501_PW, IRQ_SM501_I2C, + IRQ_SM501_G48, IRQ_SM501_G49, IRQ_SM501_G50, IRQ_SM501_G51, + IRQ_SM501_G52, IRQ_SM501_G53, IRQ_SM501_G54, IRQ_SM501_UP +}; -int voyagergx_irq_demux(int irq) +static void voyagergx_irq_demux(unsigned int irq, struct irq_desc *desc) { - - if (irq == IRQ_VOYAGER ) { - unsigned long i = 0, bit __attribute__ ((unused)); - unsigned long val = readl((void __iomem *)INT_STATUS); - - if (val & (1 << 1)) - i = 1; - else if (val & (1 << 2)) - i = 2; - else if (val & (1 << 6)) - i = 6; - else if (val & (1 << 10)) - i = 10; - else if (val & (1 << 11)) - i = 11; - else if (val & (1 << 12)) - i = 12; - else if (val & (1 << 17)) - i = 17; - else - printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val); - pr_debug("voyagergx_irq_demux %ld \n", i); - if (i < VOYAGER_IRQ_NUM) { - irq = VOYAGER_IRQ_BASE + i; - if (voyagergx_demux[i].func != 0) - irq = voyagergx_demux[i].func(irq, - voyagergx_demux[i].dev); + unsigned long intv = ctrl_inl(INT_STATUS); + struct irq_desc *ext_desc; + unsigned int ext_irq; + unsigned int k = 0; + + while (intv) { + ext_irq = voyagergx_stat2irq[k]; + if (ext_irq && (intv & 1)) { + ext_desc = irq_desc + ext_irq; + handle_level_irq(ext_irq, ext_desc); } + intv >>= 1; + k++; } - return irq; } -static struct irqaction irq0 = { - .name = "voyagergx", - .handler = voyagergx_interrupt, - .flags = IRQF_DISABLED, - .mask = CPU_MASK_NONE, -}; - void __init setup_voyagergx_irq(void) { - int i, flag; - - printk(KERN_INFO "VoyagerGX configured at 0x%x on irq %d(mapped into %d to %d)\n", - VOYAGER_BASE, + printk(KERN_INFO "VoyagerGX on irq %d (mapped into %d to %d)\n", IRQ_VOYAGER, VOYAGER_IRQ_BASE, VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1); - for (i=0; i Date: Fri, 3 Aug 2007 14:29:20 +0900 Subject: sh: remove intc2 code There is no point in keeping around the now unused intc2 code. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 3 -- arch/sh/kernel/cpu/irq/Makefile | 1 - arch/sh/kernel/cpu/irq/intc2.c | 86 ----------------------------------------- arch/sh/mm/Kconfig | 1 - include/asm-sh/hw_irq.h | 18 --------- 5 files changed, 109 deletions(-) delete mode 100644 arch/sh/kernel/cpu/irq/intc2.c (limited to 'include/asm-sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 6553325fa43..617765d5c9a 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -181,9 +181,6 @@ config CPU_HAS_MASKREG_IRQ config CPU_HAS_INTC_IRQ bool -config CPU_HAS_INTC2_IRQ - bool - config CPU_HAS_IPR_IRQ bool diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile index 60bfc05cf35..8712ec5fc0b 100644 --- a/arch/sh/kernel/cpu/irq/Makefile +++ b/arch/sh/kernel/cpu/irq/Makefile @@ -6,4 +6,3 @@ obj-y += imask.o obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o obj-$(CONFIG_CPU_HAS_INTC_IRQ) += intc.o -obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c deleted file mode 100644 index cc5221390e0..00000000000 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Interrupt handling for INTC2-based IRQ. - * - * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) - * Copyright (C) 2005, 2006 Paul Mundt (lethal@linux-sh.org) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * These are the "new Hitachi style" interrupts, as present on the - * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. - */ -#include -#include -#include -#include - -static inline struct intc2_desc *get_intc2_desc(unsigned int irq) -{ - struct irq_chip *chip = get_irq_chip(irq); - return (void *)((char *)chip - offsetof(struct intc2_desc, chip)); -} - -static void disable_intc2_irq(unsigned int irq) -{ - struct intc2_data *p = get_irq_chip_data(irq); - struct intc2_desc *d = get_intc2_desc(irq); - - ctrl_outl(1 << p->msk_shift, d->msk_base + p->msk_offset + - (hard_smp_processor_id() * 4)); -} - -static void enable_intc2_irq(unsigned int irq) -{ - struct intc2_data *p = get_irq_chip_data(irq); - struct intc2_desc *d = get_intc2_desc(irq); - - ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset + - (hard_smp_processor_id() * 4)); -} - -/* - * Setup an INTC2 style interrupt. - * NOTE: Unlike IPR interrupts, parameters are not shifted by this code, - * allowing the use of the numbers straight out of the datasheet. - * For example: - * PIO1 which is INTPRI00[19,16] and INTMSK00[13] - * would be: ^ ^ ^ ^ - * | | | | - * { 84, 0, 16, 0, 13 }, - * - * in the intc2_data table. - */ -void register_intc2_controller(struct intc2_desc *desc) -{ - int i; - - desc->chip.mask = disable_intc2_irq; - desc->chip.unmask = enable_intc2_irq; - desc->chip.mask_ack = disable_intc2_irq; - - for (i = 0; i < desc->nr_irqs; i++) { - unsigned long ipr, flags; - struct intc2_data *p = desc->intc2_data + i; - - disable_irq_nosync(p->irq); - - if (desc->prio_base) { - /* Set the priority level */ - local_irq_save(flags); - - ipr = ctrl_inl(desc->prio_base + p->ipr_offset); - ipr &= ~(0xf << p->ipr_shift); - ipr |= p->priority << p->ipr_shift; - ctrl_outl(ipr, desc->prio_base + p->ipr_offset); - - local_irq_restore(flags); - } - - set_irq_chip_and_handler_name(p->irq, &desc->chip, - handle_level_irq, "level"); - set_irq_chip_data(p->irq, p); - - disable_intc2_irq(p->irq); - } -} diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index eca68da7c0a..569292ca877 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -31,7 +31,6 @@ config CPU_SH4AL_DSP config CPU_SUBTYPE_ST40 bool select CPU_SH4 - select CPU_HAS_INTC2_IRQ config CPU_SHX2 bool diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 9f55c2dc1b5..a4086ea313c 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -6,24 +6,6 @@ extern atomic_t irq_err_count; -struct intc2_data { - unsigned short irq; - unsigned char ipr_offset, ipr_shift; - unsigned char msk_offset, msk_shift; - unsigned char priority; -}; - -struct intc2_desc { - unsigned long prio_base; - unsigned long msk_base; - unsigned long mskclr_base; - struct intc2_data *intc2_data; - unsigned int nr_irqs; - struct irq_chip chip; -}; - -void register_intc2_controller(struct intc2_desc *); - struct ipr_data { unsigned char irq; unsigned char ipr_idx; /* Index for the IPR registered */ -- cgit v1.2.3-70-g09d2 From fef96086270e8d3c99fb2bfc72eef94d95ab2240 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 8 Aug 2007 15:26:51 +0900 Subject: sh: x3proto: ILSEL IRQ support. This adds functionality for the on-board ILSEL IRQs that chain IRL mode events. Many on-board devices (ethernet, usb, etc.) rely on ILSEL IRQs directly. Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/x3proto/Makefile | 2 +- arch/sh/boards/renesas/x3proto/ilsel.c | 151 ++++++++++++++++++++++++++++++++ include/asm-sh/ilsel.h | 45 ++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 arch/sh/boards/renesas/x3proto/ilsel.c create mode 100644 include/asm-sh/ilsel.h (limited to 'include/asm-sh') diff --git a/arch/sh/boards/renesas/x3proto/Makefile b/arch/sh/boards/renesas/x3proto/Makefile index 2b9dba45893..983e4551fec 100644 --- a/arch/sh/boards/renesas/x3proto/Makefile +++ b/arch/sh/boards/renesas/x3proto/Makefile @@ -1 +1 @@ -obj-y += setup.o +obj-y += setup.o ilsel.o diff --git a/arch/sh/boards/renesas/x3proto/ilsel.c b/arch/sh/boards/renesas/x3proto/ilsel.c new file mode 100644 index 00000000000..ff9c7edf1b6 --- /dev/null +++ b/arch/sh/boards/renesas/x3proto/ilsel.c @@ -0,0 +1,151 @@ +/* + * arch/sh/boards/renesas/x3proto/ilsel.c + * + * Helper routines for SH-X3 proto board ILSEL. + * + * Copyright (C) 2007 Paul Mundt + * + * 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 +#include +#include +#include + +/* + * ILSEL is split across: + * + * ILSEL0 - 0xb8100004 [ Levels 1 - 4 ] + * ILSEL1 - 0xb8100006 [ Levels 5 - 8 ] + * ILSEL2 - 0xb8100008 [ Levels 9 - 12 ] + * ILSEL3 - 0xb810000a [ Levels 13 - 15 ] + * + * With each level being relative to an ilsel_source_t. + */ +#define ILSEL_BASE 0xb8100004 +#define ILSEL_LEVELS 15 + +/* + * ILSEL level map, in descending order from the highest level down. + * + * Supported levels are 1 - 15 spread across ILSEL0 - ILSEL4, mapping + * directly to IRLs. As the IRQs are numbered in reverse order relative + * to the interrupt level, the level map is carefully managed to ensure a + * 1:1 mapping between the bit position and the IRQ number. + * + * This careful constructions allows ilsel_enable*() to be referenced + * directly for hooking up an ILSEL set and getting back an IRQ which can + * subsequently be used for internal accounting in the (optional) disable + * path. + */ +static unsigned long ilsel_level_map; + +static inline unsigned int ilsel_offset(unsigned int bit) +{ + return ILSEL_LEVELS - bit - 1; +} + +static inline unsigned long mk_ilsel_addr(unsigned int bit) +{ + return ILSEL_BASE + ((ilsel_offset(bit) >> 1) & ~0x1); +} + +static inline unsigned int mk_ilsel_shift(unsigned int bit) +{ + return (ilsel_offset(bit) & 0x3) << 2; +} + +static void __ilsel_enable(ilsel_source_t set, unsigned int bit) +{ + unsigned int tmp, shift; + unsigned long addr; + + addr = mk_ilsel_addr(bit); + shift = mk_ilsel_shift(bit); + + pr_debug("%s: bit#%d: addr - 0x%08lx (shift %d, set %d)\n", + __FUNCTION__, bit, addr, shift, set); + + tmp = ctrl_inw(addr); + tmp &= ~(0xf << shift); + tmp |= set << shift; + ctrl_outw(tmp, addr); +} + +/** + * ilsel_enable - Enable an ILSEL set. + * @set: ILSEL source (see ilsel_source_t enum in include/asm-sh/ilsel.h). + * + * Enables a given non-aliased ILSEL source (<= ILSEL_KEY) at the highest + * available interrupt level. Callers should take care to order callsites + * noting descending interrupt levels. Aliasing FPGA and external board + * IRQs need to use ilsel_enable_fixed(). + * + * The return value is an IRQ number that can later be taken down with + * ilsel_disable(). + */ +int ilsel_enable(ilsel_source_t set) +{ + unsigned int bit; + + /* Aliased sources must use ilsel_enable_fixed() */ + BUG_ON(set > ILSEL_KEY); + + do { + bit = find_first_zero_bit(&ilsel_level_map, ILSEL_LEVELS); + } while (test_and_set_bit(bit, &ilsel_level_map)); + + __ilsel_enable(set, bit); + + return bit; +} +EXPORT_SYMBOL_GPL(ilsel_enable); + +/** + * ilsel_enable_fixed - Enable an ILSEL set at a fixed interrupt level + * @set: ILSEL source (see ilsel_source_t enum in include/asm-sh/ilsel.h). + * @level: Interrupt level (1 - 15) + * + * Enables a given ILSEL source at a fixed interrupt level. Necessary + * both for level reservation as well as for aliased sources that only + * exist on special ILSEL#s. + * + * Returns an IRQ number (as ilsel_enable()). + */ +int ilsel_enable_fixed(ilsel_source_t set, unsigned int level) +{ + unsigned int bit = ilsel_offset(level - 1); + + if (test_and_set_bit(bit, &ilsel_level_map)) + return -EBUSY; + + __ilsel_enable(set, bit); + + return bit; +} +EXPORT_SYMBOL_GPL(ilsel_enable_fixed); + +/** + * ilsel_disable - Disable an ILSEL set + * @irq: Bit position for ILSEL set value (retval from enable routines) + * + * Disable a previously enabled ILSEL set. + */ +void ilsel_disable(unsigned int irq) +{ + unsigned long addr; + unsigned int tmp; + + addr = mk_ilsel_addr(bit); + + tmp = ctrl_inw(addr); + tmp &= ~(0xf << mk_ilsel_shift(bit)); + ctrl_outw(tmp, addr); + + clear_bit(bit, &ilsel_level_map); +} +EXPORT_SYMBOL_GPL(ilsel_disable); diff --git a/include/asm-sh/ilsel.h b/include/asm-sh/ilsel.h new file mode 100644 index 00000000000..e3d304b280f --- /dev/null +++ b/include/asm-sh/ilsel.h @@ -0,0 +1,45 @@ +#ifndef __ASM_SH_ILSEL_H +#define __ASM_SH_ILSEL_H + +typedef enum { + ILSEL_NONE, + ILSEL_LAN, + ILSEL_USBH_I, + ILSEL_USBH_S, + ILSEL_USBH_V, + ILSEL_RTC, + ILSEL_USBP_I, + ILSEL_USBP_S, + ILSEL_USBP_V, + ILSEL_KEY, + + /* + * ILSEL Aliases - corner cases for interleaved level tables. + * + * Someone thought this was a good idea and less hassle than + * demuxing a shared vector, really. + */ + + /* ILSEL0 and 2 */ + ILSEL_FPGA0, + ILSEL_FPGA1, + ILSEL_EX1, + ILSEL_EX2, + ILSEL_EX3, + ILSEL_EX4, + + /* ILSEL1 and 3 */ + ILSEL_FPGA2 = ILSEL_FPGA0, + ILSEL_FPGA3 = ILSEL_FPGA1, + ILSEL_EX5 = ILSEL_EX1, + ILSEL_EX6 = ILSEL_EX2, + ILSEL_EX7 = ILSEL_EX3, + ILSEL_EX8 = ILSEL_EX4, +} ilsel_source_t; + +/* arch/sh/boards/renesas/x3proto/ilsel.c */ +int ilsel_enable(ilsel_source_t set); +int ilsel_enable_fixed(ilsel_source_t set, unsigned int level); +void ilsel_disable(unsigned int irq); + +#endif /* __ASM_SH_ILSEL_H */ -- cgit v1.2.3-70-g09d2 From dfc5ed2a939baf08f9385a8c6249b719cac63665 Mon Sep 17 00:00:00 2001 From: Markus Brunner Date: Mon, 20 Aug 2007 08:58:12 +0900 Subject: sh: Add gpio.h stubs for PFC definitions. This adds the PFC definitions for SH-3, as well as consolidating the gpio.h mess within sh-sci. Stub in sh64, as it's the odd one out between the sh-sci architectures (sh, sh64, h8300) in this capacity. Signed-off by: Markus Brunner Signed-off by: Mark Jonas Signed-off-by: Paul Mundt --- include/asm-sh/cpu-sh3/gpio.h | 66 +++++++++++++++++++++++++++++++++++++++++++ include/asm-sh/gpio.h | 19 +++++++++++++ include/asm-sh64/gpio.h | 8 ++++++ 3 files changed, 93 insertions(+) create mode 100644 include/asm-sh/cpu-sh3/gpio.h create mode 100644 include/asm-sh/gpio.h create mode 100644 include/asm-sh64/gpio.h (limited to 'include/asm-sh') diff --git a/include/asm-sh/cpu-sh3/gpio.h b/include/asm-sh/cpu-sh3/gpio.h new file mode 100644 index 00000000000..48770c1c7bd --- /dev/null +++ b/include/asm-sh/cpu-sh3/gpio.h @@ -0,0 +1,66 @@ +/* + * include/asm-sh/cpu-sh3/gpio.h + * + * Copyright (C) 2007 Markus Brunner, Mark Jonas + * + * Addresses for the Pin Function Controller + * + * 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. + */ +#ifndef _CPU_SH3_GPIO_H +#define _CPU_SH3_GPIO_H + +#if defined(CONFIG_CPU_SUBTYPE_SH7720) + +/* Control registers */ +#define PORT_PACR 0xA4050100UL +#define PORT_PBCR 0xA4050102UL +#define PORT_PCCR 0xA4050104UL +#define PORT_PDCR 0xA4050106UL +#define PORT_PECR 0xA4050108UL +#define PORT_PFCR 0xA405010AUL +#define PORT_PGCR 0xA405010CUL +#define PORT_PHCR 0xA405010EUL +#define PORT_PJCR 0xA4050110UL +#define PORT_PKCR 0xA4050112UL +#define PORT_PLCR 0xA4050114UL +#define PORT_PMCR 0xA4050116UL +#define PORT_PPCR 0xA4050118UL +#define PORT_PRCR 0xA405011AUL +#define PORT_PSCR 0xA405011CUL +#define PORT_PTCR 0xA405011EUL +#define PORT_PUCR 0xA4050120UL +#define PORT_PVCR 0xA4050122UL + +/* Data registers */ +#define PORT_PADR 0xA4050140UL +/* Address of PORT_PBDR is wrong in the datasheet, see errata 2005-09-21 */ +#define PORT_PBDR 0xA4050142UL +#define PORT_PCDR 0xA4050144UL +#define PORT_PDDR 0xA4050146UL +#define PORT_PEDR 0xA4050148UL +#define PORT_PFDR 0xA405014AUL +#define PORT_PGDR 0xA405014CUL +#define PORT_PHDR 0xA405014EUL +#define PORT_PJDR 0xA4050150UL +#define PORT_PKDR 0xA4050152UL +#define PORT_PLDR 0xA4050154UL +#define PORT_PMDR 0xA4050156UL +#define PORT_PPDR 0xA4050158UL +#define PORT_PRDR 0xA405015AUL +#define PORT_PSDR 0xA405015CUL +#define PORT_PTDR 0xA405015EUL +#define PORT_PUDR 0xA4050160UL +#define PORT_PVDR 0xA4050162UL + +/* Pin Select Registers */ +#define PORT_PSELA 0xA4050124UL +#define PORT_PSELB 0xA4050126UL +#define PORT_PSELC 0xA4050128UL +#define PORT_PSELD 0xA405012AUL + +#endif + +#endif diff --git a/include/asm-sh/gpio.h b/include/asm-sh/gpio.h new file mode 100644 index 00000000000..9bb27e0f11a --- /dev/null +++ b/include/asm-sh/gpio.h @@ -0,0 +1,19 @@ +/* + * include/asm-sh/gpio.h + * + * Copyright (C) 2007 Markus Brunner, Mark Jonas + * + * Addresses for the Pin Function Controller + * + * 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. + */ +#ifndef __ASM_SH_GPIO_H +#define __ASM_SH_GPIO_H + +#if defined(CONFIG_CPU_SH3) +#include +#endif + +#endif /* __ASM_SH_GPIO_H */ diff --git a/include/asm-sh64/gpio.h b/include/asm-sh64/gpio.h new file mode 100644 index 00000000000..6bc5a13d841 --- /dev/null +++ b/include/asm-sh64/gpio.h @@ -0,0 +1,8 @@ +#ifndef __ASM_SH64_GPIO_H +#define __ASM_SH64_GPIO_H + +/* + * This is just a stub, so that every arch using sh-sci has a gpio.h + */ + +#endif /* __ASM_SH64_GPIO_H */ -- cgit v1.2.3-70-g09d2 From 3ea6bc3de4f15fcae84fb31eeea4d420685a3da2 Mon Sep 17 00:00:00 2001 From: Markus Brunner Date: Mon, 20 Aug 2007 08:59:33 +0900 Subject: sh: Add SH7720 CPU support. This adds support for the SH7720 (SH3-DSP) CPU. Signed-off by: Markus Brunner Signed-off by: Mark Jonas Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 1 + arch/sh/drivers/dma/Kconfig | 1 + arch/sh/drivers/dma/dma-sh.c | 12 +- arch/sh/kernel/cpu/sh3/Makefile | 2 + arch/sh/kernel/cpu/sh3/probe.c | 3 + arch/sh/kernel/cpu/sh3/setup-sh7720.c | 210 ++++++++++++++++++++++++++++++++++ arch/sh/kernel/early_printk.c | 38 +++++- arch/sh/kernel/setup.c | 2 +- arch/sh/kernel/timers/timer-tmu.c | 3 +- arch/sh/mm/Kconfig | 8 ++ drivers/serial/sh-sci.c | 33 ++++++ drivers/serial/sh-sci.h | 33 ++++-- include/asm-sh/cpu-sh3/cache.h | 4 +- include/asm-sh/cpu-sh3/dma.h | 13 +++ include/asm-sh/cpu-sh3/mmu_context.h | 9 +- include/asm-sh/cpu-sh3/timer.h | 9 +- include/asm-sh/cpu-sh3/ubc.h | 3 +- include/asm-sh/processor.h | 2 +- 18 files changed, 359 insertions(+), 27 deletions(-) create mode 100644 arch/sh/kernel/cpu/sh3/setup-sh7720.c (limited to 'include/asm-sh') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 6eb31bcc1e2..c870f5fdef3 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -34,6 +34,7 @@ config EARLY_SCIF_CONSOLE_PORT default "0xfffe9800" if CPU_SUBTYPE_SH7206 default "0xf8420000" if CPU_SUBTYPE_SH7619 default "0xa4400000" if CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7705 + default "0xa4430000" if CPU_SUBTYPE_SH7720 default "0xffc30000" if CPU_SUBTYPE_SHX3 default "0xffe80000" if CPU_SH4 default "0x00000000" diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig index ee711431e50..4e711a0c3da 100644 --- a/arch/sh/drivers/dma/Kconfig +++ b/arch/sh/drivers/dma/Kconfig @@ -12,6 +12,7 @@ config SH_DMA config NR_ONCHIP_DMA_CHANNELS int depends on SH_DMA + default "6" if CPU_SUBTYPE_SH7720 default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R default "12" if CPU_SUBTYPE_SH7780 default "4" diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 06ed0609a95..6e5f16cb0aa 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -24,13 +24,18 @@ static int dmte_irq_map[] = { DMTE1_IRQ, DMTE2_IRQ, DMTE3_IRQ, -#if defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ +#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ + defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ defined(CONFIG_CPU_SUBTYPE_SH7760) || \ defined(CONFIG_CPU_SUBTYPE_SH7780) DMTE4_IRQ, DMTE5_IRQ, +#endif +#if defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ + defined(CONFIG_CPU_SUBTYPE_SH7760) || \ + defined(CONFIG_CPU_SUBTYPE_SH7780) DMTE6_IRQ, - DMTE7_IRQ, + DMTE7_IRQ, #endif }; @@ -196,7 +201,8 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan) return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan); } -#ifdef CONFIG_CPU_SUBTYPE_SH7780 +#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ + defined(CONFIG_CPU_SUBTYPE_SH7780) #define dmaor_read_reg() ctrl_inw(DMAOR) #define dmaor_write_reg(data) ctrl_outw(data, DMAOR) #else diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index cd2a35270e3..646eb693361 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh770x.o obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh770x.o obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o obj-$(CONFIG_CPU_SUBTYPE_SH7712) += setup-sh7710.o +obj-$(CONFIG_CPU_SUBTYPE_SH7720) += setup-sh7720.o # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SH3) := clock-sh3.o @@ -19,5 +20,6 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o +clock-$(CONFIG_CPU_SUBTYPE_SH7720) := clock-sh7710.o obj-y += $(clock-y) diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index 647623b22ed..1a66cf636a9 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -81,6 +81,9 @@ int __init detect_cpu_and_cache_system(void) #if defined(CONFIG_CPU_SUBTYPE_SH7712) current_cpu_data.type = CPU_SH7712; #endif +#if defined(CONFIG_CPU_SUBTYPE_SH7720) + current_cpu_data.type = CPU_SH7720; +#endif #if defined(CONFIG_CPU_SUBTYPE_SH7705) current_cpu_data.type = CPU_SH7705; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c new file mode 100644 index 00000000000..a0929b8a95a --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -0,0 +1,210 @@ +/* + * SH7720 Setup + * + * Copyright (C) 2007 Markus Brunner, Mark Jonas + * + * Based on arch/sh/kernel/cpu/sh4/setup-sh7750.c: + * + * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2006 Jamie Lenehan + * + * 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 +#include +#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, + .end = 0xa413fec0 + 0x28 - 1, + .flags = IORESOURCE_IO, + }, + [1] = { + /* Period IRQ */ + .start = 21, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* Carry IRQ */ + .start = 22, + .flags = IORESOURCE_IRQ, + }, + [3] = { + /* Alarm IRQ */ + .start = 20, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct sh_rtc_platform_info rtc_info = { + .capabilities = RTC_CAP_4_DIGIT_YEAR, +}; + +static struct platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, + .dev = { + .platform_data = &rtc_info, + }, +}; + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xa4430000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 80, 80, 80 }, + }, { + .mapbase = 0xa4438000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 81, 81, 81, 81 }, + }, { + + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7720_devices[] __initdata = { + &rtc_device, + &sci_device, +}; + +static int __init sh7720_devices_setup(void) +{ + return platform_add_devices(sh7720_devices, + ARRAY_SIZE(sh7720_devices)); +} +__initcall(sh7720_devices_setup); + +enum { + UNUSED = 0, + + /* interrupt sources */ + TMU0, TMU1, TMU2, RTC_ATI, RTC_PRI, RTC_CUI, + WDT, REF_RCMI, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND, + IRQ0, IRQ1, IRQ2, IRQ3, + USBF_SPD, TMU_SUNI, IRQ5, IRQ4, + DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3, LCDC, SSL, + ADC, DMAC2_DEI4, DMAC2_DEI5, USBFI0, USBFI1, CMT, + SCIF0, SCIF1, + PINT07, PINT815, TPU0, TPU1, TPU2, TPU3, IIC, + SIOF0, SIOF1, MMCI0, MMCI1, MMCI2, MMCI3, PCC, + USBHI, AFEIF, + H_UDI, + /* interrupt groups */ + TMU, RTC, SIM, DMAC1, USBFI, DMAC2, USB, TPU, MMC, +}; + +static struct intc_vect vectors[] __initdata = { + 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), + INTC_VECT(SIM_ERI, 0x4e0), INTC_VECT(SIM_RXI, 0x500), + INTC_VECT(SIM_TXI, 0x520), INTC_VECT(SIM_TEND, 0x540), + INTC_VECT(WDT, 0x560), INTC_VECT(REF_RCMI, 0x580), + /* H_UDI cannot be masked */ INTC_VECT(TMU_SUNI, 0x6c0), + INTC_VECT(USBF_SPD, 0x6e0), INTC_VECT(DMAC1_DEI0, 0x800), + INTC_VECT(DMAC1_DEI1, 0x820), INTC_VECT(DMAC1_DEI2, 0x840), + INTC_VECT(DMAC1_DEI3, 0x860), INTC_VECT(LCDC, 0x900), + INTC_VECT(SSL, 0x980), INTC_VECT(USBFI0, 0xa20), + INTC_VECT(USBFI1, 0xa40), INTC_VECT(USBHI, 0xa60), + INTC_VECT(DMAC2_DEI4, 0xb80), INTC_VECT(DMAC2_DEI5, 0xba0), + INTC_VECT(ADC, 0xbe0), INTC_VECT(SCIF0, 0xc00), + INTC_VECT(SCIF1, 0xc20), INTC_VECT(PINT07, 0xc80), + INTC_VECT(PINT815, 0xca0), INTC_VECT(SIOF0, 0xd00), + INTC_VECT(SIOF1, 0xd20), INTC_VECT(TPU0, 0xd80), + INTC_VECT(TPU1, 0xda0), INTC_VECT(TPU2, 0xdc0), + INTC_VECT(TPU3, 0xde0), INTC_VECT(IIC, 0xe00), + INTC_VECT(MMCI0, 0xe80), INTC_VECT(MMCI1, 0xea0), + INTC_VECT(MMCI2, 0xec0), INTC_VECT(MMCI3, 0xee0), + INTC_VECT(CMT, 0xf00), INTC_VECT(PCC, 0xf60), + INTC_VECT(AFEIF, 0xfe0), +}; + +static struct intc_group groups[] __initdata = { + INTC_GROUP(TMU, TMU0, TMU1, TMU2), + INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), + INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEND), + INTC_GROUP(DMAC1, DMAC1_DEI0, DMAC1_DEI1, DMAC1_DEI2, DMAC1_DEI3), + INTC_GROUP(USBFI, USBFI0, USBFI1), + INTC_GROUP(DMAC2, DMAC2_DEI4, DMAC2_DEI5), + INTC_GROUP(TPU, TPU0, TPU1, TPU2, TPU3), + INTC_GROUP(MMC, MMCI0, MMCI1, MMCI2, MMCI3), +}; + +static struct intc_prio priorities[] __initdata = { + INTC_PRIO(SCIF0, 2), + INTC_PRIO(SCIF1, 2), + INTC_PRIO(DMAC1, 1), + INTC_PRIO(DMAC2, 1), + INTC_PRIO(RTC, 2), + INTC_PRIO(TMU, 2), + INTC_PRIO(TPU, 2), +}; + +static struct intc_prio_reg prio_registers[] __initdata = { + { 0xA414FEE2UL, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, + { 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 } }, + { 0xA414001AUL, 0, 16, 4, /* IPRE */ { DMAC1, 0, LCDC, SSL } }, + { 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 } }, + { 0xA4080006UL, 0, 16, 4, /* IPRI */ { SIOF0, SIOF1, MMC, PCC } }, + { 0xA4080008UL, 0, 16, 4, /* IPRJ */ { 0, USBHI, 0, AFEIF } }, +}; + +static DECLARE_INTC_DESC(intc_desc, "sh7720", vectors, groups, + priorities, 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, priorities, 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); +} diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 80b637c3020..85ed5b7ef27 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef CONFIG_SH_STANDARD_BIOS #include @@ -62,6 +63,18 @@ static struct console bios_console = { #include #include "../../../drivers/serial/sh-sci.h" +#if defined(CONFIG_CPU_SUBTYPE_SH7720) +#define EPK_SCSMR_VALUE 0x000 +#define EPK_SCBRR_VALUE 0x00C +#define EPK_FIFO_SIZE 64 +#define EPK_FIFO_BITS (0x7f00 >> 8) +#else +#define EPK_FIFO_SIZE 16 +#define EPK_FIFO_BITS (0x1f00 >> 8) +#endif + + + static struct uart_port scif_port = { .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT, .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT, @@ -69,7 +82,7 @@ static struct uart_port scif_port = { static void scif_sercon_putc(int c) { - while (((sci_in(&scif_port, SCFDR) & 0x1f00 >> 8) == 16)) + while (((sci_in(&scif_port, SCFDR) & EPK_FIFO_BITS) >= EPK_FIFO_SIZE)) ; sci_out(&scif_port, SCxTDR, c); @@ -105,7 +118,22 @@ static struct console scif_console = { .index = -1, }; -#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) +#if !defined(CONFIG_SH_STANDARD_BIOS) +#if defined(CONFIG_CPU_SUBTYPE_SH7720) +static void scif_sercon_init(char *s) +{ + sci_out(&scif_port, SCSCR, 0x0000); /* clear TE and RE */ + sci_out(&scif_port, SCFCR, 0x4006); /* reset */ + sci_out(&scif_port, SCSCR, 0x0000); /* select internal clock */ + sci_out(&scif_port, SCSMR, EPK_SCSMR_VALUE); + sci_out(&scif_port, SCBRR, EPK_SCBRR_VALUE); + + mdelay(1); /* wait 1-bit time */ + + sci_out(&scif_port, SCFCR, 0x0030); /* TTRG=b'11 */ + sci_out(&scif_port, SCSCR, 0x0030); /* TE, RE */ +} +#elif defined(CONFIG_CPU_SH4) #define DEFAULT_BAUD 115200 /* * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4 @@ -146,7 +174,8 @@ static void scif_sercon_init(char *s) ctrl_outw(0, scif_port.mapbase + 36); ctrl_outw(0x30, scif_port.mapbase + 8); } -#endif /* CONFIG_CPU_SH4 && !CONFIG_SH_STANDARD_BIOS */ +#endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */ +#endif /* !defined(CONFIG_SH_STANDARD_BIOS) */ #endif /* CONFIG_EARLY_SCIF_CONSOLE */ /* @@ -186,7 +215,8 @@ int __init setup_early_printk(char *buf) if (!strncmp(buf, "serial", 6)) { early_console = &scif_console; -#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) +#if (defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720)) && \ + !defined(CONFIG_SH_STANDARD_BIOS) scif_sercon_init(buf + 6); #endif } diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 2cf7dec0d69..e0e655cba89 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -279,7 +279,7 @@ static const char *cpu_name[] = { [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", - [CPU_SH7712] = "SH7712", + [CPU_SH7712] = "SH7712", [CPU_SH7720] = "SH7720", [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R", [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R", diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index 8a545d54e2d..628ec9a15e3 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -173,7 +173,8 @@ static int tmu_timer_init(void) tmu_timer_stop(); -#if !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ +#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \ + !defined(CONFIG_CPU_SUBTYPE_SH7760) && \ !defined(CONFIG_CPU_SUBTYPE_SH7785) && \ !defined(CONFIG_CPU_SUBTYPE_SHX3) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index e5801d9aac3..5487b99d4f6 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -111,6 +111,14 @@ config CPU_SUBTYPE_SH7712 help Select SH7712 if you have a SH3-DSP SH7712 CPU. +config CPU_SUBTYPE_SH7720 + bool "Support SH7720 processor" + select CPU_SH3 + select CPU_HAS_INTC_IRQ + select CPU_HAS_DSP + help + Select SH7720 if you have a SH3-DSP SH7720 CPU. + # SH-4 Processor Support config CPU_SUBTYPE_SH7750 diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index e4abd3a7998..81318c580e2 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -4,6 +4,7 @@ * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO) * * Copyright (C) 2002 - 2006 Paul Mundt + * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007). * * based off of the old drivers/char/sh-sci.c by: * @@ -301,6 +302,38 @@ static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag) } sci_out(port, SCFCR, fcr_val); } +#elif defined(CONFIG_CPU_SUBTYPE_SH7720) +static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) +{ + unsigned int fcr_val = 0; + unsigned short data; + + if (cflag & CRTSCTS) { + /* enable RTS/CTS */ + if (port->mapbase == 0xa4430000) { /* SCIF0 */ + /* Clear PTCR bit 9-2; enable all scif pins but sck */ + data = ctrl_inw(PORT_PTCR); + ctrl_outw((data & 0xfc03), PORT_PTCR); + } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ + /* Clear PVCR bit 9-2 */ + data = ctrl_inw(PORT_PVCR); + ctrl_outw((data & 0xfc03), PORT_PVCR); + } + fcr_val |= SCFCR_MCE; + } else { + if (port->mapbase == 0xa4430000) { /* SCIF0 */ + /* Clear PTCR bit 5-2; enable only tx and rx */ + data = ctrl_inw(PORT_PTCR); + ctrl_outw((data & 0xffc3), PORT_PTCR); + } else if (port->mapbase == 0xa4438000) { /* SCIF1 */ + /* Clear PVCR bit 5-2 */ + data = ctrl_inw(PORT_PVCR); + ctrl_outw((data & 0xffc3), PORT_PVCR); + } + } + sci_out(port, SCFCR, fcr_val); +} + #elif defined(CONFIG_CPU_SH3) /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag) diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 941c504fe80..e89ae29645d 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -10,19 +10,19 @@ * Modified to support SH7300(SH-Mobile) SCIF. Takashi Kusuda (Jun 2003). * Modified to support H8/300 Series Yoshinori Sato (Feb 2004). * Removed SH7300 support (Jul 2007). + * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Aug 2007). */ #include #include -#if defined(__H8300H__) || defined(__H8300S__) #include + #if defined(CONFIG_H83007) || defined(CONFIG_H83068) #include #endif #if defined(CONFIG_H8S2678) #include #endif -#endif #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7707) || \ @@ -46,6 +46,10 @@ */ # define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0 # define SCIF_ONLY +#elif defined(CONFIG_CPU_SUBTYPE_SH7720) +# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ +# define SCIF_ONLY +#define SCIF_ORER 0x0200 /* overrun error bit */ #elif defined(CONFIG_SH_RTS7751R2D) # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ @@ -217,7 +221,8 @@ #define SCIF_RDF 0x0002 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */ #define SCIF_DR 0x0001 /* 7705 SCIF, 7707 SCIF, 7709 SCIF, 7750 SCIF */ -#if defined(CONFIG_CPU_SUBTYPE_SH7705) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7720) #define SCIF_ORER 0x0200 #define SCIF_ERRORS ( SCIF_PER | SCIF_FER | SCIF_ER | SCIF_BRK | SCIF_ORER) #define SCIF_RFDC_MASK 0x007f @@ -254,7 +259,8 @@ # define SCxSR_FER(port) SCIF_FER # define SCxSR_PER(port) SCIF_PER # define SCxSR_BRK(port) SCIF_BRK -#if defined(CONFIG_CPU_SUBTYPE_SH7705) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7720) # define SCxSR_RDxF_CLEAR(port) (sci_in(port,SCxSR)&0xfffc) # define SCxSR_ERROR_CLEAR(port) (sci_in(port,SCxSR)&0xfd73) # define SCxSR_TDxE_CLEAR(port) (sci_in(port,SCxSR)&0xffdf) @@ -362,7 +368,8 @@ CPU_SCIx_FNS(name, sh4_sci_offset, sh4_sci_size, sh4_scif_offset, sh4_scif_size) #define SCIF_FNS(name, sh3_scif_offset, sh3_scif_size, sh4_scif_offset, sh4_scif_size) \ CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) -#elif defined(CONFIG_CPU_SUBTYPE_SH7705) +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7720) #define SCIF_FNS(name, scif_offset, scif_size) \ CPU_SCIF_FNS(name, scif_offset, scif_size) #else @@ -388,7 +395,8 @@ CPU_SCIF_FNS(name, sh4_scif_offset, sh4_scif_size) #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7705) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7720) SCIF_FNS(SCSMR, 0x00, 16) SCIF_FNS(SCBRR, 0x04, 8) @@ -510,7 +518,15 @@ static inline void set_sh771x_scif_pfc(struct uart_port *port) return; } } - +#elif defined(CONFIG_CPU_SUBTYPE_SH7720) +static inline int sci_rxd_in(struct uart_port *port) +{ + if (port->mapbase == 0xa4430000) + return sci_in(port, SCxSR) & 0x0003 ? 1 : 0; + else if (port->mapbase == 0xa4438000) + return sci_in(port, SCxSR) & 0x0003 ? 1 : 0; + return 1; +} #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ defined(CONFIG_CPU_SUBTYPE_SH7751) || \ defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ @@ -692,7 +708,8 @@ static inline int sci_rxd_in(struct uart_port *port) #if defined(CONFIG_CPU_SUBTYPE_SH7780) || \ defined(CONFIG_CPU_SUBTYPE_SH7785) #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) -#elif defined(CONFIG_CPU_SUBTYPE_SH7705) +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7720) #define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) #elif defined(__H8300H__) || defined(__H8300S__) #define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1) diff --git a/include/asm-sh/cpu-sh3/cache.h b/include/asm-sh/cpu-sh3/cache.h index ffe08d2813f..255016fc91f 100644 --- a/include/asm-sh/cpu-sh3/cache.h +++ b/include/asm-sh/cpu-sh3/cache.h @@ -26,7 +26,9 @@ #define CCR_CACHE_ENABLE CCR_CACHE_CE #define CCR_CACHE_INVALIDATE CCR_CACHE_CF -#if defined(CONFIG_CPU_SUBTYPE_SH7705) || defined(CONFIG_CPU_SUBTYPE_SH7710) +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7710) || \ + defined(CONFIG_CPU_SUBTYPE_SH7720) #define CCR3 0xa40000b4 #define CCR_CACHE_16KB 0x00010000 #define CCR_CACHE_32KB 0x00020000 diff --git a/include/asm-sh/cpu-sh3/dma.h b/include/asm-sh/cpu-sh3/dma.h index 3a66dc45802..e56203086eb 100644 --- a/include/asm-sh/cpu-sh3/dma.h +++ b/include/asm-sh/cpu-sh3/dma.h @@ -1,7 +1,20 @@ #ifndef __ASM_CPU_SH3_DMA_H #define __ASM_CPU_SH3_DMA_H + +#if defined(CONFIG_CPU_SUBTYPE_SH7720) +#define SH_DMAC_BASE 0xa4010020 + +#define DMTE0_IRQ 48 +#define DMTE1_IRQ 49 +#define DMTE2_IRQ 50 +#define DMTE3_IRQ 51 +#define DMTE4_IRQ 76 +#define DMTE5_IRQ 77 + +#else #define SH_DMAC_BASE 0xa4000020 +#endif /* Definitions for the SuperH DMAC */ #define TM_BURST 0x00000020 diff --git a/include/asm-sh/cpu-sh3/mmu_context.h b/include/asm-sh/cpu-sh3/mmu_context.h index b20786d42d0..16c2d63b7e3 100644 --- a/include/asm-sh/cpu-sh3/mmu_context.h +++ b/include/asm-sh/cpu-sh3/mmu_context.h @@ -27,12 +27,13 @@ #define TRA 0xffffffd0 #define EXPEVT 0xffffffd4 -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ - defined(CONFIG_CPU_SUBTYPE_SH7709) || \ +#if defined(CONFIG_CPU_SUBTYPE_SH7705) || \ defined(CONFIG_CPU_SUBTYPE_SH7706) || \ - defined(CONFIG_CPU_SUBTYPE_SH7705) || \ + defined(CONFIG_CPU_SUBTYPE_SH7707) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7710) || \ defined(CONFIG_CPU_SUBTYPE_SH7712) || \ - defined(CONFIG_CPU_SUBTYPE_SH7710) + defined(CONFIG_CPU_SUBTYPE_SH7720) #define INTEVT 0xa4000000 /* INTEVTE2(0xa4000000) */ #else #define INTEVT 0xffffffd8 diff --git a/include/asm-sh/cpu-sh3/timer.h b/include/asm-sh/cpu-sh3/timer.h index b6c2020a2ad..3880ce047fe 100644 --- a/include/asm-sh/cpu-sh3/timer.h +++ b/include/asm-sh/cpu-sh3/timer.h @@ -23,11 +23,13 @@ * --------------------------------------------------------------------------- */ -#if !defined(CONFIG_CPU_SUBTYPE_SH7727) +#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \ + !defined(CONFIG_CPU_SUBTYPE_SH7727) #define TMU_TOCR 0xfffffe90 /* Byte access */ #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7710) +#if defined(CONFIG_CPU_SUBTYPE_SH7710) || \ + defined(CONFIG_CPU_SUBTYPE_SH7720) #define TMU_012_TSTR 0xa412fe92 /* Byte access */ #define TMU0_TCOR 0xa412fe94 /* Long access */ @@ -56,7 +58,8 @@ #define TMU2_TCOR 0xfffffeac /* Long access */ #define TMU2_TCNT 0xfffffeb0 /* Long access */ #define TMU2_TCR 0xfffffeb4 /* Word access */ -#if !defined(CONFIG_CPU_SUBTYPE_SH7727) +#if !defined(CONFIG_CPU_SUBTYPE_SH7720) && \ + !defined(CONFIG_CPU_SUBTYPE_SH7727) #define TMU2_TCPR2 0xfffffeb8 /* Long access */ #endif #endif diff --git a/include/asm-sh/cpu-sh3/ubc.h b/include/asm-sh/cpu-sh3/ubc.h index 9d308cbe9b2..18467c57453 100644 --- a/include/asm-sh/cpu-sh3/ubc.h +++ b/include/asm-sh/cpu-sh3/ubc.h @@ -11,7 +11,8 @@ #ifndef __ASM_CPU_SH3_UBC_H #define __ASM_CPU_SH3_UBC_H -#if defined(CONFIG_CPU_SUBTYPE_SH7710) +#if defined(CONFIG_CPU_SUBTYPE_SH7710) || \ + defined(CONFIG_CPU_SUBTYPE_SH7720) #define UBC_BARA 0xa4ffffb0 #define UBC_BAMRA 0xa4ffffb4 #define UBC_BBRA 0xa4ffffb8 diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 26d52174f4b..56cb3c89f84 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -45,7 +45,7 @@ enum cpu_type { CPU_SH7705, CPU_SH7706, CPU_SH7707, CPU_SH7708, CPU_SH7708S, CPU_SH7708R, CPU_SH7709, CPU_SH7709A, CPU_SH7710, CPU_SH7712, - CPU_SH7729, + CPU_SH7720, CPU_SH7729, /* SH-4 types */ CPU_SH7750, CPU_SH7750S, CPU_SH7750R, CPU_SH7751, CPU_SH7751R, -- cgit v1.2.3-70-g09d2 From 6ef5fb2cfcedaab4a43493c8f2305a67c0ce1af6 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Sun, 12 Aug 2007 15:22:02 +0900 Subject: sh: intc - add a clear register to struct intc_prio_reg We need a secondary register member in struct intc_prio_reg to support dual priority registers used by ipi on x3. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/intc.c | 8 ++++---- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 16 ++++++++-------- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 20 ++++++++++---------- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 14 +++++++------- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 22 +++++++++++----------- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 26 +++++++++++++------------- arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 24 +++++++++++++----------- arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 29 ++++++++++++++++------------- arch/sh/kernel/cpu/sh4a/setup-shx3.c | 25 ++++++++++++++----------- include/asm-sh/hw_irq.h | 2 +- 11 files changed, 105 insertions(+), 97 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index 56819409a36..24a8d554799 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -59,14 +59,14 @@ static inline unsigned int set_prio_field(struct intc_desc *desc, static void disable_prio_16(struct intc_desc *desc, unsigned int data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; + unsigned long addr = _INTC_PTR(desc, prio_regs, data)->set_reg; ctrl_outw(set_prio_field(desc, ctrl_inw(addr), 0, data), addr); } static void enable_prio_16(struct intc_desc *desc, unsigned int data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; + unsigned long addr = _INTC_PTR(desc, prio_regs, data)->set_reg; unsigned int prio = _INTC_VALUE(data); ctrl_outw(set_prio_field(desc, ctrl_inw(addr), prio, data), addr); @@ -74,14 +74,14 @@ static void enable_prio_16(struct intc_desc *desc, unsigned int data) static void disable_prio_32(struct intc_desc *desc, unsigned int data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; + unsigned long addr = _INTC_PTR(desc, prio_regs, data)->set_reg; ctrl_outl(set_prio_field(desc, ctrl_inl(addr), 0, data), addr); } static void enable_prio_32(struct intc_desc *desc, unsigned int data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->reg; + unsigned long addr = _INTC_PTR(desc, prio_regs, data)->set_reg; unsigned int prio = _INTC_VALUE(data); ctrl_outl(set_prio_field(desc, ctrl_inl(addr), prio, data), addr); diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 568cc08c254..a1b342e170c 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -73,14 +73,14 @@ static struct intc_prio priorities[] = { }; static struct intc_prio_reg prio_registers[] = { - { 0xfffffee2, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, - { 0xfffffee4, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } }, - { 0xa4000016, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, - { 0xa4000018, 16, 4, /* IPRD */ { PINT07, PINT815, IRQ5, IRQ4 } }, - { 0xa400001a, 16, 4, /* IPRE */ { DMAC, SCIF0, SCIF2, ADC_ADI } }, - { 0xa4080000, 16, 4, /* IPRF */ { 0, 0, USB } }, - { 0xa4080002, 16, 4, /* IPRG */ { TPU0, TPU1 } }, - { 0xa4080004, 16, 4, /* IPRH */ { TPU2, TPU3 } }, + { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, + { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } }, + { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, + { 0xa4000018, 0, 16, 4, /* IPRD */ { PINT07, PINT815, IRQ5, IRQ4 } }, + { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC, SCIF0, SCIF2, ADC_ADI } }, + { 0xa4080000, 0, 16, 4, /* IPRF */ { 0, 0, USB } }, + { 0xa4080002, 0, 16, 4, /* IPRG */ { TPU0, TPU1 } }, + { 0xa4080004, 0, 16, 4, /* IPRH */ { TPU2, TPU3 } }, }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index eef505b43f0..2980c44ffb2 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -89,22 +89,22 @@ static struct intc_prio priorities[] = { }; static struct intc_prio_reg prio_registers[] = { - { 0xfffffee2, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, - { 0xfffffee4, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } }, + { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, + { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } }, #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) - { 0xa4000016, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, - { 0xa4000018, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, - { 0xa400001a, 16, 4, /* IPRE */ { DMAC, 0, SCIF2, ADC_ADI } }, + { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, + { 0xa4000018, 0, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, + { 0xa400001a, 0, 16, 4, /* IPRE */ { DMAC, 0, SCIF2, ADC_ADI } }, #endif #if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) - { 0xa4000018, 16, 4, /* IPRD */ { PINT07, PINT815, } }, - { 0xa400001a, 16, 4, /* IPRE */ { 0, SCIF0 } }, + { 0xa4000018, 0, 16, 4, /* IPRD */ { PINT07, PINT815, } }, + { 0xa400001a, 0, 16, 4, /* IPRE */ { 0, SCIF0 } }, #endif #if defined(CONFIG_CPU_SUBTYPE_SH7707) - { 0xa400001c, 16, 4, /* IPRF */ { 0, LCDC, PCC0, PCC1, } }, + { 0xa400001c, 0, 16, 4, /* IPRF */ { 0, LCDC, PCC0, PCC1, } }, #endif }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index eb55ac9dbf7..5aa77710e42 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -86,18 +86,18 @@ static struct intc_prio priorities[] = { }; static struct intc_prio_reg prio_registers[] = { - { 0xfffffee2, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, - { 0xfffffee4, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } }, - { 0xa4000016, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, - { 0xa4000018, 16, 4, /* IPRD */ { 0, 0, IRQ5, IRQ4 } }, - { 0xa400001a, 16, 4, /* IPRE */ { DMAC1, SCIF0, SCIF1 } }, - { 0xa4080000, 16, 4, /* IPRF */ { 0, DMAC2 } }, + { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, + { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } }, + { 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, 16, 4, /* IPRF */ { IPSEC } }, + { 0xa4080000, 0, 16, 4, /* IPRF */ { IPSEC } }, #endif - { 0xa4080002, 16, 4, /* IPRG */ { EDMAC0, EDMAC1, EDMAC2 } }, - { 0xa4080004, 16, 4, /* IPRH */ { 0, 0, 0, SIOF0 } }, - { 0xa4080006, 16, 4, /* IPRI */ { 0, 0, SIOF1 } }, + { 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 } }, }; static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index e313be24984..062c3c1b243 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -133,13 +133,13 @@ static struct intc_prio priorities[] = { }; static struct intc_prio_reg prio_registers[] = { - { 0xffd00004, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, - { 0xffd00008, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } }, - { 0xffd0000c, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } }, - { 0xffd00010, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, - { 0xfe080000, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0, - TMU4, TMU3, - PCIC1, PCIC0_PCISERR } }, + { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, + { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } }, + { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } }, + { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, + { 0xfe080000, 0, 32, 4, /* INTPRI00 */ { 0, 0, 0, 0, + TMU4, TMU3, + PCIC1, PCIC0_PCISERR } }, }; static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups, diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 6a6686d71fb..6b4e48cbe7f 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -118,17 +118,17 @@ static struct intc_mask_reg mask_registers[] = { }; static struct intc_prio_reg prio_registers[] = { - { 0xffd00004, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2 } }, - { 0xffd00008, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } }, - { 0xffd0000c, 16, 4, /* IPRC */ { GPIOI, DMAC, 0, HUDI } }, - { 0xffd00010, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, - { 0xfe080000, 32, 4, /* INTPRI00 */ { IRQ4, IRQ5, IRQ6, IRQ7 } }, - { 0xfe080004, 32, 4, /* INTPRI04 */ { HCAN20, HCAN21, SSI0, SSI1, - HAC0, HAC1, I2C0, I2C1 } }, - { 0xfe080008, 32, 4, /* INTPRI08 */ { USB, LCDC, DMABRG, SCIF0, - SCIF1, SCIF2, SIM, HSPI } }, - { 0xfe08000c, 32, 4, /* INTPRI0C */ { 0, 0, MMCIF, 0, - MFI, 0, ADC, CMT } }, + { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2 } }, + { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } }, + { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, 0, HUDI } }, + { 0xffd00010, 0, 16, 4, /* IPRD */ { IRL0, IRL1, IRL2, IRL3 } }, + { 0xfe080000, 0, 32, 4, /* INTPRI00 */ { IRQ4, IRQ5, IRQ6, IRQ7 } }, + { 0xfe080004, 0, 32, 4, /* INTPRI04 */ { HCAN20, HCAN21, SSI0, SSI1, + HAC0, HAC1, I2C0, I2C1 } }, + { 0xfe080008, 0, 32, 4, /* INTPRI08 */ { USB, LCDC, DMABRG, SCIF0, + SCIF1, SCIF2, SIM, HSPI } }, + { 0xfe08000c, 0, 32, 4, /* INTPRI0C */ { 0, 0, MMCIF, 0, + MFI, 0, ADC, CMT } }, }; static DECLARE_INTC_DESC(intc_desc, "sh7760", vectors, groups, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 25b913e07e2..ae63635cf1e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -169,19 +169,19 @@ static struct intc_mask_reg mask_registers[] = { }; static struct intc_prio_reg prio_registers[] = { - { 0xa4080000, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } }, - { 0xa4080004, 16, 4, /* IPRB */ { JPU, LCDC, SIM } }, - { 0xa4080008, 16, 4, /* IPRC */ { } }, - { 0xa408000c, 16, 4, /* IPRD */ { } }, - { 0xa4080010, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } }, - { 0xa4080014, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } }, - { 0xa4080018, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } }, - { 0xa408001c, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } }, - { 0xa4080020, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } }, - { 0xa4080024, 16, 4, /* IPRJ */ { 0, 0, SIU } }, - { 0xa4080028, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } }, - { 0xa408002c, 16, 4, /* IPRL */ { TWODG, 0, TPU } }, - { 0xa4140010, 32, 4, /* INTPRI00 */ + { 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } }, + { 0xa4080004, 0, 16, 4, /* IPRB */ { JPU, LCDC, SIM } }, + { 0xa4080008, 0, 16, 4, /* IPRC */ { } }, + { 0xa408000c, 0, 16, 4, /* IPRD */ { } }, + { 0xa4080010, 0, 16, 4, /* IPRE */ { DMAC0123, VIOVOU, 0, VPU } }, + { 0xa4080014, 0, 16, 4, /* IPRF */ { KEYSC, DMAC45, USB, CMT } }, + { 0xa4080018, 0, 16, 4, /* IPRG */ { SCIF0, SCIF1, SCIF2 } }, + { 0xa408001c, 0, 16, 4, /* IPRH */ { SIOF0, SIOF1, FLCTL, I2C } }, + { 0xa4080020, 0, 16, 4, /* IPRI */ { SIO, 0, TSIF, RTC } }, + { 0xa4080024, 0, 16, 4, /* IPRJ */ { 0, 0, SIU } }, + { 0xa4080028, 0, 16, 4, /* IPRK */ { 0, 0, 0, SDHI } }, + { 0xa408002c, 0, 16, 4, /* IPRL */ { TWODG, 0, TPU } }, + { 0xa4140010, 0, 32, 4, /* INTPRI00 */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index a4127ec1520..c9965c0dde6 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -181,15 +181,17 @@ static struct intc_mask_reg mask_registers[] = { }; static struct intc_prio_reg prio_registers[] = { - { 0xffd40000, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } }, - { 0xffd40004, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, - { 0xffd40008, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } }, - { 0xffd4000c, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } }, - { 0xffd40010, 32, 8, /* INT2PRI4 */ { CMT, HAC, PCISERR, PCIINTA, } }, - { 0xffd40014, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC, - PCIINTD, PCIC5 } }, - { 0xffd40018, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } }, - { 0xffd4001c, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } }, + { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, + TMU2, TMU2_TICPI } }, + { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, + { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, WDT } }, + { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { HUDI, DMAC0, DMAC1 } }, + { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { CMT, HAC, + PCISERR, PCIINTA, } }, + { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { PCIINTB, PCIINTC, + PCIINTD, PCIC5 } }, + { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { SIOF, HSPI, MMCIF, SSI } }, + { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { FLCTL, GPIO } }, }; static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities, @@ -210,8 +212,8 @@ static struct intc_mask_reg irq_mask_registers[] = { }; static struct intc_prio_reg irq_prio_registers[] = { - { 0xffd00010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, - IRQ4, IRQ5, IRQ6, IRQ7 } }, + { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, + IRQ4, IRQ5, IRQ6, IRQ7 } }, }; static struct intc_sense_reg irq_sense_registers[] = { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index c49fcb0800c..a33d6a54c03 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -206,19 +206,22 @@ static struct intc_mask_reg mask_registers[] = { }; static struct intc_prio_reg prio_registers[] = { - { 0xffd00010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, - IRQ4, IRQ5, IRQ6, IRQ7 } }, - { 0xffd40000, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } }, - { 0xffd40004, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, } }, - { 0xffd40008, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, SCIF2, SCIF3 } }, - { 0xffd4000c, 32, 8, /* INT2PRI3 */ { SCIF4, SCIF5, WDT, } }, - { 0xffd40010, 32, 8, /* INT2PRI4 */ { HUDI, DMAC0, DMAC1, } }, - { 0xffd40014, 32, 8, /* INT2PRI5 */ { HAC0, HAC1, PCISERR, PCIINTA } }, - { 0xffd40018, 32, 8, /* INT2PRI6 */ { PCIINTB, PCIINTC, - PCIINTD, PCIC5 } }, - { 0xffd4001c, 32, 8, /* INT2PRI7 */ { SIOF, HSPI, MMCIF, } }, - { 0xffd40020, 32, 8, /* INT2PRI8 */ { FLCTL, GPIO, SSI0, SSI1, } }, - { 0xffd40024, 32, 8, /* INT2PRI9 */ { DU, GDTA, } }, + { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, + IRQ4, IRQ5, IRQ6, IRQ7 } }, + { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, + TMU2, TMU2_TICPI } }, + { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, } }, + { 0xffd40008, 0, 32, 8, /* INT2PRI2 */ { SCIF0, SCIF1, + SCIF2, SCIF3 } }, + { 0xffd4000c, 0, 32, 8, /* INT2PRI3 */ { SCIF4, SCIF5, WDT, } }, + { 0xffd40010, 0, 32, 8, /* INT2PRI4 */ { HUDI, DMAC0, DMAC1, } }, + { 0xffd40014, 0, 32, 8, /* INT2PRI5 */ { HAC0, HAC1, + PCISERR, PCIINTA } }, + { 0xffd40018, 0, 32, 8, /* INT2PRI6 */ { PCIINTB, PCIINTC, + PCIINTD, PCIC5 } }, + { 0xffd4001c, 0, 32, 8, /* INT2PRI7 */ { SIOF, HSPI, MMCIF, } }, + { 0xffd40020, 0, 32, 8, /* INT2PRI8 */ { FLCTL, GPIO, SSI0, SSI1, } }, + { 0xffd40024, 0, 32, 8, /* INT2PRI9 */ { DU, GDTA, } }, }; static DECLARE_INTC_DESC(intc_desc, "sh7785", vectors, groups, priorities, diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 610343ea9a8..2c13f9ceac7 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -192,18 +192,21 @@ static struct intc_mask_reg mask_registers[] = { }; static struct intc_prio_reg prio_registers[] = { - { 0xfe410010, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, + { 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, - { 0xfe410800, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4, - TMU3, TMU2, TMU1, TMU0 } }, - { 0xfe410804, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0, - SCIF3, SCIF2, SCIF1, SCIF0 } }, - { 0xfe410808, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0, PCII56789, PCII4, - PCII3, PCII2, PCII1, PCII0 } }, - { 0xfe41080c, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0, - VIN1, VIN0, IIC, DU} }, - { 0xfe410810, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3, - GPIO2, GPIO1, GPIO0, IRM } }, + { 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4, + TMU3, TMU2, TMU1, TMU0 } }, + { 0xfe410804, 0, 32, 4, /* INT2PRI1 */ { DTU3, DTU2, DTU1, DTU0, + SCIF3, SCIF2, + SCIF1, SCIF0 } }, + { 0xfe410808, 0, 32, 4, /* INT2PRI2 */ { DMAC1, DMAC0, + PCII56789, PCII4, + PCII3, PCII2, + PCII1, PCII0 } }, + { 0xfe41080c, 0, 32, 4, /* INT2PRI3 */ { FE1, FE0, ATAPI, VCORE0, + VIN1, VIN0, IIC, DU} }, + { 0xfe410810, 0, 32, 4, /* INT2PRI4 */ { 0, 0, PAM, GPIO3, + GPIO2, GPIO1, GPIO0, IRM } }, }; static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups, priorities, diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index a4086ea313c..6c759b2b892 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -53,7 +53,7 @@ struct intc_mask_reg { }; struct intc_prio_reg { - unsigned long reg, reg_width, field_width; + unsigned long set_reg, clr_reg, reg_width, field_width; intc_enum enum_ids[16]; }; -- cgit v1.2.3-70-g09d2 From 73505b445dbb8ad12df468404c4dd5cde9c40c65 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Sun, 12 Aug 2007 15:26:12 +0900 Subject: sh: intc - rework core code This patch reworks the intc core, implementing the following features: - Support dual priority registers - one set and one clear register - All 8/16/32 bit register combinations are now supported - Both single mask and single enable bitmap register are supported - Add code to set interrupt priority - Speedup sense and priority configuration code - Allocate data using bootmem, allows intc data structures to be __initdata - Save memory - allocated memory footprint is smaller than intc structures Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/cchips/voyagergx/irq.c | 2 +- arch/sh/kernel/cpu/irq/intc.c | 538 +++++++++++++++++++++++++---------------- include/asm-sh/hw_irq.h | 4 +- 3 files changed, 330 insertions(+), 214 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c index 0ca405a46a5..2d3620cc92b 100644 --- a/arch/sh/cchips/voyagergx/irq.c +++ b/arch/sh/cchips/voyagergx/irq.c @@ -50,7 +50,7 @@ static struct intc_vect vectors[] = { }; static struct intc_mask_reg mask_registers[] = { - { VOYAGER_INT_MASK, 1, 32, /* "Interrupt Mask", MMIO_base + 0x30 */ + { VOYAGER_INT_MASK, 0, 32, /* "Interrupt Mask", MMIO_base + 0x30 */ { UP, G54, G53, G52, G51, G50, G49, G48, I2C, PW, 0, DMA, PCI, I2S, AC, US, 0, 0, U1, U0, CV, MC, S1, S0, diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index 24a8d554799..d609a8ccd45 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -20,176 +20,227 @@ #include #include #include +#include + +#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ + ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ + ((addr_e) << 16) | ((addr_d << 24))) + +#define _INTC_SHIFT(h) (h & 0x1f) +#define _INTC_WIDTH(h) ((h >> 5) & 0xf) +#define _INTC_FN(h) ((h >> 9) & 0xf) +#define _INTC_MODE(h) ((h >> 13) & 0x7) +#define _INTC_ADDR_E(h) ((h >> 16) & 0xff) +#define _INTC_ADDR_D(h) ((h >> 24) & 0xff) + +struct intc_handle_int { + unsigned int irq; + unsigned long handle; +}; -#define _INTC_MK(fn, idx, bit, value) \ - ((fn) << 24 | ((value) << 16) | ((idx) << 8) | (bit)) -#define _INTC_FN(h) (h >> 24) -#define _INTC_VALUE(h) ((h >> 16) & 0xff) -#define _INTC_IDX(h) ((h >> 8) & 0xff) -#define _INTC_BIT(h) (h & 0xff) +struct intc_desc_int { + unsigned long *reg; + unsigned int nr_reg; + struct intc_handle_int *prio; + unsigned int nr_prio; + struct intc_handle_int *sense; + unsigned int nr_sense; + struct irq_chip chip; +}; -#define _INTC_PTR(desc, member, data) \ - (desc->member + _INTC_IDX(data)) +static unsigned int intc_prio_level[NR_IRQS]; /* for now */ -static inline struct intc_desc *get_intc_desc(unsigned int irq) +static inline struct intc_desc_int *get_intc_desc(unsigned int irq) { struct irq_chip *chip = get_irq_chip(irq); - return (void *)((char *)chip - offsetof(struct intc_desc, chip)); + return (void *)((char *)chip - offsetof(struct intc_desc_int, chip)); } static inline unsigned int set_field(unsigned int value, unsigned int field_value, - unsigned int width, - unsigned int shift) + unsigned int handle) { + unsigned int width = _INTC_WIDTH(handle); + unsigned int shift = _INTC_SHIFT(handle); + value &= ~(((1 << width) - 1) << shift); value |= field_value << shift; return value; } -static inline unsigned int set_prio_field(struct intc_desc *desc, - unsigned int value, - unsigned int priority, - unsigned int data) +static void write_8(unsigned long addr, unsigned long h, unsigned long data) { - unsigned int width = _INTC_PTR(desc, prio_regs, data)->field_width; - - return set_field(value, priority, width, _INTC_BIT(data)); + ctrl_outb(set_field(0, data, h), addr); } -static void disable_prio_16(struct intc_desc *desc, unsigned int data) +static void write_16(unsigned long addr, unsigned long h, unsigned long data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->set_reg; - - ctrl_outw(set_prio_field(desc, ctrl_inw(addr), 0, data), addr); + ctrl_outw(set_field(0, data, h), addr); } -static void enable_prio_16(struct intc_desc *desc, unsigned int data) +static void write_32(unsigned long addr, unsigned long h, unsigned long data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->set_reg; - unsigned int prio = _INTC_VALUE(data); - - ctrl_outw(set_prio_field(desc, ctrl_inw(addr), prio, data), addr); + ctrl_outl(set_field(0, data, h), addr); } -static void disable_prio_32(struct intc_desc *desc, unsigned int data) +static void modify_8(unsigned long addr, unsigned long h, unsigned long data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->set_reg; - - ctrl_outl(set_prio_field(desc, ctrl_inl(addr), 0, data), addr); + ctrl_outb(set_field(ctrl_inb(addr), data, h), addr); } -static void enable_prio_32(struct intc_desc *desc, unsigned int data) +static void modify_16(unsigned long addr, unsigned long h, unsigned long data) { - unsigned long addr = _INTC_PTR(desc, prio_regs, data)->set_reg; - unsigned int prio = _INTC_VALUE(data); - - ctrl_outl(set_prio_field(desc, ctrl_inl(addr), prio, data), addr); + ctrl_outw(set_field(ctrl_inw(addr), data, h), addr); } -static void write_set_reg_8(struct intc_desc *desc, unsigned int data) +static void modify_32(unsigned long addr, unsigned long h, unsigned long data) { - ctrl_outb(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->set_reg); + ctrl_outl(set_field(ctrl_inl(addr), data, h), addr); } -static void write_clr_reg_8(struct intc_desc *desc, unsigned int data) -{ - ctrl_outb(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->clr_reg); -} +enum { REG_FN_ERR = 0, REG_FN_WRITE_BASE = 1, REG_FN_MODIFY_BASE = 5 }; + +static void (*intc_reg_fns[])(unsigned long addr, + unsigned long h, + unsigned long data) = { + [REG_FN_WRITE_BASE + 0] = write_8, + [REG_FN_WRITE_BASE + 1] = write_16, + [REG_FN_WRITE_BASE + 3] = write_32, + [REG_FN_MODIFY_BASE + 0] = modify_8, + [REG_FN_MODIFY_BASE + 1] = modify_16, + [REG_FN_MODIFY_BASE + 3] = modify_32, +}; -static void write_set_reg_32(struct intc_desc *desc, unsigned int data) -{ - ctrl_outl(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->set_reg); -} +enum { MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */ + MODE_MASK_REG, /* Bit(s) set -> interrupt disabled */ + MODE_DUAL_REG, /* Two registers, set bit to enable / disable */ + MODE_PRIO_REG, /* Priority value written to enable interrupt */ + MODE_PCLR_REG, /* Above plus all bits set to disable interrupt */ +}; -static void write_clr_reg_32(struct intc_desc *desc, unsigned int data) +static void intc_mode_field(unsigned long addr, + unsigned long handle, + void (*fn)(unsigned long, + unsigned long, + unsigned long), + unsigned int irq) { - ctrl_outl(1 << _INTC_BIT(data), - _INTC_PTR(desc, mask_regs, data)->clr_reg); + fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1)); } -static void or_set_reg_16(struct intc_desc *desc, unsigned int data) +static void intc_mode_zero(unsigned long addr, + unsigned long handle, + void (*fn)(unsigned long, + unsigned long, + unsigned long), + unsigned int irq) { - unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; - - ctrl_outw(ctrl_inw(addr) | 1 << _INTC_BIT(data), addr); + fn(addr, handle, 0); } -static void and_set_reg_16(struct intc_desc *desc, unsigned int data) +static void intc_mode_prio(unsigned long addr, + unsigned long handle, + void (*fn)(unsigned long, + unsigned long, + unsigned long), + unsigned int irq) { - unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; - - ctrl_outw(ctrl_inw(addr) & ~(1 << _INTC_BIT(data)), addr); + fn(addr, handle, intc_prio_level[irq]); } -static void or_set_reg_32(struct intc_desc *desc, unsigned int data) -{ - unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; +static void (*intc_enable_fns[])(unsigned long addr, + unsigned long handle, + void (*fn)(unsigned long, + unsigned long, + unsigned long), + unsigned int irq) = { + [MODE_ENABLE_REG] = intc_mode_field, + [MODE_MASK_REG] = intc_mode_zero, + [MODE_DUAL_REG] = intc_mode_field, + [MODE_PRIO_REG] = intc_mode_prio, + [MODE_PCLR_REG] = intc_mode_prio, +}; - ctrl_outl(ctrl_inl(addr) | 1 << _INTC_BIT(data), addr); -} +static void (*intc_disable_fns[])(unsigned long addr, + unsigned long handle, + void (*fn)(unsigned long, + unsigned long, + unsigned long), + unsigned int irq) = { + [MODE_ENABLE_REG] = intc_mode_zero, + [MODE_MASK_REG] = intc_mode_field, + [MODE_DUAL_REG] = intc_mode_field, + [MODE_PRIO_REG] = intc_mode_zero, + [MODE_PCLR_REG] = intc_mode_field, +}; -static void and_set_reg_32(struct intc_desc *desc, unsigned int data) +static inline void _intc_enable(unsigned int irq, unsigned long handle) { - unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; + struct intc_desc_int *d = get_intc_desc(irq); + unsigned long addr = d->reg[_INTC_ADDR_E(handle)]; - ctrl_outl(ctrl_inl(addr) & ~(1 << _INTC_BIT(data)), addr); + intc_enable_fns[_INTC_MODE(handle)](addr, handle, + intc_reg_fns[_INTC_FN(handle)], + irq); } -enum { REG_FN_ERROR=0, - REG_FN_DUAL_8, REG_FN_DUAL_32, - REG_FN_ENA_16, REG_FN_ENA_32, - REG_FN_PRIO_16, REG_FN_PRIO_32 }; - -static struct { - void (*enable)(struct intc_desc *, unsigned int); - void (*disable)(struct intc_desc *, unsigned int); -} intc_reg_fns[] = { - [REG_FN_DUAL_8] = { write_clr_reg_8, write_set_reg_8 }, - [REG_FN_DUAL_32] = { write_clr_reg_32, write_set_reg_32 }, - [REG_FN_ENA_16] = { or_set_reg_16, and_set_reg_16 }, - [REG_FN_ENA_32] = { or_set_reg_32, and_set_reg_32 }, - [REG_FN_PRIO_16] = { enable_prio_16, disable_prio_16 }, - [REG_FN_PRIO_32] = { enable_prio_32, disable_prio_32 }, -}; - static void intc_enable(unsigned int irq) { - struct intc_desc *desc = get_intc_desc(irq); - unsigned int data = (unsigned int) get_irq_chip_data(irq); - - intc_reg_fns[_INTC_FN(data)].enable(desc, data); + _intc_enable(irq, (unsigned long)get_irq_chip_data(irq)); } static void intc_disable(unsigned int irq) { - struct intc_desc *desc = get_intc_desc(irq); - unsigned int data = (unsigned int) get_irq_chip_data(irq); + struct intc_desc_int *desc = get_intc_desc(irq); + unsigned long handle = (unsigned long) get_irq_chip_data(irq); + unsigned long addr = desc->reg[_INTC_ADDR_D(handle)]; - intc_reg_fns[_INTC_FN(data)].disable(desc, data); + intc_disable_fns[_INTC_MODE(handle)](addr, handle, + intc_reg_fns[_INTC_FN(handle)], + irq); } -static void set_sense_16(struct intc_desc *desc, unsigned int data) +static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, + unsigned int nr_hp, + unsigned int irq) { - unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg; - unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width; - unsigned int bit = _INTC_BIT(data); - unsigned int value = _INTC_VALUE(data); + int i; + + for (i = 0; i < nr_hp; i++) { + if ((hp + i)->irq != irq) + continue; + + return hp + i; + } - ctrl_outw(set_field(ctrl_inw(addr), value, width, bit), addr); + return NULL; } -static void set_sense_32(struct intc_desc *desc, unsigned int data) +int intc_set_priority(unsigned int irq, unsigned int prio) { - unsigned long addr = _INTC_PTR(desc, sense_regs, data)->reg; - unsigned int width = _INTC_PTR(desc, sense_regs, data)->field_width; - unsigned int bit = _INTC_BIT(data); - unsigned int value = _INTC_VALUE(data); + struct intc_desc_int *d = get_intc_desc(irq); + struct intc_handle_int *ihp; + + if (!intc_prio_level[irq] || prio <= 1) + return -EINVAL; + + ihp = intc_find_irq(d->prio, d->nr_prio, irq); + if (ihp) { + if (prio >= ((1 << _INTC_WIDTH(ihp->handle)) - 1)) + return -EINVAL; - ctrl_outl(set_field(ctrl_inl(addr), value, width, bit), addr); + intc_prio_level[irq] = prio; + + /* + * only set secondary masking method directly + * primary masking method is using intc_prio_level[irq] + * priority level will be set during next enable() + */ + + if (ihp->handle) + _intc_enable(irq, ihp->handle); + } + return 0; } #define VALID(x) (x | 0x80) @@ -203,92 +254,38 @@ static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { static int intc_set_sense(unsigned int irq, unsigned int type) { - struct intc_desc *desc = get_intc_desc(irq); + struct intc_desc_int *d = get_intc_desc(irq); unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK]; - unsigned int i, j, data, bit; - intc_enum enum_id = 0; - - for (i = 0; i < desc->nr_vectors; i++) { - struct intc_vect *vect = desc->vectors + i; - - if (evt2irq(vect->vect) != irq) - continue; + struct intc_handle_int *ihp; + unsigned long addr; - enum_id = vect->enum_id; - break; - } - - if (!enum_id || !value || !desc->sense_regs) + if (!value) return -EINVAL; - value ^= VALID(0); - - for (i = 0; i < desc->nr_sense_regs; i++) { - struct intc_sense_reg *sr = desc->sense_regs + i; - - for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) { - if (sr->enum_ids[j] != enum_id) - continue; - - bit = sr->reg_width - ((j + 1) * sr->field_width); - data = _INTC_MK(0, i, bit, value); - - switch(sr->reg_width) { - case 16: - set_sense_16(desc, data); - break; - case 32: - set_sense_32(desc, data); - break; - } - - return 0; - } - } - - return -EINVAL; -} - -static unsigned int __init intc_find_dual_handler(unsigned int width) -{ - switch (width) { - case 8: - return REG_FN_DUAL_8; - case 32: - return REG_FN_DUAL_32; + ihp = intc_find_irq(d->sense, d->nr_sense, irq); + if (ihp) { + addr = d->reg[_INTC_ADDR_E(ihp->handle)]; + intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value); } - - BUG(); - return REG_FN_ERROR; + return 0; } -static unsigned int __init intc_find_prio_handler(unsigned int width) +static unsigned int __init intc_get_reg(struct intc_desc_int *d, + unsigned long address) { - switch (width) { - case 16: - return REG_FN_PRIO_16; - case 32: - return REG_FN_PRIO_32; - } - - BUG(); - return REG_FN_ERROR; -} + unsigned int k; -static unsigned int __init intc_find_ena_handler(unsigned int width) -{ - switch (width) { - case 16: - return REG_FN_ENA_16; - case 32: - return REG_FN_ENA_32; + for (k = 0; k < d->nr_reg; k++) { + if (d->reg[k] == address) + return k; } BUG(); - return REG_FN_ERROR; + return 0; } -static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id) +static intc_enum __init intc_grp_id(struct intc_desc *desc, + intc_enum enum_id) { struct intc_group *g = desc->groups; unsigned int i, j; @@ -333,10 +330,12 @@ static unsigned int __init intc_prio_value(struct intc_desc *desc, } static unsigned int __init intc_mask_data(struct intc_desc *desc, + struct intc_desc_int *d, intc_enum enum_id, int do_grps) { struct intc_mask_reg *mr = desc->mask_regs; - unsigned int i, j, fn; + unsigned int i, j, fn, mode; + unsigned long reg_e, reg_d; for (i = 0; mr && enum_id && i < desc->nr_mask_regs; i++) { mr = desc->mask_regs + i; @@ -345,32 +344,46 @@ static unsigned int __init intc_mask_data(struct intc_desc *desc, if (mr->enum_ids[j] != enum_id) continue; - switch (mr->clr_reg) { - case 1: /* 1 = enabled interrupt - "enable" register */ - fn = intc_find_ena_handler(mr->reg_width); - break; - default: - fn = intc_find_dual_handler(mr->reg_width); + if (mr->set_reg && mr->clr_reg) { + fn = REG_FN_WRITE_BASE; + mode = MODE_DUAL_REG; + reg_e = mr->clr_reg; + reg_d = mr->set_reg; + } else { + fn = REG_FN_MODIFY_BASE; + if (mr->set_reg) { + mode = MODE_ENABLE_REG; + reg_e = mr->set_reg; + reg_d = mr->set_reg; + } else { + mode = MODE_MASK_REG; + reg_e = mr->clr_reg; + reg_d = mr->clr_reg; + } } - if (fn == REG_FN_ERROR) - return 0; - - return _INTC_MK(fn, i, (mr->reg_width - 1) - j, 0); + 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); } } if (do_grps) - return intc_mask_data(desc, intc_grp_id(desc, enum_id), 0); + return intc_mask_data(desc, d, intc_grp_id(desc, enum_id), 0); return 0; } static unsigned int __init intc_prio_data(struct intc_desc *desc, + struct intc_desc_int *d, intc_enum enum_id, int do_grps) { struct intc_prio_reg *pr = desc->prio_regs; - unsigned int i, j, fn, bit, prio; + unsigned int i, j, fn, mode, bit; + unsigned long reg_e, reg_d; for (i = 0; pr && enum_id && i < desc->nr_prio_regs; i++) { pr = desc->prio_regs + i; @@ -379,26 +392,69 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc, if (pr->enum_ids[j] != enum_id) continue; - fn = intc_find_prio_handler(pr->reg_width); - if (fn == REG_FN_ERROR) - return 0; + if (pr->set_reg && pr->clr_reg) { + fn = REG_FN_WRITE_BASE; + mode = MODE_PCLR_REG; + reg_e = pr->set_reg; + reg_d = pr->clr_reg; + } else { + fn = REG_FN_MODIFY_BASE; + mode = MODE_PRIO_REG; + if (!pr->set_reg) + BUG(); + reg_e = pr->set_reg; + reg_d = pr->set_reg; + } - prio = intc_prio_value(desc, enum_id, 1); + fn += (pr->reg_width >> 3) - 1; bit = pr->reg_width - ((j + 1) * pr->field_width); BUG_ON(bit < 0); - return _INTC_MK(fn, i, bit, prio); + return _INTC_MK(fn, mode, + intc_get_reg(d, reg_e), + intc_get_reg(d, reg_d), + pr->field_width, bit); } } if (do_grps) - return intc_prio_data(desc, intc_grp_id(desc, enum_id), 0); + return intc_prio_data(desc, d, intc_grp_id(desc, enum_id), 0); + + return 0; +} + +static unsigned int __init intc_sense_data(struct intc_desc *desc, + struct intc_desc_int *d, + intc_enum enum_id) +{ + struct intc_sense_reg *sr = desc->sense_regs; + unsigned int i, j, fn, bit; + + for (i = 0; sr && enum_id && i < desc->nr_sense_regs; i++) { + sr = desc->sense_regs + i; + + for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) { + if (sr->enum_ids[j] != enum_id) + continue; + + fn = REG_FN_MODIFY_BASE; + fn += (sr->reg_width >> 3) - 1; + bit = sr->reg_width - ((j + 1) * sr->field_width); + + BUG_ON(bit < 0); + + return _INTC_MK(fn, 0, intc_get_reg(d, sr->reg), + 0, sr->field_width, bit); + } + } return 0; } -static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, +static void __init intc_register_irq(struct intc_desc *desc, + struct intc_desc_int *d, + intc_enum enum_id, unsigned int irq) { unsigned int data[2], primary; @@ -410,15 +466,15 @@ static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, * 4. priority, multiple interrupt sources (groups) */ - data[0] = intc_mask_data(desc, enum_id, 0); - data[1] = intc_prio_data(desc, enum_id, 0); + data[0] = intc_mask_data(desc, d, enum_id, 0); + data[1] = intc_prio_data(desc, d, enum_id, 0); primary = 0; if (!data[0] && data[1]) primary = 1; - data[0] = data[0] ? data[0] : intc_mask_data(desc, enum_id, 1); - data[1] = data[1] ? data[1] : intc_prio_data(desc, enum_id, 1); + data[0] = data[0] ? data[0] : intc_mask_data(desc, d, enum_id, 1); + data[1] = data[1] ? data[1] : intc_prio_data(desc, d, enum_id, 1); if (!data[primary]) primary ^= 1; @@ -426,31 +482,91 @@ static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, BUG_ON(!data[primary]); /* must have primary masking method */ disable_irq_nosync(irq); - set_irq_chip_and_handler_name(irq, &desc->chip, + set_irq_chip_and_handler_name(irq, &d->chip, handle_level_irq, "level"); set_irq_chip_data(irq, (void *)data[primary]); + /* record the desired priority level */ + intc_prio_level[irq] = intc_prio_value(desc, enum_id, 1); + /* enable secondary masking method if present */ if (data[!primary]) - intc_reg_fns[_INTC_FN(data[!primary])].enable(desc, - data[!primary]); + _intc_enable(irq, data[!primary]); + + /* add irq to d->prio list if priority is available */ + if (data[1]) { + (d->prio + d->nr_prio)->irq = irq; + if (!primary) /* only secondary priority can access regs */ + (d->prio + d->nr_prio)->handle = data[1]; + d->nr_prio++; + } + + /* add irq to d->sense list if sense is available */ + data[0] = intc_sense_data(desc, d, enum_id); + if (data[0]) { + (d->sense + d->nr_sense)->irq = irq; + (d->sense + d->nr_sense)->handle = data[0]; + d->nr_sense++; + } /* irq should be disabled by default */ - desc->chip.mask(irq); + d->chip.mask(irq); } void __init register_intc_controller(struct intc_desc *desc) { - unsigned int i; + unsigned int i, k; + struct intc_desc_int *d; + + d = alloc_bootmem(sizeof(*d)); + + d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0; + d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0; + d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; + + d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg)); + k = 0; + + if (desc->mask_regs) { + for (i = 0; i < desc->nr_mask_regs; i++) { + if (desc->mask_regs[i].set_reg) + d->reg[k++] = desc->mask_regs[i].set_reg; + if (desc->mask_regs[i].clr_reg) + d->reg[k++] = desc->mask_regs[i].clr_reg; + } + } + + if (desc->prio_regs) { + d->prio = alloc_bootmem(desc->nr_vectors * sizeof(*d->prio)); + + for (i = 0; i < desc->nr_prio_regs; i++) { + if (desc->prio_regs[i].set_reg) + d->reg[k++] = desc->prio_regs[i].set_reg; + if (desc->prio_regs[i].clr_reg) + d->reg[k++] = desc->prio_regs[i].clr_reg; + } + } + + if (desc->sense_regs) { + d->sense = alloc_bootmem(desc->nr_vectors * sizeof(*d->sense)); + + for (i = 0; i < desc->nr_sense_regs; i++) { + if (desc->sense_regs[i].reg) + d->reg[k++] = desc->sense_regs[i].reg; + } + } + + BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ - desc->chip.mask = intc_disable; - desc->chip.unmask = intc_enable; - desc->chip.mask_ack = intc_disable; - desc->chip.set_type = intc_set_sense; + 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; for (i = 0; i < desc->nr_vectors; i++) { struct intc_vect *vect = desc->vectors + i; - intc_register_irq(desc, vect->enum_id, evt2irq(vect->vect)); + intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect)); } } diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 6c759b2b892..0e6a6030497 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -75,7 +75,7 @@ struct intc_desc { unsigned int nr_prio_regs; struct intc_sense_reg *sense_regs; unsigned int nr_sense_regs; - struct irq_chip chip; + char *name; }; #define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a) @@ -86,7 +86,7 @@ struct intc_desc symbol = { \ _INTC_ARRAY(priorities), \ _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ _INTC_ARRAY(sense_regs), \ - .chip.name = chipname, \ + chipname, \ } void __init register_intc_controller(struct intc_desc *desc); -- cgit v1.2.3-70-g09d2 From 2eeec85638cebcb6fbcb2abfe182a32252f3456d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Sun, 12 Aug 2007 15:29:16 +0900 Subject: sh: intc - convert board specific r2d code This patch converts the board specific interrupt code for r2d to make use of intc. While at it we improve the Kconfig to avoid confusion. - Two sets of interrupt tables exist - one for R2D-1 and one for R2D-PLUS. - R2D-1 and R2D-PLUS use the same irq constants. - R2D-1 has AX88796 support, R2D-PLUS does not hook up that IRQ. - R2D-PLUS has KEY support, R2D-1 does not hook up that IRQ. - The number and order of IRQ values are disconnected from register bits. - Interrupt sources now start from IRQ 100. - The machvec demux function converts from irlm IRQ 0-14 to IRQ 100++. Tested on R2D-1 and R2D-PLUS boards. Version 2 adds CONFIG_RTS7751R2D_1 and CONFIG_RTS7751R2D_PLUS together with intc structured as __initdata. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/rts7751r2d/Kconfig | 24 ++++- arch/sh/boards/renesas/rts7751r2d/irq.c | 173 +++++++++++++++++++++--------- arch/sh/boards/renesas/rts7751r2d/setup.c | 8 +- arch/sh/drivers/pci/ops-rts7751r2d.c | 8 +- include/asm-sh/rts7751r2d.h | 65 ++++++----- 5 files changed, 181 insertions(+), 97 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/boards/renesas/rts7751r2d/Kconfig b/arch/sh/boards/renesas/rts7751r2d/Kconfig index 7780d1fb13f..925a7aa861a 100644 --- a/arch/sh/boards/renesas/rts7751r2d/Kconfig +++ b/arch/sh/boards/renesas/rts7751r2d/Kconfig @@ -2,10 +2,28 @@ if SH_RTS7751R2D menu "RTS7751R2D options" -config RTS7751R2D_REV11 - bool "RTS7751R2D Rev. 1.1 board support" +choice + prompt "R2D Board Revision" + default RTS7751R2D_PLUS + +config RTS7751R2D_PLUS + bool "R2D-PLUS" + help + Selecting this option will configure the kernel for R2D-PLUS. + + R2D-PLUS is the smaller of the two R2D board versions, equipped + with a single PCI slot. + +config RTS7751R2D_1 + bool "R2D-1" help - Selecting this option will support version rev. 1.1. + Selecting this option will configure the kernel for R2D-1. + + R2D-1 is the larger of the two R2D board versions, equipped + with two PCI slots. + +endchoice + endmenu endif diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c index b97c25de3a4..e89932903ca 100644 --- a/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -1,9 +1,10 @@ /* * linux/arch/sh/boards/renesas/rts7751r2d/irq.c * + * Copyright (C) 2007 Magnus Damm * Copyright (C) 2000 Kazumoto Kojima * - * Renesas Technology Sales RTS7751R2D Support. + * Renesas Technology Sales RTS7751R2D Support, R2D-PLUS and R2D-1. * * Modified for RTS7751R2D by * Atom Create Engineering Co., Ltd. 2002. @@ -16,67 +17,141 @@ #include #include -#if defined(CONFIG_RTS7751R2D_REV11) -static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0}; -#else -static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0}; -#endif +#define R2D_NR_IRL 13 -static void enable_rts7751r2d_irq(unsigned int irq) -{ - /* Set priority in IPR back to original value */ - ctrl_outw(ctrl_inw(IRLCNTR1) | (1 << mask_pos[irq]), IRLCNTR1); -} +enum { + UNUSED = 0, -static void disable_rts7751r2d_irq(unsigned int irq) -{ - /* Set the priority in IPR to 0 */ - ctrl_outw(ctrl_inw(IRLCNTR1) & (0xffff ^ (1 << mask_pos[irq])), - IRLCNTR1); -} + /* board specific interrupt sources (R2D-1 and R2D-PLUS) */ + EXT, /* EXT_INT0-3 */ + RTC_T, RTC_A, /* Real Time Clock */ + AX88796, /* Ethernet controller (R2D-1 board) */ + KEY, /* Key input (R2D-PLUS board) */ + SDCARD, /* SD Card */ + CF_CD, CF_IDE, /* CF Card Detect + CF IDE */ + SM501, /* SM501 aka Voyager */ + PCI_INTD_RTL8139, /* Ethernet controller */ + PCI_INTC_PCI1520, /* Cardbus/PCMCIA bridge */ + PCI_INTB_RTL8139, /* Ethernet controller with HUB (R2D-PLUS board) */ + PCI_INTB_SLOT, /* PCI Slot 3.3v (R2D-1 board) */ + PCI_INTA_SLOT, /* PCI Slot 3.3v */ + TP, /* Touch Panel */ +}; + +#ifdef CONFIG_RTS7751R2D_1 + +/* Vectors for R2D-1 */ +static struct intc_vect vectors_r2d_1[] __initdata = { + INTC_IRQ(EXT, IRQ_EXT), + INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A), + INTC_IRQ(AX88796, IRQ_AX88796), INTC_IRQ(SDCARD, IRQ_SDCARD), + INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), /* ng */ + INTC_IRQ(SM501, IRQ_VOYAGER), + INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD), + INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC), + INTC_IRQ(PCI_INTB_SLOT, IRQ_PCI_INTB), + INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA), + INTC_IRQ(TP, IRQ_TP), +}; + +/* IRLMSK mask register layout for R2D-1 */ +static struct intc_mask_reg mask_registers_r2d_1[] __initdata = { + { 0xa4000000, 0, 16, /* IRLMSK */ + { TP, PCI_INTA_SLOT, PCI_INTB_SLOT, + PCI_INTC_PCI1520, PCI_INTD_RTL8139, + SM501, CF_IDE, CF_CD, SDCARD, AX88796, + RTC_A, RTC_T, 0, 0, 0, EXT } }, +}; + +/* IRLn to IRQ table for R2D-1 */ +static unsigned char irl2irq_r2d_1[R2D_NR_IRL] __initdata = { + IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC, + IRQ_VOYAGER, IRQ_AX88796, IRQ_RTC_A, IRQ_RTC_T, + IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT, + IRQ_TP, +}; + +static __initdata DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", + vectors_r2d_1, NULL, NULL, + mask_registers_r2d_1, NULL, NULL); + +#endif /* CONFIG_RTS7751R2D_1 */ + +#ifdef CONFIG_RTS7751R2D_PLUS + +/* Vectors for R2D-PLUS */ +static struct intc_vect vectors_r2d_plus[] __initdata = { + INTC_IRQ(EXT, IRQ_EXT), + INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A), + INTC_IRQ(KEY, IRQ_KEY), INTC_IRQ(SDCARD, IRQ_SDCARD), + INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), + INTC_IRQ(SM501, IRQ_VOYAGER), + INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD), + INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC), + INTC_IRQ(PCI_INTB_RTL8139, IRQ_PCI_INTB), + INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA), + INTC_IRQ(TP, IRQ_TP), +}; + +/* IRLMSK mask register layout for R2D-PLUS */ +static struct intc_mask_reg mask_registers_r2d_plus[] __initdata = { + { 0xa4000000, 0, 16, /* IRLMSK */ + { TP, PCI_INTA_SLOT, PCI_INTB_RTL8139, + PCI_INTC_PCI1520, PCI_INTD_RTL8139, + SM501, CF_IDE, CF_CD, SDCARD, KEY, + RTC_A, RTC_T, 0, 0, 0, EXT } }, +}; + +/* IRLn to IRQ table for R2D-PLUS */ +static unsigned char irl2irq_r2d_plus[R2D_NR_IRL] __initdata = { + IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC, + IRQ_VOYAGER, IRQ_KEY, IRQ_RTC_A, IRQ_RTC_T, + IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT, + IRQ_TP, +}; + +static __initdata DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", + vectors_r2d_plus, NULL, NULL, + mask_registers_r2d_plus, NULL, NULL); + +#endif /* CONFIG_RTS7751R2D_PLUS */ + +static unsigned char irl2irq[R2D_NR_IRL]; int rts7751r2d_irq_demux(int irq) { - return irq; -} + if (irq >= R2D_NR_IRL || !irl2irq[irq]) + return irq; -static struct irq_chip rts7751r2d_irq_chip __read_mostly = { - .name = "rts7751r2d", - .mask = disable_rts7751r2d_irq, - .unmask = enable_rts7751r2d_irq, - .mask_ack = disable_rts7751r2d_irq, -}; + return irl2irq[irq]; +} /* * Initialize IRQ setting */ void __init init_rts7751r2d_IRQ(void) { - int i; - - /* IRL0=KEY Input - * IRL1=Ethernet - * IRL2=CF Card - * IRL3=CF Card Insert - * IRL4=PCMCIA - * IRL5=VOYAGER - * IRL6=RTC Alarm - * IRL7=RTC Timer - * IRL8=SD Card - * IRL9=PCI Slot #1 - * IRL10=PCI Slot #2 - * IRL11=Extention #0 - * IRL12=Extention #1 - * IRL13=Extention #2 - * IRL14=Extention #3 - */ - - for (i=0; i<15; i++) { - disable_irq_nosync(i); - set_irq_chip_and_handler_name(i, &rts7751r2d_irq_chip, - handle_level_irq, "level"); - enable_rts7751r2d_irq(i); + struct intc_desc *d; + + switch (ctrl_inw(PA_BVERREG)) { +#ifdef CONFIG_RTS7751R2D_PLUS + case 0x10: + printk(KERN_INFO "Using R2D-PLUS interrupt controller.\n"); + d = &intc_desc_r2d_plus; + memcpy(irl2irq, irl2irq_r2d_plus, R2D_NR_IRL); + break; +#endif +#ifdef CONFIG_RTS7751R2D_1 + case 0x11: + printk(KERN_INFO "Using R2D-1 interrupt controller.\n"); + d = &intc_desc_r2d_1; + memcpy(irl2irq, irl2irq_r2d_1, R2D_NR_IRL); + break; +#endif + default: + return; } + register_intc_controller(d); setup_voyagergx_irq(); } diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c index 4d1bbd30e52..90703d5d123 100644 --- a/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -54,11 +54,7 @@ static struct resource cf_ide_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { -#ifdef CONFIG_RTS7751R2D_REV11 - .start = 1, -#else - .start = 2, -#endif + .start = IRQ_CF_IDE, .flags = IORESOURCE_IRQ, }, }; @@ -147,7 +143,7 @@ static int __init rts7751r2d_devices_setup(void) { int ret; - if (ctrl_inw(PA_BVERREG) == 0x10) { /* only working on R2D-PLUS */ + if (ctrl_inw(PA_BVERREG) == 0x10) { /* R2D-PLUS */ ret = platform_device_register(&cf_ide_device); if (ret) return ret; diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c index 4a518d94804..ec8430c8d2d 100644 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -19,10 +19,10 @@ #include "pci-sh4.h" static u8 rts7751r2d_irq_tab[] __initdata = { - IRQ_PCISLOT1, - IRQ_PCISLOT2, - IRQ_PCMCIA, - IRQ_PCIETH, + IRQ_PCI_INTA, + IRQ_PCI_INTB, + IRQ_PCI_INTC, + IRQ_PCI_INTD, }; int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) diff --git a/include/asm-sh/rts7751r2d.h b/include/asm-sh/rts7751r2d.h index 5d7800aa31b..83b9c111f17 100644 --- a/include/asm-sh/rts7751r2d.h +++ b/include/asm-sh/rts7751r2d.h @@ -9,7 +9,7 @@ * Renesas Technology Sales RTS7751R2D support */ -/* Box specific addresses. */ +/* Board specific addresses. */ #define PA_BCR 0xa4000000 /* FPGA */ #define PA_IRLMON 0xa4000002 /* Interrupt Status control */ @@ -20,19 +20,19 @@ #define PA_RTCCE 0xa400000c /* RTC(9701) Enable control */ #define PA_PCICD 0xa400000e /* PCI Extention detect control */ #define PA_VOYAGERRTS 0xa4000020 /* VOYAGER Reset control */ -#if defined(CONFIG_RTS7751R2D_REV11) -#define PA_AXRST 0xa4000022 /* AX_LAN Reset control */ -#define PA_CFRST 0xa4000024 /* CF Reset control */ -#define PA_ADMRTS 0xa4000026 /* SD Reset control */ -#define PA_EXTRST 0xa4000028 /* Extention Reset control */ -#define PA_CFCDINTCLR 0xa400002a /* CF Insert Interrupt clear */ -#else -#define PA_CFRST 0xa4000022 /* CF Reset control */ -#define PA_ADMRTS 0xa4000024 /* SD Reset control */ -#define PA_EXTRST 0xa4000026 /* Extention Reset control */ -#define PA_CFCDINTCLR 0xa4000028 /* CF Insert Interrupt clear */ -#define PA_KEYCTLCLR 0xa400002a /* Key Interrupt clear */ -#endif + +#define PA_R2D1_AXRST 0xa4000022 /* AX_LAN Reset control */ +#define PA_R2D1_CFRST 0xa4000024 /* CF Reset control */ +#define PA_R2D1_ADMRTS 0xa4000026 /* SD Reset control */ +#define PA_R2D1_EXTRST 0xa4000028 /* Extention Reset control */ +#define PA_R2D1_CFCDINTCLR 0xa400002a /* CF Insert Interrupt clear */ + +#define PA_R2DPLUS_CFRST 0xa4000022 /* CF Reset control */ +#define PA_R2DPLUS_ADMRTS 0xa4000024 /* SD Reset control */ +#define PA_R2DPLUS_EXTRST 0xa4000026 /* Extention Reset control */ +#define PA_R2DPLUS_CFCDINTCLR 0xa4000028 /* CF Insert Interrupt clear */ +#define PA_R2DPLUS_KEYCTLCLR 0xa400002a /* Key Interrupt clear */ + #define PA_POWOFF 0xa4000030 /* Board Power OFF control */ #define PA_VERREG 0xa4000032 /* FPGA Version Register */ #define PA_INPORT 0xa4000034 /* KEY Input Port control */ @@ -46,27 +46,22 @@ #define IRLCNTR1 (PA_BCR + 0) /* Interrupt Control Register1 */ -#if defined(CONFIG_RTS7751R2D_REV11) -#define IRQ_PCIETH 0 /* PCI Ethernet IRQ */ -#define IRQ_CFCARD 1 /* CF Card IRQ */ -#define IRQ_CFINST 2 /* CF Card Insert IRQ */ -#define IRQ_PCMCIA 3 /* PCMCIA IRQ */ -#define IRQ_VOYAGER 4 /* VOYAGER IRQ */ -#define IRQ_ONETH 5 /* On board Ethernet IRQ */ -#else -#define IRQ_KEYIN 0 /* Key Input IRQ */ -#define IRQ_PCIETH 1 /* PCI Ethernet IRQ */ -#define IRQ_CFCARD 2 /* CF Card IRQ */ -#define IRQ_CFINST 3 /* CF Card Insert IRQ */ -#define IRQ_PCMCIA 4 /* PCMCIA IRQ */ -#define IRQ_VOYAGER 5 /* VOYAGER IRQ */ -#endif -#define IRQ_RTCALM 6 /* RTC Alarm IRQ */ -#define IRQ_RTCTIME 7 /* RTC Timer IRQ */ -#define IRQ_SDCARD 8 /* SD Card IRQ */ -#define IRQ_PCISLOT1 9 /* PCI Slot #1 IRQ */ -#define IRQ_PCISLOT2 10 /* PCI Slot #2 IRQ */ -#define IRQ_EXTENTION 11 /* EXTn IRQ */ +#define R2D_FPGA_IRQ_BASE 100 + +#define IRQ_VOYAGER (R2D_FPGA_IRQ_BASE + 0) +#define IRQ_EXT (R2D_FPGA_IRQ_BASE + 1) +#define IRQ_TP (R2D_FPGA_IRQ_BASE + 2) +#define IRQ_RTC_T (R2D_FPGA_IRQ_BASE + 3) +#define IRQ_RTC_A (R2D_FPGA_IRQ_BASE + 4) +#define IRQ_SDCARD (R2D_FPGA_IRQ_BASE + 5) +#define IRQ_CF_CD (R2D_FPGA_IRQ_BASE + 6) +#define IRQ_CF_IDE (R2D_FPGA_IRQ_BASE + 7) +#define IRQ_AX88796 (R2D_FPGA_IRQ_BASE + 8) +#define IRQ_KEY (R2D_FPGA_IRQ_BASE + 9) +#define IRQ_PCI_INTA (R2D_FPGA_IRQ_BASE + 10) +#define IRQ_PCI_INTB (R2D_FPGA_IRQ_BASE + 11) +#define IRQ_PCI_INTC (R2D_FPGA_IRQ_BASE + 12) +#define IRQ_PCI_INTD (R2D_FPGA_IRQ_BASE + 13) /* arch/sh/boards/renesas/rts7751r2d/irq.c */ void init_rts7751r2d_IRQ(void); -- cgit v1.2.3-70-g09d2 From 5c37e025352b993d8726b0207ff2270b2f2bc7d6 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 17 Aug 2007 00:45:35 +0900 Subject: sh: intc - mark data structures as __initdata With the intc core improved it is now possible to put the intc data structures in the initdata section. Version two of this patch puts the __initdata inside DECLARE_INTC_DESC() and removes the __initdata included in the board specific r2d code. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/rts7751r2d/irq.c | 10 ++++------ arch/sh/cchips/voyagergx/irq.c | 4 ++-- arch/sh/kernel/cpu/sh3/setup-sh7705.c | 10 +++++----- arch/sh/kernel/cpu/sh3/setup-sh770x.c | 10 +++++----- arch/sh/kernel/cpu/sh3/setup-sh7710.c | 10 +++++----- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 26 +++++++++++++------------- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 12 ++++++------ arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 24 ++++++++++++------------ arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 21 ++++++++++----------- arch/sh/kernel/cpu/sh4a/setup-shx3.c | 16 ++++++++-------- include/asm-sh/hw_irq.h | 6 +++--- 12 files changed, 79 insertions(+), 82 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c index 878852158b4..12aae0ce1d1 100644 --- a/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -71,9 +71,8 @@ static unsigned char irl2irq_r2d_1[R2D_NR_IRL] __initdata = { IRQ_TP, }; -static __initdata DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", - vectors_r2d_1, NULL, NULL, - mask_registers_r2d_1, NULL, NULL); +static DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", vectors_r2d_1, + NULL, NULL, mask_registers_r2d_1, NULL, NULL); #endif /* CONFIG_RTS7751R2D_1 */ @@ -110,9 +109,8 @@ static unsigned char irl2irq_r2d_plus[R2D_NR_IRL] __initdata = { IRQ_TP, }; -static __initdata DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", - vectors_r2d_plus, NULL, NULL, - mask_registers_r2d_plus, NULL, NULL); +static DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", vectors_r2d_plus, + NULL, NULL, mask_registers_r2d_plus, NULL, NULL); #endif /* CONFIG_RTS7751R2D_PLUS */ diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c index 2d3620cc92b..ade30387684 100644 --- a/arch/sh/cchips/voyagergx/irq.c +++ b/arch/sh/cchips/voyagergx/irq.c @@ -33,7 +33,7 @@ enum { UH, TWOD, ZD, PV, CI, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_IRQ(UP, IRQ_SM501_UP), INTC_IRQ(G54, IRQ_SM501_G54), INTC_IRQ(G53, IRQ_SM501_G53), INTC_IRQ(G52, IRQ_SM501_G52), INTC_IRQ(G51, IRQ_SM501_G51), INTC_IRQ(G50, IRQ_SM501_G50), @@ -49,7 +49,7 @@ static struct intc_vect vectors[] = { INTC_IRQ(PV, IRQ_SM501_PV), INTC_IRQ(CI, IRQ_SM501_CI), }; -static struct intc_mask_reg mask_registers[] = { +static struct intc_mask_reg mask_registers[] __initdata = { { VOYAGER_INT_MASK, 0, 32, /* "Interrupt Mask", MMIO_base + 0x30 */ { UP, G54, G53, G52, G51, G50, G49, G48, I2C, PW, 0, DMA, PCI, I2S, AC, US, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index a1b342e170c..f6c65f2659e 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -36,7 +36,7 @@ enum { RTC, TMU2, DMAC, USB, SCIF2, SCIF0, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), INTC_VECT(PINT07, 0x700), INTC_VECT(PINT815, 0x720), INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), @@ -57,7 +57,7 @@ static struct intc_vect vectors[] = { INTC_VECT(REF_RCMI, 0x580), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI), INTC_GROUP(DMAC, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3), @@ -66,13 +66,13 @@ static struct intc_group groups[] = { INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_TXI), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(DMAC, 7), INTC_PRIO(SCIF2, 3), INTC_PRIO(SCIF0, 3), }; -static struct intc_prio_reg prio_registers[] = { +static struct intc_prio_reg prio_registers[] __initdata = { { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF_RCMI, 0, 0 } }, { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, @@ -87,7 +87,7 @@ static struct intc_prio_reg prio_registers[] = { static DECLARE_INTC_DESC(intc_desc, "sh7705", vectors, groups, priorities, NULL, prio_registers, NULL); -static struct intc_vect vectors_irq[] = { +static struct intc_vect vectors_irq[] __initdata = { INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 2980c44ffb2..60b04b1f945 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -39,7 +39,7 @@ enum { RTC, REF, TMU2, DMAC, SCI, SCIF2, SCIF0, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { 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), @@ -71,7 +71,7 @@ static struct intc_vect vectors[] = { #endif }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI), INTC_GROUP(REF, REF_RCMI, REF_ROVI), @@ -81,14 +81,14 @@ static struct intc_group groups[] = { INTC_GROUP(SCIF2, SCIF2_ERI, SCIF2_RXI, SCIF2_BRI, SCIF2_TXI), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(DMAC, 7), INTC_PRIO(SCI, 3), INTC_PRIO(SCIF2, 3), INTC_PRIO(SCIF0, 3), }; -static struct intc_prio_reg prio_registers[] = { +static struct intc_prio_reg prio_registers[] __initdata = { { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, SCI, 0 } }, #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ @@ -114,7 +114,7 @@ static DECLARE_INTC_DESC(intc_desc, "sh770x", vectors, groups, #if defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7707) || \ defined(CONFIG_CPU_SUBTYPE_SH7709) -static struct intc_vect vectors_irq[] = { +static struct intc_vect vectors_irq[] __initdata = { INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), }; diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 5aa77710e42..84e5629fa84 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -37,7 +37,7 @@ enum { RTC, DMAC1, SCIF0, SCIF1, DMAC2, SIOF0, SIOF1, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_VECT(IRQ4, 0x680), INTC_VECT(IRQ5, 0x6a0), INTC_VECT(DMAC_DEI0, 0x800), INTC_VECT(DMAC_DEI1, 0x820), INTC_VECT(DMAC_DEI2, 0x840), INTC_VECT(DMAC_DEI3, 0x860), @@ -63,7 +63,7 @@ static struct intc_vect vectors[] = { INTC_VECT(REF, 0x580), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), INTC_GROUP(DMAC1, DMAC_DEI0, DMAC_DEI1, DMAC_DEI2, DMAC_DEI3), INTC_GROUP(SCIF0, SCIF0_ERI, SCIF0_RXI, SCIF0_BRI, SCIF0_TXI), @@ -73,7 +73,7 @@ static struct intc_group groups[] = { INTC_GROUP(SIOF1, SIOF1_ERI, SIOF1_TXI, SIOF1_RXI, SIOF1_CCI), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(DMAC1, 7), INTC_PRIO(DMAC2, 7), INTC_PRIO(SCIF0, 3), @@ -85,7 +85,7 @@ static struct intc_prio priorities[] = { INTC_PRIO(EDMAC2, 5), }; -static struct intc_prio_reg prio_registers[] = { +static struct intc_prio_reg prio_registers[] __initdata = { { 0xfffffee2, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, { 0xfffffee4, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } }, { 0xa4000016, 0, 16, 4, /* IPRC */ { IRQ3, IRQ2, IRQ1, IRQ0 } }, @@ -103,7 +103,7 @@ static struct intc_prio_reg prio_registers[] = { static DECLARE_INTC_DESC(intc_desc, "sh7710", vectors, groups, priorities, NULL, prio_registers, NULL); -static struct intc_vect vectors_irq[] = { +static struct intc_vect vectors_irq[] __initdata = { INTC_VECT(IRQ0, 0x600), INTC_VECT(IRQ1, 0x620), INTC_VECT(IRQ2, 0x640), INTC_VECT(IRQ3, 0x660), }; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 062c3c1b243..523f68a9ce0 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -104,7 +104,7 @@ enum { DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620), INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), INTC_VECT(TMU2_TUNI, 0x440), INTC_VECT(TMU2_TICPI, 0x460), @@ -118,7 +118,7 @@ static struct intc_vect vectors[] = { INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(TMU2, TMU2_TUNI, TMU2_TICPI), INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), INTC_GROUP(SCI1, SCI1_ERI, SCI1_RXI, SCI1_TXI, SCI1_TEI), @@ -126,13 +126,13 @@ static struct intc_group groups[] = { INTC_GROUP(REF, REF_RCMI, REF_ROVI), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(SCIF, 3), INTC_PRIO(SCI1, 3), INTC_PRIO(DMAC, 7), }; -static struct intc_prio_reg prio_registers[] = { +static struct intc_prio_reg prio_registers[] __initdata = { { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, RTC } }, { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, SCI1, 0 } }, { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, SCIF, HUDI } }, @@ -150,13 +150,13 @@ static DECLARE_INTC_DESC(intc_desc, "sh7750", vectors, groups, defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ defined(CONFIG_CPU_SUBTYPE_SH7751) || \ defined(CONFIG_CPU_SUBTYPE_SH7091) -static struct intc_vect vectors_dma4[] = { +static struct intc_vect vectors_dma4[] __initdata = { INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), INTC_VECT(DMAC_DMAE, 0x6c0), }; -static struct intc_group groups_dma4[] = { +static struct intc_group groups_dma4[] __initdata = { INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, DMAC_DMAE), }; @@ -168,7 +168,7 @@ static DECLARE_INTC_DESC(intc_desc_dma4, "sh7750_dma4", /* SH7750R and SH7751R both have 8-channel DMA controllers */ #if defined(CONFIG_CPU_SUBTYPE_SH7750R) || defined(CONFIG_CPU_SUBTYPE_SH7751R) -static struct intc_vect vectors_dma8[] = { +static struct intc_vect vectors_dma8[] __initdata = { INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), INTC_VECT(DMAC_DMTE4, 0x780), INTC_VECT(DMAC_DMTE5, 0x7a0), @@ -176,7 +176,7 @@ static struct intc_vect vectors_dma8[] = { INTC_VECT(DMAC_DMAE, 0x6c0), }; -static struct intc_group groups_dma8[] = { +static struct intc_group groups_dma8[] __initdata = { INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE), @@ -191,11 +191,11 @@ static DECLARE_INTC_DESC(intc_desc_dma8, "sh7750_dma8", #if defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ defined(CONFIG_CPU_SUBTYPE_SH7751) || \ defined(CONFIG_CPU_SUBTYPE_SH7751R) -static struct intc_vect vectors_tmu34[] = { +static struct intc_vect vectors_tmu34[] __initdata = { INTC_VECT(TMU3, 0xb00), INTC_VECT(TMU4, 0xb80), }; -static struct intc_mask_reg mask_registers[] = { +static struct intc_mask_reg mask_registers[] __initdata = { { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TMU4, TMU3, @@ -210,7 +210,7 @@ static DECLARE_INTC_DESC(intc_desc_tmu34, "sh7750_tmu34", #endif /* SH7750S, SH7750R, SH7751 and SH7751R all have IRLM priority registers */ -static struct intc_vect vectors_irlm[] = { +static struct intc_vect vectors_irlm[] __initdata = { INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0), INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360), }; @@ -220,14 +220,14 @@ static DECLARE_INTC_DESC(intc_desc_irlm, "sh7750_irlm", vectors_irlm, NULL, /* SH7751 and SH7751R both have PCI */ #if defined(CONFIG_CPU_SUBTYPE_SH7751) || defined(CONFIG_CPU_SUBTYPE_SH7751R) -static struct intc_vect vectors_pci[] = { +static struct intc_vect vectors_pci[] __initdata = { INTC_VECT(PCIC0_PCISERR, 0xa00), INTC_VECT(PCIC1_PCIERR, 0xae0), INTC_VECT(PCIC1_PCIPWDWN, 0xac0), INTC_VECT(PCIC1_PCIPWON, 0xaa0), INTC_VECT(PCIC1_PCIDMA0, 0xa80), INTC_VECT(PCIC1_PCIDMA1, 0xa60), INTC_VECT(PCIC1_PCIDMA2, 0xa40), INTC_VECT(PCIC1_PCIDMA3, 0xa20), }; -static struct intc_group groups_pci[] = { +static struct intc_group groups_pci[] __initdata = { INTC_GROUP(PCIC1, PCIC1_PCIERR, PCIC1_PCIPWDWN, PCIC1_PCIPWON, PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3), }; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 6b4e48cbe7f..7a898cb1d94 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -43,7 +43,7 @@ enum { DMAC, DMABRG, SCIF0, SCIF1, SCIF2, SIM, MMCIF, TMU2, REF, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_VECT(HUDI, 0x600), INTC_VECT(GPIOI, 0x620), INTC_VECT(DMAC_DMTE0, 0x640), INTC_VECT(DMAC_DMTE1, 0x660), INTC_VECT(DMAC_DMTE2, 0x680), INTC_VECT(DMAC_DMTE3, 0x6a0), @@ -78,7 +78,7 @@ static struct intc_vect vectors[] = { INTC_VECT(REF_RCMI, 0x580), INTC_VECT(REF_ROVI, 0x5a0), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(DMAC, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7, DMAC_DMAE), @@ -92,7 +92,7 @@ static struct intc_group groups[] = { INTC_GROUP(REF, REF_RCMI, REF_ROVI), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(SCIF0, 3), INTC_PRIO(SCIF1, 3), INTC_PRIO(SCIF2, 3), @@ -101,7 +101,7 @@ static struct intc_prio priorities[] = { INTC_PRIO(DMABRG, 13), }; -static struct intc_mask_reg mask_registers[] = { +static struct intc_mask_reg mask_registers[] __initdata = { { 0xfe080040, 0xfe080060, 32, /* INTMSK00 / INTMSKCLR00 */ { IRQ4, IRQ5, IRQ6, IRQ7, 0, 0, HCAN20, HCAN21, SSI0, SSI1, HAC0, HAC1, I2C0, I2C1, USB, LCDC, @@ -117,7 +117,7 @@ static struct intc_mask_reg mask_registers[] = { 0, MFI, 0, 0, 0, 0, ADC, CMT, } }, }; -static struct intc_prio_reg prio_registers[] = { +static struct intc_prio_reg prio_registers[] __initdata = { { 0xffd00004, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2 } }, { 0xffd00008, 0, 16, 4, /* IPRB */ { WDT, REF, 0, 0 } }, { 0xffd0000c, 0, 16, 4, /* IPRC */ { GPIOI, DMAC, 0, HUDI } }, @@ -134,7 +134,7 @@ static struct intc_prio_reg prio_registers[] = { static DECLARE_INTC_DESC(intc_desc, "sh7760", vectors, groups, priorities, mask_registers, prio_registers, NULL); -static struct intc_vect vectors_irq[] = { +static struct intc_vect vectors_irq[] __initdata = { INTC_VECT(IRL0, 0x240), INTC_VECT(IRL1, 0x2a0), INTC_VECT(IRL2, 0x300), INTC_VECT(IRL3, 0x360), }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index ae63635cf1e..55f66104431 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -84,7 +84,7 @@ enum { SIM, RTC, DMAC0123, VIOVOU, USB, DMAC45, FLCTL, I2C, SDHI, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __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), @@ -117,7 +117,7 @@ static struct intc_vect vectors[] = { INTC_VECT(JPU, 0x560), INTC_VECT(LCDC, 0x580), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(SIM, SIM_ERI, SIM_RXI, SIM_TXI, SIM_TEI), INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), INTC_GROUP(DMAC0123, DMAC0, DMAC1, DMAC2, DMAC3), @@ -130,7 +130,7 @@ static struct intc_group groups[] = { INTC_GROUP(SDHI, SDHI0, SDHI1, SDHI2, SDHI3), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(SCIF0, 3), INTC_PRIO(SCIF1, 3), INTC_PRIO(SCIF2, 3), @@ -138,7 +138,7 @@ static struct intc_prio priorities[] = { INTC_PRIO(TMU1, 2), }; -static struct intc_mask_reg mask_registers[] = { +static struct intc_mask_reg mask_registers[] __initdata = { { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */ { } }, { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */ @@ -168,7 +168,7 @@ static struct intc_mask_reg mask_registers[] = { { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static struct intc_prio_reg prio_registers[] = { +static struct intc_prio_reg prio_registers[] __initdata = { { 0xa4080000, 0, 16, 4, /* IPRA */ { TMU0, TMU1, TMU2, IRDA } }, { 0xa4080004, 0, 16, 4, /* IPRB */ { JPU, LCDC, SIM } }, { 0xa4080008, 0, 16, 4, /* IPRC */ { } }, @@ -185,7 +185,7 @@ static struct intc_prio_reg prio_registers[] = { { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static struct intc_sense_reg sense_registers[] = { +static struct intc_sense_reg sense_registers[] __initdata = { { 0xa414001c, 16, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index c9965c0dde6..d84c4575fc0 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -114,7 +114,7 @@ enum { PCIC5, SCIF1, MMCIF, TMU345, FLCTL, GPIO, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_VECT(RTC_ATI, 0x480), INTC_VECT(RTC_PRI, 0x4a0), INTC_VECT(RTC_CUI, 0x4c0), INTC_VECT(WDT, 0x560), @@ -150,7 +150,7 @@ static struct intc_vect vectors[] = { INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(RTC, RTC_ATI, RTC_PRI, RTC_CUI), INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, @@ -167,12 +167,12 @@ static struct intc_group groups[] = { INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(SCIF0, 3), INTC_PRIO(SCIF1, 3), }; -static struct intc_mask_reg mask_registers[] = { +static struct intc_mask_reg mask_registers[] __initdata = { { 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */ { 0, 0, 0, 0, 0, 0, GPIO, FLCTL, SSI, MMCIF, HSPI, SIOF, PCIC5, PCIINTD, PCIINTC, PCIINTB, @@ -180,7 +180,7 @@ static struct intc_mask_reg mask_registers[] = { HUDI, 0, WDT, SCIF1, SCIF0, RTC, TMU345, TMU012 } }, }; -static struct intc_prio_reg prio_registers[] = { +static struct intc_prio_reg prio_registers[] __initdata = { { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, TMU2, TMU2_TICPI } }, { 0xffd40004, 0, 32, 8, /* INT2PRI1 */ { TMU3, TMU4, TMU5, RTC } }, @@ -199,24 +199,24 @@ static DECLARE_INTC_DESC(intc_desc, "sh7780", vectors, groups, priorities, /* Support for external interrupt pins in IRQ mode */ -static struct intc_vect irq_vectors[] = { +static struct intc_vect irq_vectors[] __initdata = { INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), }; -static struct intc_mask_reg irq_mask_registers[] = { +static struct intc_mask_reg irq_mask_registers[] __initdata = { { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static struct intc_prio_reg irq_prio_registers[] = { +static struct intc_prio_reg irq_prio_registers[] __initdata = { { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; -static struct intc_sense_reg irq_sense_registers[] = { +static struct intc_sense_reg irq_sense_registers[] __initdata = { { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; @@ -227,7 +227,7 @@ static DECLARE_INTC_DESC(intc_irq_desc, "sh7780-irq", irq_vectors, /* External interrupt pins in IRL mode */ -static struct intc_vect irl_vectors[] = { +static struct intc_vect irl_vectors[] __initdata = { INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), @@ -238,7 +238,7 @@ static struct intc_vect irl_vectors[] = { INTC_VECT(IRL_HHHL, 0x3c0), }; -static struct intc_mask_reg irl3210_mask_registers[] = { +static struct intc_mask_reg irl3210_mask_registers[] __initdata = { { 0xffd00080, 0xffd00084, 32, /* INTMSK2 / INTMSKCLR2 */ { IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, @@ -246,7 +246,7 @@ static struct intc_mask_reg irl3210_mask_registers[] = { IRL_HHLL, IRL_HHLH, IRL_HHHL, } }, }; -static struct intc_mask_reg irl7654_mask_registers[] = { +static struct intc_mask_reg irl7654_mask_registers[] __initdata = { { 0xffd00080, 0xffd00084, 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, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index a33d6a54c03..a595203f74c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -117,7 +117,7 @@ enum { PCIC5, MMCIF, GDTA, TMU345, FLCTL, GPIO }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_VECT(WDT, 0x560), INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0), INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0), @@ -158,7 +158,7 @@ static struct intc_vect vectors[] = { INTC_VECT(GPIOI2, 0xfc0), INTC_VECT(GPIOI3, 0xfe0), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(TMU012, TMU0, TMU1, TMU2, TMU2_TICPI), INTC_GROUP(DMAC0, DMAC0_DMINT0, DMAC0_DMINT1, DMAC0_DMINT2, DMAC0_DMINT3, DMAC0_DMINT4, DMAC0_DMINT5, DMAC0_DMAE), @@ -175,7 +175,7 @@ static struct intc_group groups[] = { INTC_GROUP(GPIO, GPIOI0, GPIOI1, GPIOI2, GPIOI3), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(SCIF0, 3), INTC_PRIO(SCIF1, 3), INTC_PRIO(SCIF2, 3), @@ -184,7 +184,7 @@ static struct intc_prio priorities[] = { INTC_PRIO(SCIF5, 3), }; -static struct intc_mask_reg mask_registers[] = { +static struct intc_mask_reg mask_registers[] __initdata = { { 0xffd00044, 0xffd00064, 32, /* INTMSK0 / INTMSKCLR0 */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, @@ -205,7 +205,7 @@ static struct intc_mask_reg mask_registers[] = { SCIF5, SCIF4, SCIF3, SCIF2, SCIF1, SCIF0, TMU345, TMU012 } }, }; -static struct intc_prio_reg prio_registers[] = { +static struct intc_prio_reg prio_registers[] __initdata = { { 0xffd00010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, { 0xffd40000, 0, 32, 8, /* INT2PRI0 */ { TMU0, TMU1, @@ -227,20 +227,19 @@ static struct intc_prio_reg prio_registers[] = { static DECLARE_INTC_DESC(intc_desc, "sh7785", vectors, groups, priorities, mask_registers, prio_registers, NULL); - /* Support for external interrupt pins in IRQ mode */ -static struct intc_vect vectors_irq0123[] = { +static struct intc_vect vectors_irq0123[] __initdata = { INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), }; -static struct intc_vect vectors_irq4567[] = { +static struct intc_vect vectors_irq4567[] __initdata = { INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380), INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200), }; -static struct intc_sense_reg sense_registers[] = { +static struct intc_sense_reg sense_registers[] __initdata = { { 0xffd0001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7 } }, }; @@ -255,7 +254,7 @@ static DECLARE_INTC_DESC(intc_desc_irq4567, "sh7785-irq4567", vectors_irq4567, /* External interrupt pins in IRL mode */ -static struct intc_vect vectors_irl0123[] = { +static struct intc_vect vectors_irl0123[] __initdata = { INTC_VECT(IRL0_LLLL, 0x200), INTC_VECT(IRL0_LLLH, 0x220), INTC_VECT(IRL0_LLHL, 0x240), INTC_VECT(IRL0_LLHH, 0x260), INTC_VECT(IRL0_LHLL, 0x280), INTC_VECT(IRL0_LHLH, 0x2a0), @@ -266,7 +265,7 @@ static struct intc_vect vectors_irl0123[] = { INTC_VECT(IRL0_HHHL, 0x3c0), }; -static struct intc_vect vectors_irl4567[] = { +static struct intc_vect vectors_irl4567[] __initdata = { INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20), INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60), INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0), diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 3c8a2edff2c..4cfd532086f 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -97,7 +97,7 @@ enum { DMAC0, DMAC1, DTU0, DTU1, DTU2, DTU3, }; -static struct intc_vect vectors[] = { +static struct intc_vect vectors[] __initdata = { INTC_VECT(HUDII, 0x3e0), INTC_VECT(TMU0, 0x400), INTC_VECT(TMU1, 0x420), INTC_VECT(TMU2, 0x440), INTC_VECT(TMU3, 0x460), @@ -145,7 +145,7 @@ static struct intc_vect vectors[] = { INTC_VECT(INTICI6, 0xfc0), INTC_VECT(INTICI7, 0xfe0), }; -static struct intc_group groups[] = { +static struct intc_group groups[] __initdata = { INTC_GROUP(IRL, IRL_LLLL, IRL_LLLH, IRL_LLHL, IRL_LLHH, IRL_LHLL, IRL_LHLH, IRL_LHHL, IRL_LHHH, IRL_HLLL, IRL_HLLH, IRL_HLHL, IRL_HLHH, @@ -165,14 +165,14 @@ static struct intc_group groups[] = { INTC_GROUP(DTU3, DTU3_TEND, DTU3_AE, DTU3_TMISS), }; -static struct intc_prio priorities[] = { +static struct intc_prio priorities[] __initdata = { INTC_PRIO(SCIF0, 3), INTC_PRIO(SCIF1, 3), INTC_PRIO(SCIF2, 3), INTC_PRIO(SCIF3, 3), }; -static struct intc_mask_reg mask_registers[] = { +static struct intc_mask_reg mask_registers[] __initdata = { { 0xfe410030, 0xfe410050, 32, /* CnINTMSK0 / CnINTMSKCLR0 */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, { 0xfe410040, 0xfe410060, 32, /* CnINTMSK1 / CnINTMSKCLR1 */ @@ -197,7 +197,7 @@ static struct intc_mask_reg mask_registers[] = { SCIF0_TXI, SCIF0_BRI, SCIF0_RXI, SCIF0_ERI } }, }; -static struct intc_prio_reg prio_registers[] = { +static struct intc_prio_reg prio_registers[] __initdata = { { 0xfe410010, 0, 32, 4, /* INTPRI */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, { 0xfe410800, 0, 32, 4, /* INT2PRI0 */ { 0, HUDII, TMU5, TMU4, @@ -222,12 +222,12 @@ static DECLARE_INTC_DESC(intc_desc, "shx3", vectors, groups, priorities, mask_registers, prio_registers, NULL); /* Support for external interrupt pins in IRQ mode */ -static struct intc_vect vectors_irq[] = { +static struct intc_vect vectors_irq[] __initdata = { INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280), INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300), }; -static struct intc_sense_reg sense_registers[] = { +static struct intc_sense_reg sense_registers[] __initdata = { { 0xfe41001c, 32, 2, /* ICR1 */ { IRQ0, IRQ1, IRQ2, IRQ3 } }, }; @@ -236,7 +236,7 @@ static DECLARE_INTC_DESC(intc_desc_irq, "shx3-irq", vectors_irq, groups, sense_registers); /* External interrupt pins in IRL mode */ -static struct intc_vect vectors_irl[] = { +static struct intc_vect vectors_irl[] __initdata = { INTC_VECT(IRL_LLLL, 0x200), INTC_VECT(IRL_LLLH, 0x220), INTC_VECT(IRL_LLHL, 0x240), INTC_VECT(IRL_LLHH, 0x260), INTC_VECT(IRL_LHLL, 0x280), INTC_VECT(IRL_LHLH, 0x2a0), diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 0e6a6030497..0c016e94993 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -42,10 +42,10 @@ struct intc_prio { struct intc_group { intc_enum enum_id; - intc_enum *enum_ids; + intc_enum enum_ids[32]; }; -#define INTC_GROUP(enum_id, ids...) { enum_id, (intc_enum []) { ids, 0 } } +#define INTC_GROUP(enum_id, ids...) { enum_id, { ids } } struct intc_mask_reg { unsigned long set_reg, clr_reg, reg_width; @@ -81,7 +81,7 @@ struct intc_desc { #define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a) #define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \ priorities, mask_regs, prio_regs, sense_regs) \ -struct intc_desc symbol = { \ +struct intc_desc symbol __initdata = { \ _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \ _INTC_ARRAY(priorities), \ _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ -- cgit v1.2.3-70-g09d2 From 3d37d94e5aab669f5a492bb3cda67bbbbbca50b8 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 17 Aug 2007 00:50:44 +0900 Subject: sh: intc - primary priority masking fixes This patch contains various intc fixes for problems reported by Markus Brunner on the linuxsh-dev mailing list: http://marc.info/?l=linuxsh-dev&m=118701948224991&w=1 Apart from added comments, the fixes are: - add intc_set_priority() function prototype to hw_irq.h - fix off-by-one error in intc_set_priority() - make sure _INTC_WIDTH() is set for primary priority masking Big thanks to Markus for finding these problems. Version two fixes a compile error and an inverted primary check. Signed-off-by: Magnus Damm Acked-by: Markus Brunner Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/intc.c | 33 ++++++++++++++++++++++++++++----- include/asm-sh/hw_irq.h | 1 + 2 files changed, 29 insertions(+), 5 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index d609a8ccd45..481871fee1a 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -206,6 +206,18 @@ static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, { int i; + /* this doesn't scale well, but... + * + * this function should only be used for cerain uncommon + * operations such as intc_set_priority() and intc_set_sense() + * and in those rare cases performance doesn't matter that much. + * keeping the memory footprint low is more important. + * + * one rather simple way to speed this up and still keep the + * memory footprint down is to make sure the array is sorted + * and then perform a bisect to lookup the irq. + */ + for (i = 0; i < nr_hp; i++) { if ((hp + i)->irq != irq) continue; @@ -226,7 +238,7 @@ int intc_set_priority(unsigned int irq, unsigned int prio) ihp = intc_find_irq(d->prio, d->nr_prio, irq); if (ihp) { - if (prio >= ((1 << _INTC_WIDTH(ihp->handle)) - 1)) + if (prio >= (1 << _INTC_WIDTH(ihp->handle))) return -EINVAL; intc_prio_level[irq] = prio; @@ -237,7 +249,7 @@ int intc_set_priority(unsigned int irq, unsigned int prio) * priority level will be set during next enable() */ - if (ihp->handle) + if (_INTC_FN(ihp->handle) != REG_FN_ERR) _intc_enable(irq, ihp->handle); } return 0; @@ -457,6 +469,7 @@ static void __init intc_register_irq(struct intc_desc *desc, intc_enum enum_id, unsigned int irq) { + struct intc_handle_int *hp; unsigned int data[2], primary; /* Prefer single interrupt source bitmap over other combinations: @@ -495,9 +508,19 @@ static void __init intc_register_irq(struct intc_desc *desc, /* add irq to d->prio list if priority is available */ if (data[1]) { - (d->prio + d->nr_prio)->irq = irq; - if (!primary) /* only secondary priority can access regs */ - (d->prio + d->nr_prio)->handle = data[1]; + hp = d->prio + d->nr_prio; + hp->irq = irq; + hp->handle = data[1]; + + if (primary) { + /* + * only secondary priority should access registers, so + * set _INTC_FN(h) = REG_FN_ERR for intc_set_priority() + */ + + hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0); + hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0); + } d->nr_prio++; } diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 0c016e94993..f9c90670e14 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -90,6 +90,7 @@ struct intc_desc symbol __initdata = { \ } void __init register_intc_controller(struct intc_desc *desc); +int intc_set_priority(unsigned int irq, unsigned int prio); void __init plat_irq_setup(void); -- cgit v1.2.3-70-g09d2 From 8786c952c1682a132e99b736beae4523e409b13d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Aug 2007 13:03:41 +0900 Subject: sh: heartbeat driver update. Add some flags for the heartbeat driver, and kill off some duplication in the bit positions for the boards that don't have special cases. This also allows for variable access widths and inversion. Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/r7780rp/setup.c | 16 ++++++-- arch/sh/boards/se/7206/setup.c | 8 +++- arch/sh/boards/se/770x/setup.c | 8 +++- arch/sh/boards/se/7722/setup.c | 9 +---- arch/sh/boards/se/7751/setup.c | 8 +++- arch/sh/boards/se/7780/setup.c | 7 +--- arch/sh/drivers/heartbeat.c | 70 +++++++++++++++++++++++++--------- include/asm-sh/heartbeat.h | 17 +++++++++ 8 files changed, 104 insertions(+), 39 deletions(-) create mode 100644 include/asm-sh/heartbeat.h (limited to 'include/asm-sh') diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index adb529d01ba..1062346e1d3 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c @@ -19,6 +19,7 @@ #include #include #include +#include #include static struct resource r8a66597_usb_host_resources[] = { @@ -108,16 +109,23 @@ static struct platform_device cf_ide_device = { }, }; -static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 }; - static struct resource heartbeat_resources[] = { [0] = { .start = PA_OBLED, - .end = PA_OBLED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .end = PA_OBLED + 8 - 1, .flags = IORESOURCE_MEM, }, }; +#ifndef CONFIG_SH_R7785RP +static unsigned char heartbeat_bit_pos[] = { 2, 1, 0, 3, 6, 5, 4, 7 }; + +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), +}; +#endif + static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, @@ -125,7 +133,7 @@ static struct platform_device heartbeat_device = { /* R7785RP has a slightly more sensible FPGA.. */ #ifndef CONFIG_SH_R7785RP .dev = { - .platform_data = heartbeat_bit_pos, + .platform_data = heartbeat_data, }, #endif .num_resources = ARRAY_SIZE(heartbeat_resources), diff --git a/arch/sh/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c index a074b62505e..5f041f86e3d 100644 --- a/arch/sh/boards/se/7206/setup.c +++ b/arch/sh/boards/se/7206/setup.c @@ -14,6 +14,7 @@ #include #include #include +#include static struct resource smc91x_resources[] = { [0] = { @@ -37,6 +38,11 @@ static struct platform_device smc91x_device = { static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), +}; + static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, @@ -49,7 +55,7 @@ static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, .dev = { - .platform_data = heartbeat_bit_pos, + .platform_data = heartbeat_data, }, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, diff --git a/arch/sh/boards/se/770x/setup.c b/arch/sh/boards/se/770x/setup.c index 2962da148f3..5172f994a1b 100644 --- a/arch/sh/boards/se/770x/setup.c +++ b/arch/sh/boards/se/770x/setup.c @@ -12,6 +12,7 @@ #include #include #include +#include void init_se_IRQ(void); @@ -90,6 +91,11 @@ static struct platform_device cf_ide_device = { static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), +}; + static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, @@ -102,7 +108,7 @@ static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, .dev = { - .platform_data = heartbeat_bit_pos, + .platform_data = heartbeat_data, }, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, diff --git a/arch/sh/boards/se/7722/setup.c b/arch/sh/boards/se/7722/setup.c index 495fc7e2b60..8f1c8a617bb 100644 --- a/arch/sh/boards/se/7722/setup.c +++ b/arch/sh/boards/se/7722/setup.c @@ -18,12 +18,10 @@ #include /* Heartbeat */ -static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, - .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .end = PA_LED + 8 - 1, .flags = IORESOURCE_MEM, }, }; @@ -31,9 +29,6 @@ static struct resource heartbeat_resources[] = { static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = heartbeat_bit_pos, - }, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, }; @@ -109,7 +104,7 @@ static void __init se7722_setup(char **cmdline_p) ctrl_outl(0x00051001, MSTPCR0); ctrl_outl(0x00000000, MSTPCR1); /* KEYSC, VOU, BEU, CEU, VEU, VPU, LCDC */ - ctrl_outl(0xffffbfC0, MSTPCR2); + ctrl_outl(0xffffbfC0, MSTPCR2); ctrl_outw(0x0000, PORT_PECR); /* PORT E 1 = IRQ5 ,E 0 = BS */ ctrl_outw(0x1000, PORT_PJCR); /* PORT J 1 = IRQ1,J 0 =IRQ0 */ diff --git a/arch/sh/boards/se/7751/setup.c b/arch/sh/boards/se/7751/setup.c index 7873d07e40c..5ed196827b0 100644 --- a/arch/sh/boards/se/7751/setup.c +++ b/arch/sh/boards/se/7751/setup.c @@ -13,9 +13,15 @@ #include #include #include +#include static unsigned char heartbeat_bit_pos[] = { 8, 9, 10, 11, 12, 13, 14, 15 }; +static struct heartbeat_data heartbeat_data = { + .bit_pos = heartbeat_bit_pos, + .nr_bits = ARRAY_SIZE(heartbeat_bit_pos), +}; + static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, @@ -28,7 +34,7 @@ static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, .dev = { - .platform_data = heartbeat_bit_pos, + .platform_data = heartbeat_data, }, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, diff --git a/arch/sh/boards/se/7780/setup.c b/arch/sh/boards/se/7780/setup.c index 723f2fd4d55..15c3ea4de92 100644 --- a/arch/sh/boards/se/7780/setup.c +++ b/arch/sh/boards/se/7780/setup.c @@ -16,12 +16,10 @@ #include /* Heartbeat */ -static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - static struct resource heartbeat_resources[] = { [0] = { .start = PA_LED, - .end = PA_LED + ARRAY_SIZE(heartbeat_bit_pos) - 1, + .end = PA_LED + 8 - 1, .flags = IORESOURCE_MEM, }, }; @@ -29,9 +27,6 @@ static struct resource heartbeat_resources[] = { static struct platform_device heartbeat_device = { .name = "heartbeat", .id = -1, - .dev = { - .platform_data = heartbeat_bit_pos, - }, .num_resources = ARRAY_SIZE(heartbeat_resources), .resource = heartbeat_resources, }; diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index 10c1828c9ff..b76a14f12ce 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c @@ -24,24 +24,44 @@ #include #include #include +#include #define DRV_NAME "heartbeat" -#define DRV_VERSION "0.1.0" +#define DRV_VERSION "0.1.1" -struct heartbeat_data { - void __iomem *base; - unsigned char bit_pos[8]; - struct timer_list timer; -}; +static unsigned char default_bit_pos[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +static inline void heartbeat_toggle_bit(struct heartbeat_data *hd, + unsigned bit, unsigned int inverted) +{ + unsigned int new; + + new = (1 << hd->bit_pos[bit]); + if (inverted) + new = ~new; + + switch (hd->regsize) { + case 32: + iowrite32(new, hd->base); + break; + case 16: + iowrite16(new, hd->base); + break; + default: + iowrite8(new, hd->base); + break; + } +} static void heartbeat_timer(unsigned long data) { struct heartbeat_data *hd = (struct heartbeat_data *)data; static unsigned bit = 0, up = 1; - ctrl_outw(1 << hd->bit_pos[bit], (unsigned long)hd->base); + heartbeat_toggle_bit(hd, bit, hd->flags & HEARTBEAT_INVERTED); + bit += up; - if ((bit == 0) || (bit == ARRAY_SIZE(hd->bit_pos)-1)) + if ((bit == 0) || (bit == (hd->nr_bits)-1)) up = -up; mod_timer(&hd->timer, jiffies + (110 - ((300 << FSHIFT) / @@ -64,21 +84,31 @@ static int heartbeat_drv_probe(struct platform_device *pdev) return -EINVAL; } - hd = kmalloc(sizeof(struct heartbeat_data), GFP_KERNEL); - if (unlikely(!hd)) - return -ENOMEM; - if (pdev->dev.platform_data) { - memcpy(hd->bit_pos, pdev->dev.platform_data, - ARRAY_SIZE(hd->bit_pos)); + hd = pdev->dev.platform_data; } else { - int i; + hd = kzalloc(sizeof(struct heartbeat_data), GFP_KERNEL); + if (unlikely(!hd)) + return -ENOMEM; + } + + hd->base = ioremap_nocache(res->start, res->end - res->start + 1); + if (!unlikely(hd->base)) { + dev_err(&pdev->dev, "ioremap failed\n"); + + if (!pdev->dev.platform_data) + kfree(hd); + + return -ENXIO; + } - for (i = 0; i < ARRAY_SIZE(hd->bit_pos); i++) - hd->bit_pos[i] = i; + if (!hd->nr_bits) { + hd->bit_pos = default_bit_pos; + hd->nr_bits = ARRAY_SIZE(default_bit_pos); } - hd->base = (void __iomem *)(unsigned long)res->start; + if (!hd->regsize) + hd->regsize = 8; /* default access size */ setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd); platform_set_drvdata(pdev, hd); @@ -91,10 +121,12 @@ static int heartbeat_drv_remove(struct platform_device *pdev) struct heartbeat_data *hd = platform_get_drvdata(pdev); del_timer_sync(&hd->timer); + iounmap(hd->base); platform_set_drvdata(pdev, NULL); - kfree(hd); + if (!pdev->dev.platform_data) + kfree(hd); return 0; } diff --git a/include/asm-sh/heartbeat.h b/include/asm-sh/heartbeat.h new file mode 100644 index 00000000000..724a43ed245 --- /dev/null +++ b/include/asm-sh/heartbeat.h @@ -0,0 +1,17 @@ +#ifndef __ASM_SH_HEARTBEAT_H +#define __ASM_SH_HEARTBEAT_H + +#include + +#define HEARTBEAT_INVERTED (1 << 0) + +struct heartbeat_data { + void __iomem *base; + unsigned char *bit_pos; + unsigned int nr_bits; + struct timer_list timer; + unsigned int regsize; + unsigned long flags; +}; + +#endif /* __ASM_SH_HEARTBEAT_H */ -- cgit v1.2.3-70-g09d2 From 8a467a529f01c3471b195a0e8989c6177fe145ef Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 22 Aug 2007 10:34:31 +0900 Subject: sh: Overhaul spinlocks and rwlocks for SH-4A SMP. This rips out some of the old spinlock and rwlock behaviour that the SH-2 parts were using and reworks them for LL/SC semantics on the SH-4A. This is primarily only useful for SH-X3 multi-cores, but can also be used for building CONFIG_SMP=y testing kernels on SH-4A UP. Signed-off-by: Paul Mundt --- include/asm-sh/spinlock.h | 181 +++++++++++++++++++++++++++++++--------- include/asm-sh/spinlock_types.h | 11 +-- 2 files changed, 146 insertions(+), 46 deletions(-) (limited to 'include/asm-sh') diff --git a/include/asm-sh/spinlock.h b/include/asm-sh/spinlock.h index 92f6e2008b2..e793181d64d 100644 --- a/include/asm-sh/spinlock.h +++ b/include/asm-sh/spinlock.h @@ -2,6 +2,7 @@ * include/asm-sh/spinlock.h * * Copyright (C) 2002, 2003 Paul Mundt + * Copyright (C) 2006, 2007 Akio Idehara * * 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 @@ -10,17 +11,22 @@ #ifndef __ASM_SH_SPINLOCK_H #define __ASM_SH_SPINLOCK_H -#include -#include +/* + * The only locking implemented here uses SH-4A opcodes. For others, + * split this out as per atomic-*.h. + */ +#ifndef CONFIG_CPU_SH4A +#error "Need movli.l/movco.l for spinlocks" +#endif /* * Your basic SMP spinlocks, allowing only a single CPU anywhere */ -#define __raw_spin_is_locked(x) ((x)->lock != 0) +#define __raw_spin_is_locked(x) ((x)->lock <= 0) #define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) #define __raw_spin_unlock_wait(x) \ - do { cpu_relax(); } while (__raw_spin_is_locked(x)) + do { cpu_relax(); } while ((x)->lock) /* * Simple spin lock operations. There are two variants, one clears IRQ's @@ -30,12 +36,19 @@ */ static inline void __raw_spin_lock(raw_spinlock_t *lock) { + unsigned long tmp; + unsigned long oldval; + __asm__ __volatile__ ( - "1:\n\t" - "tas.b @%0\n\t" - "bf/s 1b\n\t" - "nop\n\t" - : "=r" (lock->lock) + "1: \n\t" + "movli.l @%2, %0 ! __raw_spin_lock \n\t" + "mov %0, %1 \n\t" + "mov #0, %0 \n\t" + "movco.l %0, @%2 \n\t" + "bf 1b \n\t" + "cmp/pl %1 \n\t" + "bf 1b \n\t" + : "=&z" (tmp), "=&r" (oldval) : "r" (&lock->lock) : "t", "memory" ); @@ -43,12 +56,36 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) static inline void __raw_spin_unlock(raw_spinlock_t *lock) { - //assert_spin_locked(lock); + unsigned long tmp; - lock->lock = 0; + __asm__ __volatile__ ( + "mov #1, %0 ! __raw_spin_unlock \n\t" + "mov.l %0, @%1 \n\t" + : "=&z" (tmp) + : "r" (&lock->lock) + : "t", "memory" + ); } -#define __raw_spin_trylock(x) (!test_and_set_bit(0, &(x)->lock)) +static inline int __raw_spin_trylock(raw_spinlock_t *lock) +{ + unsigned long tmp, oldval; + + __asm__ __volatile__ ( + "1: \n\t" + "movli.l @%2, %0 ! __raw_spin_trylock \n\t" + "mov %0, %1 \n\t" + "mov #0, %0 \n\t" + "movco.l %0, @%2 \n\t" + "bf 1b \n\t" + "synco \n\t" + : "=&z" (tmp), "=&r" (oldval) + : "r" (&lock->lock) + : "t", "memory" + ); + + return oldval; +} /* * Read-write spinlocks, allowing multiple readers but only one writer. @@ -59,58 +96,124 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) * read-locks. */ +/** + * read_can_lock - would read_trylock() succeed? + * @lock: the rwlock in question. + */ +#define __raw_read_can_lock(x) ((x)->lock > 0) + +/** + * write_can_lock - would write_trylock() succeed? + * @lock: the rwlock in question. + */ +#define __raw_write_can_lock(x) ((x)->lock == RW_LOCK_BIAS) + static inline void __raw_read_lock(raw_rwlock_t *rw) { - __raw_spin_lock(&rw->lock); - - atomic_inc(&rw->counter); + unsigned long tmp; - __raw_spin_unlock(&rw->lock); + __asm__ __volatile__ ( + "1: \n\t" + "movli.l @%1, %0 ! __raw_read_lock \n\t" + "cmp/pl %0 \n\t" + "bf 1b \n\t" + "add #-1, %0 \n\t" + "movco.l %0, @%1 \n\t" + "bf 1b \n\t" + : "=&z" (tmp) + : "r" (&rw->lock) + : "t", "memory" + ); } static inline void __raw_read_unlock(raw_rwlock_t *rw) { - __raw_spin_lock(&rw->lock); - - atomic_dec(&rw->counter); + unsigned long tmp; - __raw_spin_unlock(&rw->lock); + __asm__ __volatile__ ( + "1: \n\t" + "movli.l @%1, %0 ! __raw_read_unlock \n\t" + "add #1, %0 \n\t" + "movco.l %0, @%1 \n\t" + "bf 1b \n\t" + : "=&z" (tmp) + : "r" (&rw->lock) + : "t", "memory" + ); } static inline void __raw_write_lock(raw_rwlock_t *rw) { - __raw_spin_lock(&rw->lock); - atomic_set(&rw->counter, -1); + unsigned long tmp; + + __asm__ __volatile__ ( + "1: \n\t" + "movli.l @%1, %0 ! __raw_write_lock \n\t" + "cmp/hs %2, %0 \n\t" + "bf 1b \n\t" + "sub %2, %0 \n\t" + "movco.l %0, @%1 \n\t" + "bf 1b \n\t" + : "=&z" (tmp) + : "r" (&rw->lock), "r" (RW_LOCK_BIAS) + : "t", "memory" + ); } static inline void __raw_write_unlock(raw_rwlock_t *rw) { - atomic_set(&rw->counter, 0); - __raw_spin_unlock(&rw->lock); + __asm__ __volatile__ ( + "mov.l %1, @%0 ! __raw_write_unlock \n\t" + : + : "r" (&rw->lock), "r" (RW_LOCK_BIAS) + : "t", "memory" + ); } -static inline int __raw_write_can_lock(raw_rwlock_t *rw) +static inline int __raw_read_trylock(raw_rwlock_t *rw) { - return (atomic_read(&rw->counter) == RW_LOCK_BIAS); -} + unsigned long tmp, oldval; -static inline int __raw_read_trylock(raw_rwlock_t *lock) -{ - atomic_t *count = (atomic_t*)lock; - if (atomic_dec_return(count) >= 0) - return 1; - atomic_inc(count); - return 0; + __asm__ __volatile__ ( + "1: \n\t" + "movli.l @%2, %0 ! __raw_read_trylock \n\t" + "mov %0, %1 \n\t" + "cmp/pl %0 \n\t" + "bf 2f \n\t" + "add #-1, %0 \n\t" + "movco.l %0, @%2 \n\t" + "bf 1b \n\t" + "2: \n\t" + "synco \n\t" + : "=&z" (tmp), "=&r" (oldval) + : "r" (&rw->lock) + : "t", "memory" + ); + + return (oldval > 0); } static inline int __raw_write_trylock(raw_rwlock_t *rw) { - if (atomic_sub_and_test(RW_LOCK_BIAS, &rw->counter)) - return 1; - - atomic_add(RW_LOCK_BIAS, &rw->counter); + unsigned long tmp, oldval; + + __asm__ __volatile__ ( + "1: \n\t" + "movli.l @%2, %0 ! __raw_write_trylock \n\t" + "mov %0, %1 \n\t" + "cmp/hs %3, %0 \n\t" + "bf 2f \n\t" + "sub %3, %0 \n\t" + "2: \n\t" + "movco.l %0, @%2 \n\t" + "bf 1b \n\t" + "synco \n\t" + : "=&z" (tmp), "=&r" (oldval) + : "r" (&rw->lock), "r" (RW_LOCK_BIAS) + : "t", "memory" + ); - return 0; + return (oldval > (RW_LOCK_BIAS - 1)); } #define _raw_spin_relax(lock) cpu_relax() diff --git a/include/asm-sh/spinlock_types.h b/include/asm-sh/spinlock_types.h index 5c58134f2c4..b4d244e7b60 100644 --- a/include/asm-sh/spinlock_types.h +++ b/include/asm-sh/spinlock_types.h @@ -6,19 +6,16 @@ #endif typedef struct { - volatile unsigned long lock; + volatile unsigned int lock; } raw_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { 1 } - -#include +#define __RAW_SPIN_LOCK_UNLOCKED { 1 } typedef struct { - raw_spinlock_t lock; - atomic_t counter; + volatile unsigned int lock; } raw_rwlock_t; #define RW_LOCK_BIAS 0x01000000 -#define __RAW_RW_LOCK_UNLOCKED { { 0 }, { RW_LOCK_BIAS } } +#define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } #endif -- cgit v1.2.3-70-g09d2 From 953c8ef250fc6c329d1607cf9cd7fac1d72d7579 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 Sep 2007 12:03:50 +0900 Subject: 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(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index d84c4575fc0..e8fd33ff060 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 a595203f74c..486dabe4d27 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 f9c90670e14..96d97104050 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); -- cgit v1.2.3-70-g09d2 From 897cfcd878ccc9c2b0f1b3bb00a2368c43feafc0 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 Sep 2007 12:06:03 +0900 Subject: sh: intc - rework higlander irq code for r7780mp and r7785rp This patch reworks the highlander irq code for r7780mp and r7785rp. The same strategy as for the new R2D code is used here - the board specific interrupts are now starting from HL_FPGA_IRQ_BASE. The code for r7780rp is not touched due to lack of hardware. Tested with CF, AX88796 on r7780mp and r7785rp. The touch switch interrupt has also been tested on r7780mp. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/r7780rp/Makefile | 5 ++- arch/sh/boards/renesas/r7780rp/irq-r7780mp.c | 61 ++++++++++++++++++++++++++++ arch/sh/boards/renesas/r7780rp/irq-r7780rp.c | 5 ++- arch/sh/boards/renesas/r7780rp/irq-r7785rp.c | 46 ++++++++++++++++++--- arch/sh/boards/renesas/r7780rp/setup.c | 54 +++++++++++++++++++----- include/asm-sh/r7780rp.h | 33 +++++++-------- 6 files changed, 166 insertions(+), 38 deletions(-) create mode 100644 arch/sh/boards/renesas/r7780rp/irq-r7780mp.c (limited to 'include/asm-sh') diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile index b1d20afb4eb..dd26182fbf5 100644 --- a/arch/sh/boards/renesas/r7780rp/Makefile +++ b/arch/sh/boards/renesas/r7780rp/Makefile @@ -1,9 +1,10 @@ # # Makefile for the R7780RP-1 specific parts of the kernel # -irqinit-y := irq-r7780rp.o +irqinit-$(CONFIG_SH_R7780MP) := irq-r7780mp.o irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o -obj-y := setup.o irq.o $(irqinit-y) +irqinit-$(CONFIG_SH_R7780RP) := irq-r7780rp.o irq.o +obj-y := setup.o $(irqinit-y) ifneq ($(CONFIG_SH_R7785RP),y) obj-$(CONFIG_PUSH_SWITCH) += psw.o diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c new file mode 100644 index 00000000000..59b47fe061f --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/irq-r7780mp.c @@ -0,0 +1,61 @@ +/* + * Renesas Solutions Highlander R7780MP Support. + * + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2007 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 +#include + +enum { + UNUSED = 0, + + /* board specific interrupt sources */ + AX88796, /* Ethernet controller */ + CF, /* Compact Flash */ + PSW, /* Push Switch */ + EXT1, /* EXT1n IRQ */ + EXT4, /* EXT4n IRQ */ +}; + +static struct intc_vect vectors[] __initdata = { + INTC_IRQ(CF, IRQ_CF), + INTC_IRQ(PSW, IRQ_PSW), + INTC_IRQ(AX88796, IRQ_AX88796), + INTC_IRQ(EXT1, IRQ_EXT1), + INTC_IRQ(EXT4, IRQ_EXT4), +}; + +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xa4000000, 0, 16, /* IRLMSK */ + { 0, 0, 0, 0, CF, 0, 0, 0, + 0, 0, 0, EXT4, 0, EXT1, PSW, AX88796 } }, +}; + +static unsigned char irl2irq[HL_NR_IRL] __initdata = { + 0, IRQ_CF, 0, 0, + 0, 0, 0, 0, + 0, IRQ_EXT4, 0, IRQ_EXT1, + 0, IRQ_AX88796, IRQ_PSW, +}; + +static DECLARE_INTC_DESC(intc_desc, "r7780mp", vectors, + NULL, NULL, mask_registers, NULL, NULL); + +unsigned char * __init highlander_init_irq_r7780mp(void) +{ + if ((ctrl_inw(0xa4000700) & 0xf000) == 0x2000) { + printk(KERN_INFO "Using r7780mp interrupt controller.\n"); + register_intc_controller(&intc_desc); + return irl2irq; + } + + return NULL; +} diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c index f5f358746c9..d6b107a2e0b 100644 --- a/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c +++ b/arch/sh/boards/renesas/r7780rp/irq-r7780rp.c @@ -9,13 +9,14 @@ * for more details. */ #include -#include #include -void __init highlander_init_irq(void) +unsigned char * __init highlander_init_irq_r7780rp(void) { int i; for (i = 0; i < 15; i++) make_r7780rp_irq(i); + + return NULL; } diff --git a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c index dd6ec4ce44d..b2c6a84673b 100644 --- a/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c +++ b/arch/sh/boards/renesas/r7780rp/irq-r7785rp.c @@ -1,19 +1,55 @@ /* - * Renesas Solutions Highlander R7780RP-1 Support. + * Renesas Solutions Highlander R7785RP Support. * * Copyright (C) 2002 Atom Create Engineering Co., Ltd. * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2007 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 +#include #include -void __init highlander_init_irq(void) +enum { + UNUSED = 0, + + /* board specific interrupt sources */ + AX88796, /* Ethernet controller */ + CF, /* Compact Flash */ +}; + +static struct intc_vect vectors[] __initdata = { + INTC_IRQ(CF, IRQ_CF), + INTC_IRQ(AX88796, IRQ_AX88796), +}; + +static struct intc_mask_reg mask_registers[] __initdata = { + { 0xa4000010, 0, 16, /* IRLMCR1 */ + { 0, 0, 0, 0, CF, AX88796, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 } }, +}; + +static unsigned char irl2irq[HL_NR_IRL] __initdata = { + 0, IRQ_CF, 0, 0, + 0, 0, 0, 0, + 0, 0, IRQ_AX88796, 0, + 0, 0, 0, +}; + +static DECLARE_INTC_DESC(intc_desc, "r7785rp", vectors, + NULL, NULL, mask_registers, NULL, NULL); + +unsigned char * __init highlander_init_irq_r7785rp(void) { + if ((ctrl_inw(0xa4000158) & 0xf000) != 0x1000) + return NULL; + + printk(KERN_INFO "Using r7785rp interrupt controller.\n"); + ctrl_outw(0x0000, PA_IRLSSR1); /* FPGA IRLSSR1(CF_CD clear) */ /* Setup the FPGA IRL */ @@ -24,6 +60,6 @@ void __init highlander_init_irq(void) ctrl_outw(0x4321, PA_IRLPRE); /* FPGA IRLE */ ctrl_outw(0x0000, PA_IRLPRF); /* FPGA IRLF */ - make_r7780rp_irq(1); /* CF card */ - make_r7780rp_irq(10); /* On-board ethernet */ + register_intc_controller(&intc_desc); + return irl2irq; } diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index 3ab5fc4b55b..afe9de73666 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c @@ -31,8 +31,8 @@ static struct resource r8a66597_usb_host_resources[] = { }, [1] = { .name = "r8a66597_hcd", - .start = 11, /* irq number */ - .end = 11, + .start = IRQ_EXT1, /* irq number */ + .end = IRQ_EXT1, .flags = IORESOURCE_IRQ, }, }; @@ -57,8 +57,8 @@ static struct resource m66592_usb_peripheral_resources[] = { }, [1] = { .name = "m66592_udc", - .start = 9, /* irq number */ - .end = 9, + .start = IRQ_EXT4, /* irq number */ + .end = IRQ_EXT4, .flags = IORESOURCE_IRQ, }, }; @@ -86,11 +86,7 @@ static struct resource cf_ide_resources[] = { .flags = IORESOURCE_MEM, }, [2] = { -#ifdef CONFIG_SH_R7780RP - .start = 4, -#else - .start = 1, -#endif + .start = IRQ_CF, .flags = IORESOURCE_IRQ, }, }; @@ -225,12 +221,50 @@ static void __init highlander_setup(char **cmdline_p) pm_power_off = r7780rp_power_off; } +static unsigned char irl2irq[HL_NR_IRL]; + +int highlander_irq_demux(int irq) +{ + if (irq >= HL_NR_IRL || !irl2irq[irq]) + return irq; + + return irl2irq[irq]; +} + +void __init highlander_init_irq(void) +{ + unsigned char *ucp = NULL; + + do { +#ifdef CONFIG_SH_R7780MP + ucp = highlander_init_irq_r7780mp(); + if (ucp) + break; +#endif +#ifdef CONFIG_SH_R7785RP + ucp = highlander_init_irq_r7785rp(); + if (ucp) + break; +#endif +#ifdef CONFIG_SH_R7780RP + highlander_init_irq_r7780rp(); + ucp = irl2irq; + break; +#endif + } while (0); + + if (ucp) { + plat_irq_setup_pins(IRQ_MODE_IRL3210); + memcpy(irl2irq, ucp, HL_NR_IRL); + } +} + /* * The Machine Vector */ static struct sh_machine_vector mv_highlander __initmv = { .mv_name = "Highlander", - .mv_nr_irqs = 109, .mv_setup = highlander_setup, .mv_init_irq = highlander_init_irq, + .mv_irq_demux = highlander_irq_demux, }; diff --git a/include/asm-sh/r7780rp.h b/include/asm-sh/r7780rp.h index 4083b594992..de37f933aa4 100644 --- a/include/asm-sh/r7780rp.h +++ b/include/asm-sh/r7780rp.h @@ -65,24 +65,6 @@ #define PA_PMR (PA_BCR+0x0900) /* */ #define IRLCNTR1 (PA_BCR + 0) /* Interrupt Control Register1 */ - -#define IRQ_PCISLOT1 65 /* PCI Slot #1 IRQ */ -#define IRQ_PCISLOT2 66 /* PCI Slot #2 IRQ */ -#define IRQ_PCISLOT3 67 /* PCI Slot #3 IRQ */ -#define IRQ_PCISLOT4 68 /* PCI Slot #4 IRQ */ -#define IRQ_TP 2 /* Touch Panel IRQ */ -#define IRQ_SCI1 3 /* SCI1 IRQ */ -#define IRQ_SCI0 4 /* SCI0 IRQ */ -#define IRQ_2SERIAL 5 /* Serial IRQ */ -#define IRQ_RTC 6 /* RTC A / B IRQ */ -#define IRQ_EXTENTION6 7 /* EXT6n IRQ */ -#define IRQ_EXTENTION5 8 /* EXT5n IRQ */ -#define IRQ_EXTENTION4 9 /* EXT4n IRQ */ -#define IRQ_EXTENTION2 10 /* EXT2n IRQ */ -#define IRQ_EXTENTION1 11 /* EXT1n IRQ */ -#define IRQ_ONETH 13 /* On board Ethernet IRQ */ -#define IRQ_PSW 14 /* Push Switch IRQ */ - #define IVDR_CK_ON 8 /* iVDR Clock ON */ #elif defined(CONFIG_SH_R7780RP) @@ -203,11 +185,24 @@ #define PA_MMSR (PA_BCR+0x0400) #define IVDR_CK_ON 4 /* iVDR Clock ON */ +#endif +#define HL_FPGA_IRQ_BASE 200 +#define HL_NR_IRL 15 + +#define IRQ_AX88796 (HL_FPGA_IRQ_BASE + 0) +#define IRQ_CF (HL_FPGA_IRQ_BASE + 1) +#ifndef IRQ_PSW +#define IRQ_PSW (HL_FPGA_IRQ_BASE + 2) #endif +#define IRQ_EXT1 (HL_FPGA_IRQ_BASE + 3) +#define IRQ_EXT4 (HL_FPGA_IRQ_BASE + 4) void make_r7780rp_irq(unsigned int irq); -void highlander_init_irq(void); + +unsigned char *highlander_init_irq_r7780mp(void); +unsigned char *highlander_init_irq_r7780rp(void); +unsigned char *highlander_init_irq_r7785rp(void); #define __IO_PREFIX r7780rp #include -- cgit v1.2.3-70-g09d2 From da6b003adc73011fd441a89c30d4f896667e24ba Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 10 Sep 2007 12:08:42 +0900 Subject: sh: add writesb(), readsb(), writesw() and readsw() to io.h This patch adds inline versions of writesb(), readsb(), writesw() and readsw() to include/asm-sh/io.h. Stolen from include/asm-avr32/io.h. These functions are needed to compile certain device drivers such as ax88796. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- include/asm-sh/io.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include/asm-sh') diff --git a/include/asm-sh/io.h b/include/asm-sh/io.h index e6a1877dcb2..1a336cdc75f 100644 --- a/include/asm-sh/io.h +++ b/include/asm-sh/io.h @@ -135,6 +135,32 @@ void __raw_readsl(unsigned long addr, void *data, int longlen); # define writel(v,a) ({ __raw_writel((v),(a)); mb(); }) #endif +#define __BUILD_MEMORY_STRING(bwlq, type) \ + \ +static inline void writes##bwlq(volatile void __iomem *mem, \ + const void *addr, unsigned int count) \ +{ \ + const volatile type *__addr = addr; \ + \ + while (count--) { \ + __raw_write##bwlq(*__addr, mem); \ + __addr++; \ + } \ +} \ + \ +static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \ + unsigned int count) \ +{ \ + volatile type *__addr = addr; \ + \ + while (count--) { \ + *__addr = __raw_read##bwlq(mem); \ + __addr++; \ + } \ +} + +__BUILD_MEMORY_STRING(b, u8) +__BUILD_MEMORY_STRING(w, u16) #define writesl __raw_writesl #define readsl __raw_readsl -- cgit v1.2.3-70-g09d2 From f12468a6fd9edc43c7beb8be461ca6927a371540 Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Tue, 11 Sep 2007 12:37:30 +0900 Subject: sh: Fix OFFCHIP_IRQ_BASE compile error. HP6xx uses OFFCHIP_IRQ_BASE to know the base irq number where non cpu interrupts should start. This define was in irq.h before, but since rework got lost. It really belongs inside hd64461.h since the hp6xx wont work without it. Signed-off-by: Kristoffer Ericson Signed-off-by: Paul Mundt --- include/asm-sh/hd64461.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-sh') diff --git a/include/asm-sh/hd64461.h b/include/asm-sh/hd64461.h index 4dd8592ca01..342ca55a266 100644 --- a/include/asm-sh/hd64461.h +++ b/include/asm-sh/hd64461.h @@ -226,6 +226,7 @@ #define HD64461_NIMR (CONFIG_HD64461_IOBASE + 0x5002) #define HD64461_IRQBASE OFFCHIP_IRQ_BASE +#define OFFCHIP_IRQ_BASE 64 #define HD64461_IRQ_NUM 16 #define HD64461_IRQ_UART (HD64461_IRQBASE+5) -- cgit v1.2.3-70-g09d2 From 4f247e84bdb81aab8880f556882a449782a1ea8b Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Tue, 11 Sep 2007 12:49:59 +0900 Subject: sh: dma: Fix up build for SH7709 support. Trivial build fixes for SH7709. Signed-off-by: Kristoffer Ericson Signed-off-by: Paul Mundt --- arch/sh/drivers/dma/dma-sh.c | 1 + include/asm-sh/cpu-sh3/dma.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'include/asm-sh') diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 6e5f16cb0aa..958bac1c585 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -27,6 +27,7 @@ static int dmte_irq_map[] = { #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ defined(CONFIG_CPU_SUBTYPE_SH7760) || \ + defined(CONFIG_CPU_SUBTYPE_SH7709) || \ defined(CONFIG_CPU_SUBTYPE_SH7780) DMTE4_IRQ, DMTE5_IRQ, diff --git a/include/asm-sh/cpu-sh3/dma.h b/include/asm-sh/cpu-sh3/dma.h index e56203086eb..54bfece328c 100644 --- a/include/asm-sh/cpu-sh3/dma.h +++ b/include/asm-sh/cpu-sh3/dma.h @@ -2,7 +2,7 @@ #define __ASM_CPU_SH3_DMA_H -#if defined(CONFIG_CPU_SUBTYPE_SH7720) +#if defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7709) #define SH_DMAC_BASE 0xa4010020 #define DMTE0_IRQ 48 -- cgit v1.2.3-70-g09d2 From d581593388e39d77acd643b1d7427c5ecbb85a03 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 11 Sep 2007 17:55:36 +0900 Subject: sh: dma: Fix CONFIG_SYSFS=n build. Trivial build fix for when sysfs is disabled. Signed-off-by: Paul Mundt --- include/asm-sh/dma.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/asm-sh') diff --git a/include/asm-sh/dma.h b/include/asm-sh/dma.h index 4c75b70b641..a65b02fd186 100644 --- a/include/asm-sh/dma.h +++ b/include/asm-sh/dma.h @@ -152,14 +152,9 @@ extern struct dma_info *get_dma_info_by_name(const char *dmac_name); extern int dma_extend(unsigned int chan, unsigned long op, void *param); extern int register_chan_caps(const char *dmac, struct dma_chan_caps *capslist); -#ifdef CONFIG_SYSFS /* arch/sh/drivers/dma/dma-sysfs.c */ extern int dma_create_sysfs_files(struct dma_channel *, struct dma_info *); extern void dma_remove_sysfs_files(struct dma_channel *, struct dma_info *); -#else -#define dma_create_sysfs_file(channel, info) do { } while (0) -#define dma_remove_sysfs_file(channel, info) do { } while (0) -#endif #ifdef CONFIG_PCI extern int isa_dma_bridge_buggy; -- cgit v1.2.3-70-g09d2 From ded5431ff311d963888ac951131a04fe7633aa79 Mon Sep 17 00:00:00 2001 From: Markus Brunner Date: Wed, 12 Sep 2007 11:54:58 +0900 Subject: sh: Magic Panel R2 board support. This adds support for the SH7720 (SH3-DSP) based Magic Panel R2 board. Signed-off-by: Markus Brunner Signed-off by: Mark Jonas Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 7 + arch/sh/Makefile | 1 + arch/sh/boards/magicpanelr2/Kconfig | 13 + arch/sh/boards/magicpanelr2/Makefile | 5 + arch/sh/boards/magicpanelr2/setup.c | 312 +++++++++++ arch/sh/configs/magicpanelr2_defconfig | 923 +++++++++++++++++++++++++++++++++ include/asm-sh/magicpanelr2.h | 67 +++ 7 files changed, 1328 insertions(+) create mode 100644 arch/sh/boards/magicpanelr2/Kconfig create mode 100644 arch/sh/boards/magicpanelr2/Makefile create mode 100644 arch/sh/boards/magicpanelr2/setup.c create mode 100644 arch/sh/configs/magicpanelr2_defconfig create mode 100644 include/asm-sh/magicpanelr2.h (limited to 'include/asm-sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index f6d6ac308f6..2c5cc0ed2e7 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -395,11 +395,18 @@ config SH_X3PROTO bool "SH-X3 Prototype board" depends on CPU_SUBTYPE_SHX3 +config SH_MAGIC_PANEL_R2 + bool "Magic Panel R2" + depends on CPU_SUBTYPE_SH7720 + help + Select Magic Panel R2 if configuring for Magic Panel R2. + endmenu source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" source "arch/sh/boards/renesas/rts7751r2d/Kconfig" source "arch/sh/boards/renesas/r7780rp/Kconfig" +source "arch/sh/boards/magicpanelr2/Kconfig" menu "Timer and clock configuration" diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 6c73a5b2b01..a0a2083aad3 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -126,6 +126,7 @@ machdir-$(CONFIG_SH_SHMIN) += shmin machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) += se/7206 machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) += se/7619 machdir-$(CONFIG_SH_LBOX_RE2) += lboxre2 +machdir-$(CONFIG_SH_MAGIC_PANEL_R2) += magicpanelr2 incdir-y := $(notdir $(machdir-y)) diff --git a/arch/sh/boards/magicpanelr2/Kconfig b/arch/sh/boards/magicpanelr2/Kconfig new file mode 100644 index 00000000000..b0abddc3e84 --- /dev/null +++ b/arch/sh/boards/magicpanelr2/Kconfig @@ -0,0 +1,13 @@ +if SH_MAGIC_PANEL_R2 + +menu "Magic Panel R2 options" + +config SH_MAGIC_PANEL_R2_VERSION + int SH_MAGIC_PANEL_R2_VERSION + default "3" + help + Set the version of the Magic Panel R2 + +endmenu + +endif diff --git a/arch/sh/boards/magicpanelr2/Makefile b/arch/sh/boards/magicpanelr2/Makefile new file mode 100644 index 00000000000..7a6d586b907 --- /dev/null +++ b/arch/sh/boards/magicpanelr2/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the Magic Panel specific parts +# + +obj-y := setup.o \ No newline at end of file diff --git a/arch/sh/boards/magicpanelr2/setup.c b/arch/sh/boards/magicpanelr2/setup.c new file mode 100644 index 00000000000..c5930656654 --- /dev/null +++ b/arch/sh/boards/magicpanelr2/setup.c @@ -0,0 +1,312 @@ +/* + * linux/arch/sh/boards/magicpanel/setup.c + * + * Copyright (C) 2007 Markus Brunner, Mark Jonas + * + * Magic Panel Release 2 board setup + * + * 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 +#include +#include +#include +#include +#include + +#define LAN9115_READY (ctrl_inl(0xA8000084UL) & 0x00000001UL) + +/* Wait until reset finished. Timeout is 100ms. */ +static int __init ethernet_reset_finished(void) +{ + int i; + + if (LAN9115_READY) + return 1; + + for (i = 0; i < 10; ++i) { + mdelay(10); + if (LAN9115_READY) + return 1; + } + + return 0; +} + +static void __init reset_ethernet(void) +{ + /* PMDR: LAN_RESET=on */ + CLRBITS_OUTB(0x10, PORT_PMDR); + + udelay(200); + + /* PMDR: LAN_RESET=off */ + SETBITS_OUTB(0x10, PORT_PMDR); +} + +static void __init setup_chip_select(void) +{ + /* CS2: LAN (0x08000000 - 0x0bffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + ctrl_outl(0x36db0400, CS2BCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + ctrl_outl(0x000003c0, CS2WCR); + + /* CS4: CAN1 (0xb0000000 - 0xb3ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + ctrl_outl(0x00000200, CS4BCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + ctrl_outl(0x00100981, CS4WCR); + + /* CS5a: CAN2 (0xb4000000 - 0xb5ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + ctrl_outl(0x00000200, CS5ABCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + ctrl_outl(0x00100981, CS5AWCR); + + /* CS5b: CAN3 (0xb6000000 - 0xb7ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + ctrl_outl(0x00000200, CS5BBCR); + /* (SW:1.5 WR:3 HW:1.5), ext. wait */ + ctrl_outl(0x00100981, CS5BWCR); + + /* CS6a: Rotary (0xb8000000 - 0xb9ffffff) */ + /* no idle cycles, normal space, 8 bit data bus */ + ctrl_outl(0x00000200, CS6ABCR); + /* (SW:1.5 WR:3 HW:1.5), no ext. wait */ + ctrl_outl(0x001009C1, CS6AWCR); +} + +static void __init setup_port_multiplexing(void) +{ + /* A7 GPO(LED8); A6 GPO(LED7); A5 GPO(LED6); A4 GPO(LED5); + * A3 GPO(LED4); A2 GPO(LED3); A1 GPO(LED2); A0 GPO(LED1); + */ + ctrl_outw(0x5555, PORT_PACR); /* 01 01 01 01 01 01 01 01 */ + + /* B7 GPO(RST4); B6 GPO(RST3); B5 GPO(RST2); B4 GPO(RST1); + * B3 GPO(PB3); B2 GPO(PB2); B1 GPO(PB1); B0 GPO(PB0); + */ + ctrl_outw(0x5555, PORT_PBCR); /* 01 01 01 01 01 01 01 01 */ + + /* C7 GPO(PC7); C6 GPO(PC6); C5 GPO(PC5); C4 GPO(PC4); + * C3 LCD_DATA3; C2 LCD_DATA2; C1 LCD_DATA1; C0 LCD_DATA0; + */ + ctrl_outw(0x5500, PORT_PCCR); /* 01 01 01 01 00 00 00 00 */ + + /* D7 GPO(PD7); D6 GPO(PD6); D5 GPO(PD5); D4 GPO(PD4); + * D3 GPO(PD3); D2 GPO(PD2); D1 GPO(PD1); D0 GPO(PD0); + */ + ctrl_outw(0x5555, PORT_PDCR); /* 01 01 01 01 01 01 01 01 */ + + /* E7 (x); E6 GPI(nu); E5 GPI(nu); E4 LCD_M_DISP; + * E3 LCD_CL1; E2 LCD_CL2; E1 LCD_DON; E0 LCD_FLM; + */ + ctrl_outw(0x3C00, PORT_PECR); /* 00 11 11 00 00 00 00 00 */ + + /* F7 (x); F6 DA1(VLCD); F5 DA0(nc); F4 AN3; + * F3 AN2(MID_AD); F2 AN1(EARTH_AD); F1 AN0(TEMP); F0 GPI+(nc); + */ + ctrl_outw(0x0002, PORT_PFCR); /* 00 00 00 00 00 00 00 10 */ + + /* G7 (x); G6 IRQ5(TOUCH_BUSY); G5 IRQ4(TOUCH_IRQ); G4 GPI(KEY2); + * G3 GPI(KEY1); G2 GPO(LED11); G1 GPO(LED10); G0 GPO(LED9); + */ + ctrl_outw(0x03D5, PORT_PGCR); /* 00 00 00 11 11 01 01 01 */ + + /* H7 (x); H6 /RAS(BRAS); H5 /CAS(BCAS); H4 CKE(BCKE); + * H3 GPO(EARTH_OFF); H2 GPO(EARTH_TEST); H1 USB2_PWR; H0 USB1_PWR; + */ + ctrl_outw(0x0050, PORT_PHCR); /* 00 00 00 00 01 01 00 00 */ + + /* J7 (x); J6 AUDCK; J5 ASEBRKAK; J4 AUDATA3; + * J3 AUDATA2; J2 AUDATA1; J1 AUDATA0; J0 AUDSYNC; + */ + ctrl_outw(0x0000, PORT_PJCR); /* 00 00 00 00 00 00 00 00 */ + + /* K7 (x); K6 (x); K5 (x); K4 (x); + * K3 PINT7(/PWR2); K2 PINT6(/PWR1); K1 PINT5(nu); K0 PINT4(FLASH_READY) + */ + ctrl_outw(0x00FF, PORT_PKCR); /* 00 00 00 00 11 11 11 11 */ + + /* L7 TRST; L6 TMS; L5 TDO; L4 TDI; + * L3 TCK; L2 (x); L1 (x); L0 (x); + */ + ctrl_outw(0x0000, PORT_PLCR); /* 00 00 00 00 00 00 00 00 */ + + /* M7 GPO(CURRENT_SINK); M6 GPO(PWR_SWITCH); M5 GPO(LAN_SPEED); + * M4 GPO(LAN_RESET); M3 GPO(BUZZER); M2 GPO(LCD_BL); + * M1 CS5B(CAN3_CS); M0 GPI+(nc); + */ + ctrl_outw(0x5552, PORT_PMCR); /* 01 01 01 01 01 01 00 10 */ + + /* CURRENT_SINK=off, PWR_SWITCH=off, LAN_SPEED=100MBit, + * LAN_RESET=off, BUZZER=off, LCD_BL=off + */ +#if CONFIG_SH_MAGIC_PANEL_R2_VERSION == 2 + ctrl_outb(0x30, PORT_PMDR); +#elif CONFIG_SH_MAGIC_PANEL_R2_VERSION == 3 + ctrl_outb(0xF0, PORT_PMDR); +#else +#error Unknown revision of PLATFORM_MP_R2 +#endif + + /* P7 (x); P6 (x); P5 (x); + * P4 GPO(nu); P3 IRQ3(LAN_IRQ); P2 IRQ2(CAN3_IRQ); + * P1 IRQ1(CAN2_IRQ); P0 IRQ0(CAN1_IRQ) + */ + ctrl_outw(0x0100, PORT_PPCR); /* 00 00 00 01 00 00 00 00 */ + ctrl_outb(0x10, PORT_PPDR); + + /* R7 A25; R6 A24; R5 A23; R4 A22; + * R3 A21; R2 A20; R1 A19; R0 A0; + */ + ctrl_outw(0x0000, PORT_PRCR); /* 00 00 00 00 00 00 00 00 */ + + /* S7 (x); S6 (x); S5 (x); S4 GPO(EEPROM_CS2); + * S3 GPO(EEPROM_CS1); S2 SIOF0_TXD; S1 SIOF0_RXD; S0 SIOF0_SCK; + */ + ctrl_outw(0x0140, PORT_PSCR); /* 00 00 00 01 01 00 00 00 */ + + /* T7 (x); T6 (x); T5 (x); T4 COM1_CTS; + * T3 COM1_RTS; T2 COM1_TXD; T1 COM1_RXD; T0 GPO(WDOG) + */ + ctrl_outw(0x0001, PORT_PTCR); /* 00 00 00 00 00 00 00 01 */ + + /* U7 (x); U6 (x); U5 (x); U4 GPI+(/AC_FAULT); + * U3 GPO(TOUCH_CS); U2 TOUCH_TXD; U1 TOUCH_RXD; U0 TOUCH_SCK; + */ + ctrl_outw(0x0240, PORT_PUCR); /* 00 00 00 10 01 00 00 00 */ + + /* V7 (x); V6 (x); V5 (x); V4 GPO(MID2); + * V3 GPO(MID1); V2 CARD_TxD; V1 CARD_RxD; V0 GPI+(/BAT_FAULT); + */ + ctrl_outw(0x0142, PORT_PVCR); /* 00 00 00 01 01 00 00 10 */ +} + +static void __init mpr2_setup(char **cmdline_p) +{ + __set_io_port_base(0xa0000000); + + /* set Pin Select Register A: + * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2, + * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND + */ + ctrl_outw(0xAABC, PORT_PSELA); + /* set Pin Select Register B: + * /SCIF0_RTS, /SCIF0_CTS, LCD_VCPWC, + * LCD_VEPWC, IIC_SDA, IIC_SCL, Reserved + */ + ctrl_outw(0x3C00, PORT_PSELB); + /* set Pin Select Register C: + * SIOF1_SCK, SIOF1_RxD, SCIF1_RxD, SCIF1_TxD, Reserved + */ + ctrl_outw(0x0000, PORT_PSELC); + /* set Pin Select Register D: Reserved, SIOF1_TxD, Reserved, SIOF1_MCLK, + * Reserved, SIOF1_SYNC, Reserved, SCIF1_SCK, Reserved + */ + ctrl_outw(0x0000, PORT_PSELD); + /* set USB TxRx Control: Reserved, DRV, Reserved, USB_TRANS, USB_SEL */ + ctrl_outw(0x0101, PORT_UTRCTL); + /* set USB Clock Control: USSCS, USSTB, Reserved (HighByte always A5) */ + ctrl_outw(0xA5C0, PORT_UCLKCR_W); + + setup_chip_select(); + + setup_port_multiplexing(); + + reset_ethernet(); + + printk(KERN_INFO "Magic Panel Release 2 A.%i\n", + CONFIG_SH_MAGIC_PANEL_R2_VERSION); + + if (ethernet_reset_finished() == 0) + printk(KERN_WARNING "Ethernet not ready\n"); +} + +static struct resource smc911x_resources[] = { + [0] = { + .start = 0xa8000000, + .end = 0xabffffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 35, + .end = 35, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc911x_device = { + .name = "smc911x", + .id = -1, + .num_resources = ARRAY_SIZE(smc911x_resources), + .resource = smc911x_resources, +}; + +static struct resource heartbeat_resources[] = { + [0] = { + .start = PA_LED, + .end = PA_LED, + .flags = IORESOURCE_MEM, + }, +}; + +static struct heartbeat_data heartbeat_data = { + .flags = HEARTBEAT_INVERTED, +}; + +static struct platform_device heartbeat_device = { + .name = "heartbeat", + .id = -1, + .dev = { + .platform_data = &heartbeat_data, + }, + .num_resources = ARRAY_SIZE(heartbeat_resources), + .resource = heartbeat_resources, +}; + +static struct platform_device *mpr2_devices[] __initdata = { + &heartbeat_device, + &smc911x_device, +}; + +static int __init mpr2_devices_setup(void) +{ + return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices)); +} +device_initcall(mpr2_devices_setup); + +/* + * Initialize IRQ setting + */ +static void __init init_mpr2_IRQ(void) +{ + plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-5 */ + + set_irq_type(32, IRQ_TYPE_LEVEL_LOW); /* IRQ0 CAN1 */ + set_irq_type(33, IRQ_TYPE_LEVEL_LOW); /* IRQ1 CAN2 */ + set_irq_type(34, IRQ_TYPE_LEVEL_LOW); /* IRQ2 CAN3 */ + set_irq_type(35, IRQ_TYPE_LEVEL_LOW); /* IRQ3 SMSC9115 */ + set_irq_type(36, IRQ_TYPE_EDGE_RISING); /* IRQ4 touchscreen */ + set_irq_type(37, IRQ_TYPE_EDGE_FALLING); /* IRQ5 touchscreen */ + + intc_set_priority(32, 13); /* IRQ0 CAN1 */ + intc_set_priority(33, 13); /* IRQ0 CAN2 */ + intc_set_priority(34, 13); /* IRQ0 CAN3 */ + intc_set_priority(35, 6); /* IRQ3 SMSC9115 */ +} + +/* + * The Machine Vector + */ + +static struct sh_machine_vector mv_mpr2 __initmv = { + .mv_name = "mpr2", + .mv_setup = mpr2_setup, + .mv_init_irq = init_mpr2_IRQ, +}; diff --git a/arch/sh/configs/magicpanelr2_defconfig b/arch/sh/configs/magicpanelr2_defconfig new file mode 100644 index 00000000000..ce4e76491be --- /dev/null +++ b/arch/sh/configs/magicpanelr2_defconfig @@ -0,0 +1,923 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.23-rc2 +# Fri Aug 17 12:15:16 2007 +# +CONFIG_SUPERH=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +CONFIG_ARCH_NO_VIRT_TO_BUS=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +# CONFIG_TASKSTATS is not set +# CONFIG_USER_NS is not set +CONFIG_AUDIT=y +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_SYSFS_DEPRECATED=y +CONFIG_RELAY=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_ANON_INODES=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_SLAB=y +# CONFIG_SLUB is not set +# CONFIG_SLOB is not set +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_KMOD=y +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set +# CONFIG_BLK_DEV_BSG is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# +# System type +# +CONFIG_CPU_SH3=y +# CONFIG_CPU_SUBTYPE_SH7619 is not set +# CONFIG_CPU_SUBTYPE_SH7206 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set +# CONFIG_CPU_SUBTYPE_SH7712 is not set +CONFIG_CPU_SUBTYPE_SH7720=y +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7751R is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set +# CONFIG_CPU_SUBTYPE_SHX3 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set +# CONFIG_CPU_SUBTYPE_SH7722 is not set + +# +# Memory management options +# +CONFIG_QUICKLIST=y +CONFIG_MMU=y +CONFIG_PAGE_OFFSET=0x80000000 +CONFIG_MEMORY_START=0x0C000000 +CONFIG_MEMORY_SIZE=0x03F00000 +CONFIG_VSYSCALL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_MAX_ACTIVE_REGIONS=1 +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_STATIC=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_NR_QUICK=2 + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +CONFIG_CACHE_WRITEBACK=y +# CONFIG_CACHE_WRITETHROUGH is not set +# CONFIG_CACHE_OFF is not set + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set +# CONFIG_SH_FPU_EMU is not set +CONFIG_SH_DSP=y +CONFIG_SH_ADC=y +CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_INTC_IRQ=y +CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_DSP=y + +# +# Board support +# +CONFIG_SH_MAGIC_PANEL_R2=y + +# +# Magic Panel R2 options +# +CONFIG_SH_MAGIC_PANEL_R2_VERSION=2 + +# +# Timer and clock configuration +# +CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 +CONFIG_SH_PCLK_FREQ=24000000 +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +CONFIG_SH_DMA_API=y +CONFIG_SH_DMA=y +CONFIG_NR_ONCHIP_DMA_CHANNELS=6 +# CONFIG_NR_DMA_CHANNELS_BOOL is not set + +# +# Companion Chips +# + +# +# Additional SuperH Device Drivers +# +CONFIG_HEARTBEAT=y +# CONFIG_PUSH_SWITCH is not set + +# +# Kernel features +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +# CONFIG_ARCH_SUPPORTS_MSI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_AF_RXRPC is not set + +# +# Wireless +# +# CONFIG_CFG80211 is not set +# CONFIG_WIRELESS_EXT is not set +# CONFIG_MAC80211 is not set +# CONFIG_IEEE80211 is not set +# CONFIG_RFKILL is not set +# CONFIG_NET_9P is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_FW_LOADER=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +CONFIG_MTD_CMDLINE_PARTS=y + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_SOLUTIONENGINE is not set +CONFIG_MTD_MAGICPANELR2=y +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +# CONFIG_MTD_NAND is not set +# CONFIG_MTD_ONENAND is not set + +# +# UBI - Unsorted block images +# +# CONFIG_MTD_UBI is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +CONFIG_MISC_DEVICES=y +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEVICES_MULTIQUEUE is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_PHYLIB is not set +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +# CONFIG_SMC91X is not set +CONFIG_SMC911X=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set + +# +# Wireless LAN +# +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_WLAN_80211 is not set +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_INPUT_MOUSE=y +# CONFIG_MOUSE_PS2 is not set +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=48 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_EXTENDED=y +# CONFIG_SERIAL_8250_MANY_PORTS is not set +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=2 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set +# CONFIG_W1 is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_HWMON is not set + +# +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set +# CONFIG_DVB_CORE is not set +CONFIG_DAB=y + +# +# Graphics support +# +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +# CONFIG_FB is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set +# CONFIG_HID_SUPPORT is not set +# CONFIG_USB_SUPPORT is not set +# CONFIG_MMC is not set +# CONFIG_NEW_LEDS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_HCTOSYS is not set +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# SPI RTC drivers +# + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_SH=y + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Userspace I/O +# +# CONFIG_UIO is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WRITEBUFFER is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_BIND34=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="cp437" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_SCHED_DEBUG is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_LOCK_STAT is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_DEBUG_KOBJECT=y +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +# CONFIG_FORCED_INLINING is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_SH_STANDARD_BIOS is not set +CONFIG_EARLY_SCIF_CONSOLE=y +CONFIG_EARLY_SCIF_CONSOLE_PORT=0xa4430000 +CONFIG_EARLY_PRINTK=y +# CONFIG_DEBUG_BOOTMEM is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_4KSTACKS is not set +CONFIG_SH_KGDB=y + +# +# KGDB configuration options +# +# CONFIG_MORE_COMPILE_OPTIONS is not set +# CONFIG_KGDB_NMI is not set +CONFIG_KGDB_SYSRQ=y + +# +# Serial port setup +# +CONFIG_KGDB_DEFPORT=0 +CONFIG_KGDB_DEFBAUD=115200 +CONFIG_KGDB_DEFPARITY_N=y +# CONFIG_KGDB_DEFPARITY_E is not set +# CONFIG_KGDB_DEFPARITY_O is not set +CONFIG_KGDB_DEFBITS_8=y +# CONFIG_KGDB_DEFBITS_7 is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAS_DMA=y diff --git a/include/asm-sh/magicpanelr2.h b/include/asm-sh/magicpanelr2.h new file mode 100644 index 00000000000..c644a77ee35 --- /dev/null +++ b/include/asm-sh/magicpanelr2.h @@ -0,0 +1,67 @@ +/* + * include/asm-sh/magicpanelr2.h + * + * Copyright (C) 2007 Markus Brunner, Mark Jonas + * + * I/O addresses and bitmasks for Magic Panel Release 2 board + * + * 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. + */ + +#ifndef __ASM_SH_MAGICPANELR2_H +#define __ASM_SH_MAGICPANELR2_H + +#include + +#define __IO_PREFIX mpr2 +#include + + +#define SETBITS_OUTB(mask, reg) ctrl_outb(ctrl_inb(reg) | mask, reg) +#define SETBITS_OUTW(mask, reg) ctrl_outw(ctrl_inw(reg) | mask, reg) +#define SETBITS_OUTL(mask, reg) ctrl_outl(ctrl_inl(reg) | mask, reg) +#define CLRBITS_OUTB(mask, reg) ctrl_outb(ctrl_inb(reg) & ~mask, reg) +#define CLRBITS_OUTW(mask, reg) ctrl_outw(ctrl_inw(reg) & ~mask, reg) +#define CLRBITS_OUTL(mask, reg) ctrl_outl(ctrl_inl(reg) & ~mask, reg) + + +#define PA_LED PORT_PADR /* LED */ + + +/* BSC */ +#define CMNCR 0xA4FD0000UL +#define CS0BCR 0xA4FD0004UL +#define CS2BCR 0xA4FD0008UL +#define CS3BCR 0xA4FD000CUL +#define CS4BCR 0xA4FD0010UL +#define CS5ABCR 0xA4FD0014UL +#define CS5BBCR 0xA4FD0018UL +#define CS6ABCR 0xA4FD001CUL +#define CS6BBCR 0xA4FD0020UL +#define CS0WCR 0xA4FD0024UL +#define CS2WCR 0xA4FD0028UL +#define CS3WCR 0xA4FD002CUL +#define CS4WCR 0xA4FD0030UL +#define CS5AWCR 0xA4FD0034UL +#define CS5BWCR 0xA4FD0038UL +#define CS6AWCR 0xA4FD003CUL +#define CS6BWCR 0xA4FD0040UL + + +/* usb */ + +#define PORT_UTRCTL 0xA405012CUL +#define PORT_UCLKCR_W 0xA40A0008UL + +#define INTC_ICR0 0xA414FEE0UL +#define INTC_ICR1 0xA4140010UL +#define INTC_ICR2 0xA4140012UL + +/* MTD */ + +#define MPR2_MTD_BOOTLOADER_SIZE 0x00060000UL +#define MPR2_MTD_KERNEL_SIZE 0x00200000UL + +#endif /* __ASM_SH_MAGICPANELR2_H */ -- cgit v1.2.3-70-g09d2 From d04a0f79f502a87bb17b147afc4b3e39e75275c3 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 21 Sep 2007 11:55:03 +0900 Subject: sh: Fix up extended mode TLB for SH-X2+ cores. The extended mode TLB requires both 64-bit PTEs and a 64-bit pgprot, correspondingly, the PGD also has to be 64-bits, so fix that up. The kernel and user permission bits really are decoupled in early cuts of the silicon, which means that we also have to set corresponding kernel permissions on user pages or we end up with user pages that the kernel simply can't touch (!). Finally, with those things corrected, really enable MMUCR.ME and correct the PTEA value (this simply needs to be the upper 32-bits of the PTE, with the size and protection bit encoding). Signed-off-by: Paul Mundt --- arch/sh/mm/tlb-sh4.c | 30 ++++------ include/asm-sh/cpu-sh4/mmu_context.h | 14 ++++- include/asm-sh/page.h | 4 +- include/asm-sh/pgtable.h | 112 +++++++++++++++++++---------------- 4 files changed, 88 insertions(+), 72 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/mm/tlb-sh4.c b/arch/sh/mm/tlb-sh4.c index 13fde8cc717..2d1dd604430 100644 --- a/arch/sh/mm/tlb-sh4.c +++ b/arch/sh/mm/tlb-sh4.c @@ -4,27 +4,14 @@ * SH-4 specific TLB operations * * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2002 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt * * Released under the terms of the GNU GPL v2.0. */ -#include -#include #include -#include -#include -#include -#include -#include #include -#include -#include -#include - +#include #include -#include -#include -#include #include #include @@ -62,12 +49,22 @@ void update_mmu_cache(struct vm_area_struct * vma, vpn = (address & MMU_VPN_MASK) | get_asid(); ctrl_outl(vpn, MMU_PTEH); - pteval = pte_val(pte); + pteval = pte.pte_low; /* Set PTEA register */ +#ifdef CONFIG_X2TLB + /* + * For the extended mode TLB this is trivial, only the ESZ and + * EPR bits need to be written out to PTEA, with the remainder of + * the protection bits (with the exception of the compat-mode SZ + * and PR bits, which are cleared) being written out in PTEL. + */ + ctrl_outl(pte.pte_high, MMU_PTEA); +#else if (cpu_data->flags & CPU_HAS_PTEA) /* TODO: make this look less hacky */ ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA); +#endif /* Set PTEL register */ pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ @@ -98,4 +95,3 @@ void local_flush_tlb_one(unsigned long asid, unsigned long page) ctrl_outl(data, addr); back_to_P1(); } - diff --git a/include/asm-sh/cpu-sh4/mmu_context.h b/include/asm-sh/cpu-sh4/mmu_context.h index ff4c5fbbfaf..979acddc0f8 100644 --- a/include/asm-sh/cpu-sh4/mmu_context.h +++ b/include/asm-sh/cpu-sh4/mmu_context.h @@ -22,13 +22,21 @@ #define MMU_UTLB_ADDRESS_ARRAY 0xF6000000 #define MMU_PAGE_ASSOC_BIT 0x80 -#define MMU_NTLB_ENTRIES 64 /* for 7750 */ +#ifdef CONFIG_X2TLB +#define MMUCR_ME (1 << 7) +#else +#define MMUCR_ME (0) +#endif + #ifdef CONFIG_SH_STORE_QUEUES -#define MMU_CONTROL_INIT 0x05 /* SQMD=0, SV=0, TI=1, AT=1 */ +#define MMUCR_SQMD (1 << 9) #else -#define MMU_CONTROL_INIT 0x205 /* SQMD=1, SV=0, TI=1, AT=1 */ +#define MMUCR_SQMD (0) #endif +#define MMU_NTLB_ENTRIES 64 +#define MMU_CONTROL_INIT (0x05|MMUCR_SQMD|MMUCR_ME) + #define MMU_ITLB_DATA_ARRAY 0xF3000000 #define MMU_UTLB_DATA_ARRAY 0xF7000000 diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index 48b718e7455..cb3d46c59ea 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -88,6 +88,7 @@ extern void __copy_user_page(void *to, void *from, void *orig_to); #ifdef CONFIG_X2TLB typedef struct { unsigned long pte_low, pte_high; } pte_t; typedef struct { unsigned long long pgprot; } pgprot_t; +typedef struct { unsigned long long pgd; } pgd_t; #define pte_val(x) \ ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) #define __pte(x) \ @@ -95,12 +96,11 @@ typedef struct { unsigned long long pgprot; } pgprot_t; #else typedef struct { unsigned long pte_low; } pte_t; typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct { unsigned long pgd; } pgd_t; #define pte_val(x) ((x).pte_low) #define __pte(x) ((pte_t) { (x) } ) #endif -typedef struct { unsigned long pgd; } pgd_t; - #define pgd_val(x) ((x).pgd) #define pgprot_val(x) ((x).pgprot) diff --git a/include/asm-sh/pgtable.h b/include/asm-sh/pgtable.h index 54ad5037fe4..cf0dd2b648c 100644 --- a/include/asm-sh/pgtable.h +++ b/include/asm-sh/pgtable.h @@ -42,13 +42,12 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; /* PGD bits */ #define PGDIR_SHIFT (PTE_SHIFT + PTE_BITS) -#define PGDIR_BITS (32 - PGDIR_SHIFT) #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) /* Entries per level */ #define PTRS_PER_PTE (PAGE_SIZE / (1 << PTE_MAGNITUDE)) -#define PTRS_PER_PGD (PAGE_SIZE / 4) +#define PTRS_PER_PGD (PAGE_SIZE / sizeof(pgd_t)) #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) #define FIRST_USER_ADDRESS 0 @@ -100,17 +99,18 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define _PAGE_HW_SHARED 0x002 /* SH-bit : shared among processes */ #define _PAGE_DIRTY 0x004 /* D-bit : page changed */ #define _PAGE_CACHABLE 0x008 /* C-bit : cachable */ -#ifndef CONFIG_X2TLB -# define _PAGE_SZ0 0x010 /* SZ0-bit : Size of page */ -# define _PAGE_RW 0x020 /* PR0-bit : write access allowed */ -# define _PAGE_USER 0x040 /* PR1-bit : user space access allowed*/ -# define _PAGE_SZ1 0x080 /* SZ1-bit : Size of page (on SH-4) */ -#endif +#define _PAGE_SZ0 0x010 /* SZ0-bit : Size of page */ +#define _PAGE_RW 0x020 /* PR0-bit : write access allowed */ +#define _PAGE_USER 0x040 /* PR1-bit : user space access allowed*/ +#define _PAGE_SZ1 0x080 /* SZ1-bit : Size of page (on SH-4) */ #define _PAGE_PRESENT 0x100 /* V-bit : page is valid */ #define _PAGE_PROTNONE 0x200 /* software: if not present */ #define _PAGE_ACCESSED 0x400 /* software: page referenced */ #define _PAGE_FILE _PAGE_WT /* software: pagecache or swap? */ +#define _PAGE_SZ_MASK (_PAGE_SZ0 | _PAGE_SZ1) +#define _PAGE_PR_MASK (_PAGE_RW | _PAGE_USER) + /* Extended mode bits */ #define _PAGE_EXT_ESZ0 0x0010 /* ESZ0-bit: Size of page */ #define _PAGE_EXT_ESZ1 0x0020 /* ESZ1-bit: Size of page */ @@ -126,11 +126,7 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define _PAGE_EXT_KERN_READ 0x2000 /* EPR5-bit: Kernel space readable */ /* Wrapper for extended mode pgprot twiddling */ -#ifdef CONFIG_X2TLB -# define _PAGE_EXT(x) ((unsigned long long)(x) << 32) -#else -# define _PAGE_EXT(x) (0) -#endif +#define _PAGE_EXT(x) ((unsigned long long)(x) << 32) /* software: moves to PTEA.TC (Timing Control) */ #define _PAGE_PCC_AREA5 0x00000000 /* use BSC registers for area5 */ @@ -146,10 +142,14 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define _PAGE_PCC_ATR16 0x60000001 /* Attribute Memory space, 6 bit bus */ /* Mask which drops unused bits from the PTEL value */ -#ifdef CONFIG_CPU_SH3 +#if defined(CONFIG_CPU_SH3) #define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED| \ _PAGE_FILE | _PAGE_SZ1 | \ _PAGE_HW_SHARED) +#elif defined(CONFIG_X2TLB) +/* Get rid of the legacy PR/SZ bits when using extended mode */ +#define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED | \ + _PAGE_FILE | _PAGE_PR_MASK | _PAGE_SZ_MASK) #else #define _PAGE_CLEAR_FLAGS (_PAGE_PROTNONE | _PAGE_ACCESSED | _PAGE_FILE) #endif @@ -212,27 +212,36 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]; #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_USER_READ | \ + _PAGE_EXT(_PAGE_EXT_KERN_READ | \ + _PAGE_EXT_KERN_WRITE | \ + _PAGE_EXT_USER_READ | \ _PAGE_EXT_USER_WRITE)) #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_USER_EXEC | \ + _PAGE_EXT(_PAGE_EXT_KERN_EXEC | \ + _PAGE_EXT_KERN_READ | \ + _PAGE_EXT_USER_EXEC | \ _PAGE_EXT_USER_READ)) #define PAGE_COPY PAGE_EXECREAD #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_USER_READ)) + _PAGE_EXT(_PAGE_EXT_KERN_READ | \ + _PAGE_EXT_USER_READ)) #define PAGE_WRITEONLY __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_USER_WRITE)) + _PAGE_EXT(_PAGE_EXT_KERN_WRITE | \ + _PAGE_EXT_USER_WRITE)) #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \ _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \ - _PAGE_EXT(_PAGE_EXT_USER_WRITE | \ + _PAGE_EXT(_PAGE_EXT_KERN_WRITE | \ + _PAGE_EXT_KERN_READ | \ + _PAGE_EXT_KERN_EXEC | \ + _PAGE_EXT_USER_WRITE | \ _PAGE_EXT_USER_READ | \ _PAGE_EXT_USER_EXEC)) @@ -373,11 +382,15 @@ static inline void set_pte(pte_t *ptep, pte_t pte) #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) #define pte_pfn(x) ((unsigned long)(((x).pte_low >> PAGE_SHIFT))) -#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) -#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot)) -#define pte_none(x) (!pte_val(x)) -#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) +#define pfn_pte(pfn, prot) \ + __pte(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot)) +#define pfn_pmd(pfn, prot) \ + __pmd(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot)) + +#define pte_none(x) (!pte_val(x)) +#define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE)) + #define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) #define pmd_none(x) (!pmd_val(x)) @@ -392,15 +405,15 @@ static inline void set_pte(pte_t *ptep, pte_t pte) * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -#define pte_not_present(pte) (!(pte_val(pte) & _PAGE_PRESENT)) -#define pte_dirty(pte) (pte_val(pte) & _PAGE_DIRTY) -#define pte_young(pte) (pte_val(pte) & _PAGE_ACCESSED) -#define pte_file(pte) (pte_val(pte) & _PAGE_FILE) +#define pte_not_present(pte) (!((pte).pte_low & _PAGE_PRESENT)) +#define pte_dirty(pte) ((pte).pte_low & _PAGE_DIRTY) +#define pte_young(pte) ((pte).pte_low & _PAGE_ACCESSED) +#define pte_file(pte) ((pte).pte_low & _PAGE_FILE) #ifdef CONFIG_X2TLB #define pte_write(pte) ((pte).pte_high & _PAGE_EXT_USER_WRITE) #else -#define pte_write(pte) (pte_val(pte) & _PAGE_RW) +#define pte_write(pte) ((pte).pte_low & _PAGE_RW) #endif #define PTE_BIT_FUNC(h,fn,op) \ @@ -429,17 +442,10 @@ PTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED); /* * Macro and implementation to make a page protection as uncachable. */ -#define pgprot_noncached pgprot_noncached +#define pgprot_writecombine(prot) \ + __pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE) -static inline pgprot_t pgprot_noncached(pgprot_t _prot) -{ - unsigned long prot = pgprot_val(_prot); - - prot &= ~_PAGE_CACHABLE; - return __pgprot(prot); -} - -#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE) +#define pgprot_noncached pgprot_writecombine /* * Conversion functions: convert a page and protection to a page entry, @@ -451,28 +457,33 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | - pgprot_val(newprot))); + pte.pte_low &= _PAGE_CHG_MASK; + pte.pte_low |= pgprot_val(newprot); + +#ifdef CONFIG_X2TLB + pte.pte_high |= pgprot_val(newprot) >> 32; +#endif + return pte; } -#define pmd_page_vaddr(pmd) pmd_val(pmd) +#define pmd_page_vaddr(pmd) ((unsigned long)pmd_val(pmd)) #define pmd_page(pmd) (virt_to_page(pmd_val(pmd))) /* to find an entry in a page-table-directory. */ -#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) -#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) +#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) +#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) /* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k(address) pgd_offset(&init_mm, address) +#define pgd_offset_k(address) pgd_offset(&init_mm, address) /* Find an entry in the third-level page table.. */ -#define pte_index(address) \ - ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_index(address) ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) #define pte_offset_kernel(dir, address) \ ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address)) -#define pte_offset_map(dir, address) pte_offset_kernel(dir, address) -#define pte_offset_map_nested(dir, address) pte_offset_kernel(dir, address) +#define pte_offset_map(dir, address) pte_offset_kernel(dir, address) +#define pte_offset_map_nested(dir, address) pte_offset_kernel(dir, address) + #define pte_unmap(pte) do { } while (0) #define pte_unmap_nested(pte) do { } while (0) @@ -480,13 +491,14 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pte_ERROR(e) \ printk("%s:%d: bad pte %p(%08lx%08lx).\n", __FILE__, __LINE__, \ &(e), (e).pte_high, (e).pte_low) +#define pgd_ERROR(e) \ + printk("%s:%d: bad pgd %016llx.\n", __FILE__, __LINE__, pgd_val(e)) #else #define pte_ERROR(e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) -#endif - #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) +#endif struct vm_area_struct; extern void update_mmu_cache(struct vm_area_struct * vma, -- cgit v1.2.3-70-g09d2 From 17be2d2b1c333e1e4c378369ba90ab2dd11c589a Mon Sep 17 00:00:00 2001 From: Adrian McMenamin Date: Fri, 21 Sep 2007 15:55:55 +0900 Subject: sh: Add maple bus support for the SEGA Dreamcast. The Maple bus is SEGA's proprietary serial bus for peripherals (keyboard, mouse, controller etc). The bus is capable of some (limited) hotplugging and operates at up to 2 M/bits. Drivers of one sort or another existed/exist for 2.4 and a rudimentary port, which didn't support the 2.6 device driver model was also in existence. This driver - for the bus logic itself and for the keyboard (other drivers will follow) are based on the code and concepts of those old drivers but have lots of completely rewritten parts. I have the maple bus code as a built in now as that seems the sane and rational way to handle something like that - you either want the bus or you don't. Signed-off-by: Adrian McMenamin Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 11 + drivers/sh/Makefile | 4 +- drivers/sh/maple/Makefile | 3 + drivers/sh/maple/maple.c | 735 +++++++++++++++++++++++++++++++++++++++ include/asm-sh/dreamcast/maple.h | 37 ++ include/linux/maple.h | 80 +++++ 6 files changed, 868 insertions(+), 2 deletions(-) create mode 100644 drivers/sh/maple/Makefile create mode 100644 drivers/sh/maple/maple.c create mode 100644 include/asm-sh/dreamcast/maple.h create mode 100644 include/linux/maple.h (limited to 'include/asm-sh') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 2c5cc0ed2e7..51bccbc554c 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -666,6 +666,17 @@ config SUPERHYWAY tristate "SuperHyway Bus support" depends on CPU_SUBTYPE_SH4_202 +config MAPLE + bool "Maple Bus support" + depends on SH_DREAMCAST + help + The Maple Bus is SEGA's serial communication bus for peripherals + on the Dreamcast. Without this bus support you won't be able to + get your Dreamcast keyboard etc to work, so most users + probably want to say 'Y' here, unless you are only using the + Dreamcast with a serial line terminal or a remote network + connection. + config CF_ENABLER bool "Compact Flash Enabler support" depends on SOLUTION_ENGINE || SH_SH03 diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile index 8a143894e33..a96f4a8cfeb 100644 --- a/drivers/sh/Makefile +++ b/drivers/sh/Makefile @@ -2,5 +2,5 @@ # Makefile for the SuperH specific drivers. # -obj-$(CONFIG_SUPERHYWAY) += superhyway/ - +obj-$(CONFIG_SUPERHYWAY) += superhyway/ +obj-$(CONFIG_MAPLE) += maple/ diff --git a/drivers/sh/maple/Makefile b/drivers/sh/maple/Makefile new file mode 100644 index 00000000000..65dfeeb610e --- /dev/null +++ b/drivers/sh/maple/Makefile @@ -0,0 +1,3 @@ +# Makefile for Maple Bus + +obj-$(CONFIG_MAPLE) := maple.o diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c new file mode 100644 index 00000000000..161d1021b7e --- /dev/null +++ b/drivers/sh/maple/maple.c @@ -0,0 +1,735 @@ +/* + * Core maple bus functionality + * + * Copyright (C) 2007 Adrian McMenamin + * + * Based on 2.4 code by: + * + * Copyright (C) 2000-2001 YAEGASHI Takeshi + * Copyright (C) 2001 M. R. Brown + * Copyright (C) 2001 Paul Mundt + * + * and others. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Yaegshi Takeshi, Paul Mundt, M.R. Brown, Adrian McMenamin"); +MODULE_DESCRIPTION("Maple bus driver for Dreamcast"); +MODULE_LICENSE("GPL v2"); +MODULE_SUPPORTED_DEVICE("{{SEGA, Dreamcast/Maple}}"); + +static void maple_dma_handler(struct work_struct *work); +static void maple_vblank_handler(struct work_struct *work); + +static DECLARE_WORK(maple_dma_process, maple_dma_handler); +static DECLARE_WORK(maple_vblank_process, maple_vblank_handler); + +static LIST_HEAD(maple_waitq); +static LIST_HEAD(maple_sentq); + +static DEFINE_MUTEX(maple_list_lock); + +static struct maple_driver maple_dummy_driver; +static struct device maple_bus; +static int subdevice_map[MAPLE_PORTS]; +static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr; +static unsigned long maple_pnp_time; +static int started, scanning, liststatus; +static struct kmem_cache *maple_queue_cache; + +struct maple_device_specify { + int port; + int unit; +}; + +/** + * maple_driver_register - register a device driver + * automatically makes the driver bus a maple bus + * @drv: the driver to be registered + */ +int maple_driver_register(struct device_driver *drv) +{ + if (!drv) + return -EINVAL; + drv->bus = &maple_bus_type; + return driver_register(drv); +} +EXPORT_SYMBOL_GPL(maple_driver_register); + +/* set hardware registers to enable next round of dma */ +static void maplebus_dma_reset(void) +{ + ctrl_outl(MAPLE_MAGIC, MAPLE_RESET); + /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */ + ctrl_outl(1, MAPLE_TRIGTYPE); + ctrl_outl(MAPLE_2MBPS | MAPLE_TIMEOUT(50000), MAPLE_SPEED); + ctrl_outl(PHYSADDR(maple_sendbuf), MAPLE_DMAADDR); + ctrl_outl(1, MAPLE_ENABLE); +} + +/** + * maple_getcond_callback - setup handling MAPLE_COMMAND_GETCOND + * @dev: device responding + * @callback: handler callback + * @interval: interval in jiffies between callbacks + * @function: the function code for the device + */ +void maple_getcond_callback(struct maple_device *dev, + void (*callback) (struct mapleq * mq), + unsigned long interval, unsigned long function) +{ + dev->callback = callback; + dev->interval = interval; + dev->function = cpu_to_be32(function); + dev->when = jiffies; +} +EXPORT_SYMBOL_GPL(maple_getcond_callback); + +static int maple_dma_done(void) +{ + return (ctrl_inl(MAPLE_STATE) & 1) == 0; +} + +static void maple_release_device(struct device *dev) +{ + if (dev->type) { + kfree(dev->type->name); + kfree(dev->type); + } +} + +/** + * maple_add_packet - add a single instruction to the queue + * @mq: instruction to add to waiting queue + */ +void maple_add_packet(struct mapleq *mq) +{ + mutex_lock(&maple_list_lock); + list_add(&mq->list, &maple_waitq); + mutex_unlock(&maple_list_lock); +} +EXPORT_SYMBOL_GPL(maple_add_packet); + +static struct mapleq *maple_allocq(struct maple_device *dev) +{ + struct mapleq *mq; + + mq = kmalloc(sizeof(*mq), GFP_KERNEL); + if (!mq) + return NULL; + + mq->dev = dev; + mq->recvbufdcsp = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL); + mq->recvbuf = (void *) P2SEGADDR(mq->recvbufdcsp); + if (!mq->recvbuf) { + kfree(mq); + return NULL; + } + + return mq; +} + +static struct maple_device *maple_alloc_dev(int port, int unit) +{ + struct maple_device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + + dev->port = port; + dev->unit = unit; + dev->mq = maple_allocq(dev); + + if (!dev->mq) { + kfree(dev); + return NULL; + } + + return dev; +} + +static void maple_free_dev(struct maple_device *mdev) +{ + if (!mdev) + return; + if (mdev->mq) { + kmem_cache_free(maple_queue_cache, mdev->mq->recvbufdcsp); + kfree(mdev->mq); + } + kfree(mdev); +} + +/* process the command queue into a maple command block + * terminating command has bit 32 of first long set to 0 + */ +static void maple_build_block(struct mapleq *mq) +{ + int port, unit, from, to, len; + unsigned long *lsendbuf = mq->sendbuf; + + port = mq->dev->port & 3; + unit = mq->dev->unit; + len = mq->length; + from = port << 6; + to = (port << 6) | (unit > 0 ? (1 << (unit - 1)) & 0x1f : 0x20); + + *maple_lastptr &= 0x7fffffff; + maple_lastptr = maple_sendptr; + + *maple_sendptr++ = (port << 16) | len | 0x80000000; + *maple_sendptr++ = PHYSADDR(mq->recvbuf); + *maple_sendptr++ = + mq->command | (to << 8) | (from << 16) | (len << 24); + + while (len-- > 0) + *maple_sendptr++ = *lsendbuf++; +} + +/* build up command queue */ +static void maple_send(void) +{ + int i; + int maple_packets; + struct mapleq *mq, *nmq; + + if (!list_empty(&maple_sentq)) + return; + if (list_empty(&maple_waitq) || !maple_dma_done()) + return; + maple_packets = 0; + maple_sendptr = maple_lastptr = maple_sendbuf; + list_for_each_entry_safe(mq, nmq, &maple_waitq, list) { + maple_build_block(mq); + list_move(&mq->list, &maple_sentq); + if (maple_packets++ > MAPLE_MAXPACKETS) + break; + } + if (maple_packets > 0) { + for (i = 0; i < (1 << MAPLE_DMA_PAGES); i++) + dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE, + PAGE_SIZE, DMA_BIDIRECTIONAL); + } +} + +static int attach_matching_maple_driver(struct device_driver *driver, + void *devptr) +{ + struct maple_driver *maple_drv; + struct maple_device *mdev; + + mdev = devptr; + maple_drv = to_maple_driver(driver); + if (mdev->devinfo.function & be32_to_cpu(maple_drv->function)) { + if (maple_drv->connect(mdev) == 0) { + mdev->driver = maple_drv; + return 1; + } + } + return 0; +} + +static void maple_detach_driver(struct maple_device *mdev) +{ + if (!mdev) + return; + if (mdev->driver) { + if (mdev->driver->disconnect) + mdev->driver->disconnect(mdev); + } + mdev->driver = NULL; + if (mdev->registered) { + maple_release_device(&mdev->dev); + device_unregister(&mdev->dev); + } + mdev->registered = 0; + maple_free_dev(mdev); +} + +/* process initial MAPLE_COMMAND_DEVINFO for each device or port */ +static void maple_attach_driver(struct maple_device *dev) +{ + char *p; + + char *recvbuf; + unsigned long function; + int matched, retval; + + recvbuf = dev->mq->recvbuf; + memcpy(&dev->devinfo, recvbuf + 4, sizeof(dev->devinfo)); + memcpy(dev->product_name, dev->devinfo.product_name, 30); + memcpy(dev->product_licence, dev->devinfo.product_licence, 60); + dev->product_name[30] = '\0'; + dev->product_licence[60] = '\0'; + + for (p = dev->product_name + 29; dev->product_name <= p; p--) + if (*p == ' ') + *p = '\0'; + else + break; + + for (p = dev->product_licence + 59; dev->product_licence <= p; p--) + if (*p == ' ') + *p = '\0'; + else + break; + + function = be32_to_cpu(dev->devinfo.function); + + if (function > 0x200) { + /* Do this silently - as not a real device */ + function = 0; + dev->driver = &maple_dummy_driver; + sprintf(dev->dev.bus_id, "%d:0.port", dev->port); + } else { + printk(KERN_INFO + "Maple bus at (%d, %d): Connected function 0x%lX\n", + dev->port, dev->unit, function); + + matched = + bus_for_each_drv(&maple_bus_type, NULL, dev, + attach_matching_maple_driver); + + if (matched == 0) { + /* Driver does not exist yet */ + printk(KERN_INFO + "No maple driver found for this device\n"); + dev->driver = &maple_dummy_driver; + } + + sprintf(dev->dev.bus_id, "%d:0%d.%lX", dev->port, + dev->unit, function); + } + dev->function = function; + dev->dev.bus = &maple_bus_type; + dev->dev.parent = &maple_bus; + dev->dev.release = &maple_release_device; + retval = device_register(&dev->dev); + if (retval) { + printk(KERN_INFO + "Maple bus: Attempt to register device (%x, %x) failed.\n", + dev->port, dev->unit); + maple_free_dev(dev); + } + dev->registered = 1; +} + +/* + * if device has been registered for the given + * port and unit then return 1 - allows identification + * of which devices need to be attached or detached + */ +static int detach_maple_device(struct device *device, void *portptr) +{ + struct maple_device_specify *ds; + struct maple_device *mdev; + + ds = portptr; + mdev = to_maple_dev(device); + if (mdev->port == ds->port && mdev->unit == ds->unit) + return 1; + return 0; +} + +static int setup_maple_commands(struct device *device, void *ignored) +{ + struct maple_device *maple_dev = to_maple_dev(device); + + if ((maple_dev->interval > 0) + && time_after(jiffies, maple_dev->when)) { + maple_dev->when = jiffies + maple_dev->interval; + maple_dev->mq->command = MAPLE_COMMAND_GETCOND; + maple_dev->mq->sendbuf = &maple_dev->function; + maple_dev->mq->length = 1; + maple_add_packet(maple_dev->mq); + liststatus++; + } else { + if (time_after(jiffies, maple_pnp_time)) { + maple_dev->mq->command = MAPLE_COMMAND_DEVINFO; + maple_dev->mq->length = 0; + maple_add_packet(maple_dev->mq); + liststatus++; + } + } + + return 0; +} + +/* VBLANK bottom half - implemented via workqueue */ +static void maple_vblank_handler(struct work_struct *work) +{ + if (!maple_dma_done()) + return; + if (!list_empty(&maple_sentq)) + return; + ctrl_outl(0, MAPLE_ENABLE); + liststatus = 0; + bus_for_each_dev(&maple_bus_type, NULL, NULL, + setup_maple_commands); + if (time_after(jiffies, maple_pnp_time)) + maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL; + if (liststatus && list_empty(&maple_sentq)) { + INIT_LIST_HEAD(&maple_sentq); + maple_send(); + } + maplebus_dma_reset(); +} + +/* handle devices added via hotplugs - placing them on queue for DEVINFO*/ +static void maple_map_subunits(struct maple_device *mdev, int submask) +{ + int retval, k, devcheck; + struct maple_device *mdev_add; + struct maple_device_specify ds; + + for (k = 0; k < 5; k++) { + ds.port = mdev->port; + ds.unit = k + 1; + retval = + bus_for_each_dev(&maple_bus_type, NULL, &ds, + detach_maple_device); + if (retval) { + submask = submask >> 1; + continue; + } + devcheck = submask & 0x01; + if (devcheck) { + mdev_add = maple_alloc_dev(mdev->port, k + 1); + if (!mdev_add) + return; + mdev_add->mq->command = MAPLE_COMMAND_DEVINFO; + mdev_add->mq->length = 0; + maple_add_packet(mdev_add->mq); + scanning = 1; + } + submask = submask >> 1; + } +} + +/* mark a device as removed */ +static void maple_clean_submap(struct maple_device *mdev) +{ + int killbit; + + killbit = (mdev->unit > 0 ? (1 << (mdev->unit - 1)) & 0x1f : 0x20); + killbit = ~killbit; + killbit &= 0xFF; + subdevice_map[mdev->port] = subdevice_map[mdev->port] & killbit; +} + +/* handle empty port or hotplug removal */ +static void maple_response_none(struct maple_device *mdev, + struct mapleq *mq) +{ + if (mdev->unit != 0) { + list_del(&mq->list); + maple_clean_submap(mdev); + printk(KERN_INFO + "Maple bus device detaching at (%d, %d)\n", + mdev->port, mdev->unit); + maple_detach_driver(mdev); + return; + } + if (!started) { + printk(KERN_INFO "No maple devices attached to port %d\n", + mdev->port); + return; + } + maple_clean_submap(mdev); +} + +/* preprocess hotplugs or scans */ +static void maple_response_devinfo(struct maple_device *mdev, + char *recvbuf) +{ + char submask; + if ((!started) || (scanning == 2)) { + maple_attach_driver(mdev); + return; + } + if (mdev->unit == 0) { + submask = recvbuf[2] & 0x1F; + if (submask ^ subdevice_map[mdev->port]) { + maple_map_subunits(mdev, submask); + subdevice_map[mdev->port] = submask; + } + } +} + +/* maple dma end bottom half - implemented via workqueue */ +static void maple_dma_handler(struct work_struct *work) +{ + struct mapleq *mq, *nmq; + struct maple_device *dev; + char *recvbuf; + enum maple_code code; + + if (!maple_dma_done()) + return; + ctrl_outl(0, MAPLE_ENABLE); + if (!list_empty(&maple_sentq)) { + list_for_each_entry_safe(mq, nmq, &maple_sentq, list) { + recvbuf = mq->recvbuf; + code = recvbuf[0]; + dev = mq->dev; + switch (code) { + case MAPLE_RESPONSE_NONE: + maple_response_none(dev, mq); + break; + + case MAPLE_RESPONSE_DEVINFO: + maple_response_devinfo(dev, recvbuf); + break; + + case MAPLE_RESPONSE_DATATRF: + if (dev->callback) + dev->callback(mq); + break; + + case MAPLE_RESPONSE_FILEERR: + case MAPLE_RESPONSE_AGAIN: + case MAPLE_RESPONSE_BADCMD: + case MAPLE_RESPONSE_BADFUNC: + printk(KERN_DEBUG + "Maple non-fatal error 0x%X\n", + code); + break; + + case MAPLE_RESPONSE_ALLINFO: + printk(KERN_DEBUG + "Maple - extended device information not supported\n"); + break; + + case MAPLE_RESPONSE_OK: + break; + + default: + break; + } + } + INIT_LIST_HEAD(&maple_sentq); + if (scanning == 1) { + maple_send(); + scanning = 2; + } else + scanning = 0; + + if (started == 0) + started = 1; + } + maplebus_dma_reset(); +} + +static irqreturn_t maplebus_dma_interrupt(int irq, void *dev_id) +{ + /* Load everything into the bottom half */ + schedule_work(&maple_dma_process); + return IRQ_HANDLED; +} + +static irqreturn_t maplebus_vblank_interrupt(int irq, void *dev_id) +{ + schedule_work(&maple_vblank_process); + return IRQ_HANDLED; +} + +static struct irqaction maple_dma_irq = { + .name = "maple bus DMA handler", + .handler = maplebus_dma_interrupt, + .flags = IRQF_SHARED, +}; + +static struct irqaction maple_vblank_irq = { + .name = "maple bus VBLANK handler", + .handler = maplebus_vblank_interrupt, + .flags = IRQF_SHARED, +}; + +static int maple_set_dma_interrupt_handler(void) +{ + return setup_irq(HW_EVENT_MAPLE_DMA, &maple_dma_irq); +} + +static int maple_set_vblank_interrupt_handler(void) +{ + return setup_irq(HW_EVENT_VSYNC, &maple_vblank_irq); +} + +static int maple_get_dma_buffer(void) +{ + maple_sendbuf = + (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, + MAPLE_DMA_PAGES); + if (!maple_sendbuf) + return -ENOMEM; + return 0; +} + +static int match_maple_bus_driver(struct device *devptr, + struct device_driver *drvptr) +{ + struct maple_driver *maple_drv; + struct maple_device *maple_dev; + + maple_drv = container_of(drvptr, struct maple_driver, drv); + maple_dev = container_of(devptr, struct maple_device, dev); + /* Trap empty port case */ + if (maple_dev->devinfo.function == 0xFFFFFFFF) + return 0; + else if (maple_dev->devinfo.function & + be32_to_cpu(maple_drv->function)) + return 1; + return 0; +} + +static int maple_bus_uevent(struct device *dev, char **envp, + int num_envp, char *buffer, int buffer_size) +{ + return 0; +} + +static void maple_bus_release(struct device *dev) +{ +} + +static struct maple_driver maple_dummy_driver = { + .drv = { + .name = "maple_dummy_driver", + .bus = &maple_bus_type, + }, +}; + +struct bus_type maple_bus_type = { + .name = "maple", + .match = match_maple_bus_driver, + .uevent = maple_bus_uevent, +}; +EXPORT_SYMBOL_GPL(maple_bus_type); + +static struct device maple_bus = { + .bus_id = "maple", + .release = maple_bus_release, +}; + +static int __init maple_bus_init(void) +{ + int retval, i; + struct maple_device *mdev[MAPLE_PORTS]; + ctrl_outl(0, MAPLE_STATE); + + retval = device_register(&maple_bus); + if (retval) + goto cleanup; + + retval = bus_register(&maple_bus_type); + if (retval) + goto cleanup_device; + + retval = driver_register(&maple_dummy_driver.drv); + + if (retval) + goto cleanup_bus; + + /* allocate memory for maple bus dma */ + retval = maple_get_dma_buffer(); + if (retval) { + printk(KERN_INFO + "Maple bus: Failed to allocate Maple DMA buffers\n"); + goto cleanup_basic; + } + + /* set up DMA interrupt handler */ + retval = maple_set_dma_interrupt_handler(); + if (retval) { + printk(KERN_INFO + "Maple bus: Failed to grab maple DMA IRQ\n"); + goto cleanup_dma; + } + + /* set up VBLANK interrupt handler */ + retval = maple_set_vblank_interrupt_handler(); + if (retval) { + printk(KERN_INFO "Maple bus: Failed to grab VBLANK IRQ\n"); + goto cleanup_irq; + } + + maple_queue_cache = + kmem_cache_create("maple_queue_cache", 0x400, 0, + SLAB_HWCACHE_ALIGN, NULL); + + if (!maple_queue_cache) + goto cleanup_bothirqs; + + /* setup maple ports */ + for (i = 0; i < MAPLE_PORTS; i++) { + mdev[i] = maple_alloc_dev(i, 0); + if (!mdev[i]) { + while (i-- > 0) + maple_free_dev(mdev[i]); + goto cleanup_cache; + } + mdev[i]->registered = 0; + mdev[i]->mq->command = MAPLE_COMMAND_DEVINFO; + mdev[i]->mq->length = 0; + maple_attach_driver(mdev[i]); + maple_add_packet(mdev[i]->mq); + subdevice_map[i] = 0; + } + + /* setup maplebus hardware */ + maplebus_dma_reset(); + + /* initial detection */ + maple_send(); + + maple_pnp_time = jiffies; + + printk(KERN_INFO "Maple bus core now registered.\n"); + + return 0; + +cleanup_cache: + kmem_cache_destroy(maple_queue_cache); + +cleanup_bothirqs: + free_irq(HW_EVENT_VSYNC, 0); + +cleanup_irq: + free_irq(HW_EVENT_MAPLE_DMA, 0); + +cleanup_dma: + free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES); + +cleanup_basic: + driver_unregister(&maple_dummy_driver.drv); + +cleanup_bus: + bus_unregister(&maple_bus_type); + +cleanup_device: + device_unregister(&maple_bus); + +cleanup: + printk(KERN_INFO "Maple bus registration failed\n"); + return retval; +} +subsys_initcall(maple_bus_init); diff --git a/include/asm-sh/dreamcast/maple.h b/include/asm-sh/dreamcast/maple.h new file mode 100644 index 00000000000..51f6a87f1f1 --- /dev/null +++ b/include/asm-sh/dreamcast/maple.h @@ -0,0 +1,37 @@ +#ifndef __ASM_MAPLE_H +#define __ASM_MAPLE_H + +#define MAPLE_PORTS 4 +#define MAPLE_PNP_INTERVAL HZ +#define MAPLE_MAXPACKETS 8 +#define MAPLE_DMA_ORDER 14 +#define MAPLE_DMA_SIZE (1 << MAPLE_DMA_ORDER) +#define MAPLE_DMA_PAGES ((MAPLE_DMA_ORDER > PAGE_SHIFT) ? \ + MAPLE_DMA_ORDER - PAGE_SHIFT : 0) + +/* Maple Bus registers */ +#define MAPLE_BASE 0xa05f6c00 +#define MAPLE_DMAADDR (MAPLE_BASE+0x04) +#define MAPLE_TRIGTYPE (MAPLE_BASE+0x10) +#define MAPLE_ENABLE (MAPLE_BASE+0x14) +#define MAPLE_STATE (MAPLE_BASE+0x18) +#define MAPLE_SPEED (MAPLE_BASE+0x80) +#define MAPLE_RESET (MAPLE_BASE+0x8c) + +#define MAPLE_MAGIC 0x6155404f +#define MAPLE_2MBPS 0 +#define MAPLE_TIMEOUT(n) ((n)<<15) + +/* Function codes */ +#define MAPLE_FUNC_CONTROLLER 0x001 +#define MAPLE_FUNC_MEMCARD 0x002 +#define MAPLE_FUNC_LCD 0x004 +#define MAPLE_FUNC_CLOCK 0x008 +#define MAPLE_FUNC_MICROPHONE 0x010 +#define MAPLE_FUNC_ARGUN 0x020 +#define MAPLE_FUNC_KEYBOARD 0x040 +#define MAPLE_FUNC_LIGHTGUN 0x080 +#define MAPLE_FUNC_PURUPURU 0x100 +#define MAPLE_FUNC_MOUSE 0x200 + +#endif /* __ASM_MAPLE_H */ diff --git a/include/linux/maple.h b/include/linux/maple.h new file mode 100644 index 00000000000..bad9a7b319d --- /dev/null +++ b/include/linux/maple.h @@ -0,0 +1,80 @@ +#ifndef __LINUX_MAPLE_H +#define __LINUX_MAPLE_H + +#include + +extern struct bus_type maple_bus_type; + +/* Maple Bus command and response codes */ +enum maple_code { + MAPLE_RESPONSE_FILEERR = -5, + MAPLE_RESPONSE_AGAIN = -4, /* request should be retransmitted */ + MAPLE_RESPONSE_BADCMD = -3, + MAPLE_RESPONSE_BADFUNC = -2, + MAPLE_RESPONSE_NONE = -1, /* unit didn't respond at all */ + MAPLE_COMMAND_DEVINFO = 1, + MAPLE_COMMAND_ALLINFO = 2, + MAPLE_COMMAND_RESET = 3, + MAPLE_COMMAND_KILL = 4, + MAPLE_RESPONSE_DEVINFO = 5, + MAPLE_RESPONSE_ALLINFO = 6, + MAPLE_RESPONSE_OK = 7, + MAPLE_RESPONSE_DATATRF = 8, + MAPLE_COMMAND_GETCOND = 9, + MAPLE_COMMAND_GETMINFO = 10, + MAPLE_COMMAND_BREAD = 11, + MAPLE_COMMAND_BWRITE = 12, + MAPLE_COMMAND_SETCOND = 14 +}; + +struct mapleq { + struct list_head list; + struct maple_device *dev; + void *sendbuf, *recvbuf, *recvbufdcsp; + unsigned char length; + enum maple_code command; +}; + +struct maple_devinfo { + unsigned long function; + unsigned long function_data[3]; + unsigned char area_code; + unsigned char connector_directon; + char product_name[31]; + char product_licence[61]; + unsigned short standby_power; + unsigned short max_power; +}; + +struct maple_device { + struct maple_driver *driver; + struct mapleq *mq; + void *private_data; + void (*callback) (struct mapleq * mq); + unsigned long when, interval, function; + struct maple_devinfo devinfo; + unsigned char port, unit; + char product_name[32]; + char product_licence[64]; + int registered; + struct device dev; +}; + +struct maple_driver { + unsigned long function; + int (*connect) (struct maple_device * dev); + void (*disconnect) (struct maple_device * dev); + struct device_driver drv; +}; + +void maple_getcond_callback(struct maple_device *dev, + void (*callback) (struct mapleq * mq), + unsigned long interval, + unsigned long function); +int maple_driver_register(struct device_driver *drv); +void maple_add_packet(struct mapleq *mq); + +#define to_maple_dev(n) container_of(n, struct maple_device, dev) +#define to_maple_driver(n) container_of(n, struct maple_driver, drv) + +#endif /* __LINUX_MAPLE_H */ -- cgit v1.2.3-70-g09d2 From 2d4a73d5b91528322631830784f4eb7897fb5e41 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 21 Sep 2007 18:01:40 +0900 Subject: sh: Kill off special boot_cpu_data. This consolidates the cpu_data definitions and gets rid of the special boot_cpu_data. It's made a wrapper to the boot CPU, in order to keep the existing in-tree users happy. Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 8 +++++++- arch/sh/kernel/sh_ksyms.c | 1 - include/asm-sh/processor.h | 9 ++------- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index e0e655cba89..cd69b57488d 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -42,7 +42,13 @@ extern void * __rd_start, * __rd_end; * This value will be used at the very early stage of serial setup. * The bigger value means no problem. */ -struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, }; +struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = { + [0] = { + .type = CPU_SH_NONE, + .loops_per_jiffy = 10000000, + }, +}; +EXPORT_SYMBOL(cpu_data); /* * The machine vector. First entry in .machvec.init, or clobbered by diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index 89362e05cc4..cac7380ed0b 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -43,7 +43,6 @@ EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(__copy_user); -EXPORT_SYMBOL(boot_cpu_data); #ifdef CONFIG_MMU EXPORT_SYMBOL(get_vm_area); diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 56cb3c89f84..4f2922a1979 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -73,15 +73,10 @@ struct sh_cpuinfo { unsigned long flags; } __attribute__ ((aligned(SMP_CACHE_BYTES))); -extern struct sh_cpuinfo boot_cpu_data; - -#ifdef CONFIG_SMP extern struct sh_cpuinfo cpu_data[]; +#define boot_cpu_data cpu_data[0] #define current_cpu_data cpu_data[smp_processor_id()] -#else -#define cpu_data (&boot_cpu_data) -#define current_cpu_data boot_cpu_data -#endif +#define raw_current_cpu_data cpu_data[raw_smp_processor_id()] /* * User space process size: 2GB. -- cgit v1.2.3-70-g09d2 From f18d533e3cd476aedf41fe1e6e9dc3e0a2446bba Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 21 Sep 2007 18:16:42 +0900 Subject: sh: intc - initial SMP support. This implements initial support for the SMP INTC (particularly INTC2) controllers. These are largely implemented as conventional blocks, with register sets grouped together at fixed strides relative to the CPU id. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/intc.c | 78 +++++++++++++++++++++++++++++++------------ include/asm-sh/hw_irq.h | 12 +++++++ 2 files changed, 69 insertions(+), 21 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index 481871fee1a..6ac018c15e0 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -40,6 +40,9 @@ struct intc_handle_int { struct intc_desc_int { unsigned long *reg; +#ifdef CONFIG_SMP + unsigned long *smp; +#endif unsigned int nr_reg; struct intc_handle_int *prio; unsigned int nr_prio; @@ -48,6 +51,16 @@ struct intc_desc_int { struct irq_chip chip; }; +#ifdef CONFIG_SMP +#define IS_SMP(x) x.smp +#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c)) +#define SMP_NR(d, x) ((d->smp[(x)] >> 8) ? (d->smp[(x)] >> 8) : 1) +#else +#define IS_SMP(x) 0 +#define INTC_REG(d, x, c) (d->reg[(x)]) +#define SMP_NR(d, x) 1 +#endif + static unsigned int intc_prio_level[NR_IRQS]; /* for now */ static inline struct intc_desc_int *get_intc_desc(unsigned int irq) @@ -177,11 +190,14 @@ static void (*intc_disable_fns[])(unsigned long addr, static inline void _intc_enable(unsigned int irq, unsigned long handle) { struct intc_desc_int *d = get_intc_desc(irq); - unsigned long addr = d->reg[_INTC_ADDR_E(handle)]; + unsigned long addr; + unsigned int cpu; - intc_enable_fns[_INTC_MODE(handle)](addr, handle, - intc_reg_fns[_INTC_FN(handle)], - irq); + for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { + addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); + intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\ + [_INTC_FN(handle)], irq); + } } static void intc_enable(unsigned int irq) @@ -191,13 +207,16 @@ static void intc_enable(unsigned int irq) static void intc_disable(unsigned int irq) { - struct intc_desc_int *desc = get_intc_desc(irq); + struct intc_desc_int *d = get_intc_desc(irq); unsigned long handle = (unsigned long) get_irq_chip_data(irq); - unsigned long addr = desc->reg[_INTC_ADDR_D(handle)]; + unsigned long addr; + unsigned int cpu; - intc_disable_fns[_INTC_MODE(handle)](addr, handle, - intc_reg_fns[_INTC_FN(handle)], - irq); + for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { + addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); + intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\ + [_INTC_FN(handle)], irq); + } } static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, @@ -276,7 +295,7 @@ static int intc_set_sense(unsigned int irq, unsigned int type) ihp = intc_find_irq(d->sense, d->nr_sense, irq); if (ihp) { - addr = d->reg[_INTC_ADDR_E(ihp->handle)]; + addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0); intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value); } return 0; @@ -536,9 +555,26 @@ static void __init intc_register_irq(struct intc_desc *desc, d->chip.mask(irq); } +static unsigned int __init save_reg(struct intc_desc_int *d, + unsigned int cnt, + unsigned long value, + unsigned int smp) +{ + if (value) { + d->reg[cnt] = value; +#ifdef CONFIG_SMP + d->smp[cnt] = smp; +#endif + return 1; + } + + return 0; +} + + void __init register_intc_controller(struct intc_desc *desc) { - unsigned int i, k; + unsigned int i, k, smp; struct intc_desc_int *d; d = alloc_bootmem(sizeof(*d)); @@ -548,14 +584,16 @@ void __init register_intc_controller(struct intc_desc *desc) d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0; d->reg = alloc_bootmem(d->nr_reg * sizeof(*d->reg)); +#ifdef CONFIG_SMP + d->smp = alloc_bootmem(d->nr_reg * sizeof(*d->smp)); +#endif k = 0; if (desc->mask_regs) { for (i = 0; i < desc->nr_mask_regs; i++) { - if (desc->mask_regs[i].set_reg) - d->reg[k++] = desc->mask_regs[i].set_reg; - if (desc->mask_regs[i].clr_reg) - d->reg[k++] = desc->mask_regs[i].clr_reg; + smp = IS_SMP(desc->mask_regs[i]); + k += save_reg(d, k, desc->mask_regs[i].set_reg, smp); + k += save_reg(d, k, desc->mask_regs[i].clr_reg, smp); } } @@ -563,10 +601,9 @@ void __init register_intc_controller(struct intc_desc *desc) d->prio = alloc_bootmem(desc->nr_vectors * sizeof(*d->prio)); for (i = 0; i < desc->nr_prio_regs; i++) { - if (desc->prio_regs[i].set_reg) - d->reg[k++] = desc->prio_regs[i].set_reg; - if (desc->prio_regs[i].clr_reg) - d->reg[k++] = desc->prio_regs[i].clr_reg; + smp = IS_SMP(desc->prio_regs[i]); + k += save_reg(d, k, desc->prio_regs[i].set_reg, smp); + k += save_reg(d, k, desc->prio_regs[i].clr_reg, smp); } } @@ -574,8 +611,7 @@ void __init register_intc_controller(struct intc_desc *desc) d->sense = alloc_bootmem(desc->nr_vectors * sizeof(*d->sense)); for (i = 0; i < desc->nr_sense_regs; i++) { - if (desc->sense_regs[i].reg) - d->reg[k++] = desc->sense_regs[i].reg; + k += save_reg(d, k, desc->sense_regs[i].reg, 0); } } diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 96d97104050..cb0b6c9f702 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -50,11 +50,17 @@ struct intc_group { struct intc_mask_reg { unsigned long set_reg, clr_reg, reg_width; intc_enum enum_ids[32]; +#ifdef CONFIG_SMP + unsigned long smp; +#endif }; struct intc_prio_reg { unsigned long set_reg, clr_reg, reg_width, field_width; intc_enum enum_ids[16]; +#ifdef CONFIG_SMP + unsigned long smp; +#endif }; struct intc_sense_reg { @@ -62,6 +68,12 @@ struct intc_sense_reg { intc_enum enum_ids[16]; }; +#ifdef CONFIG_SMP +#define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8) +#else +#define INTC_SMP(stride, nr) +#endif + struct intc_desc { struct intc_vect *vectors; unsigned int nr_vectors; -- cgit v1.2.3-70-g09d2 From aba1030a7e529ec9fe47a8cfc06d12a39180fa71 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 21 Sep 2007 18:32:32 +0900 Subject: sh: Bring SMP support back from the dead. There was a very preliminary bunch of SMP code scattered around for the SH7604 microcontrollers from way back when, and it has mostly suffered bitrot since then. With the tree already having been slowly getting prepped for SMP, this plugs in most of the remaining platform-independent bits. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/init.c | 16 +++-- arch/sh/kernel/head.S | 18 +++-- arch/sh/kernel/smp.c | 167 +++++++++++++++++++++++++--------------------- arch/sh/kernel/traps.c | 5 +- include/asm-sh/smp.h | 34 +++++++--- include/asm-sh/system.h | 1 + 6 files changed, 142 insertions(+), 99 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index fdc245b7b04..c217c4bf008 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * Generic wrapper for command line arguments to disable on-chip @@ -216,8 +217,11 @@ static void __init dsp_init(void) * Each processor family is still responsible for doing its own probing * and cache configuration in detect_cpu_and_cache_system(). */ -asmlinkage void __init sh_cpu_init(void) + +asmlinkage void __cpuinit sh_cpu_init(void) { + current_thread_info()->cpu = hard_smp_processor_id(); + /* First, probe the CPU */ detect_cpu_and_cache_system(); @@ -227,9 +231,10 @@ asmlinkage void __init sh_cpu_init(void) /* Init the cache */ cache_init(); - shm_align_mask = max_t(unsigned long, - current_cpu_data.dcache.way_size - 1, - PAGE_SIZE - 1); + if (raw_smp_processor_id() == 0) + shm_align_mask = max_t(unsigned long, + current_cpu_data.dcache.way_size - 1, + PAGE_SIZE - 1); /* Disable the FPU */ if (fpu_disabled) { @@ -268,6 +273,7 @@ asmlinkage void __init sh_cpu_init(void) * like PTRACE_SINGLESTEP or doing hardware watchpoints in GDB. So .. * we wake it up and hope that all is well. */ - ubc_wakeup(); + if (raw_smp_processor_id() == 0) + ubc_wakeup(); speculative_execution_init(); } diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S index 0bccc0ca5a0..3338239717f 100644 --- a/arch/sh/kernel/head.S +++ b/arch/sh/kernel/head.S @@ -54,8 +54,8 @@ ENTRY(_stext) mov.l 1f, r0 ! MD=1, RB=0, BL=0, IMASK=0xF ldc r0, sr ! Initialize global interrupt mask - mov #0, r0 #ifdef CONFIG_CPU_HAS_SR_RB + mov #0, r0 ldc r0, r6_bank #endif @@ -72,15 +72,18 @@ ENTRY(_stext) ! mov.l 2f, r0 mov r0, r15 ! Set initial r15 (stack pointer) - mov #(THREAD_SIZE >> 10), r1 - shll8 r1 ! r1 = THREAD_SIZE - shll2 r1 - sub r1, r0 ! #ifdef CONFIG_CPU_HAS_SR_RB + mov.l 7f, r0 ldc r0, r7_bank ! ... and initial thread_info #endif ! Clear BSS area +#ifdef CONFIG_SMP + mov.l 3f, r0 + cmp/eq #0, r0 ! skip clear if set to zero + bt 10f +#endif + mov.l 3f, r1 add #4, r1 mov.l 4f, r2 @@ -89,13 +92,14 @@ ENTRY(_stext) bf/s 9b ! while (r1 < r2) mov.l r0,@-r2 +10: ! Additional CPU initialization mov.l 6f, r0 jsr @r0 nop SYNCO() ! Wait for pending instructions.. - + ! Start kernel mov.l 5f, r0 jmp @r0 @@ -107,8 +111,10 @@ ENTRY(_stext) #else 1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF #endif +ENTRY(stack_start) 2: .long init_thread_union+THREAD_SIZE 3: .long __bss_start 4: .long _end 5: .long start_kernel 6: .long sh_cpu_init +7: .long init_thread_union diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index f93d5ffa941..94075e1a1e6 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -3,68 +3,40 @@ * * SMP support for the SuperH processors. * - * Copyright (C) 2002, 2003 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright (C) 2006 - 2007 Akio Idehara * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. + * 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 #include #include -#include #include -#include +#include #include -#include -#include -#include -#include - +#include #include #include #include #include #include +#include +#include -/* - * This was written with the Sega Saturn (SMP SH-2 7604) in mind, - * but is designed to be usable regardless if there's an MMU - * present or not. - */ -struct sh_cpuinfo cpu_data[NR_CPUS]; - -extern void per_cpu_trap_init(void); +int __cpu_number_map[NR_CPUS]; /* Map physical to logical */ +int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ cpumask_t cpu_possible_map; EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); -static atomic_t cpus_booted = ATOMIC_INIT(0); - -/* These are defined by the board-specific code. */ -/* - * Cause the function described by call_data to be executed on the passed - * cpu. When the function has finished, increment the finished field of - * call_data. - */ -void __smp_send_ipi(unsigned int cpu, unsigned int action); - -/* - * Find the number of available processors - */ -unsigned int __smp_probe_cpus(void); - -/* - * Start a particular processor - */ -void __smp_slave_init(unsigned int cpu); +static atomic_t cpus_booted = ATOMIC_INIT(0); /* * Run specified function on a particular processor. @@ -73,74 +45,123 @@ void __smp_call_function(unsigned int cpu); static inline void __init smp_store_cpu_info(unsigned int cpu) { - cpu_data[cpu].loops_per_jiffy = loops_per_jiffy; + struct sh_cpuinfo *c = cpu_data + cpu; + + c->loops_per_jiffy = loops_per_jiffy; } void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int cpu = smp_processor_id(); - int i; - atomic_set(&cpus_booted, 1); - smp_store_cpu_info(cpu); - - for (i = 0; i < __smp_probe_cpus(); i++) - cpu_set(i, cpu_possible_map); + init_new_context(current, &init_mm); + current_thread_info()->cpu = cpu; + plat_prepare_cpus(max_cpus); + +#ifndef CONFIG_HOTPLUG_CPU + cpu_present_map = cpu_possible_map; +#endif } void __devinit smp_prepare_boot_cpu(void) { unsigned int cpu = smp_processor_id(); + __cpu_number_map[0] = cpu; + __cpu_logical_map[0] = cpu; + cpu_set(cpu, cpu_online_map); cpu_set(cpu, cpu_possible_map); } -int __cpu_up(unsigned int cpu) +asmlinkage void __cpuinit start_secondary(void) { - struct task_struct *tsk; + unsigned int cpu; + struct mm_struct *mm = &init_mm; - tsk = fork_idle(cpu); + atomic_inc(&mm->mm_count); + atomic_inc(&mm->mm_users); + current->active_mm = mm; + BUG_ON(current->mm); + enter_lazy_tlb(mm, current); + + per_cpu_trap_init(); - if (IS_ERR(tsk)) - panic("Failed forking idle task for cpu %d\n", cpu); - - task_thread_info(tsk)->cpu = cpu; + preempt_disable(); + + local_irq_enable(); + + calibrate_delay(); + + cpu = smp_processor_id(); + smp_store_cpu_info(cpu); cpu_set(cpu, cpu_online_map); - return 0; + cpu_idle(); } -int start_secondary(void *unused) +extern struct { + unsigned long sp; + unsigned long bss_start; + unsigned long bss_end; + void *start_kernel_fn; + void *cpu_init_fn; + void *thread_info; +} stack_start; + +int __cpuinit __cpu_up(unsigned int cpu) { - unsigned int cpu; + struct task_struct *tsk; + unsigned long timeout; - cpu = smp_processor_id(); + tsk = fork_idle(cpu); + if (IS_ERR(tsk)) { + printk(KERN_ERR "Failed forking idle task for cpu %d\n", cpu); + return PTR_ERR(tsk); + } - atomic_inc(&init_mm.mm_count); - current->active_mm = &init_mm; + /* Fill in data in head.S for secondary cpus */ + stack_start.sp = tsk->thread.sp; + stack_start.thread_info = tsk->stack; + stack_start.bss_start = 0; /* don't clear bss for secondary cpus */ + stack_start.start_kernel_fn = start_secondary; - smp_store_cpu_info(cpu); + flush_cache_all(); - __smp_slave_init(cpu); - preempt_disable(); - per_cpu_trap_init(); - - atomic_inc(&cpus_booted); + plat_start_cpu(cpu, (unsigned long)_stext); - cpu_idle(); - return 0; + timeout = jiffies + HZ; + while (time_before(jiffies, timeout)) { + if (cpu_online(cpu)) + break; + + udelay(10); + } + + if (cpu_online(cpu)) + return 0; + + return -ENOENT; } void __init smp_cpus_done(unsigned int max_cpus) { - smp_mb(); + unsigned long bogosum = 0; + int cpu; + + for_each_online_cpu(cpu) + bogosum += cpu_data[cpu].loops_per_jiffy; + + printk(KERN_INFO "SMP: Total of %d processors activated " + "(%lu.%02lu BogoMIPS).\n", num_online_cpus(), + bogosum / (500000/HZ), + (bogosum / (5000/HZ)) % 100); } void smp_send_reschedule(int cpu) { - __smp_send_ipi(cpu, SMP_MSG_RESCHEDULE); + plat_send_ipi(cpu, SMP_MSG_RESCHEDULE); } static void stop_this_cpu(void *unused) @@ -157,7 +178,6 @@ void smp_send_stop(void) smp_call_function(stop_this_cpu, 0, 1, 0); } - struct smp_fn_call_struct smp_fn_call = { .lock = SPIN_LOCK_UNLOCKED, .finished = ATOMIC_INIT(0), @@ -175,9 +195,6 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, int wait) unsigned int nr_cpus = atomic_read(&cpus_booted); int i; - if (nr_cpus < 2) - return 0; - /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); @@ -189,7 +206,7 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, int wait) for (i = 0; i < nr_cpus; i++) if (i != smp_processor_id()) - __smp_call_function(i); + plat_send_ipi(i, SMP_MSG_FUNCTION); if (wait) while (atomic_read(&smp_fn_call.finished) != (nr_cpus - 1)); diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 67015044d74..dcb46e71da1 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -807,12 +807,13 @@ static inline void __init gdb_vbr_init(void) } #endif -void __init per_cpu_trap_init(void) +void __cpuinit per_cpu_trap_init(void) { extern void *vbr_base; #ifdef CONFIG_SH_STANDARD_BIOS - gdb_vbr_init(); + if (raw_smp_processor_id() == 0) + gdb_vbr_init(); #endif /* NOTE: The VBR value should be at P1 diff --git a/include/asm-sh/smp.h b/include/asm-sh/smp.h index b99ca786c0c..9c8d34b07eb 100644 --- a/include/asm-sh/smp.h +++ b/include/asm-sh/smp.h @@ -1,12 +1,3 @@ -/* - * include/asm-sh/smp.h - * - * Copyright (C) 2002, 2003 Paul Mundt - * - * 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. - */ #ifndef __ASM_SH_SMP_H #define __ASM_SH_SMP_H @@ -20,6 +11,15 @@ #include #define raw_smp_processor_id() (current_thread_info()->cpu) +#define hard_smp_processor_id() plat_smp_processor_id() + +/* Map from cpu id to sequential logical cpu number. */ +extern int __cpu_number_map[NR_CPUS]; +#define cpu_number_map(cpu) __cpu_number_map[cpu] + +/* The reverse map from sequential logical cpu number to cpu id. */ +extern int __cpu_logical_map[NR_CPUS]; +#define cpu_logical_map(cpu) __cpu_logical_map[cpu] /* I've no idea what the real meaning of this is */ #define PROC_CHANGE_PENALTY 20 @@ -35,10 +35,22 @@ struct smp_fn_call_struct { extern struct smp_fn_call_struct smp_fn_call; -#define SMP_MSG_RESCHEDULE 0x0001 +#define SMP_MSG_FUNCTION 0 +#define SMP_MSG_RESCHEDULE 1 +#define SMP_MSG_NR 2 -#endif /* CONFIG_SMP */ +void plat_smp_setup(void); +void plat_prepare_cpus(unsigned int max_cpus); +int plat_smp_processor_id(void); +void plat_start_cpu(unsigned int cpu, unsigned long entry_point); +void plat_send_ipi(unsigned int cpu, unsigned int message); +int plat_register_ipi_handler(unsigned int message, + void (*handler)(void *), void *arg); + +#else #define hard_smp_processor_id() (0) +#endif /* CONFIG_SMP */ + #endif /* __ASM_SH_SMP_H */ diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 24504253720..9d849e6df26 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -266,6 +266,7 @@ void disable_hlt(void); void enable_hlt(void); void default_idle(void); +void per_cpu_trap_init(void); asmlinkage void break_point_trap(void); asmlinkage void debug_trap_handler(unsigned long r4, unsigned long r5, -- cgit v1.2.3-70-g09d2 From 1f91bbb58413e0bce9726cd6d12bf4b95c343a7f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 24 Sep 2007 18:11:27 +0900 Subject: sh: Define _ebss for uClinux MTD map driver. The uClinux MTD device uses _ebss, add the symbol and corresponding export. Signed-off-by: Paul Mundt --- arch/sh/kernel/sh_ksyms.c | 3 ++- arch/sh/kernel/vmlinux.lds.S | 1 + include/asm-sh/sections.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index cac7380ed0b..548e4285b37 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -8,7 +8,7 @@ #include #include #include - +#include #include #include #include @@ -149,3 +149,4 @@ EXPORT_SYMBOL(csum_ipv6_magic); #endif EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(__clear_user); +EXPORT_SYMBOL(_ebss); diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 9cb95af7b09..84a203b8573 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -107,6 +107,7 @@ SECTIONS *(.bss.page_aligned) *(.bss) . = ALIGN(4); + _ebss = .; /* uClinux MTD sucks */ _end = . ; } diff --git a/include/asm-sh/sections.h b/include/asm-sh/sections.h index 2a696b8ee4f..bd9cbc967c2 100644 --- a/include/asm-sh/sections.h +++ b/include/asm-sh/sections.h @@ -4,6 +4,7 @@ #include extern long __machvec_start, __machvec_end; +extern char _ebss[]; #endif /* __ASM_SH_SECTIONS_H */ -- cgit v1.2.3-70-g09d2 From 09a4df5f0c8b7c418821fe591bf0d0f13b206c61 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 27 Sep 2007 12:57:35 +0900 Subject: sh: processor.h needs smp.h Trivial build fix for SH-2. Signed-off-by: Paul Mundt --- include/asm-sh/processor.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-sh') diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 4f2922a1979..9f3ee775fe1 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -10,6 +10,7 @@ #ifdef __KERNEL__ #include +#include #include #include #include -- cgit v1.2.3-70-g09d2 From cb7af21f7d370edb3a6a6d3e15cb17c8fd61591e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 27 Sep 2007 18:18:39 +0900 Subject: sh: Use boot_cpu_data for CPU probe. This moves off of smp_processor_id() and only sets the probe information for the boot CPU directly. This will be copied out for the secondaries, so there's no reason to do this each time. This also allows for some header tidying. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2/probe.c | 19 +++-- arch/sh/kernel/cpu/sh2a/probe.c | 18 ++--- arch/sh/kernel/cpu/sh3/probe.c | 47 ++++++----- arch/sh/kernel/cpu/sh4/probe.c | 171 ++++++++++++++++++++-------------------- include/asm-sh/processor.h | 1 - 5 files changed, 126 insertions(+), 130 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index abbf17427e5..5916d9096b9 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -10,26 +10,25 @@ * for more details. */ #include -#include #include #include int __init detect_cpu_and_cache_system(void) { #if defined(CONFIG_CPU_SUBTYPE_SH7619) - current_cpu_data.type = CPU_SH7619; - current_cpu_data.dcache.ways = 4; - current_cpu_data.dcache.way_incr = (1<<12); - current_cpu_data.dcache.sets = 256; - current_cpu_data.dcache.entry_shift = 4; - current_cpu_data.dcache.linesz = L1_CACHE_BYTES; - current_cpu_data.dcache.flags = 0; + boot_cpu_data.type = CPU_SH7619; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.dcache.way_incr = (1<<12); + boot_cpu_data.dcache.sets = 256; + boot_cpu_data.dcache.entry_shift = 4; + boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; + boot_cpu_data.dcache.flags = 0; #endif /* * SH-2 doesn't have separate caches */ - current_cpu_data.dcache.flags |= SH_CACHE_COMBINED; - current_cpu_data.icache = current_cpu_data.dcache; + boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED; + boot_cpu_data.icache = boot_cpu_data.dcache; return 0; } diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c index f455c350978..6d02465704b 100644 --- a/arch/sh/kernel/cpu/sh2a/probe.c +++ b/arch/sh/kernel/cpu/sh2a/probe.c @@ -17,15 +17,15 @@ int __init detect_cpu_and_cache_system(void) { /* Just SH7206 for now .. */ - current_cpu_data.type = CPU_SH7206; - current_cpu_data.flags |= CPU_HAS_OP32; + boot_cpu_data.type = CPU_SH7206; + boot_cpu_data.flags |= CPU_HAS_OP32; - current_cpu_data.dcache.ways = 4; - current_cpu_data.dcache.way_incr = (1 << 11); - current_cpu_data.dcache.sets = 128; - current_cpu_data.dcache.entry_shift = 4; - current_cpu_data.dcache.linesz = L1_CACHE_BYTES; - current_cpu_data.dcache.flags = 0; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.dcache.way_incr = (1 << 11); + boot_cpu_data.dcache.sets = 128; + boot_cpu_data.dcache.entry_shift = 4; + boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; + boot_cpu_data.dcache.flags = 0; /* * The icache is the same as the dcache as far as this setup is @@ -33,7 +33,7 @@ int __init detect_cpu_and_cache_system(void) * lacks the U bit that the dcache has, none of this has any bearing * on the cache info. */ - current_cpu_data.icache = current_cpu_data.dcache; + boot_cpu_data.icache = boot_cpu_data.dcache; return 0; } diff --git a/arch/sh/kernel/cpu/sh3/probe.c b/arch/sh/kernel/cpu/sh3/probe.c index 1a66cf636a9..bf579e061e0 100644 --- a/arch/sh/kernel/cpu/sh3/probe.c +++ b/arch/sh/kernel/cpu/sh3/probe.c @@ -50,47 +50,47 @@ int __init detect_cpu_and_cache_system(void) back_to_P1(); - current_cpu_data.dcache.ways = 4; - current_cpu_data.dcache.entry_shift = 4; - current_cpu_data.dcache.linesz = L1_CACHE_BYTES; - current_cpu_data.dcache.flags = 0; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.dcache.entry_shift = 4; + boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; + boot_cpu_data.dcache.flags = 0; /* * 7709A/7729 has 16K cache (256-entry), while 7702 has only * 2K(direct) 7702 is not supported (yet) */ if (data0 == data1 && data2 == data3) { /* Shadow */ - current_cpu_data.dcache.way_incr = (1 << 11); - current_cpu_data.dcache.entry_mask = 0x7f0; - current_cpu_data.dcache.sets = 128; - current_cpu_data.type = CPU_SH7708; + boot_cpu_data.dcache.way_incr = (1 << 11); + boot_cpu_data.dcache.entry_mask = 0x7f0; + boot_cpu_data.dcache.sets = 128; + boot_cpu_data.type = CPU_SH7708; - current_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC; + boot_cpu_data.flags |= CPU_HAS_MMU_PAGE_ASSOC; } else { /* 7709A or 7729 */ - current_cpu_data.dcache.way_incr = (1 << 12); - current_cpu_data.dcache.entry_mask = 0xff0; - current_cpu_data.dcache.sets = 256; - current_cpu_data.type = CPU_SH7729; + boot_cpu_data.dcache.way_incr = (1 << 12); + boot_cpu_data.dcache.entry_mask = 0xff0; + boot_cpu_data.dcache.sets = 256; + boot_cpu_data.type = CPU_SH7729; #if defined(CONFIG_CPU_SUBTYPE_SH7706) - current_cpu_data.type = CPU_SH7706; + boot_cpu_data.type = CPU_SH7706; #endif #if defined(CONFIG_CPU_SUBTYPE_SH7710) - current_cpu_data.type = CPU_SH7710; + boot_cpu_data.type = CPU_SH7710; #endif #if defined(CONFIG_CPU_SUBTYPE_SH7712) - current_cpu_data.type = CPU_SH7712; + boot_cpu_data.type = CPU_SH7712; #endif #if defined(CONFIG_CPU_SUBTYPE_SH7720) - current_cpu_data.type = CPU_SH7720; + boot_cpu_data.type = CPU_SH7720; #endif #if defined(CONFIG_CPU_SUBTYPE_SH7705) - current_cpu_data.type = CPU_SH7705; + boot_cpu_data.type = CPU_SH7705; #if defined(CONFIG_SH7705_CACHE_32KB) - current_cpu_data.dcache.way_incr = (1 << 13); - current_cpu_data.dcache.entry_mask = 0x1ff0; - current_cpu_data.dcache.sets = 512; + boot_cpu_data.dcache.way_incr = (1 << 13); + boot_cpu_data.dcache.entry_mask = 0x1ff0; + boot_cpu_data.dcache.sets = 512; ctrl_outl(CCR_CACHE_32KB, CCR3); #else ctrl_outl(CCR_CACHE_16KB, CCR3); @@ -101,9 +101,8 @@ int __init detect_cpu_and_cache_system(void) /* * SH-3 doesn't have separate caches */ - current_cpu_data.dcache.flags |= SH_CACHE_COMBINED; - current_cpu_data.icache = current_cpu_data.dcache; + boot_cpu_data.dcache.flags |= SH_CACHE_COMBINED; + boot_cpu_data.icache = boot_cpu_data.dcache; return 0; } - diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 8f318a4fe72..21375d777e9 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -12,7 +12,6 @@ */ #include #include -#include #include #include @@ -36,34 +35,34 @@ int __init detect_cpu_and_cache_system(void) /* * Setup some sane SH-4 defaults for the icache */ - current_cpu_data.icache.way_incr = (1 << 13); - current_cpu_data.icache.entry_shift = 5; - current_cpu_data.icache.sets = 256; - current_cpu_data.icache.ways = 1; - current_cpu_data.icache.linesz = L1_CACHE_BYTES; + boot_cpu_data.icache.way_incr = (1 << 13); + boot_cpu_data.icache.entry_shift = 5; + boot_cpu_data.icache.sets = 256; + boot_cpu_data.icache.ways = 1; + boot_cpu_data.icache.linesz = L1_CACHE_BYTES; /* * And again for the dcache .. */ - current_cpu_data.dcache.way_incr = (1 << 14); - current_cpu_data.dcache.entry_shift = 5; - current_cpu_data.dcache.sets = 512; - current_cpu_data.dcache.ways = 1; - current_cpu_data.dcache.linesz = L1_CACHE_BYTES; + boot_cpu_data.dcache.way_incr = (1 << 14); + boot_cpu_data.dcache.entry_shift = 5; + boot_cpu_data.dcache.sets = 512; + boot_cpu_data.dcache.ways = 1; + boot_cpu_data.dcache.linesz = L1_CACHE_BYTES; /* * Setup some generic flags we can probe on SH-4A parts */ if (((pvr >> 16) & 0xff) == 0x10) { if ((cvr & 0x10000000) == 0) - current_cpu_data.flags |= CPU_HAS_DSP; + boot_cpu_data.flags |= CPU_HAS_DSP; - current_cpu_data.flags |= CPU_HAS_LLSC; + boot_cpu_data.flags |= CPU_HAS_LLSC; } /* FPU detection works for everyone */ if ((cvr & 0x20000000) == 1) - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.flags |= CPU_HAS_FPU; /* Mask off the upper chip ID */ pvr &= 0xffff; @@ -74,140 +73,140 @@ int __init detect_cpu_and_cache_system(void) */ switch (pvr) { case 0x205: - current_cpu_data.type = CPU_SH7750; - current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | + boot_cpu_data.type = CPU_SH7750; + boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | CPU_HAS_PERF_COUNTER; break; case 0x206: - current_cpu_data.type = CPU_SH7750S; - current_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | + boot_cpu_data.type = CPU_SH7750S; + boot_cpu_data.flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | CPU_HAS_PERF_COUNTER; break; case 0x1100: - current_cpu_data.type = CPU_SH7751; - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.type = CPU_SH7751; + boot_cpu_data.flags |= CPU_HAS_FPU; break; case 0x2001: case 0x2004: - current_cpu_data.type = CPU_SH7770; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; + boot_cpu_data.type = CPU_SH7770; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC; + boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_LLSC; break; case 0x2006: case 0x200A: if (prr == 0x61) - current_cpu_data.type = CPU_SH7781; + boot_cpu_data.type = CPU_SH7781; else - current_cpu_data.type = CPU_SH7780; + boot_cpu_data.type = CPU_SH7780; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | + boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | CPU_HAS_LLSC; break; case 0x3000: case 0x3003: case 0x3009: - current_cpu_data.type = CPU_SH7343; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_LLSC; + boot_cpu_data.type = CPU_SH7343; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.flags |= CPU_HAS_LLSC; break; case 0x3004: case 0x3007: - current_cpu_data.type = CPU_SH7785; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | + boot_cpu_data.type = CPU_SH7785; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | CPU_HAS_LLSC; break; case 0x3008: if (prr == 0xa0) { - current_cpu_data.type = CPU_SH7722; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_LLSC; + boot_cpu_data.type = CPU_SH7722; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.flags |= CPU_HAS_LLSC; } break; case 0x4000: /* 1st cut */ case 0x4001: /* 2nd cut */ - current_cpu_data.type = CPU_SHX3; - current_cpu_data.icache.ways = 4; - current_cpu_data.dcache.ways = 4; - current_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | + boot_cpu_data.type = CPU_SHX3; + boot_cpu_data.icache.ways = 4; + boot_cpu_data.dcache.ways = 4; + boot_cpu_data.flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | CPU_HAS_LLSC; break; case 0x8000: - current_cpu_data.type = CPU_ST40RA; - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.type = CPU_ST40RA; + boot_cpu_data.flags |= CPU_HAS_FPU; break; case 0x8100: - current_cpu_data.type = CPU_ST40GX1; - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.type = CPU_ST40GX1; + boot_cpu_data.flags |= CPU_HAS_FPU; break; case 0x700: - current_cpu_data.type = CPU_SH4_501; - current_cpu_data.icache.ways = 2; - current_cpu_data.dcache.ways = 2; + boot_cpu_data.type = CPU_SH4_501; + boot_cpu_data.icache.ways = 2; + boot_cpu_data.dcache.ways = 2; break; case 0x600: - current_cpu_data.type = CPU_SH4_202; - current_cpu_data.icache.ways = 2; - current_cpu_data.dcache.ways = 2; - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.type = CPU_SH4_202; + boot_cpu_data.icache.ways = 2; + boot_cpu_data.dcache.ways = 2; + boot_cpu_data.flags |= CPU_HAS_FPU; break; case 0x500 ... 0x501: switch (prr) { case 0x10: - current_cpu_data.type = CPU_SH7750R; + boot_cpu_data.type = CPU_SH7750R; break; case 0x11: - current_cpu_data.type = CPU_SH7751R; + boot_cpu_data.type = CPU_SH7751R; break; case 0x50 ... 0x5f: - current_cpu_data.type = CPU_SH7760; + boot_cpu_data.type = CPU_SH7760; break; } - current_cpu_data.icache.ways = 2; - current_cpu_data.dcache.ways = 2; + boot_cpu_data.icache.ways = 2; + boot_cpu_data.dcache.ways = 2; - current_cpu_data.flags |= CPU_HAS_FPU; + boot_cpu_data.flags |= CPU_HAS_FPU; break; default: - current_cpu_data.type = CPU_SH_NONE; + boot_cpu_data.type = CPU_SH_NONE; break; } #ifdef CONFIG_SH_DIRECT_MAPPED - current_cpu_data.icache.ways = 1; - current_cpu_data.dcache.ways = 1; + boot_cpu_data.icache.ways = 1; + boot_cpu_data.dcache.ways = 1; #endif #ifdef CONFIG_CPU_HAS_PTEA - current_cpu_data.flags |= CPU_HAS_PTEA; + boot_cpu_data.flags |= CPU_HAS_PTEA; #endif /* * On anything that's not a direct-mapped cache, look to the CVR * for I/D-cache specifics. */ - if (current_cpu_data.icache.ways > 1) { + if (boot_cpu_data.icache.ways > 1) { size = sizes[(cvr >> 20) & 0xf]; - current_cpu_data.icache.way_incr = (size >> 1); - current_cpu_data.icache.sets = (size >> 6); + boot_cpu_data.icache.way_incr = (size >> 1); + boot_cpu_data.icache.sets = (size >> 6); } /* And the rest of the D-cache */ - if (current_cpu_data.dcache.ways > 1) { + if (boot_cpu_data.dcache.ways > 1) { size = sizes[(cvr >> 16) & 0xf]; - current_cpu_data.dcache.way_incr = (size >> 1); - current_cpu_data.dcache.sets = (size >> 6); + boot_cpu_data.dcache.way_incr = (size >> 1); + boot_cpu_data.dcache.sets = (size >> 6); } /* @@ -215,7 +214,7 @@ int __init detect_cpu_and_cache_system(void) * * SH-4A's have an optional PIPT L2. */ - if (current_cpu_data.flags & CPU_HAS_L2_CACHE) { + if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) { /* * Size calculation is much more sensible * than it is for the L1. @@ -226,22 +225,22 @@ int __init detect_cpu_and_cache_system(void) BUG_ON(!size); - current_cpu_data.scache.way_incr = (1 << 16); - current_cpu_data.scache.entry_shift = 5; - current_cpu_data.scache.ways = 4; - current_cpu_data.scache.linesz = L1_CACHE_BYTES; + boot_cpu_data.scache.way_incr = (1 << 16); + boot_cpu_data.scache.entry_shift = 5; + boot_cpu_data.scache.ways = 4; + boot_cpu_data.scache.linesz = L1_CACHE_BYTES; - current_cpu_data.scache.entry_mask = - (current_cpu_data.scache.way_incr - - current_cpu_data.scache.linesz); + boot_cpu_data.scache.entry_mask = + (boot_cpu_data.scache.way_incr - + boot_cpu_data.scache.linesz); - current_cpu_data.scache.sets = size / - (current_cpu_data.scache.linesz * - current_cpu_data.scache.ways); + boot_cpu_data.scache.sets = size / + (boot_cpu_data.scache.linesz * + boot_cpu_data.scache.ways); - current_cpu_data.scache.way_size = - (current_cpu_data.scache.sets * - current_cpu_data.scache.linesz); + boot_cpu_data.scache.way_size = + (boot_cpu_data.scache.sets * + boot_cpu_data.scache.linesz); } return 0; diff --git a/include/asm-sh/processor.h b/include/asm-sh/processor.h index 9f3ee775fe1..4f2922a1979 100644 --- a/include/asm-sh/processor.h +++ b/include/asm-sh/processor.h @@ -10,7 +10,6 @@ #ifdef __KERNEL__ #include -#include #include #include #include -- cgit v1.2.3-70-g09d2 From a90f354709b372c8dcabe3cd6315a83da5927573 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 3 Oct 2007 17:13:34 +0900 Subject: sh: kgdb section mismatches and tidying. The kgdb console setup was callable from a left-over deferred initialization path, which in turn depends on __init symbols. Since the deferred initialization was removed some time ago, kill off the rest of those remnants and move kgdb_init() and friends to __init. Signed-off-by: Paul Mundt --- arch/sh/kernel/kgdb_stub.c | 45 +++------------------------------------------ include/asm-sh/kgdb.h | 12 ++---------- 2 files changed, 5 insertions(+), 52 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c index edd1ec214e6..27f64b92aff 100644 --- a/arch/sh/kernel/kgdb_stub.c +++ b/arch/sh/kernel/kgdb_stub.c @@ -150,13 +150,6 @@ struct kgdb_regs trap_registers; char kgdb_in_gdb_mode; char in_nmi; /* Set during NMI to prevent reentry */ int kgdb_nofault; /* Boolean to ignore bus errs (i.e. in GDB) */ -int kgdb_enabled = 1; /* Default to enabled, cmdline can disable */ - -/* Exposed for user access */ -struct task_struct *kgdb_current; -unsigned int kgdb_g_imask; -int kgdb_trapa_val; -int kgdb_excode; /* Default values for SCI (can override via kernel args in setup.c) */ #ifndef CONFIG_KGDB_DEFPORT @@ -640,7 +633,6 @@ static void do_single_step(void) /* Flush and return */ kgdb_flush_icache_range((long) addr, (long) addr + 2); - return; } /* Undo a single step */ @@ -815,14 +807,10 @@ static void set_regs_msg(void) /* * Bring up the ports.. */ -static int kgdb_serial_setup(void) +static int __init kgdb_serial_setup(void) { - extern int kgdb_console_setup(struct console *co, char *options); struct console dummy; - - kgdb_console_setup(&dummy, 0); - - return 0; + return kgdb_console_setup(&dummy, 0); } #else #define kgdb_serial_setup() 0 @@ -833,22 +821,6 @@ static void kgdb_command_loop(const int excep_code, const int trapa_value) { int sigval; - if (excep_code == NMI_VEC) { -#ifndef CONFIG_KGDB_NMI - printk(KERN_NOTICE "KGDB: Ignoring unexpected NMI?\n"); - return; -#else /* CONFIG_KGDB_NMI */ - if (!kgdb_enabled) { - kgdb_enabled = 1; - kgdb_init(); - } -#endif /* CONFIG_KGDB_NMI */ - } - - /* Ignore if we're disabled */ - if (!kgdb_enabled) - return; - /* Enter GDB mode (e.g. after detach) */ if (!kgdb_in_gdb_mode) { /* Do serial setup, notify user, issue preemptive ack */ @@ -959,18 +931,10 @@ static void handle_exception(struct pt_regs *regs) /* Get excode for command loop call, user access */ asm("stc r2_bank, %0":"=r"(excep_code)); - kgdb_excode = excep_code; - - /* Other interesting environment items for reference */ - asm("stc r6_bank, %0":"=r"(kgdb_g_imask)); - kgdb_current = current; - kgdb_trapa_val = trapa_value; /* Act on the exception */ kgdb_command_loop(excep_code, trapa_value); - kgdb_current = NULL; - /* Copy back the (maybe modified) registers */ for (count = 0; count < 16; count++) regs->regs[count] = trap_registers.regs[count]; @@ -994,11 +958,8 @@ asmlinkage void kgdb_handle_exception(unsigned long r4, unsigned long r5, } /* Initialise the KGDB data structures and serial configuration */ -int kgdb_init(void) +int __init kgdb_init(void) { - if (!kgdb_enabled) - return 1; - in_nmi = 0; kgdb_nofault = 0; stepped_opcode = 0; diff --git a/include/asm-sh/kgdb.h b/include/asm-sh/kgdb.h index 74bd0953e5c..5334e86ccad 100644 --- a/include/asm-sh/kgdb.h +++ b/include/asm-sh/kgdb.h @@ -19,8 +19,6 @@ #include #include -struct console; - /* Same as pt_regs but has vbr in place of syscall_nr */ struct kgdb_regs { unsigned long regs[16]; @@ -35,10 +33,7 @@ struct kgdb_regs { /* State info */ extern char kgdb_in_gdb_mode; -extern int kgdb_done_init; -extern int kgdb_enabled; extern int kgdb_nofault; /* Ignore bus errors (in gdb mem access) */ -extern int kgdb_halt; /* Execute initial breakpoint at startup */ extern char in_nmi; /* Debounce flag to prevent NMI reentry*/ /* SCI */ @@ -59,6 +54,7 @@ extern kgdb_debug_hook_t *kgdb_debug_hook; extern kgdb_bus_error_hook_t *kgdb_bus_err_hook; /* Console */ +struct console; void kgdb_console_write(struct console *co, const char *s, unsigned count); extern int kgdb_console_setup(struct console *, char *); @@ -69,11 +65,7 @@ extern void longjmp(jmp_buf __jmpb, int __retval); extern int setjmp(jmp_buf __jmpb); /* Forced breakpoint */ -#define breakpoint() \ -do { \ - if (kgdb_enabled) \ - __asm__ __volatile__("trapa #0x3c"); \ -} while (0) +#define breakpoint() __asm__ __volatile__("trapa #0x3c") /* KGDB should be able to flush all kernel text space */ #if defined(CONFIG_CPU_SH4) -- cgit v1.2.3-70-g09d2 From 01bd5e9ef2ead97059a1930de43942bdfc9e8755 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 3 Oct 2007 17:21:10 +0900 Subject: sh: Make kgdb i-cache flushing less inept. kgdb had its own ranged I-cache flushing routine that attempted to duplicate the flush_icache_range() functionality, but managed to do an explicit D-cache writeback & invalidate twice on SH-4. This is a no-op for SH-3, and the flush_icache_range() semantics already do what kgdb was feebly attempting to do already, so just move over to that and kill off the wrapper. Signed-off-by: Paul Mundt --- arch/sh/kernel/kgdb_stub.c | 8 ++++---- include/asm-sh/kgdb.h | 12 ------------ 2 files changed, 4 insertions(+), 16 deletions(-) (limited to 'include/asm-sh') diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c index 27f64b92aff..2fdc700dfd6 100644 --- a/arch/sh/kernel/kgdb_stub.c +++ b/arch/sh/kernel/kgdb_stub.c @@ -609,7 +609,7 @@ static short *get_step_address(void) else addr = trap_registers.pc + 2; - kgdb_flush_icache_range(addr, addr + 2); + flush_icache_range(addr, addr + 2); return (short *) addr; } @@ -632,7 +632,7 @@ static void do_single_step(void) *addr = STEP_OPCODE; /* Flush and return */ - kgdb_flush_icache_range((long) addr, (long) addr + 2); + flush_icache_range((long) addr, (long) addr + 2); } /* Undo a single step */ @@ -642,7 +642,7 @@ static void undo_single_step(void) /* Use stepped_address in case we stopped elsewhere */ if (stepped_opcode != 0) { *(short*)stepped_address = stepped_opcode; - kgdb_flush_icache_range(stepped_address, stepped_address + 2); + flush_icache_range(stepped_address, stepped_address + 2); } stepped_opcode = 0; } @@ -728,7 +728,7 @@ static void write_mem_msg(int binary) ebin_to_mem(ptr, (char*)addr, length); else hex_to_mem(ptr, (char*)addr, length); - kgdb_flush_icache_range(addr, addr + length); + flush_icache_range(addr, addr + length); ptr = 0; send_ok_msg(); } diff --git a/include/asm-sh/kgdb.h b/include/asm-sh/kgdb.h index 5334e86ccad..4bc8cb187d1 100644 --- a/include/asm-sh/kgdb.h +++ b/include/asm-sh/kgdb.h @@ -17,7 +17,6 @@ #define __KGDB_H #include -#include /* Same as pt_regs but has vbr in place of syscall_nr */ struct kgdb_regs { @@ -67,17 +66,6 @@ extern int setjmp(jmp_buf __jmpb); /* Forced breakpoint */ #define breakpoint() __asm__ __volatile__("trapa #0x3c") -/* KGDB should be able to flush all kernel text space */ -#if defined(CONFIG_CPU_SH4) -#define kgdb_flush_icache_range(start, end) \ -{ \ - __flush_purge_region((void*)(start), (int)(end) - (int)(start));\ - flush_icache_range((start), (end)); \ -} -#else -#define kgdb_flush_icache_range(start, end) do { } while (0) -#endif - /* Taken from sh-stub.c of GDB 4.18 */ static const char hexchars[] = "0123456789abcdef"; -- cgit v1.2.3-70-g09d2 From 5d9df8eeacec943c9599f1cfd1069bc8cced3de6 Mon Sep 17 00:00:00 2001 From: Adrian McMenamin Date: Mon, 8 Oct 2007 05:19:36 +0900 Subject: sh: Fix SH-4 DMAC CHCR masking. This patch fixes the DMA cascade by masking the correct bits. Tested and working with Dreamcast PVR2 DMA. With this patch applied the existing mainline code in arch/sh/drivers/dma/dma-sh.c works, whereas before I was patching that to get round this problem. Signed-off-by: Adrian McMenamin Signed-off-by: Paul Mundt --- include/asm-sh/cpu-sh4/dma.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-sh') diff --git a/include/asm-sh/cpu-sh4/dma.h b/include/asm-sh/cpu-sh4/dma.h index 36e26a96476..aaf71b018c2 100644 --- a/include/asm-sh/cpu-sh4/dma.h +++ b/include/asm-sh/cpu-sh4/dma.h @@ -31,7 +31,7 @@ #define TS_32 0x00000030 #define TS_64 0x00000000 -#define CHCR_TS_MASK 0x30 +#define CHCR_TS_MASK 0x70 #define CHCR_TS_SHIFT 4 #define DMAOR_COD 0x00000008 -- cgit v1.2.3-70-g09d2