ChangeSet 1.2277, 2005/03/31 08:41:40-08:00, [EMAIL PROTECTED]

        [PATCH] ppc32: move powermac backlight stuff to a workqueue
        
        The powermac has a kernel-based driver for controlling the backlight 
from
        the keyboard that used to call into some fbdev's from interrupt 
contexts.
        This patch moves it to a workqueue (and additionally makes sure the 
console
        semaphore is taken and held).
        
        I hope I'll replace this by the new backlight framework in a future 
kernel
        version, but for now, this will fix the immediate issues with radeon.
        
        Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]>
        Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
        Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>



 pmac_backlight.c |   80 ++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 62 insertions(+), 18 deletions(-)


diff -Nru a/arch/ppc/platforms/pmac_backlight.c 
b/arch/ppc/platforms/pmac_backlight.c
--- a/arch/ppc/platforms/pmac_backlight.c       2005-03-31 10:22:00 -08:00
+++ b/arch/ppc/platforms/pmac_backlight.c       2005-03-31 10:22:00 -08:00
@@ -12,6 +12,7 @@
 #include <linux/stddef.h>
 #include <linux/reboot.h>
 #include <linux/nvram.h>
+#include <linux/console.h>
 #include <asm/sections.h>
 #include <asm/ptrace.h>
 #include <asm/io.h>
@@ -25,14 +26,19 @@
 #include <linux/adb.h>
 #include <linux/pmu.h>
 
-static struct backlight_controller *backlighter = NULL;
-static void* backlighter_data = NULL;
-static int backlight_autosave = 0;
+static struct backlight_controller *backlighter;
+static void* backlighter_data;
+static int backlight_autosave;
 static int backlight_level = BACKLIGHT_MAX;
 static int backlight_enabled = 1;
+static int backlight_req_level = -1;
+static int backlight_req_enable = -1;
 
-void __pmac
-register_backlight_controller(struct backlight_controller *ctrler, void *data, 
char *type)
+static void backlight_callback(void *);
+static DECLARE_WORK(backlight_work, backlight_callback, NULL);
+
+void __pmac register_backlight_controller(struct backlight_controller *ctrler,
+                                         void *data, char *type)
 {
        struct device_node* bk_node;
        char *prop;
@@ -83,16 +89,18 @@
                backlight_level = req.reply[0] >> 4;
        }
 #endif
+       acquire_console_sem();
        if (!backlighter->set_enable(1, backlight_level, data))
                backlight_enabled = 1;
+       release_console_sem();
 
-       printk(KERN_INFO "Registered \"%s\" backlight controller, level: 
%d/15\n",
-               type, backlight_level);
+       printk(KERN_INFO "Registered \"%s\" backlight controller,"
+              "level: %d/15\n", type, backlight_level);
 }
 EXPORT_SYMBOL(register_backlight_controller);
 
-void __pmac
-unregister_backlight_controller(struct backlight_controller *ctrler, void 
*data)
+void __pmac unregister_backlight_controller(struct backlight_controller
+                                           *ctrler, void *data)
 {
        /* We keep the current backlight level (for now) */
        if (ctrler == backlighter && data == backlighter_data)
@@ -100,22 +108,32 @@
 }
 EXPORT_SYMBOL(unregister_backlight_controller);
 
-int __pmac
-set_backlight_enable(int enable)
+static int __pmac __set_backlight_enable(int enable)
 {
        int rc;
 
        if (!backlighter)
                return -ENODEV;
-       rc = backlighter->set_enable(enable, backlight_level, backlighter_data);
+       acquire_console_sem();
+       rc = backlighter->set_enable(enable, backlight_level,
+                                    backlighter_data);
        if (!rc)
                backlight_enabled = enable;
+       release_console_sem();
        return rc;
 }
+int __pmac set_backlight_enable(int enable)
+{
+       if (!backlighter)
+               return -ENODEV;
+       backlight_req_enable = enable;
+       schedule_work(&backlight_work);
+       return 0;
+}
+
 EXPORT_SYMBOL(set_backlight_enable);
 
-int __pmac
-get_backlight_enable(void)
+int __pmac get_backlight_enable(void)
 {
        if (!backlighter)
                return -ENODEV;
@@ -123,8 +141,7 @@
 }
 EXPORT_SYMBOL(get_backlight_enable);
 
-int __pmac
-set_backlight_level(int level)
+static int __pmac __set_backlight_level(int level)
 {
        int rc = 0;
 
@@ -134,10 +151,12 @@
                level = BACKLIGHT_OFF;
        if (level > BACKLIGHT_MAX)
                level = BACKLIGHT_MAX;
+       acquire_console_sem();
        if (backlight_enabled)
                rc = backlighter->set_level(level, backlighter_data);
        if (!rc)
                backlight_level = level;
+       release_console_sem();
        if (!rc && !backlight_autosave) {
                level <<=1;
                if (level & 0x10)
@@ -146,13 +165,38 @@
        }
        return rc;
 }
+int __pmac set_backlight_level(int level)
+{
+       if (!backlighter)
+               return -ENODEV;
+       backlight_req_level = level;
+       schedule_work(&backlight_work);
+       return 0;
+}
+
 EXPORT_SYMBOL(set_backlight_level);
 
-int __pmac
-get_backlight_level(void)
+int __pmac get_backlight_level(void)
 {
        if (!backlighter)
                return -ENODEV;
        return backlight_level;
 }
 EXPORT_SYMBOL(get_backlight_level);
+
+static void backlight_callback(void *dummy)
+{
+       int level, enable;
+
+       do {
+               level = backlight_req_level;
+               enable = backlight_req_enable;
+               mb();
+
+               if (level >= 0)
+                       __set_backlight_level(level);
+               if (enable >= 0)
+                       __set_backlight_enable(enable);
+       } while(cmpxchg(&backlight_req_level, level, -1) != level ||
+               cmpxchg(&backlight_req_enable, enable, -1) != enable);
+}
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to