Explorar el Código

Merge commit 'v2.6.37' into perf/core

Merge reason: Add the final .37 tree.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Ingo Molnar hace 14 años
padre
commit
aef1b9cef7
Se han modificado 78 ficheros con 726 adiciones y 755 borrados
  1. 100 112
      Documentation/filesystems/Locking
  2. 1 1
      Documentation/kernel-parameters.txt
  3. 16 1
      MAINTAINERS
  4. 1 1
      Makefile
  5. 1 0
      arch/arm/include/asm/hardware/it8152.h
  6. 0 3
      arch/arm/include/asm/highmem.h
  7. 3 3
      arch/arm/include/asm/sizes.h
  8. 1 0
      arch/arm/include/asm/system.h
  9. 6 0
      arch/arm/kernel/entry-common.S
  10. 0 1
      arch/arm/kernel/smp.c
  11. 1 0
      arch/arm/mach-pxa/Kconfig
  12. 2 2
      arch/arm/mach-pxa/sleep.S
  13. 19 18
      arch/arm/mm/cache-feroceon-l2.c
  14. 21 36
      arch/arm/mm/cache-xsc3l2.c
  15. 4 3
      arch/arm/mm/dma-mapping.c
  16. 4 3
      arch/arm/mm/flush.c
  17. 0 87
      arch/arm/mm/highmem.c
  18. 1 1
      arch/mn10300/kernel/irq.c
  19. 2 0
      arch/x86/kvm/i8259.c
  20. 2 1
      arch/x86/kvm/mmu.c
  21. 16 8
      arch/x86/oprofile/op_model_amd.c
  22. 4 1
      drivers/atm/atmtcp.c
  23. 1 1
      drivers/dma/mv_xor.c
  24. 1 1
      drivers/gpu/drm/i915/dvo_ch7017.c
  25. 23 0
      drivers/gpu/drm/i915/i915_dma.c
  26. 10 0
      drivers/gpu/drm/i915/i915_reg.h
  27. 1 1
      drivers/gpu/drm/i915/intel_bios.c
  28. 20 1
      drivers/gpu/drm/i915/intel_display.c
  29. 2 1
      drivers/gpu/drm/i915/intel_sdvo.c
  30. 0 2
      drivers/hwmon/s3c-hwmon.c
  31. 1 0
      drivers/isdn/gigaset/capi.c
  32. 17 2
      drivers/media/video/cx25840/cx25840-core.c
  33. 12 87
      drivers/media/video/cx88/cx88-alsa.c
  34. 7 0
      drivers/media/video/cx88/cx88-cards.c
  35. 1 26
      drivers/media/video/cx88/cx88-video.c
  36. 2 4
      drivers/media/video/cx88/cx88.h
  37. 1 1
      drivers/media/video/em28xx/em28xx-video.c
  38. 39 65
      drivers/media/video/wm8775.c
  39. 10 0
      drivers/net/atlx/atl1.c
  40. 8 2
      drivers/net/cnic.c
  41. 7 0
      drivers/net/ehea/ehea_ethtool.c
  42. 7 2
      drivers/net/ppp_generic.c
  43. 1 1
      drivers/net/skfp/skfddi.c
  44. 1 1
      drivers/net/starfire.c
  45. 1 1
      drivers/net/tg3.c
  46. 33 3
      drivers/platform/x86/intel_ips.c
  47. 21 0
      drivers/platform/x86/intel_ips.h
  48. 1 1
      drivers/spi/coldfire_qspi.c
  49. 39 0
      drivers/spi/omap2_mcspi.c
  50. 0 6
      drivers/staging/zram/zram_drv.c
  51. 19 3
      drivers/usb/atm/ueagle-atm.c
  52. 10 3
      include/linux/dmaengine.h
  53. 0 3
      include/media/wm8775.h
  54. 1 1
      init/do_mounts.c
  55. 1 0
      kernel/user.c
  56. 2 1
      kernel/watchdog.c
  57. 9 10
      mm/memcontrol.c
  58. 18 10
      net/bridge/br_multicast.c
  59. 2 0
      net/bridge/br_stp_bpdu.c
  60. 2 2
      net/can/bcm.c
  61. 6 2
      net/ipv4/route.c
  62. 14 0
      scripts/kconfig/menu.c
  63. 2 0
      security/integrity/ima/ima_policy.c
  64. 2 2
      sound/oss/soundcard.c
  65. 1 0
      sound/pci/hda/hda_intel.c
  66. 4 6
      sound/soc/codecs/max98088.c
  67. 5 4
      sound/soc/codecs/wm8523.c
  68. 5 5
      sound/soc/codecs/wm8741.c
  69. 83 143
      sound/soc/codecs/wm8753.c
  70. 18 19
      sound/soc/codecs/wm8904.c
  71. 1 0
      sound/soc/codecs/wm8940.c
  72. 16 15
      sound/soc/codecs/wm8955.c
  73. 1 0
      sound/soc/codecs/wm8960.c
  74. 20 25
      sound/soc/codecs/wm8962.c
  75. 1 0
      sound/soc/codecs/wm8971.c
  76. 1 0
      sound/soc/codecs/wm9081.c
  77. 9 9
      sound/soc/codecs/wm9090.c
  78. 1 1
      tools/perf/util/hist.c

+ 100 - 112
Documentation/filesystems/Locking

@@ -18,7 +18,6 @@ prototypes:
 	char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
 	char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen);
 
 
 locking rules:
 locking rules:
-	none have BKL
 		dcache_lock	rename_lock	->d_lock	may block
 		dcache_lock	rename_lock	->d_lock	may block
 d_revalidate:	no		no		no		yes
 d_revalidate:	no		no		no		yes
 d_hash		no		no		no		yes
 d_hash		no		no		no		yes
@@ -42,18 +41,23 @@ ata *);
 	int (*rename) (struct inode *, struct dentry *,
 	int (*rename) (struct inode *, struct dentry *,
 			struct inode *, struct dentry *);
 			struct inode *, struct dentry *);
 	int (*readlink) (struct dentry *, char __user *,int);
 	int (*readlink) (struct dentry *, char __user *,int);
-	int (*follow_link) (struct dentry *, struct nameidata *);
+	void * (*follow_link) (struct dentry *, struct nameidata *);
+	void (*put_link) (struct dentry *, struct nameidata *, void *);
 	void (*truncate) (struct inode *);
 	void (*truncate) (struct inode *);
 	int (*permission) (struct inode *, int, struct nameidata *);
 	int (*permission) (struct inode *, int, struct nameidata *);
+	int (*check_acl)(struct inode *, int);
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*setattr) (struct dentry *, struct iattr *);
 	int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
 	int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
 	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
 	int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
 	ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
 	ssize_t (*listxattr) (struct dentry *, char *, size_t);
 	int (*removexattr) (struct dentry *, const char *);
 	int (*removexattr) (struct dentry *, const char *);
+	void (*truncate_range)(struct inode *, loff_t, loff_t);
+	long (*fallocate)(struct inode *inode, int mode, loff_t offset, loff_t len);
+	int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
 
 
 locking rules:
 locking rules:
-	all may block, none have BKL
+	all may block
 		i_mutex(inode)
 		i_mutex(inode)
 lookup:		yes
 lookup:		yes
 create:		yes
 create:		yes
@@ -66,19 +70,24 @@ rmdir:		yes (both)	(see below)
 rename:		yes (all)	(see below)
 rename:		yes (all)	(see below)
 readlink:	no
 readlink:	no
 follow_link:	no
 follow_link:	no
+put_link:	no
 truncate:	yes		(see below)
 truncate:	yes		(see below)
 setattr:	yes
 setattr:	yes
 permission:	no
 permission:	no
+check_acl:	no
 getattr:	no
 getattr:	no
 setxattr:	yes
 setxattr:	yes
 getxattr:	no
 getxattr:	no
 listxattr:	no
 listxattr:	no
 removexattr:	yes
 removexattr:	yes
+truncate_range:	yes
+fallocate:	no
+fiemap:		no
 	Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
 	Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
 victim.
 victim.
 	cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
 	cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
 	->truncate() is never called directly - it's a callback, not a
 	->truncate() is never called directly - it's a callback, not a
-method. It's called by vmtruncate() - library function normally used by
+method. It's called by vmtruncate() - deprecated library function used by
 ->setattr(). Locking information above applies to that call (i.e. is
 ->setattr(). Locking information above applies to that call (i.e. is
 inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been
 inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been
 passed).
 passed).
@@ -91,7 +100,7 @@ prototypes:
 	struct inode *(*alloc_inode)(struct super_block *sb);
 	struct inode *(*alloc_inode)(struct super_block *sb);
 	void (*destroy_inode)(struct inode *);
 	void (*destroy_inode)(struct inode *);
 	void (*dirty_inode) (struct inode *);
 	void (*dirty_inode) (struct inode *);
-	int (*write_inode) (struct inode *, int);
+	int (*write_inode) (struct inode *, struct writeback_control *wbc);
 	int (*drop_inode) (struct inode *);
 	int (*drop_inode) (struct inode *);
 	void (*evict_inode) (struct inode *);
 	void (*evict_inode) (struct inode *);
 	void (*put_super) (struct super_block *);
 	void (*put_super) (struct super_block *);
@@ -105,10 +114,10 @@ prototypes:
 	int (*show_options)(struct seq_file *, struct vfsmount *);
 	int (*show_options)(struct seq_file *, struct vfsmount *);
 	ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
 	ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
 	ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
 	ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
+	int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
 
 
 locking rules:
 locking rules:
 	All may block [not true, see below]
 	All may block [not true, see below]
-	None have BKL
 			s_umount
 			s_umount
 alloc_inode:
 alloc_inode:
 destroy_inode:
 destroy_inode:
@@ -127,6 +136,7 @@ umount_begin:		no
 show_options:		no		(namespace_sem)
 show_options:		no		(namespace_sem)
 quota_read:		no		(see below)
 quota_read:		no		(see below)
 quota_write:		no		(see below)
 quota_write:		no		(see below)
+bdev_try_to_free_page:	no		(see below)
 
 
 ->statfs() has s_umount (shared) when called by ustat(2) (native or
 ->statfs() has s_umount (shared) when called by ustat(2) (native or
 compat), but that's an accident of bad API; s_umount is used to pin
 compat), but that's an accident of bad API; s_umount is used to pin
@@ -139,19 +149,25 @@ be the only ones operating on the quota file by the quota code (via
 dqio_sem) (unless an admin really wants to screw up something and
 dqio_sem) (unless an admin really wants to screw up something and
 writes to quota files with quotas on). For other details about locking
 writes to quota files with quotas on). For other details about locking
 see also dquot_operations section.
 see also dquot_operations section.
+->bdev_try_to_free_page is called from the ->releasepage handler of
+the block device inode.  See there for more details.
 
 
 --------------------------- file_system_type ---------------------------
 --------------------------- file_system_type ---------------------------
 prototypes:
 prototypes:
 	int (*get_sb) (struct file_system_type *, int,
 	int (*get_sb) (struct file_system_type *, int,
 		       const char *, void *, struct vfsmount *);
 		       const char *, void *, struct vfsmount *);
+	struct dentry *(*mount) (struct file_system_type *, int,
+		       const char *, void *);
 	void (*kill_sb) (struct super_block *);
 	void (*kill_sb) (struct super_block *);
 locking rules:
 locking rules:
-		may block	BKL
-get_sb		yes		no
-kill_sb		yes		no
+		may block
+get_sb		yes
+mount		yes
+kill_sb		yes
 
 
 ->get_sb() returns error or 0 with locked superblock attached to the vfsmount
 ->get_sb() returns error or 0 with locked superblock attached to the vfsmount
 (exclusive on ->s_umount).
 (exclusive on ->s_umount).
+->mount() returns ERR_PTR or the root dentry.
 ->kill_sb() takes a write-locked superblock, does all shutdown work on it,
 ->kill_sb() takes a write-locked superblock, does all shutdown work on it,
 unlocks and drops the reference.
 unlocks and drops the reference.
 
 
@@ -176,27 +192,35 @@ prototypes:
 	void (*freepage)(struct page *);
 	void (*freepage)(struct page *);
 	int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
 	int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
 			loff_t offset, unsigned long nr_segs);
 			loff_t offset, unsigned long nr_segs);
-	int (*launder_page) (struct page *);
+	int (*get_xip_mem)(struct address_space *, pgoff_t, int, void **,
+				unsigned long *);
+	int (*migratepage)(struct address_space *, struct page *, struct page *);
+	int (*launder_page)(struct page *);
+	int (*is_partially_uptodate)(struct page *, read_descriptor_t *, unsigned long);
+	int (*error_remove_page)(struct address_space *, struct page *);
 
 
 locking rules:
 locking rules:
 	All except set_page_dirty and freepage may block
 	All except set_page_dirty and freepage may block
 
 
-			BKL	PageLocked(page)	i_mutex
-writepage:		no	yes, unlocks (see below)
-readpage:		no	yes, unlocks
-sync_page:		no	maybe
-writepages:		no
-set_page_dirty		no	no
-readpages:		no
-write_begin:		no	locks the page		yes
-write_end:		no	yes, unlocks		yes
-perform_write:		no	n/a			yes
-bmap:			no
-invalidatepage:		no	yes
-releasepage:		no	yes
-freepage:		no	yes
-direct_IO:		no
-launder_page:		no	yes
+			PageLocked(page)	i_mutex
+writepage:		yes, unlocks (see below)
+readpage:		yes, unlocks
+sync_page:		maybe
+writepages:
+set_page_dirty		no
+readpages:
+write_begin:		locks the page		yes
+write_end:		yes, unlocks		yes
+bmap:
+invalidatepage:		yes
+releasepage:		yes
+freepage:		yes
+direct_IO:
+get_xip_mem:					maybe
+migratepage:		yes (both)
+launder_page:		yes
+is_partially_uptodate:	yes
+error_remove_page:	yes
 
 
 	->write_begin(), ->write_end(), ->sync_page() and ->readpage()
 	->write_begin(), ->write_end(), ->sync_page() and ->readpage()
 may be called from the request handler (/dev/loop).
 may be called from the request handler (/dev/loop).
@@ -276,9 +300,8 @@ under spinlock (it cannot block) and is sometimes called with the page
 not locked.
 not locked.
 
 
 	->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some
 	->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some
-filesystems and by the swapper. The latter will eventually go away. All
-instances do not actually need the BKL. Please, keep it that way and don't
-breed new callers.
+filesystems and by the swapper. The latter will eventually go away.  Please,
+keep it that way and don't breed new callers.
 
 
 	->invalidatepage() is called when the filesystem must attempt to drop
 	->invalidatepage() is called when the filesystem must attempt to drop
 some or all of the buffers from the page when it is being truncated.  It
 some or all of the buffers from the page when it is being truncated.  It
@@ -299,47 +322,37 @@ cleaned, or an error value if not. Note that in order to prevent the page
 getting mapped back in and redirtied, it needs to be kept locked
 getting mapped back in and redirtied, it needs to be kept locked
 across the entire operation.
 across the entire operation.
 
 
-	Note: currently almost all instances of address_space methods are
-using BKL for internal serialization and that's one of the worst sources
-of contention. Normally they are calling library functions (in fs/buffer.c)
-and pass foo_get_block() as a callback (on local block-based filesystems,
-indeed). BKL is not needed for library stuff and is usually taken by
-foo_get_block(). It's an overkill, since block bitmaps can be protected by
-internal fs locking and real critical areas are much smaller than the areas
-filesystems protect now.
-
 ----------------------- file_lock_operations ------------------------------
 ----------------------- file_lock_operations ------------------------------
 prototypes:
 prototypes:
-	void (*fl_insert)(struct file_lock *);	/* lock insertion callback */
-	void (*fl_remove)(struct file_lock *);	/* lock removal callback */
 	void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
 	void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
 	void (*fl_release_private)(struct file_lock *);
 	void (*fl_release_private)(struct file_lock *);
 
 
 
 
 locking rules:
 locking rules:
-			BKL	may block
-fl_insert:		yes	no
-fl_remove:		yes	no
-fl_copy_lock:		yes	no
-fl_release_private:	yes	yes
+			file_lock_lock	may block
+fl_copy_lock:		yes		no
+fl_release_private:	maybe		no
 
 
 ----------------------- lock_manager_operations ---------------------------
 ----------------------- lock_manager_operations ---------------------------
 prototypes:
 prototypes:
 	int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
 	int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
 	void (*fl_notify)(struct file_lock *);  /* unblock callback */
 	void (*fl_notify)(struct file_lock *);  /* unblock callback */
+	int (*fl_grant)(struct file_lock *, struct file_lock *, int);
 	void (*fl_release_private)(struct file_lock *);
 	void (*fl_release_private)(struct file_lock *);
 	void (*fl_break)(struct file_lock *); /* break_lease callback */
 	void (*fl_break)(struct file_lock *); /* break_lease callback */
+	int (*fl_mylease)(struct file_lock *, struct file_lock *);
+	int (*fl_change)(struct file_lock **, int);
 
 
 locking rules:
 locking rules:
-			BKL	may block
-fl_compare_owner:	yes	no
-fl_notify:		yes	no
-fl_release_private:	yes	yes
-fl_break:		yes	no
-
-	Currently only NFSD and NLM provide instances of this class. None of the
-them block. If you have out-of-tree instances - please, show up. Locking
-in that area will change.
+			file_lock_lock	may block
+fl_compare_owner:	yes		no
+fl_notify:		yes		no
+fl_grant:		no		no
+fl_release_private:	maybe		no
+fl_break:		yes		no
+fl_mylease:		yes		no
+fl_change		yes		no
+
 --------------------------- buffer_head -----------------------------------
 --------------------------- buffer_head -----------------------------------
 prototypes:
 prototypes:
 	void (*b_end_io)(struct buffer_head *bh, int uptodate);
 	void (*b_end_io)(struct buffer_head *bh, int uptodate);
@@ -364,17 +377,17 @@ prototypes:
 	void (*swap_slot_free_notify) (struct block_device *, unsigned long);
 	void (*swap_slot_free_notify) (struct block_device *, unsigned long);
 
 
 locking rules:
 locking rules:
-			BKL	bd_mutex
-open:			no	yes
-release:		no	yes
-ioctl:			no	no
-compat_ioctl:		no	no
-direct_access:		no	no
-media_changed:		no	no
-unlock_native_capacity:	no	no
-revalidate_disk:	no	no
-getgeo:			no	no
-swap_slot_free_notify:	no	no	(see below)
+			bd_mutex
+open:			yes
+release:		yes
+ioctl:			no
+compat_ioctl:		no
+direct_access:		no
+media_changed:		no
+unlock_native_capacity:	no
+revalidate_disk:	no
+getgeo:			no
+swap_slot_free_notify:	no	(see below)
 
 
 media_changed, unlock_native_capacity and revalidate_disk are called only from
 media_changed, unlock_native_capacity and revalidate_disk are called only from
 check_disk_change().
 check_disk_change().
@@ -413,34 +426,21 @@ prototypes:
 	unsigned long (*get_unmapped_area)(struct file *, unsigned long,
 	unsigned long (*get_unmapped_area)(struct file *, unsigned long,
 			unsigned long, unsigned long, unsigned long);
 			unsigned long, unsigned long, unsigned long);
 	int (*check_flags)(int);
 	int (*check_flags)(int);
+	int (*flock) (struct file *, int, struct file_lock *);
+	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *,
+			size_t, unsigned int);
+	ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *,
+			size_t, unsigned int);
+	int (*setlease)(struct file *, long, struct file_lock **);
 };
 };
 
 
 locking rules:
 locking rules:
-	All may block.
-			BKL
-llseek:			no	(see below)
-read:			no
-aio_read:		no
-write:			no
-aio_write:		no
-readdir: 		no
-poll:			no
-unlocked_ioctl:		no
-compat_ioctl:		no
-mmap:			no
-open:			no
-flush:			no
-release:		no
-fsync:			no	(see below)
-aio_fsync:		no
-fasync:			no
-lock:			yes
-readv:			no
-writev:			no
-sendfile:		no
-sendpage:		no
-get_unmapped_area:	no
-check_flags:		no
+	All may block except for ->setlease.
+	No VFS locks held on entry except for ->fsync and ->setlease.
+
+->fsync() has i_mutex on inode.
+
+->setlease has the file_list_lock held and must not sleep.
 
 
 ->llseek() locking has moved from llseek to the individual llseek
 ->llseek() locking has moved from llseek to the individual llseek
 implementations.  If your fs is not using generic_file_llseek, you
 implementations.  If your fs is not using generic_file_llseek, you
