Browse Source

Merge branch 'master' of /home/trondmy/repositories/git/linux-2.6/

Trond Myklebust 18 years ago
parent
commit
5cf4cf65a8
89 changed files with 1648 additions and 403 deletions
  1. 15 0
      arch/avr32/boards/atstk1000/atstk1000.h
  2. 5 5
      arch/avr32/boards/atstk1000/atstk1002.c
  3. 44 1
      arch/avr32/boards/atstk1000/setup.c
  4. 0 9
      arch/avr32/kernel/irq.c
  5. 1 6
      arch/avr32/kernel/kprobes.c
  6. 3 0
      arch/avr32/kernel/syscall_table.S
  7. 60 17
      arch/avr32/mach-at32ap/at32ap7000.c
  8. 12 24
      arch/avr32/mm/fault.c
  9. 1 1
      arch/ia64/kernel/acpi.c
  10. 16 8
      arch/ia64/kernel/crash.c
  11. 3 0
      arch/ia64/kernel/entry.S
  12. 3 3
      arch/ia64/kernel/irq.c
  13. 1 1
      arch/ia64/kernel/irq_lsapic.c
  14. 4 11
      arch/ia64/kernel/kprobes.c
  15. 4 1
      arch/ia64/kernel/mca.c
  16. 2 2
      arch/ia64/kernel/mca_drv.c
  17. 1 1
      arch/ia64/kernel/module.c
  18. 9 9
      arch/ia64/kernel/perfmon.c
  19. 1 1
      arch/ia64/kernel/perfmon_mckinley.h
  20. 1 1
      arch/ia64/kernel/sal.c
  21. 1 1
      arch/ia64/kernel/salinfo.c
  22. 3 3
      arch/ia64/kernel/setup.c
  23. 6 6
      arch/ia64/kernel/smp.c
  24. 3 3
      arch/ia64/kernel/smpboot.c
  25. 1 1
      arch/ia64/kernel/traps.c
  26. 1 1
      arch/ia64/kernel/unwind.c
  27. 1 1
      arch/ia64/mm/discontig.c
  28. 14 27
      arch/ia64/mm/fault.c
  29. 6 6
      arch/ia64/sn/kernel/bte.c
  30. 2 2
      arch/ia64/sn/kernel/bte_error.c
  31. 1 1
      arch/ia64/sn/kernel/io_common.c
  32. 1 1
      arch/ia64/sn/kernel/setup.c
  33. 1 1
      arch/ia64/sn/kernel/sn2/sn2_smp.c
  34. 4 4
      arch/ia64/sn/kernel/xpc_channel.c
  35. 1 1
      arch/ia64/sn/kernel/xpnet.c
  36. 4 4
      arch/ia64/sn/pci/pci_dma.c
  37. 3 3
      arch/ia64/sn/pci/pcibr/pcibr_ate.c
  38. 1 1
      arch/ia64/sn/pci/pcibr/pcibr_dma.c
  39. 3 3
      arch/ia64/sn/pci/tioca_provider.c
  40. 8 8
      arch/ia64/sn/pci/tioce_provider.c
  41. 1 1
      arch/sparc64/kernel/Makefile
  42. 94 0
      arch/sparc64/kernel/entry.S
  43. 189 0
      arch/sparc64/kernel/hvapi.c
  44. 3 0
      arch/sparc64/kernel/setup.c
  45. 2 1
      drivers/ata/ahci.c
  46. 5 5
      drivers/ata/libata-acpi.c
  47. 49 31
      drivers/ata/libata-core.c
  48. 36 8
      drivers/ata/libata-scsi.c
  49. 2 1
      drivers/ata/libata.h
  50. 2 2
      drivers/ata/pata_scc.c
  51. 2 1
      drivers/ata/sata_sil24.c
  52. 1 0
      drivers/parport/parport_pc.c
  53. 205 71
      drivers/serial/sunhv.c
  54. 1 1
      drivers/spi/spidev.c
  55. 0 1
      fs/afs/super.c
  56. 1 2
      fs/afs/write.c
  57. 3 5
      include/asm-avr32/arch-at32ap/board.h
  58. 13 4
      include/asm-avr32/kdebug.h
  59. 1 0
      include/asm-avr32/kprobes.h
  60. 4 1
      include/asm-avr32/unistd.h
  61. 13 3
      include/asm-ia64/kdebug.h
  62. 1 0
      include/asm-ia64/kprobes.h
  63. 4 1
      include/asm-ia64/unistd.h
  64. 82 1
      include/asm-sparc64/hypervisor.h
  65. 2 1
      include/linux/libata.h
  66. 1 1
      include/linux/slub_def.h
  67. 3 1
      include/sound/soc.h
  68. 1 1
      include/sound/version.h
  69. 8 7
      kernel/power/main.c
  70. 2 1
      mm/filemap.c
  71. 1 1
      mm/slub.c
  72. 11 4
      sound/isa/cmi8330.c
  73. 14 6
      sound/isa/cs423x/cs4236.c
  74. 13 6
      sound/isa/es18xx.c
  75. 10 5
      sound/isa/gus/interwave.c
  76. 11 4
      sound/isa/opl3sa2.c
  77. 10 5
      sound/isa/sb/sb16.c
  78. 15 13
      sound/isa/sscape.c
  79. 10 4
      sound/isa/wavefront/wavefront.c
  80. 5 0
      sound/pci/ac97/ac97_patch.c
  81. 2 1
      sound/pci/hda/hda_codec.c
  82. 515 17
      sound/pci/hda/patch_realtek.c
  83. 2 0
      sound/pci/hda/patch_sigmatel.c
  84. 19 1
      sound/pci/intel8x0.c
  85. 2 1
      sound/soc/codecs/ac97.c
  86. 1 0
      sound/soc/codecs/wm9712.c
  87. 15 3
      sound/soc/soc-core.c
  88. 1 1
      sound/usb/usbmixer.c
  89. 9 0
      sound/usb/usbquirks.h

+ 15 - 0
arch/avr32/boards/atstk1000/atstk1000.h

@@ -0,0 +1,15 @@
+/*
+ * ATSTK1000 setup code: Daughterboard interface
+ *
+ * Copyright (C) 2007 Atmel 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.
+ */
+#ifndef __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H
+#define __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H
+
+extern struct atmel_lcdfb_info atstk1000_lcdc_data;
+
+#endif /* __ARCH_AVR32_BOARDS_ATSTK1000_ATSTK1000_H */

+ 5 - 5
arch/avr32/boards/atstk1000/atstk1002.c

@@ -16,6 +16,8 @@
 #include <linux/types.h>
 #include <linux/spi/spi.h>
 
+#include <video/atmel_lcdc.h>
+
 #include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/arch/at32ap7000.h>
@@ -23,6 +25,7 @@
 #include <asm/arch/init.h>
 #include <asm/arch/portmux.h>
 
+#include "atstk1000.h"
 
 #define	SW2_DEFAULT		/* MMCI and UART_A available */
 
@@ -31,9 +34,7 @@ struct eth_addr {
 };
 
 static struct eth_addr __initdata hw_addr[2];
-
 static struct eth_platform_data __initdata eth_data[2];
-static struct lcdc_platform_data atstk1000_fb0_data;
 
 static struct spi_board_info spi0_board_info[] __initdata = {
 	{
@@ -148,9 +149,8 @@ static int __init atstk1002_init(void)
 	set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
 
 	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
-	atstk1000_fb0_data.fbmem_start = fbmem_start;
-	atstk1000_fb0_data.fbmem_size = fbmem_size;
-	at32_add_device_lcdc(0, &atstk1000_fb0_data);
+	at32_add_device_lcdc(0, &atstk1000_lcdc_data,
+			     fbmem_start, fbmem_size);
 
 	return 0;
 }

+ 44 - 1
arch/avr32/boards/atstk1000/setup.c

@@ -8,13 +8,56 @@
  * published by the Free Software Foundation.
  */
 #include <linux/bootmem.h>
+#include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/linkage.h>
 
-#include <asm/setup.h>
+#include <video/atmel_lcdc.h>
 
+#include <asm/setup.h>
 #include <asm/arch/board.h>
 
+#include "atstk1000.h"
+
 /* Initialized by bootloader-specific startup code. */
 struct tag *bootloader_tags __initdata;
+
+static struct fb_videomode __initdata ltv350qv_modes[] = {
+	{
+		.name		= "320x240 @ 75",
+		.refresh	= 75,
+		.xres		= 320,		.yres		= 240,
+		.pixclock	= KHZ2PICOS(6891),
+
+		.left_margin	= 17,		.right_margin	= 33,
+		.upper_margin	= 10,		.lower_margin	= 10,
+		.hsync_len	= 16,		.vsync_len	= 1,
+
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+	},
+};
+
+static struct fb_monspecs __initdata atstk1000_default_monspecs = {
+	.manufacturer		= "SNG",
+	.monitor		= "LTV350QV",
+	.modedb			= ltv350qv_modes,
+	.modedb_len		= ARRAY_SIZE(ltv350qv_modes),
+	.hfmin			= 14820,
+	.hfmax			= 22230,
+	.vfmin			= 60,
+	.vfmax			= 90,
+	.dclkmax		= 30000000,
+};
+
+struct atmel_lcdfb_info __initdata atstk1000_lcdc_data = {
+	.default_bpp		= 24,
+	.default_dmacon		= ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
+	.default_lcdcon2	= (ATMEL_LCDC_DISTYPE_TFT
+				   | ATMEL_LCDC_INVCLK
+				   | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
+				   | ATMEL_LCDC_MEMOR_BIG),
+	.default_monspecs	= &atstk1000_default_monspecs,
+	.guard_time		= 2,
+};

+ 0 - 9
arch/avr32/kernel/irq.c

@@ -7,15 +7,6 @@
  * 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 file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
- * instead of just grabbing them. Thus setups with different IRQ numbers
- * shouldn't result in any weird surprises, and installing new handlers
- * should be easier.
- *
- * IRQ's are in fact implemented a bit like signal handlers for the kernel.
- * Naturally it's not a 1:1 relation, but there are similarities.
  */
 
 #include <linux/interrupt.h>

+ 1 - 6
arch/avr32/kernel/kprobes.c

@@ -179,7 +179,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
 	return 1;
 }
 
-static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
 	struct kprobe *cur = kprobe_running();
 
@@ -216,11 +216,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
 		if (post_kprobe_handler(args->regs))
 			ret = NOTIFY_STOP;
 		break;
-	case DIE_FAULT:
-		if (kprobe_running()
-		    && kprobe_fault_handler(args->regs, args->trapnr))
-			ret = NOTIFY_STOP;
-		break;
 	default:
 		break;
 	}

+ 3 - 0
arch/avr32/kernel/syscall_table.S

@@ -292,4 +292,7 @@ sys_call_table:
 	.long	sys_shmdt
 	.long	sys_shmctl
 	.long	sys_utimensat
+	.long	sys_signalfd
+	.long	sys_timerfd		/* 280 */
+	.long	sys_eventfd
 	.long	sys_ni_syscall		/* r8 is saturated at nr_syscalls */

+ 60 - 17
arch/avr32/mach-at32ap/at32ap7000.c

@@ -6,6 +6,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/clk.h>
+#include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
@@ -17,6 +18,8 @@
 #include <asm/arch/portmux.h>
 #include <asm/arch/sm.h>
 
+#include <video/atmel_lcdc.h>
+
 #include "clock.h"
 #include "hmatrix.h"
 #include "pio.h"
@@ -881,20 +884,26 @@ at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
 /* --------------------------------------------------------------------
  *  LCDC
  * -------------------------------------------------------------------- */
-static struct lcdc_platform_data lcdc0_data;
-static struct resource lcdc0_resource[] = {
+static struct atmel_lcdfb_info atmel_lcdfb0_data;
+static struct resource atmel_lcdfb0_resource[] = {
 	{
 		.start		= 0xff000000,
 		.end		= 0xff000fff,
 		.flags		= IORESOURCE_MEM,
 	},
 	IRQ(1),
+	{
+		/* Placeholder for pre-allocated fb memory */
+		.start		= 0x00000000,
+		.end		= 0x00000000,
+		.flags		= 0,
+	},
 };
-DEFINE_DEV_DATA(lcdc, 0);
-DEV_CLK(hclk, lcdc0, hsb, 7);
-static struct clk lcdc0_pixclk = {
-	.name		= "pixclk",
-	.dev		= &lcdc0_device.dev,
+DEFINE_DEV_DATA(atmel_lcdfb, 0);
+DEV_CLK(hck1, atmel_lcdfb0, hsb, 7);
+static struct clk atmel_lcdfb0_pixclk = {
+	.name		= "lcdc_clk",
+	.dev		= &atmel_lcdfb0_device.dev,
 	.mode		= genclk_mode,
 	.get_rate	= genclk_get_rate,
 	.set_rate	= genclk_set_rate,
@@ -903,13 +912,34 @@ static struct clk lcdc0_pixclk = {
 };
 
 struct platform_device *__init
-at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
+at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
+		     unsigned long fbmem_start, unsigned long fbmem_len)
 {
 	struct platform_device *pdev;
+	struct atmel_lcdfb_info *info;
+	struct fb_monspecs *monspecs;
+	struct fb_videomode *modedb;
+	unsigned int modedb_size;
+
+	/*
+	 * Do a deep copy of the fb data, monspecs and modedb. Make
+	 * sure all allocations are done before setting up the
+	 * portmux.
+	 */
+	monspecs = kmemdup(data->default_monspecs,
+			   sizeof(struct fb_monspecs), GFP_KERNEL);
+	if (!monspecs)
+		return NULL;
+
+	modedb_size = sizeof(struct fb_videomode) * monspecs->modedb_len;
+	modedb = kmemdup(monspecs->modedb, modedb_size, GFP_KERNEL);
+	if (!modedb)
+		goto err_dup_modedb;
+	monspecs->modedb = modedb;
 
 	switch (id) {
 	case 0:
-		pdev = &lcdc0_device;
+		pdev = &atmel_lcdfb0_device;
 		select_peripheral(PC(19), PERIPH_A, 0);	/* CC	  */
 		select_peripheral(PC(20), PERIPH_A, 0);	/* HSYNC  */
 		select_peripheral(PC(21), PERIPH_A, 0);	/* PCLK	  */
@@ -942,19 +972,32 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
 		select_peripheral(PD(16), PERIPH_A, 0);	/* DATA22 */
 		select_peripheral(PD(17), PERIPH_A, 0);	/* DATA23 */
 
-		clk_set_parent(&lcdc0_pixclk, &pll0);
-		clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0));
+		clk_set_parent(&atmel_lcdfb0_pixclk, &pll0);
+		clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0));
 		break;
 
 	default:
-		return NULL;
+		goto err_invalid_id;
 	}
 
-	memcpy(pdev->dev.platform_data, data,
-	       sizeof(struct lcdc_platform_data));
+	if (fbmem_len) {
+		pdev->resource[2].start = fbmem_start;
+		pdev->resource[2].end = fbmem_start + fbmem_len - 1;
+		pdev->resource[2].flags = IORESOURCE_MEM;
+	}
+
+	info = pdev->dev.platform_data;
+	memcpy(info, data, sizeof(struct atmel_lcdfb_info));
+	info->default_monspecs = monspecs;
 
 	platform_device_register(pdev);
 	return pdev;
+
+err_invalid_id:
+	kfree(modedb);
+err_dup_modedb:
+	kfree(monspecs);
+	return NULL;
 }
 
 /* --------------------------------------------------------------------
@@ -1037,8 +1080,8 @@ struct clk *at32_clock_list[] = {
 	&macb1_pclk,
 	&atmel_spi0_spi_clk,
 	&atmel_spi1_spi_clk,
-	&lcdc0_hclk,
-	&lcdc0_pixclk,
+	&atmel_lcdfb0_hck1,
+	&atmel_lcdfb0_pixclk,
 	&gclk0,
 	&gclk1,
 	&gclk2,
@@ -1077,7 +1120,7 @@ void __init at32_clock_init(void)
 	genclk_init_parent(&gclk2);
 	genclk_init_parent(&gclk3);
 	genclk_init_parent(&gclk4);
-	genclk_init_parent(&lcdc0_pixclk);
+	genclk_init_parent(&atmel_lcdfb0_pixclk);
 
 	/*
 	 * Turn on all clocks that have at least one user already, and

+ 12 - 24
arch/avr32/mm/fault.c

@@ -12,41 +12,30 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/pagemap.h>
-
 #include <linux/kdebug.h>
+#include <linux/kprobes.h>
+
 #include <asm/mmu_context.h>
 #include <asm/sysreg.h>
 #include <asm/tlb.h>
 #include <asm/uaccess.h>
 
 #ifdef CONFIG_KPROBES
-ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
-
-/* Hook to register for page fault notifications */
-int register_page_fault_notifier(struct notifier_block *nb)
+static inline int notify_page_fault(struct pt_regs *regs, int trap)
 {
-	return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
-}
+	int ret = 0;
 
-int unregister_page_fault_notifier(struct notifier_block *nb)
-{
-	return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
-}
+	if (!user_mode(regs)) {
+		if (kprobe_running() && kprobe_fault_handler(regs, trap))
+			ret = 1;
+	}
 
