diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 88b7c1cf65a25ea9035dbcff7b4e7ea30cf6bef0..5d80edfc61b7f61f36ed0183c886921c8a79ffd1 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-git14
-# Sat Dec  9 21:23:14 2006
+# Linux kernel version: 2.6.20-rc3
+# Fri Jan  5 11:54:46 2007
 #
 CONFIG_X86_32=y
 CONFIG_GENERIC_TIME=y
@@ -1286,6 +1286,11 @@ CONFIG_USB_MON=y
 # DMA Devices
 #
 
+#
+# Virtualization
+#
+# CONFIG_KVM is not set
+
 #
 # File systems
 #
@@ -1471,6 +1476,8 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_UNUSED_SYMBOLS=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1489,12 +1496,10 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_HIGHMEM is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_FORCED_INLINING is not set
-# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 CONFIG_EARLY_PRINTK=y
@@ -1527,6 +1532,7 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_PENDING_IRQ=y
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 2ce67228dff8a28e634b714b03e1898aa9fd3b7c..49bff3596bffd980862fcfd4480268a6b55131c1 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -36,7 +36,7 @@
 
 /* Have we found an MP table */
 int smp_found_config;
-unsigned int __initdata maxcpus = NR_CPUS;
+unsigned int __cpuinitdata maxcpus = NR_CPUS;
 
 /*
  * Various Linux-internal data structures created from the
@@ -102,9 +102,9 @@ static int __init mpf_checksum(unsigned char *mp, int len)
  */
 
 static int mpc_record; 
-static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata;
+static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __cpuinitdata;
 
-static void __devinit MP_processor_info (struct mpc_config_processor *m)
+static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
 {
  	int ver, apicid;
 	physid_mask_t phys_cpu;
@@ -822,7 +822,7 @@ void __init mp_register_lapic_address(u64 address)
 	Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid);
 }
 
