Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 7 Aug 2014 15:47:00 +0000 (08:47 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 7 Aug 2014 15:47:00 +0000 (08:47 -0700)
Pull MIPS updates from Ralf Baechle:
 "This is the main pull request for 3.17.  It contains:

   - misc Cavium Octeon, BCM47xx, BCM63xx and Alchemy  updates
   - MIPS ptrace updates and cleanups
   - various fixes that will also go to -stable
   - a number of cleanups and small non-critical fixes.
   - NUMA support for the Loongson 3.
   - more support for MSA
   - support for MAAR
   - various FP enhancements and fixes"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (139 commits)
  MIPS: jz4740: remove unnecessary null test before debugfs_remove
  MIPS: Octeon: remove unnecessary null test before debugfs_remove_recursive
  MIPS: ZBOOT: implement stack protector in compressed boot phase
  MIPS: mipsreg: remove duplicate MIPS_CONF4_FTLBSETS_SHIFT
  MIPS: Bonito64: remove a duplicate define
  MIPS: Malta: initialise MAARs
  MIPS: Initialise MAARs
  MIPS: detect presence of MAARs
  MIPS: define MAAR register accessors & bits
  MIPS: mark MSA experimental
  MIPS: Don't build MSA support unless it can be used
  MIPS: consistently clear MSA flags when starting & copying threads
  MIPS: 16 byte align MSA vector context
  MIPS: disable preemption whilst initialising MSA
  MIPS: ensure MSA gets disabled during boot
  MIPS: fix read_msa_* & write_msa_* functions on non-MSA toolchains
  MIPS: fix MSA context for tasks which don't use FP first
  MIPS: init upper 64b of vector registers when MSA is first used
  MIPS: save/disable MSA in lose_fpu
  MIPS: preserve scalar FP CSR when switching vector context
  ...

1  2 
Documentation/kernel-parameters.txt
arch/mips/Kconfig
arch/mips/configs/loongson3_defconfig
arch/mips/include/asm/processor.h
arch/mips/kernel/ftrace.c
arch/mips/kernel/mcount.S
arch/mips/kernel/scall32-o32.S
arch/mips/kernel/scall64-64.S
arch/mips/kernel/scall64-n32.S
arch/mips/kernel/scall64-o32.S
drivers/spi/spi-au1550.c

@@@ -566,11 -566,12 +566,17 @@@ bytes respectively. Such letter suffixe
                        possible to determine what the correct size should be.
                        This option provides an override for these situations.
  
 +      ca_keys=        [KEYS] This parameter identifies a specific key(s) on
 +                      the system trusted keyring to be used for certificate
 +                      trust validation.
 +                      format: { id:<keyid> | builtin }
 +
+       cca=            [MIPS] Override the kernel pages' cache coherency
+                       algorithm.  Accepted values range from 0 to 7
+                       inclusive. See arch/mips/include/asm/pgtable-bits.h
+                       for platform specific values (SB1, Loongson3 and
+                       others).
        ccw_timeout_log [S390]
                        See Documentation/s390/CommonIO for details.
  
                        that can be changed at run time by the
                        set_graph_function file in the debugfs tracing directory.
  
 +      ftrace_graph_notrace=[function-list]
 +                      [FTRACE] Do not trace from the functions specified in
 +                      function-list.  This list is a comma separated list of
 +                      functions that can be changed at run time by the
 +                      set_graph_notrace file in the debugfs tracing directory.
 +
        gamecon.map[2|3]=
                        [HW,JOY] Multisystem joystick and NES/SNES/PSX pad
                        support via parallel port (up to 5 devices per port)
                        Formats: { "ima" | "ima-ng" }
                        Default: "ima-ng"
  
 +      ima.ahash_minsize= [IMA] Minimum file size for asynchronous hash usage
 +                      Format: <min_file_size>
 +                      Set the minimal file size for using asynchronous hash.
 +                      If left unspecified, ahash usage is disabled.
 +
 +                      ahash performance varies for different data sizes on
 +                      different crypto accelerators. This option can be used
 +                      to achieve the best performance for a particular HW.
 +
 +      ima.ahash_bufsize= [IMA] Asynchronous hash buffer size
 +                      Format: <bufsize>
 +                      Set hashing buffer size. Default: 4k.
 +
 +                      ahash performance varies for different chunk sizes on
 +                      different crypto accelerators. This option can be used
 +                      to achieve best performance for particular HW.
 +
        init=           [KNL]
                        Format: <full_path>
                        Run specified binary instead of /sbin/init as init
        ip=             [IP_PNP]
                        See Documentation/filesystems/nfs/nfsroot.txt.
  
 -      ip2=            [HW] Set IO/IRQ pairs for up to 4 IntelliPort boards
 -                      See comment before ip2_setup() in
 -                      drivers/char/ip2/ip2base.c.
 -
        irqfixup        [HW]
                        When an interrupt is not handled search all handlers
                        for it. Intended to get systems with badly broken
                        7 (KERN_DEBUG)          debug-level messages
  
        log_buf_len=n[KMG]      Sets the size of the printk ring buffer,
 -                      in bytes.  n must be a power of two.  The default
 -                      size is set in the kernel config file.
 +                      in bytes.  n must be a power of two and greater
 +                      than the minimal size. The minimal size is defined
 +                      by LOG_BUF_SHIFT kernel config parameter. There is
 +                      also CONFIG_LOG_CPU_MAX_BUF_SHIFT config parameter
 +                      that allows to increase the default size depending on
 +                      the number of CPUs. See init/Kconfig for more details.
  
        logo.nologo     [FB] Disables display of the built-in Linux logo.
                        This may be used to provide more screen space for
                        leaf rcu_node structure.  Useful for very large
                        systems.
  
 +      rcutree.jiffies_till_sched_qs= [KNL]
 +                      Set required age in jiffies for a
 +                      given grace period before RCU starts
 +                      soliciting quiescent-state help from
 +                      rcu_note_context_switch().
 +
        rcutree.jiffies_till_first_fqs= [KNL]
                        Set delay from grace-period initialization to
                        first attempt to force quiescent states.
                        quiescent states.  Units are jiffies, minimum
                        value is one, and maximum value is HZ.
  
 +      rcutree.rcu_nocb_leader_stride= [KNL]
 +                      Set the number of NOCB kthread groups, which
 +                      defaults to the square root of the number of
 +                      CPUs.  Larger numbers reduces the wakeup overhead
 +                      on the per-CPU grace-period kthreads, but increases
 +                      that same overhead on each group's leader.
 +
        rcutree.qhimark= [KNL]
                        Set threshold of queued RCU callbacks beyond which
                        batch limiting is disabled.
  
        S               [KNL] Run init in single mode
  
 +      s390_iommu=     [HW,S390]
 +                      Set s390 IOTLB flushing mode
 +              strict
 +                      With strict flushing every unmap operation will result in
 +                      an IOTLB flush. Default is lazy flushing before reuse,
 +                      which is faster.
 +
        sa1100ir        [NET]
                        See drivers/net/irda/sa1100_ir.c.
  
                        the allocated input device; If set to 0, video driver
                        will only send out the event without touching backlight
                        brightness level.
 -                      default: 0
 +                      default: 1
  
        virtio_mmio.device=
                        [VMMIO] Memory mapped virtio (platform) device.
diff --combined arch/mips/Kconfig
@@@ -15,6 -15,7 +15,6 @@@ config MIP
        select HAVE_BPF_JIT if !CPU_MICROMIPS
        select ARCH_HAVE_CUSTOM_GPIO_H
        select HAVE_FUNCTION_TRACER
 -      select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_C_RECORDMCOUNT
@@@ -71,6 -72,7 +71,7 @@@ config MIPS_ALCHEM
        select SYS_SUPPORTS_APM_EMULATION
        select ARCH_REQUIRE_GPIOLIB
        select SYS_SUPPORTS_ZBOOT
+       select COMMON_CLK
  
  config AR7
        bool "Texas Instruments AR7"
@@@ -129,6 -131,8 +130,8 @@@ config BCM47X
        select SYS_SUPPORTS_MIPS16
        select SYS_HAS_EARLY_PRINTK
        select USE_GENERIC_EARLY_PRINTK_8250
+       select GPIOLIB
+       select LEDS_GPIO_REGISTER
        help
         Support for BCM47XX based boards
  
@@@ -137,6 -141,7 +140,7 @@@ config BCM63X
        select BOOT_RAW
        select CEVT_R4K
        select CSRC_R4K
+       select SYNC_R4K
        select DMA_NONCOHERENT
        select IRQ_CPU
        select SYS_SUPPORTS_32BIT_KERNEL
@@@ -2056,6 -2061,7 +2060,7 @@@ config MIPS_CP
          support is unavailable.
  
  config MIPS_CPS_PM
+       select MIPS_CPC
        bool
  
  config MIPS_GIC_IPI
@@@ -2109,9 -2115,9 +2114,9 @@@ config CPU_MICROMIP
          microMIPS ISA
  
  config CPU_HAS_MSA
-       bool "Support for the MIPS SIMD Architecture"
+       bool "Support for the MIPS SIMD Architecture (EXPERIMENTAL)"
        depends on CPU_SUPPORTS_MSA
-       default y
+       depends on 64BIT || MIPS_O32_FP64_SUPPORT
        help
          MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers
          and a set of SIMD instructions to operate on them. When this option
@@@ -1,6 -1,6 +1,6 @@@
  CONFIG_MACH_LOONGSON=y
  CONFIG_SWIOTLB=y
- CONFIG_LEMOTE_MACH3A=y
+ CONFIG_LOONGSON_MACH3X=y
  CONFIG_CPU_LOONGSON3=y
  CONFIG_64BIT=y
  CONFIG_PAGE_SIZE_16KB=y
@@@ -120,6 -120,7 +120,6 @@@ CONFIG_BLK_DEV_CRYPTOLOOP=
  CONFIG_BLK_DEV_RAM=y
  CONFIG_BLK_DEV_RAM_SIZE=8192
  CONFIG_RAID_ATTRS=m
 -CONFIG_SCSI_TGT=y
  CONFIG_BLK_DEV_SD=y
  CONFIG_BLK_DEV_SR=y
  CONFIG_CHR_DEV_SG=y
@@@ -238,7 -238,13 +238,13 @@@ typedef struct 
        unsigned long seg;
  } mm_segment_t;
  
