Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
Linus Torvalds [Tue, 15 Sep 2009 00:48:14 +0000 (17:48 -0700)]
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (257 commits)
  [ARM] Update mach-types
  ARM: 5636/1: Move vendor enum to AMBA include
  ARM: Fix pfn_valid() for sparse memory
  [ARM] orion5x: Add LaCie NAS 2Big Network support
  [ARM] pxa/sharpsl_pm: zaurus c3000 aka spitz: fix resume
  ARM: 5686/1: at91: Correct AC97 reset line in at91sam9263ek board
  ARM: 5640/1: This patch modifies the support of AC97 on the at91sam9263 ek board
  ARM: 5689/1: Update default config of HP Jornada 700-series machines
  ARM: 5691/1: fix cache aliasing issues between kmap() and kmap_atomic() with highmem
  ARM: 5688/1: ks8695_serial: disable_irq() lockup
  ARM: 5687/1: fix an oops with highmem
  ARM: 5684/1: Add nuc960 platform to w90x900
  ARM: 5683/1: Add nuc950 platform to w90x900
  ARM: 5682/1: Add cpu.c and dev.c and modify some files of w90p910 platform
  ARM: 5626/1: add suspend/resume functions to amba-pl011 serial driver
  ARM: 5625/1: fix hard coded 4K resource size in amba bus detection
  MMC: MMCI: convert realview MMC to use gpiolib
  ARM: 5685/1: Make MMCI driver compile without gpiolib
  ARM: implement highpte
  ARM: Show FIQ in /proc/interrupts on CONFIG_FIQ
  ...

Fix up trivial conflict in arch/arm/kernel/signal.c.

