--- /dev/null
+From 6b45214277bec2193ad3ccb8d7aa6100b5a0f1a9 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 14 Oct 2011 15:26:20 +0200
+Subject: ALSA: hda - Fix ADC input-amp handling for Cx20549 codec
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 6b45214277bec2193ad3ccb8d7aa6100b5a0f1a9 upstream.
+
+It seems that Conexant CX20549 chip handle only a single input-amp even
+though the audio-input widget has multiple sources. This has been never
+clear, and I implemented in the current way based on the debug information
+I got at the early time -- the device reacts individual input-amp values
+for different sources. This is true for another Conexant codec, but it's
+not applied to CX20549 actually.
+
+This patch changes the auto-parser code to handle a single input-amp
+per audio-in widget for CX20549. After applying this, you'll see only a
+single "Capture" volume control instead of separate "Mic" or "Line"
+captures when the device is set up to use a single ADC.
+
+We haven't tested 20551 and 20561 codecs yet. If these show the similar
+behavior like 20549, they need to set spec->single_adc_amp=1, too.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ sound/pci/hda/patch_conexant.c | 30 ++++++++++++++++++++++++++++--
+ 1 file changed, 28 insertions(+), 2 deletions(-)
+
+--- a/sound/pci/hda/patch_conexant.c
++++ b/sound/pci/hda/patch_conexant.c
+@@ -137,6 +137,7 @@ struct conexant_spec {
+ unsigned int hp_laptop:1;
+ unsigned int asus:1;
+ unsigned int pin_eapd_ctrls:1;
++ unsigned int single_adc_amp:1;
+
+ unsigned int adc_switching:1;
+
+@@ -4256,6 +4257,8 @@ static int cx_auto_add_capture_volume(st
+ int idx = get_input_connection(codec, adc_nid, nid);
+ if (idx < 0)
+ continue;
++ if (spec->single_adc_amp)
++ idx = 0;
+ return cx_auto_add_volume_idx(codec, label, pfx,
+ cidx, adc_nid, HDA_INPUT, idx);
+ }
+@@ -4296,14 +4299,21 @@ static int cx_auto_build_input_controls(
+ struct hda_input_mux *imux = &spec->private_imux;
+ const char *prev_label;
+ int input_conn[HDA_MAX_NUM_INPUTS];
+- int i, err, cidx;
++ int i, j, err, cidx;
+ int multi_connection;
+
++ if (!imux->num_items)
++ return 0;
++
+ multi_connection = 0;
+ for (i = 0; i < imux->num_items; i++) {
+ cidx = get_input_connection(codec, spec->imux_info[i].adc,
+ spec->imux_info[i].pin);
+- input_conn[i] = (spec->imux_info[i].adc << 8) | cidx;
++ if (cidx < 0)
++ continue;
++ input_conn[i] = spec->imux_info[i].adc;
++ if (!spec->single_adc_amp)
++ input_conn[i] |= cidx << 8;
+ if (i > 0 && input_conn[i] != input_conn[0])
+ multi_connection = 1;
+ }
+@@ -4332,6 +4342,15 @@ static int cx_auto_build_input_controls(
+ err = cx_auto_add_capture_volume(codec, nid,
+ "Capture", "", cidx);
+ } else {
++ bool dup_found = false;
++ for (j = 0; j < i; j++) {
++ if (input_conn[j] == input_conn[i]) {
++ dup_found = true;
++ break;
++ }
++ }
++ if (dup_found)
++ continue;
+ err = cx_auto_add_capture_volume(codec, nid,
+ label, " Capture", cidx);
+ }
+@@ -4408,6 +4427,13 @@ static int patch_conexant_auto(struct hd
+ return -ENOMEM;
+ codec->spec = spec;
+ codec->pin_amp_workaround = 1;
++
++ switch (codec->vendor_id) {
++ case 0x14f15045:
++ spec->single_adc_amp = 1;
++ break;
++ }
++
+ err = cx_auto_search_adcs(codec);
+ if (err < 0)
+ return err;
--- /dev/null
+From effd4d9aece9184f526e6556786a94d335e38b71 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 15 Sep 2011 11:46:52 -0700
+Subject: iwlagn: do not use interruptible waits
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit effd4d9aece9184f526e6556786a94d335e38b71 upstream.
+
+Since the dawn of its time, iwlwifi has used
+interruptible waits to wait for synchronous
+commands and firmware loading.
+
+This leads to "interesting" bugs, because it
+can't actually handle the interruptions; for
+example when a command sending is interrupted
+it will assume the command completed fully,
+and then leave it pending, which leads to all
+kinds of trouble when the command finishes
+later.
+
+Since there's no easy way to gracefully deal
+with interruptions, fix the driver to not use
+interruptible waits.
+
+This at least fixes the error
+iwlagn 0000:02:00.0: Error: Response NULL in 'REPLY_SCAN_ABORT_CMD'
+
+I have seen in P2P testing, but it is likely
+that there are other errors caused by this.
+
+Cc: Stanislaw Gruszka <sgruszka@redhat.com>
+Cc: stable@kernel.org [2.6.24+]
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+
+
+---
+ drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 9 ++-------
+ drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++--
+ drivers/net/wireless/iwlwifi/iwl-rx.c | 2 +-
+ drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c | 2 +-
+ drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c | 4 ++--
+ 5 files changed, 8 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+@@ -113,13 +113,8 @@ static int iwlagn_load_section(struct iw
+ FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
+
+ IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name);
+- ret = wait_event_interruptible_timeout(priv->wait_command_queue,
+- priv->ucode_write_complete, 5 * HZ);
+- if (ret == -ERESTARTSYS) {
+- IWL_ERR(priv, "Could not load the %s uCode section due "
+- "to interrupt\n", name);
+- return ret;
+- }
++ ret = wait_event_timeout(priv->wait_command_queue,
++ priv->ucode_write_complete, 5 * HZ);
+ if (!ret) {
+ IWL_ERR(priv, "Could not load the %s uCode section\n",
+ name);
+--- a/drivers/net/wireless/iwlwifi/iwl-core.c
++++ b/drivers/net/wireless/iwlwifi/iwl-core.c
+@@ -867,7 +867,7 @@ void iwlagn_fw_error(struct iwl_priv *pr
+ * commands by clearing the ready bit */
+ clear_bit(STATUS_READY, &priv->status);
+
+- wake_up_interruptible(&priv->wait_command_queue);
++ wake_up(&priv->wait_command_queue);
+
+ if (!ondemand) {
+ /*
+@@ -918,7 +918,7 @@ void iwl_irq_handle_error(struct iwl_pri
+ */
+ clear_bit(STATUS_READY, &priv->status);
+ clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+- wake_up_interruptible(&priv->wait_command_queue);
++ wake_up(&priv->wait_command_queue);
+ IWL_ERR(priv, "RF is used by WiMAX\n");
+ return;
+ }
+--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
++++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
+@@ -561,7 +561,7 @@ static void iwl_rx_card_state_notif(stru
+ wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+ test_bit(STATUS_RF_KILL_HW, &priv->status));
+ else
+- wake_up_interruptible(&priv->wait_command_queue);
++ wake_up(&priv->wait_command_queue);
+ }
+
+ static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
+--- a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c
++++ b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c
+@@ -671,7 +671,7 @@ void iwl_irq_tasklet(struct iwl_priv *pr
+ handled |= CSR_INT_BIT_FH_TX;
+ /* Wake up uCode load routine, now that load is complete */
+ priv->ucode_write_complete = 1;
+- wake_up_interruptible(&priv->wait_command_queue);
++ wake_up(&priv->wait_command_queue);
+ }
+
+ if (inta & ~handled) {
+--- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
++++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
+@@ -790,7 +790,7 @@ void iwl_tx_cmd_complete(struct iwl_priv
+ clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+ IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n",
+ get_cmd_string(cmd->hdr.cmd));
+- wake_up_interruptible(&priv->wait_command_queue);
++ wake_up(&priv->wait_command_queue);
+ }
+
+ meta->flags = 0;
+@@ -957,7 +957,7 @@ static int iwl_send_cmd_sync(struct iwl_
+ return ret;
+ }
+
+- ret = wait_event_interruptible_timeout(priv->wait_command_queue,
++ ret = wait_event_timeout(priv->wait_command_queue,
+ !test_bit(STATUS_HCMD_ACTIVE, &priv->status),
+ HOST_COMPLETE_TIMEOUT);
+ if (!ret) {
--- /dev/null
+From 9d898966c4a07e4a5092215b5a2829d0ef02baa2 Mon Sep 17 00:00:00 2001
+From: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
+Date: Wed, 24 Aug 2011 13:14:22 -0300
+Subject: jsm: remove buggy write queue
+
+From: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
+
+commit 9d898966c4a07e4a5092215b5a2829d0ef02baa2 upstream.
+
+jsm uses a write queue that copies from uart_core circular buffer. This
+copying however has some bugs, like not wrapping the head counter. Since
+this write queue is also a circular buffer, the consumer function is
+ready to use the uart_core circular buffer directly.
+
+This buggy copying function was making some bytes be dropped when
+transmitting to a raw tty, doing something like this.
+
+[root@hostname ~]$ cat /dev/ttyn1 > cascardo/dump &
+[1] 2658
+[root@hostname ~]$ cat /proc/tty/drivers > /dev/ttyn0
+[root@hostname ~]$ cat /proc/tty/drivers
+/dev/tty /dev/tty 5 0 system:/dev/tty
+/dev/console /dev/console 5 1 system:console
+/dev/ptmx /dev/ptmx 5 2 system
+/dev/vc/0 /dev/vc/0 4 0 system:vtmaster
+jsm /dev/ttyn 250 0-31 serial
+serial /dev/ttyS 4 64-95 serial
+hvc /dev/hvc 229 0-7 system
+pty_slave /dev/pts 136 0-1048575 pty:slave
+pty_master /dev/ptm 128 0-1048575 pty:master
+unknown /dev/tty 4 1-63 console
+[root@hostname ~]$ cat cascardo/dump
+/dev/tty /dev/tty 5 0 system:/dev/tty
+/dev/console /dev/console 5 1 system:console
+/dev/ptmx /dev/ptmx 5 2 system
+/dev/vc/0 /dev/vc/0 4 0 system:vtmaste[root@hostname ~]$
+
+This patch drops the driver write queue entirely, using the circular
+buffer from uart_core only.
+
+Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/tty/serial/jsm/jsm.h | 7 --
+ drivers/tty/serial/jsm/jsm_driver.c | 1
+ drivers/tty/serial/jsm/jsm_neo.c | 29 +++++------
+ drivers/tty/serial/jsm/jsm_tty.c | 94 ++++--------------------------------
+ 4 files changed, 28 insertions(+), 103 deletions(-)
+
+--- a/drivers/tty/serial/jsm/jsm.h
++++ b/drivers/tty/serial/jsm/jsm.h
+@@ -183,10 +183,8 @@ struct jsm_board
+ /* Our Read/Error/Write queue sizes */
+ #define RQUEUEMASK 0x1FFF /* 8 K - 1 */
+ #define EQUEUEMASK 0x1FFF /* 8 K - 1 */
+-#define WQUEUEMASK 0x0FFF /* 4 K - 1 */
+ #define RQUEUESIZE (RQUEUEMASK + 1)
+ #define EQUEUESIZE RQUEUESIZE
+-#define WQUEUESIZE (WQUEUEMASK + 1)
+
+
+ /************************************************************************
+@@ -226,10 +224,6 @@ struct jsm_channel {
+ u16 ch_e_head; /* Head location of the error queue */
+ u16 ch_e_tail; /* Tail location of the error queue */
+
+- u8 *ch_wqueue; /* Our write queue buffer - malloc'ed */
+- u16 ch_w_head; /* Head location of the write queue */
+- u16 ch_w_tail; /* Tail location of the write queue */
+-
+ u64 ch_rxcount; /* total of data received so far */
+ u64 ch_txcount; /* total of data transmitted so far */
+
+@@ -378,7 +372,6 @@ extern int jsm_debug;
+ * Prototypes for non-static functions used in more than one module
+ *
+ *************************************************************************/
+-int jsm_tty_write(struct uart_port *port);
+ int jsm_tty_init(struct jsm_board *);
+ int jsm_uart_port_init(struct jsm_board *);
+ int jsm_remove_uart_port(struct jsm_board *);
+--- a/drivers/tty/serial/jsm/jsm_driver.c
++++ b/drivers/tty/serial/jsm/jsm_driver.c
+@@ -211,7 +211,6 @@ static void __devexit jsm_remove_one(str
+ if (brd->channels[i]) {
+ kfree(brd->channels[i]->ch_rqueue);
+ kfree(brd->channels[i]->ch_equeue);
+- kfree(brd->channels[i]->ch_wqueue);
+ kfree(brd->channels[i]);
+ }
+ }
+--- a/drivers/tty/serial/jsm/jsm_neo.c
++++ b/drivers/tty/serial/jsm/jsm_neo.c
+@@ -496,12 +496,15 @@ static void neo_copy_data_from_queue_to_
+ int s;
+ int qlen;
+ u32 len_written = 0;
++ struct circ_buf *circ;
+
+ if (!ch)
+ return;
+
++ circ = &ch->uart_port.state->xmit;
++
+ /* No data to write to the UART */
+- if (ch->ch_w_tail == ch->ch_w_head)
++ if (uart_circ_empty(circ))
+ return;
+
+ /* If port is "stopped", don't send any data to the UART */
+@@ -517,11 +520,10 @@ static void neo_copy_data_from_queue_to_
+ if (ch->ch_cached_lsr & UART_LSR_THRE) {
+ ch->ch_cached_lsr &= ~(UART_LSR_THRE);
+
+- writeb(ch->ch_wqueue[ch->ch_w_tail], &ch->ch_neo_uart->txrx);
++ writeb(circ->buf[circ->tail], &ch->ch_neo_uart->txrx);
+ jsm_printk(WRITE, INFO, &ch->ch_bd->pci_dev,
+- "Tx data: %x\n", ch->ch_wqueue[ch->ch_w_head]);
+- ch->ch_w_tail++;
+- ch->ch_w_tail &= WQUEUEMASK;
++ "Tx data: %x\n", circ->buf[circ->head]);
++ circ->tail = (circ->tail + 1) & (UART_XMIT_SIZE - 1);
+ ch->ch_txcount++;
+ }
+ return;
+@@ -536,36 +538,36 @@ static void neo_copy_data_from_queue_to_
+ n = UART_17158_TX_FIFOSIZE - ch->ch_t_tlevel;
+
+ /* cache head and tail of queue */
+- head = ch->ch_w_head & WQUEUEMASK;
+- tail = ch->ch_w_tail & WQUEUEMASK;
+- qlen = (head - tail) & WQUEUEMASK;
++ head = circ->head & (UART_XMIT_SIZE - 1);
++ tail = circ->tail & (UART_XMIT_SIZE - 1);
++ qlen = uart_circ_chars_pending(circ);
+
+ /* Find minimum of the FIFO space, versus queue length */
+ n = min(n, qlen);
+
+ while (n > 0) {
+
+- s = ((head >= tail) ? head : WQUEUESIZE) - tail;
++ s = ((head >= tail) ? head : UART_XMIT_SIZE) - tail;
+ s = min(s, n);
+
+ if (s <= 0)
+ break;
+
+- memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s);
++ memcpy_toio(&ch->ch_neo_uart->txrxburst, circ->buf + tail, s);
+ /* Add and flip queue if needed */
+- tail = (tail + s) & WQUEUEMASK;
++ tail = (tail + s) & (UART_XMIT_SIZE - 1);
+ n -= s;
+ ch->ch_txcount += s;
+ len_written += s;
+ }
+
+ /* Update the final tail */
+- ch->ch_w_tail = tail & WQUEUEMASK;
++ circ->tail = tail & (UART_XMIT_SIZE - 1);
+
+ if (len_written >= ch->ch_t_tlevel)
+ ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM);
+
+- if (!jsm_tty_write(&ch->uart_port))
++ if (uart_circ_empty(circ))
+ uart_write_wakeup(&ch->uart_port);
+ }
+
+@@ -946,7 +948,6 @@ static void neo_param(struct jsm_channel
+ if ((ch->ch_c_cflag & (CBAUD)) == 0) {
+ ch->ch_r_head = ch->ch_r_tail = 0;
+ ch->ch_e_head = ch->ch_e_tail = 0;
+- ch->ch_w_head = ch->ch_w_tail = 0;
+
+ neo_flush_uart_write(ch);
+ neo_flush_uart_read(ch);
+--- a/drivers/tty/serial/jsm/jsm_tty.c
++++ b/drivers/tty/serial/jsm/jsm_tty.c
+@@ -118,6 +118,19 @@ static void jsm_tty_set_mctrl(struct uar
+ udelay(10);
+ }
+
++/*
++ * jsm_tty_write()
++ *
++ * Take data from the user or kernel and send it out to the FEP.
++ * In here exists all the Transparent Print magic as well.
++ */
++static void jsm_tty_write(struct uart_port *port)
++{
++ struct jsm_channel *channel;
++ channel = container_of(port, struct jsm_channel, uart_port);
++ channel->ch_bd->bd_ops->copy_data_from_queue_to_uart(channel);
++}
++
+ static void jsm_tty_start_tx(struct uart_port *port)
+ {
+ struct jsm_channel *channel = (struct jsm_channel *)port;
+@@ -216,14 +229,6 @@ static int jsm_tty_open(struct uart_port
+ return -ENOMEM;
+ }
+ }
+- if (!channel->ch_wqueue) {
+- channel->ch_wqueue = kzalloc(WQUEUESIZE, GFP_KERNEL);
+- if (!channel->ch_wqueue) {
+- jsm_printk(INIT, ERR, &channel->ch_bd->pci_dev,
+- "unable to allocate write queue buf");
+- return -ENOMEM;
+- }
+- }
+
+ channel->ch_flags &= ~(CH_OPENING);
+ /*
+@@ -237,7 +242,6 @@ static int jsm_tty_open(struct uart_port
+ */
+ channel->ch_r_head = channel->ch_r_tail = 0;
+ channel->ch_e_head = channel->ch_e_tail = 0;
+- channel->ch_w_head = channel->ch_w_tail = 0;
+
+ brd->bd_ops->flush_uart_write(channel);
+ brd->bd_ops->flush_uart_read(channel);
+@@ -836,75 +840,3 @@ void jsm_check_queue_flow_control(struct
+ }
+ }
+ }
+-
+-/*
+- * jsm_tty_write()
+- *
+- * Take data from the user or kernel and send it out to the FEP.
+- * In here exists all the Transparent Print magic as well.
+- */
+-int jsm_tty_write(struct uart_port *port)
+-{
+- int bufcount;
+- int data_count = 0,data_count1 =0;
+- u16 head;
+- u16 tail;
+- u16 tmask;
+- u32 remain;
+- int temp_tail = port->state->xmit.tail;
+- struct jsm_channel *channel = (struct jsm_channel *)port;
+-
+- tmask = WQUEUEMASK;
+- head = (channel->ch_w_head) & tmask;
+- tail = (channel->ch_w_tail) & tmask;
+-
+- if ((bufcount = tail - head - 1) < 0)
+- bufcount += WQUEUESIZE;
+-
+- bufcount = min(bufcount, 56);
+- remain = WQUEUESIZE - head;
+-
+- data_count = 0;
+- if (bufcount >= remain) {
+- bufcount -= remain;
+- while ((port->state->xmit.head != temp_tail) &&
+- (data_count < remain)) {
+- channel->ch_wqueue[head++] =
+- port->state->xmit.buf[temp_tail];
+-
+- temp_tail++;
+- temp_tail &= (UART_XMIT_SIZE - 1);
+- data_count++;
+- }
+- if (data_count == remain) head = 0;
+- }
+-
+- data_count1 = 0;
+- if (bufcount > 0) {
+- remain = bufcount;
+- while ((port->state->xmit.head != temp_tail) &&
+- (data_count1 < remain)) {
+- channel->ch_wqueue[head++] =
+- port->state->xmit.buf[temp_tail];
+-
+- temp_tail++;
+- temp_tail &= (UART_XMIT_SIZE - 1);
+- data_count1++;
+-
+- }
+- }
+-
+- port->state->xmit.tail = temp_tail;
+-
+- data_count += data_count1;
+- if (data_count) {
+- head &= tmask;
+- channel->ch_w_head = head;
+- }
+-
+- if (data_count) {
+- channel->ch_bd->bd_ops->copy_data_from_queue_to_uart(channel);
+- }
+-
+- return data_count;
+-}
--- /dev/null
+From f5252e009d5b87071a919221e4f6624184005368 Mon Sep 17 00:00:00 2001
+From: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
+Date: Mon, 31 Oct 2011 17:08:13 -0700
+Subject: mm: avoid null pointer access in vm_struct via /proc/vmallocinfo
+
+From: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
+
+commit f5252e009d5b87071a919221e4f6624184005368 upstream.
+
+The /proc/vmallocinfo shows information about vmalloc allocations in
+vmlist that is a linklist of vm_struct. It, however, may access pages
+field of vm_struct where a page was not allocated. This results in a null
+pointer access and leads to a kernel panic.
+
+Why this happens: In __vmalloc_node_range() called from vmalloc(), newly
+allocated vm_struct is added to vmlist at __get_vm_area_node() and then,
+some fields of vm_struct such as nr_pages and pages are set at
+__vmalloc_area_node(). In other words, it is added to vmlist before it is
+fully initialized. At the same time, when the /proc/vmallocinfo is read,
+it accesses the pages field of vm_struct according to the nr_pages field
+at show_numa_info(). Thus, a null pointer access happens.
+
+The patch adds the newly allocated vm_struct to the vmlist *after* it is
+fully initialized. So, it can avoid accessing the pages field with
+unallocated page when show_numa_info() is called.
+
+Signed-off-by: Mitsuo Hayasaka <mitsuo.hayasaka.hu@hitachi.com>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Namhyung Kim <namhyung@gmail.com>
+Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Cc: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/vmalloc.h | 1
+ mm/vmalloc.c | 65 +++++++++++++++++++++++++++++++++++-------------
+ 2 files changed, 49 insertions(+), 17 deletions(-)
+
+--- a/include/linux/vmalloc.h
++++ b/include/linux/vmalloc.h
+@@ -13,6 +13,7 @@ struct vm_area_struct; /* vma defining
+ #define VM_MAP 0x00000004 /* vmap()ed pages */
+ #define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */
+ #define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
++#define VM_UNLIST 0x00000020 /* vm_struct is not listed in vmlist */
+ /* bits [20..32] reserved for arch specific ioremap internals */
+
+ /*
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -1253,18 +1253,22 @@ EXPORT_SYMBOL_GPL(map_vm_area);
+ DEFINE_RWLOCK(vmlist_lock);
+ struct vm_struct *vmlist;
+
+-static void insert_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va,
++static void setup_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va,
+ unsigned long flags, void *caller)
+ {
+- struct vm_struct *tmp, **p;
+-
+ vm->flags = flags;
+ vm->addr = (void *)va->va_start;
+ vm->size = va->va_end - va->va_start;
+ vm->caller = caller;
+ va->private = vm;
+ va->flags |= VM_VM_AREA;
++}
++
++static void insert_vmalloc_vmlist(struct vm_struct *vm)
++{
++ struct vm_struct *tmp, **p;
+
++ vm->flags &= ~VM_UNLIST;
+ write_lock(&vmlist_lock);
+ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) {
+ if (tmp->addr >= vm->addr)
+@@ -1275,6 +1279,13 @@ static void insert_vmalloc_vm(struct vm_
+ write_unlock(&vmlist_lock);
+ }
+
++static void insert_vmalloc_vm(struct vm_struct *vm, struct vmap_area *va,
++ unsigned long flags, void *caller)
++{
++ setup_vmalloc_vm(vm, va, flags, caller);
++ insert_vmalloc_vmlist(vm);
++}
++
+ static struct vm_struct *__get_vm_area_node(unsigned long size,
+ unsigned long align, unsigned long flags, unsigned long start,
+ unsigned long end, int node, gfp_t gfp_mask, void *caller)
+@@ -1313,7 +1324,18 @@ static struct vm_struct *__get_vm_area_n
+ return NULL;
+ }
+
+- insert_vmalloc_vm(area, va, flags, caller);
++ /*
++ * When this function is called from __vmalloc_node_range,
++ * we do not add vm_struct to vmlist here to avoid
++ * accessing uninitialized members of vm_struct such as
++ * pages and nr_pages fields. They will be set later.
++ * To distinguish it from others, we use a VM_UNLIST flag.
++ */
++ if (flags & VM_UNLIST)
++ setup_vmalloc_vm(area, va, flags, caller);
++ else
++ insert_vmalloc_vm(area, va, flags, caller);
++
+ return area;
+ }
+
+@@ -1381,17 +1403,20 @@ struct vm_struct *remove_vm_area(const v
+ va = find_vmap_area((unsigned long)addr);
+ if (va && va->flags & VM_VM_AREA) {
+ struct vm_struct *vm = va->private;
+- struct vm_struct *tmp, **p;
+- /*
+- * remove from list and disallow access to this vm_struct
+- * before unmap. (address range confliction is maintained by
+- * vmap.)
+- */
+- write_lock(&vmlist_lock);
+- for (p = &vmlist; (tmp = *p) != vm; p = &tmp->next)
+- ;
+- *p = tmp->next;
+- write_unlock(&vmlist_lock);
++
++ if (!(vm->flags & VM_UNLIST)) {
++ struct vm_struct *tmp, **p;
++ /*
++ * remove from list and disallow access to
++ * this vm_struct before unmap. (address range
++ * confliction is maintained by vmap.)
++ */
++ write_lock(&vmlist_lock);
++ for (p = &vmlist; (tmp = *p) != vm; p = &tmp->next)
++ ;
++ *p = tmp->next;
++ write_unlock(&vmlist_lock);
++ }
+
+ vmap_debug_free_range(va->va_start, va->va_end);
+ free_unmap_vmap_area(va);
+@@ -1602,8 +1627,8 @@ void *__vmalloc_node_range(unsigned long
+ if (!size || (size >> PAGE_SHIFT) > totalram_pages)
+ return NULL;
+
+- area = __get_vm_area_node(size, align, VM_ALLOC, start, end, node,
+- gfp_mask, caller);
++ area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNLIST,
++ start, end, node, gfp_mask, caller);
+
+ if (!area)
+ return NULL;
+@@ -1611,6 +1636,12 @@ void *__vmalloc_node_range(unsigned long
+ addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller);
+
+ /*
++ * In this function, newly allocated vm_struct is not added
++ * to vmlist at __get_vm_area_node(). so, it is added here.
++ */
++ insert_vmalloc_vmlist(area);
++
++ /*
+ * A ref_count = 3 is needed because the vm_struct and vmap_area
+ * structures allocated in the __get_vm_area_node() function contain
+ * references to the virtual address of the vmalloc'ed block.
--- /dev/null
+From 1458d160de3f1862aeaac57447ba96e7857ac52b Mon Sep 17 00:00:00 2001
+From: Shubhrajyoti D <shubhrajyoti@ti.com>
+Date: Mon, 24 Oct 2011 15:54:24 +0530
+Subject: OMAP: SPI: Fix the trying to free nonexistent resource error
+
+From: Shubhrajyoti D <shubhrajyoti@ti.com>
+
+commit 1458d160de3f1862aeaac57447ba96e7857ac52b upstream.
+
+Currently there is a request_mem_region(r->start, ..
+followed by r->start += pdata->regs_offset;
+
+And then in remove
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, resource_size(r));
+
+Here the offset addition is not taken care. Fix the code for the
+same.
+
+Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
+Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/spi/spi-omap2-mcspi.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/spi/spi-omap2-mcspi.c
++++ b/drivers/spi/spi-omap2-mcspi.c
+@@ -1116,15 +1116,16 @@ static int __init omap2_mcspi_probe(stru
+ status = -ENODEV;
+ goto err1;
+ }
++
++ r->start += pdata->regs_offset;
++ r->end += pdata->regs_offset;
++ mcspi->phys = r->start;
+ if (!request_mem_region(r->start, resource_size(r),
+ dev_name(&pdev->dev))) {
+ status = -EBUSY;
+ goto err1;
+ }
+
+- r->start += pdata->regs_offset;
+- r->end += pdata->regs_offset;
+- mcspi->phys = r->start;
+ mcspi->base = ioremap(r->start, resource_size(r));
+ if (!mcspi->base) {
+ dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");
--- /dev/null
+From 1fa1e7f615f4d3ae436fa319af6e4eebdd4026a8 Mon Sep 17 00:00:00 2001
+From: Andy Whitcroft <apw@canonical.com>
+Date: Wed, 2 Nov 2011 09:44:39 +0100
+Subject: readlinkat: ensure we return ENOENT for the empty pathname for normal lookups
+
+From: Andy Whitcroft <apw@canonical.com>
+
+commit 1fa1e7f615f4d3ae436fa319af6e4eebdd4026a8 upstream.
+
+Since the commit below which added O_PATH support to the *at() calls, the
+error return for readlink/readlinkat for the empty pathname has switched
+from ENOENT to EINVAL:
+
+ commit 65cfc6722361570bfe255698d9cd4dccaf47570d
+ Author: Al Viro <viro@zeniv.linux.org.uk>
+ Date: Sun Mar 13 15:56:26 2011 -0400
+
+ readlinkat(), fchownat() and fstatat() with empty relative pathnames
+
+This is both unexpected for userspace and makes readlink/readlinkat
+inconsistant with all other interfaces; and inconsistant with our stated
+return for these pathnames.
+
+As the readlinkat call does not have a flags parameter we cannot use the
+AT_EMPTY_PATH approach used in the other calls. Therefore expose whether
+the original path is infact entry via a new user_path_at_empty() path
+lookup function. Use this to determine whether to default to EINVAL or
+ENOENT for failures.
+
+Addresses http://bugs.launchpad.net/bugs/817187
+
+[akpm@linux-foundation.org: remove unused getname_flags()]
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/namei.c | 18 +++++++++++++-----
+ fs/stat.c | 5 +++--
+ include/linux/namei.h | 1 +
+ 3 files changed, 17 insertions(+), 7 deletions(-)
+
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -137,7 +137,7 @@ static int do_getname(const char __user
+ return retval;
+ }
+
+-static char *getname_flags(const char __user * filename, int flags)
++static char *getname_flags(const char __user *filename, int flags, int *empty)
+ {
+ char *tmp, *result;
+
+@@ -148,6 +148,8 @@ static char *getname_flags(const char __
+
+ result = tmp;
+ if (retval < 0) {
++ if (retval == -ENOENT && empty)
++ *empty = 1;
+ if (retval != -ENOENT || !(flags & LOOKUP_EMPTY)) {
+ __putname(tmp);
+ result = ERR_PTR(retval);
+@@ -160,7 +162,7 @@ static char *getname_flags(const char __
+
+ char *getname(const char __user * filename)
+ {
+- return getname_flags(filename, 0);
++ return getname_flags(filename, 0, 0);
+ }
+
+ #ifdef CONFIG_AUDITSYSCALL
+@@ -1798,11 +1800,11 @@ struct dentry *lookup_one_len(const char
+ return __lookup_hash(&this, base, NULL);
+ }
+
+-int user_path_at(int dfd, const char __user *name, unsigned flags,
+- struct path *path)
++int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
++ struct path *path, int *empty)
+ {
+ struct nameidata nd;
+- char *tmp = getname_flags(name, flags);
++ char *tmp = getname_flags(name, flags, empty);
+ int err = PTR_ERR(tmp);
+ if (!IS_ERR(tmp)) {
+
+@@ -1816,6 +1818,12 @@ int user_path_at(int dfd, const char __u
+ return err;
+ }
+
++int user_path_at(int dfd, const char __user *name, unsigned flags,
++ struct path *path)
++{
++ return user_path_at_empty(dfd, name, flags, path, 0);
++}
++
+ static int user_path_parent(int dfd, const char __user *path,
+ struct nameidata *nd, char **name)
+ {
+--- a/fs/stat.c
++++ b/fs/stat.c
+@@ -294,15 +294,16 @@ SYSCALL_DEFINE4(readlinkat, int, dfd, co
+ {
+ struct path path;
+ int error;
++ int empty = 0;
+
+ if (bufsiz <= 0)
+ return -EINVAL;
+
+- error = user_path_at(dfd, pathname, LOOKUP_EMPTY, &path);
++ error = user_path_at_empty(dfd, pathname, LOOKUP_EMPTY, &path, &empty);
+ if (!error) {
+ struct inode *inode = path.dentry->d_inode;
+
+- error = -EINVAL;
++ error = empty ? -ENOENT : -EINVAL;
+ if (inode->i_op->readlink) {
+ error = security_inode_readlink(path.dentry);
+ if (!error) {
+--- a/include/linux/namei.h
++++ b/include/linux/namei.h
+@@ -67,6 +67,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA
+ #define LOOKUP_EMPTY 0x4000
+
+ extern int user_path_at(int, const char __user *, unsigned, struct path *);
++extern int user_path_at_empty(int, const char __user *, unsigned, struct path *, int *empty);
+
+ #define user_path(name, path) user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW, path)
+ #define user_lpath(name, path) user_path_at(AT_FDCWD, name, 0, path)
plat-mxc-iomux-v3.h-implicitly-enable-pull-up-down-when-that-s-desired.patch
arm-pxa-cm-x300-properly-set-bt_reset-pin.patch
arm-mach-ux500-unlock-i-d-l2x0-caches-before-init.patch
+mm-avoid-null-pointer-access-in-vm_struct-via-proc-vmallocinfo.patch
+alsa-hda-fix-adc-input-amp-handling-for-cx20549-codec.patch
+iwlagn-do-not-use-interruptible-waits.patch
+um-fix-ubd-cow-size.patch
+readlinkat-ensure-we-return-enoent-for-the-empty-pathname-for-normal-lookups.patch
+um-fix-kmalloc-argument-order-in-um-vdso-vma.c.patch
+omap-spi-fix-the-trying-to-free-nonexistent-resource-error.patch
+jsm-remove-buggy-write-queue.patch
--- /dev/null
+From 0d65ede0a605d6252acc5c8a9c536c4cd0211f3c Mon Sep 17 00:00:00 2001
+From: Dave Jones <davej@redhat.com>
+Date: Mon, 24 Oct 2011 18:15:32 -0400
+Subject: um: Fix kmalloc argument order in um/vdso/vma.c
+
+From: Dave Jones <davej@redhat.com>
+
+commit 0d65ede0a605d6252acc5c8a9c536c4cd0211f3c upstream.
+
+kmalloc size is 1st arg, not second.
+
+Signed-off-by: Dave Jones <davej@redhat.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/um/sys-x86_64/vdso/vma.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/um/sys-x86_64/vdso/vma.c
++++ b/arch/um/sys-x86_64/vdso/vma.c
+@@ -28,7 +28,7 @@ static int __init init_vdso(void)
+
+ um_vdso_addr = task_size - PAGE_SIZE;
+
+- vdsop = kmalloc(GFP_KERNEL, sizeof(struct page *));
++ vdsop = kmalloc(sizeof(struct page *), GFP_KERNEL);
+ if (!vdsop)
+ goto oom;
+
--- /dev/null
+From 8535639810e578960233ad39def3ac2157b0c3ec Mon Sep 17 00:00:00 2001
+From: Richard Weinberger <richard@nod.at>
+Date: Wed, 2 Nov 2011 13:17:27 +0100
+Subject: um: fix ubd cow size
+
+From: Richard Weinberger <richard@nod.at>
+
+commit 8535639810e578960233ad39def3ac2157b0c3ec upstream.
+
+ubd_file_size() cannot use ubd_dev->cow.file because at this time
+ubd_dev->cow.file is not initialized.
+Therefore, ubd_file_size() will always report a wrong disk size when
+COW files are used.
+Reading from /dev/ubd* would crash the kernel.
+
+We have to read the correct disk size from the COW file's backing
+file.
+
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/um/drivers/ubd_kern.c | 31 ++++++++++++++++++++++++++++++-
+ 1 file changed, 30 insertions(+), 1 deletion(-)
+
+--- a/arch/um/drivers/ubd_kern.c
++++ b/arch/um/drivers/ubd_kern.c
+@@ -513,8 +513,37 @@ __uml_exitcall(kill_io_thread);
+ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
+ {
+ char *file;
++ int fd;
++ int err;
+
+- file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
++ __u32 version;
++ __u32 align;
++ char *backing_file;
++ time_t mtime;
++ unsigned long long size;
++ int sector_size;
++ int bitmap_offset;
++
++ if (ubd_dev->file && ubd_dev->cow.file) {
++ file = ubd_dev->cow.file;
++
++ goto out;
++ }
++
++ fd = os_open_file(ubd_dev->file, global_openflags, 0);
++ if (fd < 0)
++ return fd;
++
++ err = read_cow_header(file_reader, &fd, &version, &backing_file, \
++ &mtime, &size, §or_size, &align, &bitmap_offset);
++ os_close_file(fd);
++
++ if(err == -EINVAL)
++ file = ubd_dev->file;
++ else
++ file = backing_file;
++
++out:
+ return os_file_size(file, size_out);
+ }
+