@@ -450,17 +450,10 @@ mutex or just to use i_size_read() instead.
 Note: this does not protect the file->f_pos against concurrent modifications
 Note: this does not protect the file->f_pos against concurrent modifications
 since this is something the userspace has to take care about.
 since this is something the userspace has to take care about.
 
 
-Note: ext2_release() was *the* source of contention on fs-intensive
-loads and dropping BKL on ->release() helps to get rid of that (we still
-grab BKL for cases when we close a file that had been opened r/w, but that
-can and should be done using the internal locking with smaller critical areas).
-Current worst offender is ext2_get_block()...
-
-->fasync() is called without BKL protection, and is responsible for
-maintaining the FASYNC bit in filp->f_flags.  Most instances call
-fasync_helper(), which does that maintenance, so it's not normally
-something one needs to worry about.  Return values > 0 will be mapped to
-zero in the VFS layer.
+->fasync() is responsible for maintaining the FASYNC bit in filp->f_flags.
+Most instances call fasync_helper(), which does that maintenance, so it's
+not normally something one needs to worry about.  Return values > 0 will be
+mapped to zero in the VFS layer.
 
 
 ->readdir() and ->ioctl() on directories must be changed. Ideally we would
 ->readdir() and ->ioctl() on directories must be changed. Ideally we would
 move ->readdir() to inode_operations and use a separate method for directory
 move ->readdir() to inode_operations and use a separate method for directory
@@ -471,8 +464,6 @@ components. And there are other reasons why the current interface is a mess...
 ->read on directories probably must go away - we should just enforce -EISDIR
 ->read on directories probably must go away - we should just enforce -EISDIR
 in sys_read() and friends.
 in sys_read() and friends.
 
 
-->fsync() has i_mutex on inode.
-
 --------------------------- dquot_operations -------------------------------
 --------------------------- dquot_operations -------------------------------
 prototypes:
 prototypes:
 	int (*write_dquot) (struct dquot *);
 	int (*write_dquot) (struct dquot *);
@@ -507,12 +498,12 @@ prototypes:
 	int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
 	int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
 
 
 locking rules:
 locking rules:
-		BKL	mmap_sem	PageLocked(page)
-open:		no	yes
-close:		no	yes
-fault:		no	yes		can return with page locked
-page_mkwrite:	no	yes		can return with page locked
-access:		no	yes
+		mmap_sem	PageLocked(page)
+open:		yes
+close:		yes
+fault:		yes		can return with page locked
+page_mkwrite:	yes		can return with page locked
+access:		yes
 
 
 	->fault() is called when a previously not present pte is about
 	->fault() is called when a previously not present pte is about
 to be faulted in. The filesystem must find and return the page associated
 to be faulted in. The filesystem must find and return the page associated
@@ -539,6 +530,3 @@ VM_IO | VM_PFNMAP VMAs.
 
 
 (if you break something or notice that it is broken and do not fix it yourself
 (if you break something or notice that it is broken and do not fix it yourself
 - at least put it here)
 - at least put it here)
-
-ipc/shm.c::shm_delete() - may need BKL.
-->read() and ->write() in many drivers are (probably) missing BKL.

+ 1 - 1
Documentation/kernel-parameters.txt

@@ -1751,7 +1751,7 @@ and is between 256 and 4096 characters. It is defined in the file
 
 
 	nousb		[USB] Disable the USB subsystem
 	nousb		[USB] Disable the USB subsystem
 
 
-	nowatchdog	[KNL] Disable the lockup detector.
+	nowatchdog	[KNL] Disable the lockup detector (NMI watchdog).
 
 
 	nowb		[ARM]
 	nowb		[ARM]
 
 

+ 16 - 1
MAINTAINERS

@@ -792,11 +792,14 @@ S:	Maintained
 
 
 ARM/NOMADIK ARCHITECTURE
 ARM/NOMADIK ARCHITECTURE
 M:	Alessandro Rubini <rubini@unipv.it>
 M:	Alessandro Rubini <rubini@unipv.it>
+M:	Linus Walleij <linus.walleij@stericsson.com>
 M:	STEricsson <STEricsson_nomadik_linux@list.st.com>
 M:	STEricsson <STEricsson_nomadik_linux@list.st.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 S:	Maintained
 F:	arch/arm/mach-nomadik/
 F:	arch/arm/mach-nomadik/
 F:	arch/arm/plat-nomadik/
 F:	arch/arm/plat-nomadik/
+F:	drivers/i2c/busses/i2c-nomadik.c
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
 
 
 ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
 ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
 M:	Nelson Castillo <arhuaco@freaks-unidos.net>
 M:	Nelson Castillo <arhuaco@freaks-unidos.net>
@@ -998,12 +1001,24 @@ F:	drivers/i2c/busses/i2c-stu300.c
 F:	drivers/rtc/rtc-coh901331.c
 F:	drivers/rtc/rtc-coh901331.c
 F:	drivers/watchdog/coh901327_wdt.c
 F:	drivers/watchdog/coh901327_wdt.c
 F:	drivers/dma/coh901318*
 F:	drivers/dma/coh901318*
+F:	drivers/mfd/ab3100*
+F:	drivers/rtc/rtc-ab3100.c
+F:	drivers/rtc/rtc-coh901331.c
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
 
 
-ARM/U8500 ARM ARCHITECTURE
+ARM/Ux500 ARM ARCHITECTURE
 M:	Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
 M:	Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+M:	Linus Walleij <linus.walleij@stericsson.com>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 S:	Maintained
 F:	arch/arm/mach-ux500/
 F:	arch/arm/mach-ux500/
+F:	drivers/dma/ste_dma40*
+F:	drivers/mfd/ab3550*
+F:	drivers/mfd/abx500*
+F:	drivers/mfd/ab8500*
+F:	drivers/mfd/stmpe*
+F:	drivers/rtc/rtc-ab8500.c
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git
 
 
 ARM/VFP SUPPORT
 ARM/VFP SUPPORT
 M:	Russell King <linux@arm.linux.org.uk>
 M:	Russell King <linux@arm.linux.org.uk>

+ 1 - 1
Makefile

@@ -1,7 +1,7 @@
 VERSION = 2
 VERSION = 2
 PATCHLEVEL = 6
 PATCHLEVEL = 6
 SUBLEVEL = 37
 SUBLEVEL = 37
-EXTRAVERSION = -rc8
+EXTRAVERSION =
 NAME = Flesh-Eating Bats with Fangs
 NAME = Flesh-Eating Bats with Fangs
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*

+ 1 - 0
arch/arm/include/asm/hardware/it8152.h

@@ -76,6 +76,7 @@ extern unsigned long it8152_base_address;
   IT8152_PD_IRQ(0)  Audio controller (ACR)
   IT8152_PD_IRQ(0)  Audio controller (ACR)
  */
  */
 #define IT8152_IRQ(x)   (IRQ_BOARD_START + (x))
 #define IT8152_IRQ(x)   (IRQ_BOARD_START + (x))
+#define IT8152_LAST_IRQ	(IRQ_BOARD_START + 40)
 
 
 /* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
 /* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */
 #define IT8152_LD_IRQ_COUNT     9
 #define IT8152_LD_IRQ_COUNT     9

+ 0 - 3
arch/arm/include/asm/highmem.h

@@ -25,9 +25,6 @@ extern void *kmap_high(struct page *page);
 extern void *kmap_high_get(struct page *page);
 extern void *kmap_high_get(struct page *page);
 extern void kunmap_high(struct page *page);
 extern void kunmap_high(struct page *page);
 
 
-extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte);
-extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
-
 /*
 /*
  * The following functions are already defined by <linux/highmem.h>
  * The following functions are already defined by <linux/highmem.h>
  * when CONFIG_HIGHMEM is not set.
  * when CONFIG_HIGHMEM is not set.

+ 3 - 3
arch/arm/include/asm/sizes.h

@@ -13,9 +13,6 @@
  * along with this program; if not, write to the Free Software
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
-/* DO NOT EDIT!! - this file automatically generated
- *                 from .s file by awk -f s2h.awk
- */
 /*  Size definitions
 /*  Size definitions
  *  Copyright (C) ARM Limited 1998. All rights reserved.
  *  Copyright (C) ARM Limited 1998. All rights reserved.
  */
  */
@@ -25,6 +22,9 @@
 
 
 /* handy sizes */
 /* handy sizes */
 #define SZ_16				0x00000010
 #define SZ_16				0x00000010
+#define SZ_32				0x00000020
+#define SZ_64				0x00000040
+#define SZ_128				0x00000080
 #define SZ_256				0x00000100
 #define SZ_256				0x00000100
 #define SZ_512				0x00000200
 #define SZ_512				0x00000200
 
 

+ 1 - 0
arch/arm/include/asm/system.h

@@ -150,6 +150,7 @@ extern unsigned int user_debug;
 #define rmb()		dmb()
 #define rmb()		dmb()
 #define wmb()		mb()
 #define wmb()		mb()
 #else
 #else
+#include <asm/memory.h>
 #define mb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define mb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define rmb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define rmb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define wmb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define wmb()	do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)

+ 6 - 0
arch/arm/kernel/entry-common.S

@@ -29,6 +29,9 @@ ret_fast_syscall:
 	ldr	r1, [tsk, #TI_FLAGS]
 	ldr	r1, [tsk, #TI_FLAGS]
 	tst	r1, #_TIF_WORK_MASK
 	tst	r1, #_TIF_WORK_MASK
 	bne	fast_work_pending
 	bne	fast_work_pending
+#if defined(CONFIG_IRQSOFF_TRACER)
+	asm_trace_hardirqs_on
+#endif
 
 
 	/* perform architecture specific actions before user return */
 	/* perform architecture specific actions before user return */
 	arch_ret_to_user r1, lr
 	arch_ret_to_user r1, lr
@@ -65,6 +68,9 @@ ret_slow_syscall:
 	tst	r1, #_TIF_WORK_MASK
 	tst	r1, #_TIF_WORK_MASK
 	bne	work_pending
 	bne	work_pending
 no_work_pending:
 no_work_pending:
+#if defined(CONFIG_IRQSOFF_TRACER)
+	asm_trace_hardirqs_on
+#endif
 	/* perform architecture specific actions before user return */
 	/* perform architecture specific actions before user return */
 	arch_ret_to_user r1, lr
 	arch_ret_to_user r1, lr
 
 

+ 0 - 1
arch/arm/kernel/smp.c

@@ -310,7 +310,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
 	 * All kernel threads share the same mm context; grab a
 	 * All kernel threads share the same mm context; grab a
 	 * reference and switch to it.
 	 * reference and switch to it.
 	 */
 	 */
-	atomic_inc(&mm->mm_users);
 	atomic_inc(&mm->mm_count);
 	atomic_inc(&mm->mm_count);
 	current->active_mm = mm;
 	current->active_mm = mm;
 	cpumask_set_cpu(cpu, mm_cpumask(mm));
 	cpumask_set_cpu(cpu, mm_cpumask(mm));

+ 1 - 0
arch/arm/mach-pxa/Kconfig

@@ -540,6 +540,7 @@ config MACH_ICONTROL
 config ARCH_PXA_ESERIES
 config ARCH_PXA_ESERIES
 	bool "PXA based Toshiba e-series PDAs"
 	bool "PXA based Toshiba e-series PDAs"
 	select PXA25x
 	select PXA25x
+	select FB_W100
 
 
 config MACH_E330
 config MACH_E330
 	bool "Toshiba e330"
 	bool "Toshiba e330"

+ 2 - 2
arch/arm/mach-pxa/sleep.S

@@ -353,8 +353,8 @@ resume_turn_on_mmu:
 
 
 	@ Let us ensure we jump to resume_after_mmu only when the mcr above
 	@ Let us ensure we jump to resume_after_mmu only when the mcr above
 	@ actually took effect.  They call it the "cpwait" operation.
 	@ actually took effect.  They call it the "cpwait" operation.
-	mrc	p15, 0, r1, c2, c0, 0		@ queue a dependency on CP15
-	sub	pc, r2, r1, lsr #32		@ jump to virtual addr
+	mrc	p15, 0, r0, c2, c0, 0		@ queue a dependency on CP15
+	sub	pc, r2, r0, lsr #32		@ jump to virtual addr
 	nop
 	nop
 	nop
 	nop
 	nop
 	nop

+ 19 - 18
arch/arm/mm/cache-feroceon-l2.c

@@ -13,13 +13,9 @@
  */
  */
 
 
 #include <linux/init.h>
 #include <linux/init.h>
+#include <linux/highmem.h>
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
-#include <asm/kmap_types.h>
-#include <asm/fixmap.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
 #include <plat/cache-feroceon-l2.h>
 #include <plat/cache-feroceon-l2.h>
-#include "mm.h"
 
 
 /*
 /*
  * Low-level cache maintenance operations.
  * Low-level cache maintenance operations.
@@ -39,27 +35,30 @@
  * between which we don't want to be preempted.
  * between which we don't want to be preempted.
  */
  */
 
 
-static inline unsigned long l2_start_va(unsigned long paddr)
+static inline unsigned long l2_get_va(unsigned long paddr)
 {
 {
 #ifdef CONFIG_HIGHMEM
 #ifdef CONFIG_HIGHMEM
 	/*
 	/*
-	 * Let's do our own fixmap stuff in a minimal way here.
 	 * Because range ops can't be done on physical addresses,
 	 * Because range ops can't be done on physical addresses,
 	 * we simply install a virtual mapping for it only for the
 	 * we simply install a virtual mapping for it only for the
 	 * TLB lookup to occur, hence no need to flush the untouched
 	 * TLB lookup to occur, hence no need to flush the untouched
-	 * memory mapping.  This is protected with the disabling of
-	 * interrupts by the caller.
+	 * memory mapping afterwards (note: a cache flush may happen
+	 * in some circumstances depending on the path taken in kunmap_atomic).
 	 */
 	 */
-	unsigned long idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
-	unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-	set_pte_ext(TOP_PTE(vaddr), pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL), 0);
-	local_flush_tlb_kernel_page(vaddr);
-	return vaddr + (paddr & ~PAGE_MASK);
+	void *vaddr = kmap_atomic_pfn(paddr >> PAGE_SHIFT);
+	return (unsigned long)vaddr + (paddr & ~PAGE_MASK);
 #else
 #else
 	return __phys_to_virt(paddr);
 	return __phys_to_virt(paddr);
 #endif
 #endif
 }
 }
 
 
+static inline void l2_put_va(unsigned long vaddr)
+{
+#ifdef CONFIG_HIGHMEM
+	kunmap_atomic((void *)vaddr);
+#endif
+}
+
 static inline void l2_clean_pa(unsigned long addr)
 static inline void l2_clean_pa(unsigned long addr)
 {
 {
 	__asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr));
 	__asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr));
@@ -76,13 +75,14 @@ static inline void l2_clean_pa_range(unsigned long start, unsigned long end)
 	 */
 	 */
 	BUG_ON((start ^ end) >> PAGE_SHIFT);
 	BUG_ON((start ^ end) >> PAGE_SHIFT);
 
 
-	raw_local_irq_save(flags);
-	va_start = l2_start_va(start);
+	va_start = l2_get_va(start);
 	va_end = va_start + (end - start);
 	va_end = va_start + (end - start);
+	raw_local_irq_save(flags);
 	__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
 	__asm__("mcr p15, 1, %0, c15, c9, 4\n\t"
 		"mcr p15, 1, %1, c15, c9, 5"
 		"mcr p15, 1, %1, c15, c9, 5"
 		: : "r" (va_start), "r" (va_end));
 		: : "r" (va_start), "r" (va_end));
 	raw_local_irq_restore(flags);
 	raw_local_irq_restore(flags);
+	l2_put_va(va_start);
 }
 }
 
 
 static inline void l2_clean_inv_pa(unsigned long addr)
 static inline void l2_clean_inv_pa(unsigned long addr)
@@ -106,13 +106,14 @@ static inline void l2_inv_pa_range(unsigned long start, unsigned long end)
 	 */
 	 */
 	BUG_ON((start ^ end) >> PAGE_SHIFT);
 	BUG_ON((start ^ end) >> PAGE_SHIFT);
 
 
-	raw_local_irq_save(flags);
-	va_start = l2_start_va(start);
+	va_start = l2_get_va(start);
 	va_end = va_start + (end - start);
 	va_end = va_start + (end - start);
+	raw_local_irq_save(flags);
 	__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
 	__asm__("mcr p15, 1, %0, c15, c11, 4\n\t"
 		"mcr p15, 1, %1, c15, c11, 5"
 		"mcr p15, 1, %1, c15, c11, 5"
 		: : "r" (va_start), "r" (va_end));
 		: : "r" (va_start), "r" (va_end));
 	raw_local_irq_restore(flags);
 	raw_local_irq_restore(flags);
+	l2_put_va(va_start);
 }
 }
 
 
 static inline void l2_inv_all(void)
 static inline void l2_inv_all(void)

+ 21 - 36
arch/arm/mm/cache-xsc3l2.c

@@ -17,14 +17,10 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
  */
 #include <linux/init.h>
 #include <linux/init.h>
+#include <linux/highmem.h>
 #include <asm/system.h>
 #include <asm/system.h>
 #include <asm/cputype.h>
 #include <asm/cputype.h>
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
-#include <asm/kmap_types.h>
-#include <asm/fixmap.h>
-#include <asm/pgtable.h>
-#include <asm/tlbflush.h>
-#include "mm.h"
 
 
 #define CR_L2	(1 << 26)
 #define CR_L2	(1 << 26)
 
 
@@ -71,16 +67,15 @@ static inline void xsc3_l2_inv_all(void)
 	dsb();
 	dsb();
 }
 }
 
 
+static inline void l2_unmap_va(unsigned long va)
+{
 #ifdef CONFIG_HIGHMEM
 #ifdef CONFIG_HIGHMEM
-#define l2_map_save_flags(x)		raw_local_save_flags(x)
-#define l2_map_restore_flags(x)		raw_local_irq_restore(x)
-#else
-#define l2_map_save_flags(x)		((x) = 0)
-#define l2_map_restore_flags(x)		((void)(x))
+	if (va != -1)
+		kunmap_atomic((void *)va);
 #endif
 #endif
+}
 
 
-static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
-				      unsigned long flags)
+static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va)
 {
 {
 #ifdef CONFIG_HIGHMEM
 #ifdef CONFIG_HIGHMEM
 	unsigned long va = prev_va & PAGE_MASK;
 	unsigned long va = prev_va & PAGE_MASK;
@@ -89,17 +84,10 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
 		/*
 		/*
 		 * Switching to a new page.  Because cache ops are
 		 * Switching to a new page.  Because cache ops are
 		 * using virtual addresses only, we must put a mapping
 		 * using virtual addresses only, we must put a mapping
-		 * in place for it.  We also enable interrupts for a
-		 * short while and disable them again to protect this
-		 * mapping.
+		 * in place for it.
 		 */
 		 */
-		unsigned long idx;
-		raw_local_irq_restore(flags);
-		idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id();
-		va = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-		raw_local_irq_restore(flags | PSR_I_BIT);
-		set_pte_ext(TOP_PTE(va), pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL), 0);
-		local_flush_tlb_kernel_page(va);
+		l2_unmap_va(prev_va);
+		va = (unsigned long)kmap_atomic_pfn(pa >> PAGE_SHIFT);
 	}
 	}
 	return va + (pa_offset >> (32 - PAGE_SHIFT));
 	return va + (pa_offset >> (32 - PAGE_SHIFT));
 #else
 #else
