Added files
This commit is contained in:
		
							parent
							
								
									8dcd507f47
								
							
						
					
					
						commit
						2ab4619732
					
				@ -0,0 +1,500 @@
 | 
			
		||||
--- b/drivers/video/fbdev/core/fbcon.c
 | 
			
		||||
+++ a/drivers/video/fbdev/core/fbcon.c
 | 
			
		||||
@@ -122,6 +122,12 @@
 | 
			
		||||
 /* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
 | 
			
		||||
    enums.  */
 | 
			
		||||
 static int logo_shown = FBCON_LOGO_CANSHOW;
 | 
			
		||||
+/* Software scrollback */
 | 
			
		||||
+static int fbcon_softback_size = 32768;
 | 
			
		||||
+static unsigned long softback_buf, softback_curr;
 | 
			
		||||
+static unsigned long softback_in;
 | 
			
		||||
+static unsigned long softback_top, softback_end;
 | 
			
		||||
+static int softback_lines;
 | 
			
		||||
 /* console mappings */
 | 
			
		||||
 static int first_fb_vc;
 | 
			
		||||
 static int last_fb_vc = MAX_NR_CONSOLES - 1;
 | 
			
		||||
@@ -161,6 +167,8 @@
 | 
			
		||||
 
 | 
			
		||||
 static const struct consw fb_con;
 | 
			
		||||
 
 | 
			
		||||
+#define CM_SOFTBACK	(8)
 | 
			
		||||
+
 | 
			
		||||
 #define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
 | 
			
		||||
 
 | 
			
		||||
 static int fbcon_set_origin(struct vc_data *);
 | 
			
		||||
@@ -365,6 +373,18 @@
 | 
			
		||||
 	return color;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void fbcon_update_softback(struct vc_data *vc)
 | 
			
		||||
+{
 | 
			
		||||
+	int l = fbcon_softback_size / vc->vc_size_row;
 | 
			
		||||
+
 | 
			
		||||
+	if (l > 5)
 | 
			
		||||
+		softback_end = softback_buf + l * vc->vc_size_row;
 | 
			
		||||
+	else
 | 
			
		||||
+		/* Smaller scrollback makes no sense, and 0 would screw
 | 
			
		||||
+		   the operation totally */
 | 
			
		||||
+		softback_top = 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void fb_flashcursor(struct work_struct *work)
 | 
			
		||||
 {
 | 
			
		||||
 	struct fb_info *info = container_of(work, struct fb_info, queue);
 | 
			
		||||
@@ -394,7 +414,7 @@
 | 
			
		||||
 	c = scr_readw((u16 *) vc->vc_pos);
 | 
			
		||||
 	mode = (!ops->cursor_flash || ops->cursor_state.enable) ?
 | 
			
		||||
 		CM_ERASE : CM_DRAW;
 | 
			
		||||
+	ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1),
 | 
			
		||||
-	ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1),
 | 
			
		||||
 		    get_color(vc, info, c, 0));
 | 
			
		||||
 	console_unlock();
 | 
			
		||||
 }
 | 
			
		||||
@@ -451,7 +471,13 @@
 | 
			
		||||
 		}
 | 
			
		||||
 		
 | 
			
		||||
 		if (!strncmp(options, "scrollback:", 11)) {
 | 
			
		||||
+			options += 11;
 | 
			
		||||
+			if (*options) {
 | 
			
		||||
+				fbcon_softback_size = simple_strtoul(options, &options, 0);
 | 
			
		||||
+				if (*options == 'k' || *options == 'K') {
 | 
			
		||||
+					fbcon_softback_size *= 1024;
 | 
			
		||||
+				}
 | 
			
		||||
+			}
 | 
			
		||||
-			pr_warn("Ignoring scrollback size option\n");
 | 
			
		||||
 			continue;
 | 
			
		||||
 		}
 | 
			
		||||
 		
 | 
			
		||||
@@ -996,6 +1022,31 @@
 | 
			
		||||
 
 | 
			
		||||
 	set_blitting_type(vc, info);
 | 
			
		||||
 
 | 
			
		||||