-static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
-				    int trap, int sig)
-{
-	struct die_args args = {
-		.regs = regs,
-		.trapnr = trap,
-	};
-	return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
+	return ret;
 }
 #else
-static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
-				    int trap, int sig)
+static inline int notify_page_fault(struct pt_regs *regs, int trap)
 {
-	return NOTIFY_DONE;
+	return 0;
 }
 #endif
 
@@ -76,8 +65,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
 	long signr;
 	int code;
 
-	if (notify_page_fault(DIE_PAGE_FAULT, regs,
-			      ecr, SIGSEGV) == NOTIFY_STOP)
+	if (notify_page_fault(regs, ecr))
 		return;
 
 	address = sysreg_read(TLBEAR);

+ 1 - 1
arch/ia64/kernel/acpi.c

@@ -791,7 +791,7 @@ static __init int setup_additional_cpus(char *s)
 early_param("additional_cpus", setup_additional_cpus);
 
 /*
- * cpu_possible_map should be static, it cannot change as cpu's
+ * cpu_possible_map should be static, it cannot change as CPUs
  * are onlined, or offlined. The reason is per-cpu data-structures
  * are allocated by some modules at init time, and dont expect to
  * do this dynamically on cpu arrival/departure.

+ 16 - 8
arch/ia64/kernel/crash.c

@@ -156,24 +156,30 @@ kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data)
 	if (!kdump_on_init)
 		return NOTIFY_DONE;
 
-	if (val != DIE_INIT_MONARCH_ENTER &&
-	    val != DIE_INIT_SLAVE_ENTER &&
+	if (val != DIE_INIT_MONARCH_LEAVE &&
+	    val != DIE_INIT_SLAVE_LEAVE &&
+	    val != DIE_INIT_MONARCH_PROCESS &&
 	    val != DIE_MCA_RENDZVOUS_LEAVE &&
 	    val != DIE_MCA_MONARCH_LEAVE)
 		return NOTIFY_DONE;
 
 	nd = (struct ia64_mca_notify_die *)args->err;
-	/* Reason code 1 means machine check rendezous*/
-	if ((val == DIE_INIT_MONARCH_ENTER || val == DIE_INIT_SLAVE_ENTER) &&
-		 nd->sos->rv_rc == 1)
+	/* Reason code 1 means machine check rendezvous*/
+	if ((val == DIE_INIT_MONARCH_LEAVE || val == DIE_INIT_SLAVE_LEAVE
+	    || val == DIE_INIT_MONARCH_PROCESS) && nd->sos->rv_rc == 1)
 		return NOTIFY_DONE;
 
 	switch (val) {
-		case DIE_INIT_MONARCH_ENTER:
+		case DIE_INIT_MONARCH_PROCESS:
+			atomic_set(&kdump_in_progress, 1);
+			*(nd->monarch_cpu) = -1;
+			break;
+		case DIE_INIT_MONARCH_LEAVE:
 			machine_kdump_on_init();
 			break;
-		case DIE_INIT_SLAVE_ENTER:
-			unw_init_running(kdump_cpu_freeze, NULL);
+		case DIE_INIT_SLAVE_LEAVE:
+			if (atomic_read(&kdump_in_progress))
+				unw_init_running(kdump_cpu_freeze, NULL);
 			break;
 		case DIE_MCA_RENDZVOUS_LEAVE:
 			if (atomic_read(&kdump_in_progress))
@@ -215,8 +221,10 @@ static ctl_table sys_table[] = {
 static int
 machine_crash_setup(void)
 {
+	/* be notified before default_monarch_init_process */
 	static struct notifier_block kdump_init_notifier_nb = {
 		.notifier_call = kdump_init_notifier,
+		.priority = 1,
 	};
 	int ret;
 	if((ret = register_die_notifier(&kdump_init_notifier_nb)) != 0)

+ 3 - 0
arch/ia64/kernel/entry.S

@@ -1585,5 +1585,8 @@ sys_call_table:
 	data8 sys_getcpu
 	data8 sys_epoll_pwait			// 1305
 	data8 sys_utimensat
+	data8 sys_signalfd
+	data8 sys_timerfd
+	data8 sys_eventfd
 
 	.org sys_call_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls

+ 3 - 3
arch/ia64/kernel/irq.c

@@ -4,7 +4,7 @@
  *	Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
  *
  * This file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
+ * asking for different IRQs should be done through these routines
  * instead of just grabbing them. Thus setups with different IRQ numbers
  * shouldn't result in any weird surprises, and installing new handlers
  * should be easier.
@@ -12,7 +12,7 @@
  * Copyright (C) Ashok Raj<ashok.raj@intel.com>, Intel Corporation 2004
  *
  * 4/14/2004: Added code to handle cpu migration and do safe irq
- *			migration without lossing interrupts for iosapic
+ *			migration without losing interrupts for iosapic
  *			architecture.
  */
 
@@ -190,7 +190,7 @@ void fixup_irqs(void)
 	}
 
 	/*
-	 * Phase 1: Locate irq's bound to this cpu and
+	 * Phase 1: Locate IRQs bound to this cpu and
 	 * relocate them for cpu removal.
 	 */
 	migrate_irqs();

+ 1 - 1
arch/ia64/kernel/irq_lsapic.c

@@ -23,7 +23,7 @@ lsapic_noop_startup (unsigned int irq)
 static void
 lsapic_noop (unsigned int irq)
 {
-	/* nuthing to do... */
+	/* nothing to do... */
 }
 
 static int lsapic_retrigger(unsigned int irq)

+ 4 - 11
arch/ia64/kernel/kprobes.c

@@ -151,12 +151,12 @@ static uint __kprobes is_cmp_ctype_unc_inst(uint template, uint slot,
 
 	cmp_inst.l = kprobe_inst;
 	if ((cmp_inst.f.x2 == 0) || (cmp_inst.f.x2 == 1)) {
-		/* Integere compare - Register Register (A6 type)*/
+		/* Integer compare - Register Register (A6 type)*/
 		if ((cmp_inst.f.tb == 0) && (cmp_inst.f.ta == 0)
 				&&(cmp_inst.f.c == 1))
 			ctype_unc = 1;
 	} else if ((cmp_inst.f.x2 == 2)||(cmp_inst.f.x2 == 3)) {
-		/* Integere compare - Immediate Register (A8 type)*/
+		/* Integer compare - Immediate Register (A8 type)*/
 		if ((cmp_inst.f.ta == 0) &&(cmp_inst.f.c == 1))
 			ctype_unc = 1;
 	}
@@ -820,7 +820,7 @@ out:
 	return 1;
 }
 
-static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
+int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
 {
 	struct kprobe *cur = kprobe_running();
 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -904,13 +904,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
 			if (post_kprobes_handler(args->regs))
 				ret = NOTIFY_STOP;
 		break;
-	case DIE_PAGE_FAULT:
-		/* kprobe_running() needs smp_processor_id() */
-		preempt_disable();
-		if (kprobe_running() &&
-			kprobes_fault_handler(args->regs, args->trapnr))
-			ret = NOTIFY_STOP;
-		preempt_enable();
 	default:
 		break;
 	}
@@ -954,7 +947,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 	/*
 	 * Callee owns the argument space and could overwrite it, eg
 	 * tail call optimization. So to be absolutely safe
-	 * we save the argument space before transfering the control
+	 * we save the argument space before transferring the control
 	 * to instrumented jprobe function which runs in
 	 * the process context
 	 */

+ 4 - 1
arch/ia64/kernel/mca.c

@@ -273,7 +273,6 @@ static void ia64_mlogbuf_finish(int wait)
 
 	mlogbuf_finished = 1;
 }
-EXPORT_SYMBOL(ia64_mlogbuf_finish);
 
 /*
  * Print buffered messages from INIT context.
@@ -1477,6 +1476,10 @@ default_monarch_init_process(struct notifier_block *self, unsigned long val, voi
 	struct task_struct *g, *t;
 	if (val != DIE_INIT_MONARCH_PROCESS)
 		return NOTIFY_DONE;
+#ifdef CONFIG_KEXEC
+	if (atomic_read(&kdump_in_progress))
+		return NOTIFY_DONE;
+#endif
 
 	/*
 	 * FIXME: mlogbuf will brim over with INIT stack dumps.

+ 2 - 2
arch/ia64/kernel/mca_drv.c

@@ -438,7 +438,7 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci,
  * @peidx:	pointer of index of processor error section
  *
  * Return value:
- *	target address on Success / 0 on Failue
+ *	target address on Success / 0 on Failure
  */
 static u64
 get_target_identifier(peidx_table_t *peidx)
@@ -701,7 +701,7 @@ recover_from_processor_error(int platform, slidx_table_t *slidx,
 		return fatal_mca("External bus check fatal status");
 
 	/*
-	 * This is a local MCA and estimated as a recoverble error.
+	 * This is a local MCA and estimated as a recoverable error.
 	 */
 	if (platform)
 		return recover_from_platform_error(slidx, peidx, pbci, sos);

+ 1 - 1
arch/ia64/kernel/module.c

@@ -861,7 +861,7 @@ apply_relocate (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 /*
  * Modules contain a single unwind table which covers both the core and the init text
  * sections but since the two are not contiguous, we need to split this table up such that
- * we can register (and unregister) each "segment" seperately.  Fortunately, this sounds
+ * we can register (and unregister) each "segment" separately.  Fortunately, this sounds
  * more complicated than it really is.
  */
 static void

+ 9 - 9
arch/ia64/kernel/perfmon.c

@@ -1318,7 +1318,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
 {
 	unsigned long flags;
 	/*
-	 * validy checks on cpu_mask have been done upstream
+	 * validity checks on cpu_mask have been done upstream
 	 */
 	LOCK_PFS(flags);
 
@@ -1384,7 +1384,7 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
 {
 	unsigned long flags;
 	/*
-	 * validy checks on cpu_mask have been done upstream
+	 * validity checks on cpu_mask have been done upstream
 	 */
 	LOCK_PFS(flags);
 
@@ -1835,7 +1835,7 @@ pfm_flush(struct file *filp, fl_owner_t id)
 	/*
 	 * remove our file from the async queue, if we use this mode.
 	 * This can be done without the context being protected. We come
-	 * here when the context has become unreacheable by other tasks.
+	 * here when the context has become unreachable by other tasks.
 	 *
 	 * We may still have active monitoring at this point and we may
 	 * end up in pfm_overflow_handler(). However, fasync_helper()
@@ -2132,7 +2132,7 @@ doit:
 	filp->private_data = NULL;
 
 	/*
-	 * if we free on the spot, the context is now completely unreacheable
+	 * if we free on the spot, the context is now completely unreachable
 	 * from the callers side. The monitored task side is also cut, so we
 	 * can freely cut.
 	 *
@@ -2562,7 +2562,7 @@ pfm_reset_pmu_state(pfm_context_t *ctx)
 	ctx->ctx_all_pmcs[0] = pmu_conf->impl_pmcs[0] & ~0x1;
 
 	/*
-	 * bitmask of all PMDs that are accesible to this context
+	 * bitmask of all PMDs that are accessible to this context
 	 */
 	ctx->ctx_all_pmds[0] = pmu_conf->impl_pmds[0];
 
@@ -3395,7 +3395,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 		if (unlikely(!PMD_IS_IMPL(cnum))) goto error;
 		/*
 		 * we can only read the register that we use. That includes
-		 * the one we explicitely initialize AND the one we want included
+		 * the one we explicitly initialize AND the one we want included
 		 * in the sampling buffer (smpl_regs).
 		 *
 		 * Having this restriction allows optimization in the ctxsw routine
@@ -3715,7 +3715,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 	 * if non-blocking, then we ensure that the task will go into
 	 * pfm_handle_work() before returning to user mode.
 	 *
-	 * We cannot explicitely reset another task, it MUST always
+	 * We cannot explicitly reset another task, it MUST always
 	 * be done by the task itself. This works for system wide because
 	 * the tool that is controlling the session is logically doing 
 	 * "self-monitoring".
@@ -4644,7 +4644,7 @@ pfm_exit_thread(struct task_struct *task)
 	switch(state) {
 		case PFM_CTX_UNLOADED:
 			/*
-	 		 * only comes to thios function if pfm_context is not NULL, i.e., cannot
+	 		 * only comes to this function if pfm_context is not NULL, i.e., cannot
 			 * be in unloaded state
 	 		 */
 			printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task->pid);
@@ -5247,7 +5247,7 @@ pfm_end_notify_user(pfm_context_t *ctx)
 
 /*
  * main overflow processing routine.
- * it can be called from the interrupt path or explicitely during the context switch code
+ * it can be called from the interrupt path or explicitly during the context switch code
  */
 static void
 pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, struct pt_regs *regs)

+ 1 - 1
arch/ia64/kernel/perfmon_mckinley.h

@@ -181,7 +181,7 @@ static pmu_config_t pmu_conf_mck={
 	.pmc_desc      = pfm_mck_pmc_desc,
 	.num_ibrs       = 8,
 	.num_dbrs       = 8,
-	.use_rr_dbregs = 1 /* debug register are use for range retrictions */
+	.use_rr_dbregs = 1 /* debug register are use for range restrictions */
 };
 
 

+ 1 - 1
arch/ia64/kernel/sal.c

@@ -134,7 +134,7 @@ set_smp_redirect (int flag)
 	 * interrupt redirection. The reason is this would require that
 	 * All interrupts be stopped and hard bind the irq to a cpu.
 	 * Later when the interrupt is fired we need to set the redir hint
-	 * on again in the vector. This is combersome for something that the
+	 * on again in the vector. This is cumbersome for something that the
 	 * user mode irq balancer will solve anyways.
 	 */
 	no_int_routing=1;

+ 1 - 1
arch/ia64/kernel/salinfo.c

@@ -162,7 +162,7 @@ static DEFINE_SPINLOCK(data_saved_lock);
 /** salinfo_platform_oemdata - optional callback to decode oemdata from an error
  * record.
  * @sect_header: pointer to the start of the section to decode.
- * @oemdata: returns vmalloc area containing the decded output.
+ * @oemdata: returns vmalloc area containing the decoded output.
  * @oemdata_size: returns length of decoded output (strlen).
  *
  * Description: If user space asks for oem data to be decoded by the kernel

+ 3 - 3
arch/ia64/kernel/setup.c

@@ -576,7 +576,7 @@ setup_arch (char **cmdline_p)
 }
 
 /*
- * Display cpu info for all cpu's.
+ * Display cpu info for all CPUs.
  */
 static int
 show_cpuinfo (struct seq_file *m, void *v)
@@ -761,7 +761,7 @@ identify_cpu (struct cpuinfo_ia64 *c)
 	c->cpu = smp_processor_id();
 
 	/* below default values will be overwritten  by identify_siblings() 
-	 * for Multi-Threading/Multi-Core capable cpu's
+	 * for Multi-Threading/Multi-Core capable CPUs
 	 */
 	c->threads_per_core = c->cores_per_socket = c->num_log = 1;
 	c->socket_id = -1;
@@ -947,7 +947,7 @@ cpu_init (void)
 	ia32_cpu_init();
 #endif
 
-	/* Clear ITC to eliminiate sched_clock() overflows in human time.  */
+	/* Clear ITC to eliminate sched_clock() overflows in human time.  */
 	ia64_set_itc(0);
 
 	/* disable all local interrupt sources: */

+ 6 - 6
arch/ia64/kernel/smp.c

@@ -186,7 +186,7 @@ handle_IPI (int irq, void *dev_id)
 }
 
 /*
- * Called with preeemption disabled.
+ * Called with preemption disabled.
  */
 static inline void
 send_IPI_single (int dest_cpu, int op)
@@ -196,7 +196,7 @@ send_IPI_single (int dest_cpu, int op)
 }
 
 /*
- * Called with preeemption disabled.
+ * Called with preemption disabled.
  */
 static inline void
 send_IPI_allbutself (int op)
@@ -210,7 +210,7 @@ send_IPI_allbutself (int op)
 }
 
 /*
- * Called with preeemption disabled.
+ * Called with preemption disabled.
  */
 static inline void
 send_IPI_all (int op)
@@ -223,7 +223,7 @@ send_IPI_all (int op)
 }
 
 /*
- * Called with preeemption disabled.
+ * Called with preemption disabled.
  */
 static inline void
 send_IPI_self (int op)
@@ -252,7 +252,7 @@ kdump_smp_send_init(void)
 }
 #endif
 /*
- * Called with preeemption disabled.
+ * Called with preemption disabled.
  */
 void
 smp_send_reschedule (int cpu)
@@ -261,7 +261,7 @@ smp_send_reschedule (int cpu)
 }
 
 /*
- * Called with preeemption disabled.
+ * Called with preemption disabled.
  */
 static void
 smp_send_local_flush_tlb (int cpu)

+ 3 - 3
arch/ia64/kernel/smpboot.c

@@ -694,7 +694,7 @@ int migrate_platform_irqs(unsigned int cpu)
 			set_cpei_target_cpu(new_cpei_cpu);
 			desc = irq_desc + ia64_cpe_irq;
 			/*
-			 * Switch for now, immediatly, we need to do fake intr
+			 * Switch for now, immediately, we need to do fake intr
 			 * as other interrupts, but need to study CPEI behaviour with
 			 * polling before making changes.
 			 */
