]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 24 Nov 2010 21:57:11 +0000 (06:57 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 24 Nov 2010 21:57:11 +0000 (06:57 +0900)
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
  virtio: fix format of sysfs driver/vendor files
  Char: virtio_console, fix memory leak
  virtio: return correct capacity to users
  module: Update prototype for ref_module (formerly use_module)

115 files changed:
Documentation/kernel-parameters.txt
MAINTAINERS
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/um/drivers/line.c
arch/x86/include/asm/fixmap.h
arch/x86/include/asm/xen/interface.h
arch/x86/include/asm/xen/interface_32.h
arch/x86/include/asm/xen/interface_64.h
arch/x86/include/asm/xen/page.h
arch/x86/xen/enlighten.c
arch/x86/xen/mmu.c
arch/x86/xen/setup.c
drivers/leds/leds-lp5521.c
drivers/leds/leds-lp5523.c
drivers/leds/leds-ss4200.c
drivers/misc/isl29020.c
drivers/misc/sgi-xp/xpc_partition.c
drivers/net/atl1c/atl1c_hw.c
drivers/net/e1000/e1000_main.c
drivers/net/irda/sh_sir.c
drivers/net/phy/marvell.c
drivers/net/qlge/qlge_main.c
drivers/usb/atm/ueagle-atm.c
drivers/usb/gadget/atmel_usba_udc.c
drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-mem.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/isp1362-hcd.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/cypress_cy7c63.c
drivers/usb/misc/trancevibrator.c
drivers/usb/misc/usbled.c
drivers/usb/misc/usbsevseg.c
drivers/usb/otg/langwell_otg.c
drivers/usb/storage/sierra_ms.c
drivers/video/backlight/backlight.c
drivers/xen/Makefile
drivers/xen/balloon.c
drivers/xen/events.c
drivers/xen/evtchn.c
drivers/xen/xenfs/privcmd.c
drivers/xen/xenfs/super.c
fs/fuse/file.c
fs/proc/task_mmu.c
fs/reiserfs/ioctl.c
include/linux/fs.h
include/linux/marvell_phy.h
include/linux/mfd/wm8350/audio.h
include/linux/page_cgroup.h
include/xen/interface/memory.h
include/xen/page.h
include/xen/privcmd.h
init/Kconfig
mm/memcontrol.c
mm/nommu.c
mm/page_alloc.c
mm/pagewalk.c
net/ceph/buffer.c
net/core/request_sock.c
net/ipv4/fib_trie.c
net/ipv6/addrconf.c
net/xfrm/xfrm_hash.c
scripts/gfp-translate
sound/atmel/abdac.c
sound/core/pcm_lib.c
sound/oss/dev_table.c
sound/oss/midibuf.c
sound/oss/pss.c
sound/oss/sequencer.c
sound/pci/asihpi/hpioctl.c
sound/pci/azt3328.c
sound/pci/ctxfi/ctpcm.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/intel8x0.c
sound/pci/mixart/mixart_hwdep.h
sound/ppc/pmac.c
sound/soc/atmel/Kconfig
sound/soc/codecs/max98088.c
sound/soc/codecs/uda134x.c
sound/soc/codecs/wm8350.c
sound/soc/codecs/wm8776.c
sound/soc/codecs/wm8962.c
sound/soc/codecs/wm8994.c
sound/soc/davinci/davinci-evm.c
sound/soc/davinci/davinci-i2s.c
sound/soc/davinci/davinci-mcasp.c
sound/soc/davinci/davinci-sffsdr.c
sound/soc/davinci/davinci-vcif.c
sound/soc/fsl/mpc5200_psc_i2s.c
sound/soc/imx/eukrea-tlv320.c
sound/soc/imx/imx-pcm-dma-mx2.c
sound/soc/imx/imx-ssi.c
sound/soc/imx/imx-ssi.h
sound/soc/imx/phycore-ac97.c
sound/soc/omap/omap-mcbsp.c
sound/soc/pxa/corgi.c
sound/soc/pxa/magician.c
sound/soc/pxa/poodle.c
sound/soc/pxa/spitz.c
sound/soc/pxa/tosa.c
sound/soc/s3c24xx/Kconfig
sound/soc/s3c24xx/rx1950_uda1380.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/spi/at73c213.c

index 92e83e53148fe8b1d4848af9a8fd7442cc5624ba..cdd2a6e8a3b79ae9fabc67230a27a21927642c9b 100644 (file)
@@ -2385,6 +2385,11 @@ and is between 256 and 4096 characters. It is defined in the file
                        improve throughput, but will also increase the
                        amount of memory reserved for use by the client.
 
+       swapaccount[=0|1]
+                       [KNL] Enable accounting of swap in memory resource
+                       controller if no parameter or 1 is given or disable
+                       it if 0 is given (See Documentation/cgroups/memory.txt)
+
        swiotlb=        [IA-64] Number of I/O TLB slabs
 
        switches=       [HW,M68k]
index a92c994ba935234d8e9cbf60552d4a6e171519af..b49ba9a43bf80a11315105fd5dfe46f172f2815a 100644 (file)
@@ -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/
index 9be261beae7ddb2a72e2e9a76d9dbf2e2bf51316..2652af124acd941bcb2f7d5bcefa88fe8a0721a2 100644 (file)
@@ -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,
index a12065e87266669a9d66f72bb21a9b4207aca4d2..c466d710d3c103cef9f64445f2e994bcdb4551ca 100644 (file)
@@ -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,
 };
index 0608dd776a16ca3fd966e02b22f93804f812e618..9a2376b3137ccd57532d0d5d6c1432d3e7c23801 100644 (file)
@@ -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,
index 7f7338c90784e01489be21b91e269ce85d757d21..1664cce7b0ac5774313ed2805b58f6cac8058279 100644 (file)
@@ -727,6 +727,9 @@ struct winch {
 
 static void free_winch(struct winch *winch, int free_irq_ok)
 {
+       if (free_irq_ok)
+               free_irq(WINCH_IRQ, winch);
+
        list_del(&winch->list);
 
        if (winch->pid != -1)
@@ -735,8 +738,6 @@ static void free_winch(struct winch *winch, int free_irq_ok)
                os_close_file(winch->fd);
        if (winch->stack != 0)
                free_stack(winch->stack, 0);
-       if (free_irq_ok)
-               free_irq(WINCH_IRQ, winch);
        kfree(winch);
 }
 
index 4d293dced62f4c178cd19e6cb2eae882678afb33..9479a037419fe1358a96cece0d877a269c71e365 100644 (file)
@@ -216,8 +216,8 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr)
 }
 
 /* Return an pointer with offset calculated */
