linux/arch/blackfin/include/asm/system.h
<<
>>
Prefs
   1/*
   2 * Copyright 2004-2009 Analog Devices Inc.
   3 *               Tony Kou (tonyko@lineo.ca)
   4 *
   5 * Licensed under the GPL-2 or later
   6 */
   7
   8#ifndef _BLACKFIN_SYSTEM_H
   9#define _BLACKFIN_SYSTEM_H
  10
  11#include <linux/linkage.h>
  12#include <linux/irqflags.h>
  13#include <mach/anomaly.h>
  14#include <asm/cache.h>
  15#include <asm/pda.h>
  16#include <asm/irq.h>
  17
  18/*
  19 * Force strict CPU ordering.
  20 */
  21#define nop()  __asm__ __volatile__ ("nop;\n\t" : : )
  22#define mb()   __asm__ __volatile__ (""   : : : "memory")
  23#define rmb()  __asm__ __volatile__ (""   : : : "memory")
  24#define wmb()  __asm__ __volatile__ (""   : : : "memory")
  25#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
  26#define read_barrier_depends()          do { } while(0)
  27
  28#ifdef CONFIG_SMP
  29asmlinkage unsigned long __raw_xchg_1_asm(volatile void *ptr, unsigned long value);
  30asmlinkage unsigned long __raw_xchg_2_asm(volatile void *ptr, unsigned long value);
  31asmlinkage unsigned long __raw_xchg_4_asm(volatile void *ptr, unsigned long value);
  32asmlinkage unsigned long __raw_cmpxchg_1_asm(volatile void *ptr,
  33                                        unsigned long new, unsigned long old);
  34asmlinkage unsigned long __raw_cmpxchg_2_asm(volatile void *ptr,
  35                                        unsigned long new, unsigned long old);
  36asmlinkage unsigned long __raw_cmpxchg_4_asm(volatile void *ptr,
  37                                        unsigned long new, unsigned long old);
  38
  39#ifdef __ARCH_SYNC_CORE_DCACHE
  40# define smp_mb()       do { barrier(); smp_check_barrier(); smp_mark_barrier(); } while (0)
  41# define smp_rmb()      do { barrier(); smp_check_barrier(); } while (0)
  42# define smp_wmb()      do { barrier(); smp_mark_barrier(); } while (0)
  43#define smp_read_barrier_depends()      do { barrier(); smp_check_barrier(); } while (0)
  44
  45#else
  46# define smp_mb()       barrier()
  47# define smp_rmb()      barrier()
  48# define smp_wmb()      barrier()
  49#define smp_read_barrier_depends()      barrier()
  50#endif
  51
  52static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
  53                                   int size)
  54{
  55        unsigned long tmp;
  56
  57        switch (size) {
  58        case 1:
  59                tmp = __raw_xchg_1_asm(ptr, x);
  60                break;
  61        case 2:
  62                tmp = __raw_xchg_2_asm(ptr, x);
  63                break;
  64        case 4:
  65                tmp = __raw_xchg_4_asm(ptr, x);
  66                break;
  67        }
  68
  69        return tmp;
  70}
  71
  72/*
  73 * Atomic compare and exchange.  Compare OLD with MEM, if identical,
  74 * store NEW in MEM.  Return the initial value in MEM.  Success is
  75 * indicated by comparing RETURN with OLD.
  76 */
  77static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
  78                                      unsigned long new, int size)
  79{
  80        unsigned long tmp;
  81
  82        switch (size) {
  83        case 1:
  84                tmp = __raw_cmpxchg_1_asm(ptr, new, old);
  85                break;
  86        case 2:
  87                tmp = __raw_cmpxchg_2_asm(ptr, new, old);
  88                break;
  89        case 4:
  90                tmp = __raw_cmpxchg_4_asm(ptr, new, old);
  91                break;
  92        }
  93
  94        return tmp;
  95}
  96#define cmpxchg(ptr, o, n) \
  97        ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \
  98                (unsigned long)(n), sizeof(*(ptr))))
  99
 100#else /* !CONFIG_SMP */
 101
 102#define smp_mb()        barrier()
 103#define smp_rmb()       barrier()
 104#define smp_wmb()       barrier()
 105#define smp_read_barrier_depends()      do { } while(0)
 106
 107struct __xchg_dummy {
 108        unsigned long a[100];
 109};
 110#define __xg(x) ((volatile struct __xchg_dummy *)(x))
 111
 112#include <mach/blackfin.h>
 113
 114static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
 115                                   int size)
 116{
 117        unsigned long tmp = 0;
 118        unsigned long flags;
 119
 120        local_irq_save_hw(flags);
 121
 122        switch (size) {
 123        case 1:
 124                __asm__ __volatile__
 125                        ("%0 = b%2 (z);\n\t"
 126                         "b%2 = %1;\n\t"
 127                         : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
 128                break;
 129        case 2:
 130                __asm__ __volatile__
 131                        ("%0 = w%2 (z);\n\t"
 132                         "w%2 = %1;\n\t"
 133                         : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
 134                break;
 135        case 4:
 136                __asm__ __volatile__
 137                        ("%0 = %2;\n\t"
 138                         "%2 = %1;\n\t"
 139                         : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
 140                break;
 141        }
 142        local_irq_restore_hw(flags);
 143        return tmp;
 144}
 145
 146#include <asm-generic/cmpxchg-local.h>
 147
 148/*
 149 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
 150 * them available.
 151 */
 152#define cmpxchg_local(ptr, o, n)                                               \
 153        ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
 154                        (unsigned long)(n), sizeof(*(ptr))))
 155#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
 156
 157#include <asm-generic/cmpxchg.h>
 158
 159#endif /* !CONFIG_SMP */
 160
 161#define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
 162#define tas(ptr) ((void)xchg((ptr), 1))
 163
 164#define prepare_to_switch()     do { } while(0)
 165
 166/*
 167 * switch_to(n) should switch tasks to task ptr, first checking that
 168 * ptr isn't the current task, in which case it does nothing.
 169 */
 170
 171#include <asm/l1layout.h>
 172#include <asm/mem_map.h>
 173
 174asmlinkage struct task_struct *resume(struct task_struct *prev, struct task_struct *next);
 175
 176#ifndef CONFIG_SMP
 177#define switch_to(prev,next,last) \
 178do {    \
 179        memcpy (&task_thread_info(prev)->l1_task_info, L1_SCRATCH_TASK_INFO, \
 180                sizeof *L1_SCRATCH_TASK_INFO); \
 181        memcpy (L1_SCRATCH_TASK_INFO, &task_thread_info(next)->l1_task_info, \
 182                sizeof *L1_SCRATCH_TASK_INFO); \
 183        (last) = resume (prev, next);   \
 184} while (0)
 185#else
 186#define switch_to(prev, next, last) \
 187do {    \
 188        (last) = resume(prev, next);   \
 189} while (0)
 190#endif
 191
 192#endif  /* _BLACKFIN_SYSTEM_H */
 193