@@ -109,7 +97,7 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va,
 
 
 static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
 static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
 {
 {
-	unsigned long vaddr, flags;
+	unsigned long vaddr;
 
 
 	if (start == 0 && end == -1ul) {
 	if (start == 0 && end == -1ul) {
 		xsc3_l2_inv_all();
 		xsc3_l2_inv_all();
@@ -117,13 +105,12 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
 	}
 	}
 
 
 	vaddr = -1;  /* to force the first mapping */
 	vaddr = -1;  /* to force the first mapping */
-	l2_map_save_flags(flags);
 
 
 	/*
 	/*
 	 * Clean and invalidate partial first cache line.
 	 * Clean and invalidate partial first cache line.
 	 */
 	 */
 	if (start & (CACHE_LINE_SIZE - 1)) {
 	if (start & (CACHE_LINE_SIZE - 1)) {
-		vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr, flags);
+		vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr);
 		xsc3_l2_clean_mva(vaddr);
 		xsc3_l2_clean_mva(vaddr);
 		xsc3_l2_inv_mva(vaddr);
 		xsc3_l2_inv_mva(vaddr);
 		start = (start | (CACHE_LINE_SIZE - 1)) + 1;
 		start = (start | (CACHE_LINE_SIZE - 1)) + 1;
@@ -133,7 +120,7 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
 	 * Invalidate all full cache lines between 'start' and 'end'.
 	 * Invalidate all full cache lines between 'start' and 'end'.
 	 */
 	 */
 	while (start < (end & ~(CACHE_LINE_SIZE - 1))) {
 	while (start < (end & ~(CACHE_LINE_SIZE - 1))) {
-		vaddr = l2_map_va(start, vaddr, flags);
+		vaddr = l2_map_va(start, vaddr);
 		xsc3_l2_inv_mva(vaddr);
 		xsc3_l2_inv_mva(vaddr);
 		start += CACHE_LINE_SIZE;
 		start += CACHE_LINE_SIZE;
 	}
 	}
@@ -142,31 +129,30 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end)
 	 * Clean and invalidate partial last cache line.
 	 * Clean and invalidate partial last cache line.
 	 */
 	 */
 	if (start < end) {
 	if (start < end) {
-		vaddr = l2_map_va(start, vaddr, flags);
+		vaddr = l2_map_va(start, vaddr);
 		xsc3_l2_clean_mva(vaddr);
 		xsc3_l2_clean_mva(vaddr);
 		xsc3_l2_inv_mva(vaddr);
 		xsc3_l2_inv_mva(vaddr);
 	}
 	}
 
 
-	l2_map_restore_flags(flags);
+	l2_unmap_va(vaddr);
 
 
 	dsb();
 	dsb();
 }
 }
 
 
 static void xsc3_l2_clean_range(unsigned long start, unsigned long end)
 static void xsc3_l2_clean_range(unsigned long start, unsigned long end)
 {
 {
-	unsigned long vaddr, flags;
+	unsigned long vaddr;
 
 
 	vaddr = -1;  /* to force the first mapping */
 	vaddr = -1;  /* to force the first mapping */
-	l2_map_save_flags(flags);
 
 
 	start &= ~(CACHE_LINE_SIZE - 1);
 	start &= ~(CACHE_LINE_SIZE - 1);
 	while (start < end) {
 	while (start < end) {
-		vaddr = l2_map_va(start, vaddr, flags);
+		vaddr = l2_map_va(start, vaddr);
 		xsc3_l2_clean_mva(vaddr);
 		xsc3_l2_clean_mva(vaddr);
 		start += CACHE_LINE_SIZE;
 		start += CACHE_LINE_SIZE;
 	}
 	}
 
 
-	l2_map_restore_flags(flags);
+	l2_unmap_va(vaddr);
 
 
 	dsb();
 	dsb();
 }
 }
@@ -193,7 +179,7 @@ static inline void xsc3_l2_flush_all(void)
 
 
 static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
 static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
 {
 {
-	unsigned long vaddr, flags;
+	unsigned long vaddr;
 
 
 	if (start == 0 && end == -1ul) {
 	if (start == 0 && end == -1ul) {
 		xsc3_l2_flush_all();
 		xsc3_l2_flush_all();
@@ -201,17 +187,16 @@ static void xsc3_l2_flush_range(unsigned long start, unsigned long end)
 	}
 	}
 
 
 	vaddr = -1;  /* to force the first mapping */
 	vaddr = -1;  /* to force the first mapping */
-	l2_map_save_flags(flags);
 
 
 	start &= ~(CACHE_LINE_SIZE - 1);
 	start &= ~(CACHE_LINE_SIZE - 1);
 	while (start < end) {
 	while (start < end) {
-		vaddr = l2_map_va(start, vaddr, flags);
+		vaddr = l2_map_va(start, vaddr);
 		xsc3_l2_clean_mva(vaddr);
 		xsc3_l2_clean_mva(vaddr);
 		xsc3_l2_inv_mva(vaddr);
 		xsc3_l2_inv_mva(vaddr);
 		start += CACHE_LINE_SIZE;
 		start += CACHE_LINE_SIZE;
 	}
 	}
 
 
-	l2_map_restore_flags(flags);
+	l2_unmap_va(vaddr);
 
 
 	dsb();
 	dsb();
 }
 }

+ 4 - 3
arch/arm/mm/dma-mapping.c

@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/dma-mapping.h>
+#include <linux/highmem.h>
 
 
 #include <asm/memory.h>
 #include <asm/memory.h>
 #include <asm/highmem.h>
 #include <asm/highmem.h>
@@ -480,10 +481,10 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
 				op(vaddr, len, dir);
 				op(vaddr, len, dir);
 				kunmap_high(page);
 				kunmap_high(page);
 			} else if (cache_is_vipt()) {
 			} else if (cache_is_vipt()) {
-				pte_t saved_pte;
-				vaddr = kmap_high_l1_vipt(page, &saved_pte);
+				/* unmapped pages might still be cached */
+				vaddr = kmap_atomic(page);
 				op(vaddr + offset, len, dir);
 				op(vaddr + offset, len, dir);
-				kunmap_high_l1_vipt(page, saved_pte);
+				kunmap_atomic(vaddr);
 			}
 			}
 		} else {
 		} else {
 			vaddr = page_address(page) + offset;
 			vaddr = page_address(page) + offset;

+ 4 - 3
arch/arm/mm/flush.c

@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/pagemap.h>
+#include <linux/highmem.h>
 
 
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 #include <asm/cachetype.h>
 #include <asm/cachetype.h>
@@ -180,10 +181,10 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
 			__cpuc_flush_dcache_area(addr, PAGE_SIZE);
 			__cpuc_flush_dcache_area(addr, PAGE_SIZE);
 			kunmap_high(page);
 			kunmap_high(page);
 		} else if (cache_is_vipt()) {
 		} else if (cache_is_vipt()) {
-			pte_t saved_pte;
-			addr = kmap_high_l1_vipt(page, &saved_pte);
+			/* unmapped pages might still be cached */
+			addr = kmap_atomic(page);
 			__cpuc_flush_dcache_area(addr, PAGE_SIZE);
 			__cpuc_flush_dcache_area(addr, PAGE_SIZE);
-			kunmap_high_l1_vipt(page, saved_pte);
+			kunmap_atomic(addr);
 		}
 		}
 	}
 	}
 
 

+ 0 - 87
arch/arm/mm/highmem.c

@@ -140,90 +140,3 @@ struct page *kmap_atomic_to_page(const void *ptr)
 	pte = TOP_PTE(vaddr);
 	pte = TOP_PTE(vaddr);
 	return pte_page(*pte);
 	return pte_page(*pte);
 }
 }
-
-#ifdef CONFIG_CPU_CACHE_VIPT
-
-#include <linux/percpu.h>
-
-/*
- * The VIVT cache of a highmem page is always flushed before the page
- * is unmapped. Hence unmapped highmem pages need no cache maintenance
- * in that case.
- *
- * However unmapped pages may still be cached with a VIPT cache, and
- * it is not possible to perform cache maintenance on them using physical
- * addresses unfortunately.  So we have no choice but to set up a temporary
- * virtual mapping for that purpose.
- *
- * Yet this VIPT cache maintenance may be triggered from DMA support
- * functions which are possibly called from interrupt context. As we don't
- * want to keep interrupt disabled all the time when such maintenance is
- * taking place, we therefore allow for some reentrancy by preserving and
- * restoring the previous fixmap entry before the interrupted context is
- * resumed.  If the reentrancy depth is 0 then there is no need to restore
- * the previous fixmap, and leaving the current one in place allow it to
- * be reused the next time without a TLB flush (common with DMA).
- */
-
-static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
-
-void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
-{
-	unsigned int idx, cpu;
-	int *depth;
-	unsigned long vaddr, flags;
-	pte_t pte, *ptep;
-
-	if (!in_interrupt())
-		preempt_disable();
-
-	cpu = smp_processor_id();
-	depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
-
-	idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
-	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-	ptep = TOP_PTE(vaddr);
-	pte = mk_pte(page, kmap_prot);
-
-	raw_local_irq_save(flags);
-	(*depth)++;
-	if (pte_val(*ptep) == pte_val(pte)) {
-		*saved_pte = pte;
-	} else {
-		*saved_pte = *ptep;
-		set_pte_ext(ptep, pte, 0);
-		local_flush_tlb_kernel_page(vaddr);
-	}
-	raw_local_irq_restore(flags);
-
-	return (void *)vaddr;
-}
-
-void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
-{
-	unsigned int idx, cpu = smp_processor_id();
-	int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
-	unsigned long vaddr, flags;
-	pte_t pte, *ptep;
-
-	idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
-	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
-	ptep = TOP_PTE(vaddr);
-	pte = mk_pte(page, kmap_prot);
-
-	BUG_ON(pte_val(*ptep) != pte_val(pte));
-	BUG_ON(*depth <= 0);
-
-	raw_local_irq_save(flags);
-	(*depth)--;
-	if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
-		set_pte_ext(ptep, saved_pte, 0);
-		local_flush_tlb_kernel_page(vaddr);
-	}
-	raw_local_irq_restore(flags);
-
-	if (!in_interrupt())
-		preempt_enable();
-}
-
-#endif  /* CONFIG_CPU_CACHE_VIPT */

+ 1 - 1
arch/mn10300/kernel/irq.c

@@ -459,7 +459,7 @@ void migrate_irqs(void)
 			tmp = CROSS_GxICR(irq, new);
 			tmp = CROSS_GxICR(irq, new);
 
 
 			x &= GxICR_LEVEL | GxICR_ENABLE;
 			x &= GxICR_LEVEL | GxICR_ENABLE;
-			if (GxICR(irq) & GxICR_REQUEST) {
+			if (GxICR(irq) & GxICR_REQUEST)
 				x |= GxICR_REQUEST | GxICR_DETECT;
 				x |= GxICR_REQUEST | GxICR_DETECT;
 			CROSS_GxICR(irq, new) = x;
 			CROSS_GxICR(irq, new) = x;
 			tmp = CROSS_GxICR(irq, new);
 			tmp = CROSS_GxICR(irq, new);

+ 2 - 0
arch/x86/kvm/i8259.c

@@ -575,6 +575,8 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm)
 	s->pics[1].elcr_mask = 0xde;
 	s->pics[1].elcr_mask = 0xde;
 	s->pics[0].pics_state = s;
 	s->pics[0].pics_state = s;
 	s->pics[1].pics_state = s;
 	s->pics[1].pics_state = s;
+	s->pics[0].isr_ack = 0xff;
+	s->pics[1].isr_ack = 0xff;
 
 
 	/*
 	/*
 	 * Initialize PIO device
 	 * Initialize PIO device

+ 2 - 1
arch/x86/kvm/mmu.c

@@ -2394,7 +2394,8 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu)
 			ASSERT(!VALID_PAGE(root));
 			ASSERT(!VALID_PAGE(root));
 			spin_lock(&vcpu->kvm->mmu_lock);
 			spin_lock(&vcpu->kvm->mmu_lock);
 			kvm_mmu_free_some_pages(vcpu);
 			kvm_mmu_free_some_pages(vcpu);
-			sp = kvm_mmu_get_page(vcpu, i << 30, i << 30,
+			sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT),
+					      i << 30,
 					      PT32_ROOT_LEVEL, 1, ACC_ALL,
 					      PT32_ROOT_LEVEL, 1, ACC_ALL,
 					      NULL);
 					      NULL);
 			root = __pa(sp->spt);
 			root = __pa(sp->spt);

+ 16 - 8
arch/x86/oprofile/op_model_amd.c

@@ -637,21 +637,29 @@ static int __init_ibs_nmi(void)
 	return 0;
 	return 0;
 }
 }
 
 
-/* initialize the APIC for the IBS interrupts if available */
+/*
+ * check and reserve APIC extended interrupt LVT offset for IBS if
+ * available
+ *
+ * init_ibs() preforms implicitly cpu-local operations, so pin this
+ * thread to its current CPU
+ */
+
 static void init_ibs(void)
 static void init_ibs(void)
 {
 {
-	ibs_caps = get_ibs_caps();
+	preempt_disable();
 
 
+	ibs_caps = get_ibs_caps();
 	if (!ibs_caps)
 	if (!ibs_caps)
-		return;
+		goto out;
 
 
-	if (__init_ibs_nmi()) {
+	if (__init_ibs_nmi() < 0)
 		ibs_caps = 0;
 		ibs_caps = 0;
-		return;
-	}
+	else
+		printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps);
 
 
-	printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n",
-	       (unsigned)ibs_caps);
+out:
+	preempt_enable();
 }
 }
 
 
 static int (*create_arch_files)(struct super_block *sb, struct dentry *root);
 static int (*create_arch_files)(struct super_block *sb, struct dentry *root);

+ 4 - 1
drivers/atm/atmtcp.c

@@ -392,7 +392,10 @@ static int atmtcp_attach(struct atm_vcc *vcc,int itf)
 			atm_dev_put(dev);
 			atm_dev_put(dev);
 			return -EMEDIUMTYPE;
 			return -EMEDIUMTYPE;
 		}
 		}
-		if (PRIV(dev)->vcc) return -EBUSY;
+		if (PRIV(dev)->vcc) {
+			atm_dev_put(dev);
+			return -EBUSY;
+		}
 	}
 	}
 	else {
 	else {
 		int error;
 		int error;

+ 1 - 1
drivers/dma/mv_xor.c

@@ -449,7 +449,7 @@ mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
 static void mv_xor_tasklet(unsigned long data)
 static void mv_xor_tasklet(unsigned long data)
 {
 {
 	struct mv_xor_chan *chan = (struct mv_xor_chan *) data;
 	struct mv_xor_chan *chan = (struct mv_xor_chan *) data;
-	__mv_xor_slot_cleanup(chan);
+	mv_xor_slot_cleanup(chan);
 }
 }
 
 
 static struct mv_xor_desc_slot *
 static struct mv_xor_desc_slot *

+ 1 - 1
drivers/gpu/drm/i915/dvo_ch7017.c

@@ -242,7 +242,7 @@ fail:
 
 
 static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo)
 static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo)
 {
 {
-	return connector_status_unknown;
+	return connector_status_connected;
 }
 }
 
 
 static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo,
 static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo,

+ 23 - 0
drivers/gpu/drm/i915/i915_dma.c

@@ -34,6 +34,7 @@
 #include "i915_drm.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
 #include "i915_drv.h"
 #include "i915_trace.h"
 #include "i915_trace.h"
+#include "../../../platform/x86/intel_ips.h"
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/vgaarb.h>
 #include <linux/vgaarb.h>
 #include <linux/acpi.h>
 #include <linux/acpi.h>
@@ -1870,6 +1871,26 @@ out_unlock:
 }
 }
 EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
 EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
 
 
+/**
+ * Tells the intel_ips driver that the i915 driver is now loaded, if
+ * IPS got loaded first.
+ *
+ * This awkward dance is so that neither module has to depend on the
+ * other in order for IPS to do the appropriate communication of
+ * GPU turbo limits to i915.
+ */
+static void
+ips_ping_for_i915_load(void)
+{
+	void (*link)(void);
+
+	link = symbol_get(ips_link_to_i915_driver);
+	if (link) {
+		link();
+		symbol_put(ips_link_to_i915_driver);
+	}
+}
+
 /**
 /**
  * i915_driver_load - setup chip and create an initial config
  * i915_driver_load - setup chip and create an initial config
  * @dev: DRM device
  * @dev: DRM device
@@ -2075,6 +2096,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 	dev_priv->mchdev_lock = &mchdev_lock;
 	dev_priv->mchdev_lock = &mchdev_lock;
 	spin_unlock(&mchdev_lock);
 	spin_unlock(&mchdev_lock);
 
 
+	ips_ping_for_i915_load();
+
 	return 0;
 	return 0;
 
 
 out_workqueue_free:
 out_workqueue_free:

+ 10 - 0
drivers/gpu/drm/i915/i915_reg.h

@@ -2471,6 +2471,9 @@
 # define MARIUNIT_CLOCK_GATE_DISABLE		(1 << 18)
 # define MARIUNIT_CLOCK_GATE_DISABLE		(1 << 18)
 # define SVSMUNIT_CLOCK_GATE_DISABLE		(1 << 1)
 # define SVSMUNIT_CLOCK_GATE_DISABLE		(1 << 1)
 
 
+#define PCH_3DCGDIS1		0x46024
+# define VFMUNIT_CLOCK_GATE_DISABLE		(1 << 11)
+
 #define FDI_PLL_FREQ_CTL        0x46030
 #define FDI_PLL_FREQ_CTL        0x46030
 #define  FDI_PLL_FREQ_CHANGE_REQUEST    (1<<24)
 #define  FDI_PLL_FREQ_CHANGE_REQUEST    (1<<24)
 #define  FDI_PLL_FREQ_LOCK_LIMIT_MASK   0xfff00
 #define  FDI_PLL_FREQ_LOCK_LIMIT_MASK   0xfff00
@@ -2588,6 +2591,13 @@
 #define ILK_DISPLAY_CHICKEN2	0x42004
 #define ILK_DISPLAY_CHICKEN2	0x42004
 #define  ILK_DPARB_GATE	(1<<22)
 #define  ILK_DPARB_GATE	(1<<22)
 #define  ILK_VSDPFD_FULL	(1<<21)
 #define  ILK_VSDPFD_FULL	(1<<21)
+#define ILK_DISPLAY_CHICKEN_FUSES	0x42014
+#define  ILK_INTERNAL_GRAPHICS_DISABLE	(1<<31)
+#define  ILK_INTERNAL_DISPLAY_DISABLE	(1<<30)
+#define  ILK_DISPLAY_DEBUG_DISABLE	(1<<29)
+#define  ILK_HDCP_DISABLE		(1<<25)
+#define  ILK_eDP_A_DISABLE		(1<<24)
+#define  ILK_DESKTOP			(1<<23)
 #define ILK_DSPCLK_GATE		0x42020
 #define ILK_DSPCLK_GATE		0x42020
 #define  ILK_DPARB_CLK_GATE	(1<<5)
 #define  ILK_DPARB_CLK_GATE	(1<<5)
 /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */
 /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */

+ 1 - 1
drivers/gpu/drm/i915/intel_bios.c

@@ -270,7 +270,7 @@ parse_general_features(struct drm_i915_private *dev_priv,
 					general->ssc_freq ? 66 : 48;
 					general->ssc_freq ? 66 : 48;
 			else if (IS_GEN5(dev) || IS_GEN6(dev))
 			else if (IS_GEN5(dev) || IS_GEN6(dev))
 				dev_priv->lvds_ssc_freq =
 				dev_priv->lvds_ssc_freq =
-					general->ssc_freq ? 120 : 100;
+					general->ssc_freq ? 100 : 120;
 			else
 			else
 				dev_priv->lvds_ssc_freq =
 				dev_priv->lvds_ssc_freq =
 					general->ssc_freq ? 100 : 96;
 					general->ssc_freq ? 100 : 96;

+ 20 - 1
drivers/gpu/drm/i915/intel_display.c

@@ -5379,6 +5379,23 @@ static int intel_encoder_clones(struct drm_device *dev, int type_mask)
 	return index_mask;
 	return index_mask;
 }
 }
 
 