-static inline unsigned long __set_fixmap_offset(enum fixed_addresses idx,
-                               phys_addr_t phys, pgprot_t flags)
+static __always_inline unsigned long
+__set_fixmap_offset(enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags)
 {
        __set_fixmap(idx, phys, flags);
        return fix_to_virt(idx) + (phys & (PAGE_SIZE - 1));
index e8506c1f0c55115e8282ef5b8177b824f88df282..1c10c88ee4e1a5154168b4b35a6ba34857687fc9 100644 (file)
@@ -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
index 42a7e004ae5ca5372553fec8a9059378ab6a55c4..8413688b2571d760f77d918713b758345bdece0a 100644 (file)
 /* 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.
index 100d2662b97c3c8a821fc6039e93a06b7a2924c7..839a4811cf983630faa5b724277aafacfefe36cb 100644 (file)
 #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)
index dd8c1414b3d57540d374fee9d923947aaa57ceb1..8760cc60a21c8af5bcc7be1993bdf0b67c0eeb06 100644 (file)
@@ -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;
        /*
index 235c0f4d3861da6f1c9d64ded710c7c2176cf895..7250bef7f49eb0105063862443d1a5d9ba1c6118 100644 (file)
@@ -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);
index 21ed8d7f75a5aa6fa85970d177979457d6b94d5c..790af908284e56424ce3c3b0c851b53eb1443b63 100644 (file)
@@ -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;
index 769c4b01fa32e11f01e3a77a37d42f4c8ab13207..38fdffaa71d3347defe9fc871f7cc29acf374d3b 100644 (file)
@@ -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");
index 3782f31f06d20b413463e5f198c77bc9f4434bde..33facd0c45d10c146867cbf2e74c050a360166b5 100644 (file)
@@ -125,11 +125,22 @@ struct lp5521_chip {
        u8                      num_leds;
 };
 
-#define cdev_to_led(c)         container_of(c, struct lp5521_led, cdev)
-#define engine_to_lp5521(eng)  container_of((eng), struct lp5521_chip, \
-                                               engines[(eng)->id - 1])
-#define led_to_lp5521(led)     container_of((led), struct lp5521_chip, \
-                                               leds[(led)->id])
+static inline struct lp5521_led *cdev_to_led(struct led_classdev *cdev)
+{
+       return container_of(cdev, struct lp5521_led, cdev);
+}
+
+static inline struct lp5521_chip *engine_to_lp5521(struct lp5521_engine *engine)
+{
+       return container_of(engine, struct lp5521_chip,
+                           engines[engine->id - 1]);
+}
+
+static inline struct lp5521_chip *led_to_lp5521(struct lp5521_led *led)
+{
+       return container_of(led, struct lp5521_chip,
+                           leds[led->id]);
+}
 
 static void lp5521_led_brightness_work(struct work_struct *work);
 
@@ -185,14 +196,17 @@ static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern)
 
        /* move current engine to direct mode and remember the state */
        ret = lp5521_set_engine_mode(eng, LP5521_CMD_DIRECT);
-       usleep_range(1000, 10000);
+       /* Mode change requires min 500 us delay. 1 - 2 ms  with margin */
+       usleep_range(1000, 2000);
        ret |= lp5521_read(client, LP5521_REG_OP_MODE, &mode);
 
        /* For loading, all the engines to load mode */
        lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
-       usleep_range(1000, 10000);
+       /* Mode change requires min 500 us delay. 1 - 2 ms  with margin */
+       usleep_range(1000, 2000);
        lp5521_write(client, LP5521_REG_OP_MODE, LP5521_CMD_LOAD);
-       usleep_range(1000, 10000);
+       /* Mode change requires min 500 us delay. 1 - 2 ms  with margin */
+       usleep_range(1000, 2000);
 
        addr = LP5521_PROG_MEM_BASE + eng->prog_page * LP5521_PROG_MEM_SIZE;
        i2c_smbus_write_i2c_block_data(client,
@@ -231,10 +245,6 @@ static int lp5521_configure(struct i2c_client *client,
 
        lp5521_init_engine(chip, attr_group);
 
-       lp5521_write(client, LP5521_REG_RESET, 0xff);
-
-       usleep_range(10000, 20000);
-
        /* Set all PWMs to direct control mode */
        ret = lp5521_write(client, LP5521_REG_OP_MODE, 0x3F);
 
@@ -251,8 +261,8 @@ static int lp5521_configure(struct i2c_client *client,
        ret |= lp5521_write(client, LP5521_REG_ENABLE,
                        LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM |
                        LP5521_EXEC_RUN);
-       /* enable takes 500us */
-       usleep_range(500, 20000);
+       /* enable takes 500us. 1 - 2 ms leaves some margin */
+       usleep_range(1000, 2000);
 
        return ret;
 }
@@ -305,7 +315,8 @@ static int lp5521_detect(struct i2c_client *client)
                        LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM);
        if (ret)
                return ret;
-       usleep_range(1000, 10000);
+       /* enable takes 500us. 1 - 2 ms leaves some margin */
+       usleep_range(1000, 2000);
        ret = lp5521_read(client, LP5521_REG_ENABLE, &buf);
        if (ret)
                return ret;
@@ -693,11 +704,16 @@ static int lp5521_probe(struct i2c_client *client,
 
        if (pdata->enable) {
                pdata->enable(0);
-               usleep_range(1000, 10000);
+               usleep_range(1000, 2000); /* Keep enable down at least 1ms */
                pdata->enable(1);
-               usleep_range(1000, 10000); /* Spec says min 500us */
+               usleep_range(1000, 2000); /* 500us abs min. */
        }
 
+       lp5521_write(client, LP5521_REG_RESET, 0xff);
+       usleep_range(10000, 20000); /*
+                                    * Exact value is not available. 10 - 20ms
+                                    * appears to be enough for reset.
+                                    */
        ret = lp5521_detect(client);
 
        if (ret) {
index 1e11fcc08b285b9c7d61590621616bba6ad78411..0cc4ead2fd8b35cdeef653a211b40a2e885b1630 100644 (file)
@@ -134,15 +134,18 @@ struct lp5523_chip {
        u8                      num_leds;
 };
 
-#define cdev_to_led(c)          container_of(c, struct lp5523_led, cdev)
+static inline struct lp5523_led *cdev_to_led(struct led_classdev *cdev)
+{
+       return container_of(cdev, struct lp5523_led, cdev);
+}
 
-static struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine)
+static inline struct lp5523_chip *engine_to_lp5523(struct lp5523_engine *engine)
 {
        return container_of(engine, struct lp5523_chip,
                            engines[engine->id - 1]);
 }
 
-static struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
+static inline struct lp5523_chip *led_to_lp5523(struct lp5523_led *led)
 {
        return container_of(led, struct lp5523_chip,
                            leds[led->id]);
@@ -200,13 +203,9 @@ static int lp5523_configure(struct i2c_client *client)
                { 0x9c, 0x50, 0x9c, 0xd0, 0x9d, 0x80, 0xd8, 0x00, 0},
        };
 
-       lp5523_write(client, LP5523_REG_RESET, 0xff);
-
-       usleep_range(10000, 100000);
-
        ret |= lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE);
-       /* Chip startup time after reset is 500 us */
-       usleep_range(1000, 10000);
+       /* Chip startup time is 500 us, 1 - 2 ms gives some margin */
+       usleep_range(1000, 2000);
 
        ret |= lp5523_write(client, LP5523_REG_CONFIG,
                            LP5523_AUTO_INC | LP5523_PWR_SAVE |
@@ -243,8 +242,8 @@ static int lp5523_configure(struct i2c_client *client)
                return -1;
        }
 
-       /* Wait 3ms and check the engine status */
-       usleep_range(3000, 20000);
+       /* Let the programs run for couple of ms and check the engine status */
+       usleep_range(3000, 6000);
        lp5523_read(client, LP5523_REG_STATUS, &status);
        status &= LP5523_ENG_STATUS_MASK;
 
@@ -449,10 +448,10 @@ static ssize_t lp5523_selftest(struct device *dev,
        /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */
        lp5523_write(chip->client, LP5523_REG_LED_TEST_CTRL,
                                    LP5523_EN_LEDTEST | 16);
-       usleep_range(3000, 10000);
+       usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */
        ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
        if (!(status & LP5523_LEDTEST_DONE))
-               usleep_range(3000, 10000);
+               usleep_range(3000, 6000); /* Was not ready. Wait little bit */
 
        ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &vdd);
        vdd--;  /* There may be some fluctuation in measurement */
@@ -468,16 +467,16 @@ static ssize_t lp5523_selftest(struct device *dev,
                        chip->pdata->led_config[i].led_current);
 
                lp5523_write(chip->client, LP5523_REG_LED_PWM_BASE + i, 0xff);
-               /* let current stabilize 2ms before measurements start */
-               usleep_range(2000, 10000);
+               /* let current stabilize 2 - 4ms before measurements start */
+               usleep_range(2000, 4000);
                lp5523_write(chip->client,
                             LP5523_REG_LED_TEST_CTRL,
                             LP5523_EN_LEDTEST | i);
-               /* ledtest takes 2.7ms */
-               usleep_range(3000, 10000);
+               /* ADC conversion time is 2.7 ms typically */
+               usleep_range(3000, 6000);
                ret = lp5523_read(chip->client, LP5523_REG_STATUS, &status);
                if (!(status & LP5523_LEDTEST_DONE))
-                       usleep_range(3000, 10000);
+                       usleep_range(3000, 6000);/* Was not ready. Wait. */
                ret |= lp5523_read(chip->client, LP5523_REG_LED_TEST_ADC, &adc);
 
                if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
@@ -930,11 +929,16 @@ static int lp5523_probe(struct i2c_client *client,
 
        if (pdata->enable) {
                pdata->enable(0);
-               usleep_range(1000, 10000);
+               usleep_range(1000, 2000); /* Keep enable down at least 1ms */
                pdata->enable(1);
-               usleep_range(1000, 10000); /* Spec says min 500us */
+               usleep_range(1000, 2000); /* 500us abs min. */
        }
 
+       lp5523_write(client, LP5523_REG_RESET, 0xff);
+       usleep_range(10000, 20000); /*
+                                    * Exact value is not available. 10 - 20ms
+                                    * appears to be enough for reset.
+                                    */
        ret = lp5523_detect(client);
        if (ret)
                goto fail2;
index a688293abd0b43a0f9e8135d0ce4d43812307f0a..614ebebaaa28cdcf7d7c765b1c0c959fd7ac4782 100644 (file)
@@ -102,6 +102,7 @@ static struct dmi_system_id __initdata nas_led_whitelist[] = {
                        DMI_MATCH(DMI_PRODUCT_VERSION, "1.00.00")
                }
        },
+       {}
 };
 
 /*
index ca47e62850752b80772bd3d77a246bfe1109b742..307aada5fffeca067520a55eecb6c020c80bd7a6 100644 (file)
@@ -183,9 +183,7 @@ static int  isl29020_probe(struct i2c_client *client,
 
 static int isl29020_remove(struct i2c_client *client)
 {
-       struct als_data *data = i2c_get_clientdata(client);
        sysfs_remove_group(&client->dev.kobj, &m_als_gr);
-       kfree(data);
        return 0;
 }
 
@@ -245,6 +243,6 @@ static void  __exit sensor_isl29020_exit(void)
 module_init(sensor_isl29020_init);
 module_exit(sensor_isl29020_exit);
 
-MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com");
+MODULE_AUTHOR("Kalhan Trisal <kalhan.trisal@intel.com>");
 MODULE_DESCRIPTION("Intersil isl29020 ALS Driver");
 MODULE_LICENSE("GPL v2");
index d551f09ccb792175d49a83c4a929df7394f50a8a..6956f7e7d43921ec80f5e450a471429bc21f55fc 100644 (file)
@@ -439,18 +439,23 @@ xpc_discovery(void)
         * nodes that can comprise an access protection grouping. The access
         * protection is in regards to memory, IOI and IPI.
         */
-       max_regions = 64;
        region_size = xp_region_size;
 
-       switch (region_size) {
-       case 128:
-               max_regions *= 2;
-       case 64:
-               max_regions *= 2;
-       case 32:
-               max_regions *= 2;
-               region_size = 16;
-               DBUG_ON(!is_shub2());
+       if (is_uv())
+               max_regions = 256;
+       else {
+               max_regions = 64;
+
+               switch (region_size) {
+               case 128:
+                       max_regions *= 2;
+               case 64:
+                       max_regions *= 2;
+               case 32:
+                       max_regions *= 2;
+                       region_size = 16;
+                       DBUG_ON(!is_shub2());
+               }
        }
 
        for (region = 0; region < max_regions; region++) {
index 919080b2c3a50eb48bea7311ac0db4e8d3e8103e..1bf67200994827fd76250e718b3bdf4a67a609e8 100644 (file)
@@ -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;
index 4686c3983fc3044f0e0af47cf75dee71b6dadb02..4d62f7bfa0367578471f2773f04a365fed7db972 100644 (file)
@@ -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);
index 00b38bccd6d0fd51f19cfe383f71a1f5952d6a43..52a7c86af66347c388d24d29b043fe52e6a2ca5f 100644 (file)
@@ -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,
index f0bd1a1aba3ab3413a16eab296b4881d99ea1145..e8b9c53c304b63d2ba2b4a530504e5fafb08f6dc 100644 (file)
 #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;
 }
 
@@ -684,6 +808,19 @@ static struct phy_driver marvell_drivers[] = {
                .config_intr = &marvell_config_intr,
                .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,
@@ -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 },
        { }
index c30e0fe55a314858828c2caa4d464b0c2301fe81..528eaef5308fa59460c8697ffc4fc0400d74a6cb 100644 (file)
@@ -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;
index ea071a5b6eee6aa929827851966dec80dfe070a0..44447f54942f6d6e1c7c7e2a777b4c882f6b546d 100644 (file)
@@ -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)                                  \
                                                                \
