Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 May 2020 12:14:12 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r360657 - head/sys/dev/acpica
Message-ID:  <202005051214.045CEC7n053618@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Tue May  5 12:14:11 2020
New Revision: 360657
URL: https://svnweb.freebsd.org/changeset/base/360657

Log:
  acpi_video: try our best to work on systems without non-essential methods
  
  Only _BCL and _BCM methods seem to be essential to the driver's
  operation.  If _BQC is missing then we can assume that the current
  brightness is whatever we set by the last _BCM invocation.  If _DCS or
  _DGS is missing the we can make assumptions as well.
  
  The change is based on a patch suggested by Anthony Jenkins
  <Scoobi_doo@yahoo.com> in PR 207086.
  
  PR:		207086
  Submitted by:	Anthony Jenkins <Scoobi_doo@yahoo.com (earlier version)
  Reviewed by:	manu
  MFC after:	3 weeks
  Differential Revision: https://reviews.freebsd.org/D24653

Modified:
  head/sys/dev/acpica/acpi_video.c

Modified: head/sys/dev/acpica/acpi_video.c
==============================================================================
--- head/sys/dev/acpica/acpi_video.c	Tue May  5 11:14:28 2020	(r360656)
+++ head/sys/dev/acpica/acpi_video.c	Tue May  5 12:14:11 2020	(r360657)
@@ -52,6 +52,8 @@ struct acpi_video_output {
 		int	num;
 		STAILQ_ENTRY(acpi_video_output) next;
 	} vo_unit;
+	int		vo_hasbqc;	/* Query method is present. */
+	int		vo_level;	/* Cached level when !vo_hasbqc. */
 	int		vo_brightness;
 	int		vo_fullpower;
 	int		vo_economy;
@@ -96,8 +98,8 @@ static void	vid_set_switch_policy(ACPI_HANDLE, UINT32)
 static int	vid_enum_outputs(ACPI_HANDLE,
 		    void(*)(ACPI_HANDLE, UINT32, void *), void *);
 static int	vo_get_brightness_levels(ACPI_HANDLE, int **);
-static int	vo_get_brightness(ACPI_HANDLE);
-static void	vo_set_brightness(ACPI_HANDLE, int);
+static int	vo_get_brightness(struct acpi_video_output *);
+static void	vo_set_brightness(struct acpi_video_output *, int);
 static UINT32	vo_get_device_status(ACPI_HANDLE);
 static UINT32	vo_get_graphics_state(ACPI_HANDLE);
 static void	vo_set_device_state(ACPI_HANDLE, UINT32);
@@ -327,9 +329,9 @@ acpi_video_resume(device_t dev)
 		if ((vo_get_device_status(vo->handle) & DCS_ACTIVE) == 0)
 			continue;
 
-		level = vo_get_brightness(vo->handle);
+		level = vo_get_brightness(vo);
 		if (level != -1)
-			vo_set_brightness(vo->handle, level);
+			vo_set_brightness(vo, level);
 	}
 	ACPI_SERIAL_END(video_output);
 	ACPI_SERIAL_END(video);
