Author: avg
Date: Tue May 26 05:54:00 2020
New Revision: 361495
URL: https://svnweb.freebsd.org/changeset/base/361495

Log:
  MFC r360657: acpi_video: support 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 then we can make assumptions as well.
  
  The change is based on a patch suggested by Anthony Jenkins
  <scoobi_...@yahoo.com> in PR 207086.
  
  PR:           207086

Modified:
  stable/12/sys/dev/acpica/acpi_video.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/acpica/acpi_video.c
==============================================================================
--- stable/12/sys/dev/acpica/acpi_video.c       Tue May 26 03:58:19 2020        
(r361494)
+++ stable/12/sys/dev/acpica/acpi_video.c       Tue May 26 05:54:00 2020        
(r361495)
@@ -51,6 +51,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;
@@ -95,8 +97,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);
@@ -326,9 +328,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);
@@ -418,7 +420,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);
        }
@@ -517,6 +519,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;
@@ -696,7 +700,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;
@@ -740,7 +744,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;
        }
 
@@ -805,7 +809,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);
@@ -846,7 +850,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:
@@ -1016,15 +1020,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);
        }
@@ -1035,16 +1063,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);
 }
@@ -1058,9 +1089,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);
 }
@@ -1073,9 +1113,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);
 }
@@ -1087,7 +1136,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));
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to