index b5e20e873cbad09bbebb7134929cf97880532bea..717ff653fa2330a9e5b78774b1a084f80186faf0 100644 (file)
@@ -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;
                }
        }
 
index 86afdc73322f21787bf0d1e003acbe563f8f316e..6e2599661b5bdcad9323185bd992dbdb7df45b21 100644 (file)
@@ -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;
 
index 502a7e6fef42a5a5c9ddbfa0ca26b4b971b043e1..e9062806d4a24898286240f139a2f28dadd8522c 100644 (file)
@@ -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.
                 */
index d36e4e75e08d4e476249a71259d8d760d5158a7b..12f70c302b0b73089451e8e93dbeb66f3c068723 100644 (file)
@@ -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);
index a1e8d273103f77b2d237a5f68438b289b51bb92a..01bb72b7183230182fac79fd307b17323e79cfb3 100644 (file)
@@ -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)
index a92526d6e5aeb4a306442df77d27b702e00c0d0c..d9f78eb265721bb065f23482e482b50d2bc8430a 100644 (file)
@@ -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);
index bde823f704e9a6d496cf735f08658fa7f2f6397b..ba8eab366b823fd7153879a801ce7a60c915af08 100644 (file)
@@ -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)
index 6c4fb4efb4bb9251c531df4cabd51e8b7a65607b..43a39eb56cc6ea77af2cc7ae930392f1cd70325a 100644 (file)
@@ -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;
index 202770676da30c409652dc1aca0b4d33a857d366..d178761c39817ec71c0b9461e69a01eb6856e473 100644 (file)
@@ -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:
index 9f3115e729b173605cb36c278509b7befb68f825..df558f6f84e30eff6d6df0fc61c3bd67fb183387 100644 (file)
@@ -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);
index 5d7d4e951ea4bc951c4783729472467a383ec1c2..06fca0835b52cc606d57a467332dec1fee916366 100644 (file)
@@ -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;
index 93d3bf4d213c76dbacc8d964f72bda2a4c2c32c5..85e65647d44518cf3c3bbf0873816b344b90cf53 100644 (file)
@@ -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)
index 2f43c57743c9c905b26e8e06dc517df6b5bb7c26..9251773ecef4ffae6102a29f356bad68cf7dd574 100644 (file)
@@ -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,
index d77aba46ae85675e58afb532078458b74b7b29a7..f63776a48e2a8717f37d5ebf68cb6b408a5d895a 100644 (file)
@@ -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)
index 63da2c3c838fd0b6495d0429a870e3b1e035e9dd..c96f51de1696581faba425fb29db3a18f9ef1458 100644 (file)
@@ -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);
index de8ef945b536d07a277c56bff506798bd90620e3..417b8f207e8b126ac5b2ee33bab0dc5fdaa232b0 100644 (file)
@@ -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);
index bdc3ea66be692dd1155828d97971cb11970a77f5..9fea48264fa2049fe7eefd18cada2013a180a5e0 100644 (file)
@@ -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,
index 57fc2f532cabe985b9b10fdd57c7042b6d0fd4be..ceba512f84d0eeeb2f3170a14df915528304dbe2 100644 (file)
@@ -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)
 {
index e207810bba3cfe9e0042f02bc447ad5b01564ff0..08703299ef61184bf3e0cd212601f2817e9e8e63 100644 (file)
@@ -197,12 +197,12 @@ static int backlight_suspend(struct device *dev, pm_message_t state)
 {
        struct backlight_device *bd = to_backlight_device(dev);
 
-       if (bd->ops->options & BL_CORE_SUSPENDRESUME) {
-               mutex_lock(&bd->ops_lock);
+       mutex_lock(&bd->ops_lock);
+       if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) {
                bd->props.state |= BL_CORE_SUSPENDED;
                backlight_update_status(bd);
-               mutex_unlock(&bd->ops_lock);
        }
+       mutex_unlock(&bd->ops_lock);
 
        return 0;
 }
@@ -211,12 +211,12 @@ static int backlight_resume(struct device *dev)
 {
        struct backlight_device *bd = to_backlight_device(dev);
 
-       if (bd->ops->options & BL_CORE_SUSPENDRESUME) {
-               mutex_lock(&bd->ops_lock);
+       mutex_lock(&bd->ops_lock);
+       if (bd->ops && bd->ops->options & BL_CORE_SUSPENDRESUME) {
                bd->props.state &= ~BL_CORE_SUSPENDED;
                backlight_update_status(bd);
-               mutex_unlock(&bd->ops_lock);
        }
+       mutex_unlock(&bd->ops_lock);
 
        return 0;
 }
index eb8a78d77d9d2a7fb70f81ac54ae902e6b29204d..533a199e7a3f94911ef9665ab5e1789c63bef6d2 100644 (file)
@@ -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
+
index 500290b150bb526cf27b9f5e82d9a08b160a2d91..2b17ad5b4b32d27277a115de4cd2fd7834f7769d 100644 (file)
@@ -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;
index 321a0c8346e581bc3504ac0891b7b4883d98589c..2811bb988ea0551b85bc4c77d15b8590382abdf4 100644 (file)
@@ -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) {
index fec6ba3c08a8e885d663ce3ac9c8b031ff971273..ef11daf0cafe9f086f3944b42fd32ff48811f4b2 100644 (file)
@@ -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);
 }
 
