Skip to contentSkip to conversation

fbdev state management

PATCH New Benjamin Herrenschmidt 1 participant 1 message Feb 15, 2004

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 fbdev state management

Hi !

This patch add some "state" information for power management to fbdev's, along with a notifier mecanism to inform clients of state changes. It also "uses" this mecanism in the function fb_set_suspend() which was an empty placeholder previously, and "shields" various places that access the HW when state isn't running. (It's best to not call them in the first place, but the current state of fbcon makes that _very_ difficult)

Ben.

# This is a BitKeeper generated diff -Nru style patch. #
# ChangeSet

#   2004/02/15 17:06:41+11:00 [email protected] 
#   Add fbdev "state" for power management, a notifer for clients to
#   be notified of states change, and shield some low level operations
#   when the fbdev state isn't running
# 
# include/linux/fb.h
#   2004/02/15 17:06:27+11:00 [email protected] +21 -0
#   Add fbdev "state" for power management, a notifer for clients to
#   be notified of states change, and shield some low level operations
#   when the fbdev state isn't running
# 
# drivers/video/softcursor.c
#   2004/02/15 17:06:27+11:00 [email protected] +3 -0
#   Add fbdev "state" for power management, a notifer for clients to
#   be notified of states change, and shield some low level operations
#   when the fbdev state isn't running
# 
# drivers/video/fbmem.c
#   2004/02/15 17:06:27+11:00 [email protected] +47 -2
#   Add fbdev "state" for power management, a notifer for clients to
#   be notified of states change, and shield some low level operations
#   when the fbdev state isn't running
# 
# drivers/video/console/fbcon.c
#   2004/02/15 17:06:27+11:00 [email protected] +8 -2
#   Add fbdev "state" for power management, a notifer for clients to
#   be notified of states change, and shield some low level operations
#   when the fbdev state isn't running
# 
# drivers/video/cfbimgblt.c
#   2004/02/15 17:06:27+11:00 [email protected] +3 -0
#   Add fbdev "state" for power management, a notifer for clients to
#   be notified of states change, and shield some low level operations
#   when the fbdev state isn't running
# 
# drivers/video/cfbfillrect.c
#   2004/02/15 17:06:27+11:00 [email protected] +3 -0
#   Add fbdev "state" for power management, a notifer for clients to
#   be notified of states change, and shield some low level operations
#   when the fbdev state isn't running
# 
# drivers/video/cfbcopyarea.c
#   2004/02/15 17:06:27+11:00 [email protected] +3 -0
#   Add fbdev "state" for power management, a notifer for clients to
#   be notified of states change, and shield some low level operations
#   when the fbdev state isn't running
# 
# drivers/video/aty/radeon_accel.c
#   2004/02/15 17:06:27+11:00 [email protected] +4 -4
#   Add fbdev "state" for power management, a notifer for clients to
#   be notified of states change, and shield some low level operations
#   when the fbdev state isn't running
# 
diff -Nru a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c
--- a/drivers/video/aty/radeon_accel.c	Sun Feb 15 17:07:11 2004
+++ b/drivers/video/aty/radeon_accel.c	Sun Feb 15 17:07:11 2004
@@ -28,7 +28,7 @@
 	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);
@@ -81,7 +81,7 @@
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);
@@ -108,7 +108,7 @@
{
struct radeonfb_info *rinfo = info->par;

- if (rinfo->asleep)
+ if (info->state != FBINFO_STATE_RUNNING)
return;
radeon_engine_idle();

@@ -119,7 +119,7 @@
{
struct radeonfb_info *rinfo = info->par;

- if (rinfo->asleep)
+ if (info->state != FBINFO_STATE_RUNNING)
return 0;
radeon_engine_idle();

drivers/video/cfbcopyarea.c +3 -0
diff -Nru a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
@@ -346,6 +346,9 @@
 	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) {
 	}	
drivers/video/cfbfillrect.c +3 -0
diff -Nru a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
@@ -367,6 +367,9 @@
 	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) {
 	}	
drivers/video/cfbimgblt.c +3 -0
diff -Nru a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
@@ -275,6 +275,9 @@
 	int x2, y2, vxres, vyres;
 	u8 *dst1;
 
+	if (p->state != FBINFO_STATE_RUNNING)
+		return;
+
 	vxres = p->var.xres_virtual;
 	vyres = p->var.yres_virtual;
 	/* 
drivers/video/console/fbcon.c +8 -2
diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
@@ -195,8 +195,8 @@
 {
 	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;
@@ -939,6 +939,8 @@
 
 	if (!info->fbops->fb_blank && console_blanked)
 		return;
+	if (info->state != FBINFO_STATE_RUNNING)
+		return;
 
 	if (!height || !width)
 		return;
@@ -963,6 +965,8 @@
 
 	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;
@@ -977,6 +981,8 @@
 	struct display *p = &fb_display[vc->vc_num];
 
 	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)
drivers/video/fbmem.c +47 -2

92 lines not on this page · raw message

drivers/video/softcursor.c +3 -0
diff -Nru a/drivers/video/softcursor.c b/drivers/video/softcursor.c
@@ -48,6 +48,9 @@
 		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;
include/linux/fb.h +21 -0
diff -Nru a/include/linux/fb.h b/include/linux/fb.h
@@ -340,6 +340,24 @@
 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
  *
  * The purpose of this structure is to translate data
@@ -447,6 +465,9 @@
 	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;	
 };