It was due to the TIF_NOTIFY_RESUME addition in commit d0420c83f ("KEYS:
Extend TIF_NOTIFY_RESUME to (almost) all architectures") and follow-ups.

1  2 
MAINTAINERS
arch/arm/include/asm/thread_info.h
arch/arm/kernel/entry-common.S
arch/arm/kernel/signal.c
arch/arm/mach-omap2/mcbsp.c
arch/arm/plat-omap/include/mach/mcbsp.h
arch/arm/plat-omap/mcbsp.c
drivers/net/Kconfig
sound/soc/atmel/sam9g20_wm8731.c

diff --combined MAINTAINERS
@@@ -439,7 -439,7 +439,7 @@@ F: drivers/hwmon/ams
  AMSO1100 RNIC DRIVER
  M:    Tom Tucker <tom@opengridcomputing.com>
  M:    Steve Wise <swise@opengridcomputing.com>
 -L:    general@lists.openfabrics.org
 +L:    linux-rdma@vger.kernel.org
  S:    Maintained
  F:    drivers/infiniband/hw/amso1100/
  
@@@ -534,10 -534,30 +534,30 @@@ L:      linux-arm-kernel@lists.arm.linux.org
  W:    http://maxim.org.za/at91_26.html
  S:    Maintained
  
+ ARM/BCMRING ARM ARCHITECTURE
+ M:    Leo Chen <leochen@broadcom.com>
+ M:    Scott Branden <sbranden@broadcom.com>
+ L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+ S:    Maintained
+ F:    arch/arm/mach-bcmring
+ ARM/BCMRING MTD NAND DRIVER
+ M:    Leo Chen <leochen@broadcom.com>
+ M:    Scott Branden <sbranden@broadcom.com>
+ L:    linux-mtd@lists.infradead.org
+ S:    Maintained
+ F:    drivers/mtd/nand/bcm_umi_nand.c
+ F:    drivers/mtd/nand/bcm_umi_bch.c
+ F:    drivers/mtd/nand/bcm_umi_hamming.c
+ F:    drivers/mtd/nand/nand_bcm_umi.h
  ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
- M:    Lennert Buytenhek <kernel@wantstofly.org>
+ M:    Hartley Sweeten <hsweeten@visionengravers.com>
+ M:    Ryan Mallon <ryan@bluewatersys.com>
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
  S:    Maintained
+ F:    arch/arm/mach-ep93xx/
+ F:    arch/arm/mach-ep93xx/include/mach/
  
  ARM/CIRRUS LOGIC EDB9315A MACHINE SUPPORT
  M:    Lennert Buytenhek <kernel@wantstofly.org>
@@@ -685,6 -705,18 +705,18 @@@ ARM/MAGICIAN MACHINE SUPPOR
  M:    Philipp Zabel <philipp.zabel@gmail.com>
  S:    Maintained
  
+ ARM/Marvell Loki/Kirkwood/MV78xx0/Orion SOC support
+ M:    Lennert Buytenhek <buytenh@marvell.com>
+ M:    Nicolas Pitre <nico@marvell.com>
+ L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+ T:    git git://git.marvell.com/orion
+ S:    Maintained
+ F:    arch/arm/mach-loki/
+ F:    arch/arm/mach-kirkwood/
+ F:    arch/arm/mach-mv78xx0/
+ F:    arch/arm/mach-orion5x/
+ F:    arch/arm/plat-orion/
  ARM/MIOA701 MACHINE SUPPORT
  M:    Robert Jarzmik <robert.jarzmik@free.fr>
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
@@@ -876,7 -908,6 +908,7 @@@ M: "Luis R. Rodriguez" <lrodriguez@athe
  M:    Bob Copeland <me@bobcopeland.com>
  L:    linux-wireless@vger.kernel.org
  L:    ath5k-devel@lists.ath5k.org
 +W:    http://wireless.kernel.org/en/users/Drivers/ath5k
  S:    Maintained
  F:    drivers/net/wireless/ath/ath5k/
  
@@@ -888,7 -919,6 +920,7 @@@ M: Vasanthakumar Thiagarajan <vasanth@a
  M:    Senthil Balasubramanian <senthilkumar@atheros.com>
  L:    linux-wireless@vger.kernel.org
  L:    ath9k-devel@lists.ath9k.org
 +W:    http://wireless.kernel.org/en/users/Drivers/ath9k
  S:    Supported
  F:    drivers/net/wireless/ath/ath9k/
  
@@@ -1496,7 -1526,7 +1528,7 @@@ F:      drivers/net/cxgb3
  
  CXGB3 IWARP RNIC DRIVER (IW_CXGB3)
  M:    Steve Wise <swise@chelsio.com>
 -L:    general@lists.openfabrics.org
 +L:    linux-rdma@vger.kernel.org
  W:    http://www.openfabrics.org
  S:    Supported
  F:    drivers/infiniband/hw/cxgb3/
@@@ -1870,7 -1900,7 +1902,7 @@@ F:      fs/efs
  EHCA (IBM GX bus InfiniBand adapter) DRIVER
  M:    Hoang-Nam Nguyen <hnguyen@de.ibm.com>
  M:    Christoph Raisch <raisch@de.ibm.com>
 -L:    general@lists.openfabrics.org
 +L:    linux-rdma@vger.kernel.org
  S:    Supported
  F:    drivers/infiniband/hw/ehca/
  
@@@ -2554,7 -2584,7 +2586,7 @@@ INFINIBAND SUBSYSTE
  M:    Roland Dreier <rolandd@cisco.com>
  M:    Sean Hefty <sean.hefty@intel.com>
  M:    Hal Rosenstock <hal.rosenstock@gmail.com>
 -L:    general@lists.openfabrics.org (moderated for non-subscribers)
 +L:    linux-rdma@vger.kernel.org
  W:    http://www.openib.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git
  S:    Supported
@@@ -2662,21 -2692,25 +2694,21 @@@ F:   drivers/net/ixgbe
  
  INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT
  M:    Zhu Yi <yi.zhu@intel.com>
 -M:    James Ketrenos <jketreno@linux.intel.com>
  M:    Reinette Chatre <reinette.chatre@intel.com>
 +M:    Intel Linux Wireless <ilw@linux.intel.com>
  L:    linux-wireless@vger.kernel.org
 -L:    ipw2100-devel@lists.sourceforge.net
 -W:    http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
  W:    http://ipw2100.sourceforge.net
 -S:    Supported
 +S:    Odd Fixes
  F:    Documentation/networking/README.ipw2100
  F:    drivers/net/wireless/ipw2x00/ipw2100.*
  
  INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT
  M:    Zhu Yi <yi.zhu@intel.com>
 -M:    James Ketrenos <jketreno@linux.intel.com>
  M:    Reinette Chatre <reinette.chatre@intel.com>
 +M:    Intel Linux Wireless <ilw@linux.intel.com>
  L:    linux-wireless@vger.kernel.org
 -L:    ipw2100-devel@lists.sourceforge.net
 -W:    http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel
  W:    http://ipw2200.sourceforge.net
 -S:    Supported
 +S:    Odd Fixes
  F:    Documentation/networking/README.ipw2200
  F:    drivers/net/wireless/ipw2x00/ipw2200.*
  
@@@ -2693,8 -2727,8 +2725,8 @@@ F:      include/linux/wimax/i2400m.
  INTEL WIRELESS WIFI LINK (iwlwifi)
  M:    Zhu Yi <yi.zhu@intel.com>
  M:    Reinette Chatre <reinette.chatre@intel.com>
 +M:    Intel Linux Wireless <ilw@linux.intel.com>
  L:    linux-wireless@vger.kernel.org
 -L:    ipw3945-devel@lists.sourceforge.net
  W:    http://intellinuxwireless.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
  S:    Supported
@@@ -2727,7 -2761,7 +2759,7 @@@ F:      drivers/net/ipg.
  
  IPATH DRIVER
  M:    Ralph Campbell <infinipath@qlogic.com>
 -L:    general@lists.openfabrics.org
 +L:    linux-rdma@vger.kernel.org
  T:    git git://git.qlogic.com/ipath-linux-2.6
  S:    Supported
  F:    drivers/infiniband/hw/ipath/
@@@ -2926,7 -2960,6 +2958,7 @@@ F:      include/linux/sunrpc
  
  KERNEL VIRTUAL MACHINE (KVM)
  M:    Avi Kivity <avi@redhat.com>
 +M:    Marcelo Tosatti <mtosatti@redhat.com>
  L:    kvm@vger.kernel.org
  W:    http://kvm.qumranet.com
  S:    Supported
@@@ -3278,12 -3311,6 +3310,12 @@@ S:    Supporte
  F:    drivers/net/mv643xx_eth.*
  F:    include/linux/mv643xx.h
  
 +MARVELL MWL8K WIRELESS DRIVER
 +M:    Lennert Buytenhek <buytenh@marvell.com>
 +L:    linux-wireless@vger.kernel.org
 +S:    Supported
 +F:    drivers/net/wireless/mwl8k.c
 +
  MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
  M:    Nicolas Pitre <nico@cam.org>
  S:    Maintained
@@@ -3490,7 -3517,7 +3522,7 @@@ F:      drivers/scsi/NCR_D700.
  NETEFFECT IWARP RNIC DRIVER (IW_NES)
  M:    Faisal Latif <faisal.latif@intel.com>
  M:    Chien Tung <chien.tin.tung@intel.com>
 -L:    general@lists.openfabrics.org
 +L:    linux-rdma@vger.kernel.org
  W:    http://www.neteffect.com
  S:    Supported
  F:    drivers/infiniband/hw/nes/
@@@ -3596,12 -3623,9 +3628,12 @@@ M:    "John W. Linville" <linville@tuxdriv
  L:    linux-wireless@vger.kernel.org
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git
  S:    Maintained
 +F:    net/mac80211/
 +F:    net/rfkill/
  F:    net/wireless/
  F:    include/net/ieee80211*
  F:    include/linux/wireless.h
 +F:    drivers/net/wireless/
  
  NETWORKING DRIVERS
  L:    netdev@vger.kernel.org
@@@ -4307,7 -4331,7 +4339,7 @@@ L:      linux-wireless@vger.kernel.or
  W:    http://linuxwireless.org/
  T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
  S:    Maintained
 -F:    drivers/net/wireless/rtl818*
 +F:    drivers/net/wireless/rtl818x/rtl8180*
  
  RTL8187 WIRELESS DRIVER
  M:    Herton Ronaldo Krzesinski <herton@mandriva.com.br>
@@@ -4534,10 -4558,9 +4566,10 @@@ S:    Supporte
  F:    drivers/net/benet/
  
  SFC NETWORK DRIVER
 -P:    Steve Hodgson
 -P:    Ben Hutchings
 -M:    Robert Stonehouse <linux-net-drivers@solarflare.com>
 +M:    Solarflare linux maintainers <linux-net-drivers@solarflare.com>
 +M:    Steve Hodgson <shodgson@solarflare.com>
 +M:    Ben Hutchings <bhutchings@solarflare.com>
 +L:    netdev@vger.kernel.org
  S:    Supported
  F:    drivers/net/sfc/
  
@@@ -5587,24 -5610,6 +5619,24 @@@ M:    Miloslav Trmac <mitr@volny.cz
  S:    Maintained
  F:    drivers/input/misc/wistron_btns.c
  
 +WL1251 WIRELESS DRIVER
 +P:    Kalle Valo
 +M:    kalle.valo@nokia.com
 +L:    linux-wireless@vger.kernel.org
 +W:    http://wireless.kernel.org
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 +S:    Maintained
 +F:    drivers/net/wireless/wl12xx/*
 +X:    drivers/net/wireless/wl12xx/wl1271*
 +
 +WL1271 WIRELESS DRIVER
 +M:    Luciano Coelho <luciano.coelho@nokia.com>
 +L:    linux-wireless@vger.kernel.org
 +W:    http://wireless.kernel.org
 +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
 +S:    Maintained
 +F:    drivers/net/wireless/wl12xx/wl1271*
 +
  WL3501 WIRELESS PCMCIA CARD DRIVER
  M:    Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
  L:    linux-wireless@vger.kernel.org
@@@ -130,26 -130,25 +130,28 @@@ extern void vfp_sync_state(struct threa
   *  TIF_SYSCALL_TRACE - syscall trace active
   *  TIF_SIGPENDING    - signal pending
   *  TIF_NEED_RESCHED  - rescheduling necessary
 + *  TIF_NOTIFY_RESUME - callback before returning to user
   *  TIF_USEDFPU               - FPU was used by this task this quantum (SMP)
   *  TIF_POLLING_NRFLAG        - true if poll_idle() is polling TIF_NEED_RESCHED
   */
  #define TIF_SIGPENDING                0
  #define TIF_NEED_RESCHED      1
 +#define TIF_NOTIFY_RESUME     2       /* callback before returning to user */
  #define TIF_SYSCALL_TRACE     8
  #define TIF_POLLING_NRFLAG    16
  #define TIF_USING_IWMMXT      17
  #define TIF_MEMDIE            18
  #define TIF_FREEZE            19
+ #define TIF_RESTORE_SIGMASK   20
  
  #define _TIF_SIGPENDING               (1 << TIF_SIGPENDING)
  #define _TIF_NEED_RESCHED     (1 << TIF_NEED_RESCHED)
 +#define _TIF_NOTIFY_RESUME    (1 << TIF_NOTIFY_RESUME)
  #define _TIF_SYSCALL_TRACE    (1 << TIF_SYSCALL_TRACE)
  #define _TIF_POLLING_NRFLAG   (1 << TIF_POLLING_NRFLAG)
  #define _TIF_USING_IWMMXT     (1 << TIF_USING_IWMMXT)
  #define _TIF_FREEZE           (1 << TIF_FREEZE)
+ #define _TIF_RESTORE_SIGMASK  (1 << TIF_RESTORE_SIGMASK)
  
  /*
   * Change these and you break ASM code in entry-common.S
@@@ -33,14 -33,7 +33,7 @@@ ret_fast_syscall
        /* perform architecture specific actions before user return */
        arch_ret_to_user r1, lr
  
-       @ fast_restore_user_regs
-       ldr     r1, [sp, #S_OFF + S_PSR]        @ get calling cpsr
-       ldr     lr, [sp, #S_OFF + S_PC]!        @ get pc
-       msr     spsr_cxsf, r1                   @ save in spsr_svc
-       ldmdb   sp, {r1 - lr}^                  @ get calling r1 - lr
-       mov     r0, r0
-       add     sp, sp, #S_FRAME_SIZE - S_PC
-       movs    pc, lr                          @ return & move spsr_svc into cpsr
+       restore_user_regs fast = 1, offset = S_OFF
   UNWIND(.fnend                )
  
  /*
@@@ -51,7 -44,7 +44,7 @@@ fast_work_pending
  work_pending:
        tst     r1, #_TIF_NEED_RESCHED
        bne     work_resched
 -      tst     r1, #_TIF_SIGPENDING
 +      tst     r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
        beq     no_work_pending
        mov     r0, sp                          @ 'regs'
        mov     r2, why                         @ 'syscall'
@@@ -73,14 -66,7 +66,7 @@@ no_work_pending
        /* perform architecture specific actions before user return */
        arch_ret_to_user r1, lr
  
-       @ slow_restore_user_regs
-       ldr     r1, [sp, #S_PSR]                @ get calling cpsr
-       ldr     lr, [sp, #S_PC]!                @ get pc
-       msr     spsr_cxsf, r1                   @ save in spsr_svc
-       ldmdb   sp, {r0 - lr}^                  @ get calling r0 - lr
-       mov     r0, r0
-       add     sp, sp, #S_FRAME_SIZE - S_PC
-       movs    pc, lr                          @ return & move spsr_svc into cpsr
+       restore_user_regs fast = 0, offset = 0
  ENDPROC(ret_to_user)
  
  /*
@@@ -132,6 -118,25 +118,25 @@@ ftrace_call
  
  #else
  
+ ENTRY(__gnu_mcount_nc)
+       stmdb sp!, {r0-r3, lr}
+       ldr r0, =ftrace_trace_function
+       ldr r2, [r0]
+       adr r0, ftrace_stub
+       cmp r0, r2
+       bne gnu_trace
+       ldmia sp!, {r0-r3, ip, lr}
+       bx ip
+ gnu_trace:
+       ldr r1, [sp, #20]                       @ lr of instrumented routine
+       mov r0, lr
+       sub r0, r0, #MCOUNT_INSN_SIZE
+       mov lr, pc
+       mov pc, r2
+       ldmia sp!, {r0-r3, ip, lr}
+       bx ip
  ENTRY(mcount)
        stmdb sp!, {r0-r3, lr}
        ldr r0, =ftrace_trace_function
@@@ -182,8 -187,10 +187,10 @@@ ftrace_stub
  ENTRY(vector_swi)
        sub     sp, sp, #S_FRAME_SIZE
        stmia   sp, {r0 - r12}                  @ Calling r0 - r12
-       add     r8, sp, #S_PC
-       stmdb   r8, {sp, lr}^                   @ Calling sp, lr
+  ARM( add     r8, sp, #S_PC           )
+  ARM( stmdb   r8, {sp, lr}^           )       @ Calling sp, lr
+  THUMB(       mov     r8, sp                  )
+  THUMB(       store_user_sp_lr r8, r10, S_SP  )       @ calling sp, lr
        mrs     r8, spsr                        @ called from non-FIQ mode, so ok.
        str     lr, [sp, #S_PC]                 @ Save calling PC
        str     r8, [sp, #S_PSR]                @ Save CPSR
        bne     __sys_trace
  
        cmp     scno, #NR_syscalls              @ check upper syscall limit
-       adr     lr, ret_fast_syscall            @ return address
+       adr     lr, BSYM(ret_fast_syscall)      @ return address
        ldrcc   pc, [tbl, scno, lsl #2]         @ call sys_* routine
  
        add     r1, sp, #S_OFF
@@@ -293,7 -300,7 +300,7 @@@ __sys_trace
        mov     r0, #0                          @ trace entry [IP = 0]
        bl      syscall_trace
  
-       adr     lr, __sys_trace_return          @ return address
+       adr     lr, BSYM(__sys_trace_return)    @ return address
        mov     scno, r0                        @ syscall number (possibly new)
        add     r1, sp, #S_R0 + S_OFF           @ pointer to regs
        cmp     scno, #NR_syscalls              @ check upper syscall limit
@@@ -373,16 -380,6 +380,6 @@@ sys_clone_wrapper
                b       sys_clone
  ENDPROC(sys_clone_wrapper)
  
- sys_sigsuspend_wrapper:
-               add     r3, sp, #S_OFF
-               b       sys_sigsuspend
- ENDPROC(sys_sigsuspend_wrapper)
- sys_rt_sigsuspend_wrapper:
-               add     r2, sp, #S_OFF
-               b       sys_rt_sigsuspend
- ENDPROC(sys_rt_sigsuspend_wrapper)
  sys_sigreturn_wrapper:
                add     r0, sp, #S_OFF
                b       sys_sigreturn
diff --combined arch/arm/kernel/signal.c
@@@ -12,7 -12,6 +12,7 @@@
  #include <linux/personality.h>
  #include <linux/freezer.h>
  #include <linux/uaccess.h>
 +#include <linux/tracehook.h>
  
  #include <asm/elf.h>
  #include <asm/cacheflush.h>
@@@ -48,57 -47,22 +48,22 @@@ const unsigned long sigreturn_codes[7] 
        MOV_R7_NR_RT_SIGRETURN, SWI_SYS_RT_SIGRETURN, SWI_THUMB_RT_SIGRETURN,
  };
  
  /*
   * atomically swap in the new signal mask, and wait for a signal.
   */
- asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask, struct pt_regs *regs)
+ asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
  {
-       sigset_t saveset;
        mask &= _BLOCKABLE;
        spin_lock_irq(&current->sighand->siglock);
-       saveset = current->blocked;
+       current->saved_sigmask = current->blocked;
        siginitset(&current->blocked, mask);
        recalc_sigpending();
        spin_unlock_irq(&current->sighand->siglock);
-       regs->ARM_r0 = -EINTR;
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(&saveset, regs, 0))
-                       return regs->ARM_r0;
-       }
- }
- asmlinkage int
- sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs)
- {
-       sigset_t saveset, newset;
-       /* XXX: Don't preclude handling different sized sigset_t's. */
-       if (sigsetsize != sizeof(sigset_t))
-               return -EINVAL;
-       if (copy_from_user(&newset, unewset, sizeof(newset)))
-               return -EFAULT;
-       sigdelsetmask(&newset, ~_BLOCKABLE);
-       spin_lock_irq(&current->sighand->siglock);
-       saveset = current->blocked;
-       current->blocked = newset;
-       recalc_sigpending();
-       spin_unlock_irq(&current->sighand->siglock);
-       regs->ARM_r0 = -EINTR;
  
-       while (1) {
-               current->state = TASK_INTERRUPTIBLE;
-               schedule();
-               if (do_signal(&saveset, regs, 0))
-                       return regs->ARM_r0;
-       }
+       current->state = TASK_INTERRUPTIBLE;
+       schedule();
+       set_restore_sigmask();
+       return -ERESTARTNOHAND;
  }
  
  asmlinkage int 
@@@ -546,7 -510,7 +511,7 @@@ static inline void setup_syscall_restar
  /*
   * OK, we're invoking a handler
   */   
- static void
+ static int
  handle_signal(unsigned long sig, struct k_sigaction *ka,
              siginfo_t *info, sigset_t *oldset,
              struct pt_regs * regs, int syscall)
  
        if (ret != 0) {
                force_sigsegv(sig, tsk);
-               return;
+               return ret;
        }
  
        /*
        recalc_sigpending();
        spin_unlock_irq(&tsk->sighand->siglock);
  
+       return 0;
  }
  
  /*
   * the kernel can handle, and then we build all the user-level signal handling
   * stack-frames in one go after that.
   */
- static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
+ static void do_signal(struct pt_regs *regs, int syscall)
  {
        struct k_sigaction ka;
        siginfo_t info;
         * if so.
         */
        if (!user_mode(regs))
-               return 0;
+               return;
  
        if (try_to_freeze())
                goto no_signal;
  
        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
        if (signr > 0) {
-               handle_signal(signr, &ka, &info, oldset, regs, syscall);
+               sigset_t *oldset;
+               if (test_thread_flag(TIF_RESTORE_SIGMASK))
+                       oldset = &current->saved_sigmask;
+               else
+                       oldset = &current->blocked;
+               if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) {
+                       /*
+                        * A signal was successfully delivered; the saved
+                        * sigmask will have been stored in the signal frame,
+                        * and will be restored by sigreturn, so we can simply
+                        * clear the TIF_RESTORE_SIGMASK flag.
+                        */
+                       if (test_thread_flag(TIF_RESTORE_SIGMASK))
+                               clear_thread_flag(TIF_RESTORE_SIGMASK);
+               }
                single_step_set(current);
-               return 1;
+               return;
        }
  
   no_signal:
                    regs->ARM_r0 == -ERESTARTNOINTR) {
                        setup_syscall_restart(regs);
                }
