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

Commit 3b0d7117 authored by Al Viro's avatar Al Viro Committed by Len Brown
Browse files

ACPI: asus-laptop: Fix failure exits

> Subject         : drivers/misc/asus-laptop.c:*: error: 'struct led_classdev' has no member named 'class_dev'
> References      : http://lkml.org/lkml/2007/7/22/299


> Submitter       : Gabriel C <nix.or.die@googlemail.com>

Fallout from f8a7c6fe.  However, looking
at it shows that checks done in ASUS_LED_UNREGISTER() can't trigger
at all (we never get to asus_led_exit() if registration fails) and
if that registration fails, we actually leak stuff.  IOW, it's worse
than just replacing class_dev with dev in there - the tests themselves
had been papering over the lousy cleanup logics.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 3cc2649b
Loading
Loading
Loading
Loading
+21 −11
Original line number Diff line number Diff line
@@ -1067,19 +1067,16 @@ static void asus_backlight_exit(void)
}

#define  ASUS_LED_UNREGISTER(object)				\
	if(object##_led.class_dev				\
	   && !IS_ERR(object##_led.class_dev))			\
	led_classdev_unregister(&object##_led)

static void asus_led_exit(void)
{
	destroy_workqueue(led_workqueue);
	ASUS_LED_UNREGISTER(mled);
	ASUS_LED_UNREGISTER(tled);
	ASUS_LED_UNREGISTER(pled);
	ASUS_LED_UNREGISTER(rled);
	ASUS_LED_UNREGISTER(gled);

	destroy_workqueue(led_workqueue);
}

static void __exit asus_laptop_exit(void)
@@ -1135,29 +1132,42 @@ static int asus_led_init(struct device *dev)

	rv = ASUS_LED_REGISTER(mled, dev);
	if (rv)
		return rv;
		goto out;

	rv = ASUS_LED_REGISTER(tled, dev);
	if (rv)
		return rv;
		goto out1;

	rv = ASUS_LED_REGISTER(rled, dev);
	if (rv)
		return rv;
		goto out2;

	rv = ASUS_LED_REGISTER(pled, dev);
	if (rv)
		return rv;
		goto out3;

	rv = ASUS_LED_REGISTER(gled, dev);
	if (rv)
		return rv;
		goto out4;

	led_workqueue = create_singlethread_workqueue("led_workqueue");
	if (!led_workqueue)
		return -ENOMEM;
		goto out5;

	return 0;
out5:
	rv = -ENOMEM;
	ASUS_LED_UNREGISTER(gled);
out4:
	ASUS_LED_UNREGISTER(pled);
out3:
	ASUS_LED_UNREGISTER(rled);
out2:
	ASUS_LED_UNREGISTER(tled);
out1:
	ASUS_LED_UNREGISTER(mled);
out:
	return rv;
}

static int __init asus_laptop_init(void)