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

Commit 28ee086d authored by Richard Purdie's avatar Richard Purdie
Browse files

backlight: Fix external uses of backlight internal semaphore



backlight_device->sem has a very specific use as documented in the
header file. The external users of this are using it for a different
reason, to serialise access to the update_status() method.

backlight users were supposed to implement their own internal
serialisation of update_status() if needed but everyone is doing
things differently and incorrectly. Therefore add a global mutex to
take care of serialisation for everyone, once and for all.

Locking for get_brightness remains optional since most users don't
need it.

Also update the lcd class in a similar way.

Signed-off-by: default avatarRichard Purdie <rpurdie@rpsys.net>
parent a8db3c19
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -107,12 +107,10 @@ int die(const char *str, struct pt_regs *regs, long err)
	if (machine_is(powermac) && pmac_backlight) {
		struct backlight_properties *props;

		down(&pmac_backlight->sem);
		props = pmac_backlight->props;
		props->brightness = props->max_brightness;
		props->power = FB_BLANK_UNBLANK;
		props->update_status(pmac_backlight);
		up(&pmac_backlight->sem);
		backlight_update_status(pmac_backlight);
	}
	mutex_unlock(&pmac_backlight_mutex);
#endif
+5 −14
Original line number Diff line number Diff line
@@ -37,7 +37,9 @@ static int pmac_backlight_set_legacy_queued;
 */
static atomic_t kernel_backlight_disabled = ATOMIC_INIT(0);

/* Protect the pmac_backlight variable */
/* Protect the pmac_backlight variable below.
   You should hold this lock when using the pmac_backlight pointer to
   prevent its potential removal. */
DEFINE_MUTEX(pmac_backlight_mutex);

/* Main backlight storage
@@ -49,9 +51,6 @@ DEFINE_MUTEX(pmac_backlight_mutex);
 * internal display, it doesn't matter. Other backlight drivers can be used
 * independently.
 *
 * Lock ordering:
 * pmac_backlight_mutex (global, main backlight)
 *   pmac_backlight->sem (backlight class)
 */
struct backlight_device *pmac_backlight;

@@ -104,7 +103,6 @@ static void pmac_backlight_key_worker(struct work_struct *work)
		struct backlight_properties *props;
		int brightness;

		down(&pmac_backlight->sem);
		props = pmac_backlight->props;

		brightness = props->brightness +
@@ -117,9 +115,7 @@ static void pmac_backlight_key_worker(struct work_struct *work)
			brightness = props->max_brightness;

		props->brightness = brightness;
		props->update_status(pmac_backlight);

		up(&pmac_backlight->sem);
		backlight_update_status(pmac_backlight);
	}
	mutex_unlock(&pmac_backlight_mutex);
}
@@ -145,7 +141,6 @@ static int __pmac_backlight_set_legacy_brightness(int brightness)
	if (pmac_backlight) {
		struct backlight_properties *props;

		down(&pmac_backlight->sem);
		props = pmac_backlight->props;
		props->brightness = brightness *
			(props->max_brightness + 1) /
@@ -156,8 +151,7 @@ static int __pmac_backlight_set_legacy_brightness(int brightness)
		else if (props->brightness < 0)
			props->brightness = 0;

		props->update_status(pmac_backlight);
		up(&pmac_backlight->sem);
		backlight_update_status(pmac_backlight);

		error = 0;
	}
@@ -196,14 +190,11 @@ int pmac_backlight_get_legacy_brightness()
	if (pmac_backlight) {
		struct backlight_properties *props;

		down(&pmac_backlight->sem);
		props = pmac_backlight->props;

		result = props->brightness *
			(OLD_BACKLIGHT_MAX + 1) /
			(props->max_brightness + 1);

		up(&pmac_backlight->sem);
	}
	mutex_unlock(&pmac_backlight_mutex);

+1 −3
Original line number Diff line number Diff line
@@ -166,11 +166,9 @@ void __init pmu_backlight_init()
				pmu_backlight_data.max_brightness / 15);
	}

	down(&bd->sem);
	bd->props->brightness = level;
	bd->props->power = FB_BLANK_UNBLANK;
	bd->props->update_status(bd);
	up(&bd->sem);
	backlight_update_status(bd);

	mutex_lock(&pmac_backlight_mutex);
	if (!pmac_backlight)
+5 −15
Original line number Diff line number Diff line
@@ -348,13 +348,8 @@ static void lcd_blank(int blank)
	struct backlight_device *bd = asus_backlight_device;

	if (bd) {
		down(&bd->sem);
		if (likely(bd->props)) {
		bd->props->power = blank;
			if (likely(bd->props->update_status))
				bd->props->update_status(bd);
		}
		up(&bd->sem);
		backlight_update_status(bd);
	}
}

@@ -1028,14 +1023,9 @@ static int asus_backlight_init(struct device *dev)

		asus_backlight_device = bd;

		down(&bd->sem);
		if (likely(bd->props)) {
		bd->props->brightness = read_brightness(NULL);
		bd->props->power = FB_BLANK_UNBLANK;
			if (likely(bd->props->update_status))
				bd->props->update_status(bd);
		}
		up(&bd->sem);
		backlight_update_status(bd);
	}
	return 0;
}
+0 −6
Original line number Diff line number Diff line
@@ -189,11 +189,9 @@ static void appledisplay_work(struct work_struct *work)
		container_of(work, struct appledisplay, work.work);
	int retval;

	up(&pdata->bd->sem);
	retval = appledisplay_bl_get_brightness(pdata->bd);
	if (retval >= 0)
		pdata->bd->props->brightness = retval;
	down(&pdata->bd->sem);

	/* Poll again in about 125ms if there's still a button pressed */
	if (pdata->button_pressed)
@@ -288,9 +286,7 @@ static int appledisplay_probe(struct usb_interface *iface,
	}

	/* Try to get brightness */
	up(&pdata->bd->sem);
	brightness = appledisplay_bl_get_brightness(pdata->bd);
	down(&pdata->bd->sem);

	if (brightness < 0) {
		retval = brightness;
@@ -299,9 +295,7 @@ static int appledisplay_probe(struct usb_interface *iface,
	}

	/* Set brightness in backlight device */
	up(&pdata->bd->sem);
	pdata->bd->props->brightness = brightness;
	down(&pdata->bd->sem);

	/* save our data pointer in the interface device */
	usb_set_intfdata(iface, pdata);
Loading