+               /* If there's no signal to deliver, we just put the saved sigmask
+                * back.
+                */
+               if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+                       clear_thread_flag(TIF_RESTORE_SIGMASK);
+                       sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+               }
        }
        single_step_set(current);
-       return 0;
  }
  
  asmlinkage void
  do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
  {
        if (thread_flags & _TIF_SIGPENDING)
-               do_signal(&current->blocked, regs, syscall);
+               do_signal(regs, syscall);
 +
 +      if (thread_flags & _TIF_NOTIFY_RESUME) {
 +              clear_thread_flag(TIF_NOTIFY_RESUME);
 +              tracehook_notify_resume(regs);
 +              if (current->replacement_session_keyring)
 +                      key_replace_session_keyring();
 +      }
  }
@@@ -128,7 -128,6 +128,7 @@@ static struct omap_mcbsp_platform_data 
                .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
                .ops            = &omap2_mcbsp_ops,
 +              .buffer_size    = 0x6F,
        },
        {
                .phys_base      = OMAP34XX_MCBSP2_BASE,
                .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
                .ops            = &omap2_mcbsp_ops,
 +              .buffer_size    = 0x3FF,
        },
        {
                .phys_base      = OMAP34XX_MCBSP3_BASE,
                .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
                .ops            = &omap2_mcbsp_ops,
 +              .buffer_size    = 0x6F,
        },
        {
                .phys_base      = OMAP34XX_MCBSP4_BASE,
                .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
                .ops            = &omap2_mcbsp_ops,
 +              .buffer_size    = 0x6F,
        },
        {
                .phys_base      = OMAP34XX_MCBSP5_BASE,
                .rx_irq         = INT_24XX_MCBSP5_IRQ_RX,
                .tx_irq         = INT_24XX_MCBSP5_IRQ_TX,
                .ops            = &omap2_mcbsp_ops,
 +              .buffer_size    = 0x6F,
        },
  };
  #define OMAP34XX_MCBSP_PDATA_SZ               ARRAY_SIZE(omap34xx_mcbsp_pdata)
  #define OMAP34XX_MCBSP_PDATA_SZ               0
  #endif
  