+static bool has_edp_a(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!IS_MOBILE(dev))
+		return false;
+
+	if ((I915_READ(DP_A) & DP_DETECTED) == 0)
+		return false;
+
+	if (IS_GEN5(dev) &&
+	    (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE))
+		return false;
+
+	return true;
+}
+
 static void intel_setup_outputs(struct drm_device *dev)
 static void intel_setup_outputs(struct drm_device *dev)
 {
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -5396,7 +5413,7 @@ static void intel_setup_outputs(struct drm_device *dev)
 	if (HAS_PCH_SPLIT(dev)) {
 	if (HAS_PCH_SPLIT(dev)) {
 		dpd_is_edp = intel_dpd_is_edp(dev);
 		dpd_is_edp = intel_dpd_is_edp(dev);
 
 
-		if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED))
+		if (has_edp_a(dev))
 			intel_dp_init(dev, DP_A);
 			intel_dp_init(dev, DP_A);
 
 
 		if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
 		if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED))
@@ -5825,6 +5842,8 @@ void intel_init_clock_gating(struct drm_device *dev)
 			I915_WRITE(PCH_3DCGDIS0,
 			I915_WRITE(PCH_3DCGDIS0,
 				   MARIUNIT_CLOCK_GATE_DISABLE |
 				   MARIUNIT_CLOCK_GATE_DISABLE |
 				   SVSMUNIT_CLOCK_GATE_DISABLE);
 				   SVSMUNIT_CLOCK_GATE_DISABLE);
+			I915_WRITE(PCH_3DCGDIS1,
+				   VFMUNIT_CLOCK_GATE_DISABLE);
 		}
 		}
 
 
 		I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
 		I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);

+ 2 - 1
drivers/gpu/drm/i915/intel_sdvo.c

@@ -2040,13 +2040,14 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
 					   SDVO_COLORIMETRY_RGB256);
 					   SDVO_COLORIMETRY_RGB256);
 		connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
 		connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
 
 
-		intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
 		intel_sdvo->is_hdmi = true;
 		intel_sdvo->is_hdmi = true;
 	}
 	}
 	intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
 	intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
 				       (1 << INTEL_ANALOG_CLONE_BIT));
 				       (1 << INTEL_ANALOG_CLONE_BIT));
 
 
 	intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
 	intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
+	if (intel_sdvo->is_hdmi)
+		intel_sdvo_add_hdmi_properties(intel_sdvo_connector);
 
 
 	return true;
 	return true;
 }
 }

+ 0 - 2
drivers/hwmon/s3c-hwmon.c