@@ -840,7 +840,7 @@ __cpu_up (unsigned int cpu)
 }
 
 /*
- * Assume that CPU's have been discovered by some platform-dependent interface.  For
+ * Assume that CPUs have been discovered by some platform-dependent interface.  For
  * SoftSDV/Lion, that would be ACPI.
  *
  * Setup of the IPI irq handler is done in irq.c:init_IRQ_SMP().
@@ -854,7 +854,7 @@ init_smp_config(void)
 	} *ap_startup;
 	long sal_ret;
 
-	/* Tell SAL where to drop the AP's.  */
+	/* Tell SAL where to drop the APs.  */
 	ap_startup = (struct fptr *) start_ap;
 	sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
 				       ia64_tpa(ap_startup->fp), ia64_tpa(ap_startup->gp), 0, 0, 0, 0);

+ 1 - 1
arch/ia64/kernel/traps.c

@@ -304,7 +304,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
 			 * Lower 4 bits are used as a count. Upper bits are a sequence
 			 * number that is updated when count is reset. The cmpxchg will
 			 * fail is seqno has changed. This minimizes mutiple cpus
-			 * reseting the count.
+			 * resetting the count.
 			 */
 			if (current_jiffies > last.time)
 				(void) cmpxchg_acq(&last.count, count, 16 + (count & ~15));

+ 1 - 1
arch/ia64/kernel/unwind.c

@@ -2,7 +2,7 @@
  * Copyright (C) 1999-2004 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 2003 Fenghua Yu <fenghua.yu@intel.com>
- * 	- Change pt_regs_off() to make it less dependant on pt_regs structure.
+ * 	- Change pt_regs_off() to make it less dependent on pt_regs structure.
  */
 /*
  * This file implements call frame unwind support for the Linux

+ 1 - 1
arch/ia64/mm/discontig.c

@@ -317,7 +317,7 @@ static void __meminit scatter_node_data(void)
 	 * node_online_map is not set for hot-added nodes at this time,
 	 * because we are halfway through initialization of the new node's
 	 * structures.  If for_each_online_node() is used, a new node's
-	 * pg_data_ptrs will be not initialized. Insted of using it,
+	 * pg_data_ptrs will be not initialized. Instead of using it,
 	 * pgdat_list[] is checked.
 	 */
 	for_each_node(node) {

+ 14 - 27
arch/ia64/mm/fault.c

@@ -19,36 +19,24 @@
 extern void die (char *, struct pt_regs *, long);
 
 #ifdef CONFIG_KPROBES
-ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
-
-/* Hook to register for page fault notifications */
-int register_page_fault_notifier(struct notifier_block *nb)
-{
-	return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
-}
-
-int unregister_page_fault_notifier(struct notifier_block *nb)
+static inline int notify_page_fault(struct pt_regs *regs, int trap)
 {
-	return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
-}
+	int ret = 0;
+
+	if (!user_mode(regs)) {
+		/* kprobe_running() needs smp_processor_id() */
+		preempt_disable();
+		if (kprobe_running() && kprobes_fault_handler(regs, trap))
+			ret = 1;
+		preempt_enable();
+	}
 
-static inline int notify_page_fault(enum die_val val, const char *str,
-			struct pt_regs *regs, long err, int trap, int sig)
-{
-	struct die_args args = {
-		.regs = regs,
-		.str = str,
-		.err = err,
-		.trapnr = trap,
-		.signr = sig
-	};
-	return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
+	return ret;
 }
 #else
-static inline int notify_page_fault(enum die_val val, const char *str,
-			struct pt_regs *regs, long err, int trap, int sig)
+static inline int notify_page_fault(struct pt_regs *regs, int trap)
 {
-	return NOTIFY_DONE;
+	return 0;
 }
 #endif
 
@@ -117,8 +105,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
 	/*
 	 * This is to handle the kprobes on user space access instructions
 	 */
-	if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, code, TRAP_BRKPT,
-					SIGSEGV) == NOTIFY_STOP)
+	if (notify_page_fault(regs, TRAP_BRKPT))
 		return;
 
 	down_read(&mm->mmap_sem);

+ 6 - 6
arch/ia64/sn/kernel/bte.c

@@ -63,7 +63,7 @@ static inline void bte_start_transfer(struct bteinfo_s *bte, u64 len, u64 mode)
  * Use the block transfer engine to move kernel memory from src to dest
  * using the assigned mode.
  *
- * Paramaters:
+ * Parameters:
  *   src - physical address of the transfer source.
  *   dest - physical address of the transfer destination.
  *   len - number of bytes to transfer from source to dest.
@@ -247,7 +247,7 @@ EXPORT_SYMBOL(bte_copy);
  * use the block transfer engine to move kernel
  * memory from src to dest using the assigned mode.
  *
- * Paramaters:
+ * Parameters:
  *   src - physical address of the transfer source.
  *   dest - physical address of the transfer destination.
  *   len - number of bytes to transfer from source to dest.
@@ -255,7 +255,7 @@ EXPORT_SYMBOL(bte_copy);
  *          for IBCT0/1 in the SGI documentation.
  *
  * NOTE: If the source, dest, and len are all cache line aligned,
- * then it would be _FAR_ preferrable to use bte_copy instead.
+ * then it would be _FAR_ preferable to use bte_copy instead.
  */
 bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
 {
@@ -300,7 +300,7 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
 	 * a standard bte copy.
 	 *
 	 * One nasty exception to the above rule is when the
-	 * source and destination are not symetrically
+	 * source and destination are not symmetrically
 	 * mis-aligned.  If the source offset from the first
 	 * cache line is different from the destination offset,
 	 * we make the first section be the entire transfer
@@ -337,7 +337,7 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
 
 			if (footBcopyDest == (headBcopyDest + headBcopyLen)) {
 				/*
-				 * We have two contigous bcopy
+				 * We have two contiguous bcopy
 				 * blocks.  Merge them.
 				 */
 				headBcopyLen += footBcopyLen;
@@ -375,7 +375,7 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
 	} else {
 
 		/*
-		 * The transfer is not symetric, we will
+		 * The transfer is not symmetric, we will
 		 * allocate a buffer large enough for all the
 		 * data, bte_copy into that buffer and then
 		 * bcopy to the destination.

+ 2 - 2
arch/ia64/sn/kernel/bte_error.c

@@ -105,7 +105,7 @@ int shub1_bte_error_handler(unsigned long _nodepda)
 	}
 
 	BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda, smp_processor_id()));
-	/* Reenable both bte interfaces */
+	/* Re-enable both bte interfaces */
 	imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM);
 	imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1;
 	REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval);
@@ -243,7 +243,7 @@ bte_crb_error_handler(cnodeid_t cnode, int btenum,
 
 	/*
 	 * The caller has already figured out the error type, we save that
-	 * in the bte handle structure for the thread excercising the
+	 * in the bte handle structure for the thread exercising the
 	 * interface to consume.
 	 */
 	bte->bh_error = ioe->ie_errortype + BTEFAIL_OFFSET;

+ 1 - 1
arch/ia64/sn/kernel/io_common.c

@@ -479,7 +479,7 @@ sn_io_early_init(void)
 	}
 
 	/*
-	 * prime sn_pci_provider[].  Individial provider init routines will
+	 * prime sn_pci_provider[].  Individual provider init routines will
 	 * override their respective default entries.
 	 */
 

+ 1 - 1
arch/ia64/sn/kernel/setup.c

@@ -167,7 +167,7 @@ void __init early_sn_setup(void)
 	 * IO on SN2 is done via SAL calls, early_printk won't work without this.
 	 *
 	 * This code duplicates some of the ACPI table parsing that is in efi.c & sal.c.
-	 * Any changes to those file may have to be made hereas well.
+	 * Any changes to those file may have to be made here as well.
 	 */
 	efi_systab = (efi_system_table_t *) __va(ia64_boot_param->efi_systab);
 	config_tables = __va(efi_systab->tables);

+ 1 - 1
arch/ia64/sn/kernel/sn2/sn2_smp.c

@@ -104,7 +104,7 @@ static inline unsigned long wait_piowc(void)
  *
  * SN2 PIO writes from separate CPUs are not guaranteed to arrive in order.
  * Context switching user threads which have memory-mapped MMIO may cause
- * PIOs to issue from seperate CPUs, thus the PIO writes must be drained
+ * PIOs to issue from separate CPUs, thus the PIO writes must be drained
  * from the previous CPU's Shub before execution resumes on the new CPU.
  */
 void sn_migrate(struct task_struct *task)

+ 4 - 4
arch/ia64/sn/kernel/xpc_channel.c

