diff options
Diffstat (limited to 'arch/mips/include/asm')
62 files changed, 931 insertions, 801 deletions
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 7fe5c61a3cb8..40ec4ca3f946 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild @@ -7,6 +7,7 @@ generic-y += emergency-restart.h  generic-y += irq_work.h  generic-y += local64.h  generic-y += mcs_spinlock.h +generic-y += mm-arch-hooks.h  generic-y += mutex.h  generic-y += parport.h  generic-y += percpu.h @@ -15,6 +16,5 @@ generic-y += sections.h  generic-y += segment.h  generic-y += serial.h  generic-y += trace_clock.h -generic-y += ucontext.h  generic-y += user.h  generic-y += xor.h diff --git a/arch/mips/include/asm/abi.h b/arch/mips/include/asm/abi.h index 7186bb51b89b..37f84078e78a 100644 --- a/arch/mips/include/asm/abi.h +++ b/arch/mips/include/asm/abi.h @@ -20,6 +20,10 @@ struct mips_abi {  				     struct pt_regs *regs, sigset_t *set);  	const unsigned long	rt_signal_return_offset;  	const unsigned long	restart; + +	unsigned	off_sc_fpregs; +	unsigned	off_sc_fpc_csr; +	unsigned	off_sc_used_math;  };  #endif /* _ASM_ABI_H */ diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index 76317a70200d..867f924b05c7 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h @@ -232,6 +232,30 @@  	.set	pop  	.endm +	.macro	ld_b	wd, off, base +	.set	push +	.set	mips32r2 +	.set	msa +	ld.b	$w\wd, \off(\base) +	.set	pop +	.endm + +	.macro	ld_h	wd, off, base +	.set	push +	.set	mips32r2 +	.set	msa +	ld.h	$w\wd, \off(\base) +	.set	pop +	.endm + +	.macro	ld_w	wd, off, base +	.set	push +	.set	mips32r2 +	.set	msa +	ld.w	$w\wd, \off(\base) +	.set	pop +	.endm +  	.macro	ld_d	wd, off, base  	.set	push  	.set	mips32r2 @@ -241,6 +265,30 @@  	.set	pop  	.endm +	.macro	st_b	wd, off, base +	.set	push +	.set	mips32r2 +	.set	msa +	st.b	$w\wd, \off(\base) +	.set	pop +	.endm + +	.macro	st_h	wd, off, base +	.set	push +	.set	mips32r2 +	.set	msa +	st.h	$w\wd, \off(\base) +	.set	pop +	.endm + +	.macro	st_w	wd, off, base +	.set	push +	.set	mips32r2 +	.set	msa +	st.w	$w\wd, \off(\base) +	.set	pop +	.endm +  	.macro	st_d	wd, off, base  	.set	push  	.set	mips32r2 @@ -290,7 +338,13 @@  #ifdef CONFIG_CPU_MICROMIPS  #define CFC_MSA_INSN		0x587e0056  #define CTC_MSA_INSN		0x583e0816 +#define LDB_MSA_INSN		0x58000807 +#define LDH_MSA_INSN		0x58000817 +#define LDW_MSA_INSN		0x58000827  #define LDD_MSA_INSN		0x58000837 +#define STB_MSA_INSN		0x5800080f +#define STH_MSA_INSN		0x5800081f +#define STW_MSA_INSN		0x5800082f  #define STD_MSA_INSN		0x5800083f  #define COPY_UW_MSA_INSN	0x58f00056  #define COPY_UD_MSA_INSN	0x58f80056 @@ -299,7 +353,13 @@  #else  #define CFC_MSA_INSN		0x787e0059  #define CTC_MSA_INSN		0x783e0819 +#define LDB_MSA_INSN		0x78000820 +#define LDH_MSA_INSN		0x78000821 +#define LDW_MSA_INSN		0x78000822  #define LDD_MSA_INSN		0x78000823 +#define STB_MSA_INSN		0x78000824 +#define STH_MSA_INSN		0x78000825 +#define STW_MSA_INSN		0x78000826  #define STD_MSA_INSN		0x78000827  #define COPY_UW_MSA_INSN	0x78f00059  #define COPY_UD_MSA_INSN	0x78f80059 @@ -329,6 +389,33 @@  	.set	pop  	.endm +	.macro	ld_b	wd, off, base +	.set	push +	.set	noat +	SET_HARDFLOAT +	addu	$1, \base, \off +	.word	LDB_MSA_INSN | (\wd << 6) +	.set	pop +	.endm + +	.macro	ld_h	wd, off, base +	.set	push +	.set	noat +	SET_HARDFLOAT +	addu	$1, \base, \off +	.word	LDH_MSA_INSN | (\wd << 6) +	.set	pop +	.endm + +	.macro	ld_w	wd, off, base +	.set	push +	.set	noat +	SET_HARDFLOAT +	addu	$1, \base, \off +	.word	LDW_MSA_INSN | (\wd << 6) +	.set	pop +	.endm +  	.macro	ld_d	wd, off, base  	.set	push  	.set	noat @@ -338,6 +425,33 @@  	.set	pop  	.endm +	.macro	st_b	wd, off, base +	.set	push +	.set	noat +	SET_HARDFLOAT +	addu	$1, \base, \off +	.word	STB_MSA_INSN | (\wd << 6) +	.set	pop +	.endm + +	.macro	st_h	wd, off, base +	.set	push +	.set	noat +	SET_HARDFLOAT +	addu	$1, \base, \off +	.word	STH_MSA_INSN | (\wd << 6) +	.set	pop +	.endm + +	.macro	st_w	wd, off, base +	.set	push +	.set	noat +	SET_HARDFLOAT +	addu	$1, \base, \off +	.word	STW_MSA_INSN | (\wd << 6) +	.set	pop +	.endm +  	.macro	st_d	wd, off, base  	.set	push  	.set	noat diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 26d436336f2e..4c42fd9af777 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -137,6 +137,10 @@ static __inline__ int atomic_##op##_return(int i, atomic_t * v)		      \  ATOMIC_OPS(add, +=, addu)  ATOMIC_OPS(sub, -=, subu) +ATOMIC_OP(and, &=, and) +ATOMIC_OP(or, |=, or) +ATOMIC_OP(xor, ^=, xor) +  #undef ATOMIC_OPS  #undef ATOMIC_OP_RETURN  #undef ATOMIC_OP @@ -416,6 +420,9 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v)	      \  ATOMIC64_OPS(add, +=, daddu)  ATOMIC64_OPS(sub, -=, dsubu) +ATOMIC64_OP(and, &=, and) +ATOMIC64_OP(or, |=, or) +ATOMIC64_OP(xor, ^=, xor)  #undef ATOMIC64_OPS  #undef ATOMIC64_OP_RETURN diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h index 7ecba84656d4..752e0b86c171 100644 --- a/arch/mips/include/asm/barrier.h +++ b/arch/mips/include/asm/barrier.h @@ -133,12 +133,12 @@  do {									\  	compiletime_assert_atomic_type(*p);				\  	smp_mb();							\ -	ACCESS_ONCE(*p) = (v);						\ +	WRITE_ONCE(*p, v);						\  } while (0)  #define smp_load_acquire(p)						\  ({									\ -	typeof(*p) ___p1 = ACCESS_ONCE(*p);				\ +	typeof(*p) ___p1 = READ_ONCE(*p);				\  	compiletime_assert_atomic_type(*p);				\  	smp_mb();							\  	___p1;								\ diff --git a/arch/mips/include/asm/cdmm.h b/arch/mips/include/asm/cdmm.h index 16e22ce9719f..bece2064cc8c 100644 --- a/arch/mips/include/asm/cdmm.h +++ b/arch/mips/include/asm/cdmm.h @@ -53,7 +53,7 @@ struct mips_cdmm_driver {   * mips_cdmm_phys_base() - Choose a physical base address for CDMM region.   *   * Picking a suitable physical address at which to map the CDMM region is - * platform specific, so this weak function can be defined by platform code to + * platform specific, so this function can be defined by platform code to   * pick a suitable value if none is configured by the bootloader.   *   * This address must be 32kB aligned, and the region occupies a maximum of 32kB @@ -61,7 +61,7 @@ struct mips_cdmm_driver {   *   * Returns:	Physical base address for CDMM region, or 0 on failure.   */ -phys_addr_t __weak mips_cdmm_phys_base(void); +phys_addr_t mips_cdmm_phys_base(void);  extern struct bus_type mips_cdmm_bustype;  void __iomem *mips_cdmm_early_probe(unsigned int dev_type); diff --git a/arch/mips/include/asm/cevt-r4k.h b/arch/mips/include/asm/cevt-r4k.h index f0edf6fcd002..2e13a038d260 100644 --- a/arch/mips/include/asm/cevt-r4k.h +++ b/arch/mips/include/asm/cevt-r4k.h @@ -21,7 +21,6 @@ DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device);  void mips_event_handler(struct clock_event_device *dev);  int c0_compare_int_usable(void); -void mips_set_clock_mode(enum clock_event_mode, struct clock_event_device *);  irqreturn_t c0_compare_interrupt(int, void *);  extern struct irqaction c0_compare_irqaction; diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index f25de771f7ed..9801ac982655 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -411,4 +411,8 @@  # define cpu_has_cdmm		(cpu_data[0].options & MIPS_CPU_CDMM)  #endif +#ifndef cpu_has_small_pages +# define cpu_has_small_pages	(cpu_data[0].options & MIPS_CPU_SP) +#endif +  #endif /* __ASM_CPU_FEATURES_H */ diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index d41e8e284825..abee2bfd10dc 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h @@ -77,6 +77,10 @@ static inline int __pure __get_cpu_type(const int cpu_type)  	 */  #endif +#ifdef CONFIG_SYS_HAS_CPU_MIPS64_R6 +	case CPU_I6400: +#endif +  #ifdef CONFIG_SYS_HAS_CPU_R3000  	case CPU_R2000:  	case CPU_R3000: diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index e46e40602af3..cd89e9855775 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -120,6 +120,7 @@  #define PRID_IMP_PROAPTIV_MP	0xa300  #define PRID_IMP_M5150		0xa700  #define PRID_IMP_P5600		0xa800 +#define PRID_IMP_I6400		0xa900  /*   * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE @@ -307,6 +308,7 @@ enum cpu_type_enum {  	CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,  	CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,  	CPU_M14KEC, CPU_INTERAPTIV, CPU_P5600, CPU_PROAPTIV, CPU_1074K, CPU_M5150, +	CPU_I6400,  	/*  	 * MIPS64 class processors @@ -382,6 +384,7 @@ enum cpu_type_enum {  #define MIPS_CPU_XPA		0x2000000000ull /* CPU supports Extended Physical Addressing */  #define MIPS_CPU_CDMM		0x4000000000ull	/* CPU has Common Device Memory Map */  #define MIPS_CPU_BP_GHIST	0x8000000000ull /* R12K+ Branch Prediction Global History */ +#define MIPS_CPU_SP		0x10000000000ull /* Small (1KB) page support */  /*   * CPU ASE encodings diff --git a/arch/mips/include/asm/debug.h b/arch/mips/include/asm/debug.h deleted file mode 100644 index 1fd5a2b39445..000000000000 --- a/arch/mips/include/asm/debug.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Debug macros for run-time debugging. - * Turned on/off with CONFIG_RUNTIME_DEBUG option. - * - * Copyright (C) 2001 MontaVista Software Inc. - * Author: Jun Sun, [email protected] or [email protected] - * - * 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. - * - */ - -#ifndef _ASM_DEBUG_H -#define _ASM_DEBUG_H - - -/* - * run-time macros for catching spurious errors.  Eable CONFIG_RUNTIME_DEBUG in - * kernel hacking config menu to use them. - * - * Use them as run-time debugging aid.  NEVER USE THEM AS ERROR HANDLING CODE!!! - */ - -#ifdef CONFIG_RUNTIME_DEBUG - -#include <linux/kernel.h> - -#define db_assert(x)  if (!(x)) { \ -	panic("assertion failed at %s:%d: %s", __FILE__, __LINE__, #x); } -#define db_warn(x)  if (!(x)) { \ -	printk(KERN_WARNING "warning at %s:%d: %s", __FILE__, __LINE__, #x); } -#define db_verify(x, y) db_assert(x y) -#define db_verify_warn(x, y) db_warn(x y) -#define db_run(x)  do { x; } while (0) - -#else - -#define db_assert(x) -#define db_warn(x) -#define db_verify(x, y) x -#define db_verify_warn(x, y) x -#define db_run(x) - -#endif - -#endif /* _ASM_DEBUG_H */ diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 360b3387182a..e604f760c4a0 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -4,7 +4,6 @@  #include <linux/scatterlist.h>  #include <asm/dma-coherence.h>  #include <asm/cache.h> -#include <asm-generic/dma-coherent.h>  #ifndef CONFIG_SGI_IP27 /* Kludge to fix 2.6.39 build for IP27 */  #include <dma-coherence.h> @@ -32,73 +31,7 @@ static inline void dma_mark_clean(void *addr, size_t size) {}  #include <asm-generic/dma-mapping-common.h> -static inline int dma_supported(struct device *dev, u64 mask) -{ -	struct dma_map_ops *ops = get_dma_ops(dev); -	return ops->dma_supported(dev, mask); -} - -static inline int dma_mapping_error(struct device *dev, u64 mask) -{ -	struct dma_map_ops *ops = get_dma_ops(dev); - -	debug_dma_mapping_error(dev, mask); -	return ops->mapping_error(dev, mask); -} - -static inline int -dma_set_mask(struct device *dev, u64 mask) -{ -	struct dma_map_ops *ops = get_dma_ops(dev); - -	if(!dev->dma_mask || !dma_supported(dev, mask)) -		return -EIO; - -	if (ops->set_dma_mask) -		return ops->set_dma_mask(dev, mask); - -	*dev->dma_mask = mask; - -	return 0; -} -  extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,  	       enum dma_data_direction direction); -#define dma_alloc_coherent(d,s,h,f)	dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, -				    dma_addr_t *dma_handle, gfp_t gfp, -				    struct dma_attrs *attrs) -{ -	void *ret; -	struct dma_map_ops *ops = get_dma_ops(dev); - -	ret = ops->alloc(dev, size, dma_handle, gfp, attrs); - -	debug_dma_alloc_coherent(dev, size, *dma_handle, ret); - -	return ret; -} - -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, -				  void *vaddr, dma_addr_t dma_handle, -				  struct dma_attrs *attrs) -{ -	struct dma_map_ops *ops = get_dma_ops(dev); - -	ops->free(dev, size, vaddr, dma_handle, attrs); - -	debug_dma_free_coherent(dev, size, vaddr, dma_handle); -} - - -void *dma_alloc_noncoherent(struct device *dev, size_t size, -			   dma_addr_t *dma_handle, gfp_t flag); - -void dma_free_noncoherent(struct device *dev, size_t size, -			 void *vaddr, dma_addr_t dma_handle); -  #endif /* _ASM_DMA_MAPPING_H */ diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index f19e890b99d2..53b26933b12c 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -382,7 +382,9 @@ do {									\     instruction set this cpu supports.  This could be done in userspace,     but it's not easy, and we've already done it here.  */ -#define ELF_HWCAP	(0) +#define ELF_HWCAP	(elf_hwcap) +extern unsigned int elf_hwcap; +#include <asm/hwcap.h>  /*   * This yields a string that ld.so will use to load implementation diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index 084780b355aa..9cbf383b8834 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h @@ -74,7 +74,7 @@ static inline int __enable_fpu(enum fpu_mode mode)  		goto fr_common;  	case FPU_64BIT: -#if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6) \ +#if !(defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) \        || defined(CONFIG_64BIT))  		/* we only have a 32-bit FPU */  		return SIGFPE; @@ -164,25 +164,30 @@ static inline int own_fpu(int restore)  	return ret;  } -static inline void lose_fpu(int save) +static inline void lose_fpu_inatomic(int save, struct task_struct *tsk)  { -	preempt_disable();  	if (is_msa_enabled()) {  		if (save) { -			save_msa(current); -			current->thread.fpu.fcr31 = +			save_msa(tsk); +			tsk->thread.fpu.fcr31 =  					read_32bit_cp1_register(CP1_STATUS);  		}  		disable_msa(); -		clear_thread_flag(TIF_USEDMSA); +		clear_tsk_thread_flag(tsk, TIF_USEDMSA);  		__disable_fpu();  	} else if (is_fpu_owner()) {  		if (save) -			_save_fp(current); +			_save_fp(tsk);  		__disable_fpu();  	} -	KSTK_STATUS(current) &= ~ST0_CU1; -	clear_thread_flag(TIF_USEDFPU); +	KSTK_STATUS(tsk) &= ~ST0_CU1; +	clear_tsk_thread_flag(tsk, TIF_USEDFPU); +} + +static inline void lose_fpu(int save) +{ +	preempt_disable(); +	lose_fpu_inatomic(save, current);  	preempt_enable();  } diff --git a/arch/mips/include/asm/gpio.h b/arch/mips/include/asm/gpio.h deleted file mode 100644 index 06e46faf862d..000000000000 --- a/arch/mips/include/asm/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_MIPS_GPIO_H -#define __ASM_MIPS_GPIO_H - -#include <gpio.h> - -#endif /* __ASM_MIPS_GPIO_H */ diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index f0db99f8defe..15e0fecbc300 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h @@ -49,7 +49,7 @@ extern int cp0_compare_irq_shift;  extern int cp0_perfcount_irq;  extern int cp0_fdc_irq; -extern int __weak get_c0_fdc_int(void); +extern int get_c0_fdc_int(void);  void arch_trigger_all_cpu_backtrace(bool);  #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace diff --git a/arch/mips/include/asm/jump_label.h b/arch/mips/include/asm/jump_label.h index 608aa57799c8..e77672539e8e 100644 --- a/arch/mips/include/asm/jump_label.h +++ b/arch/mips/include/asm/jump_label.h @@ -26,14 +26,29 @@  #define NOP_INSN "nop"  #endif -static __always_inline bool arch_static_branch(struct static_key *key) +static __always_inline bool arch_static_branch(struct static_key *key, bool branch)  {  	asm_volatile_goto("1:\t" NOP_INSN "\n\t"  		"nop\n\t"  		".pushsection __jump_table,  \"aw\"\n\t"  		WORD_INSN " 1b, %l[l_yes], %0\n\t"  		".popsection\n\t" -		: :  "i" (key) : : l_yes); +		: :  "i" (&((char *)key)[branch]) : : l_yes); + +	return false; +l_yes: +	return true; +} + +static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) +{ +	asm_volatile_goto("1:\tj %l[l_yes]\n\t" +		"nop\n\t" +		".pushsection __jump_table,  \"aw\"\n\t" +		WORD_INSN " 1b, %l[l_yes], %0\n\t" +		".popsection\n\t" +		: :  "i" (&((char *)key)[branch]) : : l_yes); +  	return false;  l_yes:  	return true; diff --git a/arch/mips/include/asm/kdebug.h b/arch/mips/include/asm/kdebug.h index cba22ab7ad4d..8e3d08e739c1 100644 --- a/arch/mips/include/asm/kdebug.h +++ b/arch/mips/include/asm/kdebug.h @@ -11,7 +11,9 @@ enum die_val {  	DIE_PAGE_FAULT,  	DIE_BREAK,  	DIE_SSTEPBP, -	DIE_MSAFP +	DIE_MSAFP, +	DIE_UPROBE, +	DIE_UPROBE_XOL,  };  #endif /* _ASM_MIPS_KDEBUG_H */ diff --git a/arch/mips/include/asm/linkage.h b/arch/mips/include/asm/linkage.h index 2767dda9e309..99651b0ea7c7 100644 --- a/arch/mips/include/asm/linkage.h +++ b/arch/mips/include/asm/linkage.h @@ -5,7 +5,6 @@  #include <asm/asm.h>  #endif -#define __weak __attribute__((weak))  #define cond_syscall(x) asm(".weak\t" #x "\n" #x "\t=\tsys_ni_syscall")  #define SYSCALL_ALIAS(alias, name)					\  	asm ( #alias " = " #name "\n\t.globl " #alias) diff --git a/arch/mips/include/asm/maar.h b/arch/mips/include/asm/maar.h index 6c62b0f899c0..b02891f9caaf 100644 --- a/arch/mips/include/asm/maar.h +++ b/arch/mips/include/asm/maar.h @@ -26,7 +26,7 @@   *   * Return:	The number of MAAR pairs configured.   */ -unsigned __weak platform_maar_init(unsigned num_pairs); +unsigned platform_maar_init(unsigned num_pairs);  /**   * write_maar_pair() - write to a pair of MAARs diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h index a47ea0c85248..468cbd61b906 100644 --- a/arch/mips/include/asm/mach-ar7/ar7.h +++ b/arch/mips/include/asm/mach-ar7/ar7.h @@ -203,4 +203,8 @@ static inline void ar7_device_off(u32 bit)  int __init ar7_gpio_init(void);  void __init ar7_init_clocks(void); +/* Board specific GPIO functions */ +int ar7_gpio_enable(unsigned gpio); +int ar7_gpio_disable(unsigned gpio); +  #endif /* __AR7_H__ */ diff --git a/arch/mips/include/asm/mach-ar7/gpio.h b/arch/mips/include/asm/mach-ar7/gpio.h deleted file mode 100644 index c177cd1eed25..000000000000 --- a/arch/mips/include/asm/mach-ar7/gpio.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2007-2009 Florian Fainelli <[email protected]> - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA - */ - -#ifndef __AR7_GPIO_H__ -#define __AR7_GPIO_H__ - -#include <asm/mach-ar7/ar7.h> - -#define AR7_GPIO_MAX 32 -#define TITAN_GPIO_MAX	51 -#define NR_BUILTIN_GPIO TITAN_GPIO_MAX - -#define gpio_to_irq(gpio)	-1 - -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value - -#define gpio_cansleep __gpio_cansleep - -/* Board specific GPIO functions */ -int ar7_gpio_enable(unsigned gpio); -int ar7_gpio_disable(unsigned gpio); - -#include <asm-generic/gpio.h> - -#endif diff --git a/arch/mips/include/asm/mach-ath25/gpio.h b/arch/mips/include/asm/mach-ath25/gpio.h deleted file mode 100644 index 713564b8e8ef..000000000000 --- a/arch/mips/include/asm/mach-ath25/gpio.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __ASM_MACH_ATH25_GPIO_H -#define __ASM_MACH_ATH25_GPIO_H - -#include <asm-generic/gpio.h> - -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value -#define gpio_cansleep __gpio_cansleep -#define gpio_to_irq __gpio_to_irq - -static inline int irq_to_gpio(unsigned irq) -{ -	return -EINVAL; -} - -#endif	/* __ASM_MACH_ATH25_GPIO_H */ diff --git a/arch/mips/include/asm/mach-ath79/gpio.h b/arch/mips/include/asm/mach-ath79/gpio.h deleted file mode 100644 index 60dcb62785b4..000000000000 --- a/arch/mips/include/asm/mach-ath79/gpio.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - *  Atheros AR71XX/AR724X/AR913X GPIO API definitions - * - *  Copyright (C) 2008-2010 Gabor Juhos <[email protected]> - *  Copyright (C) 2008 Imre Kaloz <[email protected]> - * - *  This program is free software; you can redistribute it and/or modify it - *  under the terms of the GNU General Public License version 2 as published - *  by the Free Software Foundation. - * - */ - -#ifndef __ASM_MACH_ATH79_GPIO_H -#define __ASM_MACH_ATH79_GPIO_H - -#define ARCH_NR_GPIOS	64 -#include <asm-generic/gpio.h> - -int gpio_to_irq(unsigned gpio); -int irq_to_gpio(unsigned irq); -int gpio_get_value(unsigned gpio); -void gpio_set_value(unsigned gpio, int value); - -#define gpio_cansleep	__gpio_cansleep - -#endif /* __ASM_MACH_ATH79_GPIO_H */ diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h index 9785e4ebb450..adde1fa5097e 100644 --- a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h +++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h @@ -266,6 +266,17 @@ static inline int alchemy_gpio1_to_irq(int gpio)  	return -ENXIO;  } +/* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before + * SYS_PININPUTEN is written to at least once.  On Au1550/Au1200/Au1300 this + * register enables use of GPIOs as wake source. + */ +static inline void alchemy_gpio1_input_enable(void) +{ +	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); +	__raw_writel(0, base + 0x110);		/* the write op is key */ +	wmb(); +} +  /*   * GPIO2 block macros for common linux GPIO functions. The 'gpio'   * parameter must be in range of ALCHEMY_GPIO2_BASE..ALCHEMY_GPIO2_MAX. @@ -518,141 +529,4 @@ static inline int alchemy_irq_to_gpio(int irq)  	return -ENXIO;  } -/**********************************************************************/ - -/* Linux gpio framework integration. - * - * 4 use cases of Au1000-Au1200 GPIOS: - *(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y: - *	Board must register gpiochips. - *(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n: - *	2 (1 for Au1000) gpio_chips are registered. - * - *(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y: - *	the boards' gpio.h must provide the linux gpio wrapper functions, - * - *(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n: - *	inlinable gpio functions are provided which enable access to the - *	Au1000 gpios only by using the numbers straight out of the data- - *	sheets. - - * Cases 1 and 3 are intended for boards which want to provide their own - * GPIO namespace and -operations (i.e. for example you have 8 GPIOs - * which are in part provided by spare Au1000 GPIO pins and in part by - * an external FPGA but you still want them to be accssible in linux - * as gpio0-7. The board can of course use the alchemy_gpioX_* functions - * as required). - */ - -#ifndef CONFIG_GPIOLIB - -#ifdef CONFIG_ALCHEMY_GPIOINT_AU1000 - -#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT	/* case (4) */ - -static inline int gpio_direction_input(int gpio) -{ -	return alchemy_gpio_direction_input(gpio); -} - -static inline int gpio_direction_output(int gpio, int v) -{ -	return alchemy_gpio_direction_output(gpio, v); -} - -static inline int gpio_get_value(int gpio) -{ -	return alchemy_gpio_get_value(gpio); -} - -static inline void gpio_set_value(int gpio, int v) -{ -	alchemy_gpio_set_value(gpio, v); -} - -static inline int gpio_get_value_cansleep(unsigned gpio) -{ -	return gpio_get_value(gpio); -} - -static inline void gpio_set_value_cansleep(unsigned gpio, int value) -{ -	gpio_set_value(gpio, value); -} - -static inline int gpio_is_valid(int gpio) -{ -	return alchemy_gpio_is_valid(gpio); -} - -static inline int gpio_cansleep(int gpio) -{ -	return alchemy_gpio_cansleep(gpio); -} - -static inline int gpio_to_irq(int gpio) -{ -	return alchemy_gpio_to_irq(gpio); -} - -static inline int irq_to_gpio(int irq) -{ -	return alchemy_irq_to_gpio(irq); -} - -static inline int gpio_request(unsigned gpio, const char *label) -{ -	return 0; -} - -static inline int gpio_request_one(unsigned gpio, -					unsigned long flags, const char *label) -{ -	return 0; -} - -static inline int gpio_request_array(struct gpio *array, size_t num) -{ -	return 0; -} - -static inline void gpio_free(unsigned gpio) -{ -} - -static inline void gpio_free_array(struct gpio *array, size_t num) -{ -} - -static inline int gpio_set_debounce(unsigned gpio, unsigned debounce) -{ -	return -ENOSYS; -} - -static inline int gpio_export(unsigned gpio, bool direction_may_change) -{ -	return -ENOSYS; -} - -static inline int gpio_export_link(struct device *dev, const char *name, -				   unsigned gpio) -{ -	return -ENOSYS; -} - -static inline int gpio_sysfs_set_active_low(unsigned gpio, int value) -{ -	return -ENOSYS; -} - -static inline void gpio_unexport(unsigned gpio) -{ -} - -#endif	/* !CONFIG_ALCHEMY_GPIO_INDIRECT */ - -#endif	/* CONFIG_ALCHEMY_GPIOINT_AU1000 */ - -#endif	/* !CONFIG_GPIOLIB */ -  #endif /* _ALCHEMY_GPIO_AU1000_H_ */ diff --git a/arch/mips/include/asm/mach-au1x00/gpio.h b/arch/mips/include/asm/mach-au1x00/gpio.h deleted file mode 100644 index 22e7ff17fc48..000000000000 --- a/arch/mips/include/asm/mach-au1x00/gpio.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Alchemy GPIO support. - * - * With CONFIG_GPIOLIB=y different types of on-chip GPIO can be supported within - *  the same kernel image. - * With CONFIG_GPIOLIB=n, your board must select ALCHEMY_GPIOINT_AU1XXX for the - *  appropriate CPU type (AU1000 currently). - */ - -#ifndef _ALCHEMY_GPIO_H_ -#define _ALCHEMY_GPIO_H_ - -#include <asm/mach-au1x00/au1000.h> -#include <asm/mach-au1x00/gpio-au1000.h> -#include <asm/mach-au1x00/gpio-au1300.h> - -/* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before - * SYS_PININPUTEN is written to at least once.  On Au1550/Au1200/Au1300 this - * register enables use of GPIOs as wake source. - */ -static inline void alchemy_gpio1_input_enable(void) -{ -	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); -	__raw_writel(0, base + 0x110);		/* the write op is key */ -	wmb(); -} - - -/* Linux gpio framework integration. -* -* 4 use cases of Alchemy GPIOS: -*(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y: -*	Board must register gpiochips. -*(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n: -*	A gpiochip for the 75 GPIOs is registered. -* -*(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y: -*	the boards' gpio.h must provide	the linux gpio wrapper functions, -* -*(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n: -*	inlinable gpio functions are provided which enable access to the -*	Au1300 gpios only by using the numbers straight out of the data- -*	sheets. - -* Cases 1 and 3 are intended for boards which want to provide their own -* GPIO namespace and -operations (i.e. for example you have 8 GPIOs -* which are in part provided by spare Au1300 GPIO pins and in part by -* an external FPGA but you still want them to be accssible in linux -* as gpio0-7. The board can of course use the alchemy_gpioX_* functions -* as required). -*/ - -#ifdef CONFIG_GPIOLIB - -/* wraps the cpu-dependent irq_to_gpio functions */ -/* FIXME: gpiolib needs an irq_to_gpio hook */ -static inline int __au_irq_to_gpio(unsigned int irq) -{ -	switch (alchemy_get_cputype()) { -	case ALCHEMY_CPU_AU1000...ALCHEMY_CPU_AU1200: -		return alchemy_irq_to_gpio(irq); -	case ALCHEMY_CPU_AU1300: -		return au1300_irq_to_gpio(irq); -	} -	return -EINVAL; -} - - -/* using gpiolib to provide up to 2 gpio_chips for on-chip gpios */ -#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT	/* case (2) */ - -/* get everything through gpiolib */ -#define gpio_to_irq	__gpio_to_irq -#define gpio_get_value	__gpio_get_value -#define gpio_set_value	__gpio_set_value -#define gpio_cansleep	__gpio_cansleep -#define irq_to_gpio	__au_irq_to_gpio - -#include <asm-generic/gpio.h> - -#endif	/* !CONFIG_ALCHEMY_GPIO_INDIRECT */ - - -#endif	/* CONFIG_GPIOLIB */ - -#endif	/* _ALCHEMY_GPIO_H_ */ diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h deleted file mode 100644 index 90daefa24a4d..000000000000 --- a/arch/mips/include/asm/mach-bcm47xx/gpio.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __ASM_MIPS_MACH_BCM47XX_GPIO_H -#define __ASM_MIPS_MACH_BCM47XX_GPIO_H - -#include <asm-generic/gpio.h> - -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value - -#define gpio_cansleep __gpio_cansleep -#define gpio_to_irq __gpio_to_irq - -static inline int irq_to_gpio(unsigned int irq) -{ -	return -EINVAL; -} - -#endif diff --git a/arch/mips/include/asm/mach-bcm63xx/dma-coherence.h b/arch/mips/include/asm/mach-bcm63xx/dma-coherence.h deleted file mode 100644 index 11d3b572b1b3..000000000000 --- a/arch/mips/include/asm/mach-bcm63xx/dma-coherence.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __ASM_MACH_BCM63XX_DMA_COHERENCE_H -#define __ASM_MACH_BCM63XX_DMA_COHERENCE_H - -#include <asm/bmips.h> - -#define plat_post_dma_flush	bmips_post_dma_flush - -#include <asm/mach-generic/dma-coherence.h> - -#endif /* __ASM_MACH_BCM63XX_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/mach-bcm63xx/gpio.h b/arch/mips/include/asm/mach-bcm63xx/gpio.h deleted file mode 100644 index 1eb534de8e3b..000000000000 --- a/arch/mips/include/asm/mach-bcm63xx/gpio.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __ASM_MIPS_MACH_BCM63XX_GPIO_H -#define __ASM_MIPS_MACH_BCM63XX_GPIO_H - -#include <bcm63xx_gpio.h> - -#define gpio_to_irq(gpio)	-1 - -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value - -#define gpio_cansleep __gpio_cansleep - -#include <asm-generic/gpio.h> - -#endif /* __ASM_MIPS_MACH_BCM63XX_GPIO_H */ diff --git a/arch/mips/include/asm/mach-cavium-octeon/gpio.h b/arch/mips/include/asm/mach-cavium-octeon/gpio.h deleted file mode 100644 index 34e9f7aabab4..000000000000 --- a/arch/mips/include/asm/mach-cavium-octeon/gpio.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __ASM_MACH_CAVIUM_OCTEON_GPIO_H -#define __ASM_MACH_CAVIUM_OCTEON_GPIO_H - -#ifdef CONFIG_GPIOLIB -#define gpio_get_value	__gpio_get_value -#define gpio_set_value	__gpio_set_value -#define gpio_cansleep	__gpio_cansleep -#else -int gpio_request(unsigned gpio, const char *label); -void gpio_free(unsigned gpio); -int gpio_direction_input(unsigned gpio); -int gpio_direction_output(unsigned gpio, int value); -int gpio_get_value(unsigned gpio); -void gpio_set_value(unsigned gpio, int value); -#endif - -#include <asm-generic/gpio.h> - -#define gpio_to_irq	__gpio_to_irq - -#endif /* __ASM_MACH_GENERIC_GPIO_H */ diff --git a/arch/mips/include/asm/mach-generic/gpio.h b/arch/mips/include/asm/mach-generic/gpio.h deleted file mode 100644 index b4e70208da64..000000000000 --- a/arch/mips/include/asm/mach-generic/gpio.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __ASM_MACH_GENERIC_GPIO_H -#define __ASM_MACH_GENERIC_GPIO_H - -#ifdef CONFIG_GPIOLIB -#define gpio_get_value	__gpio_get_value -#define gpio_set_value	__gpio_set_value -#define gpio_cansleep	__gpio_cansleep -#else -int gpio_request(unsigned gpio, const char *label); -void gpio_free(unsigned gpio); -int gpio_direction_input(unsigned gpio); -int gpio_direction_output(unsigned gpio, int value); -int gpio_get_value(unsigned gpio); -void gpio_set_value(unsigned gpio, int value); -#endif -int gpio_to_irq(unsigned gpio); -int irq_to_gpio(unsigned irq); - -#include <asm-generic/gpio.h>		/* cansleep wrappers */ - -#endif /* __ASM_MACH_GENERIC_GPIO_H */ diff --git a/arch/mips/include/asm/mach-jz4740/gpio.h b/arch/mips/include/asm/mach-jz4740/gpio.h index eaacba79cf18..bf8c3e1860e7 100644 --- a/arch/mips/include/asm/mach-jz4740/gpio.h +++ b/arch/mips/include/asm/mach-jz4740/gpio.h @@ -73,8 +73,6 @@ int jz_gpio_port_direction_output(int port, uint32_t mask);  void jz_gpio_port_set_value(int port, uint32_t value, uint32_t mask);  uint32_t jz_gpio_port_get_value(int port, uint32_t mask); -#include <asm/mach-generic/gpio.h> -  #define JZ_GPIO_PORTA(x) ((x) + 32 * 0)  #define JZ_GPIO_PORTB(x) ((x) + 32 * 1)  #define JZ_GPIO_PORTC(x) ((x) + 32 * 2) diff --git a/arch/mips/include/asm/mach-lantiq/gpio.h b/arch/mips/include/asm/mach-lantiq/gpio.h deleted file mode 100644 index 9ba1caebca5f..000000000000 --- a/arch/mips/include/asm/mach-lantiq/gpio.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __ASM_MIPS_MACH_LANTIQ_GPIO_H -#define __ASM_MIPS_MACH_LANTIQ_GPIO_H - -#define gpio_to_irq __gpio_to_irq - -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value - -#define gpio_cansleep __gpio_cansleep - -#include <asm-generic/gpio.h> - -#endif diff --git a/arch/mips/include/asm/mach-loongson64/gpio.h b/arch/mips/include/asm/mach-loongson64/gpio.h deleted file mode 100644 index b3b216904a9a..000000000000 --- a/arch/mips/include/asm/mach-loongson64/gpio.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Loongson GPIO Support - * - * Copyright (c) 2008  Richard Liu, STMicroelectronics <[email protected]> - * Copyright (c) 2008-2010  Arnaud Patard <[email protected]> - * Copyright (c) 2014  Huacai Chen <[email protected]> - * - * 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. - */ - -#ifndef __LOONGSON_GPIO_H -#define __LOONGSON_GPIO_H - -#include <asm-generic/gpio.h> - -#define gpio_get_value __gpio_get_value -#define gpio_set_value __gpio_set_value -#define gpio_cansleep __gpio_cansleep - -/* The chip can do interrupt - * but it has not been tested and doc not clear - */ -static inline int gpio_to_irq(int gpio) -{ -	return -EINVAL; -} - -static inline int irq_to_gpio(int gpio) -{ -	return -EINVAL; -} - -#endif	/* __LOONGSON_GPIO_H */ diff --git a/arch/mips/include/asm/mach-pistachio/gpio.h b/arch/mips/include/asm/mach-pistachio/gpio.h deleted file mode 100644 index 6c1649c27b8d..000000000000 --- a/arch/mips/include/asm/mach-pistachio/gpio.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Pistachio IRQ setup - * - * Copyright (C) 2014 Google, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - */ - -#ifndef __ASM_MACH_PISTACHIO_GPIO_H -#define __ASM_MACH_PISTACHIO_GPIO_H - -#include <asm-generic/gpio.h> - -#define gpio_get_value	__gpio_get_value -#define gpio_set_value	__gpio_set_value -#define gpio_cansleep	__gpio_cansleep -#define gpio_to_irq	__gpio_to_irq - -#endif /* __ASM_MACH_PISTACHIO_GPIO_H */ diff --git a/arch/mips/include/asm/mach-rc32434/gpio.h b/arch/mips/include/asm/mach-rc32434/gpio.h index 4dee0a34250c..db211212ce79 100644 --- a/arch/mips/include/asm/mach-rc32434/gpio.h +++ b/arch/mips/include/asm/mach-rc32434/gpio.h @@ -13,18 +13,6 @@  #ifndef _RC32434_GPIO_H_  #define _RC32434_GPIO_H_ -#include <linux/types.h> -#include <asm-generic/gpio.h> - -#define NR_BUILTIN_GPIO		32 - -#define gpio_get_value	__gpio_get_value -#define gpio_set_value	__gpio_set_value -#define gpio_cansleep	__gpio_cansleep - -#define gpio_to_irq(gpio)	(8 + 4 * 32 + gpio) -#define irq_to_gpio(irq)	(irq - (8 + 4 * 32)) -  struct rb532_gpio_reg {  	u32   gpiofunc;	  /* GPIO Function Register  			   * gpiofunc[x]==0 bit = gpio diff --git a/arch/mips/include/asm/mach-sibyte/war.h b/arch/mips/include/asm/mach-sibyte/war.h index 0a227d426b9c..520f8fc2c806 100644 --- a/arch/mips/include/asm/mach-sibyte/war.h +++ b/arch/mips/include/asm/mach-sibyte/war.h @@ -13,8 +13,7 @@  #define R4600_V2_HIT_CACHEOP_WAR	0  #define R5432_CP0_INTERRUPT_WAR		0 -#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \ -    defined(CONFIG_SB1_PASS_2_WORKAROUNDS) +#if defined(CONFIG_SB1_PASS_2_WORKAROUNDS)  #ifndef __ASSEMBLY__  extern int sb1250_m3_workaround_needed(void); diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index edc7ee95269e..d75b75e78ebb 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -33,6 +33,29 @@ extern void __iomem *mips_cm_l2sync_base;   */  extern phys_addr_t __mips_cm_phys_base(void); +/* + * mips_cm_is64 - determine CM register width + * + * The CM register width is processor and CM specific. A 64-bit processor + * usually has a 64-bit CM and a 32-bit one has a 32-bit CM but a 64-bit + * processor could come with a 32-bit CM. Moreover, accesses on 64-bit CMs + * can be done either using regular 64-bit load/store instructions, or 32-bit + * load/store instruction on 32-bit register pairs. We opt for using 64-bit + * accesses on 64-bit CMs and kernels and 32-bit in any other case. + * + * It's set to 0 for 32-bit accesses and 1 for 64-bit accesses. + */ +extern int mips_cm_is64; + +/** + * mips_cm_error_report - Report CM cache errors + */ +#ifdef CONFIG_MIPS_CM +extern void mips_cm_error_report(void); +#else +static inline void mips_cm_error_report(void) {} +#endif +  /**   * mips_cm_probe - probe for a Coherence Manager   * @@ -90,20 +113,46 @@ static inline bool mips_cm_has_l2sync(void)  /* Macros to ease the creation of register access functions */  #define BUILD_CM_R_(name, off)					\ -static inline u32 __iomem *addr_gcr_##name(void)		\ +static inline unsigned long __iomem *addr_gcr_##name(void)	\  {								\ -	return (u32 __iomem *)(mips_cm_base + (off));		\ +	return (unsigned long __iomem *)(mips_cm_base + (off));	\  }								\  								\ -static inline u32 read_gcr_##name(void)				\ +static inline u32 read32_gcr_##name(void)			\  {								\  	return __raw_readl(addr_gcr_##name());			\ +}								\ +								\ +static inline u64 read64_gcr_##name(void)			\ +{								\ +	return __raw_readq(addr_gcr_##name());			\ +}								\ +								\ +static inline unsigned long read_gcr_##name(void)		\ +{								\ +	if (mips_cm_is64)					\ +		return read64_gcr_##name();			\ +	else							\ +		return read32_gcr_##name();			\  }  #define BUILD_CM__W(name, off)					\ -static inline void write_gcr_##name(u32 value)			\ +static inline void write32_gcr_##name(u32 value)		\  {								\  	__raw_writel(value, addr_gcr_##name());			\ +}								\ +								\ +static inline void write64_gcr_##name(u64 value)		\ +{								\ +	__raw_writeq(value, addr_gcr_##name());			\ +}								\ +								\ +static inline void write_gcr_##name(unsigned long value)	\ +{								\ +	if (mips_cm_is64)					\ +		write64_gcr_##name(value);			\ +	else							\ +		write32_gcr_##name(value);			\  }  #define BUILD_CM_RW(name, off)					\ @@ -144,6 +193,7 @@ BUILD_CM_RW(reg3_base,		MIPS_CM_GCB_OFS + 0xc0)  BUILD_CM_RW(reg3_mask,		MIPS_CM_GCB_OFS + 0xc8)  BUILD_CM_R_(gic_status,		MIPS_CM_GCB_OFS + 0xd0)  BUILD_CM_R_(cpc_status,		MIPS_CM_GCB_OFS + 0xf0) +BUILD_CM_RW(l2_config,		MIPS_CM_GCB_OFS + 0x130)  /* Core Local & Core Other register accessor functions */  BUILD_CM_Cx_RW(reset_release,	0x00) @@ -189,6 +239,13 @@ BUILD_CM_Cx_R_(tcid_8_priority,	0x80)  #define CM_GCR_REV_MINOR_SHF			0  #define CM_GCR_REV_MINOR_MSK			(_ULCAST_(0xff) << 0) +#define CM_ENCODE_REV(major, minor) \ +		(((major) << CM_GCR_REV_MAJOR_SHF) | \ +		 ((minor) << CM_GCR_REV_MINOR_SHF)) + +#define CM_REV_CM2				CM_ENCODE_REV(6, 0) +#define CM_REV_CM3				CM_ENCODE_REV(8, 0) +  /* GCR_ERROR_CAUSE register fields */  #define CM_GCR_ERROR_CAUSE_ERRTYPE_SHF		27  #define CM_GCR_ERROR_CAUSE_ERRTYPE_MSK		(_ULCAST_(0x1f) << 27) @@ -249,6 +306,16 @@ BUILD_CM_Cx_R_(tcid_8_priority,	0x80)  #define CM_GCR_CPC_STATUS_EX_SHF		0  #define CM_GCR_CPC_STATUS_EX_MSK		(_ULCAST_(0x1) << 0) +/* GCR_L2_CONFIG register fields */ +#define CM_GCR_L2_CONFIG_BYPASS_SHF		20 +#define CM_GCR_L2_CONFIG_BYPASS_MSK		(_ULCAST_(0x1) << 20) +#define CM_GCR_L2_CONFIG_SET_SIZE_SHF		12 +#define CM_GCR_L2_CONFIG_SET_SIZE_MSK		(_ULCAST_(0xf) << 12) +#define CM_GCR_L2_CONFIG_LINE_SIZE_SHF		8 +#define CM_GCR_L2_CONFIG_LINE_SIZE_MSK		(_ULCAST_(0xf) << 8) +#define CM_GCR_L2_CONFIG_ASSOC_SHF		0 +#define CM_GCR_L2_CONFIG_ASSOC_MSK		(_ULCAST_(0xff) << 0) +  /* GCR_Cx_COHERENCE register fields */  #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF	0  #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK	(_ULCAST_(0xff) << 0) @@ -324,4 +391,18 @@ static inline int mips_cm_l2sync(void)  	return 0;  } +/** + * mips_cm_revision() - return CM revision + * + * Return: The revision of the CM, from GCR_REV, or 0 if no CM is present. The + * return value should be checked against the CM_REV_* macros. + */ +static inline int mips_cm_revision(void) +{ +	if (!mips_cm_present()) +		return 0; + +	return read_gcr_rev(); +} +  #endif /* __MIPS_ASM_MIPS_CM_H__ */ diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h index 1cebe8c79051..f386f32702f1 100644 --- a/arch/mips/include/asm/mips-cpc.h +++ b/arch/mips/include/asm/mips-cpc.h @@ -28,16 +28,6 @@ extern void __iomem *mips_cpc_base;  extern phys_addr_t mips_cpc_default_phys_base(void);  /** - * mips_cpc_phys_base - retrieve the physical base address of the CPC - * - * This function returns the physical base address of the Cluster Power - * Controller memory mapped registers, or 0 if no Cluster Power Controller - * is present. It may be overriden by individual platforms which determine - * this address in a different way. - */ -extern phys_addr_t __weak mips_cpc_phys_base(void); - -/**   * mips_cpc_probe - probe for a Cluster Power Controller   *   * Attempt to detect the presence of a Cluster Power Controller. Returns 0 if diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index c5b0956a8530..d3cd8eac81e3 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -112,6 +112,30 @@  #define CP0_TX39_CACHE	$7 +/* Generic EntryLo bit definitions */ +#define ENTRYLO_G		(_ULCAST_(1) << 0) +#define ENTRYLO_V		(_ULCAST_(1) << 1) +#define ENTRYLO_D		(_ULCAST_(1) << 2) +#define ENTRYLO_C_SHIFT		3 +#define ENTRYLO_C		(_ULCAST_(7) << ENTRYLO_C_SHIFT) + +/* R3000 EntryLo bit definitions */ +#define R3K_ENTRYLO_G		(_ULCAST_(1) << 8) +#define R3K_ENTRYLO_V		(_ULCAST_(1) << 9) +#define R3K_ENTRYLO_D		(_ULCAST_(1) << 10) +#define R3K_ENTRYLO_N		(_ULCAST_(1) << 11) + +/* MIPS32/64 EntryLo bit definitions */ +#ifdef CONFIG_64BIT +/* as read by dmfc0 */ +#define MIPS_ENTRYLO_XI		(_ULCAST_(1) << 62) +#define MIPS_ENTRYLO_RI		(_ULCAST_(1) << 63) +#else +/* as read by mfc0 */ +#define MIPS_ENTRYLO_XI		(_ULCAST_(1) << 30) +#define MIPS_ENTRYLO_RI		(_ULCAST_(1) << 31) +#endif +  /*   * Values for PageMask register   */ @@ -203,6 +227,9 @@  #define PG_ESP		(_ULCAST_(1) <<	 28)  #define PG_IEC		(_ULCAST_(1) <<  27) +/* MIPS32/64 EntryHI bit definitions */ +#define MIPS_ENTRYHI_EHINV	(_ULCAST_(1) << 10) +  /*   * R4x00 interrupt enable / cause bits   */ @@ -579,6 +606,8 @@  #define MIPS_CONF7_IAR		(_ULCAST_(1) << 10)  #define MIPS_CONF7_AR		(_ULCAST_(1) << 16) +/* FTLB probability bits for R6 */ +#define MIPS_CONF7_FTLBP_SHIFT	(18)  /* MAAR bit definitions */  #define MIPS_MAAR_ADDR		((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12) @@ -586,31 +615,6 @@  #define MIPS_MAAR_S		(_ULCAST_(1) << 1)  #define MIPS_MAAR_V		(_ULCAST_(1) << 0) -/*  EntryHI bit definition */ -#define MIPS_ENTRYHI_EHINV	(_ULCAST_(1) << 10) - -/* R3000 EntryLo bit definitions */ -#define R3K_ENTRYLO_G		(_ULCAST_(1) << 8) -#define R3K_ENTRYLO_V		(_ULCAST_(1) << 9) -#define R3K_ENTRYLO_D		(_ULCAST_(1) << 10) -#define R3K_ENTRYLO_N		(_ULCAST_(1) << 11) - -/* R4000 compatible EntryLo bit definitions */ -#define MIPS_ENTRYLO_G		(_ULCAST_(1) << 0) -#define MIPS_ENTRYLO_V		(_ULCAST_(1) << 1) -#define MIPS_ENTRYLO_D		(_ULCAST_(1) << 2) -#define MIPS_ENTRYLO_C_SHIFT	3 -#define MIPS_ENTRYLO_C		(_ULCAST_(7) << MIPS_ENTRYLO_C_SHIFT) -#ifdef CONFIG_64BIT -/* as read by dmfc0 */ -#define MIPS_ENTRYLO_XI		(_ULCAST_(1) << 62) -#define MIPS_ENTRYLO_RI		(_ULCAST_(1) << 63) -#else -/* as read by mfc0 */ -#define MIPS_ENTRYLO_XI		(_ULCAST_(1) << 30) -#define MIPS_ENTRYLO_RI		(_ULCAST_(1) << 31) -#endif -  /* CMGCRBase bit definitions */  #define MIPS_CMGCRB_BASE	11  #define MIPS_CMGCRF_BASE	(~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1)) @@ -932,7 +936,7 @@ do {								\   */  #define __read_32bit_c0_register(source, sel)				\ -({ int __res;								\ +({ unsigned int __res;							\  	if (sel == 0)							\  		__asm__ __volatile__(					\  			"mfc0\t%0, " #source "\n\t"			\ @@ -1014,7 +1018,7 @@ do {									\   * On RM7000/RM9000 these are uses to access cop0 set 1 registers   */  #define __read_32bit_c0_ctrl_register(source)				\ -({ int __res;								\ +({ unsigned int __res;							\  	__asm__ __volatile__(						\  		"cfc0\t%0, " #source "\n\t"				\  		: "=r" (__res));					\ @@ -1471,7 +1475,7 @@ do {									\   */  #define _read_32bit_cp1_register(source, gas_hardfloat)			\  ({									\ -	int __res;							\ +	unsigned int __res;						\  									\  	__asm__ __volatile__(						\  	"	.set	push					\n"	\ diff --git a/arch/mips/include/asm/mm-arch-hooks.h b/arch/mips/include/asm/mm-arch-hooks.h deleted file mode 100644 index b5609fe8e475..000000000000 --- a/arch/mips/include/asm/mm-arch-hooks.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Architecture specific mm hooks - * - * Copyright (C) 2015, IBM Corporation - * Author: Laurent Dufour <[email protected]> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _ASM_MIPS_MM_ARCH_HOOKS_H -#define _ASM_MIPS_MM_ARCH_HOOKS_H - -#endif /* _ASM_MIPS_MM_ARCH_HOOKS_H */ diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h index af5638b12c75..bbb85fe21642 100644 --- a/arch/mips/include/asm/msa.h +++ b/arch/mips/include/asm/msa.h @@ -14,10 +14,90 @@  #ifndef __ASSEMBLY__ +#include <asm/inst.h> +  extern void _save_msa(struct task_struct *);  extern void _restore_msa(struct task_struct *);  extern void _init_msa_upper(void); +extern void read_msa_wr_b(unsigned idx, union fpureg *to); +extern void read_msa_wr_h(unsigned idx, union fpureg *to); +extern void read_msa_wr_w(unsigned idx, union fpureg *to); +extern void read_msa_wr_d(unsigned idx, union fpureg *to); + +/** + * read_msa_wr() - Read a single MSA vector register + * @idx:	The index of the vector register to read + * @to:		The FPU register union to store the registers value in + * @fmt:	The format of the data in the vector register + * + * Read the value of MSA vector register idx into the FPU register + * union to, using the format fmt. + */ +static inline void read_msa_wr(unsigned idx, union fpureg *to, +			       enum msa_2b_fmt fmt) +{ +	switch (fmt) { +	case msa_fmt_b: +		read_msa_wr_b(idx, to); +		break; + +	case msa_fmt_h: +		read_msa_wr_h(idx, to); +		break; + +	case msa_fmt_w: +		read_msa_wr_w(idx, to); +		break; + +	case msa_fmt_d: +		read_msa_wr_d(idx, to); +		break; + +	default: +		BUG(); +	} +} + +extern void write_msa_wr_b(unsigned idx, union fpureg *from); +extern void write_msa_wr_h(unsigned idx, union fpureg *from); +extern void write_msa_wr_w(unsigned idx, union fpureg *from); +extern void write_msa_wr_d(unsigned idx, union fpureg *from); + +/** + * write_msa_wr() - Write a single MSA vector register + * @idx:	The index of the vector register to write + * @from:	The FPU register union to take the registers value from + * @fmt:	The format of the data in the vector register + * + * Write the value from the FPU register union from into MSA vector + * register idx, using the format fmt. + */ +static inline void write_msa_wr(unsigned idx, union fpureg *from, +				enum msa_2b_fmt fmt) +{ +	switch (fmt) { +	case msa_fmt_b: +		write_msa_wr_b(idx, from); +		break; + +	case msa_fmt_h: +		write_msa_wr_h(idx, from); +		break; + +	case msa_fmt_w: +		write_msa_wr_w(idx, from); +		break; + +	case msa_fmt_d: +		write_msa_wr_d(idx, from); +		break; + +	default: +		BUG(); +	} +} +  static inline void enable_msa(void)  {  	if (cpu_has_msa) { diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h index c373d95b5e2c..d92cf59bdae6 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h +++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h @@ -284,6 +284,7 @@ enum cvmx_board_types_enum {  	CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,  	CVMX_BOARD_TYPE_UBNT_E100 = 20002,  	CVMX_BOARD_TYPE_CUST_DSR1000N = 20006, +	CVMX_BOARD_TYPE_KONTRON_S1901 = 21901,  	CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,  	/* The remaining range is reserved for future use. */ @@ -384,6 +385,7 @@ static inline const char *cvmx_board_type_to_string(enum  		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)  		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100)  		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N) +		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KONTRON_S1901)  		ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)  	}  	return "Unsupported Board"; diff --git a/arch/mips/include/asm/octeon/cvmx-pip.h b/arch/mips/include/asm/octeon/cvmx-pip.h index df69bfd2b006..c210154ad941 100644 --- a/arch/mips/include/asm/octeon/cvmx-pip.h +++ b/arch/mips/include/asm/octeon/cvmx-pip.h @@ -37,7 +37,7 @@  #include <asm/octeon/cvmx-fpa.h>  #include <asm/octeon/cvmx-pip-defs.h> -#define CVMX_PIP_NUM_INPUT_PORTS		40 +#define CVMX_PIP_NUM_INPUT_PORTS		48  #define CVMX_PIP_NUM_WATCHERS			4  /* diff --git a/arch/mips/include/asm/octeon/cvmx-pko.h b/arch/mips/include/asm/octeon/cvmx-pko.h index 3da59bb8ce24..5f47f76ed510 100644 --- a/arch/mips/include/asm/octeon/cvmx-pko.h +++ b/arch/mips/include/asm/octeon/cvmx-pko.h @@ -542,6 +542,9 @@ static inline int cvmx_pko_get_base_queue_per_core(int port, int core)   */  static inline int cvmx_pko_get_base_queue(int port)  { +	if (OCTEON_IS_MODEL(OCTEON_CN68XX)) +		return port; +  	return cvmx_pko_get_base_queue_per_core(port, 0);  } diff --git a/arch/mips/include/asm/octeon/cvmx-pow-defs.h b/arch/mips/include/asm/octeon/cvmx-pow-defs.h index 9020ef443736..6a3db4b068ff 100644 --- a/arch/mips/include/asm/octeon/cvmx-pow-defs.h +++ b/arch/mips/include/asm/octeon/cvmx-pow-defs.h @@ -52,6 +52,12 @@  #define CVMX_POW_WQ_INT_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000000080ull) + ((offset) & 15) * 8)  #define CVMX_POW_WS_PCX(offset) (CVMX_ADD_IO_SEG(0x0001670000000280ull) + ((offset) & 15) * 8) +#define CVMX_SSO_WQ_INT (CVMX_ADD_IO_SEG(0x0001670000001000ull)) +#define CVMX_SSO_WQ_IQ_DIS (CVMX_ADD_IO_SEG(0x0001670000001010ull)) +#define CVMX_SSO_WQ_INT_PC (CVMX_ADD_IO_SEG(0x0001670000001020ull)) +#define CVMX_SSO_PPX_GRP_MSK(offset) (CVMX_ADD_IO_SEG(0x0001670000006000ull) + ((offset) & 31) * 8) +#define CVMX_SSO_WQ_INT_THRX(offset) (CVMX_ADD_IO_SEG(0x0001670000007000ull) + ((offset) & 63) * 8) +  union cvmx_pow_bist_stat {  	uint64_t u64;  	struct cvmx_pow_bist_stat_s { @@ -1286,4 +1292,27 @@ union cvmx_pow_ws_pcx {  	struct cvmx_pow_ws_pcx_s cnf71xx;  }; +union cvmx_sso_wq_int_thrx { +	uint64_t u64; +	struct { +#ifdef __BIG_ENDIAN_BITFIELD +		uint64_t reserved_33_63:31; +		uint64_t tc_en:1; +		uint64_t tc_thr:4; +		uint64_t reserved_26_27:2; +		uint64_t ds_thr:12; +		uint64_t reserved_12_13:2; +		uint64_t iq_thr:12; +#else +		uint64_t iq_thr:12; +		uint64_t reserved_12_13:2; +		uint64_t ds_thr:12; +		uint64_t reserved_26_27:2; +		uint64_t tc_thr:4; +		uint64_t tc_en:1; +		uint64_t reserved_33_63:31; +#endif +	} s; +}; +  #endif diff --git a/arch/mips/include/asm/octeon/cvmx-pow.h b/arch/mips/include/asm/octeon/cvmx-pow.h index d5565d758ddd..51531563f8dc 100644 --- a/arch/mips/include/asm/octeon/cvmx-pow.h +++ b/arch/mips/include/asm/octeon/cvmx-pow.h @@ -1810,10 +1810,11 @@ static inline void cvmx_pow_work_submit(cvmx_wqe_t *wqp, uint32_t tag,  	cvmx_addr_t ptr;  	cvmx_pow_tag_req_t tag_req; -	wqp->qos = qos; -	wqp->tag = tag; -	wqp->tag_type = tag_type; -	wqp->grp = grp; +	wqp->word1.tag = tag; +	wqp->word1.tag_type = tag_type; + +	cvmx_wqe_set_qos(wqp, qos); +	cvmx_wqe_set_grp(wqp, grp);  	tag_req.u64 = 0;  	tag_req.s.op = CVMX_POW_TAG_OP_ADDWQ; diff --git a/arch/mips/include/asm/octeon/cvmx-wqe.h b/arch/mips/include/asm/octeon/cvmx-wqe.h index 2d6d0c7127a7..0d697aa786d4 100644 --- a/arch/mips/include/asm/octeon/cvmx-wqe.h +++ b/arch/mips/include/asm/octeon/cvmx-wqe.h @@ -193,6 +193,53 @@ typedef union {  	        uint64_t bufs:8;  #endif  	} s; +	struct { +#ifdef __BIG_ENDIAN_BITFIELD +		uint64_t bufs:8; +		uint64_t ip_offset:8; +		uint64_t vlan_valid:1; +		uint64_t vlan_stacked:1; +		uint64_t unassigned:1; +		uint64_t vlan_cfi:1; +		uint64_t vlan_id:12; +		uint64_t port:12;		/* MAC/PIP port number. */ +		uint64_t dec_ipcomp:1; +		uint64_t tcp_or_udp:1; +		uint64_t dec_ipsec:1; +		uint64_t is_v6:1; +		uint64_t software:1; +		uint64_t L4_error:1; +		uint64_t is_frag:1; +		uint64_t IP_exc:1; +		uint64_t is_bcast:1; +		uint64_t is_mcast:1; +		uint64_t not_IP:1; +		uint64_t rcv_error:1; +		uint64_t err_code:8; +#else +		uint64_t err_code:8; +		uint64_t rcv_error:1; +		uint64_t not_IP:1; +		uint64_t is_mcast:1; +		uint64_t is_bcast:1; +		uint64_t IP_exc:1; +		uint64_t is_frag:1; +		uint64_t L4_error:1; +		uint64_t software:1; +		uint64_t is_v6:1; +		uint64_t dec_ipsec:1; +		uint64_t tcp_or_udp:1; +		uint64_t dec_ipcomp:1; +		uint64_t port:12; +		uint64_t vlan_id:12; +		uint64_t vlan_cfi:1; +		uint64_t unassigned:1; +		uint64_t vlan_stacked:1; +		uint64_t vlan_valid:1; +		uint64_t ip_offset:8; +		uint64_t bufs:8; +#endif +	} s_cn68xx;  	/* use this to get at the 16 vlan bits */  	struct { @@ -355,6 +402,146 @@ typedef union {  } cvmx_pip_wqe_word2; +union cvmx_pip_wqe_word0 { +	struct { +#ifdef __BIG_ENDIAN_BITFIELD +		/** +		 * raw chksum result generated by the HW +		 */ +		uint16_t hw_chksum; +		/** +		 * Field unused by hardware - available for software +		 */ +		uint8_t unused; +		/** +		 * Next pointer used by hardware for list maintenance. +		 * May be written/read by HW before the work queue +		 * entry is scheduled to a PP (Only 36 bits used in +		 * Octeon 1) +		 */ +		uint64_t next_ptr:40; +#else +		uint64_t next_ptr:40; +		uint8_t unused; +		uint16_t hw_chksum; +#endif +	} cn38xx; +	struct { +#ifdef __BIG_ENDIAN_BITFIELD +		uint64_t l4ptr:8;       /* 56..63 */ +		uint64_t unused0:8;     /* 48..55 */ +		uint64_t l3ptr:8;       /* 40..47 */ +		uint64_t l2ptr:8;       /* 32..39 */ +		uint64_t unused1:18;    /* 14..31 */ +		uint64_t bpid:6;        /* 8..13 */ +		uint64_t unused2:2;     /* 6..7 */ +		uint64_t pknd:6;        /* 0..5 */ +#else +		uint64_t pknd:6;        /* 0..5 */ +		uint64_t unused2:2;     /* 6..7 */ +		uint64_t bpid:6;        /* 8..13 */ +		uint64_t unused1:18;    /* 14..31 */ +		uint64_t l2ptr:8;       /* 32..39 */ +		uint64_t l3ptr:8;       /* 40..47 */ +		uint64_t unused0:8;     /* 48..55 */ +		uint64_t l4ptr:8;       /* 56..63 */ +#endif +	} cn68xx; +}; + +union cvmx_wqe_word0 { +	uint64_t u64; +	union cvmx_pip_wqe_word0 pip; +}; + +union cvmx_wqe_word1 { +	uint64_t u64; +	struct { +#ifdef __BIG_ENDIAN_BITFIELD +		uint64_t len:16; +		uint64_t varies:14; +		/** +		 * the type of the tag (ORDERED, ATOMIC, NULL) +		 */ +		uint64_t tag_type:2; +		uint64_t tag:32; +#else +		uint64_t tag:32; +		uint64_t tag_type:2; +		uint64_t varies:14; +		uint64_t len:16; +#endif +	}; +	struct { +#ifdef __BIG_ENDIAN_BITFIELD +		uint64_t len:16; +		uint64_t zero_0:1; +		/** +		 * HW sets this to what it thought the priority of +		 * the input packet was +		 */ +		uint64_t qos:3; + +		uint64_t zero_1:1; +		/** +		 * the group that the work queue entry will be scheduled to +		 */ +		uint64_t grp:6; +		uint64_t zero_2:3; +		uint64_t tag_type:2; +		uint64_t tag:32; +#else +		uint64_t tag:32; +		uint64_t tag_type:2; +		uint64_t zero_2:3; +		uint64_t grp:6; +		uint64_t zero_1:1; +		uint64_t qos:3; +		uint64_t zero_0:1; +		uint64_t len:16; +#endif +	} cn68xx; +	struct { +#ifdef __BIG_ENDIAN_BITFIELD +		/** +		 * HW sets to the total number of bytes in the packet +		 */ +		uint64_t len:16; +		/** +		 * HW sets this to input physical port +		 */ +		uint64_t ipprt:6; + +		/** +		 * HW sets this to what it thought the priority of +		 * the input packet was +		 */ +		uint64_t qos:3; + +		/** +		 * the group that the work queue entry will be scheduled to +		 */ +		uint64_t grp:4; +		/** +		 * the type of the tag (ORDERED, ATOMIC, NULL) +		 */ +		uint64_t tag_type:3; +		/** +		 * the synchronization/ordering tag +		 */ +		uint64_t tag:32; +#else +		uint64_t tag:32; +		uint64_t tag_type:2; +		uint64_t zero_2:1; +		uint64_t grp:4; +		uint64_t qos:3; +		uint64_t ipprt:6; +		uint64_t len:16; +#endif +	} cn38xx; +}; +  /**   * Work queue entry format   * @@ -366,70 +553,13 @@ typedef struct {       * WORD 0       *	HW WRITE: the following 64 bits are filled by HW when a packet arrives       */ - -#ifdef __BIG_ENDIAN_BITFIELD -    /** -     * raw chksum result generated by the HW -     */ -	uint16_t hw_chksum; -    /** -     * Field unused by hardware - available for software -     */ -	uint8_t unused; -    /** -     * Next pointer used by hardware for list maintenance. -     * May be written/read by HW before the work queue -     *		 entry is scheduled to a PP -     * (Only 36 bits used in Octeon 1) -     */ -	uint64_t next_ptr:40; -#else -	uint64_t next_ptr:40; -	uint8_t unused; -	uint16_t hw_chksum; -#endif +	union cvmx_wqe_word0 word0;      /*****************************************************************       * WORD 1       *	HW WRITE: the following 64 bits are filled by HW when a packet arrives       */ - -#ifdef __BIG_ENDIAN_BITFIELD -    /** -     * HW sets to the total number of bytes in the packet -     */ -	uint64_t len:16; -    /** -     * HW sets this to input physical port -     */ -	uint64_t ipprt:6; - -    /** -     * HW sets this to what it thought the priority of the input packet was -     */ -	uint64_t qos:3; - -    /** -     * the group that the work queue entry will be scheduled to -     */ -	uint64_t grp:4; -    /** -     * the type of the tag (ORDERED, ATOMIC, NULL) -     */ -	uint64_t tag_type:3; -    /** -     * the synchronization/ordering tag -     */ -	uint64_t tag:32; -#else -	uint64_t tag:32; -	uint64_t tag_type:2; -	uint64_t zero_2:1; -	uint64_t grp:4; -	uint64_t qos:3; -	uint64_t ipprt:6; -	uint64_t len:16; -#endif +	union cvmx_wqe_word1 word1;      /**       * WORD 2 HW WRITE: the following 64-bits are filled in by @@ -465,4 +595,64 @@ typedef struct {  } CVMX_CACHE_LINE_ALIGNED cvmx_wqe_t; +static inline int cvmx_wqe_get_port(cvmx_wqe_t *work) +{ +	int port; + +	if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE)) +		port = work->word2.s_cn68xx.port; +	else +		port = work->word1.cn38xx.ipprt; + +	return port; +} + +static inline void cvmx_wqe_set_port(cvmx_wqe_t *work, int port) +{ +	if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE)) +		work->word2.s_cn68xx.port = port; +	else +		work->word1.cn38xx.ipprt = port; +} + +static inline int cvmx_wqe_get_grp(cvmx_wqe_t *work) +{ +	int grp; + +	if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE)) +		grp = work->word1.cn68xx.grp; +	else +		grp = work->word1.cn38xx.grp; + +	return grp; +} + +static inline void cvmx_wqe_set_grp(cvmx_wqe_t *work, int grp) +{ +	if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE)) +		work->word1.cn68xx.grp = grp; +	else +		work->word1.cn38xx.grp = grp; +} + +static inline int cvmx_wqe_get_qos(cvmx_wqe_t *work) +{ +	int qos; + +	if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE)) +		qos = work->word1.cn68xx.qos; +	else +		qos = work->word1.cn38xx.qos; + +	return qos; +} + +static inline void cvmx_wqe_set_qos(cvmx_wqe_t *work, int qos) +{ +	if (octeon_has_feature(OCTEON_FEATURE_CN68XX_WQE)) +		work->word1.cn68xx.qos = qos; +	else +		work->word1.cn38xx.qos = qos; +} +  #endif /* __CVMX_WQE_H__ */ diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index c28a8499aec7..ff7ad91c85db 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h @@ -133,20 +133,13 @@  #define _PAGE_HUGE		(1 << _PAGE_HUGE_SHIFT)  #define _PAGE_SPLITTING_SHIFT	(_PAGE_HUGE_SHIFT + 1)  #define _PAGE_SPLITTING		(1 << _PAGE_SPLITTING_SHIFT) - -/* Only R2 or newer cores have the XI bit */ -#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) -#define _PAGE_NO_EXEC_SHIFT	(_PAGE_SPLITTING_SHIFT + 1) -#else -#define _PAGE_GLOBAL_SHIFT	(_PAGE_SPLITTING_SHIFT + 1) -#define _PAGE_GLOBAL		(1 << _PAGE_GLOBAL_SHIFT) -#endif	/* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ -  #endif	/* CONFIG_64BIT && CONFIG_MIPS_HUGE_TLB_SUPPORT */  #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)  /* XI - page cannot be executed */ -#ifndef _PAGE_NO_EXEC_SHIFT +#ifdef _PAGE_SPLITTING_SHIFT +#define _PAGE_NO_EXEC_SHIFT	(_PAGE_SPLITTING_SHIFT + 1) +#else  #define _PAGE_NO_EXEC_SHIFT	(_PAGE_MODIFIED_SHIFT + 1)  #endif  #define _PAGE_NO_EXEC		(cpu_has_rixi ? (1 << _PAGE_NO_EXEC_SHIFT) : 0) @@ -156,14 +149,16 @@  #define _PAGE_READ		(cpu_has_rixi ? 0 : (1 << _PAGE_READ_SHIFT))  #define _PAGE_NO_READ_SHIFT	_PAGE_READ_SHIFT  #define _PAGE_NO_READ		(cpu_has_rixi ? (1 << _PAGE_READ_SHIFT) : 0) +#endif	/* defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) */ +#if defined(_PAGE_NO_READ_SHIFT)  #define _PAGE_GLOBAL_SHIFT	(_PAGE_NO_READ_SHIFT + 1) -#define _PAGE_GLOBAL		(1 << _PAGE_GLOBAL_SHIFT) - -#else	/* !CONFIG_CPU_MIPSR2 && !CONFIG_CPU_MIPSR6 */ +#elif defined(_PAGE_SPLITTING_SHIFT) +#define _PAGE_GLOBAL_SHIFT	(_PAGE_SPLITTING_SHIFT + 1) +#else  #define _PAGE_GLOBAL_SHIFT	(_PAGE_MODIFIED_SHIFT + 1) +#endif  #define _PAGE_GLOBAL		(1 << _PAGE_GLOBAL_SHIFT) -#endif	/* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */  #define _PAGE_VALID_SHIFT	(_PAGE_GLOBAL_SHIFT + 1)  #define _PAGE_VALID		(1 << _PAGE_VALID_SHIFT) @@ -249,7 +244,7 @@ static inline uint64_t pte_to_entrylo(unsigned long pte_val)  #define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT)  /* LOONGSON       */  #define _CACHE_CACHABLE_COHERENT    (3<<_CACHE_SHIFT)  /* LOONGSON-3     */ -#elif defined(CONFIG_MACH_JZ4740) +#elif defined(CONFIG_MACH_INGENIC)  /* Ingenic uses the WA bit to achieve write-combine memory writes */  #define _CACHE_UNCACHED_ACCELERATED (1<<_CACHE_SHIFT) diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 9d8106758142..8957f15e21ec 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h @@ -182,8 +182,39 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)  		 * Make sure the buddy is global too (if it's !none,  		 * it better already be global)  		 */ +#ifdef CONFIG_SMP +		/* +		 * For SMP, multiple CPUs can race, so we need to do +		 * this atomically. +		 */ +#ifdef CONFIG_64BIT +#define LL_INSN "lld" +#define SC_INSN "scd" +#else /* CONFIG_32BIT */ +#define LL_INSN "ll" +#define SC_INSN "sc" +#endif +		unsigned long page_global = _PAGE_GLOBAL; +		unsigned long tmp; + +		__asm__ __volatile__ ( +			"	.set	push\n" +			"	.set	noreorder\n" +			"1:	" LL_INSN "	%[tmp], %[buddy]\n" +			"	bnez	%[tmp], 2f\n" +			"	 or	%[tmp], %[tmp], %[global]\n" +			"	" SC_INSN "	%[tmp], %[buddy]\n" +			"	beqz	%[tmp], 1b\n" +			"	 nop\n" +			"2:\n" +			"	.set pop" +			: [buddy] "+m" (buddy->pte), +			  [tmp] "=&r" (tmp) +			: [global] "r" (page_global)); +#else /* !CONFIG_SMP */  		if (pte_none(*buddy))  			pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL; +#endif /* CONFIG_SMP */  	}  #endif  } @@ -362,6 +393,8 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot)  	return __pgprot(prot);  } +#define pgprot_writecombine pgprot_writecombine +  static inline pgprot_t pgprot_writecombine(pgprot_t _prot)  {  	unsigned long prot = pgprot_val(_prot); diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index 9b3b48e21c22..59ee6dcf6eed 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h @@ -275,6 +275,7 @@ struct thread_struct {  	unsigned long cp0_badvaddr;	/* Last user fault */  	unsigned long cp0_baduaddr;	/* Last kernel fault accessing USEG */  	unsigned long error_code; +	unsigned long trap_nr;  #ifdef CONFIG_CPU_CAVIUM_OCTEON  	struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));  	struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128))); @@ -341,6 +342,7 @@ struct thread_struct {  	.cp0_badvaddr		= 0,				\  	.cp0_baduaddr		= 0,				\  	.error_code		= 0,				\ +	.trap_nr		= 0,				\  	/*							\  	 * Platform specific cop2 registers(null if no COP2)	\  	 */							\ diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h index ffc320389f40..f6fc6aac5496 100644 --- a/arch/mips/include/asm/ptrace.h +++ b/arch/mips/include/asm/ptrace.h @@ -14,11 +14,16 @@  #include <linux/linkage.h>  #include <linux/types.h>  #include <asm/isadep.h> +#include <asm/page.h> +#include <asm/thread_info.h>  #include <uapi/asm/ptrace.h>  /*   * This struct defines the way the registers are stored on the stack during a   * system call/exception. As usual the registers k0/k1 aren't being saved. + * + * If you add a register here, also add it to regoffset_table[] in + * arch/mips/kernel/ptrace.c.   */  struct pt_regs {  #ifdef CONFIG_32BIT @@ -43,8 +48,83 @@ struct pt_regs {  	unsigned long long mpl[6];        /* MTM{0-5} */  	unsigned long long mtp[6];        /* MTP{0-5} */  #endif +	unsigned long __last[0];  } __aligned(8); +static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) +{ +	return regs->regs[31]; +} + +/* + * Don't use asm-generic/ptrace.h it defines FP accessors that don't make + * sense on MIPS.  We rather want an error if they get invoked. + */ + +static inline void instruction_pointer_set(struct pt_regs *regs, +                                           unsigned long val) +{ +	regs->cp0_epc = val; +} + +/* Query offset/name of register from its name/offset */ +extern int regs_query_register_offset(const char *name); +#define MAX_REG_OFFSET (offsetof(struct pt_regs, __last)) + +/** + * regs_get_register() - get register value from its offset + * @regs:       pt_regs from which register value is gotten. + * @offset:     offset number of the register. + * + * regs_get_register returns the value of a register. The @offset is the + * offset of the register in struct pt_regs address which specified by @regs. + * If @offset is bigger than MAX_REG_OFFSET, this returns 0. + */ +static inline unsigned long regs_get_register(struct pt_regs *regs, +                                              unsigned int offset) +{ +	if (unlikely(offset > MAX_REG_OFFSET)) +		return 0; + +	return *(unsigned long *)((unsigned long)regs + offset); +} + +/** + * regs_within_kernel_stack() - check the address in the stack + * @regs:       pt_regs which contains kernel stack pointer. + * @addr:       address which is checked. + * + * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). + * If @addr is within the kernel stack, it returns true. If not, returns false. + */ +static inline int regs_within_kernel_stack(struct pt_regs *regs, +                                           unsigned long addr) +{ +	return ((addr & ~(THREAD_SIZE - 1))  == +		(kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))); +} + +/** + * regs_get_kernel_stack_nth() - get Nth entry of the stack + * @regs:       pt_regs which contains kernel stack pointer. + * @n:          stack entry number. + * + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which + * is specified by @regs. If the @n th entry is NOT in the kernel stack, + * this returns 0. + */ +static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, +                                                      unsigned int n) +{ +	unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); + +	addr += n; +	if (regs_within_kernel_stack(regs, (unsigned long)addr)) +		return *addr; +	else +		return 0; +} +  struct task_struct;  extern int ptrace_getregs(struct task_struct *child, diff --git a/arch/mips/include/asm/signal.h b/arch/mips/include/asm/signal.h index 8efe5a9e2c3e..003e273eff4c 100644 --- a/arch/mips/include/asm/signal.h +++ b/arch/mips/include/asm/signal.h @@ -23,4 +23,7 @@  #define __ARCH_HAS_IRIX_SIGACTION +extern int protected_save_fp_context(void __user *sc); +extern int protected_restore_fp_context(void __user *sc); +  #endif /* _ASM_SIGNAL_H */ diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index 16f1ea9ab191..03722d4326a1 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -83,8 +83,6 @@ static inline void __cpu_die(unsigned int cpu)  extern void play_dead(void);  #endif -extern asmlinkage void smp_call_function_interrupt(void); -  static inline void arch_send_call_function_single_ipi(int cpu)  {  	extern struct plat_smp_ops *mp_ops;	/* private */ diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 9de4ba43dcd1..40196bebe849 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h @@ -42,6 +42,11 @@ static inline int arch_spin_is_locked(arch_spinlock_t *lock)  	return ((counters >> 16) ^ counters) & 0xffff;  } +static inline int arch_spin_value_unlocked(arch_spinlock_t lock) +{ +	return lock.h.serving_now == lock.h.ticket; +} +  #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)  #define arch_spin_unlock_wait(x) \  	while (arch_spin_is_locked(x)) { cpu_relax(); } diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index 28d6d9364bd1..a71da576883c 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h @@ -152,6 +152,31 @@  		.set	noreorder  		bltz	k0, 8f  		 move	k1, sp +#ifdef CONFIG_EVA +		/* +		 * Flush interAptiv's Return Prediction Stack (RPS) by writing +		 * EntryHi. Toggling Config7.RPS is slower and less portable. +		 * +		 * The RPS isn't automatically flushed when exceptions are +		 * taken, which can result in kernel mode speculative accesses +		 * to user addresses if the RPS mispredicts. That's harmless +		 * when user and kernel share the same address space, but with +		 * EVA the same user segments may be unmapped to kernel mode, +		 * even containing sensitive MMIO regions or invalid memory. +		 * +		 * This can happen when the kernel sets the return address to +		 * ret_from_* and jr's to the exception handler, which looks +		 * more like a tail call than a function call. If nested calls +		 * don't evict the last user address in the RPS, it will +		 * mispredict the return and fetch from a user controlled +		 * address into the icache. +		 * +		 * More recent EVA-capable cores with MAAR to restrict +		 * speculative accesses aren't affected. +		 */ +		MFC0	k0, CP0_ENTRYHI +		MTC0	k0, CP0_ENTRYHI +#endif  		.set	reorder  		/* Called from user mode, new stack. */  		get_saved_sp diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h index 7163cd7fdd69..28b5d84a5022 100644 --- a/arch/mips/include/asm/switch_to.h +++ b/arch/mips/include/asm/switch_to.h @@ -16,29 +16,21 @@  #include <asm/watch.h>  #include <asm/dsp.h>  #include <asm/cop2.h> -#include <asm/msa.h> +#include <asm/fpu.h>  struct task_struct; -enum { -	FP_SAVE_NONE	= 0, -	FP_SAVE_VECTOR	= -1, -	FP_SAVE_SCALAR	= 1, -}; -  /**   * resume - resume execution of a task   * @prev:	The task previously executed.   * @next:	The task to begin executing.   * @next_ti:	task_thread_info(next). - * @fp_save:	Which, if any, FP context to save for prev.   *   * This function is used whilst scheduling to save the context of prev & load   * the context of next. Returns prev.   */  extern asmlinkage struct task_struct *resume(struct task_struct *prev, -		struct task_struct *next, struct thread_info *next_ti, -		s32 fp_save); +		struct task_struct *next, struct thread_info *next_ti);  extern unsigned int ll_bit;  extern struct task_struct *ll_task; @@ -83,45 +75,38 @@ do {	if (cpu_has_rw_llb) {						\  	}								\  } while (0) +/* + * For newly created kernel threads switch_to() will return to + * ret_from_kernel_thread, newly created user threads to ret_from_fork. + * That is, everything following resume() will be skipped for new threads. + * So everything that matters to new threads should be placed before resume(). + */  #define switch_to(prev, next, last)					\  do {									\ -	u32 __c0_stat;							\ -	s32 __fpsave = FP_SAVE_NONE;					\  	__mips_mt_fpaff_switch_to(prev);				\ -	if (cpu_has_dsp)						\ +	lose_fpu_inatomic(1, prev);					\ +	if (cpu_has_dsp) {						\  		__save_dsp(prev);					\ -	if (cop2_present && (KSTK_STATUS(prev) & ST0_CU2)) {		\ -		if (cop2_lazy_restore)					\ -			KSTK_STATUS(prev) &= ~ST0_CU2;			\ -		__c0_stat = read_c0_status();				\ -		write_c0_status(__c0_stat | ST0_CU2);			\ -		cop2_save(prev);					\ -		write_c0_status(__c0_stat & ~ST0_CU2);			\ +		__restore_dsp(next);					\  	}								\ -	__clear_software_ll_bit();					\ -	if (test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU))		\ -		__fpsave = FP_SAVE_SCALAR;				\ -	if (test_and_clear_tsk_thread_flag(prev, TIF_USEDMSA))		\ -		__fpsave = FP_SAVE_VECTOR;				\ -	(last) = resume(prev, next, task_thread_info(next), __fpsave);	\ -} while (0) - -#define finish_arch_switch(prev)					\ -do {									\ -	u32 __c0_stat;							\ -	if (cop2_present && !cop2_lazy_restore &&			\ -			(KSTK_STATUS(current) & ST0_CU2)) {		\ -		__c0_stat = read_c0_status();				\ -		write_c0_status(__c0_stat | ST0_CU2);			\ -		cop2_restore(current);					\ -		write_c0_status(__c0_stat & ~ST0_CU2);			\ +	if (cop2_present) {						\ +		set_c0_status(ST0_CU2);					\ +		if ((KSTK_STATUS(prev) & ST0_CU2)) {			\ +			if (cop2_lazy_restore)				\ +				KSTK_STATUS(prev) &= ~ST0_CU2;		\ +			cop2_save(prev);				\ +		}							\ +		if (KSTK_STATUS(next) & ST0_CU2 &&			\ +		    !cop2_lazy_restore) {				\ +			cop2_restore(next);				\ +		}							\ +		clear_c0_status(ST0_CU2);				\  	}								\ -	if (cpu_has_dsp)						\ -		__restore_dsp(current);					\ +	__clear_software_ll_bit();					\  	if (cpu_has_userlocal)						\ -		write_c0_userlocal(current_thread_info()->tp_value);	\ +		write_c0_userlocal(task_thread_info(next)->tp_value);	\  	__restore_watch();						\ -	disable_msa();							\ +	(last) = resume(prev, next, task_thread_info(next));		\  } while (0)  #endif /* _ASM_SWITCH_TO_H */ diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 9c0014e87c17..e309d8fcb516 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h @@ -99,6 +99,7 @@ static inline struct thread_info *current_thread_info(void)  #define TIF_SYSCALL_AUDIT	3	/* syscall auditing active */  #define TIF_SECCOMP		4	/* secure computing */  #define TIF_NOTIFY_RESUME	5	/* callback before returning to user */ +#define TIF_UPROBE		6	/* breakpointed or singlestepping */  #define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal() */  #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */  #define TIF_MEMDIE		18	/* is terminating due to OOM killer */ @@ -122,6 +123,7 @@ static inline struct thread_info *current_thread_info(void)  #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)  #define _TIF_SECCOMP		(1<<TIF_SECCOMP)  #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME) +#define _TIF_UPROBE		(1<<TIF_UPROBE)  #define _TIF_USEDFPU		(1<<TIF_USEDFPU)  #define _TIF_NOHZ		(1<<TIF_NOHZ)  #define _TIF_FIXADE		(1<<TIF_FIXADE) @@ -146,7 +148,8 @@ static inline struct thread_info *current_thread_info(void)  /* work to do on interrupt/exception return */  #define _TIF_WORK_MASK		\ -	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME) +	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME |	\ +	 _TIF_UPROBE)  /* work to do on any return to u-space */  #define _TIF_ALLWORK_MASK	(_TIF_NOHZ | _TIF_WORK_MASK |		\  				 _TIF_WORK_SYSCALL_EXIT |		\ diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index 8ab2874225c4..17d4cd20f18c 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h @@ -51,7 +51,7 @@ extern int __weak get_c0_perfcount_int(void);  /*   * Initialize the calling CPU's compare interrupt as clockevent device   */ -extern unsigned int __weak get_c0_compare_int(void); +extern unsigned int get_c0_compare_int(void);  extern int r4k_clockevent_init(void);  static inline int mips_clockevent_init(void) diff --git a/arch/mips/include/asm/tlbdebug.h b/arch/mips/include/asm/tlbdebug.h index bb8f5c29c3d9..3a25a8780ac7 100644 --- a/arch/mips/include/asm/tlbdebug.h +++ b/arch/mips/include/asm/tlbdebug.h @@ -11,6 +11,7 @@  /*   * TLB debugging functions:   */ +extern void dump_tlb_regs(void);  extern void dump_tlb_all(void);  #endif /* __ASM_TLBDEBUG_H */ diff --git a/arch/mips/include/asm/uprobes.h b/arch/mips/include/asm/uprobes.h new file mode 100644 index 000000000000..34c325c674c4 --- /dev/null +++ b/arch/mips/include/asm/uprobes.h @@ -0,0 +1,58 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License.  See the file "COPYING" in the main directory of this archive + * for more details. + */ +#ifndef __ASM_UPROBES_H +#define __ASM_UPROBES_H + +#include <linux/notifier.h> +#include <linux/types.h> + +#include <asm/break.h> +#include <asm/inst.h> + +/* + * We want this to be defined as union mips_instruction but that makes the + * generic code blow up. + */ +typedef u32 uprobe_opcode_t; + +/* + * Classic MIPS (note this implementation doesn't consider microMIPS yet) + * instructions are always 4 bytes but in order to deal with branches and + * their delay slots, we treat instructions as having 8 bytes maximum. + */ +#define MAX_UINSN_BYTES			8 +#define UPROBE_XOL_SLOT_BYTES		128	/* Max. cache line size */ + +#define UPROBE_BRK_UPROBE		0x000d000d	/* break 13 */ +#define UPROBE_BRK_UPROBE_XOL		0x000e000d	/* break 14 */ + +#define UPROBE_SWBP_INSN		UPROBE_BRK_UPROBE +#define UPROBE_SWBP_INSN_SIZE		4 + +struct arch_uprobe { +	unsigned long	resume_epc; +	u32	insn[2]; +	u32	ixol[2]; +	union	mips_instruction orig_inst[MAX_UINSN_BYTES / 4]; +}; + +struct arch_uprobe_task { +	unsigned long saved_trap_nr; +}; + +extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, +	struct mm_struct *mm, unsigned long addr); +extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); +extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); +extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); +extern int arch_uprobe_exception_notify(struct notifier_block *self, +	unsigned long val, void *data); +extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, +	struct pt_regs *regs); +extern unsigned long arch_uretprobe_hijack_return_addr( +	unsigned long trampoline_vaddr, struct pt_regs *regs); + +#endif /* __ASM_UPROBES_H */ diff --git a/arch/mips/include/asm/vpe.h b/arch/mips/include/asm/vpe.h index 7849f3978fea..80e70dbd1f64 100644 --- a/arch/mips/include/asm/vpe.h +++ b/arch/mips/include/asm/vpe.h @@ -122,7 +122,7 @@ void release_vpe(struct vpe *v);  void *alloc_progmem(unsigned long len);  void release_progmem(void *ptr); -int __weak vpe_run(struct vpe *v); +int vpe_run(struct vpe *v);  void cleanup_tc(struct tc *tc);  int __init vpe_module_init(void);  |