@@ -234,7 +234,6 @@ static int s3c_hwmon_create_attr(struct device *dev,
 	attr->index = channel;
 	attr->index = channel;
 	attr->dev_attr.attr.name  = attrs->in_name;
 	attr->dev_attr.attr.name  = attrs->in_name;
 	attr->dev_attr.attr.mode  = S_IRUGO;
 	attr->dev_attr.attr.mode  = S_IRUGO;
-	attr->dev_attr.attr.owner = THIS_MODULE;
 	attr->dev_attr.show = s3c_hwmon_ch_show;
 	attr->dev_attr.show = s3c_hwmon_ch_show;
 
 
 	ret =  device_create_file(dev, &attr->dev_attr);
 	ret =  device_create_file(dev, &attr->dev_attr);
@@ -252,7 +251,6 @@ static int s3c_hwmon_create_attr(struct device *dev,
 		attr->index = channel;
 		attr->index = channel;
 		attr->dev_attr.attr.name  = attrs->label_name;
 		attr->dev_attr.attr.name  = attrs->label_name;
 		attr->dev_attr.attr.mode  = S_IRUGO;
 		attr->dev_attr.attr.mode  = S_IRUGO;
-		attr->dev_attr.attr.owner = THIS_MODULE;
 		attr->dev_attr.show = s3c_hwmon_label_show;
 		attr->dev_attr.show = s3c_hwmon_label_show;
 
 
 		ret = device_create_file(dev, &attr->dev_attr);
 		ret = device_create_file(dev, &attr->dev_attr);

+ 1 - 0
drivers/isdn/gigaset/capi.c

@@ -1900,6 +1900,7 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
 		if (b3skb == NULL) {
 		if (b3skb == NULL) {
 			dev_err(cs->dev, "%s: out of memory\n", __func__);
 			dev_err(cs->dev, "%s: out of memory\n", __func__);
 			send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
 			send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
+			kfree(b3cmsg);
 			return;
 			return;
 		}
 		}
 		capi_cmsg2message(b3cmsg,
 		capi_cmsg2message(b3cmsg,

+ 17 - 2
drivers/media/video/cx25840/cx25840-core.c

@@ -1989,8 +1989,23 @@ static int cx25840_probe(struct i2c_client *client,
 	v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
 	v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
 			V4L2_CID_HUE, -128, 127, 1, 0);
 			V4L2_CID_HUE, -128, 127, 1, 0);
 	if (!is_cx2583x(state)) {
 	if (!is_cx2583x(state)) {
-		default_volume = 228 - cx25840_read(client, 0x8d4);
-		default_volume = ((default_volume / 2) + 23) << 9;
+		default_volume = cx25840_read(client, 0x8d4);
+		/*
+		 * Enforce the legacy PVR-350/MSP3400 to PVR-150/CX25843 volume
+		 * scale mapping limits to avoid -ERANGE errors when
+		 * initializing the volume control
+		 */
+		if (default_volume > 228) {
+			/* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
+			default_volume = 228;
+			cx25840_write(client, 0x8d4, 228);
+		}
+		else if (default_volume < 20) {
+			/* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */
+			default_volume = 20;
+			cx25840_write(client, 0x8d4, 20);
+		}
+		default_volume = (((228 - default_volume) >> 1) + 23) << 9;
 
 
 		state->volume = v4l2_ctrl_new_std(&state->hdl,
 		state->volume = v4l2_ctrl_new_std(&state->hdl,
 			&cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
 			&cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,

+ 12 - 87
drivers/media/video/cx88/cx88-alsa.c

@@ -40,7 +40,6 @@
 #include <sound/control.h>
 #include <sound/control.h>
 #include <sound/initval.h>
 #include <sound/initval.h>
 #include <sound/tlv.h>
 #include <sound/tlv.h>
-#include <media/wm8775.h>
 
 
 #include "cx88.h"
 #include "cx88.h"
 #include "cx88-reg.h"
 #include "cx88-reg.h"
@@ -587,47 +586,26 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
 	int left, right, v, b;
 	int left, right, v, b;
 	int changed = 0;
 	int changed = 0;
 	u32 old;
 	u32 old;
-	struct v4l2_control client_ctl;
-
-	/* Pass volume & balance onto any WM8775 */
-	if (value->value.integer.value[0] >= value->value.integer.value[1]) {
-		v = value->value.integer.value[0] << 10;
-		b = value->value.integer.value[0] ?
-			(0x8000 * value->value.integer.value[1]) / value->value.integer.value[0] :
-			0x8000;
-	} else {
-		v = value->value.integer.value[1] << 10;
-		b = value->value.integer.value[1] ?
-		0xffff - (0x8000 * value->value.integer.value[0]) / value->value.integer.value[1] :
-		0x8000;
-	}
-	client_ctl.value = v;
-	client_ctl.id = V4L2_CID_AUDIO_VOLUME;
-	call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
-
-	client_ctl.value = b;
-	client_ctl.id = V4L2_CID_AUDIO_BALANCE;
-	call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
 
 
 	left = value->value.integer.value[0] & 0x3f;
 	left = value->value.integer.value[0] & 0x3f;
 	right = value->value.integer.value[1] & 0x3f;
 	right = value->value.integer.value[1] & 0x3f;
 	b = right - left;
 	b = right - left;
 	if (b < 0) {
 	if (b < 0) {
-		v = 0x3f - left;
-		b = (-b) | 0x40;
+	    v = 0x3f - left;
+	    b = (-b) | 0x40;
 	} else {
 	} else {
-		v = 0x3f - right;
+	    v = 0x3f - right;
 	}
 	}
 	/* Do we really know this will always be called with IRQs on? */
 	/* Do we really know this will always be called with IRQs on? */
 	spin_lock_irq(&chip->reg_lock);
 	spin_lock_irq(&chip->reg_lock);
 	old = cx_read(AUD_VOL_CTL);
 	old = cx_read(AUD_VOL_CTL);
 	if (v != (old & 0x3f)) {
 	if (v != (old & 0x3f)) {
-		cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v);
-		changed = 1;
+	    cx_write(AUD_VOL_CTL, (old & ~0x3f) | v);
+	    changed = 1;
 	}
 	}
-	if ((cx_read(AUD_BAL_CTL) & 0x7f) != b) {
-		cx_write(AUD_BAL_CTL, b);
-		changed = 1;
+	if (cx_read(AUD_BAL_CTL) != b) {
+	    cx_write(AUD_BAL_CTL, b);
+	    changed = 1;
 	}
 	}
 	spin_unlock_irq(&chip->reg_lock);
 	spin_unlock_irq(&chip->reg_lock);
 
 
@@ -640,7 +618,7 @@ static const struct snd_kcontrol_new snd_cx88_volume = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
 	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
 		  SNDRV_CTL_ELEM_ACCESS_TLV_READ,
 		  SNDRV_CTL_ELEM_ACCESS_TLV_READ,
-	.name = "Analog-TV Volume",
+	.name = "Playback Volume",
 	.info = snd_cx88_volume_info,
 	.info = snd_cx88_volume_info,
 	.get = snd_cx88_volume_get,
 	.get = snd_cx88_volume_get,
 	.put = snd_cx88_volume_put,
 	.put = snd_cx88_volume_put,
@@ -671,14 +649,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
 	vol = cx_read(AUD_VOL_CTL);
 	vol = cx_read(AUD_VOL_CTL);
 	if (value->value.integer.value[0] != !(vol & bit)) {
 	if (value->value.integer.value[0] != !(vol & bit)) {
 		vol ^= bit;
 		vol ^= bit;
-		cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol);
-		/* Pass mute onto any WM8775 */
-		if ((1<<6) == bit) {
-			struct v4l2_control client_ctl;
-			client_ctl.value = 0 != (vol & bit);
-			client_ctl.id = V4L2_CID_AUDIO_MUTE;
-			call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
-		}
+		cx_write(AUD_VOL_CTL, vol);
 		ret = 1;
 		ret = 1;
 	}
 	}
 	spin_unlock_irq(&chip->reg_lock);
 	spin_unlock_irq(&chip->reg_lock);
@@ -687,7 +658,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
 
 
 static const struct snd_kcontrol_new snd_cx88_dac_switch = {
 static const struct snd_kcontrol_new snd_cx88_dac_switch = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Audio-Out Switch",
+	.name = "Playback Switch",
 	.info = snd_ctl_boolean_mono_info,
 	.info = snd_ctl_boolean_mono_info,
 	.get = snd_cx88_switch_get,
 	.get = snd_cx88_switch_get,
 	.put = snd_cx88_switch_put,
 	.put = snd_cx88_switch_put,
@@ -696,49 +667,13 @@ static const struct snd_kcontrol_new snd_cx88_dac_switch = {
 
 
 static const struct snd_kcontrol_new snd_cx88_source_switch = {
 static const struct snd_kcontrol_new snd_cx88_source_switch = {
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Analog-TV Switch",
+	.name = "Capture Switch",
 	.info = snd_ctl_boolean_mono_info,
 	.info = snd_ctl_boolean_mono_info,
 	.get = snd_cx88_switch_get,
 	.get = snd_cx88_switch_get,
 	.put = snd_cx88_switch_put,
 	.put = snd_cx88_switch_put,
 	.private_value = (1<<6),
 	.private_value = (1<<6),
 };
 };
 
 
-static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol,
-			       struct snd_ctl_elem_value *value)
-{
-	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
-	struct cx88_core *core = chip->core;
-	struct v4l2_control client_ctl;
-
-	client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
-	call_hw(core, WM8775_GID, core, g_ctrl, &client_ctl);
-	value->value.integer.value[0] = client_ctl.value ? 1 : 0;
-
-	return 0;
-}
-
-static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol,
-				       struct snd_ctl_elem_value *value)
-{
-	snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
-	struct cx88_core *core = chip->core;
-	struct v4l2_control client_ctl;
-
-	client_ctl.value = 0 != value->value.integer.value[0];
-	client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
-	call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
-
-	return 0;
-}
-
-static struct snd_kcontrol_new snd_cx88_alc_switch = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "Line-In ALC Switch",
-	.info = snd_ctl_boolean_mono_info,
-	.get = snd_cx88_alc_get,
-	.put = snd_cx88_alc_put,
-};
-
 /****************************************************************************
 /****************************************************************************
 			Basic Flow for Sound Devices
 			Basic Flow for Sound Devices
  ****************************************************************************/
  ****************************************************************************/
@@ -860,7 +795,6 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
 {
 {
 	struct snd_card  *card;
 	struct snd_card  *card;
 	snd_cx88_card_t  *chip;
 	snd_cx88_card_t  *chip;
-	struct v4l2_subdev *sd;
 	int              err;
 	int              err;
 
 
 	if (devno >= SNDRV_CARDS)
 	if (devno >= SNDRV_CARDS)
@@ -896,15 +830,6 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
 	if (err < 0)
 	if (err < 0)
 		goto error;
 		goto error;
 
 
-	/* If there's a wm8775 then add a Line-In ALC switch */
-	list_for_each_entry(sd, &chip->core->v4l2_dev.subdevs, list) {
-		if (WM8775_GID == sd->grp_id) {
-			snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch,
-						       chip));
-			break;
-		}
-	}
-
 	strcpy (card->driver, "CX88x");
 	strcpy (card->driver, "CX88x");
 	sprintf(card->shortname, "Conexant CX%x", pci->device);
 	sprintf(card->shortname, "Conexant CX%x", pci->device);
 	sprintf(card->longname, "%s at %#llx",
 	sprintf(card->longname, "%s at %#llx",

+ 7 - 0
drivers/media/video/cx88/cx88-cards.c

@@ -1007,15 +1007,22 @@ static const struct cx88_board cx88_boards[] = {
 		.radio_type	= UNSET,
 		.radio_type	= UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.tuner_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
 		.radio_addr	= ADDR_UNSET,
+		.audio_chip = V4L2_IDENT_WM8775,
 		.input		= {{
 		.input		= {{
 			.type	= CX88_VMUX_DVB,
 			.type	= CX88_VMUX_DVB,
 			.vmux	= 0,
 			.vmux	= 0,
+			/* 2: Line-In */
+			.audioroute = 2,
 		},{
 		},{
 			.type	= CX88_VMUX_COMPOSITE1,
 			.type	= CX88_VMUX_COMPOSITE1,
 			.vmux	= 1,
 			.vmux	= 1,
+			/* 2: Line-In */
+			.audioroute = 2,
 		},{
 		},{
 			.type	= CX88_VMUX_SVIDEO,
 			.type	= CX88_VMUX_SVIDEO,
 			.vmux	= 2,
 			.vmux	= 2,
+			/* 2: Line-In */
+			.audioroute = 2,
 		}},
 		}},
 		.mpeg           = CX88_MPEG_DVB,
 		.mpeg           = CX88_MPEG_DVB,
 	},
 	},

+ 1 - 26
drivers/media/video/cx88/cx88-video.c

@@ -40,7 +40,6 @@
 #include "cx88.h"
 #include "cx88.h"
 #include <media/v4l2-common.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-ioctl.h>
-#include <media/wm8775.h>
 
 
 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
 MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
 MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -977,7 +976,6 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl)
 	const struct cx88_ctrl *c = NULL;
 	const struct cx88_ctrl *c = NULL;
 	u32 value,mask;
 	u32 value,mask;
 	int i;
 	int i;
-	struct v4l2_control client_ctl;
 
 
 	for (i = 0; i < CX8800_CTLS; i++) {
 	for (i = 0; i < CX8800_CTLS; i++) {
 		if (cx8800_ctls[i].v.id == ctl->id) {
 		if (cx8800_ctls[i].v.id == ctl->id) {
@@ -991,27 +989,6 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl)
 		ctl->value = c->v.minimum;
 		ctl->value = c->v.minimum;
 	if (ctl->value > c->v.maximum)
 	if (ctl->value > c->v.maximum)
 		ctl->value = c->v.maximum;
 		ctl->value = c->v.maximum;
-
-	/* Pass changes onto any WM8775 */
-	client_ctl.id = ctl->id;
-	switch (ctl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		client_ctl.value = ctl->value;
-		break;
-	case V4L2_CID_AUDIO_VOLUME:
-		client_ctl.value = (ctl->value) ?
-			(0x90 + ctl->value) << 8 : 0;
-		break;
-	case V4L2_CID_AUDIO_BALANCE:
-		client_ctl.value = ctl->value << 9;
-		break;
-	default:
-		client_ctl.id = 0;
-		break;
-	}
-	if (client_ctl.id)
-		call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
-
 	mask=c->mask;
 	mask=c->mask;
 	switch (ctl->id) {
 	switch (ctl->id) {
 	case V4L2_CID_AUDIO_BALANCE:
 	case V4L2_CID_AUDIO_BALANCE:
@@ -1558,9 +1535,7 @@ static int radio_queryctrl (struct file *file, void *priv,
 	if (c->id <  V4L2_CID_BASE ||
 	if (c->id <  V4L2_CID_BASE ||
 		c->id >= V4L2_CID_LASTP1)
 		c->id >= V4L2_CID_LASTP1)
 		return -EINVAL;
 		return -EINVAL;
-	if (c->id == V4L2_CID_AUDIO_MUTE ||
-		c->id == V4L2_CID_AUDIO_VOLUME ||
-		c->id == V4L2_CID_AUDIO_BALANCE) {
+	if (c->id == V4L2_CID_AUDIO_MUTE) {
 		for (i = 0; i < CX8800_CTLS; i++) {
 		for (i = 0; i < CX8800_CTLS; i++) {
 			if (cx8800_ctls[i].v.id == c->id)
 			if (cx8800_ctls[i].v.id == c->id)
 				break;
 				break;

+ 2 - 4
drivers/media/video/cx88/cx88.h

@@ -398,19 +398,17 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
 	return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
 	return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
 }
 }
 
 
-#define call_hw(core, grpid, o, f, args...) \
+#define call_all(core, o, f, args...) 				\
 	do {							\
 	do {							\
 		if (!core->i2c_rc) {				\
 		if (!core->i2c_rc) {				\
 			if (core->gate_ctrl)			\
 			if (core->gate_ctrl)			\
 				core->gate_ctrl(core, 1);	\
 				core->gate_ctrl(core, 1);	\
-			v4l2_device_call_all(&core->v4l2_dev, grpid, o, f, ##args); \
+			v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \
 			if (core->gate_ctrl)			\
 			if (core->gate_ctrl)			\
 				core->gate_ctrl(core, 0);	\
 				core->gate_ctrl(core, 0);	\
 		}						\
 		}						\
 	} while (0)
 	} while (0)
 
 
-#define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args)
-
 struct cx8800_dev;
 struct cx8800_dev;
 struct cx8802_dev;
 struct cx8802_dev;
 
 

+ 1 - 1
drivers/media/video/em28xx/em28xx-video.c

@@ -2377,7 +2377,7 @@ static const struct v4l2_file_operations radio_fops = {
 	.owner         = THIS_MODULE,
 	.owner         = THIS_MODULE,
 	.open          = em28xx_v4l2_open,
 	.open          = em28xx_v4l2_open,
 	.release       = em28xx_v4l2_close,
 	.release       = em28xx_v4l2_close,
-	.ioctl	       = video_ioctl2,
+	.unlocked_ioctl = video_ioctl2,
 };
 };
 
 
 static const struct v4l2_ioctl_ops radio_ioctl_ops = {
 static const struct v4l2_ioctl_ops radio_ioctl_ops = {

+ 39 - 65
drivers/media/video/wm8775.c

@@ -35,7 +35,6 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-chip-ident.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-ctrls.h>
-#include <media/wm8775.h>
 
 
 MODULE_DESCRIPTION("wm8775 driver");
 MODULE_DESCRIPTION("wm8775 driver");
 MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
 MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
@@ -51,16 +50,10 @@ enum {
 	TOT_REGS
 	TOT_REGS
 };
 };
 
 
-#define ALC_HOLD 0x85 /* R17: use zero cross detection, ALC hold time 42.6 ms */
-#define ALC_EN 0x100  /* R17: ALC enable */
-
 struct wm8775_state {
 struct wm8775_state {
 	struct v4l2_subdev sd;
 	struct v4l2_subdev sd;
 	struct v4l2_ctrl_handler hdl;
 	struct v4l2_ctrl_handler hdl;
 	struct v4l2_ctrl *mute;
 	struct v4l2_ctrl *mute;
-	struct v4l2_ctrl *vol;
-	struct v4l2_ctrl *bal;
-	struct v4l2_ctrl *loud;
 	u8 input;		/* Last selected input (0-0xf) */
 	u8 input;		/* Last selected input (0-0xf) */
 };
 };
 
 
@@ -92,30 +85,6 @@ static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val)
 	return -1;
 	return -1;
 }
 }
 
 
-static void wm8775_set_audio(struct v4l2_subdev *sd, int quietly)
-{
-	struct wm8775_state *state = to_state(sd);
-	u8 vol_l, vol_r;
-	int muted = 0 != state->mute->val;
-	u16 volume = (u16)state->vol->val;
-	u16 balance = (u16)state->bal->val;
-
-	/* normalize ( 65535 to 0 -> 255 to 0 (+24dB to -103dB) ) */
-	vol_l = (min(65536 - balance, 32768) * volume) >> 23;
-	vol_r = (min(balance, (u16)32768) * volume) >> 23;
-
-	/* Mute */
-	if (muted || quietly)
-		wm8775_write(sd, R21, 0x0c0 | state->input);
-
-	wm8775_write(sd, R14, vol_l | 0x100); /* 0x100= Left channel ADC zero cross enable */
-	wm8775_write(sd, R15, vol_r | 0x100); /* 0x100= Right channel ADC zero cross enable */
-
-	/* Un-mute */
-	if (!muted)
-		wm8775_write(sd, R21, state->input);
-}
-
 static int wm8775_s_routing(struct v4l2_subdev *sd,
 static int wm8775_s_routing(struct v4l2_subdev *sd,
 			    u32 input, u32 output, u32 config)
 			    u32 input, u32 output, u32 config)
 {
 {
@@ -133,26 +102,25 @@ static int wm8775_s_routing(struct v4l2_subdev *sd,
 	state->input = input;
 	state->input = input;
 	if (!v4l2_ctrl_g_ctrl(state->mute))
 	if (!v4l2_ctrl_g_ctrl(state->mute))
 		return 0;
 		return 0;
-	if (!v4l2_ctrl_g_ctrl(state->vol))
-		return 0;
-	if (!v4l2_ctrl_g_ctrl(state->bal))
-		return 0;
-	wm8775_set_audio(sd, 1);
+	wm8775_write(sd, R21, 0x0c0);
+	wm8775_write(sd, R14, 0x1d4);
+	wm8775_write(sd, R15, 0x1d4);
+	wm8775_write(sd, R21, 0x100 + state->input);
 	return 0;
 	return 0;
 }
 }
 
 
 static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl)
 static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 {
 	struct v4l2_subdev *sd = to_sd(ctrl);
 	struct v4l2_subdev *sd = to_sd(ctrl);
+	struct wm8775_state *state = to_state(sd);
 
 
 	switch (ctrl->id) {
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_MUTE:
 	case V4L2_CID_AUDIO_MUTE:
-	case V4L2_CID_AUDIO_VOLUME:
-	case V4L2_CID_AUDIO_BALANCE:
-		wm8775_set_audio(sd, 0);
-		return 0;
-	case V4L2_CID_AUDIO_LOUDNESS:
-		wm8775_write(sd, R17, (ctrl->val ? ALC_EN : 0) | ALC_HOLD);
+		wm8775_write(sd, R21, 0x0c0);
+		wm8775_write(sd, R14, 0x1d4);
+		wm8775_write(sd, R15, 0x1d4);
+		if (!ctrl->val)
+			wm8775_write(sd, R21, 0x100 + state->input);
 		return 0;
 		return 0;
 	}
 	}
 	return -EINVAL;
 	return -EINVAL;
@@ -176,7 +144,16 @@ static int wm8775_log_status(struct v4l2_subdev *sd)
 
 
 static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
 static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
 {
 {
-	wm8775_set_audio(sd, 0);
+	struct wm8775_state *state = to_state(sd);
+
+	/* If I remove this, then it can happen that I have no
+	   sound the first time I tune from static to a valid channel.
+	   It's difficult to reproduce and is almost certainly related
+	   to the zero cross detect circuit. */
+	wm8775_write(sd, R21, 0x0c0);
+	wm8775_write(sd, R14, 0x1d4);
+	wm8775_write(sd, R15, 0x1d4);
+	wm8775_write(sd, R21, 0x100 + state->input);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -226,7 +203,6 @@ static int wm8775_probe(struct i2c_client *client,
 {
 {
 	struct wm8775_state *state;
 	struct wm8775_state *state;
 	struct v4l2_subdev *sd;
 	struct v4l2_subdev *sd;
-	int err;
 
 
 	/* Check if the adapter supports the needed features */
 	/* Check if the adapter supports the needed features */
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -240,21 +216,15 @@ static int wm8775_probe(struct i2c_client *client,
 		return -ENOMEM;
 		return -ENOMEM;
 	sd = &state->sd;
 	sd = &state->sd;
 	v4l2_i2c_subdev_init(sd, client, &wm8775_ops);
 	v4l2_i2c_subdev_init(sd, client, &wm8775_ops);
-	sd->grp_id = WM8775_GID; /* subdev group id */
 	state->input = 2;
 	state->input = 2;
 
 
-	v4l2_ctrl_handler_init(&state->hdl, 4);
+	v4l2_ctrl_handler_init(&state->hdl, 1);
 	state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
 	state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
 			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
 			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
-	state->vol = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
-			V4L2_CID_AUDIO_VOLUME, 0, 65535, (65535+99)/100, 0xCF00); /* 0dB*/
-	state->bal = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
-			V4L2_CID_AUDIO_BALANCE, 0, 65535, (65535+99)/100, 32768);
-	state->loud = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
-			V4L2_CID_AUDIO_LOUDNESS, 0, 1, 1, 1);
 	sd->ctrl_handler = &state->hdl;
 	sd->ctrl_handler = &state->hdl;
-	err = state->hdl.error;
-	if (err) {
+	if (state->hdl.error) {
+		int err = state->hdl.error;
+
 		v4l2_ctrl_handler_free(&state->hdl);
 		v4l2_ctrl_handler_free(&state->hdl);
 		kfree(state);
 		kfree(state);
 		return err;
 		return err;
@@ -266,25 +236,29 @@ static int wm8775_probe(struct i2c_client *client,
 	wm8775_write(sd, R23, 0x000);
 	wm8775_write(sd, R23, 0x000);
 	/* Disable zero cross detect timeout */
 	/* Disable zero cross detect timeout */
 	wm8775_write(sd, R7, 0x000);
 	wm8775_write(sd, R7, 0x000);
-	/* HPF enable, I2S mode, 24-bit */
-	wm8775_write(sd, R11, 0x022);
+	/* Left justified, 24-bit mode */
+	wm8775_write(sd, R11, 0x021);
 	/* Master mode, clock ratio 256fs */
 	/* Master mode, clock ratio 256fs */
 	wm8775_write(sd, R12, 0x102);
 	wm8775_write(sd, R12, 0x102);
 	/* Powered up */
 	/* Powered up */
 	wm8775_write(sd, R13, 0x000);
 	wm8775_write(sd, R13, 0x000);
-	/* ALC stereo, ALC target level -5dB FS, ALC max gain +8dB */
-	wm8775_write(sd, R16, 0x1bb);
-	/* Set ALC mode and hold time */
-	wm8775_write(sd, R17, (state->loud->val ? ALC_EN : 0) | ALC_HOLD);
+	/* ADC gain +2.5dB, enable zero cross */
+	wm8775_write(sd, R14, 0x1d4);
+	/* ADC gain +2.5dB, enable zero cross */
+	wm8775_write(sd, R15, 0x1d4);
+	/* ALC Stereo, ALC target level -1dB FS max gain +8dB */
+	wm8775_write(sd, R16, 0x1bf);
+	/* Enable gain control, use zero cross detection,
+	   ALC hold time 42.6 ms */
+	wm8775_write(sd, R17, 0x185);
 	/* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */
 	/* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */
 	wm8775_write(sd, R18, 0x0a2);
 	wm8775_write(sd, R18, 0x0a2);
 	/* Enable noise gate, threshold -72dBfs */
 	/* Enable noise gate, threshold -72dBfs */
 	wm8775_write(sd, R19, 0x005);
 	wm8775_write(sd, R19, 0x005);
-	/* Transient window 4ms, ALC min gain -5dB  */
-	wm8775_write(sd, R20, 0x0fb);
-
-	wm8775_set_audio(sd, 1);      /* set volume/mute/mux */
-
+	/* Transient window 4ms, lower PGA gain limit -1dB */
+	wm8775_write(sd, R20, 0x07a);
+	/* LRBOTH = 1, use input 2. */
+	wm8775_write(sd, R21, 0x102);
 	return 0;
 	return 0;
 }
 }
 
 

+ 10 - 0
drivers/net/atlx/atl1.c

@@ -3504,6 +3504,8 @@ static int atl1_set_ringparam(struct net_device *netdev,
 	struct atl1_rfd_ring rfd_old, rfd_new;
 	struct atl1_rfd_ring rfd_old, rfd_new;
 	struct atl1_rrd_ring rrd_old, rrd_new;
 	struct atl1_rrd_ring rrd_old, rrd_new;
 	struct atl1_ring_header rhdr_old, rhdr_new;
 	struct atl1_ring_header rhdr_old, rhdr_new;
+	struct atl1_smb smb;
+	struct atl1_cmb cmb;
 	int err;
 	int err;
 
 
 	tpd_old = adapter->tpd_ring;
 	tpd_old = adapter->tpd_ring;
@@ -3544,11 +3546,19 @@ static int atl1_set_ringparam(struct net_device *netdev,
 		adapter->rrd_ring = rrd_old;
 		adapter->rrd_ring = rrd_old;
 		adapter->tpd_ring = tpd_old;
 		adapter->tpd_ring = tpd_old;
 		adapter->ring_header = rhdr_old;
 		adapter->ring_header = rhdr_old;
+		/*
+		 * Save SMB and CMB, since atl1_free_ring_resources
+		 * will clear them.
+		 */
+		smb = adapter->smb;
+		cmb = adapter->cmb;
 		atl1_free_ring_resources(adapter);
 		atl1_free_ring_resources(adapter);
 		adapter->rfd_ring = rfd_new;
 		adapter->rfd_ring = rfd_new;
 		adapter->rrd_ring = rrd_new;
 		adapter->rrd_ring = rrd_new;
 		adapter->tpd_ring = tpd_new;
 		adapter->tpd_ring = tpd_new;
 		adapter->ring_header = rhdr_new;
 		adapter->ring_header = rhdr_new;
+		adapter->smb = smb;
+		adapter->cmb = cmb;
 
 
 		err = atl1_up(adapter);
 		err = atl1_up(adapter);
 		if (err)
 		if (err)

+ 8 - 2
drivers/net/cnic.c

@@ -940,7 +940,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
 					   &udev->l2_ring_map,
 					   &udev->l2_ring_map,
 					   GFP_KERNEL | __GFP_COMP);
 					   GFP_KERNEL | __GFP_COMP);
 	if (!udev->l2_ring)
 	if (!udev->l2_ring)
-		return -ENOMEM;
+		goto err_udev;
 
 
 	udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
 	udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size;
 	udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size);
 	udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size);
@@ -948,7 +948,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
 					  &udev->l2_buf_map,
 					  &udev->l2_buf_map,
 					  GFP_KERNEL | __GFP_COMP);
 					  GFP_KERNEL | __GFP_COMP);
 	if (!udev->l2_buf)
 	if (!udev->l2_buf)
-		return -ENOMEM;
+		goto err_dma;
 
 
 	write_lock(&cnic_dev_lock);
 	write_lock(&cnic_dev_lock);
 	list_add(&udev->list, &cnic_udev_list);
 	list_add(&udev->list, &cnic_udev_list);
@@ -959,6 +959,12 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages)
 	cp->udev = udev;
 	cp->udev = udev;
 
 
 	return 0;
 	return 0;
+ err_dma:
+	dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size,
+			  udev->l2_ring, udev->l2_ring_map);
+ err_udev:
+	kfree(udev);
+	return -ENOMEM;
 }
 }
 
 
 static int cnic_init_uio(struct cnic_dev *dev)
 static int cnic_init_uio(struct cnic_dev *dev)

+ 7 - 0
drivers/net/ehea/ehea_ethtool.c

@@ -263,6 +263,13 @@ static void ehea_get_ethtool_stats(struct net_device *dev,
 
 
 static int ehea_set_flags(struct net_device *dev, u32 data)
 static int ehea_set_flags(struct net_device *dev, u32 data)
 {
 {
+	/* Avoid changing the VLAN flags */
+	if ((data & (ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN)) !=
+	    (ethtool_op_get_flags(dev) & (ETH_FLAG_RXVLAN |
+					  ETH_FLAG_TXVLAN))){
+		return -EINVAL;
+	}
+
 	return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
 	return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
 					| ETH_FLAG_TXVLAN
 					| ETH_FLAG_TXVLAN
 					| ETH_FLAG_RXVLAN);
 					| ETH_FLAG_RXVLAN);

+ 7 - 2
drivers/net/ppp_generic.c

@@ -1285,6 +1285,11 @@ ppp_push(struct ppp *ppp)
 }
 }
 
 
 #ifdef CONFIG_PPP_MULTILINK
 #ifdef CONFIG_PPP_MULTILINK
+static bool mp_protocol_compress __read_mostly = true;
+module_param(mp_protocol_compress, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(mp_protocol_compress,
+		 "compress protocol id in multilink fragments");
+
 /*
 /*
  * Divide a packet to be transmitted into fragments and
  * Divide a packet to be transmitted into fragments and
  * send them out the individual links.
  * send them out the individual links.
@@ -1347,10 +1352,10 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb)
 	if (nfree == 0 || nfree < navail / 2)
 	if (nfree == 0 || nfree < navail / 2)
 		return 0; /* can't take now, leave it in xmit_pending */
 		return 0; /* can't take now, leave it in xmit_pending */
 
 
-	/* Do protocol field compression (XXX this should be optional) */
+	/* Do protocol field compression */
 	p = skb->data;
 	p = skb->data;
 	len = skb->len;
 	len = skb->len;
-	if (*p == 0) {
+	if (*p == 0 && mp_protocol_compress) {
 		++p;
 		++p;
 		--len;
 		--len;
 	}
 	}

+ 1 - 1
drivers/net/skfp/skfddi.c

@@ -412,7 +412,7 @@ static  int skfp_driver_init(struct net_device *dev)
 		bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev,
 		bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev,
 							 bp->SharedMemSize,
 							 bp->SharedMemSize,
 							 &bp->SharedMemDMA);
 							 &bp->SharedMemDMA);
-		if (!bp->SharedMemSize) {
+		if (!bp->SharedMemAddr) {
 			printk("could not allocate mem for ");
 			printk("could not allocate mem for ");
 			printk("hardware module: %ld byte\n",
 			printk("hardware module: %ld byte\n",
 			       bp->SharedMemSize);
 			       bp->SharedMemSize);

+ 1 - 1
drivers/net/starfire.c

@@ -148,7 +148,7 @@ static int full_duplex[MAX_UNITS] = {0, };
  * This SUCKS.
  * This SUCKS.
  * We need a much better method to determine if dma_addr_t is 64-bit.
  * We need a much better method to determine if dma_addr_t is 64-bit.
  */
  */
-#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT))
+#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || (defined(CONFIG_MIPS) && ((defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || defined(CONFIG_64BIT))) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT))
 /* 64-bit dma_addr_t */
 /* 64-bit dma_addr_t */
 #define ADDR_64BITS	/* This chip uses 64 bit addresses. */
 #define ADDR_64BITS	/* This chip uses 64 bit addresses. */
 #define netdrv_addr_t __le64
 #define netdrv_addr_t __le64

+ 1 - 1
drivers/net/tg3.c

@@ -12658,7 +12658,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp)
 			cnt = pci_read_vpd(tp->pdev, pos,
 			cnt = pci_read_vpd(tp->pdev, pos,
 					   TG3_NVM_VPD_LEN - pos,
 					   TG3_NVM_VPD_LEN - pos,
 					   &vpd_data[pos]);
 					   &vpd_data[pos]);
-			if (cnt == -ETIMEDOUT || -EINTR)
+			if (cnt == -ETIMEDOUT || cnt == -EINTR)
 				cnt = 0;
 				cnt = 0;
 			else if (cnt < 0)
 			else if (cnt < 0)
 				goto out_not_found;
 				goto out_not_found;

+ 33 - 3
drivers/platform/x86/intel_ips.c

@@ -75,6 +75,7 @@
 #include <drm/i915_drm.h>
 #include <drm/i915_drm.h>
 #include <asm/msr.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
 #include <asm/processor.h>
+#include "intel_ips.h"
 
 
 #define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32
 #define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32
 
 
@@ -245,6 +246,7 @@
 #define thm_writel(off, val) writel((val), ips->regmap + (off))
 #define thm_writel(off, val) writel((val), ips->regmap + (off))
 
 
 static const int IPS_ADJUST_PERIOD = 5000; /* ms */
 static const int IPS_ADJUST_PERIOD = 5000; /* ms */
+static bool late_i915_load = false;
 
 
 /* For initial average collection */
 /* For initial average collection */
 static const int IPS_SAMPLE_PERIOD = 200; /* ms */
 static const int IPS_SAMPLE_PERIOD = 200; /* ms */
@@ -339,6 +341,9 @@ struct ips_driver {
 	u64 orig_turbo_ratios;
 	u64 orig_turbo_ratios;
 };
 };
 
 
+static bool
+ips_gpu_turbo_enabled(struct ips_driver *ips);
+
 /**
 /**
  * ips_cpu_busy - is CPU busy?
  * ips_cpu_busy - is CPU busy?
  * @ips: IPS driver struct
  * @ips: IPS driver struct
@@ -517,7 +522,7 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips)
  */
  */
 static bool ips_gpu_busy(struct ips_driver *ips)
 static bool ips_gpu_busy(struct ips_driver *ips)
 {
 {
-	if (!ips->gpu_turbo_enabled)
+	if (!ips_gpu_turbo_enabled(ips))
 		return false;
 		return false;
 
 
 	return ips->gpu_busy();
 	return ips->gpu_busy();
@@ -532,7 +537,7 @@ static bool ips_gpu_busy(struct ips_driver *ips)
  */
  */
 static void ips_gpu_raise(struct ips_driver *ips)
 static void ips_gpu_raise(struct ips_driver *ips)
 {
 {
-	if (!ips->gpu_turbo_enabled)
+	if (!ips_gpu_turbo_enabled(ips))
 		return;
 		return;
 
 
 	if (!ips->gpu_raise())
 	if (!ips->gpu_raise())
@@ -549,7 +554,7 @@ static void ips_gpu_raise(struct ips_driver *ips)
  */
  */
 static void ips_gpu_lower(struct ips_driver *ips)
 static void ips_gpu_lower(struct ips_driver *ips)
 {
 {
-	if (!ips->gpu_turbo_enabled)
+	if (!ips_gpu_turbo_enabled(ips))
 		return;
 		return;
 
 
 	if (!ips->gpu_lower())
 	if (!ips->gpu_lower())
@@ -1454,6 +1459,31 @@ out_err:
 	return false;
 	return false;
 }
 }
 
 
+static bool
+ips_gpu_turbo_enabled(struct ips_driver *ips)
+{
+	if (!ips->gpu_busy && late_i915_load) {
+		if (ips_get_i915_syms(ips)) {
+			dev_info(&ips->dev->dev,
+				 "i915 driver attached, reenabling gpu turbo\n");
+			ips->gpu_turbo_enabled = !(thm_readl(THM_HTS) & HTS_GTD_DIS);
+		}
+	}
+
+	return ips->gpu_turbo_enabled;
+}
+
+void
+ips_link_to_i915_driver()
+{
+	/* We can't cleanly get at the various ips_driver structs from
+	 * this caller (the i915 driver), so just set a flag saying
+	 * that it's time to try getting the symbols again.
+	 */
+	late_i915_load = true;
+}
+EXPORT_SYMBOL_GPL(ips_link_to_i915_driver);
+
 static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = {
 static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
 		     PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), },
 		     PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), },

+ 21 - 0
drivers/platform/x86/intel_ips.h

@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+void ips_link_to_i915_driver(void);

+ 1 - 1
drivers/spi/coldfire_qspi.c

@@ -317,7 +317,7 @@ static void mcfqspi_work(struct work_struct *work)
 		msg = container_of(mcfqspi->msgq.next, struct spi_message,
 		msg = container_of(mcfqspi->msgq.next, struct spi_message,
 				   queue);
 				   queue);
 
 
-		list_del_init(&mcfqspi->msgq);
+		list_del_init(&msg->queue);
 		spin_unlock_irqrestore(&mcfqspi->lock, flags);
 		spin_unlock_irqrestore(&mcfqspi->lock, flags);
 
 
 		spi = msg->spi;
 		spi = msg->spi;

+ 39 - 0
drivers/spi/omap2_mcspi.c

@@ -1305,10 +1305,49 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
 /* work with hotplug and coldplug */
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:omap2_mcspi");
 MODULE_ALIAS("platform:omap2_mcspi");
 
 
+#ifdef	CONFIG_SUSPEND
+/*
+ * When SPI wake up from off-mode, CS is in activate state. If it was in
+ * unactive state when driver was suspend, then force it to unactive state at
+ * wake up.
+ */
+static int omap2_mcspi_resume(struct device *dev)
+{
+	struct spi_master	*master = dev_get_drvdata(dev);
+	struct omap2_mcspi	*mcspi = spi_master_get_devdata(master);
+	struct omap2_mcspi_cs *cs;
+
+	omap2_mcspi_enable_clocks(mcspi);
+	list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs,
+			    node) {
+		if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) {
+
+			/*
+			 * We need to toggle CS state for OMAP take this
+			 * change in account.
+			 */
+			MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1);
+			__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+			MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0);
+			__raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0);
+		}
+	}
+	omap2_mcspi_disable_clocks(mcspi);
+	return 0;
+}
+#else
+#define	omap2_mcspi_resume	NULL
+#endif
+
+static const struct dev_pm_ops omap2_mcspi_pm_ops = {
+	.resume = omap2_mcspi_resume,
+};
+
 static struct platform_driver omap2_mcspi_driver = {
 static struct platform_driver omap2_mcspi_driver = {
 	.driver = {
 	.driver = {
 		.name =		"omap2_mcspi",
 		.name =		"omap2_mcspi",
 		.owner =	THIS_MODULE,
 		.owner =	THIS_MODULE,
+		.pm =		&omap2_mcspi_pm_ops
 	},
 	},
 	.remove =	__exit_p(omap2_mcspi_remove),
 	.remove =	__exit_p(omap2_mcspi_remove),
 };
 };

