Merge branch 'cpuinit_phase2' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 18 Jul 2013 17:50:26 +0000 (10:50 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 18 Jul 2013 17:50:26 +0000 (10:50 -0700)
Pull phase two of __cpuinit removal from Paul Gortmaker:
 "With the __cpuinit infrastructure removed earlier, this group of
  commits only removes the function/data tagging that was done with the
  various (now no-op) __cpuinit related prefixes.

  Now that the dust has settled with yesterday's v3.11-rc1, there
  hopefully shouldn't be any new users leaking back in tree, but I think
  we can leave the harmless no-op stubs there for a release as a
  courtesy to those who still have out of tree stuff and weren't paying
  attention.

  Although the commits are against the recent tag to allow for minor
  context refreshes for things like yesterday's v3.11-rc1~ slab content,
  the patches have been largely unchanged for weeks, aside from such
  trivial updates.

  For detail junkies, the largely boring and mostly irrelevant history
  of the patches can be viewed at:

    http://git.kernel.org/cgit/linux/kernel/git/paulg/cpuinit-delete.git

  If nothing else, I guess it does at least demonstrate the level of
  involvement required to shepherd such a treewide change to completion.

  This is the same repository of patches that has been applied to the
  end of the daily linux-next branches for the past several weeks"

* 'cpuinit_phase2' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux: (28 commits)
  block: delete __cpuinit usage from all block files
  drivers: delete __cpuinit usage from all remaining drivers files
  kernel: delete __cpuinit usage from all core kernel files
  rcu: delete __cpuinit usage from all rcu files
  net: delete __cpuinit usage from all net files
  acpi: delete __cpuinit usage from all acpi files
  hwmon: delete __cpuinit usage from all hwmon files
  cpufreq: delete __cpuinit usage from all cpufreq files
  clocksource+irqchip: delete __cpuinit usage from all related files
  x86: delete __cpuinit usage from all x86 files
  score: delete __cpuinit usage from all score files
  xtensa: delete __cpuinit usage from all xtensa files
  openrisc: delete __cpuinit usage from all openrisc files
  m32r: delete __cpuinit usage from all m32r files
  hexagon: delete __cpuinit usage from all hexagon files
  frv: delete __cpuinit usage from all frv files
  cris: delete __cpuinit usage from all cris files
  metag: delete __cpuinit usage from all metag files
  tile: delete __cpuinit usage from all tile files
  sh: delete __cpuinit usage from all sh files
  ...

42 files changed:
arch/blackfin/mach-common/smp.c
drivers/base/regmap/regmap.c
drivers/media/pci/saa7134/saa7134-alsa.c
drivers/spi/spi-altera.c
drivers/spi/spi-nuc900.c
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-xilinx.c
drivers/staging/line6/pcm.c
fs/ext4/balloc.c
fs/ext4/extents_status.c
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/ext4/page-io.c
fs/ext4/super.c
fs/lockd/svclock.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfsd.h
fs/nfsd/nfssvc.c
include/linux/list.h
net/sunrpc/xprtrdma/svc_rdma_marshal.c
sound/arm/pxa2xx-pcm-lib.c
sound/core/seq/oss/seq_oss_init.c
sound/core/seq/oss/seq_oss_midi.c
sound/oss/vwsnd.c
sound/pci/asihpi/asihpi.c
sound/pci/atiixp.c
sound/pci/atiixp_modem.c
sound/pci/hda/patch_hdmi.c
sound/soc/atmel/atmel-pcm-dma.c
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sgtl5000.h
sound/soc/codecs/wm8978.c
sound/soc/codecs/wm8994.c
sound/soc/omap/mcbsp.c
sound/soc/omap/omap-dmic.c
sound/soc/omap/omap-mcpdm.c
sound/soc/omap/omap-pcm.c
sound/soc/s6000/s6000-pcm.c
sound/soc/samsung/i2s.c
sound/usb/6fire/pcm.c
sound/usb/misc/ua101.c
sound/usb/usx2y/usbusx2yaudio.c

index e546db2..82f301c 100644 (file)
@@ -147,7 +147,7 @@ static irqreturn_t ipi_handler_int1(int irq, void *dev_instance)
        platform_clear_ipi(cpu, IRQ_SUPPLE_1);
 
        bfin_ipi_data = &__get_cpu_var(bfin_ipi);
-       while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) {
+       while ((pending = atomic_xchg(&bfin_ipi_data->bits, 0)) != 0) {
                msg = 0;
                do {
                        msg = find_next_bit(&pending, BITS_PER_LONG, msg + 1);
@@ -182,8 +182,8 @@ static void bfin_ipi_init(void)
        struct ipi_data *bfin_ipi_data;
        for_each_possible_cpu(cpu) {
                bfin_ipi_data = &per_cpu(bfin_ipi, cpu);
-               bfin_ipi_data->bits = 0;
-               bfin_ipi_data->count = 0;
+               atomic_set(&bfin_ipi_data->bits, 0);
+               atomic_set(&bfin_ipi_data->count, 0);
        }
 }
 
index 9592058..e0d0c7d 100644 (file)
@@ -1853,7 +1853,7 @@ int regmap_async_complete(struct regmap *map)
        int ret;
 
        /* Nothing to do with no async support */
-       if (!map->bus->async_write)
+       if (!map->bus || !map->bus->async_write)
                return 0;
 
        trace_regmap_async_complete_start(map->dev);
index 10460fd..dbcdfbf 100644 (file)
@@ -172,7 +172,9 @@ static void saa7134_irq_alsa_done(struct saa7134_dev *dev,
                dprintk("irq: overrun [full=%d/%d] - Blocks in %d\n",dev->dmasound.read_count,
                        dev->dmasound.bufsize, dev->dmasound.blocks);
                spin_unlock(&dev->slock);
+               snd_pcm_stream_lock(dev->dmasound.substream);
                snd_pcm_stop(dev->dmasound.substream,SNDRV_PCM_STATE_XRUN);
+               snd_pcm_stream_unlock(dev->dmasound.substream);
                return;
        }
 
index 8a6bb37..81b9adb 100644 (file)
@@ -103,6 +103,16 @@ static void altera_spi_chipsel(struct spi_device *spi, int value)
        }
 }
 
+static int altera_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
+{
+       return 0;
+}
+
+static int altera_spi_setup(struct spi_device *spi)
+{
+       return 0;
+}
+
 static inline unsigned int hw_txbyte(struct altera_spi *hw, int count)
 {
        if (hw->tx) {
@@ -221,6 +231,7 @@ static int altera_spi_probe(struct platform_device *pdev)
        master->bus_num = pdev->id;
        master->num_chipselect = 16;
        master->mode_bits = SPI_CS_HIGH;
+       master->setup = altera_spi_setup;
 
        hw = spi_master_get_devdata(master);
        platform_set_drvdata(pdev, hw);
@@ -229,6 +240,7 @@ static int altera_spi_probe(struct platform_device *pdev)
        hw->bitbang.master = spi_master_get(master);
        if (!hw->bitbang.master)
                return err;
+       hw->bitbang.setup_transfer = altera_spi_setupxfer;
        hw->bitbang.chipselect = altera_spi_chipsel;
        hw->bitbang.txrx_bufs = altera_spi_txrx;
 
index 2ad3d74..150d854 100644 (file)
@@ -174,6 +174,17 @@ static void nuc900_spi_gobusy(struct nuc900_spi *hw)
        spin_unlock_irqrestore(&hw->lock, flags);
 }
 
+static int nuc900_spi_setupxfer(struct spi_device *spi,
+                                struct spi_transfer *t)
+{
+       return 0;
+}
+
+static int nuc900_spi_setup(struct spi_device *spi)
+{
+       return 0;
+}
+
 static inline unsigned int hw_txbyte(struct nuc900_spi *hw, int count)
 {
        return hw->tx ? hw->tx[count] : 0;
@@ -366,8 +377,10 @@ static int nuc900_spi_probe(struct platform_device *pdev)
        master->num_chipselect     = hw->pdata->num_cs;
        master->bus_num            = hw->pdata->bus_num;
        hw->bitbang.master         = hw->master;
+       hw->bitbang.setup_transfer = nuc900_spi_setupxfer;
        hw->bitbang.chipselect     = nuc900_spi_chipsel;
        hw->bitbang.txrx_bufs      = nuc900_spi_txrx;
+       hw->bitbang.master->setup  = nuc900_spi_setup;
 
        hw->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (hw->res == NULL) {
index eb53df2..63e2070 100644 (file)
@@ -434,6 +434,9 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
        dma_cap_mask_t mask;
        int ret;
 
+       if (is_polling(sdd))
+               return 0;
+
        dma_cap_zero(mask);
        dma_cap_set(DMA_SLAVE, mask);
 
index fb56fcf..09a9428 100644 (file)
@@ -233,6 +233,21 @@ static int xilinx_spi_setup_transfer(struct spi_device *spi,
        return 0;
 }
 
+static int xilinx_spi_setup(struct spi_device *spi)
+{
+       /* always return 0, we can not check the number of bits.
+        * There are cases when SPI setup is called before any driver is
+        * there, in that case the SPI core defaults to 8 bits, which we
+        * do not support in some cases. But if we return an error, the
+        * SPI device would not be registered and no driver can get hold of it
+        * When the driver is there, it will call SPI setup again with the
+        * correct number of bits per transfer.
+        * If a driver setups with the wrong bit number, it will fail when
+        * it tries to do a transfer
+        */
+       return 0;
+}
+
 static void xilinx_spi_fill_tx_fifo(struct xilinx_spi *xspi)
 {
        u8 sr;
@@ -360,6 +375,7 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
        xspi->bitbang.chipselect = xilinx_spi_chipselect;
        xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer;
        xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
+       xspi->bitbang.master->setup = xilinx_spi_setup;
        init_completion(&xspi->done);
 
        if (!request_mem_region(mem->start, resource_size(mem),
index 4795f12..0dd08ef 100644 (file)
@@ -392,8 +392,11 @@ static int snd_line6_pcm_free(struct snd_device *device)
 */
 static void pcm_disconnect_substream(struct snd_pcm_substream *substream)
 {
-       if (substream->runtime && snd_pcm_running(substream))
+       if (substream->runtime && snd_pcm_running(substream)) {
+               snd_pcm_stream_lock_irq(substream);
                snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+               snd_pcm_stream_unlock_irq(substream);
+       }
 }
 
 /*
index 5833939..ddd715e 100644 (file)
@@ -38,8 +38,8 @@ ext4_group_t ext4_get_group_number(struct super_block *sb,
        ext4_group_t group;
 
        if (test_opt2(sb, STD_GROUP_SIZE))
-               group = (le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block) +
-                        block) >>
+               group = (block -
+                        le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) >>
                        (EXT4_BLOCK_SIZE_BITS(sb) + EXT4_CLUSTER_BITS(sb) + 3);
        else
                ext4_get_group_no_and_offset(sb, block, &group, NULL);
index ee018d5..4b8df7f 100644 (file)
@@ -439,7 +439,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
                 */
                if (!ext4_es_is_written(es) && !ext4_es_is_unwritten(es)) {
                        if (in_range(es->es_lblk, ee_block, ee_len)) {
-                               pr_warn("ES insert assertation failed for "
+                               pr_warn("ES insert assertion failed for "
                                        "inode: %lu we can find an extent "
                                        "at block [%d/%d/%llu/%c], but we "
                                        "want to add an delayed/hole extent "
@@ -458,7 +458,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
                 */
                if (es->es_lblk < ee_block ||
                    ext4_es_pblock(es) != ee_start + es->es_lblk - ee_block) {
-                       pr_warn("ES insert assertation failed for inode: %lu "
+                       pr_warn("ES insert assertion failed for inode: %lu "
                                "ex_status [%d/%d/%llu/%c] != "
                                "es_status [%d/%d/%llu/%c]\n", inode->i_ino,
                                ee_block, ee_len, ee_start,
@@ -468,7 +468,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
                }
 
                if (ee_status ^ es_status) {
-                       pr_warn("ES insert assertation failed for inode: %lu "
+                       pr_warn("ES insert assertion failed for inode: %lu "
                                "ex_status [%d/%d/%llu/%c] != "
                                "es_status [%d/%d/%llu/%c]\n", inode->i_ino,
                                ee_block, ee_len, ee_start,
@@ -481,7 +481,7 @@ static void ext4_es_insert_extent_ext_check(struct inode *inode,
                 * that we don't want to add an written/unwritten extent.
                 */
                if (!ext4_es_is_delayed(es) && !ext4_es_is_hole(es)) {
-                       pr_warn("ES insert assertation failed for inode: %lu "
+                       pr_warn("ES insert assertion failed for inode: %lu "
                                "can't find an extent at block %d but we want "
                                "to add an written/unwritten extent "
                                "[%d/%d/%llu/%llx]\n", inode->i_ino,
@@ -519,7 +519,7 @@ static void ext4_es_insert_extent_ind_check(struct inode *inode,
                         * We want to add a delayed/hole extent but this
                         * block has been allocated.
                         */
-                       pr_warn("ES insert assertation failed for inode: %lu "
+                       pr_warn("ES insert assertion failed for inode: %lu "
                                "We can find blocks but we want to add a "
                                "delayed/hole extent [%d/%d/%llu/%llx]\n",
                                inode->i_ino, es->es_lblk, es->es_len,
@@ -527,13 +527,13 @@ static void ext4_es_insert_extent_ind_check(struct inode *inode,
                        return;
                } else if (ext4_es_is_written(es)) {
                        if (retval != es->es_len) {
-                               pr_warn("ES insert assertation failed for "
+                               pr_warn("ES insert assertion failed for "
                                        "inode: %lu retval %d != es_len %d\n",
                                        inode->i_ino, retval, es->es_len);
                                return;
                        }
                        if (map.m_pblk != ext4_es_pblock(es)) {
-                               pr_warn("ES insert assertation failed for "
+                               pr_warn("ES insert assertion failed for "
                                        "inode: %lu m_pblk %llu != "
                                        "es_pblk %llu\n",
                                        inode->i_ino, map.m_pblk,
@@ -549,7 +549,7 @@ static void ext4_es_insert_extent_ind_check(struct inode *inode,
                }
        } else if (retval == 0) {
                if (ext4_es_is_written(es)) {
-                       pr_warn("ES insert assertation failed for inode: %lu "
+                       pr_warn("ES insert assertion failed for inode: %lu "
                                "We can't find the block but we want to add "
                                "an written extent [%d/%d/%llu/%llx]\n",
                                inode->i_ino, es->es_lblk, es->es_len,
@@ -632,10 +632,8 @@ out:
 }
 
 /*
- * ext4_es_insert_extent() adds a space to a extent status tree.
- *
- * ext4_es_insert_extent is called by ext4_da_write_begin and
- * ext4_es_remove_extent.
+ * ext4_es_insert_extent() adds information to an inode's extent
+ * status tree.
  *
  * Return 0 on success, error code on failure.
  */
index 0188e65..98b9bff 100644 (file)
@@ -465,7 +465,7 @@ static void ext4_map_blocks_es_recheck(handle_t *handle,
        if (es_map->m_lblk != map->m_lblk ||
            es_map->m_flags != map->m_flags ||
            es_map->m_pblk != map->m_pblk) {
-               printk("ES cache assertation failed for inode: %lu "
+               printk("ES cache assertion failed for inode: %lu "
                       "es_cached ex [%d/%d/%llu/%x] != "
                       "found ex [%d/%d/%llu/%x] retval %d flags %x\n",
                       inode->i_ino, es_map->m_lblk, es_map->m_len,
@@ -558,7 +558,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
 
 #ifdef ES_AGGRESSIVE_TEST
                if (retval != map->m_len) {
-                       printk("ES len assertation failed for inode: %lu "
+                       printk("ES len assertion failed for inode: %lu "
                               "retval %d != map->m_len %d "
                               "in %s (lookup)\n", inode->i_ino, retval,
                               map->m_len, __func__);
@@ -659,7 +659,7 @@ found:
 
 #ifdef ES_AGGRESSIVE_TEST
                if (retval != map->m_len) {
-                       printk("ES len assertation failed for inode: %lu "
+                       printk("ES len assertion failed for inode: %lu "
                               "retval %d != map->m_len %d "
                               "in %s (allocation)\n", inode->i_ino, retval,
                               map->m_len, __func__);
@@ -1642,7 +1642,7 @@ add_delayed:
 
 #ifdef ES_AGGRESSIVE_TEST
                if (retval != map->m_len) {
-                       printk("ES len assertation failed for inode: %lu "
+                       printk("ES len assertion failed for inode: %lu "
                               "retval %d != map->m_len %d "
                               "in %s (lookup)\n", inode->i_ino, retval,
                               map->m_len, __func__);
@@ -2163,7 +2163,7 @@ static int mpage_map_and_submit_extent(handle_t *handle,
 
        mpd->io_submit.io_end->offset =
                                ((loff_t)map->m_lblk) << inode->i_blkbits;
-       while (map->m_len) {
+       do {
                err = mpage_map_one_extent(handle, mpd);
                if (err < 0) {
                        struct super_block *sb = inode->i_sb;
@@ -2201,7 +2201,7 @@ static int mpage_map_and_submit_extent(handle_t *handle,
                err = mpage_map_and_submit_buffers(mpd);
                if (err < 0)
                        return err;
-       }
+       } while (map->m_len);
 
        /* Update on-disk size after IO is submitted */
        disksize = ((loff_t)mpd->first_page) << PAGE_CACHE_SHIFT;
index a9ff5e5..4bbbf13 100644 (file)
@@ -4740,11 +4740,16 @@ do_more:
                 * blocks being freed are metadata. these blocks shouldn't
                 * be used until this transaction is committed
                 */
+       retry:
                new_entry = kmem_cache_alloc(ext4_free_data_cachep, GFP_NOFS);
                if (!new_entry) {
-                       ext4_mb_unload_buddy(&e4b);
-                       err = -ENOMEM;
-                       goto error_return;
+                       /*
+                        * We use a retry loop because
+                        * ext4_free_blocks() is not allowed to fail.
+                        */
+                       cond_resched();
+                       congestion_wait(BLK_RW_ASYNC, HZ/50);
+                       goto retry;
                }
                new_entry->efd_start_cluster = bit;
                new_entry->efd_group = block_group;
index 48786cd..6625d21 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
+#include <linux/ratelimit.h>
 
 #include "ext4_jbd2.h"
 #include "xattr.h"
@@ -55,7 +56,7 @@ void ext4_exit_pageio(void)
 static void buffer_io_error(struct buffer_head *bh)
 {
        char b[BDEVNAME_SIZE];
-       printk(KERN_ERR "Buffer I/O error on device %s, logical block %llu\n",
+       printk_ratelimited(KERN_ERR "Buffer I/O error on device %s, logical block %llu\n",
                        bdevname(bh->b_bdev, b),
                        (unsigned long long)bh->b_blocknr);
 }
@@ -308,6 +309,7 @@ ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end)
        return io_end;
 }
 
+/* BIO completion function for page writeback */
 static void ext4_end_bio(struct bio *bio, int error)
 {
        ext4_io_end_t *io_end = bio->bi_private;
@@ -318,18 +320,6 @@ static void ext4_end_bio(struct bio *bio, int error)
        if (test_bit(BIO_UPTODATE, &bio->bi_flags))
                error = 0;
 
-       if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
-               /*
-                * Link bio into list hanging from io_end. We have to do it
-                * atomically as bio completions can be racing against each
-                * other.
-                */
-               bio->bi_private = xchg(&io_end->bio, bio);
-       } else {
-               ext4_finish_bio(bio);
-               bio_put(bio);
-       }
-
        if (error) {
                struct inode *inode = io_end->inode;
 
@@ -341,7 +331,24 @@ static void ext4_end_bio(struct bio *bio, int error)
                             (unsigned long long)
                             bi_sector >> (inode->i_blkbits - 9));
        }
-       ext4_put_io_end_defer(io_end);
+
+       if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
+               /*
+                * Link bio into list hanging from io_end. We have to do it
+                * atomically as bio completions can be racing against each
+                * other.
+                */
+               bio->bi_private = xchg(&io_end->bio, bio);
+               ext4_put_io_end_defer(io_end);
+       } else {
+               /*
+                * Drop io_end reference early. Inode can get freed once
+                * we finish the bio.
+                */
+               ext4_put_io_end_defer(io_end);
+               ext4_finish_bio(bio);
+               bio_put(bio);
+       }
 }
 
 void ext4_io_submit(struct ext4_io_submit *io)
index 85b3dd6..bca26f3 100644 (file)
@@ -1702,12 +1702,6 @@ static inline void ext4_show_quota_options(struct seq_file *seq,
 
        if (sbi->s_qf_names[GRPQUOTA])
                seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]);
-
-       if (test_opt(sb, USRQUOTA))
-               seq_puts(seq, ",usrquota");
-
-       if (test_opt(sb, GRPQUOTA))
-               seq_puts(seq, ",grpquota");
 #endif
 }
 
@@ -3624,10 +3618,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
        sbi->s_addr_per_block_bits = ilog2(EXT4_ADDR_PER_BLOCK(sb));
        sbi->s_desc_per_block_bits = ilog2(EXT4_DESC_PER_BLOCK(sb));
 
-       /* Do we have standard group size of blocksize * 8 blocks ? */
-       if (sbi->s_blocks_per_group == blocksize << 3)
-               set_opt2(sb, STD_GROUP_SIZE);
-
        for (i = 0; i < 4; i++)
                sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]);
        sbi->s_def_hash_version = es->s_def_hash_version;
@@ -3697,6 +3687,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
                goto failed_mount;
        }
 
+       /* Do we have standard group size of clustersize * 8 blocks ? */
+       if (sbi->s_blocks_per_group == clustersize << 3)
+               set_opt2(sb, STD_GROUP_SIZE);
+
        /*
         * Test whether we have more sectors than will fit in sector_t,
         * and whether the max offset is addressable by the page cache.
index 067778b..e066a39 100644 (file)
@@ -951,6 +951,7 @@ nlmsvc_retry_blocked(void)
        unsigned long   timeout = MAX_SCHEDULE_TIMEOUT;
        struct nlm_block *block;
 
+       spin_lock(&nlm_blocked_lock);
        while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
                block = list_entry(nlm_blocked.next, struct nlm_block, b_list);
 
@@ -960,6 +961,7 @@ nlmsvc_retry_blocked(void)
                        timeout = block->b_when - jiffies;
                        break;
                }
+               spin_unlock(&nlm_blocked_lock);
 
                dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
                        block, block->b_when);
@@ -969,7 +971,9 @@ nlmsvc_retry_blocked(void)
                        retry_deferred_block(block);
                } else
                        nlmsvc_grant_blocked(block);
+               spin_lock(&nlm_blocked_lock);
        }
+       spin_unlock(&nlm_blocked_lock);
 
        return timeout;
 }
index a7cee86..0d4c410 100644 (file)
@@ -1293,7 +1293,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
         * According to RFC3010, this takes precedence over all other errors.
         */
        status = nfserr_minor_vers_mismatch;
-       if (args->minorversion > nfsd_supported_minorversion)
+       if (nfsd_minorversion(args->minorversion, NFSD_TEST) <= 0)
                goto out;
 
        status = nfs41_check_op_ordering(args);
index 2bbd94e..30f34ab 100644 (file)
@@ -53,7 +53,6 @@ struct readdir_cd {
 extern struct svc_program      nfsd_program;
 extern struct svc_version      nfsd_version2, nfsd_version3,
                                nfsd_version4;
-extern u32                     nfsd_supported_minorversion;
 extern struct mutex            nfsd_mutex;
 extern spinlock_t              nfsd_drc_lock;
 extern unsigned long           nfsd_drc_max_mem;
index 6b9f48c..760c85a 100644 (file)
@@ -116,7 +116,10 @@ struct svc_program         nfsd_program = {
 
 };
 
-u32 nfsd_supported_minorversion = 1;
+static bool nfsd_supported_minorversions[NFSD_SUPPORTED_MINOR_VERSION + 1] = {
+       [0] = 1,
+       [1] = 1,
+};
 
 int nfsd_vers(int vers, enum vers_op change)
 {
@@ -151,15 +154,13 @@ int nfsd_minorversion(u32 minorversion, enum vers_op change)
                return -1;
        switch(change) {
        case NFSD_SET:
-               nfsd_supported_minorversion = minorversion;
+               nfsd_supported_minorversions[minorversion] = true;
                break;
        case NFSD_CLEAR:
-               if (minorversion == 0)
-                       return -1;
-               nfsd_supported_minorversion = minorversion - 1;
+               nfsd_supported_minorversions[minorversion] = false;
                break;
        case NFSD_TEST:
-               return minorversion <= nfsd_supported_minorversion;
+               return nfsd_supported_minorversions[minorversion];
        case NFSD_AVAIL:
                return minorversion <= NFSD_SUPPORTED_MINOR_VERSION;
        }
index b83e565..f4d8a2f 100644 (file)
@@ -380,17 +380,6 @@ static inline void list_splice_tail_init(struct list_head *list,
 #define list_for_each(pos, head) \
        for (pos = (head)->next; pos != (head); pos = pos->next)
 
-/**
- * __list_for_each     -       iterate over a list
- * @pos:       the &struct list_head to use as a loop cursor.
- * @head:      the head for your list.
- *
- * This variant doesn't differ from list_for_each() any more.
- * We don't do prefetching in either case.
- */
-#define __list_for_each(pos, head) \
-       for (pos = (head)->next; pos != (head); pos = pos->next)
-
 /**
  * list_for_each_prev  -       iterate over a list backwards
  * @pos:       the &struct list_head to use as a loop cursor.
index 8d2eddd..65b1462 100644 (file)
@@ -98,6 +98,7 @@ void svc_rdma_rcl_chunk_counts(struct rpcrdma_read_chunk *ch,
  */
 static u32 *decode_write_list(u32 *va, u32 *vaend)
 {
+       unsigned long start, end;
        int nchunks;
 
        struct rpcrdma_write_array *ary =
@@ -113,9 +114,12 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
                return NULL;
        }
        nchunks = ntohl(ary->wc_nchunks);
-       if (((unsigned long)&ary->wc_array[0] +
-            (sizeof(struct rpcrdma_write_chunk) * nchunks)) >
-           (unsigned long)vaend) {
+
+       start = (unsigned long)&ary->wc_array[0];
+       end = (unsigned long)vaend;
+       if (nchunks < 0 ||
+           nchunks > (SIZE_MAX - start) / sizeof(struct rpcrdma_write_chunk) ||
+           (start + (sizeof(struct rpcrdma_write_chunk) * nchunks)) > end) {
                dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
                        ary, nchunks, vaend);
                return NULL;
@@ -129,6 +133,7 @@ static u32 *decode_write_list(u32 *va, u32 *vaend)
 
 static u32 *decode_reply_array(u32 *va, u32 *vaend)
 {
+       unsigned long start, end;
        int nchunks;
        struct rpcrdma_write_array *ary =
                (struct rpcrdma_write_array *)va;
@@ -143,9 +148,12 @@ static u32 *decode_reply_array(u32 *va, u32 *vaend)
                return NULL;
        }
        nchunks = ntohl(ary->wc_nchunks);
-       if (((unsigned long)&ary->wc_array[0] +
-            (sizeof(struct rpcrdma_write_chunk) * nchunks)) >
-           (unsigned long)vaend) {
+
+       start = (unsigned long)&ary->wc_array[0];
+       end = (unsigned long)vaend;
+       if (nchunks < 0 ||
+           nchunks > (SIZE_MAX - start) / sizeof(struct rpcrdma_write_chunk) ||
+           (start + (sizeof(struct rpcrdma_write_chunk) * nchunks)) > end) {
                dprintk("svcrdma: ary=%p, wc_nchunks=%d, vaend=%p\n",
                        ary, nchunks, vaend);
                return NULL;
index 76e0d56..823359e 100644 (file)
@@ -166,7 +166,9 @@ void pxa2xx_pcm_dma_irq(int dma_ch, void *dev_id)
        } else {
                printk(KERN_ERR "%s: DMA error on channel %d (DCSR=%#x)\n",
                        rtd->params->name, dma_ch, dcsr);
+               snd_pcm_stream_lock(substream);
                snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
+               snd_pcm_stream_unlock(substream);
        }
 }
 EXPORT_SYMBOL(pxa2xx_pcm_dma_irq);
index e3cb46f..b3f39b5 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/export.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
+#include <linux/workqueue.h>
 
 /*
  * common variables
@@ -60,6 +61,14 @@ static void free_devinfo(void *private);
 #define call_ctl(type,rec) snd_seq_kernel_client_ctl(system_client, type, rec)
 
 
+/* call snd_seq_oss_midi_lookup_ports() asynchronously */
+static void async_call_lookup_ports(struct work_struct *work)
+{
+       snd_seq_oss_midi_lookup_ports(system_client);
+}
+
+static DECLARE_WORK(async_lookup_work, async_call_lookup_ports);
+
 /*
  * create sequencer client for OSS sequencer
  */
@@ -85,9 +94,6 @@ snd_seq_oss_create_client(void)
        system_client = rc;
        debug_printk(("new client = %d\n", rc));
 
-       /* look up midi devices */
-       snd_seq_oss_midi_lookup_ports(system_client);
-
        /* create annoucement receiver port */
        memset(port, 0, sizeof(*port));
        strcpy(port->name, "Receiver");
@@ -115,6 +121,9 @@ snd_seq_oss_create_client(void)
        }
        rc = 0;
 
+       /* look up midi devices */
+       schedule_work(&async_lookup_work);
+
  __error:
        kfree(port);
        return rc;
@@ -160,6 +169,7 @@ receive_announce(struct snd_seq_event *ev, int direct, void *private, int atomic
 int
 snd_seq_oss_delete_client(void)
 {
+       cancel_work_sync(&async_lookup_work);
        if (system_client >= 0)
                snd_seq_delete_kernel_client(system_client);
 
index 677dc84..862d848 100644 (file)
@@ -72,7 +72,7 @@ static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev,
  * look up the existing ports
  * this looks a very exhausting job.
  */
-int __init
+int
 snd_seq_oss_midi_lookup_ports(int client)
 {
        struct snd_seq_client_info *clinfo;
index 7e814a5..4bbcc0f 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 
 #include <asm/visws/cobalt.h>
 
 #include "sound_config.h"
 
+static DEFINE_MUTEX(vwsnd_mutex);
+
 /*****************************************************************************/
 /* debug stuff */
 
 #ifdef VWSND_DEBUG
 
-static DEFINE_MUTEX(vwsnd_mutex);
 static int shut_up = 1;
 
 /*
index 185d54a..dc632cd 100644 (file)
@@ -769,7 +769,10 @@ static void snd_card_asihpi_timer_function(unsigned long data)
                                                s->number);
                                ds->drained_count++;
                                if (ds->drained_count > 20) {
+                                       unsigned long flags;
+                                       snd_pcm_stream_lock_irqsave(s, flags);
                                        snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN);
+                                       snd_pcm_stream_unlock_irqrestore(s, flags);
                                        continue;
                                }
                        } else {
index fe4c61b..f6dec3e 100644 (file)
@@ -689,7 +689,9 @@ static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma)
        if (! dma->substream || ! dma->running)
                return;
        snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type);
+       snd_pcm_stream_lock(dma->substream);
        snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN);
+       snd_pcm_stream_unlock(dma->substream);
 }
 
 /*
index cf29b9a..289563e 100644 (file)
@@ -638,7 +638,9 @@ static void snd_atiixp_xrun_dma(struct atiixp_modem *chip,
        if (! dma->substream || ! dma->running)
                return;
        snd_printdd("atiixp-modem: XRUN detected (DMA %d)\n", dma->ops->type);
+       snd_pcm_stream_lock(dma->substream);
        snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN);
+       snd_pcm_stream_unlock(dma->substream);
 }
 
 /*
index 540bdef..030ca86 100644 (file)
@@ -2622,6 +2622,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
 { .id = 0x10de0043, .name = "GPU 43 HDMI/DP",  .patch = patch_generic_hdmi },
 { .id = 0x10de0044, .name = "GPU 44 HDMI/DP",  .patch = patch_generic_hdmi },
 { .id = 0x10de0051, .name = "GPU 51 HDMI/DP",  .patch = patch_generic_hdmi },
+{ .id = 0x10de0060, .name = "GPU 60 HDMI/DP",  .patch = patch_generic_hdmi },
 { .id = 0x10de0067, .name = "MCP67 HDMI",      .patch = patch_nvhdmi_2ch },
 { .id = 0x10de8001, .name = "MCP73 HDMI",      .patch = patch_nvhdmi_2ch },
 { .id = 0x11069f80, .name = "VX900 HDMI/DP",   .patch = patch_via_hdmi },
@@ -2674,6 +2675,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0042");
 MODULE_ALIAS("snd-hda-codec-id:10de0043");
 MODULE_ALIAS("snd-hda-codec-id:10de0044");
 MODULE_ALIAS("snd-hda-codec-id:10de0051");
+MODULE_ALIAS("snd-hda-codec-id:10de0060");
 MODULE_ALIAS("snd-hda-codec-id:10de0067");
 MODULE_ALIAS("snd-hda-codec-id:10de8001");
 MODULE_ALIAS("snd-hda-codec-id:11069f80");
index 1d38fd0..d128265 100644 (file)
@@ -81,7 +81,9 @@ static void atmel_pcm_dma_irq(u32 ssc_sr,
 
                /* stop RX and capture: will be enabled again at restart */
                ssc_writex(prtd->ssc->regs, SSC_CR, prtd->mask->ssc_disable);
+               snd_pcm_stream_lock(substream);
                snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
+               snd_pcm_stream_unlock(substream);
 
                /* now drain RHR and read status to remove xrun condition */
                ssc_readx(prtd->ssc->regs, SSC_RHR);
index d441559..d659d3a 100644 (file)
@@ -38,7 +38,7 @@
 static const struct reg_default sgtl5000_reg_defaults[] = {
        { SGTL5000_CHIP_CLK_CTRL,               0x0008 },
        { SGTL5000_CHIP_I2S_CTRL,               0x0010 },
-       { SGTL5000_CHIP_SSS_CTRL,               0x0008 },
+       { SGTL5000_CHIP_SSS_CTRL,               0x0010 },
        { SGTL5000_CHIP_DAC_VOL,                0x3c3c },
        { SGTL5000_CHIP_PAD_STRENGTH,           0x015f },
        { SGTL5000_CHIP_ANA_HP_CTRL,            0x1818 },
index 4b69229..2f8c889 100644 (file)
 #define SGTL5000_PLL_INT_DIV_MASK              0xf800
 #define SGTL5000_PLL_INT_DIV_SHIFT             11
 #define SGTL5000_PLL_INT_DIV_WIDTH             5
-#define SGTL5000_PLL_FRAC_DIV_MASK             0x0700
+#define SGTL5000_PLL_FRAC_DIV_MASK             0x07ff
 #define SGTL5000_PLL_FRAC_DIV_SHIFT            0
 #define SGTL5000_PLL_FRAC_DIV_WIDTH            11
 
index 029f31c..d8fc531 100644 (file)
@@ -921,6 +921,7 @@ static struct snd_soc_dai_driver wm8978_dai = {
                .formats = WM8978_FORMATS,
        },
        .ops = &wm8978_dai_ops,
+       .symmetric_rates = 1,
 };
 
 static int wm8978_suspend(struct snd_soc_codec *codec)
index 1d4b1ec..ba832b7 100644 (file)
@@ -3852,8 +3852,6 @@ static void wm8958_mic_work(struct work_struct *work)
                                                  mic_complete_work.work);
        struct snd_soc_codec *codec = wm8994->hubs.codec;
 
-       dev_crit(codec->dev, "MIC WORK %x\n", wm8994->mic_status);
-
        pm_runtime_get_sync(codec->dev);
 
        mutex_lock(&wm8994->accdet_lock);
@@ -3863,8 +3861,6 @@ static void wm8958_mic_work(struct work_struct *work)
        mutex_unlock(&wm8994->accdet_lock);
 
        pm_runtime_put(codec->dev);
-
-       dev_crit(codec->dev, "MIC WORK %x DONE\n", wm8994->mic_status);
 }
 
 static irqreturn_t wm8958_mic_irq(int irq, void *data)
index eb68c7d..361e4c0 100644 (file)
@@ -1012,28 +1012,33 @@ int omap_mcbsp_init(struct platform_device *pdev)
                }
        }
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
-       if (!res) {
-               dev_err(&pdev->dev, "invalid rx DMA channel\n");
-               return -ENODEV;
-       }
-       /* RX DMA request number, and port address configuration */
-       mcbsp->dma_req[1] = res->start;
-       mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1];
-       mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1);
-       mcbsp->dma_data[1].maxburst = 4;
+       if (!pdev->dev.of_node) {
+               res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
+               if (!res) {
+                       dev_err(&pdev->dev, "invalid tx DMA channel\n");
+                       return -ENODEV;
+               }
+               mcbsp->dma_req[0] = res->start;
+               mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0];
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
-       if (!res) {
-               dev_err(&pdev->dev, "invalid tx DMA channel\n");
-               return -ENODEV;
+               res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
+               if (!res) {
+                       dev_err(&pdev->dev, "invalid rx DMA channel\n");
+                       return -ENODEV;
+               }
+               mcbsp->dma_req[1] = res->start;
+               mcbsp->dma_data[1].filter_data = &mcbsp->dma_req[1];
+       } else {
+               mcbsp->dma_data[0].filter_data = "tx";
+               mcbsp->dma_data[1].filter_data = "rx";
        }
-       /* TX DMA request number, and port address configuration */
-       mcbsp->dma_req[0] = res->start;
-       mcbsp->dma_data[0].filter_data = &mcbsp->dma_req[0];
+
        mcbsp->dma_data[0].addr = omap_mcbsp_dma_reg_params(mcbsp, 0);
        mcbsp->dma_data[0].maxburst = 4;
 
+       mcbsp->dma_data[1].addr = omap_mcbsp_dma_reg_params(mcbsp, 1);
+       mcbsp->dma_data[1].maxburst = 4;
+
        mcbsp->fclk = clk_get(&pdev->dev, "fck");
        if (IS_ERR(mcbsp->fclk)) {
                ret = PTR_ERR(mcbsp->fclk);
index 2ad0370..4db1f8e 100644 (file)
@@ -57,7 +57,6 @@ struct omap_dmic {
        struct mutex mutex;
 
        struct snd_dmaengine_dai_dma_data dma_data;
-       unsigned int dma_req;
 };
 
 static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
@@ -478,15 +477,7 @@ static int asoc_dmic_probe(struct platform_device *pdev)
        }
        dmic->dma_data.addr = res->start + OMAP_DMIC_DATA_REG;
 
-       res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-       if (!res) {
-               dev_err(dmic->dev, "invalid dma resource\n");
-               ret = -ENODEV;
-               goto err_put_clk;
-       }
-
-       dmic->dma_req = res->start;
-       dmic->dma_data.filter_data = &dmic->dma_req;
+       dmic->dma_data.filter_data = "up_link";
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
        if (!res) {
index eb05c7e..a49dc52 100644 (file)
@@ -66,7 +66,6 @@ struct omap_mcpdm {
        bool restart;
 
        struct snd_dmaengine_dai_dma_data dma_data[2];
-       unsigned int dma_req[2];
 };
 
 /*
@@ -477,19 +476,8 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
        mcpdm->dma_data[0].addr = res->start + MCPDM_REG_DN_DATA;
        mcpdm->dma_data[1].addr = res->start + MCPDM_REG_UP_DATA;
 
-       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link");
-       if (!res)
-               return -ENODEV;
-
-       mcpdm->dma_req[0] = res->start;
-       mcpdm->dma_data[0].filter_data = &mcpdm->dma_req[0];
-
-       res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link");
-       if (!res)
-               return -ENODEV;
-
-       mcpdm->dma_req[1] = res->start;
-       mcpdm->dma_data[1].filter_data = &mcpdm->dma_req[1];
+       mcpdm->dma_data[0].filter_data = "dn_link";
+       mcpdm->dma_data[1].filter_data = "up_link";
 
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
        if (res == NULL)
index c28e042..a11405d 100644 (file)
@@ -113,14 +113,25 @@ static int omap_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_dmaengine_dai_dma_data *dma_data;
+       int ret;
 
        snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
 
        dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
-       return snd_dmaengine_pcm_open_request_chan(substream,
-                                                  omap_dma_filter_fn,
-                                                  dma_data->filter_data);
+       /* DT boot: filter_data is the DMA name */
+       if (rtd->cpu_dai->dev->of_node) {
+               struct dma_chan *chan;
+
+               chan = dma_request_slave_channel(rtd->cpu_dai->dev,
+                                                dma_data->filter_data);
+               ret = snd_dmaengine_pcm_open(substream, chan);
+       } else {
+               ret = snd_dmaengine_pcm_open_request_chan(substream,
+                                                         omap_dma_filter_fn,
+                                                         dma_data->filter_data);
+       }
+       return ret;
 }
 
 static int omap_pcm_mmap(struct snd_pcm_substream *substream,
index 1358c7d..d0740a7 100644 (file)
@@ -128,7 +128,9 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
                    substream->runtime &&
                    snd_pcm_running(substream)) {
                        dev_dbg(pcm->dev, "xrun\n");
+                       snd_pcm_stream_lock(substream);
                        snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
+                       snd_pcm_stream_unlock(substream);
                        ret = IRQ_HANDLED;
                }
 
index 7a17346..959c702 100644 (file)
@@ -742,13 +742,13 @@ static int config_setup(struct i2s_dai *i2s)
                return -EAGAIN;
        }
 
-       /* Don't bother RFS, BFS & PSR in Slave mode */
-       if (is_slave(i2s))
-               return 0;
-
        set_bfs(i2s, bfs);
        set_rfs(i2s, rfs);
 
+       /* Don't bother with PSR in Slave mode */
+       if (is_slave(i2s))
+               return 0;
+
        if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
                psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
                writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
index c5b9cac..2aa4e13 100644 (file)
@@ -639,17 +639,25 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
 void usb6fire_pcm_abort(struct sfire_chip *chip)
 {
        struct pcm_runtime *rt = chip->pcm;
+       unsigned long flags;
        int i;
 
        if (rt) {
                rt->panic = true;
 
-               if (rt->playback.instance)
+               if (rt->playback.instance) {
+                       snd_pcm_stream_lock_irqsave(rt->playback.instance, flags);
                        snd_pcm_stop(rt->playback.instance,
                                        SNDRV_PCM_STATE_XRUN);
-               if (rt->capture.instance)
+                       snd_pcm_stream_unlock_irqrestore(rt->playback.instance, flags);
+               }
+
+               if (rt->capture.instance) {
+                       snd_pcm_stream_lock_irqsave(rt->capture.instance, flags);
                        snd_pcm_stop(rt->capture.instance,
                                        SNDRV_PCM_STATE_XRUN);
+                       snd_pcm_stream_unlock_irqrestore(rt->capture.instance, flags);
+               }
 
                for (i = 0; i < PCM_N_URBS; i++) {
                        usb_poison_urb(&rt->in_urbs[i].instance);
index 8b5d2c5..5093159 100644 (file)
@@ -613,14 +613,24 @@ static int start_usb_playback(struct ua101 *ua)
 
 static void abort_alsa_capture(struct ua101 *ua)
 {
-       if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states))
+       unsigned long flags;
+
+       if (test_bit(ALSA_CAPTURE_RUNNING, &ua->states)) {
+               snd_pcm_stream_lock_irqsave(ua->capture.substream, flags);
                snd_pcm_stop(ua->capture.substream, SNDRV_PCM_STATE_XRUN);
+               snd_pcm_stream_unlock_irqrestore(ua->capture.substream, flags);
+       }
 }
 
 static void abort_alsa_playback(struct ua101 *ua)
 {
-       if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
+       unsigned long flags;
+
+       if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) {
+               snd_pcm_stream_lock_irqsave(ua->playback.substream, flags);
                snd_pcm_stop(ua->playback.substream, SNDRV_PCM_STATE_XRUN);
+               snd_pcm_stream_unlock_irqrestore(ua->playback.substream, flags);
+       }
 }
 
 static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
index 4967fe9..63fb521 100644 (file)
@@ -273,7 +273,11 @@ static void usX2Y_clients_stop(struct usX2Ydev *usX2Y)
                struct snd_usX2Y_substream *subs = usX2Y->subs[s];
                if (subs) {
                        if (atomic_read(&subs->state) >= state_PRERUNNING) {
+                               unsigned long flags;
+
+                               snd_pcm_stream_lock_irqsave(subs->pcm_substream, flags);
                                snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN);
+                               snd_pcm_stream_unlock_irqrestore(subs->pcm_substream, flags);
                        }
                        for (u = 0; u < NRURBS; u++) {
                                struct urb *urb = subs->urb[u];