|
@@ -1537,8 +1537,10 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena,
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int do_unregister_framebuffer(struct fb_info *fb_info);
|
|
|
|
+
|
|
#define VGA_FB_PHYS 0xA0000
|
|
#define VGA_FB_PHYS 0xA0000
|
|
-void remove_conflicting_framebuffers(struct apertures_struct *a,
|
|
|
|
|
|
+static void do_remove_conflicting_framebuffers(struct apertures_struct *a,
|
|
const char *name, bool primary)
|
|
const char *name, bool primary)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
@@ -1560,39 +1562,26 @@ void remove_conflicting_framebuffers(struct apertures_struct *a,
|
|
printk(KERN_INFO "fb: conflicting fb hw usage "
|
|
printk(KERN_INFO "fb: conflicting fb hw usage "
|
|
"%s vs %s - removing generic driver\n",
|
|
"%s vs %s - removing generic driver\n",
|
|
name, registered_fb[i]->fix.id);
|
|
name, registered_fb[i]->fix.id);
|
|
- unregister_framebuffer(registered_fb[i]);
|
|
|
|
|
|
+ do_unregister_framebuffer(registered_fb[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL(remove_conflicting_framebuffers);
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * register_framebuffer - registers a frame buffer device
|
|
|
|
- * @fb_info: frame buffer info structure
|
|
|
|
- *
|
|
|
|
- * Registers a frame buffer device @fb_info.
|
|
|
|
- *
|
|
|
|
- * Returns negative errno on error, or zero for success.
|
|
|
|
- *
|
|
|
|
- */
|
|
|
|
|
|
|
|
-int
|
|
|
|
-register_framebuffer(struct fb_info *fb_info)
|
|
|
|
|
|
+static int do_register_framebuffer(struct fb_info *fb_info)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
struct fb_event event;
|
|
struct fb_event event;
|
|
struct fb_videomode mode;
|
|
struct fb_videomode mode;
|
|
|
|
|
|
- if (num_registered_fb == FB_MAX)
|
|
|
|
- return -ENXIO;
|
|
|
|
-
|
|
|
|
if (fb_check_foreignness(fb_info))
|
|
if (fb_check_foreignness(fb_info))
|
|
return -ENOSYS;
|
|
return -ENOSYS;
|
|
|
|
|
|
- remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id,
|
|
|
|
|
|
+ do_remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id,
|
|
fb_is_primary_device(fb_info));
|
|
fb_is_primary_device(fb_info));
|
|
|
|
|
|
- mutex_lock(®istration_lock);
|
|
|
|
|
|
+ if (num_registered_fb == FB_MAX)
|
|
|
|
+ return -ENXIO;
|
|
|
|
+
|
|
num_registered_fb++;
|
|
num_registered_fb++;
|
|
for (i = 0 ; i < FB_MAX; i++)
|
|
for (i = 0 ; i < FB_MAX; i++)
|
|
if (!registered_fb[i])
|
|
if (!registered_fb[i])
|
|
@@ -1635,7 +1624,6 @@ register_framebuffer(struct fb_info *fb_info)
|
|
fb_var_to_videomode(&mode, &fb_info->var);
|
|
fb_var_to_videomode(&mode, &fb_info->var);
|
|
fb_add_videomode(&mode, &fb_info->modelist);
|
|
fb_add_videomode(&mode, &fb_info->modelist);
|
|
registered_fb[i] = fb_info;
|
|
registered_fb[i] = fb_info;
|
|
- mutex_unlock(®istration_lock);
|
|
|
|
|
|
|
|
event.info = fb_info;
|
|
event.info = fb_info;
|
|
if (!lock_fb_info(fb_info))
|
|
if (!lock_fb_info(fb_info))
|
|
@@ -1645,37 +1633,14 @@ register_framebuffer(struct fb_info *fb_info)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * unregister_framebuffer - releases a frame buffer device
|
|
|
|
- * @fb_info: frame buffer info structure
|
|
|
|
- *
|
|
|
|
- * Unregisters a frame buffer device @fb_info.
|
|
|
|
- *
|
|
|
|
- * Returns negative errno on error, or zero for success.
|
|
|
|
- *
|
|
|
|
- * This function will also notify the framebuffer console
|
|
|
|
- * to release the driver.
|
|
|
|
- *
|
|
|
|
- * This is meant to be called within a driver's module_exit()
|
|
|
|
- * function. If this is called outside module_exit(), ensure
|
|
|
|
- * that the driver implements fb_open() and fb_release() to
|
|
|
|
- * check that no processes are using the device.
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-int
|
|
|
|
-unregister_framebuffer(struct fb_info *fb_info)
|
|
|
|
|
|
+static int do_unregister_framebuffer(struct fb_info *fb_info)
|
|
{
|
|
{
|
|
struct fb_event event;
|
|
struct fb_event event;
|
|
int i, ret = 0;
|
|
int i, ret = 0;
|
|
|
|
|
|
- mutex_lock(®istration_lock);
|
|
|
|
i = fb_info->node;
|
|
i = fb_info->node;
|
|
- if (!registered_fb[i]) {
|
|
|
|
- ret = -EINVAL;
|
|
|
|
- goto done;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
if (!lock_fb_info(fb_info))
|
|
if (!lock_fb_info(fb_info))
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
@@ -1683,10 +1648,8 @@ unregister_framebuffer(struct fb_info *fb_info)
|
|
ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
|
|
ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
|
|
unlock_fb_info(fb_info);
|
|
unlock_fb_info(fb_info);
|
|
|
|
|
|
- if (ret) {
|
|
|
|
- ret = -EINVAL;
|
|
|
|
- goto done;
|
|
|
|
- }
|
|
|
|
|
|
+ if (ret)
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
|
if (fb_info->pixmap.addr &&
|
|
if (fb_info->pixmap.addr &&
|
|
(fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
|
|
(fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
|
|
@@ -1701,8 +1664,64 @@ unregister_framebuffer(struct fb_info *fb_info)
|
|
|
|
|
|
/* this may free fb info */
|
|
/* this may free fb info */
|
|
put_fb_info(fb_info);
|
|
put_fb_info(fb_info);
|
|
-done:
|
|
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void remove_conflicting_framebuffers(struct apertures_struct *a,
|
|
|
|
+ const char *name, bool primary)
|
|
|
|
+{
|
|
|
|
+ mutex_lock(®istration_lock);
|
|
|
|
+ do_remove_conflicting_framebuffers(a, name, primary);
|
|
|
|
+ mutex_unlock(®istration_lock);
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(remove_conflicting_framebuffers);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * register_framebuffer - registers a frame buffer device
|
|
|
|
+ * @fb_info: frame buffer info structure
|
|
|
|
+ *
|
|
|
|
+ * Registers a frame buffer device @fb_info.
|
|
|
|
+ *
|
|
|
|
+ * Returns negative errno on error, or zero for success.
|
|
|
|
+ *
|
|
|
|
+ */
|
|
|
|
+int
|
|
|
|
+register_framebuffer(struct fb_info *fb_info)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ mutex_lock(®istration_lock);
|
|
|
|
+ ret = do_register_framebuffer(fb_info);
|
|
|
|
+ mutex_unlock(®istration_lock);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * unregister_framebuffer - releases a frame buffer device
|
|
|
|
+ * @fb_info: frame buffer info structure
|
|
|
|
+ *
|
|
|
|
+ * Unregisters a frame buffer device @fb_info.
|
|
|
|
+ *
|
|
|
|
+ * Returns negative errno on error, or zero for success.
|
|
|
|
+ *
|
|
|
|
+ * This function will also notify the framebuffer console
|
|
|
|
+ * to release the driver.
|
|
|
|
+ *
|
|
|
|
+ * This is meant to be called within a driver's module_exit()
|
|
|
|
+ * function. If this is called outside module_exit(), ensure
|
|
|
|
+ * that the driver implements fb_open() and fb_release() to
|
|
|
|
+ * check that no processes are using the device.
|
|
|
|
+ */
|
|
|
|
+int
|
|
|
|
+unregister_framebuffer(struct fb_info *fb_info)
|
|
|
|
+{
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ mutex_lock(®istration_lock);
|
|
|
|
+ ret = do_unregister_framebuffer(fb_info);
|
|
mutex_unlock(®istration_lock);
|
|
mutex_unlock(®istration_lock);
|
|
|
|
+
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|