+ 0 - 6
drivers/staging/zram/zram_drv.c

@@ -435,12 +435,6 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio)
 	int ret = 0;
 	int ret = 0;
 	struct zram *zram = queue->queuedata;
 	struct zram *zram = queue->queuedata;
 
 
-	if (unlikely(!zram->init_done)) {
-		set_bit(BIO_UPTODATE, &bio->bi_flags);
-		bio_endio(bio, 0);
-		return 0;
-	}
-
 	if (!valid_io_request(zram, bio)) {
 	if (!valid_io_request(zram, bio)) {
 		zram_stat64_inc(zram, &zram->stats.invalid_io);
 		zram_stat64_inc(zram, &zram->stats.invalid_io);
 		bio_io_error(bio);
 		bio_io_error(bio);

+ 19 - 3
drivers/usb/atm/ueagle-atm.c

@@ -2206,8 +2206,11 @@ static int uea_boot(struct uea_softc *sc)
 		goto err1;
 		goto err1;
 	}
 	}
 
 
-	sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm");
-	if (sc->kthread == ERR_PTR(-ENOMEM)) {
+	/* Create worker thread, but don't start it here.  Start it after
+	 * all usbatm generic initialization is done.
+	 */
+	sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm");
+	if (IS_ERR(sc->kthread)) {
 		uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
 		uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");
 		goto err2;
 		goto err2;
 	}
 	}
@@ -2624,6 +2627,7 @@ static struct usbatm_driver uea_usbatm_driver = {
 static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
 static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
 {
 	struct usb_device *usb = interface_to_usbdev(intf);
 	struct usb_device *usb = interface_to_usbdev(intf);
+	int ret;
 
 
 	uea_enters(usb);
 	uea_enters(usb);
 	uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n",
 	uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n",
@@ -2637,7 +2641,19 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
 	if (UEA_IS_PREFIRM(id))
 	if (UEA_IS_PREFIRM(id))
 		return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
 		return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
 
 
-	return usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+	ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver);
+	if (ret == 0) {
+		struct usbatm_data *usbatm = usb_get_intfdata(intf);
+		struct uea_softc *sc = usbatm->driver_data;
+
+		/* Ensure carrier is initialized to off as early as possible */
+		UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST);
+
+		/* Only start the worker thread when all init is done */
+		wake_up_process(sc->kthread);
+	}
+
+	return ret;
 }
 }
 
 
 static void uea_disconnect(struct usb_interface *intf)
 static void uea_disconnect(struct usb_interface *intf)

+ 10 - 3
include/linux/dmaengine.h

@@ -824,6 +824,8 @@ enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie);
 #ifdef CONFIG_DMA_ENGINE
 #ifdef CONFIG_DMA_ENGINE
 enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
 enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx);
 void dma_issue_pending_all(void);
 void dma_issue_pending_all(void);
+struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param);
+void dma_release_channel(struct dma_chan *chan);
 #else
 #else
 static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
 static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx)
 {
 {
@@ -831,7 +833,14 @@ static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descript
 }
 }
 static inline void dma_issue_pending_all(void)
 static inline void dma_issue_pending_all(void)
 {
 {
-	do { } while (0);
+}
+static inline struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask,
+					      dma_filter_fn fn, void *fn_param)
+{
+	return NULL;
+}
+static inline void dma_release_channel(struct dma_chan *chan)
+{
 }
 }
 #endif
 #endif
 
 
@@ -842,8 +851,6 @@ void dma_async_device_unregister(struct dma_device *device);
 void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
 void dma_run_dependencies(struct dma_async_tx_descriptor *tx);
 struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type);
 struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type);
 #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y)
 #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y)
-struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param);
-void dma_release_channel(struct dma_chan *chan);
 
 
 /* --- Helper iov-locking functions --- */
 /* --- Helper iov-locking functions --- */
 
 

+ 0 - 3
include/media/wm8775.h

@@ -32,7 +32,4 @@
 #define WM8775_AIN3 4
 #define WM8775_AIN3 4
 #define WM8775_AIN4 8
 #define WM8775_AIN4 8
 
 
-/* subdev group ID */
-#define WM8775_GID (1 << 0)
-
 #endif
 #endif

+ 1 - 1
init/do_mounts.c

@@ -93,7 +93,7 @@ no_match:
  *
  *
  * Returns the matching dev_t on success or 0 on failure.
  * Returns the matching dev_t on success or 0 on failure.
  */
  */
-static dev_t __init devt_from_partuuid(char *uuid_str)
+static dev_t devt_from_partuuid(char *uuid_str)
 {
 {
 	dev_t res = 0;
 	dev_t res = 0;
 	struct device *dev = NULL;
 	struct device *dev = NULL;

+ 1 - 0
kernel/user.c

@@ -158,6 +158,7 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid)
 		spin_lock_irq(&uidhash_lock);
 		spin_lock_irq(&uidhash_lock);
 		up = uid_hash_find(uid, hashent);
 		up = uid_hash_find(uid, hashent);
 		if (up) {
 		if (up) {
+			put_user_ns(ns);
 			key_put(new->uid_keyring);
 			key_put(new->uid_keyring);
 			key_put(new->session_keyring);
 			key_put(new->session_keyring);
 			kmem_cache_free(uid_cachep, new);
 			kmem_cache_free(uid_cachep, new);

+ 2 - 1
kernel/watchdog.c

@@ -366,7 +366,8 @@ static int watchdog_nmi_enable(int cpu)
 		goto out_save;
 		goto out_save;
 	}
 	}
 
 
-	printk(KERN_ERR "NMI watchdog failed to create perf event on cpu%i: %p\n", cpu, event);
+	printk(KERN_ERR "NMI watchdog disabled for cpu%i: unable to create perf event: %ld\n",
+	       cpu, PTR_ERR(event));
 	return PTR_ERR(event);
 	return PTR_ERR(event);
 
 
 	/* success path */
 	/* success path */

+ 9 - 10
mm/memcontrol.c

@@ -1925,19 +1925,18 @@ again:
 
 
 		rcu_read_lock();
 		rcu_read_lock();
 		p = rcu_dereference(mm->owner);
 		p = rcu_dereference(mm->owner);
-		VM_BUG_ON(!p);
 		/*
 		/*
-		 * because we don't have task_lock(), "p" can exit while
-		 * we're here. In that case, "mem" can point to root
-		 * cgroup but never be NULL. (and task_struct itself is freed
-		 * by RCU, cgroup itself is RCU safe.) Then, we have small
-		 * risk here to get wrong cgroup. But such kind of mis-account
-		 * by race always happens because we don't have cgroup_mutex().
-		 * It's overkill and we allow that small race, here.
+		 * Because we don't have task_lock(), "p" can exit.
+		 * In that case, "mem" can point to root or p can be NULL with
+		 * race with swapoff. Then, we have small risk of mis-accouning.
+		 * But such kind of mis-account by race always happens because
+		 * we don't have cgroup_mutex(). It's overkill and we allo that
+		 * small race, here.
+		 * (*) swapoff at el will charge against mm-struct not against
+		 * task-struct. So, mm->owner can be NULL.
 		 */
 		 */
 		mem = mem_cgroup_from_task(p);
 		mem = mem_cgroup_from_task(p);
-		VM_BUG_ON(!mem);
-		if (mem_cgroup_is_root(mem)) {
+		if (!mem || mem_cgroup_is_root(mem)) {
 			rcu_read_unlock();
 			rcu_read_unlock();
 			goto done;
 			goto done;
 		}
 		}

+ 18 - 10
net/bridge/br_multicast.c

@@ -1430,7 +1430,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
 				 struct net_bridge_port *port,
 				 struct net_bridge_port *port,
 				 struct sk_buff *skb)
 				 struct sk_buff *skb)
 {
 {
-	struct sk_buff *skb2 = skb;
+	struct sk_buff *skb2;
 	struct ipv6hdr *ip6h;
 	struct ipv6hdr *ip6h;
 	struct icmp6hdr *icmp6h;
 	struct icmp6hdr *icmp6h;
 	u8 nexthdr;
 	u8 nexthdr;
@@ -1469,15 +1469,15 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
 	if (!skb2)
 	if (!skb2)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
+	err = -EINVAL;
+	if (!pskb_may_pull(skb2, offset + sizeof(struct icmp6hdr)))
+		goto out;
+
 	len -= offset - skb_network_offset(skb2);
 	len -= offset - skb_network_offset(skb2);
 
 
 	__skb_pull(skb2, offset);
 	__skb_pull(skb2, offset);
 	skb_reset_transport_header(skb2);
 	skb_reset_transport_header(skb2);
 
 
-	err = -EINVAL;
-	if (!pskb_may_pull(skb2, sizeof(*icmp6h)))
-		goto out;
-
 	icmp6h = icmp6_hdr(skb2);
 	icmp6h = icmp6_hdr(skb2);
 
 
 	switch (icmp6h->icmp6_type) {
 	switch (icmp6h->icmp6_type) {
@@ -1516,7 +1516,12 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
 	switch (icmp6h->icmp6_type) {
 	switch (icmp6h->icmp6_type) {
 	case ICMPV6_MGM_REPORT:
 	case ICMPV6_MGM_REPORT:
 	    {
 	    {
-		struct mld_msg *mld = (struct mld_msg *)icmp6h;
+		struct mld_msg *mld;
+		if (!pskb_may_pull(skb2, sizeof(*mld))) {
+			err = -EINVAL;
+			goto out;
+		}
+		mld = (struct mld_msg *)skb_transport_header(skb2);
 		BR_INPUT_SKB_CB(skb2)->mrouters_only = 1;
 		BR_INPUT_SKB_CB(skb2)->mrouters_only = 1;
 		err = br_ip6_multicast_add_group(br, port, &mld->mld_mca);
 		err = br_ip6_multicast_add_group(br, port, &mld->mld_mca);
 		break;
 		break;
@@ -1529,15 +1534,18 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
 		break;
 		break;
 	case ICMPV6_MGM_REDUCTION:
 	case ICMPV6_MGM_REDUCTION:
 	    {
 	    {
-		struct mld_msg *mld = (struct mld_msg *)icmp6h;
+		struct mld_msg *mld;
+		if (!pskb_may_pull(skb2, sizeof(*mld))) {
+			err = -EINVAL;
+			goto out;
+		}
+		mld = (struct mld_msg *)skb_transport_header(skb2);
 		br_ip6_multicast_leave_group(br, port, &mld->mld_mca);
 		br_ip6_multicast_leave_group(br, port, &mld->mld_mca);
 	    }
 	    }
 	}
 	}
 
 
 out:
 out:
-	__skb_push(skb2, offset);
-	if (skb2 != skb)
-		kfree_skb(skb2);
+	kfree_skb(skb2);
 	return err;
 	return err;
 }
 }
 #endif
 #endif

+ 2 - 0
net/bridge/br_stp_bpdu.c

@@ -50,6 +50,8 @@ static void br_send_bpdu(struct net_bridge_port *p,
 
 
 	llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr);
 	llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr);
 
 
+	skb_reset_mac_header(skb);
+
 	NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
 	NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
 		dev_queue_xmit);
 		dev_queue_xmit);
 }
 }

+ 2 - 2
net/can/bcm.c

@@ -125,7 +125,7 @@ struct bcm_sock {
 	struct list_head tx_ops;
 	struct list_head tx_ops;
 	unsigned long dropped_usr_msgs;
 	unsigned long dropped_usr_msgs;
 	struct proc_dir_entry *bcm_proc_read;
 	struct proc_dir_entry *bcm_proc_read;
-	char procname [20]; /* pointer printed in ASCII with \0 */
+	char procname [32]; /* inode number in decimal with \0 */
 };
 };
 
 
 static inline struct bcm_sock *bcm_sk(const struct sock *sk)
 static inline struct bcm_sock *bcm_sk(const struct sock *sk)
@@ -1521,7 +1521,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
 
 
 	if (proc_dir) {
 	if (proc_dir) {
 		/* unique socket address as filename */
 		/* unique socket address as filename */
-		sprintf(bo->procname, "%p", sock);
+		sprintf(bo->procname, "%lu", sock_i_ino(sk));
 		bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
 		bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
 						     proc_dir,
 						     proc_dir,
 						     &bcm_proc_fops, sk);
 						     &bcm_proc_fops, sk);

+ 6 - 2
net/ipv4/route.c

@@ -2649,8 +2649,12 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
 	}
 	}
 
 
 	if (res.type == RTN_LOCAL) {
 	if (res.type == RTN_LOCAL) {
-		if (!fl.fl4_src)
-			fl.fl4_src = fl.fl4_dst;
+		if (!fl.fl4_src) {
+			if (res.fi->fib_prefsrc)
+				fl.fl4_src = res.fi->fib_prefsrc;
+			else
+				fl.fl4_src = fl.fl4_dst;
+		}
 		dev_out = net->loopback_dev;
 		dev_out = net->loopback_dev;
 		fl.oif = dev_out->ifindex;
 		fl.oif = dev_out->ifindex;
 		res.fi = NULL;
 		res.fi = NULL;

+ 14 - 0
scripts/kconfig/menu.c

@@ -140,6 +140,20 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
 		}
 		}
 		if (current_entry->prompt && current_entry != &rootmenu)
 		if (current_entry->prompt && current_entry != &rootmenu)
 			prop_warn(prop, "prompt redefined");
 			prop_warn(prop, "prompt redefined");
+
+		/* Apply all upper menus' visibilities to actual prompts. */
+		if(type == P_PROMPT) {
+			struct menu *menu = current_entry;
+
+			while ((menu = menu->parent) != NULL) {
+				if (!menu->visibility)
+					continue;
+				prop->visible.expr
+					= expr_alloc_and(prop->visible.expr,
+							 menu->visibility);
+			}
+		}
+
 		current_entry->prompt = prop;
 		current_entry->prompt = prop;
 	}
 	}
 	prop->text = prompt;
 	prop->text = prompt;

+ 2 - 0
security/integrity/ima/ima_policy.c

@@ -253,6 +253,8 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry,
 	result = security_filter_rule_init(entry->lsm[lsm_rule].type,
 	result = security_filter_rule_init(entry->lsm[lsm_rule].type,
 					   Audit_equal, args,
 					   Audit_equal, args,
 					   &entry->lsm[lsm_rule].rule);
 					   &entry->lsm[lsm_rule].rule);
+	if (!entry->lsm[lsm_rule].rule)
+		return -EINVAL;
 	return result;
 	return result;
 }
 }
 
 

+ 2 - 2
sound/oss/soundcard.c

