]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.1 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 22 Nov 2011 21:10:03 +0000 (13:10 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 22 Nov 2011 21:10:03 +0000 (13:10 -0800)
added patches:
alsa-hda-fix-eld-memory-leak.patch
drivers-base-node.c-fix-compilation-error-with-older-versions-of-gcc.patch
nfs-when-attempting-to-open-a-directory-fall-back-on-normal-lookup-try-5.patch
pch_phub-fix-mac-address-writing-issue-for-lapis-ml7831.patch
pch_phub-support-new-device-lapis-semiconductor-ml7831-ioh.patch
pch_uart-fix-dma-resource-leak-issue.patch
pch_uart-fix-hw-flow-control-issue.patch
pch_uart-support-new-device-lapis-semiconductor-ml7831-ioh.patch
pcie-gadget-spear-add-platform-prefix-for-platform-modalias.patch
tty-hvc_dcc-fix-duplicate-character-inputs.patch
tty-ldisc-allow-waiting-for-ldisc-arbitrarily-long.patch
tty-ldisc-move-wait-idle-to-caller.patch
tty-ldisc-wait-for-ldisc-infinitely-in-hangup.patch
usb-xhci-clear-warm-reset-change-event-during-init.patch
usb-xhci-fix-lockdep-warning-on-endpoint-timeout.patch
usb-xhci-resume-root-hubs-when-the-controller-resumes.patch
xhci-set-slot-and-ep0-flags-for-address-command.patch

18 files changed:
queue-3.1/alsa-hda-fix-eld-memory-leak.patch [new file with mode: 0644]
queue-3.1/drivers-base-node.c-fix-compilation-error-with-older-versions-of-gcc.patch [new file with mode: 0644]
queue-3.1/nfs-when-attempting-to-open-a-directory-fall-back-on-normal-lookup-try-5.patch [new file with mode: 0644]
queue-3.1/pch_phub-fix-mac-address-writing-issue-for-lapis-ml7831.patch [new file with mode: 0644]
queue-3.1/pch_phub-support-new-device-lapis-semiconductor-ml7831-ioh.patch [new file with mode: 0644]
queue-3.1/pch_uart-fix-dma-resource-leak-issue.patch [new file with mode: 0644]
queue-3.1/pch_uart-fix-hw-flow-control-issue.patch [new file with mode: 0644]
queue-3.1/pch_uart-support-new-device-lapis-semiconductor-ml7831-ioh.patch [new file with mode: 0644]
queue-3.1/pcie-gadget-spear-add-platform-prefix-for-platform-modalias.patch [new file with mode: 0644]
queue-3.1/series
queue-3.1/tty-hvc_dcc-fix-duplicate-character-inputs.patch [new file with mode: 0644]
queue-3.1/tty-ldisc-allow-waiting-for-ldisc-arbitrarily-long.patch [new file with mode: 0644]
queue-3.1/tty-ldisc-move-wait-idle-to-caller.patch [new file with mode: 0644]
queue-3.1/tty-ldisc-wait-for-ldisc-infinitely-in-hangup.patch [new file with mode: 0644]
queue-3.1/usb-xhci-clear-warm-reset-change-event-during-init.patch [new file with mode: 0644]
queue-3.1/usb-xhci-fix-lockdep-warning-on-endpoint-timeout.patch [new file with mode: 0644]
queue-3.1/usb-xhci-resume-root-hubs-when-the-controller-resumes.patch [new file with mode: 0644]
queue-3.1/xhci-set-slot-and-ep0-flags-for-address-command.patch [new file with mode: 0644]

diff --git a/queue-3.1/alsa-hda-fix-eld-memory-leak.patch b/queue-3.1/alsa-hda-fix-eld-memory-leak.patch
new file mode 100644 (file)
index 0000000..cc0c8bb
--- /dev/null
@@ -0,0 +1,86 @@
+From fengguang.wu@intel.com  Tue Nov 22 12:59:25 2011
+From: Wu Fengguang <fengguang.wu@intel.com>
+Date: Tue, 22 Nov 2011 16:58:35 +0800
+Subject: ALSA: hda - fix ELD memory leak
+To: "stable@vger.kernel.org" <stable@vger.kernel.org>
+Cc: "gregkh@suse.de" <gregkh@suse.de>, "Bossart, Pierre-louis" <pierre-louis.bossart@intel.com>, "stable@kernel.org" <stable@kernel.org>, "swarren@nvidia.com" <swarren@nvidia.com>, "tiwai@suse.de" <tiwai@suse.de>
+Message-ID: <20111122085835.GB30457@localhost>
+Content-Disposition: inline
+
+
+Backported from commit b95d68b8179764e29558b75cec35ef4a6a98925b.
+
+memset(eld) clears eld->proc_entry which will leak the struct
+snd_info_entry when unloading module.
+
+Fix it by
+- memset only the fields before eld->eld_buffer
+- set eld->eld_valid to true _after_ all eld fields have been filled
+
+Cc: Pierre-louis Bossart <pierre-louis.bossart@intel.com>
+Acked-by: Stephen Warren <swarren@nvidia.com>
+Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ sound/pci/hda/hda_eld.c    |    5 +----
+ sound/pci/hda/patch_hdmi.c |   15 +++++++++------
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+--- a/sound/pci/hda/hda_eld.c
++++ b/sound/pci/hda/hda_eld.c
+@@ -297,10 +297,10 @@ static int hdmi_update_eld(struct hdmi_e
+                                       buf + ELD_FIXED_BYTES + mnl + 3 * i);
+       }
++      e->eld_valid = true;
+       return 0;
+ out_fail:
+-      e->eld_ver = 0;
+       return -EINVAL;
+ }
+@@ -318,9 +318,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *el
+       int size;
+       unsigned char *buf;
+-      if (!eld->eld_valid)
+-              return -ENOENT;
+-
+       size = snd_hdmi_get_eld_size(codec, nid);
+       if (size == 0) {
+               /* wfg: workaround for ASUS P5E-VM HDMI board */
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -920,20 +920,23 @@ static void hdmi_present_sense(struct hd
+        * the unsolicited response to avoid custom WARs.
+        */
+       int present = snd_hda_pin_sense(codec, pin_nid);
++      bool eld_valid = false;
+-      memset(eld, 0, sizeof(*eld));
++#ifdef CONFIG_PROC_FS
++      memset(eld, 0, offsetof(struct hdmi_eld, proc_entry));
++#else
++      memset(eld, 0, sizeof(struct hdmi_eld));
++#endif
+       eld->monitor_present    = !!(present & AC_PINSENSE_PRESENCE);
+       if (eld->monitor_present)
+-              eld->eld_valid  = !!(present & AC_PINSENSE_ELDV);
+-      else
+-              eld->eld_valid  = 0;
++              eld_valid       = !!(present & AC_PINSENSE_ELDV);
+       printk(KERN_INFO
+               "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
+-              codec->addr, pin_nid, eld->monitor_present, eld->eld_valid);
++              codec->addr, pin_nid, eld->monitor_present, eld_valid);
+-      if (eld->eld_valid)
++      if (eld_valid)
+               if (!snd_hdmi_get_eld(eld, codec, pin_nid))
+                       snd_hdmi_show_eld(eld);
diff --git a/queue-3.1/drivers-base-node.c-fix-compilation-error-with-older-versions-of-gcc.patch b/queue-3.1/drivers-base-node.c-fix-compilation-error-with-older-versions-of-gcc.patch
new file mode 100644 (file)
index 0000000..bf98c69
--- /dev/null
@@ -0,0 +1,57 @@
+From 91a13c281d7d4648c0b32dede11a0144c4e7984c Mon Sep 17 00:00:00 2001
+From: Claudio Scordino <claudio@evidence.eu.com>
+Date: Thu, 17 Nov 2011 11:08:32 +0100
+Subject: drivers/base/node.c: fix compilation error with older versions of gcc
+
+From: Claudio Scordino <claudio@evidence.eu.com>
+
+commit 91a13c281d7d4648c0b32dede11a0144c4e7984c upstream.
+
+Patch to fix the error message "directives may not be used inside a macro
+argument" which appears when the kernel is compiled for the cris architecture.
+
+Signed-off-by: Claudio Scordino <claudio@evidence.eu.com>
+Acked-by: David Rientjes <rientjes@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/base/node.c |   14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/drivers/base/node.c
++++ b/drivers/base/node.c
+@@ -127,12 +127,13 @@ static ssize_t node_read_meminfo(struct
+                      nid, K(node_page_state(nid, NR_WRITEBACK)),
+                      nid, K(node_page_state(nid, NR_FILE_PAGES)),
+                      nid, K(node_page_state(nid, NR_FILE_MAPPED)),
+-                     nid, K(node_page_state(nid, NR_ANON_PAGES)
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
++                     nid, K(node_page_state(nid, NR_ANON_PAGES)
+                       + node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) *
+-                      HPAGE_PMD_NR
++                      HPAGE_PMD_NR),
++#else
++                     nid, K(node_page_state(nid, NR_ANON_PAGES)),
+ #endif
+-                     ),
+                      nid, K(node_page_state(nid, NR_SHMEM)),
+                      nid, node_page_state(nid, NR_KERNEL_STACK) *
+                               THREAD_SIZE / 1024,
+@@ -143,13 +144,14 @@ static ssize_t node_read_meminfo(struct
+                      nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) +
+                               node_page_state(nid, NR_SLAB_UNRECLAIMABLE)),
+                      nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)),
+-                     nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
++                     nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))
+                       , nid,
+                       K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) *
+-                      HPAGE_PMD_NR)
++                      HPAGE_PMD_NR));
++#else
++                     nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)));
+ #endif
+-                     );
+       n += hugetlb_report_node_meminfo(nid, buf + n);
+       return n;
+ }
diff --git a/queue-3.1/nfs-when-attempting-to-open-a-directory-fall-back-on-normal-lookup-try-5.patch b/queue-3.1/nfs-when-attempting-to-open-a-directory-fall-back-on-normal-lookup-try-5.patch
new file mode 100644 (file)
index 0000000..90f2ce7
--- /dev/null
@@ -0,0 +1,162 @@
+From 1788ea6e3b2a58cf4fb00206e362d9caff8d86a7 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Fri, 4 Nov 2011 13:31:21 -0400
+Subject: nfs: when attempting to open a directory, fall back on normal lookup (try #5)
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit 1788ea6e3b2a58cf4fb00206e362d9caff8d86a7 upstream.
+
+commit d953126 changed how nfs_atomic_lookup handles an -EISDIR return
+from an OPEN call. Prior to that patch, that caused the client to fall
+back to doing a normal lookup. When that patch went in, the code began
+returning that error to userspace. The d_revalidate codepath however
+never had the corresponding change, so it was still possible to end up
+with a NULL ctx->state pointer after that.
+
+That patch caused a regression. When we attempt to open a directory that
+does not have a cached dentry, that open now errors out with EISDIR. If
+you attempt the same open with a cached dentry, it will succeed.
+
+Fix this by reverting the change in nfs_atomic_lookup and allowing
+attempts to open directories to fall back to a normal lookup
+
+Also, add a NFSv4-specific f_ops->open routine that just returns
+-ENOTDIR. This should never be called if things are working properly,
+but if it ever is, then the dprintk may help in debugging.
+
+To facilitate this, a new file_operations field is also added to the
+nfs_rpc_ops struct.
+
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/nfs/dir.c            |    2 +-
+ fs/nfs/file.c           |   32 ++++++++++++++++++++++++++++++++
+ fs/nfs/inode.c          |    2 +-
+ fs/nfs/nfs3proc.c       |    1 +
+ fs/nfs/nfs4proc.c       |    1 +
+ fs/nfs/proc.c           |    1 +
+ include/linux/nfs_fs.h  |    3 +++
+ include/linux/nfs_xdr.h |    1 +
+ 8 files changed, 41 insertions(+), 2 deletions(-)
+
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -1468,12 +1468,12 @@ static struct dentry *nfs_atomic_lookup(
+                               res = NULL;
+                               goto out;
+                       /* This turned out not to be a regular file */
++                      case -EISDIR:
+                       case -ENOTDIR:
+                               goto no_open;
+                       case -ELOOP:
+                               if (!(nd->intent.open.flags & O_NOFOLLOW))
+                                       goto no_open;
+-                      /* case -EISDIR: */
+                       /* case -EINVAL: */
+                       default:
+                               res = ERR_CAST(inode);
+--- a/fs/nfs/file.c
++++ b/fs/nfs/file.c
+@@ -895,3 +895,35 @@ static int nfs_setlease(struct file *fil
+                       file->f_path.dentry->d_name.name, arg);
+       return -EINVAL;
+ }
++
++#ifdef CONFIG_NFS_V4
++static int
++nfs4_file_open(struct inode *inode, struct file *filp)
++{
++      /*
++       * NFSv4 opens are handled in d_lookup and d_revalidate. If we get to
++       * this point, then something is very wrong
++       */
++      dprintk("NFS: %s called! inode=%p filp=%p\n", __func__, inode, filp);
++      return -ENOTDIR;
++}
++
++const struct file_operations nfs4_file_operations = {
++      .llseek         = nfs_file_llseek,
++      .read           = do_sync_read,
++      .write          = do_sync_write,
++      .aio_read       = nfs_file_read,
++      .aio_write      = nfs_file_write,
++      .mmap           = nfs_file_mmap,
++      .open           = nfs4_file_open,
++      .flush          = nfs_file_flush,
++      .release        = nfs_file_release,
++      .fsync          = nfs_file_fsync,
++      .lock           = nfs_lock,
++      .flock          = nfs_flock,
++      .splice_read    = nfs_file_splice_read,
++      .splice_write   = nfs_file_splice_write,
++      .check_flags    = nfs_check_flags,
++      .setlease       = nfs_setlease,
++};
++#endif /* CONFIG_NFS_V4 */
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -291,7 +291,7 @@ nfs_fhget(struct super_block *sb, struct
+                */
+               inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops;
+               if (S_ISREG(inode->i_mode)) {
+-                      inode->i_fop = &nfs_file_operations;
++                      inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops;
+                       inode->i_data.a_ops = &nfs_file_aops;
+                       inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info;
+               } else if (S_ISDIR(inode->i_mode)) {
+--- a/fs/nfs/nfs3proc.c
++++ b/fs/nfs/nfs3proc.c
+@@ -853,6 +853,7 @@ const struct nfs_rpc_ops nfs_v3_clientop
+       .dentry_ops     = &nfs_dentry_operations,
+       .dir_inode_ops  = &nfs3_dir_inode_operations,
+       .file_inode_ops = &nfs3_file_inode_operations,
++      .file_ops       = &nfs_file_operations,
+       .getroot        = nfs3_proc_get_root,
+       .getattr        = nfs3_proc_getattr,
+       .setattr        = nfs3_proc_setattr,
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -6267,6 +6267,7 @@ const struct nfs_rpc_ops nfs_v4_clientop
+       .dentry_ops     = &nfs4_dentry_operations,
+       .dir_inode_ops  = &nfs4_dir_inode_operations,
+       .file_inode_ops = &nfs4_file_inode_operations,
++      .file_ops       = &nfs4_file_operations,
+       .getroot        = nfs4_proc_get_root,
+       .getattr        = nfs4_proc_getattr,
+       .setattr        = nfs4_proc_setattr,
+--- a/fs/nfs/proc.c
++++ b/fs/nfs/proc.c
+@@ -710,6 +710,7 @@ const struct nfs_rpc_ops nfs_v2_clientop
+       .dentry_ops     = &nfs_dentry_operations,
+       .dir_inode_ops  = &nfs_dir_inode_operations,
+       .file_inode_ops = &nfs_file_inode_operations,
++      .file_ops       = &nfs_file_operations,
+       .getroot        = nfs_proc_get_root,
+       .getattr        = nfs_proc_getattr,
+       .setattr        = nfs_proc_setattr,
+--- a/include/linux/nfs_fs.h
++++ b/include/linux/nfs_fs.h
+@@ -410,6 +410,9 @@ extern const struct inode_operations nfs
+ extern const struct inode_operations nfs3_file_inode_operations;
+ #endif /* CONFIG_NFS_V3 */
+ extern const struct file_operations nfs_file_operations;
++#ifdef CONFIG_NFS_V4
++extern const struct file_operations nfs4_file_operations;
++#endif /* CONFIG_NFS_V4 */
+ extern const struct address_space_operations nfs_file_aops;
+ extern const struct address_space_operations nfs_dir_aops;
+--- a/include/linux/nfs_xdr.h
++++ b/include/linux/nfs_xdr.h
+@@ -1194,6 +1194,7 @@ struct nfs_rpc_ops {
+       const struct dentry_operations *dentry_ops;
+       const struct inode_operations *dir_inode_ops;
+       const struct inode_operations *file_inode_ops;
++      const struct file_operations *file_ops;
+       int     (*getroot) (struct nfs_server *, struct nfs_fh *,
+                           struct nfs_fsinfo *);
diff --git a/queue-3.1/pch_phub-fix-mac-address-writing-issue-for-lapis-ml7831.patch b/queue-3.1/pch_phub-fix-mac-address-writing-issue-for-lapis-ml7831.patch
new file mode 100644 (file)
index 0000000..b90f8b5
--- /dev/null
@@ -0,0 +1,41 @@
+From 2a9887919457c6e1bd482e8448223be59d19010a Mon Sep 17 00:00:00 2001
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Date: Fri, 11 Nov 2011 10:12:18 +0900
+Subject: pch_phub: Fix MAC address writing issue for LAPIS ML7831
+
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+
+commit 2a9887919457c6e1bd482e8448223be59d19010a upstream.
+
+ISSUE:
+Using ML7831, MAC address writing doesn't work well.
+
+CAUSE:
+ML7831 and EG20T have the same register map for MAC address access.
+However, this driver processes the writing the same as ML7223.
+This is not true.
+This driver must process the writing the same as EG20T.
+This patch fixes the issue.
+
+Signed-off-by: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Cc: Masayuki Ohtak <masa-korg@dsn.okisemi.com>
+Cc: Alexander Stein <alexander.stein@systec-electronic.com>
+Cc: Denis Turischev <denis@compulab.co.il>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/misc/pch_phub.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/pch_phub.c
++++ b/drivers/misc/pch_phub.c
+@@ -467,7 +467,7 @@ static int pch_phub_write_gbe_mac_addr(s
+       int retval;
+       int i;
+-      if (chip->ioh_type == 1) /* EG20T */
++      if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/
+               retval = pch_phub_gbe_serial_rom_conf(chip);
+       else    /* ML7223 */
+               retval = pch_phub_gbe_serial_rom_conf_mp(chip);
diff --git a/queue-3.1/pch_phub-support-new-device-lapis-semiconductor-ml7831-ioh.patch b/queue-3.1/pch_phub-support-new-device-lapis-semiconductor-ml7831-ioh.patch
new file mode 100644 (file)
index 0000000..c22d389
--- /dev/null
@@ -0,0 +1,93 @@
+From 584ad00ce4bfe594e4c4a89944b3c635187a1ca1 Mon Sep 17 00:00:00 2001
+From: Tomoya MORINAGA <tomoya-linux@dsn.lapis-semi.com>
+Date: Fri, 28 Oct 2011 09:33:13 +0900
+Subject: pch_phub: Support new device LAPIS Semiconductor ML7831 IOH
+
+From: Tomoya MORINAGA <tomoya-linux@dsn.lapis-semi.com>
+
+commit 584ad00ce4bfe594e4c4a89944b3c635187a1ca1 upstream.
+
+ML7831 is companion chip for Intel Atom E6xx series.
+
+Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.lapis-semi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/misc/Kconfig    |   15 ++++++++-------
+ drivers/misc/pch_phub.c |   20 ++++++++++++++++++++
+ 2 files changed, 28 insertions(+), 7 deletions(-)
+
+--- a/drivers/misc/Kconfig
++++ b/drivers/misc/Kconfig
+@@ -472,7 +472,7 @@ config BMP085
+         module will be called bmp085.
+ config PCH_PHUB
+-      tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB"
++      tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB"
+       depends on PCI
+       help
+         This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
+@@ -480,12 +480,13 @@ config PCH_PHUB
+         processor. The Topcliff has MAC address and Option ROM data in SROM.
+         This driver can access MAC address and Option ROM data in SROM.
+-        This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
+-        Output Hub), ML7213 and ML7223.
+-        ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
+-        for MP(Media Phone) use.
+-        ML7213/ML7223 is companion chip for Intel Atom E6xx series.
+-        ML7213/ML7223 is completely compatible for Intel EG20T PCH.
++        This driver also can be used for LAPIS Semiconductor's IOH,
++        ML7213/ML7223/ML7831.
++        ML7213 which is for IVI(In-Vehicle Infotainment) use.
++        ML7223 IOH is for MP(Media Phone) use.
++        ML7831 IOH is for general purpose use.
++        ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
++        ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
+         To compile this driver as a module, choose M here: the module will
+         be called pch_phub.
+--- a/drivers/misc/pch_phub.c
++++ b/drivers/misc/pch_phub.c
+@@ -73,6 +73,9 @@
+ #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB       0x8012 /* for Bus-m */
+ #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB       0x8002 /* for Bus-n */
++/* Macros for ML7831 */
++#define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801
++
+ /* SROM ACCESS Macro */
+ #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
+@@ -757,6 +760,22 @@ static int __devinit pch_phub_probe(stru
+               chip->pch_opt_rom_start_address =\
+                                                PCH_PHUB_ROM_START_ADDR_ML7223;
+               chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
++      } else if (id->driver_data == 5) { /* ML7831 */
++              retval = sysfs_create_file(&pdev->dev.kobj,
++                                         &dev_attr_pch_mac.attr);
++              if (retval)
++                      goto err_sysfs_create;
++
++              retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
++              if (retval)
++                      goto exit_bin_attr;
++
++              /* set the prefech value */
++              iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
++              /* set the interrupt delay value */
++              iowrite32(0x25, chip->pch_phub_base_address + 0x44);
++              chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
++              chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
+       }
+       chip->ioh_type = id->driver_data;
+@@ -841,6 +860,7 @@ static struct pci_device_id pch_phub_pci
+       { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2,  },
+       { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3,  },
+       { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4,  },
++      { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5,  },
+       { }
+ };
+ MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id);
diff --git a/queue-3.1/pch_uart-fix-dma-resource-leak-issue.patch b/queue-3.1/pch_uart-fix-dma-resource-leak-issue.patch
new file mode 100644 (file)
index 0000000..c29e1f5
--- /dev/null
@@ -0,0 +1,71 @@
+From 90f04c2926cfb5bf74533b0a7766bc896f6a0c0e Mon Sep 17 00:00:00 2001
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Date: Fri, 11 Nov 2011 10:55:27 +0900
+Subject: pch_uart: Fix DMA resource leak issue
+
+From: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+
+commit 90f04c2926cfb5bf74533b0a7766bc896f6a0c0e upstream.
+
+Changing UART mode PIO->DMA->PIO->DMA like below, pch_uart driver can't get
+DMA channel resource.
+
+setserial /dev/ttyPCH0 ^low_latency
+setserial /dev/ttyPCH0 low_latency
+
+CAUSE:
+Changing mode using setserial command, ".startup" function which gets DMA
+channel is called before ".verify_port" function which sets
+dma-flag(use_dma/use_dma_flag) as 1.
+
+PIO->DMA
+  .startup: Since dma-flag is 0, DMA channel is not requested.
+  .verify_port: dma-flag is set as 1.
+  .shutdown: N/A
+
+DMA->PIO
+  .startup: Since dma-flag is 1, DMA channel is requested.
+  .verify_port: dma-flag is set as 0.
+  .shutdown: Since dma-flag is 0, DMA channel is not released.
+
+This means DMA channel resource leak occurs.
+Next time, this driver can't get DMA channel resource forever.
+
+MODIFICATION:
+  Currently, when release DMA channel resource, this driver checks dma-flag.
+  However, this specification occurs the above issue.
+  This driver must check whether dma_request_channel is executed or not.
+  The values are saved in private data variable "chan_tx/chan_tx".
+  These variables mean if the value is NULL, DMA channel is not requested,
+  if not NULL, DMA channel is requested.
+
+This patch fixes the issue.
+
+Signed-off-by: Tomoya MORINAGA <tomoya.rohm@gmail.com>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/tty/serial/pch_uart.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/serial/pch_uart.c
++++ b/drivers/tty/serial/pch_uart.c
+@@ -626,6 +626,7 @@ static void pch_request_dma(struct uart_
+               dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n",
+                       __func__);
+               dma_release_channel(priv->chan_tx);
++              priv->chan_tx = NULL;
+               return;
+       }
+@@ -1213,8 +1214,7 @@ static void pch_uart_shutdown(struct uar
+               dev_err(priv->port.dev,
+                       "pch_uart_hal_set_fifo Failed(ret=%d)\n", ret);
+-      if (priv->use_dma_flag)
+-              pch_free_dma(port);
++      pch_free_dma(port);
+       free_irq(priv->port.irq, priv);
+ }
diff --git a/queue-3.1/pch_uart-fix-hw-flow-control-issue.patch b/queue-3.1/pch_uart-fix-hw-flow-control-issue.patch
new file mode 100644 (file)
index 0000000..23b9574
--- /dev/null
@@ -0,0 +1,31 @@
+From a1d7cfe29f13cf45f8094929864b9c66bf0cd91b Mon Sep 17 00:00:00 2001
+From: Tomoya MORINAGA <tomoya-linux@dsn.lapis-semi.com>
+Date: Thu, 27 Oct 2011 15:45:18 +0900
+Subject: pch_uart: Fix hw-flow control issue
+
+From: Tomoya MORINAGA <tomoya-linux@dsn.lapis-semi.com>
+
+commit a1d7cfe29f13cf45f8094929864b9c66bf0cd91b upstream.
+
+Using hardware flow control,
+currently, register of the control-bit(AFE) is not set.
+This patch fixes the issue.
+
+Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.lapis-semi.com>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/tty/serial/pch_uart.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/tty/serial/pch_uart.c
++++ b/drivers/tty/serial/pch_uart.c
+@@ -1278,6 +1278,7 @@ static void pch_uart_set_termios(struct
+       if (rtn)
+               goto out;
++      pch_uart_set_mctrl(&priv->port, priv->port.mctrl);
+       /* Don't rewrite B0 */
+       if (tty_termios_baud_rate(termios))
+               tty_termios_encode_baud_rate(termios, baud, baud);
diff --git a/queue-3.1/pch_uart-support-new-device-lapis-semiconductor-ml7831-ioh.patch b/queue-3.1/pch_uart-support-new-device-lapis-semiconductor-ml7831-ioh.patch
new file mode 100644 (file)
index 0000000..3b81c71
--- /dev/null
@@ -0,0 +1,81 @@
+From 8249f743f732ccbc3056428945ab1d9bd36d46bf Mon Sep 17 00:00:00 2001
+From: Tomoya MORINAGA <tomoya-linux@dsn.lapis-semi.com>
+Date: Fri, 28 Oct 2011 09:38:49 +0900
+Subject: pch_uart: Support new device LAPIS Semiconductor ML7831 IOH
+
+From: Tomoya MORINAGA <tomoya-linux@dsn.lapis-semi.com>
+
+commit 8249f743f732ccbc3056428945ab1d9bd36d46bf upstream.
+
+ML7831 is companion chip for Intel Atom E6xx series.
+
+Signed-off-by: Tomoya MORINAGA <tomoya-linux@dsn.lapis-semi.com>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/tty/serial/Kconfig    |   14 +++++++-------
+ drivers/tty/serial/pch_uart.c |    8 ++++++++
+ 2 files changed, 15 insertions(+), 7 deletions(-)
+
+--- a/drivers/tty/serial/Kconfig
++++ b/drivers/tty/serial/Kconfig
+@@ -1570,7 +1570,7 @@ config SERIAL_IFX6X60
+         Support for the IFX6x60 modem devices on Intel MID platforms.
+ config SERIAL_PCH_UART
+-      tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART"
++      tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) UART"
+       depends on PCI
+       select SERIAL_CORE
+       help
+@@ -1578,12 +1578,12 @@ config SERIAL_PCH_UART
+         which is an IOH(Input/Output Hub) for x86 embedded processor.
+         Enabling PCH_DMA, this PCH UART works as DMA mode.
+-        This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
+-        Output Hub), ML7213 and ML7223.
+-        ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
+-        for MP(Media Phone) use.
+-        ML7213/ML7223 is companion chip for Intel Atom E6xx series.
+-        ML7213/ML7223 is completely compatible for Intel EG20T PCH.
++        This driver also can be used for LAPIS Semiconductor IOH(Input/
++        Output Hub), ML7213, ML7223 and ML7831.
++        ML7213 IOH is for IVI(In-Vehicle Infotainment) use, ML7223 IOH is
++        for MP(Media Phone) use and ML7831 IOH is for general purpose use.
++        ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
++        ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
+ config SERIAL_MSM_SMD
+       bool "Enable tty device interface for some SMD ports"
+--- a/drivers/tty/serial/pch_uart.c
++++ b/drivers/tty/serial/pch_uart.c
+@@ -256,6 +256,8 @@ enum pch_uart_num_t {
+       pch_ml7213_uart2,
+       pch_ml7223_uart0,
+       pch_ml7223_uart1,
++      pch_ml7831_uart0,
++      pch_ml7831_uart1,
+ };
+ static struct pch_uart_driver_data drv_dat[] = {
+@@ -268,6 +270,8 @@ static struct pch_uart_driver_data drv_d
+       [pch_ml7213_uart2] = {PCH_UART_2LINE, 2},
+       [pch_ml7223_uart0] = {PCH_UART_8LINE, 0},
+       [pch_ml7223_uart1] = {PCH_UART_2LINE, 1},
++      [pch_ml7831_uart0] = {PCH_UART_8LINE, 0},
++      [pch_ml7831_uart1] = {PCH_UART_2LINE, 1},
+ };
+ static unsigned int default_baud = 9600;
+@@ -1551,6 +1555,10 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_
+        .driver_data = pch_ml7223_uart0},
+       {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D),
+        .driver_data = pch_ml7223_uart1},
++      {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8811),
++       .driver_data = pch_ml7831_uart0},
++      {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8812),
++       .driver_data = pch_ml7831_uart1},
+       {0,},
+ };
diff --git a/queue-3.1/pcie-gadget-spear-add-platform-prefix-for-platform-modalias.patch b/queue-3.1/pcie-gadget-spear-add-platform-prefix-for-platform-modalias.patch
new file mode 100644 (file)
index 0000000..4f559ff
--- /dev/null
@@ -0,0 +1,30 @@
+From 161f14191dc166c4e3f37f68af1bc199c6868b7d Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@gmail.com>
+Date: Mon, 31 Oct 2011 10:20:28 +0800
+Subject: pcie-gadget-spear: Add "platform:" prefix for platform modalias
+
+From: Axel Lin <axel.lin@gmail.com>
+
+commit 161f14191dc166c4e3f37f68af1bc199c6868b7d upstream.
+
+Since 43cc71eed1250755986da4c0f9898f9a635cb3bf (platform: prefix MODALIAS
+with "platform:"), the platform modalias is prefixed with "platform:".
+
+Signed-off-by: Axel Lin <axel.lin@gmail.com>
+Acked-by: Pratyush Anand <pratyush.anand@st.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/misc/spear13xx_pcie_gadget.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/misc/spear13xx_pcie_gadget.c
++++ b/drivers/misc/spear13xx_pcie_gadget.c
+@@ -903,6 +903,6 @@ static void __exit spear_pcie_gadget_exi
+ }
+ module_exit(spear_pcie_gadget_exit);
+-MODULE_ALIAS("pcie-gadget-spear");
++MODULE_ALIAS("platform:pcie-gadget-spear");
+ MODULE_AUTHOR("Pratyush Anand");
+ MODULE_LICENSE("GPL");
index 534de5f901fc2fe04f942aa97fd9587991520c49..f4891566b58e2d201d757aca3363df761ee17f06 100644 (file)
@@ -14,3 +14,20 @@ nl80211-fix-ht-capability-attribute-validation.patch
 cfg80211-fix-bug-on-regulatory-core-exit-on-access-to-last_request.patch
 ip6_tunnel-copy-parms.name-after-register_netdevice.patch
 pm-driver-core-disable-device-s-runtime-pm-during-shutdown.patch
