From 70e541d48ef8f2c805f3bfde3d4651ab8368ea7d Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 14 Feb 2007 19:14:56 +0100 Subject: [PATCH] --- yaml --- r: 48980 b: refs/heads/master c: b3a1bde4db9889feb116330bff21214811c940e4 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/arch/arm/common/dmabounce.c | 21 ++-- trunk/arch/arm/common/gic.c | 109 +++++++++++++++++--- trunk/arch/arm/kernel/setup.c | 3 - trunk/arch/arm/mach-realview/platsmp.c | 2 +- trunk/arch/arm/mach-realview/realview_eb.c | 4 +- trunk/arch/arm/mm/Kconfig | 7 -- trunk/arch/arm/mm/Makefile | 2 - trunk/arch/arm/mm/cache-l2x0.c | 104 ------------------- trunk/arch/arm/mm/consistent.c | 17 ++- trunk/arch/arm/mm/context.c | 12 +-- trunk/arch/arm/mm/proc-v6.S | 14 ++- trunk/arch/arm/mm/tlb-v6.S | 4 - trunk/include/asm-arm/cacheflush.h | 49 ++------- trunk/include/asm-arm/dma-mapping.h | 2 +- trunk/include/asm-arm/domain.h | 1 - trunk/include/asm-arm/hardware/cache-l2x0.h | 56 ---------- trunk/include/asm-arm/hardware/gic.h | 5 +- trunk/include/asm-arm/system.h | 62 +++++------ trunk/include/asm-arm/tlbflush.h | 50 +++------ 20 files changed, 168 insertions(+), 358 deletions(-) delete mode 100644 trunk/arch/arm/mm/cache-l2x0.c delete mode 100644 trunk/include/asm-arm/hardware/cache-l2x0.h diff --git a/[refs] b/[refs] index f8a8942ddc60..bde7bb239ac5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 382266ad5ad4119ec12df889afa5062a0a0cd6ae +refs/heads/master: b3a1bde4db9889feb116330bff21214811c940e4 diff --git a/trunk/arch/arm/common/dmabounce.c b/trunk/arch/arm/common/dmabounce.c index 2362c498f52e..2e635b814c14 100644 --- a/trunk/arch/arm/common/dmabounce.c +++ b/trunk/arch/arm/common/dmabounce.c @@ -281,14 +281,10 @@ map_single(struct device *dev, void *ptr, size_t size, ptr = buf->safe; dma_addr = buf->safe_dma_addr; - } else { - /* - * We don't need to sync the DMA buffer since - * it was allocated via the coherent allocators. - */ - consistent_sync(ptr, size, dir); } + consistent_sync(ptr, size, dir); + return dma_addr; } @@ -321,12 +317,12 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, DO_STATS ( device_info->bounce_count++ ); if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { - void *ptr = buf->ptr; + unsigned long ptr; dev_dbg(dev, "%s: copy back safe %p to unsafe %p size %d\n", - __func__, buf->safe, ptr, size); - memcpy(ptr, buf->safe, size); + __func__, buf->safe, buf->ptr, size); + memcpy(buf->ptr, buf->safe, size); /* * DMA buffers must have the same cache properties @@ -336,8 +332,8 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, * bidirectional case because we know the cache * lines will be coherent with the data written. */ + ptr = (unsigned long)buf->ptr; dmac_clean_range(ptr, ptr + size); - outer_clean_range(__pa(ptr), __pa(ptr) + size); } free_safe_buffer(device_info, buf); } @@ -401,10 +397,7 @@ sync_single(struct device *dev, dma_addr_t dma_addr, size_t size, default: BUG(); } - /* - * No need to sync the safe buffer - it was allocated - * via the coherent allocators. - */ + consistent_sync(buf->safe, size, dir); } else { consistent_sync(dma_to_virt(dev, dma_addr), size, dir); } diff --git a/trunk/arch/arm/common/gic.c b/trunk/arch/arm/common/gic.c index 09b9d1b6844c..4deece5fbdf4 100644 --- a/trunk/arch/arm/common/gic.c +++ b/trunk/arch/arm/common/gic.c @@ -14,7 +14,9 @@ * * o There is one CPU Interface per CPU, which sends interrupts sent * by the Distributor, and interrupts generated locally, to the - * associated CPU. + * associated CPU. The base address of the CPU interface is usually + * aliased so that the same address points to different chips depending + * on the CPU it is accessed from. * * Note that IRQs 0-31 are special - they are local to each CPU. * As such, the enable set/clear, pending set/clear and active bit @@ -31,10 +33,38 @@ #include #include -static void __iomem *gic_dist_base; -static void __iomem *gic_cpu_base; static DEFINE_SPINLOCK(irq_controller_lock); +struct gic_chip_data { + unsigned int irq_offset; + void __iomem *dist_base; + void __iomem *cpu_base; +}; + +#ifndef MAX_GIC_NR +#define MAX_GIC_NR 1 +#endif + +static struct gic_chip_data gic_data[MAX_GIC_NR]; + +static inline void __iomem *gic_dist_base(unsigned int irq) +{ + struct gic_chip_data *gic_data = get_irq_chip_data(irq); + return gic_data->dist_base; +} + +static inline void __iomem *gic_cpu_base(unsigned int irq) +{ + struct gic_chip_data *gic_data = get_irq_chip_data(irq); + return gic_data->cpu_base; +} + +static inline unsigned int gic_irq(unsigned int irq) +{ + struct gic_chip_data *gic_data = get_irq_chip_data(irq); + return irq - gic_data->irq_offset; +} + /* * Routines to acknowledge, disable and enable interrupts * @@ -55,8 +85,8 @@ static void gic_ack_irq(unsigned int irq) u32 mask = 1 << (irq % 32); spin_lock(&irq_controller_lock); - writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4); - writel(irq, gic_cpu_base + GIC_CPU_EOI); + writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4); + writel(gic_irq(irq), gic_cpu_base(irq) + GIC_CPU_EOI); spin_unlock(&irq_controller_lock); } @@ -65,7 +95,7 @@ static void gic_mask_irq(unsigned int irq) u32 mask = 1 << (irq % 32); spin_lock(&irq_controller_lock); - writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4); + writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4); spin_unlock(&irq_controller_lock); } @@ -74,14 +104,14 @@ static void gic_unmask_irq(unsigned int irq) u32 mask = 1 << (irq % 32); spin_lock(&irq_controller_lock); - writel(mask, gic_dist_base + GIC_DIST_ENABLE_SET + (irq / 32) * 4); + writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_SET + (gic_irq(irq) / 32) * 4); spin_unlock(&irq_controller_lock); } #ifdef CONFIG_SMP static void gic_set_cpu(unsigned int irq, cpumask_t mask_val) { - void __iomem *reg = gic_dist_base + GIC_DIST_TARGET + (irq & ~3); + void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3); unsigned int shift = (irq % 4) * 8; unsigned int cpu = first_cpu(mask_val); u32 val; @@ -95,6 +125,37 @@ static void gic_set_cpu(unsigned int irq, cpumask_t mask_val) } #endif +static void fastcall gic_handle_cascade_irq(unsigned int irq, + struct irq_desc *desc) +{ + struct gic_chip_data *chip_data = get_irq_data(irq); + struct irq_chip *chip = get_irq_chip(irq); + unsigned int cascade_irq; + unsigned long status; + + /* primary controller ack'ing */ + chip->ack(irq); + + spin_lock(&irq_controller_lock); + status = readl(chip_data->cpu_base + GIC_CPU_INTACK); + spin_unlock(&irq_controller_lock); + + cascade_irq = (status & 0x3ff); + if (cascade_irq > 1020) + goto out; + if (cascade_irq < 32 || cascade_irq >= NR_IRQS) { + do_bad_IRQ(cascade_irq, desc); + goto out; + } + + cascade_irq += chip_data->irq_offset; + generic_handle_irq(cascade_irq); + + out: + /* primary controller unmasking */ + chip->unmask(irq); +} + static struct irq_chip gic_chip = { .name = "GIC", .ack = gic_ack_irq, @@ -105,15 +166,29 @@ static struct irq_chip gic_chip = { #endif }; -void __init gic_dist_init(void __iomem *base) +void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq) +{ + if (gic_nr >= MAX_GIC_NR) + BUG(); + if (set_irq_data(irq, &gic_data[gic_nr]) != 0) + BUG(); + set_irq_chained_handler(irq, gic_handle_cascade_irq); +} + +void __init gic_dist_init(unsigned int gic_nr, void __iomem *base, + unsigned int irq_start) { unsigned int max_irq, i; u32 cpumask = 1 << smp_processor_id(); + if (gic_nr >= MAX_GIC_NR) + BUG(); + cpumask |= cpumask << 8; cpumask |= cpumask << 16; - gic_dist_base = base; + gic_data[gic_nr].dist_base = base; + gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31; writel(0, base + GIC_DIST_CTRL); @@ -158,8 +233,9 @@ void __init gic_dist_init(void __iomem *base) /* * Setup the Linux IRQ subsystem. */ - for (i = 29; i < max_irq; i++) { + for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) { set_irq_chip(i, &gic_chip); + set_irq_chip_data(i, &gic_data[gic_nr]); set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } @@ -167,9 +243,13 @@ void __init gic_dist_init(void __iomem *base) writel(1, base + GIC_DIST_CTRL); } -void __cpuinit gic_cpu_init(void __iomem *base) +void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base) { - gic_cpu_base = base; + if (gic_nr >= MAX_GIC_NR) + BUG(); + + gic_data[gic_nr].cpu_base = base; + writel(0xf0, base + GIC_CPU_PRIMASK); writel(1, base + GIC_CPU_CTRL); } @@ -179,6 +259,7 @@ void gic_raise_softirq(cpumask_t cpumask, unsigned int irq) { unsigned long map = *cpus_addr(cpumask); - writel(map << 16 | irq, gic_dist_base + GIC_DIST_SOFTINT); + /* this always happens on GIC0 */ + writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT); } #endif diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 243aea458057..bbab134cd82d 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -88,9 +88,6 @@ struct cpu_user_fns cpu_user; #ifdef MULTI_CACHE struct cpu_cache_fns cpu_cache; #endif -#ifdef CONFIG_OUTER_CACHE -struct outer_cache_fns outer_cache; -#endif struct stack { u32 irq[3]; diff --git a/trunk/arch/arm/mach-realview/platsmp.c b/trunk/arch/arm/mach-realview/platsmp.c index b8484e15dacb..709a9b1ac634 100644 --- a/trunk/arch/arm/mach-realview/platsmp.c +++ b/trunk/arch/arm/mach-realview/platsmp.c @@ -52,7 +52,7 @@ void __cpuinit platform_secondary_init(unsigned int cpu) * core (e.g. timer irq), then they will not have been enabled * for us: do so */ - gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); + gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE)); /* * let the primary processor know we're out of the diff --git a/trunk/arch/arm/mach-realview/realview_eb.c b/trunk/arch/arm/mach-realview/realview_eb.c index 9741b4d3c9cf..b6a6f68cb699 100644 --- a/trunk/arch/arm/mach-realview/realview_eb.c +++ b/trunk/arch/arm/mach-realview/realview_eb.c @@ -143,8 +143,8 @@ static void __init gic_init_irq(void) writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + 0xd8); writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); #endif - gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE)); - gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); + gic_dist_init(0, __io_address(REALVIEW_GIC_DIST_BASE), 29); + gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE)); } static void __init realview_eb_init(void) diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index af3fa9d622ff..aade2f72c920 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -609,10 +609,3 @@ config NEEDS_SYSCALL_FOR_CMPXCHG Forget about fast user space cmpxchg support. It is just not possible. -config OUTER_CACHE - bool - default n - -config CACHE_L2X0 - bool - select OUTER_CACHE diff --git a/trunk/arch/arm/mm/Makefile b/trunk/arch/arm/mm/Makefile index 2f8b95947774..d2f5672ecf62 100644 --- a/trunk/arch/arm/mm/Makefile +++ b/trunk/arch/arm/mm/Makefile @@ -66,5 +66,3 @@ obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o obj-$(CONFIG_CPU_V6) += proc-v6.o - -obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o diff --git a/trunk/arch/arm/mm/cache-l2x0.c b/trunk/arch/arm/mm/cache-l2x0.c deleted file mode 100644 index 08a36f1b35d2..000000000000 --- a/trunk/arch/arm/mm/cache-l2x0.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * arch/arm/mm/cache-l2x0.c - L210/L220 cache controller support - * - * Copyright (C) 2007 ARM Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include - -#include -#include -#include - -#define CACHE_LINE_SIZE 32 - -static void __iomem *l2x0_base; - -static inline void sync_writel(unsigned long val, unsigned long reg, - unsigned long complete_mask) -{ - writel(val, l2x0_base + reg); - /* wait for the operation to complete */ - while (readl(l2x0_base + reg) & complete_mask) - ; -} - -static inline void cache_sync(void) -{ - sync_writel(0, L2X0_CACHE_SYNC, 1); -} - -static inline void l2x0_inv_all(void) -{ - /* invalidate all ways */ - sync_writel(0xff, L2X0_INV_WAY, 0xff); - cache_sync(); -} - -static void l2x0_inv_range(unsigned long start, unsigned long end) -{ - unsigned long addr; - - start &= ~(CACHE_LINE_SIZE - 1); - for (addr = start; addr < end; addr += CACHE_LINE_SIZE) - sync_writel(addr, L2X0_INV_LINE_PA, 1); - cache_sync(); -} - -static void l2x0_clean_range(unsigned long start, unsigned long end) -{ - unsigned long addr; - - start &= ~(CACHE_LINE_SIZE - 1); - for (addr = start; addr < end; addr += CACHE_LINE_SIZE) - sync_writel(addr, L2X0_CLEAN_LINE_PA, 1); - cache_sync(); -} - -static void l2x0_flush_range(unsigned long start, unsigned long end) -{ - unsigned long addr; - - start &= ~(CACHE_LINE_SIZE - 1); - for (addr = start; addr < end; addr += CACHE_LINE_SIZE) - sync_writel(addr, L2X0_CLEAN_INV_LINE_PA, 1); - cache_sync(); -} - -void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) -{ - __u32 aux; - - l2x0_base = base; - - /* disable L2X0 */ - writel(0, l2x0_base + L2X0_CTRL); - - aux = readl(l2x0_base + L2X0_AUX_CTRL); - aux &= aux_mask; - aux |= aux_val; - writel(aux, l2x0_base + L2X0_AUX_CTRL); - - l2x0_inv_all(); - - /* enable L2X0 */ - writel(1, l2x0_base + L2X0_CTRL); - - outer_cache.inv_range = l2x0_inv_range; - outer_cache.clean_range = l2x0_clean_range; - outer_cache.flush_range = l2x0_flush_range; - - printk(KERN_INFO "L2X0 cache controller enabled\n"); -} diff --git a/trunk/arch/arm/mm/consistent.c b/trunk/arch/arm/mm/consistent.c index 1f9f94f9af4b..6a9c362fef5e 100644 --- a/trunk/arch/arm/mm/consistent.c +++ b/trunk/arch/arm/mm/consistent.c @@ -205,10 +205,9 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, * kernel direct-mapped region for device DMA. */ { - void *ptr = page_address(page); - memset(ptr, 0, size); - dmac_flush_range(ptr, ptr + size); - outer_flush_range(__pa(ptr), __pa(ptr) + size); + unsigned long kaddr = (unsigned long)page_address(page); + memset(page_address(page), 0, size); + dmac_flush_range(kaddr, kaddr + size); } /* @@ -481,24 +480,20 @@ core_initcall(consistent_init); * platforms with CONFIG_DMABOUNCE. * Use the driver DMA support - see dma-mapping.h (dma_sync_*) */ -void consistent_sync(const void *start, size_t size, int direction) +void consistent_sync(void *vaddr, size_t size, int direction) { - const void *end = start + size; - - BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end - 1)); + unsigned long start = (unsigned long)vaddr; + unsigned long end = start + size; switch (direction) { case DMA_FROM_DEVICE: /* invalidate only */ dmac_inv_range(start, end); - outer_inv_range(__pa(start), __pa(end)); break; case DMA_TO_DEVICE: /* writeback only */ dmac_clean_range(start, end); - outer_clean_range(__pa(start), __pa(end)); break; case DMA_BIDIRECTIONAL: /* writeback and invalidate */ dmac_flush_range(start, end); - outer_flush_range(__pa(start), __pa(end)); break; default: BUG(); diff --git a/trunk/arch/arm/mm/context.c b/trunk/arch/arm/mm/context.c index 9da43a0fdcdf..79e800202424 100644 --- a/trunk/arch/arm/mm/context.c +++ b/trunk/arch/arm/mm/context.c @@ -19,8 +19,7 @@ unsigned int cpu_last_asid = { 1 << ASID_BITS }; /* * We fork()ed a process, and we need a new context for the child * to run in. We reserve version 0 for initial tasks so we will - * always allocate an ASID. The ASID 0 is reserved for the TTBR - * register changing sequence. + * always allocate an ASID. */ void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) { @@ -39,15 +38,8 @@ void __new_context(struct mm_struct *mm) * If we've used up all our ASIDs, we need * to start a new version and flush the TLB. */ - if ((asid & ~ASID_MASK) == 0) { - asid = ++cpu_last_asid; - /* set the reserved ASID before flushing the TLB */ - asm("mcr p15, 0, %0, c13, c0, 1 @ set reserved context ID\n" - : - : "r" (0)); - isb(); + if ((asid & ~ASID_MASK) == 0) flush_tlb_all(); - } mm->context.id = asid; } diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S index d78c0ae7c2c2..7b1843befb9c 100644 --- a/trunk/arch/arm/mm/proc-v6.S +++ b/trunk/arch/arm/mm/proc-v6.S @@ -30,12 +30,6 @@ #define TTB_RGN_WT (2 << 3) #define TTB_RGN_WB (3 << 3) -#ifndef CONFIG_SMP -#define TTB_FLAGS TTB_RGN_WBWA -#else -#define TTB_FLAGS TTB_RGN_WBWA|TTB_S -#endif - ENTRY(cpu_v6_proc_init) mov pc, lr @@ -98,7 +92,9 @@ ENTRY(cpu_v6_switch_mm) #ifdef CONFIG_MMU mov r2, #0 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id - orr r0, r0, #TTB_FLAGS +#ifdef CONFIG_SMP + orr r0, r0, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable +#endif mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB mcr p15, 0, r2, c7, c10, 4 @ drain write buffer mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 @@ -208,7 +204,9 @@ __v6_setup: #ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs mcr p15, 0, r0, c2, c0, 2 @ TTB control register - orr r4, r4, #TTB_FLAGS +#ifdef CONFIG_SMP + orr r4, r4, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable +#endif mcr p15, 0, r4, c2, c0, 1 @ load TTB1 #endif /* CONFIG_MMU */ adr r5, v6_crval diff --git a/trunk/arch/arm/mm/tlb-v6.S b/trunk/arch/arm/mm/tlb-v6.S index 20f84bbaa9bb..fd6adde39091 100644 --- a/trunk/arch/arm/mm/tlb-v6.S +++ b/trunk/arch/arm/mm/tlb-v6.S @@ -53,8 +53,6 @@ ENTRY(v6wbi_flush_user_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b - mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB - mcr p15, 0, ip, c7, c10, 4 @ data synchronization barrier mov pc, lr /* @@ -82,9 +80,7 @@ ENTRY(v6wbi_flush_kern_tlb_range) add r0, r0, #PAGE_SZ cmp r0, r1 blo 1b - mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier - mcr p15, 0, r2, c7, c5, 4 @ prefetch flush mov pc, lr .section ".text.init", #alloc, #execinstr diff --git a/trunk/include/asm-arm/cacheflush.h b/trunk/include/asm-arm/cacheflush.h index afad32c76e6c..5f531ea03059 100644 --- a/trunk/include/asm-arm/cacheflush.h +++ b/trunk/include/asm-arm/cacheflush.h @@ -185,15 +185,9 @@ struct cpu_cache_fns { void (*coherent_user_range)(unsigned long, unsigned long); void (*flush_kern_dcache_page)(void *); - void (*dma_inv_range)(const void *, const void *); - void (*dma_clean_range)(const void *, const void *); - void (*dma_flush_range)(const void *, const void *); -}; - -struct outer_cache_fns { - void (*inv_range)(unsigned long, unsigned long); - void (*clean_range)(unsigned long, unsigned long); - void (*flush_range)(unsigned long, unsigned long); + void (*dma_inv_range)(unsigned long, unsigned long); + void (*dma_clean_range)(unsigned long, unsigned long); + void (*dma_flush_range)(unsigned long, unsigned long); }; /* @@ -246,40 +240,9 @@ extern void __cpuc_flush_dcache_page(void *); #define dmac_clean_range __glue(_CACHE,_dma_clean_range) #define dmac_flush_range __glue(_CACHE,_dma_flush_range) -extern void dmac_inv_range(const void *, const void *); -extern void dmac_clean_range(const void *, const void *); -extern void dmac_flush_range(const void *, const void *); - -#endif - -#ifdef CONFIG_OUTER_CACHE - -extern struct outer_cache_fns outer_cache; - -static inline void outer_inv_range(unsigned long start, unsigned long end) -{ - if (outer_cache.inv_range) - outer_cache.inv_range(start, end); -} -static inline void outer_clean_range(unsigned long start, unsigned long end) -{ - if (outer_cache.clean_range) - outer_cache.clean_range(start, end); -} -static inline void outer_flush_range(unsigned long start, unsigned long end) -{ - if (outer_cache.flush_range) - outer_cache.flush_range(start, end); -} - -#else - -static inline void outer_inv_range(unsigned long start, unsigned long end) -{ } -static inline void outer_clean_range(unsigned long start, unsigned long end) -{ } -static inline void outer_flush_range(unsigned long start, unsigned long end) -{ } +extern void dmac_inv_range(unsigned long, unsigned long); +extern void dmac_clean_range(unsigned long, unsigned long); +extern void dmac_flush_range(unsigned long, unsigned long); #endif diff --git a/trunk/include/asm-arm/dma-mapping.h b/trunk/include/asm-arm/dma-mapping.h index a1d574cdcc14..9bc46b486afb 100644 --- a/trunk/include/asm-arm/dma-mapping.h +++ b/trunk/include/asm-arm/dma-mapping.h @@ -17,7 +17,7 @@ * platforms with CONFIG_DMABOUNCE. * Use the driver DMA support - see dma-mapping.h (dma_sync_*) */ -extern void consistent_sync(const void *kaddr, size_t size, int rw); +extern void consistent_sync(void *kaddr, size_t size, int rw); /* * Return whether the given device DMA address mask can be supported diff --git a/trunk/include/asm-arm/domain.h b/trunk/include/asm-arm/domain.h index 3c12a7625304..4c2885abbe6c 100644 --- a/trunk/include/asm-arm/domain.h +++ b/trunk/include/asm-arm/domain.h @@ -57,7 +57,6 @@ __asm__ __volatile__( \ "mcr p15, 0, %0, c3, c0 @ set domain" \ : : "r" (x)); \ - isb(); \ } while (0) #define modify_domain(dom,type) \ diff --git a/trunk/include/asm-arm/hardware/cache-l2x0.h b/trunk/include/asm-arm/hardware/cache-l2x0.h deleted file mode 100644 index 54029a740396..000000000000 --- a/trunk/include/asm-arm/hardware/cache-l2x0.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * include/asm-arm/hardware/cache-l2x0.h - * - * Copyright (C) 2007 ARM Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __ASM_ARM_HARDWARE_L2X0_H -#define __ASM_ARM_HARDWARE_L2X0_H - -#define L2X0_CACHE_ID 0x000 -#define L2X0_CACHE_TYPE 0x004 -#define L2X0_CTRL 0x100 -#define L2X0_AUX_CTRL 0x104 -#define L2X0_EVENT_CNT_CTRL 0x200 -#define L2X0_EVENT_CNT1_CFG 0x204 -#define L2X0_EVENT_CNT0_CFG 0x208 -#define L2X0_EVENT_CNT1_VAL 0x20C -#define L2X0_EVENT_CNT0_VAL 0x210 -#define L2X0_INTR_MASK 0x214 -#define L2X0_MASKED_INTR_STAT 0x218 -#define L2X0_RAW_INTR_STAT 0x21C -#define L2X0_INTR_CLEAR 0x220 -#define L2X0_CACHE_SYNC 0x730 -#define L2X0_INV_LINE_PA 0x770 -#define L2X0_INV_WAY 0x77C -#define L2X0_CLEAN_LINE_PA 0x7B0 -#define L2X0_CLEAN_LINE_IDX 0x7B8 -#define L2X0_CLEAN_WAY 0x7BC -#define L2X0_CLEAN_INV_LINE_PA 0x7F0 -#define L2X0_CLEAN_INV_LINE_IDX 0x7F8 -#define L2X0_CLEAN_INV_WAY 0x7FC -#define L2X0_LOCKDOWN_WAY_D 0x900 -#define L2X0_LOCKDOWN_WAY_I 0x904 -#define L2X0_TEST_OPERATION 0xF00 -#define L2X0_LINE_DATA 0xF10 -#define L2X0_LINE_TAG 0xF30 -#define L2X0_DEBUG_CTRL 0xF40 - -#ifndef __ASSEMBLY__ -extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); -#endif - -#endif diff --git a/trunk/include/asm-arm/hardware/gic.h b/trunk/include/asm-arm/hardware/gic.h index 3fa5eb70f64e..966e428ad32c 100644 --- a/trunk/include/asm-arm/hardware/gic.h +++ b/trunk/include/asm-arm/hardware/gic.h @@ -33,8 +33,9 @@ #define GIC_DIST_SOFTINT 0xf00 #ifndef __ASSEMBLY__ -void gic_dist_init(void __iomem *base); -void gic_cpu_init(void __iomem *base); +void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start); +void gic_cpu_init(unsigned int gic_nr, void __iomem *base); +void gic_cascade_irq(unsigned int gic_nr, unsigned int irq); void gic_raise_softirq(cpumask_t cpumask, unsigned int irq); #endif diff --git a/trunk/include/asm-arm/system.h b/trunk/include/asm-arm/system.h index f4386906b200..aa223fc546af 100644 --- a/trunk/include/asm-arm/system.h +++ b/trunk/include/asm-arm/system.h @@ -140,40 +140,6 @@ static inline int cpu_is_xsc3(void) #define cpu_is_xscale() 1 #endif -#define UDBG_UNDEFINED (1 << 0) -#define UDBG_SYSCALL (1 << 1) -#define UDBG_BADABORT (1 << 2) -#define UDBG_SEGV (1 << 3) -#define UDBG_BUS (1 << 4) - -extern unsigned int user_debug; - -#if __LINUX_ARM_ARCH__ >= 4 -#define vectors_high() (cr_alignment & CR_V) -#else -#define vectors_high() (0) -#endif - -#if __LINUX_ARM_ARCH__ >= 6 -#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \ - : : "r" (0) : "memory") -#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ - : : "r" (0) : "memory") -#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ - : : "r" (0) : "memory") -#else -#define isb() __asm__ __volatile__ ("" : : : "memory") -#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ - : : "r" (0) : "memory") -#define dmb() __asm__ __volatile__ ("" : : : "memory") -#endif -#define mb() dmb() -#define rmb() mb() -#define wmb() mb() -#define read_barrier_depends() do { } while(0) -#define set_mb(var, value) do { var = value; mb(); } while (0) -#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); - extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ extern unsigned long cr_alignment; /* defined in entry-armv.S */ @@ -188,7 +154,6 @@ static inline void set_cr(unsigned int val) { asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" : : "r" (val) : "cc"); - isb(); } #ifndef CONFIG_SMP @@ -211,9 +176,34 @@ static inline void set_copro_access(unsigned int val) { asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access" : : "r" (val) : "cc"); - isb(); } +#define UDBG_UNDEFINED (1 << 0) +#define UDBG_SYSCALL (1 << 1) +#define UDBG_BADABORT (1 << 2) +#define UDBG_SEGV (1 << 3) +#define UDBG_BUS (1 << 4) + +extern unsigned int user_debug; + +#if __LINUX_ARM_ARCH__ >= 4 +#define vectors_high() (cr_alignment & CR_V) +#else +#define vectors_high() (0) +#endif + +#if __LINUX_ARM_ARCH__ >= 6 +#define mb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ + : : "r" (0) : "memory") +#else +#define mb() __asm__ __volatile__ ("" : : : "memory") +#endif +#define rmb() mb() +#define wmb() mb() +#define read_barrier_depends() do { } while(0) +#define set_mb(var, value) do { var = value; mb(); } while (0) +#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); + /* * switch_mm() may do a full cache flush over the context switch, * so enable interrupts over the context switch to avoid high diff --git a/trunk/include/asm-arm/tlbflush.h b/trunk/include/asm-arm/tlbflush.h index 08c6991dc9c9..cd10a0b5f8ae 100644 --- a/trunk/include/asm-arm/tlbflush.h +++ b/trunk/include/asm-arm/tlbflush.h @@ -247,7 +247,7 @@ static inline void local_flush_tlb_all(void) const unsigned int __tlb_flag = __cpu_tlb_flags; if (tlb_flag(TLB_WB)) - dsb(); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V3_FULL)) asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); @@ -257,15 +257,6 @@ static inline void local_flush_tlb_all(void) asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL)) asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); - - if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | - TLB_V6_I_PAGE | TLB_V6_D_PAGE | - TLB_V6_I_ASID | TLB_V6_D_ASID)) { - /* flush the branch target cache */ - asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); - dsb(); - isb(); - } } static inline void local_flush_tlb_mm(struct mm_struct *mm) @@ -275,7 +266,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) const unsigned int __tlb_flag = __cpu_tlb_flags; if (tlb_flag(TLB_WB)) - dsb(); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) { if (tlb_flag(TLB_V3_FULL)) @@ -294,14 +285,6 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc"); if (tlb_flag(TLB_V6_I_ASID)) asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); - - if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | - TLB_V6_I_PAGE | TLB_V6_D_PAGE | - TLB_V6_I_ASID | TLB_V6_D_ASID)) { - /* flush the branch target cache */ - asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); - dsb(); - } } static inline void @@ -313,7 +296,7 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); if (tlb_flag(TLB_WB)) - dsb(); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero)); if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { if (tlb_flag(TLB_V3_PAGE)) @@ -334,14 +317,6 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); if (tlb_flag(TLB_V6_I_PAGE)) asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); - - if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | - TLB_V6_I_PAGE | TLB_V6_D_PAGE | - TLB_V6_I_ASID | TLB_V6_D_ASID)) { - /* flush the branch target cache */ - asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); - dsb(); - } } static inline void local_flush_tlb_kernel_page(unsigned long kaddr) @@ -352,7 +327,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) kaddr &= PAGE_MASK; if (tlb_flag(TLB_WB)) - dsb(); + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); if (tlb_flag(TLB_V3_PAGE)) asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc"); @@ -372,14 +347,11 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) if (tlb_flag(TLB_V6_I_PAGE)) asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | - TLB_V6_I_PAGE | TLB_V6_D_PAGE | - TLB_V6_I_ASID | TLB_V6_D_ASID)) { - /* flush the branch target cache */ - asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); - dsb(); - isb(); - } + /* The ARM ARM states that the completion of a TLB maintenance + * operation is only guaranteed by a DSB instruction + */ + if (tlb_flag(TLB_V6_U_PAGE | TLB_V6_D_PAGE | TLB_V6_I_PAGE)) + asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); } /* @@ -397,13 +369,15 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) */ static inline void flush_pmd_entry(pmd_t *pmd) { + const unsigned int zero = 0; const unsigned int __tlb_flag = __cpu_tlb_flags; if (tlb_flag(TLB_DCLEAN)) asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" : : "r" (pmd) : "cc"); if (tlb_flag(TLB_WB)) - dsb(); + asm("mcr p15, 0, %0, c7, c10, 4 @ flush_pmd" + : : "r" (zero) : "cc"); } static inline void clean_pmd_entry(pmd_t *pmd)