@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/slab.h>
+#include <linux/sysfb.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/vt.h>
@@ -1587,18 +1588,35 @@ static void do_remove_conflicting_framebuffers(struct apertures_struct *a,
if (!device) {
pr_warn("fb%d: no device set\n", i);
do_unregister_framebuffer(registered_fb[i]);
- } else if (dev_is_platform(device)) {
+ } else {
/*
* Drop the lock because if the device is unregistered, its
* driver will call to unregister_framebuffer(), that takes
* this lock.
*/
mutex_unlock(®istration_lock);
- platform_device_unregister(to_platform_device(device));
+ /*
+ * First attempt the device to be unregistered by sysfb.
+ */
+ if (!sysfb_try_unregister(device)) {
+ if (dev_is_platform(device)) {
+ /*
+ * FIXME: sysfb didn't register this device, the platform
+ * device was registered in other platform code.
+ */
+ platform_device_unregister(to_platform_device(device));
+ } else {
+ /*
+ * If is not a platform device, at least print a warning. A
+ * fix would add to make the code that registered the device
+ * to also unregister it.
+ */
+ pr_warn("fb%d: cannot remove device\n", i);
+ /* call unregister_framebuffer() since the lock was dropped */
+ unregister_framebuffer(registered_fb[i]);
+ }
+ }
mutex_lock(®istration_lock);
- } else {
- pr_warn("fb%d: cannot remove device\n", i);
- do_unregister_framebuffer(registered_fb[i]);
}
/*
* Restart the removal loop now that the device has been