+pch_phub-support-new-device-lapis-semiconductor-ml7831-ioh.patch
+pch_phub-fix-mac-address-writing-issue-for-lapis-ml7831.patch
+pch_uart-fix-hw-flow-control-issue.patch
+pch_uart-fix-dma-resource-leak-issue.patch
+pch_uart-support-new-device-lapis-semiconductor-ml7831-ioh.patch
+tty-hvc_dcc-fix-duplicate-character-inputs.patch
+tty-ldisc-allow-waiting-for-ldisc-arbitrarily-long.patch
+tty-ldisc-move-wait-idle-to-caller.patch
+tty-ldisc-wait-for-ldisc-infinitely-in-hangup.patch
+nfs-when-attempting-to-open-a-directory-fall-back-on-normal-lookup-try-5.patch
+alsa-hda-fix-eld-memory-leak.patch
+pcie-gadget-spear-add-platform-prefix-for-platform-modalias.patch
+drivers-base-node.c-fix-compilation-error-with-older-versions-of-gcc.patch
+xhci-set-slot-and-ep0-flags-for-address-command.patch
+usb-xhci-clear-warm-reset-change-event-during-init.patch
+usb-xhci-fix-lockdep-warning-on-endpoint-timeout.patch
+usb-xhci-resume-root-hubs-when-the-controller-resumes.patch
diff --git a/queue-3.1/tty-hvc_dcc-fix-duplicate-character-inputs.patch b/queue-3.1/tty-hvc_dcc-fix-duplicate-character-inputs.patch
new file mode 100644 (file)
index 0000000..a77acad
--- /dev/null
@@ -0,0 +1,49 @@
+From c2a3e84f950e7ddba1f3914b005861d46ae60359 Mon Sep 17 00:00:00 2001
+From: Stephen Boyd <sboyd@codeaurora.org>
+Date: Tue, 25 Oct 2011 19:19:43 -0700
+Subject: tty: hvc_dcc: Fix duplicate character inputs
+
+From: Stephen Boyd <sboyd@codeaurora.org>
+
+commit c2a3e84f950e7ddba1f3914b005861d46ae60359 upstream.
+
+Reading from the DCC grabs a character from the buffer and
+clears the status bit. Since this is a context-changing
+operation, instructions following the character read that rely on
+the status bit being accurate need to be synchronized with an
+ISB.
+
+In this case, the status bit check needs to execute after the
+character read otherwise we run the risk of reading the character
+and checking the status bit before the read can clear the status
+bit in the first place. When this happens, the user will see the
+same character they typed twice, instead of once.
+
+Add an ISB after the read and the write, so that the status check
+is synchronized with the read/write operations.
+
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/tty/hvc/hvc_dcc.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/tty/hvc/hvc_dcc.c
++++ b/drivers/tty/hvc/hvc_dcc.c
+@@ -46,6 +46,7 @@ static inline char __dcc_getchar(void)
+       asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg"
+               : "=r" (__c));
++      isb();
+       return __c;
+ }
+@@ -55,6 +56,7 @@ static inline void __dcc_putchar(char c)
+       asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char"
+               : /* no output register */
+               : "r" (c));
++      isb();
+ }
+ static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
diff --git a/queue-3.1/tty-ldisc-allow-waiting-for-ldisc-arbitrarily-long.patch b/queue-3.1/tty-ldisc-allow-waiting-for-ldisc-arbitrarily-long.patch
new file mode 100644 (file)
index 0000000..82b8673
--- /dev/null
@@ -0,0 +1,68 @@
+From df92d0561de364de53c42abc5d43e04ab6f326a5 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Wed, 16 Nov 2011 16:27:07 +0100
+Subject: TTY: ldisc, allow waiting for ldisc arbitrarily long
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit df92d0561de364de53c42abc5d43e04ab6f326a5 upstream.
+
+To fix a nasty bug in ldisc hup vs. reinit we need to wait infinitely
+long for ldisc to be gone. So here we add a parameter to
+tty_ldisc_wait_idle to allow that.
+
+This is only a preparation for the real fix which is done in the
+following patches.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Cc: Dave Young <hidave.darkstar@gmail.com>
+Cc: Dave Jones <davej@redhat.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Cc: Dmitriy Matrosov <sgf.dma@gmail.com>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/tty/tty_ldisc.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/tty/tty_ldisc.c
++++ b/drivers/tty/tty_ldisc.c
+@@ -548,15 +548,16 @@ static void tty_ldisc_flush_works(struct
+ /**
+  *    tty_ldisc_wait_idle     -       wait for the ldisc to become idle
+  *    @tty: tty to wait for
++ *    @timeout: for how long to wait at most
+  *
+  *    Wait for the line discipline to become idle. The discipline must
+  *    have been halted for this to guarantee it remains idle.
+  */
+-static int tty_ldisc_wait_idle(struct tty_struct *tty)
++static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
+ {
+-      int ret;
++      long ret;
+       ret = wait_event_timeout(tty_ldisc_idle,
+-                      atomic_read(&tty->ldisc->users) == 1, 5 * HZ);
++                      atomic_read(&tty->ldisc->users) == 1, timeout);
+       if (ret < 0)
+               return ret;
+       return ret > 0 ? 0 : -EBUSY;
+@@ -666,7 +667,7 @@ int tty_set_ldisc(struct tty_struct *tty
+       tty_ldisc_flush_works(tty);
+-      retval = tty_ldisc_wait_idle(tty);
++      retval = tty_ldisc_wait_idle(tty, 5 * HZ);
+       tty_lock();
+       mutex_lock(&tty->ldisc_mutex);
+@@ -763,7 +764,7 @@ static int tty_ldisc_reinit(struct tty_s
+       if (IS_ERR(ld))
+               return -1;
+-      WARN_ON_ONCE(tty_ldisc_wait_idle(tty));
++      WARN_ON_ONCE(tty_ldisc_wait_idle(tty, 5 * HZ));
+       tty_ldisc_close(tty, tty->ldisc);
+       tty_ldisc_put(tty->ldisc);
diff --git a/queue-3.1/tty-ldisc-move-wait-idle-to-caller.patch b/queue-3.1/tty-ldisc-move-wait-idle-to-caller.patch
new file mode 100644 (file)
index 0000000..163b32c
--- /dev/null
@@ -0,0 +1,47 @@
+From 300420722e0734a4254f3b634e0f82664495d210 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Wed, 16 Nov 2011 16:27:08 +0100
+Subject: TTY: ldisc, move wait idle to caller
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 300420722e0734a4254f3b634e0f82664495d210 upstream.
+
+It is the only place where reinit is called from. And we really need
+to wait for the old ldisc to go once. Actually this is the place where
+the waiting originally was (before removed and re-added later).
+
+This will make the fix in the following patch easier to implement.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Cc: Dave Young <hidave.darkstar@gmail.com>
+Cc: Dave Jones <davej@redhat.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Cc: Dmitriy Matrosov <sgf.dma@gmail.com>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/tty/tty_ldisc.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/tty_ldisc.c
++++ b/drivers/tty/tty_ldisc.c
+@@ -764,8 +764,6 @@ static int tty_ldisc_reinit(struct tty_s
+       if (IS_ERR(ld))
+               return -1;
+-      WARN_ON_ONCE(tty_ldisc_wait_idle(tty, 5 * HZ));
+-
+       tty_ldisc_close(tty, tty->ldisc);
+       tty_ldisc_put(tty->ldisc);
+       tty->ldisc = NULL;
+@@ -849,6 +847,8 @@ void tty_ldisc_hangup(struct tty_struct
+          it means auditing a lot of other paths so this is
+          a FIXME */
+       if (tty->ldisc) {       /* Not yet closed */
++              WARN_ON_ONCE(tty_ldisc_wait_idle(tty, 5 * HZ));
++
+               if (reset == 0) {
+                       if (!tty_ldisc_reinit(tty, tty->termios->c_line))
diff --git a/queue-3.1/tty-ldisc-wait-for-ldisc-infinitely-in-hangup.patch b/queue-3.1/tty-ldisc-wait-for-ldisc-infinitely-in-hangup.patch
new file mode 100644 (file)
index 0000000..5f70bbf
--- /dev/null
@@ -0,0 +1,83 @@
+From 0c73c08ec73dbe080b9ec56696ee21d32754d918 Mon Sep 17 00:00:00 2001
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Wed, 16 Nov 2011 16:27:09 +0100
+Subject: TTY: ldisc, wait for ldisc infinitely in hangup
+
+From: Jiri Slaby <jslaby@suse.cz>
+
+commit 0c73c08ec73dbe080b9ec56696ee21d32754d918 upstream.
+
+For /dev/console case, we do not kill all ldisc users. It's due to
+redirected_tty_write test in __tty_hangup. In that case there still
+might be a process waiting e.g. in n_tty_read for input.
+
+We wait for such processes to disappear. The problem is that we use a
+timeout. After this timeout, we continue closing the ldisc and start
+freeing tty resources. It obviously leads to crashes when the other
+process is woken.
+
+So to fix this, we wait infinitely before reiniting the ldisc. (The
+tiocsetd remains untouched -- times out after 5s.)
+
+This is nicely reproducible with this run from shell:
+  exec 0<>/dev/console 1<>/dev/console 2<>/dev/console
+and stopping a getty like:
+  systemctl stop serial-getty@ttyS0.service
+
+The crash proper may be produced only under load or with constified
+timing the same as for 92f6fa09b.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Cc: Dave Young <hidave.darkstar@gmail.com>
+Cc: Dave Jones <davej@redhat.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Cc: Dmitriy Matrosov <sgf.dma@gmail.com>
+Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/tty/tty_ldisc.c |   19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+--- a/drivers/tty/tty_ldisc.c
++++ b/drivers/tty/tty_ldisc.c
+@@ -36,6 +36,7 @@
+ #include <linux/kmod.h>
+ #include <linux/nsproxy.h>
++#include <linux/ratelimit.h>
+ /*
+  *    This guards the refcounted line discipline lists. The lock
+@@ -838,7 +839,7 @@ void tty_ldisc_hangup(struct tty_struct
+       tty_unlock();
+       cancel_work_sync(&tty->buf.work);
+       mutex_unlock(&tty->ldisc_mutex);
+-
++retry:
+       tty_lock();
+       mutex_lock(&tty->ldisc_mutex);
+@@ -847,7 +848,21 @@ void tty_ldisc_hangup(struct tty_struct
+          it means auditing a lot of other paths so this is
+          a FIXME */
+       if (tty->ldisc) {       /* Not yet closed */
+-              WARN_ON_ONCE(tty_ldisc_wait_idle(tty, 5 * HZ));
++              if (atomic_read(&tty->ldisc->users) != 1) {
++                      char cur_n[TASK_COMM_LEN], tty_n[64];
++                      long timeout = 3 * HZ;
++                      tty_unlock();
++
++                      while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
++                              timeout = MAX_SCHEDULE_TIMEOUT;
++                              printk_ratelimited(KERN_WARNING
++                                      "%s: waiting (%s) for %s took too long, but we keep waiting...\n",
++                                      __func__, get_task_comm(cur_n, current),
++                                      tty_name(tty, tty_n));
++                      }
++                      mutex_unlock(&tty->ldisc_mutex);
++                      goto retry;
++              }
+               if (reset == 0) {
diff --git a/queue-3.1/usb-xhci-clear-warm-reset-change-event-during-init.patch b/queue-3.1/usb-xhci-clear-warm-reset-change-event-during-init.patch
new file mode 100644 (file)
index 0000000..e37a566
--- /dev/null
@@ -0,0 +1,42 @@
+From 79c3dd8150fd5236d95766a9e662e3e932b462c9 Mon Sep 17 00:00:00 2001
+From: Don Zickus <dzickus@redhat.com>
+Date: Thu, 3 Nov 2011 09:07:18 -0400
+Subject: usb, xhci: Clear warm reset change event during init
+
+From: Don Zickus <dzickus@redhat.com>
+
+commit 79c3dd8150fd5236d95766a9e662e3e932b462c9 upstream.
+
+I noticed on my Panther Point system that I wasn't getting hotplug events
+for my usb3.0 disk on a usb3 port.  I tracked it down to the fact that the
+system had the warm reset change bit still set.  This seemed to block future
+events from being received, including a hotplug event.
+
+Clearing this bit during initialization allowed the hotplug event to be
+received and the disk to be recognized correctly.
+
+This patch should be backported to kernels as old as 2.6.39.
+
+Signed-off-by: Don Zickus <dzickus@redhat.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/hub.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -813,6 +813,12 @@ static void hub_activate(struct usb_hub
+                                       USB_PORT_FEAT_C_PORT_LINK_STATE);
+               }
++              if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
++                              hub_is_superspeed(hub->hdev)) {
++                      need_debounce_delay = true;
++                      clear_port_feature(hub->hdev, port1,
++                                      USB_PORT_FEAT_C_BH_PORT_RESET);
++              }
+               /* We can forget about a "removed" device when there's a
+                * physical disconnect or the connect status changes.
+                */
diff --git a/queue-3.1/usb-xhci-fix-lockdep-warning-on-endpoint-timeout.patch b/queue-3.1/usb-xhci-fix-lockdep-warning-on-endpoint-timeout.patch
new file mode 100644 (file)
index 0000000..6c69769
--- /dev/null
@@ -0,0 +1,178 @@
+From f43d623164022dcbf6750ef220b7a1133a1183eb Mon Sep 17 00:00:00 2001
+From: Don Zickus <dzickus@redhat.com>
+Date: Thu, 20 Oct 2011 23:52:14 -0400
+Subject: usb, xhci: fix lockdep warning on endpoint timeout
+
+From: Don Zickus <dzickus@redhat.com>
+
+commit f43d623164022dcbf6750ef220b7a1133a1183eb upstream.
+
+While debugging a usb3 problem, I stumbled upon this lockdep warning.
+
+Oct 18 21:41:17 dhcp47-74 kernel: =================================
+Oct 18 21:41:17 dhcp47-74 kernel: [ INFO: inconsistent lock state ]
+Oct 18 21:41:17 dhcp47-74 kernel: 3.1.0-rc4nmi+ #456
+Oct 18 21:41:17 dhcp47-74 kernel: ---------------------------------
+Oct 18 21:41:17 dhcp47-74 kernel: inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
+Oct 18 21:41:17 dhcp47-74 kernel: swapper/0 [HC0[0]:SC1[1]:HE1:SE0] takes:
+Oct 18 21:41:17 dhcp47-74 kernel: (&(&xhci->lock)->rlock){?.-...}, at: [<ffffffffa0228990>] xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd]
+Oct 18 21:41:17 dhcp47-74 kernel: {IN-HARDIRQ-W} state was registered at:
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8109a941>] __lock_acquire+0x781/0x1660
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8109bed7>] lock_acquire+0x97/0x170
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff81501b46>] _raw_spin_lock+0x46/0x80
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffffa02299fa>] xhci_irq+0x3a/0x1960 [xhci_hcd]
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffffa022b351>] xhci_msi_irq+0x31/0x40 [xhci_hcd]
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810d2305>] handle_irq_event_percpu+0x85/0x320
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810d25e8>] handle_irq_event+0x48/0x70
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810d537d>] handle_edge_irq+0x6d/0x130
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810048c9>] handle_irq+0x49/0xa0
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8150d56d>] do_IRQ+0x5d/0xe0
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff815029b0>] ret_from_intr+0x0/0x13
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff81388aca>] usb_set_device_state+0x8a/0x180
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8138f038>] usb_add_hcd+0x2b8/0x730
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffffa022ed7e>] xhci_pci_probe+0x9e/0xd4 [xhci_hcd]
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8127915f>] local_pci_probe+0x5f/0xd0
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8127a569>] pci_device_probe+0x119/0x120
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff81334473>] driver_probe_device+0xa3/0x2c0
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8133473b>] __driver_attach+0xab/0xb0
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8133373c>] bus_for_each_dev+0x6c/0xa0
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff813341fe>] driver_attach+0x1e/0x20
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff81333b88>] bus_add_driver+0x1f8/0x2b0
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff81334df6>] driver_register+0x76/0x140
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8127a7c6>] __pci_register_driver+0x66/0xe0
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffffa013c04a>] snd_timer_find+0x4a/0x70 [snd_timer]
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffffa013c00e>] snd_timer_find+0xe/0x70 [snd_timer]
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810001d3>] do_one_initcall+0x43/0x180
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff810a9ed2>] sys_init_module+0x92/0x1f0
+Oct 18 21:41:17 dhcp47-74 kernel:  [<ffffffff8150ab6b>] system_call_fastpath+0x16/0x1b
+Oct 18 21:41:17 dhcp47-74 kernel: irq event stamp: 631984
+Oct 18 21:41:17 dhcp47-74 kernel: hardirqs last  enabled at (631984): [<ffffffff81502720>] _raw_spin_unlock_irq+0x30/0x50
+Oct 18 21:41:17 dhcp47-74 kernel: hardirqs last disabled at (631983): [<ffffffff81501c49>] _raw_spin_lock_irq+0x19/0x90
+Oct 18 21:41:17 dhcp47-74 kernel: softirqs last  enabled at (631980): [<ffffffff8105ff63>] _local_bh_enable+0x13/0x20
+Oct 18 21:41:17 dhcp47-74 kernel: softirqs last disabled at (631981): [<ffffffff8150ce6c>] call_softirq+0x1c/0x30
+Oct 18 21:41:17 dhcp47-74 kernel:
+Oct 18 21:41:17 dhcp47-74 kernel: other info that might help us debug this:
+Oct 18 21:41:17 dhcp47-74 kernel: Possible unsafe locking scenario:
+Oct 18 21:41:17 dhcp47-74 kernel:
+Oct 18 21:41:17 dhcp47-74 kernel:       CPU0
+Oct 18 21:41:17 dhcp47-74 kernel:       ----
+Oct 18 21:41:17 dhcp47-74 kernel:  lock(&(&xhci->lock)->rlock);
+Oct 18 21:41:17 dhcp47-74 kernel:  <Interrupt>
+Oct 18 21:41:17 dhcp47-74 kernel:    lock(&(&xhci->lock)->rlock);
+Oct 18 21:41:17 dhcp47-74 kernel:
+Oct 18 21:41:17 dhcp47-74 kernel: *** DEADLOCK ***
+Oct 18 21:41:17 dhcp47-74 kernel:
+Oct 18 21:41:17 dhcp47-74 kernel: 1 lock held by swapper/0:
+Oct 18 21:41:17 dhcp47-74 kernel: #0:  (&ep->stop_cmd_timer){+.-...}, at: [<ffffffff8106abf2>] run_timer_softirq+0x162/0x570
+Oct 18 21:41:17 dhcp47-74 kernel:
+Oct 18 21:41:17 dhcp47-74 kernel: stack backtrace:
+Oct 18 21:41:17 dhcp47-74 kernel: Pid: 0, comm: swapper Tainted: G        W   3.1.0-rc4nmi+ #456
+Oct 18 21:41:17 dhcp47-74 kernel: Call Trace:
+Oct 18 21:41:17 dhcp47-74 kernel: <IRQ>  [<ffffffff81098ed7>] print_usage_bug+0x227/0x270
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff810999c6>] mark_lock+0x346/0x410
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8109a7de>] __lock_acquire+0x61e/0x1660
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81099893>] ? mark_lock+0x213/0x410
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8109bed7>] lock_acquire+0x97/0x170
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffffa0228990>] ? xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd]
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81501b46>] _raw_spin_lock+0x46/0x80
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffffa0228990>] ? xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd]
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffffa0228990>] xhci_stop_endpoint_command_watchdog+0x30/0x340 [xhci_hcd]
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8106abf2>] ? run_timer_softirq+0x162/0x570
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8106ac9d>] run_timer_softirq+0x20d/0x570
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8106abf2>] ? run_timer_softirq+0x162/0x570
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffffa0228960>] ? xhci_queue_isoc_tx_prepare+0x8e0/0x8e0 [xhci_hcd]
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff810604d2>] __do_softirq+0xf2/0x3f0
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81020edd>] ? lapic_next_event+0x1d/0x30
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81090d4e>] ? clockevents_program_event+0x5e/0x90
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8150ce6c>] call_softirq+0x1c/0x30
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8100484d>] do_softirq+0x8d/0xc0
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8105ff35>] irq_exit+0xe5/0x100
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8150d65e>] smp_apic_timer_interrupt+0x6e/0x99
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff8150b6f0>] apic_timer_interrupt+0x70/0x80
+Oct 18 21:41:17 dhcp47-74 kernel: <EOI>  [<ffffffff81095d8d>] ? trace_hardirqs_off+0xd/0x10
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff812ddb76>] ? acpi_idle_enter_bm+0x227/0x25b
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff812ddb71>] ? acpi_idle_enter_bm+0x222/0x25b
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff813eda63>] cpuidle_idle_call+0x103/0x290
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81002155>] cpu_idle+0xe5/0x160
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff814e7f50>] rest_init+0xe0/0xf0
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff814e7e70>] ? csum_partial_copy_generic+0x170/0x170
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81df8e23>] start_kernel+0x3fc/0x407
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81df8321>] x86_64_start_reservations+0x131/0x135
+Oct 18 21:41:17 dhcp47-74 kernel: [<ffffffff81df8412>] x86_64_start_kernel+0xed/0xf4
+Oct 18 21:41:17 dhcp47-74 kernel: xhci_hcd 0000:00:14.0: xHCI host not responding to stop endpoint command.
+Oct 18 21:41:17 dhcp47-74 kernel: xhci_hcd 0000:00:14.0: Assuming host is dying, halting host.
+Oct 18 21:41:17 dhcp47-74 kernel: xhci_hcd 0000:00:14.0: HC died; cleaning up
+Oct 18 21:41:17 dhcp47-74 kernel: usb 3-4: device descriptor read/8, error -110
+Oct 18 21:41:17 dhcp47-74 kernel: usb 3-4: device descriptor read/8, error -22
+Oct 18 21:41:17 dhcp47-74 kernel: hub 3-0:1.0: cannot disable port 4 (err = -19)
+
+Basically what is happening is in xhci_stop_endpoint_command_watchdog()
+the xhci->lock is grabbed with just spin_lock.  What lockdep deduces is
+that if an interrupt occurred while in this function it would deadlock
+with xhci_irq because that function also grabs the xhci->lock.
+
+Fixing it is trivial by using spin_lock_irqsave instead.
+
+This should be queued to stable kernels as far back as 2.6.33.
+
+Signed-off-by: Don Zickus <dzickus@redhat.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c |   13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -816,23 +816,24 @@ void xhci_stop_endpoint_command_watchdog
+       struct xhci_ring *ring;
+       struct xhci_td *cur_td;
+       int ret, i, j;
++      unsigned long flags;
+       ep = (struct xhci_virt_ep *) arg;
+       xhci = ep->xhci;
+-      spin_lock(&xhci->lock);
++      spin_lock_irqsave(&xhci->lock, flags);
+       ep->stop_cmds_pending--;
+       if (xhci->xhc_state & XHCI_STATE_DYING) {
+               xhci_dbg(xhci, "Stop EP timer ran, but another timer marked "
+                               "xHCI as DYING, exiting.\n");
+-              spin_unlock(&xhci->lock);
++              spin_unlock_irqrestore(&xhci->lock, flags);
+               return;
+       }
+       if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) {
+               xhci_dbg(xhci, "Stop EP timer ran, but no command pending, "
+                               "exiting.\n");
+-              spin_unlock(&xhci->lock);
++              spin_unlock_irqrestore(&xhci->lock, flags);
+               return;
+       }
+@@ -844,11 +845,11 @@ void xhci_stop_endpoint_command_watchdog
+       xhci->xhc_state |= XHCI_STATE_DYING;
+       /* Disable interrupts from the host controller and start halting it */
+       xhci_quiesce(xhci);
+-      spin_unlock(&xhci->lock);
++      spin_unlock_irqrestore(&xhci->lock, flags);
+       ret = xhci_halt(xhci);
+-      spin_lock(&xhci->lock);
++      spin_lock_irqsave(&xhci->lock, flags);
+       if (ret < 0) {
+               /* This is bad; the host is not responding to commands and it's
+                * not allowing itself to be halted.  At least interrupts are
+@@ -896,7 +897,7 @@ void xhci_stop_endpoint_command_watchdog
+                       }
+               }
+       }
+-      spin_unlock(&xhci->lock);
++      spin_unlock_irqrestore(&xhci->lock, flags);
+       xhci_dbg(xhci, "Calling usb_hc_died()\n");
+       usb_hc_died(xhci_to_hcd(xhci)->primary_hcd);
+       xhci_dbg(xhci, "xHCI host controller is dead.\n");
diff --git a/queue-3.1/usb-xhci-resume-root-hubs-when-the-controller-resumes.patch b/queue-3.1/usb-xhci-resume-root-hubs-when-the-controller-resumes.patch
new file mode 100644 (file)
index 0000000..bcbcc5f
--- /dev/null
@@ -0,0 +1,97 @@
+From f69e3120df82391a0ee8118e0a156239a06b2afb Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Thu, 3 Nov 2011 11:37:10 -0400
+Subject: USB: XHCI: resume root hubs when the controller resumes
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit f69e3120df82391a0ee8118e0a156239a06b2afb upstream.
+
+This patch (as1494) fixes a problem in xhci-hcd's resume routine.
+When the controller is runtime-resumed, this can only mean that one of
+the two root hubs has made a wakeup request and therefore needs to be
+resumed as well.  Rather than try to determine which root hub requires
+attention (which might be difficult in the case where a new
+non-SuperSpeed device has been plugged in), the patch simply resumes
+both root hubs.
+
+Without this change, there is a race: The controller might be put back
+to sleep before it can activate its IRQ line, and the wakeup condition
+might never get handled.
+
+The patch also simplifies the logic in xhci_resume a little, combining
+some repeated flag settings into a single pair of statements.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Tested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci.c |   29 ++++++++++++++---------------
+ 1 file changed, 14 insertions(+), 15 deletions(-)
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -749,7 +749,7 @@ int xhci_resume(struct xhci_hcd *xhci, b
+       u32                     command, temp = 0;
+       struct usb_hcd          *hcd = xhci_to_hcd(xhci);
+       struct usb_hcd          *secondary_hcd;
+-      int                     retval;
++      int                     retval = 0;
+       /* Wait a bit if either of the roothubs need to settle from the
+        * transition into bus suspend.
+@@ -759,6 +759,9 @@ int xhci_resume(struct xhci_hcd *xhci, b
+                               xhci->bus_state[1].next_statechange))
+               msleep(100);
++      set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
++      set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
++
+       spin_lock_irq(&xhci->lock);
+       if (xhci->quirks & XHCI_RESET_ON_RESUME)
+               hibernated = true;
+@@ -828,20 +831,13 @@ int xhci_resume(struct xhci_hcd *xhci, b
+                       return retval;
+               xhci_dbg(xhci, "Start the primary HCD\n");
+               retval = xhci_run(hcd->primary_hcd);
+-              if (retval)
+-                      goto failed_restart;
+-
+-              xhci_dbg(xhci, "Start the secondary HCD\n");
+-              retval = xhci_run(secondary_hcd);
+               if (!retval) {
+-                      set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+-                      set_bit(HCD_FLAG_HW_ACCESSIBLE,
+-                                      &xhci->shared_hcd->flags);
++                      xhci_dbg(xhci, "Start the secondary HCD\n");
++                      retval = xhci_run(secondary_hcd);
+               }
+-failed_restart:
+               hcd->state = HC_STATE_SUSPENDED;
+               xhci->shared_hcd->state = HC_STATE_SUSPENDED;
+-              return retval;
++              goto done;
+       }
+       /* step 4: set Run/Stop bit */
+@@ -860,11 +856,14 @@ failed_restart:
+        * Running endpoints by ringing their doorbells
+        */
+-      set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+-      set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
+-
+       spin_unlock_irq(&xhci->lock);
+-      return 0;
++
++ done:
++      if (retval == 0) {
++              usb_hcd_resume_root_hub(hcd);
++              usb_hcd_resume_root_hub(xhci->shared_hcd);
++      }
++      return retval;
+ }
+ #endif        /* CONFIG_PM */
diff --git a/queue-3.1/xhci-set-slot-and-ep0-flags-for-address-command.patch b/queue-3.1/xhci-set-slot-and-ep0-flags-for-address-command.patch
new file mode 100644 (file)
index 0000000..c75b469
--- /dev/null
@@ -0,0 +1,111 @@
+From d31c285b3a71cf9056e6a060de41f37780b0af86 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Thu, 3 Nov 2011 13:06:08 -0700
+Subject: xhci: Set slot and ep0 flags for address command.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit d31c285b3a71cf9056e6a060de41f37780b0af86 upstream.
+
+Matt's AsMedia xHCI host controller was responding with a Context Error
+to an address device command after a configured device reset.  Some
+sequence of events leads both the slot and endpoint zero add flags
+cleared to zero, which the AsMedia host doesn't like:
+
+[  223.701839] xhci_hcd 0000:03:00.0: Slot ID 1 Input Context:
+[  223.701841] xhci_hcd 0000:03:00.0: @ffff880137b25000 (virt) @ffffc000 (dma) 0x000000 - drop flags
+[  223.701843] xhci_hcd 0000:03:00.0: @ffff880137b25004 (virt) @ffffc004 (dma) 0x000000 - add flags
+[  223.701846] xhci_hcd 0000:03:00.0: @ffff880137b25008 (virt) @ffffc008 (dma) 0x000000 - rsvd2[0]
+[  223.701848] xhci_hcd 0000:03:00.0: @ffff880137b2500c (virt) @ffffc00c (dma) 0x000000 - rsvd2[1]
+[  223.701850] xhci_hcd 0000:03:00.0: @ffff880137b25010 (virt) @ffffc010 (dma) 0x000000 - rsvd2[2]
+[  223.701852] xhci_hcd 0000:03:00.0: @ffff880137b25014 (virt) @ffffc014 (dma) 0x000000 - rsvd2[3]
+[  223.701854] xhci_hcd 0000:03:00.0: @ffff880137b25018 (virt) @ffffc018 (dma) 0x000000 - rsvd2[4]
+[  223.701857] xhci_hcd 0000:03:00.0: @ffff880137b2501c (virt) @ffffc01c (dma) 0x000000 - rsvd2[5]
+[  223.701858] xhci_hcd 0000:03:00.0: Slot Context:
+[  223.701860] xhci_hcd 0000:03:00.0: @ffff880137b25020 (virt) @ffffc020 (dma) 0x8400000 - dev_info
+[  223.701862] xhci_hcd 0000:03:00.0: @ffff880137b25024 (virt) @ffffc024 (dma) 0x010000 - dev_info2
+[  223.701864] xhci_hcd 0000:03:00.0: @ffff880137b25028 (virt) @ffffc028 (dma) 0x000000 - tt_info
+[  223.701866] xhci_hcd 0000:03:00.0: @ffff880137b2502c (virt) @ffffc02c (dma) 0x000000 - dev_state
+[  223.701869] xhci_hcd 0000:03:00.0: @ffff880137b25030 (virt) @ffffc030 (dma) 0x000000 - rsvd[0]
+[  223.701871] xhci_hcd 0000:03:00.0: @ffff880137b25034 (virt) @ffffc034 (dma) 0x000000 - rsvd[1]
+[  223.701873] xhci_hcd 0000:03:00.0: @ffff880137b25038 (virt) @ffffc038 (dma) 0x000000 - rsvd[2]
+[  223.701875] xhci_hcd 0000:03:00.0: @ffff880137b2503c (virt) @ffffc03c (dma) 0x000000 - rsvd[3]
+[  223.701877] xhci_hcd 0000:03:00.0: Endpoint 00 Context:
+[  223.701879] xhci_hcd 0000:03:00.0: @ffff880137b25040 (virt) @ffffc040 (dma) 0x000000 - ep_info
+[  223.701881] xhci_hcd 0000:03:00.0: @ffff880137b25044 (virt) @ffffc044 (dma) 0x2000026 - ep_info2
+[  223.701883] xhci_hcd 0000:03:00.0: @ffff880137b25048 (virt) @ffffc048 (dma) 0xffffe8e0 - deq
+[  223.701885] xhci_hcd 0000:03:00.0: @ffff880137b25050 (virt) @ffffc050 (dma) 0x000000 - tx_info
+[  223.701887] xhci_hcd 0000:03:00.0: @ffff880137b25054 (virt) @ffffc054 (dma) 0x000000 - rsvd[0]
+[  223.701889] xhci_hcd 0000:03:00.0: @ffff880137b25058 (virt) @ffffc058 (dma) 0x000000 - rsvd[1]
+[  223.701892] xhci_hcd 0000:03:00.0: @ffff880137b2505c (virt) @ffffc05c (dma) 0x000000 - rsvd[2]
+...
+[  223.701927] xhci_hcd 0000:03:00.0: // Ding dong!
+[  223.701992] xhci_hcd 0000:03:00.0: Setup ERROR: address device command for slot 1.
+
+The xHCI spec says that both flags must be set to one for the Address
+Device command.  When the device is first enumerated,
+xhci_setup_addressable_virt_dev() does set those flags.  However, when
+the device is addressed after it has been reset in the configured state,
+xhci_setup_addressable_virt_dev() is not called, and
+xhci_copy_ep0_dequeue_into_input_ctx() is called instead.  That function
+relies on the flags being set up by previous commands, which apparently
+isn't a good assumption.
+
+Move the setting of the flags into the common parent function.
+
+This should be queued for stable kernels as old as 2.6.35, since that
+was the first introduction of xhci_copy_ep0_dequeue_into_input_ctx.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Tested-by: Matt <mdm@iinet.net.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-mem.c |    5 -----
+ drivers/usb/host/xhci.c     |    5 ++++-
+ 2 files changed, 4 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/host/xhci-mem.c
++++ b/drivers/usb/host/xhci-mem.c
+@@ -875,7 +875,6 @@ int xhci_setup_addressable_virt_dev(stru
+       struct xhci_virt_device *dev;
+       struct xhci_ep_ctx      *ep0_ctx;
+       struct xhci_slot_ctx    *slot_ctx;
+-      struct xhci_input_control_ctx *ctrl_ctx;
+       u32                     port_num;
+       struct usb_device *top_dev;
+@@ -887,12 +886,8 @@ int xhci_setup_addressable_virt_dev(stru
+               return -EINVAL;
+       }
+       ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0);
+-      ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx);
+       slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx);
+-      /* 2) New slot context and endpoint 0 context are valid*/
+-      ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
+-
+       /* 3) Only the control endpoint is valid - one endpoint context */
+       slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route);
+       switch (udev->speed) {
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -2873,6 +2873,10 @@ int xhci_address_device(struct usb_hcd *
+       /* Otherwise, update the control endpoint ring enqueue pointer. */
+       else
+               xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev);
++      ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
++      ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
++      ctrl_ctx->drop_flags = 0;
++
+       xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
+       xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
+@@ -2954,7 +2958,6 @@ int xhci_address_device(struct usb_hcd *
+       virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK)
+               + 1;
+       /* Zero the input context control for later use */
+-      ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+       ctrl_ctx->add_flags = 0;
+       ctrl_ctx->drop_flags = 0;