[PATCH] powermac: Combined fixes for backlight code
[powerpc.git] / arch / powerpc / platforms / powermac / backlight.c
index 498b042..74eed6b 100644 (file)
@@ -7,7 +7,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/fb.h>
 #include <linux/backlight.h>
 
 #define OLD_BACKLIGHT_MAX 15
 
+static void pmac_backlight_key_worker(void *data);
+static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL);
+
+/* Although this variable is used in interrupt context, it makes no sense to
+ * protect it. No user is able to produce enough key events per second and
+ * notice the errors that might happen.
+ */
+static int pmac_backlight_key_queued;
+
 /* Protect the pmac_backlight variable */
 DEFINE_MUTEX(pmac_backlight_mutex);
 
@@ -72,7 +80,7 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value)
        return level;
 }
 
-static void pmac_backlight_key(int direction)
+static void pmac_backlight_key_worker(void *data)
 {
        mutex_lock(&pmac_backlight_mutex);
        if (pmac_backlight) {
@@ -83,7 +91,8 @@ static void pmac_backlight_key(int direction)
                props = pmac_backlight->props;
 
                brightness = props->brightness +
-                       ((direction?-1:1) * (props->max_brightness / 15));
+                       ((pmac_backlight_key_queued?-1:1) *
+                        (props->max_brightness / 15));
 
                if (brightness < 0)
                        brightness = 0;
@@ -98,14 +107,13 @@ static void pmac_backlight_key(int direction)
        mutex_unlock(&pmac_backlight_mutex);
 }
 
-void pmac_backlight_key_up()
-{
-       pmac_backlight_key(0);
-}
-
-void pmac_backlight_key_down()
+void pmac_backlight_key(int direction)
 {
-       pmac_backlight_key(1);
+       /* we can receive multiple interrupts here, but the scheduled work
+        * will run only once, with the last value
+        */
+       pmac_backlight_key_queued = direction;
+       schedule_work(&pmac_backlight_key_work);
 }
 
 int pmac_backlight_set_legacy_brightness(int brightness)
@@ -119,7 +127,14 @@ int pmac_backlight_set_legacy_brightness(int brightness)
                down(&pmac_backlight->sem);
                props = pmac_backlight->props;
                props->brightness = brightness *
-                       props->max_brightness / OLD_BACKLIGHT_MAX;
+                       (props->max_brightness + 1) /
+                       (OLD_BACKLIGHT_MAX + 1);
+
+               if (props->brightness > props->max_brightness)
+                       props->brightness = props->max_brightness;
+               else if (props->brightness < 0)
+                       props->brightness = 0;
+
                props->update_status(pmac_backlight);
                up(&pmac_backlight->sem);
 
@@ -140,11 +155,18 @@ int pmac_backlight_get_legacy_brightness()
 
                down(&pmac_backlight->sem);
                props = pmac_backlight->props;
+
                result = props->brightness *
-                       OLD_BACKLIGHT_MAX / props->max_brightness;
+                       (OLD_BACKLIGHT_MAX + 1) /
+                       (props->max_brightness + 1);
+
                up(&pmac_backlight->sem);
        }
        mutex_unlock(&pmac_backlight_mutex);
 
        return result;
 }
+
+EXPORT_SYMBOL_GPL(pmac_backlight);
+EXPORT_SYMBOL_GPL(pmac_backlight_mutex);
+EXPORT_SYMBOL_GPL(pmac_has_backlight_type);