Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  rcu: fix synchronize_rcu() so that kernel-doc works
diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO
index 488c77f..0775cf4 100644
--- a/Documentation/ja_JP/HOWTO
+++ b/Documentation/ja_JP/HOWTO
@@ -11,14 +11,14 @@
 fork. So if you have any comments or updates for this file, please try
 to update the original English file first.
 
-Last Updated: 2007/11/16
+Last Updated: 2008/08/21
 ==================================
 これは、
-linux-2.6.24/Documentation/HOWTO
+linux-2.6.27/Documentation/HOWTO
 の和訳です。
 
 翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
-翻訳日: 2007/11/10
+翻訳日: 2008/8/5
 翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com>
 校正者: 松倉さん <nbh--mats at nifty dot com>
          小林 雅典さん (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp>
@@ -287,13 +287,15 @@
     に安定した状態にあると判断したときにリリースされます。目標は毎週新
     しい -rc カーネルをリリースすることです。
 
-   - 以下の URL で各 -rc リリースに存在する既知の後戻り問題のリスト
-     が追跡されます-
-     http://kernelnewbies.org/known_regressions
-
   - このプロセスはカーネルが 「準備ができた」と考えられるまで継続しま
     す。このプロセスはだいたい 6週間継続します。
 
+  - 各リリースでの既知の後戻り問題(regression: このリリースの中で新規
+    に作り込まれた問題を指す) はその都度 Linux-kernel メーリングリスト
+    に投稿されます。ゴールとしては、カーネルが 「準備ができた」と宣言
+    する前にこのリストの長さをゼロに減らすことですが、現実には、数個の
+    後戻り問題がリリース時にたびたび残ってしまいます。
+
 Andrew Morton が Linux-kernel メーリングリストにカーネルリリースについ
 て書いたことをここで言っておくことは価値があります-
   「カーネルがいつリリースされるかは誰も知りません。なぜなら、これは現
@@ -303,18 +305,20 @@
 2.6.x.y -stable カーネルツリー
 ---------------------------
 
-バージョンに4つ目の数字がついたカーネルは -stable カーネルです。これに
-は、2.6.x カーネルで見つかったセキュリティ問題や重大な後戻りに対する比
-較的小さい重要な修正が含まれます。
+バージョン番号が4つの数字に分かれているカーネルは -stable カーネルです。
+これには、2.6.x カーネルで見つかったセキュリティ問題や重大な後戻りに対
+する比較的小さい重要な修正が含まれます。
 
 これは、開発/実験的バージョンのテストに協力することに興味が無く、
 最新の安定したカーネルを使いたいユーザに推奨するブランチです。
 
-もし、2.6.x.y カーネルが存在しない場合には、番号が一番大きい 2.6.x
-が最新の安定版カーネルです。
+もし、2.6.x.y カーネルが存在しない場合には、番号が一番大きい 2.6.x が
+最新の安定版カーネルです。
 
-2.6.x.y は "stable" チーム <stable@kernel.org> でメンテされており、だ
-いたい隔週でリリースされています。
+2.6.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必
+要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
+た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
+の場合はこれに対してだいたいの場合、すぐにリリースがされます。
 
 カーネルツリーに入っている、Documentation/stable_kernel_rules.txt ファ
 イルにはどのような種類の変更が -stable ツリーに受け入れ可能か、またリ
@@ -341,7 +345,9 @@
 メインラインへ入れるように Linus にプッシュします。
 
 メインカーネルツリーに含めるために Linus に送る前に、すべての新しいパッ
-チが -mm ツリーでテストされることが強く推奨されます。
+チが -mm ツリーでテストされることが強く推奨されています。マージウィン
+ドウが開く前に -mm ツリーに現れなかったパッチはメインラインにマージさ
+れることは困難になります。
 
 これらのカーネルは安定して動作すべきシステムとして使うのには適切ではあ
 りませんし、カーネルブランチの中でももっとも動作にリスクが高いものです。
@@ -395,13 +401,15 @@
     - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
 	git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
 
-    - SCSI, James Bottomley <James.Bottomley@SteelEye.com>
+    - SCSI, James Bottomley <James.Bottomley@hansenpartnership.com>
 	git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
 
+    - x86, Ingo Molnar <mingo@elte.hu>
+	git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
+
   quilt ツリー-
-    - USB, PCI ドライバコアと I2C, Greg Kroah-Hartman <gregkh@suse.de>
+    - USB, ドライバコアと I2C, Greg Kroah-Hartman <gregkh@suse.de>
 	kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
-    - x86-64 と i386 の仲間 Andi Kleen <ak@suse.de>
 
   その他のカーネルツリーは http://git.kernel.org/ と MAINTAINERS ファ
   イルに一覧表があります。
@@ -412,13 +420,32 @@
 bugzilla.kernel.org は Linux カーネル開発者がカーネルのバグを追跡する
 場所です。ユーザは見つけたバグの全てをこのツールで報告すべきです。
 どう kernel bugzilla を使うかの詳細は、以下を参照してください-
-	http://test.kernel.org/bugzilla/faq.html
-
+	http://bugzilla.kernel.org/page.cgi?id=faq.html
 メインカーネルソースディレクトリにあるファイル REPORTING-BUGS はカーネ
 ルバグらしいものについてどうレポートするかの良いテンプレートであり、問
 題の追跡を助けるためにカーネル開発者にとってどんな情報が必要なのかの詳
 細が書かれています。
 
+バグレポートの管理
+-------------------
+
+あなたのハッキングのスキルを訓練する最高の方法のひとつに、他人がレポー
+トしたバグを修正することがあります。あなたがカーネルをより安定化させる
+こに寄与するということだけでなく、あなたは 現実の問題を修正することを
+学び、自分のスキルも強化でき、また他の開発者があなたの存在に気がつき
+ます。バグを修正することは、多くの開発者の中から自分が功績をあげる最善
+の道です、なぜなら多くの人は他人のバグの修正に時間を浪費することを好ま
+ないからです。
+
+すでにレポートされたバグのために仕事をするためには、
+http://bugzilla.kernel.org に行ってください。もし今後のバグレポートに
+ついてアドバイスを受けたいのであれば、bugme-new メーリングリスト(新し
+いバグレポートだけがここにメールされる) または bugme-janitor メーリン
+グリスト(bugzilla の変更毎にここにメールされる)を購読できます。
+
+	http://lists.linux-foundation.org/mailman/listinfo/bugme-new
+	http://lists.linux-foundation.org/mailman/listinfo/bugme-janitors
+
 メーリングリスト
 -------------
 
diff --git a/Documentation/ja_JP/SubmitChecklist b/Documentation/ja_JP/SubmitChecklist
new file mode 100644
index 0000000..6c42e07
--- /dev/null
+++ b/Documentation/ja_JP/SubmitChecklist
@@ -0,0 +1,111 @@
+NOTE:
+This is a version of Documentation/SubmitChecklist into Japanese.
+This document is maintained by Takenori Nagano <t-nagano@ah.jp.nec.com>
+and the JF Project team <http://www.linux.or.jp/JF/>.
+If you find any difference between this document and the original file
+or a problem with the translation,
+please contact the maintainer of this file or JF project.
+
+Please also note that the purpose of this file is to be easier to read
+for non English (read: Japanese) speakers and is not intended as a
+fork. So if you have any comments or updates of this file, please try
+to update the original English file first.
+
+Last Updated: 2008/07/14
+==================================
+これは、
+linux-2.6.26/Documentation/SubmitChecklist の和訳です。
+
+翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
+翻訳日: 2008/07/14
+翻訳者: Takenori Nagano <t-nagano at ah dot jp dot nec dot com>
+校正者: Masanori Kobayashi さん <zap03216 at nifty dot ne dot jp>
+==================================
+
+
+Linux カーネルパッチ投稿者向けチェックリスト
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+本書では、パッチをより素早く取り込んでもらいたい開発者が実践すべき基本的な事柄
+をいくつか紹介します。ここにある全ての事柄は、Documentation/SubmittingPatches
+などのLinuxカーネルパッチ投稿に際しての心得を補足するものです。
+
+ 1: 妥当なCONFIGオプションや変更されたCONFIGオプション、つまり =y, =m, =n
+    全てで正しくビルドできることを確認してください。その際、gcc及びリンカが
+    warningやerrorを出していないことも確認してください。
+
+ 2: allnoconfig, allmodconfig オプションを用いて正しくビルドできることを
+    確認してください。
+
+ 3: 手許のクロスコンパイルツールやOSDLのPLMのようなものを用いて、複数の
+    アーキテクチャにおいても正しくビルドできることを確認してください。
+
+ 4: 64bit長の'unsigned long'を使用しているppc64は、クロスコンパイルでの
+    チェックに適当なアーキテクチャです。
+
+ 5: カーネルコーディングスタイルに準拠しているかどうか確認してください(!)
+
+ 6: CONFIGオプションの追加・変更をした場合には、CONFIGメニューが壊れていない
+    ことを確認してください。
+
+ 7: 新しくKconfigのオプションを追加する際には、必ずそのhelpも記述してください。
+
+ 8: 適切なKconfigの依存関係を考えながら慎重にチェックしてください。
+    ただし、この作業はマシンを使ったテストできちんと行うのがとても困難です。
+    うまくやるには、自分の頭で考えることです。
+
+ 9: sparseを利用してちゃんとしたコードチェックをしてください。
+
+10: 'make checkstack' と 'make namespacecheck' を利用し、問題が発見されたら
+    修正してください。'make checkstack' は明示的に問題を示しませんが、どれか
+    1つの関数が512バイトより大きいスタックを使っていれば、修正すべき候補と
+    なります。
+
+11: グローバルなkernel API を説明する kernel-doc をソースの中に含めてください。
+    ( staticな関数においては必須ではありませんが、含めてもらっても結構です )
+    そして、'make htmldocs' もしくは 'make mandocs' を利用して追記した
+    ドキュメントのチェックを行い、問題が見つかった場合には修正を行ってください。
+
+12: CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, CONFIG_DEBUG_SLAB,
+    CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES, CONFIG_DEBUG_SPINLOCK,
+    CONFIG_DEBUG_SPINLOCK_SLEEP これら全てを同時に有効にして動作確認を
+    行ってください。
+
+13: CONFIG_SMP, CONFIG_PREEMPT を有効にした場合と無効にした場合の両方で
+    ビルドした上、動作確認を行ってください。
+
+14: もしパッチがディスクのI/O性能などに影響を与えるようであれば、
+    'CONFIG_LBD'オプションを有効にした場合と無効にした場合の両方で
+    テストを実施してみてください。
+
+15: lockdepの機能を全て有効にした上で、全てのコードパスを評価してください。
+
+16: /proc に新しいエントリを追加した場合には、Documentation/ 配下に
+    必ずドキュメントを追加してください。
+
+17: 新しいブートパラメータを追加した場合には、
+    必ずDocumentation/kernel-parameters.txt に説明を追加してください。
+
+18: 新しくmoduleにパラメータを追加した場合には、MODULE_PARM_DESC()を
+    利用して必ずその説明を記述してください。
+
+19: 新しいuserspaceインタフェースを作成した場合には、Documentation/ABI/ に
+    Documentation/ABI/README を参考にして必ずドキュメントを追加してください。
+
+20: 'make headers_check'を実行して全く問題がないことを確認してください。
+
+21: 少なくともslabアロケーションとpageアロケーションに失敗した場合の
+    挙動について、fault-injectionを利用して確認してください。
+    Documentation/fault-injection/ を参照してください。
+
+    追加したコードがかなりの量であったならば、サブシステム特有の
+    fault-injectionを追加したほうが良いかもしれません。
+
+22: 新たに追加したコードは、`gcc -W'でコンパイルしてください。
+    このオプションは大量の不要なメッセージを出力しますが、
+    "warning: comparison between signed and unsigned" のようなメッセージは、
+    バグを見つけるのに役に立ちます。
+
+23: 投稿したパッチが -mm パッチセットにマージされた後、全ての既存のパッチや
+    VM, VFS およびその他のサブシステムに関する様々な変更と、現時点でも共存
+    できることを確認するテストを行ってください。
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a897646..1150444 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1074,6 +1074,9 @@
 
 			* [no]ncq: Turn on or off NCQ.
 
+			* nohrst, nosrst, norst: suppress hard, soft
+                          and both resets.
+
 			If there are multiple matching configurations changing
 			the same attribute, the last one is used.
 
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 0a7b326..3c8383d 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -405,7 +405,7 @@
 
 		ret = amba_device_register(d, &dev->resource);
 		if (ret) {
-			dev_err(&d->dev, "unable to register device: %d\n");
+			dev_err(&d->dev, "unable to register device: %d\n", ret);
 			kfree(d);
 		}
 	}
diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c
index 0db3a90..501dfdc 100644
--- a/arch/arm/mach-ixp4xx/fsg-setup.c
+++ b/arch/arm/mach-ixp4xx/fsg-setup.c
@@ -64,7 +64,7 @@
 
 static struct i2c_board_info __initdata fsg_i2c_board_info [] = {
 	{
-		I2C_BOARD_INFO("rtc-isl1208", 0x6f),
+		I2C_BOARD_INFO("isl1208", 0x6f),
 	},
 };
 
@@ -179,7 +179,6 @@
 {
 	DECLARE_MAC_BUF(mac_buf);
 	uint8_t __iomem *f;
-	int i;
 
 	ixp4xx_sys_init();
 
@@ -228,6 +227,7 @@
 	f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x400000);
 	if (f) {
 #ifdef __ARMEB__
+		int i;
 		for (i = 0; i < 6; i++) {
 			fsg_plat_eth[0].hwaddr[i] = readb(f + 0x3C0422 + i);
 			fsg_plat_eth[1].hwaddr[i] = readb(f + 0x3C043B + i);
diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c
index c01eea8..ca8e205 100644
--- a/arch/arm/mach-pxa/clock.c
+++ b/arch/arm/mach-pxa/clock.c
@@ -125,3 +125,28 @@
 		list_add(&clks[i].node, &clocks);
 	mutex_unlock(&clocks_mutex);
 }
+
+int clk_add_alias(char *alias, struct device *alias_dev, char *id,
+	struct device *dev)
+{
+	struct clk *r = clk_lookup(dev, id);
+	struct clk *new;
+
+	if (!r)
+		return -ENODEV;
+
+	new = kzalloc(sizeof(struct clk), GFP_KERNEL);
+
+	if (!new)
+		return -ENOMEM;
+
+	new->name = alias;
+	new->dev = alias_dev;
+	new->other = r;
+
+	mutex_lock(&clocks_mutex);
+	list_add(&new->node, &clocks);
+	mutex_unlock(&clocks_mutex);
+
+	return 0;
+}
diff --git a/arch/arm/mach-pxa/clock.h b/arch/arm/mach-pxa/clock.h
index 1ec8f91..73be795 100644
--- a/arch/arm/mach-pxa/clock.h
+++ b/arch/arm/mach-pxa/clock.h
@@ -1,3 +1,5 @@
+#include <linux/list.h>
+
 struct clk;
 
 struct clkops {
@@ -86,3 +88,6 @@
 #endif
 
 void clks_register(struct clk *clks, size_t num);
+int clk_add_alias(char *alias, struct device *alias_dev, char *id,
+	struct device *dev);
+
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index 0394245..001a252 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -10,18 +10,78 @@
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/init.h>
 
 #include <asm/setup.h>
 #include <asm/mach/arch.h>
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+
 #include "generic.h"
 
+static unsigned long e740_pin_config[] __initdata = {
+	/* Chip selects */
+	GPIO15_nCS_1,   /* CS1 - Flash */
+	GPIO79_nCS_3,   /* CS3 - IMAGEON */
+	GPIO80_nCS_4,   /* CS4 - TMIO */
+
+	/* Clocks */
+	GPIO12_32KHz,
+
+	/* BTUART */
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_GPIO, /* Used by TMIO for #SUSPEND */
+
+	/* PC Card */
+	GPIO8_GPIO,   /* CD0 */
+	GPIO44_GPIO,  /* CD1 */
+	GPIO11_GPIO,  /* IRQ0 */
+	GPIO6_GPIO,   /* IRQ1 */
+	GPIO27_GPIO,  /* RST0 */
+	GPIO24_GPIO,  /* RST1 */
+	GPIO20_GPIO,  /* PWR0 */
+	GPIO23_GPIO,  /* PWR1 */
+	GPIO48_nPOE,
+	GPIO49_nPWE,
+	GPIO50_nPIOR,
+	GPIO51_nPIOW,
+	GPIO52_nPCE_1,
+	GPIO53_nPCE_2,
+	GPIO54_nPSKTSEL,
+	GPIO55_nPREG,
+	GPIO56_nPWAIT,
+	GPIO57_nIOIS16,
+
+	/* wakeup */
+	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
+static unsigned long e400_pin_config[] __initdata = {
+	/* Chip selects */
+	GPIO15_nCS_1,   /* CS1 - Flash */
+	GPIO80_nCS_4,   /* CS4 - TMIO */
+
+	/* Clocks */
+	GPIO12_32KHz,
+
+	/* BTUART */
+	GPIO42_BTUART_RXD,
+	GPIO43_BTUART_TXD,
+	GPIO44_BTUART_CTS,
+	GPIO45_GPIO, /* Used by TMIO for #SUSPEND */
+
+	/* wakeup */
+	GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
 /* Only e800 has 128MB RAM */
 static void __init eseries_fixup(struct machine_desc *desc,
-                      struct tag *tags, char **cmdline, struct meminfo *mi)
+	struct tag *tags, char **cmdline, struct meminfo *mi)
 {
 	mi->nr_banks=1;
 	mi->bank[0].start = 0xa0000000;
@@ -32,83 +92,95 @@
 		mi->bank[0].size = (64*1024*1024);
 }
 
+static void __init e740_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config));
+}
+
+static void __init e400_init(void)
+{
+	pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config));
+}
+
 /* e-series machine definitions */
 
 #ifdef CONFIG_MACH_E330
 MACHINE_START(E330, "Toshiba e330")
-        /* Maintainer: Ian Molton (spyro@f2s.com) */
-        .phys_io        = 0x40000000,
-        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-        .boot_params    = 0xa0000100,
-        .map_io         = pxa_map_io,
-        .init_irq       = pxa25x_init_irq,
-        .fixup          = eseries_fixup,
-        .timer = &pxa_timer,
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_E350
 MACHINE_START(E350, "Toshiba e350")
 	/* Maintainer: Ian Molton (spyro@f2s.com) */
-	.phys_io        = 0x40000000,
-	.io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-	.boot_params    = 0xa0000100,
-	.map_io         = pxa_map_io,
-	.init_irq       = pxa25x_init_irq,
-	.fixup          = eseries_fixup,
-	.timer = &pxa_timer,
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_E740
 MACHINE_START(E740, "Toshiba e740")
-        /* Maintainer: Ian Molton (spyro@f2s.com) */
-        .phys_io        = 0x40000000,
-        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-        .boot_params    = 0xa0000100,
-        .map_io         = pxa_map_io,
-        .init_irq       = pxa25x_init_irq,
-        .fixup          = eseries_fixup,
-        .timer = &pxa_timer,
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.init_machine	= e740_init,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_E750
 MACHINE_START(E750, "Toshiba e750")
-        /* Maintainer: Ian Molton (spyro@f2s.com) */
-        .phys_io        = 0x40000000,
-        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-        .boot_params    = 0xa0000100,
-        .map_io         = pxa_map_io,
-        .init_irq       = pxa25x_init_irq,
-        .fixup          = eseries_fixup,
-        .timer = &pxa_timer,
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_E400
 MACHINE_START(E400, "Toshiba e400")
-        /* Maintainer: Ian Molton (spyro@f2s.com) */
-        .phys_io        = 0x40000000,
-        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-        .boot_params    = 0xa0000100,
-        .map_io         = pxa_map_io,
-        .init_irq       = pxa25x_init_irq,
-        .fixup          = eseries_fixup,
-        .timer = &pxa_timer,
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.init_machine	= e400_init,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_E800
 MACHINE_START(E800, "Toshiba e800")
-        /* Maintainer: Ian Molton (spyro@f2s.com) */
-        .phys_io        = 0x40000000,
-        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-        .boot_params    = 0xa0000100,
-        .map_io         = pxa_map_io,
-        .init_irq       = pxa25x_init_irq,
-        .fixup          = eseries_fixup,
-        .timer = &pxa_timer,
+	/* Maintainer: Ian Molton (spyro@f2s.com) */
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+	.init_irq	= pxa25x_init_irq,
+	.fixup		= eseries_fixup,
+	.timer		= &pxa_timer,
 MACHINE_END
 #endif
 
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index 32772bc..108b5db 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -183,6 +183,7 @@
       defined(CONFIG_MACH_TOSA) || \
       defined(CONFIG_MACH_MAINSTONE) || \
       defined(CONFIG_MACH_PCM027) || \
+      defined(CONFIG_ARCH_PXA_ESERIES) || \
       defined(CONFIG_MACH_MAGICIAN)
 #define NR_IRQS			(IRQ_BOARD_END)
 #elif defined(CONFIG_MACH_ZYLONITE)
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index bb9e092..4ffdff2 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -52,6 +52,7 @@
 #include <mach/mmc.h>
 
 #include "generic.h"
+#include "clock.h"
 #include "devices.h"
 
 static unsigned long lubbock_pin_config[] __initdata = {
@@ -485,6 +486,7 @@
 
 	pxa2xx_mfp_config(ARRAY_AND_SIZE(lubbock_pin_config));
 
+	clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
 	pxa_set_udc_info(&udc_info);
 	set_pxa_fb_info(&sharp_lm8v31);
 	pxa_set_mci_info(&lubbock_mci_platform_data);
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 9e5d8a8..305452b 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -166,8 +166,7 @@
 ;
 
 /*
- * PXA 2xx clock declarations. Order is important (see aliases below)
- * Please be careful not to disrupt the ordering.
+ * PXA 2xx clock declarations.
  */
 static struct clk pxa25x_clks[] = {
 	INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev),
@@ -194,11 +193,6 @@
 	INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL),
 };
 
-static struct clk pxa2xx_clk_aliases[] = {
-	INIT_CKOTHER("GPIO7_CLK", &pxa25x_clks[4], NULL),
-	INIT_CKOTHER("SA1111_CLK", &pxa25x_clks[5], NULL),
-};
-
 #ifdef CONFIG_PM
 
 #define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
@@ -375,8 +369,6 @@
 	if (cpu_is_pxa255())
 		ret = platform_device_register(&pxa_device_hwuart);
 
-	clks_register(pxa2xx_clk_aliases, ARRAY_SIZE(pxa2xx_clk_aliases));
-
 	return ret;
 }
 
diff --git a/arch/arm/mach-pxa/pxa300.c b/arch/arm/mach-pxa/pxa300.c
index 494fc1f..9adc7fc 100644
--- a/arch/arm/mach-pxa/pxa300.c
+++ b/arch/arm/mach-pxa/pxa300.c
@@ -90,7 +90,9 @@
 };
 
 static struct clk pxa310_clks[] = {
+#ifdef CONFIG_CPU_PXA310
 	PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev),
+#endif
 };
 
 static int __init pxa300_init(void)
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index c5cdb97..9b0bc2c 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Fri May 30 09:49:33 2008
+# Linux kernel version: 2.6.27-rc4
+# Thu Aug 21 19:43:29 2008
 #
 CONFIG_SCHED_MC=y
 CONFIG_MMU=y
@@ -68,7 +68,6 @@
 CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -93,11 +92,17 @@
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
 CONFIG_KRETPROBES=y
+# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -113,6 +118,7 @@
 CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
 
 #
@@ -175,6 +181,8 @@
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -185,8 +193,12 @@
 CONFIG_SPARSEMEM_EXTREME=y
 CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
 CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
@@ -198,6 +210,7 @@
 CONFIG_MACHCHK_WARNING=y
 CONFIG_QDIO=y
 # CONFIG_QDIO_DEBUG is not set
+CONFIG_CHSC_SCH=m
 
 #
 # Misc
@@ -206,6 +219,7 @@
 # CONFIG_IPL_TAPE is not set
 CONFIG_IPL_VM=y
 CONFIG_BINFMT_ELF=y
+CONFIG_COMPAT_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 CONFIG_FORCE_MAX_ZONEORDER=9
 # CONFIG_PROCESS_DEBUG is not set
@@ -226,10 +240,6 @@
 CONFIG_KEXEC=y
 # CONFIG_ZFCPDUMP is not set
 CONFIG_S390_GUEST=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -364,7 +374,6 @@
 # CONFIG_NET_SCH_HTB is not set
 # CONFIG_NET_SCH_HFSC is not set
 CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RR=m
 CONFIG_NET_SCH_RED=m
 CONFIG_NET_SCH_SFQ=m
 CONFIG_NET_SCH_TEQL=m
@@ -430,7 +439,9 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 CONFIG_SYS_HYPERVISOR=y
@@ -507,6 +518,11 @@
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_ZFCP=y
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=m
@@ -522,14 +538,10 @@
 CONFIG_DM_SNAPSHOT=y
 CONFIG_DM_MIRROR=y
 CONFIG_DM_ZERO=y
-CONFIG_DM_MULTIPATH=y
-# CONFIG_DM_MULTIPATH_EMC is not set
-# CONFIG_DM_MULTIPATH_RDAC is not set
-# CONFIG_DM_MULTIPATH_HP is not set
+CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 # CONFIG_DM_UEVENT is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_IFB is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
@@ -544,7 +556,6 @@
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NETDEV_1000=y
-# CONFIG_E1000E_ENABLED is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_TR is not set
 # CONFIG_WAN is not set
@@ -576,7 +587,10 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_HVC_DRIVER=y
+CONFIG_VIRTIO_CONSOLE=y
 CONFIG_HW_RANDOM=m
+CONFIG_HW_RANDOM_VIRTIO=m
 # CONFIG_R3964 is not set
 CONFIG_RAW_DRIVER=m
 CONFIG_MAX_RAW_DEVS=256
@@ -616,6 +630,7 @@
 CONFIG_S390_VMUR=m
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -693,6 +708,7 @@
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -712,7 +728,6 @@
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -780,6 +795,7 @@
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_FRAME_POINTER is not set
@@ -789,6 +805,7 @@
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_SAMPLES=y
 # CONFIG_SAMPLE_KOBJECT is not set
 # CONFIG_SAMPLE_KPROBES is not set
@@ -847,6 +864,10 @@
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -895,6 +916,7 @@
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=m
 CONFIG_CRC7=m
diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h
index b4eb24a..8e9243a 100644
--- a/arch/s390/include/asm/bitops.h
+++ b/arch/s390/include/asm/bitops.h
@@ -709,7 +709,7 @@
 		 * __ffz_word returns __BITOPS_WORDSIZE
 		 * if no zero bit is present in the word.
 		 */
-		set = __ffz_word(0, *p >> bit) + bit;
+		set = __ffz_word(bit, *p >> bit);
 		if (set >= size)
 			return size + offset;
 		if (set < __BITOPS_WORDSIZE)
@@ -824,7 +824,7 @@
 		 * s390 version of ffz returns __BITOPS_WORDSIZE
 		 * if no zero bit is present in the word.
 		 */
-		set = ffz(__load_ulong_le(p, 0) >> bit) + bit;
+		set = __ffz_word(bit, __load_ulong_le(p, 0) >> bit);
 		if (set >= size)
 			return size + offset;
 		if (set < __BITOPS_WORDSIZE)
@@ -865,7 +865,7 @@
 		 * s390 version of ffz returns __BITOPS_WORDSIZE
 		 * if no zero bit is present in the word.
 		 */
-		set = ffs(__load_ulong_le(p, 0) >> bit) + bit;
+		set = __ffs_word(0, __load_ulong_le(p, 0) & (~0UL << bit));
 		if (set >= size)
 			return size + offset;
 		if (set < __BITOPS_WORDSIZE)
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 9839767..3e2c05c 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -75,7 +75,9 @@
 	return sf->gprs[8];
 }
 
-DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
+DEFINE_PER_CPU(struct s390_idle_data, s390_idle) = {
+	.lock = __SPIN_LOCK_UNLOCKED(s390_idle.lock)
+};
 
 static int s390_idle_enter(void)
 {
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index b795b3e..00b9b4d 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -610,7 +610,6 @@
 	if (IS_ERR(p))
 		panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
 	current_set[cpu] = p;
-	spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock);
 }
 
 static int __cpuinit smp_alloc_lowcore(int cpu)
@@ -845,7 +844,6 @@
 	current_set[0] = current;
 	smp_cpu_state[0] = CPU_STATE_CONFIGURED;
 	smp_cpu_polarization[0] = POLARIZATION_UNKNWN;
-	spin_lock_init(&(&__get_cpu_var(s390_idle))->lock);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index de39e1f..69b4d06 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -65,7 +65,7 @@
 	u8 *target;
 
 	tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
-	target = (iommu->cmd_buf + tail);
+	target = iommu->cmd_buf + tail;
 	memcpy_toio(target, cmd, sizeof(*cmd));
 	tail = (tail + sizeof(*cmd)) % iommu->cmd_buf_size;
 	head = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c
index 84a8220..a6ef672 100644
--- a/arch/x86/kernel/cpu/addon_cpuid_features.c
+++ b/arch/x86/kernel/cpu/addon_cpuid_features.c
@@ -56,9 +56,22 @@
 
 	switch (c->x86_vendor) {
 	case X86_VENDOR_INTEL:
-		if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
+		/*
+		 * There is a known erratum on Pentium III and Core Solo
+		 * and Core Duo CPUs.
+		 * " Page with PAT set to WC while associated MTRR is UC
+		 *   may consolidate to UC "
+		 * Because of this erratum, it is better to stick with
+		 * setting WC in MTRR rather than using PAT on these CPUs.
+		 *
+		 * Enable PAT WC only on P4, Core 2 or later CPUs.
+		 */
+		if (c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 15))
 			return;
-		break;
+
+		pat_disable("PAT WC disabled due to known CPU erratum.");
+		return;
+
 	case X86_VENDOR_AMD:
 	case X86_VENDOR_CENTAUR:
 	case X86_VENDOR_TRANSMETA:
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
index 3fd7a67..e710a21 100644
--- a/arch/x86/kernel/cpu/cyrix.c
+++ b/arch/x86/kernel/cpu/cyrix.c
@@ -134,23 +134,6 @@
 	setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14);
 }
 
-static void __cpuinit set_cx86_inc(void)
-{
-	unsigned char ccr3;
-
-	printk(KERN_INFO "Enable Incrementor on Cyrix/NSC processor.\n");
-
-	ccr3 = getCx86(CX86_CCR3);
-	setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
-	/* PCR1 -- Performance Control */
-	/* Incrementor on, whatever that is */
-	setCx86(CX86_PCR1, getCx86(CX86_PCR1) | 0x02);
-	/* PCR0 -- Performance Control */
-	/* Incrementor Margin 10 */
-	setCx86(CX86_PCR0, getCx86(CX86_PCR0) | 0x04);
-	setCx86(CX86_CCR3, ccr3);	/* disable MAPEN */
-}
-
 /*
  *	Configure later MediaGX and/or Geode processor.
  */
@@ -174,7 +157,6 @@
 
 	set_cx86_memwb();
 	set_cx86_reorder();
-	set_cx86_inc();
 
 	local_irq_restore(flags);
 }
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 509bd3d..cb7d3b6 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -379,6 +379,7 @@
 			     unsigned long *size, mtrr_type *type)
 {
 	unsigned int mask_lo, mask_hi, base_lo, base_hi;
+	unsigned int tmp, hi;
 
 	rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
 	if ((mask_lo & 0x800) == 0) {
@@ -392,8 +393,23 @@
 	rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
 
 	/* Work out the shifted address mask. */
-	mask_lo = size_or_mask | mask_hi << (32 - PAGE_SHIFT)
-	    | mask_lo >> PAGE_SHIFT;
+	tmp = mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT;
+	mask_lo = size_or_mask | tmp;
+	/* Expand tmp with high bits to all 1s*/
+	hi = fls(tmp);
+	if (hi > 0) {
+		tmp |= ~((1<<(hi - 1)) - 1);
+
+		if (tmp != mask_lo) {
+			static int once = 1;
+
+			if (once) {
+				printk(KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
+				once = 0;
+			}
+			mask_lo = tmp;
+		}
+	}
 
 	/* This works correctly if size is a power of two, i.e. a
 	   contiguous range. */
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 6f23969..b117d7f 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -1496,11 +1496,8 @@
 
 	/* kvm/qemu doesn't have mtrr set right, don't trim them all */
 	if (!highest_pfn) {
-		if (!kvm_para_available()) {
-			printk(KERN_WARNING
+		WARN(!kvm_para_available(), KERN_WARNING
 				"WARNING: strange, CPU MTRRs all blank?\n");
-			WARN_ON(1);
-		}
 		return 0;
 	}
 
diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c
index 2d7e307..bfa837c 100644
--- a/arch/x86/kernel/genx2apic_uv_x.c
+++ b/arch/x86/kernel/genx2apic_uv_x.c
@@ -293,7 +293,9 @@
 		sn_rtc_cycles_per_second = ticks_per_sec;
 }
 
-static __init void uv_system_init(void)
+static bool uv_system_inited;
+
+void __init uv_system_init(void)
 {
 	union uvh_si_addr_map_config_u m_n_config;
 	union uvh_node_id_u node_id;
@@ -383,6 +385,7 @@
 	map_mmr_high(max_pnode);
 	map_config_high(max_pnode);
 	map_mmioh_high(max_pnode);
+	uv_system_inited = true;
 }
 
 /*
@@ -391,8 +394,7 @@
  */
 void __cpuinit uv_cpu_init(void)
 {
-	if (!uv_node_to_blade)
-		uv_system_init();
+	BUG_ON(!uv_system_inited);
 
 	uv_blade_info[uv_numa_blade_id()].nr_online_cpus++;
 
diff --git a/arch/x86/kernel/numaq_32.c b/arch/x86/kernel/numaq_32.c
index b8c4561..eecc8c1 100644
--- a/arch/x86/kernel/numaq_32.c
+++ b/arch/x86/kernel/numaq_32.c
@@ -73,7 +73,7 @@
 }
 
 
-void __init numaq_tsc_disable(void)
+void __cpuinit numaq_tsc_disable(void)
 {
 	if (!found_numaq)
 		return;
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 94da4d5..300da17 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -471,7 +471,7 @@
 	.spin_unlock = __ticket_spin_unlock,
 #endif
 };
-EXPORT_SYMBOL_GPL(pv_lock_ops);
+EXPORT_SYMBOL(pv_lock_ops);
 
 EXPORT_SYMBOL_GPL(pv_time_ops);
 EXPORT_SYMBOL    (pv_cpu_ops);
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 218d783..dcdac6c 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -343,9 +343,8 @@
 	/* were we called with bad_dma_address? */
 	badend = bad_dma_address + (EMERGENCY_PAGES * PAGE_SIZE);
 	if (unlikely((dma_addr >= bad_dma_address) && (dma_addr < badend))) {
-		printk(KERN_ERR "Calgary: driver tried unmapping bad DMA "
+		WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA "
 		       "address 0x%Lx\n", dma_addr);
-		WARN_ON(1);
 		return;
 	}
 
@@ -1269,13 +1268,15 @@
 static int __init build_detail_arrays(void)
 {
 	unsigned long ptr;
-	int i, scal_detail_size, rio_detail_size;
+	unsigned numnodes, i;
+	int scal_detail_size, rio_detail_size;
 
-	if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){
+	numnodes = rio_table_hdr->num_scal_dev;
+	if (numnodes > MAX_NUMNODES){
 		printk(KERN_WARNING
 			"Calgary: MAX_NUMNODES too low! Defined as %d, "
 			"but system has %d nodes.\n",
-			MAX_NUMNODES, rio_table_hdr->num_scal_dev);
+			MAX_NUMNODES, numnodes);
 		return -ENODEV;
 	}
 
@@ -1296,8 +1297,7 @@
 	}
 
 	ptr = ((unsigned long)rio_table_hdr) + 3;
-	for (i = 0; i < rio_table_hdr->num_scal_dev;
-		    i++, ptr += scal_detail_size)
+	for (i = 0; i < numnodes; i++, ptr += scal_detail_size)
 		scal_devs[i] = (struct scal_detail *)ptr;
 
 	for (i = 0; i < rio_table_hdr->num_rio_dev;
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index a4656ad..362d4e7 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -604,14 +604,6 @@
 	early_cpu_init();
 	early_ioremap_init();
 
-#if defined(CONFIG_VMI) && defined(CONFIG_X86_32)
-	/*
-	 * Must be before kernel pagetables are setup
-	 * or fixmap area is touched.
-	 */
-	vmi_init();
-#endif
-
 	ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
 	screen_info = boot_params.screen_info;
 	edid_info = boot_params.edid_info;
@@ -678,6 +670,14 @@
 
 	parse_early_param();
 
+#if defined(CONFIG_VMI) && defined(CONFIG_X86_32)
+	/*
+	 * Must be before kernel pagetables are setup
+	 * or fixmap area is touched.
+	 */
+	vmi_init();
+#endif
+
 	/* after early param, so could get panic from serial */
 	reserve_early_setup_data();
 
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index e139e61..7985c5b 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1221,6 +1221,9 @@
 	printk(KERN_INFO "CPU%d: ", 0);
 	print_cpu_info(&cpu_data(0));
 	setup_boot_clock();
+
+	if (is_uv_system())
+		uv_system_init();
 out:
 	preempt_enable();
 }
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index d0fbb77..8b8c0d66 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -17,6 +17,7 @@
 #include <asm/genapic.h>
 #include <asm/idle.h>
 #include <asm/tsc.h>
+#include <asm/irq_vectors.h>
 
 #include <mach_apic.h>
 
@@ -783,7 +784,7 @@
 		uv_init_blade(blade, node, cur_cpu);
 		cur_cpu += uv_blade_nr_possible_cpus(blade);
 	}
-	set_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1);
+	alloc_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1);
 	uv_enable_timeouts();
 
 	return 0;
diff --git a/arch/x86/kernel/tsc_sync.c b/arch/x86/kernel/tsc_sync.c
index 0577825..9ffb01c 100644
--- a/arch/x86/kernel/tsc_sync.c
+++ b/arch/x86/kernel/tsc_sync.c
@@ -88,11 +88,9 @@
 			__raw_spin_unlock(&sync_lock);
 		}
 	}
-	if (!(now-start)) {
-		printk("Warning: zero tsc calibration delta: %Ld [max: %Ld]\n",
+	WARN(!(now-start),
+		"Warning: zero tsc calibration delta: %Ld [max: %Ld]\n",
 			now-start, end-start);
-		WARN_ON(1);
-	}
 }
 
 /*
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index a87ea0e..d3746ef 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -241,7 +241,7 @@
 static unsigned long __meminitdata table_end;
 static unsigned long __meminitdata table_top;
 
-static __meminit void *alloc_low_page(unsigned long *phys)
+static __ref void *alloc_low_page(unsigned long *phys)
 {
 	unsigned long pfn = table_end++;
 	void *adr;
@@ -262,7 +262,7 @@
 	return adr;
 }
 
-static __meminit void unmap_low_page(void *adr)
+static __ref void unmap_low_page(void *adr)
 {
 	if (after_bootmem)
 		return;
@@ -336,9 +336,12 @@
 		}
 
 		if (pmd_val(*pmd)) {
-			if (!pmd_large(*pmd))
+			if (!pmd_large(*pmd)) {
+				spin_lock(&init_mm.page_table_lock);
 				last_map_addr = phys_pte_update(pmd, address,
-								 end);
+								end);
+				spin_unlock(&init_mm.page_table_lock);
+			}
 			/* Count entries we're using from level2_ident_pgt */
 			if (start == 0)
 				pages++;
@@ -347,8 +350,10 @@
 
 		if (page_size_mask & (1<<PG_LEVEL_2M)) {
 			pages++;
+			spin_lock(&init_mm.page_table_lock);
 			set_pte((pte_t *)pmd,
 				pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL_LARGE));
+			spin_unlock(&init_mm.page_table_lock);
 			last_map_addr = (address & PMD_MASK) + PMD_SIZE;
 			continue;
 		}
@@ -357,7 +362,9 @@
 		last_map_addr = phys_pte_init(pte, address, end);
 		unmap_low_page(pte);
 
+		spin_lock(&init_mm.page_table_lock);
 		pmd_populate_kernel(&init_mm, pmd, __va(pte_phys));
+		spin_unlock(&init_mm.page_table_lock);
 	}
 	update_page_count(PG_LEVEL_2M, pages);
 	return last_map_addr;
@@ -370,9 +377,7 @@
 	pmd_t *pmd = pmd_offset(pud, 0);
 	unsigned long last_map_addr;
 
-	spin_lock(&init_mm.page_table_lock);
 	last_map_addr = phys_pmd_init(pmd, address, end, page_size_mask);
-	spin_unlock(&init_mm.page_table_lock);
 	__flush_tlb_all();
 	return last_map_addr;
 }
@@ -408,20 +413,21 @@
 
 		if (page_size_mask & (1<<PG_LEVEL_1G)) {
 			pages++;
+			spin_lock(&init_mm.page_table_lock);
 			set_pte((pte_t *)pud,
 				pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL_LARGE));
+			spin_unlock(&init_mm.page_table_lock);
 			last_map_addr = (addr & PUD_MASK) + PUD_SIZE;
 			continue;
 		}
 
 		pmd = alloc_low_page(&pmd_phys);
-
-		spin_lock(&init_mm.page_table_lock);
 		last_map_addr = phys_pmd_init(pmd, addr, end, page_size_mask);
 		unmap_low_page(pmd);
+
+		spin_lock(&init_mm.page_table_lock);
 		pud_populate(&init_mm, pud, __va(pmd_phys));
 		spin_unlock(&init_mm.page_table_lock);
-
 	}
 	__flush_tlb_all();
 	update_page_count(PG_LEVEL_1G, pages);
@@ -513,16 +519,14 @@
 			continue;
 		}
 
-		if (after_bootmem)
-			pud = pud_offset(pgd, start & PGDIR_MASK);
-		else
-			pud = alloc_low_page(&pud_phys);
-
+		pud = alloc_low_page(&pud_phys);
 		last_map_addr = phys_pud_init(pud, __pa(start), __pa(next),
 						 page_size_mask);
 		unmap_low_page(pud);
-		pgd_populate(&init_mm, pgd_offset_k(start),
-			     __va(pud_phys));
+
+		spin_lock(&init_mm.page_table_lock);
+		pgd_populate(&init_mm, pgd, __va(pud_phys));
+		spin_unlock(&init_mm.page_table_lock);
 	}
 
 	return last_map_addr;
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 6ba6f88..d4b6e6a 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -553,13 +553,11 @@
 {
 	if (!early_ioremap_nested)
 		return 0;
-
-	printk(KERN_WARNING
+	WARN(1, KERN_WARNING
 	       "Debug warning: early ioremap leak of %d areas detected.\n",
-	       early_ioremap_nested);
+		early_ioremap_nested);
 	printk(KERN_WARNING
-	       "please boot with early_ioremap_debug and report the dmesg.\n");
-	WARN_ON(1);
+		"please boot with early_ioremap_debug and report the dmesg.\n");
 
 	return 1;
 }
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index e7397e1..635b50e 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -430,7 +430,9 @@
 						"may miss events.\n");
 }
 
-static void leave_uniprocessor(void)
+/* __ref because leave_uniprocessor calls cpu_up which is __cpuinit,
+   but this whole function is ifdefed CONFIG_HOTPLUG_CPU */
+static void __ref leave_uniprocessor(void)
 {
 	int cpu;
 	int err;
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index f5f5154..43e2f84 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -849,7 +849,7 @@
 	/*
 	 * for now UC MINUS. see comments in ioremap_nocache()
 	 */
-	if (reserve_memtype(addr, addr + numpages * PAGE_SIZE,
+	if (reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
 			    _PAGE_CACHE_UC_MINUS, NULL))
 		return -EINVAL;
 
@@ -868,7 +868,7 @@
 	if (!pat_enabled)
 		return set_memory_uc(addr, numpages);
 
-	if (reserve_memtype(addr, addr + numpages * PAGE_SIZE,
+	if (reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
 		_PAGE_CACHE_WC, NULL))
 		return -EINVAL;
 
@@ -884,7 +884,7 @@
 
 int set_memory_wb(unsigned long addr, int numpages)
 {
-	free_memtype(addr, addr + numpages * PAGE_SIZE);
+	free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
 
 	return _set_memory_wb(addr, numpages);
 }
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 2fe3091..2a50e0f 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -207,6 +207,9 @@
 	return -EBUSY;
 }
 
+static struct memtype *cached_entry;
+static u64 cached_start;
+
 /*
  * req_type typically has one of the:
  * - _PAGE_CACHE_WB
@@ -280,11 +283,17 @@
 
 	spin_lock(&memtype_lock);
 
+	if (cached_entry && start >= cached_start)
+		entry = cached_entry;
+	else
+		entry = list_entry(&memtype_list, struct memtype, nd);
+
 	/* Search for existing mapping that overlaps the current range */
 	where = NULL;
-	list_for_each_entry(entry, &memtype_list, nd) {
+	list_for_each_entry_continue(entry, &memtype_list, nd) {
 		if (end <= entry->start) {
 			where = entry->nd.prev;
+			cached_entry = list_entry(where, struct memtype, nd);
 			break;
 		} else if (start <= entry->start) { /* end > entry->start */
 			err = chk_conflict(new, entry, new_type);
@@ -292,6 +301,8 @@
 				dprintk("Overlap at 0x%Lx-0x%Lx\n",
 					entry->start, entry->end);
 				where = entry->nd.prev;
+				cached_entry = list_entry(where,
+							struct memtype, nd);
 			}
 			break;
 		} else if (start < entry->end) { /* start > entry->start */
@@ -299,7 +310,20 @@
 			if (!err) {
 				dprintk("Overlap at 0x%Lx-0x%Lx\n",
 					entry->start, entry->end);
-				where = &entry->nd;
+				cached_entry = list_entry(entry->nd.prev,
+							struct memtype, nd);
+
+				/*
+				 * Move to right position in the linked
+				 * list to add this new entry
+				 */
+				list_for_each_entry_continue(entry,
+							&memtype_list, nd) {
+					if (start <= entry->start) {
+						where = entry->nd.prev;
+						break;
+					}
+				}
 			}
 			break;
 		}
@@ -314,6 +338,8 @@
 		return err;
 	}
 
+	cached_start = start;
+
 	if (where)
 		list_add(&new->nd, where);
 	else
@@ -343,6 +369,9 @@
 	spin_lock(&memtype_lock);
 	list_for_each_entry(entry, &memtype_list, nd) {
 		if (entry->start == start && entry->end == end) {
+			if (cached_entry == entry || cached_start == start)
+				cached_entry = NULL;
+
 			list_del(&entry->nd);
 			kfree(entry);
 			err = 0;
@@ -361,14 +390,6 @@
 }
 
 
-/*
- * /dev/mem mmap interface. The memtype used for mapping varies:
- * - Use UC for mappings with O_SYNC flag
- * - Without O_SYNC flag, if there is any conflict in reserve_memtype,
- *   inherit the memtype from existing mapping.
- * - Else use UC_MINUS memtype (for backward compatibility with existing
- *   X drivers.
- */
 pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 				unsigned long size, pgprot_t vma_prot)
 {
@@ -406,14 +427,14 @@
 				unsigned long size, pgprot_t *vma_prot)
 {
 	u64 offset = ((u64) pfn) << PAGE_SHIFT;
-	unsigned long flags = _PAGE_CACHE_UC_MINUS;
+	unsigned long flags = -1;
 	int retval;
 
 	if (!range_is_allowed(pfn, size))
 		return 0;
 
 	if (file->f_flags & O_SYNC) {
-		flags = _PAGE_CACHE_UC;
+		flags = _PAGE_CACHE_UC_MINUS;
 	}
 
 #ifdef CONFIG_X86_32
@@ -436,13 +457,14 @@
 #endif
 
 	/*
-	 * With O_SYNC, we can only take UC mapping. Fail if we cannot.
+	 * With O_SYNC, we can only take UC_MINUS mapping. Fail if we cannot.
+	 *
 	 * Without O_SYNC, we want to get
 	 * - WB for WB-able memory and no other conflicting mappings
 	 * - UC_MINUS for non-WB-able memory with no other conflicting mappings
 	 * - Inherit from confliting mappings otherwise
 	 */
-	if (flags != _PAGE_CACHE_UC_MINUS) {
+	if (flags != -1) {
 		retval = reserve_memtype(offset, offset + size, flags, NULL);
 	} else {
 		retval = reserve_memtype(offset, offset + size, -1, &flags);
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index 3f90289..0227694 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/kdebug.h>
+#include <linux/cpu.h>
 #include <asm/nmi.h>
 #include <asm/msr.h>
 #include <asm/apic.h>
@@ -28,23 +29,48 @@
 
 static int nmi_start(void);
 static void nmi_stop(void);
+static void nmi_cpu_start(void *dummy);
+static void nmi_cpu_stop(void *dummy);
 
 /* 0 == registered but off, 1 == registered and on */
 static int nmi_enabled = 0;
 
+#ifdef CONFIG_SMP
+static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
+				 void *data)
+{
+	int cpu = (unsigned long)data;
+	switch (action) {
+	case CPU_DOWN_FAILED:
+	case CPU_ONLINE:
+		smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
+		break;
+	case CPU_DOWN_PREPARE:
+		smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block oprofile_cpu_nb = {
+	.notifier_call = oprofile_cpu_notifier
+};
+#endif
+
 #ifdef CONFIG_PM
 
 static int nmi_suspend(struct sys_device *dev, pm_message_t state)
 {
+	/* Only one CPU left, just stop that one */
 	if (nmi_enabled == 1)
-		nmi_stop();
+		nmi_cpu_stop(NULL);
 	return 0;
 }
 
 static int nmi_resume(struct sys_device *dev)
 {
 	if (nmi_enabled == 1)
-		nmi_start();
+		nmi_cpu_start(NULL);
 	return 0;
 }
 
@@ -463,6 +489,9 @@
 	}
 
 	init_sysfs();
+#ifdef CONFIG_SMP
+	register_cpu_notifier(&oprofile_cpu_nb);
+#endif
 	using_nmi = 1;
 	ops->create_files = nmi_create_files;
 	ops->setup = nmi_setup;
@@ -476,6 +505,10 @@
 
 void op_nmi_exit(void)
 {
-	if (using_nmi)
+	if (using_nmi) {
 		exit_sysfs();
+#ifdef CONFIG_SMP
+		unregister_cpu_notifier(&oprofile_cpu_nb);
+#endif
+	}
 }
diff --git a/block/genhd.c b/block/genhd.c
index c13cc77..656c2c7 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -293,27 +293,30 @@
 /* iterator */
 static int find_start(struct device *dev, void *data)
 {
-	loff_t k = *(loff_t *)data;
+	loff_t *k = data;
 
 	if (dev->type != &disk_type)
 		return 0;
-	if (!k--)
+	if (!*k)
 		return 1;
+	(*k)--;
 	return 0;
 }
 
 static void *part_start(struct seq_file *part, loff_t *pos)
 {
 	struct device *dev;
-	loff_t n = *pos;
+	loff_t k = *pos;
 
-	if (!n)
+	if (!k)
 		seq_puts(part, "major minor  #blocks  name\n\n");
 
 	mutex_lock(&block_class_lock);
-	dev = class_find_device(&block_class, NULL, (void *)pos, find_start);
-	if (dev)
+	dev = class_find_device(&block_class, NULL, &k, find_start);
+	if (dev) {
+		put_device(dev);
 		return dev_to_disk(dev);
+	}
 	return NULL;
 }
 
@@ -330,8 +333,10 @@
 	struct device *dev;
 	++*pos;
 	dev = class_find_device(&block_class, &gp->dev, NULL, find_next);
-	if (dev)
+	if (dev) {
+		put_device(dev);
 		return dev_to_disk(dev);
+	}
 	return NULL;
 }
 
@@ -568,11 +573,14 @@
 static void *diskstats_start(struct seq_file *part, loff_t *pos)
 {
 	struct device *dev;
+	loff_t k = *pos;
 
 	mutex_lock(&block_class_lock);
-	dev = class_find_device(&block_class, NULL, (void *)pos, find_start);
-	if (dev)
+	dev = class_find_device(&block_class, NULL, &k, find_start);
+	if (dev) {
+		put_device(dev);
 		return dev_to_disk(dev);
+	}
 	return NULL;
 }
 
@@ -583,8 +591,10 @@
 
 	++*pos;
 	dev = class_find_device(&block_class, &gp->dev, NULL, find_next);
-	if (dev)
+	if (dev) {
+		put_device(dev);
 		return dev_to_disk(dev);
+	}
 	return NULL;
 }
 
@@ -712,10 +722,12 @@
 	mutex_lock(&block_class_lock);
 	find.name = name;
 	find.part = part;
-	dev = class_find_device(&block_class, NULL, (void *)&find, match_id);
-	if (dev)
+	dev = class_find_device(&block_class, NULL, &find, match_id);
+	if (dev) {
+		put_device(dev);
 		devt = MKDEV(MAJOR(dev->devt),
 			     MINOR(dev->devt) + part);
+	}
 	mutex_unlock(&block_class_lock);
 
 	return devt;
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ef3e552..c729e69 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -486,6 +486,8 @@
 	{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
 	{ PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
 	{ PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */
+	{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
+	{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -575,9 +577,9 @@
 	{ PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci },		/* MCP7B */
 
 	/* SiS */
-	{ PCI_VDEVICE(SI, 0x1184), board_ahci_nopmp },		/* SiS 966 */
-	{ PCI_VDEVICE(SI, 0x1185), board_ahci_nopmp },		/* SiS 968 */
-	{ PCI_VDEVICE(SI, 0x0186), board_ahci_nopmp },		/* SiS 968 */
+	{ PCI_VDEVICE(SI, 0x1184), board_ahci },		/* SiS 966 */
+	{ PCI_VDEVICE(SI, 0x1185), board_ahci },		/* SiS 968 */
+	{ PCI_VDEVICE(SI, 0x0186), board_ahci },		/* SiS 968 */
 
 	/* Marvell */
 	{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv },	/* 6145 */
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index c294121..b1d08a8 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -275,6 +275,14 @@
 	{ 0x8086, 0x3a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
 	/* SATA Controller IDE (ICH10) */
 	{ 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+	/* SATA Controller IDE (PCH) */
+	{ 0x8086, 0x3b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+	/* SATA Controller IDE (PCH) */
+	{ 0x8086, 0x3b26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+	/* SATA Controller IDE (PCH) */
+	{ 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+	/* SATA Controller IDE (PCH) */
+	{ 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
 
 	{ }	/* terminate list */
 };
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 5ba96c5..79e3a8e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -104,6 +104,7 @@
 	unsigned long	xfer_mask;
 	unsigned int	horkage_on;
 	unsigned int	horkage_off;
+	unsigned int	lflags;
 };
 
 struct ata_force_ent {
@@ -196,22 +197,23 @@
 }
 
 /**
- *	ata_force_spd_limit - force SATA spd limit according to libata.force
+ *	ata_force_link_limits - force link limits according to libata.force
  *	@link: ATA link of interest
  *
- *	Force SATA spd limit according to libata.force and whine about
- *	it.  When only the port part is specified (e.g. 1:), the limit
- *	applies to all links connected to both the host link and all
- *	fan-out ports connected via PMP.  If the device part is
- *	specified as 0 (e.g. 1.00:), it specifies the first fan-out
- *	link not the host link.  Device number 15 always points to the
- *	host link whether PMP is attached or not.
+ *	Force link flags and SATA spd limit according to libata.force
+ *	and whine about it.  When only the port part is specified
+ *	(e.g. 1:), the limit applies to all links connected to both
+ *	the host link and all fan-out ports connected via PMP.  If the
+ *	device part is specified as 0 (e.g. 1.00:), it specifies the
+ *	first fan-out link not the host link.  Device number 15 always
+ *	points to the host link whether PMP is attached or not.
  *
  *	LOCKING:
  *	EH context.
  */
-static void ata_force_spd_limit(struct ata_link *link)
+static void ata_force_link_limits(struct ata_link *link)
 {
+	bool did_spd = false;
 	int linkno, i;
 
 	if (ata_is_host_link(link))
@@ -228,13 +230,22 @@
 		if (fe->device != -1 && fe->device != linkno)
 			continue;
 
-		if (!fe->param.spd_limit)
-			continue;
+		/* only honor the first spd limit */
+		if (!did_spd && fe->param.spd_limit) {
+			link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
+			ata_link_printk(link, KERN_NOTICE,
+					"FORCE: PHY spd limit set to %s\n",
+					fe->param.name);
+			did_spd = true;
+		}
 
-		link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
-		ata_link_printk(link, KERN_NOTICE,
-			"FORCE: PHY spd limit set to %s\n", fe->param.name);
-		return;
+		/* let lflags stack */
+		if (fe->param.lflags) {
+			link->flags |= fe->param.lflags;
+			ata_link_printk(link, KERN_NOTICE,
+					"FORCE: link flag 0x%x forced -> 0x%x\n",
+					fe->param.lflags, link->flags);
+		}
 	}
 }
 
@@ -3277,7 +3288,7 @@
 		dev->dma_mode = ata_xfer_mask2mode(dma_mask);
 
 		found = 1;
-		if (dev->dma_mode != 0xff)
+		if (ata_dma_enabled(dev))
 			used_dma = 1;
 	}
 	if (!found)
@@ -3302,7 +3313,7 @@
 
 	/* step 3: set host DMA timings */
 	ata_link_for_each_dev(dev, link) {
-		if (!ata_dev_enabled(dev) || dev->dma_mode == 0xff)
+		if (!ata_dev_enabled(dev) || !ata_dma_enabled(dev))
 			continue;
 
 		dev->xfer_mode = dev->dma_mode;
@@ -5188,19 +5199,18 @@
  */
 int sata_link_init_spd(struct ata_link *link)
 {
-	u32 scontrol;
 	u8 spd;
 	int rc;
 
-	rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
+	rc = sata_scr_read(link, SCR_CONTROL, &link->saved_scontrol);
 	if (rc)
 		return rc;
 
-	spd = (scontrol >> 4) & 0xf;
+	spd = (link->saved_scontrol >> 4) & 0xf;
 	if (spd)
 		link->hw_sata_spd_limit &= (1 << spd) - 1;
 
-	ata_force_spd_limit(link);
+	ata_force_link_limits(link);
 
 	link->sata_spd_limit = link->hw_sata_spd_limit;
 
@@ -5783,9 +5793,10 @@
 	ata_port_wait_eh(ap);
 
 	/* EH is now guaranteed to see UNLOADING - EH context belongs
-	 * to us.  Disable all existing devices.
+	 * to us.  Restore SControl and disable all existing devices.
 	 */
-	ata_port_for_each_link(link, ap) {
+	__ata_port_for_each_link(link, ap) {
+		sata_scr_write(link, SCR_CONTROL, link->saved_scontrol);
 		ata_link_for_each_dev(dev, link)
 			ata_dev_disable(dev);
 	}
@@ -5991,6 +6002,9 @@
 		{ "udma133",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 6) },
 		{ "udma/133",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 6) },
 		{ "udma7",	.xfer_mask	= 1 << (ATA_SHIFT_UDMA + 7) },
+		{ "nohrst",	.lflags		= ATA_LFLAG_NO_HRST },
+		{ "nosrst",	.lflags		= ATA_LFLAG_NO_SRST },
+		{ "norst",	.lflags		= ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
 	};
 	char *start = *cur, *p = *cur;
 	char *id, *val, *endp;
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 58bdc53..c1db2f2 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2040,7 +2040,7 @@
 	}
 
 	if (ehc->i.serror)
-		ata_port_printk(ap, KERN_ERR,
+		ata_link_printk(link, KERN_ERR,
 		  "SError: { %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s}\n",
 		  ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "",
 		  ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "",
@@ -2171,18 +2171,12 @@
 }
 
 static int ata_eh_followup_srst_needed(struct ata_link *link,
-				       int rc, int classify,
-				       const unsigned int *classes)
+				       int rc, const unsigned int *classes)
 {
 	if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
 		return 0;
-	if (rc == -EAGAIN) {
-		if (classify)
-			return 1;
-		rc = 0;
-	}
-	if (rc != 0)
-		return 0;
+	if (rc == -EAGAIN)
+		return 1;
 	if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
 		return 1;
 	return 0;
@@ -2210,6 +2204,10 @@
 	 */
 	while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX)
 		max_tries++;
+	if (link->flags & ATA_LFLAG_NO_HRST)
+		hardreset = NULL;
+	if (link->flags & ATA_LFLAG_NO_SRST)
+		softreset = NULL;
 
 	now = jiffies;
 	deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN);
@@ -2247,10 +2245,10 @@
 	ehc->i.action &= ~ATA_EH_RESET;
 	if (hardreset) {
 		reset = hardreset;
-		ehc->i.action = ATA_EH_HARDRESET;
+		ehc->i.action |= ATA_EH_HARDRESET;
 	} else if (softreset) {
 		reset = softreset;
-		ehc->i.action = ATA_EH_SOFTRESET;
+		ehc->i.action |= ATA_EH_SOFTRESET;
 	}
 
 	if (prereset) {
@@ -2305,9 +2303,11 @@
 			ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
 
 		rc = ata_do_reset(link, reset, classes, deadline);
+		if (rc && rc != -EAGAIN)
+			goto fail;
 
 		if (reset == hardreset &&
-		    ata_eh_followup_srst_needed(link, rc, classify, classes)) {
+		    ata_eh_followup_srst_needed(link, rc, classes)) {
 			/* okay, let's do follow-up softreset */
 			reset = softreset;
 
@@ -2322,10 +2322,6 @@
 			ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
 			rc = ata_do_reset(link, reset, classes, deadline);
 		}
-
-		/* -EAGAIN can happen if we skipped followup SRST */
-		if (rc && rc != -EAGAIN)
-			goto fail;
 	} else {
 		if (verbose)
 			ata_link_printk(link, KERN_INFO, "no reset method "
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index fbe6057..eb919c1 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -181,7 +181,7 @@
 
 	if (adev != acpi->last) {
 		pacpi_set_piomode(ap, adev);
-		if (adev->dma_mode)
+		if (ata_dma_enabled(adev))
 			pacpi_set_dmamode(ap, adev);
 		acpi->last = adev;
 	}
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index d7de7ba..e8a0d99 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -183,7 +183,7 @@
 	u16 tmp16;
 
 	pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
-	if (adev->dma_mode >= XFER_UDMA_0)
+	if (ata_using_udma(adev))
 		tmp16 |= (1 << dn);
 	else
 		tmp16 &= ~(1 << dn);
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 744beeb..0c4b271 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -149,10 +149,10 @@
 	struct ata_device *prev = ap->private_data;
 
 	/* See if the DMA settings could be wrong */
-	if (adev->dma_mode != 0 && adev != prev && prev != NULL) {
+	if (ata_dma_enabled(adev) && adev != prev && prev != NULL) {
 		/* Maybe, but do the channels match MWDMA/UDMA ? */
-		if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
-		    (adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
+		if ((ata_using_udma(adev) && !ata_using_udma(prev)) ||
+		    (ata_using_udma(prev) && !ata_using_udma(adev)))
 		    	/* Switch the mode bits */
 		    	cs5530_set_dmamode(ap, adev);
 	}
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 27843c7..0221c9a 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -606,7 +606,7 @@
 {
 	unsigned char id[41];
 	int mode = 0;
-	char *mtype;
+	char *mtype = "";
 	char mbuf[8];
 	char *cbl = "(40 wire cable)";
 
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index e678af3..df64f24 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -198,7 +198,7 @@
 
 	if (adev != ap->private_data) {
 		oldpiix_set_piomode(ap, adev);
-		if (adev->dma_mode)
+		if (ata_dma_enabled(adev))
 			oldpiix_set_dmamode(ap, adev);
 	}
 	return ata_sff_qc_issue(qc);
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index cbab397..0278fd2 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -167,10 +167,10 @@
 	struct ata_device *prev = ap->private_data;
 
 	/* See if the DMA settings could be wrong */
-	if (adev->dma_mode != 0 && adev != prev && prev != NULL) {
+	if (ata_dma_enabled(adev) && adev != prev && prev != NULL) {
 		/* Maybe, but do the channels match MWDMA/UDMA ? */
-		if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
-		    (adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
+		if ((ata_using_udma(adev) && !ata_using_udma(prev)) ||
+		    (ata_using_udma(prev) && !ata_using_udma(adev)))
 		    	/* Switch the mode bits */
 		    	sc1200_set_dmamode(ap, adev);
 	}
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 57d951b..8fdb2ce 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -324,62 +324,26 @@
 }
 
 /**
- *	via_ata_sff_tf_load - send taskfile registers to host controller
+ *	via_tf_load - send taskfile registers to host controller
  *	@ap: Port to which output is sent
  *	@tf: ATA taskfile register set
  *
  *	Outputs ATA taskfile to standard ATA host controller.
  *
  *	Note: This is to fix the internal bug of via chipsets, which
- *  will reset the device register after changing the IEN bit on
- *  ctl register
+ *	will reset the device register after changing the IEN bit on
+ *	ctl register
  */
-static void via_ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
 {
-	struct ata_ioports *ioaddr = &ap->ioaddr;
-	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+	struct ata_taskfile tmp_tf;
 
-	if (tf->ctl != ap->last_ctl) {
-		iowrite8(tf->ctl, ioaddr->ctl_addr);
-		iowrite8(tf->device, ioaddr->device_addr);
-		ap->last_ctl = tf->ctl;
-		ata_wait_idle(ap);
+	if (ap->ctl != ap->last_ctl && !(tf->flags & ATA_TFLAG_DEVICE)) {
+		tmp_tf = *tf;
+		tmp_tf.flags |= ATA_TFLAG_DEVICE;
+		tf = &tmp_tf;
 	}
-
-	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-		iowrite8(tf->hob_feature, ioaddr->feature_addr);
-		iowrite8(tf->hob_nsect, ioaddr->nsect_addr);
-		iowrite8(tf->hob_lbal, ioaddr->lbal_addr);
-		iowrite8(tf->hob_lbam, ioaddr->lbam_addr);
-		iowrite8(tf->hob_lbah, ioaddr->lbah_addr);
-		VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
-			tf->hob_feature,
-			tf->hob_nsect,
-			tf->hob_lbal,
-			tf->hob_lbam,
-			tf->hob_lbah);
-	}
-
-	if (is_addr) {
-		iowrite8(tf->feature, ioaddr->feature_addr);
-		iowrite8(tf->nsect, ioaddr->nsect_addr);
-		iowrite8(tf->lbal, ioaddr->lbal_addr);
-		iowrite8(tf->lbam, ioaddr->lbam_addr);
-		iowrite8(tf->lbah, ioaddr->lbah_addr);
-		VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
-			tf->feature,
-			tf->nsect,
-			tf->lbal,
-			tf->lbam,
-			tf->lbah);
-	}
-
-	if (tf->flags & ATA_TFLAG_DEVICE) {
-		iowrite8(tf->device, ioaddr->device_addr);
-		VPRINTK("device 0x%X\n", tf->device);
-	}
-
-	ata_wait_idle(ap);
+	ata_sff_tf_load(ap, tf);
 }
 
 static struct scsi_host_template via_sht = {
@@ -392,13 +356,12 @@
 	.set_piomode	= via_set_piomode,
 	.set_dmamode	= via_set_dmamode,
 	.prereset	= via_pre_reset,
-	.sff_tf_load = via_ata_tf_load,
+	.sff_tf_load	= via_tf_load,
 };
 
 static struct ata_port_operations via_port_ops_noirq = {
 	.inherits	= &via_port_ops,
 	.sff_data_xfer	= ata_sff_data_xfer_noirq,
-	.sff_tf_load = via_ata_tf_load,
 };
 
 /**
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index ad169ff..13c1d2a 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1134,30 +1134,16 @@
 	if (ap->nr_active_links == 0)
 		return 0;
 
-	if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
-		/*
-		 * The port is operating in host queuing mode (EDMA).
-		 * It can accomodate a new qc if the qc protocol
-		 * is compatible with the current host queue mode.
-		 */
-		if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) {
-			/*
-			 * The host queue (EDMA) is in NCQ mode.
-			 * If the new qc is also an NCQ command,
-			 * then allow the new qc.
-			 */
-			if (qc->tf.protocol == ATA_PROT_NCQ)
-				return 0;
-		} else {
-			/*
-			 * The host queue (EDMA) is in non-NCQ, DMA mode.
-			 * If the new qc is also a non-NCQ, DMA command,
-			 * then allow the new qc.
-			 */
-			if (qc->tf.protocol == ATA_PROT_DMA)
-				return 0;
-		}
-	}
+	/*
+	 * The port is operating in host queuing mode (EDMA) with NCQ
+	 * enabled, allow multiple NCQ commands.  EDMA also allows
+	 * queueing multiple DMA commands but libata core currently
+	 * doesn't allow it.
+	 */
+	if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
+	    (pp->pp_flags & MV_PP_FLAG_NCQ_EN) && ata_is_ncq(qc->tf.protocol))
+		return 0;
+
 	return ATA_DEFER_PORT;
 }
 
@@ -3036,7 +3022,8 @@
 		break;
 	case chip_soc:
 		hpriv->ops = &mv_soc_ops;
-		hp_flags |= MV_HP_FLAG_SOC | MV_HP_ERRATA_60X1C0;
+		hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
+			MV_HP_ERRATA_60X1C0;
 		break;
 
 	default:
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 5667c2f..cc5e28c 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -295,6 +295,12 @@
 
 	if (!class)
 		return -EINVAL;
+	if (!class->p) {
+		WARN(1, "%s called for class '%s' before it was initialized",
+		     __func__, class->name);
+		return -EINVAL;
+	}
+
 	mutex_lock(&class->p->class_mutex);
 	list_for_each_entry(dev, &class->p->class_devices, node) {
 		if (start) {
@@ -344,6 +350,11 @@
 
 	if (!class)
 		return NULL;
+	if (!class->p) {
+		WARN(1, "%s called for class '%s' before it was initialized",
+		     __func__, class->name);
+		return NULL;
+	}
 
 	mutex_lock(&class->p->class_mutex);
 	list_for_each_entry(dev, &class->p->class_devices, node) {
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 068aa1c..d021c98 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -53,7 +53,7 @@
  * it is attached to.  If it is not attached to a bus either, an empty
  * string will be returned.
  */
-const char *dev_driver_string(struct device *dev)
+const char *dev_driver_string(const struct device *dev)
 {
 	return dev->driver ? dev->driver->name :
 			(dev->bus ? dev->bus->name :
@@ -541,6 +541,7 @@
 	spin_lock_init(&dev->devres_lock);
 	INIT_LIST_HEAD(&dev->devres_head);
 	device_init_wakeup(dev, 0);
+	device_pm_init(dev);
 	set_dev_node(dev, -1);
 }
 
@@ -843,13 +844,19 @@
 {
 	struct device *parent = NULL;
 	struct class_interface *class_intf;
-	int error;
+	int error = -EINVAL;
 
 	dev = get_device(dev);
-	if (!dev || !strlen(dev->bus_id)) {
-		error = -EINVAL;
-		goto Done;
-	}
+	if (!dev)
+		goto done;
+
+	/* Temporarily support init_name if it is set.
+	 * It will override bus_id for now */
+	if (dev->init_name)
+		dev_set_name(dev, "%s", dev->init_name);
+
+	if (!strlen(dev->bus_id))
+		goto done;
 
 	pr_debug("device: '%s': %s\n", dev->bus_id, __func__);
 
@@ -897,9 +904,10 @@
 	error = bus_add_device(dev);
 	if (error)
 		goto BusError;
-	error = device_pm_add(dev);
+	error = dpm_sysfs_add(dev);
 	if (error)
-		goto PMError;
+		goto DPMError;
+	device_pm_add(dev);
 	kobject_uevent(&dev->kobj, KOBJ_ADD);
 	bus_attach_device(dev);
 	if (parent)
@@ -917,10 +925,10 @@
 				class_intf->add_dev(dev, class_intf);
 		mutex_unlock(&dev->class->p->class_mutex);
 	}
- Done:
+done:
 	put_device(dev);
 	return error;
- PMError:
+ DPMError:
 	bus_remove_device(dev);
  BusError:
 	if (dev->bus)
@@ -944,7 +952,7 @@
 	cleanup_device_parent(dev);
 	if (parent)
 		put_device(parent);
-	goto Done;
+	goto done;
 }
 
 /**
@@ -1007,6 +1015,7 @@
 	struct class_interface *class_intf;
 
 	device_pm_remove(dev);
+	dpm_sysfs_remove(dev);
 	if (parent)
 		klist_del(&dev->knode_parent);
 	if (MAJOR(dev->devt)) {
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 2ef5acf..1e2bda7 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -16,9 +16,6 @@
 #include <linux/string.h>
 #include "base.h"
 
-#define to_dev(node) container_of(node, struct device, driver_list)
-
-
 static struct device *next_device(struct klist_iter *i)
 {
 	struct klist_node *n = klist_next(i);
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 3250c52..273a944 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -67,20 +67,16 @@
  *	device_pm_add - add a device to the list of active devices
  *	@dev:	Device to be added to the list
  */
-int device_pm_add(struct device *dev)
+void device_pm_add(struct device *dev)
 {
-	int error;
-
 	pr_debug("PM: Adding info for %s:%s\n",
 		 dev->bus ? dev->bus->name : "No Bus",
 		 kobject_name(&dev->kobj));
 	mutex_lock(&dpm_list_mtx);
 	if (dev->parent) {
-		if (dev->parent->power.status >= DPM_SUSPENDING) {
-			dev_warn(dev, "parent %s is sleeping, will not add\n",
+		if (dev->parent->power.status >= DPM_SUSPENDING)
+			dev_warn(dev, "parent %s should not be sleeping\n",
 				dev->parent->bus_id);
-			WARN_ON(true);
-		}
 	} else if (transition_started) {
 		/*
 		 * We refuse to register parentless devices while a PM
@@ -89,13 +85,9 @@
 		 */
 		WARN_ON(true);
 	}
-	error = dpm_sysfs_add(dev);
-	if (!error) {
-		dev->power.status = DPM_ON;
-		list_add_tail(&dev->power.entry, &dpm_list);
-	}
+
+	list_add_tail(&dev->power.entry, &dpm_list);
 	mutex_unlock(&dpm_list_mtx);
-	return error;
 }
 
 /**
@@ -110,7 +102,6 @@
 		 dev->bus ? dev->bus->name : "No Bus",
 		 kobject_name(&dev->kobj));
 	mutex_lock(&dpm_list_mtx);
-	dpm_sysfs_remove(dev);
 	list_del_init(&dev->power.entry);
 	mutex_unlock(&dpm_list_mtx);
 }
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h
index a3252c0..41f51fa 100644
--- a/drivers/base/power/power.h
+++ b/drivers/base/power/power.h
@@ -1,3 +1,8 @@
+static inline void device_pm_init(struct device *dev)
+{
+	dev->power.status = DPM_ON;
+}
+
 #ifdef CONFIG_PM_SLEEP
 
 /*
@@ -11,12 +16,12 @@
 	return container_of(entry, struct device, power.entry);
 }
 
-extern int device_pm_add(struct device *);
+extern void device_pm_add(struct device *);
 extern void device_pm_remove(struct device *);
 
 #else /* CONFIG_PM_SLEEP */
 
-static inline int device_pm_add(struct device *dev) { return 0; }
+static inline void device_pm_add(struct device *dev) {}
 static inline void device_pm_remove(struct device *dev) {}
 
 #endif
diff --git a/drivers/infiniband/hw/ipath/ipath_iba7220.c b/drivers/infiniband/hw/ipath/ipath_iba7220.c
index d90f5e9..9839e20 100644
--- a/drivers/infiniband/hw/ipath/ipath_iba7220.c
+++ b/drivers/infiniband/hw/ipath/ipath_iba7220.c
@@ -1720,7 +1720,7 @@
 				 "not 2KB aligned!\n", pa);
 			return;
 		}
-		if (pa >= (1UL << IBA7220_TID_SZ_SHIFT)) {
+		if (chippa >= (1UL << IBA7220_TID_SZ_SHIFT)) {
 			ipath_dev_err(dd,
 				      "BUG: Physical page address 0x%lx "
 				      "larger than supported\n", pa);
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c
index 36aa242..729446f 100644
--- a/drivers/infiniband/hw/ipath/ipath_ud.c
+++ b/drivers/infiniband/hw/ipath/ipath_ud.c
@@ -267,6 +267,7 @@
 	u16 lrh0;
 	u16 lid;
 	int ret = 0;
+	int next_cur;
 
 	spin_lock_irqsave(&qp->s_lock, flags);
 
@@ -290,8 +291,9 @@
 		goto bail;
 
 	wqe = get_swqe_ptr(qp, qp->s_cur);
-	if (++qp->s_cur >= qp->s_size)
-		qp->s_cur = 0;
+	next_cur = qp->s_cur + 1;
+	if (next_cur >= qp->s_size)
+		next_cur = 0;
 
 	/* Construct the header. */
 	ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr;
@@ -315,6 +317,7 @@
 				qp->s_flags |= IPATH_S_WAIT_DMA;
 				goto bail;
 			}
+			qp->s_cur = next_cur;
 			spin_unlock_irqrestore(&qp->s_lock, flags);
 			ipath_ud_loopback(qp, wqe);
 			spin_lock_irqsave(&qp->s_lock, flags);
@@ -323,6 +326,7 @@
 		}
 	}
 
+	qp->s_cur = next_cur;
 	extra_bytes = -wqe->length & 3;
 	nwords = (wqe->length + extra_bytes) >> 2;
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index f51201b..7e9e218 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -156,14 +156,8 @@
 
 	netif_stop_queue(dev);
 
-	/*
-	 * Now flush workqueue to make sure a scheduled task doesn't
-	 * bring our internal state back up.
-	 */
-	flush_workqueue(ipoib_workqueue);
-
-	ipoib_ib_dev_down(dev, 1);
-	ipoib_ib_dev_stop(dev, 1);
+	ipoib_ib_dev_down(dev, 0);
+	ipoib_ib_dev_stop(dev, 0);
 
 	if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
 		struct ipoib_dev_priv *cpriv;
@@ -1314,7 +1308,7 @@
 
 register_failed:
 	ib_unregister_event_handler(&priv->event_handler);
-	flush_scheduled_work();
+	flush_workqueue(ipoib_workqueue);
 
 event_failed:
 	ipoib_dev_cleanup(priv->dev);
@@ -1373,7 +1367,12 @@
 
 	list_for_each_entry_safe(priv, tmp, dev_list, list) {
 		ib_unregister_event_handler(&priv->event_handler);
-		flush_scheduled_work();
+
+		rtnl_lock();
+		dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP);
+		rtnl_unlock();
+
+		flush_workqueue(ipoib_workqueue);
 
 		unregister_netdev(priv->dev);
 		ipoib_dev_cleanup(priv->dev);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 8950e95..ac33c8f 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -392,8 +392,16 @@
 					   &priv->mcast_task, 0);
 		mutex_unlock(&mcast_mutex);
 
-		if (mcast == priv->broadcast)
+		if (mcast == priv->broadcast) {
+			/*
+			 * Take RTNL lock here to avoid racing with
+			 * ipoib_stop() and turning the carrier back
+			 * on while a device is being removed.
+			 */
+			rtnl_lock();
 			netif_carrier_on(dev);
+			rtnl_unlock();
+		}
 
 		return 0;
 	}
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 1b6c52e..acb7801 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -2333,13 +2333,11 @@
 {
 	struct dasd_device *device;
 	struct dasd_ccw_req *cqr;
-	unsigned long flags;
 	int ret;
 
-	device = dasd_device_from_cdev(cdev);
+	device = dasd_device_from_cdev_locked(cdev);
 	if (IS_ERR(device))
 		return 0;
-	spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
 	ret = 0;
 	switch (event) {
 	case CIO_GONE:
@@ -2369,7 +2367,6 @@
 		ret = 1;
 		break;
 	}
-	spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
 	dasd_put_device(device);
 	return ret;
 }
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 4bf0aa5..2476f87 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -308,7 +308,7 @@
 	unsigned char flags;
 	unsigned char reserved[4];
 	unsigned char suborder;
-	unsigned char varies[9];
+	unsigned char varies[5];
 } __attribute__ ((packed));
 
 /*
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 29da441..bf512ac 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -16,6 +16,7 @@
 #include <linux/poll.h>
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
+#include <linux/err.h>
 
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
@@ -457,7 +458,7 @@
 
 	cqr = dasd_kmalloc_request("ECKD", 1 /* SNSS */,
 				   SNSS_DATA_SIZE, device);
-	if (!cqr)
+	if (IS_ERR(cqr))
 		return -ENOMEM;
 
 	cqr->startdev = device;
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 01fcdd9..db85f1f 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -384,6 +384,10 @@
 	 * get minor, add to list
 	 */
 	down_write(&dcssblk_devices_sem);
+	if (dcssblk_get_segment_by_name(local_buf)) {
+		rc = -EEXIST;
+		goto release_gd;
+	}
 	rc = dcssblk_assign_free_minor(dev_info);
 	if (rc) {
 		up_write(&dcssblk_devices_sem);
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c
index 687720b..be0ce22 100644
--- a/drivers/s390/char/tape_char.c
+++ b/drivers/s390/char/tape_char.c
@@ -109,7 +109,7 @@
 
 	/* The current idal buffer is not correct. Allocate a new one. */
 	new = idal_buffer_alloc(block_size, 0);
-	if (new == NULL)
+	if (IS_ERR(new))
 		return -ENOMEM;
 
 	if (device->char_data.idal_buf != NULL)
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c
index 2a1af4e..cc8fd78 100644
--- a/drivers/s390/char/tape_std.c
+++ b/drivers/s390/char/tape_std.c
@@ -248,7 +248,7 @@
 
 	/* Allocate a new idal buffer. */
 	new = idal_buffer_alloc(count, 0);
-	if (new == NULL)
+	if (IS_ERR(new))
 		return -ENOMEM;
 	if (device->char_data.idal_buf != NULL)
 		idal_buffer_free(device->char_data.idal_buf);
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 26a930e..e0ce65f 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -112,8 +112,10 @@
 	gdev = to_ccwgroupdev(dev);
 
 	for (i = 0; i < gdev->count; i++) {
-		dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
-		put_device(&gdev->cdev[i]->dev);
+		if (gdev->cdev[i]) {
+			dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
+			put_device(&gdev->cdev[i]->dev);
+		}
 	}
 	kfree(gdev);
 }
@@ -221,6 +223,13 @@
 	atomic_set(&gdev->onoff, 0);
 	mutex_init(&gdev->reg_mutex);
 	mutex_lock(&gdev->reg_mutex);
+	gdev->creator_id = creator_id;
+	gdev->count = num_devices;
+	gdev->dev.bus = &ccwgroup_bus_type;
+	gdev->dev.parent = root;
+	gdev->dev.release = ccwgroup_release;
+	device_initialize(&gdev->dev);
+
 	curr_buf = buf;
 	for (i = 0; i < num_devices && curr_buf; i++) {
 		rc = __get_next_bus_id(&curr_buf, tmp_bus_id);
@@ -258,16 +267,11 @@
 		rc = -EINVAL;
 		goto error;
 	}
-	gdev->creator_id = creator_id;
-	gdev->count = num_devices;
-	gdev->dev.bus = &ccwgroup_bus_type;
-	gdev->dev.parent = root;
-	gdev->dev.release = ccwgroup_release;
 
 	snprintf (gdev->dev.bus_id, BUS_ID_SIZE, "%s",
 			gdev->cdev[0]->dev.bus_id);
 
-	rc = device_register(&gdev->dev);
+	rc = device_add(&gdev->dev);
 	if (rc)
 		goto error;
 	get_device(&gdev->dev);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 46c021d..51489ef 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -477,7 +477,6 @@
 
 void css_wait_for_slow_path(void)
 {
-	flush_workqueue(ccw_device_notify_work);
 	flush_workqueue(slow_path_wq);
 }
 
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index e818d0c..2822103 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -150,7 +150,6 @@
 };
 
 struct workqueue_struct *ccw_device_work;
-struct workqueue_struct *ccw_device_notify_work;
 wait_queue_head_t ccw_device_init_wq;
 atomic_t ccw_device_init_count;
 
@@ -168,11 +167,6 @@
 	ccw_device_work = create_singlethread_workqueue("cio");
 	if (!ccw_device_work)
 		return -ENOMEM; /* FIXME: better errno ? */
-	ccw_device_notify_work = create_singlethread_workqueue("cio_notify");
-	if (!ccw_device_notify_work) {
-		ret = -ENOMEM; /* FIXME: better errno ? */
-		goto out_err;
-	}
 	slow_path_wq = create_singlethread_workqueue("kslowcrw");
 	if (!slow_path_wq) {
 		ret = -ENOMEM; /* FIXME: better errno ? */
@@ -192,8 +186,6 @@
 out_err:
 	if (ccw_device_work)
 		destroy_workqueue(ccw_device_work);
-	if (ccw_device_notify_work)
-		destroy_workqueue(ccw_device_notify_work);
 	if (slow_path_wq)
 		destroy_workqueue(slow_path_wq);
 	return ret;
@@ -204,7 +196,6 @@
 {
 	css_driver_unregister(&io_subchannel_driver);
 	bus_unregister(&ccw_bus_type);
-	destroy_workqueue(ccw_device_notify_work);
 	destroy_workqueue(ccw_device_work);
 }
 
@@ -1496,11 +1487,22 @@
 		ccw_device_schedule_recovery();
 }
 
+void ccw_device_set_notoper(struct ccw_device *cdev)
+{
+	struct subchannel *sch = to_subchannel(cdev->dev.parent);
+
+	CIO_TRACE_EVENT(2, "notoper");
+	CIO_TRACE_EVENT(2, sch->dev.bus_id);
+	ccw_device_set_timeout(cdev, 0);
+	cio_disable_subchannel(sch);
+	cdev->private->state = DEV_STATE_NOT_OPER;
+}
+
 static int io_subchannel_sch_event(struct subchannel *sch, int slow)
 {
 	int event, ret, disc;
 	unsigned long flags;
-	enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE } action;
+	enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE, DISC } action;
 	struct ccw_device *cdev;
 
 	spin_lock_irqsave(sch->lock, flags);
@@ -1535,16 +1537,11 @@
 		}
 		/* fall through */
 	case CIO_GONE:
-		/* Prevent unwanted effects when opening lock. */
-		cio_disable_subchannel(sch);
-		device_set_disconnected(cdev);
 		/* Ask driver what to do with device. */
-		action = UNREGISTER;
-		spin_unlock_irqrestore(sch->lock, flags);
-		ret = io_subchannel_notify(sch, event);
-		spin_lock_irqsave(sch->lock, flags);
-		if (ret)
-			action = NONE;
+		if (io_subchannel_notify(sch, event))
+			action = DISC;
+		else
+			action = UNREGISTER;
 		break;
 	case CIO_REVALIDATE:
 		/* Device will be removed, so no notify necessary. */
@@ -1565,6 +1562,7 @@
 	switch (action) {
 	case UNREGISTER:
 	case UNREGISTER_PROBE:
+		ccw_device_set_notoper(cdev);
 		/* Unregister device (will use subchannel lock). */
 		spin_unlock_irqrestore(sch->lock, flags);
 		css_sch_device_unregister(sch);
@@ -1577,6 +1575,9 @@
 	case REPROBE:
 		ccw_device_trigger_reprobe(cdev);
 		break;
+	case DISC:
+		device_set_disconnected(cdev);
+		break;
 	default:
 		break;
 	}
@@ -1828,5 +1829,4 @@
 EXPORT_SYMBOL(get_ccwdev_by_busid);
 EXPORT_SYMBOL(ccw_bus_type);
 EXPORT_SYMBOL(ccw_device_work);
-EXPORT_SYMBOL(ccw_device_notify_work);
 EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id);
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 9800a83..6f5c3f2 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -72,7 +72,6 @@
 }
 
 extern struct workqueue_struct *ccw_device_work;
-extern struct workqueue_struct *ccw_device_notify_work;
 extern wait_queue_head_t ccw_device_init_wq;
 extern atomic_t ccw_device_init_count;
 
@@ -120,6 +119,7 @@
 void ccw_device_trigger_reprobe(struct ccw_device *);
 void ccw_device_kill_io(struct ccw_device *);
 int ccw_device_notify(struct ccw_device *, int);
+void ccw_device_set_notoper(struct ccw_device *cdev);
 
 /* qdio needs this. */
 void ccw_device_set_timeout(struct ccw_device *, int);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 8b5fe57..550508d 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -337,26 +337,34 @@
 		return 0;
 	if (!cdev->online)
 		return 0;
+	CIO_MSG_EVENT(2, "notify called for 0.%x.%04x, event=%d\n",
+		      cdev->private->dev_id.ssid, cdev->private->dev_id.devno,
+		      event);
 	return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0;
 }
 
-static void
-ccw_device_oper_notify(struct work_struct *work)
+static void cmf_reenable_delayed(struct work_struct *work)
 {
 	struct ccw_device_private *priv;
 	struct ccw_device *cdev;
-	int ret;
 
 	priv = container_of(work, struct ccw_device_private, kick_work);
 	cdev = priv->cdev;
-	ret = ccw_device_notify(cdev, CIO_OPER);
-	if (ret) {
+	cmf_reenable(cdev);
+}
+
+static void ccw_device_oper_notify(struct ccw_device *cdev)
+{
+	if (ccw_device_notify(cdev, CIO_OPER)) {
 		/* Reenable channel measurements, if needed. */
-		cmf_reenable(cdev);
-		wake_up(&cdev->private->wait_q);
-	} else
-		/* Driver doesn't want device back. */
-		ccw_device_do_unreg_rereg(work);
+		PREPARE_WORK(&cdev->private->kick_work, cmf_reenable_delayed);
+		queue_work(ccw_device_work, &cdev->private->kick_work);
+		return;
+	}
+	/* Driver doesn't want device back. */
+	ccw_device_set_notoper(cdev);
+	PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unreg_rereg);
+	queue_work(ccw_device_work, &cdev->private->kick_work);
 }
 
 /*
@@ -386,8 +394,7 @@
 
 	if (cdev->private->flags.donotify) {
 		cdev->private->flags.donotify = 0;
-		PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify);
-		queue_work(ccw_device_notify_work, &cdev->private->kick_work);
+		ccw_device_oper_notify(cdev);
 	}
 	wake_up(&cdev->private->wait_q);
 
diff --git a/drivers/s390/cio/qdio_debug.h b/drivers/s390/cio/qdio_debug.h
index 8484b83..5a4d85b 100644
--- a/drivers/s390/cio/qdio_debug.h
+++ b/drivers/s390/cio/qdio_debug.h
@@ -61,18 +61,18 @@
 
 /* s390dbf views */
 #define QDIO_DBF_SETUP_LEN		8
-#define QDIO_DBF_SETUP_PAGES		4
+#define QDIO_DBF_SETUP_PAGES		8
 #define QDIO_DBF_SETUP_NR_AREAS		1
 
 #define QDIO_DBF_TRACE_LEN		8
 #define QDIO_DBF_TRACE_NR_AREAS		2
 
 #ifdef CONFIG_QDIO_DEBUG
-#define QDIO_DBF_TRACE_PAGES		16
+#define QDIO_DBF_TRACE_PAGES		32
 #define QDIO_DBF_SETUP_LEVEL		6
 #define QDIO_DBF_TRACE_LEVEL		4
 #else /* !CONFIG_QDIO_DEBUG */
-#define QDIO_DBF_TRACE_PAGES		4
+#define QDIO_DBF_TRACE_PAGES		8
 #define QDIO_DBF_SETUP_LEVEL		2
 #define QDIO_DBF_TRACE_LEVEL		2
 #endif /* CONFIG_QDIO_DEBUG */
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index d156485..e6eabc8 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -330,6 +330,7 @@
 	int cc;
 	u32 busy_bit;
 	u64 start_time = 0;
+	char dbf_text[15];
 
 	QDIO_DBF_TEXT5(0, trace, "sigaout");
 	QDIO_DBF_HEX5(0, trace, &q, sizeof(void *));
@@ -338,6 +339,9 @@
 again:
 	cc = qdio_do_siga_output(q, &busy_bit);
 	if (queue_type(q) == QDIO_IQDIO_QFMT && cc == 2 && busy_bit) {
+		sprintf(dbf_text, "bb%4x%2x", q->irq_ptr->schid.sch_no, q->nr);
+		QDIO_DBF_TEXT3(0, trace, dbf_text);
+
 		if (!start_time)
 			start_time = get_usecs();
 		else if ((get_usecs() - start_time) < QDIO_BUSY_BIT_PATIENCE)
@@ -748,16 +752,18 @@
 	rc = qdio_siga_output(q);
 	switch (rc) {
 	case 0:
-		/* went smooth this time, reset timestamp */
-		q->u.out.timestamp = 0;
-
 		/* TODO: improve error handling for CC=0 case */
 #ifdef CONFIG_QDIO_DEBUG
-		QDIO_DBF_TEXT3(0, trace, "cc2reslv");
-		sprintf(dbf_text, "%4x%2x%2x", q->irq_ptr->schid.sch_no, q->nr,
-			atomic_read(&q->u.out.busy_siga_counter));
-		QDIO_DBF_TEXT3(0, trace, dbf_text);
+		if (q->u.out.timestamp) {
+			QDIO_DBF_TEXT3(0, trace, "cc2reslv");
+			sprintf(dbf_text, "%4x%2x%2x", q->irq_ptr->schid.sch_no,
+				q->nr,
+				atomic_read(&q->u.out.busy_siga_counter));
+			QDIO_DBF_TEXT3(0, trace, dbf_text);
+		}
 #endif /* CONFIG_QDIO_DEBUG */
+		/* went smooth this time, reset timestamp */
+		q->u.out.timestamp = 0;
 		break;
 	/* cc=2 and busy bit */
 	case (2 | QDIO_ERROR_SIGA_BUSY):
@@ -1066,14 +1072,12 @@
 	if (IS_ERR(irb)) {
 		switch (PTR_ERR(irb)) {
 		case -EIO:
-			sprintf(dbf_text, "ierr%4x",
-				cdev->private->schid.sch_no);
+			sprintf(dbf_text, "ierr%4x", irq_ptr->schid.sch_no);
 			QDIO_DBF_TEXT2(1, setup, dbf_text);
 			qdio_int_error(cdev);
 			return;
 		case -ETIMEDOUT:
-			sprintf(dbf_text, "qtoh%4x",
-				cdev->private->schid.sch_no);
+			sprintf(dbf_text, "qtoh%4x", irq_ptr->schid.sch_no);
 			QDIO_DBF_TEXT2(1, setup, dbf_text);
 			qdio_int_error(cdev);
 			return;
@@ -1124,8 +1128,10 @@
 struct qdio_ssqd_desc *qdio_get_ssqd_desc(struct ccw_device *cdev)
 {
 	struct qdio_irq *irq_ptr;
+	char dbf_text[15];
 
-	QDIO_DBF_TEXT0(0, setup, "getssqd");
+	sprintf(dbf_text, "qssq%4x", cdev->private->schid.sch_no);
+	QDIO_DBF_TEXT0(0, setup, dbf_text);
 
 	irq_ptr = cdev->private->qdio_data;
 	if (!irq_ptr)
@@ -1149,14 +1155,13 @@
 	char dbf_text[15];
 	int rc;
 
+	sprintf(dbf_text, "qcln%4x", cdev->private->schid.sch_no);
+	QDIO_DBF_TEXT0(0, setup, dbf_text);
+
 	irq_ptr = cdev->private->qdio_data;
 	if (!irq_ptr)
 		return -ENODEV;
 
-	sprintf(dbf_text, "qcln%4x", irq_ptr->schid.sch_no);
-	QDIO_DBF_TEXT1(0, trace, dbf_text);
-	QDIO_DBF_TEXT0(0, setup, dbf_text);
-
 	rc = qdio_shutdown(cdev, how);
 	if (rc == 0)
 		rc = qdio_free(cdev);
@@ -1191,6 +1196,9 @@
 	unsigned long flags;
 	char dbf_text[15];
 
+	sprintf(dbf_text, "qshu%4x", cdev->private->schid.sch_no);
+	QDIO_DBF_TEXT0(0, setup, dbf_text);
+
 	irq_ptr = cdev->private->qdio_data;
 	if (!irq_ptr)
 		return -ENODEV;
@@ -1205,10 +1213,6 @@
 		return 0;
 	}
 
-	sprintf(dbf_text, "qsqs%4x", irq_ptr->schid.sch_no);
-	QDIO_DBF_TEXT1(0, trace, dbf_text);
-	QDIO_DBF_TEXT0(0, setup, dbf_text);
-
 	tiqdio_remove_input_queues(irq_ptr);
 	qdio_shutdown_queues(cdev);
 	qdio_shutdown_debug_entries(irq_ptr, cdev);
@@ -1247,7 +1251,6 @@
 
 	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
 	mutex_unlock(&irq_ptr->setup_mutex);
-	module_put(THIS_MODULE);
 	if (rc)
 		return rc;
 	return 0;
@@ -1263,16 +1266,14 @@
 	struct qdio_irq *irq_ptr;
 	char dbf_text[15];
 
+	sprintf(dbf_text, "qfre%4x", cdev->private->schid.sch_no);
+	QDIO_DBF_TEXT0(0, setup, dbf_text);
+
 	irq_ptr = cdev->private->qdio_data;
 	if (!irq_ptr)
 		return -ENODEV;
 
 	mutex_lock(&irq_ptr->setup_mutex);
-
-	sprintf(dbf_text, "qfqs%4x", irq_ptr->schid.sch_no);
-	QDIO_DBF_TEXT1(0, trace, dbf_text);
-	QDIO_DBF_TEXT0(0, setup, dbf_text);
-
 	cdev->private->qdio_data = NULL;
 	mutex_unlock(&irq_ptr->setup_mutex);
 
@@ -1295,7 +1296,6 @@
 
 	sprintf(dbf_text, "qini%4x", init_data->cdev->private->schid.sch_no);
 	QDIO_DBF_TEXT0(0, setup, dbf_text);
-	QDIO_DBF_TEXT0(0, trace, dbf_text);
 
 	rc = qdio_allocate(init_data);
 	if (rc)
@@ -1319,7 +1319,6 @@
 
 	sprintf(dbf_text, "qalc%4x", init_data->cdev->private->schid.sch_no);
 	QDIO_DBF_TEXT0(0, setup, dbf_text);
-	QDIO_DBF_TEXT0(0, trace, dbf_text);
 
 	if ((init_data->no_input_qs && !init_data->input_handler) ||
 	    (init_data->no_output_qs && !init_data->output_handler))
@@ -1389,6 +1388,9 @@
 	unsigned long saveflags;
 	int rc;
 
+	sprintf(dbf_text, "qest%4x", cdev->private->schid.sch_no);
+	QDIO_DBF_TEXT0(0, setup, dbf_text);
+
 	irq_ptr = cdev->private->qdio_data;
 	if (!irq_ptr)
 		return -ENODEV;
@@ -1396,13 +1398,6 @@
 	if (cdev->private->state != DEV_STATE_ONLINE)
 		return -EINVAL;
 
-	if (!try_module_get(THIS_MODULE))
-		return -EINVAL;
-
-	sprintf(dbf_text, "qest%4x", cdev->private->schid.sch_no);
-	QDIO_DBF_TEXT0(0, setup, dbf_text);
-	QDIO_DBF_TEXT0(0, trace, dbf_text);
-
 	mutex_lock(&irq_ptr->setup_mutex);
 	qdio_setup_irq(init_data);
 
@@ -1472,6 +1467,9 @@
 	unsigned long saveflags;
 	char dbf_text[20];
 
+	sprintf(dbf_text, "qact%4x", cdev->private->schid.sch_no);
+	QDIO_DBF_TEXT0(0, setup, dbf_text);
+
 	irq_ptr = cdev->private->qdio_data;
 	if (!irq_ptr)
 		return -ENODEV;
@@ -1485,10 +1483,6 @@
 		goto out;
 	}
 
-	sprintf(dbf_text, "qact%4x", irq_ptr->schid.sch_no);
-	QDIO_DBF_TEXT2(0, setup, dbf_text);
-	QDIO_DBF_TEXT2(0, trace, dbf_text);
-
 	irq_ptr->ccw.cmd_code = irq_ptr->aqueue.cmd;
 	irq_ptr->ccw.flags = CCW_FLAG_SLI;
 	irq_ptr->ccw.count = irq_ptr->aqueue.count;
@@ -1663,7 +1657,7 @@
 #ifdef CONFIG_QDIO_DEBUG
 	char dbf_text[20];
 
-	sprintf(dbf_text, "doQD%04x", cdev->private->schid.sch_no);
+	sprintf(dbf_text, "doQD%4x", cdev->private->schid.sch_no);
 	QDIO_DBF_TEXT3(0, trace, dbf_text);
 #endif /* CONFIG_QDIO_DEBUG */
 
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 1bd2a20..1679e2f 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -165,7 +165,7 @@
 	void **output_sbal_array = qdio_init->output_sbal_addr_array;
 	int i;
 
-	sprintf(dbf_text, "qfqs%4x", qdio_init->cdev->private->schid.sch_no);
+	sprintf(dbf_text, "qset%4x", qdio_init->cdev->private->schid.sch_no);
 	QDIO_DBF_TEXT0(0, setup, dbf_text);
 
 	for_each_input_queue(irq_ptr, q, i) {
@@ -285,7 +285,7 @@
 	rc = __get_ssqd_info(irq_ptr);
 	if (rc) {
 		QDIO_DBF_TEXT2(0, setup, "ssqdasig");
-		sprintf(dbf_text, "schno%x", irq_ptr->schid.sch_no);
+		sprintf(dbf_text, "schn%4x", irq_ptr->schid.sch_no);
 		QDIO_DBF_TEXT2(0, setup, dbf_text);
 		sprintf(dbf_text, "rc:%d", rc);
 		QDIO_DBF_TEXT2(0, setup, dbf_text);
@@ -447,7 +447,7 @@
 {
 	char s[80];
 
-	sprintf(s, "%s ", cdev->dev.bus_id);
+	sprintf(s, "%s sc:%x ", cdev->dev.bus_id, irq_ptr->schid.sch_no);
 
 	switch (irq_ptr->qib.qfmt) {
 	case QDIO_QETH_QFMT:
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 9291a77..ea7f614 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -113,7 +113,11 @@
 	struct qdio_q *q;
 	int i;
 
-	for_each_input_queue(irq_ptr, q, i) {
+	for (i = 0; i < irq_ptr->nr_input_qs; i++) {
+		q = irq_ptr->input_qs[i];
+		/* if establish triggered an error */
+		if (!q || !q->entry.prev || !q->entry.next)
+			continue;
 		list_del_rcu(&q->entry);
 		synchronize_rcu();
 	}
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 2e9079d..4190be6 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -33,6 +33,19 @@
 
 	  If you don't know what to do here, say N.
 
+config UIO_PDRV_GENIRQ
+	tristate "Userspace I/O platform driver with generic IRQ handling"
+	help
+	  Platform driver for Userspace I/O devices, including generic
+	  interrupt handling code. Shared interrupts are not supported.
+
+	  This kernel driver requires that the matching userspace driver
+	  handles interrupts in a special way. Userspace is responsible
+	  for acknowledging the hardware device if needed, and re-enabling
+	  interrupts in the interrupt controller using the write() syscall.
+
+	  If you don't know what to do here, say N.
+
 config UIO_SMX
 	tristate "SMX cryptengine UIO interface"
 	default n
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index e00ce0d..8667bbd 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_UIO)	+= uio.o
 obj-$(CONFIG_UIO_CIF)	+= uio_cif.o
 obj-$(CONFIG_UIO_PDRV)	+= uio_pdrv.o
+obj-$(CONFIG_UIO_PDRV_GENIRQ)	+= uio_pdrv_genirq.o
 obj-$(CONFIG_UIO_SMX)	+= uio_smx.o
diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c
index 5d0d2e8..0b4ef39 100644
--- a/drivers/uio/uio_pdrv.c
+++ b/drivers/uio/uio_pdrv.c
@@ -88,6 +88,8 @@
 
 	uio_unregister_device(pdata->uioinfo);
 
+	kfree(pdata);
+
 	return 0;
 }
 
@@ -114,5 +116,5 @@
 
 MODULE_AUTHOR("Uwe Kleine-Koenig");
 MODULE_DESCRIPTION("Userspace I/O platform driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
new file mode 100644
index 0000000..1f82c83
--- /dev/null
+++ b/drivers/uio/uio_pdrv_genirq.c
@@ -0,0 +1,188 @@
+/*
+ * drivers/uio/uio_pdrv_genirq.c
+ *
+ * Userspace I/O platform driver with generic IRQ handling code.
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * Based on uio_pdrv.c by Uwe Kleine-Koenig,
+ * Copyright (C) 2008 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/stringify.h>
+
+#define DRIVER_NAME "uio_pdrv_genirq"
+
+struct uio_pdrv_genirq_platdata {
+	struct uio_info *uioinfo;
+	spinlock_t lock;
+	unsigned long flags;
+};
+
+static irqreturn_t uio_pdrv_genirq_handler(int irq, struct uio_info *dev_info)
+{
+	struct uio_pdrv_genirq_platdata *priv = dev_info->priv;
+
+	/* Just disable the interrupt in the interrupt controller, and
+	 * remember the state so we can allow user space to enable it later.
+	 */
+
+	if (!test_and_set_bit(0, &priv->flags))
+		disable_irq_nosync(irq);
+
+	return IRQ_HANDLED;
+}
+
+static int uio_pdrv_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on)
+{
+	struct uio_pdrv_genirq_platdata *priv = dev_info->priv;
+	unsigned long flags;
+
+	/* Allow user space to enable and disable the interrupt
+	 * in the interrupt controller, but keep track of the
+	 * state to prevent per-irq depth damage.
+	 *
+	 * Serialize this operation to support multiple tasks.
+	 */
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (irq_on) {
+		if (test_and_clear_bit(0, &priv->flags))
+			enable_irq(dev_info->irq);
+	} else {
+		if (!test_and_set_bit(0, &priv->flags))
+			disable_irq(dev_info->irq);
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static int uio_pdrv_genirq_probe(struct platform_device *pdev)
+{
+	struct uio_info *uioinfo = pdev->dev.platform_data;
+	struct uio_pdrv_genirq_platdata *priv;
+	struct uio_mem *uiomem;
+	int ret = -EINVAL;
+	int i;
+
+	if (!uioinfo || !uioinfo->name || !uioinfo->version) {
+		dev_err(&pdev->dev, "missing platform_data\n");
+		goto bad0;
+	}
+
+	if (uioinfo->handler || uioinfo->irqcontrol || uioinfo->irq_flags) {
+		dev_err(&pdev->dev, "interrupt configuration error\n");
+		goto bad0;
+	}
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		ret = -ENOMEM;
+		dev_err(&pdev->dev, "unable to kmalloc\n");
+		goto bad0;
+	}
+
+	priv->uioinfo = uioinfo;
+	spin_lock_init(&priv->lock);
+	priv->flags = 0; /* interrupt is enabled to begin with */
+
+	uiomem = &uioinfo->mem[0];
+
+	for (i = 0; i < pdev->num_resources; ++i) {
+		struct resource *r = &pdev->resource[i];
+
+		if (r->flags != IORESOURCE_MEM)
+			continue;
+
+		if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
+			dev_warn(&pdev->dev, "device has more than "
+					__stringify(MAX_UIO_MAPS)
+					" I/O memory resources.\n");
+			break;
+		}
+
+		uiomem->memtype = UIO_MEM_PHYS;
+		uiomem->addr = r->start;
+		uiomem->size = r->end - r->start + 1;
+		++uiomem;
+	}
+
+	while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
+		uiomem->size = 0;
+		++uiomem;
+	}
+
+	/* This driver requires no hardware specific kernel code to handle
+	 * interrupts. Instead, the interrupt handler simply disables the
+	 * interrupt in the interrupt controller. User space is responsible
+	 * for performing hardware specific acknowledge and re-enabling of
+	 * the interrupt in the interrupt controller.
+	 *
+	 * Interrupt sharing is not supported.
+	 */
+
+	uioinfo->irq_flags = IRQF_DISABLED;
+	uioinfo->handler = uio_pdrv_genirq_handler;
+	uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol;
+	uioinfo->priv = priv;
+
+	ret = uio_register_device(&pdev->dev, priv->uioinfo);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to register uio device\n");
+		goto bad1;
+	}
+
+	platform_set_drvdata(pdev, priv);
+	return 0;
+ bad1:
+	kfree(priv);
+ bad0:
+	return ret;
+}
+
+static int uio_pdrv_genirq_remove(struct platform_device *pdev)
+{
+	struct uio_pdrv_genirq_platdata *priv = platform_get_drvdata(pdev);
+
+	uio_unregister_device(priv->uioinfo);
+	kfree(priv);
+	return 0;
+}
+
+static struct platform_driver uio_pdrv_genirq = {
+	.probe = uio_pdrv_genirq_probe,
+	.remove = uio_pdrv_genirq_remove,
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init uio_pdrv_genirq_init(void)
+{
+	return platform_driver_register(&uio_pdrv_genirq);
+}
+
+static void __exit uio_pdrv_genirq_exit(void)
+{
+	platform_driver_unregister(&uio_pdrv_genirq);
+}
+
+module_init(uio_pdrv_genirq_init);
+module_exit(uio_pdrv_genirq_exit);
+
+MODULE_AUTHOR("Magnus Damm");
+MODULE_DESCRIPTION("Userspace I/O platform driver with generic IRQ handling");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index efc4373..c257453 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -589,8 +589,8 @@
 	tasklet_schedule(&acm->urb_task);
 
 done:
-err_out:
 	mutex_unlock(&acm->mutex);
+err_out:
 	mutex_unlock(&open_mutex);
 	return rv;
 
@@ -1362,6 +1362,9 @@
 	{ USB_DEVICE(0x0803, 0x3095), /* Zoom Telephonics Model 3095F USB MODEM */
 	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
 	},
+	{ USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */
+	.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+	},
 
 	/* control interfaces with various AT-command sets */
 	{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 2be37fe..5a7fa6f 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -230,6 +230,13 @@
 		 */
 		intf->pm_usage_cnt = !(driver->supports_autosuspend);
 
+		/* Carry out a deferred switch to altsetting 0 */
+		if (intf->needs_altsetting0) {
+			usb_set_interface(udev, intf->altsetting[0].
+					desc.bInterfaceNumber, 0);
+			intf->needs_altsetting0 = 0;
+		}
+
 		error = driver->probe(intf, id);
 		if (error) {
 			mark_quiesced(intf);
@@ -266,8 +273,17 @@
 
 	driver->disconnect(intf);
 
-	/* reset other interface state */
-	usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
+	/* Reset other interface state.
+	 * We cannot do a Set-Interface if the device is suspended or
+	 * if it is prepared for a system sleep (since installing a new
+	 * altsetting means creating new endpoint device entries).
+	 * When either of these happens, defer the Set-Interface.
+	 */
+	if (!error && intf->dev.power.status == DPM_ON)
+		usb_set_interface(udev, intf->altsetting[0].
+				desc.bInterfaceNumber, 0);
+	else
+		intf->needs_altsetting0 = 1;
 	usb_set_intfdata(intf, NULL);
 
 	intf->condition = USB_INTERFACE_UNBOUND;
@@ -798,7 +814,8 @@
  * The caller must hold @intf's device's lock, but not its pm_mutex
  * and not @intf->dev.sem.
  *
- * FIXME: The caller must block system sleep transitions.
+ * Note: Rebinds will be skipped if a system sleep transition is in
+ * progress and the PM "complete" callback hasn't occurred yet.
  */
 void usb_rebind_intf(struct usb_interface *intf)
 {
@@ -814,10 +831,12 @@
 	}
 
 	/* Try to rebind the interface */
-	intf->needs_binding = 0;
-	rc = device_attach(&intf->dev);
-	if (rc < 0)
-		dev_warn(&intf->dev, "rebind failed: %d\n", rc);
+	if (intf->dev.power.status == DPM_ON) {
+		intf->needs_binding = 0;
+		rc = device_attach(&intf->dev);
+		if (rc < 0)
+			dev_warn(&intf->dev, "rebind failed: %d\n", rc);
+	}
 }
 
 #ifdef CONFIG_PM
@@ -829,7 +848,6 @@
  * or rebind interfaces that have been unbound, according to @action.
  *
  * The caller must hold @udev's device lock.
- * FIXME: For rebinds, the caller must block system sleep transitions.
  */
 static void do_unbind_rebind(struct usb_device *udev, int action)
 {
@@ -851,22 +869,8 @@
 				}
 				break;
 			case DO_REBIND:
-				if (intf->needs_binding) {
-
-	/* FIXME: The next line is needed because we are going to probe
-	 * the interface, but as far as the PM core is concerned the
-	 * interface is still suspended.  The problem wouldn't exist
-	 * if we could rebind the interface during the interface's own
-	 * resume() call, but at the time the usb_device isn't locked!
-	 *
-	 * The real solution will be to carry this out during the device's
-	 * complete() callback.  Until that is implemented, we have to
-	 * use this hack.
-	 */
-//					intf->dev.power.sleeping = 0;
-
+				if (intf->needs_binding)
 					usb_rebind_intf(intf);
-				}
 				break;
 			}
 		}
@@ -926,14 +930,14 @@
 }
 
 /* Caller has locked intf's usb_device's pm mutex */
-static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
+static int usb_suspend_interface(struct usb_device *udev,
+		struct usb_interface *intf, pm_message_t msg)
 {
 	struct usb_driver	*driver;
 	int			status = 0;
 
 	/* with no hardware, USB interfaces only use FREEZE and ON states */
-	if (interface_to_usbdev(intf)->state == USB_STATE_NOTATTACHED ||
-			!is_active(intf))
+	if (udev->state == USB_STATE_NOTATTACHED || !is_active(intf))
 		goto done;
 
 	if (intf->condition == USB_INTERFACE_UNBOUND)	/* This can't happen */
@@ -944,7 +948,7 @@
 		status = driver->suspend(intf, msg);
 		if (status == 0)
 			mark_quiesced(intf);
-		else if (!interface_to_usbdev(intf)->auto_pm)
+		else if (!udev->auto_pm)
 			dev_err(&intf->dev, "%s error %d\n",
 					"suspend", status);
 	} else {
@@ -961,13 +965,13 @@
 }
 
 /* Caller has locked intf's usb_device's pm_mutex */
-static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
+static int usb_resume_interface(struct usb_device *udev,
+		struct usb_interface *intf, int reset_resume)
 {
 	struct usb_driver	*driver;
 	int			status = 0;
 
-	if (interface_to_usbdev(intf)->state == USB_STATE_NOTATTACHED ||
-			is_active(intf))
+	if (udev->state == USB_STATE_NOTATTACHED || is_active(intf))
 		goto done;
 
 	/* Don't let autoresume interfere with unbinding */
@@ -975,8 +979,17 @@
 		goto done;
 
 	/* Can't resume it if it doesn't have a driver. */
-	if (intf->condition == USB_INTERFACE_UNBOUND)
+	if (intf->condition == USB_INTERFACE_UNBOUND) {
+
+		/* Carry out a deferred switch to altsetting 0 */
+		if (intf->needs_altsetting0 &&
+				intf->dev.power.status == DPM_ON) {
+			usb_set_interface(udev, intf->altsetting[0].
+					desc.bInterfaceNumber, 0);
+			intf->needs_altsetting0 = 0;
+		}
 		goto done;
+	}
 
 	/* Don't resume if the interface is marked for rebinding */
 	if (intf->needs_binding)
@@ -1151,7 +1164,7 @@
 	if (udev->actconfig) {
 		for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
 			intf = udev->actconfig->interface[i];
-			status = usb_suspend_interface(intf, msg);
+			status = usb_suspend_interface(udev, intf, msg);
 			if (status != 0)
 				break;
 		}
@@ -1163,7 +1176,7 @@
 	if (status != 0) {
 		while (--i >= 0) {
 			intf = udev->actconfig->interface[i];
-			usb_resume_interface(intf, 0);
+			usb_resume_interface(udev, intf, 0);
 		}
 
 		/* Try another autosuspend when the interfaces aren't busy */
@@ -1276,7 +1289,7 @@
 	if (status == 0 && udev->actconfig) {
 		for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
 			intf = udev->actconfig->interface[i];
-			usb_resume_interface(intf, udev->reset_resume);
+			usb_resume_interface(udev, intf, udev->reset_resume);
 		}
 	}
 
@@ -1605,12 +1618,10 @@
 	return status;
 }
 
-static int usb_suspend(struct device *dev, pm_message_t message)
+int usb_suspend(struct device *dev, pm_message_t message)
 {
 	struct usb_device	*udev;
 
-	if (!is_usb_device(dev))	/* Ignore PM for interfaces */
-		return 0;
 	udev = to_usb_device(dev);
 
 	/* If udev is already suspended, we can skip this suspend and
@@ -1629,12 +1640,10 @@
 	return usb_external_suspend_device(udev, message);
 }
 
-static int usb_resume(struct device *dev)
+int usb_resume(struct device *dev)
 {
 	struct usb_device	*udev;
 
-	if (!is_usb_device(dev))	/* Ignore PM for interfaces */
-		return 0;
 	udev = to_usb_device(dev);
 
 	/* If udev->skip_sys_resume is set then udev was already suspended
@@ -1646,17 +1655,10 @@
 	return usb_external_resume_device(udev);
 }
 
-#else
-
-#define usb_suspend	NULL
-#define usb_resume	NULL
-
 #endif /* CONFIG_PM */
 
 struct bus_type usb_bus_type = {
 	.name =		"usb",
 	.match =	usb_device_match,
 	.uevent =	usb_uevent,
-	.suspend =	usb_suspend,
-	.resume =	usb_resume,
 };
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index f7bfd72..8abd4e5 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -924,15 +924,6 @@
 	return retval;
 }
 
-void usb_enable_root_hub_irq (struct usb_bus *bus)
-{
-	struct usb_hcd *hcd;
-
-	hcd = container_of (bus, struct usb_hcd, self);
-	if (hcd->driver->hub_irq_enable && hcd->state != HC_STATE_HALT)
-		hcd->driver->hub_irq_enable (hcd);
-}
-
 
 /*-------------------------------------------------------------------------*/
 
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 5b0b59b..e710ce0 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -212,8 +212,6 @@
 	int	(*bus_suspend)(struct usb_hcd *);
 	int	(*bus_resume)(struct usb_hcd *);
 	int	(*start_port_reset)(struct usb_hcd *, unsigned port_num);
-	void	(*hub_irq_enable)(struct usb_hcd *);
-		/* Needed only if port-change IRQs are level-triggered */
 
 		/* force handover of high-speed port to full-speed companion */
 	void	(*relinquish_port)(struct usb_hcd *, int);
@@ -379,8 +377,6 @@
 extern struct mutex usb_bus_list_lock;
 extern wait_queue_head_t usb_kill_urb_queue;
 
-extern void usb_enable_root_hub_irq(struct usb_bus *bus);
-
 extern int usb_find_interface_driver(struct usb_device *dev,
 	struct usb_interface *interface);
 
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 107e1d2..6a5cb01 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2102,8 +2102,6 @@
 	}
 
 	clear_bit(port1, hub->busy_bits);
-	if (!hub->hdev->parent && !hub->busy_bits[0])
-		usb_enable_root_hub_irq(hub->hdev->bus);
 
 	status = check_port_resume_type(udev,
 			hub, port1, status, portchange, portstatus);
@@ -3081,11 +3079,6 @@
 			}
 		}
 
-		/* If this is a root hub, tell the HCD it's okay to
-		 * re-enable port-change interrupts now. */
-		if (!hdev->parent && !hub->busy_bits[0])
-			usb_enable_root_hub_irq(hdev->bus);
-
 loop_autopm:
 		/* Allow autosuspend if we're not going to run again */
 		if (list_empty(&hub->event_list))
@@ -3311,8 +3304,6 @@
 			break;
 	}
 	clear_bit(port1, parent_hub->busy_bits);
-	if (!parent_hdev->parent && !parent_hub->busy_bits[0])
-		usb_enable_root_hub_irq(parent_hdev->bus);
 
 	if (ret < 0)
 		goto re_enumerate;
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index c0b1ae2..47111e8 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -601,15 +601,20 @@
 void usb_unlink_anchored_urbs(struct usb_anchor *anchor)
 {
 	struct urb *victim;
+	unsigned long flags;
 
-	spin_lock_irq(&anchor->lock);
+	spin_lock_irqsave(&anchor->lock, flags);
 	while (!list_empty(&anchor->urb_list)) {
 		victim = list_entry(anchor->urb_list.prev, struct urb,
 				    anchor_list);
+		usb_get_urb(victim);
+		spin_unlock_irqrestore(&anchor->lock, flags);
 		/* this will unanchor the URB */
 		usb_unlink_urb(victim);
+		usb_put_urb(victim);
+		spin_lock_irqsave(&anchor->lock, flags);
 	}
-	spin_unlock_irq(&anchor->lock);
+	spin_unlock_irqrestore(&anchor->lock, flags);
 }
 EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs);
 
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 84fcaa6..be1fa07 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -219,12 +219,6 @@
 }
 #endif	/* CONFIG_HOTPLUG */
 
-struct device_type usb_device_type = {
-	.name =		"usb_device",
-	.release =	usb_release_dev,
-	.uevent =	usb_dev_uevent,
-};
-
 #ifdef	CONFIG_PM
 
 static int ksuspend_usb_init(void)
@@ -244,13 +238,80 @@
 	destroy_workqueue(ksuspend_usb_wq);
 }
 
+/* USB device Power-Management thunks.
+ * There's no need to distinguish here between quiescing a USB device
+ * and powering it down; the generic_suspend() routine takes care of
+ * it by skipping the usb_port_suspend() call for a quiesce.  And for
+ * USB interfaces there's no difference at all.
+ */
+
+static int usb_dev_prepare(struct device *dev)
+{
+	return 0;		/* Implement eventually? */
+}
+
+static void usb_dev_complete(struct device *dev)
+{
+	/* Currently used only for rebinding interfaces */
+	usb_resume(dev);	/* Implement eventually? */
+}
+
+static int usb_dev_suspend(struct device *dev)
+{
+	return usb_suspend(dev, PMSG_SUSPEND);
+}
+
+static int usb_dev_resume(struct device *dev)
+{
+	return usb_resume(dev);
+}
+
+static int usb_dev_freeze(struct device *dev)
+{
+	return usb_suspend(dev, PMSG_FREEZE);
+}
+
+static int usb_dev_thaw(struct device *dev)
+{
+	return usb_resume(dev);
+}
+
+static int usb_dev_poweroff(struct device *dev)
+{
+	return usb_suspend(dev, PMSG_HIBERNATE);
+}
+
+static int usb_dev_restore(struct device *dev)
+{
+	return usb_resume(dev);
+}
+
+static struct pm_ops usb_device_pm_ops = {
+	.prepare =	usb_dev_prepare,
+	.complete =	usb_dev_complete,
+	.suspend =	usb_dev_suspend,
+	.resume =	usb_dev_resume,
+	.freeze =	usb_dev_freeze,
+	.thaw =		usb_dev_thaw,
+	.poweroff =	usb_dev_poweroff,
+	.restore =	usb_dev_restore,
+};
+
 #else
 
 #define ksuspend_usb_init()	0
 #define ksuspend_usb_cleanup()	do {} while (0)
+#define usb_device_pm_ops	(*(struct pm_ops *)0)
 
 #endif	/* CONFIG_PM */
 
+struct device_type usb_device_type = {
+	.name =		"usb_device",
+	.release =	usb_release_dev,
+	.uevent =	usb_dev_uevent,
+	.pm =		&usb_device_pm_ops,
+};
+
 
 /* Returns 1 if @usb_bus is WUSB, 0 otherwise */
 static unsigned usb_bus_is_wusb(struct usb_bus *bus)
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index d9a6e16..9a1a45a 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -41,6 +41,9 @@
 
 #ifdef	CONFIG_PM
 
+extern int usb_suspend(struct device *dev, pm_message_t msg);
+extern int usb_resume(struct device *dev);
+
 extern void usb_autosuspend_work(struct work_struct *work);
 extern int usb_port_suspend(struct usb_device *dev);
 extern int usb_port_resume(struct usb_device *dev);
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index a28513e..7cbc78a 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -1622,7 +1622,7 @@
 	struct pxa_udc *udc = the_controller;
 	int retval;
 
-	if (!driver || driver->speed != USB_SPEED_FULL || !driver->bind
+	if (!driver || driver->speed < USB_SPEED_FULL || !driver->bind
 			|| !driver->disconnect || !driver->setup)
 		return -EINVAL;
 	if (!udc)
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index d22a84f..8017f1c 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -988,7 +988,7 @@
 		/*
 		 * write bank1 address twice to ensure the 90ns delay (time
 		 * between BANK0 write and the priv_read_copy() call is at
-		 * least 3*t_WHWL + 2*t_w11 = 3*25ns + 2*17ns = 92ns)
+		 * least 3*t_WHWL + 2*t_w11 = 3*25ns + 2*17ns = 109ns)
 		 */
 		isp1760_writel(payload  + ISP_BANK(1), usb_hcd->regs +
 				HC_MEMORY_REG);
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 6db7a28..4ed228a 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -260,7 +260,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index c094800..2ac4e02 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -163,7 +163,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
index cb0b506..fb3055f 100644
--- a/drivers/usb/host/ohci-ep93xx.c
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -134,7 +134,6 @@
 	.get_frame_number	= ohci_get_frame,
 	.hub_status_data	= ohci_hub_status_data,
 	.hub_control		= ohci_hub_control,
-	.hub_irq_enable		= ohci_rhsc_enable,
 #ifdef CONFIG_PM
 	.bus_suspend		= ohci_bus_suspend,
 	.bus_resume		= ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 439beb7..7ea9a7b 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -36,18 +36,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* hcd->hub_irq_enable() */
-static void ohci_rhsc_enable (struct usb_hcd *hcd)
-{
-	struct ohci_hcd		*ohci = hcd_to_ohci (hcd);
-
-	spin_lock_irq(&ohci->lock);
-	if (!ohci->autostop)
-		del_timer(&hcd->rh_timer);	/* Prevent next poll */
-	ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
-	spin_unlock_irq(&ohci->lock);
-}
-
 #define OHCI_SCHED_ENABLES \
 	(OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
 
@@ -374,18 +362,28 @@
 		int any_connected)
 {
 	int	poll_rh = 1;
+	int	rhsc;
 
+	rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC;
 	switch (ohci->hc_control & OHCI_CTRL_HCFS) {
 
 	case OHCI_USB_OPER:
-		/* keep on polling until we know a device is connected
-		 * and RHSC is enabled */
+		/* If no status changes are pending, enable status-change
+		 * interrupts.
+		 */
+		if (!rhsc && !changed) {
+			rhsc = OHCI_INTR_RHSC;
+			ohci_writel(ohci, rhsc, &ohci->regs->intrenable);
+		}
+
+		/* Keep on polling until we know a device is connected
+		 * and RHSC is enabled, or until we autostop.
+		 */
 		if (!ohci->autostop) {
 			if (any_connected ||
 					!device_may_wakeup(&ohci_to_hcd(ohci)
 						->self.root_hub->dev)) {
-				if (ohci_readl(ohci, &ohci->regs->intrenable) &
-						OHCI_INTR_RHSC)
+				if (rhsc)
 					poll_rh = 0;
 			} else {
 				ohci->autostop = 1;
@@ -398,12 +396,13 @@
 				ohci->autostop = 0;
 				ohci->next_statechange = jiffies +
 						STATECHANGE_DELAY;
-			} else if (time_after_eq(jiffies,
+			} else if (rhsc && time_after_eq(jiffies,
 						ohci->next_statechange)
 					&& !ohci->ed_rm_list
 					&& !(ohci->hc_control &
 						OHCI_SCHED_ENABLES)) {
 				ohci_rh_suspend(ohci, 1);
+				poll_rh = 0;
 			}
 		}
 		break;
@@ -417,6 +416,12 @@
 			else
 				usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
 		} else {
+			if (!rhsc && (ohci->autostop ||
+					ohci_to_hcd(ohci)->self.root_hub->
+						do_remote_wakeup))
+				ohci_writel(ohci, OHCI_INTR_RHSC,
+						&ohci->regs->intrenable);
+
 			/* everything is idle, no need for polling */
 			poll_rh = 0;
 		}
@@ -438,12 +443,16 @@
 static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
 		int any_connected)
 {
-	int	poll_rh = 1;
-
-	/* keep on polling until RHSC is enabled */
+	/* If RHSC is enabled, don't poll */
 	if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
-		poll_rh = 0;
-	return poll_rh;
+		return 0;
+
+	/* If no status changes are pending, enable status-change interrupts */
+	if (!changed) {
+		ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
+		return 0;
+	}
+	return 1;
 }
 
 #endif	/* CONFIG_PM */
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c
index 9e31d44..de42283 100644
--- a/drivers/usb/host/ohci-lh7a404.c
+++ b/drivers/usb/host/ohci-lh7a404.c
@@ -193,7 +193,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 3d532b7..1eb64d0 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -470,7 +470,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 083e8df..a9c2ae3 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -459,7 +459,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c
index b02cd07..658a2a9 100644
--- a/drivers/usb/host/ohci-pnx4008.c
+++ b/drivers/usb/host/ohci-pnx4008.c
@@ -277,7 +277,6 @@
 	 */
 	.hub_status_data = ohci_hub_status_data,
 	.hub_control = ohci_hub_control,
-	.hub_irq_enable = ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend = ohci_bus_suspend,
 	.bus_resume = ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c
index 605d59c..28467e2 100644
--- a/drivers/usb/host/ohci-pnx8550.c
+++ b/drivers/usb/host/ohci-pnx8550.c
@@ -201,7 +201,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c
index 91e6e10..7ac5326 100644
--- a/drivers/usb/host/ohci-ppc-of.c
+++ b/drivers/usb/host/ohci-ppc-of.c
@@ -72,7 +72,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c
index 523c301..cd3398b 100644
--- a/drivers/usb/host/ohci-ppc-soc.c
+++ b/drivers/usb/host/ohci-ppc-soc.c
@@ -172,7 +172,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 55c9564..2089d8a 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -68,7 +68,6 @@
 	.get_frame_number	= ohci_get_frame,
 	.hub_status_data	= ohci_hub_status_data,
 	.hub_control		= ohci_hub_control,
-	.hub_irq_enable		= ohci_rhsc_enable,
 	.start_port_reset	= ohci_start_port_reset,
 #if defined(CONFIG_PM)
 	.bus_suspend 		= ohci_bus_suspend,
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 8c9c484..7f0f35c 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -298,7 +298,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef  CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c
index 9e3dc40..f46af7a 100644
--- a/drivers/usb/host/ohci-s3c2410.c
+++ b/drivers/usb/host/ohci-s3c2410.c
@@ -466,7 +466,6 @@
 	 */
 	.hub_status_data =	ohci_s3c2410_hub_status_data,
 	.hub_control =		ohci_s3c2410_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index 4626b00..e4bbe8e 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -231,7 +231,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-sh.c b/drivers/usb/host/ohci-sh.c
index e7ee607..60f03cc 100644
--- a/drivers/usb/host/ohci-sh.c
+++ b/drivers/usb/host/ohci-sh.c
@@ -68,7 +68,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c
index 21b164e..cff2363 100644
--- a/drivers/usb/host/ohci-sm501.c
+++ b/drivers/usb/host/ohci-sm501.c
@@ -75,7 +75,6 @@
 	 */
 	.hub_status_data =	ohci_hub_status_data,
 	.hub_control =		ohci_hub_control,
-	.hub_irq_enable =	ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend =		ohci_bus_suspend,
 	.bus_resume =		ohci_bus_resume,
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c
index 3660c83..23fd6a8 100644
--- a/drivers/usb/host/ohci-ssb.c
+++ b/drivers/usb/host/ohci-ssb.c
@@ -81,7 +81,6 @@
 
 	.hub_status_data	= ohci_hub_status_data,
 	.hub_control		= ohci_hub_control,
-	.hub_irq_enable		= ohci_rhsc_enable,
 #ifdef	CONFIG_PM
 	.bus_suspend		= ohci_bus_suspend,
 	.bus_resume		= ohci_bus_resume,
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index 20ad3c4..228f2b0 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -2934,16 +2934,6 @@
 		return 0;
 }
 
-static void u132_hub_irq_enable(struct usb_hcd *hcd)
-{
-	struct u132 *u132 = hcd_to_u132(hcd);
-	if (u132->going > 1) {
-		dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
-			, u132->going);
-	} else if (u132->going > 0)
-		dev_err(&u132->platform_dev->dev, "device is being removed\n");
-}
-
 
 #ifdef CONFIG_PM
 static int u132_bus_suspend(struct usb_hcd *hcd)
@@ -2995,7 +2985,6 @@
 	.bus_suspend = u132_bus_suspend,
 	.bus_resume = u132_bus_resume,
 	.start_port_reset = u132_start_port_reset,
-	.hub_irq_enable = u132_hub_irq_enable,
 };
 
 /*
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index fbace41..69c34a5 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -3270,6 +3270,7 @@
 	{ USB_DEVICE(0x0711, 0x0900) },
 	{ USB_DEVICE(0x0711, 0x0901) },
 	{ USB_DEVICE(0x0711, 0x0902) },
+	{ USB_DEVICE(0x0711, 0x0918) },
 	{ USB_DEVICE(0x182d, 0x021c) },
 	{ USB_DEVICE(0x182d, 0x0269) },
 	{ }
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index faca433..a001748 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -165,12 +165,11 @@
 	help
 	  Enable DMA transfers on TUSB 6010 when OMAP DMA is available.
 
-config	USB_MUSB_LOGLEVEL
+config	USB_MUSB_DEBUG
 	depends on USB_MUSB_HDRC
-	int  'Logging Level (0 - none / 3 - annoying / ... )'
-	default 0
+	bool "Enable debugging messages"
+	default n
 	help
-	  Set the logging level. 0 disables the debugging altogether,
-	  although when USB_DEBUG is set the value is at least 1.
-	  Starting at level 3, per-transfer (urb, usb_request, packet,
-	  or dma transfer) tracing may kick in.
+	  This enables musb debugging. To set the logging level use the debug
+	  module parameter. Starting at level 3, per-transfer (urb, usb_request,
+	  packet, or dma transfer) tracing may kick in.
diff --git a/drivers/usb/musb/Makefile b/drivers/usb/musb/Makefile
index 88eb67d..b6af0d6 100644
--- a/drivers/usb/musb/Makefile
+++ b/drivers/usb/musb/Makefile
@@ -64,23 +64,6 @@
 
 # Debugging
 
-MUSB_DEBUG:=$(CONFIG_USB_MUSB_LOGLEVEL)
-
-ifeq ("$(strip $(MUSB_DEBUG))","")
-    ifdef CONFIG_USB_DEBUG
-	MUSB_DEBUG:=1
-    else
-	MUSB_DEBUG:=0
-    endif
+ifeq ($(CONFIG_USB_MUSB_DEBUG),y)
+	EXTRA_CFLAGS += -DDEBUG
 endif
-
-ifneq ($(MUSB_DEBUG),0)
-    EXTRA_CFLAGS += -DDEBUG
-
-    ifeq ($(CONFIG_PROC_FS),y)
-	musb_hdrc-objs		+= musb_procfs.o
-    endif
-
-endif
-
-EXTRA_CFLAGS += -DMUSB_DEBUG=$(MUSB_DEBUG)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index d68ec6d..c5b8f02 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -114,23 +114,14 @@
 
 
 
-#if MUSB_DEBUG > 0
-unsigned debug = MUSB_DEBUG;
-module_param(debug, uint, 0);
-MODULE_PARM_DESC(debug, "initial debug message level");
-
-#define MUSB_VERSION_SUFFIX	"/dbg"
-#endif
+unsigned debug;
+module_param(debug, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug message level. Default = 0");
 
 #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
 #define DRIVER_DESC "Inventra Dual-Role USB Controller Driver"
 
-#define MUSB_VERSION_BASE "6.0"
-
-#ifndef MUSB_VERSION_SUFFIX
-#define MUSB_VERSION_SUFFIX	""
-#endif
-#define MUSB_VERSION	MUSB_VERSION_BASE MUSB_VERSION_SUFFIX
+#define MUSB_VERSION "6.0"
 
 #define DRIVER_INFO DRIVER_DESC ", v" MUSB_VERSION
 
@@ -2037,6 +2028,8 @@
 		musb->xceiv.state = OTG_STATE_A_IDLE;
 
 		status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
+		if (status)
+			goto fail;
 
 		DBG(1, "%s mode, status %d, devctl %02x %c\n",
 			"HOST", status,
@@ -2051,6 +2044,8 @@
 		musb->xceiv.state = OTG_STATE_B_IDLE;
 
 		status = musb_gadget_setup(musb);
+		if (status)
+			goto fail;
 
 		DBG(1, "%s mode, status %d, dev%02x\n",
 			is_otg_enabled(musb) ? "OTG" : "PERIPHERAL",
@@ -2059,16 +2054,14 @@
 
 	}
 
-	if (status == 0)
-		musb_debug_create("driver/musb_hdrc", musb);
-	else {
+	return 0;
+
 fail:
-		if (musb->clock)
-			clk_put(musb->clock);
-		device_init_wakeup(dev, 0);
-		musb_free(musb);
-		return status;
-	}
+	if (musb->clock)
+		clk_put(musb->clock);
+	device_init_wakeup(dev, 0);
+	musb_free(musb);
+	return status;
 
 #ifdef CONFIG_SYSFS
 	status = device_create_file(dev, &dev_attr_mode);
@@ -2131,7 +2124,6 @@
 	 *  - OTG mode: both roles are deactivated (or never-activated)
 	 */
 	musb_shutdown(pdev);
-	musb_debug_delete("driver/musb_hdrc", musb);
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
 	if (musb->board_mode == MUSB_HOST)
 		usb_remove_hcd(musb_to_hcd(musb));
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index eade46d..8222725 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -485,23 +485,4 @@
 extern int __init musb_platform_init(struct musb *musb);
 extern int musb_platform_exit(struct musb *musb);
 
-/*-------------------------- ProcFS definitions ---------------------*/
-
-struct proc_dir_entry;
-
-#if (MUSB_DEBUG > 0) && defined(MUSB_CONFIG_PROC_FS)
-extern struct proc_dir_entry *musb_debug_create(char *name, struct musb *data);
-extern void musb_debug_delete(char *name, struct musb *data);
-
-#else
-static inline struct proc_dir_entry *
-musb_debug_create(char *name, struct musb *data)
-{
-	return NULL;
-}
-static inline void musb_debug_delete(char *name, struct musb *data)
-{
-}
-#endif
-
 #endif	/* __MUSB_CORE_H__ */
diff --git a/drivers/usb/musb/musb_debug.h b/drivers/usb/musb/musb_debug.h
index 3bdb311..4d27944 100644
--- a/drivers/usb/musb/musb_debug.h
+++ b/drivers/usb/musb/musb_debug.h
@@ -48,11 +48,7 @@
 				__func__, __LINE__ , ## args); \
 	} } while (0)
 
-#if MUSB_DEBUG > 0
 extern unsigned debug;
-#else
-#define debug	0
-#endif
 
 static inline int _dbg_level(unsigned l)
 {
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
index 48d7d3c..a57652f 100644
--- a/drivers/usb/musb/musb_gadget_ep0.c
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -476,6 +476,7 @@
 			return;
 		musb->ackpend = 0;
 	}
+	musb_ep_select(musb->mregs, 0);
 	musb_writew(regs, MUSB_CSR0, tmp);
 }
 
@@ -528,6 +529,7 @@
 	}
 
 	/* send it out, triggering a "txpktrdy cleared" irq */
+	musb_ep_select(musb->mregs, 0);
 	musb_writew(regs, MUSB_CSR0, csr);
 }
 
diff --git a/drivers/usb/musb/musb_procfs.c b/drivers/usb/musb/musb_procfs.c
deleted file mode 100644
index 55e6b78..0000000
--- a/drivers/usb/musb/musb_procfs.c
+++ /dev/null
@@ -1,830 +0,0 @@
-/*
- * MUSB OTG driver debug support
- *
- * Copyright 2005 Mentor Graphics Corporation
- * Copyright (C) 2005-2006 by Texas Instruments
- * Copyright (C) 2006-2007 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>	/* FIXME remove procfs writes */
-#include <asm/arch/hardware.h>
-
-#include "musb_core.h"
-
-#include "davinci.h"
-
-#ifdef CONFIG_USB_MUSB_HDRC_HCD
-
-static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
-{
-	int				count;
-	int				tmp;
-	struct usb_host_endpoint	*hep = qh->hep;
-	struct urb			*urb;
-
-	count = snprintf(buf, max, "    qh %p dev%d ep%d%s max%d\n",
-			qh, qh->dev->devnum, qh->epnum,
-			({ char *s; switch (qh->type) {
-			case USB_ENDPOINT_XFER_BULK:
-				s = "-bulk"; break;
-			case USB_ENDPOINT_XFER_INT:
-				s = "-int"; break;
-			case USB_ENDPOINT_XFER_CONTROL:
-				s = ""; break;
-			default:
-				s = "iso"; break;
-			}; s; }),
-			qh->maxpacket);
-	if (count <= 0)
-		return 0;
-	buf += count;
-	max -= count;
-
-	list_for_each_entry(urb, &hep->urb_list, urb_list) {
-		tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n",
-				usb_pipein(urb->pipe) ? "in" : "out",
-				urb, urb->actual_length,
-				urb->transfer_buffer_length);
-		if (tmp <= 0)
-			break;
-		tmp = min(tmp, (int)max);
-		count += tmp;
-		buf += tmp;
-		max -= tmp;
-	}
-	return count;
-}
-
-static int
-dump_queue(struct list_head *q, char *buf, unsigned max)
-{
-	int		count = 0;
-	struct musb_qh	*qh;
-
-	list_for_each_entry(qh, q, ring) {
-		int	tmp;
-
-		tmp = dump_qh(qh, buf, max);
-		if (tmp <= 0)
-			break;
-		tmp = min(tmp, (int)max);
-		count += tmp;
-		buf += tmp;
-		max -= tmp;
-	}
-	return count;
-}
-
-#endif	/* HCD */
-
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max)
-{
-	char		*buf = buffer;
-	int		code = 0;
-	void __iomem	*regs = ep->hw_ep->regs;
-	char		*mode = "1buf";
-
-	if (ep->is_in) {
-		if (ep->hw_ep->tx_double_buffered)
-			mode = "2buf";
-	} else {
-		if (ep->hw_ep->rx_double_buffered)
-			mode = "2buf";
-	}
-
-	do {
-		struct usb_request	*req;
-
-		code = snprintf(buf, max,
-				"\n%s (hw%d): %s%s, csr %04x maxp %04x\n",
-				ep->name, ep->current_epnum,
-				mode, ep->dma ? " dma" : "",
-				musb_readw(regs,
-					(ep->is_in || !ep->current_epnum)
-						? MUSB_TXCSR
-						: MUSB_RXCSR),
-				musb_readw(regs, ep->is_in
-						? MUSB_TXMAXP
-						: MUSB_RXMAXP)
-				);
-		if (code <= 0)
-			break;
-		code = min(code, (int) max);
-		buf += code;
-		max -= code;
-
-		if (is_cppi_enabled() && ep->current_epnum) {
-			unsigned	cppi = ep->current_epnum - 1;
-			void __iomem	*base = ep->musb->ctrl_base;
-			unsigned	off1 = cppi << 2;
-			void __iomem	*ram = base;
-			char		tmp[16];
-
-			if (ep->is_in) {
-				ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi);
-				tmp[0] = 0;
-			} else {
-				ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi);
-				snprintf(tmp, sizeof tmp, "%d left, ",
-					musb_readl(base,
-					DAVINCI_RXCPPI_BUFCNT0_REG + off1));
-			}
-
-			code = snprintf(buf, max, "%cX DMA%d: %s"
-					"%08x %08x, %08x %08x; "
-					"%08x %08x %08x .. %08x\n",
-				ep->is_in ? 'T' : 'R',
-				ep->current_epnum - 1, tmp,
-				musb_readl(ram, 0 * 4),
-				musb_readl(ram, 1 * 4),
-				musb_readl(ram, 2 * 4),
-				musb_readl(ram, 3 * 4),
-				musb_readl(ram, 4 * 4),
-				musb_readl(ram, 5 * 4),
-				musb_readl(ram, 6 * 4),
-				musb_readl(ram, 7 * 4));
-			if (code <= 0)
-				break;
-			code = min(code, (int) max);
-			buf += code;
-			max -= code;
-		}
-
-		if (list_empty(&ep->req_list)) {
-			code = snprintf(buf, max, "\t(queue empty)\n");
-			if (code <= 0)
-				break;
-			code = min(code, (int) max);
-			buf += code;
-			max -= code;
-			break;
-		}
-		list_for_each_entry(req, &ep->req_list, list) {
-			code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n",
-					req,
-					req->zero ? "zero, " : "",
-					req->short_not_ok ? "!short, " : "",
-					req->actual, req->length);
-			if (code <= 0)
-				break;
-			code = min(code, (int) max);
-			buf += code;
-			max -= code;
-		}
-	} while (0);
-	return buf - buffer;
-}
-#endif
-
-static int
-dump_end_info(struct musb *musb, u8 epnum, char *aBuffer, unsigned max)
-{
-	int			code = 0;
-	char			*buf = aBuffer;
-	struct musb_hw_ep	*hw_ep = &musb->endpoints[epnum];
-
-	do {
-		musb_ep_select(musb->mregs, epnum);
-#ifdef CONFIG_USB_MUSB_HDRC_HCD
-		if (is_host_active(musb)) {
-			int		dump_rx, dump_tx;
-			void __iomem	*regs = hw_ep->regs;
-
-			/* TEMPORARY (!) until we have a real periodic
-			 * schedule tree ...
-			 */
-			if (!epnum) {
-				/* control is shared, uses RX queue
-				 * but (mostly) shadowed tx registers
-				 */
-				dump_tx = !list_empty(&musb->control);
-				dump_rx = 0;
-			} else if (hw_ep == musb->bulk_ep) {
-				dump_tx = !list_empty(&musb->out_bulk);
-				dump_rx = !list_empty(&musb->in_bulk);
-			} else if (musb->periodic[epnum]) {
-				struct usb_host_endpoint	*hep;
-
-				hep = musb->periodic[epnum]->hep;
-				dump_rx = hep->desc.bEndpointAddress
-						& USB_ENDPOINT_DIR_MASK;
-				dump_tx = !dump_rx;
-			} else
-				break;
-			/* END TEMPORARY */
-
-
-			if (dump_rx) {
-				code = snprintf(buf, max,
-					"\nRX%d: %s rxcsr %04x interval %02x "
-					"max %04x type %02x; "
-					"dev %d hub %d port %d"
-					"\n",
-					epnum,
-					hw_ep->rx_double_buffered
-						? "2buf" : "1buf",
-					musb_readw(regs, MUSB_RXCSR),
-					musb_readb(regs, MUSB_RXINTERVAL),
-					musb_readw(regs, MUSB_RXMAXP),
-					musb_readb(regs, MUSB_RXTYPE),
-					/* FIXME:  assumes multipoint */
-					musb_readb(musb->mregs,
-						MUSB_BUSCTL_OFFSET(epnum,
-						MUSB_RXFUNCADDR)),
-					musb_readb(musb->mregs,
-						MUSB_BUSCTL_OFFSET(epnum,
-						MUSB_RXHUBADDR)),
-					musb_readb(musb->mregs,
-						MUSB_BUSCTL_OFFSET(epnum,
-						MUSB_RXHUBPORT))
-					);
-				if (code <= 0)
-					break;
-				code = min(code, (int) max);
-				buf += code;
-				max -= code;
-
-				if (is_cppi_enabled()
-						&& epnum
-						&& hw_ep->rx_channel) {
-					unsigned	cppi = epnum - 1;
-					unsigned	off1 = cppi << 2;
-					void __iomem	*base;
-					void __iomem	*ram;
-					char		tmp[16];
-
-					base = musb->ctrl_base;
-					ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
-							cppi) + base;
-					snprintf(tmp, sizeof tmp, "%d left, ",
-						musb_readl(base,
-						DAVINCI_RXCPPI_BUFCNT0_REG
-								+ off1));
-
-					code = snprintf(buf, max,
-						"    rx dma%d: %s"
-						"%08x %08x, %08x %08x; "
-						"%08x %08x %08x .. %08x\n",
-						cppi, tmp,
-						musb_readl(ram, 0 * 4),
-						musb_readl(ram, 1 * 4),
-						musb_readl(ram, 2 * 4),
-						musb_readl(ram, 3 * 4),
-						musb_readl(ram, 4 * 4),
-						musb_readl(ram, 5 * 4),
-						musb_readl(ram, 6 * 4),
-						musb_readl(ram, 7 * 4));
-					if (code <= 0)
-						break;
-					code = min(code, (int) max);
-					buf += code;
-					max -= code;
-				}
-
-				if (hw_ep == musb->bulk_ep
-						&& !list_empty(
-							&musb->in_bulk)) {
-					code = dump_queue(&musb->in_bulk,
-							buf, max);
-					if (code <= 0)
-						break;
-					code = min(code, (int) max);
-					buf += code;
-					max -= code;
-				} else if (musb->periodic[epnum]) {
-					code = dump_qh(musb->periodic[epnum],
-							buf, max);
-					if (code <= 0)
-						break;
-					code = min(code, (int) max);
-					buf += code;
-					max -= code;
-				}
-			}
-
-			if (dump_tx) {
-				code = snprintf(buf, max,
-					"\nTX%d: %s txcsr %04x interval %02x "
-					"max %04x type %02x; "
-					"dev %d hub %d port %d"
-					"\n",
-					epnum,
-					hw_ep->tx_double_buffered
-						? "2buf" : "1buf",
-					musb_readw(regs, MUSB_TXCSR),
-					musb_readb(regs, MUSB_TXINTERVAL),
-					musb_readw(regs, MUSB_TXMAXP),
-					musb_readb(regs, MUSB_TXTYPE),
-					/* FIXME:  assumes multipoint */
-					musb_readb(musb->mregs,
-						MUSB_BUSCTL_OFFSET(epnum,
-						MUSB_TXFUNCADDR)),
-					musb_readb(musb->mregs,
-						MUSB_BUSCTL_OFFSET(epnum,
-						MUSB_TXHUBADDR)),
-					musb_readb(musb->mregs,
-						MUSB_BUSCTL_OFFSET(epnum,
-						MUSB_TXHUBPORT))
-					);
-				if (code <= 0)
-					break;
-				code = min(code, (int) max);
-				buf += code;
-				max -= code;
-
-				if (is_cppi_enabled()
-						&& epnum
-						&& hw_ep->tx_channel) {
-					unsigned	cppi = epnum - 1;
-					void __iomem	*base;
-					void __iomem	*ram;
-
-					base = musb->ctrl_base;
-					ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
-							cppi) + base;
-					code = snprintf(buf, max,
-						"    tx dma%d: "
-						"%08x %08x, %08x %08x; "
-						"%08x %08x %08x .. %08x\n",
-						cppi,
-						musb_readl(ram, 0 * 4),
-						musb_readl(ram, 1 * 4),
-						musb_readl(ram, 2 * 4),
-						musb_readl(ram, 3 * 4),
-						musb_readl(ram, 4 * 4),
-						musb_readl(ram, 5 * 4),
-						musb_readl(ram, 6 * 4),
-						musb_readl(ram, 7 * 4));
-					if (code <= 0)
-						break;
-					code = min(code, (int) max);
-					buf += code;
-					max -= code;
-				}
-
-				if (hw_ep == musb->control_ep
-						&& !list_empty(
-							&musb->control)) {
-					code = dump_queue(&musb->control,
-							buf, max);
-					if (code <= 0)
-						break;
-					code = min(code, (int) max);
-					buf += code;
-					max -= code;
-				} else if (hw_ep == musb->bulk_ep
-						&& !list_empty(
-							&musb->out_bulk)) {
-					code = dump_queue(&musb->out_bulk,
-							buf, max);
-					if (code <= 0)
-						break;
-					code = min(code, (int) max);
-					buf += code;
-					max -= code;
-				} else if (musb->periodic[epnum]) {
-					code = dump_qh(musb->periodic[epnum],
-							buf, max);
-					if (code <= 0)
-						break;
-					code = min(code, (int) max);
-					buf += code;
-					max -= code;
-				}
-			}
-		}
-#endif
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-		if (is_peripheral_active(musb)) {
-			code = 0;
-
-			if (hw_ep->ep_in.desc || !epnum) {
-				code = dump_ep(&hw_ep->ep_in, buf, max);
-				if (code <= 0)
-					break;
-				code = min(code, (int) max);
-				buf += code;
-				max -= code;
-			}
-			if (hw_ep->ep_out.desc) {
-				code = dump_ep(&hw_ep->ep_out, buf, max);
-				if (code <= 0)
-					break;
-				code = min(code, (int) max);
-				buf += code;
-				max -= code;
-			}
-		}
-#endif
-	} while (0);
-
-	return buf - aBuffer;
-}
-
-/* Dump the current status and compile options.
- * @param musb the device driver instance
- * @param buffer where to dump the status; it must be big enough to hold the
- * result otherwise "BAD THINGS HAPPENS(TM)".
- */
-static int dump_header_stats(struct musb *musb, char *buffer)
-{
-	int code, count = 0;
-	const void __iomem *mbase = musb->mregs;
-
-	*buffer = 0;
-	count = sprintf(buffer, "Status: %sHDRC, Mode=%s "
-				"(Power=%02x, DevCtl=%02x)\n",
-			(musb->is_multipoint ? "M" : ""), MUSB_MODE(musb),
-			musb_readb(mbase, MUSB_POWER),
-			musb_readb(mbase, MUSB_DEVCTL));
-	if (count <= 0)
-		return 0;
-	buffer += count;
-
-	code = sprintf(buffer, "OTG state: %s; %sactive\n",
-			otg_state_string(musb),
-			musb->is_active ? "" : "in");
-	if (code <= 0)
-		goto done;
-	buffer += code;
-	count += code;
-
-	code = sprintf(buffer,
-			"Options: "
-#ifdef CONFIG_MUSB_PIO_ONLY
-			"pio"
-#elif defined(CONFIG_USB_TI_CPPI_DMA)
-			"cppi-dma"
-#elif defined(CONFIG_USB_INVENTRA_DMA)
-			"musb-dma"
-#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
-			"tusb-omap-dma"
-#else
-			"?dma?"
-#endif
-			", "
-#ifdef CONFIG_USB_MUSB_OTG
-			"otg (peripheral+host)"
-#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
-			"peripheral"
-#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
-			"host"
-#endif
-			", debug=%d [eps=%d]\n",
-		debug,
-		musb->nr_endpoints);
-	if (code <= 0)
-		goto done;
-	count += code;
-	buffer += code;
-
-#ifdef	CONFIG_USB_GADGET_MUSB_HDRC
-	code = sprintf(buffer, "Peripheral address: %02x\n",
-			musb_readb(musb->ctrl_base, MUSB_FADDR));
-	if (code <= 0)
-		goto done;
-	buffer += code;
-	count += code;
-#endif
-
-#ifdef	CONFIG_USB_MUSB_HDRC_HCD
-	code = sprintf(buffer, "Root port status: %08x\n",
-			musb->port1_status);
-	if (code <= 0)
-		goto done;
-	buffer += code;
-	count += code;
-#endif
-
-#ifdef	CONFIG_ARCH_DAVINCI
-	code = sprintf(buffer,
-			"DaVinci: ctrl=%02x stat=%1x phy=%03x\n"
-			"\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x"
-			"\n",
-			musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG),
-			musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG),
-			__raw_readl((void __force __iomem *)
-					IO_ADDRESS(USBPHY_CTL_PADDR)),
-			musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG),
-			musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG),
-			musb_readl(musb->ctrl_base,
-					DAVINCI_USB_INT_SOURCE_REG),
-			musb_readl(musb->ctrl_base,
-					DAVINCI_USB_INT_MASK_REG));
-	if (code <= 0)
-		goto done;
-	count += code;
-	buffer += code;
-#endif	/* DAVINCI */
-
-#ifdef CONFIG_USB_TUSB6010
-	code = sprintf(buffer,
-			"TUSB6010: devconf %08x, phy enable %08x drive %08x"
-			"\n\totg %03x timer %08x"
-			"\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x"
-			"\n",
-			musb_readl(musb->ctrl_base, TUSB_DEV_CONF),
-			musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
-			musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL),
-			musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT),
-			musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER),
-			musb_readl(musb->ctrl_base, TUSB_PRCM_CONF),
-			musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT),
-			musb_readl(musb->ctrl_base, TUSB_INT_SRC),
-			musb_readl(musb->ctrl_base, TUSB_INT_MASK));
-	if (code <= 0)
-		goto done;
-	count += code;
-	buffer += code;
-#endif	/* DAVINCI */
-
-	if (is_cppi_enabled() && musb->dma_controller) {
-		code = sprintf(buffer,
-				"CPPI: txcr=%d txsrc=%01x txena=%01x; "
-				"rxcr=%d rxsrc=%01x rxena=%01x "
-				"\n",
-				musb_readl(musb->ctrl_base,
-						DAVINCI_TXCPPI_CTRL_REG),
-				musb_readl(musb->ctrl_base,
-						DAVINCI_TXCPPI_RAW_REG),
-				musb_readl(musb->ctrl_base,
-						DAVINCI_TXCPPI_INTENAB_REG),
-				musb_readl(musb->ctrl_base,
-						DAVINCI_RXCPPI_CTRL_REG),
-				musb_readl(musb->ctrl_base,
-						DAVINCI_RXCPPI_RAW_REG),
-				musb_readl(musb->ctrl_base,
-						DAVINCI_RXCPPI_INTENAB_REG));
-		if (code <= 0)
-			goto done;
-		count += code;
-		buffer += code;
-	}
-
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-	if (is_peripheral_enabled(musb)) {
-		code = sprintf(buffer, "Gadget driver: %s\n",
-				musb->gadget_driver
-					? musb->gadget_driver->driver.name
-					: "(none)");
-		if (code <= 0)
-			goto done;
-		count += code;
-		buffer += code;
-	}
-#endif
-
-done:
-	return count;
-}
-
-/* Write to ProcFS
- *
- * C soft-connect
- * c soft-disconnect
- * I enable HS
- * i disable HS
- * s stop session
- * F force session (OTG-unfriendly)
- * E rElinquish bus (OTG)
- * H request host mode
- * h cancel host request
- * T start sending TEST_PACKET
- * D<num> set/query the debug level
- */
-static int musb_proc_write(struct file *file, const char __user *buffer,
-			unsigned long count, void *data)
-{
-	char cmd;
-	u8 reg;
-	struct musb *musb = (struct musb *)data;
-	void __iomem *mbase = musb->mregs;
-
-	/* MOD_INC_USE_COUNT; */
-
-	if (unlikely(copy_from_user(&cmd, buffer, 1)))
-		return -EFAULT;
-
-	switch (cmd) {
-	case 'C':
-		if (mbase) {
-			reg = musb_readb(mbase, MUSB_POWER)
-					| MUSB_POWER_SOFTCONN;
-			musb_writeb(mbase, MUSB_POWER, reg);
-		}
-		break;
-
-	case 'c':
-		if (mbase) {
-			reg = musb_readb(mbase, MUSB_POWER)
-					& ~MUSB_POWER_SOFTCONN;
-			musb_writeb(mbase, MUSB_POWER, reg);
-		}
-		break;
-
-	case 'I':
-		if (mbase) {
-			reg = musb_readb(mbase, MUSB_POWER)
-					| MUSB_POWER_HSENAB;
-			musb_writeb(mbase, MUSB_POWER, reg);
-		}
-		break;
-
-	case 'i':
-		if (mbase) {
-			reg = musb_readb(mbase, MUSB_POWER)
-					& ~MUSB_POWER_HSENAB;
-			musb_writeb(mbase, MUSB_POWER, reg);
-		}
-		break;
-
-	case 'F':
-		reg = musb_readb(mbase, MUSB_DEVCTL);
-		reg |= MUSB_DEVCTL_SESSION;
-		musb_writeb(mbase, MUSB_DEVCTL, reg);
-		break;
-
-	case 'H':
-		if (mbase) {
-			reg = musb_readb(mbase, MUSB_DEVCTL);
-			reg |= MUSB_DEVCTL_HR;
-			musb_writeb(mbase, MUSB_DEVCTL, reg);
-			/* MUSB_HST_MODE( ((struct musb*)data) ); */
-			/* WARNING("Host Mode\n"); */
-		}
-		break;
-
-	case 'h':
-		if (mbase) {
-			reg = musb_readb(mbase, MUSB_DEVCTL);
-			reg &= ~MUSB_DEVCTL_HR;
-			musb_writeb(mbase, MUSB_DEVCTL, reg);
-		}
-		break;
-
-	case 'T':
-		if (mbase) {
-			musb_load_testpacket(musb);
-			musb_writeb(mbase, MUSB_TESTMODE,
-					MUSB_TEST_PACKET);
-		}
-		break;
-
-#if (MUSB_DEBUG > 0)
-		/* set/read debug level */
-	case 'D':{
-			if (count > 1) {
-				char digits[8], *p = digits;
-				int i = 0, level = 0, sign = 1;
-				int len = min(count - 1, (unsigned long)8);
-
-				if (copy_from_user(&digits, &buffer[1], len))
-					return -EFAULT;
-
-				/* optional sign */
-				if (*p == '-') {
-					len -= 1;
-					sign = -sign;
-					p++;
-				}
-
-				/* read it */
-				while (i++ < len && *p > '0' && *p < '9') {
-					level = level * 10 + (*p - '0');
-					p++;
-				}
-
-				level *= sign;
-				DBG(1, "debug level %d\n", level);
-				debug = level;
-			}
-		}
-		break;
-
-
-	case '?':
-		INFO("?: you are seeing it\n");
-		INFO("C/c: soft connect enable/disable\n");
-		INFO("I/i: hispeed enable/disable\n");
-		INFO("F: force session start\n");
-		INFO("H: host mode\n");
-		INFO("T: start sending TEST_PACKET\n");
-		INFO("D: set/read dbug level\n");
-		break;
-#endif
-
-	default:
-		ERR("Command %c not implemented\n", cmd);
-		break;
-	}
-
-	musb_platform_try_idle(musb, 0);
-
-	return count;
-}
-
-static int musb_proc_read(char *page, char **start,
-			off_t off, int count, int *eof, void *data)
-{
-	char *buffer = page;
-	int code = 0;
-	unsigned long	flags;
-	struct musb	*musb = data;
-	unsigned	epnum;
-
-	count -= off;
-	count -= 1;		/* for NUL at end */
-	if (count <= 0)
-		return -EINVAL;
-
-	spin_lock_irqsave(&musb->lock, flags);
-
-	code = dump_header_stats(musb, buffer);
-	if (code > 0) {
-		buffer += code;
-		count -= code;
-	}
-
-	/* generate the report for the end points */
-	/* REVISIT ... not unless something's connected! */
-	for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints;
-			epnum++) {
-		code = dump_end_info(musb, epnum, buffer, count);
-		if (code > 0) {
-			buffer += code;
-			count -= code;
-		}
-	}
-
-	musb_platform_try_idle(musb, 0);
-
-	spin_unlock_irqrestore(&musb->lock, flags);
-	*eof = 1;
-
-	return buffer - page;
-}
-
-void __devexit musb_debug_delete(char *name, struct musb *musb)
-{
-	if (musb->proc_entry)
-		remove_proc_entry(name, NULL);
-}
-
-struct proc_dir_entry *__init
-musb_debug_create(char *name, struct musb *data)
-{
-	struct proc_dir_entry	*pde;
-
-	/* FIXME convert everything to seq_file; then later, debugfs */
-
-	if (!name)
-		return NULL;
-
-	pde = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, NULL);
-	data->proc_entry = pde;
-	if (pde) {
-		pde->data = data;
-		/* pde->owner = THIS_MODULE; */
-
-		pde->read_proc = musb_proc_read;
-		pde->write_proc = musb_proc_write;
-
-		pde->size = 0;
-
-		pr_debug("Registered /proc/%s\n", name);
-	} else {
-		pr_debug("Cannot create a valid proc file entry");
-	}
-
-	return pde;
-}
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index e143198..9f9cd36 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -173,6 +173,7 @@
 #define KYOCERA_PRODUCT_KPC680			0x180a
 
 #define ANYDATA_VENDOR_ID			0x16d5
+#define ANYDATA_PRODUCT_ADU_620UW		0x6202
 #define ANYDATA_PRODUCT_ADU_E100A		0x6501
 #define ANYDATA_PRODUCT_ADU_500A		0x6502
 
@@ -318,6 +319,7 @@
 	{ USB_DEVICE(DELL_VENDOR_ID, 0x8138) },	/* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
 	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
+	{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
 	{ USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
 	{ USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) },
 	{ USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
diff --git a/include/asm-x86/genapic_32.h b/include/asm-x86/genapic_32.h
index b02ea6e..754d635 100644
--- a/include/asm-x86/genapic_32.h
+++ b/include/asm-x86/genapic_32.h
@@ -118,6 +118,7 @@
 #define get_uv_system_type()		UV_NONE
 #define is_uv_system()			0
 #define uv_wakeup_secondary(a, b)	1
+#define uv_system_init()		do {} while (0)
 
 
 #endif
diff --git a/include/asm-x86/genapic_64.h b/include/asm-x86/genapic_64.h
index 0f85046..a47d631 100644
--- a/include/asm-x86/genapic_64.h
+++ b/include/asm-x86/genapic_64.h
@@ -42,6 +42,7 @@
 extern struct genapic apic_x2apic_uv_x;
 DECLARE_PER_CPU(int, x2apic_extra_bits);
 extern void uv_cpu_init(void);
+extern void uv_system_init(void);
 extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip);
 
 extern void setup_apic_routing(void);
diff --git a/include/asm-x86/irq_vectors.h b/include/asm-x86/irq_vectors.h
index b95d167..a48c7f2 100644
--- a/include/asm-x86/irq_vectors.h
+++ b/include/asm-x86/irq_vectors.h
@@ -76,6 +76,7 @@
 #define CALL_FUNCTION_SINGLE_VECTOR	0xfb
 #define THERMAL_APIC_VECTOR		0xfa
 #define THRESHOLD_APIC_VECTOR		0xf9
+#define UV_BAU_MESSAGE			0xf8
 #define INVALIDATE_TLB_VECTOR_END	0xf7
 #define INVALIDATE_TLB_VECTOR_START	0xf0	/* f0-f7 used for TLB flush */
 
diff --git a/include/asm-x86/uv/uv_bau.h b/include/asm-x86/uv/uv_bau.h
index 91ac0df..610b6b3 100644
--- a/include/asm-x86/uv/uv_bau.h
+++ b/include/asm-x86/uv/uv_bau.h
@@ -40,11 +40,6 @@
 #define UV_ACTIVATION_DESCRIPTOR_SIZE	32
 #define UV_DISTRIBUTION_SIZE		256
 #define UV_SW_ACK_NPENDING		8
-#define UV_BAU_MESSAGE			200
-/*
- * Messaging irq; see irq_64.h and include/asm-x86/hw_irq_64.h
- * To be dynamically allocated in the future
- */
 #define UV_NET_ENDPOINT_INTD		0x38
 #define UV_DESC_BASE_PNODE_SHIFT	49
 #define UV_PAYLOADQ_PNODE_SHIFT		49
diff --git a/include/linux/device.h b/include/linux/device.h
index d24a47f..4d8372d 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -358,6 +358,7 @@
 
 	struct kobject kobj;
 	char	bus_id[BUS_ID_SIZE];	/* position on parent bus */
+	const char		*init_name; /* initial name of the device */
 	struct device_type	*type;
 	unsigned		uevent_suppress:1;
 
@@ -406,7 +407,7 @@
 /* Get the wakeup routines, which depend on struct device */
 #include <linux/pm_wakeup.h>
 
-static inline const char *dev_name(struct device *dev)
+static inline const char *dev_name(const struct device *dev)
 {
 	/* will be changed into kobject_name(&dev->kobj) in the near future */
 	return dev->bus_id;
@@ -518,7 +519,7 @@
 extern void sysdev_shutdown(void);
 
 /* debugging and troubleshooting/diagnostic helpers. */
-extern const char *dev_driver_string(struct device *dev);
+extern const char *dev_driver_string(const struct device *dev);
 #define dev_printk(level, dev, format, arg...)	\
 	printk(level "%s %s: " format , dev_driver_string(dev) , \
 	       dev_name(dev) , ## arg)
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 06b8033..225bfc5 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -163,6 +163,7 @@
 	ATA_DEV_NONE		= 9,	/* no device */
 
 	/* struct ata_link flags */
+	ATA_LFLAG_NO_HRST	= (1 << 1), /* avoid hardreset */
 	ATA_LFLAG_NO_SRST	= (1 << 2), /* avoid softreset */
 	ATA_LFLAG_ASSUME_ATA	= (1 << 3), /* assume ATA class */
 	ATA_LFLAG_ASSUME_SEMB	= (1 << 4), /* assume SEMB class */
@@ -646,6 +647,7 @@
 
 	unsigned int		flags;		/* ATA_LFLAG_xxx */
 
+	u32			saved_scontrol;	/* SControl on probe */
 	unsigned int		hw_sata_spd_limit;
 	unsigned int		sata_spd_limit;
 	unsigned int		sata_spd;	/* current SATA PHY speed */
@@ -1427,6 +1429,28 @@
 	return from_jiffies + msecs_to_jiffies(timeout_msecs);
 }
 
+/* Don't open code these in drivers as there are traps. Firstly the range may
+   change in future hardware and specs, secondly 0xFF means 'no DMA' but is
+   > UDMA_0. Dyma ddreigiau */
+
+static inline int ata_using_mwdma(struct ata_device *adev)
+{
+	if (adev->dma_mode >= XFER_MW_DMA_0 && adev->dma_mode <= XFER_MW_DMA_4)
+		return 1;
+	return 0;
+}
+
+static inline int ata_using_udma(struct ata_device *adev)
+{
+	if (adev->dma_mode >= XFER_UDMA_0 && adev->dma_mode <= XFER_UDMA_7)
+		return 1;
+	return 0;
+}
+
+static inline int ata_dma_enabled(struct ata_device *adev)
+{
+	return (adev->dma_mode == 0xFF ? 0 : 1);
+}
 
 /**************************************************************************
  * PMP - drivers/ata/libata-pmp.c
diff --git a/include/linux/tick.h b/include/linux/tick.h
index d3c0269..8cf8cfe 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -74,10 +74,13 @@
 extern int tick_init_highres(void);
 extern int tick_program_event(ktime_t expires, int force);
 extern void tick_setup_sched_timer(void);
+# endif
+
+# if defined CONFIG_NO_HZ || defined CONFIG_HIGH_RES_TIMERS
 extern void tick_cancel_sched_timer(int cpu);
 # else
 static inline void tick_cancel_sched_timer(int cpu) { }
-# endif /* HIGHRES */
+# endif
 
 # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 extern struct tick_device *tick_get_broadcast_device(void);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 0924cd9..94ac74a 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -110,6 +110,8 @@
  * @sysfs_files_created: sysfs attributes exist
  * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
  *	capability during autosuspend.
+ * @needs_altsetting0: flag set when a set-interface request for altsetting 0
+ *	has been deferred.
  * @needs_binding: flag set when the driver should be re-probed or unbound
  *	following a reset or suspend operation it doesn't support.
  * @dev: driver model's view of this device
@@ -162,6 +164,7 @@
 	unsigned is_active:1;		/* the interface is not suspended */
 	unsigned sysfs_files_created:1;	/* the sysfs attributes exist */
 	unsigned needs_remote_wakeup:1;	/* driver requires remote wakeup */
+	unsigned needs_altsetting0:1;	/* switch to altsetting 0 is pending */
 	unsigned needs_binding:1;	/* needs delayed unbind/rebind */
 
 	struct device dev;		/* interface specific device info */
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index f5da526..7a46bde 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -643,17 +643,21 @@
 		ts->nohz_mode = NOHZ_MODE_HIGHRES;
 #endif
 }
+#endif /* HIGH_RES_TIMERS */
 
+#if defined CONFIG_NO_HZ || defined CONFIG_HIGH_RES_TIMERS
 void tick_cancel_sched_timer(int cpu)
 {
 	struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
 
+# ifdef CONFIG_HIGH_RES_TIMERS
 	if (ts->sched_timer.base)
 		hrtimer_cancel(&ts->sched_timer);
+# endif
 
 	ts->nohz_mode = NOHZ_MODE_INACTIVE;
 }
-#endif /* HIGH_RES_TIMERS */
+#endif
 
 /**
  * Async notification about clocksource changes
diff --git a/lib/kobject.c b/lib/kobject.c
index bd732ff..fbf0ae2 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -223,8 +223,7 @@
 		return -ENOMEM;
 
 	/* ewww... some of these buggers have '/' in the name ... */
-	s = strchr(kobj->name, '/');
-	if (s)
+	while ((s = strchr(kobj->name, '/')))
 		s[0] = '!';
 
 	kfree(old_name);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 4fa1f3a..4c9890e 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -344,14 +344,20 @@
 				struct module *mod)
 {
 	const unsigned long id_size = sizeof(struct pnp_device_id);
-	const struct pnp_device_id *id = symval;
+	const unsigned int count = (size / id_size)-1;
+	const struct pnp_device_id *devs = symval;
+	unsigned int i;
 
 	device_id_check(mod->name, "pnp", size, id_size, symval);
 
-	buf_printf(&mod->dev_table_buf,
-		   "MODULE_ALIAS(\"pnp:d%s*\");\n", id->id);
-	buf_printf(&mod->dev_table_buf,
-		   "MODULE_ALIAS(\"acpi*:%s:*\");\n", id->id);
+	for (i = 0; i < count; i++) {
+		const char *id = (char *)devs[i].id;
+
+		buf_printf(&mod->dev_table_buf,
+			   "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
+		buf_printf(&mod->dev_table_buf,
+			   "MODULE_ALIAS(\"acpi*:%s:*\");\n", id);
+	}
 }
 
 /* looks like: "pnp:dD" for every device of the card */