[ibm-acpi-devel] [ltp] thinkpad-acpi release 0.17-20071002 uploaded to ibm-acpi.sf.net

Henrique de Moraes Holschuh linux-thinkpad@linux-thinkpad.org
Wed, 3 Oct 2007 21:13:30 -0300


--ZGiS0Q5IWpPtfppv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, 03 Oct 2007, Henrique de Moraes Holschuh wrote:
> You found the problem.  It is not doing a depth-walk to find LCD0._BCL.  I
> shall have it fixed soon, there is a ugly and a nice way to do it.

Jeez, it took some doing to get it right.  Here it is, and this time it
should work just fine.  Apply on top of the 0.17-20071002 release without
the other patches.

If this works, I only need to find out what the heck is happening on the T60
(without 16 brightness levels) that gets stuck returning -EINVAL...

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh

--ZGiS0Q5IWpPtfppv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch

commit 3f03108f7e31cb3c42b9ce71638f2ab149efc7f0
Author: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Date:   Wed Oct 3 21:09:05 2007 -0300

    ACPI: thinkpad-acpi: fix issues in brightness 16-levels support (v3)
    
    Fix some issues with the new 16-level brightness support.
    
    Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>

diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index b0ef877..2fea9b2 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -3578,34 +3578,44 @@ static struct backlight_ops ibm_backlight_data = {
 
 static struct mutex brightness_mutex;
 
+static acpi_status __init brightness_find_bccl(acpi_handle handle, u32 lvl,
+					void *context, void **rv)
+{
+	char name[ACPI_PATH_SEGMENT_LENGTH];
+	struct acpi_buffer buffer = { sizeof(name), &name };
+
+	if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
+	    !strncmp("BCCL", name, sizeof(name) - 1)) {
+		*rv = handle;
+		return AE_CTRL_TERMINATE;
+	} else {
+		return AE_OK;
+	}
+}
+
 static int __init brightness_check_levels(void)
 {
 	int status;
-	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	union acpi_object *obj;
+	void *found_node = NULL;
 
-	status = acpi_evaluate_object(vid_handle, "BCLL", NULL, &buffer);
-	if (!ACPI_SUCCESS(status))
+	if (!vid_handle) {
+		IBM_ACPIHANDLE_INIT(vid);
+	}
+	if (!vid_handle)
 		return 0;
 
-	status = 0;
-	obj = (union acpi_object *)buffer.pointer;
+	/*
+	 * Assume any thinkpad with a BCLL node has 16 levels, and not, say,
+	 * 32 levels or 12 levels, etc.  We could do better, but the code would
+	 * be that more complex, so we shall wait until such a beast is made,
+	 * first.  It's not like BCLL is standard, anyway...
+	 */
 
-	if (obj && obj->type == ACPI_TYPE_PACKAGE &&
-	    obj->package.count == 16) {
-		/*
-		 * We could actually parse them all, and get the minimum and
-		 * maximum levels used by the ACPI firmware if we wanted,
-		 * instead of this ugly hack of 16 levels or nothing...
-		 */
-		status = 1;
-	} else {
-		printk(IBM_ERR "unexpected return from BCLL\n");
-		printk(IBM_ERR "please report this to %s\n", IBM_MAIL);
-	}
+	/* Search for a BCLL package node */
+	status = acpi_walk_namespace(ACPI_TYPE_PACKAGE, vid_handle, 3,
+					brightness_find_bccl, NULL, &found_node);
 
-	kfree(buffer.pointer);
-	return status;
+	return (ACPI_SUCCESS(status) && found_node != NULL);
 }
 
 static int __init brightness_init(struct ibm_init_struct *iibm)
@@ -3693,6 +3703,7 @@ static int brightness_get(struct backlight_device *bd)
 		lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
 			 & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
 			>> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
+		lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
 		level = lcmos;
 	}
 

--ZGiS0Q5IWpPtfppv--