+ static struct omap_mcbsp_platform_data omap44xx_mcbsp_pdata[] = {
+       {
+               .phys_base      = OMAP44XX_MCBSP1_BASE,
+               .dma_rx_sync    = OMAP44XX_DMA_MCBSP1_RX,
+               .dma_tx_sync    = OMAP44XX_DMA_MCBSP1_TX,
+               .rx_irq         = INT_24XX_MCBSP1_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP1_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+       },
+       {
+               .phys_base      = OMAP44XX_MCBSP2_BASE,
+               .dma_rx_sync    = OMAP44XX_DMA_MCBSP2_RX,
+               .dma_tx_sync    = OMAP44XX_DMA_MCBSP2_TX,
+               .rx_irq         = INT_24XX_MCBSP2_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP2_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+       },
+       {
+               .phys_base      = OMAP44XX_MCBSP3_BASE,
+               .dma_rx_sync    = OMAP44XX_DMA_MCBSP3_RX,
+               .dma_tx_sync    = OMAP44XX_DMA_MCBSP3_TX,
+               .rx_irq         = INT_24XX_MCBSP3_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP3_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+       },
+       {
+               .phys_base      = OMAP44XX_MCBSP4_BASE,
+               .dma_rx_sync    = OMAP44XX_DMA_MCBSP4_RX,
+               .dma_tx_sync    = OMAP44XX_DMA_MCBSP4_TX,
+               .rx_irq         = INT_24XX_MCBSP4_IRQ_RX,
+               .tx_irq         = INT_24XX_MCBSP4_IRQ_TX,
+               .ops            = &omap2_mcbsp_ops,
+       },
+ };
+ #define OMAP44XX_MCBSP_PDATA_SZ               ARRAY_SIZE(omap44xx_mcbsp_pdata)
  static int __init omap2_mcbsp_init(void)
  {
        if (cpu_is_omap2420())
                omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
        if (cpu_is_omap34xx())
                omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
+       if (cpu_is_omap44xx())
+               omap_mcbsp_count = OMAP44XX_MCBSP_PDATA_SZ;
  
        mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
                                                                GFP_KERNEL);
        if (cpu_is_omap34xx())
                omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
                                                OMAP34XX_MCBSP_PDATA_SZ);
+       if (cpu_is_omap44xx())
+               omap_mcbsp_register_board_cfg(omap44xx_mcbsp_pdata,
+                                               OMAP44XX_MCBSP_PDATA_SZ);
  
        return omap_mcbsp_init();
  }
  #define OMAP34XX_MCBSP4_BASE  0x49026000
  #define OMAP34XX_MCBSP5_BASE  0x48096000
  
+ #define OMAP44XX_MCBSP1_BASE  0x49022000
+ #define OMAP44XX_MCBSP2_BASE  0x49024000
+ #define OMAP44XX_MCBSP3_BASE  0x49026000
+ #define OMAP44XX_MCBSP4_BASE  0x48074000
  #if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)
  
  #define OMAP_MCBSP_REG_DRR2   0x00
  #define AUDIO_DMA_TX          OMAP_DMA_MCBSP1_TX
  #define AUDIO_DMA_RX          OMAP_DMA_MCBSP1_RX
  