@@ -419,7 +421,7 @@ acpi_video_power_profile(void *context)
 	ACPI_SERIAL_BEGIN(video_output);
 	STAILQ_FOREACH(vo, &sc->vid_outputs, vo_next) {
 		if (vo->vo_levels != NULL && vo->vo_brightness == -1)
-			vo_set_brightness(vo->handle,
+			vo_set_brightness(vo,
 			    state == POWER_PROFILE_ECONOMY ?
 			    vo->vo_economy : vo->vo_fullpower);
 	}
@@ -518,6 +520,8 @@ acpi_video_vo_init(UINT32 adr)
 		vo->handle = NULL;
 		vo->adr = adr;
 		vo->vo_unit.num = n;
+		vo->vo_hasbqc = -1;
+		vo->vo_level = -1;
 		vo->vo_brightness = -1;
 		vo->vo_fullpower = -1;	/* TODO: override with tunables */
 		vo->vo_economy = -1;
@@ -698,7 +702,7 @@ acpi_video_vo_notify_handler(ACPI_HANDLE handle, UINT3
 	case VID_NOTIFY_ZERO_BRN:
 		if (vo->vo_levels == NULL)
 			goto out;
-		level = vo_get_brightness(handle);
+		level = vo_get_brightness(vo);
 		if (level < 0)
 			goto out;
 		break;
@@ -742,7 +746,7 @@ acpi_video_vo_notify_handler(ACPI_HANDLE handle, UINT3
 		break;
 	}
 	if (new_level != level) {
-		vo_set_brightness(handle, new_level);
+		vo_set_brightness(vo, new_level);
 		vo->vo_brightness = new_level;
 	}
 
@@ -807,7 +811,7 @@ acpi_video_vo_bright_sysctl(SYSCTL_HANDLER_ARGS)
 	if (level != -1 && (err = acpi_video_vo_check_level(vo, level)))
 		goto out;
 	vo->vo_brightness = level;
-	vo_set_brightness(vo->handle, (level == -1) ? preset : level);
+	vo_set_brightness(vo, (level == -1) ? preset : level);
 
 out:
 	ACPI_SERIAL_END(video_output);
@@ -848,7 +852,7 @@ acpi_video_vo_presets_sysctl(SYSCTL_HANDLER_ARGS)
 		goto out;
 
 	if (vo->vo_brightness == -1 && (power_profile_get_state() == arg2))
-		vo_set_brightness(vo->handle, level);
+		vo_set_brightness(vo, level);
 	*preset = level;
 
 out:
@@ -1018,15 +1022,39 @@ out:
 }
 
 static int
-vo_get_brightness(ACPI_HANDLE handle)
+vo_get_bqc(struct acpi_video_output *vo, UINT32 *level)
 {
+	ACPI_STATUS status;
+
+	switch (vo->vo_hasbqc) {
+	case 1:
+	case -1:
+		status = acpi_GetInteger(vo->handle, "_BQC", level);
+		if (vo->vo_hasbqc == 1)
+			break;
+		vo->vo_hasbqc = status != AE_NOT_FOUND;
+		if (vo->vo_hasbqc == 1)
+			break;
+		/* FALLTHROUGH */
+	default:
+		KASSERT(vo->vo_hasbqc == 0,
+		    ("bad vo_hasbqc state %d", vo->vo_hasbqc));
+		*level = vo->vo_level;
+		status = AE_OK;
+	}
+	return (status);
+}
+
+static int
+vo_get_brightness(struct acpi_video_output *vo)
+{
 	UINT32 level;
 	ACPI_STATUS status;
 
 	ACPI_SERIAL_ASSERT(video_output);
-	status = acpi_GetInteger(handle, "_BQC", &level);
+	status = vo_get_bqc(vo, &level);
 	if (ACPI_FAILURE(status)) {
-		printf("can't evaluate %s._BQC - %s\n", acpi_name(handle),
+		printf("can't evaluate %s._BQC - %s\n", acpi_name(vo->handle),
 		    AcpiFormatException(status));
 		return (-1);
 	}
@@ -1037,16 +1065,19 @@ vo_get_brightness(ACPI_HANDLE handle)
 }
 
 static void
-vo_set_brightness(ACPI_HANDLE handle, int level)
+vo_set_brightness(struct acpi_video_output *vo, int level)
 {
 	char notify_buf[16];
 	ACPI_STATUS status;
 
 	ACPI_SERIAL_ASSERT(video_output);
-	status = acpi_SetInteger(handle, "_BCM", level);
-	if (ACPI_FAILURE(status))
+	status = acpi_SetInteger(vo->handle, "_BCM", level);
+	if (ACPI_FAILURE(status)) {
 		printf("can't evaluate %s._BCM - %s\n",
-		       acpi_name(handle), AcpiFormatException(status));
+		    acpi_name(vo->handle), AcpiFormatException(status));
+	} else {
+		vo->vo_level = level;
+	}
 	snprintf(notify_buf, sizeof(notify_buf), "notify=%d", level);
 	devctl_notify("ACPI", "Video", "brightness", notify_buf);
 }
@@ -1060,9 +1091,18 @@ vo_get_device_status(ACPI_HANDLE handle)
 	ACPI_SERIAL_ASSERT(video_output);
 	dcs = 0;
 	status = acpi_GetInteger(handle, "_DCS", &dcs);
-	if (ACPI_FAILURE(status))
-		printf("can't evaluate %s._DCS - %s\n",
-		       acpi_name(handle), AcpiFormatException(status));
+	if (ACPI_FAILURE(status)) {
+		/*
+		 * If the method is missing, assume that the device is always
+		 * operational.
+		 */
+		if (status != AE_NOT_FOUND) {
+			printf("can't evaluate %s._DCS - %s\n",
+			    acpi_name(handle), AcpiFormatException(status));
+		} else {
+			dcs = 0xff;
+		}
+	}
 
 	return (dcs);
 }
@@ -1075,9 +1115,18 @@ vo_get_graphics_state(ACPI_HANDLE handle)
 
 	dgs = 0;
 	status = acpi_GetInteger(handle, "_DGS", &dgs);
-	if (ACPI_FAILURE(status))
-		printf("can't evaluate %s._DGS - %s\n",
-		       acpi_name(handle), AcpiFormatException(status));
+	if (ACPI_FAILURE(status)) {
+		/*
+		 * If the method is missing, assume that the device is always
+		 * operational.
+		 */
+		if (status != AE_NOT_FOUND) {
+			printf("can't evaluate %s._DGS - %s\n",
+			    acpi_name(handle), AcpiFormatException(status));
+		} else {
+			dgs = 0xff;
+		}
+	}
 
 	return (dgs);
 }
@@ -1089,7 +1138,7 @@ vo_set_device_state(ACPI_HANDLE handle, UINT32 state)
 
 	ACPI_SERIAL_ASSERT(video_output);
 	status = acpi_SetInteger(handle, "_DSS", state);
-	if (ACPI_FAILURE(status))
+	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
 		printf("can't evaluate %s._DSS - %s\n",
-		       acpi_name(handle), AcpiFormatException(status));
+		    acpi_name(handle), AcpiFormatException(status));
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005051214.045CEC7n053618>