Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4273af8d authored by Henrique de Moraes Holschuh's avatar Henrique de Moraes Holschuh Committed by Len Brown
Browse files

ACPI: thinkpad-acpi: fix brightness_set error paths



The code calling brightness_set() can't handle EINTR/ERESTARTSYS well, nor
is it checking brightness_set() return status properly.

Fix it.

Signed-off-by: default avatarHenrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent fc589a3c
Loading
Loading
Loading
Loading
+21 −13
Original line number Diff line number Diff line
@@ -3278,6 +3278,8 @@ static void brightness_exit(void)

static int brightness_update_status(struct backlight_device *bd)
{
	/* it is the backlight class's job (caller) to handle
	 * EINTR and other errors properly */
	return brightness_set(
		(bd->props.fb_blank == FB_BLANK_UNBLANK &&
		 bd->props.power == FB_BLANK_UNBLANK) ?
@@ -3318,6 +3320,7 @@ static int brightness_get(struct backlight_device *bd)
	return level;
}

/* May return EINTR which can always be mapped to ERESTARTSYS */
static int brightness_set(int value)
{
	int cmos_cmd, inc, i, res;
@@ -3381,29 +3384,34 @@ static int brightness_read(char *p)
static int brightness_write(char *buf)
{
	int level;
	int new_level;
	int rc;
	char *cmd;
	int max_level = (tp_features.bright_16levels) ? 15 : 7;

	while ((cmd = next_cmd(&buf))) {
		if ((level = brightness_get(NULL)) < 0)
	level = brightness_get(NULL);
	if (level < 0)
		return level;

	while ((cmd = next_cmd(&buf))) {
		if (strlencmp(cmd, "up") == 0) {
			new_level = level == (max_level)?
						max_level : level + 1;
			if (level < max_level)
				level++;
		} else if (strlencmp(cmd, "down") == 0) {
			new_level = level == 0? 0 : level - 1;
		} else if (sscanf(cmd, "level %d", &new_level) == 1 &&
			   new_level >= 0 && new_level <= max_level) {
			/* new_level set */
			if (level > 0)
				level--;
		} else if (sscanf(cmd, "level %d", &level) == 1 &&
			   level >= 0 && level <= max_level) {
			/* new level set */
		} else
			return -EINVAL;

		brightness_set(new_level);
	}

	return 0;
	/*
	 * Now we know what the final level should be, so we try to set it.
	 * Doing it this way makes the syscall restartable in case of EINTR
	 */
	rc = brightness_set(level);
	return (rc == -EINTR)? ERESTARTSYS : rc;
}

static struct ibm_struct brightness_driver_data = {