- #elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+ #elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
+       defined(CONFIG_ARCH_OMAP4)
  
  #define OMAP_MCBSP_REG_DRR2   0x00
  #define OMAP_MCBSP_REG_DRR1   0x04
  #define OMAP_MCBSP_REG_XCERG  0x74
  #define OMAP_MCBSP_REG_XCERH  0x78
  #define OMAP_MCBSP_REG_SYSCON 0x8C
 +#define OMAP_MCBSP_REG_THRSH2 0x90
 +#define OMAP_MCBSP_REG_THRSH1 0x94
 +#define OMAP_MCBSP_REG_IRQST  0xA0
 +#define OMAP_MCBSP_REG_IRQEN  0xA4
 +#define OMAP_MCBSP_REG_WAKEUPEN       0xA8
  #define OMAP_MCBSP_REG_XCCR   0xAC
  #define OMAP_MCBSP_REG_RCCR   0xB0
  
  #define RDISABLE              0x0001
  
  /********************** McBSP SYSCONFIG bit definitions ********************/
 +#define CLOCKACTIVITY(value)  ((value)<<8)
 +#define SIDLEMODE(value)      ((value)<<3)
 +#define ENAWAKEUP             0x0004
  #define SOFTRST                       0x0002
  
 +/********************** McBSP DMA operating modes **************************/
 +#define MCBSP_DMA_MODE_ELEMENT                0
 +#define MCBSP_DMA_MODE_THRESHOLD      1
 +#define MCBSP_DMA_MODE_FRAME          2
 +
 +/********************** McBSP WAKEUPEN bit definitions *********************/
 +#define XEMPTYEOFEN           0x4000
 +#define XRDYEN                        0x0400
 +#define XEOFEN                        0x0200
 +#define XFSXEN                        0x0100
 +#define XSYNCERREN            0x0080
 +#define RRDYEN                        0x0008
 +#define REOFEN                        0x0004
 +#define RFSREN                        0x0002
 +#define RSYNCERREN            0x0001
 +
  /* we don't do multichannel for now */
  struct omap_mcbsp_reg_cfg {
        u16 spcr2;
@@@ -368,9 -350,6 +374,9 @@@ struct omap_mcbsp_platform_data 
        u8 dma_rx_sync, dma_tx_sync;
        u16 rx_irq, tx_irq;
        struct omap_mcbsp_ops *ops;
 +#ifdef CONFIG_ARCH_OMAP34XX
 +      u16 buffer_size;
 +#endif
  };
  
  struct omap_mcbsp {
        struct omap_mcbsp_platform_data *pdata;
        struct clk *iclk;
        struct clk *fclk;
 +#ifdef CONFIG_ARCH_OMAP34XX
 +      int dma_op_mode;
 +      u16 max_tx_thres;
 +      u16 max_rx_thres;
 +#endif
  };
  extern struct omap_mcbsp **mcbsp_ptr;
  extern int omap_mcbsp_count;
@@@ -417,25 -391,10 +423,25 @@@ int omap_mcbsp_init(void)
  void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
                                        int size);
  void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
 +#ifdef CONFIG_ARCH_OMAP34XX
 +void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
 +void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
 +u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
 +u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
 +int omap_mcbsp_get_dma_op_mode(unsigned int id);
 +#else
 +static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
 +{ }
 +static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
 +{ }
 +static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
 +static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
 +static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
 +#endif
  int omap_mcbsp_request(unsigned int id);
  void omap_mcbsp_free(unsigned int id);
 -void omap_mcbsp_start(unsigned int id);
 -void omap_mcbsp_stop(unsigned int id);
 +void omap_mcbsp_start(unsigned int id, int tx, int rx);
 +void omap_mcbsp_stop(unsigned int id, int tx, int rx);
  void omap_mcbsp_xmit_word(unsigned int id, u32 word);
  u32 omap_mcbsp_recv_word(unsigned int id);
  
