From daece59689e76ed55d8863cae04993679a8e844e Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Fri, 12 Aug 2011 00:14:29 +0100 Subject: ARM: 7013/1: P2V: Remove ARM_PATCH_PHYS_VIRT_16BIT This code can be removed now that MSM targets no longer need the 16-bit offsets for P2V. Signed-off-by: Nicolas Pitre Signed-off-by: Stephen Boyd Signed-off-by: Russell King --- arch/arm/kernel/head.S | 61 +++++++++++--------------------------------------- 1 file changed, 13 insertions(+), 48 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 742b6108a00..136abb61094 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -488,13 +488,8 @@ __fixup_pv_table: add r5, r5, r3 @ adjust table end address add r7, r7, r3 @ adjust __pv_phys_offset address str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset -#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT mov r6, r3, lsr #24 @ constant for add/sub instructions teq r3, r6, lsl #24 @ must be 16MiB aligned -#else - mov r6, r3, lsr #16 @ constant for add/sub instructions - teq r3, r6, lsl #16 @ must be 64kiB aligned -#endif THUMB( it ne @ cross section branch ) bne __error str r6, [r7, #4] @ save to __pv_offset @@ -510,20 +505,8 @@ ENDPROC(__fixup_pv_table) .text __fixup_a_pv_table: #ifdef CONFIG_THUMB2_KERNEL -#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT - lsls r0, r6, #24 - lsr r6, #8 - beq 1f - clz r7, r0 - lsr r0, #24 - lsl r0, r7 - bic r0, 0x0080 - lsrs r7, #1 - orrcs r0, #0x0080 - orr r0, r0, r7, lsl #12 -#endif -1: lsls r6, #24 - beq 4f + lsls r6, #24 + beq 2f clz r7, r6 lsr r6, #24 lsl r6, r7 @@ -532,43 +515,25 @@ __fixup_a_pv_table: orrcs r6, #0x0080 orr r6, r6, r7, lsl #12 orr r6, #0x4000 - b 4f -2: @ at this point the C flag is always clear - add r7, r3 -#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT - ldrh ip, [r7] - tst ip, 0x0400 @ the i bit tells us LS or MS byte - beq 3f - cmp r0, #0 @ set C flag, and ... - biceq ip, 0x0400 @ immediate zero value has a special encoding - streqh ip, [r7] @ that requires the i bit cleared -#endif -3: ldrh ip, [r7, #2] + b 2f +1: add r7, r3 + ldrh ip, [r7, #2] and ip, 0x8f00 - orrcc ip, r6 @ mask in offset bits 31-24 - orrcs ip, r0 @ mask in offset bits 23-16 + orr ip, r6 @ mask in offset bits 31-24 strh ip, [r7, #2] -4: cmp r4, r5 +2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slot - bcc 2b + bcc 1b bx lr #else -#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT - and r0, r6, #255 @ offset bits 23-16 - mov r6, r6, lsr #8 @ offset bits 31-24 -#else - mov r0, #0 @ just in case... -#endif - b 3f -2: ldr ip, [r7, r3] + b 2f +1: ldr ip, [r7, r3] bic ip, ip, #0x000000ff - tst ip, #0x400 @ rotate shift tells us LS or MS byte - orrne ip, ip, r6 @ mask in offset bits 31-24 - orreq ip, ip, r0 @ mask in offset bits 23-16 + orr ip, ip, r6 @ mask in offset bits 31-24 str ip, [r7, r3] -3: cmp r4, r5 +2: cmp r4, r5 ldrcc r7, [r4], #4 @ use branch for delay slot - bcc 2b + bcc 1b mov pc, lr #endif ENDPROC(__fixup_a_pv_table) -- cgit v1.2.3-70-g09d2 From 1ace756628443ac41e8b6b409277fc4ee847472e Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 7 Jul 2011 10:56:41 +0100 Subject: ARM: io: ecard: move ioaddr() inside __ecard_address Signed-off-by: Russell King --- arch/arm/include/asm/ecard.h | 1 - arch/arm/kernel/ecard.c | 11 ++++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/include/asm/ecard.h b/arch/arm/include/asm/ecard.h index 29f2610efc7..eaea14676d5 100644 --- a/arch/arm/include/asm/ecard.h +++ b/arch/arm/include/asm/ecard.h @@ -161,7 +161,6 @@ struct expansion_card { /* Private internal data */ const char *card_desc; /* Card description */ - CONST unsigned int podaddr; /* Base Linux address for card */ CONST loader_t loader; /* loader program */ u64 dma_mask; }; diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index d16500110ee..920f1a371a2 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -678,13 +678,13 @@ static int __init ecard_probeirqhw(void) #define IO_EC_MEMC8_BASE 0 #endif -static unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed) +static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed) { unsigned long address = 0; int slot = ec->slot_no; if (ec->slot_no == 8) - return IO_EC_MEMC8_BASE; + return (void __iomem *)ioaddr(IO_EC_MEMC8_BASE); ectcr &= ~(1 << slot); @@ -719,7 +719,7 @@ static unsigned int __ecard_address(ecard_t *ec, card_type_t type, card_speed_t #ifdef IOMD_ECTCR iomd_writeb(ectcr, IOMD_ECTCR); #endif - return address; + return (void __iomem *)(address ? ioaddr(address) : NULL); } static int ecard_prints(struct seq_file *m, ecard_t *ec) @@ -990,6 +990,7 @@ ecard_probe(int slot, card_type_t type) ecard_t **ecp; ecard_t *ec; struct ex_ecid cid; + void __iomem *addr; int i, rc; ec = ecard_alloc_card(type, slot); @@ -999,7 +1000,7 @@ ecard_probe(int slot, card_type_t type) } rc = -ENODEV; - if ((ec->podaddr = __ecard_address(ec, type, ECARD_SYNC)) == 0) + if ((addr = __ecard_address(ec, type, ECARD_SYNC)) == NULL) goto nodev; cid.r_zero = 1; @@ -1019,7 +1020,7 @@ ecard_probe(int slot, card_type_t type) ec->cid.fiqmask = cid.r_fiqmask; ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff); ec->fiqaddr = - ec->irqaddr = (void __iomem *)ioaddr(ec->podaddr); + ec->irqaddr = addr; if (ec->cid.is) { ec->irqmask = ec->cid.irqmask; -- cgit v1.2.3-70-g09d2 From 06cf0b5468f204754f32e571f8415b20cedbe5f0 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 7 Jul 2011 11:07:36 +0100 Subject: ARM: io: ecard: remove ioaddr() from ecard.c Remove ioaddr() usage from ecard.c, updating (and renaming) the constants in RiscPC's hardware.h to contain the proper translation. As this gets rid of the last ioaddr() usage, kill that too. Signed-off-by: Russell King --- arch/arm/kernel/ecard.c | 29 +++++++++-------------------- arch/arm/mach-rpc/include/mach/hardware.h | 11 +++++------ arch/arm/mach-rpc/include/mach/io.h | 3 --- 3 files changed, 14 insertions(+), 29 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 920f1a371a2..3e84f66de8f 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -674,44 +674,37 @@ static int __init ecard_probeirqhw(void) #define ecard_probeirqhw() (0) #endif -#ifndef IO_EC_MEMC8_BASE -#define IO_EC_MEMC8_BASE 0 -#endif - static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t speed) { - unsigned long address = 0; + void __iomem *address = NULL; int slot = ec->slot_no; if (ec->slot_no == 8) - return (void __iomem *)ioaddr(IO_EC_MEMC8_BASE); + return ECARD_MEMC8_BASE; ectcr &= ~(1 << slot); switch (type) { case ECARD_MEMC: if (slot < 4) - address = IO_EC_MEMC_BASE + (slot << 12); + address = ECARD_MEMC_BASE + (slot << 14); break; case ECARD_IOC: if (slot < 4) - address = IO_EC_IOC_BASE + (slot << 12); -#ifdef IO_EC_IOC4_BASE + address = ECARD_IOC_BASE + (slot << 14); else - address = IO_EC_IOC4_BASE + ((slot - 4) << 12); -#endif + address = ECARD_IOC4_BASE + ((slot - 4) << 14); if (address) - address += speed << 17; + address += speed << 19; break; -#ifdef IO_EC_EASI_BASE case ECARD_EASI: - address = IO_EC_EASI_BASE + (slot << 22); + address = ECARD_EASI_BASE + (slot << 24); if (speed == ECARD_FAST) ectcr |= 1 << slot; break; -#endif + default: break; } @@ -719,7 +712,7 @@ static void __iomem *__ecard_address(ecard_t *ec, card_type_t type, card_speed_t #ifdef IOMD_ECTCR iomd_writeb(ectcr, IOMD_ECTCR); #endif - return (void __iomem *)(address ? ioaddr(address) : NULL); + return address; } static int ecard_prints(struct seq_file *m, ecard_t *ec) @@ -1049,10 +1042,8 @@ ecard_probe(int slot, card_type_t type) set_irq_flags(ec->irq, IRQF_VALID); } -#ifdef IO_EC_MEMC8_BASE if (slot == 8) ec->irq = 11; -#endif #ifdef CONFIG_ARCH_RPC /* On RiscPC, only first two slots have DMA capability */ if (slot < 2) @@ -1098,9 +1089,7 @@ static int __init ecard_init(void) ecard_probe(slot, ECARD_IOC); } -#ifdef IO_EC_MEMC8_BASE ecard_probe(8, ECARD_IOC); -#endif irqhw = ecard_probeirqhw(); diff --git a/arch/arm/mach-rpc/include/mach/hardware.h b/arch/arm/mach-rpc/include/mach/hardware.h index 822b810215d..41777660d9f 100644 --- a/arch/arm/mach-rpc/include/mach/hardware.h +++ b/arch/arm/mach-rpc/include/mach/hardware.h @@ -51,21 +51,20 @@ /* * IO Addresses */ +#define ECARD_EASI_BASE (IO_BASE + 0x05000000) #define VIDC_BASE (IO_BASE + 0x00400000) #define EXPMASK_BASE (IO_BASE + 0x00360000) +#define ECARD_IOC4_BASE (IO_BASE + 0x00270000) +#define ECARD_IOC_BASE (IO_BASE + 0x00240000) #define IOMD_BASE (IO_BASE + 0x00200000) #define IOC_BASE (IO_BASE + 0x00200000) +#define ECARD_MEMC8_BASE (IO_BASE + 0x0002b000) #define FLOPPYDMA_BASE (IO_BASE + 0x0002a000) #define PCIO_BASE (IO_BASE + 0x00010000) +#define ECARD_MEMC_BASE (IO_BASE + 0x00000000) #define vidc_writel(val) __raw_writel(val, VIDC_BASE) -#define IO_EC_EASI_BASE 0x81400000 -#define IO_EC_IOC4_BASE 0x8009c000 -#define IO_EC_IOC_BASE 0x80090000 -#define IO_EC_MEMC8_BASE 0x8000ac00 -#define IO_EC_MEMC_BASE 0x80000000 - #define NETSLOT_BASE 0x0302b000 #define NETSLOT_SIZE 0x00001000 diff --git a/arch/arm/mach-rpc/include/mach/io.h b/arch/arm/mach-rpc/include/mach/io.h index 20da7f486e5..dd706ff2594 100644 --- a/arch/arm/mach-rpc/include/mach/io.h +++ b/arch/arm/mach-rpc/include/mach/io.h @@ -196,9 +196,6 @@ DECLARE_IO(int,l,"") #define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p)) #define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p)) -/* the following macro is deprecated */ -#define ioaddr(port) ((unsigned long)__ioaddr((port))) - #define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l) #define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l) -- cgit v1.2.3-70-g09d2 From 5e4cdb83edd69d24b744cd88a9537680e905a518 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 7 Jul 2011 11:40:52 +0100 Subject: ARM: io: RiscPC: make EASI_BASE a void iomem pointer Signed-off-by: Russell King --- arch/arm/kernel/ecard.c | 2 +- arch/arm/mach-rpc/include/mach/hardware.h | 4 ++-- arch/arm/mach-rpc/riscpc.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 3e84f66de8f..4dd0edab6a6 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -237,7 +237,7 @@ static void ecard_init_pgtables(struct mm_struct *mm) memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (IO_SIZE / PGDIR_SIZE)); - src_pgd = pgd_offset(mm, EASI_BASE); + src_pgd = pgd_offset(mm, (unsigned long)EASI_BASE); dst_pgd = pgd_offset(mm, EASI_START); memcpy(dst_pgd, src_pgd, sizeof(pgd_t) * (EASI_SIZE / PGDIR_SIZE)); diff --git a/arch/arm/mach-rpc/include/mach/hardware.h b/arch/arm/mach-rpc/include/mach/hardware.h index 41777660d9f..050d63c74cc 100644 --- a/arch/arm/mach-rpc/include/mach/hardware.h +++ b/arch/arm/mach-rpc/include/mach/hardware.h @@ -36,7 +36,7 @@ #define EASI_SIZE 0x08000000 /* EASI I/O */ #define EASI_START 0x08000000 -#define EASI_BASE 0xe5000000 +#define EASI_BASE IOMEM(0xe5000000) #define IO_START 0x03000000 /* I/O */ #define IO_SIZE 0x01000000 @@ -51,7 +51,7 @@ /* * IO Addresses */ -#define ECARD_EASI_BASE (IO_BASE + 0x05000000) +#define ECARD_EASI_BASE (EASI_BASE) #define VIDC_BASE (IO_BASE + 0x00400000) #define EXPMASK_BASE (IO_BASE + 0x00360000) #define ECARD_IOC4_BASE (IO_BASE + 0x00270000) diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 580b3c73d2c..1e0e60d0462 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -74,7 +74,7 @@ static struct map_desc rpc_io_desc[] __initdata = { .length = IO_SIZE , .type = MT_DEVICE }, { /* EASI space */ - .virtual = EASI_BASE, + .virtual = (unsigned long)EASI_BASE, .pfn = __phys_to_pfn(EASI_START), .length = EASI_SIZE, .type = MT_DEVICE -- cgit v1.2.3-70-g09d2 From e73fc88e19d74fd4dd664cff45b88caab8cde45c Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 23 Aug 2011 14:07:23 +0100 Subject: ARM: 7059/1: LPAE: Use PMD_(SHIFT|SIZE|MASK) instead of PGDIR_* PGDIR_SHIFT and PMD_SHIFT for the classic 2-level page table format have the same value (21). This patch converts the PGDIR_* uses in the kernel to the PMD_* equivalent so that LPAE builds can reuse the same code. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/kernel/head.S | 74 +++++++++++++++++++++++++---------------------- arch/arm/kernel/module.c | 2 +- arch/arm/mm/dma-mapping.c | 6 ++-- arch/arm/mm/mmu.c | 14 +++++---- 4 files changed, 51 insertions(+), 45 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 742b6108a00..4598c9699d3 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -21,6 +21,7 @@ #include #include #include +#include #ifdef CONFIG_DEBUG_LL #include @@ -38,11 +39,14 @@ #error KERNEL_RAM_VADDR must start at 0xXXXX8000 #endif +#define PG_DIR_SIZE 0x4000 +#define PMD_ORDER 2 + .globl swapper_pg_dir - .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000 + .equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE .macro pgtbl, rd, phys - add \rd, \phys, #TEXT_OFFSET - 0x4000 + add \rd, \phys, #TEXT_OFFSET - PG_DIR_SIZE .endm #ifdef CONFIG_XIP_KERNEL @@ -148,11 +152,11 @@ __create_page_tables: pgtbl r4, r8 @ page table address /* - * Clear the 16K level 1 swapper page table + * Clear the swapper page table */ mov r0, r4 mov r3, #0 - add r6, r0, #0x4000 + add r6, r0, #PG_DIR_SIZE 1: str r3, [r0], #4 str r3, [r0], #4 str r3, [r0], #4 @@ -171,30 +175,30 @@ __create_page_tables: sub r0, r0, r3 @ virt->phys offset add r5, r5, r0 @ phys __enable_mmu add r6, r6, r0 @ phys __enable_mmu_end - mov r5, r5, lsr #20 - mov r6, r6, lsr #20 + mov r5, r5, lsr #SECTION_SHIFT + mov r6, r6, lsr #SECTION_SHIFT -1: orr r3, r7, r5, lsl #20 @ flags + kernel base - str r3, [r4, r5, lsl #2] @ identity mapping - teq r5, r6 - addne r5, r5, #1 @ next section - bne 1b +1: orr r3, r7, r5, lsl #SECTION_SHIFT @ flags + kernel base + str r3, [r4, r5, lsl #PMD_ORDER] @ identity mapping + cmp r5, r6 + addlo r5, r5, #1 @ next section + blo 1b /* * Now setup the pagetables for our kernel direct * mapped region. */ mov r3, pc - mov r3, r3, lsr #20 - orr r3, r7, r3, lsl #20 - add r0, r4, #(KERNEL_START & 0xff000000) >> 18 - str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]! + mov r3, r3, lsr #SECTION_SHIFT + orr r3, r7, r3, lsl #SECTION_SHIFT + add r0, r4, #(KERNEL_START & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER) + str r3, [r0, #((KERNEL_START & 0x00f00000) >> SECTION_SHIFT) << PMD_ORDER]! ldr r6, =(KERNEL_END - 1) - add r0, r0, #4 - add r6, r4, r6, lsr #18 + add r0, r0, #1 << PMD_ORDER + add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER) 1: cmp r0, r6 - add r3, r3, #1 << 20 - strls r3, [r0], #4 + add r3, r3, #1 << SECTION_SHIFT + strls r3, [r0], #1 << PMD_ORDER bls 1b #ifdef CONFIG_XIP_KERNEL @@ -203,11 +207,11 @@ __create_page_tables: */ add r3, r8, #TEXT_OFFSET orr r3, r3, r7 - add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18 - str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]! + add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> (SECTION_SHIFT - PMD_ORDER) + str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> (SECTION_SHIFT - PMD_ORDER)]! ldr r6, =(_end - 1) add r0, r0, #4 - add r6, r4, r6, lsr #18 + add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER) 1: cmp r0, r6 add r3, r3, #1 << 20 strls r3, [r0], #4 @@ -218,12 +222,12 @@ __create_page_tables: * Then map boot params address in r2 or * the first 1MB of ram if boot params address is not specified. */ - mov r0, r2, lsr #20 - movs r0, r0, lsl #20 + mov r0, r2, lsr #SECTION_SHIFT + movs r0, r0, lsl #SECTION_SHIFT moveq r0, r8 sub r3, r0, r8 add r3, r3, #PAGE_OFFSET - add r3, r4, r3, lsr #18 + add r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER) orr r6, r7, r0 str r6, [r3] @@ -236,21 +240,21 @@ __create_page_tables: */ addruart r7, r3 - mov r3, r3, lsr #20 - mov r3, r3, lsl #2 + mov r3, r3, lsr #SECTION_SHIFT + mov r3, r3, lsl #PMD_ORDER add r0, r4, r3 rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long) cmp r3, #0x0800 @ limit to 512MB movhi r3, #0x0800 add r6, r0, r3 - mov r3, r7, lsr #20 + mov r3, r7, lsr #SECTION_SHIFT ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags - orr r3, r7, r3, lsl #20 + orr r3, r7, r3, lsl #SECTION_SHIFT 1: str r3, [r0], #4 - add r3, r3, #1 << 20 - teq r0, r6 - bne 1b + add r3, r3, #1 << SECTION_SHIFT + cmp r0, r6 + blo 1b #else /* CONFIG_DEBUG_ICEDCC */ /* we don't need any serial debugging mappings for ICEDCC */ @@ -262,7 +266,7 @@ __create_page_tables: * If we're using the NetWinder or CATS, we also need to map * in the 16550-type serial port for the debug messages */ - add r0, r4, #0xff000000 >> 18 + add r0, r4, #0xff000000 >> (SECTION_SHIFT - PMD_ORDER) orr r3, r7, #0x7c000000 str r3, [r0] #endif @@ -272,10 +276,10 @@ __create_page_tables: * Similar reasons here - for debug. This is * only for Acorn RiscPC architectures. */ - add r0, r4, #0x02000000 >> 18 + add r0, r4, #0x02000000 >> (SECTION_SHIFT - PMD_ORDER) orr r3, r7, #0x02000000 str r3, [r0] - add r0, r4, #0xd8000000 >> 18 + add r0, r4, #0xd8000000 >> (SECTION_SHIFT - PMD_ORDER) str r3, [r0] #endif #endif diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index cc2020c2c70..1e9be5d25e5 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -33,7 +33,7 @@ * recompiling the whole kernel when CONFIG_XIP_KERNEL is turned on/off. */ #undef MODULES_VADDR -#define MODULES_VADDR (((unsigned long)_etext + ~PGDIR_MASK) & PGDIR_MASK) +#define MODULES_VADDR (((unsigned long)_etext + ~PMD_MASK) & PMD_MASK) #endif #ifdef CONFIG_MMU diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 0a0a1e7c20d..4f01bfd6899 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -123,8 +123,8 @@ static void __dma_free_buffer(struct page *page, size_t size) #endif #define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) -#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PGDIR_SHIFT) -#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PGDIR_SHIFT) +#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PMD_SHIFT) +#define NUM_CONSISTENT_PTES (CONSISTENT_DMA_SIZE >> PMD_SHIFT) /* * These are the page tables (2MB each) covering uncached, DMA consistent allocations @@ -183,7 +183,7 @@ static int __init consistent_init(void) } consistent_pte[i++] = pte; - base += (1 << PGDIR_SHIFT); + base += PMD_SIZE; } while (base < CONSISTENT_END); return ret; diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 594d677b92c..36e983d9831 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -863,14 +863,14 @@ static inline void prepare_page_table(void) /* * Clear out all the mappings below the kernel image. */ - for (addr = 0; addr < MODULES_VADDR; addr += PGDIR_SIZE) + for (addr = 0; addr < MODULES_VADDR; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); #ifdef CONFIG_XIP_KERNEL /* The XIP kernel is mapped in the module area -- skip over it */ - addr = ((unsigned long)_etext + PGDIR_SIZE - 1) & PGDIR_MASK; + addr = ((unsigned long)_etext + PMD_SIZE - 1) & PMD_MASK; #endif - for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) + for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); /* @@ -885,10 +885,12 @@ static inline void prepare_page_table(void) * memory bank, up to the end of the vmalloc region. */ for (addr = __phys_to_virt(end); - addr < VMALLOC_END; addr += PGDIR_SIZE) + addr < VMALLOC_END; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); } +#define SWAPPER_PG_DIR_SIZE (PTRS_PER_PGD * sizeof(pgd_t)) + /* * Reserve the special regions of memory */ @@ -898,7 +900,7 @@ void __init arm_mm_memblock_reserve(void) * Reserve the page tables. These are already in use, * and can only be in node 0. */ - memblock_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t)); + memblock_reserve(__pa(swapper_pg_dir), SWAPPER_PG_DIR_SIZE); #ifdef CONFIG_SA1111 /* @@ -926,7 +928,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc) */ vectors_page = early_alloc(PAGE_SIZE); - for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) + for (addr = VMALLOC_END; addr; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); /* -- cgit v1.2.3-70-g09d2 From 63216d3c235d662726d6f5c55ceca91c70bb3eda Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 10 Jun 2011 13:58:30 +0000 Subject: ARM: export rtc_lock for nvram driver The rtc_lock is used by both the nvram and rtc drivers, so we need to export it if at least one of the two is built, not just for the rtc driver. Signed-off-by: Arnd Bergmann --- arch/arm/kernel/time.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index cb634c3e28e..5a54b95d6bd 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -39,13 +39,11 @@ */ static struct sys_timer *system_timer; -#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) +#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || \ + defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) /* this needs a better home */ DEFINE_SPINLOCK(rtc_lock); - -#ifdef CONFIG_RTC_DRV_CMOS_MODULE EXPORT_SYMBOL(rtc_lock); -#endif #endif /* pc-style 'CMOS' RTC support */ /* change this if you have some constant time drift */ -- cgit v1.2.3-70-g09d2 From 15e0d9e37c7fe9711b60f47221c394d45553ad8c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 1 Oct 2011 21:09:39 +0200 Subject: ARM: pm: let platforms select cpu_suspend support Support for the cpu_suspend functions is only built-in when CONFIG_PM_SLEEP is enabled, but omap3/4, exynos4 and pxa always call cpu_suspend when CONFIG_PM is enabled. Signed-off-by: Arnd Bergmann --- arch/arm/Kconfig | 4 ++++ arch/arm/kernel/Makefile | 2 +- arch/arm/mach-exynos4/Kconfig | 1 + arch/arm/mach-omap2/Kconfig | 2 ++ arch/arm/mm/proc-v7.S | 2 +- 5 files changed, 9 insertions(+), 2 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 497af51e917..3445f50b0b7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -631,6 +631,7 @@ config ARCH_PXA select SPARSE_IRQ select AUTO_ZRELADDR select MULTI_IRQ_HANDLER + select ARM_CPU_SUSPEND if PM help Support for Intel/Marvell's PXA2xx/PXA3xx processor line. @@ -2077,6 +2078,9 @@ config ARCH_SUSPEND_POSSIBLE CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE def_bool y +config ARM_CPU_SUSPEND + def_bool PM_SLEEP + endmenu source "net/Kconfig" diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index f7887dc53c1..4ce3303a419 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_MODULES) += armksyms.o module.o obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_PCI) += bios32.o isa.o -obj-$(CONFIG_PM_SLEEP) += sleep.o +obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o obj-$(CONFIG_SMP) += smp.o smp_tlb.o obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig index 0c77ab99fa1..fc1f92dfbea 100644 --- a/arch/arm/mach-exynos4/Kconfig +++ b/arch/arm/mach-exynos4/Kconfig @@ -12,6 +12,7 @@ if ARCH_EXYNOS4 config CPU_EXYNOS4210 bool select S3C_PL330_DMA + select ARM_CPU_SUSPEND if PM help Enable EXYNOS4210 CPU support diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 57b66d590c5..89bfb49389f 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -36,6 +36,7 @@ config ARCH_OMAP3 select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4 select ARCH_HAS_OPP select PM_OPP if PM + select ARM_CPU_SUSPEND if PM config ARCH_OMAP4 bool "TI OMAP4" @@ -50,6 +51,7 @@ config ARCH_OMAP4 select ARCH_HAS_OPP select PM_OPP if PM select USB_ARCH_HAS_EHCI + select ARM_CPU_SUSPEND if PM comment "OMAP Core Type" depends on ARCH_OMAP2 diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index a30e78542cc..591accdb56e 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -217,7 +217,7 @@ ENDPROC(cpu_v7_set_pte_ext) /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */ .globl cpu_v7_suspend_size .equ cpu_v7_suspend_size, 4 * 9 -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_ARM_CPU_SUSPEND ENTRY(cpu_v7_do_suspend) stmfd sp!, {r4 - r11, lr} mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID -- cgit v1.2.3-70-g09d2 From b214bea525c5b62f6f8984557022e4593c441205 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sun, 4 Sep 2011 22:30:06 +0200 Subject: ARM: pci: always export pcibios_bus_to_resource Some PCI drivers call pcibios_bus_to_resource directly, but it is only exported when CONFIG_HOTPLUG is set, because it was initially mean for pccard support. Moving the export out of the #ifdef lets us avoid these build errors: ERROR: "pcibios_bus_to_resource" [drivers/video/vt8623fb.ko] undefined! ERROR: "pcibios_bus_to_resource" [drivers/video/arkfb.ko] undefined! ERROR: "pcibios_bus_to_resource" [drivers/video/s3fb.ko] undefined! Signed-off-by: Arnd Bergmann --- arch/arm/kernel/bios32.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index d6df359408f..c0d9203fc75 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -412,6 +412,9 @@ void pcibios_fixup_bus(struct pci_bus *bus) printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); } +#ifdef CONFIG_HOTPLUG +EXPORT_SYMBOL(pcibios_fixup_bus); +#endif /* * Convert from Linux-centric to bus-centric addresses for bridge devices. @@ -431,6 +434,7 @@ pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, region->start = res->start - offset; region->end = res->end - offset; } +EXPORT_SYMBOL(pcibios_resource_to_bus); void __devinit pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, @@ -447,12 +451,7 @@ pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, res->start = region->start + offset; res->end = region->end + offset; } - -#ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pcibios_fixup_bus); -EXPORT_SYMBOL(pcibios_resource_to_bus); EXPORT_SYMBOL(pcibios_bus_to_resource); -#endif /* * Swizzle the device pin each time we cross a bridge. -- cgit v1.2.3-70-g09d2 From c9018aab8eee24b993c12c7aff7fc99d3d73f298 Mon Sep 17 00:00:00 2001 From: Vincent Guittot Date: Mon, 8 Aug 2011 13:21:59 +0100 Subject: ARM: 7011/1: Add ARM cpu topology definition The affinity between ARM processors is defined in the MPIDR register. We can identify which processors are in the same cluster, and which ones have performance interdependency. We can define the cpu topology of ARM platform, that is then used by sched_mc and sched_smt. The default state of sched_mc and sched_smt config is disable. When enabled, the behavior of the scheduler can be modified with sched_mc_power_savings and sched_smt_power_savings sysfs interfaces. Changes since v4 : * Remove unnecessary parentheses and blank lines Changes since v3 : * Update the format of printk message * Remove blank line Changes since v2 : * Update the commit message and some comments Changes since v1 : * Update the commit message * Add read_cpuid_mpidr in arch/arm/include/asm/cputype.h * Modify header of arch/arm/kernel/topology.c * Modify tests and manipulation of MPIDR's bitfields * Modify the place and dependancy of the config * Modify Noop functions Signed-off-by: Vincent Guittot Reviewed-by: Amit Kucheria Signed-off-by: Russell King --- arch/arm/Kconfig | 25 +++++++ arch/arm/include/asm/cputype.h | 6 ++ arch/arm/include/asm/topology.h | 33 +++++++++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/smp.c | 5 ++ arch/arm/kernel/topology.c | 148 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 218 insertions(+) create mode 100644 arch/arm/kernel/topology.c (limited to 'arch/arm/kernel') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3269576dbfa..c208fd97c18 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1393,6 +1393,31 @@ config SMP_ON_UP If you don't know what to do here, say Y. +config ARM_CPU_TOPOLOGY + bool "Support cpu topology definition" + depends on SMP && CPU_V7 + default y + help + Support ARM cpu topology definition. The MPIDR register defines + affinity between processors which is then used to describe the cpu + topology of an ARM System. + +config SCHED_MC + bool "Multi-core scheduler support" + depends on ARM_CPU_TOPOLOGY + help + Multi-core scheduler support improves the CPU scheduler's decision + making when dealing with multi-core CPU chips at a cost of slightly + increased overhead in some places. If unsure say N here. + +config SCHED_SMT + bool "SMT scheduler support" + depends on ARM_CPU_TOPOLOGY + help + Improves the CPU scheduler's decision making when dealing with + MultiThreading at a cost of slightly increased overhead in some + places. If unsure say N here. + config HAVE_ARM_SCU bool help diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index cd4458f6417..cb47d28cbe1 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -8,6 +8,7 @@ #define CPUID_CACHETYPE 1 #define CPUID_TCM 2 #define CPUID_TLBTYPE 3 +#define CPUID_MPIDR 5 #define CPUID_EXT_PFR0 "c1, 0" #define CPUID_EXT_PFR1 "c1, 1" @@ -70,6 +71,11 @@ static inline unsigned int __attribute_const__ read_cpuid_tcmstatus(void) return read_cpuid(CPUID_TCM); } +static inline unsigned int __attribute_const__ read_cpuid_mpidr(void) +{ + return read_cpuid(CPUID_MPIDR); +} + /* * Intel's XScale3 core supports some v6 features (supersections, L2) * but advertises itself as v5 as it does not support the v6 ISA. For diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h index accbd7cad9b..a7e457ed27c 100644 --- a/arch/arm/include/asm/topology.h +++ b/arch/arm/include/asm/topology.h @@ -1,6 +1,39 @@ #ifndef _ASM_ARM_TOPOLOGY_H #define _ASM_ARM_TOPOLOGY_H +#ifdef CONFIG_ARM_CPU_TOPOLOGY + +#include + +struct cputopo_arm { + int thread_id; + int core_id; + int socket_id; + cpumask_t thread_sibling; + cpumask_t core_sibling; +}; + +extern struct cputopo_arm cpu_topology[NR_CPUS]; + +#define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id) +#define topology_core_id(cpu) (cpu_topology[cpu].core_id) +#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling) +#define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_sibling) + +#define mc_capable() (cpu_topology[0].socket_id != -1) +#define smt_capable() (cpu_topology[0].thread_id != -1) + +void init_cpu_topology(void); +void store_cpu_topology(unsigned int cpuid); +const struct cpumask *cpu_coregroup_mask(unsigned int cpu); + +#else + +static inline void init_cpu_topology(void) { } +static inline void store_cpu_topology(unsigned int cpuid) { } + +#endif + #include #endif /* _ASM_ARM_TOPOLOGY_H */ diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index f7887dc53c1..c687bceba7d 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -66,6 +66,7 @@ obj-$(CONFIG_IWMMXT) += iwmmxt.o obj-$(CONFIG_CPU_HAS_PMU) += pmu.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt +obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o ifneq ($(CONFIG_ARCH_EBSA110),y) obj-y += io.o diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index d88ff0230e8..62775c5c5ba 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -268,6 +269,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid) struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid); cpu_info->loops_per_jiffy = loops_per_jiffy; + + store_cpu_topology(cpuid); } /* @@ -358,6 +361,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus) { unsigned int ncores = num_possible_cpus(); + init_cpu_topology(); + smp_store_cpu_info(smp_processor_id()); /* diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c new file mode 100644 index 00000000000..1040c00405d --- /dev/null +++ b/arch/arm/kernel/topology.c @@ -0,0 +1,148 @@ +/* + * arch/arm/kernel/topology.c + * + * Copyright (C) 2011 Linaro Limited. + * Written by: Vincent Guittot + * + * based on arch/sh/kernel/topology.c + * + * 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 + +#define MPIDR_SMP_BITMASK (0x3 << 30) +#define MPIDR_SMP_VALUE (0x2 << 30) + +#define MPIDR_MT_BITMASK (0x1 << 24) + +/* + * These masks reflect the current use of the affinity levels. + * The affinity level can be up to 16 bits according to ARM ARM + */ + +#define MPIDR_LEVEL0_MASK 0x3 +#define MPIDR_LEVEL0_SHIFT 0 + +#define MPIDR_LEVEL1_MASK 0xF +#define MPIDR_LEVEL1_SHIFT 8 + +#define MPIDR_LEVEL2_MASK 0xFF +#define MPIDR_LEVEL2_SHIFT 16 + +struct cputopo_arm cpu_topology[NR_CPUS]; + +const struct cpumask *cpu_coregroup_mask(unsigned int cpu) +{ + return &cpu_topology[cpu].core_sibling; +} + +/* + * store_cpu_topology is called at boot when only one cpu is running + * and with the mutex cpu_hotplug.lock locked, when several cpus have booted, + * which prevents simultaneous write access to cpu_topology array + */ +void store_cpu_topology(unsigned int cpuid) +{ + struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid]; + unsigned int mpidr; + unsigned int cpu; + + /* If the cpu topology has been already set, just return */ + if (cpuid_topo->core_id != -1) + return; + + mpidr = read_cpuid_mpidr(); + + /* create cpu topology mapping */ + if ((mpidr & MPIDR_SMP_BITMASK) == MPIDR_SMP_VALUE) { + /* + * This is a multiprocessor system + * multiprocessor format & multiprocessor mode field are set + */ + + if (mpidr & MPIDR_MT_BITMASK) { + /* core performance interdependency */ + cpuid_topo->thread_id = (mpidr >> MPIDR_LEVEL0_SHIFT) + & MPIDR_LEVEL0_MASK; + cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL1_SHIFT) + & MPIDR_LEVEL1_MASK; + cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL2_SHIFT) + & MPIDR_LEVEL2_MASK; + } else { + /* largely independent cores */ + cpuid_topo->thread_id = -1; + cpuid_topo->core_id = (mpidr >> MPIDR_LEVEL0_SHIFT) + & MPIDR_LEVEL0_MASK; + cpuid_topo->socket_id = (mpidr >> MPIDR_LEVEL1_SHIFT) + & MPIDR_LEVEL1_MASK; + } + } else { + /* + * This is an uniprocessor system + * we are in multiprocessor format but uniprocessor system + * or in the old uniprocessor format + */ + cpuid_topo->thread_id = -1; + cpuid_topo->core_id = 0; + cpuid_topo->socket_id = -1; + } + + /* update core and thread sibling masks */ + for_each_possible_cpu(cpu) { + struct cputopo_arm *cpu_topo = &cpu_topology[cpu]; + + if (cpuid_topo->socket_id == cpu_topo->socket_id) { + cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); + if (cpu != cpuid) + cpumask_set_cpu(cpu, + &cpuid_topo->core_sibling); + + if (cpuid_topo->core_id == cpu_topo->core_id) { + cpumask_set_cpu(cpuid, + &cpu_topo->thread_sibling); + if (cpu != cpuid) + cpumask_set_cpu(cpu, + &cpuid_topo->thread_sibling); + } + } + } + smp_wmb(); + + printk(KERN_INFO "CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n", + cpuid, cpu_topology[cpuid].thread_id, + cpu_topology[cpuid].core_id, + cpu_topology[cpuid].socket_id, mpidr); +} + +/* + * init_cpu_topology is called at boot when only one cpu is running + * which prevent simultaneous write access to cpu_topology array + */ +void init_cpu_topology(void) +{ + unsigned int cpu; + + /* init core mask */ + for_each_possible_cpu(cpu) { + struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]); + + cpu_topo->thread_id = -1; + cpu_topo->core_id = -1; + cpu_topo->socket_id = -1; + cpumask_clear(&cpu_topo->core_sibling); + cpumask_clear(&cpu_topo->thread_sibling); + } + smp_wmb(); +} -- cgit v1.2.3-70-g09d2 From d6257288c4052465feeff7e283e35ec0ed06ca03 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 23 Aug 2011 22:19:29 +0100 Subject: ARM: 7060/1: smp: populate logical CPU mapping during boot To allow booting Linux on a CPU with physical ID != 0, we need to provide a mapping from the logical CPU number to the physical CPU number. This patch adds such a mapping and populates it during boot. Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/smp.h | 6 ++++++ arch/arm/kernel/smp.c | 15 +++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'arch/arm/kernel') diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index e42d96a45d3..674ebcd337f 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -65,6 +65,12 @@ extern void platform_secondary_init(unsigned int cpu); */ extern void platform_smp_prepare_cpus(unsigned int); +/* + * Logical CPU mapping. + */ +extern int __cpu_logical_map[NR_CPUS]; +#define cpu_logical_map(cpu) __cpu_logical_map[cpu] + /* * Initial data for bringing up a secondary CPU. */ diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 62775c5c5ba..3f12ce9b079 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -40,6 +40,7 @@ #include #include #include +#include /* * as from 2.5, kernels no longer have an init_tasks structure @@ -260,6 +261,20 @@ void __ref cpu_die(void) } #endif /* CONFIG_HOTPLUG_CPU */ +int __cpu_logical_map[NR_CPUS]; + +void __init smp_setup_processor_id(void) +{ + int i; + u32 cpu = is_smp() ? read_cpuid_mpidr() & 0xff : 0; + + cpu_logical_map(0) = cpu; + for (i = 1; i < NR_CPUS; ++i) + cpu_logical_map(i) = i == cpu ? 0 : i; + + printk(KERN_INFO "Booting Linux on physical CPU %d\n", cpu); +} + /* * Called by both boot and secondaries to move global data into * per-processor storage. -- cgit v1.2.3-70-g09d2 From 26a527e69d6e6077bff9e2cddcb08337ac33a52d Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 25 Sep 2011 08:25:43 +0100 Subject: ARM: 7100/1: smp_scu: remove __init annotation from scu_enable() When Cortex-A9 MPCore resumes from Dormant or Shutdown modes, SCU needs to be re-enabled. This patch removes __init annotation from function scu_enable(), so that platform resume procedure can call it to re-enable SCU. Signed-off-by: Shawn Guo Signed-off-by: Russell King --- arch/arm/kernel/smp_scu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c index 79ed5e7f204..5b6d536cbfe 100644 --- a/arch/arm/kernel/smp_scu.c +++ b/arch/arm/kernel/smp_scu.c @@ -33,7 +33,7 @@ unsigned int __init scu_get_core_count(void __iomem *scu_base) /* * Enable the SCU */ -void __init scu_enable(void __iomem *scu_base) +void scu_enable(void __iomem *scu_base) { u32 scu_ctrl; -- cgit v1.2.3-70-g09d2 From 0b5a1b95dcdfa451125132d5ce3f79a27ffb0950 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 6 Oct 2011 15:18:14 +0100 Subject: ARM: 7123/1: smp: Add an IPI handler callable from C code In order to be able to handle IPI directly from C code instead of assembly code, introduce handle_IPI(), which is modeled after handle_IRQ(). Signed-off-by: Marc Zyngier Signed-off-by: Russell King --- arch/arm/include/asm/smp.h | 5 +++++ arch/arm/kernel/smp.c | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'arch/arm/kernel') diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index 674ebcd337f..0a17b62538c 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h @@ -32,6 +32,11 @@ extern void show_ipi_list(struct seq_file *, int); */ asmlinkage void do_IPI(int ipinr, struct pt_regs *regs); +/* + * Called from C code, this handles an IPI. + */ +void handle_IPI(int ipinr, struct pt_regs *regs); + /* * Setup the set of possible CPUs (via set_cpu_possible) */ diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 3f12ce9b079..2e49f1883fe 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -586,6 +586,11 @@ static void ipi_cpu_stop(unsigned int cpu) * Main handler for inter-processor interrupts */ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs) +{ + handle_IPI(ipinr, regs); +} + +void handle_IPI(int ipinr, struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); struct pt_regs *old_regs = set_irq_regs(regs); -- cgit v1.2.3-70-g09d2 From 0af8aa0069e43f90d59666510342c05e97d8c4b8 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 6 Oct 2011 15:19:14 +0100 Subject: ARM: 7124/1: smp: Add a localtimer handler callable from C code In order to be able to handle localtimer directly from C code instead of assembly code, introduce handle_local_timer(), which is modeled after handle_IRQ(). Signed-off-by: Shawn Guo Signed-off-by: Russell King --- arch/arm/include/asm/localtimer.h | 4 ++++ arch/arm/kernel/smp.c | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'arch/arm/kernel') diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h index 080d74f8128..3306f281333 100644 --- a/arch/arm/include/asm/localtimer.h +++ b/arch/arm/include/asm/localtimer.h @@ -22,6 +22,10 @@ void percpu_timer_setup(void); */ asmlinkage void do_local_timer(struct pt_regs *); +/* + * Called from C code + */ +void handle_local_timer(struct pt_regs *); #ifdef CONFIG_LOCAL_TIMERS diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 2e49f1883fe..0949007d09a 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -479,6 +479,11 @@ static void ipi_timer(void) #ifdef CONFIG_LOCAL_TIMERS asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs) +{ + handle_local_timer(regs); +} + +void handle_local_timer(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); int cpu = smp_processor_id(); -- cgit v1.2.3-70-g09d2 From 5a567d78c437e3be1c512734cdfe64b4ae6b82d7 Mon Sep 17 00:00:00 2001 From: Jamie Iles Date: Sat, 8 Oct 2011 11:20:42 +0100 Subject: ARM: 7115/4: move __exception and friends to asm/exception.h The definition of __exception_irq_entry for CONFIG_FUNCTION_GRAPH_TRACER=y needs linux/ftrace.h, but this creates a circular dependency with it's current home in asm/system.h. Create asm/exception.h and update all current users. v4: - rebase to rmk/for-next v3: - remove redundant includes of linux/ftrace.h v2: - document the usage restricitions of __exception* Cc: Zoltan Devai Signed-off-by: Jamie Iles Signed-off-by: Russell King --- arch/arm/include/asm/exception.h | 19 +++++++++++++++++++ arch/arm/include/asm/system.h | 7 ------- arch/arm/kernel/irq.c | 2 +- arch/arm/kernel/smp.c | 2 +- arch/arm/kernel/traps.c | 1 + arch/arm/mach-pxa/irq.c | 2 ++ arch/arm/mm/fault.c | 1 + 7 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 arch/arm/include/asm/exception.h (limited to 'arch/arm/kernel') diff --git a/arch/arm/include/asm/exception.h b/arch/arm/include/asm/exception.h new file mode 100644 index 00000000000..5abaf5bbd98 --- /dev/null +++ b/arch/arm/include/asm/exception.h @@ -0,0 +1,19 @@ +/* + * Annotations for marking C functions as exception handlers. + * + * These should only be used for C functions that are called from the low + * level exception entry code and not any intervening C code. + */ +#ifndef __ASM_ARM_EXCEPTION_H +#define __ASM_ARM_EXCEPTION_H + +#include + +#define __exception __attribute__((section(".exception.text"))) +#ifdef CONFIG_FUNCTION_GRAPH_TRACER +#define __exception_irq_entry __irq_entry +#else +#define __exception_irq_entry __exception +#endif + +#endif /* __ASM_ARM_EXCEPTION_H */ diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 832888d0c20..ed6b0499a10 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -62,13 +62,6 @@ #include -#define __exception __attribute__((section(".exception.text"))) -#ifdef CONFIG_FUNCTION_GRAPH_TRACER -#define __exception_irq_entry __irq_entry -#else -#define __exception_irq_entry __exception -#endif - struct thread_info; struct task_struct; diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index de3dcab8610..53919b230e8 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -35,8 +35,8 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 0949007d09a..35417d0fb8a 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -31,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index bc9f9da782c..210382555af 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index b09e848eb6c..ca607571782 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -19,6 +19,8 @@ #include #include +#include + #include #include #include diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 3b5ea68acbb..aa33949fef6 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3-70-g09d2 From 91c2ebb90b1890abc648ba9dec5608cbc97e1cb9 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Fri, 30 Sep 2011 14:43:12 +0100 Subject: ARM: 7114/1: cache-l2x0: add resume entry for l2 in secure mode we save the l2x0 registers at the first initialization, and platform codes can get them to restore l2x0 status after wakeup. Cc: Lorenzo Pieralisi Signed-off-by: Barry Song Reviewed-by: Santosh Shilimkar Tested-by: Shawn Guo Signed-off-by: Russell King --- arch/arm/include/asm/hardware/cache-l2x0.h | 25 ++++++ arch/arm/include/asm/outercache.h | 7 ++ arch/arm/kernel/asm-offsets.c | 12 +++ arch/arm/mm/cache-l2x0.c | 129 ++++++++++++++++++++++++++--- 4 files changed, 163 insertions(+), 10 deletions(-) (limited to 'arch/arm/kernel') diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index c48cb1e1c46..434edccdf7f 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -67,6 +67,13 @@ #define L2X0_CACHE_ID_PART_MASK (0xf << 6) #define L2X0_CACHE_ID_PART_L210 (1 << 6) #define L2X0_CACHE_ID_PART_L310 (3 << 6) +#define L2X0_CACHE_ID_RTL_MASK 0x3f +#define L2X0_CACHE_ID_RTL_R0P0 0x0 +#define L2X0_CACHE_ID_RTL_R1P0 0x2 +#define L2X0_CACHE_ID_RTL_R2P0 0x4 +#define L2X0_CACHE_ID_RTL_R3P0 0x5 +#define L2X0_CACHE_ID_RTL_R3P1 0x6 +#define L2X0_CACHE_ID_RTL_R3P2 0x8 #define L2X0_AUX_CTRL_MASK 0xc0000fff #define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT 0 @@ -96,6 +103,24 @@ #ifndef __ASSEMBLY__ extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask); + +struct l2x0_regs { + unsigned long phy_base; + unsigned long aux_ctrl; + /* + * Whether the following registers need to be saved/restored + * depends on platform + */ + unsigned long tag_latency; + unsigned long data_latency; + unsigned long filter_start; + unsigned long filter_end; + unsigned long prefetch_ctrl; + unsigned long pwr_ctrl; +}; + +extern struct l2x0_regs l2x0_saved_regs; + #endif #endif diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h index d8387437ec5..53426c66352 100644 --- a/arch/arm/include/asm/outercache.h +++ b/arch/arm/include/asm/outercache.h @@ -34,6 +34,7 @@ struct outer_cache_fns { void (*sync)(void); #endif void (*set_debug)(unsigned long); + void (*resume)(void); }; #ifdef CONFIG_OUTER_CACHE @@ -74,6 +75,12 @@ static inline void outer_disable(void) outer_cache.disable(); } +static inline void outer_resume(void) +{ + if (outer_cache.resume) + outer_cache.resume(); +} + #else static inline void outer_inv_range(phys_addr_t start, phys_addr_t end) diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 16baba2e436..1429d8989fb 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -20,6 +20,7 @@ #include #include #include +#include #include /* @@ -92,6 +93,17 @@ int main(void) DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0)); DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); BLANK(); +#ifdef CONFIG_CACHE_L2X0 + DEFINE(L2X0_R_PHY_BASE, offsetof(struct l2x0_regs, phy_base)); + DEFINE(L2X0_R_AUX_CTRL, offsetof(struct l2x0_regs, aux_ctrl)); + DEFINE(L2X0_R_TAG_LATENCY, offsetof(struct l2x0_regs, tag_latency)); + DEFINE(L2X0_R_DATA_LATENCY, offsetof(struct l2x0_regs, data_latency)); + DEFINE(L2X0_R_FILTER_START, offsetof(struct l2x0_regs, filter_start)); + DEFINE(L2X0_R_FILTER_END, offsetof(struct l2x0_regs, filter_end)); + DEFINE(L2X0_R_PREFETCH_CTRL, offsetof(struct l2x0_regs, prefetch_ctrl)); + DEFINE(L2X0_R_PWR_CTRL, offsetof(struct l2x0_regs, pwr_ctrl)); + BLANK(); +#endif #ifdef CONFIG_CPU_HAS_ASID DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id)); BLANK(); diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index 0d85d221d7b..3f9b9980478 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -33,6 +33,14 @@ static DEFINE_SPINLOCK(l2x0_lock); static uint32_t l2x0_way_mask; /* Bitmask of active ways */ static uint32_t l2x0_size; +struct l2x0_regs l2x0_saved_regs; + +struct l2x0_of_data { + void (*setup)(const struct device_node *, __u32 *, __u32 *); + void (*save)(void); + void (*resume)(void); +}; + static inline void cache_wait_way(void __iomem *reg, unsigned long mask) { /* wait for cache operation by line or way to complete */ @@ -280,7 +288,7 @@ static void l2x0_disable(void) spin_unlock_irqrestore(&l2x0_lock, flags); } -static void __init l2x0_unlock(__u32 cache_id) +static void l2x0_unlock(__u32 cache_id) { int lockregs; int i; @@ -356,6 +364,8 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) /* l2x0 controller is disabled */ writel_relaxed(aux, l2x0_base + L2X0_AUX_CTRL); + l2x0_saved_regs.aux_ctrl = aux; + l2x0_inv_all(); /* enable L2X0 */ @@ -445,33 +455,132 @@ static void __init pl310_of_setup(const struct device_node *np, } } +static void __init pl310_save(void) +{ + u32 l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) & + L2X0_CACHE_ID_RTL_MASK; + + l2x0_saved_regs.tag_latency = readl_relaxed(l2x0_base + + L2X0_TAG_LATENCY_CTRL); + l2x0_saved_regs.data_latency = readl_relaxed(l2x0_base + + L2X0_DATA_LATENCY_CTRL); + l2x0_saved_regs.filter_end = readl_relaxed(l2x0_base + + L2X0_ADDR_FILTER_END); + l2x0_saved_regs.filter_start = readl_relaxed(l2x0_base + + L2X0_ADDR_FILTER_START); + + if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) { + /* + * From r2p0, there is Prefetch offset/control register + */ + l2x0_saved_regs.prefetch_ctrl = readl_relaxed(l2x0_base + + L2X0_PREFETCH_CTRL); + /* + * From r3p0, there is Power control register + */ + if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0) + l2x0_saved_regs.pwr_ctrl = readl_relaxed(l2x0_base + + L2X0_POWER_CTRL); + } +} + +static void l2x0_resume(void) +{ + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { + /* restore aux ctrl and enable l2 */ + l2x0_unlock(readl_relaxed(l2x0_base + L2X0_CACHE_ID)); + + writel_relaxed(l2x0_saved_regs.aux_ctrl, l2x0_base + + L2X0_AUX_CTRL); + + l2x0_inv_all(); + + writel_relaxed(1, l2x0_base + L2X0_CTRL); + } +} + +static void pl310_resume(void) +{ + u32 l2x0_revision; + + if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { + /* restore pl310 setup */ + writel_relaxed(l2x0_saved_regs.tag_latency, + l2x0_base + L2X0_TAG_LATENCY_CTRL); + writel_relaxed(l2x0_saved_regs.data_latency, + l2x0_base + L2X0_DATA_LATENCY_CTRL); + writel_relaxed(l2x0_saved_regs.filter_end, + l2x0_base + L2X0_ADDR_FILTER_END); + writel_relaxed(l2x0_saved_regs.filter_start, + l2x0_base + L2X0_ADDR_FILTER_START); + + l2x0_revision = readl_relaxed(l2x0_base + L2X0_CACHE_ID) & + L2X0_CACHE_ID_RTL_MASK; + + if (l2x0_revision >= L2X0_CACHE_ID_RTL_R2P0) { + writel_relaxed(l2x0_saved_regs.prefetch_ctrl, + l2x0_base + L2X0_PREFETCH_CTRL); + if (l2x0_revision >= L2X0_CACHE_ID_RTL_R3P0) + writel_relaxed(l2x0_saved_regs.pwr_ctrl, + l2x0_base + L2X0_POWER_CTRL); + } + } + + l2x0_resume(); +} + +static const struct l2x0_of_data pl310_data = { + pl310_of_setup, + pl310_save, + pl310_resume, +}; + +static const struct l2x0_of_data l2x0_data = { + l2x0_of_setup, + NULL, + l2x0_resume, +}; + static const struct of_device_id l2x0_ids[] __initconst = { - { .compatible = "arm,pl310-cache", .data = pl310_of_setup }, - { .compatible = "arm,l220-cache", .data = l2x0_of_setup }, - { .compatible = "arm,l210-cache", .data = l2x0_of_setup }, + { .compatible = "arm,pl310-cache", .data = (void *)&pl310_data }, + { .compatible = "arm,l220-cache", .data = (void *)&l2x0_data }, + { .compatible = "arm,l210-cache", .data = (void *)&l2x0_data }, {} }; int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask) { struct device_node *np; - void (*l2_setup)(const struct device_node *np, - __u32 *aux_val, __u32 *aux_mask); + struct l2x0_of_data *data; + struct resource res; np = of_find_matching_node(NULL, l2x0_ids); if (!np) return -ENODEV; - l2x0_base = of_iomap(np, 0); + + if (of_address_to_resource(np, 0, &res)) + return -ENODEV; + + l2x0_base = ioremap(res.start, resource_size(&res)); if (!l2x0_base) return -ENOMEM; + l2x0_saved_regs.phy_base = res.start; + + data = of_match_node(l2x0_ids, np)->data; + /* L2 configuration can only be changed if the cache is disabled */ if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & 1)) { - l2_setup = of_match_node(l2x0_ids, np)->data; - if (l2_setup) - l2_setup(np, &aux_val, &aux_mask); + if (data->setup) + data->setup(np, &aux_val, &aux_mask); } + + if (data->save) + data->save(); + l2x0_init(l2x0_base, aux_val, aux_mask); + + outer_cache.resume = data->resume; return 0; } #endif -- cgit v1.2.3-70-g09d2