--- /dev/null
+From 2550326ac7a062fdfc204f9a3b98bdb9179638fc Mon Sep 17 00:00:00 2001
+From: Randy Dunlap <randy.dunlap@oracle.com>
+Date: Thu, 20 Jan 2011 14:44:31 -0800
+Subject: backlight: fix 88pm860x_bl macro collision
+
+From: Randy Dunlap <randy.dunlap@oracle.com>
+
+commit 2550326ac7a062fdfc204f9a3b98bdb9179638fc upstream.
+
+Fix collision with kernel-supplied #define:
+
+ drivers/video/backlight/88pm860x_bl.c:24:1: warning: "CURRENT_MASK" redefined
+ arch/x86/include/asm/page_64_types.h:6:1: warning: this is the location of the previous definition
+
+Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com>
+Cc: Haojian Zhuang <haojian.zhuang@marvell.com>
+Cc: Richard Purdie <rpurdie@rpsys.net>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/video/backlight/88pm860x_bl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/video/backlight/88pm860x_bl.c
++++ b/drivers/video/backlight/88pm860x_bl.c
+@@ -21,7 +21,7 @@
+ #define MAX_BRIGHTNESS (0xFF)
+ #define MIN_BRIGHTNESS (0)
+
+-#define CURRENT_MASK (0x1F << 1)
++#define CURRENT_BITMASK (0x1F << 1)
+
+ struct pm860x_backlight_data {
+ struct pm860x_chip *chip;
+@@ -85,7 +85,7 @@ static int pm860x_backlight_set(struct b
+ if ((data->current_brightness == 0) && brightness) {
+ if (data->iset) {
+ ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
+- CURRENT_MASK, data->iset);
++ CURRENT_BITMASK, data->iset);
+ if (ret < 0)
+ goto out;
+ }
--- /dev/null
+From d2478521afc20227658a10a8c5c2bf1a2aa615b3 Mon Sep 17 00:00:00 2001
+From: Corey Minyard <minyard@acm.org>
+Date: Thu, 10 Feb 2011 16:08:38 -0600
+Subject: char/ipmi: fix OOPS caused by pnp_unregister_driver on unregistered driver
+
+From: Corey Minyard <minyard@acm.org>
+
+commit d2478521afc20227658a10a8c5c2bf1a2aa615b3 upstream.
+
+This patch fixes an OOPS triggered when calling modprobe ipmi_si a
+second time after the first modprobe returned without finding any ipmi
+devices. This can happen if you reload the module after having the
+first module load fail. The driver was not deregistering from PNP in
+that case.
+
+Peter Huewe originally reported this patch and supplied a fix, I have a
+different patch based on Linus' suggestion that cleans things up a bit
+more.
+
+Cc: openipmi-developer@lists.sourceforge.net
+Reviewed-by: Peter Huewe <peterhuewe@gmx.de>
+Cc: Randy Dunlap <randy.dunlap@oracle.com>
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/char/ipmi/ipmi_si_intf.c | 12 ++----------
+ 1 file changed, 2 insertions(+), 10 deletions(-)
+
+--- a/drivers/char/ipmi/ipmi_si_intf.c
++++ b/drivers/char/ipmi/ipmi_si_intf.c
+@@ -320,6 +320,7 @@ static int unload_when_empty = 1;
+ static int add_smi(struct smi_info *smi);
+ static int try_smi_init(struct smi_info *smi);
+ static void cleanup_one_si(struct smi_info *to_clean);
++static void cleanup_ipmi_si(void);
+
+ static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list);
+ static int register_xaction_notifier(struct notifier_block *nb)
+@@ -3436,16 +3437,7 @@ static __devinit int init_ipmi_si(void)
+ mutex_lock(&smi_infos_lock);
+ if (unload_when_empty && list_empty(&smi_infos)) {
+ mutex_unlock(&smi_infos_lock);
+-#ifdef CONFIG_PCI
+- if (pci_registered)
+- pci_unregister_driver(&ipmi_pci_driver);
+-#endif
+-
+-#ifdef CONFIG_PPC_OF
+- if (of_registered)
+- of_unregister_platform_driver(&ipmi_of_platform_driver);
+-#endif
+- driver_unregister(&ipmi_driver.driver);
++ cleanup_ipmi_si();
+ printk(KERN_WARNING PFX
+ "Unable to find any System Interface(s)\n");
+ return -ENODEV;
--- /dev/null
+From 20d9600cb407b0b55fef6ee814b60345c6f58264 Mon Sep 17 00:00:00 2001
+From: David Dillow <dillowda@ornl.gov>
+Date: Thu, 20 Jan 2011 14:44:22 -0800
+Subject: fs/direct-io.c: don't try to allocate more than BIO_MAX_PAGES in a bio
+
+From: David Dillow <dillowda@ornl.gov>
+
+commit 20d9600cb407b0b55fef6ee814b60345c6f58264 upstream.
+
+When using devices that support max_segments > BIO_MAX_PAGES (256), direct
+IO tries to allocate a bio with more pages than allowed, which leads to an
+oops in dio_bio_alloc(). Clamp the request to the supported maximum, and
+change dio_bio_alloc() to reflect that bio_alloc() will always return a
+bio when called with __GFP_WAIT and a valid number of vectors.
+
+[akpm@linux-foundation.org: remove redundant BUG_ON()]
+Signed-off-by: David Dillow <dillowda@ornl.gov>
+Reviewed-by: Jeff Moyer <jmoyer@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/direct-io.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+--- a/fs/direct-io.c
++++ b/fs/direct-io.c
+@@ -325,12 +325,16 @@ void dio_end_io(struct bio *bio, int err
+ }
+ EXPORT_SYMBOL_GPL(dio_end_io);
+
+-static int
++static void
+ dio_bio_alloc(struct dio *dio, struct block_device *bdev,
+ sector_t first_sector, int nr_vecs)
+ {
+ struct bio *bio;
+
++ /*
++ * bio_alloc() is guaranteed to return a bio when called with
++ * __GFP_WAIT and we request a valid number of vectors.
++ */
+ bio = bio_alloc(GFP_KERNEL, nr_vecs);
+
+ bio->bi_bdev = bdev;
+@@ -342,7 +346,6 @@ dio_bio_alloc(struct dio *dio, struct bl
+
+ dio->bio = bio;
+ dio->logical_offset_in_bio = dio->cur_page_fs_offset;
+- return 0;
+ }
+
+ /*
+@@ -583,8 +586,9 @@ static int dio_new_bio(struct dio *dio,
+ goto out;
+ sector = start_sector << (dio->blkbits - 9);
+ nr_pages = min(dio->pages_in_io, bio_get_nr_vecs(dio->map_bh.b_bdev));
++ nr_pages = min(nr_pages, BIO_MAX_PAGES);
+ BUG_ON(nr_pages <= 0);
+- ret = dio_bio_alloc(dio, dio->map_bh.b_bdev, sector, nr_pages);
++ dio_bio_alloc(dio, dio->map_bh.b_bdev, sector, nr_pages);
+ dio->boundary = 0;
+ out:
+ return ret;
--- /dev/null
+From 6dc19899958e420a931274b94019e267e2396d3e Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Thu, 20 Jan 2011 14:44:33 -0800
+Subject: kernel/smp.c: fix smp_call_function_many() SMP race
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 6dc19899958e420a931274b94019e267e2396d3e upstream.
+
+I noticed a failure where we hit the following WARN_ON in
+generic_smp_call_function_interrupt:
+
+ if (!cpumask_test_and_clear_cpu(cpu, data->cpumask))
+ continue;
+
+ data->csd.func(data->csd.info);
+
+ refs = atomic_dec_return(&data->refs);
+ WARN_ON(refs < 0); <-------------------------
+
+We atomically tested and cleared our bit in the cpumask, and yet the
+number of cpus left (ie refs) was 0. How can this be?
+
+It turns out commit 54fdade1c3332391948ec43530c02c4794a38172
+("generic-ipi: make struct call_function_data lockless") is at fault. It
+removes locking from smp_call_function_many and in doing so creates a
+rather complicated race.
+
+The problem comes about because:
+
+ - The smp_call_function_many interrupt handler walks call_function.queue
+ without any locking.
+ - We reuse a percpu data structure in smp_call_function_many.
+ - We do not wait for any RCU grace period before starting the next
+ smp_call_function_many.
+
+Imagine a scenario where CPU A does two smp_call_functions back to back,
+and CPU B does an smp_call_function in between. We concentrate on how CPU
+C handles the calls:
+
+CPU A CPU B CPU C CPU D
+
+smp_call_function
+ smp_call_function_interrupt
+ walks
+ call_function.queue sees
+ data from CPU A on list
+
+ smp_call_function
+
+ smp_call_function_interrupt
+ walks
+
+ call_function.queue sees
+ (stale) CPU A on list
+ smp_call_function int
+ clears last ref on A
+ list_del_rcu, unlock
+smp_call_function reuses
+percpu *data A
+ data->cpumask sees and
+ clears bit in cpumask
+ might be using old or new fn!
+ decrements refs below 0
+
+set data->refs (too late!)
+
+The important thing to note is since the interrupt handler walks a
+potentially stale call_function.queue without any locking, then another
+cpu can view the percpu *data structure at any time, even when the owner
+is in the process of initialising it.
+
+The following test case hits the WARN_ON 100% of the time on my PowerPC
+box (having 128 threads does help :)
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#define ITERATIONS 100
+
+static void do_nothing_ipi(void *dummy)
+{
+}
+
+static void do_ipis(struct work_struct *dummy)
+{
+ int i;
+
+ for (i = 0; i < ITERATIONS; i++)
+ smp_call_function(do_nothing_ipi, NULL, 1);
+
+ printk(KERN_DEBUG "cpu %d finished\n", smp_processor_id());
+}
+
+static struct work_struct work[NR_CPUS];
+
+static int __init testcase_init(void)
+{
+ int cpu;
+
+ for_each_online_cpu(cpu) {
+ INIT_WORK(&work[cpu], do_ipis);
+ schedule_work_on(cpu, &work[cpu]);
+ }
+
+ return 0;
+}
+
+static void __exit testcase_exit(void)
+{
+}
+
+module_init(testcase_init)
+module_exit(testcase_exit)
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Anton Blanchard");
+
+I tried to fix it by ordering the read and the write of ->cpumask and
+->refs. In doing so I missed a critical case but Paul McKenney was able
+to spot my bug thankfully :) To ensure we arent viewing previous
+iterations the interrupt handler needs to read ->refs then ->cpumask then
+->refs _again_.
+
+Thanks to Milton Miller and Paul McKenney for helping to debug this issue.
+
+[miltonm@bga.com: add WARN_ON and BUG_ON, remove extra read of refs before initial read of mask that doesn't help (also noted by Peter Zijlstra), adjust comments, hopefully clarify scenario ]
+[miltonm@bga.com: remove excess tests]
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Milton Miller <miltonm@bga.com>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/smp.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+--- a/kernel/smp.c
++++ b/kernel/smp.c
+@@ -194,6 +194,24 @@ void generic_smp_call_function_interrupt
+ list_for_each_entry_rcu(data, &call_function.queue, csd.list) {
+ int refs;
+
++ /*
++ * Since we walk the list without any locks, we might
++ * see an entry that was completed, removed from the
++ * list and is in the process of being reused.
++ *
++ * We must check that the cpu is in the cpumask before
++ * checking the refs, and both must be set before
++ * executing the callback on this cpu.
++ */
++
++ if (!cpumask_test_cpu(cpu, data->cpumask))
++ continue;
++
++ smp_rmb();
++
++ if (atomic_read(&data->refs) == 0)
++ continue;
++
+ if (!cpumask_test_and_clear_cpu(cpu, data->cpumask))
+ continue;
+
+@@ -202,6 +220,8 @@ void generic_smp_call_function_interrupt
+ refs = atomic_dec_return(&data->refs);
+ WARN_ON(refs < 0);
+ if (!refs) {
++ WARN_ON(!cpumask_empty(data->cpumask));
++
+ raw_spin_lock(&call_function.lock);
+ list_del_rcu(&data->csd.list);
+ raw_spin_unlock(&call_function.lock);
+@@ -453,11 +473,21 @@ void smp_call_function_many(const struct
+
+ data = &__get_cpu_var(cfd_data);
+ csd_lock(&data->csd);
++ BUG_ON(atomic_read(&data->refs) || !cpumask_empty(data->cpumask));
+
+ data->csd.func = func;
+ data->csd.info = info;
+ cpumask_and(data->cpumask, mask, cpu_online_mask);
+ cpumask_clear_cpu(this_cpu, data->cpumask);
++
++ /*
++ * To ensure the interrupt handler gets an complete view
++ * we order the cpumask and refs writes and order the read
++ * of them in the interrupt handler. In addition we may
++ * only clear our own cpu bit from the mask.
++ */
++ smp_wmb();
++
+ atomic_set(&data->refs, cpumask_weight(data->cpumask));
+
+ raw_spin_lock_irqsave(&call_function.lock, flags);
--- /dev/null
+From fbea668498e93bb38ac9226c7af9120a25957375 Mon Sep 17 00:00:00 2001
+From: Guy Martin <gmsoft@tuxicoman.be>
+Date: Mon, 6 Dec 2010 16:48:04 +0100
+Subject: parisc : Remove broken line wrapping handling pdc_iodc_print()
+
+From: Guy Martin <gmsoft@tuxicoman.be>
+
+commit fbea668498e93bb38ac9226c7af9120a25957375 upstream.
+
+Remove the broken line wrapping handling in pdc_iodc_print().
+It is broken in 3 ways :
+ - It doesn't keep track of the current screen position, it just
+ assumes that the new buffer will be printed at the begining of the
+ screen.
+ - It doesn't take in account that non printable characters won't
+ increase the current position on the screen.
+ - And last but not least, it triggers a kernel panic if a backspace
+ is the first char in the provided buffer :
+
+ Backtrace:
+ [<0000000040128ec4>] pdc_console_write+0x44/0x78
+ [<0000000040128f18>] pdc_console_tty_write+0x20/0x38
+ [<000000004032f1ac>] n_tty_write+0x2a4/0x550
+ [<000000004032b158>] tty_write+0x1e0/0x2d8
+ [<00000000401bb420>] vfs_write+0xb8/0x188
+ [<00000000401bb630>] sys_write+0x68/0xb8
+ [<0000000040104eb8>] syscall_exit+0x0/0x14
+
+Most terminals handle the line wrapping just fine. I've confirmed that
+it works correctly on a C8000 with both vga and serial output.
+
+Signed-off-by: Guy Martin <gmsoft@tuxicoman.be>
+Signed-off-by: James Bottomley <James.Bottomley@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/parisc/kernel/firmware.c | 13 +------------
+ 1 file changed, 1 insertion(+), 12 deletions(-)
+
+--- a/arch/parisc/kernel/firmware.c
++++ b/arch/parisc/kernel/firmware.c
+@@ -1126,15 +1126,13 @@ int pdc_iodc_print(const unsigned char *
+ unsigned int i;
+ unsigned long flags;
+
+- for (i = 0; i < count && i < 79;) {
++ for (i = 0; i < count;) {
+ switch(str[i]) {
+ case '\n':
+ iodc_dbuf[i+0] = '\r';
+ iodc_dbuf[i+1] = '\n';
+ i += 2;
+ goto print;
+- case '\b': /* BS */
+- i--; /* overwrite last */
+ default:
+ iodc_dbuf[i] = str[i];
+ i++;
+@@ -1142,15 +1140,6 @@ int pdc_iodc_print(const unsigned char *
+ }
+ }
+
+- /* if we're at the end of line, and not already inserting a newline,
+- * insert one anyway. iodc console doesn't claim to support >79 char
+- * lines. don't account for this in the return value.
+- */
+- if (i == 79 && iodc_dbuf[i-1] != '\n') {
+- iodc_dbuf[i+0] = '\r';
+- iodc_dbuf[i+1] = '\n';
+- }
+-
+ print:
+ spin_lock_irqsave(&pdc_lock, flags);
+ real32_call(PAGE0->mem_cons.iodc_io,
powerpc-numa-fix-bug-in-unmap_cpu_from_node.patch
powerpc-fix-some-6xx-7xxx-cpu-setup-functions.patch
firewire-core-fix-unstable-i-o-with-canon-camcorder.patch
+parisc-remove-broken-line-wrapping-handling-pdc_iodc_print.patch
+watchdog-fix-sysctl-consistency.patch
+watchdog-don-t-change-watchdog-state-on-read-of-sysctl.patch
+char-ipmi-fix-oops-caused-by-pnp_unregister_driver-on-unregistered-driver.patch
+ssb-pcmcia-fix-parsing-of-invariants-tuples.patch
+backlight-fix-88pm860x_bl-macro-collision.patch
+fs-direct-io.c-don-t-try-to-allocate-more-than-bio_max_pages-in-a-bio.patch
+kernel-smp.c-fix-smp_call_function_many-smp-race.patch
--- /dev/null
+From dd3cb633078fb12e06ce6cebbdfbf55a7562e929 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michael=20B=C3=BCsch?= <mb@bu3sch.de>
+Date: Fri, 4 Feb 2011 23:34:45 +0100
+Subject: ssb-pcmcia: Fix parsing of invariants tuples
+
+From: =?UTF-8?q?Michael=20B=C3=BCsch?= <mb@bu3sch.de>
+
+commit dd3cb633078fb12e06ce6cebbdfbf55a7562e929 upstream.
+
+This fixes parsing of the device invariants (MAC address)
+for PCMCIA SSB devices.
+
+ssb_pcmcia_do_get_invariants expects an iv pointer as data
+argument.
+
+Tested-by: dylan cristiani <d.cristiani@idem-tech.it>
+Signed-off-by: Michael Buesch <mb@bu3sch.de>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ssb/pcmcia.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/ssb/pcmcia.c
++++ b/drivers/ssb/pcmcia.c
+@@ -734,7 +734,7 @@ int ssb_pcmcia_get_invariants(struct ssb
+
+ /* Fetch the vendor specific tuples. */
+ res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
+- ssb_pcmcia_do_get_invariants, sprom);
++ ssb_pcmcia_do_get_invariants, iv);
+ if ((res == 0) || (res == -ENOSPC))
+ return 0;
+
--- /dev/null
+From 9ffdc6c37df131f89d52001e0ef03091b158826f Mon Sep 17 00:00:00 2001
+From: Marcin Slusarz <marcin.slusarz@gmail.com>
+Date: Fri, 28 Jan 2011 11:00:33 -0500
+Subject: watchdog: Don't change watchdog state on read of sysctl
+
+From: Marcin Slusarz <marcin.slusarz@gmail.com>
+
+commit 9ffdc6c37df131f89d52001e0ef03091b158826f upstream.
+
+Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
+[ add {}'s to fix a warning ]
+Signed-off-by: Don Zickus <dzickus@redhat.com>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+LKML-Reference: <1296230433-6261-3-git-send-email-dzickus@redhat.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/watchdog.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -505,10 +505,12 @@ int proc_dowatchdog_enabled(struct ctl_t
+ {
+ proc_dointvec(table, write, buffer, length, ppos);
+
+- if (watchdog_enabled)
+- watchdog_enable_all_cpus();
+- else
+- watchdog_disable_all_cpus();
++ if (write) {
++ if (watchdog_enabled)
++ watchdog_enable_all_cpus();
++ else
++ watchdog_disable_all_cpus();
++ }
+ return 0;
+ }
+
--- /dev/null
+From 397357666de6b5b6adb5fa99f9758ec8cf30ac34 Mon Sep 17 00:00:00 2001
+From: Marcin Slusarz <marcin.slusarz@gmail.com>
+Date: Fri, 28 Jan 2011 11:00:32 -0500
+Subject: watchdog: Fix sysctl consistency
+
+From: Marcin Slusarz <marcin.slusarz@gmail.com>
+
+commit 397357666de6b5b6adb5fa99f9758ec8cf30ac34 upstream.
+
+If it was not possible to enable watchdog for any cpu, switch
+watchdog_enabled back to 0, because it's visible via
+kernel.watchdog sysctl.
+
+Signed-off-by: Marcin Slusarz <marcin.slusarz@gmail.com>
+Signed-off-by: Don Zickus <dzickus@redhat.com>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+LKML-Reference: <1296230433-6261-2-git-send-email-dzickus@redhat.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/watchdog.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -441,9 +441,6 @@ static int watchdog_enable(int cpu)
+ wake_up_process(p);
+ }
+
+- /* if any cpu succeeds, watchdog is considered enabled for the system */
+- watchdog_enabled = 1;
+-
+ return 0;
+ }
+
+@@ -471,12 +468,16 @@ static void watchdog_disable(int cpu)
+ static void watchdog_enable_all_cpus(void)
+ {
+ int cpu;
+- int result = 0;
++
++ watchdog_enabled = 0;
+
+ for_each_online_cpu(cpu)
+- result += watchdog_enable(cpu);
++ if (!watchdog_enable(cpu))
++ /* if any cpu succeeds, watchdog is considered
++ enabled for the system */
++ watchdog_enabled = 1;
+
+- if (result)
++ if (!watchdog_enabled)
+ printk(KERN_ERR "watchdog: failed to be enabled on some cpus\n");
+
+ }