@@@ -191,177 -191,13 +191,177 @@@ void omap_mcbsp_config(unsigned int id
        OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
        OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
        OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
-       if (cpu_is_omap2430() || cpu_is_omap34xx()) {
+       if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
                OMAP_MCBSP_WRITE(io_base, XCCR, config->xccr);
                OMAP_MCBSP_WRITE(io_base, RCCR, config->rccr);
        }
  }
  EXPORT_SYMBOL(omap_mcbsp_config);
  
 +#ifdef CONFIG_ARCH_OMAP34XX
 +/*
 + * omap_mcbsp_set_tx_threshold configures how to deal
 + * with transmit threshold. the threshold value and handler can be
 + * configure in here.
 + */
 +void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
 +{
 +      struct omap_mcbsp *mcbsp;
 +      void __iomem *io_base;
 +
 +      if (!cpu_is_omap34xx())
 +              return;
 +
 +      if (!omap_mcbsp_check_valid_id(id)) {
 +              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 +              return;
 +      }
 +      mcbsp = id_to_mcbsp_ptr(id);
 +      io_base = mcbsp->io_base;
 +
 +      OMAP_MCBSP_WRITE(io_base, THRSH2, threshold);
 +}
 +EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
 +
 +/*
 + * omap_mcbsp_set_rx_threshold configures how to deal
 + * with receive threshold. the threshold value and handler can be
 + * configure in here.
 + */
 +void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
 +{
 +      struct omap_mcbsp *mcbsp;
 +      void __iomem *io_base;
 +
 +      if (!cpu_is_omap34xx())
 +              return;
 +
 +      if (!omap_mcbsp_check_valid_id(id)) {
 +              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 +              return;
 +      }
 +      mcbsp = id_to_mcbsp_ptr(id);
 +      io_base = mcbsp->io_base;
 +
 +      OMAP_MCBSP_WRITE(io_base, THRSH1, threshold);
 +}
 +EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
 +
 +/*
 + * omap_mcbsp_get_max_tx_thres just return the current configured
 + * maximum threshold for transmission
 + */
 +u16 omap_mcbsp_get_max_tx_threshold(unsigned int id)
 +{
 +      struct omap_mcbsp *mcbsp;
 +
 +      if (!omap_mcbsp_check_valid_id(id)) {
 +              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 +              return -ENODEV;
 +      }
 +      mcbsp = id_to_mcbsp_ptr(id);
 +
 +      return mcbsp->max_tx_thres;
 +}
 +EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold);
 +
 +/*
 + * omap_mcbsp_get_max_rx_thres just return the current configured
 + * maximum threshold for reception
 + */
 +u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
 +{
 +      struct omap_mcbsp *mcbsp;
 +
 +      if (!omap_mcbsp_check_valid_id(id)) {
 +              printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
 +              return -ENODEV;
 +      }
 +      mcbsp = id_to_mcbsp_ptr(id);
 +
 +      return mcbsp->max_rx_thres;
 +}
 +EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
 +
 +/*
 + * omap_mcbsp_get_dma_op_mode just return the current configured
 + * operating mode for the mcbsp channel
 + */
 +int omap_mcbsp_get_dma_op_mode(unsigned int id)
 +{
 +      struct omap_mcbsp *mcbsp;
 +      int dma_op_mode;
 +
 +      if (!omap_mcbsp_check_valid_id(id)) {
 +              printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1);
 +              return -ENODEV;
 +      }
 +      mcbsp = id_to_mcbsp_ptr(id);
 +
 +      spin_lock_irq(&mcbsp->lock);
 +      dma_op_mode = mcbsp->dma_op_mode;
 +      spin_unlock_irq(&mcbsp->lock);
 +
 +      return dma_op_mode;
 +}
 +EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
 +
 +static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
 +{
 +      /*
 +       * Enable wakup behavior, smart idle and all wakeups
 +       * REVISIT: some wakeups may be unnecessary
 +       */
 +      if (cpu_is_omap34xx()) {
 +              u16 syscon;
 +
 +              syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
 +              syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 +
 +              spin_lock_irq(&mcbsp->lock);
 +              if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
 +                      syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
 +                                      CLOCKACTIVITY(0x02));
 +                      OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN,
 +                                      XRDYEN | RRDYEN);
 +              } else {
 +                      syscon |= SIDLEMODE(0x01);
 +              }
 +              spin_unlock_irq(&mcbsp->lock);
 +
 +              OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
 +      }
 +}
 +
 +static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
 +{
 +      /*
 +       * Disable wakup behavior, smart idle and all wakeups
 +       */
 +      if (cpu_is_omap34xx()) {
 +              u16 syscon;
 +
 +              syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
 +              syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
 +              /*
 +               * HW bug workaround - If no_idle mode is taken, we need to
 +               * go to smart_idle before going to always_idle, or the
 +               * device will not hit retention anymore.
 +               */
 +              syscon |= SIDLEMODE(0x02);
 +              OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
 +
 +              syscon &= ~(SIDLEMODE(0x03));
 +              OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
 +
 +              OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, 0);
 +      }
 +}
 +#else
 +static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
 +static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
 +#endif
 +
  /*
   * We can choose between IRQ based or polled IO.
   * This needs to be called before omap_mcbsp_request().
@@@ -421,9 -257,6 +421,9 @@@ int omap_mcbsp_request(unsigned int id
        clk_enable(mcbsp->iclk);
        clk_enable(mcbsp->fclk);
  
 +      /* Do procedure specific to omap34xx arch, if applicable */
 +      omap34xx_mcbsp_request(mcbsp);
 +
        /*
         * Make sure that transmitter, receiver and sample-rate generator are
         * not running before activating IRQs.
@@@ -472,9 -305,6 +472,9 @@@ void omap_mcbsp_free(unsigned int id
        if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
                mcbsp->pdata->ops->free(id);
  
 +      /* Do procedure specific to omap34xx arch, if applicable */
 +      omap34xx_mcbsp_free(mcbsp);
 +
        clk_disable(mcbsp->fclk);
        clk_disable(mcbsp->iclk);
  
  EXPORT_SYMBOL(omap_mcbsp_free);
  
  /*
 - * Here we start the McBSP, by enabling the sample
 - * generator, both transmitter and receivers,
 - * and the frame sync.
 + * Here we start the McBSP, by enabling transmitter, receiver or both.
 + * If no transmitter or receiver is active prior calling, then sample-rate
 + * generator and frame sync are started.
   */
 -void omap_mcbsp_start(unsigned int id)
 +void omap_mcbsp_start(unsigned int id, int tx, int rx)
  {
        struct omap_mcbsp *mcbsp;
        void __iomem *io_base;
 +      int idle;
        u16 w;
  
        if (!omap_mcbsp_check_valid_id(id)) {
        mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
        mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
  
 -      /* Start the sample generator */
 -      w = OMAP_MCBSP_READ(io_base, SPCR2);
 -      OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
 +      idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
 +                OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
 +
 +      if (idle) {
 +              /* Start the sample generator */
 +              w = OMAP_MCBSP_READ(io_base, SPCR2);
 +              OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
 +      }
  
        /* Enable transmitter and receiver */
 +      tx &= 1;
        w = OMAP_MCBSP_READ(io_base, SPCR2);
 -      OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1);
 +      OMAP_MCBSP_WRITE(io_base, SPCR2, w | tx);
  
 +      rx &= 1;
        w = OMAP_MCBSP_READ(io_base, SPCR1);
 -      OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1);
 +      OMAP_MCBSP_WRITE(io_base, SPCR1, w | rx);
  
 -      udelay(100);
 +      /*
 +       * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
 +       * REVISIT: 100us may give enough time for two CLKSRG, however
 +       * due to some unknown PM related, clock gating etc. reason it
 +       * is now at 500us.
 +       */
 +      udelay(500);
  
 -      /* Start frame sync */
 -      w = OMAP_MCBSP_READ(io_base, SPCR2);
 -      OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
 +      if (idle) {
 +              /* Start frame sync */
 +              w = OMAP_MCBSP_READ(io_base, SPCR2);
 +              OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
 +      }
 +
 +      if (cpu_is_omap2430() || cpu_is_omap34xx()) {
 +              /* Release the transmitter and receiver */
 +              w = OMAP_MCBSP_READ(io_base, XCCR);
 +              w &= ~(tx ? XDISABLE : 0);
 +              OMAP_MCBSP_WRITE(io_base, XCCR, w);
 +              w = OMAP_MCBSP_READ(io_base, RCCR);
 +              w &= ~(rx ? RDISABLE : 0);
 +              OMAP_MCBSP_WRITE(io_base, RCCR, w);
 +      }
  
        /* Dump McBSP Regs */
        omap_mcbsp_dump_reg(id);
  }
  EXPORT_SYMBOL(omap_mcbsp_start);
  
 -void omap_mcbsp_stop(unsigned int id)
 +void omap_mcbsp_stop(unsigned int id, int tx, int rx)
  {
        struct omap_mcbsp *mcbsp;
        void __iomem *io_base;
 +      int idle;
        u16 w;
  
        if (!omap_mcbsp_check_valid_id(id)) {
        io_base = mcbsp->io_base;
  
        /* Reset transmitter */
 +      tx &= 1;
 +      if (cpu_is_omap2430() || cpu_is_omap34xx()) {
 +              w = OMAP_MCBSP_READ(io_base, XCCR);
 +              w |= (tx ? XDISABLE : 0);
 +              OMAP_MCBSP_WRITE(io_base, XCCR, w);
 +      }
        w = OMAP_MCBSP_READ(io_base, SPCR2);
 -      OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
 +      OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~tx);
  
        /* Reset receiver */
 +      rx &= 1;
 +      if (cpu_is_omap2430() || cpu_is_omap34xx()) {
 +              w = OMAP_MCBSP_READ(io_base, RCCR);
 +              w |= (tx ? RDISABLE : 0);
 +              OMAP_MCBSP_WRITE(io_base, RCCR, w);
 +      }
        w = OMAP_MCBSP_READ(io_base, SPCR1);
 -      OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
 +      OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~rx);
  
 -      /* Reset the sample rate generator */
 -      w = OMAP_MCBSP_READ(io_base, SPCR2);
 -      OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
 +      idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
 +                OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
 +
 +      if (idle) {
 +              /* Reset the sample rate generator */
 +              w = OMAP_MCBSP_READ(io_base, SPCR2);
 +              OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
 +      }
  }
  EXPORT_SYMBOL(omap_mcbsp_stop);
  