+	if (info->fix.type != FB_TYPE_TEXT) {
 | 
			
		||||
+		if (fbcon_softback_size) {
 | 
			
		||||
+			if (!softback_buf) {
 | 
			
		||||
+				softback_buf =
 | 
			
		||||
+				    (unsigned long)
 | 
			
		||||
+				    kvmalloc(fbcon_softback_size,
 | 
			
		||||
+					    GFP_KERNEL);
 | 
			
		||||
+				if (!softback_buf) {
 | 
			
		||||
+					fbcon_softback_size = 0;
 | 
			
		||||
+					softback_top = 0;
 | 
			
		||||
+				}
 | 
			
		||||
+			}
 | 
			
		||||
+		} else {
 | 
			
		||||
+			if (softback_buf) {
 | 
			
		||||
+				kvfree((void *) softback_buf);
 | 
			
		||||
+				softback_buf = 0;
 | 
			
		||||
+				softback_top = 0;
 | 
			
		||||
+			}
 | 
			
		||||
+		}
 | 
			
		||||
+		if (softback_buf)
 | 
			
		||||
+			softback_in = softback_top = softback_curr =
 | 
			
		||||
+			    softback_buf;
 | 
			
		||||
+		softback_lines = 0;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	/* Setup default font */
 | 
			
		||||
 	if (!p->fontdata && !vc->vc_font.data) {
 | 
			
		||||
 		if (!fontname[0] || !(font = find_font(fontname)))
 | 
			
		||||
@@ -1169,6 +1220,9 @@
 | 
			
		||||
 	if (logo)
 | 
			
		||||
 		fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
 | 
			
		||||
 
 | 
			
		||||
+	if (vc == svc && softback_buf)
 | 
			
		||||
+		fbcon_update_softback(vc);
 | 
			
		||||
+
 | 
			
		||||
 	if (ops->rotate_font && ops->rotate_font(info, vc)) {
 | 
			
		||||
 		ops->rotate = FB_ROTATE_UR;
 | 
			
		||||
 		set_blitting_type(vc, info);
 | 
			
		||||
@@ -1331,6 +1385,7 @@
 | 
			
		||||
 {
 | 
			
		||||
 	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
 | 
			
		||||
 	struct fbcon_ops *ops = info->fbcon_par;
 | 
			
		||||
+	int y;
 | 
			
		||||
  	int c = scr_readw((u16 *) vc->vc_pos);
 | 
			
		||||
 
 | 
			
		||||
 	ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms);
 | 
			
		||||
@@ -1334,11 +1389,19 @@ static void fbcon_cursor(struct vc_data
 | 
			
		||||
 		fbcon_add_cursor_timer(info);
 | 
			
		||||
 
 | 
			
		||||
 	ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
 | 
			
		||||
+	if (mode & CM_SOFTBACK) {
 | 
			
		||||
+		mode &= ~CM_SOFTBACK;
 | 
			
		||||
+		y = softback_lines;
 | 
			
		||||
+	} else {
 | 
			
		||||
+		if (softback_lines)
 | 
			
		||||
+			fbcon_set_origin(vc);
 | 
			
		||||
+		y = 0;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	if (!ops->cursor)
 | 
			
		||||
 		return;
 | 
			
		||||
 
 | 
			
		||||
-	ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1),
 | 
			
		||||
+	ops->cursor(vc, info, mode, y, get_color(vc, info, c, 1),
 | 
			
		||||
 		    get_color(vc, info, c, 0));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -1416,6 +1479,8 @@
 | 
			
		||||
 
 | 
			
		||||
 	if (con_is_visible(vc)) {
 | 
			
		||||
 		update_screen(vc);
 | 
			
		||||
+		if (softback_buf)
 | 
			
		||||
+			fbcon_update_softback(vc);
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -1553,6 +1618,99 @@
 | 
			
		||||
 	scrollback_current = 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void fbcon_redraw_softback(struct vc_data *vc, struct fbcon_display *p,
 | 
			
		||||
+				  long delta)
 | 
			
		||||
+{
 | 
			
		||||
+	int count = vc->vc_rows;
 | 
			
		||||
+	unsigned short *d, *s;
 | 
			
		||||
+	unsigned long n;
 | 
			
		||||
+	int line = 0;
 | 
			
		||||
+
 | 
			
		||||
+	d = (u16 *) softback_curr;
 | 
			
		||||
+	if (d == (u16 *) softback_in)
 | 
			
		||||
+		d = (u16 *) vc->vc_origin;
 | 
			
		||||
+	n = softback_curr + delta * vc->vc_size_row;
 | 
			
		||||
+	softback_lines -= delta;
 | 
			
		||||
+	if (delta < 0) {
 | 
			
		||||
+		if (softback_curr < softback_top && n < softback_buf) {
 | 
			
		||||
+			n += softback_end - softback_buf;
 | 
			
		||||
+			if (n < softback_top) {
 | 
			
		||||
+				softback_lines -=
 | 
			
		||||
+				    (softback_top - n) / vc->vc_size_row;
 | 
			
		||||
+				n = softback_top;
 | 
			
		||||
+			}
 | 
			
		||||
+		} else if (softback_curr >= softback_top
 | 
			
		||||
+			   && n < softback_top) {
 | 
			
		||||
+			softback_lines -=
 | 
			
		||||
+			    (softback_top - n) / vc->vc_size_row;
 | 
			
		||||
+			n = softback_top;
 | 
			
		||||
+		}
 | 
			
		||||
+	} else {
 | 
			
		||||
+		if (softback_curr > softback_in && n >= softback_end) {
 | 
			
		||||
+			n += softback_buf - softback_end;
 | 
			
		||||
+			if (n > softback_in) {
 | 
			
		||||
+				n = softback_in;
 | 
			
		||||
+				softback_lines = 0;
 | 
			
		||||
+			}
 | 
			
		||||
+		} else if (softback_curr <= softback_in && n > softback_in) {
 | 
			
		||||
+			n = softback_in;
 | 
			
		||||
+			softback_lines = 0;
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+	if (n == softback_curr)
 | 
			
		||||
+		return;
 | 
			
		||||
+	softback_curr = n;
 | 
			
		||||
+	s = (u16 *) softback_curr;
 | 
			
		||||
+	if (s == (u16 *) softback_in)
 | 
			
		||||
+		s = (u16 *) vc->vc_origin;
 | 
			
		||||
+	while (count--) {
 | 
			
		||||
+		unsigned short *start;
 | 
			
		||||
+		unsigned short *le;
 | 
			
		||||
+		unsigned short c;
 | 
			
		||||
+		int x = 0;
 | 
			
		||||
+		unsigned short attr = 1;
 | 
			
		||||
+
 | 
			
		||||
+		start = s;
 | 
			
		||||
+		le = advance_row(s, 1);
 | 
			
		||||
+		do {
 | 
			
		||||
+			c = scr_readw(s);
 | 
			
		||||
+			if (attr != (c & 0xff00)) {
 | 
			
		||||
+				attr = c & 0xff00;
 | 
			
		||||
+				if (s > start) {
 | 
			
		||||
+					fbcon_putcs(vc, start, s - start,
 | 
			
		||||
+						    line, x);
 | 
			
		||||
+					x += s - start;
 | 
			
		||||
+					start = s;
 | 
			
		||||
+				}
 | 
			
		||||
+			}
 | 
			
		||||
+			if (c == scr_readw(d)) {
 | 
			
		||||
+				if (s > start) {
 | 
			
		||||
+					fbcon_putcs(vc, start, s - start,
 | 
			
		||||
+						    line, x);
 | 
			
		||||
+					x += s - start + 1;
 | 
			
		||||
+					start = s + 1;
 | 
			
		||||
+				} else {
 | 
			
		||||
+					x++;
 | 
			
		||||
+					start++;
 | 
			
		||||
+				}
 | 
			
		||||
+			}
 | 
			
		||||
+			s++;
 | 
			
		||||
+			d++;
 | 
			
		||||
+		} while (s < le);
 | 
			
		||||
+		if (s > start)
 | 
			
		||||
+			fbcon_putcs(vc, start, s - start, line, x);
 | 
			
		||||
+		line++;
 | 
			
		||||
+		if (d == (u16 *) softback_end)
 | 
			
		||||
+			d = (u16 *) softback_buf;
 | 
			
		||||
+		if (d == (u16 *) softback_in)
 | 
			
		||||
+			d = (u16 *) vc->vc_origin;
 | 
			
		||||
+		if (s == (u16 *) softback_end)
 | 
			
		||||
+			s = (u16 *) softback_buf;
 | 
			
		||||
+		if (s == (u16 *) softback_in)
 | 
			
		||||
+			s = (u16 *) vc->vc_origin;
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p,
 | 
			
		||||
 			      int line, int count, int dy)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1692,6 +1850,31 @@
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static inline void fbcon_softback_note(struct vc_data *vc, int t,
 | 
			
		||||
+				       int count)
 | 
			
		||||
+{
 | 
			
		||||
+	unsigned short *p;
 | 
			
		||||
+
 | 
			
		||||
+	if (vc->vc_num != fg_console)
 | 
			
		||||
+		return;
 | 
			
		||||
+	p = (unsigned short *) (vc->vc_origin + t * vc->vc_size_row);
 | 
			
		||||
+
 | 
			
		||||
+	while (count) {
 | 
			
		||||
+		scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row);
 | 
			
		||||
+		count--;
 | 
			
		||||
+		p = advance_row(p, 1);
 | 
			
		||||
+		softback_in += vc->vc_size_row;
 | 
			
		||||
+		if (softback_in == softback_end)
 | 
			
		||||
+			softback_in = softback_buf;
 | 
			
		||||
+		if (softback_in == softback_top) {
 | 
			
		||||
+			softback_top += vc->vc_size_row;
 | 
			
		||||
+			if (softback_top == softback_end)
 | 
			
		||||
+				softback_top = softback_buf;
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+	softback_curr = softback_in;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
 | 
			
		||||
 		enum con_scroll dir, unsigned int count)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1714,6 +1897,8 @@
 | 
			
		||||
 	case SM_UP:
 | 
			
		||||
 		if (count > vc->vc_rows)	/* Maximum realistic size */
 | 
			
		||||
 			count = vc->vc_rows;
 | 
			
		||||
+		if (softback_top)
 | 
			
		||||
+			fbcon_softback_note(vc, t, count);
 | 
			
		||||
 		if (logo_shown >= 0)
 | 
			
		||||
 			goto redraw_up;
 | 
			
		||||
 		switch (p->scrollmode) {
 | 
			
		||||
@@ -2084,6 +2269,14 @@
 | 
			
		||||
 	info = registered_fb[con2fb_map[vc->vc_num]];
 | 
			
		||||
 	ops = info->fbcon_par;
 | 
			
		||||
 
 | 
			
		||||
+	if (softback_top) {
 | 
			
		||||
+		if (softback_lines)
 | 
			
		||||
+			fbcon_set_origin(vc);
 | 
			
		||||
+		softback_top = softback_curr = softback_in = softback_buf;
 | 
			
		||||
+		softback_lines = 0;
 | 
			
		||||
+		fbcon_update_softback(vc);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	if (logo_shown >= 0) {
 | 
			
		||||
 		struct vc_data *conp2 = vc_cons[logo_shown].d;
 | 
			
		||||
 
 | 
			
		||||
@@ -2407,6 +2600,9 @@
 | 
			
		||||
 	int cnt;
 | 
			
		||||
 	char *old_data = NULL;
 | 
			
		||||
 
 | 
			
		||||
+	if (con_is_visible(vc) && softback_lines)
 | 
			
		||||
+		fbcon_set_origin(vc);
 | 
			
		||||
+
 | 
			
		||||
 	resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
 | 
			
		||||
 	if (p->userfont)
 | 
			
		||||
 		old_data = vc->vc_font.data;
 | 
			
		||||
@@ -2432,6 +2628,8 @@
 | 
			
		||||
 		cols /= w;
 | 
			
		||||
 		rows /= h;
 | 
			
		||||
 		vc_resize(vc, cols, rows);
 | 
			
		||||
+		if (con_is_visible(vc) && softback_buf)
 | 
			
		||||
+			fbcon_update_softback(vc);
 | 
			
		||||
 	} else if (con_is_visible(vc)
 | 
			
		||||
 		   && vc->vc_mode == KD_TEXT) {
 | 
			
		||||
 		fbcon_clear_margins(vc, 0);
 | 
			
		||||
@@ -2590,7 +2788,19 @@
 | 
			
		||||
 
 | 
			
		||||
 static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
 | 
			
		||||
 {
 | 
			
		||||
+	unsigned long p;
 | 
			
		||||
+	int line;
 | 
			
		||||
+	
 | 
			
		||||
+	if (vc->vc_num != fg_console || !softback_lines)
 | 
			
		||||
+		return (u16 *) (vc->vc_origin + offset);
 | 
			
		||||
+	line = offset / vc->vc_size_row;
 | 
			
		||||
+	if (line >= softback_lines)
 | 
			
		||||
+		return (u16 *) (vc->vc_origin + offset -
 | 
			
		||||
+				softback_lines * vc->vc_size_row);
 | 
			
		||||
+	p = softback_curr + offset;
 | 
			
		||||
+	if (p >= softback_end)
 | 
			
		||||
+		p += softback_buf - softback_end;
 | 
			
		||||
+	return (u16 *) p;
 | 
			
		||||
-	return (u16 *) (vc->vc_origin + offset);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos,
 | 
			
		||||
@@ -2604,7 +2814,22 @@
 | 
			
		||||
 
 | 
			
		||||
 		x = offset % vc->vc_cols;
 | 
			
		||||
 		y = offset / vc->vc_cols;
 | 
			
		||||
+		if (vc->vc_num == fg_console)
 | 
			
		||||
+			y += softback_lines;
 | 
			
		||||
 		ret = pos + (vc->vc_cols - x) * 2;
 | 
			
		||||
+	} else if (vc->vc_num == fg_console && softback_lines) {
 | 
			
		||||
+		unsigned long offset = pos - softback_curr;
 | 
			
		||||
+
 | 
			
		||||
+		if (pos < softback_curr)
 | 
			
		||||
+			offset += softback_end - softback_buf;
 | 
			
		||||
+		offset /= 2;
 | 
			
		||||
+		x = offset % vc->vc_cols;
 | 
			
		||||
+		y = offset / vc->vc_cols;
 | 
			
		||||
+		ret = pos + (vc->vc_cols - x) * 2;
 | 
			
		||||
+		if (ret == softback_end)
 | 
			
		||||
+			ret = softback_buf;
 | 
			
		||||
+		if (ret == softback_in)
 | 
			
		||||
+			ret = vc->vc_origin;
 | 
			
		||||
 	} else {
 | 
			
		||||
 		/* Should not happen */
 | 
			
		||||
 		x = y = 0;
 | 
			
		||||
@@ -2632,11 +2857,106 @@
 | 
			
		||||
 			a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) |
 | 
			
		||||
 			    (((a) & 0x0700) << 4);
 | 
			
		||||
 		scr_writew(a, p++);
 | 
			
		||||
+		if (p == (u16 *) softback_end)
 | 
			
		||||
+			p = (u16 *) softback_buf;
 | 
			
		||||
+		if (p == (u16 *) softback_in)
 | 
			
		||||
+			p = (u16 *) vc->vc_origin;
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void fbcon_scrolldelta(struct vc_data *vc, int lines)
 | 
			
		||||
+{
 | 
			
		||||
+	struct fb_info *info = registered_fb[con2fb_map[fg_console]];
 | 
			
		||||
+	struct fbcon_ops *ops = info->fbcon_par;
 | 
			
		||||
+	struct fbcon_display *disp = &fb_display[fg_console];
 | 
			
		||||
+	int offset, limit, scrollback_old;
 | 
			
		||||
+
 | 
			
		||||
+	if (softback_top) {
 | 
			
		||||
+		if (vc->vc_num != fg_console)
 | 
			
		||||
+			return;
 | 
			
		||||
+		if (vc->vc_mode != KD_TEXT || !lines)
 | 
			
		||||
+			return;
 | 
			
		||||
+		if (logo_shown >= 0) {
 | 
			
		||||
+			struct vc_data *conp2 = vc_cons[logo_shown].d;
 | 
			
		||||
+
 | 
			
		||||
+			if (conp2->vc_top == logo_lines
 | 
			
		||||
+			    && conp2->vc_bottom == conp2->vc_rows)
 | 
			
		||||
+				conp2->vc_top = 0;
 | 
			
		||||
+			if (logo_shown == vc->vc_num) {
 | 
			
		||||
+				unsigned long p, q;
 | 
			
		||||
+				int i;
 | 
			
		||||
+
 | 
			
		||||
+				p = softback_in;
 | 
			
		||||
+				q = vc->vc_origin +
 | 
			
		||||
+				    logo_lines * vc->vc_size_row;
 | 
			
		||||
+				for (i = 0; i < logo_lines; i++) {
 | 
			
		||||
+					if (p == softback_top)
 | 
			
		||||
+						break;
 | 
			
		||||
+					if (p == softback_buf)
 | 
			
		||||
+						p = softback_end;
 | 
			
		||||
+					p -= vc->vc_size_row;
 | 
			
		||||
+					q -= vc->vc_size_row;
 | 
			
		||||
+					scr_memcpyw((u16 *) q, (u16 *) p,
 | 
			
		||||
+						    vc->vc_size_row);
 | 
			
		||||
+				}
 | 
			
		||||
+				softback_in = softback_curr = p;
 | 
			
		||||
+				update_region(vc, vc->vc_origin,
 | 
			
		||||
+					      logo_lines * vc->vc_cols);
 | 
			
		||||
+			}
 | 
			
		||||
+			logo_shown = FBCON_LOGO_CANSHOW;
 | 
			
		||||
+		}
 | 
			
		||||
+		fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK);
 | 
			
		||||
+		fbcon_redraw_softback(vc, disp, lines);
 | 
			
		||||
+		fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK);
 | 
			
		||||
+		return;
 | 
			
		||||
 	}
 | 
			
		||||
+
 | 
			
		||||
+	if (!scrollback_phys_max)
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	scrollback_old = scrollback_current;
 | 
			
		||||
+	scrollback_current -= lines;
 | 
			
		||||
+	if (scrollback_current < 0)
 | 
			
		||||
+		scrollback_current = 0;
 | 
			
		||||
+	else if (scrollback_current > scrollback_max)
 | 
			
		||||
+		scrollback_current = scrollback_max;
 | 
			
		||||
+	if (scrollback_current == scrollback_old)
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	if (fbcon_is_inactive(vc, info))
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
+	fbcon_cursor(vc, CM_ERASE);
 | 
			
		||||
+
 | 
			
		||||
+	offset = disp->yscroll - scrollback_current;
 | 
			
		||||
+	limit = disp->vrows;
 | 
			
		||||
+	switch (disp->scrollmode) {
 | 
			
		||||
+	case SCROLL_WRAP_MOVE:
 | 
			
		||||
+		info->var.vmode |= FB_VMODE_YWRAP;
 | 
			
		||||
+		break;
 | 
			
		||||
+	case SCROLL_PAN_MOVE:
 | 
			
		||||
+	case SCROLL_PAN_REDRAW:
 | 
			
		||||
+		limit -= vc->vc_rows;
 | 
			
		||||
+		info->var.vmode &= ~FB_VMODE_YWRAP;
 | 
			
		||||
+		break;
 | 
			
		||||
+	}
 | 
			
		||||
+	if (offset < 0)
 | 
			
		||||
+		offset += limit;
 | 
			
		||||
+	else if (offset >= limit)
 | 
			
		||||
+		offset -= limit;
 | 
			
		||||
+
 | 
			
		||||
+	ops->var.xoffset = 0;
 | 
			
		||||
+	ops->var.yoffset = offset * vc->vc_font.height;
 | 
			
		||||
+	ops->update_start(info);
 | 
			
		||||
+
 | 
			
		||||
+	if (!scrollback_current)
 | 
			
		||||
+		fbcon_cursor(vc, CM_DRAW);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int fbcon_set_origin(struct vc_data *vc)
 | 
			
		||||
 {
 | 
			
		||||
+	if (softback_lines)
 | 
			
		||||
+		fbcon_scrolldelta(vc, softback_lines);
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -2700,6 +3020,8 @@
 | 
			
		||||
 
 | 
			
		||||
 		fbcon_set_palette(vc, color_table);
 | 
			
		||||
 		update_screen(vc);
 | 
			
		||||
+		if (softback_buf)
 | 
			
		||||
+			fbcon_update_softback(vc);
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -3110,6 +3432,7 @@
 | 
			
		||||
 	.con_font_default	= fbcon_set_def_font,
 | 
			
		||||
 	.con_font_copy 		= fbcon_copy_font,
 | 
			
		||||
 	.con_set_palette 	= fbcon_set_palette,
 | 
			
		||||
+	.con_scrolldelta 	= fbcon_scrolldelta,
 | 
			
		||||
 	.con_set_origin 	= fbcon_set_origin,
 | 
			
		||||
 	.con_invert_region 	= fbcon_invert_region,
 | 
			
		||||
 	.con_screen_pos 	= fbcon_screen_pos,
 | 
			
		||||
@@ -3344,6 +3667,9 @@
 | 
			
		||||
 	}
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
+	kvfree((void *)softback_buf);
 | 
			
		||||
+	softback_buf = 0UL;
 | 
			
		||||
+
 | 
			
		||||
 	for_each_registered_fb(i) {
 | 
			
		||||
 		int pending = 0;
 | 
			
		||||
 
 | 
			
		||||
@ -0,0 +1,130 @@
 | 
			
		||||
From 465a75a727ae5eb4c94859bfac4742cb14e38b3e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Arnaud Ferraris <arnaud.ferraris@collabora.com>
 | 
			
		||||
Date: Fri, 3 Apr 2020 17:13:55 +0200
 | 
			
		||||
Subject: [PATCH 179/183] arm64: dts: allwinner: pinephone: improve device tree
 | 
			
		||||
 | 
			
		||||
On PinePhone, the headset mic bias resistor isn't populated on the
 | 
			
		||||
schematics (R811), therefore we need to enable the codec's internal
 | 
			
		||||
resistor. Additionnally, the jack detection IRQ's are inverted due to the
 | 
			
		||||
connector wiring, so the necessary property is added to the codec node
 | 
			
		||||
to made the driver aware of this fact.
 | 
			
		||||
 | 
			
		||||
We also stop LEDs during suspend to improve battery life, lower
 | 
			
		||||
cpu_alert* temperatures so the phone doesn't get too hot and improve the
 | 
			
		||||
backlight brightness values so we have a wider usable range.
 | 
			
		||||
 | 
			
		||||
Finally, the RGB LED max_brightness is set to 1 as it isn't using a PWM
 | 
			
		||||
output.
 | 
			
		||||
---
 | 
			
		||||
 .../dts/allwinner/sun50i-a64-pinephone-1.1.dts | 10 +++++-----
 | 
			
		||||
 .../dts/allwinner/sun50i-a64-pinephone-1.2.dts | 13 ++++++-------
 | 
			
		||||
 .../dts/allwinner/sun50i-a64-pinephone.dtsi    | 18 +++++++++++++-----
 | 
			
		||||
 3 files changed, 24 insertions(+), 17 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
 | 
			
		||||
index f084c4f21f12..573f1929da4f 100644
 | 
			
		||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
 | 
			
		||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.1.dts
 | 
			
		||||
@@ -29,11 +29,11 @@ &backlight {
 | 
			
		||||
 	 * value here was chosen as a safe default.
 | 
			
		||||
 	 */
 | 
			
		||||
 	brightness-levels = <
 | 
			
		||||
-		774  793  814  842
 | 
			
		||||
-		882  935  1003 1088
 | 
			
		||||
-		1192 1316 1462 1633
 | 
			
		||||
-		1830 2054 2309 2596
 | 
			
		||||
-		2916 3271 3664 4096>;
 | 
			
		||||
+		392  413  436  468
 | 
			
		||||
+		512  571  647  742
 | 
			
		||||
+		857  995  1159 1349
 | 
			
		||||
+		1568 1819 2103 2423
 | 
			
		||||
+		2779 3176 3614 4096>;
 | 
			
		||||
 	num-interpolated-steps = <50>;
 | 
			
		||||
 	default-brightness-level = <400>;
 | 
			
		||||
 };
 | 
			
		||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
 | 
			
		||||
index bbf64677c22b..6c3922543fec 100644
 | 
			
		||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
 | 
			
		||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone-1.2.dts
 | 
			
		||||
@@ -34,14 +34,13 @@ &backlight {
 | 
			
		||||
 	 * chosen as a safe default.
 | 
			
		||||
 	 */
 | 
			
		||||
 	brightness-levels = <
 | 
			
		||||
-		5000 5248 5506 5858 6345
 | 
			
		||||
-		6987 7805 8823 10062 11543
 | 
			
		||||
-		13287 15317 17654 20319 23336
 | 
			
		||||
-		26724 30505 34702 39335 44427
 | 
			
		||||
-		50000
 | 
			
		||||
-	>;
 | 
			
		||||
+		392  413  436  468
 | 
			
		||||
+		512  571  647  742
 | 
			
		||||
+		857  995  1159 1349
 | 
			
		||||
+		1568 1819 2103 2423
 | 
			
		||||
+		2779 3176 3614 4096>;
 | 
			
		||||
 	num-interpolated-steps = <50>;
 | 
			
		||||
-	default-brightness-level = <500>;
 | 
			
		||||
+	default-brightness-level = <400>;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 &lis3mdl {
 | 
			
		||||
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
 | 
			
		||||
index c55709197804..441358592072 100644
 | 
			
		||||
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
 | 
			
		||||
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
 | 
			
		||||
@@ -219,21 +219,21 @@
 | 
			
		||||
 			function = LED_FUNCTION_INDICATOR;
 | 
			
		||||
 			color = <LED_COLOR_ID_BLUE>;
 | 
			
		||||
 			gpios = <&pio 3 20 GPIO_ACTIVE_HIGH>; /* PD20 */
 | 
			
		||||
-			retain-state-suspended;
 | 
			
		||||
+			max-brightness = <1>;
 | 
			
		||||
 		};
 | 
			
		||||
 
 | 
			
		||||
 		led-1 {
 | 
			
		||||
 			function = LED_FUNCTION_INDICATOR;
 | 
			
		||||
 			color = <LED_COLOR_ID_GREEN>;
 | 
			
		||||
 			gpios = <&pio 3 18 GPIO_ACTIVE_HIGH>; /* PD18 */
 | 
			
		||||
-			retain-state-suspended;
 | 
			
		||||
+			max-brightness = <1>;
 | 
			
		||||
 		};
 | 
			
		||||
 
 | 
			
		||||
 		led-2 {
 | 
			
		||||
 			function = LED_FUNCTION_INDICATOR;
 | 
			
		||||
 			color = <LED_COLOR_ID_RED>;
 | 
			
		||||
 			gpios = <&pio 3 19 GPIO_ACTIVE_HIGH>; /* PD19 */
 | 
			
		||||
-			retain-state-suspended;
 | 
			
		||||
+			max-brightness = <1>;
 | 
			
		||||
 		};
 | 
			
		||||
 	};
 | 
			
		||||
 
 | 
			
		||||
@@ -380,6 +380,14 @@
 | 
			
		||||
 	cpu-supply = <®_dcdc2>;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+&cpu_alert0 {
 | 
			
		||||
+	temperature = <60000>;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+&cpu_alert1 {
 | 
			
		||||
+	temperature = <80000>;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 &csi {
 | 
			
		||||
 	pinctrl-0 = <&csi_pins>, <&csi_mclk_pin>;
 | 
			
		||||
 	status = "okay";
 | 
			
		||||
@@ -816,11 +824,11 @@
 | 
			
		||||
 	simple-audio-card,aux-devs = <&codec_analog>, <&speaker_amp>;
 | 
			
		||||
 	simple-audio-card,widgets = "Microphone", "Headset Microphone",
 | 
			
		||||
 				    "Microphone", "Internal Microphone",
 | 
			
		||||
-				    "Headphone", "Headphone Jack",
 | 
			
		||||
+				    "Headphone", "Headphone",
 | 
			
		||||
 				    "Speaker", "Internal Earpiece",
 | 
			
		||||
 				    "Speaker", "Internal Speaker";
 | 
			
		||||
 	simple-audio-card,routing =
 | 
			
		||||
-			"Headphone Jack", "HP",
 | 
			
		||||
+			"Headphone", "HP",
 | 
			
		||||
 			"Internal Earpiece", "EARPIECE",
 | 
			
		||||
 			"Internal Speaker", "Speaker Amp OUTL",
 | 
			
		||||
 			"Internal Speaker", "Speaker Amp OUTR",
 | 
			
		||||
-- 
 | 
			
		||||
2.30.0
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user