@@ -293,7 +293,7 @@ xpc_pull_remote_cachelines(struct xpc_partition *part, void *dst,
 
 
 /*
- * Pull the remote per partititon specific variables from the specified
+ * Pull the remote per partition specific variables from the specified
  * partition.
  */
 enum xpc_retval
@@ -461,7 +461,7 @@ xpc_allocate_local_msgqueue(struct xpc_channel *ch)
 	// >>> may want to check for ch->flags & XPC_C_DISCONNECTING between
 	// >>> iterations of the for-loop, bail if set?
 
-	// >>> should we impose a minumum #of entries? like 4 or 8?
+	// >>> should we impose a minimum #of entries? like 4 or 8?
 	for (nentries = ch->local_nentries; nentries > 0; nentries--) {
 
 		nbytes = nentries * ch->msg_size;
@@ -514,7 +514,7 @@ xpc_allocate_remote_msgqueue(struct xpc_channel *ch)
 	// >>> may want to check for ch->flags & XPC_C_DISCONNECTING between
 	// >>> iterations of the for-loop, bail if set?
 
-	// >>> should we impose a minumum #of entries? like 4 or 8?
+	// >>> should we impose a minimum #of entries? like 4 or 8?
 	for (nentries = ch->remote_nentries; nentries > 0; nentries--) {
 
 		nbytes = nentries * ch->msg_size;
@@ -1478,7 +1478,7 @@ xpc_teardown_infrastructure(struct xpc_partition *part)
 
 
 	/*
-	 * Before proceding with the teardown we have to wait until all
+	 * Before proceeding with the teardown we have to wait until all
 	 * existing references cease.
 	 */
 	wait_event(part->teardown_wq, (atomic_read(&part->references) == 0));

+ 1 - 1
arch/ia64/sn/kernel/xpnet.c

@@ -531,7 +531,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev_dbg(xpnet, "destination Partitions mask (dp) = 0x%lx\n", dp);
 
 	/*
-	 * If we wanted to allow promiscous mode to work like an
+	 * If we wanted to allow promiscuous mode to work like an
 	 * unswitched network, this would be a good point to OR in a
 	 * mask of partitions which should be receiving all packets.
 	 */

+ 4 - 4
arch/ia64/sn/pci/pci_dma.c

@@ -333,7 +333,7 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
 	/*
 	 * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
 	 * around hw issues at the pci bus level.  SGI proms older than
-	 * 4.10 don't implment this.
+	 * 4.10 don't implement this.
 	 */
 
 	SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
@@ -348,7 +348,7 @@ int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
 	/*
 	 * If the above failed, retry using the SAL_PROBE call which should
 	 * be present in all proms (but which cannot work round PCI chipset
-	 * bugs).  This code is retained for compatability with old
+	 * bugs).  This code is retained for compatibility with old
 	 * pre-4.10 proms, and should be removed at some point in the future.
 	 */
 
@@ -379,7 +379,7 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
 	/*
 	 * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
 	 * around hw issues at the pci bus level.  SGI proms older than
-	 * 4.10 don't implment this.
+	 * 4.10 don't implement this.
 	 */
 
 	SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
@@ -394,7 +394,7 @@ int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
 	/*
 	 * If the above failed, retry using the SAL_PROBE call which should
 	 * be present in all proms (but which cannot work round PCI chipset
-	 * bugs).  This code is retained for compatability with old
+	 * bugs).  This code is retained for compatibility with old
 	 * pre-4.10 proms, and should be removed at some point in the future.
 	 */
 

+ 3 - 3
arch/ia64/sn/pci/pcibr/pcibr_ate.c

@@ -30,7 +30,7 @@ static void mark_ate(struct ate_resource *ate_resource, int start, int number,
 
 /*
  * find_free_ate:  Find the first free ate index starting from the given
- *		   index for the desired consequtive count.
+ *		   index for the desired consecutive count.
  */
 static int find_free_ate(struct ate_resource *ate_resource, int start,
 			 int count)
@@ -88,7 +88,7 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource,
 		return -1;
 
 	/*
-	 * Find the required number of free consequtive ates.
+	 * Find the required number of free consecutive ates.
 	 */
 	start_index =
 	    find_free_ate(ate_resource, ate_resource->lowest_free_index,
@@ -105,7 +105,7 @@ static inline int alloc_ate_resource(struct ate_resource *ate_resource,
 /*
  * Allocate "count" contiguous Bridge Address Translation Entries
  * on the specified bridge to be used for PCI to XTALK mappings.
- * Indices in rm map range from 1..num_entries.  Indicies returned
+ * Indices in rm map range from 1..num_entries.  Indices returned
  * to caller range from 0..num_entries-1.
  *
  * Return the start index on success, -1 on failure.

+ 1 - 1
arch/ia64/sn/pci/pcibr/pcibr_dma.c

@@ -201,7 +201,7 @@ pcibr_dmatrans_direct32(struct pcidev_info * info,
 }
 
 /*
- * Wrapper routine for free'ing DMA maps
+ * Wrapper routine for freeing DMA maps
  * DMA mappings for Direct 64 and 32 do not have any DMA maps.
  */
 void

+ 3 - 3
arch/ia64/sn/pci/tioca_provider.c

@@ -223,7 +223,7 @@ tioca_fastwrite_enable(struct tioca_kernel *tioca_kern)
 
 	/*
 	 * Scan all vga controllers on this bus making sure they all
-	 * suport FW.  If not, return.
+	 * support FW.  If not, return.
 	 */
 
 	list_for_each_entry(pdev, tioca_kern->ca_devices, bus_list) {
@@ -364,7 +364,7 @@ tioca_dma_d48(struct pci_dev *pdev, u64 paddr)
  * @req_size: len (bytes) to map
  *
  * Map @paddr into CA address space using the GART mechanism.  The mapped
- * dma_addr_t is guarenteed to be contiguous in CA bus space.
+ * dma_addr_t is guaranteed to be contiguous in CA bus space.
  */
 static dma_addr_t
 tioca_dma_mapped(struct pci_dev *pdev, u64 paddr, size_t req_size)
@@ -526,7 +526,7 @@ tioca_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count, int dma_flags)
 		return 0;
 
 	/*
-	 * If card is 64 or 48 bit addresable, use a direct mapping.  32
+	 * If card is 64 or 48 bit addressable, use a direct mapping.  32
 	 * bit direct is so restrictive w.r.t. where the memory resides that
 	 * we don't use it even though CA has some support.
 	 */

+ 8 - 8
arch/ia64/sn/pci/tioce_provider.c

@@ -256,9 +256,9 @@ pcidev_to_tioce(struct pci_dev *pdev, struct tioce __iomem **base,
  * @ct_addr: the coretalk address to map
  * @len: number of bytes to map
  *
- * Given the addressing type, set up various paramaters that define the
+ * Given the addressing type, set up various parameters that define the
  * ATE pool to use.  Search for a contiguous block of entries to cover the
- * length, and if enough resources exist, fill in the ATE's and construct a
+ * length, and if enough resources exist, fill in the ATEs and construct a
  * tioce_dmamap struct to track the mapping.
  */
 static u64
@@ -581,8 +581,8 @@ tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
 	 */
 	if (!mapaddr && !barrier && dma_mask >= 0xffffffffffUL) {
 		/*
-		 * We have two options for 40-bit mappings:  16GB "super" ATE's
-		 * and 64MB "regular" ATE's.  We'll try both if needed for a
+		 * We have two options for 40-bit mappings:  16GB "super" ATEs
+		 * and 64MB "regular" ATEs.  We'll try both if needed for a
 		 * given mapping but which one we try first depends on the
 		 * size.  For requests >64MB, prefer to use a super page with
 		 * regular as the fallback. Otherwise, try in the reverse order.
@@ -687,8 +687,8 @@ tioce_error_intr_handler(int irq, void *arg)
 }
 
 /**
- * tioce_reserve_m32 - reserve M32 ate's for the indicated address range
- * @tioce_kernel: TIOCE context to reserve ate's for
+ * tioce_reserve_m32 - reserve M32 ATEs for the indicated address range
+ * @tioce_kernel: TIOCE context to reserve ATEs for
  * @base: starting bus address to reserve
  * @limit: last bus address to reserve
  *
@@ -763,7 +763,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
 
 	/*
 	 * Set PMU pagesize to the largest size available, and zero out
-	 * the ate's.
+	 * the ATEs.
 	 */
 
 	tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base;
@@ -784,7 +784,7 @@ tioce_kern_init(struct tioce_common *tioce_common)
 	}
 
 	/*
-	 * Reserve ATE's corresponding to reserved address ranges.  These
+	 * Reserve ATEs corresponding to reserved address ranges.  These
 	 * include:
 	 *
 	 *	Memory space covered by each PPB mem base/limit register

+ 1 - 1
arch/sparc64/kernel/Makefile

@@ -12,7 +12,7 @@ obj-y		:= process.o setup.o cpu.o idprom.o \
 		   irq.o ptrace.o time.o sys_sparc.o signal.o \
 		   unaligned.o central.o pci.o starfire.o semaphore.o \
 		   power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
-		   visemul.o prom.o of_device.o
+		   visemul.o prom.o of_device.o hvapi.o
 
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-$(CONFIG_PCI)	 += ebus.o isa.o pci_common.o pci_iommu.o \

+ 94 - 0
arch/sparc64/kernel/entry.S

@@ -1843,3 +1843,97 @@ sun4v_cpu_state:
 	mov	%o1, %o0
 1:	retl
 	 nop
+
+	/* %o0:	API group number
+	 * %o1: pointer to unsigned long major number storage
+	 * %o2: pointer to unsigned long minor number storage
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_get_version
+sun4v_get_version:
+	mov	HV_CORE_GET_VER, %o5
+	mov	%o1, %o3
+	mov	%o2, %o4
+	ta	HV_CORE_TRAP
+	stx	%o1, [%o3]
+	retl
+	 stx	%o2, [%o4]
+
+	/* %o0: API group number
+	 * %o1: desired major number
+	 * %o2: desired minor number
+	 * %o3: pointer to unsigned long actual minor number storage
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_set_version
+sun4v_set_version:
+	mov	HV_CORE_SET_VER, %o5
+	mov	%o3, %o4
+	ta	HV_CORE_TRAP
+	retl
+	 stx	%o1, [%o4]
+
+	/* %o0: pointer to unsigned long status
+	 *
+	 * returns %o0: signed character
+	 */
+	.globl	sun4v_con_getchar
+sun4v_con_getchar:
+	mov	%o0, %o4
+	mov	HV_FAST_CONS_GETCHAR, %o5
+	clr	%o0
+	clr	%o1
+	ta	HV_FAST_TRAP
+	stx	%o0, [%o4]
+	retl
+	 sra	%o1, 0, %o0
+
+	/* %o0: signed long character
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_con_putchar
+sun4v_con_putchar:
+	mov	HV_FAST_CONS_PUTCHAR, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 sra	%o0, 0, %o0
+
+	/* %o0: buffer real address
+	 * %o1: buffer size
+	 * %o2: pointer to unsigned long bytes_read
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_con_read
+sun4v_con_read:
+	mov	%o2, %o4
+	mov	HV_FAST_CONS_READ, %o5
+	ta	HV_FAST_TRAP
+	brnz	%o0, 1f
+	 cmp	%o1, -1		/* break */
+	be,a,pn	%icc, 1f
+	 mov	%o1, %o0
+	cmp	%o1, -2		/* hup */
+	be,a,pn	%icc, 1f
+	 mov	%o1, %o0
+	stx	%o1, [%o4]
+1:	retl
+	 nop
+
+	/* %o0: buffer real address
+	 * %o1: buffer size
+	 * %o2: pointer to unsigned long bytes_written
+	 *
+	 * returns %o0: status
+	 */
+	.globl	sun4v_con_write
+sun4v_con_write:
+	mov	%o2, %o4
+	mov	HV_FAST_CONS_WRITE, %o5
+	ta	HV_FAST_TRAP
+	stx	%o1, [%o4]
+	retl
+	 nop

+ 189 - 0
arch/sparc64/kernel/hvapi.c

@@ -0,0 +1,189 @@
+/* hvapi.c: Hypervisor API management.
+ *
+ * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+
+#include <asm/hypervisor.h>
+#include <asm/oplib.h>
+
+/* If the hypervisor indicates that the API setting
+ * calls are unsupported, by returning HV_EBADTRAP or
+ * HV_ENOTSUPPORTED, we assume that API groups with the
+ * PRE_API flag set are major 1 minor 0.
+ */
+struct api_info {
+	unsigned long group;
+	unsigned long major;
+	unsigned long minor;
+	unsigned int refcnt;
+	unsigned int flags;
+#define FLAG_PRE_API		0x00000001
+};
+
+static struct api_info api_table[] = {
+	{ .group = HV_GRP_SUN4V,	.flags = FLAG_PRE_API	},
+	{ .group = HV_GRP_CORE,		.flags = FLAG_PRE_API	},
+	{ .group = HV_GRP_INTR,					},
+	{ .group = HV_GRP_SOFT_STATE,				},
+	{ .group = HV_GRP_PCI,		.flags = FLAG_PRE_API	},
+	{ .group = HV_GRP_LDOM,					},
+	{ .group = HV_GRP_SVC_CHAN,	.flags = FLAG_PRE_API	},
+	{ .group = HV_GRP_NCS,		.flags = FLAG_PRE_API	},
+	{ .group = HV_GRP_NIAG_PERF,	.flags = FLAG_PRE_API	},
+	{ .group = HV_GRP_FIRE_PERF,				},
+	{ .group = HV_GRP_DIAG,		.flags = FLAG_PRE_API	},
+};
+
+static DEFINE_SPINLOCK(hvapi_lock);
+
+static struct api_info *__get_info(unsigned long group)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(api_table); i++) {
+		if (api_table[i].group == group)
+			return &api_table[i];
+	}
+	return NULL;
+}
+
+static void __get_ref(struct api_info *p)
+{
+	p->refcnt++;
+}
+
+static void __put_ref(struct api_info *p)
+{
+	if (--p->refcnt == 0) {
+		unsigned long ignore;
+
+		sun4v_set_version(p->group, 0, 0, &ignore);
+		p->major = p->minor = 0;
+	}
+}
+
+/* Register a hypervisor API specification.  It indicates the
+ * API group and desired major+minor.
+ *
+ * If an existing API registration exists '0' (success) will
+ * be returned if it is compatible with the one being registered.
+ * Otherwise a negative error code will be returned.
+ *
+ * Otherwise an attempt will be made to negotiate the requested
+ * API group/major/minor with the hypervisor, and errors returned
+ * if that does not succeed.
+ */
+int sun4v_hvapi_register(unsigned long group, unsigned long major,
+			 unsigned long *minor)
+{
+	struct api_info *p;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&hvapi_lock, flags);
+	p = __get_info(group);
+	ret = -EINVAL;
+	if (p) {
+		if (p->refcnt) {
+			ret = -EINVAL;
+			if (p->major == major) {
+				*minor = p->minor;
+				ret = 0;
+			}
+		} else {
+			unsigned long actual_minor;
+			unsigned long hv_ret;
+
+			hv_ret = sun4v_set_version(group, major, *minor,
+						   &actual_minor);
+			ret = -EINVAL;
+			if (hv_ret == HV_EOK) {
+				*minor = actual_minor;
+				p->major = major;
+				p->minor = actual_minor;
+				ret = 0;
+			} else if (hv_ret == HV_EBADTRAP ||
+				   HV_ENOTSUPPORTED) {
+				if (p->flags & FLAG_PRE_API) {
+					if (major == 1) {
+						p->major = 1;
+						p->minor = 0;
+						*minor = 0;
+						ret = 0;
+					}
+				}
+			}
+		}
+
+		if (ret == 0)
+			__get_ref(p);
+	}
+	spin_unlock_irqrestore(&hvapi_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(sun4v_hvapi_register);
+
+void sun4v_hvapi_unregister(unsigned long group)
+{
+	struct api_info *p;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hvapi_lock, flags);
+	p = __get_info(group);
+	if (p)
+		__put_ref(p);
+	spin_unlock_irqrestore(&hvapi_lock, flags);
+}
+EXPORT_SYMBOL(sun4v_hvapi_unregister);
+
+int sun4v_hvapi_get(unsigned long group,
+		    unsigned long *major,
+		    unsigned long *minor)
+{
+	struct api_info *p;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&hvapi_lock, flags);
+	ret = -EINVAL;
+	p = __get_info(group);
+	if (p && p->refcnt) {
+		*major = p->major;
+		*minor = p->minor;
+		ret = 0;
+	}
+	spin_unlock_irqrestore(&hvapi_lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(sun4v_hvapi_get);
+
+void __init sun4v_hvapi_init(void)
+{
+	unsigned long group, major, minor;
+
+	group = HV_GRP_SUN4V;
+	major = 1;
+	minor = 0;
+	if (sun4v_hvapi_register(group, major, &minor))
+		goto bad;
+
+	group = HV_GRP_CORE;
+	major = 1;
+	minor = 1;
+	if (sun4v_hvapi_register(group, major, &minor))
+		goto bad;
+
+	return;
+
+bad:
+	prom_printf("HVAPI: Cannot register API group "
+		    "%lx with major(%u) minor(%u)\n",
+		    group, major, minor);
+	prom_halt();
+}

+ 3 - 0
arch/sparc64/kernel/setup.c

@@ -269,6 +269,7 @@ void __init per_cpu_patch(void)
 
 void __init sun4v_patch(void)
 {
+	extern void sun4v_hvapi_init(void);
 	struct sun4v_1insn_patch_entry *p1;
 	struct sun4v_2insn_patch_entry *p2;
 
@@ -300,6 +301,8 @@ void __init sun4v_patch(void)
 
 		p2++;
 	}
+
+	sun4v_hvapi_init();
 }
 
 #ifdef CONFIG_SMP

+ 2 - 1
drivers/ata/ahci.c

@@ -173,7 +173,8 @@ enum {
 
 	AHCI_FLAG_COMMON		= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 					  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-					  ATA_FLAG_SKIP_D2H_BSY,
+					  ATA_FLAG_SKIP_D2H_BSY |
+					  ATA_FLAG_ACPI_SATA,
 };
 
 struct ahci_cmd_hdr {

+ 5 - 5
drivers/ata/libata-acpi.c

@@ -321,7 +321,7 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
 
 	/* Don't continue if device has no _ADR method.
 	 * _GTF is intended for known motherboard devices. */
-	if (!(ap->cbl == ATA_CBL_SATA)) {
+	if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
 		err = pata_get_dev_handle(gdev, &dev_handle, &pcidevfn);
 		if (err < 0) {
 			if (ata_msg_probe(ap))
@@ -343,7 +343,7 @@ static int do_drive_get_GTF(struct ata_device *dev, unsigned int *gtf_length,
 
 	/* Get this drive's _ADR info. if not already known. */
 	if (!dev->obj_handle) {
-		if (!(ap->cbl == ATA_CBL_SATA)) {
+		if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
 			/* get child objects of dev_handle == channel objects,
 	 		 * + _their_ children == drive objects */
 			/* channel is ap->port_no */
@@ -528,7 +528,7 @@ static int do_drive_set_taskfiles(struct ata_device *dev,
 		ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER: port#: %d\n",
 			       __FUNCTION__, ap->port_no);
 
-	if (libata_noacpi || !(ap->cbl == ATA_CBL_SATA))
+	if (libata_noacpi || !(ap->flags & ATA_FLAG_ACPI_SATA))
 		return 0;
 
 	if (!ata_dev_enabled(dev) || (ap->flags & ATA_FLAG_DISABLED))
@@ -578,7 +578,7 @@ int ata_acpi_exec_tfs(struct ata_port *ap)
 	 * we should not run GTF on PATA devices since some
 	 * PATA require execution of GTM/STM before GTF.
 	 */
-	if (!(ap->cbl == ATA_CBL_SATA))
+	if (!(ap->flags & ATA_FLAG_ACPI_SATA))
 		return 0;
 
 	for (ix = 0; ix < ATA_MAX_DEVICES; ix++) {
@@ -641,7 +641,7 @@ int ata_acpi_push_id(struct ata_device *dev)
 			       __FUNCTION__, dev->devno, ap->port_no);
 
 	/* Don't continue if not a SATA device. */
-	if (!(ap->cbl == ATA_CBL_SATA)) {
+	if (!(ap->flags & ATA_FLAG_ACPI_SATA)) {
 		if (ata_msg_probe(ap))
 			ata_dev_printk(dev, KERN_DEBUG,
 				"%s: Not a SATA device\n", __FUNCTION__);

+ 49 - 31
drivers/ata/libata-core.c

@@ -1919,7 +1919,6 @@ int ata_dev_configure(struct ata_device *dev)
 			snprintf(revbuf, 7, "ATA-%d",  ata_id_major_version(id));
 
 		dev->n_sectors = ata_id_n_sectors(id);
-		dev->n_sectors_boot = dev->n_sectors;
 
 		/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
 		ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
@@ -3632,7 +3631,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
 	const u16 *old_id = dev->id;
 	unsigned char model[2][ATA_ID_PROD_LEN + 1];
 	unsigned char serial[2][ATA_ID_SERNO_LEN + 1];
-	u64 new_n_sectors;
 
 	if (dev->class != new_class) {
 		ata_dev_printk(dev, KERN_INFO, "class mismatch %d != %d\n",
@@ -3644,7 +3642,6 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
 	ata_id_c_string(new_id, model[1], ATA_ID_PROD, sizeof(model[1]));
 	ata_id_c_string(old_id, serial[0], ATA_ID_SERNO, sizeof(serial[0]));
 	ata_id_c_string(new_id, serial[1], ATA_ID_SERNO, sizeof(serial[1]));
-	new_n_sectors = ata_id_n_sectors(new_id);
 
 	if (strcmp(model[0], model[1])) {
 		ata_dev_printk(dev, KERN_INFO, "model number mismatch "
@@ -3658,25 +3655,12 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
 		return 0;
 	}
 
-	if (dev->class == ATA_DEV_ATA && dev->n_sectors != new_n_sectors) {
-		ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
-			       "%llu != %llu\n",
-			       (unsigned long long)dev->n_sectors,
-			       (unsigned long long)new_n_sectors);
-		/* Are we the boot time size - if so we appear to be the
-		   same disk at this point and our HPA got reapplied */
-		if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors 
-		    && ata_id_hpa_enabled(new_id))
-			return 1;
-		return 0;
-	}
-
 	return 1;
 }
 
 /**
- *	ata_dev_revalidate - Revalidate ATA device
- *	@dev: device to revalidate
+ *	ata_dev_reread_id - Re-read IDENTIFY data
+ *	@adev: target ATA device
  *	@readid_flags: read ID flags
  *
  *	Re-read IDENTIFY page and make sure @dev is still attached to
@@ -3688,34 +3672,68 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
  *	RETURNS:
  *	0 on success, negative errno otherwise
  */
-int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
+int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags)
 {
 	unsigned int class = dev->class;
 	u16 *id = (void *)dev->ap->sector_buf;
 	int rc;
 
-	if (!ata_dev_enabled(dev)) {
-		rc = -ENODEV;
-		goto fail;
-	}
-
 	/* read ID data */
 	rc = ata_dev_read_id(dev, &class, readid_flags, id);
 	if (rc)
-		goto fail;
+		return rc;
 
 	/* is the device still there? */
-	if (!ata_dev_same_device(dev, class, id)) {
-		rc = -ENODEV;
-		goto fail;
-	}
+	if (!ata_dev_same_device(dev, class, id))
+		return -ENODEV;
 
 	memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
+	return 0;
+}
+
+/**
+ *	ata_dev_revalidate - Revalidate ATA device
+ *	@dev: device to revalidate
+ *	@readid_flags: read ID flags
+ *
+ *	Re-read IDENTIFY page, make sure @dev is still attached to the
+ *	port and reconfigure it according to the new IDENTIFY page.
+ *
+ *	LOCKING:
+ *	Kernel thread context (may sleep)
+ *
+ *	RETURNS:
+ *	0 on success, negative errno otherwise
+ */
+int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
+{
+	u64 n_sectors = dev->n_sectors;
+	int rc;
+
+	if (!ata_dev_enabled(dev))
+		return -ENODEV;
+
+	/* re-read ID */
+	rc = ata_dev_reread_id(dev, readid_flags);
+	if (rc)
+		goto fail;
 
 	/* configure device according to the new ID */
 	rc = ata_dev_configure(dev);
-	if (rc == 0)
-		return 0;
+	if (rc)
+		goto fail;
+
+	/* verify n_sectors hasn't changed */
+	if (dev->class == ATA_DEV_ATA && dev->n_sectors != n_sectors) {
+		ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
+			       "%llu != %llu\n",
+			       (unsigned long long)n_sectors,
+			       (unsigned long long)dev->n_sectors);
+		rc = -ENODEV;
+		goto fail;
+	}
+
+	return 0;
 
  fail:
 	ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc);

+ 36 - 8
drivers/ata/libata-scsi.c

@@ -893,6 +893,23 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
 	return queue_depth;
 }
 
+/* XXX: for ata_spindown_compat */
+static void ata_delayed_done_timerfn(unsigned long arg)
+{
+	struct scsi_cmnd *scmd = (void *)arg;
+
+	scmd->scsi_done(scmd);
+}
+
+/* XXX: for ata_spindown_compat */
+static void ata_delayed_done(struct scsi_cmnd *scmd)
+{
+	static struct timer_list timer;
+
+	setup_timer(&timer, ata_delayed_done_timerfn, (unsigned long)scmd);
+	mod_timer(&timer, jiffies + 5 * HZ);
+}
+
 /**
  *	ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
  *	@qc: Storage for translated ATA taskfile
@@ -950,21 +967,24 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
 		 * for more info.
 		 */
 		if (ata_spindown_compat &&
+		    (qc->dev->flags & ATA_DFLAG_SPUNDOWN) &&
 		    (system_state == SYSTEM_HALT ||
 		     system_state == SYSTEM_POWER_OFF)) {
-			static int warned = 0;
+			static unsigned long warned = 0;
 
-			if (!warned) {
-				spin_unlock_irq(qc->ap->lock);
+			if (!test_and_set_bit(0, &warned)) {
 				ata_dev_printk(qc->dev, KERN_WARNING,
 					"DISK MIGHT NOT BE SPUN DOWN PROPERLY. "
 					"UPDATE SHUTDOWN UTILITY\n");
 				ata_dev_printk(qc->dev, KERN_WARNING,
 					"For more info, visit "
 					"http://linux-ata.org/shutdown.html\n");
-				warned = 1;
-				ssleep(5);
-				spin_lock_irq(qc->ap->lock);
+
+				/* ->scsi_done is not used, use it for
+				 * delayed completion.
+				 */
+				scmd->scsi_done = qc->scsidone;
+				qc->scsidone = ata_delayed_done;
 			}
 			scmd->result = SAM_STAT_GOOD;
 			return 1;
@@ -1375,6 +1395,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 		}
 	}
 
+	/* XXX: track spindown state for spindown_compat */
+	if (unlikely(qc->tf.command == ATA_CMD_STANDBY ||
+		     qc->tf.command == ATA_CMD_STANDBYNOW1))
+		qc->dev->flags |= ATA_DFLAG_SPUNDOWN;
+	else if (likely(system_state != SYSTEM_HALT &&
+			system_state != SYSTEM_POWER_OFF))
+		qc->dev->flags &= ~ATA_DFLAG_SPUNDOWN;
+
 	if (need_sense && !ap->ops->error_handler)
 		ata_dump_status(ap->print_id, &qc->result_tf);
 
@@ -1488,14 +1516,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
 
 early_finish:
         ata_qc_free(qc);
-	done(cmd);
+	qc->scsidone(cmd);
 	DPRINTK("EXIT - early finish (good or error)\n");
 	return 0;
 
 err_did:
 	ata_qc_free(qc);
 	cmd->result = (DID_ERROR << 16);
-	done(cmd);
+	qc->scsidone(cmd);
 err_mem:
 	DPRINTK("EXIT - internal\n");
 	return 0;

+ 2 - 1
drivers/ata/libata.h

@@ -76,7 +76,8 @@ extern unsigned ata_exec_internal_sg(struct ata_device *dev,
 extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
 extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
 			   unsigned int flags, u16 *id);
-extern int ata_dev_revalidate(struct ata_device *dev, unsigned int flags);
+extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
+extern int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags);
 extern int ata_dev_configure(struct ata_device *dev);
 extern int sata_down_spd_limit(struct ata_port *ap);
 extern int sata_set_spd_needed(struct ata_port *ap);

+ 2 - 2
drivers/ata/pata_scc.c

@@ -864,10 +864,10 @@ static void scc_bmdma_freeze (struct ata_port *ap)
  *	@ap: ATA port to be reset
  */
 
-static int scc_pata_prereset (struct ata_port *ap)
+static int scc_pata_prereset (struct ata_port *ap, unsigned long deadline)
 {
 	ap->cbl = ATA_CBL_PATA80;
-	return ata_std_prereset(ap);
+	return ata_std_prereset(ap, deadline);
 }
 
 /**

+ 2 - 1
drivers/ata/sata_sil24.c

@@ -237,7 +237,8 @@ enum {
 	/* host flags */
 	SIL24_COMMON_FLAGS	= ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
 				  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-				  ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY,
+				  ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY |
+				  ATA_FLAG_ACPI_SATA,
 	SIL24_FLAG_PCIX_IRQ_WOC	= (1 << 24), /* IRQ loss errata on PCI-X */
 
 	IRQ_STAT_4PORTS		= 0xf,

+ 1 - 0
drivers/parport/parport_pc.c

@@ -51,6 +51,7 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/dma-mapping.h>
 #include <linux/pci.h>
 #include <linux/pnp.h>
 #include <linux/platform_device.h>

+ 205 - 71
drivers/serial/sunhv.c

@@ -1,6 +1,6 @@
 /* sunhv.c: Serial driver for SUN4V hypervisor console.
  *
- * Copyright (C) 2006 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/module.h>
@@ -35,57 +35,51 @@
 #define CON_BREAK	((long)-1)
 #define CON_HUP		((long)-2)
 
-static inline long hypervisor_con_getchar(long *status)
-{
-	register unsigned long func asm("%o5");
-	register unsigned long arg0 asm("%o0");
-	register unsigned long arg1 asm("%o1");
-
-	func = HV_FAST_CONS_GETCHAR;
-	arg0 = 0;
-	arg1 = 0;
-	__asm__ __volatile__("ta	%6"
-			     : "=&r" (func), "=&r" (arg0), "=&r" (arg1)
-			     : "0" (func), "1" (arg0), "2" (arg1),
-			       "i" (HV_FAST_TRAP));
+#define IGNORE_BREAK	0x1
+#define IGNORE_ALL	0x2
 
-	*status = arg0;
+static char *con_write_page;
+static char *con_read_page;
 
-	return (long) arg1;
-}
+static int hung_up = 0;
 
-static inline long hypervisor_con_putchar(long ch)
+static void transmit_chars_putchar(struct uart_port *port, struct circ_buf *xmit)
 {
-	register unsigned long func asm("%o5");
-	register unsigned long arg0 asm("%o0");
+	while (!uart_circ_empty(xmit)) {
+		long status = sun4v_con_putchar(xmit->buf[xmit->tail]);
 
-	func = HV_FAST_CONS_PUTCHAR;
-	arg0 = ch;
-	__asm__ __volatile__("ta	%4"
-			     : "=&r" (func), "=&r" (arg0)
-			     : "0" (func), "1" (arg0), "i" (HV_FAST_TRAP));
+		if (status != HV_EOK)
+			break;
 
-	return (long) arg0;
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+	}
 }
 
-#define IGNORE_BREAK	0x1
-#define IGNORE_ALL	0x2
+static void transmit_chars_write(struct uart_port *port, struct circ_buf *xmit)
+{
+	while (!uart_circ_empty(xmit)) {
+		unsigned long ra = __pa(xmit->buf + xmit->tail);
+		unsigned long len, status, sent;
 
-static int hung_up = 0;
+		len = CIRC_CNT_TO_END(xmit->head, xmit->tail,
+				      UART_XMIT_SIZE);
+		status = sun4v_con_write(ra, len, &sent);
+		if (status != HV_EOK)
+			break;
+		xmit->tail = (xmit->tail + sent) & (UART_XMIT_SIZE - 1);
+		port->icount.tx += sent;
+	}
+}
 
-static struct tty_struct *receive_chars(struct uart_port *port)
+static int receive_chars_getchar(struct uart_port *port, struct tty_struct *tty)
 {
-	struct tty_struct *tty = NULL;
 	int saw_console_brk = 0;
 	int limit = 10000;
 
-	if (port->info != NULL)		/* Unopened serial console */
-		tty = port->info->tty;
-
 	while (limit-- > 0) {
 		long status;
-		long c = hypervisor_con_getchar(&status);
-		unsigned char flag;
+		long c = sun4v_con_getchar(&status);
 
 		if (status == HV_EWOULDBLOCK)
 			break;
@@ -110,27 +104,90 @@ static struct tty_struct *receive_chars(struct uart_port *port)
 			continue;
 		}
 
-		flag = TTY_NORMAL;
 		port->icount.rx++;
-		if (c == CON_BREAK) {
-			port->icount.brk++;
-			if (uart_handle_break(port))
-				continue;
-			flag = TTY_BREAK;
-		}
 
 		if (uart_handle_sysrq_char(port, c))
 			continue;
 
-		if ((port->ignore_status_mask & IGNORE_ALL) ||
-		    ((port->ignore_status_mask & IGNORE_BREAK) &&
-		     (c == CON_BREAK)))
+		tty_insert_flip_char(tty, c, TTY_NORMAL);
+	}
+
+	return saw_console_brk;
+}
+
+static int receive_chars_read(struct uart_port *port, struct tty_struct *tty)
+{
+	int saw_console_brk = 0;
+	int limit = 10000;
+
+	while (limit-- > 0) {
+		unsigned long ra = __pa(con_read_page);
+		unsigned long bytes_read, i;
+		long stat = sun4v_con_read(ra, PAGE_SIZE, &bytes_read);
+
+		if (stat != HV_EOK) {
+			bytes_read = 0;
+
+			if (stat == CON_BREAK) {
+				if (uart_handle_break(port))
+					continue;
+				saw_console_brk = 1;
+				*con_read_page = 0;
+				bytes_read = 1;
+			} else if (stat == CON_HUP) {
+				hung_up = 1;
+				uart_handle_dcd_change(port, 0);
+				continue;
+			} else {
+				/* HV_EWOULDBLOCK, etc.  */
+				break;
+			}
+		}
+
+		if (hung_up) {
+			hung_up = 0;
+			uart_handle_dcd_change(port, 1);
+		}
+
+		for (i = 0; i < bytes_read; i++)
+			uart_handle_sysrq_char(port, con_read_page[i]);
+
+		if (tty == NULL)
 			continue;
 
-		tty_insert_flip_char(tty, c, flag);
+		port->icount.rx += bytes_read;
+
+		tty_insert_flip_string(tty, con_read_page, bytes_read);
 	}
 
-	if (saw_console_brk)
+	return saw_console_brk;
+}
+
+struct sunhv_ops {
+	void (*transmit_chars)(struct uart_port *port, struct circ_buf *xmit);
+	int (*receive_chars)(struct uart_port *port, struct tty_struct *tty);
+};
+
+static struct sunhv_ops bychar_ops = {
+	.transmit_chars = transmit_chars_putchar,
+	.receive_chars = receive_chars_getchar,
+};
+
+static struct sunhv_ops bywrite_ops = {
+	.transmit_chars = transmit_chars_write,
+	.receive_chars = receive_chars_read,
+};
+
+static struct sunhv_ops *sunhv_ops = &bychar_ops;
+
+static struct tty_struct *receive_chars(struct uart_port *port)
+{
+	struct tty_struct *tty = NULL;
+
+	if (port->info != NULL)		/* Unopened serial console */
+		tty = port->info->tty;
+
+	if (sunhv_ops->receive_chars(port, tty))
 		sun_do_break();
 
 	return tty;
@@ -147,15 +204,7 @@ static void transmit_chars(struct uart_port *port)
 	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
 		return;
 
-	while (!uart_circ_empty(xmit)) {
-		long status = hypervisor_con_putchar(xmit->buf[xmit->tail]);
-
-		if (status != HV_EOK)
-			break;
-
-		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-		port->icount.tx++;
-	}
+	sunhv_ops->transmit_chars(port, xmit);
 
 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
 		uart_write_wakeup(port);
@@ -212,7 +261,7 @@ static void sunhv_start_tx(struct uart_port *port)
 	struct circ_buf *xmit = &port->info->xmit;
 
 	while (!uart_circ_empty(xmit)) {
-		long status = hypervisor_con_putchar(xmit->buf[xmit->tail]);
+		long status = sun4v_con_putchar(xmit->buf[xmit->tail]);
 
 		if (status != HV_EOK)
 			break;
@@ -231,9 +280,10 @@ static void sunhv_send_xchar(struct uart_port *port, char ch)
 	spin_lock_irqsave(&port->lock, flags);
 
 	while (limit-- > 0) {
-		long status = hypervisor_con_putchar(ch);
+		long status = sun4v_con_putchar(ch);
 		if (status == HV_EOK)
 			break;
+		udelay(1);
 	}
 
 	spin_unlock_irqrestore(&port->lock, flags);
@@ -254,15 +304,15 @@ static void sunhv_break_ctl(struct uart_port *port, int break_state)
 {
 	if (break_state) {
 		unsigned long flags;
-		int limit = 1000000;
+		int limit = 10000;
 
 		spin_lock_irqsave(&port->lock, flags);
 
 		while (limit-- > 0) {
-			long status = hypervisor_con_putchar(CON_BREAK);
+			long status = sun4v_con_putchar(CON_BREAK);
 			if (status == HV_EOK)
 				break;
-			udelay(2);
+			udelay(1);
 		}
 
 		spin_unlock_irqrestore(&port->lock, flags);
@@ -359,38 +409,99 @@ static struct uart_driver sunhv_reg = {
 
 static struct uart_port *sunhv_port;
 
-static inline void sunhv_console_putchar(struct uart_port *port, char c)
+/* Copy 's' into the con_write_page, decoding "\n" into
+ * "\r\n" along the way.  We have to return two lengths
+ * because the caller needs to know how much to advance
+ * 's' and also how many bytes to output via con_write_page.
+ */
+static int fill_con_write_page(const char *s, unsigned int n,
+			       unsigned long *page_bytes)
+{
+	const char *orig_s = s;
+	char *p = con_write_page;
+	int left = PAGE_SIZE;
+
+	while (n--) {
+		if (*s == '\n') {
+			if (left < 2)
+				break;
+			*p++ = '\r';
+			left--;
+		} else if (left < 1)
+			break;
+		*p++ = *s++;
+		left--;
+	}
+	*page_bytes = p - con_write_page;
+	return s - orig_s;
+}
+
+static void sunhv_console_write_paged(struct console *con, const char *s, unsigned n)
 {
+	struct uart_port *port = sunhv_port;
 	unsigned long flags;
-	int limit = 1000000;
 
 	spin_lock_irqsave(&port->lock, flags);
+	while (n > 0) {
+		unsigned long ra = __pa(con_write_page);
+		unsigned long page_bytes;
+		unsigned int cpy = fill_con_write_page(s, n,
+						       &page_bytes);
+
+		n -= cpy;
+		s += cpy;
+		while (page_bytes > 0) {
+			unsigned long written;
+			int limit = 1000000;
+
+			while (limit--) {
+				unsigned long stat;
+
+				stat = sun4v_con_write(ra, page_bytes,
+						       &written);
+				if (stat == HV_EOK)
+					break;
+				udelay(1);
+			}
+			if (limit <= 0)
+				break;
+			page_bytes -= written;
+			ra += written;
+		}
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static inline void sunhv_console_putchar(struct uart_port *port, char c)
+{
+	int limit = 1000000;
 
 	while (limit-- > 0) {
-		long status = hypervisor_con_putchar(c);
+		long status = sun4v_con_putchar(c);
 		if (status == HV_EOK)
 			break;
-		udelay(2);
+		udelay(1);
 	}
-
-	spin_unlock_irqrestore(&port->lock, flags);
 }
 
-static void sunhv_console_write(struct console *con, const char *s, unsigned n)
+static void sunhv_console_write_bychar(struct console *con, const char *s, unsigned n)
 {
 	struct uart_port *port = sunhv_port;
+	unsigned long flags;
 	int i;
 
+	spin_lock_irqsave(&port->lock, flags);
 	for (i = 0; i < n; i++) {
 		if (*s == '\n')
 			sunhv_console_putchar(port, '\r');
 		sunhv_console_putchar(port, *s++);
 	}
+	spin_unlock_irqrestore(&port->lock, flags);
 }
 
 static struct console sunhv_console = {
 	.name	=	"ttyHV",
-	.write	=	sunhv_console_write,
+	.write	=	sunhv_console_write_bychar,
 	.device	=	uart_console_device,
 	.flags	=	CON_PRINTBUFFER,
 	.index	=	-1,
@@ -410,6 +521,7 @@ static inline struct console *SUNHV_CONSOLE(void)
 static int __devinit hv_probe(struct of_device *op, const struct of_device_id *match)
 {
 	struct uart_port *port;
+	unsigned long minor;
 	int err;
 
 	if (op->irqs[0] == 0xffffffff)
@@ -419,6 +531,22 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
 	if (unlikely(!port))
 		return -ENOMEM;
 
+	minor = 1;
+	if (sun4v_hvapi_register(HV_GRP_CORE, 1, &minor) == 0 &&
+	    minor >= 1) {
+		err = -ENOMEM;
+		con_write_page = kzalloc(PAGE_SIZE, GFP_KERNEL);
+		if (!con_write_page)
+			goto out_free_port;
+
+		con_read_page = kzalloc(PAGE_SIZE, GFP_KERNEL);
+		if (!con_read_page)
+			goto out_free_con_write_page;
+
+		sunhv_console.write = sunhv_console_write_paged;
+		sunhv_ops = &bywrite_ops;
+	}
+
 	sunhv_port = port;
 
 	port->line = 0;
@@ -437,7 +565,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
 
 	err = uart_register_driver(&sunhv_reg);
 	if (err)
-		goto out_free_port;
+		goto out_free_con_read_page;
 
 	sunhv_reg.tty_driver->name_base = sunhv_reg.minor - 64;
 	sunserial_current_minor += 1;
@@ -463,6 +591,12 @@ out_unregister_driver:
 	sunserial_current_minor -= 1;
 	uart_unregister_driver(&sunhv_reg);
 
+out_free_con_read_page:
+	kfree(con_read_page);
+
+out_free_con_write_page:
+	kfree(con_write_page);
+
 out_free_port:
 	kfree(port);
 	sunhv_port = NULL;

+ 1 - 1
drivers/spi/spidev.c

@@ -484,7 +484,7 @@ static int spidev_probe(struct spi_device *spi)
 	 * Reusing minors is fine so long as udev or mdev is working.
 	 */
 	mutex_lock(&device_list_lock);
-	minor = find_first_zero_bit(minors, ARRAY_SIZE(minors));
+	minor = find_first_zero_bit(minors, N_SPI_MINORS);
 	if (minor < N_SPI_MINORS) {
 		spidev->dev.parent = &spi->dev;
 		spidev->dev.class = &spidev_class;

+ 0 - 1
fs/afs/super.c

@@ -47,7 +47,6 @@ struct file_system_type afs_fs_type = {
 static const struct super_operations afs_super_ops = {
 	.statfs		= afs_statfs,
 	.alloc_inode	= afs_alloc_inode,
-	.drop_inode	= generic_delete_inode,
 	.write_inode	= afs_write_inode,
 	.destroy_inode	= afs_destroy_inode,
 	.clear_inode	= afs_clear_inode,

+ 1 - 2
fs/afs/write.c

@@ -206,7 +206,6 @@ int afs_prepare_write(struct file *file, struct page *page,
 			_leave(" = %d [prep]", ret);
 			return ret;
 		}
-		SetPageUptodate(page);
 	}
 
 try_again:
@@ -311,8 +310,8 @@ int afs_commit_write(struct file *file, struct page *page,
 		spin_unlock(&vnode->writeback_lock);
 	}
 
+	SetPageUptodate(page);
 	set_page_dirty(page);
-
 	if (PageDirty(page))
 		_debug("dirtied");
 

+ 3 - 5
include/asm-avr32/arch-at32ap/board.h

@@ -30,11 +30,9 @@ struct spi_board_info;
 struct platform_device *
 at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n);
 
-struct lcdc_platform_data {
-	unsigned long fbmem_start;
-	unsigned long fbmem_size;
-};
+struct atmel_lcdfb_info;
 struct platform_device *
-at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data);
+at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
+		     unsigned long fbmem_start, unsigned long fbmem_len);
 
 #endif /* __ASM_ARCH_BOARD_H */

+ 13 - 4
include/asm-avr32/kdebug.h

@@ -5,13 +5,22 @@
 
 /* Grossly misnamed. */
 enum die_val {
-	DIE_FAULT,
 	DIE_BREAKPOINT,
 	DIE_SSTEP,
-	DIE_PAGE_FAULT,
 };
 
-int register_page_fault_notifier(struct notifier_block *nb);
-int unregister_page_fault_notifier(struct notifier_block *nb);
+/*
+ * These are only here because kprobes.c wants them to implement a
+ * blatant layering violation.  Will hopefully go away soon once all
+ * architectures are updated.
+ */
+static inline int register_page_fault_notifier(struct notifier_block *nb)
+{
+	return 0;
+}
+static inline int unregister_page_fault_notifier(struct notifier_block *nb)
+{
+	return 0;
+}
 
 #endif /* __ASM_AVR32_KDEBUG_H */

+ 1 - 0
include/asm-avr32/kprobes.h

@@ -26,6 +26,7 @@ struct arch_specific_insn {
 	kprobe_opcode_t	insn[MAX_INSN_SIZE];
 };
 
+extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
 extern int kprobe_exceptions_notify(struct notifier_block *self,
 				    unsigned long val, void *data);
 

+ 4 - 1
include/asm-avr32/unistd.h

@@ -296,9 +296,12 @@
 #define __NR_shmctl		277
 
 #define __NR_utimensat		278
+#define __NR_signalfd		279
+#define __NR_timerfd		280
+#define __NR_eventfd		281
 
 #ifdef __KERNEL__
-#define NR_syscalls		279
+#define NR_syscalls		282
 
 
 #define __ARCH_WANT_IPC_PARSE_VERSION

+ 13 - 3
include/asm-ia64/kdebug.h

@@ -28,14 +28,24 @@
  */
 #include <linux/notifier.h>
 
-extern int register_page_fault_notifier(struct notifier_block *);
-extern int unregister_page_fault_notifier(struct notifier_block *);
+/*
+ * These are only here because kprobes.c wants them to implement a
+ * blatant layering violation.  Will hopefully go away soon once all
+ * architectures are updated.
+ */
+static inline int register_page_fault_notifier(struct notifier_block *nb)
+{
+	return 0;
+}
+static inline int unregister_page_fault_notifier(struct notifier_block *nb)
+{
+	return 0;
+}
 
 enum die_val {
 	DIE_BREAK = 1,
 	DIE_FAULT,
 	DIE_OOPS,
-	DIE_PAGE_FAULT,
 	DIE_MACHINE_HALT,
 	DIE_MACHINE_RESTART,
 	DIE_MCA_MONARCH_ENTER,

+ 1 - 0
include/asm-ia64/kprobes.h

@@ -120,6 +120,7 @@ struct arch_specific_insn {
 	unsigned short slot;
 };
 
+extern int kprobes_fault_handler(struct pt_regs *regs, int trapnr);
 extern int kprobe_exceptions_notify(struct notifier_block *self,
 				    unsigned long val, void *data);
 

+ 4 - 1
include/asm-ia64/unistd.h

@@ -296,11 +296,14 @@
 #define __NR_getcpu			1304
 #define __NR_epoll_pwait		1305
 #define __NR_utimensat			1306
+#define __NR_signalfd			1307
+#define __NR_timerfd			1308
+#define __NR_eventfd			1309
 
 #ifdef __KERNEL__
 
 
-#define NR_syscalls			283 /* length of syscall table */
+#define NR_syscalls			286 /* length of syscall table */
 
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND

+ 82 - 1
include/asm-sparc64/hypervisor.h

@@ -940,6 +940,54 @@ struct hv_fault_status {
  */
 #define HV_FAST_CONS_PUTCHAR		0x61
 
+/* con_read()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_CONS_READ
+ * ARG0:	buffer real address
+ * ARG1:	buffer size in bytes
+ * RET0:	status
+ * RET1:	bytes read or BREAK or HUP
+ * ERRORS:	EWOULDBLOCK	No character available.
+ *
+ * Reads characters into a buffer from the console device.  If no
+ * character is available then an EWOULDBLOCK error is returned.
+ * If a character is available, then the returned status is EOK
+ * and the number of bytes read into the given buffer is provided
+ * in RET1.
+ *
+ * A virtual BREAK is represented by the 64-bit RET1 value -1.
+ *
+ * A virtual HUP signal is represented by the 64-bit RET1 value -2.
+ *
+ * If BREAK or HUP are indicated, no bytes were read into buffer.
+ */
+#define HV_FAST_CONS_READ		0x62
+
+/* con_write()
+ * TRAP:	HV_FAST_TRAP
+ * FUNCTION:	HV_FAST_CONS_WRITE
+ * ARG0:	buffer real address
+ * ARG1:	buffer size in bytes
+ * RET0:	status
+ * RET1:	bytes written
+ * ERRORS:	EWOULDBLOCK	Output buffer currently full, would block
+ *
+ * Send a characters in buffer to the console device.  Breaks must be
+ * sent using con_putchar().
+ */
+#define HV_FAST_CONS_WRITE		0x63
+
+#ifndef __ASSEMBLY__
+extern long sun4v_con_getchar(long *status);
+extern long sun4v_con_putchar(long c);
+extern long sun4v_con_read(unsigned long buffer,
+			   unsigned long size,
+			   unsigned long *bytes_read);
+extern unsigned long sun4v_con_write(unsigned long buffer,
+				     unsigned long size,
+				     unsigned long *bytes_written);
+#endif
+
 /* Trap trace services.
  *
  * The hypervisor provides a trap tracing capability for privileged
@@ -2121,8 +2169,41 @@ struct hv_mmu_statistics {
 #define HV_FAST_MMUSTAT_INFO		0x103
 
 /* Function numbers for HV_CORE_TRAP.  */
-#define HV_CORE_VER			0x00
+#define HV_CORE_SET_VER			0x00
 #define HV_CORE_PUTCHAR			0x01
 #define HV_CORE_EXIT			0x02
+#define HV_CORE_GET_VER			0x03
+
+/* Hypervisor API groups for use with HV_CORE_SET_VER and
+ * HV_CORE_GET_VER.
+ */
+#define HV_GRP_SUN4V			0x0000
+#define HV_GRP_CORE			0x0001
+#define HV_GRP_INTR			0x0002
+#define HV_GRP_SOFT_STATE		0x0003
+#define HV_GRP_PCI			0x0100
+#define HV_GRP_LDOM			0x0101
+#define HV_GRP_SVC_CHAN			0x0102
+#define HV_GRP_NCS			0x0103
+#define HV_GRP_NIAG_PERF		0x0200
+#define HV_GRP_FIRE_PERF		0x0201
+#define HV_GRP_DIAG			0x0300
+
+#ifndef __ASSEMBLY__
+extern unsigned long sun4v_get_version(unsigned long group,
+				       unsigned long *major,
+				       unsigned long *minor);
+extern unsigned long sun4v_set_version(unsigned long group,
+				       unsigned long major,
+				       unsigned long minor,
+				       unsigned long *actual_minor);
+
+extern int sun4v_hvapi_register(unsigned long group, unsigned long major,
+				unsigned long *minor);
+extern void sun4v_hvapi_unregister(unsigned long group);
+extern int sun4v_hvapi_get(unsigned long group,
+			   unsigned long *major,
+			   unsigned long *minor);
+#endif
 
 #endif /* !(_SPARC64_HYPERVISOR_H) */

+ 2 - 1
include/linux/libata.h

@@ -140,6 +140,7 @@ enum {
 
 	ATA_DFLAG_PIO		= (1 << 8), /* device limited to PIO mode */
 	ATA_DFLAG_NCQ_OFF	= (1 << 9), /* device limited to non-NCQ mode */
+	ATA_DFLAG_SPUNDOWN	= (1 << 10), /* XXX: for spindown_compat */
 	ATA_DFLAG_INIT_MASK	= (1 << 16) - 1,
 
 	ATA_DFLAG_DETACH	= (1 << 16),
@@ -173,6 +174,7 @@ enum {
 	ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
 	ATA_FLAG_IGN_SIMPLEX	= (1 << 15), /* ignore SIMPLEX */
 	ATA_FLAG_NO_IORDY	= (1 << 16), /* controller lacks iordy */
+	ATA_FLAG_ACPI_SATA	= (1 << 17), /* need native SATA ACPI layout */
 
 	/* The following flag belongs to ap->pflags but is kept in
 	 * ap->flags because it's referenced in many LLDs and will be
@@ -431,7 +433,6 @@ struct ata_device {
 	struct scsi_device	*sdev;		/* attached SCSI device */
 	/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
 	u64			n_sectors;	/* size of device, if ATA */
-	u64			n_sectors_boot;	/* size of ATA device at startup */
 	unsigned int		class;		/* ATA_DEV_xxx */
 	u16			id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
 	u8			pio_mode;

+ 1 - 1
include/linux/slub_def.h

@@ -88,7 +88,7 @@ static inline int kmalloc_index(int size)
 	 */
 	WARN_ON_ONCE(size == 0);
 
-	if (size >= (1 << KMALLOC_SHIFT_HIGH))
+	if (size > (1 << KMALLOC_SHIFT_HIGH))
 		return -1;
 
 	if (size > 64 && size <= 96)

+ 3 - 1
include/sound/soc.h

@@ -22,7 +22,7 @@
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
 
-#define SND_SOC_VERSION "0.13.0"
+#define SND_SOC_VERSION "0.13.1"
 
 /*
  * Convenience kcontrol builders
@@ -83,6 +83,7 @@
 #define SND_SOC_DAI_AC97	0x1
 #define SND_SOC_DAI_I2S		0x2
 #define SND_SOC_DAI_PCM		0x4
+#define SND_SOC_DAI_AC97_BUS	0x8	/* for custom i.e. non ac97_codec.c */
 
 /*
  * DAI hardware audio formats
@@ -278,6 +279,7 @@ struct snd_soc_cpu_ops {
 struct snd_soc_codec_dai {
 	char *name;
 	int id;
+	unsigned char type;
 
 	/* DAI capabilities */
 	struct snd_soc_pcm_stream playback;

+ 1 - 1
include/sound/version.h

@@ -1,3 +1,3 @@
 /* include/version.h.  Generated by alsa/ksync script.  */
 #define CONFIG_SND_VERSION "1.0.14rc4"
-#define CONFIG_SND_DATE " (Wed May 09 09:51:39 2007 UTC)"
+#define CONFIG_SND_DATE " (Wed May 16 09:45:46 2007 UTC)"

+ 8 - 7
kernel/power/main.c

@@ -97,25 +97,26 @@ static int suspend_prepare(suspend_state_t state)
 		}
 	}
 
-	if (pm_ops->prepare) {
-		if ((error = pm_ops->prepare(state)))
-			goto Thaw;
-	}
-
 	suspend_console();
 	error = device_suspend(PMSG_SUSPEND);
 	if (error) {
 		printk(KERN_ERR "Some devices failed to suspend\n");
-		goto Resume_devices;
+		goto Resume_console;
 	}
+	if (pm_ops->prepare) {
+		if ((error = pm_ops->prepare(state)))
+			goto Resume_devices;
+	}
+
 	error = disable_nonboot_cpus();
 	if (!error)
 		return 0;
 
 	enable_nonboot_cpus();
- Resume_devices:
 	pm_finish(state);
+ Resume_devices:
 	device_resume();
+ Resume_console:
 	resume_console();
  Thaw:
 	thaw_processes();

+ 2 - 1
mm/filemap.c

@@ -670,7 +670,8 @@ repeat:
 	page = find_lock_page(mapping, index);
 	if (!page) {
 		if (!cached_page) {
-			cached_page = alloc_page(gfp_mask);
+			cached_page =
+				__page_cache_alloc(gfp_mask);
 			if (!cached_page)
 				return NULL;
 		}

+ 1 - 1
mm/slub.c

@@ -2522,7 +2522,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
 	struct kmem_cache *s;
 
 	down_write(&slub_lock);
-	s = find_mergeable(size, align, flags, dtor, ctor);
+	s = find_mergeable(size, align, flags, ctor, dtor);
 	if (s) {
 		s->refcount++;
 		/*

+ 11 - 4
sound/isa/cmi8330.c

@@ -109,6 +109,7 @@ module_param_array(wssdma, int, NULL, 0444);
 MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver.");
 
 #ifdef CONFIG_PNP
+static int isa_registered;
 static int pnp_registered;
 #endif
 
@@ -686,14 +687,18 @@ static int __init alsa_card_cmi8330_init(void)
 	int err;
 
 	err = isa_register_driver(&snd_cmi8330_driver, SNDRV_CARDS);
-	if (err < 0)
-		return err;
 #ifdef CONFIG_PNP
+	if (!err)
+		isa_registered = 1;
+
 	err = pnp_register_card_driver(&cmi8330_pnpc_driver);
 	if (!err)
 		pnp_registered = 1;
+
+	if (isa_registered)
+		err = 0;
 #endif
-	return 0;
+	return err;
 }
 
 static void __exit alsa_card_cmi8330_exit(void)
@@ -701,8 +706,10 @@ static void __exit alsa_card_cmi8330_exit(void)
 #ifdef CONFIG_PNP
 	if (pnp_registered)
 		pnp_unregister_card_driver(&cmi8330_pnpc_driver);
+
+	if (isa_registered)
 #endif
-	isa_unregister_driver(&snd_cmi8330_driver);
+		isa_unregister_driver(&snd_cmi8330_driver);
 }
 
 module_init(alsa_card_cmi8330_init)

+ 14 - 6
sound/isa/cs423x/cs4236.c

@@ -127,6 +127,7 @@ module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA2 # for " IDENT " driver.");
 
 #ifdef CONFIG_PNP
+static int isa_registered;
 static int pnpc_registered;
 #ifdef CS4232
 static int pnp_registered;
@@ -770,9 +771,9 @@ static int __init alsa_card_cs423x_init(void)
 	int err;
 
 	err = isa_register_driver(&cs423x_isa_driver, SNDRV_CARDS);
-	if (err < 0)
-		return err;
 #ifdef CONFIG_PNP
+	if (!err)
+		isa_registered = 1;
 #ifdef CS4232
 	err = pnp_register_driver(&cs4232_pnp_driver);
 	if (!err)
@@ -781,8 +782,14 @@ static int __init alsa_card_cs423x_init(void)
 	err = pnp_register_card_driver(&cs423x_pnpc_driver);
 	if (!err)
 		pnpc_registered = 1;
-#endif /* CONFIG_PNP */
-	return 0;
+#ifdef CS4232
+	if (pnp_registered)
+		err = 0;
+#endif
+	if (isa_registered)
+		err = 0;
+#endif
+	return err;
 }
 
 static void __exit alsa_card_cs423x_exit(void)
@@ -794,8 +801,9 @@ static void __exit alsa_card_cs423x_exit(void)
 	if (pnp_registered)
 		pnp_unregister_driver(&cs4232_pnp_driver);
 #endif
-#endif /* CONFIG_PNP */
-	isa_unregister_driver(&cs423x_isa_driver);
+	if (isa_registered)
+#endif
+		isa_unregister_driver(&cs423x_isa_driver);
 }
 
 module_init(alsa_card_cs423x_init)

+ 13 - 6
sound/isa/es18xx.c

@@ -2036,7 +2036,9 @@ module_param_array(dma2, int, NULL, 0444);
 MODULE_PARM_DESC(dma2, "DMA 2 # for ES18xx driver.");
 
 #ifdef CONFIG_PNP
-static int pnp_registered, pnpc_registered;
+static int isa_registered;
+static int pnp_registered;
+static int pnpc_registered;
 
 static struct pnp_device_id snd_audiodrive_pnpbiosids[] = {
 	{ .id = "ESS1869" },
@@ -2466,18 +2468,22 @@ static int __init alsa_card_es18xx_init(void)
 	int err;
 
 	err = isa_register_driver(&snd_es18xx_isa_driver, SNDRV_CARDS);
-	if (err < 0)
-		return err;
-
 #ifdef CONFIG_PNP
+	if (!err)
+		isa_registered = 1;
+
 	err = pnp_register_driver(&es18xx_pnp_driver);
 	if (!err)
 		pnp_registered = 1;
+
 	err = pnp_register_card_driver(&es18xx_pnpc_driver);
 	if (!err)
 		pnpc_registered = 1;
+
+	if (isa_registered || pnp_registered)
+		err = 0;
 #endif
-	return 0;
+	return err;
 }
 
 static void __exit alsa_card_es18xx_exit(void)
@@ -2487,8 +2493,9 @@ static void __exit alsa_card_es18xx_exit(void)
 		pnp_unregister_card_driver(&es18xx_pnpc_driver);
 	if (pnp_registered)
 		pnp_unregister_driver(&es18xx_pnp_driver);
+	if (isa_registered)
 #endif
-	isa_unregister_driver(&snd_es18xx_isa_driver);
+		isa_unregister_driver(&snd_es18xx_isa_driver);
 }
 
 module_init(alsa_card_es18xx_init)

+ 10 - 5
sound/isa/gus/interwave.c

@@ -135,6 +135,7 @@ struct snd_interwave {
 
 
 #ifdef CONFIG_PNP
+static int isa_registered;
 static int pnp_registered;
 
 static struct pnp_card_device_id snd_interwave_pnpids[] = {
@@ -934,15 +935,18 @@ static int __init alsa_card_interwave_init(void)
 	int err;
 
 	err = isa_register_driver(&snd_interwave_driver, SNDRV_CARDS);
-	if (err < 0)
-		return err;
 #ifdef CONFIG_PNP
-	/* ISA PnP cards */
+	if (!err)
+		isa_registered = 1;
+
 	err = pnp_register_card_driver(&interwave_pnpc_driver);
 	if (!err)
 		pnp_registered = 1;
+
+	if (isa_registered)
+		err = 0;
 #endif
-	return 0;
+	return err;
 }
 
 static void __exit alsa_card_interwave_exit(void)
@@ -950,8 +954,9 @@ static void __exit alsa_card_interwave_exit(void)
 #ifdef CONFIG_PNP
 	if (pnp_registered)
 		pnp_unregister_card_driver(&interwave_pnpc_driver);
+	if (isa_registered)
 #endif
-	isa_unregister_driver(&snd_interwave_driver);
+		isa_unregister_driver(&snd_interwave_driver);
 }
 
 module_init(alsa_card_interwave_init)

+ 11 - 4
sound/isa/opl3sa2.c

@@ -92,6 +92,7 @@ module_param_array(opl3sa3_ymode, int, NULL, 0444);
 MODULE_PARM_DESC(opl3sa3_ymode, "Speaker size selection for 3D Enhancement mode: Desktop/Large Notebook/Small Notebook/HiFi.");
 
 #ifdef CONFIG_PNP
+static int isa_registered;
 static int pnp_registered;
 static int pnpc_registered;
 #endif
@@ -967,17 +968,22 @@ static int __init alsa_card_opl3sa2_init(void)
 	int err;
 
 	err = isa_register_driver(&snd_opl3sa2_isa_driver, SNDRV_CARDS);
-	if (err < 0)
-		return err;
 #ifdef CONFIG_PNP
+	if (!err)
+		isa_registered = 1;
+
 	err = pnp_register_driver(&opl3sa2_pnp_driver);
 	if (!err)
 		pnp_registered = 1;
+
 	err = pnp_register_card_driver(&opl3sa2_pnpc_driver);
 	if (!err)
 		pnpc_registered = 1;
+
+	if (isa_registered || pnp_registered)
+		err = 0;
 #endif
-	return 0;
+	return err;
 }
 
 static void __exit alsa_card_opl3sa2_exit(void)
@@ -987,8 +993,9 @@ static void __exit alsa_card_opl3sa2_exit(void)
 		pnp_unregister_card_driver(&opl3sa2_pnpc_driver);
 	if (pnp_registered)
 		pnp_unregister_driver(&opl3sa2_pnp_driver);
+	if (isa_registered)
 #endif
-	isa_unregister_driver(&snd_opl3sa2_isa_driver);
+		isa_unregister_driver(&snd_opl3sa2_isa_driver);
 }
 
 module_init(alsa_card_opl3sa2_init)

+ 10 - 5
sound/isa/sb/sb16.c

@@ -129,6 +129,7 @@ MODULE_PARM_DESC(seq_ports, "Number of sequencer ports for WaveTable synth.");
 #endif
 
 #ifdef CONFIG_PNP
+static int isa_registered;
 static int pnp_registered;
 #endif
 
@@ -702,15 +703,18 @@ static int __init alsa_card_sb16_init(void)
 	int err;
 
 	err = isa_register_driver(&snd_sb16_isa_driver, SNDRV_CARDS);
-	if (err < 0)
-		return err;
 #ifdef CONFIG_PNP
-	/* PnP cards at last */
+	if (!err)
+		isa_registered = 1;
+
 	err = pnp_register_card_driver(&sb16_pnpc_driver);
 	if (!err)
 		pnp_registered = 1;
+
+	if (isa_registered)
+		err = 0;
 #endif
-	return 0;
+	return err;
 }
 
 static void __exit alsa_card_sb16_exit(void)
@@ -718,8 +722,9 @@ static void __exit alsa_card_sb16_exit(void)
 #ifdef CONFIG_PNP
 	if (pnp_registered)
 		pnp_unregister_card_driver(&sb16_pnpc_driver);
+	if (isa_registered)
 #endif
-	isa_unregister_driver(&snd_sb16_isa_driver);
+		isa_unregister_driver(&snd_sb16_isa_driver);
 }
 
 module_init(alsa_card_sb16_init)

+ 15 - 13
sound/isa/sscape.c

@@ -69,7 +69,9 @@ module_param_array(dma, int, NULL, 0444);
 MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
 
 #ifdef CONFIG_PNP
+static int isa_registered;
 static int pnp_registered;
+
 static struct pnp_card_device_id sscape_pnpids[] = {
 	{ .id = "ENS3081", .devs = { { "ENS0000" } } },
 	{ .id = "" }	/* end */
@@ -1405,22 +1407,21 @@ static struct pnp_card_driver sscape_pnpc_driver = {
 
 static int __init sscape_init(void)
 {
-	int ret;
+	int err;
 
-	/*
-	 * First check whether we were passed any parameters.
-	 * These MUST take precedence over ANY automatic way
-	 * of allocating cards, because the operator is
-	 * S-P-E-L-L-I-N-G it out for us...
-	 */
-	ret = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
-	if (ret < 0)
-		return ret;
+	err = isa_register_driver(&snd_sscape_driver, SNDRV_CARDS);
 #ifdef CONFIG_PNP
-	if (pnp_register_card_driver(&sscape_pnpc_driver) == 0)
+	if (!err)
+		isa_registered = 1;
+
+	err = pnp_register_card_driver(&sscape_pnpc_driver);
+	if (!err)
 		pnp_registered = 1;
+
+	if (isa_registered)
+		err = 0;
 #endif
-	return 0;
+	return err;
 }
 
 static void __exit sscape_exit(void)
@@ -1428,8 +1429,9 @@ static void __exit sscape_exit(void)
 #ifdef CONFIG_PNP
 	if (pnp_registered)
 		pnp_unregister_card_driver(&sscape_pnpc_driver);
+	if (isa_registered)
 #endif
-	isa_unregister_driver(&snd_sscape_driver);
+		isa_unregister_driver(&snd_sscape_driver);
 }
 
 module_init(sscape_init);

+ 10 - 4
sound/isa/wavefront/wavefront.c

@@ -86,6 +86,7 @@ module_param_array(use_cs4232_midi, bool, NULL, 0444);
 MODULE_PARM_DESC(use_cs4232_midi, "Use CS4232 MPU-401 interface (inaccessibly located inside your computer)");
 
 #ifdef CONFIG_PNP
+static int isa_registered;
 static int pnp_registered;
 
 static struct pnp_card_device_id snd_wavefront_pnpids[] = {
@@ -706,14 +707,18 @@ static int __init alsa_card_wavefront_init(void)
 	int err;
 
 	err = isa_register_driver(&snd_wavefront_driver, SNDRV_CARDS);
-	if (err < 0)
-		return err;
 #ifdef CONFIG_PNP
+	if (!err)
+		isa_registered = 1;
+
 	err = pnp_register_card_driver(&wavefront_pnpc_driver);
 	if (!err)
 		pnp_registered = 1;
+
+	if (isa_registered)
+		err = 0;
 #endif
-	return 0;
+	return err;
 }
 
 static void __exit alsa_card_wavefront_exit(void)
@@ -721,8 +726,9 @@ static void __exit alsa_card_wavefront_exit(void)
 #ifdef CONFIG_PNP
 	if (pnp_registered)
 		pnp_unregister_card_driver(&wavefront_pnpc_driver);
+	if (isa_registered)
 #endif
-	isa_unregister_driver(&snd_wavefront_driver);
+		isa_unregister_driver(&snd_wavefront_driver);
 }
 
 module_init(alsa_card_wavefront_init)

+ 5 - 0
sound/pci/ac97/ac97_patch.c

@@ -1782,6 +1782,11 @@ static unsigned int ad1981_jacks_blacklist[] = {
 	0x10140534, /* Thinkpad X31 */
 	0x10140537, /* Thinkpad T41p */
 	0x10140554, /* Thinkpad T42p/R50p */
+	0x10140567, /* Thinkpad T43p 2668-G7U */
+	0x10140581, /* Thinkpad X41-2527 */
+	0x104380b0, /* Asus A7V8X-MX */
+	0x11790241, /* Toshiba Satellite A-15 S127 */
+	0x144dc01a, /* Samsung NP-X20C004/SEG */
 	0 /* end */
 };
 

+ 2 - 1
sound/pci/hda/hda_codec.c

@@ -707,7 +707,8 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
 						    direction == HDA_OUTPUT ?
 						    AC_PAR_AMP_OUT_CAP :
 						    AC_PAR_AMP_IN_CAP);
-		info->status |= INFO_AMP_CAPS;
+		if (info->amp_caps)
+			info->status |= INFO_AMP_CAPS;
 	}
 	return info->amp_caps;
 }

+ 515 - 17
sound/pci/hda/patch_realtek.c

@@ -93,6 +93,7 @@ enum {
 	ALC262_HP_BPC_D7000_WL,
 	ALC262_HP_BPC_D7000_WF,
 	ALC262_BENQ_ED8,
+	ALC262_SONY_ASSAMD,
 	ALC262_AUTO,
 	ALC262_MODEL_LAST /* last tag */
 };
@@ -118,6 +119,7 @@ enum {
 	ALC861VD_3ST_DIG,
 	ALC861VD_6ST_DIG,
 	ALC861VD_LENOVO,
+	ALC861VD_DALLAS,
 	ALC861VD_AUTO,
 	ALC861VD_MODEL_LAST,
 };
@@ -139,8 +141,10 @@ enum {
 	ALC882_6ST_DIG,
 	ALC882_ARIMA,
 	ALC882_W2JC,
-	ALC882_AUTO,
+	ALC882_TARGA,
+	ALC882_ASUS_A7J,
 	ALC885_MACPRO,
+	ALC882_AUTO,
 	ALC882_MODEL_LAST,
 };
 
@@ -152,11 +156,13 @@ enum {
 	ALC883_6ST_DIG,
 	ALC883_TARGA_DIG,
 	ALC883_TARGA_2ch_DIG,
-	ALC888_DEMO_BOARD,
 	ALC883_ACER,
 	ALC883_MEDION,
+	ALC883_MEDION_MD2,	
 	ALC883_LAPTOP_EAPD,
 	ALC883_LENOVO_101E_2ch,
+	ALC883_LENOVO_NB0763,
+	ALC888_LENOVO_MS7195_DIG,		
 	ALC883_AUTO,
 	ALC883_MODEL_LAST,
 };
@@ -4752,6 +4758,35 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
 	return 1;
 }
 
+/*
+ * 2ch mode
+ */
+static struct hda_verb alc882_3ST_ch2_init[] = {
+	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
+	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
+	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
+	{ } /* end */
+};
+
+/*
+ * 6ch mode
+ */
+static struct hda_verb alc882_3ST_ch6_init[] = {
+	{ 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	{ 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
+	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
+	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
+	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
+	{ } /* end */
+};
+
+static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
+	{ 2, alc882_3ST_ch2_init },
+	{ 6, alc882_3ST_ch6_init },
+};
+
 /*
  * 6ch mode
  */
@@ -4824,6 +4859,40 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
 	{ } /* end */
 };
 
+static struct snd_kcontrol_new alc882_targa_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+	{ } /* end */
+};
+
+/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
+ *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
+ */
+static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
+	HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	{ } /* end */
+};
+
 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -4985,6 +5054,66 @@ static struct hda_verb alc882_macpro_init_verbs[] = {
 	{ }
 };
 
+static struct hda_verb alc882_targa_verbs[] = {
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	
+	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
+	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
+	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+
+	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+	{0x01, AC_VERB_SET_GPIO_MASK, 0x03},
+	{0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
+	{0x01, AC_VERB_SET_GPIO_DATA, 0x03},
+	{ } /* end */
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc882_targa_automute(struct hda_codec *codec)
+{
+ 	unsigned int present;
+ 
+ 	present = snd_hda_codec_read(codec, 0x14, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
+}
+
+static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+	/* Looks like the unsol event is incompatible with the standard
+	 * definition.  4bit tag is placed at 26 bit!
+	 */
+	if (((res >> 26) == ALC880_HP_EVENT)) {
+		alc882_targa_automute(codec);
+	}
+}
+
+static struct hda_verb alc882_asus_a7j_verbs[] = {
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	
+	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+	{0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
+
+	{0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
+	{0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
+	{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
+	{ } /* end */
+};
+
 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
 {
 	unsigned int gpiostate, gpiomask, gpiodir;
@@ -5152,7 +5281,9 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
 	SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
 	SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
+	SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
 	SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
+	SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
 	SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
 	SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
 	{}
@@ -5214,6 +5345,36 @@ static struct alc_config_preset alc882_presets[] = {
 		.channel_mode = alc882_ch_modes,
 		.input_mux = &alc882_capture_source,
 	},
+	[ALC882_TARGA] = {
+		.mixers = { alc882_targa_mixer, alc882_chmode_mixer,
+			    alc882_capture_mixer },
+		.init_verbs = { alc882_init_verbs, alc882_targa_verbs},
+		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
+		.dac_nids = alc882_dac_nids,
+		.dig_out_nid = ALC882_DIGOUT_NID,
+		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
+		.adc_nids = alc882_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
+		.channel_mode = alc882_3ST_6ch_modes,
+		.need_dac_fix = 1,
+		.input_mux = &alc882_capture_source,
+		.unsol_event = alc882_targa_unsol_event,
+		.init_hook = alc882_targa_automute,
+	},
+	[ALC882_ASUS_A7J] = {
+		.mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
+			    alc882_capture_mixer },
+		.init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
+		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
+		.dac_nids = alc882_dac_nids,
+		.dig_out_nid = ALC882_DIGOUT_NID,
+		.num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
+		.adc_nids = alc882_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
+		.channel_mode = alc882_3ST_6ch_modes,
+		.need_dac_fix = 1,
+		.input_mux = &alc882_capture_source,
+	},	
 };
 
 
@@ -5441,6 +5602,16 @@ static struct hda_input_mux alc883_lenovo_101e_capture_source = {
 	},
 };
 
+static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
+	.num_items = 4,
+	.items = {
+		{ "Mic", 0x0 },
+		{ "iMic", 0x1 },
+		{ "Line", 0x2 },
+		{ "CD", 0x4 },
+	},
+};
+
 #define alc883_mux_enum_info alc_mux_enum_info
 #define alc883_mux_enum_get alc_mux_enum_get
 
@@ -5772,6 +5943,58 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
 	{ } /* end */
 };
 
+static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
+	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 2,
+		.info = alc883_mux_enum_info,
+		.get = alc883_mux_enum_get,
+		.put = alc883_mux_enum_put,
+	},
+	{ } /* end */
+};
+
+static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 2,
+		.info = alc883_mux_enum_info,
+		.get = alc883_mux_enum_get,
+		.put = alc883_mux_enum_put,
+	},
+	{ } /* end */
+};	
+
 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -5886,6 +6109,93 @@ static struct hda_verb alc883_lenovo_101e_verbs[] = {
 	{ } /* end */
 };
 
+static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
+        {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+	{ } /* end */
+};
+
+static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
+	{0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
+	{ } /* end */
+};
+
+/* toggle front-jack and RCA according to the hp-jack state */
+static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
+{
+ 	unsigned int present;
+ 
+ 	present = snd_hda_codec_read(codec, 0x1b, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	
+}
+
+/* toggle RCA according to the front-jack state */
+static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
+{
+ 	unsigned int present;
+ 
+ 	present = snd_hda_codec_read(codec, 0x14, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	
+}
+static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
+					     unsigned int res)
+{
+	if ((res >> 26) == ALC880_HP_EVENT)
+		alc888_lenovo_ms7195_front_automute(codec);
+	if ((res >> 26) == ALC880_FRONT_EVENT)
+		alc888_lenovo_ms7195_rca_automute(codec);
+}
+
+static struct hda_verb alc883_medion_md2_verbs[] = {
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+
+	{0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
+	{ } /* end */
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc883_medion_md2_automute(struct hda_codec *codec)
+{
+ 	unsigned int present;
+ 
+ 	present = snd_hda_codec_read(codec, 0x14, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+}
+
+static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
+					  unsigned int res)
+{
+	if ((res >> 26) == ALC880_HP_EVENT)
+		alc883_medion_md2_automute(codec);
+}
+
 /* toggle speaker-output according to the hp-jack state */
 static void alc883_tagra_automute(struct hda_codec *codec)
 {
@@ -6051,11 +6361,13 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
 	[ALC883_6ST_DIG]	= "6stack-dig",
 	[ALC883_TARGA_DIG]	= "targa-dig",
 	[ALC883_TARGA_2ch_DIG]	= "targa-2ch-dig",
-	[ALC888_DEMO_BOARD]	= "6stack-dig-demo",
 	[ALC883_ACER]		= "acer",
 	[ALC883_MEDION]		= "medion",
+	[ALC883_MEDION_MD2]	= "medion-md2",
 	[ALC883_LAPTOP_EAPD]	= "laptop-eapd",
 	[ALC883_LENOVO_101E_2ch] = "lenovo-101e",
+	[ALC883_LENOVO_NB0763]	= "lenovo-nb0763",
+	[ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
 	[ALC883_AUTO]		= "auto",
 };
 
@@ -6082,7 +6394,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
 	SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
 	SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
-	SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch),
+	SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
+	SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
+	SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
+	SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
 	{}
 };
 
@@ -6168,19 +6483,6 @@ static struct alc_config_preset alc883_presets[] = {
 		.unsol_event = alc883_tagra_unsol_event,
 		.init_hook = alc883_tagra_automute,
 	},
-	[ALC888_DEMO_BOARD] = {
-		.mixers = { alc883_base_mixer, alc883_chmode_mixer },
-		.init_verbs = { alc883_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
-		.dac_nids = alc883_dac_nids,
-		.dig_out_nid = ALC883_DIGOUT_NID,
-		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
-		.adc_nids = alc883_adc_nids,
-		.dig_in_nid = ALC883_DIGIN_NID,
-		.num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
-		.channel_mode = alc883_sixstack_modes,
-		.input_mux = &alc883_capture_source,
-	},
 	[ALC883_ACER] = {
 		.mixers = { alc883_base_mixer,
 			    alc883_chmode_mixer },
@@ -6211,6 +6513,20 @@ static struct alc_config_preset alc883_presets[] = {
 		.channel_mode = alc883_sixstack_modes,
 		.input_mux = &alc883_capture_source,
 	},
+	[ALC883_MEDION_MD2] = {
+		.mixers = { alc883_medion_md2_mixer},
+		.init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
+		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
+		.dac_nids = alc883_dac_nids,
+		.dig_out_nid = ALC883_DIGOUT_NID,
+		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+		.adc_nids = alc883_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+		.channel_mode = alc883_3ST_2ch_modes,
+		.input_mux = &alc883_capture_source,
+		.unsol_event = alc883_medion_md2_unsol_event,
+		.init_hook = alc883_medion_md2_automute,
+	},	
 	[ALC883_LAPTOP_EAPD] = {
 		.mixers = { alc883_base_mixer,
 			    alc883_chmode_mixer },
@@ -6236,6 +6552,35 @@ static struct alc_config_preset alc883_presets[] = {
 		.unsol_event = alc883_lenovo_101e_unsol_event,
 		.init_hook = alc883_lenovo_101e_all_automute,
 	},
+	[ALC883_LENOVO_NB0763] = {
+		.mixers = { alc883_lenovo_nb0763_mixer },
+		.init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
+		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
+		.dac_nids = alc883_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+		.adc_nids = alc883_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
+		.channel_mode = alc883_3ST_2ch_modes,
+		.need_dac_fix = 1,
+		.input_mux = &alc883_lenovo_nb0763_capture_source,
+		.unsol_event = alc883_medion_md2_unsol_event,
+		.init_hook = alc883_medion_md2_automute,
+	},
+	[ALC888_LENOVO_MS7195_DIG] = {
+		.mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
+		.init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
+		.num_dacs = ARRAY_SIZE(alc883_dac_nids),
+		.dac_nids = alc883_dac_nids,
+		.dig_out_nid = ALC883_DIGOUT_NID,
+		.num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
+		.adc_nids = alc883_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
+		.channel_mode = alc883_3ST_6ch_modes,
+		.need_dac_fix = 1,
+		.input_mux = &alc883_capture_source,
+		.unsol_event = alc883_lenovo_ms7195_unsol_event,
+		.init_hook = alc888_lenovo_ms7195_front_automute,
+	},	
 };
 
 
@@ -6499,6 +6844,18 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
 	{ } /* end */
 };
 
+static struct snd_kcontrol_new alc262_sony_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
+	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
+	{ } /* end */
+};
+
+
+
 #define alc262_capture_mixer		alc882_capture_mixer
 #define alc262_capture_alt_mixer	alc882_capture_alt_mixer
 
@@ -6597,6 +6954,15 @@ static struct hda_verb alc262_hippo1_unsol_verbs[] = {
 	{}
 };
 
+static struct hda_verb alc262_sony_unsol_verbs[] = {
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},	// Front Mic
+
+	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
+};
+
 /* mute/unmute internal speaker according to the hp jack and mute state */
 static void alc262_hippo_automute(struct hda_codec *codec, int force)
 {
@@ -7215,6 +7581,7 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
 	[ALC262_HP_BPC]		= "hp-bpc",
 	[ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
 	[ALC262_BENQ_ED8]	= "benq",
+	[ALC262_BENQ_ED8]	= "sony-assamd",
 	[ALC262_AUTO]		= "auto",
 };
 
@@ -7236,6 +7603,9 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
 	SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
 	SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
+	SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
+	SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
+	SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
 	{}
 };
 
@@ -7327,6 +7697,17 @@ static struct alc_config_preset alc262_presets[] = {
 		.channel_mode = alc262_modes,
 		.input_mux = &alc262_capture_source,
 	},
+	[ALC262_SONY_ASSAMD] = {
+		.mixers = { alc262_sony_mixer },
+		.init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
+		.num_dacs = ARRAY_SIZE(alc262_dac_nids),
+		.dac_nids = alc262_dac_nids,
+		.hp_nid = 0x02,
+		.num_channel_mode = ARRAY_SIZE(alc262_modes),
+		.channel_mode = alc262_modes,
+		.input_mux = &alc262_capture_source,
+		.unsol_event = alc262_hippo_unsol_event,
+	},	
 };
 
 static int patch_alc262(struct hda_codec *codec)
@@ -8599,6 +8980,15 @@ static struct hda_input_mux alc861vd_capture_source = {
 	},
 };
 
+static struct hda_input_mux alc861vd_dallas_capture_source = {
+	.num_items = 3,
+	.items = {
+		{ "Front Mic", 0x0 },
+		{ "ATAPI Mic", 0x1 },
+		{ "Line In", 0x5 },
+	},
+};
+
 #define alc861vd_mux_enum_info alc_mux_enum_info
 #define alc861vd_mux_enum_get alc_mux_enum_get
 
@@ -8782,6 +9172,34 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
 	{ } /* end */
 };
 
+/* Pin assignment: Front=0x14, HP = 0x15,
+ *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
+ */
+static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
+	HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
+	HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
+	HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
+	HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
+	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
+	HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
+	HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
+	HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		/* .name = "Capture Source", */
+		.name = "Input Source",
+		.count = 1,
+		.info = alc882_mux_enum_info,
+		.get = alc882_mux_enum_get,
+		.put = alc882_mux_enum_put,
+	},
+	{ } /* end */
+};
+
 /*
  * generic initialization of ADC, input mixers and output mixers
  */