index 0f5d4162b22d50b66ce84eca9add1f6fdaa5c3d2..dbd3b16fd1317adc9f1fa8afedfd0e6d3fc53400 100644 (file)
@@ -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;
 
index f6339d11d59cbdebc8d558f552cc199175003e05..1aa3897198462112a3bc1db479986653cf0a716f 100644 (file)
@@ -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>
 
 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)
index c8224587123f6e2ff84c8933f8d56a50ffd06c80..9242d294fe90d382fb7a40f1220923baea71c97e 100644 (file)
@@ -134,6 +134,7 @@ EXPORT_SYMBOL_GPL(fuse_do_open);
 void fuse_finish_open(struct inode *inode, struct file *file)
 {
        struct fuse_file *ff = file->private_data;
+       struct fuse_conn *fc = get_fuse_conn(inode);
 
        if (ff->open_flags & FOPEN_DIRECT_IO)
                file->f_op = &fuse_direct_io_file_operations;
@@ -141,6 +142,15 @@ void fuse_finish_open(struct inode *inode, struct file *file)
                invalidate_inode_pages2(inode->i_mapping);
        if (ff->open_flags & FOPEN_NONSEEKABLE)
                nonseekable_open(inode, file);
+       if (fc->atomic_o_trunc && (file->f_flags & O_TRUNC)) {
+               struct fuse_inode *fi = get_fuse_inode(inode);
+
+               spin_lock(&fc->lock);
+               fi->attr_version = ++fc->attr_version;
+               i_size_write(inode, 0);
+               spin_unlock(&fc->lock);
+               fuse_invalidate_attr(inode);
+       }
 }
 
 int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
