From: Greg Kroah-Hartman Date: Tue, 26 Feb 2013 22:09:41 +0000 (-0800) Subject: 3.0-stable patches X-Git-Tag: v3.7.10~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=515e2f6fa4855744d15a72ae92e55497afdf91f5;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: arm-pxa3xx-program-the-csmsadrcfg-register.patch fbcon-don-t-lose-the-console-font-across-generic-chip-driver-switch.patch fb-rework-locking-to-fix-lock-ordering-on-takeover.patch fb-yet-another-band-aid-for-fixing-lockdep-mess.patch pcmcia-vrc4171-add-missing-spinlock-init.patch powerpc-kexec-disable-hard-irq-before-kexec.patch purge-existing-tlb-entries-in-set_pte_at-and-ptep_set_wrprotect.patch --- diff --git a/queue-3.0/arm-pxa3xx-program-the-csmsadrcfg-register.patch b/queue-3.0/arm-pxa3xx-program-the-csmsadrcfg-register.patch new file mode 100644 index 00000000000..dd32dd9f0b3 --- /dev/null +++ b/queue-3.0/arm-pxa3xx-program-the-csmsadrcfg-register.patch @@ -0,0 +1,70 @@ +From d107a204154ddd79339203c2deeb7433f0cf6777 Mon Sep 17 00:00:00 2001 +From: Igor Grinberg +Date: Sun, 13 Jan 2013 13:49:47 +0200 +Subject: ARM: PXA3xx: program the CSMSADRCFG register + +From: Igor Grinberg + +commit d107a204154ddd79339203c2deeb7433f0cf6777 upstream. + +The Chip Select Configuration Register must be programmed to 0x2 in +order to achieve the correct behavior of the Static Memory Controller. + +Without this patch devices wired to DFI and accessed through SMC cannot +be accessed after resume from S2. + +Do not rely on the boot loader to program the CSMSADRCFG register by +programming it in the kernel smemc module. + +Signed-off-by: Igor Grinberg +Acked-by: Eric Miao +Signed-off-by: Haojian Zhuang +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mach-pxa/include/mach/smemc.h | 1 + + arch/arm/mach-pxa/smemc.c | 15 ++++++++++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) + +--- a/arch/arm/mach-pxa/include/mach/smemc.h ++++ b/arch/arm/mach-pxa/include/mach/smemc.h +@@ -37,6 +37,7 @@ + #define CSADRCFG1 (SMEMC_VIRT + 0x84) /* Address Configuration Register for CS1 */ + #define CSADRCFG2 (SMEMC_VIRT + 0x88) /* Address Configuration Register for CS2 */ + #define CSADRCFG3 (SMEMC_VIRT + 0x8C) /* Address Configuration Register for CS3 */ ++#define CSMSADRCFG (SMEMC_VIRT + 0xA0) /* Chip Select Configuration Register */ + + /* + * More handy macros for PCMCIA +--- a/arch/arm/mach-pxa/smemc.c ++++ b/arch/arm/mach-pxa/smemc.c +@@ -40,6 +40,8 @@ static void pxa3xx_smemc_resume(void) + __raw_writel(csadrcfg[1], CSADRCFG1); + __raw_writel(csadrcfg[2], CSADRCFG2); + __raw_writel(csadrcfg[3], CSADRCFG3); ++ /* CSMSADRCFG wakes up in its default state (0), so we need to set it */ ++ __raw_writel(0x2, CSMSADRCFG); + } + + static struct syscore_ops smemc_syscore_ops = { +@@ -49,8 +51,19 @@ static struct syscore_ops smemc_syscore_ + + static int __init smemc_init(void) + { +- if (cpu_is_pxa3xx()) ++ if (cpu_is_pxa3xx()) { ++ /* ++ * The only documentation we have on the ++ * Chip Select Configuration Register (CSMSADRCFG) is that ++ * it must be programmed to 0x2. ++ * Moreover, in the bit definitions, the second bit ++ * (CSMSADRCFG[1]) is called "SETALWAYS". ++ * Other bits are reserved in this register. ++ */ ++ __raw_writel(0x2, CSMSADRCFG); ++ + register_syscore_ops(&smemc_syscore_ops); ++ } + + return 0; + } diff --git a/queue-3.0/fb-rework-locking-to-fix-lock-ordering-on-takeover.patch b/queue-3.0/fb-rework-locking-to-fix-lock-ordering-on-takeover.patch new file mode 100644 index 00000000000..bfc0a202be1 --- /dev/null +++ b/queue-3.0/fb-rework-locking-to-fix-lock-ordering-on-takeover.patch @@ -0,0 +1,302 @@ +From 50e244cc793d511b86adea24972f3a7264cae114 Mon Sep 17 00:00:00 2001 +From: Alan Cox +Date: Fri, 25 Jan 2013 10:28:15 +1000 +Subject: fb: rework locking to fix lock ordering on takeover + +From: Alan Cox + +commit 50e244cc793d511b86adea24972f3a7264cae114 upstream. + +Adjust the console layer to allow a take over call where the caller +already holds the locks. Make the fb layer lock in order. + +This is partly a band aid, the fb layer is terminally confused about the +locking rules it uses for its notifiers it seems. + +[akpm@linux-foundation.org: remove stray non-ascii char, tidy comment] +[akpm@linux-foundation.org: export do_take_over_console()] +[airlied: cleanup another non-ascii char] +Signed-off-by: Alan Cox +Cc: Florian Tobias Schandinat +Cc: Stephen Rothwell +Cc: Jiri Kosina +Tested-by: Sedat Dilek +Reviewed-by: Daniel Vetter +Signed-off-by: Andrew Morton +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/vt/vt.c | 93 +++++++++++++++++++++++++++++++----------- + drivers/video/console/fbcon.c | 29 ++++++++++++- + drivers/video/fbmem.c | 5 -- + drivers/video/fbsysfs.c | 3 + + include/linux/console.h | 1 + 5 files changed, 104 insertions(+), 27 deletions(-) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -3016,7 +3016,7 @@ int __init vty_init(const struct file_op + + static struct class *vtconsole_class; + +-static int bind_con_driver(const struct consw *csw, int first, int last, ++static int do_bind_con_driver(const struct consw *csw, int first, int last, + int deflt) + { + struct module *owner = csw->owner; +@@ -3027,7 +3027,7 @@ static int bind_con_driver(const struct + if (!try_module_get(owner)) + return -ENODEV; + +- console_lock(); ++ WARN_CONSOLE_UNLOCKED(); + + /* check if driver is registered */ + for (i = 0; i < MAX_NR_CON_DRIVER; i++) { +@@ -3112,11 +3112,22 @@ static int bind_con_driver(const struct + + retval = 0; + err: +- console_unlock(); + module_put(owner); + return retval; + }; + ++ ++static int bind_con_driver(const struct consw *csw, int first, int last, ++ int deflt) ++{ ++ int ret; ++ ++ console_lock(); ++ ret = do_bind_con_driver(csw, first, last, deflt); ++ console_unlock(); ++ return ret; ++} ++ + #ifdef CONFIG_VT_HW_CONSOLE_BINDING + static int con_is_graphics(const struct consw *csw, int first, int last) + { +@@ -3228,9 +3239,9 @@ int unbind_con_driver(const struct consw + if (!con_is_bound(csw)) + con_driver->flag &= ~CON_DRIVER_FLAG_INIT; + +- console_unlock(); + /* ignore return value, binding should not fail */ +- bind_con_driver(defcsw, first, last, deflt); ++ do_bind_con_driver(defcsw, first, last, deflt); ++ console_unlock(); + err: + module_put(owner); + return retval; +@@ -3508,28 +3519,18 @@ int con_debug_leave(void) + } + EXPORT_SYMBOL_GPL(con_debug_leave); + +-/** +- * register_con_driver - register console driver to console layer +- * @csw: console driver +- * @first: the first console to take over, minimum value is 0 +- * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1 +- * +- * DESCRIPTION: This function registers a console driver which can later +- * bind to a range of consoles specified by @first and @last. It will +- * also initialize the console driver by calling con_startup(). +- */ +-int register_con_driver(const struct consw *csw, int first, int last) ++static int do_register_con_driver(const struct consw *csw, int first, int last) + { + struct module *owner = csw->owner; + struct con_driver *con_driver; + const char *desc; + int i, retval = 0; + ++ WARN_CONSOLE_UNLOCKED(); ++ + if (!try_module_get(owner)) + return -ENODEV; + +- console_lock(); +- + for (i = 0; i < MAX_NR_CON_DRIVER; i++) { + con_driver = ®istered_con_driver[i]; + +@@ -3582,10 +3583,29 @@ int register_con_driver(const struct con + } + + err: +- console_unlock(); + module_put(owner); + return retval; + } ++ ++/** ++ * register_con_driver - register console driver to console layer ++ * @csw: console driver ++ * @first: the first console to take over, minimum value is 0 ++ * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1 ++ * ++ * DESCRIPTION: This function registers a console driver which can later ++ * bind to a range of consoles specified by @first and @last. It will ++ * also initialize the console driver by calling con_startup(). ++ */ ++int register_con_driver(const struct consw *csw, int first, int last) ++{ ++ int retval; ++ ++ console_lock(); ++ retval = do_register_con_driver(csw, first, last); ++ console_unlock(); ++ return retval; ++} + EXPORT_SYMBOL(register_con_driver); + + /** +@@ -3639,17 +3659,44 @@ EXPORT_SYMBOL(unregister_con_driver); + * when a driver wants to take over some existing consoles + * and become default driver for newly opened ones. + * +- * take_over_console is basically a register followed by unbind ++ * take_over_console is basically a register followed by unbind ++ */ ++int do_take_over_console(const struct consw *csw, int first, int last, int deflt) ++{ ++ int err; ++ ++ err = do_register_con_driver(csw, first, last); ++ /* ++ * If we get an busy error we still want to bind the console driver ++ * and return success, as we may have unbound the console driver ++ * but not unregistered it. ++ */ ++ if (err == -EBUSY) ++ err = 0; ++ if (!err) ++ do_bind_con_driver(csw, first, last, deflt); ++ ++ return err; ++} ++EXPORT_SYMBOL_GPL(do_take_over_console); ++ ++/* ++ * If we support more console drivers, this function is used ++ * when a driver wants to take over some existing consoles ++ * and become default driver for newly opened ones. ++ * ++ * take_over_console is basically a register followed by unbind + */ + int take_over_console(const struct consw *csw, int first, int last, int deflt) + { + int err; + + err = register_con_driver(csw, first, last); +- /* if we get an busy error we still want to bind the console driver ++ /* ++ * If we get an busy error we still want to bind the console driver + * and return success, as we may have unbound the console driver +-  * but not unregistered it. +- */ ++ * but not unregistered it. ++ */ + if (err == -EBUSY) + err = 0; + if (!err) +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -530,6 +530,33 @@ static int search_for_mapped_con(void) + return retval; + } + ++static int do_fbcon_takeover(int show_logo) ++{ ++ int err, i; ++ ++ if (!num_registered_fb) ++ return -ENODEV; ++ ++ if (!show_logo) ++ logo_shown = FBCON_LOGO_DONTSHOW; ++ ++ for (i = first_fb_vc; i <= last_fb_vc; i++) ++ con2fb_map[i] = info_idx; ++ ++ err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc, ++ fbcon_is_default); ++ ++ if (err) { ++ for (i = first_fb_vc; i <= last_fb_vc; i++) ++ con2fb_map[i] = -1; ++ info_idx = -1; ++ } else { ++ fbcon_has_console_bind = 1; ++ } ++ ++ return err; ++} ++ + static int fbcon_takeover(int show_logo) + { + int err, i; +@@ -3122,7 +3149,7 @@ static int fbcon_fb_registered(struct fb + } + + if (info_idx != -1) +- ret = fbcon_takeover(1); ++ ret = do_fbcon_takeover(1); + } else { + for (i = first_fb_vc; i <= last_fb_vc; i++) { + if (con2fb_map_boot[i] == idx) +--- a/drivers/video/fbmem.c ++++ b/drivers/video/fbmem.c +@@ -1628,7 +1628,9 @@ static int do_register_framebuffer(struc + event.info = fb_info; + if (!lock_fb_info(fb_info)) + return -ENODEV; ++ console_lock(); + fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); ++ console_unlock(); + unlock_fb_info(fb_info); + return 0; + } +@@ -1831,11 +1833,8 @@ int fb_new_modelist(struct fb_info *info + err = 1; + + if (!list_empty(&info->modelist)) { +- if (!lock_fb_info(info)) +- return -ENODEV; + event.info = info; + err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); +- unlock_fb_info(info); + } + + return err; +--- a/drivers/video/fbsysfs.c ++++ b/drivers/video/fbsysfs.c +@@ -175,6 +175,8 @@ static ssize_t store_modes(struct device + if (i * sizeof(struct fb_videomode) != count) + return -EINVAL; + ++ if (!lock_fb_info(fb_info)) ++ return -ENODEV; + console_lock(); + list_splice(&fb_info->modelist, &old_list); + fb_videomode_to_modelist((const struct fb_videomode *)buf, i, +@@ -186,6 +188,7 @@ static ssize_t store_modes(struct device + fb_destroy_modelist(&old_list); + + console_unlock(); ++ unlock_fb_info(fb_info); + + return 0; + } +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -78,6 +78,7 @@ int con_is_bound(const struct consw *csw + int register_con_driver(const struct consw *csw, int first, int last); + int unregister_con_driver(const struct consw *csw); + int take_over_console(const struct consw *sw, int first, int last, int deflt); ++int do_take_over_console(const struct consw *sw, int first, int last, int deflt); + void give_up_console(const struct consw *sw); + #ifdef CONFIG_HW_CONSOLE + int con_debug_enter(struct vc_data *vc); diff --git a/queue-3.0/fb-yet-another-band-aid-for-fixing-lockdep-mess.patch b/queue-3.0/fb-yet-another-band-aid-for-fixing-lockdep-mess.patch new file mode 100644 index 00000000000..6c62f5eca13 --- /dev/null +++ b/queue-3.0/fb-yet-another-band-aid-for-fixing-lockdep-mess.patch @@ -0,0 +1,202 @@ +From e93a9a868792ad71cdd09d75e5a02d8067473c4e Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 25 Jan 2013 10:28:18 +1000 +Subject: fb: Yet another band-aid for fixing lockdep mess + +From: Takashi Iwai + +commit e93a9a868792ad71cdd09d75e5a02d8067473c4e upstream. + +I've still got lockdep warnings even after Alan's patch, and it seems that +yet more band aids are required to paper over similar paths for +unbind_con_driver() and unregister_con_driver(). After this hack, lockdep +warnings are finally gone. + +Signed-off-by: Takashi Iwai +Cc: Alan Cox +Cc: Florian Tobias Schandinat +Cc: Jiri Kosina +Tested-by: Sedat Dilek +Signed-off-by: Andrew Morton +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/tty/vt/vt.c | 43 +++++++++++++++++++++++++++--------------- + drivers/video/console/fbcon.c | 4 +-- + drivers/video/fbmem.c | 4 +++ + include/linux/console.h | 1 + include/linux/vt_kern.h | 2 + + 5 files changed, 37 insertions(+), 17 deletions(-) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -3164,6 +3164,18 @@ static int con_is_graphics(const struct + */ + int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) + { ++ int retval; ++ ++ console_lock(); ++ retval = do_unbind_con_driver(csw, first, last, deflt); ++ console_unlock(); ++ return retval; ++} ++EXPORT_SYMBOL(unbind_con_driver); ++ ++/* unlocked version of unbind_con_driver() */ ++int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt) ++{ + struct module *owner = csw->owner; + const struct consw *defcsw = NULL; + struct con_driver *con_driver = NULL, *con_back = NULL; +@@ -3172,7 +3184,7 @@ int unbind_con_driver(const struct consw + if (!try_module_get(owner)) + return -ENODEV; + +- console_lock(); ++ WARN_CONSOLE_UNLOCKED(); + + /* check if driver is registered and if it is unbindable */ + for (i = 0; i < MAX_NR_CON_DRIVER; i++) { +@@ -3185,10 +3197,8 @@ int unbind_con_driver(const struct consw + } + } + +- if (retval) { +- console_unlock(); ++ if (retval) + goto err; +- } + + retval = -ENODEV; + +@@ -3204,15 +3214,11 @@ int unbind_con_driver(const struct consw + } + } + +- if (retval) { +- console_unlock(); ++ if (retval) + goto err; +- } + +- if (!con_is_bound(csw)) { +- console_unlock(); ++ if (!con_is_bound(csw)) + goto err; +- } + + first = max(first, con_driver->first); + last = min(last, con_driver->last); +@@ -3241,13 +3247,12 @@ int unbind_con_driver(const struct consw + + /* ignore return value, binding should not fail */ + do_bind_con_driver(defcsw, first, last, deflt); +- console_unlock(); + err: + module_put(owner); + return retval; + + } +-EXPORT_SYMBOL(unbind_con_driver); ++EXPORT_SYMBOL_GPL(do_unbind_con_driver); + + static int vt_bind(struct con_driver *con) + { +@@ -3621,9 +3626,18 @@ EXPORT_SYMBOL(register_con_driver); + */ + int unregister_con_driver(const struct consw *csw) + { +- int i, retval = -ENODEV; ++ int retval; + + console_lock(); ++ retval = do_unregister_con_driver(csw); ++ console_unlock(); ++ return retval; ++} ++EXPORT_SYMBOL(unregister_con_driver); ++ ++int do_unregister_con_driver(const struct consw *csw) ++{ ++ int i, retval = -ENODEV; + + /* cannot unregister a bound driver */ + if (con_is_bound(csw)) +@@ -3649,10 +3663,9 @@ int unregister_con_driver(const struct c + } + } + err: +- console_unlock(); + return retval; + } +-EXPORT_SYMBOL(unregister_con_driver); ++EXPORT_SYMBOL_GPL(do_unregister_con_driver); + + /* + * If we support more console drivers, this function is used +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -3011,7 +3011,7 @@ static int fbcon_unbind(void) + { + int ret; + +- ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, ++ ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, + fbcon_is_default); + + if (!ret) +@@ -3084,7 +3084,7 @@ static int fbcon_fb_unregistered(struct + primary_device = -1; + + if (!num_registered_fb) +- unregister_con_driver(&fb_con); ++ do_unregister_con_driver(&fb_con); + + return 0; + } +--- a/drivers/video/fbmem.c ++++ b/drivers/video/fbmem.c +@@ -1646,8 +1646,10 @@ static int do_unregister_framebuffer(str + + if (!lock_fb_info(fb_info)) + return -ENODEV; ++ console_lock(); + event.info = fb_info; + ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); ++ console_unlock(); + unlock_fb_info(fb_info); + + if (ret) +@@ -1662,7 +1664,9 @@ static int do_unregister_framebuffer(str + num_registered_fb--; + fb_cleanup_device(fb_info); + event.info = fb_info; ++ console_lock(); + fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); ++ console_unlock(); + + /* this may free fb info */ + put_fb_info(fb_info); +--- a/include/linux/console.h ++++ b/include/linux/console.h +@@ -77,6 +77,7 @@ extern const struct consw prom_con; /* S + int con_is_bound(const struct consw *csw); + int register_con_driver(const struct consw *csw, int first, int last); + int unregister_con_driver(const struct consw *csw); ++int do_unregister_con_driver(const struct consw *csw); + int take_over_console(const struct consw *sw, int first, int last, int deflt); + int do_take_over_console(const struct consw *sw, int first, int last, int deflt); + void give_up_console(const struct consw *sw); +--- a/include/linux/vt_kern.h ++++ b/include/linux/vt_kern.h +@@ -131,6 +131,8 @@ void vt_event_post(unsigned int event, u + int vt_waitactive(int n); + void change_console(struct vc_data *new_vc); + void reset_vc(struct vc_data *vc); ++extern int do_unbind_con_driver(const struct consw *csw, int first, int last, ++ int deflt); + extern int unbind_con_driver(const struct consw *csw, int first, int last, + int deflt); + int vty_init(const struct file_operations *console_fops); diff --git a/queue-3.0/fbcon-don-t-lose-the-console-font-across-generic-chip-driver-switch.patch b/queue-3.0/fbcon-don-t-lose-the-console-font-across-generic-chip-driver-switch.patch new file mode 100644 index 00000000000..338c857a9c5 --- /dev/null +++ b/queue-3.0/fbcon-don-t-lose-the-console-font-across-generic-chip-driver-switch.patch @@ -0,0 +1,92 @@ +From ae1287865f5361fa138d4d3b1b6277908b54eac9 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Thu, 24 Jan 2013 16:12:41 +1000 +Subject: fbcon: don't lose the console font across generic->chip driver switch + +From: Dave Airlie + +commit ae1287865f5361fa138d4d3b1b6277908b54eac9 upstream. + +If grub2 loads efifb/vesafb, then when systemd starts it can set the console +font on that framebuffer device, however when we then load the native KMS +driver, the first thing it does is tear down the generic framebuffer driver. + +The thing is the generic code is doing the right thing, it frees the font +because otherwise it would leak memory. However we can assume that if you +are removing the generic firmware driver (vesa/efi/offb), that a new driver +*should* be loading soon after, so we effectively leak the font. + +However the old code left a dangling pointer in vc->vc_font.data and we +can now reuse that dangling pointer to load the font into the new +driver, now that we aren't freeing it. + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=892340 + +Signed-off-by: Dave Airlie +Cc: Kay Sievers +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/console/fbcon.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -991,7 +991,7 @@ static const char *fbcon_startup(void) + } + + /* Setup default font */ +- if (!p->fontdata) { ++ if (!p->fontdata && !vc->vc_font.data) { + if (!fontname[0] || !(font = find_font(fontname))) + font = get_default_font(info->var.xres, + info->var.yres, +@@ -1001,6 +1001,8 @@ static const char *fbcon_startup(void) + vc->vc_font.height = font->height; + vc->vc_font.data = (void *)(p->fontdata = font->data); + vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ ++ } else { ++ p->fontdata = vc->vc_font.data; + } + + cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); +@@ -1160,9 +1162,9 @@ static void fbcon_init(struct vc_data *v + ops->p = &fb_display[fg_console]; + } + +-static void fbcon_free_font(struct display *p) ++static void fbcon_free_font(struct display *p, bool freefont) + { +- if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) ++ if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) + kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); + p->fontdata = NULL; + p->userfont = 0; +@@ -1174,8 +1176,8 @@ static void fbcon_deinit(struct vc_data + struct fb_info *info; + struct fbcon_ops *ops; + int idx; ++ bool free_font = true; + +- fbcon_free_font(p); + idx = con2fb_map[vc->vc_num]; + + if (idx == -1) +@@ -1186,6 +1188,8 @@ static void fbcon_deinit(struct vc_data + if (!info) + goto finished; + ++ if (info->flags & FBINFO_MISC_FIRMWARE) ++ free_font = false; + ops = info->fbcon_par; + + if (!ops) +@@ -1197,6 +1201,8 @@ static void fbcon_deinit(struct vc_data + ops->flags &= ~FBCON_FLAGS_INIT; + finished: + ++ fbcon_free_font(p, free_font); ++ + if (!con_is_bound(&fb_con)) + fbcon_exit(); + diff --git a/queue-3.0/pcmcia-vrc4171-add-missing-spinlock-init.patch b/queue-3.0/pcmcia-vrc4171-add-missing-spinlock-init.patch new file mode 100644 index 00000000000..621b602ff1e --- /dev/null +++ b/queue-3.0/pcmcia-vrc4171-add-missing-spinlock-init.patch @@ -0,0 +1,29 @@ +From 811af9723859884f2f771f3174f3ddedab7c53b5 Mon Sep 17 00:00:00 2001 +From: Jean Delvare +Date: Sun, 16 Dec 2012 22:00:50 +0100 +Subject: pcmcia/vrc4171: Add missing spinlock init + +From: Jean Delvare + +commit 811af9723859884f2f771f3174f3ddedab7c53b5 upstream. + +It doesn't seem this spinlock was properly initialized. This bug was +introduced by commit 7a410e8d4d97457c8c381e2de9cdc7bd3306badc. + +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pcmcia/vrc4171_card.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/pcmcia/vrc4171_card.c ++++ b/drivers/pcmcia/vrc4171_card.c +@@ -246,6 +246,7 @@ static int pccard_init(struct pcmcia_soc + socket = &vrc4171_sockets[slot]; + socket->csc_irq = search_nonuse_irq(); + socket->io_irq = search_nonuse_irq(); ++ spin_lock_init(&socket->lock); + + return 0; + } diff --git a/queue-3.0/powerpc-kexec-disable-hard-irq-before-kexec.patch b/queue-3.0/powerpc-kexec-disable-hard-irq-before-kexec.patch new file mode 100644 index 00000000000..6fd57ceeade --- /dev/null +++ b/queue-3.0/powerpc-kexec-disable-hard-irq-before-kexec.patch @@ -0,0 +1,49 @@ +From 8520e443aa56cc157b015205ea53e7b9fc831291 Mon Sep 17 00:00:00 2001 +From: Phileas Fogg +Date: Sat, 23 Feb 2013 00:32:19 +0100 +Subject: powerpc/kexec: Disable hard IRQ before kexec + +From: Phileas Fogg + +commit 8520e443aa56cc157b015205ea53e7b9fc831291 upstream. + +Disable hard IRQ before kexec a new kernel image. +Not doing it can result in corrupted data in the memory segments +reserved for the new kernel. + +Signed-off-by: Phileas Fogg +Signed-off-by: Benjamin Herrenschmidt +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/machine_kexec_64.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/powerpc/kernel/machine_kexec_64.c ++++ b/arch/powerpc/kernel/machine_kexec_64.c +@@ -163,6 +163,8 @@ static int kexec_all_irq_disabled = 0; + static void kexec_smp_down(void *arg) + { + local_irq_disable(); ++ hard_irq_disable(); ++ + mb(); /* make sure our irqs are disabled before we say they are */ + get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF; + while(kexec_all_irq_disabled == 0) +@@ -245,6 +247,8 @@ static void kexec_prepare_cpus(void) + wake_offline_cpus(); + smp_call_function(kexec_smp_down, NULL, /* wait */0); + local_irq_disable(); ++ hard_irq_disable(); ++ + mb(); /* make sure IRQs are disabled before we say they are */ + get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF; + +@@ -282,6 +286,7 @@ static void kexec_prepare_cpus(void) + if (ppc_md.kexec_cpu_down) + ppc_md.kexec_cpu_down(0, 0); + local_irq_disable(); ++ hard_irq_disable(); + } + + #endif /* SMP */ diff --git a/queue-3.0/purge-existing-tlb-entries-in-set_pte_at-and-ptep_set_wrprotect.patch b/queue-3.0/purge-existing-tlb-entries-in-set_pte_at-and-ptep_set_wrprotect.patch new file mode 100644 index 00000000000..b75e0862a59 --- /dev/null +++ b/queue-3.0/purge-existing-tlb-entries-in-set_pte_at-and-ptep_set_wrprotect.patch @@ -0,0 +1,92 @@ +From 7139bc1579901b53db7e898789e916ee2fb52d78 Mon Sep 17 00:00:00 2001 +From: John David Anglin +Date: Mon, 14 Jan 2013 19:45:00 -0500 +Subject: [PARISC] Purge existing TLB entries in set_pte_at and ptep_set_wrprotect + +From: John David Anglin + +commit 7139bc1579901b53db7e898789e916ee2fb52d78 upstream. + +This patch goes a long way toward fixing the minifail bug, and +it  significantly improves the stability of SMP machines such as +the rp3440.  When write  protecting a page for COW, we need to +purge the existing translation.  Otherwise, the COW break +doesn't occur as expected because the TLB may still have a stale entry +which allows writes. + +[jejb: fix up checkpatch errors] +Signed-off-by: John David Anglin +Signed-off-by: James Bottomley +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/include/asm/pgtable.h | 13 ++++++++++--- + arch/parisc/kernel/cache.c | 18 ++++++++++++++++++ + 2 files changed, 28 insertions(+), 3 deletions(-) + +--- a/arch/parisc/include/asm/pgtable.h ++++ b/arch/parisc/include/asm/pgtable.h +@@ -12,11 +12,10 @@ + + #include + #include ++#include + #include + #include + +-struct vm_area_struct; +- + /* + * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel + * memory. For the return value to be meaningful, ADDR must be >= +@@ -40,7 +39,14 @@ struct vm_area_struct; + do{ \ + *(pteptr) = (pteval); \ + } while(0) +-#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) ++ ++extern void purge_tlb_entries(struct mm_struct *, unsigned long); ++ ++#define set_pte_at(mm, addr, ptep, pteval) \ ++ do { \ ++ set_pte(ptep, pteval); \ ++ purge_tlb_entries(mm, addr); \ ++ } while (0) + + #endif /* !__ASSEMBLY__ */ + +@@ -464,6 +470,7 @@ static inline void ptep_set_wrprotect(st + old = pte_val(*ptep); + new = pte_val(pte_wrprotect(__pte (old))); + } while (cmpxchg((unsigned long *) ptep, old, new) != old); ++ purge_tlb_entries(mm, addr); + #else + pte_t old_pte = *ptep; + set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); +--- a/arch/parisc/kernel/cache.c ++++ b/arch/parisc/kernel/cache.c +@@ -421,6 +421,24 @@ void kunmap_parisc(void *addr) + EXPORT_SYMBOL(kunmap_parisc); + #endif + ++void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) ++{ ++ unsigned long flags; ++ ++ /* Note: purge_tlb_entries can be called at startup with ++ no context. */ ++ ++ /* Disable preemption while we play with %sr1. */ ++ preempt_disable(); ++ mtsp(mm->context, 1); ++ purge_tlb_start(flags); ++ pdtlb(addr); ++ pitlb(addr); ++ purge_tlb_end(flags); ++ preempt_enable(); ++} ++EXPORT_SYMBOL(purge_tlb_entries); ++ + void __flush_tlb_range(unsigned long sid, unsigned long start, + unsigned long end) + { diff --git a/queue-3.0/series b/queue-3.0/series index 27edb64e846..8edb32ac9ae 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -32,3 +32,10 @@ nls-improve-utf8-utf16-string-conversion-routine.patch drm-i915-disable-shared-panel-fitter-for-pipe.patch staging-comedi-disallow-comedi_devconfig-on-non-board-minors.patch staging-vt6656-fix-urb-submitted-while-active-warning.patch +arm-pxa3xx-program-the-csmsadrcfg-register.patch +powerpc-kexec-disable-hard-irq-before-kexec.patch +purge-existing-tlb-entries-in-set_pte_at-and-ptep_set_wrprotect.patch +pcmcia-vrc4171-add-missing-spinlock-init.patch +fbcon-don-t-lose-the-console-font-across-generic-chip-driver-switch.patch +fb-rework-locking-to-fix-lock-ordering-on-takeover.patch +fb-yet-another-band-aid-for-fixing-lockdep-mess.patch