aboutsummaryrefslogtreecommitdiff
path: root/include/asm-m32r
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-m32r')
-rw-r--r--include/asm-m32r/a.out.h7
-rw-r--r--include/asm-m32r/delay.h2
-rw-r--r--include/asm-m32r/elf.h2
-rw-r--r--include/asm-m32r/irq.h2
-rw-r--r--include/asm-m32r/local.h362
-rw-r--r--include/asm-m32r/m32700ut/m32700ut_pld.h4
-rw-r--r--include/asm-m32r/page.h3
-rw-r--r--include/asm-m32r/param.h2
-rw-r--r--include/asm-m32r/pgalloc.h18
-rw-r--r--include/asm-m32r/posix_types.h8
-rw-r--r--include/asm-m32r/processor.h5
-rw-r--r--include/asm-m32r/system.h115
-rw-r--r--include/asm-m32r/unistd.h2
-rw-r--r--include/asm-m32r/user.h2
14 files changed, 487 insertions, 47 deletions
diff --git a/include/asm-m32r/a.out.h b/include/asm-m32r/a.out.h
index 6a1b5d42f32..ab150f5c166 100644
--- a/include/asm-m32r/a.out.h
+++ b/include/asm-m32r/a.out.h
@@ -17,11 +17,4 @@ struct exec
#define N_DRSIZE(a) ((a).a_drsize)
#define N_SYMSIZE(a) ((a).a_syms)
-#ifdef __KERNEL__
-
-#define STACK_TOP TASK_SIZE
-#define STACK_TOP_MAX STACK_TOP
-
-#endif
-
#endif /* _ASM_M32R_A_OUT_H */
diff --git a/include/asm-m32r/delay.h b/include/asm-m32r/delay.h
index 164448d2385..9dd9e999ea6 100644
--- a/include/asm-m32r/delay.h
+++ b/include/asm-m32r/delay.h
@@ -12,7 +12,7 @@ extern void __bad_ndelay(void);
extern void __udelay(unsigned long usecs);
extern void __ndelay(unsigned long nsecs);
-extern void __const_udelay(unsigned long usecs);
+extern void __const_udelay(unsigned long xloops);
extern void __delay(unsigned long loops);
#define udelay(n) (__builtin_constant_p(n) ? \
diff --git a/include/asm-m32r/elf.h b/include/asm-m32r/elf.h
index bbee8b25d17..67bcd77494a 100644
--- a/include/asm-m32r/elf.h
+++ b/include/asm-m32r/elf.h
@@ -129,8 +129,6 @@ typedef elf_fpreg_t elf_fpregset_t;
intent than poking at uname or /proc/cpuinfo. */
#define ELF_PLATFORM (NULL)
-#ifdef __KERNEL__
#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
-#endif
#endif /* _ASM_M32R__ELF_H */
diff --git a/include/asm-m32r/irq.h b/include/asm-m32r/irq.h
index 2f93f4743ad..242028b4d86 100644
--- a/include/asm-m32r/irq.h
+++ b/include/asm-m32r/irq.h
@@ -3,7 +3,7 @@
#define _ASM_M32R_IRQ_H
-#if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_USRV)
+#if defined(CONFIG_PLAT_USRV)
/*
* IRQ definitions for M32700UT
* M32700 Chip: 64 interrupts
diff --git a/include/asm-m32r/local.h b/include/asm-m32r/local.h
index def29d09574..22256d13863 100644
--- a/include/asm-m32r/local.h
+++ b/include/asm-m32r/local.h
@@ -1,6 +1,366 @@
#ifndef __M32R_LOCAL_H
#define __M32R_LOCAL_H
-#include <asm-generic/local.h>
+/*
+ * linux/include/asm-m32r/local.h
+ *
+ * M32R version:
+ * Copyright (C) 2001, 2002 Hitoshi Yamamoto
+ * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org>
+ * Copyright (C) 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ */
+
+#include <linux/percpu.h>
+#include <asm/assembler.h>
+#include <asm/system.h>
+#include <asm/local.h>
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ */
+
+/*
+ * Make sure gcc doesn't try to be clever and move things around
+ * on us. We need to use _exactly_ the address the user gave us,
+ * not some alias that contains the same information.
+ */
+typedef struct { volatile int counter; } local_t;
+
+#define LOCAL_INIT(i) { (i) }
+
+/**
+ * local_read - read local variable
+ * @l: pointer of type local_t
+ *
+ * Atomically reads the value of @l.
+ */
+#define local_read(l) ((l)->counter)
+
+/**
+ * local_set - set local variable
+ * @l: pointer of type local_t
+ * @i: required value
+ *
+ * Atomically sets the value of @l to @i.
+ */
+#define local_set(l, i) (((l)->counter) = (i))
+
+/**
+ * local_add_return - add long to local variable and return it
+ * @i: long value to add
+ * @l: pointer of type local_t
+ *
+ * Atomically adds @i to @l and return (@i + @l).
+ */
+static inline long local_add_return(long i, local_t *l)
+{
+ unsigned long flags;
+ long result;
+
+ local_irq_save(flags);
+ __asm__ __volatile__ (
+ "# local_add_return \n\t"
+ DCACHE_CLEAR("%0", "r4", "%1")
+ "ld %0, @%1; \n\t"
+ "add %0, %2; \n\t"
+ "st %0, @%1; \n\t"
+ : "=&r" (result)
+ : "r" (&l->counter), "r" (i)
+ : "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+ , "r4"
+#endif /* CONFIG_CHIP_M32700_TS1 */
+ );
+ local_irq_restore(flags);
+
+ return result;
+}
+
+/**
+ * local_sub_return - subtract long from local variable and return it
+ * @i: long value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l and return (@l - @i).
+ */
+static inline long local_sub_return(long i, local_t *l)
+{
+ unsigned long flags;
+ long result;
+
+ local_irq_save(flags);
+ __asm__ __volatile__ (
+ "# local_sub_return \n\t"
+ DCACHE_CLEAR("%0", "r4", "%1")
+ "ld %0, @%1; \n\t"
+ "sub %0, %2; \n\t"
+ "st %0, @%1; \n\t"
+ : "=&r" (result)
+ : "r" (&l->counter), "r" (i)
+ : "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+ , "r4"
+#endif /* CONFIG_CHIP_M32700_TS1 */
+ );
+ local_irq_restore(flags);
+
+ return result;
+}
+
+/**
+ * local_add - add long to local variable
+ * @i: long value to add
+ * @l: pointer of type local_t
+ *
+ * Atomically adds @i to @l.
+ */
+#define local_add(i, l) ((void) local_add_return((i), (l)))
+
+/**
+ * local_sub - subtract the local variable
+ * @i: long value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l.
+ */
+#define local_sub(i, l) ((void) local_sub_return((i), (l)))
+
+/**
+ * local_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @l: pointer of type local_t
+ *
+ * Atomically subtracts @i from @l and returns
+ * true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_sub_and_test(i, l) (local_sub_return((i), (l)) == 0)
+
+/**
+ * local_inc_return - increment local variable and return it
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1 and returns the result.
+ */
+static inline long local_inc_return(local_t *l)
+{
+ unsigned long flags;
+ long result;
+
+ local_irq_save(flags);
+ __asm__ __volatile__ (
+ "# local_inc_return \n\t"
+ DCACHE_CLEAR("%0", "r4", "%1")
+ "ld %0, @%1; \n\t"
+ "addi %0, #1; \n\t"
+ "st %0, @%1; \n\t"
+ : "=&r" (result)
+ : "r" (&l->counter)
+ : "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+ , "r4"
+#endif /* CONFIG_CHIP_M32700_TS1 */
+ );
+ local_irq_restore(flags);
+
+ return result;
+}
+
+/**
+ * local_dec_return - decrement local variable and return it
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1 and returns the result.
+ */
+static inline long local_dec_return(local_t *l)
+{
+ unsigned long flags;
+ long result;
+
+ local_irq_save(flags);
+ __asm__ __volatile__ (
+ "# local_dec_return \n\t"
+ DCACHE_CLEAR("%0", "r4", "%1")
+ "ld %0, @%1; \n\t"
+ "addi %0, #-1; \n\t"
+ "st %0, @%1; \n\t"
+ : "=&r" (result)
+ : "r" (&l->counter)
+ : "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+ , "r4"
+#endif /* CONFIG_CHIP_M32700_TS1 */
+ );
+ local_irq_restore(flags);
+
+ return result;
+}
+
+/**
+ * local_inc - increment local variable
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1.
+ */
+#define local_inc(l) ((void)local_inc_return(l))
+
+/**
+ * local_dec - decrement local variable
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1.
+ */
+#define local_dec(l) ((void)local_dec_return(l))
+
+/**
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+/**
+ * local_dec_and_test - decrement and test
+ * @l: pointer of type local_t
+ *
+ * Atomically decrements @l by 1 and
+ * returns true if the result is 0, or false for all
+ * other cases.
+ */
+#define local_dec_and_test(l) (local_dec_return(l) == 0)
+
+/**
+ * local_add_negative - add and test if negative
+ * @l: pointer of type local_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @l and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero.
+ */
+#define local_add_negative(i, l) (local_add_return((i), (l)) < 0)
+
+#define local_cmpxchg(l, o, n) (cmpxchg_local(&((l)->counter), (o), (n)))
+#define local_xchg(v, new) (xchg_local(&((l)->counter), new))
+
+/**
+ * local_add_unless - add unless the number is a given value
+ * @l: pointer of type local_t
+ * @a: the amount to add to l...
+ * @u: ...unless l is equal to u.
+ *
+ * Atomically adds @a to @l, so long as it was not @u.
+ * Returns non-zero if @l was not @u, and zero otherwise.
+ */
+static inline int local_add_unless(local_t *l, long a, long u)
+{
+ long c, old;
+ c = local_read(l);
+ for (;;) {
+ if (unlikely(c == (u)))
+ break;
+ old = local_cmpxchg((l), c, c + (a));
+ if (likely(old == c))
+ break;
+ c = old;
+ }
+ return c != (u);
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+static inline void local_clear_mask(unsigned long mask, local_t *addr)
+{
+ unsigned long flags;
+ unsigned long tmp;
+
+ local_irq_save(flags);
+ __asm__ __volatile__ (
+ "# local_clear_mask \n\t"
+ DCACHE_CLEAR("%0", "r5", "%1")
+ "ld %0, @%1; \n\t"
+ "and %0, %2; \n\t"
+ "st %0, @%1; \n\t"
+ : "=&r" (tmp)
+ : "r" (addr), "r" (~mask)
+ : "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+ , "r5"
+#endif /* CONFIG_CHIP_M32700_TS1 */
+ );
+ local_irq_restore(flags);
+}
+
+static inline void local_set_mask(unsigned long mask, local_t *addr)
+{
+ unsigned long flags;
+ unsigned long tmp;
+
+ local_irq_save(flags);
+ __asm__ __volatile__ (
+ "# local_set_mask \n\t"
+ DCACHE_CLEAR("%0", "r5", "%1")
+ "ld %0, @%1; \n\t"
+ "or %0, %2; \n\t"
+ "st %0, @%1; \n\t"
+ : "=&r" (tmp)
+ : "r" (addr), "r" (mask)
+ : "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+ , "r5"
+#endif /* CONFIG_CHIP_M32700_TS1 */
+ );
+ local_irq_restore(flags);
+}
+
+/* Atomic operations are already serializing on m32r */
+#define smp_mb__before_local_dec() barrier()
+#define smp_mb__after_local_dec() barrier()
+#define smp_mb__before_local_inc() barrier()
+#define smp_mb__after_local_inc() barrier()
+
+/* Use these for per-cpu local_t variables: on some archs they are
+ * much more efficient than these naive implementations. Note they take
+ * a variable, not an address.
+ */
+
+#define __local_inc(l) ((l)->a.counter++)
+#define __local_dec(l) ((l)->a.counter++)
+#define __local_add(i, l) ((l)->a.counter += (i))
+#define __local_sub(i, l) ((l)->a.counter -= (i))
+
+/* Use these for per-cpu local_t variables: on some archs they are
+ * much more efficient than these naive implementations. Note they take
+ * a variable, not an address.
+ */
+
+/* Need to disable preemption for the cpu local counters otherwise we could
+ still access a variable of a previous CPU in a non local way. */
+#define cpu_local_wrap_v(l) \
+ ({ local_t res__; \
+ preempt_disable(); \
+ res__ = (l); \
+ preempt_enable(); \
+ res__; })
+#define cpu_local_wrap(l) \
+ ({ preempt_disable(); \
+ l; \
+ preempt_enable(); }) \
+
+#define cpu_local_read(l) cpu_local_wrap_v(local_read(&__get_cpu_var(l)))
+#define cpu_local_set(l, i) cpu_local_wrap(local_set(&__get_cpu_var(l), (i)))
+#define cpu_local_inc(l) cpu_local_wrap(local_inc(&__get_cpu_var(l)))
+#define cpu_local_dec(l) cpu_local_wrap(local_dec(&__get_cpu_var(l)))
+#define cpu_local_add(i, l) cpu_local_wrap(local_add((i), &__get_cpu_var(l)))
+#define cpu_local_sub(i, l) cpu_local_wrap(local_sub((i), &__get_cpu_var(l)))
+
+#define __cpu_local_inc(l) cpu_local_inc(l)
+#define __cpu_local_dec(l) cpu_local_dec(l)
+#define __cpu_local_add(i, l) cpu_local_add((i), (l))
+#define __cpu_local_sub(i, l) cpu_local_sub((i), (l))
#endif /* __M32R_LOCAL_H */
diff --git a/include/asm-m32r/m32700ut/m32700ut_pld.h b/include/asm-m32r/m32700ut/m32700ut_pld.h
index d39121279a1..57623beb44c 100644
--- a/include/asm-m32r/m32700ut/m32700ut_pld.h
+++ b/include/asm-m32r/m32700ut/m32700ut_pld.h
@@ -13,9 +13,7 @@
* this archive for more details.
*/
-#if defined(CONFIG_PLAT_M32700UT_Alpha)
-#define PLD_PLAT_BASE 0x08c00000
-#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV)
+#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV)
#define PLD_PLAT_BASE 0x04c00000
#else
#error "no platform configuration"
diff --git a/include/asm-m32r/page.h b/include/asm-m32r/page.h
index 04fd183a2c5..8a677f3fca6 100644
--- a/include/asm-m32r/page.h
+++ b/include/asm-m32r/page.h
@@ -6,7 +6,6 @@
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-#ifdef __KERNEL__
#ifndef __ASSEMBLY__
extern void clear_page(void *to);
@@ -29,6 +28,7 @@ typedef struct { unsigned long pgd; } pgd_t;
#define PTE_MASK PAGE_MASK
typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct page *pgtable_t;
#define pmd_val(x) ((x).pmd)
#define pgd_val(x) ((x).pgd)
@@ -87,5 +87,4 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#include <asm-generic/memory_model.h>
#include <asm-generic/page.h>
-#endif /* __KERNEL__ */
#endif /* _ASM_M32R_PAGE_H */
diff --git a/include/asm-m32r/param.h b/include/asm-m32r/param.h
index 3e14026e39c..94c77019604 100644
--- a/include/asm-m32r/param.h
+++ b/include/asm-m32r/param.h
@@ -2,7 +2,7 @@
#define _ASM_M32R_PARAM_H
#ifdef __KERNEL__
-# define HZ 100 /* Internal kernel timer frequency */
+# define HZ CONFIG_HZ /* Internal kernel timer frequency */
# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
#endif
diff --git a/include/asm-m32r/pgalloc.h b/include/asm-m32r/pgalloc.h
index 943ba63c1eb..f11a2b909cd 100644
--- a/include/asm-m32r/pgalloc.h
+++ b/include/asm-m32r/pgalloc.h
@@ -9,10 +9,11 @@
set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
- struct page *pte)
+ pgtable_t pte)
{
set_pmd(pmd, __pmd(_PAGE_TABLE + page_to_phys(pte)));
}
+#define pmd_pgtable(pmd) pmd_page(pmd)
/*
* Allocate and free page tables.
@@ -24,7 +25,7 @@ static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
return pgd;
}
-static __inline__ void pgd_free(pgd_t *pgd)
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
free_page((unsigned long)pgd);
}
@@ -37,26 +38,27 @@ static __inline__ pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
return pte;
}
-static __inline__ struct page *pte_alloc_one(struct mm_struct *mm,
+static __inline__ pgtable_t pte_alloc_one(struct mm_struct *mm,
unsigned long address)
{
struct page *pte = alloc_page(GFP_KERNEL|__GFP_ZERO);
-
+ pgtable_page_ctor(pte);
return pte;
}
-static __inline__ void pte_free_kernel(pte_t *pte)
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
free_page((unsigned long)pte);
}
-static __inline__ void pte_free(struct page *pte)
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
{
+ pgtable_page_dtor(pte);
__free_page(pte);
}
-#define __pte_free_tlb(tlb, pte) pte_free((pte))
+#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte))
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
@@ -65,7 +67,7 @@ static __inline__ void pte_free(struct page *pte)
*/
#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
-#define pmd_free(x) do { } while (0)
+#define pmd_free(mm, x) do { } while (0)
#define __pmd_free_tlb(tlb, x) do { } while (0)
#define pgd_populate(mm, pmd, pte) BUG()
diff --git a/include/asm-m32r/posix_types.h b/include/asm-m32r/posix_types.h
index 1caac65d208..b309c585863 100644
--- a/include/asm-m32r/posix_types.h
+++ b/include/asm-m32r/posix_types.h
@@ -39,14 +39,10 @@ typedef long long __kernel_loff_t;
#endif
typedef struct {
-#if defined(__KERNEL__) || defined(__USE_ALL)
int val[2];
-#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
- int __val[2];
-#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
} __kernel_fsid_t;
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+#if defined(__KERNEL__)
#undef __FD_SET
static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
@@ -117,6 +113,6 @@ static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
}
}
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+#endif /* defined(__KERNEL__) */
#endif /* _ASM_M32R_POSIX_TYPES_H */
diff --git a/include/asm-m32r/processor.h b/include/asm-m32r/processor.h
index 32755bf136d..1a997fc148a 100644
--- a/include/asm-m32r/processor.h
+++ b/include/asm-m32r/processor.h
@@ -60,6 +60,11 @@ extern struct cpuinfo_m32r cpu_data[];
#define TASK_SIZE (0x00400000UL)
#endif
+#ifdef __KERNEL__
+#define STACK_TOP TASK_SIZE
+#define STACK_TOP_MAX STACK_TOP
+#endif
+
/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h
index 2365de5c295..70a57c8c002 100644
--- a/include/asm-m32r/system.h
+++ b/include/asm-m32r/system.h
@@ -121,12 +121,13 @@ static inline void local_irq_disable(void)
#define nop() __asm__ __volatile__ ("nop" : : )
-#define xchg(ptr,x) \
- ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define xchg(ptr, x) \
+ ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+#define xchg_local(ptr, x) \
+ ((__typeof__(*(ptr)))__xchg_local((unsigned long)(x), (ptr), \
+ sizeof(*(ptr))))
-#ifdef CONFIG_SMP
extern void __xchg_called_with_bad_pointer(void);
-#endif
#ifdef CONFIG_CHIP_M32700_TS1
#define DCACHE_CLEAR(reg0, reg1, addr) \
@@ -146,7 +147,7 @@ extern void __xchg_called_with_bad_pointer(void);
#endif /* CONFIG_CHIP_M32700_TS1 */
static __always_inline unsigned long
-__xchg(unsigned long x, volatile void * ptr, int size)
+__xchg(unsigned long x, volatile void *ptr, int size)
{
unsigned long flags;
unsigned long tmp = 0;
@@ -186,9 +187,45 @@ __xchg(unsigned long x, volatile void * ptr, int size)
#endif /* CONFIG_CHIP_M32700_TS1 */
);
break;
+#endif /* CONFIG_SMP */
+ default:
+ __xchg_called_with_bad_pointer();
+ }
+
+ local_irq_restore(flags);
+
+ return (tmp);
+}
+
+static __always_inline unsigned long
+__xchg_local(unsigned long x, volatile void *ptr, int size)
+{
+ unsigned long flags;
+ unsigned long tmp = 0;
+
+ local_irq_save(flags);
+
+ switch (size) {
+ case 1:
+ __asm__ __volatile__ (
+ "ldb %0, @%2 \n\t"
+ "stb %1, @%2 \n\t"
+ : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
+ break;
+ case 2:
+ __asm__ __volatile__ (
+ "ldh %0, @%2 \n\t"
+ "sth %1, @%2 \n\t"
+ : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
+ break;
+ case 4:
+ __asm__ __volatile__ (
+ "ld %0, @%2 \n\t"
+ "st %1, @%2 \n\t"
+ : "=&r" (tmp) : "r" (x), "r" (ptr) : "memory");
+ break;
default:
__xchg_called_with_bad_pointer();
-#endif /* CONFIG_SMP */
}
local_irq_restore(flags);
@@ -228,6 +265,37 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new)
return retval;
}
+static inline unsigned long
+__cmpxchg_local_u32(volatile unsigned int *p, unsigned int old,
+ unsigned int new)
+{
+ unsigned long flags;
+ unsigned int retval;
+
+ local_irq_save(flags);
+ __asm__ __volatile__ (
+ DCACHE_CLEAR("%0", "r4", "%1")
+ "ld %0, @%1; \n"
+ " bne %0, %2, 1f; \n"
+ "st %3, @%1; \n"
+ " bra 2f; \n"
+ " .fillinsn \n"
+ "1:"
+ "st %0, @%1; \n"
+ " .fillinsn \n"
+ "2:"
+ : "=&r" (retval)
+ : "r" (p), "r" (old), "r" (new)
+ : "cbit", "memory"
+#ifdef CONFIG_CHIP_M32700_TS1
+ , "r4"
+#endif /* CONFIG_CHIP_M32700_TS1 */
+ );
+ local_irq_restore(flags);
+
+ return retval;
+}
+
/* This function doesn't exist, so you'll get a linker error
if something tries to do an invalid cmpxchg(). */
extern void __cmpxchg_called_with_bad_pointer(void);
@@ -247,13 +315,34 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
return old;
}
-#define cmpxchg(ptr,o,n) \
- ({ \
- __typeof__(*(ptr)) _o_ = (o); \
- __typeof__(*(ptr)) _n_ = (n); \
- (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \
- (unsigned long)_n_, sizeof(*(ptr))); \
- })
+#define cmpxchg(ptr, o, n) \
+ ((__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))))
+
+#include <asm-generic/cmpxchg-local.h>
+
+static inline unsigned long __cmpxchg_local(volatile void *ptr,
+ unsigned long old,
+ unsigned long new, int size)
+{
+ switch (size) {
+ case 4:
+ return __cmpxchg_local_u32(ptr, old, new);
+ default:
+ return __cmpxchg_local_generic(ptr, old, new, size);
+ }
+
+ return old;
+}
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n) \
+ ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \
+ (unsigned long)(n), sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
#endif /* __KERNEL__ */
diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h
index f467eac9ba7..cf701c93324 100644
--- a/include/asm-m32r/unistd.h
+++ b/include/asm-m32r/unistd.h
@@ -327,7 +327,7 @@
#define __NR_epoll_pwait 319
#define __NR_utimensat 320
#define __NR_signalfd 321
-#define __NR_timerfd 322
+/* #define __NR_timerfd 322 removed */
#define __NR_eventfd 323
#define __NR_fallocate 324
diff --git a/include/asm-m32r/user.h b/include/asm-m32r/user.h
index 035258d713d..03b3c11c2af 100644
--- a/include/asm-m32r/user.h
+++ b/include/asm-m32r/user.h
@@ -38,7 +38,7 @@ struct user {
unsigned long start_data; /* data starting address */
unsigned long start_stack; /* stack starting address */
long int signal; /* signal causing core dump */
- struct regs * u_ar0; /* help gdb find registers */
+ unsigned long u_ar0; /* help gdb find registers */
unsigned long magic; /* identifies a core file */
char u_comm[32]; /* user command name */
};