From 6bebb572404f96d367170fb263603cda7251f932 Mon Sep 17 00:00:00 2001 From: Linus Walleij <linus.walleij@linaro.org> Date: Wed, 4 Jan 2012 10:50:09 +0100 Subject: ARM: 7268/1: integrator: defconfig for both AP and CP This updates the Integrator defconfig to include the hardware found on the Integrator/CP: SMC91X, CLCD, MMCI/PL180. Further the sometimes disrupting VGA_CONSOLE is disabled (those who have a VGA card can enable it) and typical default VFAT layouts of the MMC cards are supported by enabling VFAT and CP437 encoding of the file system. After this my default kernels boot successfully on Integrator AP and CP alike. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/configs/integrator_defconfig | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig index 1103f62a196..a8314c3ee84 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig @@ -57,18 +57,24 @@ CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_NET_PCI=y CONFIG_E100=y +CONFIG_SMC91X=y # CONFIG_KEYBOARD_ATKBD is not set # CONFIG_SERIO_SERPORT is not set CONFIG_SERIAL_AMBA_PL010=y CONFIG_SERIAL_AMBA_PL010_CONSOLE=y CONFIG_FB=y CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_ARMCLCD=y CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y +# CONFIG_VGA_CONSOLE is not set +CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_PL030=y CONFIG_EXT2_FS=y +CONFIG_VFAT_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_CRAMFS=y @@ -78,5 +84,7 @@ CONFIG_ROOT_NFS=y CONFIG_NFSD=y CONFIG_NFSD_V3=y CONFIG_PARTITION_ADVANCED=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y -- cgit v1.2.3-18-g5258 From 3e175ca4cab37b1eb99f7cf032142a1e5cdb3d97 Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Sun, 18 Sep 2011 11:27:30 +0100 Subject: ARM: cache-l2x0.c: consistently use u32 __u32 exists to avoid namespace clashes with userspace programs. It should not be used outside header files, so convert to use u32 instead. Also, don't mix uint32_t and __u32 - use the same type throughout the file for consistency. Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/include/asm/hardware/cache-l2x0.h | 6 +++--- arch/arm/mm/cache-l2x0.c | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h index 7df239bcdf2..c4c87bc1223 100644 --- a/arch/arm/include/asm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -103,11 +103,11 @@ #define L2X0_ADDR_FILTER_EN 1 #ifndef __ASSEMBLY__ -extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask); +extern void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask); #if defined(CONFIG_CACHE_L2X0) && defined(CONFIG_OF) -extern int l2x0_of_init(__u32 aux_val, __u32 aux_mask); +extern int l2x0_of_init(u32 aux_val, u32 aux_mask); #else -static inline int l2x0_of_init(__u32 aux_val, __u32 aux_mask) +static inline int l2x0_of_init(u32 aux_val, u32 aux_mask) { return -ENODEV; } diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index b1e192ba8c2..a53fd2aaa2f 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -30,13 +30,13 @@ static void __iomem *l2x0_base; static DEFINE_RAW_SPINLOCK(l2x0_lock); -static uint32_t l2x0_way_mask; /* Bitmask of active ways */ -static uint32_t l2x0_size; +static u32 l2x0_way_mask; /* Bitmask of active ways */ +static u32 l2x0_size; struct l2x0_regs l2x0_saved_regs; struct l2x0_of_data { - void (*setup)(const struct device_node *, __u32 *, __u32 *); + void (*setup)(const struct device_node *, u32 *, u32 *); void (*save)(void); void (*resume)(void); }; @@ -288,7 +288,7 @@ static void l2x0_disable(void) raw_spin_unlock_irqrestore(&l2x0_lock, flags); } -static void l2x0_unlock(__u32 cache_id) +static void l2x0_unlock(u32 cache_id) { int lockregs; int i; @@ -307,11 +307,11 @@ static void l2x0_unlock(__u32 cache_id) } } -void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) +void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) { - __u32 aux; - __u32 cache_id; - __u32 way_size = 0; + u32 aux; + u32 cache_id; + u32 way_size = 0; int ways; const char *type; @@ -388,7 +388,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) #ifdef CONFIG_OF static void __init l2x0_of_setup(const struct device_node *np, - __u32 *aux_val, __u32 *aux_mask) + u32 *aux_val, u32 *aux_mask) { u32 data[2] = { 0, 0 }; u32 tag = 0; @@ -422,7 +422,7 @@ static void __init l2x0_of_setup(const struct device_node *np, } static void __init pl310_of_setup(const struct device_node *np, - __u32 *aux_val, __u32 *aux_mask) + u32 *aux_val, u32 *aux_mask) { u32 data[3] = { 0, 0, 0 }; u32 tag[3] = { 0, 0, 0 }; @@ -548,7 +548,7 @@ static const struct of_device_id l2x0_ids[] __initconst = { {} }; -int __init l2x0_of_init(__u32 aux_val, __u32 aux_mask) +int __init l2x0_of_init(u32 aux_val, u32 aux_mask) { struct device_node *np; struct l2x0_of_data *data; -- cgit v1.2.3-18-g5258 From 45cd5290bfd358e9885c0bf47a8c46671a92f716 Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Thu, 12 Jan 2012 23:08:07 +0000 Subject: ARM: add dma coherent region reporting via procfs Add a new seqfile for reporting coherent DMA allocations. This contains the address range, size and the function which was used to allocate each region, allowing these allocations to be viewed in much the same way as /proc/vmallocinfo. The DMA coherent region has limited space, so this allows allocation failures to be viewed, as well as finding out how much space is being used. Make sure this file is only readable by root - same as vmallocinfo - to prevent information leakage. Acked-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/mm/dma-mapping.c | 20 ++++++++----- arch/arm/mm/vmregion.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- arch/arm/mm/vmregion.h | 5 +++- 3 files changed, 92 insertions(+), 9 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 1aa664a1999..db23ae4aaaa 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -214,7 +214,8 @@ static int __init consistent_init(void) core_initcall(consistent_init); static void * -__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) +__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot, + const void *caller) { struct arm_vmregion *c; size_t align; @@ -241,7 +242,7 @@ __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) * Allocate a virtual address in the consistent mapping region. */ c = arm_vmregion_alloc(&consistent_head, align, size, - gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); + gfp & ~(__GFP_DMA | __GFP_HIGHMEM), caller); if (c) { pte_t *pte; int idx = CONSISTENT_PTE_INDEX(c->vm_start); @@ -320,14 +321,14 @@ static void __dma_free_remap(void *cpu_addr, size_t size) #else /* !CONFIG_MMU */ -#define __dma_alloc_remap(page, size, gfp, prot) page_address(page) +#define __dma_alloc_remap(page, size, gfp, prot, c) page_address(page) #define __dma_free_remap(addr, size) do { } while (0) #endif /* CONFIG_MMU */ static void * __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, - pgprot_t prot) + pgprot_t prot, const void *caller) { struct page *page; void *addr; @@ -349,7 +350,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, return NULL; if (!arch_is_coherent()) - addr = __dma_alloc_remap(page, size, gfp, prot); + addr = __dma_alloc_remap(page, size, gfp, prot, caller); else addr = page_address(page); @@ -374,7 +375,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf return memory; return __dma_alloc(dev, size, handle, gfp, - pgprot_dmacoherent(pgprot_kernel)); + pgprot_dmacoherent(pgprot_kernel), + __builtin_return_address(0)); } EXPORT_SYMBOL(dma_alloc_coherent); @@ -386,7 +388,8 @@ void * dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) { return __dma_alloc(dev, size, handle, gfp, - pgprot_writecombine(pgprot_kernel)); + pgprot_writecombine(pgprot_kernel), + __builtin_return_address(0)); } EXPORT_SYMBOL(dma_alloc_writecombine); @@ -723,6 +726,9 @@ EXPORT_SYMBOL(dma_set_mask); static int __init dma_debug_do_init(void) { +#ifdef CONFIG_MMU + arm_vmregion_create_proc("dma-mappings", &consistent_head); +#endif dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); return 0; } diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c index 036fdbfdd62..a631016e1f8 100644 --- a/arch/arm/mm/vmregion.c +++ b/arch/arm/mm/vmregion.c @@ -1,5 +1,8 @@ +#include <linux/fs.h> #include <linux/spinlock.h> #include <linux/list.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/slab.h> #include "vmregion.h" @@ -36,7 +39,7 @@ struct arm_vmregion * arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, - size_t size, gfp_t gfp) + size_t size, gfp_t gfp, const void *caller) { unsigned long start = head->vm_start, addr = head->vm_end; unsigned long flags; @@ -52,6 +55,8 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align, if (!new) goto out; + new->caller = caller; + spin_lock_irqsave(&head->vm_lock, flags); addr = rounddown(addr - size, align); @@ -129,3 +134,72 @@ void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c) kfree(c); } + +#ifdef CONFIG_PROC_FS +static int arm_vmregion_show(struct seq_file *m, void *p) +{ + struct arm_vmregion *c = list_entry(p, struct arm_vmregion, vm_list); + + seq_printf(m, "0x%08lx-0x%08lx %7lu", c->vm_start, c->vm_end, + c->vm_end - c->vm_start); + if (c->caller) + seq_printf(m, " %pS", (void *)c->caller); + seq_putc(m, '\n'); + return 0; +} + +static void *arm_vmregion_start(struct seq_file *m, loff_t *pos) +{ + struct arm_vmregion_head *h = m->private; + spin_lock_irq(&h->vm_lock); + return seq_list_start(&h->vm_list, *pos); +} + +static void *arm_vmregion_next(struct seq_file *m, void *p, loff_t *pos) +{ + struct arm_vmregion_head *h = m->private; + return seq_list_next(p, &h->vm_list, pos); +} + +static void arm_vmregion_stop(struct seq_file *m, void *p) +{ + struct arm_vmregion_head *h = m->private; + spin_unlock_irq(&h->vm_lock); +} + +static const struct seq_operations arm_vmregion_ops = { + .start = arm_vmregion_start, + .stop = arm_vmregion_stop, + .next = arm_vmregion_next, + .show = arm_vmregion_show, +}; + +static int arm_vmregion_open(struct inode *inode, struct file *file) +{ + struct arm_vmregion_head *h = PDE(inode)->data; + int ret = seq_open(file, &arm_vmregion_ops); + if (!ret) { + struct seq_file *m = file->private_data; + m->private = h; + } + return ret; +} + +static const struct file_operations arm_vmregion_fops = { + .open = arm_vmregion_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h) +{ + proc_create_data(path, S_IRUSR, NULL, &arm_vmregion_fops, h); + return 0; +} +#else +int arm_vmregion_create_proc(const char *path, struct arm_vmregion_head *h) +{ + return 0; +} +#endif diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h index 15e9f044db9..162be662c08 100644 --- a/arch/arm/mm/vmregion.h +++ b/arch/arm/mm/vmregion.h @@ -19,11 +19,14 @@ struct arm_vmregion { unsigned long vm_end; struct page *vm_pages; int vm_active; + const void *caller; }; -struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t); +struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, size_t, gfp_t, const void *); struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long); struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long); void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *); +int arm_vmregion_create_proc(const char *, struct arm_vmregion_head *); + #endif -- cgit v1.2.3-18-g5258 From 94e5a85b3be0ce109d26aa6812b2a02c518a0e4b Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Wed, 18 Jan 2012 15:32:49 +0000 Subject: ARM: earlier initialization of vectors page Initialize the contents of the vectors page immediately after we allocate the page, but before we map it. This avoids any possible aliases with other mappings which may need to be flushed after the page has been mapped irrespective of the cache type. We follow this later with a flush_cache_all() after all static memory mappings have been initialized, which ensures that this is safe from any cache effects. Tested-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/include/asm/traps.h | 2 +- arch/arm/kernel/setup.c | 1 - arch/arm/kernel/traps.c | 10 ++++------ arch/arm/mm/mmu.c | 7 +++++-- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h index 5b29a667362..f555bb3664d 100644 --- a/arch/arm/include/asm/traps.h +++ b/arch/arm/include/asm/traps.h @@ -46,7 +46,7 @@ static inline int in_exception_text(unsigned long ptr) return in ? : __in_irqentry_text(ptr); } -extern void __init early_trap_init(void); +extern void __init early_trap_init(void *); extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame); extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 129fbd55bde..9b65cb4589e 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -961,7 +961,6 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif #endif - early_trap_init(); if (mdesc->init_early) mdesc->init_early(); diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 99a57270250..be15dafaa88 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -781,18 +781,16 @@ static void __init kuser_get_tls_init(unsigned long vectors) memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4); } -void __init early_trap_init(void) +void __init early_trap_init(void *vectors_base) { -#if defined(CONFIG_CPU_USE_DOMAINS) - unsigned long vectors = CONFIG_VECTORS_BASE; -#else - unsigned long vectors = (unsigned long)vectors_page; -#endif + unsigned long vectors = (unsigned long)vectors_base; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; extern char __kuser_helper_start[], __kuser_helper_end[]; int kuser_sz = __kuser_helper_end - __kuser_helper_start; + vectors_page = vectors_base; + /* * Copy the vectors, stubs and kuser helpers (in entry-armv.S) * into the vector page, mapped at 0xffff0000, and ensure these diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 94c5a0c94f5..c1263adc2a2 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -997,11 +997,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc) { struct map_desc map; unsigned long addr; + void *vectors; /* * Allocate the vector page early. */ - vectors_page = early_alloc(PAGE_SIZE); + vectors = early_alloc(PAGE_SIZE); + + early_trap_init(vectors); for (addr = VMALLOC_START; addr; addr += PMD_SIZE) pmd_clear(pmd_off_k(addr)); @@ -1041,7 +1044,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc) * location (0xffff0000). If we aren't using high-vectors, also * create a mapping at the low-vectors virtual address. */ - map.pfn = __phys_to_pfn(virt_to_phys(vectors_page)); + map.pfn = __phys_to_pfn(virt_to_phys(vectors)); map.virtual = 0xffff0000; map.length = PAGE_SIZE; map.type = MT_HIGH_VECTORS; -- cgit v1.2.3-18-g5258 From 2ed86b16eabe4efbf80cc725a8cbb5310746a2fc Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Wed, 25 Jan 2012 20:02:40 -0600 Subject: irq: make SPARSE_IRQ an optionally hidden option On ARM, we don't want SPARSE_IRQ to be a user visible option. Make SPARSE_IRQ visible based on MAY_HAVE_SPARSE_IRQ instead of depending on HAVE_SPARSE_IRQ. With this, SPARSE_IRQ is not visible on C6X and ARM. Signed-off-by: Rob Herring <rob.herring@calxeda.com> Cc: Russell King <linux@arm.linux.org.uk> Cc: Mark Salter <msalter@redhat.com> Cc: Aurelien Jacquiot <a-jacquiot@ti.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Paul Mundt <lethal@linux-sh.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Cc: linux-c6x-dev@linux-c6x.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-sh@vger.kernel.org --- arch/arm/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 24626b0419e..30e7840498c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -28,7 +28,6 @@ config ARM select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)) select HAVE_C_RECORDMCOUNT select HAVE_GENERIC_HARDIRQS - select HAVE_SPARSE_IRQ select GENERIC_IRQ_SHOW select CPU_PM if (SUSPEND || CPU_IDLE) select GENERIC_PCI_IOMAP -- cgit v1.2.3-18-g5258 From ba3e88acfbb0ba52ea9ae522e5ea74ac3927fc9c Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Sun, 15 Jan 2012 17:05:56 -0600 Subject: ARM: remove mc146818rtc.h from time.c mc146818rtc.h is not needed in time.c, so remove it. Signed-off-by: Rob Herring <rob.herring@calxeda.com> --- arch/arm/kernel/time.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 8c57dd3680e..60955179113 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -25,8 +25,6 @@ #include <linux/timer.h> #include <linux/irq.h> -#include <linux/mc146818rtc.h> - #include <asm/leds.h> #include <asm/thread_info.h> #include <asm/sched_clock.h> -- cgit v1.2.3-18-g5258 From bd8abc9a32c9b7b8179e701699141566dd8f7eb8 Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Tue, 3 Jan 2012 14:55:24 -0600 Subject: ARM: mc146818rtc: remove unnecessary include of mach/irqs.h The include of mach/irqs.h isn't needed, so remove it. Compiled CMOS rtc driver. Add a check to make sure nothing depends on RTC_IRQ. Signed-off-by: Rob Herring <rob.herring@calxeda.com> --- arch/arm/include/asm/mc146818rtc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/mc146818rtc.h b/arch/arm/include/asm/mc146818rtc.h index 6b884d2b0b6..e8567bb99df 100644 --- a/arch/arm/include/asm/mc146818rtc.h +++ b/arch/arm/include/asm/mc146818rtc.h @@ -5,7 +5,9 @@ #define _ASM_MC146818RTC_H #include <linux/io.h> -#include <mach/irqs.h> +#include <linux/kernel.h> + +#define RTC_IRQ BUILD_BUG_ON(1) #ifndef RTC_PORT #define RTC_PORT(x) (0x70 + (x)) -- cgit v1.2.3-18-g5258 From bc0a15171a75a67f22ba85baa607f1ffc10751e3 Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Tue, 3 Jan 2012 15:52:42 -0600 Subject: ARM: it8152: explicitly include mach/irqs.h In preparation to make mach/irqs.h optional, directly include mach/irq.h to get IRQ_BOARD_START. Signed-off-by: Rob Herring <rob.herring@calxeda.com> --- arch/arm/include/asm/hardware/it8152.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h index 43cab498bc2..73f84fa4f36 100644 --- a/arch/arm/include/asm/hardware/it8152.h +++ b/arch/arm/include/asm/hardware/it8152.h @@ -9,6 +9,9 @@ #ifndef __ASM_HARDWARE_IT8152_H #define __ASM_HARDWARE_IT8152_H + +#include <mach/irqs.h> + extern void __iomem *it8152_base_address; #define IT8152_IO_BASE (it8152_base_address + 0x03e00000) -- cgit v1.2.3-18-g5258 From 7f1e76370b717be264f0af54719182a96fb8f36d Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Tue, 17 Jan 2012 11:20:23 -0600 Subject: sh: intc: unify evt2irq/irq2evt macros for sh and arm Move evt2irq and irq2evt macros definitions out of sh and arm includes into a common location. Signed-off-by: Rob Herring <rob.herring@calxeda.com> --- arch/arm/mach-shmobile/Kconfig | 4 ++++ arch/arm/mach-shmobile/include/mach/irqs.h | 6 ++---- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 060e5644c49..34560cab45d 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -100,6 +100,10 @@ config MACH_MARZEN comment "SH-Mobile System Configuration" +config CPU_HAS_INTEVT + bool + default y + menu "Memory configuration" config MEMORY_START diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h index dcb714f4d75..828807dce5a 100644 --- a/arch/arm/mach-shmobile/include/mach/irqs.h +++ b/arch/arm/mach-shmobile/include/mach/irqs.h @@ -1,15 +1,13 @@ #ifndef __ASM_MACH_IRQS_H #define __ASM_MACH_IRQS_H +#include <linux/sh_intc.h> + #define NR_IRQS 1024 /* GIC */ #define gic_spi(nr) ((nr) + 32) -/* INTCA */ -#define evt2irq(evt) (((evt) >> 5) - 16) -#define irq2evt(irq) (((irq) + 16) << 5) - /* INTCS */ #define INTCS_VECT_BASE 0x2200 #define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect)) -- cgit v1.2.3-18-g5258 From 8661fb92045c5710754d450ebb82461fcfa08b65 Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Tue, 3 Jan 2012 16:50:40 -0600 Subject: ARM: mmp: remove NR_IRQS Remove NR_IRQS and add a per machine .nr_irqs setting. Clean-up namespace replacing usage of IRQ_BOARD_START with MMP_NR_IRQS. Signed-off-by: Rob Herring <rob.herring@calxeda.com> --- arch/arm/mach-mmp/aspenite.c | 5 +++-- arch/arm/mach-mmp/avengers_lite.c | 1 + arch/arm/mach-mmp/brownstone.c | 4 ++-- arch/arm/mach-mmp/flint.c | 3 ++- arch/arm/mach-mmp/gplugd.c | 2 +- arch/arm/mach-mmp/include/mach/irqs.h | 3 +-- arch/arm/mach-mmp/irq-mmp2.c | 1 + arch/arm/mach-mmp/jasper.c | 5 +++-- arch/arm/mach-mmp/tavorevb.c | 1 + arch/arm/mach-mmp/teton_bga.c | 3 ++- arch/arm/mach-mmp/ttc_dkb.c | 4 ++-- 11 files changed, 19 insertions(+), 13 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index 17cb7606012..5483d6f5c6d 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c @@ -24,6 +24,7 @@ #include <mach/addr-map.h> #include <mach/mfp-pxa168.h> #include <mach/pxa168.h> +#include <mach/irqs.h> #include <video/pxa168fb.h> #include <linux/input.h> #include <plat/pxa27x_keypad.h> @@ -240,7 +241,7 @@ static void __init common_init(void) MACHINE_START(ASPENITE, "PXA168-based Aspenite Development Platform") .map_io = mmp_map_io, - .nr_irqs = IRQ_BOARD_START, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = common_init, @@ -249,7 +250,7 @@ MACHINE_END MACHINE_START(ZYLONITE2, "PXA168-based Zylonite2 Development Platform") .map_io = mmp_map_io, - .nr_irqs = IRQ_BOARD_START, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = common_init, diff --git a/arch/arm/mach-mmp/avengers_lite.c b/arch/arm/mach-mmp/avengers_lite.c index b148a9dc5a4..603542ae6fb 100644 --- a/arch/arm/mach-mmp/avengers_lite.c +++ b/arch/arm/mach-mmp/avengers_lite.c @@ -43,6 +43,7 @@ static void __init avengers_lite_init(void) MACHINE_START(AVENGERS_LITE, "PXA168 Avengers lite Development Platform") .map_io = mmp_map_io, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = avengers_lite_init, diff --git a/arch/arm/mach-mmp/brownstone.c b/arch/arm/mach-mmp/brownstone.c index d839fe6421e..5cb769cd26d 100644 --- a/arch/arm/mach-mmp/brownstone.c +++ b/arch/arm/mach-mmp/brownstone.c @@ -28,7 +28,7 @@ #include "common.h" -#define BROWNSTONE_NR_IRQS (IRQ_BOARD_START + 40) +#define BROWNSTONE_NR_IRQS (MMP_NR_IRQS + 40) #define GPIO_5V_ENABLE (89) @@ -158,7 +158,7 @@ static struct platform_device brownstone_v_5vp_device = { }; static struct max8925_platform_data brownstone_max8925_info = { - .irq_base = IRQ_BOARD_START, + .irq_base = MMP_NR_IRQS, }; static struct i2c_board_info brownstone_twsi1_info[] = { diff --git a/arch/arm/mach-mmp/flint.c b/arch/arm/mach-mmp/flint.c index 2ee8cd7829d..8059cc0905c 100644 --- a/arch/arm/mach-mmp/flint.c +++ b/arch/arm/mach-mmp/flint.c @@ -23,10 +23,11 @@ #include <mach/addr-map.h> #include <mach/mfp-mmp2.h> #include <mach/mmp2.h> +#include <mach/irqs.h> #include "common.h" -#define FLINT_NR_IRQS (IRQ_BOARD_START + 48) +#define FLINT_NR_IRQS (MMP_NR_IRQS + 48) static unsigned long flint_pin_config[] __initdata = { /* UART1 */ diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c index 87765467de6..f516e74ce0d 100644 --- a/arch/arm/mach-mmp/gplugd.c +++ b/arch/arm/mach-mmp/gplugd.c @@ -191,7 +191,7 @@ static void __init gplugd_init(void) MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform") .map_io = mmp_map_io, - .nr_irqs = IRQ_BOARD_START, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = gplugd_init, diff --git a/arch/arm/mach-mmp/include/mach/irqs.h b/arch/arm/mach-mmp/include/mach/irqs.h index 34635a0bbb5..d0e746626a3 100644 --- a/arch/arm/mach-mmp/include/mach/irqs.h +++ b/arch/arm/mach-mmp/include/mach/irqs.h @@ -223,7 +223,6 @@ #define MMP_GPIO_TO_IRQ(gpio) (IRQ_GPIO_START + (gpio)) #define IRQ_BOARD_START (IRQ_GPIO_START + MMP_NR_BUILTIN_GPIO) - -#define NR_IRQS (IRQ_BOARD_START) +#define MMP_NR_IRQS IRQ_BOARD_START #endif /* __ASM_MACH_IRQS_H */ diff --git a/arch/arm/mach-mmp/irq-mmp2.c b/arch/arm/mach-mmp/irq-mmp2.c index d21c5441a3d..7895d277421 100644 --- a/arch/arm/mach-mmp/irq-mmp2.c +++ b/arch/arm/mach-mmp/irq-mmp2.c @@ -15,6 +15,7 @@ #include <linux/irq.h> #include <linux/io.h> +#include <mach/irqs.h> #include <mach/regs-icu.h> #include <mach/mmp2.h> diff --git a/arch/arm/mach-mmp/jasper.c b/arch/arm/mach-mmp/jasper.c index 96cf5c8fe47..ff73249884d 100644 --- a/arch/arm/mach-mmp/jasper.c +++ b/arch/arm/mach-mmp/jasper.c @@ -19,6 +19,7 @@ #include <linux/mfd/max8925.h> #include <linux/interrupt.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <mach/addr-map.h> @@ -27,7 +28,7 @@ #include "common.h" -#define JASPER_NR_IRQS (IRQ_BOARD_START + 48) +#define JASPER_NR_IRQS (MMP_NR_IRQS + 48) static unsigned long jasper_pin_config[] __initdata = { /* UART1 */ @@ -135,7 +136,7 @@ static struct max8925_power_pdata jasper_power_data = { static struct max8925_platform_data jasper_max8925_info = { .backlight = &jasper_backlight_data, .power = &jasper_power_data, - .irq_base = IRQ_BOARD_START, + .irq_base = MMP_NR_IRQS, }; static struct i2c_board_info jasper_twsi1_info[] = { diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c index 8e3b5af04a5..507e6c0e34f 100644 --- a/arch/arm/mach-mmp/tavorevb.c +++ b/arch/arm/mach-mmp/tavorevb.c @@ -102,6 +102,7 @@ static void __init tavorevb_init(void) MACHINE_START(TAVOREVB, "PXA910 Evaluation Board (aka TavorEVB)") .map_io = mmp_map_io, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa910_init_irq, .timer = &pxa910_timer, .init_machine = tavorevb_init, diff --git a/arch/arm/mach-mmp/teton_bga.c b/arch/arm/mach-mmp/teton_bga.c index 0523e422990..42bef6674ec 100644 --- a/arch/arm/mach-mmp/teton_bga.c +++ b/arch/arm/mach-mmp/teton_bga.c @@ -26,6 +26,7 @@ #include <mach/mfp-pxa168.h> #include <mach/pxa168.h> #include <mach/teton_bga.h> +#include <mach/irqs.h> #include "common.h" @@ -83,7 +84,7 @@ static void __init teton_bga_init(void) MACHINE_START(TETON_BGA, "PXA168-based Teton BGA Development Platform") .map_io = mmp_map_io, - .nr_irqs = IRQ_BOARD_START, + .nr_irqs = MMP_NR_IRQS, .init_irq = pxa168_init_irq, .timer = &pxa168_timer, .init_machine = teton_bga_init, diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index 5ac5d5832e4..4c5fd5bb0c9 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -38,7 +38,7 @@ * 16 board interrupts -- PCA9575 GPIO expander * 24 board interrupts -- 88PM860x PMIC */ -#define TTCDKB_NR_IRQS (IRQ_BOARD_START + 16 + 16 + 24) +#define TTCDKB_NR_IRQS (MMP_NR_IRQS + 16 + 16 + 24) static unsigned long ttc_dkb_pin_config[] __initdata = { /* UART2 */ @@ -130,7 +130,7 @@ static struct platform_device *ttc_dkb_devices[] = { static struct pca953x_platform_data max7312_data[] = { { .gpio_base = TTCDKB_GPIO_EXT0(0), - .irq_base = IRQ_BOARD_START, + .irq_base = MMP_NR_IRQS, }, }; -- cgit v1.2.3-18-g5258 From 4e611091f859906c28921cf8d3c75a848fd249bd Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Tue, 3 Jan 2012 16:53:48 -0600 Subject: ARM: pxa: remove NR_IRQS Remove NR_IRQS and add a per machine .nr_irqs setting. Signed-off-by: Rob Herring <rob.herring@calxeda.com> --- arch/arm/mach-pxa/capc7117.c | 1 + arch/arm/mach-pxa/cm-x300.c | 1 + arch/arm/mach-pxa/colibri-pxa270.c | 2 ++ arch/arm/mach-pxa/colibri-pxa300.c | 1 + arch/arm/mach-pxa/colibri-pxa320.c | 1 + arch/arm/mach-pxa/corgi.c | 3 +++ arch/arm/mach-pxa/csb726.c | 1 + arch/arm/mach-pxa/devices.c | 1 + arch/arm/mach-pxa/em-x270.c | 2 ++ arch/arm/mach-pxa/gumstix.c | 1 + arch/arm/mach-pxa/h5000.c | 1 + arch/arm/mach-pxa/himalaya.c | 1 + arch/arm/mach-pxa/icontrol.c | 1 + arch/arm/mach-pxa/idp.c | 1 + arch/arm/mach-pxa/include/mach/irqs.h | 2 +- arch/arm/mach-pxa/mioa701.c | 1 + arch/arm/mach-pxa/mp900.c | 1 + arch/arm/mach-pxa/palmld.c | 1 + arch/arm/mach-pxa/palmt5.c | 1 + arch/arm/mach-pxa/palmtc.c | 1 + arch/arm/mach-pxa/palmte2.c | 1 + arch/arm/mach-pxa/palmtreo.c | 2 ++ arch/arm/mach-pxa/palmtx.c | 1 + arch/arm/mach-pxa/palmz72.c | 1 + arch/arm/mach-pxa/pxa3xx.c | 1 + arch/arm/mach-pxa/raumfeld.c | 3 +++ arch/arm/mach-pxa/saar.c | 1 + arch/arm/mach-pxa/spitz.c | 3 +++ arch/arm/mach-pxa/stargate2.c | 1 + arch/arm/mach-pxa/tavorevb.c | 1 + arch/arm/mach-pxa/time.c | 1 + arch/arm/mach-pxa/trizeps4.c | 2 ++ arch/arm/mach-pxa/viper.c | 1 + arch/arm/mach-pxa/vpac270.c | 1 + arch/arm/mach-pxa/xcep.c | 1 + arch/arm/mach-pxa/z2.c | 1 + 36 files changed, 46 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/capc7117.c b/arch/arm/mach-pxa/capc7117.c index c91727d1fe0..9a8760b7291 100644 --- a/arch/arm/mach-pxa/capc7117.c +++ b/arch/arm/mach-pxa/capc7117.c @@ -150,6 +150,7 @@ MACHINE_START(CAPC7117, "Embedian CAPC-7117 evaluation kit based on the MXM-8x10 CoM") .atag_offset = 0x100, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c index 4b981b82d2a..133cceefd2a 100644 --- a/arch/arm/mach-pxa/cm-x300.c +++ b/arch/arm/mach-pxa/cm-x300.c @@ -853,6 +853,7 @@ static void __init cm_x300_fixup(struct tag *tags, char **cmdline, MACHINE_START(CM_X300, "CM-X300 module") .atag_offset = 0x100, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/colibri-pxa270.c b/arch/arm/mach-pxa/colibri-pxa270.c index 29d5d541f60..b2f227d3612 100644 --- a/arch/arm/mach-pxa/colibri-pxa270.c +++ b/arch/arm/mach-pxa/colibri-pxa270.c @@ -310,6 +310,7 @@ MACHINE_START(COLIBRI, "Toradex Colibri PXA270") .atag_offset = 0x100, .init_machine = colibri_pxa270_init, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, @@ -320,6 +321,7 @@ MACHINE_START(INCOME, "Income s.r.o. SH-Dmaster PXA270 SBC") .atag_offset = 0x100, .init_machine = colibri_pxa270_income_init, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/colibri-pxa300.c b/arch/arm/mach-pxa/colibri-pxa300.c index 0846d210cb0..bb6def8ec97 100644 --- a/arch/arm/mach-pxa/colibri-pxa300.c +++ b/arch/arm/mach-pxa/colibri-pxa300.c @@ -186,6 +186,7 @@ MACHINE_START(COLIBRI300, "Toradex Colibri PXA300") .atag_offset = 0x100, .init_machine = colibri_pxa300_init, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/colibri-pxa320.c b/arch/arm/mach-pxa/colibri-pxa320.c index 6ad3359063a..d88e7b37f1d 100644 --- a/arch/arm/mach-pxa/colibri-pxa320.c +++ b/arch/arm/mach-pxa/colibri-pxa320.c @@ -256,6 +256,7 @@ MACHINE_START(COLIBRI320, "Toradex Colibri PXA320") .atag_offset = 0x100, .init_machine = colibri_pxa320_init, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 11f1e735966..039aafa455c 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -730,6 +730,7 @@ static void __init fixup_corgi(struct tag *tags, char **cmdline, MACHINE_START(CORGI, "SHARP Corgi") .fixup = fixup_corgi, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, @@ -742,6 +743,7 @@ MACHINE_END MACHINE_START(SHEPHERD, "SHARP Shepherd") .fixup = fixup_corgi, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, @@ -754,6 +756,7 @@ MACHINE_END MACHINE_START(HUSKY, "SHARP Husky") .fixup = fixup_corgi, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_machine = corgi_init, diff --git a/arch/arm/mach-pxa/csb726.c b/arch/arm/mach-pxa/csb726.c index fb5a51d834e..67f0de37f46 100644 --- a/arch/arm/mach-pxa/csb726.c +++ b/arch/arm/mach-pxa/csb726.c @@ -274,6 +274,7 @@ static void __init csb726_init(void) MACHINE_START(CSB726, "Cogent CSB726") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .init_machine = csb726_init, diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 18fd177073f..72a15a62ab0 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -12,6 +12,7 @@ #include <mach/pxafb.h> #include <mach/mmc.h> #include <mach/irda.h> +#include <mach/irqs.h> #include <mach/ohci.h> #include <plat/pxa27x_keypad.h> #include <mach/camera.h> diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index d80c0ba9a09..c1b65da2633 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -1301,6 +1301,7 @@ static void __init em_x270_init(void) MACHINE_START(EM_X270, "Compulab EM-X270") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, @@ -1311,6 +1312,7 @@ MACHINE_END MACHINE_START(EXEDA, "Compulab eXeda") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c index ac3b1cef475..e529a35a44c 100644 --- a/arch/arm/mach-pxa/gumstix.c +++ b/arch/arm/mach-pxa/gumstix.c @@ -235,6 +235,7 @@ static void __init gumstix_init(void) MACHINE_START(GUMSTIX, "Gumstix") .atag_offset = 0x100, /* match u-boot bi_boot_params */ .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/h5000.c b/arch/arm/mach-pxa/h5000.c index fde6b4c873c..e7dec589f01 100644 --- a/arch/arm/mach-pxa/h5000.c +++ b/arch/arm/mach-pxa/h5000.c @@ -205,6 +205,7 @@ static void __init h5000_init(void) MACHINE_START(H5400, "HP iPAQ H5000") .atag_offset = 0x100, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/himalaya.c b/arch/arm/mach-pxa/himalaya.c index 26d069a9f90..2962de898da 100644 --- a/arch/arm/mach-pxa/himalaya.c +++ b/arch/arm/mach-pxa/himalaya.c @@ -160,6 +160,7 @@ static void __init himalaya_init(void) MACHINE_START(HIMALAYA, "HTC Himalaya") .atag_offset = 0x100, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_machine = himalaya_init, diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c index 67400192ed3..1d02eabc9c6 100644 --- a/arch/arm/mach-pxa/icontrol.c +++ b/arch/arm/mach-pxa/icontrol.c @@ -193,6 +193,7 @@ static void __init icontrol_init(void) MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM") .atag_offset = 0x100, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index 8af1840e12c..6ff466bd43e 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -195,6 +195,7 @@ static void __init idp_map_io(void) MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") /* Maintainer: Vibren Technologies */ .map_io = idp_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h index 32975adf3ca..8765782dd95 100644 --- a/arch/arm/mach-pxa/include/mach/irqs.h +++ b/arch/arm/mach-pxa/include/mach/irqs.h @@ -100,7 +100,7 @@ */ #define IRQ_BOARD_START (PXA_GPIO_IRQ_BASE + PXA_NR_BUILTIN_GPIO) -#define NR_IRQS (IRQ_BOARD_START) +#define PXA_NR_IRQS (IRQ_BOARD_START) #ifndef __ASSEMBLY__ struct irq_data; diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index e80a3db735c..061d57009ce 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -758,6 +758,7 @@ MACHINE_START(MIOA701, "MIO A701") .atag_offset = 0x100, .restart_mode = 's', .map_io = &pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = &pxa27x_init_irq, .handle_irq = &pxa27x_handle_irq, .init_machine = mioa701_machine_init, diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c index 169bf8f97af..152efbf093f 100644 --- a/arch/arm/mach-pxa/mp900.c +++ b/arch/arm/mach-pxa/mp900.c @@ -95,6 +95,7 @@ MACHINE_START(NEC_MP900, "MobilePro900/C") .atag_offset = 0x220100, .timer = &pxa_timer, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .init_machine = mp900c_init, diff --git a/arch/arm/mach-pxa/palmld.c b/arch/arm/mach-pxa/palmld.c index 1fa80f4f80c..31e0433d83b 100644 --- a/arch/arm/mach-pxa/palmld.c +++ b/arch/arm/mach-pxa/palmld.c @@ -344,6 +344,7 @@ static void __init palmld_init(void) MACHINE_START(PALMLD, "Palm LifeDrive") .atag_offset = 0x100, .map_io = palmld_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c index 5ba14316bd9..0f6bd4fcfa3 100644 --- a/arch/arm/mach-pxa/palmt5.c +++ b/arch/arm/mach-pxa/palmt5.c @@ -205,6 +205,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5") .atag_offset = 0x100, .map_io = pxa27x_map_io, .reserve = palmt5_reserve, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c index 29b51b40f09..e2d97eed07a 100644 --- a/arch/arm/mach-pxa/palmtc.c +++ b/arch/arm/mach-pxa/palmtc.c @@ -539,6 +539,7 @@ static void __init palmtc_init(void) MACHINE_START(PALMTC, "Palm Tungsten|C") .atag_offset = 0x100, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c index 5ebf49acb82..c054827c567 100644 --- a/arch/arm/mach-pxa/palmte2.c +++ b/arch/arm/mach-pxa/palmte2.c @@ -358,6 +358,7 @@ static void __init palmte2_init(void) MACHINE_START(PALMTE2, "Palm Tungsten|E2") .atag_offset = 0x100, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c index ec8249156c0..fbdebee39a5 100644 --- a/arch/arm/mach-pxa/palmtreo.c +++ b/arch/arm/mach-pxa/palmtreo.c @@ -448,6 +448,7 @@ MACHINE_START(TREO680, "Palm Treo 680") .atag_offset = 0x100, .map_io = pxa27x_map_io, .reserve = treo_reserve, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, @@ -461,6 +462,7 @@ MACHINE_START(CENTRO, "Palm Centro 685") .atag_offset = 0x100, .map_io = pxa27x_map_io, .reserve = treo_reserve, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 6170d76dfba..9507605ed54 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -366,6 +366,7 @@ static void __init palmtx_init(void) MACHINE_START(PALMTX, "Palm T|X") .atag_offset = 0x100, .map_io = palmtx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index b2dff9d415e..a97b59965bb 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c @@ -401,6 +401,7 @@ static void __init palmz72_init(void) MACHINE_START(PALMZ72, "Palm Zire72") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index f107c71c758..d2e562d62cf 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -31,6 +31,7 @@ #include <mach/pm.h> #include <mach/dma.h> #include <mach/smemc.h> +#include <mach/irqs.h> #include "generic.h" #include "devices.h" diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 22818c7694a..7d691e51cb5 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c @@ -1090,6 +1090,7 @@ MACHINE_START(RAUMFELD_RC, "Raumfeld Controller") .atag_offset = 0x100, .init_machine = raumfeld_controller_init, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, @@ -1102,6 +1103,7 @@ MACHINE_START(RAUMFELD_CONNECTOR, "Raumfeld Connector") .atag_offset = 0x100, .init_machine = raumfeld_connector_init, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, @@ -1114,6 +1116,7 @@ MACHINE_START(RAUMFELD_SPEAKER, "Raumfeld Speaker") .atag_offset = 0x100, .init_machine = raumfeld_speaker_init, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c index 0fe354efb93..86c95a5d853 100644 --- a/arch/arm/mach-pxa/saar.c +++ b/arch/arm/mach-pxa/saar.c @@ -598,6 +598,7 @@ MACHINE_START(SAAR, "PXA930 Handheld Platform (aka SAAR)") /* Maintainer: Eric Miao <eric.miao@marvell.com> */ .atag_offset = 0x100, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index abf355d0c92..df2ab0fb2ac 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -984,6 +984,7 @@ MACHINE_START(SPITZ, "SHARP Spitz") .restart_mode = 'g', .fixup = spitz_fixup, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, @@ -997,6 +998,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi") .restart_mode = 'g', .fixup = spitz_fixup, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, @@ -1010,6 +1012,7 @@ MACHINE_START(AKITA, "SHARP Akita") .restart_mode = 'g', .fixup = spitz_fixup, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .init_machine = spitz_init, diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c index b0656e158d9..adb601a3762 100644 --- a/arch/arm/mach-pxa/stargate2.c +++ b/arch/arm/mach-pxa/stargate2.c @@ -1006,6 +1006,7 @@ static void __init stargate2_init(void) #ifdef CONFIG_MACH_INTELMOTE2 MACHINE_START(INTELMOTE2, "IMOTE 2") .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c index 9fb38e80e07..736bfdc50ee 100644 --- a/arch/arm/mach-pxa/tavorevb.c +++ b/arch/arm/mach-pxa/tavorevb.c @@ -491,6 +491,7 @@ MACHINE_START(TAVOREVB, "PXA930 Evaluation Board (aka TavorEVB)") /* Maintainer: Eric Miao <eric.miao@marvell.com> */ .atag_offset = 0x100, .map_io = pxa3xx_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa3xx_init_irq, .handle_irq = pxa3xx_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index b503049d6d2..3d6c9bd90de 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -22,6 +22,7 @@ #include <asm/mach/time.h> #include <asm/sched_clock.h> #include <mach/regs-ost.h> +#include <mach/irqs.h> /* * This is PXA's sched_clock implementation. This has a resolution diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 0f30af617d8..2b6ac00b2cd 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -558,6 +558,7 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module") .atag_offset = 0x100, .init_machine = trizeps4_init, .map_io = trizeps4_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, @@ -569,6 +570,7 @@ MACHINE_START(TRIZEPS4WL, "Keith und Koep Trizeps IV-WL module") .atag_offset = 0x100, .init_machine = trizeps4_init, .map_io = trizeps4_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 023d6ca789d..3143c3910c7 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -994,6 +994,7 @@ MACHINE_START(VIPER, "Arcom/Eurotech VIPER SBC") /* Maintainer: Marc Zyngier <maz@misterjones.org> */ .atag_offset = 0x100, .map_io = viper_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = viper_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index 1f5cfa96f6d..c57ab636ea9 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c @@ -718,6 +718,7 @@ static void __init vpac270_init(void) MACHINE_START(VPAC270, "Voipac PXA270") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/xcep.c b/arch/arm/mach-pxa/xcep.c index 4bbe9a36fe7..4275713ccd1 100644 --- a/arch/arm/mach-pxa/xcep.c +++ b/arch/arm/mach-pxa/xcep.c @@ -182,6 +182,7 @@ MACHINE_START(XCEP, "Iskratel XCEP") .atag_offset = 0x100, .init_machine = xcep_init, .map_io = pxa25x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa25x_init_irq, .handle_irq = pxa25x_handle_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c index b6476848b56..fa861997084 100644 --- a/arch/arm/mach-pxa/z2.c +++ b/arch/arm/mach-pxa/z2.c @@ -721,6 +721,7 @@ static void __init z2_init(void) MACHINE_START(ZIPIT2, "Zipit Z2") .atag_offset = 0x100, .map_io = pxa27x_map_io, + .nr_irqs = PXA_NR_IRQS, .init_irq = pxa27x_init_irq, .handle_irq = pxa27x_handle_irq, .timer = &pxa_timer, -- cgit v1.2.3-18-g5258 From 250a27237e0e0694f8f8451594a0f03e0a4f5a73 Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Tue, 3 Jan 2012 16:57:33 -0600 Subject: ARM: shmobile: remove NR_IRQS Remove NR_IRQS and explicitly include mach/irqs.h as needed. shmobile properly allocates irq_descs for each irqchip, so setting .nr_irqs for each machine is not needed. Signed-off-by: Rob Herring <rob.herring@calxeda.com> --- arch/arm/mach-shmobile/board-ag5evm.c | 1 + arch/arm/mach-shmobile/board-bonito.c | 1 + arch/arm/mach-shmobile/board-g3evm.c | 1 + arch/arm/mach-shmobile/board-g4evm.c | 1 + arch/arm/mach-shmobile/board-kota2.c | 1 + arch/arm/mach-shmobile/board-mackerel.c | 1 + arch/arm/mach-shmobile/board-marzen.c | 1 + arch/arm/mach-shmobile/include/mach/irqs.h | 2 -- arch/arm/mach-shmobile/intc-r8a7740.c | 1 + arch/arm/mach-shmobile/intc-sh7367.c | 1 + arch/arm/mach-shmobile/intc-sh7372.c | 1 + arch/arm/mach-shmobile/intc-sh7377.c | 1 + arch/arm/mach-shmobile/intc-sh73a0.c | 1 + arch/arm/mach-shmobile/setup-r8a7740.c | 1 + arch/arm/mach-shmobile/setup-r8a7779.c | 1 + arch/arm/mach-shmobile/setup-sh7367.c | 1 + arch/arm/mach-shmobile/setup-sh7372.c | 1 + arch/arm/mach-shmobile/setup-sh7377.c | 1 + arch/arm/mach-shmobile/setup-sh73a0.c | 1 + 19 files changed, 18 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index eff8a96c75e..e922e92111c 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -42,6 +42,7 @@ #include <video/sh_mipi_dsi.h> #include <sound/sh_fsi.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <mach/sh73a0.h> #include <mach/common.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c index 4d220162232..df9a6538244 100644 --- a/arch/arm/mach-shmobile/board-bonito.c +++ b/arch/arm/mach-shmobile/board-bonito.c @@ -34,6 +34,7 @@ #include <asm/mach/time.h> #include <asm/hardware/cache-l2x0.h> #include <mach/r8a7740.h> +#include <mach/irqs.h> #include <video/sh_mobile_lcdc.h> /* diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c index 72d557281b1..6dbdc428c24 100644 --- a/arch/arm/mach-shmobile/board-g3evm.c +++ b/arch/arm/mach-shmobile/board-g3evm.c @@ -33,6 +33,7 @@ #include <linux/input.h> #include <linux/input/sh_keysc.h> #include <linux/dma-mapping.h> +#include <mach/irqs.h> #include <mach/sh7367.h> #include <mach/common.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c index 2220b885cff..2936ccc9595 100644 --- a/arch/arm/mach-shmobile/board-g4evm.c +++ b/arch/arm/mach-shmobile/board-g4evm.c @@ -34,6 +34,7 @@ #include <linux/mmc/sh_mobile_sdhi.h> #include <linux/gpio.h> #include <linux/dma-mapping.h> +#include <mach/irqs.h> #include <mach/sh7377.h> #include <mach/common.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c index 857ceeec1bb..c71780b2232 100644 --- a/arch/arm/mach-shmobile/board-kota2.c +++ b/arch/arm/mach-shmobile/board-kota2.c @@ -39,6 +39,7 @@ #include <linux/mfd/tmio.h> #include <linux/mmc/sh_mobile_sdhi.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <mach/sh73a0.h> #include <mach/common.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 9b42fbd10f8..73f00971d0d 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -55,6 +55,7 @@ #include <sound/sh_fsi.h> #include <mach/common.h> +#include <mach/irqs.h> #include <mach/sh7372.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index f0e02c0ce99..3b2e88ae26b 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -31,6 +31,7 @@ #include <mach/hardware.h> #include <mach/r8a7779.h> #include <mach/common.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h index 828807dce5a..4e686cc201f 100644 --- a/arch/arm/mach-shmobile/include/mach/irqs.h +++ b/arch/arm/mach-shmobile/include/mach/irqs.h @@ -3,8 +3,6 @@ #include <linux/sh_intc.h> -#define NR_IRQS 1024 - /* GIC */ #define gic_spi(nr) ((nr) + 32) diff --git a/arch/arm/mach-shmobile/intc-r8a7740.c b/arch/arm/mach-shmobile/intc-r8a7740.c index 272c84c20c8..09c42afcb22 100644 --- a/arch/arm/mach-shmobile/intc-r8a7740.c +++ b/arch/arm/mach-shmobile/intc-r8a7740.c @@ -25,6 +25,7 @@ #include <linux/io.h> #include <linux/sh_intc.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c index cfde9bfc366..5bf776495b7 100644 --- a/arch/arm/mach-shmobile/intc-sh7367.c +++ b/arch/arm/mach-shmobile/intc-sh7367.c @@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/sh_intc.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c index 89afcaba99a..6447e0af52d 100644 --- a/arch/arm/mach-shmobile/intc-sh7372.c +++ b/arch/arm/mach-shmobile/intc-sh7372.c @@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/sh_intc.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c index 2af4e6e9bc5..b84a460a340 100644 --- a/arch/arm/mach-shmobile/intc-sh7377.c +++ b/arch/arm/mach-shmobile/intc-sh7377.c @@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/sh_intc.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c index 1eda6b0b69e..9a8207c6d31 100644 --- a/arch/arm/mach-shmobile/intc-sh73a0.c +++ b/arch/arm/mach-shmobile/intc-sh73a0.c @@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/sh_intc.h> #include <mach/intc.h> +#include <mach/irqs.h> #include <mach/sh73a0.h> #include <asm/hardware/gic.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 986dca6b3fa..fa15d81267e 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c @@ -25,6 +25,7 @@ #include <linux/serial_sci.h> #include <linux/sh_timer.h> #include <mach/r8a7740.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 4725663bd03..55df21add2d 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -29,6 +29,7 @@ #include <linux/sh_intc.h> #include <linux/sh_timer.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <mach/r8a7779.h> #include <mach/common.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c index e546017f15d..8e84819833a 100644 --- a/arch/arm/mach-shmobile/setup-sh7367.c +++ b/arch/arm/mach-shmobile/setup-sh7367.c @@ -29,6 +29,7 @@ #include <linux/serial_sci.h> #include <linux/sh_timer.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 6fcf304d3cd..420d25c0d74 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -32,6 +32,7 @@ #include <linux/sh_timer.h> #include <linux/pm_domain.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <mach/sh7372.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c index bb405b8e459..747ed8ef84e 100644 --- a/arch/arm/mach-shmobile/setup-sh7377.c +++ b/arch/arm/mach-shmobile/setup-sh7377.c @@ -30,6 +30,7 @@ #include <linux/sh_intc.h> #include <linux/sh_timer.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 20e71e5cace..7bf740e29a3 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -31,6 +31,7 @@ #include <linux/sh_intc.h> #include <linux/sh_timer.h> #include <mach/hardware.h> +#include <mach/irqs.h> #include <mach/sh73a0.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> -- cgit v1.2.3-18-g5258 From de27c308223dc9bd48de9742c7c2b53a15c1b012 Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Sat, 2 Jul 2011 14:46:27 +0100 Subject: ARM: pgtable: move TOP_PTE address definitions to arch/arm/mm/mm.h Move the TOP_PTE address definitions to one central place so that it's easy to discover what they're being used for. This helps to ensure that there are no overlaps. Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/mm/copypage-v4mc.c | 10 +++------- arch/arm/mm/copypage-v6.c | 16 ++++++---------- arch/arm/mm/copypage-xscale.c | 6 ------ arch/arm/mm/flush.c | 8 +++----- arch/arm/mm/mm.h | 13 +++++++++++++ 5 files changed, 25 insertions(+), 28 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c index 7d0a8c23034..87a23ca1fc6 100644 --- a/arch/arm/mm/copypage-v4mc.c +++ b/arch/arm/mm/copypage-v4mc.c @@ -23,10 +23,6 @@ #include "mm.h" -/* - * 0xffff8000 to 0xffffffff is reserved for any ARM architecture - * specific hacks for copying pages efficiently. - */ #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_MT_MINICACHE) @@ -78,10 +74,10 @@ void v4_mc_copy_user_highpage(struct page *to, struct page *from, raw_spin_lock(&minicache_lock); - set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); - flush_tlb_kernel_page(0xffff8000); + set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); + flush_tlb_kernel_page(COPYPAGE_MINICACHE); - mc_copy_user_page((void *)0xffff8000, kto); + mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); raw_spin_unlock(&minicache_lock); diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 3d9a1552cef..c00a7501443 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -24,9 +24,6 @@ #error FIX ME #endif -#define from_address (0xffff8000) -#define to_address (0xffffc000) - static DEFINE_RAW_SPINLOCK(v6_lock); /* @@ -90,11 +87,11 @@ static void v6_copy_user_highpage_aliasing(struct page *to, */ raw_spin_lock(&v6_lock); - set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0); - set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0); + kfrom = COPYPAGE_V6_FROM + (offset << PAGE_SHIFT); + kto = COPYPAGE_V6_TO + (offset << PAGE_SHIFT); - kfrom = from_address + (offset << PAGE_SHIFT); - kto = to_address + (offset << PAGE_SHIFT); + set_pte_ext(TOP_PTE(kfrom), pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0); + set_pte_ext(TOP_PTE(kto), pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0); flush_tlb_kernel_page(kfrom); flush_tlb_kernel_page(kto); @@ -111,8 +108,7 @@ static void v6_copy_user_highpage_aliasing(struct page *to, */ static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vaddr) { - unsigned int offset = CACHE_COLOUR(vaddr); - unsigned long to = to_address + (offset << PAGE_SHIFT); + unsigned long to = COPYPAGE_V6_TO + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); /* FIXME: not highmem safe */ discard_old_kernel_data(page_address(page)); @@ -123,7 +119,7 @@ static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vad */ raw_spin_lock(&v6_lock); - set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(page_to_pfn(page), PAGE_KERNEL), 0); + set_pte_ext(TOP_PTE(to), pfn_pte(page_to_pfn(page), PAGE_KERNEL), 0); flush_tlb_kernel_page(to); clear_page((void *)to); diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c index 610c24ced31..90f3bb58eaf 100644 --- a/arch/arm/mm/copypage-xscale.c +++ b/arch/arm/mm/copypage-xscale.c @@ -23,12 +23,6 @@ #include "mm.h" -/* - * 0xffff8000 to 0xffffffff is reserved for any ARM architecture - * specific hacks for copying pages efficiently. - */ -#define COPYPAGE_MINICACHE 0xffff8000 - #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_MT_MINICACHE) diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 1a8d4aa821b..f4d407af469 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -23,11 +23,9 @@ #ifdef CONFIG_CPU_CACHE_VIPT -#define ALIAS_FLUSH_START 0xffff4000 - static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) { - unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); + unsigned long to = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); const int zero = 0; set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0); @@ -46,8 +44,8 @@ static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned unsigned long offset = vaddr & (PAGE_SIZE - 1); unsigned long to; - set_pte_ext(TOP_PTE(ALIAS_FLUSH_START) + colour, pfn_pte(pfn, PAGE_KERNEL), 0); - to = ALIAS_FLUSH_START + (colour << PAGE_SHIFT) + offset; + set_pte_ext(TOP_PTE(FLUSH_ALIAS_START) + colour, pfn_pte(pfn, PAGE_KERNEL), 0); + to = FLUSH_ALIAS_START + (colour << PAGE_SHIFT) + offset; flush_tlb_kernel_page(to); flush_icache_range(to, to + len); } diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 70f6d3ea483..6ee1ff2c1da 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -5,6 +5,19 @@ extern pmd_t *top_pmd; #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) +/* + * 0xffff8000 to 0xffffffff is reserved for any ARM architecture + * specific hacks for copying pages efficiently, while 0xffff4000 + * is reserved for VIPT aliasing flushing by generic code. + * + * Note that we don't allow VIPT aliasing caches with SMP. + */ +#define COPYPAGE_MINICACHE 0xffff8000 +#define COPYPAGE_V6_FROM 0xffff8000 +#define COPYPAGE_V6_TO 0xffffc000 +/* PFN alias flushing, for VIPT caches */ +#define FLUSH_ALIAS_START 0xffff4000 + static inline pmd_t *pmd_off_k(unsigned long virt) { return pmd_offset(pud_offset(pgd_offset_k(virt), virt), virt); -- cgit v1.2.3-18-g5258 From 6e78df176141f2cb673bed7fa47825e3c6a8719f Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Sat, 2 Jul 2011 14:56:42 +0100 Subject: ARM: pgtable: use mk_pte rather than pfn_pte(page_to_pfn()) mk_pte is provided to do this translation for us, so use it rather than open-coding it in the copypage code. Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/mm/copypage-v4mc.c | 2 +- arch/arm/mm/copypage-v6.c | 6 +++--- arch/arm/mm/copypage-xscale.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c index 87a23ca1fc6..e4dc2f49112 100644 --- a/arch/arm/mm/copypage-v4mc.c +++ b/arch/arm/mm/copypage-v4mc.c @@ -74,7 +74,7 @@ void v4_mc_copy_user_highpage(struct page *to, struct page *from, raw_spin_lock(&minicache_lock); - set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); + set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), mk_pte(from, minicache_pgprot), 0); flush_tlb_kernel_page(COPYPAGE_MINICACHE); mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index c00a7501443..86524591b1b 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -90,8 +90,8 @@ static void v6_copy_user_highpage_aliasing(struct page *to, kfrom = COPYPAGE_V6_FROM + (offset << PAGE_SHIFT); kto = COPYPAGE_V6_TO + (offset << PAGE_SHIFT); - set_pte_ext(TOP_PTE(kfrom), pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0); - set_pte_ext(TOP_PTE(kto), pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0); + set_pte_ext(TOP_PTE(kfrom), mk_pte(from, PAGE_KERNEL), 0); + set_pte_ext(TOP_PTE(kto), mk_pte(to, PAGE_KERNEL), 0); flush_tlb_kernel_page(kfrom); flush_tlb_kernel_page(kto); @@ -119,7 +119,7 @@ static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vad */ raw_spin_lock(&v6_lock); - set_pte_ext(TOP_PTE(to), pfn_pte(page_to_pfn(page), PAGE_KERNEL), 0); + set_pte_ext(TOP_PTE(to), mk_pte(page, PAGE_KERNEL), 0); flush_tlb_kernel_page(to); clear_page((void *)to); diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c index 90f3bb58eaf..2497dcf6d9a 100644 --- a/arch/arm/mm/copypage-xscale.c +++ b/arch/arm/mm/copypage-xscale.c @@ -94,7 +94,7 @@ void xscale_mc_copy_user_highpage(struct page *to, struct page *from, raw_spin_lock(&minicache_lock); - set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(page_to_pfn(from), minicache_pgprot), 0); + set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), mk_pte(from, minicache_pgprot), 0); flush_tlb_kernel_page(COPYPAGE_MINICACHE); mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); -- cgit v1.2.3-18-g5258 From 67ece1443174d852e71c42facb3e2d7dd338c88a Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Sat, 2 Jul 2011 15:20:44 +0100 Subject: ARM: pgtable: consolidate set_pte_ext(TOP_PTE,...) + tlb flush A number of places establish a PTE in our top page table and immediately flush the TLB. Rather than having this at every callsite, provide an inline function for this purpose. This changes some global tlb flushes to be local; each time we setup one of these mappings, we always do it with preemption disabled which would prevent us migrating to another CPU. Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/mm/copypage-v4mc.c | 3 +-- arch/arm/mm/copypage-v6.c | 10 +++------- arch/arm/mm/copypage-xscale.c | 3 +-- arch/arm/mm/flush.c | 10 ++++------ arch/arm/mm/highmem.c | 13 +++++-------- arch/arm/mm/mm.h | 6 ++++++ 6 files changed, 20 insertions(+), 25 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c index e4dc2f49112..6e06180a8bc 100644 --- a/arch/arm/mm/copypage-v4mc.c +++ b/arch/arm/mm/copypage-v4mc.c @@ -74,8 +74,7 @@ void v4_mc_copy_user_highpage(struct page *to, struct page *from, raw_spin_lock(&minicache_lock); - set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), mk_pte(from, minicache_pgprot), 0); - flush_tlb_kernel_page(COPYPAGE_MINICACHE); + set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot)); mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 86524591b1b..29c770463e4 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -90,11 +90,8 @@ static void v6_copy_user_highpage_aliasing(struct page *to, kfrom = COPYPAGE_V6_FROM + (offset << PAGE_SHIFT); kto = COPYPAGE_V6_TO + (offset << PAGE_SHIFT); - set_pte_ext(TOP_PTE(kfrom), mk_pte(from, PAGE_KERNEL), 0); - set_pte_ext(TOP_PTE(kto), mk_pte(to, PAGE_KERNEL), 0); - - flush_tlb_kernel_page(kfrom); - flush_tlb_kernel_page(kto); + set_top_pte(kfrom, mk_pte(from, PAGE_KERNEL)); + set_top_pte(kto, mk_pte(to, PAGE_KERNEL)); copy_page((void *)kto, (void *)kfrom); @@ -119,8 +116,7 @@ static void v6_clear_user_highpage_aliasing(struct page *page, unsigned long vad */ raw_spin_lock(&v6_lock); - set_pte_ext(TOP_PTE(to), mk_pte(page, PAGE_KERNEL), 0); - flush_tlb_kernel_page(to); + set_top_pte(to, mk_pte(page, PAGE_KERNEL)); clear_page((void *)to); raw_spin_unlock(&v6_lock); diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c index 2497dcf6d9a..804eeddda97 100644 --- a/arch/arm/mm/copypage-xscale.c +++ b/arch/arm/mm/copypage-xscale.c @@ -94,8 +94,7 @@ void xscale_mc_copy_user_highpage(struct page *to, struct page *from, raw_spin_lock(&minicache_lock); - set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), mk_pte(from, minicache_pgprot), 0); - flush_tlb_kernel_page(COPYPAGE_MINICACHE); + set_top_pte(COPYPAGE_MINICACHE, mk_pte(from, minicache_pgprot)); mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index f4d407af469..4d0b70f035e 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -28,8 +28,7 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) unsigned long to = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); const int zero = 0; - set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0); - flush_tlb_kernel_page(to); + set_top_pte(to, pfn_pte(pfn, PAGE_KERNEL)); asm( "mcrr p15, 0, %1, %0, c14\n" " mcr p15, 0, %2, c7, c10, 4" @@ -40,13 +39,12 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) static void flush_icache_alias(unsigned long pfn, unsigned long vaddr, unsigned long len) { - unsigned long colour = CACHE_COLOUR(vaddr); + unsigned long va = FLUSH_ALIAS_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); unsigned long offset = vaddr & (PAGE_SIZE - 1); unsigned long to; - set_pte_ext(TOP_PTE(FLUSH_ALIAS_START) + colour, pfn_pte(pfn, PAGE_KERNEL), 0); - to = FLUSH_ALIAS_START + (colour << PAGE_SHIFT) + offset; - flush_tlb_kernel_page(to); + set_top_pte(va, pfn_pte(pfn, PAGE_KERNEL)); + to = va + offset; flush_icache_range(to, to + len); } diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 807c0573abb..35352517a5d 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -71,13 +71,12 @@ void *__kmap_atomic(struct page *page) */ BUG_ON(!pte_none(*(TOP_PTE(vaddr)))); #endif - set_pte_ext(TOP_PTE(vaddr), mk_pte(page, kmap_prot), 0); /* * When debugging is off, kunmap_atomic leaves the previous mapping - * in place, so this TLB flush ensures the TLB is updated with the - * new mapping. + * in place, so the contained TLB flush ensures the TLB is updated + * with the new mapping. */ - local_flush_tlb_kernel_page(vaddr); + set_top_pte(vaddr, mk_pte(page, kmap_prot)); return (void *)vaddr; } @@ -96,8 +95,7 @@ void __kunmap_atomic(void *kvaddr) __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE); #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); - set_pte_ext(TOP_PTE(vaddr), __pte(0), 0); - local_flush_tlb_kernel_page(vaddr); + set_top_pte(vaddr, __pte(0)); #else (void) idx; /* to kill a warning */ #endif @@ -123,8 +121,7 @@ void *kmap_atomic_pfn(unsigned long pfn) #ifdef CONFIG_DEBUG_HIGHMEM BUG_ON(!pte_none(*(TOP_PTE(vaddr)))); #endif - set_pte_ext(TOP_PTE(vaddr), pfn_pte(pfn, kmap_prot), 0); - local_flush_tlb_kernel_page(vaddr); + set_top_pte(vaddr, pfn_pte(pfn, kmap_prot)); return (void *)vaddr; } diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 6ee1ff2c1da..a4e7febeb6a 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -18,6 +18,12 @@ extern pmd_t *top_pmd; /* PFN alias flushing, for VIPT caches */ #define FLUSH_ALIAS_START 0xffff4000 +static inline void set_top_pte(unsigned long va, pte_t pte) +{ + set_pte_ext(TOP_PTE(va), pte, 0); + local_flush_tlb_kernel_page(va); +} + static inline pmd_t *pmd_off_k(unsigned long virt) { return pmd_offset(pud_offset(pgd_offset_k(virt), virt), virt); -- cgit v1.2.3-18-g5258 From 0d31fe47b0f62e6546779eae2fc9b2e024aff4ce Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Mon, 4 Jul 2011 11:22:27 +0100 Subject: ARM: pgtable: provide get_top_pte() to complement set_top_pte() Provide get_top_pte() to complement set_top_pte(), moving the only users of TOP_PTE to arch/arm/mm/mm.h. Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/mm/highmem.c | 8 +++----- arch/arm/mm/mm.h | 5 +++++ 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index 35352517a5d..3a9e8aa1975 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c @@ -69,7 +69,7 @@ void *__kmap_atomic(struct page *page) * With debugging enabled, kunmap_atomic forces that entry to 0. * Make sure it was indeed properly unmapped. */ - BUG_ON(!pte_none(*(TOP_PTE(vaddr)))); + BUG_ON(!pte_none(get_top_pte(vaddr))); #endif /* * When debugging is off, kunmap_atomic leaves the previous mapping @@ -119,7 +119,7 @@ void *kmap_atomic_pfn(unsigned long pfn) idx = type + KM_TYPE_NR * smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); #ifdef CONFIG_DEBUG_HIGHMEM - BUG_ON(!pte_none(*(TOP_PTE(vaddr)))); + BUG_ON(!pte_none(get_top_pte(vaddr))); #endif set_top_pte(vaddr, pfn_pte(pfn, kmap_prot)); @@ -129,11 +129,9 @@ void *kmap_atomic_pfn(unsigned long pfn) struct page *kmap_atomic_to_page(const void *ptr) { unsigned long vaddr = (unsigned long)ptr; - pte_t *pte; if (vaddr < FIXADDR_START) return virt_to_page(ptr); - pte = TOP_PTE(vaddr); - return pte_page(*pte); + return pte_page(get_top_pte(vaddr)); } diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index a4e7febeb6a..1651d5aa04a 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -24,6 +24,11 @@ static inline void set_top_pte(unsigned long va, pte_t pte) local_flush_tlb_kernel_page(va); } +static inline pte_t get_top_pte(unsigned long va) +{ + return *TOP_PTE(va); +} + static inline pmd_t *pmd_off_k(unsigned long virt) { return pmd_offset(pud_offset(pgd_offset_k(virt), virt), virt); -- cgit v1.2.3-18-g5258 From 60db4fcf14c6b562399579473a67e51eed694ff4 Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Mon, 4 Jul 2011 11:25:53 +0100 Subject: ARM: pgtable: get rid of TOP_PTE() Get rid of the TOP_PTE() macro as we now have proper accessor functions instead. No one should be directly referencing the top pte table anymore. Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/mm/mm.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 1651d5aa04a..27f4a619b35 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -3,8 +3,6 @@ /* the upper-most page table pointer */ extern pmd_t *top_pmd; -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - /* * 0xffff8000 to 0xffffffff is reserved for any ARM architecture * specific hacks for copying pages efficiently, while 0xffff4000 @@ -20,13 +18,15 @@ extern pmd_t *top_pmd; static inline void set_top_pte(unsigned long va, pte_t pte) { - set_pte_ext(TOP_PTE(va), pte, 0); + pte_t *ptep = pte_offset_kernel(top_pmd, va); + set_pte_ext(ptep, pte, 0); local_flush_tlb_kernel_page(va); } static inline pte_t get_top_pte(unsigned long va) { - return *TOP_PTE(va); + pte_t *ptep = pte_offset_kernel(top_pmd, va); + return *ptep; } static inline pmd_t *pmd_off_k(unsigned long virt) -- cgit v1.2.3-18-g5258 From a2be01b15443d5bc45d23b970dab0abba773ef2a Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Tue, 3 Jan 2012 15:17:23 -0600 Subject: ARM: only include mach/irqs.h for !SPARSE_IRQ Make mach/irqs.h optional for SPARSE_IRQ. With this change mach/irqs.h can be removed by converting platforms over to sparse irq. Platforms either need to set nr_irqs in their machine desc or all irqchips used by a platform need to allocate their irq_descs. There cannot be a mixture. Once this is done, the platforms can select SPARSE_IRQ. shmobile does the latter, and mmp and pxa do the former. Signed-off-by: Rob Herring <rob.herring@calxeda.com> --- arch/arm/include/asm/irq.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index 5a526afb5f1..35c21c375d8 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -1,14 +1,18 @@ #ifndef __ASM_ARM_IRQ_H #define __ASM_ARM_IRQ_H +#define NR_IRQS_LEGACY 16 + +#ifndef CONFIG_SPARSE_IRQ #include <mach/irqs.h> +#else +#define NR_IRQS NR_IRQS_LEGACY +#endif #ifndef irq_canonicalize #define irq_canonicalize(i) (i) #endif -#define NR_IRQS_LEGACY 16 - /* * Use this value to indicate lack of interrupt * capability -- cgit v1.2.3-18-g5258 From fdfa64a4b7e6253583fa49f26e676d119bc22e76 Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Tue, 3 Jan 2012 14:44:31 -0600 Subject: ARM: highbank: select SPARSE_IRQ and remove irqs.h irqs.h is optional now for SPARSE_IRQ, so select it and remove mach/irqs.h from highbank. Signed-off-by: Rob Herring <rob.herring@calxeda.com> --- arch/arm/Kconfig | 1 + arch/arm/mach-highbank/highbank.c | 1 - arch/arm/mach-highbank/include/mach/irqs.h | 6 ------ 3 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 arch/arm/mach-highbank/include/mach/irqs.h (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 30e7840498c..dcd77dbf466 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -349,6 +349,7 @@ config ARCH_HIGHBANK select GENERIC_CLOCKEVENTS select HAVE_ARM_SCU select HAVE_SMP + select SPARSE_IRQ select USE_OF help Support for the Calxeda Highbank SoC based boards. diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index 7afbe1e55be..ee228ef3d27 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -33,7 +33,6 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/time.h> -#include <mach/irqs.h> #include "core.h" #include "sysregs.h" diff --git a/arch/arm/mach-highbank/include/mach/irqs.h b/arch/arm/mach-highbank/include/mach/irqs.h deleted file mode 100644 index 9746aab14e9..00000000000 --- a/arch/arm/mach-highbank/include/mach/irqs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __MACH_IRQS_H -#define __MACH_IRQS_H - -#define NR_IRQS 192 - -#endif -- cgit v1.2.3-18-g5258 From 72ee8499eb27f5724ac97b147350a5457a598aa3 Mon Sep 17 00:00:00 2001 From: Jamie Iles <jamie@jamieiles.com> Date: Fri, 13 Jan 2012 17:42:45 +0000 Subject: ARM: picoxcell: remove mach/irqs.h picoxcell uses SPARSE_IRQ which means we don't need a mach/irqs.h anymore so kill it off. Signed-off-by: Jamie Iles <jamie@jamieiles.com> Signed-off-by: Rob Herring <rob.herring@calxeda.com> --- arch/arm/mach-picoxcell/include/mach/irqs.h | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 arch/arm/mach-picoxcell/include/mach/irqs.h (limited to 'arch/arm') diff --git a/arch/arm/mach-picoxcell/include/mach/irqs.h b/arch/arm/mach-picoxcell/include/mach/irqs.h deleted file mode 100644 index 59eac1ee282..00000000000 --- a/arch/arm/mach-picoxcell/include/mach/irqs.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2011 Picochip Ltd., Jamie Iles - * - * 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 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. - */ -#ifndef __MACH_IRQS_H -#define __MACH_IRQS_H - -/* We dynamically allocate our irq_desc's. */ -#define NR_IRQS 0 - -#endif /* __MACH_IRQS_H */ -- cgit v1.2.3-18-g5258 From 5d0ef6ae63092d9814bb5c35a9bf6fc1caf6ccfe Mon Sep 17 00:00:00 2001 From: Sekhar Nori <nsekhar@ti.com> Date: Fri, 23 Dec 2011 17:57:19 +0000 Subject: ARM: davinci: time.c: group related header files together Rearrange header files to keep related header files together. Signed-off-by: Sekhar Nori <nsekhar@ti.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> --- arch/arm/mach-davinci/time.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index e1969ce904d..f2afb2de549 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -19,11 +19,13 @@ #include <linux/err.h> #include <linux/platform_device.h> -#include <mach/hardware.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> + #include <mach/cputype.h> +#include <mach/hardware.h> #include <mach/time.h> + #include "clock.h" static struct clock_event_device clockevent_davinci; -- cgit v1.2.3-18-g5258 From 30c9c5b157b70d0a2f1fd0f37b936e63bade0d58 Mon Sep 17 00:00:00 2001 From: Marc Zyngier <marc.zyngier@arm.com> Date: Mon, 16 Jan 2012 11:44:12 +0000 Subject: ARM: davinci: convert to common sched_clock() implementation Davinci has its own sched_clock() implementation, which gets in the way of a single zImage. Moving to the common sched_clock framework makes the code slightly cleaner. Acked-by: Sekhar Nori <nsekhar@ti.com> Cc: Kevin Hilman <khilman@ti.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> --- arch/arm/Kconfig | 1 + arch/arm/mach-davinci/time.c | 24 +++++++----------------- 2 files changed, 8 insertions(+), 17 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 24626b0419e..cb757342a66 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -932,6 +932,7 @@ config ARCH_DAVINCI select ARCH_REQUIRE_GPIOLIB select ZONE_DMA select HAVE_IDE + select HAVE_SCHED_CLOCK select CLKDEV_LOOKUP select GENERIC_ALLOCATOR select GENERIC_IRQ_CHIP diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index f2afb2de549..75da315b658 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -19,6 +19,7 @@ #include <linux/err.h> #include <linux/platform_device.h> +#include <asm/sched_clock.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> @@ -274,19 +275,9 @@ static cycle_t read_cycles(struct clocksource *cs) return (cycles_t)timer32_read(t); } -/* - * Kernel assumes that sched_clock can be called early but may not have - * things ready yet. - */ -static cycle_t read_dummy(struct clocksource *cs) -{ - return 0; -} - - static struct clocksource clocksource_davinci = { .rating = 300, - .read = read_dummy, + .read = read_cycles, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -294,12 +285,9 @@ static struct clocksource clocksource_davinci = { /* * Overwrite weak default sched_clock with something more precise */ -unsigned long long notrace sched_clock(void) +static u32 notrace davinci_read_sched_clock(void) { - const cycle_t cyc = clocksource_davinci.read(&clocksource_davinci); - - return clocksource_cyc2ns(cyc, clocksource_davinci.mult, - clocksource_davinci.shift); + return timer32_read(&timers[TID_CLOCKSOURCE]); } /* @@ -399,12 +387,14 @@ static void __init davinci_timer_init(void) davinci_clock_tick_rate = clk_get_rate(timer_clk); /* setup clocksource */ - clocksource_davinci.read = read_cycles; clocksource_davinci.name = id_to_name[clocksource_id]; if (clocksource_register_hz(&clocksource_davinci, davinci_clock_tick_rate)) printk(err, clocksource_davinci.name); + setup_sched_clock(davinci_read_sched_clock, 32, + davinci_clock_tick_rate); + /* setup clockevent */ clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id]; clockevent_davinci.mult = div_sc(davinci_clock_tick_rate, NSEC_PER_SEC, -- cgit v1.2.3-18-g5258 From bc8d849d9171a2014f8e9b0322f3ac5af9d3f2b2 Mon Sep 17 00:00:00 2001 From: Marc Zyngier <marc.zyngier@arm.com> Date: Mon, 16 Jan 2012 11:44:12 +0000 Subject: ARM: prima2: convert to common sched_clock() implementation Prima2 has its own sched_clock() implementation, which gets in the way of a single zImage. Moving to the common sched_clock framework makes the code slightly cleaner (the mapping hack in sched_clock() goes away...). Acked-by: Barry Song <baohua.song@csr.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> --- arch/arm/Kconfig | 1 + arch/arm/mach-prima2/timer.c | 21 +++++++-------------- 2 files changed, 8 insertions(+), 14 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cb757342a66..a18550ee2f2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -388,6 +388,7 @@ config ARCH_PRIMA2 select GENERIC_CLOCKEVENTS select CLKDEV_LOOKUP select GENERIC_IRQ_CHIP + select HAVE_SCHED_CLOCK select MIGHT_HAVE_CACHE_L2X0 select USE_OF select ZONE_DMA diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c index b7a6091ce79..0d024b1e916 100644 --- a/arch/arm/mach-prima2/timer.c +++ b/arch/arm/mach-prima2/timer.c @@ -18,6 +18,7 @@ #include <linux/of.h> #include <linux/of_address.h> #include <mach/map.h> +#include <asm/sched_clock.h> #include <asm/mach/time.h> #define SIRFSOC_TIMER_COUNTER_LO 0x0000 @@ -165,21 +166,9 @@ static struct irqaction sirfsoc_timer_irq = { }; /* Overwrite weak default sched_clock with more precise one */ -unsigned long long notrace sched_clock(void) +static u32 notrace sirfsoc_read_sched_clock(void) { - static int is_mapped; - - /* - * sched_clock is called earlier than .init of sys_timer - * if we map timer memory in .init of sys_timer, system - * will panic due to illegal memory access - */ - if (!is_mapped) { - sirfsoc_of_timer_map(); - is_mapped = 1; - } - - return sirfsoc_timer_read(NULL) * (NSEC_PER_SEC / CLOCK_TICK_RATE); + return (u32)(sirfsoc_timer_read(NULL) & 0xffffffff); } static void __init sirfsoc_clockevent_init(void) @@ -210,6 +199,8 @@ static void __init sirfsoc_timer_init(void) BUG_ON(rate < CLOCK_TICK_RATE); BUG_ON(rate % CLOCK_TICK_RATE); + sirfsoc_of_timer_map(); + writel_relaxed(rate / CLOCK_TICK_RATE / 2 - 1, sirfsoc_timer_base + SIRFSOC_TIMER_DIV); writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); @@ -217,6 +208,8 @@ static void __init sirfsoc_timer_init(void) BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); + setup_sched_clock(sirfsoc_read_sched_clock, 32, CLOCK_TICK_RATE); + BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); sirfsoc_clockevent_init(); -- cgit v1.2.3-18-g5258 From 6905a65879b51d326396e63dfea40861a30bc17f Mon Sep 17 00:00:00 2001 From: Marc Zyngier <marc.zyngier@arm.com> Date: Wed, 18 Jan 2012 15:05:11 +0000 Subject: ARM: Make the sched_clock framework mandatory All sched_clock() providers have been converted to the sched_clock framework, which also provides a jiffy based implementation for the platforms that do not provide a counter. It is now possible to make the sched_clock framework mandatory, effectively preventing new platforms to add new sched_clock() functions, which would be detrimental to the single zImage work. Acked-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> --- arch/arm/Kconfig | 18 ------------------ arch/arm/kernel/Makefile | 5 ++--- arch/arm/kernel/time.c | 2 -- arch/arm/plat-nomadik/Kconfig | 1 - arch/arm/plat-versatile/Kconfig | 1 - 5 files changed, 2 insertions(+), 25 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a18550ee2f2..d1fcfe06683 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -52,9 +52,6 @@ config MIGHT_HAVE_PCI config SYS_SUPPORTS_APM_EMULATION bool -config HAVE_SCHED_CLOCK - bool - config GENERIC_GPIO bool @@ -388,7 +385,6 @@ config ARCH_PRIMA2 select GENERIC_CLOCKEVENTS select CLKDEV_LOOKUP select GENERIC_IRQ_CHIP - select HAVE_SCHED_CLOCK select MIGHT_HAVE_CACHE_L2X0 select USE_OF select ZONE_DMA @@ -439,7 +435,6 @@ config ARCH_MXC select CLKDEV_LOOKUP select CLKSRC_MMIO select GENERIC_IRQ_CHIP - select HAVE_SCHED_CLOCK select MULTI_IRQ_HANDLER help Support for Freescale MXC/iMX-based family of processors @@ -531,7 +526,6 @@ config ARCH_IXP4XX select CPU_XSCALE select GENERIC_GPIO select GENERIC_CLOCKEVENTS - select HAVE_SCHED_CLOCK select MIGHT_HAVE_PCI select DMABOUNCE if PCI help @@ -602,7 +596,6 @@ config ARCH_MMP select CLKDEV_LOOKUP select GENERIC_CLOCKEVENTS select GPIO_PXA - select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ @@ -643,7 +636,6 @@ config ARCH_TEGRA select GENERIC_CLOCKEVENTS select GENERIC_GPIO select HAVE_CLK - select HAVE_SCHED_CLOCK select HAVE_SMP select MIGHT_HAVE_CACHE_L2X0 select ARCH_HAS_CPUFREQ @@ -660,7 +652,6 @@ config ARCH_PICOXCELL select DW_APB_TIMER select GENERIC_CLOCKEVENTS select GENERIC_GPIO - select HAVE_SCHED_CLOCK select HAVE_TCM select NO_IOPORT select SPARSE_IRQ @@ -688,7 +679,6 @@ config ARCH_PXA select ARCH_REQUIRE_GPIOLIB select GENERIC_CLOCKEVENTS select GPIO_PXA - select HAVE_SCHED_CLOCK select TICK_ONESHOT select PLAT_PXA select SPARSE_IRQ @@ -756,7 +746,6 @@ config ARCH_SA1100 select CPU_FREQ select GENERIC_CLOCKEVENTS select CLKDEV_LOOKUP - select HAVE_SCHED_CLOCK select TICK_ONESHOT select ARCH_REQUIRE_GPIOLIB select HAVE_IDE @@ -813,7 +802,6 @@ config ARCH_S5P64X0 select CLKSRC_MMIO select HAVE_S3C2410_WATCHDOG if WATCHDOG select GENERIC_CLOCKEVENTS - select HAVE_SCHED_CLOCK select HAVE_S3C2410_I2C if I2C select HAVE_S3C_RTC if RTC_CLASS help @@ -846,7 +834,6 @@ config ARCH_S5PV210 select ARM_L1_CACHE_SHIFT_6 select ARCH_HAS_CPUFREQ select GENERIC_CLOCKEVENTS - select HAVE_SCHED_CLOCK select HAVE_S3C2410_I2C if I2C select HAVE_S3C_RTC if RTC_CLASS select HAVE_S3C2410_WATCHDOG if WATCHDOG @@ -889,7 +876,6 @@ config ARCH_U300 depends on MMU select CLKSRC_MMIO select CPU_ARM926T - select HAVE_SCHED_CLOCK select HAVE_TCM select ARM_AMBA select ARM_PATCH_PHYS_VIRT @@ -933,7 +919,6 @@ config ARCH_DAVINCI select ARCH_REQUIRE_GPIOLIB select ZONE_DMA select HAVE_IDE - select HAVE_SCHED_CLOCK select CLKDEV_LOOKUP select GENERIC_ALLOCATOR select GENERIC_IRQ_CHIP @@ -948,7 +933,6 @@ config ARCH_OMAP select ARCH_HAS_CPUFREQ select CLKSRC_MMIO select GENERIC_CLOCKEVENTS - select HAVE_SCHED_CLOCK select ARCH_HAS_HOLES_MEMORYMODEL help Support for TI's OMAP platform (OMAP1/2/3/4). @@ -1114,13 +1098,11 @@ config ARCH_ACORN config PLAT_IOP bool select GENERIC_CLOCKEVENTS - select HAVE_SCHED_CLOCK config PLAT_ORION bool select CLKSRC_MMIO select GENERIC_IRQ_CHIP - select HAVE_SCHED_CLOCK config PLAT_PXA bool diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 43b740d0e37..9b0eb3febcb 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -14,8 +14,8 @@ CFLAGS_REMOVE_return_address.o = -pg # Object file lists. obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \ - process.o ptrace.o return_address.o setup.o signal.o \ - sys_arm.o stacktrace.o time.o traps.o + process.o ptrace.o return_address.o sched_clock.o \ + setup.o signal.o stacktrace.o sys_arm.o time.o traps.o obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o @@ -30,7 +30,6 @@ obj-$(CONFIG_ARTHUR) += arthur.o obj-$(CONFIG_ISA_DMA) += dma-isa.o obj-$(CONFIG_PCI) += bios32.o isa.o obj-$(CONFIG_ARM_CPU_SUSPEND) += sleep.o suspend.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 obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 8c57dd3680e..5bff28839cb 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -149,8 +149,6 @@ void __init time_init(void) { system_timer = machine_desc->timer; system_timer->init(); -#ifdef CONFIG_HAVE_SCHED_CLOCK sched_clock_postinit(); -#endif } diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig index bca4914b4b9..4c48c8b60b5 100644 --- a/arch/arm/plat-nomadik/Kconfig +++ b/arch/arm/plat-nomadik/Kconfig @@ -23,7 +23,6 @@ config HAS_MTU config NOMADIK_MTU_SCHED_CLOCK bool depends on HAS_MTU - select HAVE_SCHED_CLOCK help Use the Multi Timer Unit as the sched_clock. diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig index 52353beb369..c6f4b9625e7 100644 --- a/arch/arm/plat-versatile/Kconfig +++ b/arch/arm/plat-versatile/Kconfig @@ -12,6 +12,5 @@ config PLAT_VERSATILE_LEDS config PLAT_VERSATILE_SCHED_CLOCK def_bool y if !ARCH_INTEGRATOR_AP - select HAVE_SCHED_CLOCK endif -- cgit v1.2.3-18-g5258 From dc38d82676d87a21a0f924cb1728f869412749a9 Mon Sep 17 00:00:00 2001 From: Rob Herring <rob.herring@calxeda.com> Date: Thu, 23 Feb 2012 14:30:51 +0100 Subject: ARM: 7344/1: pxa: mainstone: add missing include for IRQ_BOARD_START As part of mach/irqs.h include removal from sparse, mainstone.h was missed. This fixes the compile of the pcmcia driver. Signed-off-by: Rob Herring <rob.herring@calxeda.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/mach-pxa/include/mach/mainstone.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mach-pxa/include/mach/mainstone.h b/arch/arm/mach-pxa/include/mach/mainstone.h index 4c2d11cd824..1bfc4e822a4 100644 --- a/arch/arm/mach-pxa/include/mach/mainstone.h +++ b/arch/arm/mach-pxa/include/mach/mainstone.h @@ -13,6 +13,8 @@ #ifndef ASM_ARCH_MAINSTONE_H #define ASM_ARCH_MAINSTONE_H +#include <mach/irqs.h> + #define MST_ETH_PHYS PXA_CS4_PHYS #define MST_FPGA_PHYS PXA_CS2_PHYS -- cgit v1.2.3-18-g5258 From f8e56c42e4e3527f629682ca123f881c1bea8500 Mon Sep 17 00:00:00 2001 From: Stephen Boyd <sboyd@codeaurora.org> Date: Wed, 22 Feb 2012 01:39:37 +0000 Subject: msm: timer: Support sched_clock() Now that sched_clock is mandatory on ARM it's simple to add sched_clock support to the MSM timer code. Add it so that we get more accurate sched_clock output than the jiffies based version that's provided by default. Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Acked-by: David Brown <davidb@codeaurora.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> --- arch/arm/mach-msm/timer.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 11d0d8f2656..61983daa7bb 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -24,6 +24,7 @@ #include <asm/mach/time.h> #include <asm/hardware/gic.h> #include <asm/localtimer.h> +#include <asm/sched_clock.h> #include <mach/msm_iomap.h> #include <mach/cpu.h> @@ -105,12 +106,12 @@ static union { static void __iomem *source_base; -static cycle_t msm_read_timer_count(struct clocksource *cs) +static notrace cycle_t msm_read_timer_count(struct clocksource *cs) { return readl_relaxed(source_base + TIMER_COUNT_VAL); } -static cycle_t msm_read_timer_count_shift(struct clocksource *cs) +static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs) { /* * Shift timer count down by a constant due to unreliable lower bits @@ -127,6 +128,11 @@ static struct clocksource msm_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +static notrace u32 msm_sched_clock_read(void) +{ + return msm_clocksource.read(&msm_clocksource); +} + static void __init msm_timer_init(void) { struct clock_event_device *ce = &msm_clockevent; @@ -189,6 +195,8 @@ err: res = clocksource_register_hz(cs, dgt_hz); if (res) pr_err("clocksource_register failed\n"); + setup_sched_clock(msm_sched_clock_read, + cpu_is_msm7x01() ? 32 - MSM_DGT_SHIFT : 32, dgt_hz); } #ifdef CONFIG_LOCAL_TIMERS -- cgit v1.2.3-18-g5258 From 149c24151e8577b2a033639722dc5734de5e6eaf Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Wed, 18 Jan 2012 15:59:45 +0000 Subject: ARM: SMP: use a timing out completion for cpu hotplug Rather than open-coding the jiffy-based wait, and polling for the secondary CPU to come online, use a completion instead. This removes the need to poll, instead we will be notified when the secondary CPU has initialized. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/kernel/smp.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 57db122a4f6..2b26dca2168 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -58,6 +58,8 @@ enum ipi_msg_type { IPI_CPU_STOP, }; +static DECLARE_COMPLETION(cpu_running); + int __cpuinit __cpu_up(unsigned int cpu) { struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); @@ -98,20 +100,12 @@ int __cpuinit __cpu_up(unsigned int cpu) */ ret = boot_secondary(cpu, idle); if (ret == 0) { - unsigned long timeout; - /* * CPU was successfully started, wait for it * to come online or time out. */ - timeout = jiffies + HZ; - while (time_before(jiffies, timeout)) { - if (cpu_online(cpu)) - break; - - udelay(10); - barrier(); - } + wait_for_completion_timeout(&cpu_running, + msecs_to_jiffies(1000)); if (!cpu_online(cpu)) { pr_crit("CPU%u: failed to come online\n", cpu); @@ -300,9 +294,10 @@ asmlinkage void __cpuinit secondary_start_kernel(void) /* * OK, now it's safe to let the boot CPU continue. Wait for * the CPU migration code to notice that the CPU is online - * before we continue. + * before we continue - which happens after __cpu_up returns. */ set_cpu_online(cpu, true); + complete(&cpu_running); /* * Setup the percpu timer for this CPU. -- cgit v1.2.3-18-g5258 From 195864cf3d6f5b6b743793bda3aaa2ff65d322ae Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Thu, 19 Jan 2012 10:05:41 +0000 Subject: ARM: move CP15 definitions to separate header file Avoid namespace conflicts with drivers over the CP15 definitions by moving CP15 related prototypes and definitions to a private header file. Acked-by: Stephen Warren <swarren@nvidia.com> Tested-by: Stephen Warren <swarren@nvidia.com> [Tegra] Acked-by: H Hartley Sweeten <hsweeten@visionengravers.com> Tested-by: H Hartley Sweeten <hsweeten@visionengravers.com> [EP93xx] Acked-by: Nicolas Pitre <nico@linaro.org> Acked-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/include/asm/cp15.h | 87 ++++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/system.h | 77 ----------------------------------- arch/arm/kernel/fiq.c | 2 +- arch/arm/kernel/head-nommu.S | 2 +- arch/arm/kernel/head.S | 2 +- arch/arm/kernel/setup.c | 2 +- arch/arm/mach-exynos/hotplug.c | 1 + arch/arm/mach-realview/hotplug.c | 1 + arch/arm/mach-tegra/hotplug.c | 1 + arch/arm/mach-vexpress/hotplug.c | 2 +- arch/arm/mm/alignment.c | 2 +- arch/arm/mm/cache-feroceon-l2.c | 1 + arch/arm/mm/cache-tauros2.c | 1 + arch/arm/mm/cache-xsc3l2.c | 2 +- arch/arm/mm/ioremap.c | 1 + arch/arm/mm/mmu.c | 1 + arch/arm/mm/pgd.c | 1 + arch/arm/vfp/vfpmodule.c | 1 + 18 files changed, 103 insertions(+), 84 deletions(-) create mode 100644 arch/arm/include/asm/cp15.h (limited to 'arch/arm') diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h new file mode 100644 index 00000000000..3dabd8dd404 --- /dev/null +++ b/arch/arm/include/asm/cp15.h @@ -0,0 +1,87 @@ +#ifndef __ASM_ARM_CP15_H +#define __ASM_ARM_CP15_H + +#include <asm/system.h> + +/* + * CR1 bits (CP#15 CR1) + */ +#define CR_M (1 << 0) /* MMU enable */ +#define CR_A (1 << 1) /* Alignment abort enable */ +#define CR_C (1 << 2) /* Dcache enable */ +#define CR_W (1 << 3) /* Write buffer enable */ +#define CR_P (1 << 4) /* 32-bit exception handler */ +#define CR_D (1 << 5) /* 32-bit data address range */ +#define CR_L (1 << 6) /* Implementation defined */ +#define CR_B (1 << 7) /* Big endian */ +#define CR_S (1 << 8) /* System MMU protection */ +#define CR_R (1 << 9) /* ROM MMU protection */ +#define CR_F (1 << 10) /* Implementation defined */ +#define CR_Z (1 << 11) /* Implementation defined */ +#define CR_I (1 << 12) /* Icache enable */ +#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ +#define CR_RR (1 << 14) /* Round Robin cache replacement */ +#define CR_L4 (1 << 15) /* LDR pc can set T bit */ +#define CR_DT (1 << 16) +#define CR_IT (1 << 18) +#define CR_ST (1 << 19) +#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ +#define CR_U (1 << 22) /* Unaligned access operation */ +#define CR_XP (1 << 23) /* Extended page tables */ +#define CR_VE (1 << 24) /* Vectored interrupts */ +#define CR_EE (1 << 25) /* Exception (Big) Endian */ +#define CR_TRE (1 << 28) /* TEX remap enable */ +#define CR_AFE (1 << 29) /* Access flag enable */ +#define CR_TE (1 << 30) /* Thumb exception enable */ + +#ifndef __ASSEMBLY__ + +#if __LINUX_ARM_ARCH__ >= 4 +#define vectors_high() (cr_alignment & CR_V) +#else +#define vectors_high() (0) +#endif + +extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ +extern unsigned long cr_alignment; /* defined in entry-armv.S */ + +static inline unsigned int get_cr(void) +{ + unsigned int val; + asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc"); + return val; +} + +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 +extern void adjust_cr(unsigned long mask, unsigned long set); +#endif + +#define CPACC_FULL(n) (3 << (n * 2)) +#define CPACC_SVC(n) (1 << (n * 2)) +#define CPACC_DISABLE(n) (0 << (n * 2)) + +static inline unsigned int get_copro_access(void) +{ + unsigned int val; + asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access" + : "=r" (val) : : "cc"); + return val; +} + +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(); +} + +#endif + +#endif diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index e4c96cc6ec0..774c41e8add 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -14,37 +14,6 @@ #define CPU_ARCH_ARMv6 8 #define CPU_ARCH_ARMv7 9 -/* - * CR1 bits (CP#15 CR1) - */ -#define CR_M (1 << 0) /* MMU enable */ -#define CR_A (1 << 1) /* Alignment abort enable */ -#define CR_C (1 << 2) /* Dcache enable */ -#define CR_W (1 << 3) /* Write buffer enable */ -#define CR_P (1 << 4) /* 32-bit exception handler */ -#define CR_D (1 << 5) /* 32-bit data address range */ -#define CR_L (1 << 6) /* Implementation defined */ -#define CR_B (1 << 7) /* Big endian */ -#define CR_S (1 << 8) /* System MMU protection */ -#define CR_R (1 << 9) /* ROM MMU protection */ -#define CR_F (1 << 10) /* Implementation defined */ -#define CR_Z (1 << 11) /* Implementation defined */ -#define CR_I (1 << 12) /* Icache enable */ -#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */ -#define CR_RR (1 << 14) /* Round Robin cache replacement */ -#define CR_L4 (1 << 15) /* LDR pc can set T bit */ -#define CR_DT (1 << 16) -#define CR_IT (1 << 18) -#define CR_ST (1 << 19) -#define CR_FI (1 << 21) /* Fast interrupt (lower latency mode) */ -#define CR_U (1 << 22) /* Unaligned access operation */ -#define CR_XP (1 << 23) /* Extended page tables */ -#define CR_VE (1 << 24) /* Vectored interrupts */ -#define CR_EE (1 << 25) /* Exception (Big) Endian */ -#define CR_TRE (1 << 28) /* TEX remap enable */ -#define CR_AFE (1 << 29) /* Access flag enable */ -#define CR_TE (1 << 30) /* Thumb exception enable */ - /* * This is used to ensure the compiler did actually allocate the register we * asked it for some inline assembly sequences. Apparently we can't trust @@ -119,12 +88,6 @@ extern void (*arm_pm_restart)(char str, const char *cmd); 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__ >= 7 || \ (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K)) #define sev() __asm__ __volatile__ ("sev" : : : "memory") @@ -185,46 +148,6 @@ extern unsigned int user_debug; #define set_mb(var, value) do { var = value; smp_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 */ - -static inline unsigned int get_cr(void) -{ - unsigned int val; - asm("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc"); - return val; -} - -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 -extern void adjust_cr(unsigned long mask, unsigned long set); -#endif - -#define CPACC_FULL(n) (3 << (n * 2)) -#define CPACC_SVC(n) (1 << (n * 2)) -#define CPACC_DISABLE(n) (0 << (n * 2)) - -static inline unsigned int get_copro_access(void) -{ - unsigned int val; - asm("mrc p15, 0, %0, c1, c0, 2 @ get copro access" - : "=r" (val) : : "cc"); - return val; -} - -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(); -} - /* * 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/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index 4c164ece589..c32f8456aa0 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -42,9 +42,9 @@ #include <linux/seq_file.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> #include <asm/fiq.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/traps.h> static unsigned long no_fiq_insn; diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index d46f25968be..278cfc144f4 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -17,8 +17,8 @@ #include <asm/assembler.h> #include <asm/ptrace.h> #include <asm/asm-offsets.h> +#include <asm/cp15.h> #include <asm/thread_info.h> -#include <asm/system.h> /* * Kernel startup entry point. diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 6d579114406..a2e9694a68e 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -15,12 +15,12 @@ #include <linux/init.h> #include <asm/assembler.h> +#include <asm/cp15.h> #include <asm/domain.h> #include <asm/ptrace.h> #include <asm/asm-offsets.h> #include <asm/memory.h> #include <asm/thread_info.h> -#include <asm/system.h> #include <asm/pgtable.h> #ifdef CONFIG_DEBUG_LL diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 9b65cb4589e..e5c37fc1d1d 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -34,6 +34,7 @@ #include <linux/sort.h> #include <asm/unified.h> +#include <asm/cp15.h> #include <asm/cpu.h> #include <asm/cputype.h> #include <asm/elf.h> @@ -45,7 +46,6 @@ #include <asm/cacheflush.h> #include <asm/cachetype.h> #include <asm/tlbflush.h> -#include <asm/system.h> #include <asm/prom.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-exynos/hotplug.c b/arch/arm/mach-exynos/hotplug.c index da70e7e3993..c9146fa7f22 100644 --- a/arch/arm/mach-exynos/hotplug.c +++ b/arch/arm/mach-exynos/hotplug.c @@ -16,6 +16,7 @@ #include <linux/io.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> #include <mach/regs-pmu.h> diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c index ac1aed2a8da..5e64fbf8d0e 100644 --- a/arch/arm/mach-realview/hotplug.c +++ b/arch/arm/mach-realview/hotplug.c @@ -13,6 +13,7 @@ #include <linux/smp.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> extern volatile int pen_release; diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c index f3294040d35..d8dc9ddd6d1 100644 --- a/arch/arm/mach-tegra/hotplug.c +++ b/arch/arm/mach-tegra/hotplug.c @@ -13,6 +13,7 @@ #include <linux/smp.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> static inline void cpu_enter_lowpower(void) { diff --git a/arch/arm/mach-vexpress/hotplug.c b/arch/arm/mach-vexpress/hotplug.c index 813ee08f96e..7a05548544c 100644 --- a/arch/arm/mach-vexpress/hotplug.c +++ b/arch/arm/mach-vexpress/hotplug.c @@ -13,7 +13,7 @@ #include <linux/smp.h> #include <asm/cacheflush.h> -#include <asm/system.h> +#include <asm/cp15.h> extern volatile int pen_release; diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index caf14dc059e..78459b8a2a1 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -22,7 +22,7 @@ #include <linux/sched.h> #include <linux/uaccess.h> -#include <asm/system.h> +#include <asm/cp15.h> #include <asm/unaligned.h> #include "fault.h" diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c index e0b0e7a4ec6..dd3d59122cc 100644 --- a/arch/arm/mm/cache-feroceon-l2.c +++ b/arch/arm/mm/cache-feroceon-l2.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/highmem.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> #include <plat/cache-feroceon-l2.h> /* diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c index 50868651890..1fbca05fe90 100644 --- a/arch/arm/mm/cache-tauros2.c +++ b/arch/arm/mm/cache-tauros2.c @@ -16,6 +16,7 @@ #include <linux/init.h> #include <asm/cacheflush.h> +#include <asm/cp15.h> #include <asm/hardware/cache-tauros2.h> diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c index 5a32020471e..6c3edeb66e7 100644 --- a/arch/arm/mm/cache-xsc3l2.c +++ b/arch/arm/mm/cache-xsc3l2.c @@ -18,7 +18,7 @@ */ #include <linux/init.h> #include <linux/highmem.h> -#include <asm/system.h> +#include <asm/cp15.h> #include <asm/cputype.h> #include <asm/cacheflush.h> diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 80632e8d753..66daf17b5e3 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -26,6 +26,7 @@ #include <linux/vmalloc.h> #include <linux/io.h> +#include <asm/cp15.h> #include <asm/cputype.h> #include <asm/cacheflush.h> #include <asm/mmu_context.h> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index c1263adc2a2..f77f1dbbdf5 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -17,6 +17,7 @@ #include <linux/fs.h> #include <linux/vmalloc.h> +#include <asm/cp15.h> #include <asm/cputype.h> #include <asm/sections.h> #include <asm/cachetype.h> diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index a3e78ccabd6..0acb089d0f7 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -12,6 +12,7 @@ #include <linux/highmem.h> #include <linux/slab.h> +#include <asm/cp15.h> #include <asm/pgalloc.h> #include <asm/page.h> #include <asm/tlbflush.h> diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 8f3ccddbdaf..d89068f6d6e 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -18,6 +18,7 @@ #include <linux/smp.h> #include <linux/init.h> +#include <asm/cp15.h> #include <asm/cputype.h> #include <asm/thread_notify.h> #include <asm/vfp.h> -- cgit v1.2.3-18-g5258 From f9d4861fc32b995b1616775614459b8f266c803c Mon Sep 17 00:00:00 2001 From: Will Deacon <will.deacon@arm.com> Date: Fri, 20 Jan 2012 12:01:13 +0100 Subject: ARM: 7294/1: vectors: use gate_vma for vectors user mapping The current user mapping for the vectors page is inserted as a `horrible hack vma' into each task via arch_setup_additional_pages. This causes problems with the MM subsystem and vm_normal_page, as described here: https://lkml.org/lkml/2012/1/14/55 Following the suggestion from Hugh in the above thread, this patch uses the gate_vma for the vectors user mapping, therefore consolidating the horrible hack VMAs into one. Acked-and-Tested-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/include/asm/elf.h | 4 ---- arch/arm/include/asm/mmu_context.h | 29 +---------------------------- arch/arm/include/asm/page.h | 2 ++ arch/arm/kernel/process.c | 38 ++++++++++++++++++++++++++++---------- 4 files changed, 31 insertions(+), 42 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h index 0e9ce8d9686..38050b1c480 100644 --- a/arch/arm/include/asm/elf.h +++ b/arch/arm/include/asm/elf.h @@ -130,8 +130,4 @@ struct mm_struct; extern unsigned long arch_randomize_brk(struct mm_struct *mm); #define arch_randomize_brk arch_randomize_brk -extern int vectors_user_mapping(void); -#define arch_setup_additional_pages(bprm, uses_interp) vectors_user_mapping() -#define ARCH_HAS_SETUP_ADDITIONAL_PAGES - #endif diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h index 71605d9f8e4..a0b3cac0547 100644 --- a/arch/arm/include/asm/mmu_context.h +++ b/arch/arm/include/asm/mmu_context.h @@ -18,6 +18,7 @@ #include <asm/cacheflush.h> #include <asm/cachetype.h> #include <asm/proc-fns.h> +#include <asm-generic/mm_hooks.h> void __check_kvm_seq(struct mm_struct *mm); @@ -133,32 +134,4 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, #define deactivate_mm(tsk,mm) do { } while (0) #define activate_mm(prev,next) switch_mm(prev, next, NULL) -/* - * We are inserting a "fake" vma for the user-accessible vector page so - * gdb and friends can get to it through ptrace and /proc/<pid>/mem. - * But we also want to remove it before the generic code gets to see it - * during process exit or the unmapping of it would cause total havoc. - * (the macro is used as remove_vma() is static to mm/mmap.c) - */ -#define arch_exit_mmap(mm) \ -do { \ - struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \ - if (high_vma) { \ - BUG_ON(high_vma->vm_next); /* it should be last */ \ - if (high_vma->vm_prev) \ - high_vma->vm_prev->vm_next = NULL; \ - else \ - mm->mmap = NULL; \ - rb_erase(&high_vma->vm_rb, &mm->mm_rb); \ - mm->mmap_cache = NULL; \ - mm->map_count--; \ - remove_vma(high_vma); \ - } \ -} while (0) - -static inline void arch_dup_mmap(struct mm_struct *oldmm, - struct mm_struct *mm) -{ -} - #endif diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h index 97b440c25c5..5838361c48b 100644 --- a/arch/arm/include/asm/page.h +++ b/arch/arm/include/asm/page.h @@ -151,6 +151,8 @@ extern void __cpu_copy_user_highpage(struct page *to, struct page *from, #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) extern void copy_page(void *to, const void *from); +#define __HAVE_ARCH_GATE_AREA 1 + #ifdef CONFIG_ARM_LPAE #include <asm/pgtable-3level-types.h> #else diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 971d65c253a..e11b523db33 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -526,22 +526,40 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) #ifdef CONFIG_MMU /* * The vectors page is always readable from user space for the - * atomic helpers and the signal restart code. Let's declare a mapping - * for it so it is visible through ptrace and /proc/<pid>/mem. + * atomic helpers and the signal restart code. Insert it into the + * gate_vma so that it is visible through ptrace and /proc/<pid>/mem. */ +static struct vm_area_struct gate_vma; -int vectors_user_mapping(void) +static int __init gate_vma_init(void) { - struct mm_struct *mm = current->mm; - return install_special_mapping(mm, 0xffff0000, PAGE_SIZE, - VM_READ | VM_EXEC | - VM_MAYREAD | VM_MAYEXEC | - VM_ALWAYSDUMP | VM_RESERVED, - NULL); + gate_vma.vm_start = 0xffff0000; + gate_vma.vm_end = 0xffff0000 + PAGE_SIZE; + gate_vma.vm_page_prot = PAGE_READONLY_EXEC; + gate_vma.vm_flags = VM_READ | VM_EXEC | + VM_MAYREAD | VM_MAYEXEC | + VM_ALWAYSDUMP; + return 0; +} +arch_initcall(gate_vma_init); + +struct vm_area_struct *get_gate_vma(struct mm_struct *mm) +{ + return &gate_vma; +} + +int in_gate_area(struct mm_struct *mm, unsigned long addr) +{ + return (addr >= gate_vma.vm_start) && (addr < gate_vma.vm_end); +} + +int in_gate_area_no_mm(unsigned long addr) +{ + return in_gate_area(NULL, addr); } const char *arch_vma_name(struct vm_area_struct *vma) { - return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL; + return (vma == &gate_vma) ? "[vectors]" : NULL; } #endif -- cgit v1.2.3-18-g5258 From a9d6d15131b0519363b0c94734ee80955c411093 Mon Sep 17 00:00:00 2001 From: Linus Walleij <linus.walleij@linaro.org> Date: Tue, 31 Jan 2012 23:38:23 +0100 Subject: ARM: 7310/1: integrator: implement sched_clock across all boards Now that we can select a sched_clock at runtime, let's implement it for the Integrator AP, default-select the one found in all other board it for all plat-versatile boards and make the right clock kick in at runtime. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/mach-integrator/Kconfig | 1 + arch/arm/mach-integrator/integrator_ap.c | 7 +++++++ arch/arm/plat-versatile/Kconfig | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-integrator/Kconfig b/arch/arm/mach-integrator/Kconfig index 350e26636a0..5a6148ab6da 100644 --- a/arch/arm/mach-integrator/Kconfig +++ b/arch/arm/mach-integrator/Kconfig @@ -5,6 +5,7 @@ menu "Integrator Options" config ARCH_INTEGRATOR_AP bool "Support Integrator/AP and Integrator/PP2 platforms" select CLKSRC_MMIO + select HAVE_SCHED_CLOCK select MIGHT_HAVE_PCI select SERIAL_AMBA_PL010 select SERIAL_AMBA_PL010_CONSOLE diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 21a1d6cbef4..4dde28b9dc0 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -42,6 +42,7 @@ #include <asm/setup.h> #include <asm/param.h> /* HZ */ #include <asm/mach-types.h> +#include <asm/sched_clock.h> #include <mach/lm.h> @@ -325,6 +326,11 @@ static void __init ap_init(void) static unsigned long timer_reload; +static u32 notrace integrator_read_sched_clock(void) +{ + return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE); +} + static void integrator_clocksource_init(unsigned long inrate) { void __iomem *base = (void __iomem *)TIMER2_VA_BASE; @@ -341,6 +347,7 @@ static void integrator_clocksource_init(unsigned long inrate) clocksource_mmio_init(base + TIMER_VALUE, "timer2", rate, 200, 16, clocksource_mmio_readl_down); + setup_sched_clock(integrator_read_sched_clock, 16, rate); } static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig index 52353beb369..aa63f38f284 100644 --- a/arch/arm/plat-versatile/Kconfig +++ b/arch/arm/plat-versatile/Kconfig @@ -11,7 +11,7 @@ config PLAT_VERSATILE_LEDS depends on ARCH_REALVIEW || ARCH_VERSATILE config PLAT_VERSATILE_SCHED_CLOCK - def_bool y if !ARCH_INTEGRATOR_AP + def_bool y select HAVE_SCHED_CLOCK endif -- cgit v1.2.3-18-g5258 From f5f5195487affe53f90d99cba4aee73a20cae565 Mon Sep 17 00:00:00 2001 From: Dave Martin <dave.martin@linaro.org> Date: Wed, 1 Feb 2012 10:42:22 +0100 Subject: ARM: 7311/1: Add generic instruction opcode manipulation helpers This patch adds some endianness-agnostic helpers to convert machine instructions between canonical integer form and in-memory representation. A canonical integer form for representing instructions is also formalised here. Signed-off-by: Dave Martin <dave.martin@linaro.org> Acked-by: Nicolas Pitre <nico@linaro.org> Tested-by: Jon Medhurst <tixy@yxit.co.uk> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/include/asm/opcodes.h | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h index c0efdd60966..19c48deda70 100644 --- a/arch/arm/include/asm/opcodes.h +++ b/arch/arm/include/asm/opcodes.h @@ -17,4 +17,63 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); #define ARM_OPCODE_CONDTEST_PASS 1 #define ARM_OPCODE_CONDTEST_UNCOND 2 + +/* + * Opcode byteswap helpers + * + * These macros help with converting instructions between a canonical integer + * format and in-memory representation, in an endianness-agnostic manner. + * + * __mem_to_opcode_*() convert from in-memory representation to canonical form. + * __opcode_to_mem_*() convert from canonical form to in-memory representation. + * + * + * Canonical instruction representation: + * + * ARM: 0xKKLLMMNN + * Thumb 16-bit: 0x0000KKLL, where KK < 0xE8 + * Thumb 32-bit: 0xKKLLMMNN, where KK >= 0xE8 + * + * There is no way to distinguish an ARM instruction in canonical representation + * from a Thumb instruction (just as these cannot be distinguished in memory). + * Where this distinction is important, it needs to be tracked separately. + * + * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not + * represent any valid Thumb-2 instruction. For this range, + * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false. + */ + +#ifndef __ASSEMBLY__ + +#include <linux/types.h> +#include <linux/swab.h> + +#ifdef CONFIG_CPU_ENDIAN_BE8 +#define __opcode_to_mem_arm(x) swab32(x) +#define __opcode_to_mem_thumb16(x) swab16(x) +#define __opcode_to_mem_thumb32(x) swahb32(x) +#else +#define __opcode_to_mem_arm(x) ((u32)(x)) +#define __opcode_to_mem_thumb16(x) ((u16)(x)) +#define __opcode_to_mem_thumb32(x) swahw32(x) +#endif + +#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x) +#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x) +#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x) + +/* Operations specific to Thumb opcodes */ + +/* Instruction size checks: */ +#define __opcode_is_thumb32(x) ((u32)(x) >= 0xE8000000UL) +#define __opcode_is_thumb16(x) ((u32)(x) < 0xE800UL) + +/* Operations to construct or split 32-bit Thumb instructions: */ +#define __opcode_thumb32_first(x) ((u16)((x) >> 16)) +#define __opcode_thumb32_second(x) ((u16)(x)) +#define __opcode_thumb32_compose(first, second) \ + (((u32)(u16)(first) << 16) | (u32)(u16)(second)) + +#endif /* __ASSEMBLY__ */ + #endif /* __ASM_ARM_OPCODES_H */ -- cgit v1.2.3-18-g5258 From a7f464f3db93ae5492bee6f6e48939fd8a45fa99 Mon Sep 17 00:00:00 2001 From: Imre Kaloz <kaloz@openwrt.org> Date: Thu, 26 Jan 2012 13:08:57 +0100 Subject: ARM: 7001/2: Wire up support for the XZ decompressor Wire up support for the XZ decompressor Signed-off-by: Imre Kaloz <kaloz@openwrt.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/Kconfig | 1 + arch/arm/boot/compressed/.gitignore | 2 ++ arch/arm/boot/compressed/Makefile | 15 ++++++++++++--- arch/arm/boot/compressed/decompress.c | 6 ++++++ arch/arm/boot/compressed/piggy.xzkern.S | 6 ++++++ 5 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 arch/arm/boot/compressed/piggy.xzkern.S (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 24626b0419e..385a3861a02 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -21,6 +21,7 @@ config ARM select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZO select HAVE_KERNEL_LZMA + select HAVE_KERNEL_XZ select HAVE_IRQ_WORK select HAVE_PERF_EVENTS select PERF_USE_VMALLOC diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore index e0936a14851..d0d441c429a 100644 --- a/arch/arm/boot/compressed/.gitignore +++ b/arch/arm/boot/compressed/.gitignore @@ -1,8 +1,10 @@ +ashldi3.S font.c lib1funcs.S piggy.gzip piggy.lzo piggy.lzma +piggy.xzkern vmlinux vmlinux.lds diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index cf0a64ce4b8..bb267562e7e 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -92,6 +92,7 @@ SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ suffix_$(CONFIG_KERNEL_GZIP) = gzip suffix_$(CONFIG_KERNEL_LZO) = lzo suffix_$(CONFIG_KERNEL_LZMA) = lzma +suffix_$(CONFIG_KERNEL_XZ) = xzkern # Borrowed libfdt files for the ATAG compatibility mode @@ -112,10 +113,12 @@ endif targets := vmlinux vmlinux.lds \ piggy.$(suffix_y) piggy.$(suffix_y).o \ - lib1funcs.o lib1funcs.S font.o font.c head.o misc.o $(OBJS) + lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S \ + font.o font.c head.o misc.o $(OBJS) # Make sure files are removed during clean -extra-y += piggy.gzip piggy.lzo piggy.lzma lib1funcs.S $(libfdt) $(libfdt_hdrs) +extra-y += piggy.gzip piggy.lzo piggy.lzma piggy.xzkern \ + lib1funcs.S ashldi3.S $(libfdt) $(libfdt_hdrs) ifeq ($(CONFIG_FUNCTION_TRACER),y) ORIG_CFLAGS := $(KBUILD_CFLAGS) @@ -151,6 +154,12 @@ lib1funcs = $(obj)/lib1funcs.o $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S $(call cmd,shipped) +# For __aeabi_llsl +ashldi3 = $(obj)/ashldi3.o + +$(obj)/ashldi3.S: $(srctree)/arch/$(SRCARCH)/lib/ashldi3.S + $(call cmd,shipped) + # We need to prevent any GOTOFF relocs being used with references # to symbols in the .bss section since we cannot relocate them # independently from the rest at run time. This can be achieved by @@ -172,7 +181,7 @@ if [ $(words $(ZRELADDR)) -gt 1 -a "$(CONFIG_AUTO_ZRELADDR)" = "" ]; then \ fi $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \ - $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE + $(addprefix $(obj)/, $(OBJS)) $(lib1funcs) $(ashldi3) FORCE @$(check_for_multiple_zreladdr) $(call if_changed,ld) @$(check_for_bad_syms) diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c index 07be5a2f830..f41b38cafce 100644 --- a/arch/arm/boot/compressed/decompress.c +++ b/arch/arm/boot/compressed/decompress.c @@ -44,6 +44,12 @@ extern void error(char *); #include "../../../../lib/decompress_unlzma.c" #endif +#ifdef CONFIG_KERNEL_XZ +#define memmove memmove +#define memcpy memcpy +#include "../../../../lib/decompress_unxz.c" +#endif + int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x)) { return decompress(input, len, NULL, NULL, output, NULL, error); diff --git a/arch/arm/boot/compressed/piggy.xzkern.S b/arch/arm/boot/compressed/piggy.xzkern.S new file mode 100644 index 00000000000..5703f300d02 --- /dev/null +++ b/arch/arm/boot/compressed/piggy.xzkern.S @@ -0,0 +1,6 @@ + .section .piggydata,#alloc + .globl input_data +input_data: + .incbin "arch/arm/boot/compressed/piggy.xzkern" + .globl input_data_end +input_data_end: -- cgit v1.2.3-18-g5258 From d9277d51a8eeaa097d3c1385f458c99d65ffc4f4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Date: Wed, 1 Feb 2012 11:16:51 +0100 Subject: ARM: 7312/1: only show modules in the memory layout for MODULES=y MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This line is irritating and wrong when modules are not supported, so don't show it then. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Acked-by: Nicolas Pitre <nico@linaro.org> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/mm/init.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 6ec1226fc62..42d906f8996 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -659,7 +659,9 @@ void __init mem_init(void) #ifdef CONFIG_HIGHMEM " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n" #endif +#ifdef CONFIG_MODULES " modules : 0x%08lx - 0x%08lx (%4ld MB)\n" +#endif " .text : 0x%p" " - 0x%p" " (%4d kB)\n" " .init : 0x%p" " - 0x%p" " (%4d kB)\n" " .data : 0x%p" " - 0x%p" " (%4d kB)\n" @@ -678,7 +680,9 @@ void __init mem_init(void) MLM(PKMAP_BASE, (PKMAP_BASE) + (LAST_PKMAP) * (PAGE_SIZE)), #endif +#ifdef CONFIG_MODULES MLM(MODULES_VADDR, MODULES_END), +#endif MLK_ROUNDUP(_text, _etext), MLK_ROUNDUP(__init_begin, __init_end), -- cgit v1.2.3-18-g5258 From 87067a935a174cf5e0b336d338a0ab535ffe199d Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Sat, 4 Feb 2012 10:55:38 +0000 Subject: ARM: Optimize multi-CPU tlb flushing a little more The compiler does not conditionalize the assembly instructions for the tlb operations, which leads to sub-optimal code being generated when building a kernel for multiple CPUs. We can tweak things fairly simply as the code fragment below shows: 17f8: e3120001 tst r2, #1 ; 0x1 ... 1800: 0a000000 beq 1808 <handle_pte_fault+0x194> 1804: ee061f10 mcr 15, 0, r1, cr6, cr0, {0} 1808: e3120004 tst r2, #4 ; 0x4 180c: 0a000000 beq 1814 <handle_pte_fault+0x1a0> 1810: ee081f36 mcr 15, 0, r1, cr8, cr6, {1} becomes: 17f0: e3120001 tst r2, #1 ; 0x1 17f4: 1e063f10 mcrne 15, 0, r3, cr6, cr0, {0} 17f8: e3120004 tst r2, #4 ; 0x4 17fc: 1e083f36 mcrne 15, 0, r3, cr8, cr6, {1} Overall, for Realview with V6 and V7 CPUs configured: text data bss dec hex filename 4153998 207340 5371036 9732374 948116 ../build/realview/vmlinux.before 4153366 207332 5371036 9731734 947e96 ../build/realview/vmlinux.after Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/include/asm/tlbflush.h | 136 +++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 78 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index 02b2f820398..85fe61e7320 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h @@ -318,6 +318,21 @@ extern struct cpu_tlb_fns cpu_tlb; #define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) +#define __tlb_op(f, insnarg, arg) \ + do { \ + if (always_tlb_flags & (f)) \ + asm("mcr " insnarg \ + : : "r" (arg) : "cc"); \ + else if (possible_tlb_flags & (f)) \ + asm("tst %1, %2\n\t" \ + "mcrne " insnarg \ + : : "r" (arg), "r" (__tlb_flag), "Ir" (f) \ + : "cc"); \ + } while (0) + +#define tlb_op(f, regs, arg) __tlb_op(f, "p15, 0, %0, " regs, arg) +#define tlb_l2_op(f, regs, arg) __tlb_op(f, "p15, 1, %0, " regs, arg) + static inline void local_flush_tlb_all(void) { const int zero = 0; @@ -326,16 +341,11 @@ static inline void local_flush_tlb_all(void) if (tlb_flag(TLB_WB)) dsb(); - if (tlb_flag(TLB_V3_FULL)) - asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL)) - asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL)) - 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_V7_UIS_FULL)) - asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); + tlb_op(TLB_V3_FULL, "c6, c0, 0", zero); + tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero); + tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero); + tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero); + tlb_op(TLB_V7_UIS_FULL, "c8, c3, 0", zero); if (tlb_flag(TLB_BARRIER)) { dsb(); @@ -352,29 +362,23 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) if (tlb_flag(TLB_WB)) dsb(); - if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { - if (tlb_flag(TLB_V3_FULL)) - asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_U_FULL)) - asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_D_FULL)) - asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V4_I_FULL)) - asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); + if (possible_tlb_flags & (TLB_V3_FULL|TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { + if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { + tlb_op(TLB_V3_FULL, "c6, c0, 0", zero); + tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero); + tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero); + tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero); + } + put_cpu(); } - put_cpu(); - - if (tlb_flag(TLB_V6_U_ASID)) - asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc"); - if (tlb_flag(TLB_V6_D_ASID)) - 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_V7_UIS_ASID)) + + tlb_op(TLB_V6_U_ASID, "c8, c7, 2", asid); + tlb_op(TLB_V6_D_ASID, "c8, c6, 2", asid); + tlb_op(TLB_V6_I_ASID, "c8, c5, 2", asid); #ifdef CONFIG_ARM_ERRATA_720789 - asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); + tlb_op(TLB_V7_UIS_ASID, "c8, c3, 0", zero); #else - asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc"); + tlb_op(TLB_V7_UIS_ASID, "c8, c3, 2", asid); #endif if (tlb_flag(TLB_BARRIER)) @@ -392,30 +396,23 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) if (tlb_flag(TLB_WB)) dsb(); - if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { - if (tlb_flag(TLB_V3_PAGE)) - asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc"); - if (tlb_flag(TLB_V4_U_PAGE)) - asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); - if (tlb_flag(TLB_V4_D_PAGE)) - asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); - if (tlb_flag(TLB_V4_I_PAGE)) - asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); + if (possible_tlb_flags & (TLB_V3_PAGE|TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && + cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { + tlb_op(TLB_V3_PAGE, "c6, c0, 0", uaddr); + tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr); + tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr); + tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr); if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); } - if (tlb_flag(TLB_V6_U_PAGE)) - asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); - if (tlb_flag(TLB_V6_D_PAGE)) - 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_V7_UIS_PAGE)) + tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", uaddr); + tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", uaddr); + tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", uaddr); #ifdef CONFIG_ARM_ERRATA_720789 - asm("mcr p15, 0, %0, c8, c3, 3" : : "r" (uaddr & PAGE_MASK) : "cc"); + tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 3", uaddr & PAGE_MASK); #else - asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc"); + tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", uaddr); #endif if (tlb_flag(TLB_BARRIER)) @@ -432,25 +429,17 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) if (tlb_flag(TLB_WB)) dsb(); - if (tlb_flag(TLB_V3_PAGE)) - asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V4_U_PAGE)) - asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V4_D_PAGE)) - asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V4_I_PAGE)) - asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); + tlb_op(TLB_V3_PAGE, "c6, c0, 0", kaddr); + tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr); + tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr); + tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr); if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); - if (tlb_flag(TLB_V6_U_PAGE)) - asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V6_D_PAGE)) - asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V6_I_PAGE)) - asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); - if (tlb_flag(TLB_V7_UIS_PAGE)) - asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc"); + tlb_op(TLB_V6_U_PAGE, "c8, c7, 1", kaddr); + tlb_op(TLB_V6_D_PAGE, "c8, c6, 1", kaddr); + tlb_op(TLB_V6_I_PAGE, "c8, c5, 1", kaddr); + tlb_op(TLB_V7_UIS_PAGE, "c8, c3, 1", kaddr); if (tlb_flag(TLB_BARRIER)) { dsb(); @@ -475,13 +464,8 @@ static inline void flush_pmd_entry(void *pmd) { 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_L2CLEAN_FR)) - asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd" - : : "r" (pmd) : "cc"); + tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd); + tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd); if (tlb_flag(TLB_WB)) dsb(); @@ -491,15 +475,11 @@ static inline void clean_pmd_entry(void *pmd) { 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_L2CLEAN_FR)) - asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd" - : : "r" (pmd) : "cc"); + tlb_op(TLB_DCLEAN, "c7, c10, 1 @ flush_pmd", pmd); + tlb_l2_op(TLB_L2CLEAN_FR, "c15, c9, 1 @ L2 flush_pmd", pmd); } +#undef tlb_op #undef tlb_flag #undef always_tlb_flags #undef possible_tlb_flags -- cgit v1.2.3-18-g5258 From 8211ca658728d03ba331de0276950289e52a1b0f Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Sat, 4 Feb 2012 12:12:11 +0000 Subject: ARM: Add compiled ISA to oops dumps Add the compiled ISA to oops dumps, along side the preempt/smp configuration. This allows us to see immediately whether the kernel was compiled for Thumb-2 or not. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/kernel/traps.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index be15dafaa88..23377a3bf50 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -227,6 +227,11 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) #else #define S_SMP "" #endif +#ifdef CONFIG_THUMB2_KERNEL +#define S_ISA " THUMB2" +#else +#define S_ISA " ARM" +#endif static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs) { @@ -234,8 +239,8 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt static int die_counter; int ret; - printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n", - str, err, ++die_counter); + printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP + S_ISA "\n", str, err, ++die_counter); /* trap and error numbers are mostly meaningless on ARM */ ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); -- cgit v1.2.3-18-g5258 From f153d017ab70d2954f5456278f3cbc39e6e060f3 Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Sat, 4 Feb 2012 12:31:27 +0000 Subject: ARM: sync sched_clock() state on suspend Ensure that the software state for sched_clock() is updated at the point of suspend so that we avoid losing ticks since the last update. This prevents the platform dependent possibility that sched_clock() may appear to go backwards across a suspend/resume cycle. Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/kernel/sched_clock.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c index 5416c7c1252..27d186abbc0 100644 --- a/arch/arm/kernel/sched_clock.c +++ b/arch/arm/kernel/sched_clock.c @@ -10,6 +10,7 @@ #include <linux/jiffies.h> #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/syscore_ops.h> #include <linux/timer.h> #include <asm/sched_clock.h> @@ -164,3 +165,20 @@ void __init sched_clock_postinit(void) sched_clock_poll(sched_clock_timer.data); } + +static int sched_clock_suspend(void) +{ + sched_clock_poll(sched_clock_timer.data); + return 0; +} + +static struct syscore_ops sched_clock_ops = { + .suspend = sched_clock_suspend, +}; + +static int __init sched_clock_syscore_init(void) +{ + register_syscore_ops(&sched_clock_ops); + return 0; +} +device_initcall(sched_clock_syscore_init); -- cgit v1.2.3-18-g5258 From d33c88c659d708e7c5d518a05ef9349a36217bb2 Mon Sep 17 00:00:00 2001 From: Will Deacon <will.deacon@arm.com> Date: Fri, 3 Feb 2012 14:46:01 +0100 Subject: ARM: 7315/1: perf: add support for the Cortex-A7 PMU Cortex-A7 implements an ARMv7-compatible PMU compliant with the PMUv2 architecture specification. This patch adds support for the PMU to the ARM perf backend. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/include/asm/perf_event.h | 1 + arch/arm/kernel/perf_event.c | 3 + arch/arm/kernel/perf_event_v7.c | 145 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h index 99cfe360798..ee7c056be3f 100644 --- a/arch/arm/include/asm/perf_event.h +++ b/arch/arm/include/asm/perf_event.h @@ -26,6 +26,7 @@ enum arm_perf_pmu_ids { ARM_PERF_PMU_ID_CA9, ARM_PERF_PMU_ID_CA5, ARM_PERF_PMU_ID_CA15, + ARM_PERF_PMU_ID_CA7, ARM_NUM_PMU_IDS, }; diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 5bb91bf3d47..ab59c3bae5e 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c @@ -712,6 +712,9 @@ init_hw_perf_events(void) case 0xC0F0: /* Cortex-A15 */ cpu_pmu = armv7_a15_pmu_init(); break; + case 0xC070: /* Cortex-A7 */ + cpu_pmu = armv7_a7_pmu_init(); + break; } /* Intel CPUs [xscale]. */ } else if (0x69 == implementor) { diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 460bbbb6b88..b2b764ec011 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -581,6 +581,130 @@ static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] }, }; +/* + * Cortex-A7 HW events mapping + */ +static const unsigned armv7_a7_perf_map[PERF_COUNT_HW_MAX] = { + [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES, + [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED, + [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, + [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE, + [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES, + [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED, + [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED, +}; + +static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX] + [PERF_COUNT_HW_CACHE_OP_MAX] + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { + [C(L1D)] = { + /* + * The performance counters don't differentiate between read + * and write accesses/misses so this isn't strictly correct, + * but it's the best we can do. Writes and reads get + * combined. + */ + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(L1I)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(LL)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_CACHE_ACCESS, + [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(DTLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(ITLB)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(BPU)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED, + [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, + [C(NODE)] = { + [C(OP_READ)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_WRITE)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + [C(OP_PREFETCH)] = { + [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED, + [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED, + }, + }, +}; + /* * Perf Events' indices */ @@ -1067,6 +1191,12 @@ static int armv7_a15_map_event(struct perf_event *event) &armv7_a15_perf_cache_map, 0xFF); } +static int armv7_a7_map_event(struct perf_event *event) +{ + return map_cpu_event(event, &armv7_a7_perf_map, + &armv7_a7_perf_cache_map, 0xFF); +} + static struct arm_pmu armv7pmu = { .handle_irq = armv7pmu_handle_irq, .enable = armv7pmu_enable_event, @@ -1127,6 +1257,16 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void) armv7pmu.set_event_filter = armv7pmu_set_event_filter; return &armv7pmu; } + +static struct arm_pmu *__init armv7_a7_pmu_init(void) +{ + armv7pmu.id = ARM_PERF_PMU_ID_CA7; + armv7pmu.name = "ARMv7 Cortex-A7"; + armv7pmu.map_event = armv7_a7_map_event; + armv7pmu.num_events = armv7_read_num_pmnc_events(); + armv7pmu.set_event_filter = armv7pmu_set_event_filter; + return &armv7pmu; +} #else static struct arm_pmu *__init armv7_a8_pmu_init(void) { @@ -1147,4 +1287,9 @@ static struct arm_pmu *__init armv7_a15_pmu_init(void) { return NULL; } + +static struct arm_pmu *__init armv7_a7_pmu_init(void) +{ + return NULL; +} #endif /* CONFIG_CPU_V7 */ -- cgit v1.2.3-18-g5258 From 342d00ae2b85af003f11036484a33e12e906fe92 Mon Sep 17 00:00:00 2001 From: Will Deacon <will.deacon@arm.com> Date: Fri, 3 Feb 2012 14:50:07 +0100 Subject: ARM: 7317/1: irq: avoid NULL check in for_each_irq_desc loop ARM unconditionally selects CONFIG_GENERIC_HARDIRQS, so the definition of for_each_irq_desc will check that the desc is non-NULL anyway. This patch removes a redundant check from the IRQ migration code. Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/kernel/irq.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 3efd82cc95f..3f86ee11f54 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -181,10 +181,7 @@ void migrate_irqs(void) local_irq_save(flags); for_each_irq_desc(i, desc) { - bool affinity_broken = false; - - if (!desc) - continue; + bool affinity_broken; raw_spin_lock(&desc->lock); affinity_broken = migrate_one_irq(desc); -- cgit v1.2.3-18-g5258 From e0b823e9a543527dbb0f806252ee03a60f2aefbc Mon Sep 17 00:00:00 2001 From: Will Deacon <will.deacon@arm.com> Date: Fri, 3 Feb 2012 14:52:14 +0100 Subject: ARM: 7318/1: gic: refactor irq_start assignment The irq_start and hwirq_base assignment code is fairly hairy and ended up being difficult to read following a conflict resolution for 3.2. This patch rearranges the code slightly to make it easier to read. Cc: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/common/gic.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index b2dc2dd7f1d..a3bc86fa315 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -697,13 +697,12 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, * For primary GICs, skip over SGIs. * For secondary GICs, skip over PPIs, too. */ - domain->hwirq_base = 32; - if (gic_nr == 0) { - if ((irq_start & 31) > 0) { - domain->hwirq_base = 16; - if (irq_start != -1) - irq_start = (irq_start & ~31) + 16; - } + if (gic_nr == 0 && (irq_start & 31) > 0) { + domain->hwirq_base = 16; + if (irq_start != -1) + irq_start = (irq_start & ~31) + 16; + } else { + domain->hwirq_base = 32; } /* -- cgit v1.2.3-18-g5258 From f5274c2d0d8d91076af8605187d762dfa0b92825 Mon Sep 17 00:00:00 2001 From: Javi Merino <javi.merino@arm.com> Date: Mon, 6 Feb 2012 15:45:36 +0100 Subject: ARM: 7319/1: Print debug info for SIGBUS in user faults Print debug information on user faults for SIGBUS if user_debug = 16 in the kernel command line. Reference: <1327333344-26340-1-git-send-email-javi.merino@arm.com> Signed-off-by: Javi Merino <javi.merino@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/mm/fault.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index bb7eac381a8..40c43a94ba7 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -164,7 +164,8 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, struct siginfo si; #ifdef CONFIG_DEBUG_USER - if (user_debug & UDBG_SEGV) { + if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) || + ((user_debug & UDBG_BUS) && (sig == SIGBUS))) { printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n", tsk->comm, sig, addr, fsr); show_pte(tsk->mm, addr); -- cgit v1.2.3-18-g5258 From 5936d1161ff503a1170722fe9b2d9ac4da700eef Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Thu, 9 Feb 2012 16:16:28 +0000 Subject: ARM: get rid of asm/irq.h in asm/prom.h Avoid potential build problems caused by lacking mach/irqs.h includes on non-OF builds caused by an errant include in asm/prom.h. asm/prom.h requires nothing from asm/irq.h, as Grant says: On Mon, Feb 06, 2012 at 05:56:23AM +0000, Grant Likely wrote: > On Sat, Feb 04, 2012 at 10:17:48PM +0000, Russell King wrote: > > Finally, do we need asm/irq.h in our asm/prom.h ? That's causing > > fragility between DT and non-DT builds, because people are finding > > that their DT builds work without their mach/irqs.h includes but > > fail when built with non-DT. The only thing which DT might need - > > at the most - is NR_IRQS, but I'd hope with things like irq domains > > it doesn't actually require it. > > I don't think so. There may be a file or two that break because they're > not including everything they need, but I don't think anything in the > header requires it. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/include/asm/prom.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h index ee036330791..aeae9c609df 100644 --- a/arch/arm/include/asm/prom.h +++ b/arch/arm/include/asm/prom.h @@ -13,8 +13,6 @@ #ifdef CONFIG_OF -#include <asm/irq.h> - extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys); extern void arm_dt_memblock_reserve(void); -- cgit v1.2.3-18-g5258 From ba81f502e73cee92964af6c39eb8c8d7e44e38c1 Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Wed, 15 Feb 2012 11:55:22 +0000 Subject: ARM: Versatile Express: add NO_IOPORT On Versatile Express, the PCI Express buses are broken and unusable, so we aren't going to support PCI/ISA IO cycles on this platform. Remove the PCI/ISA IO inb et.al. support for this platform. Acked-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/Kconfig | 1 + arch/arm/mach-vexpress/include/mach/io.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 385a3861a02..6b5f84887ce 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -313,6 +313,7 @@ config ARCH_VEXPRESS select HAVE_CLK select HAVE_PATA_PLATFORM select ICST + select NO_IOPORT select PLAT_VERSATILE select PLAT_VERSATILE_CLCD help diff --git a/arch/arm/mach-vexpress/include/mach/io.h b/arch/arm/mach-vexpress/include/mach/io.h index 13522d86685..0088cd388a8 100644 --- a/arch/arm/mach-vexpress/include/mach/io.h +++ b/arch/arm/mach-vexpress/include/mach/io.h @@ -20,7 +20,6 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H -#define __io(a) __typesafe_io(a) #define __mem_pci(a) (a) #endif -- cgit v1.2.3-18-g5258 From 9141a003a491c7230d17b9c29677ce2be437b95c Mon Sep 17 00:00:00 2001 From: Will Deacon <will.deacon@arm.com> Date: Fri, 3 Feb 2012 14:48:01 +0100 Subject: ARM: 7316/1: kexec: EOI active and mask all interrupts in kexec crash path The kexec machine crash code can be called in interrupt context via a sysrq trigger made using the magic key combination. If the irq chip dealing with the serial interrupt is using the fasteoi flow handler, then we will never EOI the interrupt because the interrupt handler will be fatal. In the case of a GIC, this results in the crash kernel not receiving interrupts on that CPU interface. This patch adds code (based on the PowerPC implementation) to EOI any pending interrupts on the crash CPU before masking and disabling all interrupts. Secondary cores are not a problem since they are placed into a cpu_relax() loop via an IPI. Reported-by: Lei Wen <leiwen@marvell.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/kernel/machine_kexec.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index 764bd456d84..a30004476e7 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -7,6 +7,7 @@ #include <linux/delay.h> #include <linux/reboot.h> #include <linux/io.h> +#include <linux/irq.h> #include <asm/pgtable.h> #include <asm/pgalloc.h> #include <asm/mmu_context.h> @@ -53,6 +54,29 @@ void machine_crash_nonpanic_core(void *unused) cpu_relax(); } +static void machine_kexec_mask_interrupts(void) +{ + unsigned int i; + struct irq_desc *desc; + + for_each_irq_desc(i, desc) { + struct irq_chip *chip; + + chip = irq_desc_get_chip(desc); + if (!chip) + continue; + + if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) + chip->irq_eoi(&desc->irq_data); + + if (chip->irq_mask) + chip->irq_mask(&desc->irq_data); + + if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) + chip->irq_disable(&desc->irq_data); + } +} + void machine_crash_shutdown(struct pt_regs *regs) { unsigned long msecs; @@ -70,6 +94,7 @@ void machine_crash_shutdown(struct pt_regs *regs) printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n"); crash_save_cpu(regs, smp_processor_id()); + machine_kexec_mask_interrupts(); printk(KERN_INFO "Loading crashdump kernel...\n"); } -- cgit v1.2.3-18-g5258 From dc283d7037555aa6891188719be2f1b4af9535c9 Mon Sep 17 00:00:00 2001 From: Rabin Vincent <rabin@rab.in> Date: Wed, 29 Feb 2012 15:59:07 +0100 Subject: ARM: 7351/1: ftrace: remove useless memory checks Before replacing an instruction, the ftrace code determines what the old instruction should be and verifies that that's what's really there in memory before replacing it. This is useful if for example a bug in mcountrecord causes it to record wrong locations. However, in cases where we replace call sites in entry-common.S, these checks are not needed. For these, we currently just memcpy() the memory content and then "verify" it -- this is quite useless and can be removed. Signed-off-by: Rabin Vincent <rabin@rab.in> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/kernel/ftrace.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index c0062ad1e84..6fd7c4a1e53 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c @@ -121,15 +121,17 @@ static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) } static int ftrace_modify_code(unsigned long pc, unsigned long old, - unsigned long new) + unsigned long new, bool validate) { unsigned long replaced; - if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE)) - return -EFAULT; + if (validate) { + if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE)) + return -EFAULT; - if (replaced != old) - return -EINVAL; + if (replaced != old) + return -EINVAL; + } if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE)) return -EPERM; @@ -141,23 +143,21 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old, int ftrace_update_ftrace_func(ftrace_func_t func) { - unsigned long pc, old; + unsigned long pc; unsigned long new; int ret; pc = (unsigned long)&ftrace_call; - memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE); new = ftrace_call_replace(pc, (unsigned long)func); - ret = ftrace_modify_code(pc, old, new); + ret = ftrace_modify_code(pc, 0, new, false); #ifdef CONFIG_OLD_MCOUNT if (!ret) { pc = (unsigned long)&ftrace_call_old; - memcpy(&old, &ftrace_call_old, MCOUNT_INSN_SIZE); new = ftrace_call_replace(pc, (unsigned long)func); - ret = ftrace_modify_code(pc, old, new); + ret = ftrace_modify_code(pc, 0, new, false); } #endif @@ -172,7 +172,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) old = ftrace_nop_replace(rec); new = ftrace_call_replace(ip, adjust_address(rec, addr)); - return ftrace_modify_code(rec->ip, old, new); + return ftrace_modify_code(rec->ip, old, new, true); } int ftrace_make_nop(struct module *mod, @@ -185,7 +185,7 @@ int ftrace_make_nop(struct module *mod, old = ftrace_call_replace(ip, adjust_address(rec, addr)); new = ftrace_nop_replace(rec); - ret = ftrace_modify_code(ip, old, new); + ret = ftrace_modify_code(ip, old, new, true); #ifdef CONFIG_OLD_MCOUNT if (ret == -EINVAL && addr == MCOUNT_ADDR) { @@ -193,7 +193,7 @@ int ftrace_make_nop(struct module *mod, old = ftrace_call_replace(ip, adjust_address(rec, addr)); new = ftrace_nop_replace(rec); - ret = ftrace_modify_code(ip, old, new); + ret = ftrace_modify_code(ip, old, new, true); } #endif @@ -254,7 +254,7 @@ static int __ftrace_modify_caller(unsigned long *callsite, unsigned long old = enable ? nop : branch; unsigned long new = enable ? branch : nop; - return ftrace_modify_code(pc, old, new); + return ftrace_modify_code(pc, old, new, true); } static int ftrace_modify_graph_caller(bool enable) -- cgit v1.2.3-18-g5258 From 4394e2824c8d97d81a336edb469b13c8806604e4 Mon Sep 17 00:00:00 2001 From: Rabin Vincent <rabin@rab.in> Date: Sat, 18 Feb 2012 17:47:03 +0100 Subject: ARM: 7330/1: ftrace: use canonical Thumb-2 wide instruction format As commit 592201a9f15 (ARM: Thumb-2: Support Thumb-2 in undefined instruction handler) says: 32-bit Thumb instructions are specified in the form: ((first_half << 16 ) | second_half) which matches the layout used by the ARM ARM. Convert the ftrace code to use the same format to avoid the usage of different formats in kernel code. Acked-by: Dave Martin <dave.martin@linaro.org> Signed-off-by: Rabin Vincent <rabin@rab.in> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/kernel/ftrace.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index 6fd7c4a1e53..5c9cecfaeb2 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c @@ -16,10 +16,11 @@ #include <linux/uaccess.h> #include <asm/cacheflush.h> +#include <asm/opcodes.h> #include <asm/ftrace.h> #ifdef CONFIG_THUMB2_KERNEL -#define NOP 0xeb04f85d /* pop.w {lr} */ +#define NOP 0xf85deb04 /* pop.w {lr} */ #else #define NOP 0xe8bd4000 /* pop {lr} */ #endif @@ -88,7 +89,7 @@ static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr, if (link) second |= 1 << 14; - return (second << 16) | first; + return __opcode_thumb32_compose(first, second); } #else static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr, @@ -125,6 +126,14 @@ static int ftrace_modify_code(unsigned long pc, unsigned long old, { unsigned long replaced; + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) { + old = __opcode_to_mem_thumb32(old); + new = __opcode_to_mem_thumb32(new); + } else { + old = __opcode_to_mem_arm(old); + new = __opcode_to_mem_arm(new); + } + if (validate) { if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE)) return -EFAULT; -- cgit v1.2.3-18-g5258 From d82227cf8f0b42ff42c21ed47025fdf54cb1698d Mon Sep 17 00:00:00 2001 From: Rabin Vincent <rabin@rab.in> Date: Sat, 18 Feb 2012 17:50:06 +0100 Subject: ARM: 7331/1: extract out insn generation code from ftrace Extract out the instruction generation code so that it can be used for jump labels too. Signed-off-by: Rabin Vincent <rabin@rab.in> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/kernel/Makefile | 5 ++-- arch/arm/kernel/ftrace.c | 61 ++++-------------------------------------------- arch/arm/kernel/insn.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/insn.h | 19 +++++++++++++++ 4 files changed, 87 insertions(+), 59 deletions(-) create mode 100644 arch/arm/kernel/insn.c create mode 100644 arch/arm/kernel/insn.h (limited to 'arch/arm') diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 43b740d0e37..dd3d5f16c14 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -7,6 +7,7 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_ftrace.o = -pg +CFLAGS_REMOVE_insn.o = -pg endif CFLAGS_REMOVE_return_address.o = -pg @@ -34,8 +35,8 @@ obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o obj-$(CONFIG_SMP) += smp.o smp_tlb.o obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o -obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o -obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o +obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o +obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o ifdef CONFIG_THUMB2_KERNEL diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index 5c9cecfaeb2..df0bf0c8cb7 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c @@ -19,6 +19,8 @@ #include <asm/opcodes.h> #include <asm/ftrace.h> +#include "insn.h" + #ifdef CONFIG_THUMB2_KERNEL #define NOP 0xf85deb04 /* pop.w {lr} */ #else @@ -61,64 +63,9 @@ static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr) } #endif -#ifdef CONFIG_THUMB2_KERNEL -static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr, - bool link) -{ - unsigned long s, j1, j2, i1, i2, imm10, imm11; - unsigned long first, second; - long offset; - - offset = (long)addr - (long)(pc + 4); - if (offset < -16777216 || offset > 16777214) { - WARN_ON_ONCE(1); - return 0; - } - - s = (offset >> 24) & 0x1; - i1 = (offset >> 23) & 0x1; - i2 = (offset >> 22) & 0x1; - imm10 = (offset >> 12) & 0x3ff; - imm11 = (offset >> 1) & 0x7ff; - - j1 = (!i1) ^ s; - j2 = (!i2) ^ s; - - first = 0xf000 | (s << 10) | imm10; - second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11; - if (link) - second |= 1 << 14; - - return __opcode_thumb32_compose(first, second); -} -#else -static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr, - bool link) -{ - unsigned long opcode = 0xea000000; - long offset; - - if (link) - opcode |= 1 << 24; - - offset = (long)addr - (long)(pc + 8); - if (unlikely(offset < -33554432 || offset > 33554428)) { - /* Can't generate branches that far (from ARM ARM). Ftrace - * doesn't generate branches outside of kernel text. - */ - WARN_ON_ONCE(1); - return 0; - } - - offset = (offset >> 2) & 0x00ffffff; - - return opcode | offset; -} -#endif - static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) { - return ftrace_gen_branch(pc, addr, true); + return arm_gen_branch_link(pc, addr); } static int ftrace_modify_code(unsigned long pc, unsigned long old, @@ -258,7 +205,7 @@ static int __ftrace_modify_caller(unsigned long *callsite, { unsigned long caller_fn = (unsigned long) func; unsigned long pc = (unsigned long) callsite; - unsigned long branch = ftrace_gen_branch(pc, caller_fn, false); + unsigned long branch = arm_gen_branch(pc, caller_fn); unsigned long nop = 0xe1a00000; /* mov r0, r0 */ unsigned long old = enable ? nop : branch; unsigned long new = enable ? branch : nop; diff --git a/arch/arm/kernel/insn.c b/arch/arm/kernel/insn.c new file mode 100644 index 00000000000..ab312e51654 --- /dev/null +++ b/arch/arm/kernel/insn.c @@ -0,0 +1,61 @@ +#include <linux/kernel.h> +#include <asm/opcodes.h> + +static unsigned long +__arm_gen_branch_thumb2(unsigned long pc, unsigned long addr, bool link) +{ + unsigned long s, j1, j2, i1, i2, imm10, imm11; + unsigned long first, second; + long offset; + + offset = (long)addr - (long)(pc + 4); + if (offset < -16777216 || offset > 16777214) { + WARN_ON_ONCE(1); + return 0; + } + + s = (offset >> 24) & 0x1; + i1 = (offset >> 23) & 0x1; + i2 = (offset >> 22) & 0x1; + imm10 = (offset >> 12) & 0x3ff; + imm11 = (offset >> 1) & 0x7ff; + + j1 = (!i1) ^ s; + j2 = (!i2) ^ s; + + first = 0xf000 | (s << 10) | imm10; + second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11; + if (link) + second |= 1 << 14; + + return __opcode_thumb32_compose(first, second); +} + +static unsigned long +__arm_gen_branch_arm(unsigned long pc, unsigned long addr, bool link) +{ + unsigned long opcode = 0xea000000; + long offset; + + if (link) + opcode |= 1 << 24; + + offset = (long)addr - (long)(pc + 8); + if (unlikely(offset < -33554432 || offset > 33554428)) { + WARN_ON_ONCE(1); + return 0; + } + + offset = (offset >> 2) & 0x00ffffff; + + return opcode | offset; +} + +unsigned long +__arm_gen_branch(unsigned long pc, unsigned long addr, bool link) +{ + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) + return __arm_gen_branch_thumb2(pc, addr, link); + else + return __arm_gen_branch_arm(pc, addr, link); +} diff --git a/arch/arm/kernel/insn.h b/arch/arm/kernel/insn.h new file mode 100644 index 00000000000..994d60fd3ff --- /dev/null +++ b/arch/arm/kernel/insn.h @@ -0,0 +1,19 @@ +#ifndef __ASM_ARM_INSN_H +#define __ASM_ARM_INSN_H + +unsigned long +__arm_gen_branch(unsigned long pc, unsigned long addr, bool link); + +static inline unsigned long +arm_gen_branch(unsigned long pc, unsigned long addr) +{ + return __arm_gen_branch(pc, addr, false); +} + +static inline unsigned long +arm_gen_branch_link(unsigned long pc, unsigned long addr) +{ + return __arm_gen_branch(pc, addr, true); +} + +#endif -- cgit v1.2.3-18-g5258 From b21d55e98ac2bbcbbeec9a8cb091f717fd95b072 Mon Sep 17 00:00:00 2001 From: Rabin Vincent <rabin@rab.in> Date: Sat, 18 Feb 2012 17:50:51 +0100 Subject: ARM: 7332/1: extract out code patch function from kprobes Extract out the code patching code from kprobes so that it can be used from the jump label code. Additionally, the separated code: - Uses the IS_ENABLED() macros instead of the #ifdefs for THUMB2 support - Unifies the two separate functions in kprobes, providing one function that uses stop_machine() internally, and one that can be called from stop_machine() directly - Patches the text on all CPUs only on processors requiring software broadcasting of cache operations Acked-by: Jon Medhurst <tixy@yxit.co.uk> Tested-by: Jon Medhurst <tixy@yxit.co.uk> Signed-off-by: Rabin Vincent <rabin@rab.in> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/kernel/Makefile | 3 +- arch/arm/kernel/kprobes.c | 86 +++++++++++++---------------------------------- arch/arm/kernel/patch.c | 75 +++++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/patch.h | 7 ++++ 4 files changed, 108 insertions(+), 63 deletions(-) create mode 100644 arch/arm/kernel/patch.c create mode 100644 arch/arm/kernel/patch.h (limited to 'arch/arm') diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index dd3d5f16c14..8c63ee8d3c4 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -8,6 +8,7 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) ifdef CONFIG_FUNCTION_TRACER CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_insn.o = -pg +CFLAGS_REMOVE_patch.o = -pg endif CFLAGS_REMOVE_return_address.o = -pg @@ -38,7 +39,7 @@ obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o -obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o +obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o patch.o ifdef CONFIG_THUMB2_KERNEL obj-$(CONFIG_KPROBES) += kprobes-thumb.o else diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c index 129c1163248..ab1869dac97 100644 --- a/arch/arm/kernel/kprobes.c +++ b/arch/arm/kernel/kprobes.c @@ -29,6 +29,7 @@ #include <asm/cacheflush.h> #include "kprobes.h" +#include "patch.h" #define MIN_STACK_SIZE(addr) \ min((unsigned long)MAX_STACK_SIZE, \ @@ -103,57 +104,33 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) return 0; } -#ifdef CONFIG_THUMB2_KERNEL - -/* - * For a 32-bit Thumb breakpoint spanning two memory words we need to take - * special precautions to insert the breakpoint atomically, especially on SMP - * systems. This is achieved by calling this arming function using stop_machine. - */ -static int __kprobes set_t32_breakpoint(void *addr) -{ - ((u16 *)addr)[0] = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION >> 16; - ((u16 *)addr)[1] = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION & 0xffff; - flush_insns(addr, 2*sizeof(u16)); - return 0; -} - void __kprobes arch_arm_kprobe(struct kprobe *p) { - uintptr_t addr = (uintptr_t)p->addr & ~1; /* Remove any Thumb flag */ - - if (!is_wide_instruction(p->opcode)) { - *(u16 *)addr = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION; - flush_insns(addr, sizeof(u16)); - } else if (addr & 2) { - /* A 32-bit instruction spanning two words needs special care */ - stop_machine(set_t32_breakpoint, (void *)addr, &cpu_online_map); + unsigned int brkp; + void *addr; + + if (IS_ENABLED(CONFIG_THUMB2_KERNEL)) { + /* Remove any Thumb flag */ + addr = (void *)((uintptr_t)p->addr & ~1); + + if (is_wide_instruction(p->opcode)) + brkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION; + else + brkp = KPROBE_THUMB16_BREAKPOINT_INSTRUCTION; } else { - /* Word aligned 32-bit instruction can be written atomically */ - u32 bkp = KPROBE_THUMB32_BREAKPOINT_INSTRUCTION; -#ifndef __ARMEB__ /* Swap halfwords for little-endian */ - bkp = (bkp >> 16) | (bkp << 16); -#endif - *(u32 *)addr = bkp; - flush_insns(addr, sizeof(u32)); - } -} + kprobe_opcode_t insn = p->opcode; -#else /* !CONFIG_THUMB2_KERNEL */ + addr = p->addr; + brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION; -void __kprobes arch_arm_kprobe(struct kprobe *p) -{ - kprobe_opcode_t insn = p->opcode; - kprobe_opcode_t brkp = KPROBE_ARM_BREAKPOINT_INSTRUCTION; - if (insn >= 0xe0000000) - brkp |= 0xe0000000; /* Unconditional instruction */ - else - brkp |= insn & 0xf0000000; /* Copy condition from insn */ - *p->addr = brkp; - flush_insns(p->addr, sizeof(p->addr[0])); -} + if (insn >= 0xe0000000) + brkp |= 0xe0000000; /* Unconditional instruction */ + else + brkp |= insn & 0xf0000000; /* Copy condition from insn */ + } -#endif /* !CONFIG_THUMB2_KERNEL */ + patch_text(addr, brkp); +} /* * The actual disarming is done here on each CPU and synchronized using @@ -166,25 +143,10 @@ void __kprobes arch_arm_kprobe(struct kprobe *p) int __kprobes __arch_disarm_kprobe(void *p) { struct kprobe *kp = p; -#ifdef CONFIG_THUMB2_KERNEL - u16 *addr = (u16 *)((uintptr_t)kp->addr & ~1); - kprobe_opcode_t insn = kp->opcode; - unsigned int len; + void *addr = (void *)((uintptr_t)kp->addr & ~1); - if (is_wide_instruction(insn)) { - ((u16 *)addr)[0] = insn>>16; - ((u16 *)addr)[1] = insn; - len = 2*sizeof(u16); - } else { - ((u16 *)addr)[0] = insn; - len = sizeof(u16); - } - flush_insns(addr, len); + __patch_text(addr, kp->opcode); -#else /* !CONFIG_THUMB2_KERNEL */ - *kp->addr = kp->opcode; - flush_insns(kp->addr, sizeof(kp->addr[0])); -#endif return 0; } diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c new file mode 100644 index 00000000000..07314af4773 --- /dev/null +++ b/arch/arm/kernel/patch.c @@ -0,0 +1,75 @@ +#include <linux/kernel.h> +#include <linux/kprobes.h> +#include <linux/stop_machine.h> + +#include <asm/cacheflush.h> +#include <asm/smp_plat.h> +#include <asm/opcodes.h> + +#include "patch.h" + +struct patch { + void *addr; + unsigned int insn; +}; + +void __kprobes __patch_text(void *addr, unsigned int insn) +{ + bool thumb2 = IS_ENABLED(CONFIG_THUMB2_KERNEL); + int size; + + if (thumb2 && __opcode_is_thumb16(insn)) { + *(u16 *)addr = __opcode_to_mem_thumb16(insn); + size = sizeof(u16); + } else if (thumb2 && ((uintptr_t)addr & 2)) { + u16 first = __opcode_thumb32_first(insn); + u16 second = __opcode_thumb32_second(insn); + u16 *addrh = addr; + + addrh[0] = __opcode_to_mem_thumb16(first); + addrh[1] = __opcode_to_mem_thumb16(second); + + size = sizeof(u32); + } else { + if (thumb2) + insn = __opcode_to_mem_thumb32(insn); + else + insn = __opcode_to_mem_arm(insn); + + *(u32 *)addr = insn; + size = sizeof(u32); + } + + flush_icache_range((uintptr_t)(addr), + (uintptr_t)(addr) + size); +} + +static int __kprobes patch_text_stop_machine(void *data) +{ + struct patch *patch = data; + + __patch_text(patch->addr, patch->insn); + + return 0; +} + +void __kprobes patch_text(void *addr, unsigned int insn) +{ + struct patch patch = { + .addr = addr, + .insn = insn, + }; + + if (cache_ops_need_broadcast()) { + stop_machine(patch_text_stop_machine, &patch, cpu_online_mask); + } else { + bool straddles_word = IS_ENABLED(CONFIG_THUMB2_KERNEL) + && __opcode_is_thumb32(insn) + && ((uintptr_t)addr & 2); + + if (straddles_word) + stop_machine(patch_text_stop_machine, &patch, NULL); + else + __patch_text(addr, insn); + } +} diff --git a/arch/arm/kernel/patch.h b/arch/arm/kernel/patch.h new file mode 100644 index 00000000000..b4731f2dac3 --- /dev/null +++ b/arch/arm/kernel/patch.h @@ -0,0 +1,7 @@ +#ifndef _ARM_KERNEL_PATCH_H +#define _ARM_KERNEL_PATCH_H + +void patch_text(void *addr, unsigned int insn); +void __patch_text(void *addr, unsigned int insn); + +#endif -- cgit v1.2.3-18-g5258 From e88443cdfc61af5cd22d6aeb245ee94833c473bc Mon Sep 17 00:00:00 2001 From: Mathias Krause <minipli@googlemail.com> Date: Mon, 5 Mar 2012 15:05:34 -0800 Subject: ARM: exec: remove redundant set_fs(USER_DS) The address limit is already set in flush_old_exec() so this set_fs(USER_DS) is redundant. Signed-off-by: Mathias Krause <minipli@googlemail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/include/asm/processor.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index ce280b8d613..d7038fa2234 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h @@ -55,7 +55,6 @@ struct thread_struct { #define start_thread(regs,pc,sp) \ ({ \ unsigned long *stack = (unsigned long *)sp; \ - set_fs(USER_DS); \ memset(regs->uregs, 0, sizeof(regs->uregs)); \ if (current->personality & ADDR_LIMIT_32BIT) \ regs->ARM_cpsr = USR_MODE; \ -- cgit v1.2.3-18-g5258 From 101d9b0dedbc9e560737d3357104bf09db48eb3e Mon Sep 17 00:00:00 2001 From: Matt Fleming <matt.fleming@intel.com> Date: Mon, 5 Mar 2012 15:05:34 -0800 Subject: ARM: use set_current_blocked() and block_sigmask() As described in e6fa16ab ("signal: sigprocmask() should do retarget_shared_pending()") the modification of current->blocked is incorrect as we need to check for shared signals we're about to block. Also, use the new helper function introduced in commit 5e6292c0f28f ("signal: add block_sigmask() for adding sigmask to current->blocked") which centralises the code for updating current->blocked after successfully delivering a signal and reduces the amount of duplicate code across architectures. In the past some architectures got this code wrong, so using this helper function should stop that from happening again. Cc: Arnd Bergmann <arnd.bergmann@linaro.org> Cc: Dave Martin <dave.martin@linaro.org> Cc: Nicolas Pitre <nicolas.pitre@linaro.org> Cc: Will Deacon <will.deacon@arm.com> Acked-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/kernel/signal.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 0340224cf73..d13e61ac18d 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -66,12 +66,13 @@ const unsigned long syscall_restart_code[2] = { */ asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask) { - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); + sigset_t blocked; + current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + + mask &= _BLOCKABLE; + siginitset(&blocked, mask); + set_current_blocked(&blocked); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -281,10 +282,7 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); if (err == 0) { sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - current->blocked = set; - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); } __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); @@ -637,13 +635,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, /* * Block the signal if we were successful. */ - spin_lock_irq(&tsk->sighand->siglock); - sigorsets(&tsk->blocked, &tsk->blocked, - &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(&tsk->blocked, sig); - recalc_sigpending(); - spin_unlock_irq(&tsk->sighand->siglock); + block_sigmask(ka, sig); return 0; } -- cgit v1.2.3-18-g5258 From 9b5a146a43db3733c731d47022f4f5259e6b31e6 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre <nicolas.pitre@linaro.org> Date: Wed, 22 Feb 2012 21:58:03 +0100 Subject: ARM: 7338/1: add support for early console output via semihosting This is a very simple method for code running in an emulator, or under the supervision of a debugger, to use I/O facilities on the controlling host. Tested with OpenOCD, and ARM's Fast Models. Details on semihosting can be found in chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd. Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/Kconfig.debug | 16 ++++++++++++++++ arch/arm/kernel/debug.S | 25 ++++++++++++++++++++++++- arch/arm/kernel/head.S | 8 ++++---- 3 files changed, 44 insertions(+), 5 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index e0d236d7ff7..755d9fbe323 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -100,6 +100,22 @@ choice Note that the system will appear to hang during boot if there is nothing connected to read from the DCC. + config DEBUG_SEMIHOSTING + bool "Kernel low-level debug output via semihosting I" + help + Semihosting enables code running on an ARM target to use + the I/O facilities on a host debugger/emulator through a + simple SVC calls. The host debugger or emulator must have + semihosting enabled for the special svc call to be trapped + otherwise the kernel will crash. + + This is known to work with OpenOCD, as wellas + ARM's Fast Models, or any other controlling environment + that implements semihosting. + + For more details about semihosting, please see + chapter 8 of DUI0203I_rvct_developer_guide.pdf from ARM Ltd. + config AT91_DEBUG_LL_DBGU0 bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl" depends on HAVE_AT91_DBGU0 diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index 204e2160cfc..e5a765c5f06 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -100,7 +100,7 @@ #endif /* CONFIG_CPU_V6 */ -#else +#elif !defined(CONFIG_DEBUG_SEMIHOSTING) #include <mach/debug-macro.S> #endif /* CONFIG_DEBUG_ICEDCC */ @@ -155,6 +155,8 @@ hexbuf: .space 16 .ltorg +#ifndef CONFIG_DEBUG_SEMIHOSTING + ENTRY(printascii) addruart_current r3, r1, r2 b 2f @@ -177,3 +179,24 @@ ENTRY(printch) mov r0, #0 b 1b ENDPROC(printch) + +#else + +ENTRY(printascii) + mov r1, r0 + mov r0, #0x04 @ SYS_WRITE0 + ARM( svc #0x123456 ) + THUMB( svc #0xab ) + mov pc, lr +ENDPROC(printascii) + +ENTRY(printch) + adr r1, hexbuf + strb r0, [r1] + mov r0, #0x03 @ SYS_WRITEC + ARM( svc #0x123456 ) + THUMB( svc #0xab ) + mov pc, lr +ENDPROC(printch) + +#endif diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index a2e9694a68e..3bf0c7f8b04 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -265,7 +265,7 @@ __create_page_tables: str r6, [r3] #ifdef CONFIG_DEBUG_LL -#ifndef CONFIG_DEBUG_ICEDCC +#if !defined(CONFIG_DEBUG_ICEDCC) && !defined(CONFIG_DEBUG_SEMIHOSTING) /* * Map in IO space for serial debugging. * This allows debug messages to be output @@ -297,10 +297,10 @@ __create_page_tables: cmp r0, r6 blo 1b -#else /* CONFIG_DEBUG_ICEDCC */ - /* we don't need any serial debugging mappings for ICEDCC */ +#else /* CONFIG_DEBUG_ICEDCC || CONFIG_DEBUG_SEMIHOSTING */ + /* we don't need any serial debugging mappings */ ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags -#endif /* !CONFIG_DEBUG_ICEDCC */ +#endif #if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS) /* -- cgit v1.2.3-18-g5258 From 09f05d8529ff4aa92311c1a55ce35ac98cb59b8c Mon Sep 17 00:00:00 2001 From: Rabin Vincent <rabin@rab.in> Date: Sat, 18 Feb 2012 17:52:41 +0100 Subject: ARM: 7334/1: add jump label support Add the arch-specific code to support jump labels for ARM and Thumb-2. This code will only be activated on compilers that are capable of building it. It has been tested with GCC 4.6 patched with the patch from GCC bug 48637. Cc: Jason Baron <jbaron@redhat.com> Signed-off-by: Rabin Vincent <rabin@rab.in> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/Kconfig | 1 + arch/arm/include/asm/jump_label.h | 41 +++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/insn.h | 10 ++++++++++ arch/arm/kernel/jump_label.c | 39 +++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+) create mode 100644 arch/arm/include/asm/jump_label.h create mode 100644 arch/arm/kernel/jump_label.c (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6b5f84887ce..ee6c7154c9a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -9,6 +9,7 @@ config ARM select SYS_SUPPORTS_APM_EMULATION select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI) select HAVE_OPROFILE if (HAVE_PERF_EVENTS) + select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL select HAVE_ARCH_KGDB select HAVE_KPROBES if !XIP_KERNEL select HAVE_KRETPROBES if (HAVE_KPROBES) diff --git a/arch/arm/include/asm/jump_label.h b/arch/arm/include/asm/jump_label.h new file mode 100644 index 00000000000..5c5ca2ea62b --- /dev/null +++ b/arch/arm/include/asm/jump_label.h @@ -0,0 +1,41 @@ +#ifndef _ASM_ARM_JUMP_LABEL_H +#define _ASM_ARM_JUMP_LABEL_H + +#ifdef __KERNEL__ + +#include <linux/types.h> +#include <asm/system.h> + +#define JUMP_LABEL_NOP_SIZE 4 + +#ifdef CONFIG_THUMB2_KERNEL +#define JUMP_LABEL_NOP "nop.w" +#else +#define JUMP_LABEL_NOP "nop" +#endif + +static __always_inline bool arch_static_branch(struct jump_label_key *key) +{ + asm goto("1:\n\t" + JUMP_LABEL_NOP "\n\t" + ".pushsection __jump_table, \"aw\"\n\t" + ".word 1b, %l[l_yes], %c0\n\t" + ".popsection\n\t" + : : "i" (key) : : l_yes); + + return false; +l_yes: + return true; +} + +#endif /* __KERNEL__ */ + +typedef u32 jump_label_t; + +struct jump_entry { + jump_label_t code; + jump_label_t target; + jump_label_t key; +}; + +#endif diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 8c63ee8d3c4..1b7d9a39097 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -38,6 +38,7 @@ obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o +obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_KPROBES) += kprobes.o kprobes-common.o patch.o ifdef CONFIG_THUMB2_KERNEL diff --git a/arch/arm/kernel/insn.h b/arch/arm/kernel/insn.h index 994d60fd3ff..e96065da4da 100644 --- a/arch/arm/kernel/insn.h +++ b/arch/arm/kernel/insn.h @@ -1,6 +1,16 @@ #ifndef __ASM_ARM_INSN_H #define __ASM_ARM_INSN_H +static inline unsigned long +arm_gen_nop(void) +{ +#ifdef CONFIG_THUMB2_KERNEL + return 0xf3af8000; /* nop.w */ +#else + return 0xe1a00000; /* mov r0, r0 */ +#endif +} + unsigned long __arm_gen_branch(unsigned long pc, unsigned long addr, bool link); diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c new file mode 100644 index 00000000000..4ce4f789446 --- /dev/null +++ b/arch/arm/kernel/jump_label.c @@ -0,0 +1,39 @@ +#include <linux/kernel.h> +#include <linux/jump_label.h> + +#include "insn.h" +#include "patch.h" + +#ifdef HAVE_JUMP_LABEL + +static void __arch_jump_label_transform(struct jump_entry *entry, + enum jump_label_type type, + bool is_static) +{ + void *addr = (void *)entry->code; + unsigned int insn; + + if (type == JUMP_LABEL_ENABLE) + insn = arm_gen_branch(entry->code, entry->target); + else + insn = arm_gen_nop(); + + if (is_static) + __patch_text(addr, insn); + else + patch_text(addr, insn); +} + +void arch_jump_label_transform(struct jump_entry *entry, + enum jump_label_type type) +{ + __arch_jump_label_transform(entry, type, false); +} + +void arch_jump_label_transform_static(struct jump_entry *entry, + enum jump_label_type type) +{ + __arch_jump_label_transform(entry, type, true); +} + +#endif -- cgit v1.2.3-18-g5258 From ddecdfcea0ae891f782ae853771c867ab51024c2 Mon Sep 17 00:00:00 2001 From: Mircea Gherzan <mgherzan@gmail.com> Date: Fri, 16 Mar 2012 13:37:12 +0100 Subject: ARM: 7259/3: net: JIT compiler for packet filters Based of Matt Evans's PPC64 implementation. The compiler generates ARM instructions but interworking is supported for Thumb2 kernels. Supports both little and big endian. Unaligned loads are emitted for ARMv6+. Not all the BPF opcodes that deal with ancillary data are supported. The scratch memory of the filter lives on the stack. Hardware integer division is used if it is available. Enabled in the same way as for x86-64 and PPC64: echo 1 > /proc/sys/net/core/bpf_jit_enable A value greater than 1 enables opcode output. Signed-off-by: Mircea Gherzan <mgherzan@gmail.com> Acked-by: David S. Miller <davem@davemloft.net> Acked-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/Kconfig | 1 + arch/arm/Makefile | 1 + arch/arm/net/Makefile | 3 + arch/arm/net/bpf_jit_32.c | 915 ++++++++++++++++++++++++++++++++++++++++++++++ arch/arm/net/bpf_jit_32.h | 190 ++++++++++ 5 files changed, 1110 insertions(+) create mode 100644 arch/arm/net/Makefile create mode 100644 arch/arm/net/bpf_jit_32.c create mode 100644 arch/arm/net/bpf_jit_32.h (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ee6c7154c9a..746ab6d6a20 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -34,6 +34,7 @@ config ARM select GENERIC_IRQ_SHOW select CPU_PM if (SUSPEND || CPU_IDLE) select GENERIC_PCI_IOMAP + select HAVE_BPF_JIT help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 40319d91bb7..93d63be8fa5 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -253,6 +253,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/ # If we have a machine-specific directory, then include it in the build. core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ +core-y += arch/arm/net/ core-y += $(machdirs) $(platdirs) drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ diff --git a/arch/arm/net/Makefile b/arch/arm/net/Makefile new file mode 100644 index 00000000000..c2c10841b6b --- /dev/null +++ b/arch/arm/net/Makefile @@ -0,0 +1,3 @@ +# ARM-specific networking code + +obj-$(CONFIG_BPF_JIT) += bpf_jit_32.o diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c new file mode 100644 index 00000000000..62135849f48 --- /dev/null +++ b/arch/arm/net/bpf_jit_32.c @@ -0,0 +1,915 @@ +/* + * Just-In-Time compiler for BPF filters on 32bit ARM + * + * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com> + * + * 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; version 2 of the License. + */ + +#include <linux/bitops.h> +#include <linux/compiler.h> +#include <linux/errno.h> +#include <linux/filter.h> +#include <linux/moduleloader.h> +#include <linux/netdevice.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <asm/cacheflush.h> +#include <asm/hwcap.h> + +#include "bpf_jit_32.h" + +/* + * ABI: + * + * r0 scratch register + * r4 BPF register A + * r5 BPF register X + * r6 pointer to the skb + * r7 skb->data + * r8 skb_headlen(skb) + */ + +#define r_scratch ARM_R0 +/* r1-r3 are (also) used for the unaligned loads on the non-ARMv7 slowpath */ +#define r_off ARM_R1 +#define r_A ARM_R4 +#define r_X ARM_R5 +#define r_skb ARM_R6 +#define r_skb_data ARM_R7 +#define r_skb_hl ARM_R8 + +#define SCRATCH_SP_OFFSET 0 +#define SCRATCH_OFF(k) (SCRATCH_SP_OFFSET + (k)) + +#define SEEN_MEM ((1 << BPF_MEMWORDS) - 1) +#define SEEN_MEM_WORD(k) (1 << (k)) +#define SEEN_X (1 << BPF_MEMWORDS) +#define SEEN_CALL (1 << (BPF_MEMWORDS + 1)) +#define SEEN_SKB (1 << (BPF_MEMWORDS + 2)) +#define SEEN_DATA (1 << (BPF_MEMWORDS + 3)) + +#define FLAG_NEED_X_RESET (1 << 0) + +struct jit_ctx { + const struct sk_filter *skf; + unsigned idx; + unsigned prologue_bytes; + int ret0_fp_idx; + u32 seen; + u32 flags; + u32 *offsets; + u32 *target; +#if __LINUX_ARM_ARCH__ < 7 + u16 epilogue_bytes; + u16 imm_count; + u32 *imms; +#endif +}; + +int bpf_jit_enable __read_mostly; + +static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset) +{ + u8 ret; + int err; + + err = skb_copy_bits(skb, offset, &ret, 1); + + return (u64)err << 32 | ret; +} + +static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset) +{ + u16 ret; + int err; + + err = skb_copy_bits(skb, offset, &ret, 2); + + return (u64)err << 32 | ntohs(ret); +} + +static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset) +{ + u32 ret; + int err; + + err = skb_copy_bits(skb, offset, &ret, 4); + + return (u64)err << 32 | ntohl(ret); +} + +/* + * Wrapper that handles both OABI and EABI and assures Thumb2 interworking + * (where the assembly routines like __aeabi_uidiv could cause problems). + */ +static u32 jit_udiv(u32 dividend, u32 divisor) +{ + return dividend / divisor; +} + +static inline void _emit(int cond, u32 inst, struct jit_ctx *ctx) +{ + if (ctx->target != NULL) + ctx->target[ctx->idx] = inst | (cond << 28); + + ctx->idx++; +} + +/* + * Emit an instruction that will be executed unconditionally. + */ +static inline void emit(u32 inst, struct jit_ctx *ctx) +{ + _emit(ARM_COND_AL, inst, ctx); +} + +static u16 saved_regs(struct jit_ctx *ctx) +{ + u16 ret = 0; + + if ((ctx->skf->len > 1) || + (ctx->skf->insns[0].code == BPF_S_RET_A)) + ret |= 1 << r_A; + +#ifdef CONFIG_FRAME_POINTER + ret |= (1 << ARM_FP) | (1 << ARM_IP) | (1 << ARM_LR) | (1 << ARM_PC); +#else + if (ctx->seen & SEEN_CALL) + ret |= 1 << ARM_LR; +#endif + if (ctx->seen & (SEEN_DATA | SEEN_SKB)) + ret |= 1 << r_skb; + if (ctx->seen & SEEN_DATA) + ret |= (1 << r_skb_data) | (1 << r_skb_hl); + if (ctx->seen & SEEN_X) + ret |= 1 << r_X; + + return ret; +} + +static inline int mem_words_used(struct jit_ctx *ctx) +{ + /* yes, we do waste some stack space IF there are "holes" in the set" */ + return fls(ctx->seen & SEEN_MEM); +} + +static inline bool is_load_to_a(u16 inst) +{ + switch (inst) { + case BPF_S_LD_W_LEN: + case BPF_S_LD_W_ABS: + case BPF_S_LD_H_ABS: + case BPF_S_LD_B_ABS: + case BPF_S_ANC_CPU: + case BPF_S_ANC_IFINDEX: + case BPF_S_ANC_MARK: + case BPF_S_ANC_PROTOCOL: + case BPF_S_ANC_RXHASH: + case BPF_S_ANC_QUEUE: + return true; + default: + return false; + } +} + +static void build_prologue(struct jit_ctx *ctx) +{ + u16 reg_set = saved_regs(ctx); + u16 first_inst = ctx->skf->insns[0].code; + u16 off; + +#ifdef CONFIG_FRAME_POINTER + emit(ARM_MOV_R(ARM_IP, ARM_SP), ctx); + emit(ARM_PUSH(reg_set), ctx); + emit(ARM_SUB_I(ARM_FP, ARM_IP, 4), ctx); +#else + if (reg_set) + emit(ARM_PUSH(reg_set), ctx); +#endif + + if (ctx->seen & (SEEN_DATA | SEEN_SKB)) + emit(ARM_MOV_R(r_skb, ARM_R0), ctx); + + if (ctx->seen & SEEN_DATA) { + off = offsetof(struct sk_buff, data); + emit(ARM_LDR_I(r_skb_data, r_skb, off), ctx); + /* headlen = len - data_len */ + off = offsetof(struct sk_buff, len); + emit(ARM_LDR_I(r_skb_hl, r_skb, off), ctx); + off = offsetof(struct sk_buff, data_len); + emit(ARM_LDR_I(r_scratch, r_skb, off), ctx); + emit(ARM_SUB_R(r_skb_hl, r_skb_hl, r_scratch), ctx); + } + + if (ctx->flags & FLAG_NEED_X_RESET) + emit(ARM_MOV_I(r_X, 0), ctx); + + /* do not leak kernel data to userspace */ + if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst))) + emit(ARM_MOV_I(r_A, 0), ctx); + + /* stack space for the BPF_MEM words */ + if (ctx->seen & SEEN_MEM) + emit(ARM_SUB_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx); +} + +static void build_epilogue(struct jit_ctx *ctx) +{ + u16 reg_set = saved_regs(ctx); + + if (ctx->seen & SEEN_MEM) + emit(ARM_ADD_I(ARM_SP, ARM_SP, mem_words_used(ctx) * 4), ctx); + + reg_set &= ~(1 << ARM_LR); + +#ifdef CONFIG_FRAME_POINTER + /* the first instruction of the prologue was: mov ip, sp */ + reg_set &= ~(1 << ARM_IP); + reg_set |= (1 << ARM_SP); + emit(ARM_LDM(ARM_SP, reg_set), ctx); +#else + if (reg_set) { + if (ctx->seen & SEEN_CALL) + reg_set |= 1 << ARM_PC; + emit(ARM_POP(reg_set), ctx); + } + + if (!(ctx->seen & SEEN_CALL)) + emit(ARM_BX(ARM_LR), ctx); +#endif +} + +static int16_t imm8m(u32 x) +{ + u32 rot; + + for (rot = 0; rot < 16; rot++) + if ((x & ~ror32(0xff, 2 * rot)) == 0) + return rol32(x, 2 * rot) | (rot << 8); + + return -1; +} + +#if __LINUX_ARM_ARCH__ < 7 + +static u16 imm_offset(u32 k, struct jit_ctx *ctx) +{ + unsigned i = 0, offset; + u16 imm; + + /* on the "fake" run we just count them (duplicates included) */ + if (ctx->target == NULL) { + ctx->imm_count++; + return 0; + } + + while ((i < ctx->imm_count) && ctx->imms[i]) { + if (ctx->imms[i] == k) + break; + i++; + } + + if (ctx->imms[i] == 0) + ctx->imms[i] = k; + + /* constants go just after the epilogue */ + offset = ctx->offsets[ctx->skf->len]; + offset += ctx->prologue_bytes; + offset += ctx->epilogue_bytes; + offset += i * 4; + + ctx->target[offset / 4] = k; + + /* PC in ARM mode == address of the instruction + 8 */ + imm = offset - (8 + ctx->idx * 4); + + return imm; +} + +#endif /* __LINUX_ARM_ARCH__ */ + +/* + * Move an immediate that's not an imm8m to a core register. + */ +static inline void emit_mov_i_no8m(int rd, u32 val, struct jit_ctx *ctx) +{ +#if __LINUX_ARM_ARCH__ < 7 + emit(ARM_LDR_I(rd, ARM_PC, imm_offset(val, ctx)), ctx); +#else + emit(ARM_MOVW(rd, val & 0xffff), ctx); + if (val > 0xffff) + emit(ARM_MOVT(rd, val >> 16), ctx); +#endif +} + +static inline void emit_mov_i(int rd, u32 val, struct jit_ctx *ctx) +{ + int imm12 = imm8m(val); + + if (imm12 >= 0) + emit(ARM_MOV_I(rd, imm12), ctx); + else + emit_mov_i_no8m(rd, val, ctx); +} + +#if __LINUX_ARM_ARCH__ < 6 + +static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +{ + _emit(cond, ARM_LDRB_I(ARM_R3, r_addr, 1), ctx); + _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx); + _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 3), ctx); + _emit(cond, ARM_LSL_I(ARM_R3, ARM_R3, 16), ctx); + _emit(cond, ARM_LDRB_I(ARM_R0, r_addr, 2), ctx); + _emit(cond, ARM_ORR_S(ARM_R3, ARM_R3, ARM_R1, SRTYPE_LSL, 24), ctx); + _emit(cond, ARM_ORR_R(ARM_R3, ARM_R3, ARM_R2), ctx); + _emit(cond, ARM_ORR_S(r_res, ARM_R3, ARM_R0, SRTYPE_LSL, 8), ctx); +} + +static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +{ + _emit(cond, ARM_LDRB_I(ARM_R1, r_addr, 0), ctx); + _emit(cond, ARM_LDRB_I(ARM_R2, r_addr, 1), ctx); + _emit(cond, ARM_ORR_S(r_res, ARM_R2, ARM_R1, SRTYPE_LSL, 8), ctx); +} + +static inline void emit_swap16(u8 r_dst, u8 r_src, struct jit_ctx *ctx) +{ + emit(ARM_LSL_R(ARM_R1, r_src, 8), ctx); + emit(ARM_ORR_S(r_dst, ARM_R1, r_src, SRTYPE_LSL, 8), ctx); + emit(ARM_LSL_I(r_dst, r_dst, 8), ctx); + emit(ARM_LSL_R(r_dst, r_dst, 8), ctx); +} + +#else /* ARMv6+ */ + +static void emit_load_be32(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +{ + _emit(cond, ARM_LDR_I(r_res, r_addr, 0), ctx); +#ifdef __LITTLE_ENDIAN + _emit(cond, ARM_REV(r_res, r_res), ctx); +#endif +} + +static void emit_load_be16(u8 cond, u8 r_res, u8 r_addr, struct jit_ctx *ctx) +{ + _emit(cond, ARM_LDRH_I(r_res, r_addr, 0), ctx); +#ifdef __LITTLE_ENDIAN + _emit(cond, ARM_REV16(r_res, r_res), ctx); +#endif +} + +static inline void emit_swap16(u8 r_dst __maybe_unused, + u8 r_src __maybe_unused, + struct jit_ctx *ctx __maybe_unused) +{ +#ifdef __LITTLE_ENDIAN + emit(ARM_REV16(r_dst, r_src), ctx); +#endif +} + +#endif /* __LINUX_ARM_ARCH__ < 6 */ + + +/* Compute the immediate value for a PC-relative branch. */ +static inline u32 b_imm(unsigned tgt, struct jit_ctx *ctx) +{ + u32 imm; + + if (ctx->target == NULL) + return 0; + /* + * BPF allows only forward jumps and the offset of the target is + * still the one computed during the first pass. + */ + imm = ctx->offsets[tgt] + ctx->prologue_bytes - (ctx->idx * 4 + 8); + + return imm >> 2; +} + +#define OP_IMM3(op, r1, r2, imm_val, ctx) \ + do { \ + imm12 = imm8m(imm_val); \ + if (imm12 < 0) { \ + emit_mov_i_no8m(r_scratch, imm_val, ctx); \ + emit(op ## _R((r1), (r2), r_scratch), ctx); \ + } else { \ + emit(op ## _I((r1), (r2), imm12), ctx); \ + } \ + } while (0) + +static inline void emit_err_ret(u8 cond, struct jit_ctx *ctx) +{ + if (ctx->ret0_fp_idx >= 0) { + _emit(cond, ARM_B(b_imm(ctx->ret0_fp_idx, ctx)), ctx); + /* NOP to keep the size constant between passes */ + emit(ARM_MOV_R(ARM_R0, ARM_R0), ctx); + } else { + _emit(cond, ARM_MOV_I(ARM_R0, 0), ctx); + _emit(cond, ARM_B(b_imm(ctx->skf->len, ctx)), ctx); + } +} + +static inline void emit_blx_r(u8 tgt_reg, struct jit_ctx *ctx) +{ +#if __LINUX_ARM_ARCH__ < 5 + emit(ARM_MOV_R(ARM_LR, ARM_PC), ctx); + + if (elf_hwcap & HWCAP_THUMB) + emit(ARM_BX(tgt_reg), ctx); + else + emit(ARM_MOV_R(ARM_PC, tgt_reg), ctx); +#else + emit(ARM_BLX_R(tgt_reg), ctx); +#endif +} + +static inline void emit_udiv(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx) +{ +#if __LINUX_ARM_ARCH__ == 7 + if (elf_hwcap & HWCAP_IDIVA) { + emit(ARM_UDIV(rd, rm, rn), ctx); + return; + } +#endif + if (rm != ARM_R0) + emit(ARM_MOV_R(ARM_R0, rm), ctx); + if (rn != ARM_R1) + emit(ARM_MOV_R(ARM_R1, rn), ctx); + + ctx->seen |= SEEN_CALL; + emit_mov_i(ARM_R3, (u32)jit_udiv, ctx); + emit_blx_r(ARM_R3, ctx); + + if (rd != ARM_R0) + emit(ARM_MOV_R(rd, ARM_R0), ctx); +} + +static inline void update_on_xread(struct jit_ctx *ctx) +{ + if (!(ctx->seen & SEEN_X)) + ctx->flags |= FLAG_NEED_X_RESET; + + ctx->seen |= SEEN_X; +} + +static int build_body(struct jit_ctx *ctx) +{ + void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w}; + const struct sk_filter *prog = ctx->skf; + const struct sock_filter *inst; + unsigned i, load_order, off, condt; + int imm12; + u32 k; + + for (i = 0; i < prog->len; i++) { + inst = &(prog->insns[i]); + /* K as an immediate value operand */ + k = inst->k; + + /* compute offsets only in the fake pass */ + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx * 4; + + switch (inst->code) { + case BPF_S_LD_IMM: + emit_mov_i(r_A, k, ctx); + break; + case BPF_S_LD_W_LEN: + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); + emit(ARM_LDR_I(r_A, r_skb, + offsetof(struct sk_buff, len)), ctx); + break; + case BPF_S_LD_MEM: + /* A = scratch[k] */ + ctx->seen |= SEEN_MEM_WORD(k); + emit(ARM_LDR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx); + break; + case BPF_S_LD_W_ABS: + load_order = 2; + goto load; + case BPF_S_LD_H_ABS: + load_order = 1; + goto load; + case BPF_S_LD_B_ABS: + load_order = 0; +load: + /* the interpreter will deal with the negative K */ + if ((int)k < 0) + return -ENOTSUPP; + emit_mov_i(r_off, k, ctx); +load_common: + ctx->seen |= SEEN_DATA | SEEN_CALL; + + if (load_order > 0) { + emit(ARM_SUB_I(r_scratch, r_skb_hl, + 1 << load_order), ctx); + emit(ARM_CMP_R(r_scratch, r_off), ctx); + condt = ARM_COND_HS; + } else { + emit(ARM_CMP_R(r_skb_hl, r_off), ctx); + condt = ARM_COND_HI; + } + + _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data), + ctx); + + if (load_order == 0) + _emit(condt, ARM_LDRB_I(r_A, r_scratch, 0), + ctx); + else if (load_order == 1) + emit_load_be16(condt, r_A, r_scratch, ctx); + else if (load_order == 2) + emit_load_be32(condt, r_A, r_scratch, ctx); + + _emit(condt, ARM_B(b_imm(i + 1, ctx)), ctx); + + /* the slowpath */ + emit_mov_i(ARM_R3, (u32)load_func[load_order], ctx); + emit(ARM_MOV_R(ARM_R0, r_skb), ctx); + /* the offset is already in R1 */ + emit_blx_r(ARM_R3, ctx); + /* check the result of skb_copy_bits */ + emit(ARM_CMP_I(ARM_R1, 0), ctx); + emit_err_ret(ARM_COND_NE, ctx); + emit(ARM_MOV_R(r_A, ARM_R0), ctx); + break; + case BPF_S_LD_W_IND: + load_order = 2; + goto load_ind; + case BPF_S_LD_H_IND: + load_order = 1; + goto load_ind; + case BPF_S_LD_B_IND: + load_order = 0; +load_ind: + OP_IMM3(ARM_ADD, r_off, r_X, k, ctx); + goto load_common; + case BPF_S_LDX_IMM: + ctx->seen |= SEEN_X; + emit_mov_i(r_X, k, ctx); + break; + case BPF_S_LDX_W_LEN: + ctx->seen |= SEEN_X | SEEN_SKB; + emit(ARM_LDR_I(r_X, r_skb, + offsetof(struct sk_buff, len)), ctx); + break; + case BPF_S_LDX_MEM: + ctx->seen |= SEEN_X | SEEN_MEM_WORD(k); + emit(ARM_LDR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx); + break; + case BPF_S_LDX_B_MSH: + /* x = ((*(frame + k)) & 0xf) << 2; */ + ctx->seen |= SEEN_X | SEEN_DATA | SEEN_CALL; + /* the interpreter should deal with the negative K */ + if (k < 0) + return -1; + /* offset in r1: we might have to take the slow path */ + emit_mov_i(r_off, k, ctx); + emit(ARM_CMP_R(r_skb_hl, r_off), ctx); + + /* load in r0: common with the slowpath */ + _emit(ARM_COND_HI, ARM_LDRB_R(ARM_R0, r_skb_data, + ARM_R1), ctx); + /* + * emit_mov_i() might generate one or two instructions, + * the same holds for emit_blx_r() + */ + _emit(ARM_COND_HI, ARM_B(b_imm(i + 1, ctx) - 2), ctx); + + emit(ARM_MOV_R(ARM_R0, r_skb), ctx); + /* r_off is r1 */ + emit_mov_i(ARM_R3, (u32)jit_get_skb_b, ctx); + emit_blx_r(ARM_R3, ctx); + /* check the return value of skb_copy_bits */ + emit(ARM_CMP_I(ARM_R1, 0), ctx); + emit_err_ret(ARM_COND_NE, ctx); + + emit(ARM_AND_I(r_X, ARM_R0, 0x00f), ctx); + emit(ARM_LSL_I(r_X, r_X, 2), ctx); + break; + case BPF_S_ST: + ctx->seen |= SEEN_MEM_WORD(k); + emit(ARM_STR_I(r_A, ARM_SP, SCRATCH_OFF(k)), ctx); + break; + case BPF_S_STX: + update_on_xread(ctx); + ctx->seen |= SEEN_MEM_WORD(k); + emit(ARM_STR_I(r_X, ARM_SP, SCRATCH_OFF(k)), ctx); + break; + case BPF_S_ALU_ADD_K: + /* A += K */ + OP_IMM3(ARM_ADD, r_A, r_A, k, ctx); + break; + case BPF_S_ALU_ADD_X: + update_on_xread(ctx); + emit(ARM_ADD_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_SUB_K: + /* A -= K */ + OP_IMM3(ARM_SUB, r_A, r_A, k, ctx); + break; + case BPF_S_ALU_SUB_X: + update_on_xread(ctx); + emit(ARM_SUB_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_MUL_K: + /* A *= K */ + emit_mov_i(r_scratch, k, ctx); + emit(ARM_MUL(r_A, r_A, r_scratch), ctx); + break; + case BPF_S_ALU_MUL_X: + update_on_xread(ctx); + emit(ARM_MUL(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_DIV_K: + /* current k == reciprocal_value(userspace k) */ + emit_mov_i(r_scratch, k, ctx); + /* A = top 32 bits of the product */ + emit(ARM_UMULL(r_scratch, r_A, r_A, r_scratch), ctx); + break; + case BPF_S_ALU_DIV_X: + update_on_xread(ctx); + emit(ARM_CMP_I(r_X, 0), ctx); + emit_err_ret(ARM_COND_EQ, ctx); + emit_udiv(r_A, r_A, r_X, ctx); + break; + case BPF_S_ALU_OR_K: + /* A |= K */ + OP_IMM3(ARM_ORR, r_A, r_A, k, ctx); + break; + case BPF_S_ALU_OR_X: + update_on_xread(ctx); + emit(ARM_ORR_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_AND_K: + /* A &= K */ + OP_IMM3(ARM_AND, r_A, r_A, k, ctx); + break; + case BPF_S_ALU_AND_X: + update_on_xread(ctx); + emit(ARM_AND_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_LSH_K: + if (unlikely(k > 31)) + return -1; + emit(ARM_LSL_I(r_A, r_A, k), ctx); + break; + case BPF_S_ALU_LSH_X: + update_on_xread(ctx); + emit(ARM_LSL_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_RSH_K: + if (unlikely(k > 31)) + return -1; + emit(ARM_LSR_I(r_A, r_A, k), ctx); + break; + case BPF_S_ALU_RSH_X: + update_on_xread(ctx); + emit(ARM_LSR_R(r_A, r_A, r_X), ctx); + break; + case BPF_S_ALU_NEG: + /* A = -A */ + emit(ARM_RSB_I(r_A, r_A, 0), ctx); + break; + case BPF_S_JMP_JA: + /* pc += K */ + emit(ARM_B(b_imm(i + k + 1, ctx)), ctx); + break; + case BPF_S_JMP_JEQ_K: + /* pc += (A == K) ? pc->jt : pc->jf */ + condt = ARM_COND_EQ; + goto cmp_imm; + case BPF_S_JMP_JGT_K: + /* pc += (A > K) ? pc->jt : pc->jf */ + condt = ARM_COND_HI; + goto cmp_imm; + case BPF_S_JMP_JGE_K: + /* pc += (A >= K) ? pc->jt : pc->jf */ + condt = ARM_COND_HS; +cmp_imm: + imm12 = imm8m(k); + if (imm12 < 0) { + emit_mov_i_no8m(r_scratch, k, ctx); + emit(ARM_CMP_R(r_A, r_scratch), ctx); + } else { + emit(ARM_CMP_I(r_A, imm12), ctx); + } +cond_jump: + if (inst->jt) + _emit(condt, ARM_B(b_imm(i + inst->jt + 1, + ctx)), ctx); + if (inst->jf) + _emit(condt ^ 1, ARM_B(b_imm(i + inst->jf + 1, + ctx)), ctx); + break; + case BPF_S_JMP_JEQ_X: + /* pc += (A == X) ? pc->jt : pc->jf */ + condt = ARM_COND_EQ; + goto cmp_x; + case BPF_S_JMP_JGT_X: + /* pc += (A > X) ? pc->jt : pc->jf */ + condt = ARM_COND_HI; + goto cmp_x; + case BPF_S_JMP_JGE_X: + /* pc += (A >= X) ? pc->jt : pc->jf */ + condt = ARM_COND_CS; +cmp_x: + update_on_xread(ctx); + emit(ARM_CMP_R(r_A, r_X), ctx); + goto cond_jump; + case BPF_S_JMP_JSET_K: + /* pc += (A & K) ? pc->jt : pc->jf */ + condt = ARM_COND_NE; + /* not set iff all zeroes iff Z==1 iff EQ */ + + imm12 = imm8m(k); + if (imm12 < 0) { + emit_mov_i_no8m(r_scratch, k, ctx); + emit(ARM_TST_R(r_A, r_scratch), ctx); + } else { + emit(ARM_TST_I(r_A, imm12), ctx); + } + goto cond_jump; + case BPF_S_JMP_JSET_X: + /* pc += (A & X) ? pc->jt : pc->jf */ + update_on_xread(ctx); + condt = ARM_COND_NE; + emit(ARM_TST_R(r_A, r_X), ctx); + goto cond_jump; + case BPF_S_RET_A: + emit(ARM_MOV_R(ARM_R0, r_A), ctx); + goto b_epilogue; + case BPF_S_RET_K: + if ((k == 0) && (ctx->ret0_fp_idx < 0)) + ctx->ret0_fp_idx = i; + emit_mov_i(ARM_R0, k, ctx); +b_epilogue: + if (i != ctx->skf->len - 1) + emit(ARM_B(b_imm(prog->len, ctx)), ctx); + break; + case BPF_S_MISC_TAX: + /* X = A */ + ctx->seen |= SEEN_X; + emit(ARM_MOV_R(r_X, r_A), ctx); + break; + case BPF_S_MISC_TXA: + /* A = X */ + update_on_xread(ctx); + emit(ARM_MOV_R(r_A, r_X), ctx); + break; + case BPF_S_ANC_PROTOCOL: + /* A = ntohs(skb->protocol) */ + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, + protocol) != 2); + off = offsetof(struct sk_buff, protocol); + emit(ARM_LDRH_I(r_scratch, r_skb, off), ctx); + emit_swap16(r_A, r_scratch, ctx); + break; + case BPF_S_ANC_CPU: + /* r_scratch = current_thread_info() */ + OP_IMM3(ARM_BIC, r_scratch, ARM_SP, THREAD_SIZE - 1, ctx); + /* A = current_thread_info()->cpu */ + BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, cpu) != 4); + off = offsetof(struct thread_info, cpu); + emit(ARM_LDR_I(r_A, r_scratch, off), ctx); + break; + case BPF_S_ANC_IFINDEX: + /* A = skb->dev->ifindex */ + ctx->seen |= SEEN_SKB; + off = offsetof(struct sk_buff, dev); + emit(ARM_LDR_I(r_scratch, r_skb, off), ctx); + + emit(ARM_CMP_I(r_scratch, 0), ctx); + emit_err_ret(ARM_COND_EQ, ctx); + + BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, + ifindex) != 4); + off = offsetof(struct net_device, ifindex); + emit(ARM_LDR_I(r_A, r_scratch, off), ctx); + break; + case BPF_S_ANC_MARK: + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); + off = offsetof(struct sk_buff, mark); + emit(ARM_LDR_I(r_A, r_skb, off), ctx); + break; + case BPF_S_ANC_RXHASH: + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4); + off = offsetof(struct sk_buff, rxhash); + emit(ARM_LDR_I(r_A, r_skb, off), ctx); + break; + case BPF_S_ANC_QUEUE: + ctx->seen |= SEEN_SKB; + BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, + queue_mapping) != 2); + BUILD_BUG_ON(offsetof(struct sk_buff, + queue_mapping) > 0xff); + off = offsetof(struct sk_buff, queue_mapping); + emit(ARM_LDRH_I(r_A, r_skb, off), ctx); + break; + default: + return -1; + } + } + + /* compute offsets only during the first pass */ + if (ctx->target == NULL) + ctx->offsets[i] = ctx->idx * 4; + + return 0; +} + + +void bpf_jit_compile(struct sk_filter *fp) +{ + struct jit_ctx ctx; + unsigned tmp_idx; + unsigned alloc_size; + + if (!bpf_jit_enable) + return; + + memset(&ctx, 0, sizeof(ctx)); + ctx.skf = fp; + ctx.ret0_fp_idx = -1; + + ctx.offsets = kzalloc(GFP_KERNEL, 4 * (ctx.skf->len + 1)); + if (ctx.offsets == NULL) + return; + + /* fake pass to fill in the ctx->seen */ + if (unlikely(build_body(&ctx))) + goto out; + + tmp_idx = ctx.idx; + build_prologue(&ctx); + ctx.prologue_bytes = (ctx.idx - tmp_idx) * 4; + +#if __LINUX_ARM_ARCH__ < 7 + tmp_idx = ctx.idx; + build_epilogue(&ctx); + ctx.epilogue_bytes = (ctx.idx - tmp_idx) * 4; + + ctx.idx += ctx.imm_count; + if (ctx.imm_count) { + ctx.imms = kzalloc(GFP_KERNEL, 4 * ctx.imm_count); + if (ctx.imms == NULL) + goto out; + } +#else + /* there's nothing after the epilogue on ARMv7 */ + build_epilogue(&ctx); +#endif + + alloc_size = 4 * ctx.idx; + ctx.target = module_alloc(max(sizeof(struct work_struct), + alloc_size)); + if (unlikely(ctx.target == NULL)) + goto out; + + ctx.idx = 0; + build_prologue(&ctx); + build_body(&ctx); + build_epilogue(&ctx); + + flush_icache_range((u32)ctx.target, (u32)(ctx.target + ctx.idx)); + +#if __LINUX_ARM_ARCH__ < 7 + if (ctx.imm_count) + kfree(ctx.imms); +#endif + + if (bpf_jit_enable > 1) + print_hex_dump(KERN_INFO, "BPF JIT code: ", + DUMP_PREFIX_ADDRESS, 16, 4, ctx.target, + alloc_size, false); + + fp->bpf_func = (void *)ctx.target; +out: + kfree(ctx.offsets); + return; +} + +static void bpf_jit_free_worker(struct work_struct *work) +{ + module_free(NULL, work); +} + +void bpf_jit_free(struct sk_filter *fp) +{ + struct work_struct *work; + + if (fp->bpf_func != sk_run_filter) { + work = (struct work_struct *)fp->bpf_func; + + INIT_WORK(work, bpf_jit_free_worker); + schedule_work(work); + } +} diff --git a/arch/arm/net/bpf_jit_32.h b/arch/arm/net/bpf_jit_32.h new file mode 100644 index 00000000000..99ae5e3f46d --- /dev/null +++ b/arch/arm/net/bpf_jit_32.h @@ -0,0 +1,190 @@ +/* + * Just-In-Time compiler for BPF filters on 32bit ARM + * + * Copyright (c) 2011 Mircea Gherzan <mgherzan@gmail.com> + * + * 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; version 2 of the License. + */ + +#ifndef PFILTER_OPCODES_ARM_H +#define PFILTER_OPCODES_ARM_H + +#define ARM_R0 0 +#define ARM_R1 1 +#define ARM_R2 2 +#define ARM_R3 3 +#define ARM_R4 4 +#define ARM_R5 5 +#define ARM_R6 6 +#define ARM_R7 7 +#define ARM_R8 8 +#define ARM_R9 9 +#define ARM_R10 10 +#define ARM_FP 11 +#define ARM_IP 12 +#define ARM_SP 13 +#define ARM_LR 14 +#define ARM_PC 15 + +#define ARM_COND_EQ 0x0 +#define ARM_COND_NE 0x1 +#define ARM_COND_CS 0x2 +#define ARM_COND_HS ARM_COND_CS +#define ARM_COND_CC 0x3 +#define ARM_COND_LO ARM_COND_CC +#define ARM_COND_MI 0x4 +#define ARM_COND_PL 0x5 +#define ARM_COND_VS 0x6 +#define ARM_COND_VC 0x7 +#define ARM_COND_HI 0x8 +#define ARM_COND_LS 0x9 +#define ARM_COND_GE 0xa +#define ARM_COND_LT 0xb +#define ARM_COND_GT 0xc +#define ARM_COND_LE 0xd +#define ARM_COND_AL 0xe + +/* register shift types */ +#define SRTYPE_LSL 0 +#define SRTYPE_LSR 1 +#define SRTYPE_ASR 2 +#define SRTYPE_ROR 3 + +#define ARM_INST_ADD_R 0x00800000 +#define ARM_INST_ADD_I 0x02800000 + +#define ARM_INST_AND_R 0x00000000 +#define ARM_INST_AND_I 0x02000000 + +#define ARM_INST_BIC_R 0x01c00000 +#define ARM_INST_BIC_I 0x03c00000 + +#define ARM_INST_B 0x0a000000 +#define ARM_INST_BX 0x012FFF10 +#define ARM_INST_BLX_R 0x012fff30 + +#define ARM_INST_CMP_R 0x01500000 +#define ARM_INST_CMP_I 0x03500000 + +#define ARM_INST_LDRB_I 0x05d00000 +#define ARM_INST_LDRB_R 0x07d00000 +#define ARM_INST_LDRH_I 0x01d000b0 +#define ARM_INST_LDR_I 0x05900000 + +#define ARM_INST_LDM 0x08900000 + +#define ARM_INST_LSL_I 0x01a00000 +#define ARM_INST_LSL_R 0x01a00010 + +#define ARM_INST_LSR_I 0x01a00020 +#define ARM_INST_LSR_R 0x01a00030 + +#define ARM_INST_MOV_R 0x01a00000 +#define ARM_INST_MOV_I 0x03a00000 +#define ARM_INST_MOVW 0x03000000 +#define ARM_INST_MOVT 0x03400000 + +#define ARM_INST_MUL 0x00000090 + +#define ARM_INST_POP 0x08bd0000 +#define ARM_INST_PUSH 0x092d0000 + +#define ARM_INST_ORR_R 0x01800000 +#define ARM_INST_ORR_I 0x03800000 + +#define ARM_INST_REV 0x06bf0f30 +#define ARM_INST_REV16 0x06bf0fb0 + +#define ARM_INST_RSB_I 0x02600000 + +#define ARM_INST_SUB_R 0x00400000 +#define ARM_INST_SUB_I 0x02400000 + +#define ARM_INST_STR_I 0x05800000 + +#define ARM_INST_TST_R 0x01100000 +#define ARM_INST_TST_I 0x03100000 + +#define ARM_INST_UDIV 0x0730f010 + +#define ARM_INST_UMULL 0x00800090 + +/* register */ +#define _AL3_R(op, rd, rn, rm) ((op ## _R) | (rd) << 12 | (rn) << 16 | (rm)) +/* immediate */ +#define _AL3_I(op, rd, rn, imm) ((op ## _I) | (rd) << 12 | (rn) << 16 | (imm)) + +#define ARM_ADD_R(rd, rn, rm) _AL3_R(ARM_INST_ADD, rd, rn, rm) +#define ARM_ADD_I(rd, rn, imm) _AL3_I(ARM_INST_ADD, rd, rn, imm) + +#define ARM_AND_R(rd, rn, rm) _AL3_R(ARM_INST_AND, rd, rn, rm) +#define ARM_AND_I(rd, rn, imm) _AL3_I(ARM_INST_AND, rd, rn, imm) + +#define ARM_BIC_R(rd, rn, rm) _AL3_R(ARM_INST_BIC, rd, rn, rm) +#define ARM_BIC_I(rd, rn, imm) _AL3_I(ARM_INST_BIC, rd, rn, imm) + +#define ARM_B(imm24) (ARM_INST_B | ((imm24) & 0xffffff)) +#define ARM_BX(rm) (ARM_INST_BX | (rm)) +#define ARM_BLX_R(rm) (ARM_INST_BLX_R | (rm)) + +#define ARM_CMP_R(rn, rm) _AL3_R(ARM_INST_CMP, 0, rn, rm) +#define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm) + +#define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \ + | (off)) +#define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \ + | (off)) +#define ARM_LDRB_R(rt, rn, rm) (ARM_INST_LDRB_R | (rt) << 12 | (rn) << 16 \ + | (rm)) +#define ARM_LDRH_I(rt, rn, off) (ARM_INST_LDRH_I | (rt) << 12 | (rn) << 16 \ + | (((off) & 0xf0) << 4) | ((off) & 0xf)) + +#define ARM_LDM(rn, regs) (ARM_INST_LDM | (rn) << 16 | (regs)) + +#define ARM_LSL_R(rd, rn, rm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (rm) << 8) +#define ARM_LSL_I(rd, rn, imm) (_AL3_I(ARM_INST_LSL, rd, 0, rn) | (imm) << 7) + +#define ARM_LSR_R(rd, rn, rm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (rm) << 8) +#define ARM_LSR_I(rd, rn, imm) (_AL3_I(ARM_INST_LSR, rd, 0, rn) | (imm) << 7) + +#define ARM_MOV_R(rd, rm) _AL3_R(ARM_INST_MOV, rd, 0, rm) +#define ARM_MOV_I(rd, imm) _AL3_I(ARM_INST_MOV, rd, 0, imm) + +#define ARM_MOVW(rd, imm) \ + (ARM_INST_MOVW | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff)) + +#define ARM_MOVT(rd, imm) \ + (ARM_INST_MOVT | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff)) + +#define ARM_MUL(rd, rm, rn) (ARM_INST_MUL | (rd) << 16 | (rm) << 8 | (rn)) + +#define ARM_POP(regs) (ARM_INST_POP | (regs)) +#define ARM_PUSH(regs) (ARM_INST_PUSH | (regs)) + +#define ARM_ORR_R(rd, rn, rm) _AL3_R(ARM_INST_ORR, rd, rn, rm) +#define ARM_ORR_I(rd, rn, imm) _AL3_I(ARM_INST_ORR, rd, rn, imm) +#define ARM_ORR_S(rd, rn, rm, type, rs) \ + (ARM_ORR_R(rd, rn, rm) | (type) << 5 | (rs) << 7) + +#define ARM_REV(rd, rm) (ARM_INST_REV | (rd) << 12 | (rm)) +#define ARM_REV16(rd, rm) (ARM_INST_REV16 | (rd) << 12 | (rm)) + +#define ARM_RSB_I(rd, rn, imm) _AL3_I(ARM_INST_RSB, rd, rn, imm) + +#define ARM_SUB_R(rd, rn, rm) _AL3_R(ARM_INST_SUB, rd, rn, rm) +#define ARM_SUB_I(rd, rn, imm) _AL3_I(ARM_INST_SUB, rd, rn, imm) + +#define ARM_STR_I(rt, rn, off) (ARM_INST_STR_I | (rt) << 12 | (rn) << 16 \ + | (off)) + +#define ARM_TST_R(rn, rm) _AL3_R(ARM_INST_TST, 0, rn, rm) +#define ARM_TST_I(rn, imm) _AL3_I(ARM_INST_TST, 0, rn, imm) + +#define ARM_UDIV(rd, rn, rm) (ARM_INST_UDIV | (rd) << 16 | (rn) | (rm) << 8) + +#define ARM_UMULL(rd_lo, rd_hi, rn, rm) (ARM_INST_UMULL | (rd_hi) << 16 \ + | (rd_lo) << 12 | (rm) << 8 | rn) + +#endif /* PFILTER_OPCODES_ARM_H */ -- cgit v1.2.3-18-g5258 From 695436e3738ec6375a4a1026034d14433be3fb3a Mon Sep 17 00:00:00 2001 From: Linus Walleij <linus.walleij@linaro.org> Date: Sun, 26 Feb 2012 10:46:48 +0100 Subject: ARM: 7349/1: integrator: convert to sparse irqs This converts the Integrator AP/CP to use sparse IRQs. Tested on both machines. Acked-by: Rob Herring <rob.herring@calxeda.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/Kconfig | 1 + arch/arm/mach-integrator/core.c | 3 ++- arch/arm/mach-integrator/include/mach/irqs.h | 3 ++- arch/arm/mach-integrator/integrator_ap.c | 3 ++- arch/arm/mach-integrator/integrator_cp.c | 3 ++- arch/arm/mach-integrator/pci.c | 3 ++- arch/arm/mach-integrator/pci_v3.c | 3 ++- 7 files changed, 13 insertions(+), 6 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 746ab6d6a20..93f89d5b24c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -269,6 +269,7 @@ config ARCH_INTEGRATOR select PLAT_VERSATILE select PLAT_VERSATILE_FPGA_IRQ select NEED_MACH_MEMORY_H + select SPARSE_IRQ help Support for ARM's Integrator platform. diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 019f0ab08f6..cba1907c2e1 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -25,8 +25,9 @@ #include <mach/hardware.h> #include <mach/platform.h> -#include <asm/irq.h> #include <mach/cm.h> +#include <mach/irqs.h> + #include <asm/system.h> #include <asm/leds.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-integrator/include/mach/irqs.h b/arch/arm/mach-integrator/include/mach/irqs.h index 1fbe6d19022..a19a1a2fcf6 100644 --- a/arch/arm/mach-integrator/include/mach/irqs.h +++ b/arch/arm/mach-integrator/include/mach/irqs.h @@ -78,5 +78,6 @@ #define IRQ_SIC_CP_LMINT7 46 #define IRQ_SIC_END 46 -#define NR_IRQS 47 +#define NR_IRQS_INTEGRATOR_AP 34 +#define NR_IRQS_INTEGRATOR_CP 47 diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 4dde28b9dc0..871f148ffd7 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -38,13 +38,13 @@ #include <mach/hardware.h> #include <mach/platform.h> #include <asm/hardware/arm_timer.h> -#include <asm/irq.h> #include <asm/setup.h> #include <asm/param.h> /* HZ */ #include <asm/mach-types.h> #include <asm/sched_clock.h> #include <mach/lm.h> +#include <mach/irqs.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> @@ -475,6 +475,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator") .atag_offset = 0x100, .reserve = integrator_reserve, .map_io = ap_map_io, + .nr_irqs = NR_IRQS_INTEGRATOR_AP, .init_early = integrator_init_early, .init_irq = ap_init_irq, .timer = &ap_timer, diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index a8b6aa6003f..38d997dc96f 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -26,7 +26,6 @@ #include <mach/hardware.h> #include <mach/platform.h> -#include <asm/irq.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/hardware/arm_timer.h> @@ -34,6 +33,7 @@ #include <mach/cm.h> #include <mach/lm.h> +#include <mach/irqs.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> @@ -495,6 +495,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") .atag_offset = 0x100, .reserve = integrator_reserve, .map_io = intcp_map_io, + .nr_irqs = NR_IRQS_INTEGRATOR_CP, .init_early = intcp_init_early, .init_irq = intcp_init_irq, .timer = &cp_timer, diff --git a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c index 520b6bf81bb..e15aa43cfd2 100644 --- a/arch/arm/mach-integrator/pci.c +++ b/arch/arm/mach-integrator/pci.c @@ -26,11 +26,12 @@ #include <linux/interrupt.h> #include <linux/init.h> -#include <asm/irq.h> #include <asm/system.h> #include <asm/mach/pci.h> #include <asm/mach-types.h> +#include <mach/irqs.h> + /* * A small note about bridges and interrupts. The DECchip 21050 (and * later) adheres to the PCI-PCI bridge specification. This says that diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 3c82566acec..65e5896630e 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -30,7 +30,8 @@ #include <mach/hardware.h> #include <mach/platform.h> -#include <asm/irq.h> +#include <mach/irqs.h> + #include <asm/signal.h> #include <asm/system.h> #include <asm/mach/pci.h> -- cgit v1.2.3-18-g5258 From 38b4205abeaed7eaae0a2a9e9af8e1252fa5c86a Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Date: Wed, 14 Mar 2012 10:30:52 +0100 Subject: ARM: 7361/1: provide XIP_VIRT_ADDR for no-MMU builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit XIP_VIRT_ADDR is needed for XIP builds and currently only defined for builds with CONFIG_MMU. Also provide it for no-MMU builds to make it possible to build an XIP kernel for MMU-less machines. As these lack an MMU it has to be an identity mapping. Acked-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/include/asm/memory.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index a8997d71084..fcb575747e5 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -116,6 +116,8 @@ #define MODULES_END (END_MEM) #define MODULES_VADDR (PHYS_OFFSET) +#define XIP_VIRT_ADDR(physaddr) (physaddr) + #endif /* !CONFIG_MMU */ /* -- cgit v1.2.3-18-g5258 From fada8dcf2d085f4e2eb1ba760c8d37111977dbec Mon Sep 17 00:00:00 2001 From: Russell King <rmk+kernel@arm.linux.org.uk> Date: Tue, 27 Mar 2012 10:44:23 +0100 Subject: ARM: fix Kconfig warning for HAVE_BPF_JIT Last night's randconfig and the allnoconfig builds spat out the following warning while building: warning: (ARM) selects HAVE_BPF_JIT which has unmet direct dependencies (NET) Acked-by: Mircea Gherzan <mgherzan@gmail.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> --- arch/arm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 93f89d5b24c..be8f634f001 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -34,7 +34,7 @@ config ARM select GENERIC_IRQ_SHOW select CPU_PM if (SUSPEND || CPU_IDLE) select GENERIC_PCI_IOMAP - select HAVE_BPF_JIT + select HAVE_BPF_JIT if NET help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and -- cgit v1.2.3-18-g5258