- #define ARCH_MIN_TASKALIGN    8
+ #ifdef CONFIG_CPU_HAS_MSA
+ # define ARCH_MIN_TASKALIGN   16
+ # define FPU_ALIGN            __aligned(16)
+ #else
+ # define ARCH_MIN_TASKALIGN   8
+ # define FPU_ALIGN
+ #endif
  
  struct mips_abi;
  
@@@ -255,7 -261,7 +261,7 @@@ struct thread_struct 
        unsigned long cp0_status;
  
        /* Saved fpu/fpu emulator stuff. */
-       struct mips_fpu_struct fpu;
+       struct mips_fpu_struct fpu FPU_ALIGN;
  #ifdef CONFIG_MIPS_MT_FPAFF
        /* Emulated instruction count */
        unsigned long emulated_fp;
@@@ -367,7 -373,6 +373,7 @@@ unsigned long get_wchan(struct task_str
  #define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status)
  
  #define cpu_relax()   barrier()
 +#define cpu_relax_lowlatency() cpu_relax()
  
  /*
   * Return_address is a replacement for __builtin_return_address(count)
@@@ -63,7 -63,7 +63,7 @@@ static inline int in_kernel_space(unsig
        ((unsigned int)(JAL | (((addr) >> 2) & ADDR_MASK)))
  
  static unsigned int insn_jal_ftrace_caller __read_mostly;
- static unsigned int insn_lui_v1_hi16_mcount __read_mostly;
+ static unsigned int insn_la_mcount[2] __read_mostly;
  static unsigned int insn_j_ftrace_graph_caller __maybe_unused __read_mostly;
  
  static inline void ftrace_dyn_arch_init_insns(void)
        u32 *buf;
        unsigned int v1;
  
-       /* lui v1, hi16_mcount */
+       /* la v1, _mcount */
        v1 = 3;
-       buf = (u32 *)&insn_lui_v1_hi16_mcount;
-       UASM_i_LA_mostly(&buf, v1, MCOUNT_ADDR);
+       buf = (u32 *)&insn_la_mcount[0];
+       UASM_i_LA(&buf, v1, MCOUNT_ADDR);
  
        /* jal (ftrace_caller + 8), jump over the first two instruction */
        buf = (u32 *)&insn_jal_ftrace_caller;
@@@ -111,14 -111,47 +111,47 @@@ static int ftrace_modify_code_2(unsigne
                                unsigned int new_code2)
  {
        int faulted;
+       mm_segment_t old_fs;
  
        safe_store_code(new_code1, ip, faulted);
        if (unlikely(faulted))
                return -EFAULT;
-       safe_store_code(new_code2, ip + 4, faulted);
+       ip += 4;
+       safe_store_code(new_code2, ip, faulted);
        if (unlikely(faulted))
                return -EFAULT;
+       ip -= 4;
+       old_fs = get_fs();
+       set_fs(get_ds());
        flush_icache_range(ip, ip + 8);
+       set_fs(old_fs);
+       return 0;
+ }
+ static int ftrace_modify_code_2r(unsigned long ip, unsigned int new_code1,
+                                unsigned int new_code2)
+ {
+       int faulted;
+       mm_segment_t old_fs;
+       ip += 4;
+       safe_store_code(new_code2, ip, faulted);
+       if (unlikely(faulted))
+               return -EFAULT;
+       ip -= 4;
+       safe_store_code(new_code1, ip, faulted);
+       if (unlikely(faulted))
+               return -EFAULT;
+       old_fs = get_fs();
+       set_fs(get_ds());
+       flush_icache_range(ip, ip + 8);
+       set_fs(old_fs);
        return 0;
  }
  #endif
   *
   * move at, ra
   * jal _mcount                --> nop
+  *  sub sp, sp, 8     --> nop  (CONFIG_32BIT)
   *
   * 2. For modules:
   *
   * 2.1 For KBUILD_MCOUNT_RA_ADDRESS and CONFIG_32BIT
   *
   * lui v1, hi_16bit_of_mcount      --> b 1f (0x10000005)
-  * addiu v1, v1, low_16bit_of_mcount
+  * addiu v1, v1, low_16bit_of_mcount --> nop  (CONFIG_32BIT)
   * move at, ra
   * move $12, ra_address
   * jalr v1
   * 2.2 For the Other situations
   *
   * lui v1, hi_16bit_of_mcount      --> b 1f (0x10000004)
-  * addiu v1, v1, low_16bit_of_mcount
+  * addiu v1, v1, low_16bit_of_mcount --> nop  (CONFIG_32BIT)
   * move at, ra
   * jalr v1
   *  nop | move $12, ra_address | sub sp, sp, 8
@@@ -184,10 -218,14 +218,14 @@@ int ftrace_make_call(struct dyn_ftrace 
        unsigned int new;
        unsigned long ip = rec->ip;
  
-       new = in_kernel_space(ip) ? insn_jal_ftrace_caller :
-               insn_lui_v1_hi16_mcount;
+       new = in_kernel_space(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0];
  
+ #ifdef CONFIG_64BIT
        return ftrace_modify_code(ip, new);
+ #else
+       return ftrace_modify_code_2r(ip, new, in_kernel_space(ip) ?
+                                               INSN_NOP : insn_la_mcount[1]);
+ #endif
  }
  
  #define FTRACE_CALL_IP ((unsigned long)(&ftrace_call))
@@@ -302,9 -340,6 +340,9 @@@ void prepare_ftrace_return(unsigned lon
            &return_to_handler;
        int faulted, insns;
  
 +      if (unlikely(ftrace_graph_is_dead()))
 +              return;
 +
        if (unlikely(atomic_read(&current->tracing_graph_pause)))
                return;
  
@@@ -74,12 -74,29 +74,25 @@@ _mcount
  #endif
  
        /* When tracing is activated, it calls ftrace_caller+8 (aka here) */
 -      lw      t1, function_trace_stop
 -      bnez    t1, ftrace_stub
 -       nop
 -
        MCOUNT_SAVE_REGS
  #ifdef KBUILD_MCOUNT_RA_ADDRESS
        PTR_S   MCOUNT_RA_ADDRESS_REG, PT_R12(sp)
  #endif
  
        PTR_SUBU a0, ra, 8      /* arg1: self address */
+       PTR_LA   t1, _stext
+       sltu     t2, a0, t1     /* t2 = (a0 < _stext) */
+       PTR_LA   t1, _etext
+       sltu     t3, t1, a0     /* t3 = (a0 > _etext) */
+       or       t1, t2, t3
+       beqz     t1, ftrace_call
+        nop
+ #if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
+       PTR_SUBU a0, a0, 16     /* arg1: adjust to module's recorded callsite */
+ #else
+       PTR_SUBU a0, a0, 12
+ #endif
        .globl ftrace_call
  ftrace_call:
        nop     /* a placeholder for the call to a real tracing function */
@@@ -101,6 -118,9 +114,6 @@@ ftrace_stub
  #else /* ! CONFIG_DYNAMIC_FTRACE */
  
  NESTED(_mcount, PT_SIZE, ra)
 -      lw      t1, function_trace_stop
 -      bnez    t1, ftrace_stub
 -       nop
        PTR_LA  t1, ftrace_stub
        PTR_L   t2, ftrace_trace_function /* Prepare t2 for (1) */
        bne     t1, t2, static_trace
@@@ -67,8 -67,6 +67,6 @@@ NESTED(handle_sys, PT_SIZE, sp
  
        /*
         * Ok, copy the args from the luser stack to the kernel stack.
-        * t3 is the precomputed number of instruction bytes needed to
-        * load or store arguments 6-8.
         */
  
        .set    push
@@@ -495,8 -493,8 +493,8 @@@ EXPORT(sys_call_table
        PTR     sys_tgkill
        PTR     sys_utimes
        PTR     sys_mbind
-       PTR     sys_ni_syscall                  /* sys_get_mempolicy */
-       PTR     sys_ni_syscall                  /* 4270 sys_set_mempolicy */
+       PTR     sys_get_mempolicy
+       PTR     sys_set_mempolicy               /* 4270 */
        PTR     sys_mq_open
        PTR     sys_mq_unlink
        PTR     sys_mq_timedsend
        PTR     sys_sched_setattr
        PTR     sys_sched_getattr               /* 4350 */
        PTR     sys_renameat2
 +      PTR     sys_seccomp
@@@ -347,8 -347,8 +347,8 @@@ EXPORT(sys_call_table
        PTR     sys_tgkill                      /* 5225 */
        PTR     sys_utimes
        PTR     sys_mbind
-       PTR     sys_ni_syscall                  /* sys_get_mempolicy */
-       PTR     sys_ni_syscall                  /* sys_set_mempolicy */
+       PTR     sys_get_mempolicy
+       PTR     sys_set_mempolicy
        PTR     sys_mq_open                     /* 5230 */
        PTR     sys_mq_unlink
        PTR     sys_mq_timedsend
        PTR     sys_sched_setattr
        PTR     sys_sched_getattr               /* 5310 */
        PTR     sys_renameat2
 +      PTR     sys_seccomp
        .size   sys_call_table,.-sys_call_table
@@@ -162,7 -162,7 +162,7 @@@ EXPORT(sysn32_call_table
        PTR     sys_getpeername
        PTR     sys_socketpair
        PTR     compat_sys_setsockopt
-       PTR     sys_getsockopt
+       PTR     compat_sys_getsockopt
        PTR     __sys_clone                     /* 6055 */
        PTR     __sys_fork
        PTR     compat_sys_execve
        PTR     compat_sys_clock_nanosleep
        PTR     sys_tgkill
        PTR     compat_sys_utimes               /* 6230 */
-       PTR     sys_ni_syscall                  /* sys_mbind */
-       PTR     sys_ni_syscall                  /* sys_get_mempolicy */
-       PTR     sys_ni_syscall                  /* sys_set_mempolicy */
+       PTR     compat_sys_mbind
+       PTR     compat_sys_get_mempolicy
+       PTR     compat_sys_set_mempolicy
        PTR     compat_sys_mq_open
        PTR     sys_mq_unlink                   /* 6235 */
        PTR     compat_sys_mq_timedsend
        PTR     sys_inotify_init
        PTR     sys_inotify_add_watch
        PTR     sys_inotify_rm_watch
-       PTR     sys_migrate_pages               /* 6250 */
+       PTR     compat_sys_migrate_pages        /* 6250 */
        PTR     sys_openat
        PTR     sys_mkdirat
        PTR     sys_mknodat
        PTR     sys_sync_file_range
        PTR     sys_tee
        PTR     compat_sys_vmsplice             /* 6270 */
-       PTR     sys_move_pages
+       PTR     compat_sys_move_pages
        PTR     compat_sys_set_robust_list
        PTR     compat_sys_get_robust_list
        PTR     compat_sys_kexec_load
        PTR     sys_sched_setattr
        PTR     sys_sched_getattr
        PTR     sys_renameat2                   /* 6315 */
 +      PTR     sys_seccomp
        .size   sysn32_call_table,.-sysn32_call_table
@@@ -473,9 -473,9 +473,9 @@@ EXPORT(sys32_call_table
        PTR     compat_sys_clock_nanosleep      /* 4265 */
        PTR     sys_tgkill
        PTR     compat_sys_utimes
-       PTR     sys_ni_syscall                  /* sys_mbind */
-       PTR     sys_ni_syscall                  /* sys_get_mempolicy */
-       PTR     sys_ni_syscall                  /* 4270 sys_set_mempolicy */
+       PTR     compat_sys_mbind
+       PTR     compat_sys_get_mempolicy
+       PTR     compat_sys_set_mempolicy        /* 4270 */
        PTR     compat_sys_mq_open
        PTR     sys_mq_unlink
        PTR     compat_sys_mq_timedsend
        PTR     sys_inotify_init
        PTR     sys_inotify_add_watch           /* 4285 */
        PTR     sys_inotify_rm_watch
-       PTR     sys_migrate_pages
+       PTR     compat_sys_migrate_pages
        PTR     compat_sys_openat
        PTR     sys_mkdirat
        PTR     sys_mknodat                     /* 4290 */
        PTR     sys_sched_setattr
        PTR     sys_sched_getattr               /* 4350 */
        PTR     sys_renameat2
 +      PTR     sys_seccomp
        .size   sys32_call_table,.-sys32_call_table
diff --combined drivers/spi/spi-au1550.c
@@@ -141,13 -141,13 +141,13 @@@ static inline void au1550_spi_mask_ack_
                  PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO
                | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO
                | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        hw->regs->psc_spievent =
                  PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO
                | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO
                | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD;
-       au_sync();
+       wmb(); /* drain writebuffer */
  }
  
  static void au1550_spi_reset_fifos(struct au1550_spi *hw)
        u32 pcr;
  
        hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC;
-       au_sync();
+       wmb(); /* drain writebuffer */
        do {
                pcr = hw->regs->psc_spipcr;
-               au_sync();
+               wmb(); /* drain writebuffer */
        } while (pcr != 0);
  }
  
@@@ -188,9 -188,9 +188,9 @@@ static void au1550_spi_chipsel(struct s
                au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
  
                cfg = hw->regs->psc_spicfg;
-               au_sync();
+               wmb(); /* drain writebuffer */
                hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
-               au_sync();
+               wmb(); /* drain writebuffer */
  
                if (spi->mode & SPI_CPOL)
                        cfg |= PSC_SPICFG_BI;
                cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz);
  
                hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE;
-               au_sync();
+               wmb(); /* drain writebuffer */
                do {
                        stat = hw->regs->psc_spistat;
-                       au_sync();
+                       wmb(); /* drain writebuffer */
                } while ((stat & PSC_SPISTAT_DR) == 0);
  
                if (hw->pdata->activate_cs)
@@@ -252,9 -252,9 +252,9 @@@ static int au1550_spi_setupxfer(struct 
        au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
  
        cfg = hw->regs->psc_spicfg;
-       au_sync();
+       wmb(); /* drain writebuffer */
        hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        if (hw->usedma && bpw <= 8)
                cfg &= ~PSC_SPICFG_DD_DISABLE;
        cfg |= au1550_spi_baudcfg(hw, hz);
  
        hw->regs->psc_spicfg = cfg;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        if (cfg & PSC_SPICFG_DE_ENABLE) {
                do {
                        stat = hw->regs->psc_spistat;
-                       au_sync();
+                       wmb(); /* drain writebuffer */
                } while ((stat & PSC_SPISTAT_DR) == 0);
        }
  
@@@ -396,11 -396,11 +396,11 @@@ static int au1550_spi_dma_txrxb(struct 
  
        /* by default enable nearly all events interrupt */
        hw->regs->psc_spimsk = PSC_SPIMSK_SD;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        /* start the transfer */
        hw->regs->psc_spipcr = PSC_SPIPCR_MS;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        wait_for_completion(&hw->master_done);
  
@@@ -429,7 -429,7 +429,7 @@@ static irqreturn_t au1550_spi_dma_irq_c
  
        stat = hw->regs->psc_spistat;
        evnt = hw->regs->psc_spievent;
-       au_sync();
+       wmb(); /* drain writebuffer */
        if ((stat & PSC_SPISTAT_DI) == 0) {
                dev_err(hw->dev, "Unexpected IRQ!\n");
                return IRQ_NONE;
  static void au1550_spi_rx_word_##size(struct au1550_spi *hw)          \
  {                                                                     \
        u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask);             \
-       au_sync();                                                      \
+       wmb(); /* drain writebuffer */                                  \
        if (hw->rx) {                                                   \
                *(u##size *)hw->rx = (u##size)fifoword;                 \
                hw->rx += (size) / 8;                                   \
@@@ -504,7 -504,7 +504,7 @@@ static void au1550_spi_tx_word_##size(s
        if (hw->tx_count >= hw->len)                                    \
                fifoword |= PSC_SPITXRX_LC;                             \
        hw->regs->psc_spitxrx = fifoword;                               \
-       au_sync();                                                      \
+       wmb(); /* drain writebuffer */                                  \
  }
  
  AU1550_SPI_RX_WORD(8,0xff)
@@@ -539,18 -539,18 +539,18 @@@ static int au1550_spi_pio_txrxb(struct 
                }
  
                stat = hw->regs->psc_spistat;
-               au_sync();
+               wmb(); /* drain writebuffer */
                if (stat & PSC_SPISTAT_TF)
                        break;
        }
  
        /* enable event interrupts */
        hw->regs->psc_spimsk = mask;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        /* start the transfer */
        hw->regs->psc_spipcr = PSC_SPIPCR_MS;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        wait_for_completion(&hw->master_done);
  
@@@ -564,7 -564,7 +564,7 @@@ static irqreturn_t au1550_spi_pio_irq_c
  
        stat = hw->regs->psc_spistat;
        evnt = hw->regs->psc_spievent;
-       au_sync();
+       wmb(); /* drain writebuffer */
        if ((stat & PSC_SPISTAT_DI) == 0) {
                dev_err(hw->dev, "Unexpected IRQ!\n");
                return IRQ_NONE;
        do {
                busy = 0;
                stat = hw->regs->psc_spistat;
-               au_sync();
+               wmb(); /* drain writebuffer */
  
                /*
                 * Take care to not let the Rx FIFO overflow.
        } while (busy);
  
        hw->regs->psc_spievent = PSC_SPIEVNT_RR | PSC_SPIEVNT_TR;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        /*
         * Restart the SPI transmission in case of a transmit underflow.
         */
        if (evnt & PSC_SPIEVNT_TU) {
                hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD;
-               au_sync();
+               wmb(); /* drain writebuffer */
                hw->regs->psc_spipcr = PSC_SPIPCR_MS;
-               au_sync();
+               wmb(); /* drain writebuffer */
        }
  
        if (hw->rx_count >= hw->len) {
@@@ -690,19 -690,19 +690,19 @@@ static void au1550_spi_setup_psc_as_spi
  
        /* set up the PSC for SPI mode */
        hw->regs->psc_ctrl = PSC_CTRL_DISABLE;
-       au_sync();
+       wmb(); /* drain writebuffer */
        hw->regs->psc_sel = PSC_SEL_PS_SPIMODE;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        hw->regs->psc_spicfg = 0;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        hw->regs->psc_ctrl = PSC_CTRL_ENABLE;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        do {
                stat = hw->regs->psc_spistat;
-               au_sync();
+               wmb(); /* drain writebuffer */
        } while ((stat & PSC_SPISTAT_SR) == 0);
  
  
  #endif
  
        hw->regs->psc_spicfg = cfg;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        au1550_spi_mask_ack_all(hw);
  
        hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE;
-       au_sync();
+       wmb(); /* drain writebuffer */
  
        do {
                stat = hw->regs->psc_spistat;
-               au_sync();
+               wmb(); /* drain writebuffer */
        } while ((stat & PSC_SPISTAT_DR) == 0);
  
        au1550_spi_reset_fifos(hw);
@@@ -925,7 -925,8 +925,7 @@@ err_no_txdma
        iounmap((void __iomem *)hw->regs);
  
  err_ioremap:
 -      release_resource(hw->ioarea);
 -      kfree(hw->ioarea);
 +      release_mem_region(r->start, sizeof(psc_spi_t));
  
  err_no_iores:
  err_no_pdata:
@@@ -945,7 -946,8 +945,7 @@@ static int au1550_spi_remove(struct pla
        spi_bitbang_stop(&hw->bitbang);
        free_irq(hw->irq, hw);
        iounmap((void __iomem *)hw->regs);
 -      release_resource(hw->ioarea);
 -      kfree(hw->ioarea);
 +      release_mem_region(r->start, sizeof(psc_spi_t));
  
        if (hw->usedma) {
                au1550_spi_dma_rxtmp_free(hw);