index da6b01d70f019506face0dae73f0b78c3200d299..c126c83b9a45bc838125d1ac12b44e13f89d8b26 100644 (file)
@@ -706,6 +706,7 @@ static int pagemap_hugetlb_range(pte_t *pte, unsigned long hmask,
  * skip over unmapped regions.
  */
 #define PAGEMAP_WALK_SIZE      (PMD_SIZE)
+#define PAGEMAP_WALK_MASK      (PMD_MASK)
 static ssize_t pagemap_read(struct file *file, char __user *buf,
                            size_t count, loff_t *ppos)
 {
@@ -776,7 +777,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf,
                unsigned long end;
 
                pm.pos = 0;
-               end = start_vaddr + PAGEMAP_WALK_SIZE;
+               end = (start_vaddr + PAGEMAP_WALK_SIZE) & PAGEMAP_WALK_MASK;
                /* overflow ? */
                if (end < start_vaddr || end > end_vaddr)
                        end = end_vaddr;
index bd9763e76bae42844a6cf792d1da86a3454dbe38..79265fdc317a09889c6ce3c2343bb17594bce40e 100644 (file)
@@ -183,12 +183,11 @@ int reiserfs_unpack(struct inode *inode, struct file *filp)
                return 0;
        }
 
-       /* we need to make sure nobody is changing the file size beneath
-        ** us
-        */
-       reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb);
        depth = reiserfs_write_lock_once(inode->i_sb);
 
