summaryrefslogtreecommitdiff |
diff options
author | Jeff Mahoney <jeffm@suse.com> | 2010-11-24 09:49:45 -0500 |
---|---|---|
committer | Jeff Mahoney <jeffm@suse.com> | 2010-11-24 09:49:45 -0500 |
commit | 4ad245fa8cc06cea3ba2d14af230c16ee7da523a (patch) | |
tree | 57efb9165c9a222357675c1cee1aa18c514d9ae2 | |
parent | 12ac0acca09ab7ae651970f3a7e181e42e8cf4e2 (diff) |
- Update to 2.6.37-rc3-git1.rpm-2.6.37-6--openSUSE-11.4-Milestone4rpm-2.6.37-6
-rw-r--r-- | config/i386/debug | 2 | ||||
-rw-r--r-- | config/i386/default | 2 | ||||
-rw-r--r-- | config/i386/desktop | 2 | ||||
-rw-r--r-- | config/i386/pae | 2 | ||||
-rw-r--r-- | config/i386/trace | 2 | ||||
-rw-r--r-- | config/i386/vmi | 2 | ||||
-rw-r--r-- | config/ia64/debug | 2 | ||||
-rw-r--r-- | config/ia64/default | 2 | ||||
-rw-r--r-- | config/ia64/trace | 2 | ||||
-rw-r--r-- | config/ppc/default | 2 | ||||
-rw-r--r-- | config/ppc/ppc64 | 2 | ||||
-rw-r--r-- | config/ppc/ps3 | 2 | ||||
-rw-r--r-- | config/ppc64/debug | 2 | ||||
-rw-r--r-- | config/ppc64/default | 2 | ||||
-rw-r--r-- | config/ppc64/ppc64 | 2 | ||||
-rw-r--r-- | config/ppc64/trace | 2 | ||||
-rw-r--r-- | config/s390/s390 | 2 | ||||
-rw-r--r-- | config/s390/trace | 2 | ||||
-rw-r--r-- | config/s390x/default | 2 | ||||
-rw-r--r-- | config/s390x/trace | 2 | ||||
-rw-r--r-- | config/x86_64/debug | 2 | ||||
-rw-r--r-- | config/x86_64/default | 2 | ||||
-rw-r--r-- | config/x86_64/desktop | 2 | ||||
-rw-r--r-- | config/x86_64/trace | 2 | ||||
-rw-r--r-- | patches.kernel.org/patch-2.6.37-rc3-git1 | 3631 | ||||
-rw-r--r-- | series.conf | 1 |
26 files changed, 3656 insertions, 24 deletions
diff --git a/config/i386/debug b/config/i386/debug index e2c7855311..dc601fde6e 100644 --- a/config/i386/debug +++ b/config/i386/debug @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/i386 2.6.37-rc3 Kernel Configuration +# Linux/i386 2.6.37-rc3-git1 Kernel Configuration # # CONFIG_64BIT is not set CONFIG_X86_32=y diff --git a/config/i386/default b/config/i386/default index 397df00145..9578170938 100644 --- a/config/i386/default +++ b/config/i386/default @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/i386 2.6.37-rc3 Kernel Configuration +# Linux/i386 2.6.37-rc3-git1 Kernel Configuration # # CONFIG_64BIT is not set CONFIG_X86_32=y diff --git a/config/i386/desktop b/config/i386/desktop index 9ac866a74a..2f864d20d8 100644 --- a/config/i386/desktop +++ b/config/i386/desktop @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/i386 2.6.37-rc3 Kernel Configuration +# Linux/i386 2.6.37-rc3-git1 Kernel Configuration # # CONFIG_64BIT is not set CONFIG_X86_32=y diff --git a/config/i386/pae b/config/i386/pae index ebc13cb746..2b2c0b6e12 100644 --- a/config/i386/pae +++ b/config/i386/pae @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/i386 2.6.37-rc3 Kernel Configuration +# Linux/i386 2.6.37-rc3-git1 Kernel Configuration # # CONFIG_64BIT is not set CONFIG_X86_32=y diff --git a/config/i386/trace b/config/i386/trace index bf470795b3..bfa52c2535 100644 --- a/config/i386/trace +++ b/config/i386/trace @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/i386 2.6.37-rc3 Kernel Configuration +# Linux/i386 2.6.37-rc3-git1 Kernel Configuration # # CONFIG_64BIT is not set CONFIG_X86_32=y diff --git a/config/i386/vmi b/config/i386/vmi index 1b85ca7e1e..3c224552a8 100644 --- a/config/i386/vmi +++ b/config/i386/vmi @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/i386 2.6.37-rc3 Kernel Configuration +# Linux/i386 2.6.37-rc3-git1 Kernel Configuration # # CONFIG_64BIT is not set CONFIG_X86_32=y diff --git a/config/ia64/debug b/config/ia64/debug index f932ad19e1..fa28584aa2 100644 --- a/config/ia64/debug +++ b/config/ia64/debug @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/ia64 2.6.37-rc3 Kernel Configuration +# Linux/ia64 2.6.37-rc3-git1 Kernel Configuration # CONFIG_SUSE_KERNEL=y # CONFIG_ENTERPRISE_SUPPORT is not set diff --git a/config/ia64/default b/config/ia64/default index daa54fd1de..4d5f27bf9a 100644 --- a/config/ia64/default +++ b/config/ia64/default @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/ia64 2.6.37-rc3 Kernel Configuration +# Linux/ia64 2.6.37-rc3-git1 Kernel Configuration # CONFIG_SUSE_KERNEL=y # CONFIG_ENTERPRISE_SUPPORT is not set diff --git a/config/ia64/trace b/config/ia64/trace index 912206d911..99fc1f84b0 100644 --- a/config/ia64/trace +++ b/config/ia64/trace @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/ia64 2.6.37-rc3 Kernel Configuration +# Linux/ia64 2.6.37-rc3-git1 Kernel Configuration # CONFIG_SUSE_KERNEL=y # CONFIG_ENTERPRISE_SUPPORT is not set diff --git a/config/ppc/default b/config/ppc/default index abc808da97..00dd6ebd13 100644 --- a/config/ppc/default +++ b/config/ppc/default @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/powerpc 2.6.37-rc3 Kernel Configuration +# Linux/powerpc 2.6.37-rc3-git1 Kernel Configuration # # CONFIG_PPC64 is not set diff --git a/config/ppc/ppc64 b/config/ppc/ppc64 index 15458cbead..6bf743929b 100644 --- a/config/ppc/ppc64 +++ b/config/ppc/ppc64 @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/powerpc 2.6.37-rc3 Kernel Configuration +# Linux/powerpc 2.6.37-rc3-git1 Kernel Configuration # CONFIG_PPC64=y diff --git a/config/ppc/ps3 b/config/ppc/ps3 index bd5a71e13f..a07c446613 100644 --- a/config/ppc/ps3 +++ b/config/ppc/ps3 @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/powerpc 2.6.37-rc3 Kernel Configuration +# Linux/powerpc 2.6.37-rc3-git1 Kernel Configuration # CONFIG_PPC64=y diff --git a/config/ppc64/debug b/config/ppc64/debug index a890a5bc30..abf6c8a3de 100644 --- a/config/ppc64/debug +++ b/config/ppc64/debug @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/powerpc 2.6.37-rc3 Kernel Configuration +# Linux/powerpc 2.6.37-rc3-git1 Kernel Configuration # CONFIG_PPC64=y diff --git a/config/ppc64/default b/config/ppc64/default index 6ec53ed581..2f706ac9b9 100644 --- a/config/ppc64/default +++ b/config/ppc64/default @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/powerpc 2.6.37-rc3 Kernel Configuration +# Linux/powerpc 2.6.37-rc3-git1 Kernel Configuration # CONFIG_PPC64=y diff --git a/config/ppc64/ppc64 b/config/ppc64/ppc64 index de0a29a3ea..4693f1341a 100644 --- a/config/ppc64/ppc64 +++ b/config/ppc64/ppc64 @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/powerpc 2.6.37-rc3 Kernel Configuration +# Linux/powerpc 2.6.37-rc3-git1 Kernel Configuration # CONFIG_PPC64=y diff --git a/config/ppc64/trace b/config/ppc64/trace index 15b7b106c9..4c6caaf829 100644 --- a/config/ppc64/trace +++ b/config/ppc64/trace @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/powerpc 2.6.37-rc3 Kernel Configuration +# Linux/powerpc 2.6.37-rc3-git1 Kernel Configuration # CONFIG_PPC64=y diff --git a/config/s390/s390 b/config/s390/s390 index f892a3ff27..8d2a82db4a 100644 --- a/config/s390/s390 +++ b/config/s390/s390 @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/s390 2.6.37-rc3 Kernel Configuration +# Linux/s390 2.6.37-rc3-git1 Kernel Configuration # CONFIG_SCHED_MC=y CONFIG_MMU=y diff --git a/config/s390/trace b/config/s390/trace index 190e2dd2e9..80c074a720 100644 --- a/config/s390/trace +++ b/config/s390/trace @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/s390 2.6.37-rc3 Kernel Configuration +# Linux/s390 2.6.37-rc3-git1 Kernel Configuration # CONFIG_SCHED_MC=y CONFIG_MMU=y diff --git a/config/s390x/default b/config/s390x/default index ade5d6fe07..50ec3516a0 100644 --- a/config/s390x/default +++ b/config/s390x/default @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/s390 2.6.37-rc3 Kernel Configuration +# Linux/s390 2.6.37-rc3-git1 Kernel Configuration # CONFIG_SCHED_MC=y CONFIG_MMU=y diff --git a/config/s390x/trace b/config/s390x/trace index 727a5308e4..d3f271580f 100644 --- a/config/s390x/trace +++ b/config/s390x/trace @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/s390 2.6.37-rc3 Kernel Configuration +# Linux/s390 2.6.37-rc3-git1 Kernel Configuration # CONFIG_SCHED_MC=y CONFIG_MMU=y diff --git a/config/x86_64/debug b/config/x86_64/debug index feb4a2e0c7..81060fc4d0 100644 --- a/config/x86_64/debug +++ b/config/x86_64/debug @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/x86_64 2.6.37-rc3 Kernel Configuration +# Linux/x86_64 2.6.37-rc3-git1 Kernel Configuration # CONFIG_64BIT=y # CONFIG_X86_32 is not set diff --git a/config/x86_64/default b/config/x86_64/default index d6ae715474..b9e506b042 100644 --- a/config/x86_64/default +++ b/config/x86_64/default @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/x86_64 2.6.37-rc3 Kernel Configuration +# Linux/x86_64 2.6.37-rc3-git1 Kernel Configuration # CONFIG_64BIT=y # CONFIG_X86_32 is not set diff --git a/config/x86_64/desktop b/config/x86_64/desktop index e95ba8d29f..9d659c9dfa 100644 --- a/config/x86_64/desktop +++ b/config/x86_64/desktop @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/x86_64 2.6.37-rc3 Kernel Configuration +# Linux/x86_64 2.6.37-rc3-git1 Kernel Configuration # CONFIG_64BIT=y # CONFIG_X86_32 is not set diff --git a/config/x86_64/trace b/config/x86_64/trace index fc8396f3fe..2695c4011a 100644 --- a/config/x86_64/trace +++ b/config/x86_64/trace @@ -1,6 +1,6 @@ # # Automatically generated make config: don't edit -# Linux/x86_64 2.6.37-rc3 Kernel Configuration +# Linux/x86_64 2.6.37-rc3-git1 Kernel Configuration # CONFIG_64BIT=y # CONFIG_X86_32 is not set diff --git a/patches.kernel.org/patch-2.6.37-rc3-git1 b/patches.kernel.org/patch-2.6.37-rc3-git1 new file mode 100644 index 0000000000..020038b10e --- /dev/null +++ b/patches.kernel.org/patch-2.6.37-rc3-git1 @@ -0,0 +1,3631 @@ +From: Linux Kernel Mailing Linux <linux-kernel@vger.kernel.org> +Subject: Linux: 2.6.37-rc3-git1 +Patch-mainline: 2.6.37-rc4 + + This patch contains the differences between 2.6.37-rc3 and -rc3-git1. + +Acked-by: Jeff Mahoney <jeffm@suse.com> +--- + + MAINTAINERS | 2 + Makefile | 2 + arch/arm/mach-davinci/dm355.c | 6 + arch/arm/mach-davinci/dm365.c | 6 + arch/arm/mach-davinci/dm644x.c | 4 + arch/x86/include/asm/xen/interface.h | 6 + arch/x86/include/asm/xen/interface_32.h | 5 + arch/x86/include/asm/xen/interface_64.h | 13 - + arch/x86/include/asm/xen/page.h | 7 - + arch/x86/xen/enlighten.c | 19 ++ + arch/x86/xen/mmu.c | 17 ++ + arch/x86/xen/setup.c | 11 - + drivers/net/atl1c/atl1c_hw.c | 2 + drivers/net/e1000/e1000_main.c | 12 + + drivers/net/irda/sh_sir.c | 2 + drivers/net/phy/marvell.c | 164 +++++++++++++++++++++-- + drivers/net/qlge/qlge_main.c | 6 + drivers/usb/atm/ueagle-atm.c | 7 - + drivers/usb/gadget/atmel_usba_udc.c | 2 + drivers/usb/host/ehci-dbg.c | 2 + drivers/usb/host/ehci-hcd.c | 10 - + drivers/usb/host/ehci-mem.c | 26 +++ + drivers/usb/host/ehci-pci.c | 13 + + drivers/usb/host/ehci-sched.c | 21 ++- + drivers/usb/host/ehci.h | 2 + drivers/usb/host/isp1362-hcd.c | 2 + drivers/usb/host/xhci-mem.c | 4 + drivers/usb/host/xhci-ring.c | 1 + drivers/usb/host/xhci.c | 73 +++++++++- + drivers/usb/host/xhci.h | 5 + drivers/usb/misc/cypress_cy7c63.c | 6 + drivers/usb/misc/trancevibrator.c | 2 + drivers/usb/misc/usbled.c | 2 + drivers/usb/misc/usbsevseg.c | 10 - + drivers/usb/otg/langwell_otg.c | 9 - + drivers/usb/storage/sierra_ms.c | 2 + drivers/xen/Makefile | 5 + drivers/xen/balloon.c | 32 ++-- + drivers/xen/events.c | 13 + + drivers/xen/evtchn.c | 100 +++++++++++--- + drivers/xen/xenfs/privcmd.c | 13 - + drivers/xen/xenfs/super.c | 46 +----- + include/linux/marvell_phy.h | 1 + include/linux/mfd/wm8350/audio.h | 3 + include/xen/interface/memory.h | 13 + + include/xen/page.h | 7 + + include/xen/privcmd.h | 5 + net/ceph/buffer.c | 2 + net/core/request_sock.c | 4 + net/ipv4/fib_trie.c | 2 + net/ipv6/addrconf.c | 6 + net/xfrm/xfrm_hash.c | 2 + sound/atmel/abdac.c | 4 + sound/core/pcm_lib.c | 2 + sound/oss/dev_table.c | 6 + sound/oss/midibuf.c | 4 + sound/oss/pss.c | 6 + sound/oss/sequencer.c | 4 + sound/pci/asihpi/hpioctl.c | 2 + sound/pci/azt3328.c | 26 ++- + sound/pci/ctxfi/ctpcm.c | 16 +- + sound/pci/hda/patch_conexant.c | 2 + sound/pci/hda/patch_realtek.c | 28 +++- + sound/pci/hda/patch_sigmatel.c | 18 +- + sound/pci/intel8x0.c | 6 + sound/pci/mixart/mixart_hwdep.h | 10 + + sound/ppc/pmac.c | 12 - + sound/soc/atmel/Kconfig | 5 + sound/soc/codecs/max98088.c | 11 + + sound/soc/codecs/uda134x.c | 1 + sound/soc/codecs/wm8350.c | 9 + + sound/soc/codecs/wm8776.c | 1 + sound/soc/codecs/wm8962.c | 5 + sound/soc/codecs/wm8994.c | 2 + sound/soc/davinci/davinci-evm.c | 40 ++++- + sound/soc/davinci/davinci-i2s.c | 15 +- + sound/soc/davinci/davinci-mcasp.c | 13 + + sound/soc/davinci/davinci-sffsdr.c | 2 + sound/soc/davinci/davinci-vcif.c | 13 + + sound/soc/fsl/mpc5200_psc_i2s.c | 2 + sound/soc/imx/eukrea-tlv320.c | 8 - + sound/soc/imx/imx-pcm-dma-mx2.c | 221 ++++++++++++++------------------ + sound/soc/imx/imx-ssi.c | 44 ++++-- + sound/soc/imx/imx-ssi.h | 4 + sound/soc/imx/phycore-ac97.c | 5 + sound/soc/omap/omap-mcbsp.c | 8 + + sound/soc/pxa/corgi.c | 5 + sound/soc/pxa/magician.c | 4 + sound/soc/pxa/poodle.c | 5 + sound/soc/pxa/spitz.c | 5 + sound/soc/pxa/tosa.c | 5 + sound/soc/s3c24xx/Kconfig | 1 + sound/soc/s3c24xx/rx1950_uda1380.c | 20 -- + sound/soc/soc-core.c | 9 - + sound/soc/soc-dapm.c | 4 + sound/spi/at73c213.c | 2 + 96 files changed, 886 insertions(+), 466 deletions(-) + +diff --git a/MAINTAINERS b/MAINTAINERS +index a92c994..b49ba9a 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1359,7 +1359,7 @@ F: include/net/bluetooth/ + + BONDING DRIVER + M: Jay Vosburgh <fubar@us.ibm.com> +-L: bonding-devel@lists.sourceforge.net ++L: netdev@vger.kernel.org + W: http://sourceforge.net/projects/bonding/ + S: Supported + F: drivers/net/bonding/ +diff --git a/Makefile b/Makefile +index b31d213..b062f8e 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,7 +1,7 @@ + VERSION = 2 + PATCHLEVEL = 6 + SUBLEVEL = 37 +-EXTRAVERSION = -rc3 ++EXTRAVERSION = -rc3-git1 + NAME = Flesh-Eating Bats with Fangs + + # *DOCUMENTATION* +diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c +index 9be261b..2652af1 100644 +--- a/arch/arm/mach-davinci/dm355.c ++++ b/arch/arm/mach-davinci/dm355.c +@@ -359,8 +359,8 @@ static struct clk_lookup dm355_clks[] = { + CLK(NULL, "uart1", &uart1_clk), + CLK(NULL, "uart2", &uart2_clk), + CLK("i2c_davinci.1", NULL, &i2c_clk), +- CLK("davinci-asp.0", NULL, &asp0_clk), +- CLK("davinci-asp.1", NULL, &asp1_clk), ++ CLK("davinci-mcbsp.0", NULL, &asp0_clk), ++ CLK("davinci-mcbsp.1", NULL, &asp1_clk), + CLK("davinci_mmc.0", NULL, &mmcsd0_clk), + CLK("davinci_mmc.1", NULL, &mmcsd1_clk), + CLK("spi_davinci.0", NULL, &spi0_clk), +@@ -664,7 +664,7 @@ static struct resource dm355_asp1_resources[] = { + }; + + static struct platform_device dm355_asp1_device = { +- .name = "davinci-asp", ++ .name = "davinci-mcbsp", + .id = 1, + .num_resources = ARRAY_SIZE(dm355_asp1_resources), + .resource = dm355_asp1_resources, +diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c +index a12065e..c466d71 100644 +--- a/arch/arm/mach-davinci/dm365.c ++++ b/arch/arm/mach-davinci/dm365.c +@@ -459,7 +459,7 @@ static struct clk_lookup dm365_clks[] = { + CLK(NULL, "usb", &usb_clk), + CLK("davinci_emac.1", NULL, &emac_clk), + CLK("davinci_voicecodec", NULL, &voicecodec_clk), +- CLK("davinci-asp.0", NULL, &asp0_clk), ++ CLK("davinci-mcbsp", NULL, &asp0_clk), + CLK(NULL, "rto", &rto_clk), + CLK(NULL, "mjcp", &mjcp_clk), + CLK(NULL, NULL, NULL), +@@ -922,8 +922,8 @@ static struct resource dm365_asp_resources[] = { + }; + + static struct platform_device dm365_asp_device = { +- .name = "davinci-asp", +- .id = 0, ++ .name = "davinci-mcbsp", ++ .id = -1, + .num_resources = ARRAY_SIZE(dm365_asp_resources), + .resource = dm365_asp_resources, + }; +diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c +index 0608dd7..9a2376b 100644 +--- a/arch/arm/mach-davinci/dm644x.c ++++ b/arch/arm/mach-davinci/dm644x.c +@@ -302,7 +302,7 @@ static struct clk_lookup dm644x_clks[] = { + CLK("davinci_emac.1", NULL, &emac_clk), + CLK("i2c_davinci.1", NULL, &i2c_clk), + CLK("palm_bk3710", NULL, &ide_clk), +- CLK("davinci-asp", NULL, &asp_clk), ++ CLK("davinci-mcbsp", NULL, &asp_clk), + CLK("davinci_mmc.0", NULL, &mmcsd_clk), + CLK(NULL, "spi", &spi_clk), + CLK(NULL, "gpio", &gpio_clk), +@@ -580,7 +580,7 @@ static struct resource dm644x_asp_resources[] = { + }; + + static struct platform_device dm644x_asp_device = { +- .name = "davinci-asp", ++ .name = "davinci-mcbsp", + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_asp_resources), + .resource = dm644x_asp_resources, +diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h +index e8506c1..1c10c88 100644 +--- a/arch/x86/include/asm/xen/interface.h ++++ b/arch/x86/include/asm/xen/interface.h +@@ -61,9 +61,9 @@ DEFINE_GUEST_HANDLE(void); + #define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) + #endif + +-#ifndef machine_to_phys_mapping +-#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) +-#endif ++#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) ++#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) ++#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>__MACH2PHYS_SHIFT) + + /* Maximum number of virtual CPUs in multi-processor guests. */ + #define MAX_VIRT_CPUS 32 +diff --git a/arch/x86/include/asm/xen/interface_32.h b/arch/x86/include/asm/xen/interface_32.h +index 42a7e00..8413688 100644 +--- a/arch/x86/include/asm/xen/interface_32.h ++++ b/arch/x86/include/asm/xen/interface_32.h +@@ -32,6 +32,11 @@ + /* And the trap vector is... */ + #define TRAP_INSTR "int $0x82" + ++#define __MACH2PHYS_VIRT_START 0xF5800000 ++#define __MACH2PHYS_VIRT_END 0xF6800000 ++ ++#define __MACH2PHYS_SHIFT 2 ++ + /* + * Virtual addresses beyond this are not modifiable by guest OSes. The + * machine->physical mapping table starts at this address, read-only. +diff --git a/arch/x86/include/asm/xen/interface_64.h b/arch/x86/include/asm/xen/interface_64.h +index 100d266..839a481 100644 +--- a/arch/x86/include/asm/xen/interface_64.h ++++ b/arch/x86/include/asm/xen/interface_64.h +@@ -39,18 +39,7 @@ + #define __HYPERVISOR_VIRT_END 0xFFFF880000000000 + #define __MACH2PHYS_VIRT_START 0xFFFF800000000000 + #define __MACH2PHYS_VIRT_END 0xFFFF804000000000 +- +-#ifndef HYPERVISOR_VIRT_START +-#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) +-#define HYPERVISOR_VIRT_END mk_unsigned_long(__HYPERVISOR_VIRT_END) +-#endif +- +-#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) +-#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) +-#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3) +-#ifndef machine_to_phys_mapping +-#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) +-#endif ++#define __MACH2PHYS_SHIFT 3 + + /* + * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) +diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h +index dd8c141..8760cc6 100644 +--- a/arch/x86/include/asm/xen/page.h ++++ b/arch/x86/include/asm/xen/page.h +@@ -5,6 +5,7 @@ + #include <linux/types.h> + #include <linux/spinlock.h> + #include <linux/pfn.h> ++#include <linux/mm.h> + + #include <asm/uaccess.h> + #include <asm/page.h> +@@ -35,6 +36,8 @@ typedef struct xpaddr { + #define MAX_DOMAIN_PAGES \ + ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE)) + ++extern unsigned long *machine_to_phys_mapping; ++extern unsigned int machine_to_phys_order; + + extern unsigned long get_phys_to_machine(unsigned long pfn); + extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); +@@ -69,10 +72,8 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn) + if (xen_feature(XENFEAT_auto_translated_physmap)) + return mfn; + +-#if 0 + if (unlikely((mfn >> machine_to_phys_order) != 0)) +- return max_mapnr; +-#endif ++ return ~0; + + pfn = 0; + /* +diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c +index 235c0f4..7250bef 100644 +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -75,6 +75,11 @@ DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); + enum xen_domain_type xen_domain_type = XEN_NATIVE; + EXPORT_SYMBOL_GPL(xen_domain_type); + ++unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START; ++EXPORT_SYMBOL(machine_to_phys_mapping); ++unsigned int machine_to_phys_order; ++EXPORT_SYMBOL(machine_to_phys_order); ++ + struct start_info *xen_start_info; + EXPORT_SYMBOL_GPL(xen_start_info); + +@@ -1090,6 +1095,8 @@ static void __init xen_setup_stackprotector(void) + /* First C function to be called on Xen boot */ + asmlinkage void __init xen_start_kernel(void) + { ++ struct physdev_set_iopl set_iopl; ++ int rc; + pgd_t *pgd; + + if (!xen_start_info) +@@ -1097,6 +1104,8 @@ asmlinkage void __init xen_start_kernel(void) + + xen_domain_type = XEN_PV_DOMAIN; + ++ xen_setup_machphys_mapping(); ++ + /* Install Xen paravirt ops */ + pv_info = xen_info; + pv_init_ops = xen_init_ops; +@@ -1202,10 +1211,18 @@ asmlinkage void __init xen_start_kernel(void) + #else + pv_info.kernel_rpl = 0; + #endif +- + /* set the limit of our address space */ + xen_reserve_top(); + ++ /* We used to do this in xen_arch_setup, but that is too late on AMD ++ * were early_cpu_init (run before ->arch_setup()) calls early_amd_init ++ * which pokes 0xcf8 port. ++ */ ++ set_iopl.iopl = 1; ++ rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl); ++ if (rc != 0) ++ xen_raw_printk("physdev_op failed %d\n", rc); ++ + #ifdef CONFIG_X86_32 + /* set up basic CPUID stuff */ + cpu_detect(&new_cpu_data); +diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c +index 21ed8d7..790af90 100644 +--- a/arch/x86/xen/mmu.c ++++ b/arch/x86/xen/mmu.c +@@ -2034,6 +2034,20 @@ static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) + set_page_prot(pmd, PAGE_KERNEL_RO); + } + ++void __init xen_setup_machphys_mapping(void) ++{ ++ struct xen_machphys_mapping mapping; ++ unsigned long machine_to_phys_nr_ents; ++ ++ if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) { ++ machine_to_phys_mapping = (unsigned long *)mapping.v_start; ++ machine_to_phys_nr_ents = mapping.max_mfn + 1; ++ } else { ++ machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES; ++ } ++ machine_to_phys_order = fls(machine_to_phys_nr_ents - 1); ++} ++ + #ifdef CONFIG_X86_64 + static void convert_pfn_mfn(void *v) + { +@@ -2627,7 +2641,8 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma, + + prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP); + +- vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; ++ BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_RESERVED | VM_IO)) == ++ (VM_PFNMAP | VM_RESERVED | VM_IO))); + + rmd.mfn = mfn; + rmd.prot = prot; +diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c +index 769c4b0..38fdffa 100644 +--- a/arch/x86/xen/setup.c ++++ b/arch/x86/xen/setup.c +@@ -248,8 +248,7 @@ char * __init xen_memory_setup(void) + else + extra_pages = 0; + +- if (!xen_initial_domain()) +- xen_add_extra_mem(extra_pages); ++ xen_add_extra_mem(extra_pages); + + return "Xen"; + } +@@ -337,9 +336,6 @@ void __cpuinit xen_enable_syscall(void) + + void __init xen_arch_setup(void) + { +- struct physdev_set_iopl set_iopl; +- int rc; +- + xen_panic_handler_init(); + + HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); +@@ -356,11 +352,6 @@ void __init xen_arch_setup(void) + xen_enable_sysenter(); + xen_enable_syscall(); + +- set_iopl.iopl = 1; +- rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl); +- if (rc != 0) +- printk(KERN_INFO "physdev_op failed %d\n", rc); +- + #ifdef CONFIG_ACPI + if (!(xen_start_info->flags & SIF_INITDOMAIN)) { + printk(KERN_INFO "ACPI in unprivileged domain disabled\n"); +diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c +index 919080b..1bf6720 100644 +--- a/drivers/net/atl1c/atl1c_hw.c ++++ b/drivers/net/atl1c/atl1c_hw.c +@@ -82,7 +82,7 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw) + addr[0] = addr[1] = 0; + AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data); + if (atl1c_check_eeprom_exist(hw)) { +- if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b) { ++ if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) { + /* Enable OTP CLK */ + if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) { + otp_ctrl_data |= OTP_CTRL_CLK_EN; +diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c +index 4686c39..4d62f7b 100644 +--- a/drivers/net/e1000/e1000_main.c ++++ b/drivers/net/e1000/e1000_main.c +@@ -31,7 +31,7 @@ + + char e1000_driver_name[] = "e1000"; + static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; +-#define DRV_VERSION "7.3.21-k6-NAPI" ++#define DRV_VERSION "7.3.21-k8-NAPI" + const char e1000_driver_version[] = DRV_VERSION; + static const char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation."; + +@@ -485,9 +485,6 @@ void e1000_down(struct e1000_adapter *adapter) + struct net_device *netdev = adapter->netdev; + u32 rctl, tctl; + +- /* signal that we're down so the interrupt handler does not +- * reschedule our watchdog timer */ +- set_bit(__E1000_DOWN, &adapter->flags); + + /* disable receives in the hardware */ + rctl = er32(RCTL); +@@ -508,6 +505,13 @@ void e1000_down(struct e1000_adapter *adapter) + + e1000_irq_disable(adapter); + ++ /* ++ * Setting DOWN must be after irq_disable to prevent ++ * a screaming interrupt. Setting DOWN also prevents ++ * timers and tasks from rescheduling. ++ */ ++ set_bit(__E1000_DOWN, &adapter->flags); ++ + del_timer_sync(&adapter->tx_fifo_stall_timer); + del_timer_sync(&adapter->watchdog_timer); + del_timer_sync(&adapter->phy_info_timer); +diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c +index 00b38bc..52a7c86 100644 +--- a/drivers/net/irda/sh_sir.c ++++ b/drivers/net/irda/sh_sir.c +@@ -258,7 +258,7 @@ static int sh_sir_set_baudrate(struct sh_sir_self *self, u32 baudrate) + + /* Baud Rate Error Correction x 10000 */ + u32 rate_err_array[] = { +- 0000, 0625, 1250, 1875, ++ 0, 625, 1250, 1875, + 2500, 3125, 3750, 4375, + 5000, 5625, 6250, 6875, + 7500, 8125, 8750, 9375, +diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c +index f0bd1a1..e8b9c53 100644 +--- a/drivers/net/phy/marvell.c ++++ b/drivers/net/phy/marvell.c +@@ -30,11 +30,14 @@ + #include <linux/ethtool.h> + #include <linux/phy.h> + #include <linux/marvell_phy.h> ++#include <linux/of.h> + + #include <asm/io.h> + #include <asm/irq.h> + #include <asm/uaccess.h> + ++#define MII_MARVELL_PHY_PAGE 22 ++ + #define MII_M1011_IEVENT 0x13 + #define MII_M1011_IEVENT_CLEAR 0x0000 + +@@ -80,7 +83,6 @@ + #define MII_88E1121_PHY_LED_CTRL 16 + #define MII_88E1121_PHY_LED_PAGE 3 + #define MII_88E1121_PHY_LED_DEF 0x0030 +-#define MII_88E1121_PHY_PAGE 22 + + #define MII_M1011_PHY_STATUS 0x11 + #define MII_M1011_PHY_STATUS_1000 0x8000 +@@ -186,13 +188,94 @@ static int marvell_config_aneg(struct phy_device *phydev) + return 0; + } + ++#ifdef CONFIG_OF_MDIO ++/* ++ * Set and/or override some configuration registers based on the ++ * marvell,reg-init property stored in the of_node for the phydev. ++ * ++ * marvell,reg-init = <reg-page reg mask value>,...; ++ * ++ * There may be one or more sets of <reg-page reg mask value>: ++ * ++ * reg-page: which register bank to use. ++ * reg: the register. ++ * mask: if non-zero, ANDed with existing register value. ++ * value: ORed with the masked value and written to the regiser. ++ * ++ */ ++static int marvell_of_reg_init(struct phy_device *phydev) ++{ ++ const __be32 *paddr; ++ int len, i, saved_page, current_page, page_changed, ret; ++ ++ if (!phydev->dev.of_node) ++ return 0; ++ ++ paddr = of_get_property(phydev->dev.of_node, "marvell,reg-init", &len); ++ if (!paddr || len < (4 * sizeof(*paddr))) ++ return 0; ++ ++ saved_page = phy_read(phydev, MII_MARVELL_PHY_PAGE); ++ if (saved_page < 0) ++ return saved_page; ++ page_changed = 0; ++ current_page = saved_page; ++ ++ ret = 0; ++ len /= sizeof(*paddr); ++ for (i = 0; i < len - 3; i += 4) { ++ u16 reg_page = be32_to_cpup(paddr + i); ++ u16 reg = be32_to_cpup(paddr + i + 1); ++ u16 mask = be32_to_cpup(paddr + i + 2); ++ u16 val_bits = be32_to_cpup(paddr + i + 3); ++ int val; ++ ++ if (reg_page != current_page) { ++ current_page = reg_page; ++ page_changed = 1; ++ ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, reg_page); ++ if (ret < 0) ++ goto err; ++ } ++ ++ val = 0; ++ if (mask) { ++ val = phy_read(phydev, reg); ++ if (val < 0) { ++ ret = val; ++ goto err; ++ } ++ val &= mask; ++ } ++ val |= val_bits; ++ ++ ret = phy_write(phydev, reg, val); ++ if (ret < 0) ++ goto err; ++ ++ } ++err: ++ if (page_changed) { ++ i = phy_write(phydev, MII_MARVELL_PHY_PAGE, saved_page); ++ if (ret == 0) ++ ret = i; ++ } ++ return ret; ++} ++#else ++static int marvell_of_reg_init(struct phy_device *phydev) ++{ ++ return 0; ++} ++#endif /* CONFIG_OF_MDIO */ ++ + static int m88e1121_config_aneg(struct phy_device *phydev) + { + int err, oldpage, mscr; + +- oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE); ++ oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); + +- err = phy_write(phydev, MII_88E1121_PHY_PAGE, ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, + MII_88E1121_PHY_MSCR_PAGE); + if (err < 0) + return err; +@@ -218,7 +301,7 @@ static int m88e1121_config_aneg(struct phy_device *phydev) + return err; + } + +- phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage); ++ phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); + + err = phy_write(phydev, MII_BMCR, BMCR_RESET); + if (err < 0) +@@ -229,11 +312,11 @@ static int m88e1121_config_aneg(struct phy_device *phydev) + if (err < 0) + return err; + +- oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE); ++ oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); + +- phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); ++ phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE); + phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF); +- phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage); ++ phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); + + err = genphy_config_aneg(phydev); + +@@ -244,9 +327,9 @@ static int m88e1318_config_aneg(struct phy_device *phydev) + { + int err, oldpage, mscr; + +- oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE); ++ oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE); + +- err = phy_write(phydev, MII_88E1121_PHY_PAGE, ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, + MII_88E1121_PHY_MSCR_PAGE); + if (err < 0) + return err; +@@ -258,7 +341,7 @@ static int m88e1318_config_aneg(struct phy_device *phydev) + if (err < 0) + return err; + +- err = phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage); ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage); + if (err < 0) + return err; + +@@ -368,6 +451,9 @@ static int m88e1111_config_init(struct phy_device *phydev) + return err; + } + ++ err = marvell_of_reg_init(phydev); ++ if (err < 0) ++ return err; + + err = phy_write(phydev, MII_BMCR, BMCR_RESET); + if (err < 0) +@@ -398,7 +484,7 @@ static int m88e1118_config_init(struct phy_device *phydev) + int err; + + /* Change address */ +- err = phy_write(phydev, 0x16, 0x0002); ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002); + if (err < 0) + return err; + +@@ -408,7 +494,7 @@ static int m88e1118_config_init(struct phy_device *phydev) + return err; + + /* Change address */ +- err = phy_write(phydev, 0x16, 0x0003); ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0003); + if (err < 0) + return err; + +@@ -420,8 +506,42 @@ static int m88e1118_config_init(struct phy_device *phydev) + if (err < 0) + return err; + ++ err = marvell_of_reg_init(phydev); ++ if (err < 0) ++ return err; ++ + /* Reset address */ +- err = phy_write(phydev, 0x16, 0x0); ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); ++ if (err < 0) ++ return err; ++ ++ err = phy_write(phydev, MII_BMCR, BMCR_RESET); ++ if (err < 0) ++ return err; ++ ++ return 0; ++} ++ ++static int m88e1149_config_init(struct phy_device *phydev) ++{ ++ int err; ++ ++ /* Change address */ ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002); ++ if (err < 0) ++ return err; ++ ++ /* Enable 1000 Mbit */ ++ err = phy_write(phydev, 0x15, 0x1048); ++ if (err < 0) ++ return err; ++ ++ err = marvell_of_reg_init(phydev); ++ if (err < 0) ++ return err; ++ ++ /* Reset address */ ++ err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0); + if (err < 0) + return err; + +@@ -491,6 +611,10 @@ static int m88e1145_config_init(struct phy_device *phydev) + } + } + ++ err = marvell_of_reg_init(phydev); ++ if (err < 0) ++ return err; ++ + return 0; + } + +@@ -685,6 +809,19 @@ static struct phy_driver marvell_drivers[] = { + .driver = { .owner = THIS_MODULE }, + }, + { ++ .phy_id = MARVELL_PHY_ID_88E1149R, ++ .phy_id_mask = MARVELL_PHY_ID_MASK, ++ .name = "Marvell 88E1149R", ++ .features = PHY_GBIT_FEATURES, ++ .flags = PHY_HAS_INTERRUPT, ++ .config_init = &m88e1149_config_init, ++ .config_aneg = &m88e1118_config_aneg, ++ .read_status = &genphy_read_status, ++ .ack_interrupt = &marvell_ack_interrupt, ++ .config_intr = &marvell_config_intr, ++ .driver = { .owner = THIS_MODULE }, ++ }, ++ { + .phy_id = MARVELL_PHY_ID_88E1240, + .phy_id_mask = MARVELL_PHY_ID_MASK, + .name = "Marvell 88E1240", +@@ -735,6 +872,7 @@ static struct mdio_device_id __maybe_unused marvell_tbl[] = { + { 0x01410e10, 0xfffffff0 }, + { 0x01410cb0, 0xfffffff0 }, + { 0x01410cd0, 0xfffffff0 }, ++ { 0x01410e50, 0xfffffff0 }, + { 0x01410e30, 0xfffffff0 }, + { 0x01410e90, 0xfffffff0 }, + { } +diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c +index c30e0fe..528eaef 100644 +--- a/drivers/net/qlge/qlge_main.c ++++ b/drivers/net/qlge/qlge_main.c +@@ -62,15 +62,15 @@ static const u32 default_msg = + /* NETIF_MSG_PKTDATA | */ + NETIF_MSG_HW | NETIF_MSG_WOL | 0; + +-static int debug = 0x00007fff; /* defaults above */ +-module_param(debug, int, 0); ++static int debug = -1; /* defaults above */ ++module_param(debug, int, 0664); + MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); + + #define MSIX_IRQ 0 + #define MSI_IRQ 1 + #define LEG_IRQ 2 + static int qlge_irq_type = MSIX_IRQ; +-module_param(qlge_irq_type, int, MSIX_IRQ); ++module_param(qlge_irq_type, int, 0664); + MODULE_PARM_DESC(qlge_irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy."); + + static int qlge_mpi_coredump; +diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c +index ea071a5..44447f5 100644 +--- a/drivers/usb/atm/ueagle-atm.c ++++ b/drivers/usb/atm/ueagle-atm.c +@@ -2301,7 +2301,7 @@ out: + return ret; + } + +-static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot); ++static DEVICE_ATTR(stat_status, S_IWUSR | S_IRUGO, read_status, reboot); + + static ssize_t read_human_status(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -2364,8 +2364,7 @@ out: + return ret; + } + +-static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, +- read_human_status, NULL); ++static DEVICE_ATTR(stat_human_status, S_IRUGO, read_human_status, NULL); + + static ssize_t read_delin(struct device *dev, struct device_attribute *attr, + char *buf) +@@ -2397,7 +2396,7 @@ out: + return ret; + } + +-static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL); ++static DEVICE_ATTR(stat_delin, S_IRUGO, read_delin, NULL); + + #define UEA_ATTR(name, reset) \ + \ +diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c +index b5e20e8..717ff65 100644 +--- a/drivers/usb/gadget/atmel_usba_udc.c ++++ b/drivers/usb/gadget/atmel_usba_udc.c +@@ -2017,7 +2017,7 @@ static int __init usba_udc_probe(struct platform_device *pdev) + } + } else { + /* gpio_request fail so use -EINVAL for gpio_is_valid */ +- ubc->vbus_pin = -EINVAL; ++ udc->vbus_pin = -EINVAL; + } + } + +diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c +index 86afdc7..6e25996 100644 +--- a/drivers/usb/host/ehci-dbg.c ++++ b/drivers/usb/host/ehci-dbg.c +@@ -1067,7 +1067,7 @@ static inline void create_debug_files (struct ehci_hcd *ehci) + &debug_registers_fops)) + goto file_error; + +- if (!debugfs_create_file("lpm", S_IRUGO|S_IWUGO, ehci->debug_dir, bus, ++ if (!debugfs_create_file("lpm", S_IRUGO|S_IWUSR, ehci->debug_dir, bus, + &debug_lpm_fops)) + goto file_error; + +diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c +index 502a7e6..e906280 100644 +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -1063,10 +1063,11 @@ rescan: + tmp && tmp != qh; + tmp = tmp->qh_next.qh) + continue; +- /* periodic qh self-unlinks on empty */ +- if (!tmp) +- goto nogood; +- unlink_async (ehci, qh); ++ /* periodic qh self-unlinks on empty, and a COMPLETING qh ++ * may already be unlinked. ++ */ ++ if (tmp) ++ unlink_async(ehci, qh); + /* FALL THROUGH */ + case QH_STATE_UNLINK: /* wait for hw to finish? */ + case QH_STATE_UNLINK_WAIT: +@@ -1083,7 +1084,6 @@ idle_timeout: + } + /* else FALL THROUGH */ + default: +-nogood: + /* caller was supposed to have unlinked any requests; + * that's not our job. just leak this memory. + */ +diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c +index d36e4e7..12f70c3 100644 +--- a/drivers/usb/host/ehci-mem.c ++++ b/drivers/usb/host/ehci-mem.c +@@ -141,6 +141,10 @@ static void ehci_mem_cleanup (struct ehci_hcd *ehci) + qh_put (ehci->async); + ehci->async = NULL; + ++ if (ehci->dummy) ++ qh_put(ehci->dummy); ++ ehci->dummy = NULL; ++ + /* DMA consistent memory and pools */ + if (ehci->qtd_pool) + dma_pool_destroy (ehci->qtd_pool); +@@ -227,8 +231,26 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags) + if (ehci->periodic == NULL) { + goto fail; + } +- for (i = 0; i < ehci->periodic_size; i++) +- ehci->periodic [i] = EHCI_LIST_END(ehci); ++ ++ if (ehci->use_dummy_qh) { ++ struct ehci_qh_hw *hw; ++ ehci->dummy = ehci_qh_alloc(ehci, flags); ++ if (!ehci->dummy) ++ goto fail; ++ ++ hw = ehci->dummy->hw; ++ hw->hw_next = EHCI_LIST_END(ehci); ++ hw->hw_qtd_next = EHCI_LIST_END(ehci); ++ hw->hw_alt_next = EHCI_LIST_END(ehci); ++ hw->hw_token &= ~QTD_STS_ACTIVE; ++ ehci->dummy->hw = hw; ++ ++ for (i = 0; i < ehci->periodic_size; i++) ++ ehci->periodic[i] = ehci->dummy->qh_dma; ++ } else { ++ for (i = 0; i < ehci->periodic_size; i++) ++ ehci->periodic[i] = EHCI_LIST_END(ehci); ++ } + + /* software shadow of hardware table */ + ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags); +diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c +index a1e8d27..01bb72b 100644 +--- a/drivers/usb/host/ehci-pci.c ++++ b/drivers/usb/host/ehci-pci.c +@@ -103,6 +103,19 @@ static int ehci_pci_setup(struct usb_hcd *hcd) + if (retval) + return retval; + ++ if ((pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x7808) || ++ (pdev->vendor == PCI_VENDOR_ID_ATI && pdev->device == 0x4396)) { ++ /* EHCI controller on AMD SB700/SB800/Hudson-2/3 platforms may ++ * read/write memory space which does not belong to it when ++ * there is NULL pointer with T-bit set to 1 in the frame list ++ * table. To avoid the issue, the frame list link pointer ++ * should always contain a valid pointer to a inactive qh. ++ */ ++ ehci->use_dummy_qh = 1; ++ ehci_info(ehci, "applying AMD SB700/SB800/Hudson-2/3 EHCI " ++ "dummy qh workaround\n"); ++ } ++ + /* data structure init */ + retval = ehci_init(hcd); + if (retval) +diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c +index a92526d..d9f78eb 100644 +--- a/drivers/usb/host/ehci-sched.c ++++ b/drivers/usb/host/ehci-sched.c +@@ -98,7 +98,14 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) + */ + *prev_p = *periodic_next_shadow(ehci, &here, + Q_NEXT_TYPE(ehci, *hw_p)); +- *hw_p = *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p)); ++ ++ if (!ehci->use_dummy_qh || ++ *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p)) ++ != EHCI_LIST_END(ehci)) ++ *hw_p = *shadow_next_periodic(ehci, &here, ++ Q_NEXT_TYPE(ehci, *hw_p)); ++ else ++ *hw_p = ehci->dummy->qh_dma; + } + + /* how many of the uframe's 125 usecs are allocated? */ +@@ -2335,7 +2342,11 @@ restart: + * pointer for much longer, if at all. + */ + *q_p = q.itd->itd_next; +- *hw_p = q.itd->hw_next; ++ if (!ehci->use_dummy_qh || ++ q.itd->hw_next != EHCI_LIST_END(ehci)) ++ *hw_p = q.itd->hw_next; ++ else ++ *hw_p = ehci->dummy->qh_dma; + type = Q_NEXT_TYPE(ehci, q.itd->hw_next); + wmb(); + modified = itd_complete (ehci, q.itd); +@@ -2368,7 +2379,11 @@ restart: + * URB completion. + */ + *q_p = q.sitd->sitd_next; +- *hw_p = q.sitd->hw_next; ++ if (!ehci->use_dummy_qh || ++ q.sitd->hw_next != EHCI_LIST_END(ehci)) ++ *hw_p = q.sitd->hw_next; ++ else ++ *hw_p = ehci->dummy->qh_dma; + type = Q_NEXT_TYPE(ehci, q.sitd->hw_next); + wmb(); + modified = sitd_complete (ehci, q.sitd); +diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h +index bde823f..ba8eab3 100644 +--- a/drivers/usb/host/ehci.h ++++ b/drivers/usb/host/ehci.h +@@ -73,6 +73,7 @@ struct ehci_hcd { /* one per controller */ + + /* async schedule support */ + struct ehci_qh *async; ++ struct ehci_qh *dummy; /* For AMD quirk use */ + struct ehci_qh *reclaim; + unsigned scanning : 1; + +@@ -131,6 +132,7 @@ struct ehci_hcd { /* one per controller */ + unsigned need_io_watchdog:1; + unsigned broken_periodic:1; + unsigned fs_i_thresh:1; /* Intel iso scheduling */ ++ unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/ + + /* required for usb32 quirk */ + #define OHCI_CTRL_HCFS (3 << 6) +diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c +index 6c4fb4e..43a39eb 100644 +--- a/drivers/usb/host/isp1362-hcd.c ++++ b/drivers/usb/host/isp1362-hcd.c +@@ -2683,7 +2683,7 @@ static int __devexit isp1362_remove(struct platform_device *pdev) + return 0; + } + +-static int __init isp1362_probe(struct platform_device *pdev) ++static int __devinit isp1362_probe(struct platform_device *pdev) + { + struct usb_hcd *hcd; + struct isp1362_hcd *isp1362_hcd; +diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c +index 2027706..d178761 100644 +--- a/drivers/usb/host/xhci-mem.c ++++ b/drivers/usb/host/xhci-mem.c +@@ -1045,7 +1045,7 @@ static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, + if (udev->speed == USB_SPEED_SUPER) + return ep->ss_ep_comp.wBytesPerInterval; + +- max_packet = ep->desc.wMaxPacketSize & 0x3ff; ++ max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize); + max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11; + /* A 0 in max burst means 1 transfer per ESIT */ + return max_packet * (max_burst + 1); +@@ -1135,7 +1135,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, + /* Fall through */ + case USB_SPEED_FULL: + case USB_SPEED_LOW: +- max_packet = ep->desc.wMaxPacketSize & 0x3ff; ++ max_packet = GET_MAX_PACKET(ep->desc.wMaxPacketSize); + ep_ctx->ep_info2 |= MAX_PACKET(max_packet); + break; + default: +diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c +index 9f3115e..df558f6 100644 +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -2104,7 +2104,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) + + if (!(status & STS_EINT)) { + spin_unlock(&xhci->lock); +- xhci_warn(xhci, "Spurious interrupt.\n"); + return IRQ_NONE; + } + xhci_dbg(xhci, "op reg status = %08x\n", status); +diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c +index 5d7d4e9..06fca08 100644 +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -577,6 +577,65 @@ static void xhci_restore_registers(struct xhci_hcd *xhci) + xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base); + } + ++static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) ++{ ++ u64 val_64; ++ ++ /* step 2: initialize command ring buffer */ ++ val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); ++ val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | ++ (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, ++ xhci->cmd_ring->dequeue) & ++ (u64) ~CMD_RING_RSVD_BITS) | ++ xhci->cmd_ring->cycle_state; ++ xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n", ++ (long unsigned long) val_64); ++ xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); ++} ++ ++/* ++ * The whole command ring must be cleared to zero when we suspend the host. ++ * ++ * The host doesn't save the command ring pointer in the suspend well, so we ++ * need to re-program it on resume. Unfortunately, the pointer must be 64-byte ++ * aligned, because of the reserved bits in the command ring dequeue pointer ++ * register. Therefore, we can't just set the dequeue pointer back in the ++ * middle of the ring (TRBs are 16-byte aligned). ++ */ ++static void xhci_clear_command_ring(struct xhci_hcd *xhci) ++{ ++ struct xhci_ring *ring; ++ struct xhci_segment *seg; ++ ++ ring = xhci->cmd_ring; ++ seg = ring->deq_seg; ++ do { ++ memset(seg->trbs, 0, SEGMENT_SIZE); ++ seg = seg->next; ++ } while (seg != ring->deq_seg); ++ ++ /* Reset the software enqueue and dequeue pointers */ ++ ring->deq_seg = ring->first_seg; ++ ring->dequeue = ring->first_seg->trbs; ++ ring->enq_seg = ring->deq_seg; ++ ring->enqueue = ring->dequeue; ++ ++ /* ++ * Ring is now zeroed, so the HW should look for change of ownership ++ * when the cycle bit is set to 1. ++ */ ++ ring->cycle_state = 1; ++ ++ /* ++ * Reset the hardware dequeue pointer. ++ * Yes, this will need to be re-written after resume, but we're paranoid ++ * and want to make sure the hardware doesn't access bogus memory ++ * because, say, the BIOS or an SMI started the host without changing ++ * the command ring pointers. ++ */ ++ xhci_set_cmd_ring_deq(xhci); ++} ++ + /* + * Stop HC (not bus-specific) + * +@@ -604,6 +663,7 @@ int xhci_suspend(struct xhci_hcd *xhci) + spin_unlock_irq(&xhci->lock); + return -ETIMEDOUT; + } ++ xhci_clear_command_ring(xhci); + + /* step 3: save registers */ + xhci_save_registers(xhci); +@@ -635,7 +695,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + u32 command, temp = 0; + struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); +- u64 val_64; + int old_state, retval; + + old_state = hcd->state; +@@ -648,15 +707,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + /* step 1: restore register */ + xhci_restore_registers(xhci); + /* step 2: initialize command ring buffer */ +- val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); +- val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | +- (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, +- xhci->cmd_ring->dequeue) & +- (u64) ~CMD_RING_RSVD_BITS) | +- xhci->cmd_ring->cycle_state; +- xhci_dbg(xhci, "// Setting command ring address to 0x%llx\n", +- (long unsigned long) val_64); +- xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring); ++ xhci_set_cmd_ring_deq(xhci); + /* step 3: restore state and start state*/ + /* step 3: set CRS flag */ + command = xhci_readl(xhci, &xhci->op_regs->command); +@@ -714,6 +765,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + return retval; + } + ++ spin_unlock_irq(&xhci->lock); + /* Re-setup MSI-X */ + if (hcd->irq) + free_irq(hcd->irq, hcd); +@@ -736,6 +788,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) + hcd->irq = pdev->irq; + } + ++ spin_lock_irq(&xhci->lock); + /* step 4: set Run/Stop bit */ + command = xhci_readl(xhci, &xhci->op_regs->command); + command |= CMD_RUN; +diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h +index 93d3bf4..85e6564 100644 +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -621,6 +621,11 @@ struct xhci_ep_ctx { + #define MAX_PACKET_MASK (0xffff << 16) + #define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff) + ++/* Get max packet size from ep desc. Bit 10..0 specify the max packet size. ++ * USB2.0 spec 9.6.6. ++ */ ++#define GET_MAX_PACKET(p) ((p) & 0x7ff) ++ + /* tx_info bitmasks */ + #define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff) + #define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16) +diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c +index 2f43c57..9251773 100644 +--- a/drivers/usb/misc/cypress_cy7c63.c ++++ b/drivers/usb/misc/cypress_cy7c63.c +@@ -196,11 +196,9 @@ static ssize_t get_port1_handler(struct device *dev, + return read_port(dev, attr, buf, 1, CYPRESS_READ_PORT_ID1); + } + +-static DEVICE_ATTR(port0, S_IWUGO | S_IRUGO, +- get_port0_handler, set_port0_handler); ++static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR, get_port0_handler, set_port0_handler); + +-static DEVICE_ATTR(port1, S_IWUGO | S_IRUGO, +- get_port1_handler, set_port1_handler); ++static DEVICE_ATTR(port1, S_IRUGO | S_IWUSR, get_port1_handler, set_port1_handler); + + + static int cypress_probe(struct usb_interface *interface, +diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c +index d77aba4..f63776a 100644 +--- a/drivers/usb/misc/trancevibrator.c ++++ b/drivers/usb/misc/trancevibrator.c +@@ -86,7 +86,7 @@ static ssize_t set_speed(struct device *dev, struct device_attribute *attr, + return count; + } + +-static DEVICE_ATTR(speed, S_IWUGO | S_IRUGO, show_speed, set_speed); ++static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR, show_speed, set_speed); + + static int tv_probe(struct usb_interface *interface, + const struct usb_device_id *id) +diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c +index 63da2c3..c96f51d 100644 +--- a/drivers/usb/misc/usbled.c ++++ b/drivers/usb/misc/usbled.c +@@ -94,7 +94,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co + change_color(led); \ + return count; \ + } \ +-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value); ++static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, show_##value, set_##value); + show_set(blue); + show_set(red); + show_set(green); +diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c +index de8ef94..417b8f2 100644 +--- a/drivers/usb/misc/usbsevseg.c ++++ b/drivers/usb/misc/usbsevseg.c +@@ -192,7 +192,7 @@ static ssize_t set_attr_##name(struct device *dev, \ + \ + return count; \ + } \ +-static DEVICE_ATTR(name, S_IWUGO | S_IRUGO, show_attr_##name, set_attr_##name); ++static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_attr_##name, set_attr_##name); + + static ssize_t show_attr_text(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -223,7 +223,7 @@ static ssize_t set_attr_text(struct device *dev, + return count; + } + +-static DEVICE_ATTR(text, S_IWUGO | S_IRUGO, show_attr_text, set_attr_text); ++static DEVICE_ATTR(text, S_IRUGO | S_IWUSR, show_attr_text, set_attr_text); + + static ssize_t show_attr_decimals(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -272,8 +272,7 @@ static ssize_t set_attr_decimals(struct device *dev, + return count; + } + +-static DEVICE_ATTR(decimals, S_IWUGO | S_IRUGO, +- show_attr_decimals, set_attr_decimals); ++static DEVICE_ATTR(decimals, S_IRUGO | S_IWUSR, show_attr_decimals, set_attr_decimals); + + static ssize_t show_attr_textmode(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -319,8 +318,7 @@ static ssize_t set_attr_textmode(struct device *dev, + return -EINVAL; + } + +-static DEVICE_ATTR(textmode, S_IWUGO | S_IRUGO, +- show_attr_textmode, set_attr_textmode); ++static DEVICE_ATTR(textmode, S_IRUGO | S_IWUSR, show_attr_textmode, set_attr_textmode); + + + MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered); +diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c +index bdc3ea6..9fea482 100644 +--- a/drivers/usb/otg/langwell_otg.c ++++ b/drivers/usb/otg/langwell_otg.c +@@ -1896,7 +1896,7 @@ set_a_bus_req(struct device *dev, struct device_attribute *attr, + } + return count; + } +-static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req); ++static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req); + + static ssize_t + get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf) +@@ -1942,8 +1942,7 @@ set_a_bus_drop(struct device *dev, struct device_attribute *attr, + } + return count; + } +-static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO, +- get_a_bus_drop, set_a_bus_drop); ++static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop, set_a_bus_drop); + + static ssize_t + get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf) +@@ -1988,7 +1987,7 @@ set_b_bus_req(struct device *dev, struct device_attribute *attr, + } + return count; + } +-static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req); ++static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req); + + static ssize_t + set_a_clr_err(struct device *dev, struct device_attribute *attr, +@@ -2012,7 +2011,7 @@ set_a_clr_err(struct device *dev, struct device_attribute *attr, + } + return count; + } +-static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err); ++static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err); + + static struct attribute *inputs_attrs[] = { + &dev_attr_a_bus_req.attr, +diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c +index 57fc2f5..ceba512 100644 +--- a/drivers/usb/storage/sierra_ms.c ++++ b/drivers/usb/storage/sierra_ms.c +@@ -121,7 +121,7 @@ static ssize_t show_truinst(struct device *dev, struct device_attribute *attr, + } + return result; + } +-static DEVICE_ATTR(truinst, S_IWUGO | S_IRUGO, show_truinst, NULL); ++static DEVICE_ATTR(truinst, S_IRUGO, show_truinst, NULL); + + int sierra_ms_init(struct us_data *us) + { +diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile +index eb8a78d..533a199 100644 +--- a/drivers/xen/Makefile ++++ b/drivers/xen/Makefile +@@ -8,9 +8,12 @@ obj-$(CONFIG_BLOCK) += biomerge.o + obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o + obj-$(CONFIG_XEN_XENCOMM) += xencomm.o + obj-$(CONFIG_XEN_BALLOON) += balloon.o +-obj-$(CONFIG_XEN_DEV_EVTCHN) += evtchn.o ++obj-$(CONFIG_XEN_DEV_EVTCHN) += xen-evtchn.o + obj-$(CONFIG_XENFS) += xenfs/ + obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o + obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o + obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o + obj-$(CONFIG_XEN_DOM0) += pci.o ++ ++xen-evtchn-y := evtchn.o ++ +diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c +index 500290b..2b17ad5 100644 +--- a/drivers/xen/balloon.c ++++ b/drivers/xen/balloon.c +@@ -50,6 +50,7 @@ + #include <asm/pgtable.h> + #include <asm/uaccess.h> + #include <asm/tlb.h> ++#include <asm/e820.h> + + #include <asm/xen/hypervisor.h> + #include <asm/xen/hypercall.h> +@@ -119,7 +120,7 @@ static void scrub_page(struct page *page) + } + + /* balloon_append: add the given page to the balloon. */ +-static void balloon_append(struct page *page) ++static void __balloon_append(struct page *page) + { + /* Lowmem is re-populated first, so highmem pages go at list tail. */ + if (PageHighMem(page)) { +@@ -130,7 +131,11 @@ static void balloon_append(struct page *page) + list_add(&page->lru, &ballooned_pages); + balloon_stats.balloon_low++; + } ++} + ++static void balloon_append(struct page *page) ++{ ++ __balloon_append(page); + totalram_pages--; + } + +@@ -191,7 +196,7 @@ static unsigned long current_target(void) + + static int increase_reservation(unsigned long nr_pages) + { +- unsigned long pfn, i, flags; ++ unsigned long pfn, i; + struct page *page; + long rc; + struct xen_memory_reservation reservation = { +@@ -203,8 +208,6 @@ static int increase_reservation(unsigned long nr_pages) + if (nr_pages > ARRAY_SIZE(frame_list)) + nr_pages = ARRAY_SIZE(frame_list); + +- spin_lock_irqsave(&xen_reservation_lock, flags); +- + page = balloon_first_page(); + for (i = 0; i < nr_pages; i++) { + BUG_ON(page == NULL); +@@ -247,14 +250,12 @@ static int increase_reservation(unsigned long nr_pages) + balloon_stats.current_pages += rc; + + out: +- spin_unlock_irqrestore(&xen_reservation_lock, flags); +- + return rc < 0 ? rc : rc != nr_pages; + } + + static int decrease_reservation(unsigned long nr_pages) + { +- unsigned long pfn, i, flags; ++ unsigned long pfn, i; + struct page *page; + int need_sleep = 0; + int ret; +@@ -292,8 +293,6 @@ static int decrease_reservation(unsigned long nr_pages) + kmap_flush_unused(); + flush_tlb_all(); + +- spin_lock_irqsave(&xen_reservation_lock, flags); +- + /* No more mappings: invalidate P2M and add to balloon. */ + for (i = 0; i < nr_pages; i++) { + pfn = mfn_to_pfn(frame_list[i]); +@@ -308,8 +307,6 @@ static int decrease_reservation(unsigned long nr_pages) + + balloon_stats.current_pages -= nr_pages; + +- spin_unlock_irqrestore(&xen_reservation_lock, flags); +- + return need_sleep; + } + +@@ -395,7 +392,7 @@ static struct notifier_block xenstore_notifier; + + static int __init balloon_init(void) + { +- unsigned long pfn; ++ unsigned long pfn, extra_pfn_end; + struct page *page; + + if (!xen_pv_domain()) +@@ -416,10 +413,15 @@ static int __init balloon_init(void) + register_balloon(&balloon_sysdev); + + /* Initialise the balloon with excess memory space. */ +- for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) { ++ extra_pfn_end = min(e820_end_of_ram_pfn(), ++ (unsigned long)PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size)); ++ for (pfn = PFN_UP(xen_extra_mem_start); ++ pfn < extra_pfn_end; ++ pfn++) { + page = pfn_to_page(pfn); +- if (!PageReserved(page)) +- balloon_append(page); ++ /* totalram_pages doesn't include the boot-time ++ balloon extension, so don't subtract from it. */ ++ __balloon_append(page); + } + + target_watch.callback = watch_target; +diff --git a/drivers/xen/events.c b/drivers/xen/events.c +index 321a0c8..2811bb9 100644 +--- a/drivers/xen/events.c ++++ b/drivers/xen/events.c +@@ -278,17 +278,17 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu) + cpumask_copy(irq_to_desc(irq)->affinity, cpumask_of(cpu)); + #endif + +- __clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq))); +- __set_bit(chn, cpu_evtchn_mask(cpu)); ++ clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq))); ++ set_bit(chn, cpu_evtchn_mask(cpu)); + + irq_info[irq].cpu = cpu; + } + + static void init_evtchn_cpu_bindings(void) + { ++ int i; + #ifdef CONFIG_SMP + struct irq_desc *desc; +- int i; + + /* By default all event channels notify CPU#0. */ + for_each_irq_desc(i, desc) { +@@ -296,7 +296,10 @@ static void init_evtchn_cpu_bindings(void) + } + #endif + +- memset(cpu_evtchn_mask(0), ~0, sizeof(struct cpu_evtchn_s)); ++ for_each_possible_cpu(i) ++ memset(cpu_evtchn_mask(i), ++ (i == 0) ? ~0 : 0, sizeof(struct cpu_evtchn_s)); ++ + } + + static inline void clear_evtchn(int port) +@@ -752,7 +755,7 @@ int xen_destroy_irq(int irq) + goto out; + + if (xen_initial_domain()) { +- unmap_irq.pirq = info->u.pirq.gsi; ++ unmap_irq.pirq = info->u.pirq.pirq; + unmap_irq.domid = DOMID_SELF; + rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq); + if (rc) { +diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c +index fec6ba3..ef11daf 100644 +--- a/drivers/xen/evtchn.c ++++ b/drivers/xen/evtchn.c +@@ -69,20 +69,51 @@ struct per_user_data { + const char *name; + }; + +-/* Who's bound to each port? */ +-static struct per_user_data *port_user[NR_EVENT_CHANNELS]; ++/* ++ * Who's bound to each port? This is logically an array of struct ++ * per_user_data *, but we encode the current enabled-state in bit 0. ++ */ ++static unsigned long *port_user; + static DEFINE_SPINLOCK(port_user_lock); /* protects port_user[] and ring_prod */ + +-irqreturn_t evtchn_interrupt(int irq, void *data) ++static inline struct per_user_data *get_port_user(unsigned port) ++{ ++ return (struct per_user_data *)(port_user[port] & ~1); ++} ++ ++static inline void set_port_user(unsigned port, struct per_user_data *u) ++{ ++ port_user[port] = (unsigned long)u; ++} ++ ++static inline bool get_port_enabled(unsigned port) ++{ ++ return port_user[port] & 1; ++} ++ ++static inline void set_port_enabled(unsigned port, bool enabled) ++{ ++ if (enabled) ++ port_user[port] |= 1; ++ else ++ port_user[port] &= ~1; ++} ++ ++static irqreturn_t evtchn_interrupt(int irq, void *data) + { + unsigned int port = (unsigned long)data; + struct per_user_data *u; + + spin_lock(&port_user_lock); + +- u = port_user[port]; ++ u = get_port_user(port); ++ ++ WARN(!get_port_enabled(port), ++ "Interrupt for port %d, but apparently not enabled; per-user %p\n", ++ port, u); + + disable_irq_nosync(irq); ++ set_port_enabled(port, false); + + if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) { + u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port; +@@ -92,9 +123,8 @@ irqreturn_t evtchn_interrupt(int irq, void *data) + kill_fasync(&u->evtchn_async_queue, + SIGIO, POLL_IN); + } +- } else { ++ } else + u->ring_overflow = 1; +- } + + spin_unlock(&port_user_lock); + +@@ -198,9 +228,18 @@ static ssize_t evtchn_write(struct file *file, const char __user *buf, + goto out; + + spin_lock_irq(&port_user_lock); +- for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) +- if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u)) +- enable_irq(irq_from_evtchn(kbuf[i])); ++ ++ for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) { ++ unsigned port = kbuf[i]; ++ ++ if (port < NR_EVENT_CHANNELS && ++ get_port_user(port) == u && ++ !get_port_enabled(port)) { ++ set_port_enabled(port, true); ++ enable_irq(irq_from_evtchn(port)); ++ } ++ } ++ + spin_unlock_irq(&port_user_lock); + + rc = count; +@@ -222,8 +261,9 @@ static int evtchn_bind_to_user(struct per_user_data *u, int port) + * interrupt handler yet, and our caller has already + * serialized bind operations.) + */ +- BUG_ON(port_user[port] != NULL); +- port_user[port] = u; ++ BUG_ON(get_port_user(port) != NULL); ++ set_port_user(port, u); ++ set_port_enabled(port, true); /* start enabled */ + + rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED, + u->name, (void *)(unsigned long)port); +@@ -239,10 +279,7 @@ static void evtchn_unbind_from_user(struct per_user_data *u, int port) + + unbind_from_irqhandler(irq, (void *)(unsigned long)port); + +- /* make sure we unbind the irq handler before clearing the port */ +- barrier(); +- +- port_user[port] = NULL; ++ set_port_user(port, NULL); + } + + static long evtchn_ioctl(struct file *file, +@@ -333,15 +370,17 @@ static long evtchn_ioctl(struct file *file, + spin_lock_irq(&port_user_lock); + + rc = -ENOTCONN; +- if (port_user[unbind.port] != u) { ++ if (get_port_user(unbind.port) != u) { + spin_unlock_irq(&port_user_lock); + break; + } + +- evtchn_unbind_from_user(u, unbind.port); ++ disable_irq(irq_from_evtchn(unbind.port)); + + spin_unlock_irq(&port_user_lock); + ++ evtchn_unbind_from_user(u, unbind.port); ++ + rc = 0; + break; + } +@@ -355,7 +394,7 @@ static long evtchn_ioctl(struct file *file, + + if (notify.port >= NR_EVENT_CHANNELS) { + rc = -EINVAL; +- } else if (port_user[notify.port] != u) { ++ } else if (get_port_user(notify.port) != u) { + rc = -ENOTCONN; + } else { + notify_remote_via_evtchn(notify.port); +@@ -431,7 +470,7 @@ static int evtchn_open(struct inode *inode, struct file *filp) + + filp->private_data = u; + +- return 0; ++ return nonseekable_open(inode, filp);; + } + + static int evtchn_release(struct inode *inode, struct file *filp) +@@ -444,14 +483,21 @@ static int evtchn_release(struct inode *inode, struct file *filp) + free_page((unsigned long)u->ring); + + for (i = 0; i < NR_EVENT_CHANNELS; i++) { +- if (port_user[i] != u) ++ if (get_port_user(i) != u) + continue; + +- evtchn_unbind_from_user(port_user[i], i); ++ disable_irq(irq_from_evtchn(i)); + } + + spin_unlock_irq(&port_user_lock); + ++ for (i = 0; i < NR_EVENT_CHANNELS; i++) { ++ if (get_port_user(i) != u) ++ continue; ++ ++ evtchn_unbind_from_user(get_port_user(i), i); ++ } ++ + kfree(u->name); + kfree(u); + +@@ -467,12 +513,12 @@ static const struct file_operations evtchn_fops = { + .fasync = evtchn_fasync, + .open = evtchn_open, + .release = evtchn_release, +- .llseek = noop_llseek, ++ .llseek = no_llseek, + }; + + static struct miscdevice evtchn_miscdev = { + .minor = MISC_DYNAMIC_MINOR, +- .name = "evtchn", ++ .name = "xen/evtchn", + .fops = &evtchn_fops, + }; + static int __init evtchn_init(void) +@@ -482,8 +528,11 @@ static int __init evtchn_init(void) + if (!xen_domain()) + return -ENODEV; + ++ port_user = kcalloc(NR_EVENT_CHANNELS, sizeof(*port_user), GFP_KERNEL); ++ if (port_user == NULL) ++ return -ENOMEM; ++ + spin_lock_init(&port_user_lock); +- memset(port_user, 0, sizeof(port_user)); + + /* Create '/dev/misc/evtchn'. */ + err = misc_register(&evtchn_miscdev); +@@ -499,6 +548,9 @@ static int __init evtchn_init(void) + + static void __exit evtchn_cleanup(void) + { ++ kfree(port_user); ++ port_user = NULL; ++ + misc_deregister(&evtchn_miscdev); + } + +diff --git a/drivers/xen/xenfs/privcmd.c b/drivers/xen/xenfs/privcmd.c +index 0f5d416..dbd3b16 100644 +--- a/drivers/xen/xenfs/privcmd.c ++++ b/drivers/xen/xenfs/privcmd.c +@@ -265,9 +265,7 @@ static int mmap_return_errors(void *data, void *state) + xen_pfn_t *mfnp = data; + struct mmap_batch_state *st = state; + +- put_user(*mfnp, st->user++); +- +- return 0; ++ return put_user(*mfnp, st->user++); + } + + static struct vm_operations_struct privcmd_vm_ops; +@@ -322,10 +320,8 @@ static long privcmd_ioctl_mmap_batch(void __user *udata) + up_write(&mm->mmap_sem); + + if (state.err > 0) { +- ret = 0; +- + state.user = m.arr; +- traverse_pages(m.num, sizeof(xen_pfn_t), ++ ret = traverse_pages(m.num, sizeof(xen_pfn_t), + &pagelist, + mmap_return_errors, &state); + } +@@ -383,8 +379,9 @@ static int privcmd_mmap(struct file *file, struct vm_area_struct *vma) + if (xen_feature(XENFEAT_auto_translated_physmap)) + return -ENOSYS; + +- /* DONTCOPY is essential for Xen as copy_page_range is broken. */ +- vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY; ++ /* DONTCOPY is essential for Xen because copy_page_range doesn't know ++ * how to recreate these mappings */ ++ vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP; + vma->vm_ops = &privcmd_vm_ops; + vma->vm_private_data = NULL; + +diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c +index f6339d1..1aa3897 100644 +--- a/drivers/xen/xenfs/super.c ++++ b/drivers/xen/xenfs/super.c +@@ -12,8 +12,6 @@ + #include <linux/module.h> + #include <linux/fs.h> + #include <linux/magic.h> +-#include <linux/mm.h> +-#include <linux/backing-dev.h> + + #include <xen/xen.h> + +@@ -24,28 +22,12 @@ + MODULE_DESCRIPTION("Xen filesystem"); + MODULE_LICENSE("GPL"); + +-static int xenfs_set_page_dirty(struct page *page) +-{ +- return !TestSetPageDirty(page); +-} +- +-static const struct address_space_operations xenfs_aops = { +- .set_page_dirty = xenfs_set_page_dirty, +-}; +- +-static struct backing_dev_info xenfs_backing_dev_info = { +- .ra_pages = 0, /* No readahead */ +- .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, +-}; +- + static struct inode *xenfs_make_inode(struct super_block *sb, int mode) + { + struct inode *ret = new_inode(sb); + + if (ret) { + ret->i_mode = mode; +- ret->i_mapping->a_ops = &xenfs_aops; +- ret->i_mapping->backing_dev_info = &xenfs_backing_dev_info; + ret->i_uid = ret->i_gid = 0; + ret->i_blocks = 0; + ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; +@@ -121,9 +103,9 @@ static int xenfs_fill_super(struct super_block *sb, void *data, int silent) + return rc; + } + +-static int xenfs_mount(struct file_system_type *fs_type, +- int flags, const char *dev_name, +- void *data) ++static struct dentry *xenfs_mount(struct file_system_type *fs_type, ++ int flags, const char *dev_name, ++ void *data) + { + return mount_single(fs_type, flags, data, xenfs_fill_super); + } +@@ -137,25 +119,11 @@ static struct file_system_type xenfs_type = { + + static int __init xenfs_init(void) + { +- int err; +- if (!xen_domain()) { +- printk(KERN_INFO "xenfs: not registering filesystem on non-xen platform\n"); +- return 0; +- } +- +- err = register_filesystem(&xenfs_type); +- if (err) { +- printk(KERN_ERR "xenfs: Unable to register filesystem!\n"); +- goto out; +- } +- +- err = bdi_init(&xenfs_backing_dev_info); +- if (err) +- unregister_filesystem(&xenfs_type); +- +- out: ++ if (xen_domain()) ++ return register_filesystem(&xenfs_type); + +- return err; ++ printk(KERN_INFO "XENFS: not registering filesystem on non-xen platform\n"); ++ return 0; + } + + static void __exit xenfs_exit(void) +diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h +index 1ff81b5..dd3c34e 100644 +--- a/include/linux/marvell_phy.h ++++ b/include/linux/marvell_phy.h +@@ -11,6 +11,7 @@ + #define MARVELL_PHY_ID_88E1118 0x01410e10 + #define MARVELL_PHY_ID_88E1121R 0x01410cb0 + #define MARVELL_PHY_ID_88E1145 0x01410cd0 ++#define MARVELL_PHY_ID_88E1149R 0x01410e50 + #define MARVELL_PHY_ID_88E1240 0x01410e30 + #define MARVELL_PHY_ID_88E1318S 0x01410e90 + +diff --git a/include/linux/mfd/wm8350/audio.h b/include/linux/mfd/wm8350/audio.h +index a95141e..bd581c6 100644 +--- a/include/linux/mfd/wm8350/audio.h ++++ b/include/linux/mfd/wm8350/audio.h +@@ -522,9 +522,6 @@ + #define WM8350_MCLK_SEL_PLL_32K 3 + #define WM8350_MCLK_SEL_MCLK 5 + +-#define WM8350_MCLK_DIR_OUT 0 +-#define WM8350_MCLK_DIR_IN 1 +- + /* clock divider id's */ + #define WM8350_ADC_CLKDIV 0 + #define WM8350_DAC_CLKDIV 1 +diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h +index d7a6c13..eac3ce1 100644 +--- a/include/xen/interface/memory.h ++++ b/include/xen/interface/memory.h +@@ -141,6 +141,19 @@ struct xen_machphys_mfn_list { + DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mfn_list); + + /* ++ * Returns the location in virtual address space of the machine_to_phys ++ * mapping table. Architectures which do not have a m2p table, or which do not ++ * map it by default into guest address space, do not implement this command. ++ * arg == addr of xen_machphys_mapping_t. ++ */ ++#define XENMEM_machphys_mapping 12 ++struct xen_machphys_mapping { ++ unsigned long v_start, v_end; /* Start and end virtual addresses. */ ++ unsigned long max_mfn; /* Maximum MFN that can be looked up. */ ++}; ++DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t); ++ ++/* + * Sets the GPFN at which a particular page appears in the specified guest's + * pseudophysical address space. + * arg == addr of xen_add_to_physmap_t. +diff --git a/include/xen/page.h b/include/xen/page.h +index eaf85fa..0be36b9 100644 +--- a/include/xen/page.h ++++ b/include/xen/page.h +@@ -1 +1,8 @@ ++#ifndef _XEN_PAGE_H ++#define _XEN_PAGE_H ++ + #include <asm/xen/page.h> ++ ++extern phys_addr_t xen_extra_mem_start, xen_extra_mem_size; ++ ++#endif /* _XEN_PAGE_H */ +diff --git a/include/xen/privcmd.h b/include/xen/privcmd.h +index b42cdfd..17857fb 100644 +--- a/include/xen/privcmd.h ++++ b/include/xen/privcmd.h +@@ -34,13 +34,10 @@ + #define __LINUX_PUBLIC_PRIVCMD_H__ + + #include <linux/types.h> ++#include <linux/compiler.h> + + typedef unsigned long xen_pfn_t; + +-#ifndef __user +-#define __user +-#endif +- + struct privcmd_hypercall { + __u64 op; + __u64 arg[5]; +diff --git a/net/ceph/buffer.c b/net/ceph/buffer.c +index 53d8abf..bf3e6a1 100644 +--- a/net/ceph/buffer.c ++++ b/net/ceph/buffer.c +@@ -19,7 +19,7 @@ struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp) + if (b->vec.iov_base) { + b->is_vmalloc = false; + } else { +- b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL); ++ b->vec.iov_base = __vmalloc(len, gfp | __GFP_HIGHMEM, PAGE_KERNEL); + if (!b->vec.iov_base) { + kfree(b); + return NULL; +diff --git a/net/core/request_sock.c b/net/core/request_sock.c +index 7552495..fceeb37 100644 +--- a/net/core/request_sock.c ++++ b/net/core/request_sock.c +@@ -45,9 +45,7 @@ int reqsk_queue_alloc(struct request_sock_queue *queue, + nr_table_entries = roundup_pow_of_two(nr_table_entries + 1); + lopt_size += nr_table_entries * sizeof(struct request_sock *); + if (lopt_size > PAGE_SIZE) +- lopt = __vmalloc(lopt_size, +- GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, +- PAGE_KERNEL); ++ lopt = vzalloc(lopt_size); + else + lopt = kzalloc(lopt_size, GFP_KERNEL); + if (lopt == NULL) +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index 200eb53..0f28034 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -365,7 +365,7 @@ static struct tnode *tnode_alloc(size_t size) + if (size <= PAGE_SIZE) + return kzalloc(size, GFP_KERNEL); + else +- return __vmalloc(size, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); ++ return vzalloc(size); + } + + static void __tnode_vfree(struct work_struct *arg) +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 2fc35b3..23cc8e1 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2758,13 +2758,13 @@ static int addrconf_ifdown(struct net_device *dev, int how) + ifa->state = INET6_IFADDR_STATE_DEAD; + spin_unlock_bh(&ifa->state_lock); + +- if (state == INET6_IFADDR_STATE_DEAD) { +- in6_ifa_put(ifa); +- } else { ++ if (state != INET6_IFADDR_STATE_DEAD) { + __ipv6_ifa_notify(RTM_DELADDR, ifa); + atomic_notifier_call_chain(&inet6addr_chain, + NETDEV_DOWN, ifa); + } ++ ++ in6_ifa_put(ifa); + write_lock_bh(&idev->lock); + } + } +diff --git a/net/xfrm/xfrm_hash.c b/net/xfrm/xfrm_hash.c +index a2023ec..1e98bc0 100644 +--- a/net/xfrm/xfrm_hash.c ++++ b/net/xfrm/xfrm_hash.c +@@ -19,7 +19,7 @@ struct hlist_head *xfrm_hash_alloc(unsigned int sz) + if (sz <= PAGE_SIZE) + n = kzalloc(sz, GFP_KERNEL); + else if (hashdist) +- n = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); ++ n = vzalloc(sz); + else + n = (struct hlist_head *) + __get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO, +diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c +index f2f41c8..6e24091 100644 +--- a/sound/atmel/abdac.c ++++ b/sound/atmel/abdac.c +@@ -420,9 +420,9 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev) + return PTR_ERR(pclk); + } + sample_clk = clk_get(&pdev->dev, "sample_clk"); +- if (IS_ERR(pclk)) { ++ if (IS_ERR(sample_clk)) { + dev_dbg(&pdev->dev, "no sample clock\n"); +- retval = PTR_ERR(pclk); ++ retval = PTR_ERR(sample_clk); + goto out_put_pclk; + } + clk_enable(pclk); +diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c +index a1707cc..b75db8e 100644 +--- a/sound/core/pcm_lib.c ++++ b/sound/core/pcm_lib.c +@@ -223,7 +223,7 @@ static void xrun_log(struct snd_pcm_substream *substream, + entry->jiffies = jiffies; + entry->pos = pos; + entry->period_size = runtime->period_size; +- entry->buffer_size = runtime->buffer_size;; ++ entry->buffer_size = runtime->buffer_size; + entry->old_hw_ptr = runtime->status->hw_ptr; + entry->hw_ptr_base = runtime->hw_ptr_base; + log->idx = (log->idx + 1) % XRUN_LOG_CNT; +diff --git a/sound/oss/dev_table.c b/sound/oss/dev_table.c +index 727bdb9..d8cf3e5 100644 +--- a/sound/oss/dev_table.c ++++ b/sound/oss/dev_table.c +@@ -71,7 +71,7 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver, + if (sound_nblocks >= MAX_MEM_BLOCKS) + sound_nblocks = MAX_MEM_BLOCKS - 1; + +- op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_operations))); ++ op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct audio_operations))); + sound_nblocks++; + if (sound_nblocks >= MAX_MEM_BLOCKS) + sound_nblocks = MAX_MEM_BLOCKS - 1; +@@ -81,7 +81,6 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver, + sound_unload_audiodev(num); + return -(ENOMEM); + } +- memset((char *) op, 0, sizeof(struct audio_operations)); + init_waitqueue_head(&op->in_sleeper); + init_waitqueue_head(&op->out_sleeper); + init_waitqueue_head(&op->poll_sleeper); +@@ -128,7 +127,7 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver, + /* FIXME: This leaks a mixer_operations struct every time its called + until you unload sound! */ + +- op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct mixer_operations))); ++ op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct mixer_operations))); + sound_nblocks++; + if (sound_nblocks >= MAX_MEM_BLOCKS) + sound_nblocks = MAX_MEM_BLOCKS - 1; +@@ -137,7 +136,6 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver, + printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name); + return -ENOMEM; + } +- memset((char *) op, 0, sizeof(struct mixer_operations)); + memcpy((char *) op, (char *) driver, driver_size); + + strlcpy(op->name, name, sizeof(op->name)); +diff --git a/sound/oss/midibuf.c b/sound/oss/midibuf.c +index 782b3b8..ceedb1e 100644 +--- a/sound/oss/midibuf.c ++++ b/sound/oss/midibuf.c +@@ -178,7 +178,7 @@ int MIDIbuf_open(int dev, struct file *file) + return err; + + parms[dev].prech_timeout = MAX_SCHEDULE_TIMEOUT; +- midi_in_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf)); ++ midi_in_buf[dev] = vmalloc(sizeof(struct midi_buf)); + + if (midi_in_buf[dev] == NULL) + { +@@ -188,7 +188,7 @@ int MIDIbuf_open(int dev, struct file *file) + } + midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0; + +- midi_out_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf)); ++ midi_out_buf[dev] = vmalloc(sizeof(struct midi_buf)); + + if (midi_out_buf[dev] == NULL) + { +diff --git a/sound/oss/pss.c b/sound/oss/pss.c +index e19dd5d..9b800ce 100644 +--- a/sound/oss/pss.c ++++ b/sound/oss/pss.c +@@ -859,7 +859,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, + return 0; + + case SNDCTL_COPR_LOAD: +- buf = (copr_buffer *) vmalloc(sizeof(copr_buffer)); ++ buf = vmalloc(sizeof(copr_buffer)); + if (buf == NULL) + return -ENOSPC; + if (copy_from_user(buf, arg, sizeof(copr_buffer))) { +@@ -871,7 +871,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, + return err; + + case SNDCTL_COPR_SENDMSG: +- mbuf = (copr_msg *)vmalloc(sizeof(copr_msg)); ++ mbuf = vmalloc(sizeof(copr_msg)); + if (mbuf == NULL) + return -ENOSPC; + if (copy_from_user(mbuf, arg, sizeof(copr_msg))) { +@@ -895,7 +895,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, + + case SNDCTL_COPR_RCVMSG: + err = 0; +- mbuf = (copr_msg *)vmalloc(sizeof(copr_msg)); ++ mbuf = vmalloc(sizeof(copr_msg)); + if (mbuf == NULL) + return -ENOSPC; + data = (unsigned short *)mbuf->data; +diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c +index e85789e..5ea1098 100644 +--- a/sound/oss/sequencer.c ++++ b/sound/oss/sequencer.c +@@ -1646,13 +1646,13 @@ void sequencer_init(void) + { + if (sequencer_ok) + return; +- queue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * EV_SZ); ++ queue = vmalloc(SEQ_MAX_QUEUE * EV_SZ); + if (queue == NULL) + { + printk(KERN_ERR "sequencer: Can't allocate memory for sequencer output queue\n"); + return; + } +- iqueue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * IEV_SZ); ++ iqueue = vmalloc(SEQ_MAX_QUEUE * IEV_SZ); + if (iqueue == NULL) + { + printk(KERN_ERR "sequencer: Can't allocate memory for sequencer input queue\n"); +diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c +index 62895a7..22dbd91 100644 +--- a/sound/pci/asihpi/hpioctl.c ++++ b/sound/pci/asihpi/hpioctl.c +@@ -435,7 +435,7 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev) + struct hpi_message hm; + struct hpi_response hr; + struct hpi_adapter *pa; +- pa = (struct hpi_adapter *)pci_get_drvdata(pci_dev); ++ pa = pci_get_drvdata(pci_dev); + + hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, + HPI_SUBSYS_DELETE_ADAPTER); +diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c +index 4679ed8..2f3cacb 100644 +--- a/sound/pci/azt3328.c ++++ b/sound/pci/azt3328.c +@@ -1129,10 +1129,11 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, + + count_areas = size/2; + addr_area2 = addr+count_areas; +- count_areas--; /* max. index */ + snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n", + addr, count_areas, addr_area2, count_areas); + ++ count_areas--; /* max. index */ ++ + /* build combined I/O buffer length word */ + lengths = (count_areas << 16) | (count_areas); + spin_lock_irqsave(&chip->reg_lock, flags); +@@ -1740,11 +1741,15 @@ static const struct snd_pcm_hardware snd_azf3328_hardware = + .rate_max = AZF_FREQ_66200, + .channels_min = 1, + .channels_max = 2, +- .buffer_bytes_max = 65536, +- .period_bytes_min = 64, +- .period_bytes_max = 65536, +- .periods_min = 1, +- .periods_max = 1024, ++ .buffer_bytes_max = (64*1024), ++ .period_bytes_min = 1024, ++ .period_bytes_max = (32*1024), ++ /* We simply have two DMA areas (instead of a list of descriptors ++ such as other cards); I believe that this is a fixed hardware ++ attribute and there isn't much driver magic to be done to expand it. ++ Thus indicate that we have at least and at most 2 periods. */ ++ .periods_min = 2, ++ .periods_max = 2, + /* FIXME: maybe that card actually has a FIFO? + * Hmm, it seems newer revisions do have one, but we still don't know + * its size... */ +@@ -1980,8 +1985,13 @@ snd_azf3328_timer_stop(struct snd_timer *timer) + chip = snd_timer_chip(timer); + spin_lock_irqsave(&chip->reg_lock, flags); + /* disable timer countdown and interrupt */ +- /* FIXME: should we write TIMER_IRQ_ACK here? */ +- snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); ++ /* Hmm, should we write TIMER_IRQ_ACK here? ++ YES indeed, otherwise a rogue timer operation - which prompts ++ ALSA(?) to call repeated stop() in vain, but NOT start() - ++ will never end (value 0x03 is kept shown in control byte). ++ Simply manually poking 0x04 _once_ immediately successfully stops ++ the hardware/ALSA interrupt activity. */ ++ snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04); + spin_unlock_irqrestore(&chip->reg_lock, flags); + snd_azf3328_dbgcallleave(); + return 0; +diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c +index 85ab43e..457d211 100644 +--- a/sound/pci/ctxfi/ctpcm.c ++++ b/sound/pci/ctxfi/ctpcm.c +@@ -129,8 +129,6 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) + + apcm->substream = substream; + apcm->interrupt = ct_atc_pcm_interrupt; +- runtime->private_data = apcm; +- runtime->private_free = ct_atc_pcm_free_substream; + if (IEC958 == substream->pcm->device) { + runtime->hw = ct_spdif_passthru_playback_hw; + atc->spdif_out_passthru(atc, 1); +@@ -155,8 +153,12 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) + } + + apcm->timer = ct_timer_instance_new(atc->timer, apcm); +- if (!apcm->timer) ++ if (!apcm->timer) { ++ kfree(apcm); + return -ENOMEM; ++ } ++ runtime->private_data = apcm; ++ runtime->private_free = ct_atc_pcm_free_substream; + + return 0; + } +@@ -278,8 +280,6 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) + apcm->started = 0; + apcm->substream = substream; + apcm->interrupt = ct_atc_pcm_interrupt; +- runtime->private_data = apcm; +- runtime->private_free = ct_atc_pcm_free_substream; + runtime->hw = ct_pcm_capture_hw; + runtime->hw.rate_max = atc->rsr * atc->msr; + +@@ -298,8 +298,12 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) + } + + apcm->timer = ct_timer_instance_new(atc->timer, apcm); +- if (!apcm->timer) ++ if (!apcm->timer) { ++ kfree(apcm); + return -ENOMEM; ++ } ++ runtime->private_data = apcm; ++ runtime->private_free = ct_atc_pcm_free_substream; + + return 0; + } +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index 6361f75..846d1ea 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -3100,6 +3100,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), + SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), ++ SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_HP_LAPTOP), + SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), + SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), +@@ -3110,6 +3111,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), ++ SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), + SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD), +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 5f00589..0ac6aed 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -14623,7 +14623,10 @@ static int alc275_setup_dual_adc(struct hda_codec *codec) + /* different alc269-variants */ + enum { + ALC269_TYPE_NORMAL, ++ ALC269_TYPE_ALC258, + ALC269_TYPE_ALC259, ++ ALC269_TYPE_ALC269VB, ++ ALC269_TYPE_ALC270, + ALC269_TYPE_ALC271X, + }; + +@@ -15023,7 +15026,7 @@ static int alc269_fill_coef(struct hda_codec *codec) + static int patch_alc269(struct hda_codec *codec) + { + struct alc_spec *spec; +- int board_config; ++ int board_config, coef; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); +@@ -15034,14 +15037,23 @@ static int patch_alc269(struct hda_codec *codec) + + alc_auto_parse_customize_define(codec); + +- if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ ++ coef = alc_read_coef_idx(codec, 0); ++ if ((coef & 0x00f0) == 0x0010) { + if (codec->bus->pci->subsystem_vendor == 0x1025 && + spec->cdefine.platform_type == 1) { + alc_codec_rename(codec, "ALC271X"); + spec->codec_variant = ALC269_TYPE_ALC271X; +- } else { ++ } else if ((coef & 0xf000) == 0x1000) { ++ spec->codec_variant = ALC269_TYPE_ALC270; ++ } else if ((coef & 0xf000) == 0x2000) { + alc_codec_rename(codec, "ALC259"); + spec->codec_variant = ALC269_TYPE_ALC259; ++ } else if ((coef & 0xf000) == 0x3000) { ++ alc_codec_rename(codec, "ALC258"); ++ spec->codec_variant = ALC269_TYPE_ALC258; ++ } else { ++ alc_codec_rename(codec, "ALC269VB"); ++ spec->codec_variant = ALC269_TYPE_ALC269VB; + } + } else + alc_fix_pll_init(codec, 0x20, 0x04, 15); +@@ -15104,7 +15116,7 @@ static int patch_alc269(struct hda_codec *codec) + spec->stream_digital_capture = &alc269_pcm_digital_capture; + + if (!spec->adc_nids) { /* wasn't filled automatically? use default */ +- if (spec->codec_variant != ALC269_TYPE_NORMAL) { ++ if (spec->codec_variant == ALC269_TYPE_NORMAL) { + spec->adc_nids = alc269_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); + spec->capsrc_nids = alc269_capsrc_nids; +@@ -19298,6 +19310,7 @@ static const struct alc_fixup alc662_fixups[] = { + + static struct snd_pci_quirk alc662_fixup_tbl[] = { + SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), ++ SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), + SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), + SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), + {} +@@ -19419,7 +19432,10 @@ static int patch_alc888(struct hda_codec *codec) + { + if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ + kfree(codec->chip_name); +- codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); ++ if (codec->vendor_id == 0x10ec0887) ++ codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL); ++ else ++ codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); + if (!codec->chip_name) { + alc_free(codec); + return -ENOMEM; +@@ -19909,7 +19925,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { + { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", + .patch = patch_alc882 }, + { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, +- { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, ++ { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 }, + { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", + .patch = patch_alc882 }, + { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, +diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c +index 93fa59c..5c71080 100644 +--- a/sound/pci/hda/patch_sigmatel.c ++++ b/sound/pci/hda/patch_sigmatel.c +@@ -389,6 +389,11 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { + 0x11, 0x20, 0 + }; + ++#define STAC92HD87B_NUM_DMICS 1 ++static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = { ++ 0x11, 0 ++}; ++ + #define STAC92HD83XXX_NUM_CAPS 2 + static unsigned long stac92hd83xxx_capvols[] = { + HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), +@@ -3486,10 +3491,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, + return err; + } + +- if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) { ++ if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) + snd_hda_add_imux_item(imux, label, index, NULL); +- spec->num_analog_muxes++; +- } + } + + return 0; +@@ -5452,12 +5455,17 @@ again: + stac92hd83xxx_brd_tbl[spec->board_config]); + + switch (codec->vendor_id) { ++ case 0x111d76d1: ++ case 0x111d76d9: ++ spec->dmic_nids = stac92hd87b_dmic_nids; ++ spec->num_dmics = stac92xx_connected_ports(codec, ++ stac92hd87b_dmic_nids, ++ STAC92HD87B_NUM_DMICS); ++ /* Fall through */ + case 0x111d7666: + case 0x111d7667: + case 0x111d7668: + case 0x111d7669: +- case 0x111d76d1: +- case 0x111d76d9: + spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); + spec->pin_nids = stac92hd88xxx_pin_nids; + spec->mono_nid = 0; +diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c +index 400f9eb..629a549 100644 +--- a/sound/pci/intel8x0.c ++++ b/sound/pci/intel8x0.c +@@ -1866,6 +1866,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { + }, + { + .subvendor = 0x1028, ++ .subdevice = 0x0182, ++ .name = "Dell Latitude D610", /* STAC9750/51 */ ++ .type = AC97_TUNE_HP_ONLY ++ }, ++ { ++ .subvendor = 0x1028, + .subdevice = 0x0186, + .name = "Dell Latitude D810", /* cf. Malone #41015 */ + .type = AC97_TUNE_HP_MUTE_LED +diff --git a/sound/pci/mixart/mixart_hwdep.h b/sound/pci/mixart/mixart_hwdep.h +index a46f508..812e288 100644 +--- a/sound/pci/mixart/mixart_hwdep.h ++++ b/sound/pci/mixart/mixart_hwdep.h +@@ -25,11 +25,21 @@ + + #include <sound/hwdep.h> + ++#ifndef readl_be + #define readl_be(x) be32_to_cpu(__raw_readl(x)) ++#endif ++ ++#ifndef writel_be + #define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr) ++#endif + ++#ifndef readl_le + #define readl_le(x) le32_to_cpu(__raw_readl(x)) ++#endif ++ ++#ifndef writel_le + #define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr) ++#endif + + #define MIXART_MEM(mgr,x) ((mgr)->mem[0].virt + (x)) + #define MIXART_REG(mgr,x) ((mgr)->mem[1].virt + (x)) +diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c +index 8508117..b47cfd4 100644 +--- a/sound/ppc/pmac.c ++++ b/sound/ppc/pmac.c +@@ -1228,10 +1228,8 @@ int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) + chip->rsrc[i].start + 1, + rnames[i]) == NULL) { + printk(KERN_ERR "snd: can't request rsrc " +- " %d (%s: 0x%016llx:%016llx)\n", +- i, rnames[i], +- (unsigned long long)chip->rsrc[i].start, +- (unsigned long long)chip->rsrc[i].end); ++ " %d (%s: %pR)\n", ++ i, rnames[i], &chip->rsrc[i]); + err = -ENODEV; + goto __error; + } +@@ -1256,10 +1254,8 @@ int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) + chip->rsrc[i].start + 1, + rnames[i]) == NULL) { + printk(KERN_ERR "snd: can't request rsrc " +- " %d (%s: 0x%016llx:%016llx)\n", +- i, rnames[i], +- (unsigned long long)chip->rsrc[i].start, +- (unsigned long long)chip->rsrc[i].end); ++ " %d (%s: %pR)\n", ++ i, rnames[i], &chip->rsrc[i]); + err = -ENODEV; + goto __error; + } +diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig +index e720d5e..bee3c94 100644 +--- a/sound/soc/atmel/Kconfig ++++ b/sound/soc/atmel/Kconfig +@@ -16,7 +16,8 @@ config SND_ATMEL_SOC_SSC + + config SND_AT91_SOC_SAM9G20_WM8731 + tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" +- depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC ++ depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \ ++ AT91_PROGRAMMABLE_CLOCKS + select SND_ATMEL_SOC_SSC + select SND_SOC_WM8731 + help +@@ -25,7 +26,7 @@ config SND_AT91_SOC_SAM9G20_WM8731 + + config SND_AT32_SOC_PLAYPAQ + tristate "SoC Audio support for PlayPaq with WM8510" +- depends on SND_ATMEL_SOC && BOARD_PLAYPAQ ++ depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS + select SND_ATMEL_SOC_SSC + select SND_SOC_WM8510 + help +diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c +index bc22ee9..470cb93 100644 +--- a/sound/soc/codecs/max98088.c ++++ b/sound/soc/codecs/max98088.c +@@ -28,6 +28,11 @@ + #include <sound/max98088.h> + #include "max98088.h" + ++enum max98088_type { ++ MAX98088, ++ MAX98089, ++}; ++ + struct max98088_cdata { + unsigned int rate; + unsigned int fmt; +@@ -36,6 +41,7 @@ struct max98088_cdata { + + struct max98088_priv { + u8 reg_cache[M98088_REG_CNT]; ++ enum max98088_type devtype; + void *control_data; + struct max98088_pdata *pdata; + unsigned int sysclk; +@@ -2040,6 +2046,8 @@ static int max98088_i2c_probe(struct i2c_client *i2c, + if (max98088 == NULL) + return -ENOMEM; + ++ max98088->devtype = id->driver_data; ++ + i2c_set_clientdata(i2c, max98088); + max98088->control_data = i2c; + max98088->pdata = i2c->dev.platform_data; +@@ -2059,7 +2067,8 @@ static int __devexit max98088_i2c_remove(struct i2c_client *client) + } + + static const struct i2c_device_id max98088_i2c_id[] = { +- { "max98088", 0 }, ++ { "max98088", MAX98088 }, ++ { "max98089", MAX98089 }, + { } + }; + MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); +diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c +index 7540a50..464f0cf 100644 +--- a/sound/soc/codecs/uda134x.c ++++ b/sound/soc/codecs/uda134x.c +@@ -597,6 +597,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = { + .resume = uda134x_soc_resume, + .reg_cache_size = sizeof(uda134x_reg), + .reg_word_size = sizeof(u8), ++ .reg_cache_default = uda134x_reg, + .reg_cache_step = 1, + .read = uda134x_read_reg_cache, + .write = uda134x_write, +diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c +index f4f1fba..7611add 100644 +--- a/sound/soc/codecs/wm8350.c ++++ b/sound/soc/codecs/wm8350.c +@@ -831,7 +831,7 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai, + } + + /* MCLK direction */ +- if (dir == WM8350_MCLK_DIR_OUT) ++ if (dir == SND_SOC_CLOCK_OUT) + wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2, + WM8350_MCLK_DIR); + else +@@ -1586,6 +1586,13 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) + wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, + WM8350_OUT2_VU | WM8350_OUT2R_MUTE); + ++ /* Make sure AIF tristating is disabled by default */ ++ wm8350_clear_bits(wm8350, WM8350_AI_FORMATING, WM8350_AIF_TRI); ++ ++ /* Make sure we've got a sane companding setup too */ ++ wm8350_clear_bits(wm8350, WM8350_ADC_DAC_COMP, ++ WM8350_DAC_COMP | WM8350_LOOPBACK); ++ + /* Make sure jack detect is disabled to start off with */ + wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, + WM8350_JDL_ENA | WM8350_JDR_ENA); +diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c +index 04182c4..0132a27 100644 +--- a/sound/soc/codecs/wm8776.c ++++ b/sound/soc/codecs/wm8776.c +@@ -34,7 +34,6 @@ + /* codec private data */ + struct wm8776_priv { + enum snd_soc_control_type control_type; +- u16 reg_cache[WM8776_CACHEREGNUM]; + int sysclk[2]; + }; + +diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c +index 894d0cd..e809274 100644 +--- a/sound/soc/codecs/wm8962.c ++++ b/sound/soc/codecs/wm8962.c +@@ -3500,8 +3500,11 @@ static ssize_t wm8962_beep_set(struct device *dev, + { + struct wm8962_priv *wm8962 = dev_get_drvdata(dev); + long int time; ++ int ret; + +- strict_strtol(buf, 10, &time); ++ ret = strict_strtol(buf, 10, &time); ++ if (ret != 0) ++ return ret; + + input_event(wm8962->beep, EV_SND, SND_TONE, time); + +diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c +index 0db59c3..830dfdd 100644 +--- a/sound/soc/codecs/wm8994.c ++++ b/sound/soc/codecs/wm8994.c +@@ -3903,6 +3903,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) + return -ENOMEM; + snd_soc_codec_set_drvdata(codec, wm8994); + ++ codec->reg_cache = &wm8994->reg_cache; ++ + wm8994->pdata = dev_get_platdata(codec->dev->parent); + wm8994->codec = codec; + +diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c +index 2b07b17..bc9e6b0 100644 +--- a/sound/soc/davinci/davinci-evm.c ++++ b/sound/soc/davinci/davinci-evm.c +@@ -157,12 +157,23 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) + } + + /* davinci-evm digital audio interface glue - connects codec <--> CPU */ +-static struct snd_soc_dai_link evm_dai = { ++static struct snd_soc_dai_link dm6446_evm_dai = { + .name = "TLV320AIC3X", + .stream_name = "AIC3X", +- .cpu_dai_name = "davinci-mcasp.0", ++ .cpu_dai_name = "davinci-mcbsp", + .codec_dai_name = "tlv320aic3x-hifi", +- .codec_name = "tlv320aic3x-codec.0-001a", ++ .codec_name = "tlv320aic3x-codec.1-001b", ++ .platform_name = "davinci-pcm-audio", ++ .init = evm_aic3x_init, ++ .ops = &evm_ops, ++}; ++ ++static struct snd_soc_dai_link dm355_evm_dai = { ++ .name = "TLV320AIC3X", ++ .stream_name = "AIC3X", ++ .cpu_dai_name = "davinci-mcbsp.1", ++ .codec_dai_name = "tlv320aic3x-hifi", ++ .codec_name = "tlv320aic3x-codec.1-001b", + .platform_name = "davinci-pcm-audio", + .init = evm_aic3x_init, + .ops = &evm_ops, +@@ -172,10 +183,10 @@ static struct snd_soc_dai_link dm365_evm_dai = { + #ifdef CONFIG_SND_DM365_AIC3X_CODEC + .name = "TLV320AIC3X", + .stream_name = "AIC3X", +- .cpu_dai_name = "davinci-i2s", ++ .cpu_dai_name = "davinci-mcbsp", + .codec_dai_name = "tlv320aic3x-hifi", + .init = evm_aic3x_init, +- .codec_name = "tlv320aic3x-codec.0-001a", ++ .codec_name = "tlv320aic3x-codec.1-0018", + .ops = &evm_ops, + #elif defined(CONFIG_SND_DM365_VOICE_CODEC) + .name = "Voice Codec - CQ93VC", +@@ -219,10 +230,17 @@ static struct snd_soc_dai_link da8xx_evm_dai = { + .ops = &evm_ops, + }; + +-/* davinci dm6446, dm355 evm audio machine driver */ +-static struct snd_soc_card snd_soc_card_evm = { +- .name = "DaVinci EVM", +- .dai_link = &evm_dai, ++/* davinci dm6446 evm audio machine driver */ ++static struct snd_soc_card dm6446_snd_soc_card_evm = { ++ .name = "DaVinci DM6446 EVM", ++ .dai_link = &dm6446_evm_dai, ++ .num_links = 1, ++}; ++ ++/* davinci dm355 evm audio machine driver */ ++static struct snd_soc_card dm355_snd_soc_card_evm = { ++ .name = "DaVinci DM355 EVM", ++ .dai_link = &dm355_evm_dai, + .num_links = 1, + }; + +@@ -261,10 +279,10 @@ static int __init evm_init(void) + int ret; + + if (machine_is_davinci_evm()) { +- evm_snd_dev_data = &snd_soc_card_evm; ++ evm_snd_dev_data = &dm6446_snd_soc_card_evm; + index = 0; + } else if (machine_is_davinci_dm355_evm()) { +- evm_snd_dev_data = &snd_soc_card_evm; ++ evm_snd_dev_data = &dm355_snd_soc_card_evm; + index = 1; + } else if (machine_is_davinci_dm365_evm()) { + evm_snd_dev_data = &dm365_snd_soc_card_evm; +diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c +index d46b545..9e0e565 100644 +--- a/sound/soc/davinci/davinci-i2s.c ++++ b/sound/soc/davinci/davinci-i2s.c +@@ -426,9 +426,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, + snd_pcm_format_t fmt; + unsigned element_cnt = 1; + +- dai->capture_dma_data = dev->dma_params; +- dai->playback_dma_data = dev->dma_params; +- + /* general line settings */ + spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { +@@ -601,6 +598,15 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd, + return ret; + } + ++static int davinci_i2s_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ snd_soc_dai_set_dma_data(dai, substream, dev->dma_params); ++ return 0; ++} ++ + static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) + { +@@ -612,6 +618,7 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, + #define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 + + static struct snd_soc_dai_ops davinci_i2s_dai_ops = { ++ .startup = davinci_i2s_startup, + .shutdown = davinci_i2s_shutdown, + .prepare = davinci_i2s_prepare, + .trigger = davinci_i2s_trigger, +@@ -749,7 +756,7 @@ static struct platform_driver davinci_mcbsp_driver = { + .probe = davinci_i2s_probe, + .remove = davinci_i2s_remove, + .driver = { +- .name = "davinci-i2s", ++ .name = "davinci-mcbsp", + .owner = THIS_MODULE, + }, + }; +diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c +index 86918ee..fb55d2c 100644 +--- a/sound/soc/davinci/davinci-mcasp.c ++++ b/sound/soc/davinci/davinci-mcasp.c +@@ -715,9 +715,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, + int word_length; + u8 fifo_level; + +- cpu_dai->capture_dma_data = dev->dma_params; +- cpu_dai->playback_dma_data = dev->dma_params; +- + davinci_hw_common_param(dev, substream->stream); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + fifo_level = dev->txnumevt; +@@ -799,7 +796,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, + return ret; + } + ++static int davinci_mcasp_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ snd_soc_dai_set_dma_data(dai, substream, dev->dma_params); ++ return 0; ++} ++ + static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { ++ .startup = davinci_mcasp_startup, + .trigger = davinci_mcasp_trigger, + .hw_params = davinci_mcasp_hw_params, + .set_fmt = davinci_mcasp_set_dai_fmt, +diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c +index 009b652..6c6666a 100644 +--- a/sound/soc/davinci/davinci-sffsdr.c ++++ b/sound/soc/davinci/davinci-sffsdr.c +@@ -84,7 +84,7 @@ static struct snd_soc_ops sffsdr_ops = { + static struct snd_soc_dai_link sffsdr_dai = { + .name = "PCM3008", /* Codec name */ + .stream_name = "PCM3008 HiFi", +- .cpu_dai_name = "davinci-asp.0", ++ .cpu_dai_name = "davinci-mcbsp", + .codec_dai_name = "pcm3008-hifi", + .codec_name = "pcm3008-codec", + .platform_name = "davinci-pcm-audio", +diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c +index ea232f6..fb4cc1e 100644 +--- a/sound/soc/davinci/davinci-vcif.c ++++ b/sound/soc/davinci/davinci-vcif.c +@@ -97,9 +97,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream, + &davinci_vcif_dev->dma_params[substream->stream]; + u32 w; + +- dai->capture_dma_data = davinci_vcif_dev->dma_params; +- dai->playback_dma_data = davinci_vcif_dev->dma_params; +- + /* Restart the codec before setup */ + davinci_vcif_stop(substream); + davinci_vcif_start(substream); +@@ -174,9 +171,19 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd, + return ret; + } + ++static int davinci_vcif_startup(struct snd_pcm_substream *substream, ++ struct snd_soc_dai *dai) ++{ ++ struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai); ++ ++ snd_soc_dai_set_dma_data(dai, substream, dev->dma_params); ++ return 0; ++} ++ + #define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000 + + static struct snd_soc_dai_ops davinci_vcif_dai_ops = { ++ .startup = davinci_vcif_startup, + .trigger = davinci_vcif_trigger, + .hw_params = davinci_vcif_hw_params, + }; +diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c +index 74ffed4..9018fa5 100644 +--- a/sound/soc/fsl/mpc5200_psc_i2s.c ++++ b/sound/soc/fsl/mpc5200_psc_i2s.c +@@ -160,7 +160,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op, + rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); + if (rc != 0) { + pr_err("Failed to register DAI\n"); +- return 0; ++ return rc; + } + + psc_dma = dev_get_drvdata(&op->dev); +diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c +index b596752..dd4fffd 100644 +--- a/sound/soc/imx/eukrea-tlv320.c ++++ b/sound/soc/imx/eukrea-tlv320.c +@@ -34,8 +34,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) + { + struct snd_soc_pcm_runtime *rtd = substream->private_data; +- struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; +- struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; ++ struct snd_soc_dai *codec_dai = rtd->codec_dai; ++ struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret; + + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | +@@ -79,10 +79,10 @@ static struct snd_soc_ops eukrea_tlv320_snd_ops = { + static struct snd_soc_dai_link eukrea_tlv320_dai = { + .name = "tlv320aic23", + .stream_name = "TLV320AIC23", +- .codec_dai = "tlv320aic23-hifi", ++ .codec_dai_name = "tlv320aic23-hifi", + .platform_name = "imx-pcm-audio.0", + .codec_name = "tlv320aic23-codec.0-001a", +- .cpu_dai = "imx-ssi.0", ++ .cpu_dai_name = "imx-ssi.0", + .ops = &eukrea_tlv320_snd_ops, + }; + +diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c +index fd493ee..671ef8d 100644 +--- a/sound/soc/imx/imx-pcm-dma-mx2.c ++++ b/sound/soc/imx/imx-pcm-dma-mx2.c +@@ -20,6 +20,7 @@ + #include <linux/module.h> + #include <linux/platform_device.h> + #include <linux/slab.h> ++#include <linux/dmaengine.h> + + #include <sound/core.h> + #include <sound/initval.h> +@@ -27,165 +28,146 @@ + #include <sound/pcm_params.h> + #include <sound/soc.h> + +-#include <mach/dma-mx1-mx2.h> ++#include <mach/dma.h> + + #include "imx-ssi.h" + + struct imx_pcm_runtime_data { +- int sg_count; +- struct scatterlist *sg_list; +- int period; ++ int period_bytes; + int periods; +- unsigned long dma_addr; + int dma; +- struct snd_pcm_substream *substream; + unsigned long offset; + unsigned long size; +- unsigned long period_cnt; + void *buf; + int period_time; ++ struct dma_async_tx_descriptor *desc; ++ struct dma_chan *dma_chan; ++ struct imx_dma_data dma_data; + }; + +-/* Called by the DMA framework when a period has elapsed */ +-static void imx_ssi_dma_progression(int channel, void *data, +- struct scatterlist *sg) ++static void audio_dma_irq(void *data) + { +- struct snd_pcm_substream *substream = data; ++ struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct imx_pcm_runtime_data *iprtd = runtime->private_data; + +- if (!sg) +- return; +- +- runtime = iprtd->substream->runtime; ++ iprtd->offset += iprtd->period_bytes; ++ iprtd->offset %= iprtd->period_bytes * iprtd->periods; + +- iprtd->offset = sg->dma_address - runtime->dma_addr; +- +- snd_pcm_period_elapsed(iprtd->substream); ++ snd_pcm_period_elapsed(substream); + } + +-static void imx_ssi_dma_callback(int channel, void *data) ++static bool filter(struct dma_chan *chan, void *param) + { +- pr_err("%s shouldn't be called\n", __func__); +-} ++ struct imx_pcm_runtime_data *iprtd = param; + +-static void snd_imx_dma_err_callback(int channel, void *data, int err) +-{ +- struct snd_pcm_substream *substream = data; +- struct snd_soc_pcm_runtime *rtd = substream->private_data; +- struct imx_pcm_dma_params *dma_params = +- snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); +- struct snd_pcm_runtime *runtime = substream->runtime; +- struct imx_pcm_runtime_data *iprtd = runtime->private_data; +- int ret; ++ if (!imx_dma_is_general_purpose(chan)) ++ return false; + +- pr_err("DMA timeout on channel %d -%s%s%s%s\n", +- channel, +- err & IMX_DMA_ERR_BURST ? " burst" : "", +- err & IMX_DMA_ERR_REQUEST ? " request" : "", +- err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", +- err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); ++ chan->private = &iprtd->dma_data; + +- imx_dma_disable(iprtd->dma); +- ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, +- IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, +- substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? +- DMA_MODE_WRITE : DMA_MODE_READ); +- if (!ret) +- imx_dma_enable(iprtd->dma); ++ return true; + } + +-static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) ++static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, ++ struct snd_pcm_hw_params *params) + { + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct imx_pcm_dma_params *dma_params; + struct snd_pcm_runtime *runtime = substream->runtime; + struct imx_pcm_runtime_data *iprtd = runtime->private_data; ++ struct dma_slave_config slave_config; ++ dma_cap_mask_t mask; ++ enum dma_slave_buswidth buswidth; + int ret; + + dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + +- iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); +- if (iprtd->dma < 0) { +- pr_err("Failed to claim the audio DMA\n"); +- return -ENODEV; +- } ++ iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI; ++ iprtd->dma_data.priority = DMA_PRIO_HIGH; ++ iprtd->dma_data.dma_request = dma_params->dma; + +- ret = imx_dma_setup_handlers(iprtd->dma, +- imx_ssi_dma_callback, +- snd_imx_dma_err_callback, substream); +- if (ret) +- goto out; ++ /* Try to grab a DMA channel */ ++ dma_cap_zero(mask); ++ dma_cap_set(DMA_SLAVE, mask); ++ iprtd->dma_chan = dma_request_channel(mask, filter, iprtd); ++ if (!iprtd->dma_chan) ++ return -EINVAL; + +- ret = imx_dma_setup_progression_handler(iprtd->dma, +- imx_ssi_dma_progression); +- if (ret) { +- pr_err("Failed to setup the DMA handler\n"); +- goto out; ++ switch (params_format(params)) { ++ case SNDRV_PCM_FORMAT_S16_LE: ++ buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; ++ break; ++ case SNDRV_PCM_FORMAT_S20_3LE: ++ case SNDRV_PCM_FORMAT_S24_LE: ++ buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; ++ break; ++ default: ++ return 0; + } + +- ret = imx_dma_config_channel(iprtd->dma, +- IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO, +- IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, +- dma_params->dma, 1); +- if (ret < 0) { +- pr_err("Cannot configure DMA channel: %d\n", ret); +- goto out; ++ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { ++ slave_config.direction = DMA_TO_DEVICE; ++ slave_config.dst_addr = dma_params->dma_addr; ++ slave_config.dst_addr_width = buswidth; ++ slave_config.dst_maxburst = dma_params->burstsize; ++ } else { ++ slave_config.direction = DMA_FROM_DEVICE; ++ slave_config.src_addr = dma_params->dma_addr; ++ slave_config.src_addr_width = buswidth; ++ slave_config.src_maxburst = dma_params->burstsize; + } + +- imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2); ++ ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config); ++ if (ret) ++ return ret; + + return 0; +-out: +- imx_dma_free(iprtd->dma); +- return ret; + } + + static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) + { ++ struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + struct imx_pcm_runtime_data *iprtd = runtime->private_data; +- int i; + unsigned long dma_addr; ++ struct dma_chan *chan; ++ struct imx_pcm_dma_params *dma_params; ++ int ret; + +- imx_ssi_dma_alloc(substream); ++ dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); ++ ret = imx_ssi_dma_alloc(substream, params); ++ if (ret) ++ return ret; ++ chan = iprtd->dma_chan; + + iprtd->size = params_buffer_bytes(params); + iprtd->periods = params_periods(params); +- iprtd->period = params_period_bytes(params); ++ iprtd->period_bytes = params_period_bytes(params); + iprtd->offset = 0; + iprtd->period_time = HZ / (params_rate(params) / + params_period_size(params)); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + +- if (iprtd->sg_count != iprtd->periods) { +- kfree(iprtd->sg_list); +- +- iprtd->sg_list = kcalloc(iprtd->periods + 1, +- sizeof(struct scatterlist), GFP_KERNEL); +- if (!iprtd->sg_list) +- return -ENOMEM; +- iprtd->sg_count = iprtd->periods + 1; +- } +- +- sg_init_table(iprtd->sg_list, iprtd->sg_count); + dma_addr = runtime->dma_addr; + +- for (i = 0; i < iprtd->periods; i++) { +- iprtd->sg_list[i].page_link = 0; +- iprtd->sg_list[i].offset = 0; +- iprtd->sg_list[i].dma_address = dma_addr; +- iprtd->sg_list[i].length = iprtd->period; +- dma_addr += iprtd->period; ++ iprtd->buf = (unsigned int *)substream->dma_buffer.area; ++ ++ iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr, ++ iprtd->period_bytes * iprtd->periods, ++ iprtd->period_bytes, ++ substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? ++ DMA_TO_DEVICE : DMA_FROM_DEVICE); ++ if (!iprtd->desc) { ++ dev_err(&chan->dev->device, "cannot prepare slave dma\n"); ++ return -EINVAL; + } + +- /* close the loop */ +- iprtd->sg_list[iprtd->sg_count - 1].offset = 0; +- iprtd->sg_list[iprtd->sg_count - 1].length = 0; +- iprtd->sg_list[iprtd->sg_count - 1].page_link = +- ((unsigned long) iprtd->sg_list | 0x01) & ~0x02; ++ iprtd->desc->callback = audio_dma_irq; ++ iprtd->desc->callback_param = substream; ++ + return 0; + } + +@@ -194,41 +176,21 @@ static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream) + struct snd_pcm_runtime *runtime = substream->runtime; + struct imx_pcm_runtime_data *iprtd = runtime->private_data; + +- if (iprtd->dma >= 0) { +- imx_dma_free(iprtd->dma); +- iprtd->dma = -EINVAL; ++ if (iprtd->dma_chan) { ++ dma_release_channel(iprtd->dma_chan); ++ iprtd->dma_chan = NULL; + } + +- kfree(iprtd->sg_list); +- iprtd->sg_list = NULL; +- + return 0; + } + + static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) + { +- struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct imx_pcm_dma_params *dma_params; +- struct imx_pcm_runtime_data *iprtd = runtime->private_data; +- int err; + + dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + +- iprtd->substream = substream; +- iprtd->buf = (unsigned int *)substream->dma_buffer.area; +- iprtd->period_cnt = 0; +- +- pr_debug("%s: buf: %p period: %d periods: %d\n", +- __func__, iprtd->buf, iprtd->period, iprtd->periods); +- +- err = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, +- IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, +- substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? +- DMA_MODE_WRITE : DMA_MODE_READ); +- if (err) +- return err; +- + return 0; + } + +@@ -241,14 +203,14 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: +- imx_dma_enable(iprtd->dma); ++ dmaengine_submit(iprtd->desc); + + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: +- imx_dma_disable(iprtd->dma); ++ dmaengine_terminate_all(iprtd->dma_chan); + + break; + default: +@@ -263,6 +225,9 @@ static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream + struct snd_pcm_runtime *runtime = substream->runtime; + struct imx_pcm_runtime_data *iprtd = runtime->private_data; + ++ pr_debug("%s: %ld %ld\n", __func__, iprtd->offset, ++ bytes_to_frames(substream->runtime, iprtd->offset)); ++ + return bytes_to_frames(substream->runtime, iprtd->offset); + } + +@@ -279,7 +244,7 @@ static struct snd_pcm_hardware snd_imx_hardware = { + .channels_max = 2, + .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, + .period_bytes_min = 128, +- .period_bytes_max = 16 * 1024, ++ .period_bytes_max = 65535, /* Limited by SDMA engine */ + .periods_min = 2, + .periods_max = 255, + .fifo_size = 0, +@@ -304,11 +269,23 @@ static int snd_imx_open(struct snd_pcm_substream *substream) + } + + snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); ++ ++ return 0; ++} ++ ++static int snd_imx_close(struct snd_pcm_substream *substream) ++{ ++ struct snd_pcm_runtime *runtime = substream->runtime; ++ struct imx_pcm_runtime_data *iprtd = runtime->private_data; ++ ++ kfree(iprtd); ++ + return 0; + } + + static struct snd_pcm_ops imx_pcm_ops = { + .open = snd_imx_open, ++ .close = snd_imx_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_imx_pcm_hw_params, + .hw_free = snd_imx_pcm_hw_free, +@@ -340,7 +317,6 @@ static struct platform_driver imx_pcm_driver = { + .name = "imx-pcm-audio", + .owner = THIS_MODULE, + }, +- + .probe = imx_soc_platform_probe, + .remove = __devexit_p(imx_soc_platform_remove), + }; +@@ -356,4 +332,3 @@ static void __exit snd_imx_pcm_exit(void) + platform_driver_unregister(&imx_pcm_driver); + } + module_exit(snd_imx_pcm_exit); +- +diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c +index d4bd345..d2d98c7 100644 +--- a/sound/soc/imx/imx-ssi.c ++++ b/sound/soc/imx/imx-ssi.c +@@ -439,7 +439,22 @@ void imx_pcm_free(struct snd_pcm *pcm) + } + EXPORT_SYMBOL_GPL(imx_pcm_free); + ++static int imx_ssi_dai_probe(struct snd_soc_dai *dai) ++{ ++ struct imx_ssi *ssi = dev_get_drvdata(dai->dev); ++ uint32_t val; ++ ++ snd_soc_dai_set_drvdata(dai, ssi); ++ ++ val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) | ++ SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize); ++ writel(val, ssi->base + SSI_SFCSR); ++ ++ return 0; ++} ++ + static struct snd_soc_dai_driver imx_ssi_dai = { ++ .probe = imx_ssi_dai_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, +@@ -455,20 +470,6 @@ static struct snd_soc_dai_driver imx_ssi_dai = { + .ops = &imx_ssi_pcm_dai_ops, + }; + +-static int imx_ssi_dai_probe(struct snd_soc_dai *dai) +-{ +- struct imx_ssi *ssi = dev_get_drvdata(dai->dev); +- uint32_t val; +- +- snd_soc_dai_set_drvdata(dai, ssi); +- +- val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) | +- SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize); +- writel(val, ssi->base + SSI_SFCSR); +- +- return 0; +-} +- + static struct snd_soc_dai_driver imx_ac97_dai = { + .probe = imx_ssi_dai_probe, + .ac97_control = 1, +@@ -677,7 +678,17 @@ static int imx_ssi_probe(struct platform_device *pdev) + goto failed_register; + } + +- ssi->soc_platform_pdev = platform_device_alloc("imx-fiq-pcm-audio", pdev->id); ++ ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id); ++ if (!ssi->soc_platform_pdev_fiq) ++ goto failed_pdev_fiq_alloc; ++ platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi); ++ ret = platform_device_add(ssi->soc_platform_pdev_fiq); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to add platform device\n"); ++ goto failed_pdev_fiq_add; ++ } ++ ++ ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id); + if (!ssi->soc_platform_pdev) + goto failed_pdev_alloc; + platform_set_drvdata(ssi->soc_platform_pdev, ssi); +@@ -692,6 +703,9 @@ static int imx_ssi_probe(struct platform_device *pdev) + failed_pdev_add: + platform_device_put(ssi->soc_platform_pdev); + failed_pdev_alloc: ++failed_pdev_fiq_add: ++ platform_device_put(ssi->soc_platform_pdev_fiq); ++failed_pdev_fiq_alloc: + snd_soc_unregister_dai(&pdev->dev); + failed_register: + failed_ac97: +diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h +index 53b780d..a4406a1 100644 +--- a/sound/soc/imx/imx-ssi.h ++++ b/sound/soc/imx/imx-ssi.h +@@ -185,6 +185,9 @@ + + #define DRV_NAME "imx-ssi" + ++#include <linux/dmaengine.h> ++#include <mach/dma.h> ++ + struct imx_pcm_dma_params { + int dma; + unsigned long dma_addr; +@@ -212,6 +215,7 @@ struct imx_ssi { + int enabled; + + struct platform_device *soc_platform_pdev; ++ struct platform_device *soc_platform_pdev_fiq; + }; + + struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev, +diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c +index 6a65dd7..39f2373 100644 +--- a/sound/soc/imx/phycore-ac97.c ++++ b/sound/soc/imx/phycore-ac97.c +@@ -20,9 +20,6 @@ + #include <sound/soc-dapm.h> + #include <asm/mach-types.h> + +-#include "../codecs/wm9712.h" +-#include "imx-ssi.h" +- + static struct snd_soc_card imx_phycore; + + static struct snd_soc_ops imx_phycore_hifi_ops = { +@@ -41,7 +38,7 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = { + }; + + static struct snd_soc_card imx_phycore = { +- .name = "PhyCORE-audio", ++ .name = "PhyCORE-ac97-audio", + .dai_link = imx_phycore_dai_ac97, + .num_links = ARRAY_SIZE(imx_phycore_dai_ac97), + }; +diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c +index d211c9f..7e84f24 100644 +--- a/sound/soc/omap/omap-mcbsp.c ++++ b/sound/soc/omap/omap-mcbsp.c +@@ -644,15 +644,23 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, + + + case OMAP_MCBSP_CLKR_SRC_CLKR: ++ if (cpu_class_is_omap1()) ++ break; + omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR); + break; + case OMAP_MCBSP_CLKR_SRC_CLKX: ++ if (cpu_class_is_omap1()) ++ break; + omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX); + break; + case OMAP_MCBSP_FSR_SRC_FSR: ++ if (cpu_class_is_omap1()) ++ break; + omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR); + break; + case OMAP_MCBSP_FSR_SRC_FSX: ++ if (cpu_class_is_omap1()) ++ break; + omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX); + break; + default: +diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c +index 97e9423..f451acd 100644 +--- a/sound/soc/pxa/corgi.c ++++ b/sound/soc/pxa/corgi.c +@@ -100,8 +100,13 @@ static int corgi_startup(struct snd_pcm_substream *substream) + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + ++ mutex_lock(&codec->mutex); ++ + /* check the jack status at stream startup */ + corgi_ext_control(codec); ++ ++ mutex_unlock(&codec->mutex); ++ + return 0; + } + +diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c +index b8207ce..5ef0526 100644 +--- a/sound/soc/pxa/magician.c ++++ b/sound/soc/pxa/magician.c +@@ -72,9 +72,13 @@ static int magician_startup(struct snd_pcm_substream *substream) + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + ++ mutex_lock(&codec->mutex); ++ + /* check the jack status at stream startup */ + magician_ext_control(codec); + ++ mutex_unlock(&codec->mutex); ++ + return 0; + } + +diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c +index af84ee9..84edd03 100644 +--- a/sound/soc/pxa/poodle.c ++++ b/sound/soc/pxa/poodle.c +@@ -77,8 +77,13 @@ static int poodle_startup(struct snd_pcm_substream *substream) + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + ++ mutex_lock(&codec->mutex); ++ + /* check the jack status at stream startup */ + poodle_ext_control(codec); ++ ++ mutex_unlock(&codec->mutex); ++ + return 0; + } + +diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c +index f470f36..0b30d7d 100644 +--- a/sound/soc/pxa/spitz.c ++++ b/sound/soc/pxa/spitz.c +@@ -108,8 +108,13 @@ static int spitz_startup(struct snd_pcm_substream *substream) + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + ++ mutex_lock(&codec->mutex); ++ + /* check the jack status at stream startup */ + spitz_ext_control(codec); ++ ++ mutex_unlock(&codec->mutex); ++ + return 0; + } + +diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c +index 73d0edd..7b983f9 100644 +--- a/sound/soc/pxa/tosa.c ++++ b/sound/soc/pxa/tosa.c +@@ -81,8 +81,13 @@ static int tosa_startup(struct snd_pcm_substream *substream) + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + ++ mutex_lock(&codec->mutex); ++ + /* check the jack status at stream startup */ + tosa_ext_control(codec); ++ ++ mutex_unlock(&codec->mutex); ++ + return 0; + } + +diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig +index 8a6b53c..d85bf8a 100644 +--- a/sound/soc/s3c24xx/Kconfig ++++ b/sound/soc/s3c24xx/Kconfig +@@ -2,6 +2,7 @@ config SND_S3C24XX_SOC + tristate "SoC Audio for the Samsung S3CXXXX chips" + depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 + select S3C64XX_DMA if ARCH_S3C64XX ++ select S3C2410_DMA if ARCH_S3C2410 + help + Say Y or M if you want to add support for codecs attached to + the S3C24XX AC97 or I2S interfaces. You will also need to +diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/s3c24xx/rx1950_uda1380.c +index ffd5cf2..468cc11 100644 +--- a/sound/soc/s3c24xx/rx1950_uda1380.c ++++ b/sound/soc/s3c24xx/rx1950_uda1380.c +@@ -50,7 +50,6 @@ static unsigned int rates[] = { + 16000, + 44100, + 48000, +- 88200, + }; + + static struct snd_pcm_hw_constraint_list hw_rates = { +@@ -130,7 +129,6 @@ static const struct snd_soc_dapm_route audio_map[] = { + }; + + static struct platform_device *s3c24xx_snd_device; +-static struct clk *xtal; + + static int rx1950_startup(struct snd_pcm_substream *substream) + { +@@ -179,10 +177,8 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, + case 44100: + case 88200: + clk_source = S3C24XX_CLKSRC_MPLL; +- fs_mode = S3C2410_IISMOD_256FS; +- div = clk_get_rate(xtal) / (256 * rate); +- if (clk_get_rate(xtal) % (256 * rate) > (128 * rate)) +- div++; ++ fs_mode = S3C2410_IISMOD_384FS; ++ div = 1; + break; + default: + printk(KERN_ERR "%s: rate %d is not supported\n", +@@ -210,7 +206,7 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, + + /* set MCLK division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, +- S3C2410_IISMOD_384FS); ++ fs_mode); + if (ret < 0) + return ret; + +@@ -295,17 +291,8 @@ static int __init rx1950_init(void) + goto err_plat_add; + } + +- xtal = clk_get(&s3c24xx_snd_device->dev, "xtal"); +- +- if (IS_ERR(xtal)) { +- ret = PTR_ERR(xtal); +- platform_device_unregister(s3c24xx_snd_device); +- goto err_clk; +- } +- + return 0; + +-err_clk: + err_plat_add: + err_plat_alloc: + err_gpio_conf: +@@ -320,7 +307,6 @@ static void __exit rx1950_exit(void) + platform_device_unregister(s3c24xx_snd_device); + snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), + hp_jack_gpios); +- clk_put(xtal); + gpio_free(S3C2410_GPA(1)); + } + +diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c +index 614a8b3..441285a 100644 +--- a/sound/soc/soc-core.c ++++ b/sound/soc/soc-core.c +@@ -3043,8 +3043,10 @@ int snd_soc_register_dais(struct device *dev, + for (i = 0; i < count; i++) { + + dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); +- if (dai == NULL) +- return -ENOMEM; ++ if (dai == NULL) { ++ ret = -ENOMEM; ++ goto err; ++ } + + /* create DAI component name */ + dai->name = fmt_multiple_name(dev, &dai_drv[i]); +@@ -3263,9 +3265,6 @@ int snd_soc_register_codec(struct device *dev, + return 0; + + error: +- for (i--; i >= 0; i--) +- snd_soc_unregister_dai(dev); +- + if (codec->reg_cache) + kfree(codec->reg_cache); + kfree(codec->name); +diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c +index 7d85c64..75ed649 100644 +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -683,12 +683,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a, + struct snd_soc_dapm_widget *b, + int sort[]) + { +- if (a->codec != b->codec) +- return (unsigned long)a - (unsigned long)b; + if (sort[a->id] != sort[b->id]) + return sort[a->id] - sort[b->id]; + if (a->reg != b->reg) + return a->reg - b->reg; ++ if (a->codec != b->codec) ++ return (unsigned long)a->codec - (unsigned long)b->codec; + + return 0; + } +diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c +index 1bc56b2..337a002 100644 +--- a/sound/spi/at73c213.c ++++ b/sound/spi/at73c213.c +@@ -155,7 +155,7 @@ static int snd_at73c213_set_bitrate(struct snd_at73c213 *chip) + if (max_tries < 1) + max_tries = 1; + +- /* ssc_div must be a power of 2. */ ++ /* ssc_div must be even. */ + ssc_div = (ssc_div + 1) & ~1UL; + + if ((ssc_rate / (ssc_div * 2 * 16)) < BITRATE_MIN) { diff --git a/series.conf b/series.conf index 044c601d3b..13a0e669fa 100644 --- a/series.conf +++ b/series.conf @@ -30,6 +30,7 @@ patches.kernel.org/patch-2.6.37-rc1 patches.kernel.org/patch-2.6.37-rc1-rc2 patches.kernel.org/patch-2.6.37-rc2-rc3 + patches.kernel.org/patch-2.6.37-rc3-git1 ######################################################## # Build fixes that apply to the vanilla kernel too. |