Commit bec33cd2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'arc-v4.2-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc

Pull ARC fixes from Vineet Gupta:
 - Makefile changes (top-level+ARC) reinstates -O3 builds (regression
   since 3.16)
 - IDU intc related fixes, IRQ affinity
 - patch to make bitops safer for ARC
 - perf fix from Alexey to remove signed PC braino
 - Futex backend gets llock/scond support

* tag 'arc-v4.2-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
  ARCv2: support HS38 releases
  ARC: make sure instruction_pointer() returns unsigned value
  ARC: slightly refactor macros for boot logging
  ARC: Add llock/scond to futex backend
  arc:irqchip: prepare for drivers/irqchip/irqchip.h removal
  ARC: Make ARC bitops "safer" (add anti-optimization)
  ARCv2: [axs103] bump CPU frequency from 75 to 90 MHZ
  ARCv2: intc: IDU: Fix potential race in installing a chained IRQ handler
  ARCv2: intc: IDU: support irq affinity
  ARC: fix unused var wanring
  ARC: Don't memzero twice in dma_alloc_coherent for __GFP_ZERO
  ARC: Override toplevel default -O2 with -O3
  kbuild: Allow arch Makefiles to override {cpp,ld,c}flags
  ARCv2: guard SLC DMA ops with spinlock
  ARC: Kconfig: better way to disable ARC_HAS_LLSC for ARC_CPU_750D