@@@ -1097,149 -883,6 +1097,149 @@@ void omap_mcbsp_set_spi_mode(unsigned i
  }
  EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
  
 +#ifdef CONFIG_ARCH_OMAP34XX
 +#define max_thres(m)                  (mcbsp->pdata->buffer_size)
 +#define valid_threshold(m, val)               ((val) <= max_thres(m))
 +#define THRESHOLD_PROP_BUILDER(prop)                                  \
 +static ssize_t prop##_show(struct device *dev,                                \
 +                      struct device_attribute *attr, char *buf)       \
 +{                                                                     \
 +      struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);                \
 +                                                                      \
 +      return sprintf(buf, "%u\n", mcbsp->prop);                       \
 +}                                                                     \
 +                                                                      \
 +static ssize_t prop##_store(struct device *dev,                               \
 +                              struct device_attribute *attr,          \
 +                              const char *buf, size_t size)           \
 +{                                                                     \
 +      struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);                \
 +      unsigned long val;                                              \
 +      int status;                                                     \
 +                                                                      \
 +      status = strict_strtoul(buf, 0, &val);                          \
 +      if (status)                                                     \
 +              return status;                                          \
 +                                                                      \
 +      if (!valid_threshold(mcbsp, val))                               \
 +              return -EDOM;                                           \
 +                                                                      \
 +      mcbsp->prop = val;                                              \
 +      return size;                                                    \
 +}                                                                     \
 +                                                                      \
 +static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
 +
 +THRESHOLD_PROP_BUILDER(max_tx_thres);
 +THRESHOLD_PROP_BUILDER(max_rx_thres);
 +
 +static const char *dma_op_modes[] = {
 +      "element", "threshold", "frame",
 +};
 +
 +static ssize_t dma_op_mode_show(struct device *dev,
 +                      struct device_attribute *attr, char *buf)
 +{
 +      struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
 +      int dma_op_mode, i = 0;
 +      ssize_t len = 0;
 +      const char * const *s;
 +
 +      spin_lock_irq(&mcbsp->lock);
 +      dma_op_mode = mcbsp->dma_op_mode;
 +      spin_unlock_irq(&mcbsp->lock);
 +
 +      for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
 +              if (dma_op_mode == i)
 +                      len += sprintf(buf + len, "[%s] ", *s);
 +              else
 +                      len += sprintf(buf + len, "%s ", *s);
 +      }
 +      len += sprintf(buf + len, "\n");
 +
 +      return len;
 +}
 +
 +static ssize_t dma_op_mode_store(struct device *dev,
 +                              struct device_attribute *attr,
 +                              const char *buf, size_t size)
 +{
 +      struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
 +      const char * const *s;
 +      int i = 0;
 +
 +      for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++)
 +              if (sysfs_streq(buf, *s))
 +                      break;
 +
 +      if (i == ARRAY_SIZE(dma_op_modes))
 +              return -EINVAL;
 +
 +      spin_lock_irq(&mcbsp->lock);
 +      if (!mcbsp->free) {
 +              size = -EBUSY;
 +              goto unlock;
 +      }
 +      mcbsp->dma_op_mode = i;
 +
 +unlock:
 +      spin_unlock_irq(&mcbsp->lock);
 +
 +      return size;
 +}
 +
 +static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
 +
 +static const struct attribute *additional_attrs[] = {
 +      &dev_attr_max_tx_thres.attr,
 +      &dev_attr_max_rx_thres.attr,
 +      &dev_attr_dma_op_mode.attr,
 +      NULL,
 +};
 +
 +static const struct attribute_group additional_attr_group = {
 +      .attrs = (struct attribute **)additional_attrs,
 +};
 +
 +static inline int __devinit omap_additional_add(struct device *dev)
 +{
 +      return sysfs_create_group(&dev->kobj, &additional_attr_group);
 +}
 +
 +static inline void __devexit omap_additional_remove(struct device *dev)
 +{
 +      sysfs_remove_group(&dev->kobj, &additional_attr_group);
 +}
 +
 +static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
 +{
 +      mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
 +      if (cpu_is_omap34xx()) {
 +              mcbsp->max_tx_thres = max_thres(mcbsp);
 +              mcbsp->max_rx_thres = max_thres(mcbsp);
 +              /*
 +               * REVISIT: Set dmap_op_mode to THRESHOLD as default
 +               * for mcbsp2 instances.
 +               */
 +              if (omap_additional_add(mcbsp->dev))
 +                      dev_warn(mcbsp->dev,
 +                              "Unable to create additional controls\n");
 +      } else {
 +              mcbsp->max_tx_thres = -EINVAL;
 +              mcbsp->max_rx_thres = -EINVAL;
 +      }
 +}
 +
 +static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
 +{
 +      if (cpu_is_omap34xx())
 +              omap_additional_remove(mcbsp->dev);
 +}
 +#else
 +static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
 +static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
 +#endif /* CONFIG_ARCH_OMAP34XX */
 +
  /*
   * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
   * 730 has only 2 McBSP, and both of them are MPU peripherals.
@@@ -1310,10 -953,6 +1310,10 @@@ static int __devinit omap_mcbsp_probe(s
        mcbsp->dev = &pdev->dev;
        mcbsp_ptr[id] = mcbsp;
        platform_set_drvdata(pdev, mcbsp);
 +
 +      /* Initialize mcbsp properties for OMAP34XX if needed / applicable */
 +      omap34xx_device_init(mcbsp);
 +
        return 0;
  
  err_fclk:
@@@ -1337,8 -976,6 +1337,8 @@@ static int __devexit omap_mcbsp_remove(
                                mcbsp->pdata->ops->free)
                        mcbsp->pdata->ops->free(mcbsp->id);
  
 +              omap34xx_device_exit(mcbsp);
 +
                clk_disable(mcbsp->fclk);
                clk_disable(mcbsp->iclk);
                clk_put(mcbsp->fclk);
diff --combined drivers/net/Kconfig
@@@ -209,7 -209,7 +209,7 @@@ config MI
  
  config MACB
        tristate "Atmel MACB support"
-       depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91CAP9
+       depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263 || ARCH_AT91SAM9G20 || ARCH_AT91SAM9G45 || ARCH_AT91CAP9
        select PHYLIB
        help
          The Atmel MACB ethernet interface is found on many AT32 and AT91
@@@ -1776,7 -1776,7 +1776,7 @@@ config SC9203
  
  config CPMAC
        tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
 -      depends on NET_ETHERNET && EXPERIMENTAL && AR7 && BROKEN
 +      depends on NET_ETHERNET && EXPERIMENTAL && AR7
        select PHYLIB
        help
          TI AR7 CPMAC Ethernet support
@@@ -1928,12 -1928,6 +1928,12 @@@ config ATL
          To compile this driver as a module, choose M here.  The module
          will be called atl2.
  
 +config XILINX_EMACLITE
 +      tristate "Xilinx 10/100 Ethernet Lite support"
 +      depends on PPC32 || MICROBLAZE
 +      help
 +        This driver supports the 10/100 Ethernet Lite from Xilinx.
 +
  source "drivers/net/fs_enet/Kconfig"
  
  endif # NET_ETHERNET
@@@ -2375,6 -2369,10 +2375,6 @@@ config UCC_GET
          This driver supports the Gigabit Ethernet mode of the QUICC Engine,
          which is available on some Freescale SOCs.
  
 -config UGETH_MAGIC_PACKET
 -      bool "Magic Packet detection support"
 -      depends on UCC_GETH
 -
  config UGETH_TX_ON_DEMAND
        bool "Transmit on Demand support"
        depends on UCC_GETH