@@ -8969,6 +9387,70 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
 	}
 }
 
+static struct hda_verb alc861vd_dallas_verbs[] = {
+	{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	
+	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
+	{0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+
+	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
+	{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
+	{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
+	{0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+	{0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
+
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
+	{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
+
+	{0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x09, AC_VERB_SET_CONNECT_SEL, 0x00},	
+	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
+
+	{ } /* end */
+};
+
+/* toggle speaker-output according to the hp-jack state */
+static void alc861vd_dallas_automute(struct hda_codec *codec)
+{
+	unsigned int present;
+
+	present = snd_hda_codec_read(codec, 0x15, 0,
+				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+	snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+	snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
+				 0x80, present ? 0x80 : 0);
+}
+
+static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+	if ((res >> 26) == ALC880_HP_EVENT)
+		alc861vd_dallas_automute(codec);
+}
+
 /* pcm configuration: identiacal with ALC880 */
 #define alc861vd_pcm_analog_playback	alc880_pcm_analog_playback
 #define alc861vd_pcm_analog_capture	alc880_pcm_analog_capture
@@ -8984,6 +9466,7 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
 	[ALC861VD_3ST_DIG]	= "3stack-digout",
 	[ALC861VD_6ST_DIG]	= "6stack-digout",
 	[ALC861VD_LENOVO]	= "lenovo",
+	[ALC861VD_DALLAS]	= "dallas",
 	[ALC861VD_AUTO]		= "auto",
 };
 
@@ -8993,6 +9476,8 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
 	SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
 	SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
 
+	SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),
+	SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
 	SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
 	SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
 	{}
@@ -9059,6 +9544,19 @@ static struct alc_config_preset alc861vd_presets[] = {
 		.unsol_event = alc861vd_lenovo_unsol_event,
 		.init_hook = alc861vd_lenovo_automute,
 	},
+	[ALC861VD_DALLAS] = {
+		.mixers = { alc861vd_dallas_mixer },
+		.init_verbs = { alc861vd_dallas_verbs },
+		.num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
+		.dac_nids = alc861vd_dac_nids,
+		.num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
+		.adc_nids = alc861vd_adc_nids,
+		.num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
+		.channel_mode = alc861vd_3stack_2ch_modes,
+		.input_mux = &alc861vd_dallas_capture_source,
+		.unsol_event = alc861vd_dallas_unsol_event,
+		.init_hook = alc861vd_dallas_automute,
+	},	
 };
 
 /*

+ 2 - 0
sound/pci/hda/patch_sigmatel.c

@@ -467,6 +467,8 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = {
 		      "Dell XPS M1710", STAC_REF),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cf,
 		      "Dell Precision M90", STAC_REF),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d6,
+		      "unknown Dell", STAC_REF),
 	{} /* terminator */
 };
 

+ 19 - 1
sound/pci/intel8x0.c

@@ -1797,6 +1797,18 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
 		.name = "Dell Unknown",	/* STAC9750/51 */
 		.type = AC97_TUNE_HP_ONLY
 	},
+	{
+		.subvendor = 0x1028,
+		.subdevice = 0x0186,
+		.name = "Dell Latitude D810", /* cf. Malone #41015 */
+		.type = AC97_TUNE_HP_MUTE_LED
+	},
+	{
+		.subvendor = 0x1028,
+		.subdevice = 0x0188,
+		.name = "Dell Inspiron 6000",
+		.type = AC97_TUNE_HP_MUTE_LED /* cf. Malone #41015 */
+	},
 	{
 		.subvendor = 0x1028,
 		.subdevice = 0x0191,
@@ -1819,7 +1831,7 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
 		.subvendor = 0x103c,
 		.subdevice = 0x088c,
 		.name = "HP nc8000",
-		.type = AC97_TUNE_MUTE_LED
+		.type = AC97_TUNE_HP_MUTE_LED
 	},
 	{
 		.subvendor = 0x103c,
@@ -1911,6 +1923,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
 		.name = "Fujitsu S6210",	/* STAC9750/51 */
 		.type = AC97_TUNE_HP_ONLY
 	},
+	{
+		.subvendor = 0x10cf,
+		.subdevice = 0x127e,
+		.name = "Fujitsu Lifebook C1211D",
+		.type = AC97_TUNE_HP_ONLY
+	},
 	{
 		.subvendor = 0x10cf,
 		.subdevice = 0x12ec,

+ 2 - 1
sound/soc/codecs/ac97.c

@@ -43,8 +43,9 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
 #define STD_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
 		SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
 
-static struct snd_soc_codec_dai ac97_dai = {
+struct snd_soc_codec_dai ac97_dai = {
 	.name = "AC97 HiFi",
+	.type = SND_SOC_DAI_AC97,
 	.playback = {
 		.stream_name = "AC97 Playback",
 		.channels_min = 1,

+ 1 - 0
sound/soc/codecs/wm9712.c

@@ -544,6 +544,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
 struct snd_soc_codec_dai wm9712_dai[] = {
 {
 	.name = "AC97 HiFi",
+	.type = SND_SOC_DAI_AC97_BUS,
 	.playback = {
 		.stream_name = "HiFi Playback",
 		.channels_min = 1,

+ 15 - 3
sound/soc/soc-core.c

@@ -116,6 +116,7 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
 static inline const char* get_dai_name(int type)
 {
 	switch(type) {
+	case SND_SOC_DAI_AC97_BUS:
 	case SND_SOC_DAI_AC97:
 		return "AC97";
 	case SND_SOC_DAI_I2S:
@@ -1099,7 +1100,8 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
 				continue;
 			}
 		}
-		if (socdev->machine->dai_link[i].cpu_dai->type == SND_SOC_DAI_AC97)
+		if (socdev->machine->dai_link[i].codec_dai->type == 
+			SND_SOC_DAI_AC97_BUS)
 			ac97 = 1;
 	}
 	snprintf(codec->card->shortname, sizeof(codec->card->shortname),
@@ -1148,11 +1150,21 @@ EXPORT_SYMBOL_GPL(snd_soc_register_card);
 void snd_soc_free_pcms(struct snd_soc_device *socdev)
 {
 	struct snd_soc_codec *codec = socdev->codec;
+#ifdef CONFIG_SND_SOC_AC97_BUS
+	struct snd_soc_codec_dai *codec_dai;
+	int i;
+#endif
 
 	mutex_lock(&codec->mutex);
 #ifdef CONFIG_SND_SOC_AC97_BUS
-	if (codec->ac97)
-		soc_ac97_dev_unregister(codec);
+	for(i = 0; i < codec->num_dai; i++) {
+		codec_dai = &codec->dai[i];
+		if (codec_dai->type == SND_SOC_DAI_AC97_BUS && codec->ac97) {
+			soc_ac97_dev_unregister(codec);
+			goto free_card;
+		}
+	}
+free_card:
 #endif
 
 	if (codec->card)

+ 1 - 1
sound/usb/usbmixer.c

@@ -360,7 +360,7 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali
 				    request,
 				    USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
 				    validx, cval->mixer->ctrlif | (cval->id << 8),
-				    buf, val_len, 100) >= 0) {
+				    buf, val_len, 100) >= val_len) {
 			*value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len));
 			return 0;
 		}

+ 9 - 0
sound/usb/usbquirks.h

@@ -43,6 +43,15 @@
  * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface
  * class matches do not take effect without an explicit ID match.
  */
+{
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+		       USB_DEVICE_ID_MATCH_INT_CLASS |
+		       USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+	.idVendor = 0x046d,
+	.idProduct = 0x0850,
+	.bInterfaceClass = USB_CLASS_AUDIO,
+	.bInterfaceSubClass = USB_SUBCLASS_AUDIO_CONTROL
+},
 {
 	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
 		       USB_DEVICE_ID_MATCH_INT_CLASS |