+       /* we need to make sure nobody is changing the file size beneath us */
+       reiserfs_mutex_lock_safe(&inode->i_mutex, inode->i_sb);
+
        write_from = inode->i_size & (blocksize - 1);
        /* if we are on a block boundary, we are already unpacked.  */
        if (write_from == 0) {
index eedc00b7b1ee7a6c6ed887e264891911fa370c3c..c9e06cc70dad585c6c185db2d1503d3fad4a5a48 100644 (file)
@@ -34,9 +34,9 @@
 #define SEEK_MAX       SEEK_END
 
 struct fstrim_range {
-       uint64_t start;
-       uint64_t len;
-       uint64_t minlen;
+       __u64 start;
+       __u64 len;
+       __u64 minlen;
 };
 
 /* And dynamically-tunable limits and defaults: */
index 1ff81b51b656a13f32c4d8b5253f803593cd033b..dd3c34ebca9a67e05c2e59649da81486210e802c 100644 (file)
@@ -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
 
index a95141eafce390d7586c17c4eb3f3777c20669db..bd581c6fa0855bf9014a5cb061d5dc78df204e21 100644 (file)
 #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
index 5bb13b3db84d46ee155784a26acfd850e94c91ff..b02195dfc1b0d3eb3044972db401b50acb0ad27d 100644 (file)
@@ -59,8 +59,6 @@ static inline void ClearPageCgroup##uname(struct page_cgroup *pc)     \
 static inline int TestClearPageCgroup##uname(struct page_cgroup *pc)   \
        { return test_and_clear_bit(PCG_##lname, &pc->flags);  }
 
-TESTPCGFLAG(Locked, LOCK)
-
 /* Cache flag is set only once (at allocation) */
 TESTPCGFLAG(Cache, CACHE)
 CLEARPCGFLAG(Cache, CACHE)
@@ -104,6 +102,11 @@ static inline void unlock_page_cgroup(struct page_cgroup *pc)
        bit_spin_unlock(PCG_LOCK, &pc->flags);
 }
 
+static inline int page_is_cgroup_locked(struct page_cgroup *pc)
+{
+       return bit_spin_is_locked(PCG_LOCK, &pc->flags);
+}
+
 #else /* CONFIG_CGROUP_MEM_RES_CTLR */
 struct page_cgroup;
 
index d7a6c13bde69cf505bef40027bcd555a4463d57f..eac3ce1537190228ba8dc74f0398d8e6e4795572 100644 (file)
@@ -140,6 +140,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.
index eaf85fab12632d45cc00d8976d9108a3eacc2850..0be36b976f4b02905034532919e7fc576eba19d7 100644 (file)
@@ -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 */
index b42cdfd92fee5becfa065aeaeec36b743b9664e8..17857fb4d5509b24a475609e2806af53c79d5317 100644 (file)
 #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];
index 88c10468db467bb862554aab55f5d4891e4b0f03..c9728992a776356e043d21df7b33aa045c2d7904 100644 (file)
@@ -613,6 +613,19 @@ config CGROUP_MEM_RES_CTLR_SWAP
          if boot option "noswapaccount" is set, swap will not be accounted.
          Now, memory usage of swap_cgroup is 2 bytes per entry. If swap page
          size is 4096bytes, 512k per 1Gbytes of swap.
+config CGROUP_MEM_RES_CTLR_SWAP_ENABLED
+       bool "Memory Resource Controller Swap Extension enabled by default"
+       depends on CGROUP_MEM_RES_CTLR_SWAP
+       default y
+       help
+         Memory Resource Controller Swap Extension comes with its price in
+         a bigger memory consumption. General purpose distribution kernels
+         which want to enable the feautre but keep it disabled by default
+         and let the user enable it by swapaccount boot command line
+         parameter should have this option unselected.
+         For those who want to have the feature enabled by default should
+         select this option (if, for some reason, they need to disable it
+         then noswapaccount does the trick).
 
 menuconfig CGROUP_SCHED
        bool "Group CPU scheduler"
index 2efa8ea07ff7d931577da964c190f5524088da3d..7a22b41292115f78dc039ebf5e271090dc5a8f9d 100644 (file)
@@ -61,7 +61,14 @@ struct mem_cgroup *root_mem_cgroup __read_mostly;
 #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
 /* Turned on only when memory cgroup is enabled && really_do_swap_account = 1 */
 int do_swap_account __read_mostly;
-static int really_do_swap_account __initdata = 1; /* for remember boot option*/
+
+/* for remember boot option*/
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED
+static int really_do_swap_account __initdata = 1;
+#else
+static int really_do_swap_account __initdata = 0;
+#endif
+
 #else
 #define do_swap_account                (0)
 #endif
@@ -278,13 +285,14 @@ enum move_type {
 
 /* "mc" and its members are protected by cgroup_mutex */
 static struct move_charge_struct {
-       spinlock_t        lock; /* for from, to, moving_task */
+       spinlock_t        lock; /* for from, to */
        struct mem_cgroup *from;
        struct mem_cgroup *to;
        unsigned long precharge;
        unsigned long moved_charge;
        unsigned long moved_swap;
        struct task_struct *moving_task;        /* a task moving charges */
+       struct mm_struct *mm;
        wait_queue_head_t waitq;                /* a waitq for other context */
 } mc = {
        .lock = __SPIN_LOCK_UNLOCKED(mc.lock),
@@ -2152,7 +2160,7 @@ static void __mem_cgroup_move_account(struct page_cgroup *pc,
 {
        VM_BUG_ON(from == to);
        VM_BUG_ON(PageLRU(pc->page));
-       VM_BUG_ON(!PageCgroupLocked(pc));
+       VM_BUG_ON(!page_is_cgroup_locked(pc));
        VM_BUG_ON(!PageCgroupUsed(pc));
        VM_BUG_ON(pc->mem_cgroup != from);
 
@@ -4631,7 +4639,7 @@ static unsigned long mem_cgroup_count_precharge(struct mm_struct *mm)
        unsigned long precharge;
        struct vm_area_struct *vma;
 
-       down_read(&mm->mmap_sem);
+       /* We've already held the mmap_sem */
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
                struct mm_walk mem_cgroup_count_precharge_walk = {
                        .pmd_entry = mem_cgroup_count_precharge_pte_range,
@@ -4643,7 +4651,6 @@ static unsigned long mem_cgroup_count_precharge(struct mm_struct *mm)
                walk_page_range(vma->vm_start, vma->vm_end,
                                        &mem_cgroup_count_precharge_walk);
        }
-       up_read(&mm->mmap_sem);
 
        precharge = mc.precharge;
        mc.precharge = 0;
@@ -4694,11 +4701,16 @@ static void mem_cgroup_clear_mc(void)
 
                mc.moved_swap = 0;
        }
+       if (mc.mm) {
+               up_read(&mc.mm->mmap_sem);
+               mmput(mc.mm);
+       }
        spin_lock(&mc.lock);
        mc.from = NULL;
        mc.to = NULL;
-       mc.moving_task = NULL;
        spin_unlock(&mc.lock);
+       mc.moving_task = NULL;
+       mc.mm = NULL;
        mem_cgroup_end_move(from);
        memcg_oom_recover(from);
        memcg_oom_recover(to);
@@ -4724,12 +4736,21 @@ static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
                        return 0;
                /* We move charges only when we move a owner of the mm */
                if (mm->owner == p) {
+                       /*
+                        * We do all the move charge works under one mmap_sem to
+                        * avoid deadlock with down_write(&mmap_sem)
+                        * -> try_charge() -> if (mc.moving_task) -> sleep.
+                        */
+                       down_read(&mm->mmap_sem);
+
                        VM_BUG_ON(mc.from);
                        VM_BUG_ON(mc.to);
                        VM_BUG_ON(mc.precharge);
                        VM_BUG_ON(mc.moved_charge);
                        VM_BUG_ON(mc.moved_swap);
                        VM_BUG_ON(mc.moving_task);
+                       VM_BUG_ON(mc.mm);
+
                        mem_cgroup_start_move(from);
                        spin_lock(&mc.lock);
                        mc.from = from;
@@ -4737,14 +4758,16 @@ static int mem_cgroup_can_attach(struct cgroup_subsys *ss,
                        mc.precharge = 0;
                        mc.moved_charge = 0;
                        mc.moved_swap = 0;
-                       mc.moving_task = current;
                        spin_unlock(&mc.lock);
+                       mc.moving_task = current;
+                       mc.mm = mm;
 
                        ret = mem_cgroup_precharge_mc(mm);
                        if (ret)
                                mem_cgroup_clear_mc();
-               }
-               mmput(mm);
+                       /* We call up_read() and mmput() in clear_mc(). */
+               } else
+                       mmput(mm);
        }
        return ret;
 }
@@ -4832,7 +4855,7 @@ static void mem_cgroup_move_charge(struct mm_struct *mm)
        struct vm_area_struct *vma;
 
        lru_add_drain_all();
-       down_read(&mm->mmap_sem);
+       /* We've already held the mmap_sem */
        for (vma = mm->mmap; vma; vma = vma->vm_next) {
                int ret;
                struct mm_walk mem_cgroup_move_charge_walk = {
@@ -4851,7 +4874,6 @@ static void mem_cgroup_move_charge(struct mm_struct *mm)
                         */
                        break;
        }
-       up_read(&mm->mmap_sem);
 }
 
 static void mem_cgroup_move_task(struct cgroup_subsys *ss,
@@ -4860,17 +4882,11 @@ static void mem_cgroup_move_task(struct cgroup_subsys *ss,
                                struct task_struct *p,
                                bool threadgroup)
 {
-       struct mm_struct *mm;
-
-       if (!mc.to)
+       if (!mc.mm)
                /* no need to move charge */
                return;
 
-       mm = get_task_mm(p);
-       if (mm) {
-               mem_cgroup_move_charge(mm);
-               mmput(mm);
-       }
+       mem_cgroup_move_charge(mc.mm);
        mem_cgroup_clear_mc();
 }
 #else  /* !CONFIG_MMU */
@@ -4911,10 +4927,20 @@ struct cgroup_subsys mem_cgroup_subsys = {
 };
 
 #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP
+static int __init enable_swap_account(char *s)
+{
+       /* consider enabled if no parameter or 1 is given */
+       if (!s || !strcmp(s, "1"))
+               really_do_swap_account = 1;
+       else if (!strcmp(s, "0"))
+               really_do_swap_account = 0;
+       return 1;
+}
+__setup("swapaccount", enable_swap_account);
 
 static int __init disable_swap_account(char *s)
 {
-       really_do_swap_account = 0;
+       enable_swap_account("0");
        return 1;
 }
 __setup("noswapaccount", disable_swap_account);
index 3613517c75929b17e1b3d93a650e5d9957c2315a..27a9ac58851678d30c7c477d00a857cf2f63bc35 100644 (file)
@@ -1717,6 +1717,7 @@ void exit_mmap(struct mm_struct *mm)
                mm->mmap = vma->vm_next;
                delete_vma_from_mm(vma);
                delete_vma(mm, vma);
+               cond_resched();
        }
 
        kleave("");
index 07a654486f75cfdfe13035f7bf501e2d2dbf0a4a..e4092704c1a9a281985d7fc650e7655b1e00ea09 100644 (file)
@@ -3008,14 +3008,6 @@ static __init_refok int __build_all_zonelists(void *data)
                build_zonelist_cache(pgdat);
        }
 
-#ifdef CONFIG_MEMORY_HOTPLUG
-       /* Setup real pagesets for the new zone */
-       if (data) {
-               struct zone *zone = data;
-               setup_zone_pageset(zone);
-       }
-#endif
-
        /*
         * Initialize the boot_pagesets that are going to be used
         * for bootstrapping processors. The real pagesets for
@@ -3064,7 +3056,11 @@ void build_all_zonelists(void *data)
        } else {
                /* we have to stop all cpus to guarantee there is no user
                   of zonelist */
-               stop_machine(__build_all_zonelists, data, NULL);
+#ifdef CONFIG_MEMORY_HOTPLUG
+               if (data)
+                       setup_zone_pageset((struct zone *)data);
+#endif
+               stop_machine(__build_all_zonelists, NULL, NULL);
                /* cpuset refresh routine should be here */
        }
        vm_total_pages = nr_free_pagecache_pages();
index 8b1a2ce21ee53f3a6ea598759faf02c21c4c5dd2..38cc58b8b2b0d37340f6e327c56c796bd7c24516 100644 (file)
@@ -139,7 +139,6 @@ int walk_page_range(unsigned long addr, unsigned long end,
        pgd_t *pgd;
        unsigned long next;
        int err = 0;
-       struct vm_area_struct *vma;
 
        if (addr >= end)
                return err;
@@ -149,15 +148,17 @@ int walk_page_range(unsigned long addr, unsigned long end,
 
        pgd = pgd_offset(walk->mm, addr);
        do {
+               struct vm_area_struct *uninitialized_var(vma);
+
                next = pgd_addr_end(addr, end);
 
+#ifdef CONFIG_HUGETLB_PAGE
                /*
                 * handle hugetlb vma individually because pagetable walk for
                 * the hugetlb page is dependent on the architecture and
                 * we can't handled it in the same manner as non-huge pages.
                 */
                vma = find_vma(walk->mm, addr);
-#ifdef CONFIG_HUGETLB_PAGE
                if (vma && is_vm_hugetlb_page(vma)) {
                        if (vma->vm_end < next)
                                next = vma->vm_end;
index 53d8abfa25d5ede4b487c88a5341b376c4921c26..bf3e6a13c215cd61cd7372e85ba19e7fc7974e9a 100644 (file)
@@ -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;
index 7552495aff7aef090d99654312d5365afa421e95..fceeb37d7161697922dd46e00d62e3c1cd89eb4b 100644 (file)
@@ -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)
index 200eb538fbb3f77101fe9646893dddbd9e83117b..0f280348e0fdad70adb37f3b33bdbe6fedd99025 100644 (file)
@@ -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)
index 2fc35b32df9eacb3c1dcebf153700b5056bc9689..23cc8e1ce8d4995a551ca93d98434e9150ad1740 100644 (file)
@@ -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);
                }
        }
