struct fb_fillrect modded;
int vxres, vyres;
- if (rinfo->asleep)
+ if (info->state != FBINFO_STATE_RUNNING)
return;
if (radeon_accel_disabled()) {
cfb_fillrect(info, region);
modded.width = area->width;
modded.height = area->height;
- if (rinfo->asleep)
+ if (info->state != FBINFO_STATE_RUNNING)
return;
if (radeon_accel_disabled()) {
cfb_copyarea(info, area);
{
struct radeonfb_info *rinfo = info->par;
- if (rinfo->asleep)
+ if (info->state != FBINFO_STATE_RUNNING)
return;
radeon_engine_idle();
{
struct radeonfb_info *rinfo = info->par;
- if (rinfo->asleep)
+ if (info->state != FBINFO_STATE_RUNNING)
return 0;
radeon_engine_idle();
int dst_idx = 0, src_idx = 0, rev_copy = 0;
unsigned long *dst = NULL, *src = NULL;
+ if (p->state != FBINFO_STATE_RUNNING)
+ return;
+
/* We want rotation but lack hardware to do it for us. */
if (!p->fbops->fb_rotate && p->var.rotate) {
}
unsigned long *dst;
int dst_idx, left;
+ if (p->state != FBINFO_STATE_RUNNING)
+ return;
+
/* We want rotation but lack hardware to do it for us. */
if (!p->fbops->fb_rotate && p->var.rotate) {
}
int x2, y2, vxres, vyres;
u8 *dst1;
+ if (p->state != FBINFO_STATE_RUNNING)
+ return;
+
vxres = p->var.xres_virtual;
vyres = p->var.yres_virtual;
/*
{
struct fb_info *info = (struct fb_info *) private;
- /* Test to see if the cursor is erased but still on */
- if (!info || (info->cursor.rop == ROP_COPY))
+ if (!info || info->state != FBINFO_STATE_RUNNING ||
+ info->cursor.rop == ROP_COPY)
return;
acquire_console_sem();
info->cursor.enable ^= 1;
if (!info->fbops->fb_blank && console_blanked)
return;
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
if (!height || !width)
return;
if (!info->fbops->fb_blank && console_blanked)
return;
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
return;
if (!info->fbops->fb_blank && console_blanked)
return;
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
return;
static initcall_t pref_init_funcs[FB_MAX];
static int num_pref_init_funcs __initdata = 0;
+static struct notifier_block *fb_notifier_list;
struct fb_info *registered_fb[FB_MAX];
int num_registered_fb;
struct fb_image image;
int x;
- /* Return if the frame buffer is not mapped */
- if (fb_logo.logo == NULL)
+ /* Return if the frame buffer is not mapped or suspended */
+ if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING)
return 0;
image.depth = fb_logo.depth;
if (!info || ! info->screen_base)
return -ENODEV;
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
if (info->fbops->fb_read)
return info->fbops->fb_read(file, buf, count, ppos);
if (!info || !info->screen_base)
return -ENODEV;
+ if (info->state != FBINFO_STATE_RUNNING)
+ return -EPERM;
+
if (info->fbops->fb_write)
return info->fbops->fb_write(file, buf, count, ppos);
fb_pan_display(info, &info->var);
fb_set_cmap(&info->cmap, 1, info);
+
+ notifier_call_chain(&fb_notifier_list, FB_EVENT_MODE_CHANGE, info);
}
}
return 0;
return 0;
}
+/**
+ * fb_register_client - register a client notifier
+ * @nb: notifier block to callback on events
+ */
+int fb_register_client(struct notifier_block *nb)
+{
+ return notifier_chain_register(&fb_notifier_list, nb);
+}
+
+/**
+ * fb_unregister_client - unregister a client notifier
+ * @nb: notifier block to callback on events
+ */
+int fb_unregister_client(struct notifier_block *nb)
+{
+ return notifier_chain_unregister(&fb_notifier_list, nb);
+}
+
+/**
+ * fb_set_suspend - low level driver signals suspend
+ * @info: framebuffer affected
+ * @state: 0 = resuming, !=0 = suspending
+ *
+ * This is meant to be used by low level drivers to
+ * signal suspend/resume to the core & clients.
+ * It must be called with the console semaphore held
+ */
void fb_set_suspend(struct fb_info *info, int state)
{
+ if (state) {
+ notifier_call_chain(&fb_notifier_list, FB_EVENT_SUSPEND, info);
+ info->state = FBINFO_STATE_SUSPENDED;
+ } else {
+ info->state = FBINFO_STATE_RUNNING;
+ notifier_call_chain(&fb_notifier_list, FB_EVENT_RESUME, info);
+ }
}
/**
EXPORT_SYMBOL(move_buf_unaligned);
EXPORT_SYMBOL(move_buf_aligned);
EXPORT_SYMBOL(fb_set_suspend);
+EXPORT_SYMBOL(fb_register_client);
+EXPORT_SYMBOL(fb_unregister_client);
MODULE_LICENSE("GPL");
info->cursor.image.depth = cursor->image.depth;
}
+ if (info->state != FBINFO_STATE_RUNNING)
+ return 0;
+
s_pitch = (info->cursor.image.width + 7) >> 3;
dsize = s_pitch * info->cursor.image.height;
d_pitch = (s_pitch + scan_align) & ~scan_align;
struct device;
struct file;
+/*
+ * Register/unregister for framebuffer events
+ */
+
+/* The resolution of the passed in fb_info about to change */
+#define FB_EVENT_MODE_CHANGE 0x01
+/* The display on this fb_info is beeing suspended, no access to the
+ * framebuffer is allowed any more after that call returns
+ */
+#define FB_EVENT_SUSPEND 0x02
+/* The display on this fb_info was resumed, you can restore the display
+ * if you own it
+ */
+#define FB_EVENT_RESUME 0x03
+
+extern int fb_register_client(struct notifier_block *nb);
+extern int fb_unregister_client(struct notifier_block *nb);
+
/*
* Pixmap structure definition
*
struct vc_data *display_fg; /* Console visible on this display */
int currcon; /* Current VC. */
void *pseudo_palette; /* Fake palette of 16 colors */
+#define FBINFO_STATE_RUNNING 0
+#define FBINFO_STATE_SUSPENDED 1
+ u32 state; /* Hardware state i.e suspend */
/* From here on everything is device dependent */
void *par;
};