-void __devinit mp_register_lapic (u8 id, u8 enabled)
+void __cpuinit mp_register_lapic (u8 id, u8 enabled)
 {
 	struct mpc_config_processor processor;
 	int boot_cpu = 0;
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 6f6cb7b31d18a6384f7debe36040fd4ae80ff07e..4b31ad70c1ac6699c6710faf415ec6e1c30d488b 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -77,7 +77,7 @@ extern struct resource code_resource;
 extern struct resource data_resource;
 
 /* cpu data as detected by the assembly code in head.S */
-struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
+struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
 /* common cpu data for all cpus */
 struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
 EXPORT_SYMBOL(boot_cpu_data);
@@ -495,7 +495,7 @@ static void set_mca_bus(int x) { }
 #endif
 
 /* Overridden in paravirt.c if CONFIG_PARAVIRT */
-char * __attribute__((weak)) memory_setup(void)
+char * __init __attribute__((weak)) memory_setup(void)
 {
 	return machine_specific_memory_setup();
 }
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 300d9b38d02ec449ebbe9817743b5bf8a639743b..dea7ef9d3e82804ea6b87089cafd88c435223113 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -159,7 +159,7 @@ void __init smp_alloc_memory(void)
  * a given CPU
  */
 
-static void __devinit smp_store_cpu_info(int id)
+static void __cpuinit smp_store_cpu_info(int id)
 {
 	struct cpuinfo_x86 *c = cpu_data + id;
 
@@ -364,7 +364,7 @@ extern void calibrate_delay(void);
 
 static atomic_t init_deasserted;
 
-static void __devinit smp_callin(void)
+static void __cpuinit smp_callin(void)
 {
 	int cpuid, phys_id;
 	unsigned long timeout;
@@ -538,7 +538,7 @@ set_cpu_sibling_map(int cpu)
 /*
  * Activate a secondary processor.
  */
-static void __devinit start_secondary(void *unused)
+static void __cpuinit start_secondary(void *unused)
 {
 	/*
 	 * Don't put *anything* before secondary_cpu_init(), SMP
@@ -931,7 +931,7 @@ static inline struct task_struct * alloc_idle_task(int cpu)
 #define alloc_idle_task(cpu) fork_idle(cpu)
 #endif
 
-static int __devinit do_boot_cpu(int apicid, int cpu)
+static int __cpuinit do_boot_cpu(int apicid, int cpu)
 /*
  * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
  * (ie clustered apic addressing mode), this is a LOGICAL apic ID.
@@ -1432,7 +1432,7 @@ void __cpu_die(unsigned int cpu)
 }
 #endif /* CONFIG_HOTPLUG_CPU */
 
-int __devinit __cpu_up(unsigned int cpu)
+int __cpuinit __cpu_up(unsigned int cpu)
 {
 #ifdef CONFIG_HOTPLUG_CPU
 	int ret=0;
diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c
index 33d9f93557badd2d1a466ba5268cf81665904e67..8a210fa915b5fd300e1a9ef0771bbdcb354ecadd 100644
--- a/arch/i386/mach-generic/bigsmp.c
+++ b/arch/i386/mach-generic/bigsmp.c
@@ -45,7 +45,7 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = {
 };
 
 
-static __init int probe_bigsmp(void)
+static int probe_bigsmp(void)
 { 
 	if (def_to_bigsmp)
         	dmi_bigsmp = 1;
diff --git a/arch/i386/mach-generic/default.c b/arch/i386/mach-generic/default.c
index 96c19821e47d6546c288e28edd8ec1120ab095ee..8685208d85125fab08ba234a4dcaafdfbf6894dd 100644
--- a/arch/i386/mach-generic/default.c
+++ b/arch/i386/mach-generic/default.c
@@ -18,7 +18,7 @@
 #include <asm/mach-default/mach_mpparse.h>
 
 /* should be called last. */
-static __init int probe_default(void)
+static int probe_default(void)
 { 
 	return 1;
 } 
diff --git a/arch/i386/mach-generic/es7000.c b/arch/i386/mach-generic/es7000.c
index aa144d82334de969c921f70b04ca1fb41fc46fc5..b8963a5a3b25e3eba94760585927c342fa18c9a8 100644
--- a/arch/i386/mach-generic/es7000.c
+++ b/arch/i386/mach-generic/es7000.c
@@ -19,7 +19,7 @@
 #include <asm/mach-es7000/mach_mpparse.h>
 #include <asm/mach-es7000/mach_wakecpu.h>
 
-static __init int probe_es7000(void)
+static int probe_es7000(void)
 {
 	/* probed later in mptable/ACPI hooks */
 	return 0;
diff --git a/arch/i386/mach-generic/summit.c b/arch/i386/mach-generic/summit.c
index f7e5d66648dc1ee16d30981e49847ffc509077b6..74883ccb8f73c75b027213f858e9a06e7649170d 100644
--- a/arch/i386/mach-generic/summit.c
+++ b/arch/i386/mach-generic/summit.c
@@ -18,7 +18,7 @@
 #include <asm/mach-summit/mach_ipi.h>
 #include <asm/mach-summit/mach_mpparse.h>
 
-static __init int probe_summit(void)
+static int probe_summit(void)
 { 
 	/* probed later in mptable/ACPI hooks */
 	return 0;
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 60a7e57af19796fb7876222e67bf76d64dc2fb15..c5c5ea700cc708ae0e08388bfc492da509f173eb 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -283,7 +283,7 @@ void __init add_one_highpage_init(struct page *page, int pfn, int bad_ppro)
 		SetPageReserved(page);
 }
 
-static int add_one_highpage_hotplug(struct page *page, unsigned long pfn)
+static int __meminit add_one_highpage_hotplug(struct page *page, unsigned long pfn)
 {
 	free_new_highpage(page);
 	totalram_pages++;
@@ -300,7 +300,7 @@ static int add_one_highpage_hotplug(struct page *page, unsigned long pfn)
  * has been added dynamically that would be
  * onlined here is in HIGHMEM
  */
-void online_page(struct page *page)
+void __meminit online_page(struct page *page)
 {
 	ClearPageReserved(page);
 	add_one_highpage_hotplug(page, page_to_pfn(page));
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 9cc7c21547a23f41d0f62cf41223037307b2f474..69584c2953057fdda7b69b723920ecd8dbb38185 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.19-git14
-# Sat Dec  9 21:23:09 2006
+# Linux kernel version: 2.6.20-rc3
+# Fri Jan  5 11:54:41 2007
 #
 CONFIG_X86_64=y
 CONFIG_64BIT=y
@@ -1056,6 +1056,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
 # CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
@@ -1066,6 +1067,7 @@ CONFIG_SENSORS_SMSC47B397=m
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83791D is not set
 # CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
@@ -1310,6 +1312,11 @@ CONFIG_USB_MON=y
 # DMA Devices
 #
 
+#
+# Virtualization
+#
+# CONFIG_KVM is not set
+
 #
 # Firmware Drivers
 #
@@ -1502,6 +1509,8 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 # CONFIG_ENABLE_MUST_CHECK is not set
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_DETECT_SOFTLOCKUP=y
@@ -1519,12 +1528,10 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_FORCED_INLINING is not set
-# CONFIG_HEADERS_CHECK is not set
 # CONFIG_RCU_TORTURE_TEST is not set
 # CONFIG_LKDTM is not set
 # CONFIG_DEBUG_RODATA is not set
@@ -1553,3 +1560,4 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_PLIST=y
+CONFIG_IOMAP_COPY=y
diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
index be87df506f39dded7f4426bf518f4d36656d46d3..fe83edb93c1029e3a33b02da0f8619f1accc27e6 100644
--- a/arch/x86_64/ia32/ia32_aout.c
+++ b/arch/x86_64/ia32/ia32_aout.c
@@ -241,7 +241,7 @@ static u32 __user *create_aout_tables(char __user *p, struct linux_binprm *bprm)
 			get_user(c,p++);
 		} while (c);
 	}
-	put_user(NULL,argv);
+	put_user(0, argv);
 	current->mm->arg_end = current->mm->env_start = (unsigned long) p;
 	while (envc-->0) {
 		char c;
@@ -250,7 +250,7 @@ static u32 __user *create_aout_tables(char __user *p, struct linux_binprm *bprm)
 			get_user(c,p++);
 		} while (c);
 	}
-	put_user(NULL,envp);
+	put_user(0, envp);
 	current->mm->env_end = (unsigned long) p;
 	return sp;
 }
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index 87d90cb68a743be271da231719cc025580a087bf..3d65b1d4c2b39e4110dc913159615089e4a5ab02 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -1068,6 +1068,8 @@ void __init detect_calgary(void)
 	if (!early_pci_allowed())
 		return;
 
+	printk(KERN_DEBUG "Calgary: detecting Calgary via BIOS EBDA area\n");
+
 	ptr = (unsigned long)phys_to_virt(get_bios_ebda());
 
 	rio_table_hdr = NULL;
@@ -1088,14 +1090,14 @@ void __init detect_calgary(void)
 		offset = *((unsigned short *)(ptr + offset));
 	}
 	if (!rio_table_hdr) {
-		printk(KERN_ERR "Calgary: Unable to locate "
-				"Rio Grande Table in EBDA - bailing!\n");
+		printk(KERN_DEBUG "Calgary: Unable to locate Rio Grande table "
+		       "in EBDA - bailing!\n");
 		return;
 	}
 
 	ret = build_detail_arrays();
 	if (ret) {
-		printk(KERN_ERR "Calgary: build_detail_arrays ret %d\n", ret);
+		printk(KERN_DEBUG "Calgary: build_detail_arrays ret %d\n", ret);
 		return;
 	}
 
@@ -1128,6 +1130,9 @@ void __init detect_calgary(void)
 		}
 	}
 
+	printk(KERN_DEBUG "Calgary: finished detection, Calgary %s\n",
+	       calgary_found ? "found" : "not found");
+
 	if (calgary_found) {
 		iommu_detected = 1;
 		calgary_detected = 1;
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
index 9f05bc9b2dad7023573de34d6f33260eb0c9fe33..5cc76d0d331f0d0fe2b1f7913d7705887112b073 100644
--- a/arch/x86_64/kernel/time.c
+++ b/arch/x86_64/kernel/time.c
@@ -656,6 +656,25 @@ core_initcall(cpufreq_tsc);
  */
 
 #define TICK_COUNT 100000000
+#define TICK_MIN   5000
+
+/*
+ * Some platforms take periodic SMI interrupts with 5ms duration. Make sure none
+ * occurs between the reads of the hpet & TSC.
+ */
+static void __init read_hpet_tsc(int *hpet, int *tsc)
+{
+	int tsc1, tsc2, hpet1;
+
+	do {
+		tsc1 = get_cycles_sync();
+		hpet1 = hpet_readl(HPET_COUNTER);
+		tsc2 = get_cycles_sync();
+	} while (tsc2 - tsc1 > TICK_MIN);
+	*hpet = hpet1;
+	*tsc = tsc2;
+}
+
 
 static unsigned int __init hpet_calibrate_tsc(void)
 {
@@ -666,13 +685,11 @@ static unsigned int __init hpet_calibrate_tsc(void)
 	local_irq_save(flags);
 	local_irq_disable();
 
-	hpet_start = hpet_readl(HPET_COUNTER);
-	rdtscl(tsc_start);
+	read_hpet_tsc(&hpet_start, &tsc_start);
 
 	do {
 		local_irq_disable();
-		hpet_now = hpet_readl(HPET_COUNTER);
-		tsc_now = get_cycles_sync();
+		read_hpet_tsc(&hpet_now, &tsc_now);
 		local_irq_restore(flags);
 	} while ((tsc_now - tsc_start) < TICK_COUNT &&
 		 (hpet_now - hpet_start) < TICK_COUNT);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 0535efc4f184ac26bcc7cd04447b142fb8db60db..0a70943f8bb6b5748ae3cf16d9da429b7120f9ec 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -955,7 +955,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho
  * becomes necessary to do this tweak in two steps -- I've chosen the Host
  * bridge as trigger.
  */
-static int __initdata asus_hides_smbus;
+static int asus_hides_smbus;
 
 static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
 {
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 51f3c739f7e1b87943734ae1fd746c72492891eb..5261f0af8b101bcf4e1149caebdb484bbe92aa70 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2296,7 +2296,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
 	local_irq_restore(flags);
 }
 
-static int serial8250_console_setup(struct console *co, char *options)
+static int __init serial8250_console_setup(struct console *co, char *options)
 {
 	struct uart_port *port;
 	int baud = 9600;
diff --git a/include/asm-x86_64/bitops.h b/include/asm-x86_64/bitops.h
index 5b535eaf5309b08252097cbcb630fb6afee89a72..8da9609070f471eaac12ae7269c4479eca459b1e 100644
--- a/include/asm-x86_64/bitops.h
+++ b/include/asm-x86_64/bitops.h
@@ -7,7 +7,13 @@
 
 #include <asm/alternative.h>
 
-#define ADDR (*(volatile long *) addr)
+#if __GNUC__ < 4 || __GNUC_MINOR__ < 1
+/* Technically wrong, but this avoids compilation errors on some gcc
+   versions. */
+#define ADDR "=m" (*(volatile long *) addr)
+#else
+#define ADDR "+m" (*(volatile long *) addr)
+#endif
 
 /**
  * set_bit - Atomically set a bit in memory
@@ -23,7 +29,7 @@ static __inline__ void set_bit(int nr, volatile void * addr)
 {
 	__asm__ __volatile__( LOCK_PREFIX
 		"btsl %1,%0"
-		:"+m" (ADDR)
+		:ADDR
 		:"dIr" (nr) : "memory");
 }
 
@@ -40,7 +46,7 @@ static __inline__ void __set_bit(int nr, volatile void * addr)
 {
 	__asm__ volatile(
 		"btsl %1,%0"
-		:"+m" (ADDR)
+		:ADDR
 		:"dIr" (nr) : "memory");
 }
 
@@ -58,7 +64,7 @@ static __inline__ void clear_bit(int nr, volatile void * addr)
 {
 	__asm__ __volatile__( LOCK_PREFIX
 		"btrl %1,%0"
-		:"+m" (ADDR)
+		:ADDR
 		:"dIr" (nr));
 }
 
@@ -66,7 +72,7 @@ static __inline__ void __clear_bit(int nr, volatile void * addr)
 {
 	__asm__ __volatile__(
 		"btrl %1,%0"
-		:"+m" (ADDR)
+		:ADDR
 		:"dIr" (nr));
 }
 
@@ -86,7 +92,7 @@ static __inline__ void __change_bit(int nr, volatile void * addr)
 {
 	__asm__ __volatile__(
 		"btcl %1,%0"
-		:"+m" (ADDR)
+		:ADDR
 		:"dIr" (nr));
 }
 
@@ -103,7 +109,7 @@ static __inline__ void change_bit(int nr, volatile void * addr)
 {
 	__asm__ __volatile__( LOCK_PREFIX
 		"btcl %1,%0"
-		:"+m" (ADDR)
+		:ADDR
 		:"dIr" (nr));
 }
 
@@ -121,7 +127,7 @@ static __inline__ int test_and_set_bit(int nr, volatile void * addr)
 
 	__asm__ __volatile__( LOCK_PREFIX
 		"btsl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit),"+m" (ADDR)
+		:"=r" (oldbit),ADDR
 		:"dIr" (nr) : "memory");
 	return oldbit;
 }
@@ -141,7 +147,7 @@ static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
 
 	__asm__(
 		"btsl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit),"+m" (ADDR)
+		:"=r" (oldbit),ADDR
 		:"dIr" (nr));
 	return oldbit;
 }
@@ -160,7 +166,7 @@ static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
 
 	__asm__ __volatile__( LOCK_PREFIX
 		"btrl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit),"+m" (ADDR)
+		:"=r" (oldbit),ADDR
 		:"dIr" (nr) : "memory");
 	return oldbit;
 }
@@ -180,7 +186,7 @@ static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
 
 	__asm__(
 		"btrl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit),"+m" (ADDR)
+		:"=r" (oldbit),ADDR
 		:"dIr" (nr));
 	return oldbit;
 }
@@ -192,7 +198,7 @@ static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
 
 	__asm__ __volatile__(
 		"btcl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit),"+m" (ADDR)
+		:"=r" (oldbit),ADDR
 		:"dIr" (nr) : "memory");
 	return oldbit;
 }
@@ -211,7 +217,7 @@ static __inline__ int test_and_change_bit(int nr, volatile void * addr)
 
 	__asm__ __volatile__( LOCK_PREFIX
 		"btcl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit),"+m" (ADDR)
+		:"=r" (oldbit),ADDR
 		:"dIr" (nr) : "memory");
 	return oldbit;
 }
@@ -237,7 +243,7 @@ static __inline__ int variable_test_bit(int nr, volatile const void * addr)
 	__asm__ __volatile__(
 		"btl %2,%1\n\tsbbl %0,%0"
 		:"=r" (oldbit)
-		:"m" (ADDR),"dIr" (nr));
+		:"m" (*(volatile long *)addr),"dIr" (nr));
 	return oldbit;
 }
 
diff --git a/init/main.c b/init/main.c
index d908d3e03344331768e0a0fbb87f7327a767e982..8b4a7d76916235df139b98bd41019a228615a2dd 100644
--- a/init/main.c
+++ b/init/main.c
@@ -695,7 +695,7 @@ static void __init do_basic_setup(void)
 	do_initcalls();
 }
 
-static void do_pre_smp_initcalls(void)
+static void __init do_pre_smp_initcalls(void)
 {
 	extern int spawn_ksoftirqd(void);
 #ifdef CONFIG_SMP
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 543ea2e5ad9301944ab520303bd7fe84e4e92f88..9d8c79b48823fdfb44d27fe3a3bf1c7adc9cdbc7 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -176,7 +176,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
 
 int noirqdebug __read_mostly;
 
-int __init noirqdebug_setup(char *str)
+int noirqdebug_setup(char *str)
 {
 	noirqdebug = 1;
 	printk(KERN_INFO "IRQ lockup detection disabled\n");
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 15ab5d02e80a1689a554dac4893cd1edb910c26c..2aa47623f5f8cec51322f883b60d6c932722663c 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -582,9 +582,19 @@ static int strrcmp(const char *s, const char *sub)
  *   tosec   = .init.text | .exit.text | .init.data
  *   fromsec = .data
  *   atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one
+ *
+ * Pattern 3:
+ *   Some symbols belong to init section but still it is ok to reference
+ *   these from non-init sections as these symbols don't have any memory
+ *   allocated for them and symbol address and value are same. So even
+ *   if init section is freed, its ok to reference those symbols.
+ *   For ex. symbols marking the init section boundaries.
+ *   This pattern is identified by
+ *   refsymname = __init_begin, _sinittext, _einittext
  **/
 static int secref_whitelist(const char *modname, const char *tosec,
-			    const char *fromsec, const char *atsym)
+			    const char *fromsec, const char *atsym,
+			    const char *refsymname)
 {
 	int f1 = 1, f2 = 1;
 	const char **s;
@@ -595,6 +605,14 @@ static int secref_whitelist(const char *modname, const char *tosec,
 		"_ops",
 		"_probe",
 		"_probe_one",
+		"_console",
+		NULL
+	};
+
+	const char *pat3refsym[] = {
+		"__init_begin",
+		"_sinittext",
+		"_einittext",
 		NULL
 	};
 
@@ -628,6 +646,11 @@ static int secref_whitelist(const char *modname, const char *tosec,
 		if ((strcmp(fromsec, ".pci_fixup") == 0) &&
 		    (strcmp(tosec, ".init.text") == 0))
 		return 1;
+
+		/* Check for pattern 3 */
+		for (s = pat3refsym; *s; s++)
+			if (strcmp(refsymname, *s) == 0)
+				return 1;
 	}
 	return 0;
 }
@@ -737,7 +760,7 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
 	/* check whitelist - we may ignore it */
 	if (before &&
 	    secref_whitelist(modname, secname, fromsec,
-			     elf->strtab + before->st_name))
+			     elf->strtab + before->st_name, refsymname))
 		return;
 
 	if (before && after) {