index a2023ec52329ef66b95e14dc94f7086e5683e534..1e98bc0fe0a54bbca2a7fc1f94ab9344af0fbded 100644 (file)
@@ -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,
index d81b968d864e5009d89f11bff18cfc3b344bdd00..c9230e158a8f60c0a9206b3db4df3dc21f372cf4 100644 (file)
@@ -63,7 +63,12 @@ fi
 
 # Extract GFP flags from the kernel source
 TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1
-grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE
+grep -q ___GFP $SOURCE/include/linux/gfp.h
+if [ $? -eq 0 ]; then
+       grep "^#define ___GFP" $SOURCE/include/linux/gfp.h | sed -e 's/u$//' | grep -v GFP_BITS > $TMPFILE
+else
+       grep "^#define __GFP" $SOURCE/include/linux/gfp.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE
+fi
 
 # Parse the flags
 IFS="
index f2f41c8542211143cc56e83328092d1bcb27a2bf..6e24091818950edc9c298241be2d28a751b39f83 100644 (file)
@@ -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);
index a1707cca9c6635c8b4cd7e79b5cebe21bffc2d9e..b75db8e9cc0f36fff03d0ecf1884b23b3bad724b 100644 (file)
@@ -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;
index 727bdb9ba2dc1bc9b0cc62fd8abde19403ca292d..d8cf3e58dc76aa1017ef5b9424e862e95498ee6d 100644 (file)
@@ -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));
index 782b3b84dac68ccd036c52ee3533336f243ac15b..ceedb1eff203812e85049f7cdb46b92a588fc557 100644 (file)
@@ -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)
        {
index e19dd5dcc2debd9e3b4a7fa9ec481849f8442a30..9b800ce5100ef286864234b308fb646c7d5dc9a1 100644 (file)
@@ -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;
index e85789e53816640f8e7e7224fdd0199787e5f4de..5ea1098ac427a5546bdf9f211587bbe8030d1821 100644 (file)
@@ -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");
index 62895a719fcbcce841b05f44fce0a90813d70477..22dbd91811a4e61398a9b9077c5cbe26c0139119 100644 (file)
@@ -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);
index 4679ed83a43b8687402b7efca98ed47a0518ac98..2f3cacbd5528da80cccca5791147d6f516dcdf82 100644 (file)
@@ -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;
index 85ab43e89212c6724c1e70f3cad3de33e9816935..457d21189b0db1fc5b2fcd2af22e30d20089dcb1 100644 (file)
@@ -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;
 }