@@ -87,7 +87,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
 	int             i, n;
 	int             i, n;
 
 
 	for (i = 0; i < num_mixer_volumes; i++) {
 	for (i = 0; i < num_mixer_volumes; i++) {
-		if (strcmp(name, mixer_vols[i].name) == 0) {
+		if (strncmp(name, mixer_vols[i].name, 32) == 0) {
 			if (present)
 			if (present)
 				mixer_vols[i].num = i;
 				mixer_vols[i].num = i;
 			return mixer_vols[i].levels;
 			return mixer_vols[i].levels;
@@ -99,7 +99,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
 	}
 	}
 	n = num_mixer_volumes++;
 	n = num_mixer_volumes++;
 
 
-	strcpy(mixer_vols[n].name, name);
+	strncpy(mixer_vols[n].name, name, 32);
 
 
 	if (present)
 	if (present)
 		mixer_vols[n].num = n;
 		mixer_vols[n].num = n;

+ 1 - 0
sound/pci/hda/hda_intel.c

@@ -2300,6 +2300,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
 	SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
+	SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
 	SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),

+ 4 - 6
sound/soc/codecs/max98088.c

@@ -40,7 +40,6 @@ struct max98088_cdata {
 };
 };
 
 
 struct max98088_priv {
 struct max98088_priv {
-       u8 reg_cache[M98088_REG_CNT];
        enum max98088_type devtype;
        enum max98088_type devtype;
        void *control_data;
        void *control_data;
        struct max98088_pdata *pdata;
        struct max98088_pdata *pdata;
@@ -1588,7 +1587,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai,
 
 
 static void max98088_sync_cache(struct snd_soc_codec *codec)
 static void max98088_sync_cache(struct snd_soc_codec *codec)
 {
 {
-       struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec);
+       u16 *reg_cache = codec->reg_cache;
        int i;
        int i;
 
 
        if (!codec->cache_sync)
        if (!codec->cache_sync)
@@ -1599,14 +1598,14 @@ static void max98088_sync_cache(struct snd_soc_codec *codec)
        /* write back cached values if they're writeable and
        /* write back cached values if they're writeable and
         * different from the hardware default.
         * different from the hardware default.
         */
         */
-       for (i = 1; i < ARRAY_SIZE(max98088->reg_cache); i++) {
+       for (i = 1; i < codec->driver->reg_cache_size; i++) {
                if (!max98088_access[i].writable)
                if (!max98088_access[i].writable)
                        continue;
                        continue;
 
 
-               if (max98088->reg_cache[i] == max98088_reg[i])
+               if (reg_cache[i] == max98088_reg[i])
                        continue;
                        continue;
 
 
-               snd_soc_write(codec, i, max98088->reg_cache[i]);
+               snd_soc_write(codec, i, reg_cache[i]);
        }
        }
 
 
        codec->cache_sync = 0;
        codec->cache_sync = 0;
@@ -1951,7 +1950,6 @@ static int max98088_probe(struct snd_soc_codec *codec)
        int ret = 0;
        int ret = 0;
 
 
        codec->cache_sync = 1;
        codec->cache_sync = 1;
-       memcpy(codec->reg_cache, max98088_reg, sizeof(max98088_reg));
 
 
        ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
        ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
        if (ret != 0) {
        if (ret != 0) {

+ 5 - 4
sound/soc/codecs/wm8523.c

@@ -41,7 +41,6 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
 /* codec private data */
 /* codec private data */
 struct wm8523_priv {
 struct wm8523_priv {
 	enum snd_soc_control_type control_type;
 	enum snd_soc_control_type control_type;
-	u16 reg_cache[WM8523_REGISTER_COUNT];
 	struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
 	struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
 	unsigned int sysclk;
 	unsigned int sysclk;
 	unsigned int rate_constraint_list[WM8523_NUM_RATES];
 	unsigned int rate_constraint_list[WM8523_NUM_RATES];
@@ -314,6 +313,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 				 enum snd_soc_bias_level level)
 {
 {
 	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
 	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+	u16 *reg_cache = codec->reg_cache;
 	int ret, i;
 	int ret, i;
 
 
 	switch (level) {
 	switch (level) {
@@ -344,7 +344,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
 			/* Sync back default/cached values */
 			/* Sync back default/cached values */
 			for (i = WM8523_AIF_CTRL1;
 			for (i = WM8523_AIF_CTRL1;
 			     i < WM8523_MAX_REGISTER; i++)
 			     i < WM8523_MAX_REGISTER; i++)
-				snd_soc_write(codec, i, wm8523->reg_cache[i]);
+				snd_soc_write(codec, i, reg_cache[i]);
 
 
 
 
 			msleep(100);
 			msleep(100);
@@ -414,6 +414,7 @@ static int wm8523_resume(struct snd_soc_codec *codec)
 static int wm8523_probe(struct snd_soc_codec *codec)
 static int wm8523_probe(struct snd_soc_codec *codec)
 {
 {
 	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
 	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
+	u16 *reg_cache = codec->reg_cache;
 	int ret, i;
 	int ret, i;
 
 
 	codec->hw_write = (hw_write_t)i2c_master_send;
 	codec->hw_write = (hw_write_t)i2c_master_send;
@@ -470,8 +471,8 @@ static int wm8523_probe(struct snd_soc_codec *codec)
 	}
 	}
 
 
 	/* Change some default settings - latch VU and enable ZC */
 	/* Change some default settings - latch VU and enable ZC */
-	wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
-	wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
+	reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
+	reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
 
 
 	wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 	wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
 

+ 5 - 5
sound/soc/codecs/wm8741.c

@@ -41,7 +41,6 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
 /* codec private data */
 /* codec private data */
 struct wm8741_priv {
 struct wm8741_priv {
 	enum snd_soc_control_type control_type;
 	enum snd_soc_control_type control_type;
-	u16 reg_cache[WM8741_REGISTER_COUNT];
 	struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
 	struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
 	unsigned int sysclk;
 	unsigned int sysclk;
 	struct snd_pcm_hw_constraint_list *sysclk_constraints;
 	struct snd_pcm_hw_constraint_list *sysclk_constraints;
@@ -422,6 +421,7 @@ static int wm8741_resume(struct snd_soc_codec *codec)
 static int wm8741_probe(struct snd_soc_codec *codec)
 static int wm8741_probe(struct snd_soc_codec *codec)
 {
 {
 	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
 	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
+	u16 *reg_cache = codec->reg_cache;
 	int ret = 0;
 	int ret = 0;
 
 
 	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
 	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
@@ -437,10 +437,10 @@ static int wm8741_probe(struct snd_soc_codec *codec)
 	}
 	}
 
 
 	/* Change some default settings - latch VU */
 	/* Change some default settings - latch VU */
-	wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
-	wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
-	wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
-	wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
+	reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL;
+	reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM;
+	reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL;
+	reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM;
 
 
 	snd_soc_add_controls(codec, wm8741_snd_controls,
 	snd_soc_add_controls(codec, wm8741_snd_controls,
 			     ARRAY_SIZE(wm8741_snd_controls));
 			     ARRAY_SIZE(wm8741_snd_controls));

+ 83 - 143
sound/soc/codecs/wm8753.c

@@ -65,22 +65,22 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
  * are using 2 wire for device control, so we cache them instead.
  * are using 2 wire for device control, so we cache them instead.
  */
  */
 static const u16 wm8753_reg[] = {
 static const u16 wm8753_reg[] = {
-	0x0008, 0x0000, 0x000a, 0x000a,
-	0x0033, 0x0000, 0x0007, 0x00ff,
-	0x00ff, 0x000f, 0x000f, 0x007b,
-	0x0000, 0x0032, 0x0000, 0x00c3,
-	0x00c3, 0x00c0, 0x0000, 0x0000,
+	0x0000, 0x0008, 0x0000, 0x000a,
+	0x000a, 0x0033, 0x0000, 0x0007,
+	0x00ff, 0x00ff, 0x000f, 0x000f,
+	0x007b, 0x0000, 0x0032, 0x0000,
+	0x00c3, 0x00c3, 0x00c0, 0x0000,
 	0x0000, 0x0000, 0x0000, 0x0000,
 	0x0000, 0x0000, 0x0000, 0x0000,
 	0x0000, 0x0000, 0x0000, 0x0000,
 	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0055,
-	0x0005, 0x0050, 0x0055, 0x0050,
-	0x0055, 0x0050, 0x0055, 0x0079,
-	0x0079, 0x0079, 0x0079, 0x0079,
 	0x0000, 0x0000, 0x0000, 0x0000,
 	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0097, 0x0097, 0x0000, 0x0004,
-	0x0000, 0x0083, 0x0024, 0x01ba,
-	0x0000, 0x0083, 0x0024, 0x01ba,
-	0x0000, 0x0000, 0x0000
+	0x0055, 0x0005, 0x0050, 0x0055,
+	0x0050, 0x0055, 0x0050, 0x0055,
+	0x0079, 0x0079, 0x0079, 0x0079,
+	0x0079, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0097, 0x0097, 0x0000,
+	0x0004, 0x0000, 0x0083, 0x0024,
+	0x01ba, 0x0000, 0x0083, 0x0024,
+	0x01ba, 0x0000, 0x0000, 0x0000
 };
 };
 
 
 /* codec private data */
 /* codec private data */
@@ -88,57 +88,10 @@ struct wm8753_priv {
 	enum snd_soc_control_type control_type;
 	enum snd_soc_control_type control_type;
 	unsigned int sysclk;
 	unsigned int sysclk;
 	unsigned int pcmclk;
 	unsigned int pcmclk;
-	u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
 	int dai_func;
 	int dai_func;
 };
 };
 
 
-/*
- * read wm8753 register cache
- */
-static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
-	unsigned int reg)
-{
-	u16 *cache = codec->reg_cache;
-	if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
-		return -1;
-	return cache[reg - 1];
-}
-
-/*
- * write wm8753 register cache
- */
-static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
-	unsigned int reg, unsigned int value)
-{
-	u16 *cache = codec->reg_cache;
-	if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
-		return;
-	cache[reg - 1] = value;
-}
-
-/*
- * write to the WM8753 register space
- */
-static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg,
-	unsigned int value)
-{
-	u8 data[2];
-
-	/* data is
-	 *   D15..D9 WM8753 register offset
-	 *   D8...D0 register data
-	 */
-	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
-	data[1] = value & 0x00ff;
-
-	wm8753_write_reg_cache(codec, reg, value);
-	if (codec->hw_write(codec->control_data, data, 2) == 2)
-		return 0;
-	else
-		return -EIO;
-}
-
-#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0)
+#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
 
 
 /*
 /*
  * WM8753 Controls
  * WM8753 Controls
@@ -218,7 +171,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 	struct snd_ctl_elem_value *ucontrol)
 {
 {
 	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
 	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
-	int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+	int mode = snd_soc_read(codec, WM8753_IOCTL);
 
 
 	ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
 	ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
 	return 0;
 	return 0;
@@ -228,7 +181,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
 	struct snd_ctl_elem_value *ucontrol)
 	struct snd_ctl_elem_value *ucontrol)
 {
 {
 	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
 	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
-	int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
+	int mode = snd_soc_read(codec, WM8753_IOCTL);
 	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
 	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
 
 
 	if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
 	if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
@@ -738,17 +691,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 	if (pll_id == WM8753_PLL1) {
 	if (pll_id == WM8753_PLL1) {
 		offset = 0;
 		offset = 0;
 		enable = 0x10;
 		enable = 0x10;
-		reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef;
+		reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
 	} else {
 	} else {
 		offset = 4;
 		offset = 4;
 		enable = 0x8;
 		enable = 0x8;
-		reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7;
+		reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
 	}
 	}
 
 
 	if (!freq_in || !freq_out) {
 	if (!freq_in || !freq_out) {
 		/* disable PLL  */
 		/* disable PLL  */
-		wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
-		wm8753_write(codec, WM8753_CLOCK, reg);
+		snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
+		snd_soc_write(codec, WM8753_CLOCK, reg);
 		return 0;
 		return 0;
 	} else {
 	} else {
 		u16 value = 0;
 		u16 value = 0;
@@ -759,20 +712,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
 		/* set up N and K PLL divisor ratios */
 		/* set up N and K PLL divisor ratios */
 		/* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
 		/* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
 		value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
 		value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
-		wm8753_write(codec, WM8753_PLL1CTL2 + offset, value);
+		snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
 
 
 		/* bits 8:0 = PLL_K[17:9] */
 		/* bits 8:0 = PLL_K[17:9] */
 		value = (pll_div.k & 0x03fe00) >> 9;
 		value = (pll_div.k & 0x03fe00) >> 9;
-		wm8753_write(codec, WM8753_PLL1CTL3 + offset, value);
+		snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
 
 
 		/* bits 8:0 = PLL_K[8:0] */
 		/* bits 8:0 = PLL_K[8:0] */
 		value = pll_div.k & 0x0001ff;
 		value = pll_div.k & 0x0001ff;
-		wm8753_write(codec, WM8753_PLL1CTL4 + offset, value);
+		snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
 
 
 		/* set PLL as input and enable */
 		/* set PLL as input and enable */
-		wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
+		snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
 			(pll_div.div2 << 3));
 			(pll_div.div2 << 3));
-		wm8753_write(codec, WM8753_CLOCK, reg | enable);
+		snd_soc_write(codec, WM8753_CLOCK, reg | enable);
 	}
 	}
 	return 0;
 	return 0;
 }
 }
@@ -879,7 +832,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 		unsigned int fmt)
 {
 {
 	struct snd_soc_codec *codec = codec_dai->codec;
 	struct snd_soc_codec *codec = codec_dai->codec;
-	u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec;
+	u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
 
 
 	/* interface format */
 	/* interface format */
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -901,7 +854,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	wm8753_write(codec, WM8753_PCM, voice);
+	snd_soc_write(codec, WM8753_PCM, voice);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -922,8 +875,8 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
 	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-	u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
-	u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
+	u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
+	u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
 
 
 	/* bit size */
 	/* bit size */
 	switch (params_format(params)) {
 	switch (params_format(params)) {
@@ -943,9 +896,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
 	/* sample rate */
 	/* sample rate */
 	if (params_rate(params) * 384 == wm8753->pcmclk)
 	if (params_rate(params) * 384 == wm8753->pcmclk)
 		srate |= 0x80;
 		srate |= 0x80;
-	wm8753_write(codec, WM8753_SRATE1, srate);
+	snd_soc_write(codec, WM8753_SRATE1, srate);
 
 
-	wm8753_write(codec, WM8753_PCM, voice);
+	snd_soc_write(codec, WM8753_PCM, voice);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -958,8 +911,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	struct snd_soc_codec *codec = codec_dai->codec;
 	struct snd_soc_codec *codec = codec_dai->codec;
 	u16 voice, ioctl;
 	u16 voice, ioctl;
 
 
-	voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f;
-	ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d;
+	voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
+	ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
 
 
 	/* set master/slave audio interface */
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1013,8 +966,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	wm8753_write(codec, WM8753_PCM, voice);
-	wm8753_write(codec, WM8753_IOCTL, ioctl);
+	snd_soc_write(codec, WM8753_PCM, voice);
+	snd_soc_write(codec, WM8753_IOCTL, ioctl);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1026,16 +979,16 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
 
 
 	switch (div_id) {
 	switch (div_id) {
 	case WM8753_PCMDIV:
 	case WM8753_PCMDIV:
-		reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f;
-		wm8753_write(codec, WM8753_CLOCK, reg | div);
+		reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
+		snd_soc_write(codec, WM8753_CLOCK, reg | div);
 		break;
 		break;
 	case WM8753_BCLKDIV:
 	case WM8753_BCLKDIV:
-		reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7;
-		wm8753_write(codec, WM8753_SRATE2, reg | div);
+		reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
+		snd_soc_write(codec, WM8753_SRATE2, reg | div);
 		break;
 		break;
 	case WM8753_VXCLKDIV:
 	case WM8753_VXCLKDIV:
-		reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f;
-		wm8753_write(codec, WM8753_SRATE2, reg | div);
+		reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
+		snd_soc_write(codec, WM8753_SRATE2, reg | div);
 		break;
 		break;
 	default:
 	default:
 		return -EINVAL;
 		return -EINVAL;
@@ -1050,7 +1003,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		unsigned int fmt)
 		unsigned int fmt)
 {
 {
 	struct snd_soc_codec *codec = codec_dai->codec;
 	struct snd_soc_codec *codec = codec_dai->codec;
-	u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0;
+	u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
 
 
 	/* interface format */
 	/* interface format */
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1072,7 +1025,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	wm8753_write(codec, WM8753_HIFI, hifi);
+	snd_soc_write(codec, WM8753_HIFI, hifi);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1085,8 +1038,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	struct snd_soc_codec *codec = codec_dai->codec;
 	struct snd_soc_codec *codec = codec_dai->codec;
 	u16 ioctl, hifi;
 	u16 ioctl, hifi;
 
 
-	hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f;
-	ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae;
+	hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
+	ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
 
 
 	/* set master/slave audio interface */
 	/* set master/slave audio interface */
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1140,8 +1093,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	wm8753_write(codec, WM8753_HIFI, hifi);
-	wm8753_write(codec, WM8753_IOCTL, ioctl);
+	snd_soc_write(codec, WM8753_HIFI, hifi);
+	snd_soc_write(codec, WM8753_IOCTL, ioctl);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1162,8 +1115,8 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
 	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-	u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
-	u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
+	u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
+	u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
 	int coeff;
 	int coeff;
 
 
 	/* is digital filter coefficient valid ? */
 	/* is digital filter coefficient valid ? */
@@ -1172,7 +1125,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
 		printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
 		printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
 		return coeff;
 		return coeff;
 	}
 	}
-	wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
+	snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
 		coeff_div[coeff].usb);
 		coeff_div[coeff].usb);
 
 
 	/* bit size */
 	/* bit size */
@@ -1190,7 +1143,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
 		break;
 		break;
 	}
 	}
 
 
-	wm8753_write(codec, WM8753_HIFI, hifi);
+	snd_soc_write(codec, WM8753_HIFI, hifi);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -1201,8 +1154,8 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	u16 clock;
 	u16 clock;
 
 
 	/* set clk source as pcmclk */
 	/* set clk source as pcmclk */
-	clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
-	wm8753_write(codec, WM8753_CLOCK, clock);
+	clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
+	snd_soc_write(codec, WM8753_CLOCK, clock);
 
 
 	if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
 	if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
 		return -EINVAL;
 		return -EINVAL;
@@ -1224,8 +1177,8 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	u16 clock;
 	u16 clock;
 
 
 	/* set clk source as pcmclk */
 	/* set clk source as pcmclk */
-	clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
-	wm8753_write(codec, WM8753_CLOCK, clock);
+	clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
+	snd_soc_write(codec, WM8753_CLOCK, clock);
 
 
 	if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
 	if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
 		return -EINVAL;
 		return -EINVAL;
@@ -1239,8 +1192,8 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
 	u16 clock;
 	u16 clock;
 
 
 	/* set clk source as mclk */
 	/* set clk source as mclk */
-	clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
-	wm8753_write(codec, WM8753_CLOCK, clock | 0x4);
+	clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
+	snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
 
 
 	if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
 	if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
 		return -EINVAL;
 		return -EINVAL;
@@ -1252,19 +1205,19 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
 static int wm8753_mute(struct snd_soc_dai *dai, int mute)
 static int wm8753_mute(struct snd_soc_dai *dai, int mute)
 {
 {
 	struct snd_soc_codec *codec = dai->codec;
 	struct snd_soc_codec *codec = dai->codec;
-	u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
+	u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
 	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
 	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
 
 
 	/* the digital mute covers the HiFi and Voice DAC's on the WM8753.
 	/* the digital mute covers the HiFi and Voice DAC's on the WM8753.
 	 * make sure we check if they are not both active when we mute */
 	 * make sure we check if they are not both active when we mute */
 	if (mute && wm8753->dai_func == 1) {
 	if (mute && wm8753->dai_func == 1) {
 		if (!codec->active)
 		if (!codec->active)
-			wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
+			snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
 	} else {
 	} else {
 		if (mute)
 		if (mute)
-			wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
+			snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
 		else
 		else
-			wm8753_write(codec, WM8753_DAC, mute_reg);
+			snd_soc_write(codec, WM8753_DAC, mute_reg);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -1273,23 +1226,23 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
 static int wm8753_set_bias_level(struct snd_soc_codec *codec,
 static int wm8753_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 				 enum snd_soc_bias_level level)
 {
 {
-	u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e;
+	u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
 
 
 	switch (level) {
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 	case SND_SOC_BIAS_ON:
 		/* set vmid to 50k and unmute dac */
 		/* set vmid to 50k and unmute dac */
-		wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
+		snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
 		break;
 		break;
 	case SND_SOC_BIAS_PREPARE:
 	case SND_SOC_BIAS_PREPARE:
 		/* set vmid to 5k for quick power up */
 		/* set vmid to 5k for quick power up */
-		wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
+		snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
 		break;
 		break;
 	case SND_SOC_BIAS_STANDBY:
 	case SND_SOC_BIAS_STANDBY:
 		/* mute dac and set vmid to 500k, enable VREF */
 		/* mute dac and set vmid to 500k, enable VREF */
-		wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
+		snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
 		break;
 		break;
 	case SND_SOC_BIAS_OFF:
 	case SND_SOC_BIAS_OFF:
-		wm8753_write(codec, WM8753_PWR1, 0x0001);
+		snd_soc_write(codec, WM8753_PWR1, 0x0001);
 		break;
 		break;
 	}
 	}
 	codec->bias_level = level;
 	codec->bias_level = level;
@@ -1477,7 +1430,7 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
 		else
 		else
 			dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
 			dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
 	}
 	}
-	wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func);
+	snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
 }
 }
 
 
 static void wm8753_work(struct work_struct *work)
 static void wm8753_work(struct work_struct *work)
@@ -1495,22 +1448,19 @@ static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
 
 static int wm8753_resume(struct snd_soc_codec *codec)
 static int wm8753_resume(struct snd_soc_codec *codec)
 {
 {
+	u16 *reg_cache = codec->reg_cache;
 	int i;
 	int i;
-	u8 data[2];
-	u16 *cache = codec->reg_cache;
 
 
 	/* Sync reg_cache with the hardware */
 	/* Sync reg_cache with the hardware */
-	for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
-		if (i + 1 == WM8753_RESET)
+	for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
+		if (i == WM8753_RESET)
 			continue;
 			continue;
 
 
 		/* No point in writing hardware default values back */
 		/* No point in writing hardware default values back */
-		if (cache[i] == wm8753_reg[i])
+		if (reg_cache[i] == wm8753_reg[i])
 			continue;
 			continue;
 
 
-		data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
-		data[1] = cache[i] & 0x00ff;
-		codec->hw_write(codec->control_data, data, 2);
+		snd_soc_write(codec, i, reg_cache[i]);
 	}
 	}
 
 
 	wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 	wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1548,7 +1498,7 @@ static int run_delayed_work(struct delayed_work *dwork)
 static int wm8753_probe(struct snd_soc_codec *codec)
 static int wm8753_probe(struct snd_soc_codec *codec)
 {
 {
 	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
 	struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
-	int ret = 0, reg;
+	int ret;
 
 
 	INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
 	INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
 
 
@@ -1573,26 +1523,16 @@ static int wm8753_probe(struct snd_soc_codec *codec)
 			      msecs_to_jiffies(caps_charge));
 			      msecs_to_jiffies(caps_charge));
 
 
 	/* set the update bits */
 	/* set the update bits */
-	reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
-	wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
-	reg = wm8753_read_reg_cache(codec, WM8753_RDAC);
-	wm8753_write(codec, WM8753_RDAC, reg | 0x0100);
-	reg = wm8753_read_reg_cache(codec, WM8753_LADC);
-	wm8753_write(codec, WM8753_LADC, reg | 0x0100);
-	reg = wm8753_read_reg_cache(codec, WM8753_RADC);
-	wm8753_write(codec, WM8753_RADC, reg | 0x0100);
-	reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V);
-	wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100);
-	reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V);
-	wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100);
-	reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V);
-	wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100);
-	reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V);
-	wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100);
-	reg = wm8753_read_reg_cache(codec, WM8753_LINVOL);
-	wm8753_write(codec, WM8753_LINVOL, reg | 0x0100);
-	reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
-	wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
+	snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
+	snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
+	snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
+	snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
+	snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
+	snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
+	snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
+	snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
+	snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
+	snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
 
 
 	snd_soc_add_controls(codec, wm8753_snd_controls,
 	snd_soc_add_controls(codec, wm8753_snd_controls,
 			     ARRAY_SIZE(wm8753_snd_controls));
 			     ARRAY_SIZE(wm8753_snd_controls));