parents 9c69481e 624b71ee
...@@ -952,6 +952,14 @@ When kbuild executes, the following steps are followed (roughly): ...@@ -952,6 +952,14 @@ When kbuild executes, the following steps are followed (roughly):
$(KBUILD_ARFLAGS) set by the top level Makefile to "D" (deterministic $(KBUILD_ARFLAGS) set by the top level Makefile to "D" (deterministic
mode) if this option is supported by $(AR). mode) if this option is supported by $(AR).
ARCH_CPPFLAGS, ARCH_AFLAGS, ARCH_CFLAGS Overrides the kbuild defaults
These variables are appended to the KBUILD_CPPFLAGS,
KBUILD_AFLAGS, and KBUILD_CFLAGS, respectively, after the
top-level Makefile has set any other flags. This provides a
means for an architecture to override the defaults.
--- 6.2 Add prerequisites to archheaders: --- 6.2 Add prerequisites to archheaders:
The archheaders: rule is used to generate header files that The archheaders: rule is used to generate header files that
......
...@@ -780,10 +780,11 @@ endif ...@@ -780,10 +780,11 @@ endif
include scripts/Makefile.kasan include scripts/Makefile.kasan
include scripts/Makefile.extrawarn include scripts/Makefile.extrawarn
# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments # Add any arch overrides and user supplied CPPFLAGS, AFLAGS and CFLAGS as the
KBUILD_CPPFLAGS += $(KCPPFLAGS) # last assignments
KBUILD_AFLAGS += $(KAFLAGS) KBUILD_CPPFLAGS += $(ARCH_CPPFLAGS) $(KCPPFLAGS)
KBUILD_CFLAGS += $(KCFLAGS) KBUILD_AFLAGS += $(ARCH_AFLAGS) $(KAFLAGS)
KBUILD_CFLAGS += $(ARCH_CFLAGS) $(KCFLAGS)
# Use --build-id when available. # Use --build-id when available.
LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\ LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
......
...@@ -115,6 +115,7 @@ if ISA_ARCOMPACT ...@@ -115,6 +115,7 @@ if ISA_ARCOMPACT
config ARC_CPU_750D config ARC_CPU_750D
bool "ARC750D" bool "ARC750D"
select ARC_CANT_LLSC
help help
Support for ARC750 core Support for ARC750 core
...@@ -362,7 +363,7 @@ config ARC_CANT_LLSC ...@@ -362,7 +363,7 @@ config ARC_CANT_LLSC
config ARC_HAS_LLSC config ARC_HAS_LLSC
bool "Insn: LLOCK/SCOND (efficient atomic ops)" bool "Insn: LLOCK/SCOND (efficient atomic ops)"
default y default y
depends on !ARC_CPU_750D && !ARC_CANT_LLSC depends on !ARC_CANT_LLSC
config ARC_HAS_SWAPE config ARC_HAS_SWAPE
bool "Insn: SWAPE (endian-swap)" bool "Insn: SWAPE (endian-swap)"
......
...@@ -49,7 +49,8 @@ endif ...@@ -49,7 +49,8 @@ endif
ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE
# Generic build system uses -O2, we want -O3 # Generic build system uses -O2, we want -O3
cflags-y += -O3 # Note: No need to add to cflags-y as that happens anyways
ARCH_CFLAGS += -O3
endif endif
# small data is default for elf32 tool-chain. If not usable, disable it # small data is default for elf32 tool-chain. If not usable, disable it
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
/ { / {
compatible = "snps,arc"; compatible = "snps,arc";
clock-frequency = <75000000>; clock-frequency = <90000000>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
/ { / {
compatible = "snps,arc"; compatible = "snps,arc";
clock-frequency = <75000000>; clock-frequency = <90000000>;
#address-cells = <1>; #address-cells = <1>;
#size-cells = <1>; #size-cells = <1>;
......
...@@ -50,8 +50,7 @@ static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\ ...@@ -50,8 +50,7 @@ static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
* done for const @nr, but no code is generated due to gcc \ * done for const @nr, but no code is generated due to gcc \
* const prop. \ * const prop. \
*/ \ */ \
if (__builtin_constant_p(nr)) \ nr &= 0x1f; \
nr &= 0x1f; \
\ \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: llock %0, [%1] \n" \ "1: llock %0, [%1] \n" \
...@@ -82,8 +81,7 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long * ...@@ -82,8 +81,7 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
\ \
m += nr >> 5; \ m += nr >> 5; \
\ \
if (__builtin_constant_p(nr)) \ nr &= 0x1f; \
nr &= 0x1f; \
\ \
/* \ /* \
* Explicit full memory barrier needed before/after as \ * Explicit full memory barrier needed before/after as \
...@@ -129,16 +127,13 @@ static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\ ...@@ -129,16 +127,13 @@ static inline void op##_bit(unsigned long nr, volatile unsigned long *m)\
unsigned long temp, flags; \ unsigned long temp, flags; \
m += nr >> 5; \ m += nr >> 5; \
\ \
if (__builtin_constant_p(nr)) \
nr &= 0x1f; \
\
/* \ /* \
* spin lock/unlock provide the needed smp_mb() before/after \ * spin lock/unlock provide the needed smp_mb() before/after \
*/ \ */ \
bitops_lock(flags); \ bitops_lock(flags); \
\ \
temp = *m; \ temp = *m; \
*m = temp c_op (1UL << nr); \ *m = temp c_op (1UL << (nr & 0x1f)); \
\ \
bitops_unlock(flags); \ bitops_unlock(flags); \
} }
...@@ -149,17 +144,14 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long * ...@@ -149,17 +144,14 @@ static inline int test_and_##op##_bit(unsigned long nr, volatile unsigned long *
unsigned long old, flags; \ unsigned long old, flags; \
m += nr >> 5; \ m += nr >> 5; \
\ \
if (__builtin_constant_p(nr)) \
nr &= 0x1f; \
\
bitops_lock(flags); \ bitops_lock(flags); \
\ \
old = *m; \ old = *m; \
*m = old c_op (1 << nr); \ *m = old c_op (1UL << (nr & 0x1f)); \
\ \
bitops_unlock(flags); \ bitops_unlock(flags); \
\ \
return (old & (1 << nr)) != 0; \ return (old & (1UL << (nr & 0x1f))) != 0; \
} }
#endif /* CONFIG_ARC_HAS_LLSC */ #endif /* CONFIG_ARC_HAS_LLSC */
...@@ -174,11 +166,8 @@ static inline void __##op##_bit(unsigned long nr, volatile unsigned long *m) \ ...@@ -174,11 +166,8 @@ static inline void __##op##_bit(unsigned long nr, volatile unsigned long *m) \
unsigned long temp; \ unsigned long temp; \
m += nr >> 5; \ m += nr >> 5; \
\ \
if (__builtin_constant_p(nr)) \
nr &= 0x1f; \
\
temp = *m; \ temp = *m; \
*m = temp c_op (1UL << nr); \ *m = temp c_op (1UL << (nr & 0x1f)); \
} }
#define __TEST_N_BIT_OP(op, c_op, asm_op) \ #define __TEST_N_BIT_OP(op, c_op, asm_op) \
...@@ -187,13 +176,10 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long ...@@ -187,13 +176,10 @@ static inline int __test_and_##op##_bit(unsigned long nr, volatile unsigned long
unsigned long old; \ unsigned long old; \
m += nr >> 5; \ m += nr >> 5; \
\ \
if (__builtin_constant_p(nr)) \
nr &= 0x1f; \
\
old = *m; \ old = *m; \
*m = old c_op (1 << nr); \ *m = old c_op (1UL << (nr & 0x1f)); \
\ \
return (old & (1 << nr)) != 0; \ return (old & (1UL << (nr & 0x1f))) != 0; \
} }
#define BIT_OPS(op, c_op, asm_op) \ #define BIT_OPS(op, c_op, asm_op) \
...@@ -224,10 +210,7 @@ test_bit(unsigned int nr, const volatile unsigned long *addr) ...@@ -224,10 +210,7 @@ test_bit(unsigned int nr, const volatile unsigned long *addr)
addr += nr >> 5; addr += nr >> 5;
if (__builtin_constant_p(nr)) mask = 1UL << (nr & 0x1f);
nr &= 0x1f;
mask = 1 << nr;
return ((mask & *addr) != 0); return ((mask & *addr) != 0);
} }
......
...@@ -16,12 +16,40 @@ ...@@ -16,12 +16,40 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/errno.h> #include <asm/errno.h>
#ifdef CONFIG_ARC_HAS_LLSC
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)\
\
__asm__ __volatile__( \
"1: llock %1, [%2] \n" \
insn "\n" \
"2: scond %0, [%2] \n" \
" bnz 1b \n" \
" mov %0, 0 \n" \
"3: \n" \
" .section .fixup,\"ax\" \n" \
" .align 4 \n" \
"4: mov %0, %4 \n" \
" b 3b \n" \
" .previous \n" \
" .section __ex_table,\"a\" \n" \
" .align 4 \n" \
" .word 1b, 4b \n" \
" .word 2b, 4b \n" \
" .previous \n" \
\
: "=&r" (ret), "=&r" (oldval) \
: "r" (uaddr), "r" (oparg), "ir" (-EFAULT) \
: "cc", "memory")
#else /* !CONFIG_ARC_HAS_LLSC */
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)\ #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)\
\ \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: ld %1, [%2] \n" \ "1: ld %1, [%2] \n" \
insn "\n" \ insn "\n" \
"2: st %0, [%2] \n" \ "2: st %0, [%2] \n" \
" mov %0, 0 \n" \ " mov %0, 0 \n" \
"3: \n" \ "3: \n" \
" .section .fixup,\"ax\" \n" \ " .section .fixup,\"ax\" \n" \
...@@ -39,6 +67,8 @@ ...@@ -39,6 +67,8 @@
: "r" (uaddr), "r" (oparg), "ir" (-EFAULT) \ : "r" (uaddr), "r" (oparg), "ir" (-EFAULT) \
: "cc", "memory") : "cc", "memory")
#endif
static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr) static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
{ {
int op = (encoded_op >> 28) & 7; int op = (encoded_op >> 28) & 7;
...@@ -123,11 +153,17 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, ...@@ -123,11 +153,17 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval,
pagefault_disable(); pagefault_disable();
/* TBD : can use llock/scond */
__asm__ __volatile__( __asm__ __volatile__(
"1: ld %0, [%3] \n" #ifdef CONFIG_ARC_HAS_LLSC
" brne %0, %1, 3f \n" "1: llock %0, [%3] \n"
"2: st %2, [%3] \n" " brne %0, %1, 3f \n"
"2: scond %2, [%3] \n"
" bnz 1b \n"
#else
"1: ld %0, [%3] \n"
" brne %0, %1, 3f \n"
"2: st %2, [%3] \n"
#endif
"3: \n" "3: \n"
" .section .fixup,\"ax\" \n" " .section .fixup,\"ax\" \n"
"4: mov %0, %4 \n" "4: mov %0, %4 \n"
......
...@@ -106,7 +106,7 @@ struct callee_regs { ...@@ -106,7 +106,7 @@ struct callee_regs {
long r25, r24, r23, r22, r21, r20, r19, r18, r17, r16, r15, r14, r13; long r25, r24, r23, r22, r21, r20, r19, r18, r17, r16, r15, r14, r13;
}; };
#define instruction_pointer(regs) ((regs)->ret) #define instruction_pointer(regs) (unsigned long)((regs)->ret)
#define profile_pc(regs) instruction_pointer(regs) #define profile_pc(regs) instruction_pointer(regs)
/* return 1 if user mode or 0 if kernel mode */ /* return 1 if user mode or 0 if kernel mode */
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include "../../drivers/irqchip/irqchip.h"
#include <asm/irq.h> #include <asm/irq.h>
/* /*
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include "../../drivers/irqchip/irqchip.h"
#include <asm/irq.h> #include <asm/irq.h>
/* /*
......
...@@ -175,7 +175,6 @@ void mcip_init_early_smp(void) ...@@ -175,7 +175,6 @@ void mcip_init_early_smp(void)
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include "../../drivers/irqchip/irqchip.h"
/* /*
* Set the DEST for @cmn_irq to @cpu_mask (1 bit per core) * Set the DEST for @cmn_irq to @cpu_mask (1 bit per core)
...@@ -218,11 +217,28 @@ static void idu_irq_unmask(struct irq_data *data) ...@@ -218,11 +217,28 @@ static void idu_irq_unmask(struct irq_data *data)
raw_spin_unlock_irqrestore(&mcip_lock, flags); raw_spin_unlock_irqrestore(&mcip_lock, flags);
} }
#ifdef CONFIG_SMP
static int static int
idu_irq_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool f) idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
bool force)
{ {
unsigned long flags;
cpumask_t online;
/* errout if no online cpu per @cpumask */
if (!cpumask_and(&online, cpumask, cpu_online_mask))
return -EINVAL;
raw_spin_lock_irqsave(&mcip_lock, flags);
idu_set_dest(data->hwirq, cpumask_bits(&online)[0]);
idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, IDU_M_DISTRI_RR);
raw_spin_unlock_irqrestore(&mcip_lock, flags);
return IRQ_SET_MASK_OK; return IRQ_SET_MASK_OK;
} }
#endif
static struct irq_chip idu_irq_chip = { static struct irq_chip idu_irq_chip = {
.name = "MCIP IDU Intc", .name = "MCIP IDU Intc",
...@@ -330,8 +346,7 @@ idu_of_init(struct device_node *intc, struct device_node *parent) ...@@ -330,8 +346,7 @@ idu_of_init(struct device_node *intc, struct device_node *parent)
if (!i) if (!i)
idu_first_irq = irq; idu_first_irq = irq;
irq_set_handler_data(irq, domain); irq_set_chained_handler_and_data(irq, idu_cascade_isr, domain);
irq_set_chained_handler(irq, idu_cascade_isr);
} }
__mcip_cmd(CMD_IDU_ENABLE, 0); __mcip_cmd(CMD_IDU_ENABLE, 0);
......
...@@ -142,17 +142,22 @@ static void read_arc_build_cfg_regs(void) ...@@ -142,17 +142,22 @@ static void read_arc_build_cfg_regs(void)
} }
static const struct cpuinfo_data arc_cpu_tbl[] = { static const struct cpuinfo_data arc_cpu_tbl[] = {
#ifdef CONFIG_ISA_ARCOMPACT
{ {0x20, "ARC 600" }, 0x2F}, { {0x20, "ARC 600" }, 0x2F},
{ {0x30, "ARC 700" }, 0x33}, { {0x30, "ARC 700" }, 0x33},
{ {0x34, "ARC 700 R4.10"}, 0x34}, { {0x34, "ARC 700 R4.10"}, 0x34},
{ {0x35, "ARC 700 R4.11"}, 0x35}, { {0x35, "ARC 700 R4.11"}, 0x35},
{ {0x50, "ARC HS38" }, 0x51}, #else
{ {0x50, "ARC HS38 R2.0"}, 0x51},
{ {0x52, "ARC HS38 R2.1"}, 0x52},
#endif
{ {0x00, NULL } } { {0x00, NULL } }
}; };
#define IS_AVAIL1(v, str) ((v) ? str : "") #define IS_AVAIL1(v, s) ((v) ? s : "")
#define IS_USED(cfg) (IS_ENABLED(cfg) ? "" : "(not used) ") #define IS_USED_RUN(v) ((v) ? "" : "(not used) ")
#define IS_AVAIL2(v, str, cfg) IS_AVAIL1(v, str), IS_AVAIL1(v, IS_USED(cfg)) #define IS_USED_CFG(cfg) IS_USED_RUN(IS_ENABLED(cfg))
#define IS_AVAIL2(v, s, cfg) IS_AVAIL1(v, s), IS_AVAIL1(v, IS_USED_CFG(cfg))
static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
{ {
...@@ -226,7 +231,7 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) ...@@ -226,7 +231,7 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
n += scnprintf(buf + n, len - n, "mpy[opt %d] ", opt); n += scnprintf(buf + n, len - n, "mpy[opt %d] ", opt);
} }
n += scnprintf(buf + n, len - n, "%s", n += scnprintf(buf + n, len - n, "%s",
IS_USED(CONFIG_ARC_HAS_HW_MPY)); IS_USED_CFG(CONFIG_ARC_HAS_HW_MPY));
} }
n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n", n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n",
......
...@@ -58,7 +58,6 @@ static void show_callee_regs(struct callee_regs *cregs) ...@@ -58,7 +58,6 @@ static void show_callee_regs(struct callee_regs *cregs)
static void print_task_path_n_nm(struct task_struct *tsk, char *buf) static void print_task_path_n_nm(struct task_struct *tsk, char *buf)
{ {
struct path path;
char *path_nm = NULL; char *path_nm = NULL;
struct mm_struct *mm; struct mm_struct *mm;
struct file *exe_file; struct file *exe_file;
......
...@@ -468,10 +468,18 @@ static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr, ...@@ -468,10 +468,18 @@ static void __ic_line_inv_vaddr(unsigned long paddr, unsigned long vaddr,
noinline void slc_op(unsigned long paddr, unsigned long sz, const int op) noinline void slc_op(unsigned long paddr, unsigned long sz, const int op)
{ {
#ifdef CONFIG_ISA_ARCV2 #ifdef CONFIG_ISA_ARCV2
/*
* SLC is shared between all cores and concurrent aux operations from
* multiple cores need to be serialized using a spinlock
* A concurrent operation can be silently ignored and/or the old/new
* operation can remain incomplete forever (lockup in SLC_CTRL_BUSY loop
* below)
*/
static DEFINE_SPINLOCK(lock);
unsigned long flags; unsigned long flags;
unsigned int ctrl; unsigned int ctrl;
local_irq_save(flags); spin_lock_irqsave(&lock, flags);
/* /*
* The Region Flush operation is specified by CTRL.RGN_OP[11..9] * The Region Flush operation is specified by CTRL.RGN_OP[11..9]
...@@ -504,7 +512,7 @@ noinline void slc_op(unsigned long paddr, unsigned long sz, const int op) ...@@ -504,7 +512,7 @@ noinline void slc_op(unsigned long paddr, unsigned long sz, const int op)
while (read_aux_reg(ARC_REG_SLC_CTRL) & SLC_CTRL_BUSY); while (read_aux_reg(ARC_REG_SLC_CTRL) & SLC_CTRL_BUSY);
local_irq_restore(flags); spin_unlock_irqrestore(&lock, flags);
#endif #endif
} }
......
...@@ -60,8 +60,8 @@ void *dma_alloc_coherent(struct device *dev, size_t size, ...@@ -60,8 +60,8 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
/* This is kernel Virtual address (0x7000_0000 based) */ /* This is kernel Virtual address (0x7000_0000 based) */
kvaddr = ioremap_nocache((unsigned long)paddr, size); kvaddr = ioremap_nocache((unsigned long)paddr, size);
if (kvaddr != NULL) if (kvaddr == NULL)
memset(kvaddr, 0, size); return NULL;
/* This is bus address, platform dependent */ /* This is bus address, platform dependent */
*dma_handle = (dma_addr_t)paddr; *dma_handle = (dma_addr_t)paddr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment