Merge branch 'android-tegra-2.6.36' into android-tegra-moto-2.6.36
authorColin Cross <ccross@android.com>
Fri, 15 Oct 2010 00:19:09 +0000 (17:19 -0700)
committerColin Cross <ccross@android.com>
Fri, 15 Oct 2010 00:19:09 +0000 (17:19 -0700)
Conflicts:
arch/arm/mach-tegra/tegra_i2s_audio.c

Change-Id: I9e2892c49d97c63de3a8e5797d6d9a123ae2d161

arch/arm/mach-tegra/dma.c
arch/arm/mach-tegra/include/mach/i2s.h
arch/arm/mach-tegra/tegra_i2s_audio.c
drivers/mmc/core/core.c
drivers/serial/tegra_hsuart.c
drivers/spi/spi_tegra.c
drivers/usb/gadget/fsl_udc_core.c
drivers/video/tegra/fb.c
include/linux/mmc/host.h
include/linux/tegra_audio.h

index 87309818d254701e247e06fea30e7b038fd8813c..163993bfa816c0d82226b05a24e9db2e86fad1ac 100644 (file)
@@ -341,7 +341,7 @@ EXPORT_SYMBOL(tegra_dma_enqueue_req);
 struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
 {
        int channel;
-       struct tegra_dma_channel *ch = NULL;;
+       struct tegra_dma_channel *ch = NULL;
 
        mutex_lock(&tegra_dma_lock);
 
@@ -351,8 +351,10 @@ struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
        } else {
                channel = find_first_zero_bit(channel_usage,
                        ARRAY_SIZE(dma_channels));
-               if (channel >= ARRAY_SIZE(dma_channels))
+               if (channel >= ARRAY_SIZE(dma_channels)) {
+                       pr_err("%s: failed to allocate a DMA channel",__func__);
                        goto out;
+               }
        }
        __set_bit(channel, channel_usage);
        ch = &dma_channels[channel];
index 4801cec44999df8f1427a308d06c4998bd6229c0..ed8bc14c4ca4501def785e8669cc30e2bd63adf1 100644 (file)
                (I2S_FIFO_ATN_LVL_EIGHT_SLOTS  << I2S_FIFO1_ATN_LVL_SHIFT)
 #define I2S_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS    \
                (I2S_FIFO_ATN_LVL_TWELVE_SLOTS << I2S_FIFO1_ATN_LVL_SHIFT)
+/*
+ * I2S_I2S_PCM_CTRL_0
+ */
+#define I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ             0
+#define I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ                        1
+#define I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ             2
+#define I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ                        3
+#define I2S_PCM_TRM_EDGE_CTRL_SHIFT                    9
+
+#define I2S_I2S_PCM_TRM_EDGE_CTRL_MASK                 \
+               (3 << I2S_I2S_PCM_TRM_EDGE_CTRL_SHIFT)
+#define I2S_I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ         \
+               (I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ        \
+               << I2S_PCM_TRM_EDGE_CTRL_SHIFT)
+#define I2S_I2S_PCM_TRM_EDGE_POS_EDGE_HIGHZ            \
+               (I2S_PCM_TRM_EDGE_POS_EDGE_NO_HIGHZ     \
+               << I2S_PCM_TRM_EDGE_CTRL_SHIFT)
+#define I2S_I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ         \
+               (I2S_PCM_TRM_EDGE_NEG_EDGE_NO_HIGHZ     \
+               << I2S_PCM_TRM_EDGE_CTRL_SHIFT)
+#define I2S_I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ            \
+               (I2S_PCM_TRM_EDGE_NEG_EDGE_HIGHZ        \
+               << I2S_PCM_TRM_EDGE_CTRL_SHIFT)
+
+#define I2S_PCM_TRM_MASK_BITS_ZERO                     0
+#define I2S_PCM_TRM_MASK_BITS_ONE                      1
+#define I2S_PCM_TRM_MASK_BITS_TWO                      2
+#define I2S_PCM_TRM_MASK_BITS_THREE                    3
+#define I2S_PCM_TRM_MASK_BITS_FOUR                     4
+#define I2S_PCM_TRM_MASK_BITS_FIVE                     5
+#define I2S_PCM_TRM_MASK_BITS_SIX                      6
+#define I2S_PCM_TRM_MASK_BITS_SEVEN                    7
+#define I2S_PCM_TRM_MASK_BITS_SHIFT                    6
+
+#define I2S_I2S_PCM_TRM_MASK_BITS_MASK                 \
+               (7 << I2S_PCM_TRM_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_TRM_MASK_BITS_ZERO                 \
+               (I2S_PCM_TRM_MASK_BITS_ZERO             \
+               << I2S_PCM_TRM_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_TRM_MASK_BITS_ONE                  \
+               (I2S_PCM_TRM_MASK_BITS_ONE              \
+               << I2S_PCM_TRM_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_TRM_MASK_BITS_TWO                  \
+               (I2S_PCM_TRM_MASK_BITS_TWO              \
+               << I2S_PCM_TRM_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_TRM_MASK_BITS_THREE                        \
+               (I2S_PCM_TRM_MASK_BITS_THREE            \
+               << I2S_PCM_TRM_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_TRM_MASK_BITS_FOUR                 \
+               (I2S_PCM_TRM_MASK_BITS_FOUR             \
+               << I2S_PCM_TRM_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_TRM_MASK_BITS_FIVE                 \
+               (I2S_PCM_TRM_MASK_BITS_FIVE             \
+               << I2S_PCM_TRM_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_TRM_MASK_BITS_SIX                  \
+               (I2S_PCM_TRM_MASK_BITS_SIX              \
+               << I2S_PCM_TRM_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_TRM_MASK_BITS_SEVEN                        \
+               (I2S_PCM_TRM_MASK_BITS_SEVEN            \
+               << I2S_PCM_TRM_MASK_BITS_SHIFT)
+
+#define I2S_I2S_PCM_CTRL_FSYNC_PCM_CTRL                        (1<<5)
+#define I2S_I2S_PCM_CTRL_TRM_MODE                      (1<<4)
+
+#define I2S_PCM_RCV_MASK_BITS_ZERO                     0
+#define I2S_PCM_RCV_MASK_BITS_ONE                      1
+#define I2S_PCM_RCV_MASK_BITS_TWO                      2
+#define I2S_PCM_RCV_MASK_BITS_THREE                    3
+#define I2S_PCM_RCV_MASK_BITS_FOUR                     4
+#define I2S_PCM_RCV_MASK_BITS_FIVE                     5
+#define I2S_PCM_RCV_MASK_BITS_SIX                      6
+#define I2S_PCM_RCV_MASK_BITS_SEVEN                    7
+#define I2S_PCM_RCV_MASK_BITS_SHIFT                    1
+
+#define I2S_I2S_PCM_RCV_MASK_BITS_MASK                 \
+               (7 << I2S_PCM_RCV_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_RCV_MASK_BITS_ZERO                 \
+               (I2S_PCM_RCV_MASK_BITS_ZERO             \
+               << I2S_PCM_RCV_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_RCV_MASK_BITS_ONE                  \
+               (I2S_PCM_RCV_MASK_BITS_ONE              \
+               << I2S_PCM_RCV_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_RCV_MASK_BITS_TWO                  \
+               (I2S_PCM_RCV_MASK_BITS_TWO              \
+               << I2S_PCM_RCV_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_RCV_MASK_BITS_THREE                        \
+               (I2S_PCM_RCV_MASK_BITS_THREE            \
+               << I2S_PCM_RCV_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_RCV_MASK_BITS_FOUR                 \
+               (I2S_PCM_RCV_MASK_BITS_FOUR             \
+               << I2S_PCM_RCV_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_RCV_MASK_BITS_FIVE                 \
+               (I2S_PCM_RCV_MASK_BITS_FIVE             \
+               << I2S_PCM_RCV_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_RCV_MASK_BITS_SIX                  \
+               (I2S_PCM_RCV_MASK_BITS_SIX              \
+               << I2S_PCM_RCV_MASK_BITS_SHIFT)
+#define I2S_I2S_PCM_RCV_MASK_BITS_SEVEN                        \
+               (I2S_PCM_RCV_MASK_BITS_SEVEN            \
+               << I2S_PCM_RCV_MASK_BITS_SHIFT)
+
+#define I2S_I2S_PCM_CTRL_RCV_MODE                      (1<<0)
+
 
 #endif /* __ARCH_ARM_MACH_TEGRA_I2S_H */
index 26bf301b5794115d4293a88059f42c2219361225..48df628ac8c4376d914c33c9a6e0333c7c03c658 100644 (file)
@@ -42,7 +42,7 @@
 #include <linux/sysfs.h>
 #include <linux/pm_qos_params.h>
 #include <linux/wakelock.h>
-
+#include <linux/delay.h>
 #include <linux/tegra_audio.h>
 
 #include <mach/dma.h>
@@ -79,6 +79,7 @@ struct audio_stream {
 
        ktime_t last_dma_ts;
        struct tegra_dma_channel *dma_chan;
+       bool stop;
        struct completion stop_completion;
        spinlock_t dma_req_lock; /* guards dma_has_it */
        int dma_has_it;
@@ -86,6 +87,7 @@ struct audio_stream {
 
        struct pm_qos_request_list pm_qos;
        struct wake_lock wake_lock;
+       char wake_lock_name[100];
 };
 
 struct i2s_pio_stats {
@@ -116,7 +118,6 @@ struct audio_driver_state {
 
        int irq; /* for pio mode */
        struct i2s_pio_stats pio_stats;
-       bool recording_cancelled;
        struct tegra_audio_in_config in_config;
        const int *in_divs;
        int in_divs_len;
@@ -212,6 +213,20 @@ static inline struct audio_driver_state *ads_from_in(
        return container_of(ais, struct audio_driver_state, in);
 }
 
+static inline void prevent_suspend(struct audio_stream *as)
+{
+       pr_debug("%s\n", __func__);
+       wake_lock(&as->wake_lock);
+       pm_qos_update_request(&as->pm_qos, 0);
+}
+
+static inline void allow_suspend(struct audio_stream *as)
+{
+       pr_debug("%s\n", __func__);
+       pm_qos_update_request(&as->pm_qos, PM_QOS_DEFAULT_VALUE);
+       wake_unlock(&as->wake_lock);
+}
+
 #define I2S_I2S_FIFO_TX_BUSY   I2S_I2S_STATUS_FIFO1_BSY
 #define I2S_I2S_FIFO_TX_QS     I2S_I2S_STATUS_QS_FIFO1
 #define I2S_I2S_FIFO_TX_ERR    I2S_I2S_STATUS_FIFO1_ERR
@@ -367,8 +382,14 @@ static int i2s_set_bit_format(unsigned long base, unsigned fmt)
        val = i2s_readl(base, I2S_I2S_CTRL_0);
        val &= ~I2S_I2S_CTRL_BIT_FORMAT_MASK;
        val |= fmt << I2S_BIT_FORMAT_SHIFT;
-
        i2s_writel(base, val, I2S_I2S_CTRL_0);
+
+       if (fmt == I2S_BIT_FORMAT_DSP) {
+               val = i2s_readl(base, I2S_I2S_PCM_CTRL_0);
+               val |= I2S_I2S_PCM_CTRL_TRM_MODE|I2S_I2S_PCM_CTRL_RCV_MODE;
+               i2s_writel(base, val, I2S_I2S_PCM_CTRL_0);
+       }
+
        return 0;
 }
 
@@ -547,29 +568,26 @@ static int start_playback(struct audio_stream *aos)
        pr_debug("%s: starting playback\n", __func__);
        rc = sound_ops->start_playback(aos);
        spin_unlock_irqrestore(&aos->dma_req_lock, flags);
-       if (!rc) {
-               pm_qos_update_request(&aos->pm_qos, 0);
-               wake_lock(&aos->wake_lock);
-       }
+       if (!rc)
+               prevent_suspend(aos);
        return rc;
 }
 
 static int start_recording_if_necessary(struct audio_stream *ais)
 {
        int rc = 0;
+       bool started = false;
        unsigned long flags;
-       struct audio_driver_state *ads = ads_from_in(ais);
 
        spin_lock_irqsave(&ais->dma_req_lock, flags);
-       if (!ads->recording_cancelled && !kfifo_is_full(&ais->fifo)) {
+       if (!ais->stop && !kfifo_is_full(&ais->fifo)) {
                pr_debug("%s: starting recording\n", __func__);
                rc = sound_ops->start_recording(ais);
+               started = !rc;
        }
        spin_unlock_irqrestore(&ais->dma_req_lock, flags);
-       if (!rc) {
-               pm_qos_update_request(&ais->pm_qos, 0);
-               wake_lock(&ais->wake_lock);
-       }
+       if (started)
+               prevent_suspend(ais);
        return rc;
 }
 
@@ -579,11 +597,8 @@ static bool stop_playback_if_necessary(struct audio_stream *aos)
        spin_lock_irqsave(&aos->dma_req_lock, flags);
        if (kfifo_is_empty(&aos->fifo)) {
                sound_ops->stop_playback(aos);
-               if (aos->active)
-                       aos->errors.full_empty++; /* underflow */
                spin_unlock_irqrestore(&aos->dma_req_lock, flags);
-               pm_qos_update_request(&aos->pm_qos, PM_QOS_DEFAULT_VALUE);
-               wake_unlock(&aos->wake_lock);
+               allow_suspend(aos);
                return true;
        }
        spin_unlock_irqrestore(&aos->dma_req_lock, flags);
@@ -593,9 +608,7 @@ static bool stop_playback_if_necessary(struct audio_stream *aos)
 
 static bool stop_recording_if_necessary_nosync(struct audio_stream *ais)
 {
-       struct audio_driver_state *ads = ads_from_in(ais);
-
-       if (ads->recording_cancelled || kfifo_is_full(&ais->fifo)) {
+       if (ais->stop || kfifo_is_full(&ais->fifo)) {
                if (kfifo_is_full(&ais->fifo))
                        ais->errors.full_empty++;  /* overflow */
                sound_ops->stop_recording(ais);
@@ -605,18 +618,37 @@ static bool stop_recording_if_necessary_nosync(struct audio_stream *ais)
        return false;
 }
 
-static bool stop_recording(struct audio_stream *ais)
+/* playback and recording */
+static bool wait_till_stopped(struct audio_stream *as)
 {
        int rc;
        pr_debug("%s: wait for completion\n", __func__);
        rc = wait_for_completion_interruptible(
-                       &ais->stop_completion);
+                       &as->stop_completion);
+       allow_suspend(as);
        pr_debug("%s: done: %d\n", __func__, rc);
-       pm_qos_update_request(&ais->pm_qos, PM_QOS_DEFAULT_VALUE);
-       wake_unlock(&ais->wake_lock);
        return true;
 }
 
+/* Ask for playback and recording to stop.  The _nosync means that
+ * as->lock has to be locked by the caller.
+ */
+static void request_stop_nosync(struct audio_stream *as)
+{
+       pr_debug("%s\n", __func__);
+       if (!as->stop) {
+               as->stop = true;
+               wait_till_stopped(as);
+               if (!completion_done(&as->fifo_completion)) {
+                       pr_debug("%s: complete\n", __func__);
+                       complete(&as->fifo_completion);
+               }
+       }
+       kfifo_reset(&as->fifo);
+       as->active = false; /* applies to recording only */
+       pr_debug("%s: done\n", __func__);
+}
+
 static void toggle_dma(struct audio_driver_state *ads)
 {
        pr_info("%s: %s\n", __func__, ads->using_dma ? "pio" : "dma");
@@ -726,15 +758,21 @@ static void dma_tx_complete_callback(struct tegra_dma_req *req)
        kfifo_dma_out_finish(&aos->fifo, count);
        dma_unmap_sg(NULL, &aos->sg, 1, DMA_TO_DEVICE);
 
-       if (kfifo_avail(&aos->fifo) >= threshold_size(aos) &&
-                       !completion_done(&aos->fifo_completion)) {
+       if (!completion_done(&aos->fifo_completion)) {
                pr_debug("%s: complete (%d avail)\n", __func__,
                                kfifo_avail(&aos->fifo));
                complete(&aos->fifo_completion);
        }
 
-       if (stop_playback_if_necessary(aos))
+       if (stop_playback_if_necessary(aos)) {
+               pr_debug("%s: done (stopped)\n", __func__);
+               if (!completion_done(&aos->stop_completion)) {
+                       pr_debug("%s: signalling stop completion\n", __func__);
+                       complete(&aos->stop_completion);
+               }
                return;
+       }
+
        spin_lock_irqsave(&aos->dma_req_lock, flags);
        resume_dma_playback(aos);
        spin_unlock_irqrestore(&aos->dma_req_lock, flags);
@@ -742,7 +780,7 @@ static void dma_tx_complete_callback(struct tegra_dma_req *req)
 
 static void dma_rx_complete_threshold(struct tegra_dma_req *req)
 {
-       pr_info("%s\n", __func__);
+       pr_debug("%s\n", __func__);
 }
 
 static void dma_rx_complete_callback(struct tegra_dma_req *req)
@@ -764,8 +802,7 @@ static void dma_rx_complete_callback(struct tegra_dma_req *req)
        kfifo_dma_in_finish(&ais->fifo, count);
        dma_unmap_sg(NULL, &ais->sg, 1, DMA_FROM_DEVICE);
 
-       if (kfifo_avail(&ais->fifo) <= threshold_size(ais) &&
-                       !completion_done(&ais->fifo_completion)) {
+       if (!completion_done(&ais->fifo_completion)) {
                pr_debug("%s: signalling fifo completion\n", __func__);
                complete(&ais->fifo_completion);
        }
@@ -894,9 +931,11 @@ static void stop_dma_playback(struct audio_stream *aos)
        pr_debug("%s\n", __func__);
        i2s_fifo_enable(ads->i2s_base, I2S_FIFO_TX, 0);
        while ((i2s_get_status(ads->i2s_base) & I2S_I2S_FIFO_TX_BUSY) &&
-                       spin < 100)
+                       spin < 100) {
+               udelay(10);
                if (spin++ > 50)
                        pr_info("%s: spin %d\n", __func__, spin);
+       }
        if (spin == 100)
                pr_warn("%s: spinny\n", __func__);
 }
@@ -971,9 +1010,11 @@ static void stop_dma_recording(struct audio_stream *ais)
        i2s_fifo_enable(ads->i2s_base, I2S_FIFO_RX, 0);
        i2s_fifo_clear(ads->i2s_base, I2S_FIFO_RX);
        while ((i2s_get_status(ads->i2s_base) & I2S_I2S_FIFO_RX_BUSY) &&
-                       spin < 100)
+                       spin < 100) {
+               udelay(10);
                if (spin++ > 50)
                        pr_info("%s: spin %d\n", __func__, spin);
+       }
        if (spin == 100)
                pr_warn("%s: spinny\n", __func__);
 }
@@ -1010,9 +1051,10 @@ static int start_pio_playback(struct audio_stream *aos)
        i2s_fifo_clear(ads->i2s_base, I2S_FIFO_TX);
 #endif
 
+       i2s_fifo_enable(ads->i2s_base, I2S_FIFO_TX, 1);
+
        i2s_set_fifo_irq_on_err(ads->i2s_base, I2S_FIFO_TX, 1);
        i2s_set_fifo_irq_on_qe(ads->i2s_base, I2S_FIFO_TX, 1);
-       i2s_fifo_enable(ads->i2s_base, I2S_FIFO_TX, 1);
 
        return 0;
 }
@@ -1027,7 +1069,7 @@ static void stop_pio_playback(struct audio_stream *aos)
        while (i2s_get_status(ads->i2s_base) & I2S_I2S_FIFO_TX_BUSY)
                /* spin */;
 
-       pr_info("%s: interrupts %d\n", __func__,
+       pr_debug("%s: interrupts %d\n", __func__,
                        ads->pio_stats.i2s_interrupt_count);
        pr_info("%s: sent       %d\n", __func__,
                        ads->pio_stats.tx_fifo_written);
@@ -1054,11 +1096,11 @@ static int start_pio_recording(struct audio_stream *ais)
        i2s_fifo_clear(ads->i2s_base, I2S_FIFO_RX);
 #endif
 
+       i2s_fifo_enable(ads->i2s_base, I2S_FIFO_RX, 1);
+
        i2s_set_fifo_irq_on_err(ads->i2s_base, I2S_FIFO_RX, 1);
        i2s_set_fifo_irq_on_qe(ads->i2s_base, I2S_FIFO_RX, 1);
 
-       i2s_fifo_enable(ads->i2s_base, I2S_FIFO_RX, 1);
-
        return 0;
 }
 
@@ -1119,15 +1161,21 @@ static irqreturn_t i2s_interrupt(int irq, void *data)
 
                pr_debug("%s tx fifo is ready\n", __func__);
 
-               if (kfifo_avail(&out->fifo) > threshold_size(out) &&
-                               !completion_done(&out->fifo_completion)) {
+               if (!completion_done(&out->fifo_completion)) {
                        pr_debug("%s: tx complete (%d avail)\n", __func__,
                                        kfifo_avail(&out->fifo));
                        complete(&out->fifo_completion);
                }
 
-               if (stop_playback_if_necessary(out))
+               if (stop_playback_if_necessary(out)) {
+                       pr_debug("%s: done (stopped)\n", __func__);
+                       if (!completion_done(&out->stop_completion)) {
+                               pr_debug("%s: signalling stop completion\n",
+                                       __func__);
+                               complete(&out->stop_completion);
+                       }
                        goto check_rx;
+               }
 
                empty = i2s_get_fifo_full_empty_count(ads->i2s_base,
                                I2S_FIFO_TX);
@@ -1183,8 +1231,7 @@ check_rx:
 
                ads->pio_stats.rx_fifo_read += full * sizeof(u16);
 
-               if (kfifo_avail(&in->fifo) < threshold_size(in) &&
-                               !completion_done(&in->fifo_completion)) {
+               if (!completion_done(&in->fifo_completion)) {
                        pr_debug("%s: rx complete (%d avail)\n", __func__,
                                        kfifo_avail(&in->fifo));
                        complete(&in->fifo_completion);
@@ -1212,15 +1259,13 @@ done:
 static ssize_t tegra_audio_write(struct file *file,
                const char __user *buf, size_t size, loff_t *off)
 {
-       ssize_t rc, total = 0;
+       ssize_t rc = 0, total = 0;
        unsigned nw = 0;
 
        struct audio_driver_state *ads = ads_from_misc_out(file);
 
        mutex_lock(&ads->out.lock);
 
-       ads->out.active = true;
-
        if (!IS_ALIGNED(size, 4)) {
                pr_err("%s: user size request %d not aligned to 4\n",
                        __func__, size);
@@ -1232,6 +1277,12 @@ static ssize_t tegra_audio_write(struct file *file,
                        size, kfifo_avail(&ads->out.fifo));
 
 again:
+       if (ads->out.stop) {
+               pr_info("%s: playback has been cancelled (%d/%d bytes)\n",
+                               __func__, total, size);
+               goto done;
+       }
+
        rc = kfifo_from_user(&ads->out.fifo, buf + total, size - total, &nw);
        if (rc < 0) {
                pr_err("%s: error copying from user\n", __func__);
@@ -1264,7 +1315,6 @@ again:
        *off += total;
 
 done:
-       ads->out.active = false;
        mutex_unlock(&ads->out.lock);
        return rc;
 }
@@ -1285,7 +1335,7 @@ static long tegra_audio_out_ioctl(struct file *file,
                        rc = -EFAULT;
                        break;
                }
-               if (aos->active) {
+               if (kfifo_len(&aos->fifo)) {
                        pr_err("%s: playback in progress\n", __func__);
                        rc = -EBUSY;
                        break;
@@ -1308,25 +1358,13 @@ static long tegra_audio_out_ioctl(struct file *file,
                if (!rc)
                        memset(&aos->errors, 0, sizeof(aos->errors));
                break;
-       case TEGRA_AUDIO_OUT_PRELOAD_FIFO: {
-               struct tegra_audio_out_preload preload;
-               if (copy_from_user(&preload, (void __user *)arg,
-                               sizeof(preload))) {
-                       rc = -EFAULT;
-                       break;
+       case TEGRA_AUDIO_OUT_FLUSH:
+               if (kfifo_len(&aos->fifo)) {
+                       pr_debug("%s: flushing\n", __func__);
+                       request_stop_nosync(aos);
+                       pr_debug("%s: flushed\n", __func__);
                }
-               rc = kfifo_from_user(&ads->out.fifo,
-                               (void __user *)preload.data, preload.len,
-                               &preload.len_written);
-               if (rc < 0) {
-                       pr_err("%s: error copying from user\n", __func__);
-                       break;
-               }
-               if (copy_to_user((void __user *)arg, &preload, sizeof(preload)))
-                       rc = -EFAULT;
-               pr_info("%s: preloaded output fifo with %d bytes\n", __func__,
-                       preload.len_written);
-       }
+               aos->stop = false;
                break;
        default:
                rc = -EINVAL;
@@ -1354,6 +1392,7 @@ static long tegra_audio_ioctl(struct file *file,
                case TEGRA_AUDIO_BIT_FORMAT_DEFAULT:
                        i2s_set_bit_format(ads->i2s_base, ads->pdata->mode);
                        ads->bit_format = mode;
+                       break;
                case TEGRA_AUDIO_BIT_FORMAT_DSP:
                        i2s_set_bit_format(ads->i2s_base, I2S_BIT_FORMAT_DSP);
                        ads->bit_format = mode;
@@ -1385,20 +1424,15 @@ static long tegra_audio_in_ioctl(struct file *file,
 
        switch (cmd) {
        case TEGRA_AUDIO_IN_START:
-               pr_info("%s: start recording\n", __func__);
-               ads->recording_cancelled = false;
-               start_recording_if_necessary(ais);
+               pr_debug("%s: start recording\n", __func__);
+               ais->stop = false;
+               rc = start_recording_if_necessary(ais);
+               ais->active = !rc || rc == -EALREADY;
                break;
        case TEGRA_AUDIO_IN_STOP:
-               pr_info("%s: stop recording\n", __func__);
-               if (ais->active && !ads->recording_cancelled) {
-                       ads->recording_cancelled = true;
-                       stop_recording(ais);
-                       if (!completion_done(&ais->fifo_completion)) {
-                               pr_info("%s: complete\n", __func__);
-                               complete(&ais->fifo_completion);
-                       }
-               }
+               pr_debug("%s: start recording\n", __func__);
+               if (ais->active)
+                       request_stop_nosync(ais);
                break;
        case TEGRA_AUDIO_IN_SET_CONFIG: {
                struct tegra_audio_in_config cfg;
@@ -1671,8 +1705,6 @@ static ssize_t tegra_audio_read(struct file *file, char __user *buf,
 
        mutex_lock(&ads->in.lock);
 
-       ads->in.active = true;
-
        if (!IS_ALIGNED(size, 4)) {
                pr_err("%s: user size request %d not aligned to 4\n",
                        __func__, size);
@@ -1684,22 +1716,24 @@ static ssize_t tegra_audio_read(struct file *file, char __user *buf,
                        smp_processor_id(),
                        size, kfifo_len(&ads->in.fifo));
 
-       rc = start_recording_if_necessary(&ads->in);
-       if (rc < 0 && rc != -EALREADY) {
-               pr_err("%s: could not start recording\n", __func__);
-               goto done_err;
-       }
-
 again:
        /* If we want recording to stop immediately after it gets cancelled,
         * then we do not want to wait for the fifo to get drained.
         */
-       if (ads->recording_cancelled /* && kfifo_is_empty(&ads->in.fifo) */) {
-               pr_debug("%s: recording has been cancelled (read %d bytes)\n",
-                               __func__, total);
+       if (ads->in.stop /* && kfifo_is_empty(&ads->in.fifo) */) {
+               pr_debug("%s: recording has been cancelled (%d/%d bytes)\n",
+                               __func__, total, size);
                goto done_ok;
        }
 
+       rc = start_recording_if_necessary(&ads->in);
+       if (rc < 0 && rc != -EALREADY) {
+               pr_err("%s: could not start recording\n", __func__);
+               goto done_err;
+       }
+
+       ads->in.active = true;
+
        nr = 0;
        do {
                nr = downsample_to_user(ads, buf + total, size - total);
@@ -1714,15 +1748,6 @@ again:
                        __func__, nr, total, size);
 
        if (total < size) {
-               /* If we lost data, recording was stopped, so we need to resume
-                * it here.
-               */
-               rc = start_recording_if_necessary(&ads->in);
-               if (rc < 0 && rc != -EALREADY) {
-                       pr_err("%s: could not resume recording\n", __func__);
-                       goto done_err;
-               }
-
                mutex_unlock(&ads->in.lock);
                pr_debug("%s: sleep (user %d total %d nr %d)\n", __func__,
                                size, total, nr);
@@ -1745,7 +1770,6 @@ done_ok:
        *off += total;
 
 done_err:
-       ads->in.active = false;
        mutex_unlock(&ads->in.lock);
        return rc;
 }
@@ -1754,11 +1778,12 @@ static int tegra_audio_out_open(struct inode *inode, struct file *file)
 {
        struct audio_driver_state *ads = ads_from_misc_out(file);
 
-       pr_info("%s\n", __func__);
+       pr_debug("%s\n", __func__);
 
        mutex_lock(&ads->out.lock);
        if (!ads->out.opened++) {
-               pr_info("%s: resetting fifo and error count\n", __func__);
+               pr_debug("%s: resetting fifo and error count\n", __func__);
+               ads->out.stop = false;
                memset(&ads->out.errors, 0, sizeof(ads->out.errors));
                kfifo_reset(&ads->out.fifo);
        }
@@ -1771,13 +1796,20 @@ static int tegra_audio_out_release(struct inode *inode, struct file *file)
 {
        struct audio_driver_state *ads = ads_from_misc_out(file);
 
-       pr_info("%s\n", __func__);
+       pr_debug("%s\n", __func__);
 
        mutex_lock(&ads->out.lock);
        if (ads->out.opened)
                ads->out.opened--;
-       if (!ads->out.opened)
+       if (!ads->out.opened) {
                stop_playback_if_necessary(&ads->out);
+               if (wake_lock_active(&ads->out.wake_lock))
+                       pr_err("%s: wake lock is still held!\n", __func__);
+               if (kfifo_len(&ads->out.fifo))
+                       pr_err("%s: output fifo is not empty (%d bytes left)\n",
+                               __func__, kfifo_len(&ads->out.fifo));
+               allow_suspend(&ads->out);
+       }
        mutex_unlock(&ads->out.lock);
 
        return 0;
@@ -1787,21 +1819,21 @@ static int tegra_audio_in_open(struct inode *inode, struct file *file)
 {
        struct audio_driver_state *ads = ads_from_misc_in(file);
 
-       pr_info("%s\n", __func__);
+       pr_debug("%s\n", __func__);
 
        mutex_lock(&ads->in.lock);
        if (!ads->in.opened++) {
-               pr_info("%s: resetting fifo\n", __func__);
+               pr_debug("%s: resetting fifo\n", __func__);
                /* By default, do not start recording when someone reads from
                 * input device.
                 */
-               ads->recording_cancelled = false;
+               ads->in.stop = false;
                memset(&ads->in.errors, 0, sizeof(ads->in.errors));
                kfifo_reset(&ads->in.fifo);
        }
        mutex_unlock(&ads->in.lock);
 
-       pr_info("%s: done\n", __func__);
+       pr_debug("%s: done\n", __func__);
        return 0;
 }
 
@@ -1809,12 +1841,25 @@ static int tegra_audio_in_release(struct inode *inode, struct file *file)
 {
        struct audio_driver_state *ads = ads_from_misc_in(file);
 
-       pr_info("%s\n", __func__);
+       pr_debug("%s\n", __func__);
+
        mutex_lock(&ads->in.lock);
        if (ads->in.opened)
                ads->in.opened--;
+
+       if (!ads->in.opened) {
+               if (ads->in.active)
+                       request_stop_nosync(&ads->in);
+               if (wake_lock_active(&ads->in.wake_lock))
+                       pr_err("%s: wake lock is still held!\n", __func__);
+               if (kfifo_len(&ads->in.fifo))
+                       pr_err("%s: input fifo is not empty (%d bytes left)\n",
+                               __func__, kfifo_len(&ads->in.fifo));
+               allow_suspend(&ads->in);
+       }
+
        mutex_unlock(&ads->in.lock);
-       pr_info("%s: done\n", __func__);
+       pr_debug("%s: done\n", __func__);
        return 0;
 }
 
@@ -1867,7 +1912,7 @@ static int init_stream_buffer(struct audio_stream *s,
                                struct tegra_audio_buf_config *cfg,
                                unsigned padding)
 {
-       pr_info("%s (size %d threshold %d chunk %d)\n", __func__,
+       pr_debug("%s (size %d threshold %d chunk %d)\n", __func__,
                cfg->size, cfg->threshold, cfg->chunk);
 
        if (cfg->chunk < PCM_DMA_CHUNK_MIN_SIZE_ORDER) {
@@ -1979,7 +2024,7 @@ static ssize_t dma_toggle_store(struct device *dev,
 
        mutex_lock(&ads->out.lock);
        mutex_lock(&ads->in.lock);
-       if (ads->out.active || ads->in.active) {
+       if (kfifo_len(&ads->out.fifo) || ads->in.active) {
                dev_err(dev, "%s: playback or recording in progress.\n",
                        __func__);
                mutex_unlock(&ads->in.lock);
@@ -2054,15 +2099,8 @@ static ssize_t __attr_fifo_atn_write(struct audio_driver_state *ads,
                return -EINVAL;
        }
 
-       mutex_lock(&as->lock);
-       if (as->active) {
-               pr_err("%s: in progress.\n", __func__);
-               mutex_unlock(&as->lock);
-               return -EBUSY;
-       }
        *fifo_lvl = lvl;
        pr_info("%s: fifo level %d\n", __func__, *fifo_lvl);
-       mutex_unlock(&as->lock);
 
        return size;
 }
@@ -2080,10 +2118,21 @@ static ssize_t tx_fifo_atn_store(struct device *dev,
                        struct device_attribute *attr,
                        const char *buf, size_t count)
 {
+       ssize_t rc;
        struct tegra_audio_platform_data *pdata = dev->platform_data;
        struct audio_driver_state *ads = pdata->driver_data;
-       return __attr_fifo_atn_write(ads, &ads->out,
-                       &ads->out.i2s_fifo_atn_level, buf, count);
+       mutex_lock(&ads->out.lock);
+       if (kfifo_len(&ads->out.fifo)) {
+               pr_err("%s: playback in progress.\n", __func__);
+               rc = -EBUSY;
+               goto done;
+       }
+       rc = __attr_fifo_atn_write(ads, &ads->out,
+                       &ads->out.i2s_fifo_atn_level,
+                       buf, count);
+done:
+       mutex_unlock(&ads->out.lock);
+       return rc;
 }
 
 static DEVICE_ATTR(tx_fifo_atn, 0644, tx_fifo_atn_show, tx_fifo_atn_store);
@@ -2101,10 +2150,21 @@ static ssize_t rx_fifo_atn_store(struct device *dev,
                        struct device_attribute *attr,
                        const char *buf, size_t count)
 {
+       ssize_t rc;
        struct tegra_audio_platform_data *pdata = dev->platform_data;
        struct audio_driver_state *ads = pdata->driver_data;
-       return __attr_fifo_atn_write(ads, &ads->in,
-                       &ads->in.i2s_fifo_atn_level, buf, count);
+       mutex_lock(&ads->in.lock);
+       if (ads->in.active) {
+               pr_err("%s: recording in progress.\n", __func__);
+               rc = -EBUSY;
+               goto done;
+       }
+       rc = __attr_fifo_atn_write(ads, &ads->in,
+                       &ads->in.i2s_fifo_atn_level,
+                       buf, count);
+done:
+       mutex_unlock(&ads->in.lock);
+       return rc;
 }
 
 static DEVICE_ATTR(rx_fifo_atn, 0644, rx_fifo_atn_show, rx_fifo_atn_store);
@@ -2257,10 +2317,14 @@ static int tegra_audio_probe(struct platform_device *pdev)
        pm_qos_add_request(&state->out.pm_qos, PM_QOS_CPU_DMA_LATENCY,
                                PM_QOS_DEFAULT_VALUE);
 
+       snprintf(state->in.wake_lock_name, sizeof(state->in.wake_lock_name),
+               "i2s.%d-audio-in", state->pdev->id);
        wake_lock_init(&state->in.wake_lock, WAKE_LOCK_SUSPEND,
-                       "tegra-audio-in");
+                       state->in.wake_lock_name);
+       snprintf(state->out.wake_lock_name, sizeof(state->out.wake_lock_name),
+               "i2s.%d-audio-out", state->pdev->id);
        wake_lock_init(&state->out.wake_lock, WAKE_LOCK_SUSPEND,
-                       "tegra-audio-out");
+                       state->out.wake_lock_name);
 
        if (request_irq(state->irq, i2s_interrupt,
                        IRQF_DISABLED, state->pdev->name, state) < 0) {
index 708f33f20cb7d3c10df4a9d19b8bacce3c17eace..265e88e187dce63246825bcadae706c90523e744 100644 (file)
@@ -980,11 +980,17 @@ static inline void mmc_bus_put(struct mmc_host *host)
 
 int mmc_resume_bus(struct mmc_host *host)
 {
+       unsigned long flags;
+
        if (!mmc_bus_needs_resume(host))
                return -EINVAL;
 
        printk("%s: Starting deferred resume\n", mmc_hostname(host));
+       spin_lock_irqsave(&host->lock, flags);
        host->bus_resume_flags &= ~MMC_BUSRESUME_NEEDS_RESUME;
+       host->rescan_disable = 0;
+       spin_unlock_irqrestore(&host->lock, flags);
+
        mmc_bus_get(host);
        if (host->bus_ops && !host->bus_dead) {
                mmc_power_up(host);
@@ -1694,7 +1700,7 @@ int mmc_resume_host(struct mmc_host *host)
        int err = 0;
 
        mmc_bus_get(host);
-       if (host->bus_resume_flags & MMC_BUSRESUME_MANUAL_RESUME) {
+       if (mmc_bus_manual_resume(host)) {
                host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME;
                mmc_bus_put(host);
                return 0;
@@ -1737,6 +1743,10 @@ int mmc_pm_notify(struct notifier_block *notify_block,
        case PM_SUSPEND_PREPARE:
 
                spin_lock_irqsave(&host->lock, flags);
+               if (mmc_bus_needs_resume(host)) {
+                       spin_unlock_irqrestore(&host->lock, flags);
+                       break;
+               }
                host->rescan_disable = 1;
                spin_unlock_irqrestore(&host->lock, flags);
                cancel_delayed_work_sync(&host->detect);
@@ -1758,6 +1768,10 @@ int mmc_pm_notify(struct notifier_block *notify_block,
        case PM_POST_HIBERNATION:
 
                spin_lock_irqsave(&host->lock, flags);
+               if (mmc_bus_manual_resume(host)) {
+                       spin_unlock_irqrestore(&host->lock, flags);
+                       break;
+               }
                host->rescan_disable = 0;
                spin_unlock_irqrestore(&host->lock, flags);
                mmc_detect_change(host, 0);
index d992d36bbd2925c565d782e8bcd35eed20e5d5bd..a8e3a5c93812d46e2c406e2ad102ea0161292679 100644 (file)
@@ -213,7 +213,7 @@ static void tegra_start_next_tx(struct tegra_uart_port *t)
        if (count == 0)
                goto out;
 
-       if (TX_FORCE_PIO || count < TEGRA_UART_MIN_DMA)
+       if (!t->use_tx_dma || count < TEGRA_UART_MIN_DMA)
                tegra_start_pio_tx(t, count);
        else if (BYTES_TO_ALIGN(tail) > 0)
                tegra_start_pio_tx(t, BYTES_TO_ALIGN(tail));
@@ -666,8 +666,10 @@ static int tegra_uart_init_rx_dma(struct tegra_uart_port *t)
        void *rx_dma_virt;
 
        t->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS);
-       if (!t->rx_dma)
+       if (!t->rx_dma) {
+               pr_err("%s: failed to allocate RX DMA.\n", __func__);
                return -ENODEV;
+       }
 
        memset(&t->rx_dma_req, 0, sizeof(t->rx_dma_req));
 
@@ -712,6 +714,8 @@ static int tegra_startup(struct uart_port *u)
                t->tx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT);
                if (t->tx_dma)
                        t->use_tx_dma = true;
+               else
+                       pr_err("%s: failed to allocate TX DMA.\n", __func__);
        }
        if (t->use_tx_dma) {
                t->tx_dma_req.instance = u->line;
@@ -733,7 +737,7 @@ static int tegra_startup(struct uart_port *u)
        t->tx_in_progress = 0;
 
        t->use_rx_dma = false;
-       if (!TX_FORCE_PIO) {
+       if (!RX_FORCE_PIO) {
                if (!tegra_uart_init_rx_dma(t))
                        t->use_rx_dma = true;
        }
index 3709d5dccd76a73fbae55c5c067b67fff962acbb..33226408b447004427d7ca9a9e79356b2301a0c5 100644 (file)
@@ -473,11 +473,6 @@ static int spi_tegra_transfer(struct spi_device *spi, struct spi_message *m)
        return 0;
 }
 
-static void spi_tegra_cleanup(struct spi_device *spi)
-{
-       dev_dbg(&spi->dev, "cleanup\n");
-}
-
 static int __init spi_tegra_probe(struct platform_device *pdev)
 {
        struct spi_master       *master;
@@ -494,12 +489,10 @@ static int __init spi_tegra_probe(struct platform_device *pdev)
        /* the spi->mode bits understood by this driver: */
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 
-       if (pdev->id != -1)
-               master->bus_num = pdev->id;
+       master->bus_num = pdev->id;
 
        master->setup = spi_tegra_setup;
        master->transfer = spi_tegra_transfer;
-       master->cleanup = spi_tegra_cleanup;
        master->num_chipselect = 4;
 
        dev_set_drvdata(&pdev->dev, master);
index 0619c4f7be24183da91ebbfec543fccfd1018241..20fab22cc13b50237ded9cdb71a4046348495220 100644 (file)
@@ -94,6 +94,25 @@ static int reset_queues(struct fsl_udc *udc);
 #define fsl_writel(val32, addr) writel(val32, addr)
 #endif
 
+/*
+ * High speed test mode packet(53 bytes).
+ * See USB 2.0 spec, section 7.1.20.
+ */
+static const u8 fsl_udc_test_packet[53] = {
+       /* JKJKJKJK x9 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* JJKKJJKK x8 */
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       /* JJJJKKKK x8 */
+       0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
+       /* JJJJJJJKKKKKKK x8 */
+       0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+       /* JJJJJJJK x8 */
+       0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd,
+       /* JKKKKKKK x10, JK */
+       0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e
+};
+
 /********************************************************************
  *     Internal Used Function
 ********************************************************************/
@@ -1342,6 +1361,107 @@ stall:
        ep0stall(udc);
 }
 
+static void udc_test_mode(struct fsl_udc *udc, u32 test_mode)
+{
+       struct fsl_req *req;
+       struct fsl_ep *ep;
+       u32 portsc, bitmask;
+       unsigned long timeout;
+
+       /* Ack the ep0 IN */
+       if (ep0_prime_status(udc, EP_DIR_IN))
+               ep0stall(udc);
+
+       /* get the ep0 */
+       ep = &udc->eps[0];
+       bitmask = ep_is_in(ep)
+               ? (1 << (ep_index(ep) + 16))
+               : (1 << (ep_index(ep)));
+
+       timeout = jiffies + HZ;
+       /* Wait until ep0 IN endpoint txfr is complete */
+       while (!(fsl_readl(&dr_regs->endptcomplete) & bitmask)) {
+               if (time_after(jiffies, timeout)) {
+                       pr_err("Timeout for Ep0 IN Ack\n");
+                       break;
+               }
+               cpu_relax();
+       }
+
+       switch (test_mode << PORTSCX_PTC_BIT_POS) {
+       case PORTSCX_PTC_JSTATE:
+               VDBG("TEST_J\n");
+               break;
+       case PORTSCX_PTC_KSTATE:
+               VDBG("TEST_K\n");
+               break;
+       case PORTSCX_PTC_SEQNAK:
+               VDBG("TEST_SE0_NAK\n");
+               break;
+       case PORTSCX_PTC_PACKET:
+               VDBG("TEST_PACKET\n");
+
+               /* get the ep and configure for IN direction */
+               ep = &udc->eps[0];
+               udc->ep0_dir = USB_DIR_IN;
+
+               /* Initialize ep0 status request structure */
+               req = container_of(fsl_alloc_request(NULL, GFP_ATOMIC),
+                               struct fsl_req, req);
+               /* allocate a small amount of memory to get valid address */
+               req->req.buf = kmalloc(sizeof(fsl_udc_test_packet), GFP_ATOMIC);
+               req->req.dma = virt_to_phys(req->req.buf);
+
+               /* Fill in the reqest structure */
+               memcpy(req->req.buf, fsl_udc_test_packet, sizeof(fsl_udc_test_packet));
+               req->ep = ep;
+               req->req.length = sizeof(fsl_udc_test_packet);
+               req->req.status = -EINPROGRESS;
+               req->req.actual = 0;
+               req->req.complete = NULL;
+               req->dtd_count = 0;
+               req->mapped = 0;
+
+               dma_sync_single_for_device(ep->udc->gadget.dev.parent,
+                                       req->req.dma, req->req.length,
+                                       ep_is_in(ep)
+                                               ? DMA_TO_DEVICE
+                                               : DMA_FROM_DEVICE);
+
+               /* prime the data phase */
+               if ((fsl_req_to_dtd(req, GFP_ATOMIC) == 0))
+                       fsl_queue_td(ep, req);
+               else                    /* no mem */
+                       goto stall;
+
+               list_add_tail(&req->queue, &ep->queue);
+               udc->ep0_state = DATA_STATE_XMIT;
+               break;
+       case PORTSCX_PTC_FORCE_EN:
+               VDBG("TEST_FORCE_EN\n");
+               break;
+       default:
+               ERR("udc unknown test mode[%d]!\n", test_mode);
+               goto stall;
+       }
+
+       /* read the portsc register */
+       portsc = fsl_readl(&dr_regs->portsc1);
+       /* set the test mode selector */
+       portsc |= test_mode << PORTSCX_PTC_BIT_POS;
+       fsl_writel(portsc, &dr_regs->portsc1);
+
+       /*
+        * The device must have its power cycled to exit test mode.
+        * See USB 2.0 spec, section 9.4.9 for test modes operation in "Set Feature"
+        * See USB 2.0 spec, section 7.1.20 for test modes.
+        */
+       pr_info("udc entering the test mode, power cycle to exit test mode\n");
+       return;
+stall:
+       ep0stall(udc);
+}
+
 static void setup_received_irq(struct fsl_udc *udc,
                struct usb_ctrlrequest *setup)
 {
@@ -1375,7 +1495,17 @@ static void setup_received_irq(struct fsl_udc *udc,
        {
                int rc = -EOPNOTSUPP;
 
-               if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
+               if (setup->bRequestType == USB_RECIP_DEVICE &&
+                                wValue == USB_DEVICE_TEST_MODE) {
+                       /*
+                        * If the feature selector is TEST_MODE, then the most
+                        * significant byte of wIndex is used to specify the specific
+                        * test mode and the lower byte of wIndex must be zero.
+                        */
+                       udc_test_mode(udc, wIndex >> 8);
+                       return;
+
+               } else if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
                                == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) {
                        int pipe = get_pipe_by_windex(wIndex);
                        struct fsl_ep *ep;
index 87ba58b06cd1fcd4e4de805e02f99304100e3db2..746ea532661c32eb59cbd62ad2ec830f7c6dc4b1 100644 (file)
@@ -149,6 +149,7 @@ static int tegra_fb_set_par(struct fb_info *info)
                return -EINVAL;
        }
        info->fix.line_length = var->xres * var->bits_per_pixel / 8;
+       tegra_fb->win->stride = info->fix.line_length;
 
        if (var->pixclock) {
                struct tegra_dc_mode mode;
index cdfbe59534828fd296f31da5638dad0117ddf6ee..8187e32d917dee8a071f6e45b85d1ff463c8f21a 100644 (file)
@@ -255,6 +255,7 @@ static inline void *mmc_priv(struct mmc_host *host)
 #define mmc_classdev(x)        (&(x)->class_dev)
 #define mmc_hostname(x)        (dev_name(&(x)->class_dev))
 #define mmc_bus_needs_resume(host) ((host)->bus_resume_flags & MMC_BUSRESUME_NEEDS_RESUME)
+#define mmc_bus_manual_resume(host) ((host)->bus_resume_flags & MMC_BUSRESUME_MANUAL_RESUME)
 
 static inline void mmc_set_bus_resume_policy(struct mmc_host *host, int manual)
 {
index b97b640819a036bb12fe2510c225396739356ae9..0ca6250beac4db0e117937926f3d133a12a51576 100644 (file)
@@ -63,20 +63,13 @@ struct tegra_audio_error_counts {
 #define TEGRA_AUDIO_OUT_GET_ERROR_COUNT        _IOR(TEGRA_AUDIO_MAGIC, 9, \
                        struct tegra_audio_error_counts *)
 
-struct tegra_audio_out_preload {
-       void *data;
-       size_t len;
-       size_t len_written;
-};
-
-#define TEGRA_AUDIO_OUT_PRELOAD_FIFO   _IOWR(TEGRA_AUDIO_MAGIC, 10, \
-                       struct tegra_audio_out_preload *)
+#define TEGRA_AUDIO_OUT_FLUSH          _IO(TEGRA_AUDIO_MAGIC, 10)
 
 #define TEGRA_AUDIO_BIT_FORMAT_DEFAULT 0
 #define TEGRA_AUDIO_BIT_FORMAT_DSP 1
-#define TEGRA_AUDIO_SET_BIT_FORMAT       _IOW(TEGRA_AUDIO_MAGIC, 11, \
+#define TEGRA_AUDIO_SET_BIT_FORMAT     _IOW(TEGRA_AUDIO_MAGIC, 11, \
                        unsigned int *)
-#define TEGRA_AUDIO_GET_BIT_FORMAT       _IOR(TEGRA_AUDIO_MAGIC, 12, \
+#define TEGRA_AUDIO_GET_BIT_FORMAT     _IOR(TEGRA_AUDIO_MAGIC, 12, \
                        unsigned int *)
 
 #endif/*_CPCAP_AUDIO_H*/