+ 18 - 19
sound/soc/codecs/wm8904.c

@@ -50,8 +50,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
 /* codec private data */
 /* codec private data */
 struct wm8904_priv {
 struct wm8904_priv {
 
 
-	u16 reg_cache[WM8904_MAX_REGISTER + 1];
-
 	enum wm8904_type devtype;
 	enum wm8904_type devtype;
 	void *control_data;
 	void *control_data;
 
 
@@ -2094,7 +2092,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 
 
 static void wm8904_sync_cache(struct snd_soc_codec *codec)
 static void wm8904_sync_cache(struct snd_soc_codec *codec)
 {
 {
-	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+	u16 *reg_cache = codec->reg_cache;
 	int i;
 	int i;
 
 
 	if (!codec->cache_sync)
 	if (!codec->cache_sync)
@@ -2105,14 +2103,14 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec)
 	/* Sync back cached values if they're different from the
 	/* Sync back cached values if they're different from the
 	 * hardware default.
 	 * hardware default.
 	 */
 	 */
-	for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
+	for (i = 1; i < codec->driver->reg_cache_size; i++) {
 		if (!wm8904_access[i].writable)
 		if (!wm8904_access[i].writable)
 			continue;
 			continue;
 
 
-		if (wm8904->reg_cache[i] == wm8904_reg[i])
+		if (reg_cache[i] == wm8904_reg[i])
 			continue;
 			continue;
 
 
-		snd_soc_write(codec, i, wm8904->reg_cache[i]);
+		snd_soc_write(codec, i, reg_cache[i]);
 	}
 	}
 
 
 	codec->cache_sync = 0;
 	codec->cache_sync = 0;
@@ -2371,6 +2369,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
 {
 {
 	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
 	struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
 	struct wm8904_pdata *pdata = wm8904->pdata;
 	struct wm8904_pdata *pdata = wm8904->pdata;
+	u16 *reg_cache = codec->reg_cache;
 	int ret, i;
 	int ret, i;
 
 
 	codec->cache_sync = 1;
 	codec->cache_sync = 1;
@@ -2437,19 +2436,19 @@ static int wm8904_probe(struct snd_soc_codec *codec)
 	}
 	}
 
 
 	/* Change some default settings - latch VU and enable ZC */
 	/* Change some default settings - latch VU and enable ZC */
-	wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
-	wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
-	wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
-	wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
-	wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
+	reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
+	reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
+	reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
+	reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
+	reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
 		WM8904_HPOUTLZC;
 		WM8904_HPOUTLZC;
-	wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
+	reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
 		WM8904_HPOUTRZC;
 		WM8904_HPOUTRZC;
-	wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
+	reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
 		WM8904_LINEOUTLZC;
 		WM8904_LINEOUTLZC;
-	wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
+	reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
 		WM8904_LINEOUTRZC;
 		WM8904_LINEOUTRZC;
-	wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
+	reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
 
 
 	/* Apply configuration from the platform data. */
 	/* Apply configuration from the platform data. */
 	if (wm8904->pdata) {
 	if (wm8904->pdata) {
@@ -2457,23 +2456,23 @@ static int wm8904_probe(struct snd_soc_codec *codec)
 			if (!pdata->gpio_cfg[i])
 			if (!pdata->gpio_cfg[i])
 				continue;
 				continue;
 
 
-			wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i]
+			reg_cache[WM8904_GPIO_CONTROL_1 + i]
 				= pdata->gpio_cfg[i] & 0xffff;
 				= pdata->gpio_cfg[i] & 0xffff;
 		}
 		}
 
 
 		/* Zero is the default value for these anyway */
 		/* Zero is the default value for these anyway */
 		for (i = 0; i < WM8904_MIC_REGS; i++)
 		for (i = 0; i < WM8904_MIC_REGS; i++)
-			wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
+			reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
 				= pdata->mic_cfg[i];
 				= pdata->mic_cfg[i];
 	}
 	}
 
 
 	/* Set Class W by default - this will be managed by the Class
 	/* Set Class W by default - this will be managed by the Class
 	 * G widget at runtime where bypass paths are available.
 	 * G widget at runtime where bypass paths are available.
 	 */
 	 */
-	wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
+	reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
 
 
 	/* Use normal bias source */
 	/* Use normal bias source */
-	wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
+	reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
 
 
 	wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 	wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
 

+ 1 - 0
sound/soc/codecs/wm8940.c

@@ -768,6 +768,7 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c,
 
 
 	i2c_set_clientdata(i2c, wm8940);
 	i2c_set_clientdata(i2c, wm8940);
 	wm8940->control_data = i2c;
 	wm8940->control_data = i2c;
+	wm8940->control_type = SND_SOC_I2C;
 
 
 	ret = snd_soc_register_codec(&i2c->dev,
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8940, &wm8940_dai, 1);
 			&soc_codec_dev_wm8940, &wm8940_dai, 1);

+ 16 - 15
sound/soc/codecs/wm8955.c

@@ -42,8 +42,6 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
 struct wm8955_priv {
 struct wm8955_priv {
 	enum snd_soc_control_type control_type;
 	enum snd_soc_control_type control_type;
 
 
-	u16 reg_cache[WM8955_MAX_REGISTER + 1];
-
 	unsigned int mclk_rate;
 	unsigned int mclk_rate;
 
 
 	int deemph;
 	int deemph;
@@ -768,6 +766,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 				 enum snd_soc_bias_level level)
 {
 {
 	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
 	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
+	u16 *reg_cache = codec->reg_cache;
 	int ret, i;
 	int ret, i;
 
 
 	switch (level) {
 	switch (level) {
@@ -800,14 +799,14 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
 			/* Sync back cached values if they're
 			/* Sync back cached values if they're
 			 * different from the hardware default.
 			 * different from the hardware default.
 			 */
 			 */
-			for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) {
+			for (i = 0; i < codec->driver->reg_cache_size; i++) {
 				if (i == WM8955_RESET)
 				if (i == WM8955_RESET)
 					continue;
 					continue;
 
 
-				if (wm8955->reg_cache[i] == wm8955_reg[i])
+				if (reg_cache[i] == wm8955_reg[i])
 					continue;
 					continue;
 
 
-				snd_soc_write(codec, i, wm8955->reg_cache[i]);
+				snd_soc_write(codec, i, reg_cache[i]);
 			}
 			}
 
 
 			/* Enable VREF and VMID */
 			/* Enable VREF and VMID */
@@ -902,6 +901,7 @@ static int wm8955_probe(struct snd_soc_codec *codec)
 {
 {
 	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
 	struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
 	struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
 	struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
+	u16 *reg_cache = codec->reg_cache;
 	int ret, i;
 	int ret, i;
 
 
 	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type);
 	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type);
@@ -934,25 +934,25 @@ static int wm8955_probe(struct snd_soc_codec *codec)
 	}
 	}
 
 
 	/* Change some default settings - latch VU and enable ZC */
 	/* Change some default settings - latch VU and enable ZC */
-	wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
-	wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
-	wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
-	wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
-	wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
-	wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
-	wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
+	reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
+	reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
+	reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
+	reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
+	reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
+	reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
+	reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
 
 
 	/* Also enable adaptive bass boost by default */
 	/* Also enable adaptive bass boost by default */
-	wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
+	reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
 
 
 	/* Set platform data values */
 	/* Set platform data values */
 	if (pdata) {
 	if (pdata) {
 		if (pdata->out2_speaker)
 		if (pdata->out2_speaker)
-			wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
+			reg_cache[WM8955_ADDITIONAL_CONTROL_2]
 				|= WM8955_ROUT2INV;
 				|= WM8955_ROUT2INV;
 
 
 		if (pdata->monoin_diff)
 		if (pdata->monoin_diff)
-			wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
+			reg_cache[WM8955_MONO_OUT_MIX_1]
 				|= WM8955_DMEN;
 				|= WM8955_DMEN;
 	}
 	}
 
 
@@ -1003,6 +1003,7 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	i2c_set_clientdata(i2c, wm8955);
 	i2c_set_clientdata(i2c, wm8955);
+	wm8955->control_type = SND_SOC_I2C;
 
 
 	ret = snd_soc_register_codec(&i2c->dev,
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8955, &wm8955_dai, 1);
 			&soc_codec_dev_wm8955, &wm8955_dai, 1);

+ 1 - 0
sound/soc/codecs/wm8960.c

@@ -1013,6 +1013,7 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	i2c_set_clientdata(i2c, wm8960);
 	i2c_set_clientdata(i2c, wm8960);
+	wm8960->control_type = SND_SOC_I2C;
 	wm8960->control_data = i2c;
 	wm8960->control_data = i2c;
 
 
 	ret = snd_soc_register_codec(&i2c->dev,
 	ret = snd_soc_register_codec(&i2c->dev,

+ 20 - 25
sound/soc/codecs/wm8962.c

@@ -52,8 +52,6 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
 struct wm8962_priv {
 struct wm8962_priv {
 	struct snd_soc_codec *codec;
 	struct snd_soc_codec *codec;
 
 
-	u16 reg_cache[WM8962_MAX_REGISTER + 1];
-
 	int sysclk;
 	int sysclk;
 	int sysclk_rate;
 	int sysclk_rate;
 
 
@@ -1991,8 +1989,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
 			    struct snd_ctl_elem_value *ucontrol)
 			    struct snd_ctl_elem_value *ucontrol)
 {
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-	u16 *reg_cache = wm8962->reg_cache;
+	u16 *reg_cache = codec->reg_cache;
 	int ret;
 	int ret;
 
 
 	/* Apply the update (if any) */
 	/* Apply the update (if any) */
@@ -2020,8 +2017,7 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
 			    struct snd_ctl_elem_value *ucontrol)
 			    struct snd_ctl_elem_value *ucontrol)
 {
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-	u16 *reg_cache = wm8962->reg_cache;
+	u16 *reg_cache = codec->reg_cache;
 	int ret;
 	int ret;
 
 
 	/* Apply the update (if any) */
 	/* Apply the update (if any) */
@@ -2329,8 +2325,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
 			 struct snd_kcontrol *kcontrol, int event)
 			 struct snd_kcontrol *kcontrol, int event)
 {
 {
 	struct snd_soc_codec *codec = w->codec;
 	struct snd_soc_codec *codec = w->codec;
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
-	u16 *reg_cache = wm8962->reg_cache;
+	u16 *reg_cache = codec->reg_cache;
 	int reg;
 	int reg;
 
 
 	switch (w->shift) {
 	switch (w->shift) {
@@ -2719,7 +2714,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
 
 
 static void wm8962_sync_cache(struct snd_soc_codec *codec)
 static void wm8962_sync_cache(struct snd_soc_codec *codec)
 {
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+	u16 *reg_cache = codec->reg_cache;
 	int i;
 	int i;
 
 
 	if (!codec->cache_sync)
 	if (!codec->cache_sync)
@@ -2732,13 +2727,13 @@ static void wm8962_sync_cache(struct snd_soc_codec *codec)
 	/* Sync back cached values if they're different from the
 	/* Sync back cached values if they're different from the
 	 * hardware default.
 	 * hardware default.
 	 */
 	 */
-	for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) {
+	for (i = 1; i < codec->driver->reg_cache_size; i++) {
 		if (i == WM8962_SOFTWARE_RESET)
 		if (i == WM8962_SOFTWARE_RESET)
 			continue;
 			continue;
-		if (wm8962->reg_cache[i] == wm8962_reg[i])
+		if (reg_cache[i] == wm8962_reg[i])
 			continue;
 			continue;
 
 
-		snd_soc_write(codec, i, wm8962->reg_cache[i]);
+		snd_soc_write(codec, i, reg_cache[i]);
 	}
 	}
 
 
 	codec->cache_sync = 0;
 	codec->cache_sync = 0;
@@ -3406,12 +3401,11 @@ EXPORT_SYMBOL_GPL(wm8962_mic_detect);
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM
 static int wm8962_resume(struct snd_soc_codec *codec)
 static int wm8962_resume(struct snd_soc_codec *codec)
 {
 {
-	struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
 	u16 *reg_cache = codec->reg_cache;
 	u16 *reg_cache = codec->reg_cache;
 	int i;
 	int i;
 
 
 	/* Restore the registers */
 	/* Restore the registers */
-	for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) {
+	for (i = 1; i < codec->driver->reg_cache_size; i++) {
 		switch (i) {
 		switch (i) {
 		case WM8962_SOFTWARE_RESET:
 		case WM8962_SOFTWARE_RESET:
 			continue;
 			continue;
@@ -3705,6 +3699,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
 	struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
 	struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
 	struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
 	struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
 					      dev);
 					      dev);
+	u16 *reg_cache = codec->reg_cache;
 	int i, trigger, irq_pol;
 	int i, trigger, irq_pol;
 
 
 	wm8962->codec = codec;
 	wm8962->codec = codec;
@@ -3804,7 +3799,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
 
 
 		/* Put the speakers into mono mode? */
 		/* Put the speakers into mono mode? */
 		if (pdata->spk_mono)
 		if (pdata->spk_mono)
-			wm8962->reg_cache[WM8962_CLASS_D_CONTROL_2]
+			reg_cache[WM8962_CLASS_D_CONTROL_2]
 				|= WM8962_SPK_MONO;
 				|= WM8962_SPK_MONO;
 
 
 		/* Micbias setup, detection enable and detection
 		/* Micbias setup, detection enable and detection
@@ -3819,16 +3814,16 @@ static int wm8962_probe(struct snd_soc_codec *codec)
 	}
 	}
 
 
 	/* Latch volume update bits */
 	/* Latch volume update bits */
-	wm8962->reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU;
-	wm8962->reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU;
-	wm8962->reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU;
-	wm8962->reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU;	
-	wm8962->reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU;
-	wm8962->reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU;
-	wm8962->reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU;
-	wm8962->reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU;
-	wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
-	wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
+	reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU;
+	reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU;
+	reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU;
+	reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU;
+	reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU;
+	reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU;
+	reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU;
+	reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU;
+	reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
+	reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
 
 
 	wm8962_add_widgets(codec);
 	wm8962_add_widgets(codec);
 
 

+ 1 - 0
sound/soc/codecs/wm8971.c

@@ -718,6 +718,7 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c,
 	if (wm8971 == NULL)
 	if (wm8971 == NULL)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
+	wm8971->control_type = SND_SOC_I2C;
 	i2c_set_clientdata(i2c, wm8971);
 	i2c_set_clientdata(i2c, wm8971);
 
 
 	ret = snd_soc_register_codec(&i2c->dev,
 	ret = snd_soc_register_codec(&i2c->dev,

+ 1 - 0
sound/soc/codecs/wm9081.c

@@ -1335,6 +1335,7 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	i2c_set_clientdata(i2c, wm9081);
 	i2c_set_clientdata(i2c, wm9081);
+	wm9081->control_type = SND_SOC_I2C;
 	wm9081->control_data = i2c;
 	wm9081->control_data = i2c;
 
 
 	ret = snd_soc_register_codec(&i2c->dev,
 	ret = snd_soc_register_codec(&i2c->dev,

+ 9 - 9
sound/soc/codecs/wm9090.c

@@ -141,7 +141,6 @@ static const u16 wm9090_reg_defaults[] = {
 /* This struct is used to save the context */
 /* This struct is used to save the context */
 struct wm9090_priv {
 struct wm9090_priv {
 	struct mutex mutex;
 	struct mutex mutex;
-	u16 reg_cache[WM9090_MAX_REGISTER + 1];
 	struct wm9090_platform_data pdata;
 	struct wm9090_platform_data pdata;
 	void *control_data;
 	void *control_data;
 };
 };
@@ -552,6 +551,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
 static int wm9090_probe(struct snd_soc_codec *codec)
 static int wm9090_probe(struct snd_soc_codec *codec)
 {
 {
 	struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
 	struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
+	u16 *reg_cache = codec->reg_cache;
 	int ret;
 	int ret;
 
 
 	codec->control_data = wm9090->control_data;
 	codec->control_data = wm9090->control_data;
@@ -576,22 +576,22 @@ static int wm9090_probe(struct snd_soc_codec *codec)
 	/* Configure some defaults; they will be written out when we
 	/* Configure some defaults; they will be written out when we
 	 * bring the bias up.
 	 * bring the bias up.
 	 */
 	 */
-	wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
+	reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU
 		| WM9090_IN1A_ZC;
 		| WM9090_IN1A_ZC;
-	wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
+	reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU
 		| WM9090_IN1B_ZC;
 		| WM9090_IN1B_ZC;
-	wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
+	reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU
 		| WM9090_IN2A_ZC;
 		| WM9090_IN2A_ZC;
-	wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
+	reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU
 		| WM9090_IN2B_ZC;
 		| WM9090_IN2B_ZC;
-	wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
+	reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |=
 		WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
 		WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC;
-	wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
+	reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |=
 		WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
 		WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC;
-	wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
+	reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |=
 		WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
 		WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC;
 
 
-	wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
+	reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA;
 
 
 	wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 	wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
 

+ 1 - 1
tools/perf/util/hist.c

@@ -356,7 +356,7 @@ static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
 
 
 static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
 static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
 				     int depth, int depth_mask, int period,
 				     int depth, int depth_mask, int period,
-				     u64 total_samples, int hits,
+				     u64 total_samples, u64 hits,
 				     int left_margin)
 				     int left_margin)
 {
 {
 	int i;
 	int i;