index 6361f752b5f35cfddff7f8423f0d5d185a9003d8..846d1ead47fdf1c184fb92f37ae1faf099ec45af 100644 (file)
@@ -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),
index 5f00589cb791aebed2d7aa1f0bd908819b9123b8..0ac6aed0c889f7cb1c029b08430e83e0e9eac770 100644 (file)
@@ -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 },
index 93fa59cc60ef9ba0f5b2315c6461d3966608994c..5c710807dfe588decaf764c29a618cd83711d3d8 100644 (file)
@@ -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;
index 400f9ebd243e84ebf595cb4cba69f6a3cb3552b7..629a5494347a021600ed6f2dbf82feb5971d10ac 100644 (file)
@@ -1864,6 +1864,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
                .name = "Dell Inspiron 8600",   /* STAC9750/51 */
                .type = AC97_TUNE_HP_ONLY
        },
+       {
+               .subvendor = 0x1028,
+               .subdevice = 0x0182,
+               .name = "Dell Latitude D610",   /* STAC9750/51 */
+               .type = AC97_TUNE_HP_ONLY
+       },
        {
                .subvendor = 0x1028,
                .subdevice = 0x0186,
index a46f5083db99229c88797895b9de5170bede8245..812e288ef2e76eb58de27118a7522700f0f21a38 100644 (file)
 
 #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))
index 85081172403f25ec056a99eb58a341fbd5d57370..b47cfd45b3b98f04b2c6d89135de310fb3b264ef 100644 (file)
@@ -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;
                        }
index e720d5e6f04cfdd135ea42e5b74ed74e75724bed..bee3c94f58b0736c57f361141e0ed32e58640317 100644 (file)
@@ -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
index bc22ee93a75daf3c852ce65f9767df519445251c..470cb93b1d1f0a3e5d6caffb69e466cf7f5815d4 100644 (file)
 #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);
index 7540a509a6f58acec8c29aad5c76b65a86a5f83a..464f0cfa4c7a538b7eef3a86752d57f551952d54 100644 (file)
@@ -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,
index f4f1fba38eb9458176f5bda41cc93d12c87722eb..7611add7f8c38751806684a521d891ede746197f 100644 (file)
@@ -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);
index 04182c464e35ffeffb069ad06242dca74da52248..0132a27140ae539c85c822b06b984b0733d84e41 100644 (file)
@@ -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];
 };
 
index 894d0cd3aa9b95896fbaff30db883b1fe39bc668..e8092745a207674caaf4351d815870e7367b4003 100644 (file)
@@ -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);
 
index 0db59c3aa5d4dbb6cd2a821d29eaa75887290977..830dfdd66c5f6c3685ca542cb4c28cec1cabf008 100644 (file)
@@ -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;
 
index 2b07b17a6b2d68f3173380bc16de4eb07b921689..bc9e6b0b3f6fd67c4061ce364198a272d7a557d3 100644 (file)
@@ -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;
index d46b545d41f432f037c58eb6c3b4b0f1b13cc2a2..9e0e565e6ed9c2e9308e74e80f2bad50d8f58b28 100644 (file)
@@ -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,
        },
 };
index 86918ee12419e7fd3ff626bdb2ccd18a1bd09021..fb55d2c5d704ff25983fd5ef4d16dfc461e60a76 100644 (file)
@@ -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,
index 009b6521a1bf9f3731e9d597f09ff3644126b967..6c6666a1f942682907cae74b6bf4aa382ad955e8 100644 (file)
@@ -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",
index ea232f6a2c21912e408a69ea2d1f8df28e4552dd..fb4cc1edf339cb4ee8541cf528e002a2cfbae7a6 100644 (file)
@@ -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,
 };
index 74ffed41340ff00c5d9ba97dc927059731b80673..9018fa5bf0db8db93737ef946073613f20b279df 100644 (file)
@@ -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);
index b59675257ce55b61b6410f04008f12d6d705e37d..dd4fffdbd17751d496a388dd38606fcd08ec319a 100644 (file)
@@ -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,
 };
 
index fd493ee1428e2a977ac96ba7f7acc3a88d226025..671ef8dd524cb81b7ef8fae3dd6b033bd644e143 100644 (file)
@@ -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>
 #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);
-
index d4bd345b0a8d4ba891222f5752fe6eca56aec7b4..d2d98c75ee8a42b6e840a61307d8a133d54b93a2 100644 (file)
@@ -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:
index 53b780d9b2b09375fdc7bf7f60a81af5045ab406..a4406a13489279280a1635f0dab2563475c7426f 100644 (file)
 
 #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,
index 6a65dd7055199febc9a63393430461d086e2d4e8..39f23734781afe1686c68eb812f654daebd13d13 100644 (file)
@@ -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),
 };
index d211c9fa5a914774534de29f51f40035320bfafb..7e84f24b9a88bf56ef0d000901d6c69d39f7461c 100644 (file)
@@ -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:
index 97e9423615c9c84d859a2b5b5b31695d73f4ab2f..f451acd4935b81db8d04d67da8e99c4e650f4a5d 100644 (file)
@@ -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;
 }
 
index b8207ced40729b0b375f28566b09de404313f28a..5ef0526924b9e3b2f20d56d181d7fc3781468df3 100644 (file)
@@ -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;
 }
 
index af84ee9c5e11edde0c8a253e3a5072e5f3ac0e36..84edd0385a21fb39f3dfa7f429fa69df5c1dcdf1 100644 (file)
@@ -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;
 }
 
index f470f360f4dda9a3193b5f5011a7b9688cfb3b32..0b30d7de24ecc20e4adf3924257fe6a070741953 100644 (file)
@@ -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;
 }
 
index 73d0edd8ded9de053db82b27c60433fe1a7b8686..7b983f935454159d0a3569d6f747285231cbc6ae 100644 (file)
@@ -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;
 }
 
index 8a6b53ccd203e0a8dfe14dd7579325284e736591..d85bf8a0abb2935941b008ab12dfcf5831536e73 100644 (file)
@@ -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
index ffd5cf2fb0a91c3ebbb45d7c58951e3915670a69..468cc11fdf47abf84bc7a6b2dbcc5298bd6f16ce 100644 (file)
@@ -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));
 }
 
index 614a8b30d87bdefdb99414f06d1d74438e60cd18..441285ade024ff33589cd22204ef5cb82a1f14ea 100644 (file)
@@ -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);
index 7d85c6496afa432cbd9791be5f1a9510e7cb78c7..75ed6491222d1d283d69d5881560a823c958d253 100644 (file)
@@ -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;
 }
index 1bc56b2b94e29f9143baa9911f72fa962202d17a..337a00241a1f3a406506c4baad93e0f10a8ac7d8 100644 (file)
@@ -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) {