aboutsummaryrefslogtreecommitdiffstats
path: root/arch/metag
diff options
context:
space:
mode:
Diffstat (limited to 'arch/metag')
-rw-r--r--arch/metag/Kconfig2
-rw-r--r--arch/metag/Kconfig.soc1
-rw-r--r--arch/metag/include/asm/atomic_lnkget.h36
-rw-r--r--arch/metag/include/asm/atomic_lock1.h33
-rw-r--r--arch/metag/include/asm/metag_regs.h2
-rw-r--r--arch/metag/include/asm/pgalloc.h5
-rw-r--r--arch/metag/include/asm/processor.h2
-rw-r--r--arch/metag/include/asm/spinlock.h14
-rw-r--r--arch/metag/include/asm/tbx.h6
-rw-r--r--arch/metag/include/uapi/asm/unistd.h2
-rw-r--r--arch/metag/kernel/ftrace.c1
-rw-r--r--arch/metag/kernel/perf/perf_event.c29
-rw-r--r--arch/metag/kernel/perf_callchain.c10
-rw-r--r--arch/metag/kernel/process.c6
-rw-r--r--arch/metag/mm/fault.c2
-rw-r--r--arch/metag/mm/hugetlbpage.c1
-rw-r--r--arch/metag/tbx/tbipcx.S2
-rw-r--r--arch/metag/tbx/tbisoft.S6
18 files changed, 107 insertions, 53 deletions
diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig
index a0fa88da3e31..5b7a45d99cfb 100644
--- a/arch/metag/Kconfig
+++ b/arch/metag/Kconfig
@@ -11,6 +11,7 @@ config METAG
select HAVE_DEBUG_KMEMLEAK
select HAVE_DEBUG_STACKOVERFLOW
select HAVE_DYNAMIC_FTRACE
+ select HAVE_EXIT_THREAD
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_TRACER
select HAVE_KERNEL_BZIP2
@@ -29,6 +30,7 @@ config METAG
select OF
select OF_EARLY_FLATTREE
select SPARSE_IRQ
+ select CPU_NO_EFFICIENT_FFS
config STACKTRACE_SUPPORT
def_bool y
diff --git a/arch/metag/Kconfig.soc b/arch/metag/Kconfig.soc
index 973640f46752..50f979c2b02d 100644
--- a/arch/metag/Kconfig.soc
+++ b/arch/metag/Kconfig.soc
@@ -16,7 +16,6 @@ config META21_FPGA
config SOC_TZ1090
bool "Toumaz Xenif TZ1090 SoC (Comet)"
- select ARCH_WANT_OPTIONAL_GPIOLIB
select IMGPDC_IRQ
select METAG_LNKGET_AROUND_CACHE
select METAG_META21
diff --git a/arch/metag/include/asm/atomic_lnkget.h b/arch/metag/include/asm/atomic_lnkget.h
index a62581815624..def2c642f053 100644
--- a/arch/metag/include/asm/atomic_lnkget.h
+++ b/arch/metag/include/asm/atomic_lnkget.h
@@ -61,6 +61,30 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
" CMPT %0, #HI(0x02000000)\n" \
" BNZ 1b\n" \
: "=&d" (temp), "=&da" (result) \
+ : "da" (&v->counter), "br" (i) \
+ : "cc"); \
+ \
+ smp_mb(); \
+ \
+ return result; \
+}
+
+#define ATOMIC_FETCH_OP(op) \
+static inline int atomic_fetch_##op(int i, atomic_t *v) \
+{ \
+ int result, temp; \
+ \
+ smp_mb(); \
+ \
+ asm volatile ( \
+ "1: LNKGETD %1, [%2]\n" \
+ " " #op " %0, %1, %3\n" \
+ " LNKSETD [%2], %0\n" \
+ " DEFR %0, TXSTAT\n" \
+ " ANDT %0, %0, #HI(0x3f000000)\n" \
+ " CMPT %0, #HI(0x02000000)\n" \
+ " BNZ 1b\n" \
+ : "=&d" (temp), "=&d" (result) \
: "da" (&v->counter), "bd" (i) \
: "cc"); \
\
@@ -69,16 +93,20 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return result; \
}
-#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op)
+#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) ATOMIC_FETCH_OP(op)
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
-ATOMIC_OP(and)
-ATOMIC_OP(or)
-ATOMIC_OP(xor)
+#undef ATOMIC_OPS
+#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_FETCH_OP(op)
+
+ATOMIC_OPS(and)
+ATOMIC_OPS(or)
+ATOMIC_OPS(xor)
#undef ATOMIC_OPS
+#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
diff --git a/arch/metag/include/asm/atomic_lock1.h b/arch/metag/include/asm/atomic_lock1.h
index 0295d9b8d5bf..6c1380a8a0d4 100644
--- a/arch/metag/include/asm/atomic_lock1.h
+++ b/arch/metag/include/asm/atomic_lock1.h
@@ -64,15 +64,40 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return result; \
}
-#define ATOMIC_OPS(op, c_op) ATOMIC_OP(op, c_op) ATOMIC_OP_RETURN(op, c_op)
+#define ATOMIC_FETCH_OP(op, c_op) \
+static inline int atomic_fetch_##op(int i, atomic_t *v) \
+{ \
+ unsigned long result; \
+ unsigned long flags; \
+ \
+ __global_lock1(flags); \
+ result = v->counter; \
+ fence(); \
+ v->counter c_op i; \
+ __global_unlock1(flags); \
+ \
+ return result; \
+}
+
+#define ATOMIC_OPS(op, c_op) \
+ ATOMIC_OP(op, c_op) \
+ ATOMIC_OP_RETURN(op, c_op) \
+ ATOMIC_FETCH_OP(op, c_op)
ATOMIC_OPS(add, +=)
ATOMIC_OPS(sub, -=)
-ATOMIC_OP(and, &=)
-ATOMIC_OP(or, |=)
-ATOMIC_OP(xor, ^=)
#undef ATOMIC_OPS
+#define ATOMIC_OPS(op, c_op) \
+ ATOMIC_OP(op, c_op) \
+ ATOMIC_FETCH_OP(op, c_op)
+
+ATOMIC_OPS(and, &=)
+ATOMIC_OPS(or, |=)
+ATOMIC_OPS(xor, ^=)
+
+#undef ATOMIC_OPS
+#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
diff --git a/arch/metag/include/asm/metag_regs.h b/arch/metag/include/asm/metag_regs.h
index acf4b8e6e9d1..40c3f679c5b8 100644
--- a/arch/metag/include/asm/metag_regs.h
+++ b/arch/metag/include/asm/metag_regs.h
@@ -1165,7 +1165,7 @@
#define TXSTATUS_IPTOGGLE_BIT 0x80000000 /* Prev PToggle of TXPRIVEXT */
#define TXSTATUS_ISTATE_BIT 0x40000000 /* IState bit */
#define TXSTATUS_IWAIT_BIT 0x20000000 /* wait indefinitely in decision step*/
-#define TXSTATUS_IEXCEPT_BIT 0x10000000 /* Indicate an exception occured */
+#define TXSTATUS_IEXCEPT_BIT 0x10000000 /* Indicate an exception occurred */
#define TXSTATUS_IRPCOUNT_BITS 0x0E000000 /* Number of 'dirty' date entries*/
#define TXSTATUS_IRPCOUNT_S 25
#define TXSTATUS_IRQSTAT_BITS 0x0000F000 /* IRQEnc bits, trigger or interrupts */
diff --git a/arch/metag/include/asm/pgalloc.h b/arch/metag/include/asm/pgalloc.h
index 3104df0a4822..c2caa1ee4360 100644
--- a/arch/metag/include/asm/pgalloc.h
+++ b/arch/metag/include/asm/pgalloc.h
@@ -42,8 +42,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
- pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT |
- __GFP_ZERO);
+ pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
return pte;
}
@@ -51,7 +50,7 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
unsigned long address)
{
struct page *pte;
- pte = alloc_pages(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO, 0);
+ pte = alloc_pages(GFP_KERNEL | __GFP_ZERO, 0);
if (!pte)
return NULL;
if (!pgtable_page_ctor(pte)) {
diff --git a/arch/metag/include/asm/processor.h b/arch/metag/include/asm/processor.h
index 0838ca699764..a0333ebcac35 100644
--- a/arch/metag/include/asm/processor.h
+++ b/arch/metag/include/asm/processor.h
@@ -134,8 +134,6 @@ static inline void release_thread(struct task_struct *dead_task)
#define copy_segments(tsk, mm) do { } while (0)
#define release_segments(mm) do { } while (0)
-extern void exit_thread(void);
-
/*
* Return saved PC of a blocked thread.
*/
diff --git a/arch/metag/include/asm/spinlock.h b/arch/metag/include/asm/spinlock.h
index 86a7cf3d1386..c0c7a22be1ae 100644
--- a/arch/metag/include/asm/spinlock.h
+++ b/arch/metag/include/asm/spinlock.h
@@ -1,14 +1,24 @@
#ifndef __ASM_SPINLOCK_H
#define __ASM_SPINLOCK_H
+#include <asm/barrier.h>
+#include <asm/processor.h>
+
#ifdef CONFIG_METAG_ATOMICITY_LOCK1
#include <asm/spinlock_lock1.h>
#else
#include <asm/spinlock_lnkget.h>
#endif
-#define arch_spin_unlock_wait(lock) \
- do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
+/*
+ * both lock1 and lnkget are test-and-set spinlocks with 0 unlocked and 1
+ * locked.
+ */
+
+static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
+{
+ smp_cond_load_acquire(&lock->lock, !VAL);
+}
#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
diff --git a/arch/metag/include/asm/tbx.h b/arch/metag/include/asm/tbx.h
index 703b9cb0ac5c..5cd2a6c86223 100644
--- a/arch/metag/include/asm/tbx.h
+++ b/arch/metag/include/asm/tbx.h
@@ -668,7 +668,7 @@ typedef union _tbires_tag_ {
State.Sig.TrigMask will indicate the bits set within TXMASKI at
the time of the handler call that have all been cleared to prevent
- nested interrupt occuring immediately.
+ nested interrupt occurring immediately.
State.Sig.SaveMask is a bit-mask which will be set to Zero when a trigger
occurs at background level and TBICTX_CRIT_BIT and optionally
@@ -1083,7 +1083,7 @@ TBIRES __TBINestInts( TBIRES State, void *pExt, int NoNestMask );
/* This routine causes the TBICTX structure specified in State.Sig.pCtx to
be restored. This implies that execution will not return to the caller.
The State.Sig.TrigMask field will be restored during the context switch
- such that any immediately occuring interrupts occur in the context of the
+ such that any immediately occurring interrupts occur in the context of the
newly specified task. The State.Sig.SaveMask parameter is ignored. */
void __TBIASyncResume( TBIRES State );
@@ -1305,7 +1305,7 @@ extern const char __TBISigNames[];
/*
* Calculate linear PC value from real PC and Minim mode control, the LSB of
- * the result returned indicates if address compression has occured.
+ * the result returned indicates if address compression has occurred.
*/
#ifndef __ASSEMBLY__
#define METAG_LINPC( PCVal ) (\
diff --git a/arch/metag/include/uapi/asm/unistd.h b/arch/metag/include/uapi/asm/unistd.h
index b80b8e899d22..459b6ec15848 100644
--- a/arch/metag/include/uapi/asm/unistd.h
+++ b/arch/metag/include/uapi/asm/unistd.h
@@ -7,6 +7,8 @@
* (at your option) any later version.
*/
+#define __ARCH_WANT_RENAMEAT
+
/* Use the standard ABI for syscalls. */
#include <asm-generic/unistd.h>
diff --git a/arch/metag/kernel/ftrace.c b/arch/metag/kernel/ftrace.c
index ac8c039b0318..f7b23d300881 100644
--- a/arch/metag/kernel/ftrace.c
+++ b/arch/metag/kernel/ftrace.c
@@ -115,7 +115,6 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
return ftrace_modify_code(ip, old, new);
}
-/* run from kstop_machine */
int __init ftrace_dyn_arch_init(void)
{
return 0;
diff --git a/arch/metag/kernel/perf/perf_event.c b/arch/metag/kernel/perf/perf_event.c
index 2478ec6d23c9..052cba23708c 100644
--- a/arch/metag/kernel/perf/perf_event.c
+++ b/arch/metag/kernel/perf/perf_event.c
@@ -618,6 +618,8 @@ static void metag_pmu_enable_counter(struct hw_perf_event *event, int idx)
/* Check for a core internal or performance channel event. */
if (tmp) {
+ /* PERF_ICORE/PERF_CHAN only exist since Meta2 */
+#ifdef METAC_2_1
void *perf_addr;
/*
@@ -640,6 +642,7 @@ static void metag_pmu_enable_counter(struct hw_perf_event *event, int idx)
if (perf_addr)
metag_out32((config & 0x0f), perf_addr);
+#endif
/*
* Now we use the high nibble as the performance event to
@@ -803,25 +806,16 @@ static struct metag_pmu _metag_pmu = {
};
/* PMU CPU hotplug notifier */
-static int metag_pmu_cpu_notify(struct notifier_block *b, unsigned long action,
- void *hcpu)
+static int metag_pmu_starting_cpu(unsigned int cpu)
{
- unsigned int cpu = (unsigned int)hcpu;
struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
- if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
- return NOTIFY_DONE;
-
memset(cpuc, 0, sizeof(struct cpu_hw_events));
raw_spin_lock_init(&cpuc->pmu_lock);
- return NOTIFY_OK;
+ return 0;
}
-static struct notifier_block metag_pmu_notifier = {
- .notifier_call = metag_pmu_cpu_notify,
-};
-
/* PMU Initialisation */
static int __init init_hw_perf_events(void)
{
@@ -873,16 +867,13 @@ static int __init init_hw_perf_events(void)
metag_out32(0, PERF_COUNT(0));
metag_out32(0, PERF_COUNT(1));
- for_each_possible_cpu(cpu) {
- struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
+ cpuhp_setup_state(CPUHP_AP_PERF_METAG_STARTING,
+ "AP_PERF_METAG_STARTING", metag_pmu_starting_cpu,
+ NULL);
- memset(cpuc, 0, sizeof(struct cpu_hw_events));
- raw_spin_lock_init(&cpuc->pmu_lock);
- }
-
- register_cpu_notifier(&metag_pmu_notifier);
ret = perf_pmu_register(&pmu, metag_pmu->name, PERF_TYPE_RAW);
-out:
+ if (ret)
+ cpuhp_remove_state_nocalls(CPUHP_AP_PERF_METAG_STARTING);
return ret;
}
early_initcall(init_hw_perf_events);
diff --git a/arch/metag/kernel/perf_callchain.c b/arch/metag/kernel/perf_callchain.c
index 315633461a94..3e8e048040df 100644
--- a/arch/metag/kernel/perf_callchain.c
+++ b/arch/metag/kernel/perf_callchain.c
@@ -29,7 +29,7 @@ static bool is_valid_call(unsigned long calladdr)
static struct metag_frame __user *
user_backtrace(struct metag_frame __user *user_frame,
- struct perf_callchain_entry *entry)
+ struct perf_callchain_entry_ctx *entry)
{
struct metag_frame frame;
unsigned long calladdr;
@@ -56,7 +56,7 @@ user_backtrace(struct metag_frame __user *user_frame,
}
void
-perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
+perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
{
unsigned long sp = regs->ctx.AX[0].U0;
struct metag_frame __user *frame;
@@ -65,7 +65,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
--frame;
- while ((entry->nr < PERF_MAX_STACK_DEPTH) && frame)
+ while ((entry->nr < entry->max_stack) && frame)
frame = user_backtrace(frame, entry);
}
@@ -78,13 +78,13 @@ static int
callchain_trace(struct stackframe *fr,
void *data)
{
- struct perf_callchain_entry *entry = data;
+ struct perf_callchain_entry_ctx *entry = data;
perf_callchain_store(entry, fr->pc);
return 0;
}
void
-perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
+perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
{
struct stackframe fr;
diff --git a/arch/metag/kernel/process.c b/arch/metag/kernel/process.c
index 7f546183a0f0..35062796edf2 100644
--- a/arch/metag/kernel/process.c
+++ b/arch/metag/kernel/process.c
@@ -345,10 +345,10 @@ void flush_thread(void)
/*
* Free current thread data structures etc.
*/
-void exit_thread(void)
+void exit_thread(struct task_struct *tsk)
{
- clear_fpu(&current->thread);
- clear_dsp(&current->thread);
+ clear_fpu(&tsk->thread);
+ clear_dsp(&tsk->thread);
}
/* TODO: figure out how to unwind the kernel stack here to figure out
diff --git a/arch/metag/mm/fault.c b/arch/metag/mm/fault.c
index f57edca63609..372783a67dda 100644
--- a/arch/metag/mm/fault.c
+++ b/arch/metag/mm/fault.c
@@ -133,7 +133,7 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
- fault = handle_mm_fault(mm, vma, address, flags);
+ fault = handle_mm_fault(vma, address, flags);
if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
return 0;
diff --git a/arch/metag/mm/hugetlbpage.c b/arch/metag/mm/hugetlbpage.c
index b38700ae4e84..db1b7da91e4f 100644
--- a/arch/metag/mm/hugetlbpage.c
+++ b/arch/metag/mm/hugetlbpage.c
@@ -239,6 +239,7 @@ static __init int setup_hugepagesz(char *opt)
if (ps == (1 << HPAGE_SHIFT)) {
hugetlb_add_hstate(HPAGE_SHIFT - PAGE_SHIFT);
} else {
+ hugetlb_bad_size();
pr_err("hugepagesz: Unsupported page size %lu M\n",
ps >> 20);
return 0;
diff --git a/arch/metag/tbx/tbipcx.S b/arch/metag/tbx/tbipcx.S
index de0626fdad25..163c79ac913b 100644
--- a/arch/metag/tbx/tbipcx.S
+++ b/arch/metag/tbx/tbipcx.S
@@ -15,7 +15,7 @@
#include <asm/tbx.h>
/* BEGIN HACK */
-/* define these for now while doing inital conversion to GAS
+/* define these for now while doing initial conversion to GAS
will fix properly later */
/* Signal identifiers always have the TBID_SIGNAL_BIT set and contain the
diff --git a/arch/metag/tbx/tbisoft.S b/arch/metag/tbx/tbisoft.S
index 0346fe8a53b1..b04f50df8d91 100644
--- a/arch/metag/tbx/tbisoft.S
+++ b/arch/metag/tbx/tbisoft.S
@@ -56,7 +56,7 @@ ___TBIJumpX:
/*
* TBIRES __TBISwitch( TBIRES Switch, PTBICTX *rpSaveCtx )
*
- * Software syncronous context switch between soft threads, save only the
+ * Software synchronous context switch between soft threads, save only the
* registers which are actually valid on call entry.
*
* A0FrP, D0RtP, D0.5, D0.6, D0.7 - Saved on stack
@@ -76,7 +76,7 @@ $LSwitchStart:
SETL [A0StP+#8++],D0FrT,D1RtP
/*
* Save current frame state - we save all regs because we don't want
- * uninitialised crap in the TBICTX structure that the asyncronous resumption
+ * uninitialised crap in the TBICTX structure that the asynchronous resumption
* of a thread will restore.
*/
MOVT D1Re0,#HI($LSwitchExit) /* ASync resume point here */
@@ -117,7 +117,7 @@ $LSwitchExit:
* This routine causes the TBICTX structure specified in State.Sig.pCtx to
* be restored. This implies that execution will not return to the caller.
* The State.Sig.TrigMask field will be ored into TXMASKI during the
- * context switch such that any immediately occuring interrupts occur in
+ * context switch such that any immediately occurring interrupts occur in
* the context of the newly specified task. The State.Sig.SaveMask parameter
* is ignored.
*/