@@@ -2726,7 -2724,6 +2726,7 @@@ config BNX2
        select FW_LOADER
        select ZLIB_INFLATE
        select LIBCRC32C
 +      select MDIO
        help
          This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
          To compile this driver as a module, choose M here: the module
  
  #define MCLK_RATE 12000000
  
 -static struct clk *mclk;
 -
 -static int at91sam9g20ek_startup(struct snd_pcm_substream *substream)
 -{
 -      struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
 -      struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
 -      int ret;
 -
 -      ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
 -              MCLK_RATE, SND_SOC_CLOCK_IN);
 -      if (ret < 0) {
 -              clk_disable(mclk);
 -              return ret;
 -      }
 -
 -      return 0;
 -}
 -
 -static void at91sam9g20ek_shutdown(struct snd_pcm_substream *substream)
 -{
 -      struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
 +/*
 + * As shipped the board does not have inputs.  However, it is relatively
 + * straightforward to modify the board to hook them up so support is left
 + * in the driver.
 + */
 +#undef ENABLE_MIC_INPUT
  
 -      dev_dbg(rtd->socdev->dev, "shutdown");
 -}
 +static struct clk *mclk;
  
  static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params)
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
 -      struct atmel_ssc_info *ssc_p = cpu_dai->private_data;
 -      struct ssc_device *ssc = ssc_p->ssc;
        int ret;
  
 -      unsigned int rate;
 -      int cmr_div, period;
 -
 -      if (ssc == NULL) {
 -              printk(KERN_INFO "at91sam9g20ek_hw_params: ssc is NULL!\n");
 -              return -EINVAL;
 -      }
 -
        /* set codec DAI configuration */
        ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
 -              SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
 +              SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
        if (ret < 0)
                return ret;
  
        /* set cpu DAI configuration */
        ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
 -              SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
 -      if (ret < 0)
 -              return ret;
 -
 -      /*
 -       * The SSC clock dividers depend on the sample rate.  The CMR.DIV
 -       * field divides the system master clock MCK to drive the SSC TK
 -       * signal which provides the codec BCLK.  The TCMR.PERIOD and
 -       * RCMR.PERIOD fields further divide the BCLK signal to drive
 -       * the SSC TF and RF signals which provide the codec DACLRC and
 -       * ADCLRC clocks.
 -       *
 -       * The dividers were determined through trial and error, where a
 -       * CMR.DIV value is chosen such that the resulting BCLK value is
 -       * divisible, or almost divisible, by (2 * sample rate), and then
 -       * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
 -       */
 -      rate = params_rate(params);
 -
 -      switch (rate) {
 -      case 8000:
 -              cmr_div = 55;   /* BCLK = 133MHz/(2*55) = 1.209MHz */
 -              period = 74;    /* LRC = BCLK/(2*(74+1)) ~= 8060,6Hz */
 -              break;
 -      case 11025:
 -              cmr_div = 67;   /* BCLK = 133MHz/(2*60) = 1.108MHz */
 -              period = 45;    /* LRC = BCLK/(2*(49+1)) = 11083,3Hz */
 -              break;
 -      case 16000:
 -              cmr_div = 63;   /* BCLK = 133MHz/(2*63) = 1.055MHz */
 -              period = 32;    /* LRC = BCLK/(2*(32+1)) = 15993,2Hz */
 -              break;
 -      case 22050:
 -              cmr_div = 52;   /* BCLK = 133MHz/(2*52) = 1.278MHz */
 -              period = 28;    /* LRC = BCLK/(2*(28+1)) = 22049Hz */
 -              break;
 -      case 32000:
 -              cmr_div = 66;   /* BCLK = 133MHz/(2*66) = 1.007MHz */
 -              period = 15;    /* LRC = BCLK/(2*(15+1)) = 31486,742Hz */
 -              break;
 -      case 44100:
 -              cmr_div = 29;   /* BCLK = 133MHz/(2*29) = 2.293MHz */
 -              period = 25;    /* LRC = BCLK/(2*(25+1)) = 44098Hz */
 -              break;
 -      case 48000:
 -              cmr_div = 33;   /* BCLK = 133MHz/(2*33) = 2.015MHz */
 -              period = 20;    /* LRC = BCLK/(2*(20+1)) = 47979,79Hz */
 -              break;
 -      case 88200:
 -              cmr_div = 29;   /* BCLK = 133MHz/(2*29) = 2.293MHz */
 -              period = 12;    /* LRC = BCLK/(2*(12+1)) = 88196Hz */
 -              break;
 -      case 96000:
 -              cmr_div = 23;   /* BCLK = 133MHz/(2*23) = 2.891MHz */
 -              period = 14;    /* LRC = BCLK/(2*(14+1)) = 96376Hz */
 -              break;
 -      default:
 -              printk(KERN_WARNING "unsupported rate %d"
 -                              " on at91sam9g20ek board\n", rate);
 -              return -EINVAL;
 -      }
 -
 -      /* set the MCK divider for BCLK */
 -      ret = snd_soc_dai_set_clkdiv(cpu_dai, ATMEL_SSC_CMR_DIV, cmr_div);
 -      if (ret < 0)
 -              return ret;
 -
 -      if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 -              /* set the BCLK divider for DACLRC */
 -              ret = snd_soc_dai_set_clkdiv(cpu_dai,
 -                                              ATMEL_SSC_TCMR_PERIOD, period);
 -      } else {
 -              /* set the BCLK divider for ADCLRC */
 -              ret = snd_soc_dai_set_clkdiv(cpu_dai,
 -                                              ATMEL_SSC_RCMR_PERIOD, period);
 -      }
 +              SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
        if (ret < 0)
                return ret;
  
  }
  
  static struct snd_soc_ops at91sam9g20ek_ops = {
 -      .startup = at91sam9g20ek_startup,
        .hw_params = at91sam9g20ek_hw_params,
 -      .shutdown = at91sam9g20ek_shutdown,
  };
  
  static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card,
@@@ -138,20 -241,10 +138,20 @@@ static const struct snd_soc_dapm_route 
   */
  static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
  {
 +      struct snd_soc_dai *codec_dai = &codec->dai[0];
 +      int ret;
 +
        printk(KERN_DEBUG
                        "at91sam9g20ek_wm8731 "
                        ": at91sam9g20ek_wm8731_init() called\n");
  
 +      ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
 +              MCLK_RATE, SND_SOC_CLOCK_IN);
 +      if (ret < 0) {
 +              printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret);
 +              return ret;
 +      }
 +
        /* Add specific widgets */
        snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
                                  ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
        snd_soc_dapm_nc_pin(codec, "RLINEIN");
        snd_soc_dapm_nc_pin(codec, "LLINEIN");
  
 -      /* always connected */
 +#ifdef ENABLE_MIC_INPUT
        snd_soc_dapm_enable_pin(codec, "Int Mic");
 +#else
 +      snd_soc_dapm_nc_pin(codec, "Int Mic");
 +#endif
 +
 +      /* always connected */
        snd_soc_dapm_enable_pin(codec, "Ext Spk");
  
        snd_soc_dapm_sync(codec);
@@@ -193,38 -281,6 +193,6 @@@ static struct snd_soc_card snd_soc_at91
        .set_bias_level = at91sam9g20ek_set_bias_level,
  };
  
- /*
-  * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
-  * New drivers should register the wm8731 I2C device in the machine
-  * setup code (under arch/arm for ARM systems).
-  */
- static int wm8731_i2c_register(void)
- {
-       struct i2c_board_info info;
-       struct i2c_adapter *adapter;
-       struct i2c_client *client;
-       memset(&info, 0, sizeof(struct i2c_board_info));
-       info.addr = 0x1b;
-       strlcpy(info.type, "wm8731", I2C_NAME_SIZE);
-       adapter = i2c_get_adapter(0);
-       if (!adapter) {
-               printk(KERN_ERR "can't get i2c adapter 0\n");
-               return -ENODEV;
-       }
-       client = i2c_new_device(adapter, &info);
-       i2c_put_adapter(adapter);
-       if (!client) {
-               printk(KERN_ERR "can't add i2c device at 0x%x\n",
-                       (unsigned int)info.addr);
-               return -ENODEV;
-       }
-       return 0;
- }
  static struct snd_soc_device at91sam9g20ek_snd_devdata = {
        .card = &snd_soc_at91sam9g20ek,
        .codec_dev = &soc_codec_dev_wm8731,
@@@ -279,10 -335,6 +247,6 @@@ static int __init at91sam9g20ek_init(vo
        }
        ssc_p->ssc = ssc;
  
-       ret = wm8731_i2c_register();
-       if (ret != 0)
-               goto err_ssc;
        at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
        if (!at91sam9g20ek_snd_device) {
                printk(KERN_ERR "ASoC: Platform device allocation failed\n");