|
From: <jsi...@us...> - 2007-04-15 14:13:14
|
Revision: 2376
http://linuxconsole.svn.sourceforge.net/linuxconsole/?rev=2376&view=rev
Author: jsimmons
Date: 2007-04-15 07:13:12 -0700 (Sun, 15 Apr 2007)
Log Message:
-----------
Lots of fixes to makeit compile
Modified Paths:
--------------
branches/ruby-2.6.21/ruby-2.6/drivers/char/consolemap.c
branches/ruby-2.6.21/ruby-2.6/drivers/char/decvte.c
branches/ruby-2.6.21/ruby-2.6/drivers/char/keyboard.c
branches/ruby-2.6.21/ruby-2.6/drivers/char/sysrq.c
branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c
branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_proc.c
branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_sysfs.c
branches/ruby-2.6.21/ruby-2.6/drivers/video/console/dummycon.c
branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c
branches/ruby-2.6.21/ruby-2.6/include/linux/kbd_kern.h
branches/ruby-2.6.21/ruby-2.6/include/linux/vt_kern.h
Added Paths:
-----------
branches/ruby-2.6.21/ruby-2.6/kernel/power/
branches/ruby-2.6.21/ruby-2.6/kernel/power/Makefile
branches/ruby-2.6.21/ruby-2.6/kernel/power/disk.c
branches/ruby-2.6.21/ruby-2.6/kernel/power/main.c
Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/consolemap.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/drivers/char/consolemap.c 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/drivers/char/consolemap.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -412,8 +412,8 @@
static int
con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
{
- int i, n;
u16 **p1, *p2;
+ int n;
if (!(p1 = p->uni_pgdir[n = unicode >> 11])) {
p1 = p->uni_pgdir[n] = kzalloc(32*sizeof(u16 *), GFP_KERNEL);
Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/decvte.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/drivers/char/decvte.c 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/drivers/char/decvte.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -34,12 +34,10 @@
#include <linux/major.h>
#include <linux/mm.h>
#include <linux/init.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/vt_kern.h>
#include <linux/vt_buffer.h>
#include <linux/selection.h>
#include <linux/consolemap.h>
-#include <linux/config.h>
#include <linux/version.h>
#include <asm/io.h>
@@ -123,7 +121,7 @@
/*
* CARRIAGE RETURN (CR)
*/
-inline void vte_cr(struct vc_data *vc)
+void vte_cr(struct vc_data *vc)
{
vc->vc_pos -= vc->vc_x << 1;
vc->vc_need_wrap = vc->vc_x = 0;
@@ -132,7 +130,7 @@
/*
* BACK SPACE (BS)
*/
-inline void vte_bs(struct vc_data *vc)
+void vte_bs(struct vc_data *vc)
{
if (vc->vc_x) {
vc->vc_pos -= 2;
Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/keyboard.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/drivers/char/keyboard.c 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/drivers/char/keyboard.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -43,28 +43,6 @@
static void kbd_disconnect(struct input_handle *handle);
extern void ctrl_alt_del(void);
-
-/*
- * Exported functions/variables
- */
-
-#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
-
-/*
- * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
- * This seems a good reason to start with NumLock off. On HIL keyboards
- * of PARISC machines however there is no NumLock key and everyone expects the keypad
- * to be used for numbers.
- */
-
-#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
-#define KBD_DEFLEDS (1 << VC_NUMLOCK)
-#else
-#define KBD_DEFLEDS 0
-#endif
-
-#define KBD_DEFLOCK 0
-
void compute_shiftstate(void);
/*
@@ -197,7 +175,7 @@
/*
* Making beeps and bells.
*/
-static void kd_nosound(unsigned long private)
+void kd_nosound(unsigned long private)
{
struct input_handle *handle = (struct input_handle *) private;
@@ -209,7 +187,7 @@
}
}
-static void kd_mksound(struct input_handle *handle, unsigned int hz, unsigned int ticks)
+void kd_mksound(struct input_handle *handle, unsigned int hz, unsigned int ticks)
{
struct vt_struct *vt;
@@ -245,9 +223,9 @@
if (test_bit(EV_REP, dev->evbit)) {
if (rep->delay > 0)
- input_inject_event(dev, EV_REP, REP_DELAY, rep->delay);
+ input_inject_event(handle, EV_REP, REP_DELAY, rep->delay);
if (rep->period > 0)
- input_inject_event(dev, EV_REP, REP_PERIOD, rep->period);
+ input_inject_event(handle, EV_REP, REP_PERIOD, rep->period);
d = dev->rep[REP_DELAY];
p = dev->rep[REP_PERIOD];
}
@@ -265,11 +243,11 @@
if (tty) {
tty_insert_flip_char(tty, ch, 0);
- schedule_work(&tty->flip.work);
+ tty_schedule_flip(tty);
}
}
-static void puts_queue(struct vc_data *vc, char *cp)
+void puts_queue(struct vc_data *vc, char *cp)
{
struct tty_struct *tty = vc->vc_tty;
@@ -280,7 +258,7 @@
tty_insert_flip_char(tty, *cp, 0);
cp++;
}
- schedule_work(&tty->flip.work);
+ tty_schedule_flip(tty);
}
static void applkey(struct vc_data *vc, int key, char mode)
@@ -393,7 +371,7 @@
static void fn_enter(struct vc_data *vc)
{
if (diacr) {
- if (kbd->kbdmode == VC_UNICODE)
+ if (vc->kbd_table.kbdmode == VC_UNICODE)
to_utf8(vc, diacr);
else if (diacr < 0x100)
put_queue(vc, diacr);
@@ -508,7 +486,7 @@
if (!tty)
return;
tty_insert_flip_char(tty, 0, TTY_BREAK);
- schedule_work(&tty->flip.work);
+ tty_schedule_flip(tty);
}
static void fn_scroll_forw(struct vc_data *vc)
@@ -608,7 +586,7 @@
diacr = value;
return;
}
- if (kbd->kbdmode == VC_UNICODE)
+ if (vc->kbd_table.kbdmode == VC_UNICODE)
to_utf8(vc, value);
else if (value < 0x100)
put_queue(vc, value);
@@ -1316,7 +1294,6 @@
break;
}
}
- kbd_start(handle);
} else if (test_bit(EV_SND, dev->evbit) && admin_vt && !admin_vt->beeper) {
admin_vt->beeper = handle;
handle->private = admin_vt;
Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/sysrq.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/drivers/char/sysrq.c 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/drivers/char/sysrq.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -90,9 +90,8 @@
{
if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) {
struct vc_data *vc = (struct vc_data *) tty->driver_data;
- struct work_struct *SAK_work = vc->SAK_work; // Should this be fg_console
-
- schedule_work(SAK_work);
+ // Should this be fg_console
+ schedule_work(&vc->SAK_work);
}
}
static struct sysrq_key_op sysrq_SAK_op = {
Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -714,28 +714,6 @@
* Screen blanking
*/
-static void powerdown_screen(unsigned long private)
-{
- /*
- * Power down if currently suspended (1 or 2),
- * suspend if currently blanked (0),
- * else do nothing (i.e. already powered down (3)).
- * Called only if powerdown features are allowed.
- */
- struct vt_struct *vt = (struct vt_struct *) private;
- struct vc_data *vc = vt->fg_console;
-
- switch (vc->display_fg->blank_mode) {
- case VESA_NO_BLANKING:
- sw->con_blank(vc, VESA_VSYNC_SUSPEND+1, 0);
- break;
- case VESA_VSYNC_SUSPEND:
- case VESA_HSYNC_SUSPEND:
- sw->con_blank(vc, VESA_POWERDOWN+1, 0);
- break;
- }
-}
-
void do_blank_screen(struct vt_struct *vt, int entering_gfx)
{
struct vc_data *vc = vt->fg_console;
@@ -746,7 +724,7 @@
if (vt->vt_blanked) {
if (vt->blank_state == blank_vesa_wait) {
vt->blank_state = blank_off;
- vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
+ vt->vt_sw->con_blank(vc, vt->blank_mode + 1, 0);
}
return;
}
@@ -776,7 +754,7 @@
save_screen(vc);
/* In case we need to reset origin, blanking hook returns 1 */
- i = sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0);
+ i = sw->con_blank(vc, vt->off_interval ? 1 : (vt->blank_mode + 1), 0);
vt->vt_blanked = 1;
if (i)
set_origin(vc);
@@ -884,7 +862,7 @@
*/
static void vt_callback(struct work_struct *work)
{
- struct vt_struct *vt = container_of(work, struct vt_struct, SAK_work);
+ struct vt_struct *vt = container_of(work, struct vt_struct, vt_work);
if (!vt || !vt->want_vc || !vt->want_vc->vc_tty)
return;
@@ -916,6 +894,26 @@
release_console_sem();
}
+void vc_SAK(struct work_struct *work)
+{
+ struct vc_data *vc =
+ container_of(work, struct vc_data, SAK_work);
+ struct tty_struct *tty;
+
+ acquire_console_sem();
+ if (vc) {
+ tty = vc->vc_tty;
+ /*
+ * SAK should also work in all raw modes and reset
+ * them properly.
+ */
+ if (tty)
+ __do_SAK(tty);
+ reset_vc(vc);
+ }
+ release_console_sem();
+}
+
int set_console(struct vc_data *vc)
{
if (!vc || vc->display_fg->vt_dont_switch ||
@@ -1074,7 +1072,7 @@
module_put(sw->owner);
vt->vc_cons[vc->vc_num - vt->first_vc] = NULL;
if (vt->kmalloced)
- kfree(screenbuf);
+ kfree(vc->vc_screenbuf);
kfree(vc);
}
return 0;
@@ -1223,38 +1221,6 @@
return 0;
}
-int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
-{
- int rc;
-
- acquire_console_sem();
- rc = vc_resize(vc, cols, lines);
- release_console_sem();
- return rc;
-}
-
-void vc_SAK(struct work_struct *work)
-{
- struct vc *vc_con =
- container_of(work, struct vc, SAK_work);
- struct tty_struct *tty;
- struct vc_data *vc;
-
- acquire_console_sem();
- vc = vc_con->d;
- if (vc) {
- tty = vc->vc_tty;
- /*
- * SAK should also work in all raw modes and reset
- * them properly.
- */
- if (tty)
- __do_SAK(tty);
- reset_vc(vc);
- }
- release_console_sem();
-}
-
/*
* Selection stuff for GPM.
*/
@@ -1311,7 +1277,7 @@
if (!vc) {
printk("vt_write: tty %d not allocated\n", tty->index);
release_console_sem();
- return 0;
+ return n;
}
release_console_sem();
@@ -1335,7 +1301,9 @@
hide_cursor(vc);
while (!tty->stopped && count) {
- c = *buf;
+ int orig = *buf;
+
+ c = orig;
buf++;
n++;
count--;
@@ -1348,7 +1316,7 @@
/* Malformed sequences as sequences of replacement glyphs */
rescan_last_byte:
if(c > 0x7f) {
- if (vc->vc_utf_count > 0)
+ if (vc->vc_utf_count > 0) {
if ((c & 0xc0) == 0x80) {
vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
if (--vc->vc_utf_count) {
@@ -1356,8 +1324,8 @@
continue;
}
tc = c = vc->vc_utf_char;
- else
- goto replacement;
+ } else
+ goto replacement_glyph;
} else {
vc->vc_npar = 0;
if ((c & 0xe0) == 0xc0) {
@@ -1464,8 +1432,6 @@
FLUSH
console_conditional_schedule();
release_console_sem();
-
-out:
return n;
#undef FLUSH
}
@@ -1854,7 +1820,7 @@
list_add_tail(&vt->node, &vt_list);
init_MUTEX(&vt->lock);
vt->vt_num = current_vt;
- vt->display_desc = (char *)display_desc;
+ vt->desc = (char *)display_desc;
vt->vt_dont_switch = 0;
vt->scrollback_delta = 0;
vt->vt_blanked = 0;
@@ -1866,7 +1832,7 @@
vt->timer.function = blank_screen_t;
mod_timer(&vt->timer, jiffies + vt->blank_interval);
vt->keyboard = NULL;
- INIT_WORK(&vt->vt_work, vt_callback, vt);
+ INIT_WORK(&vt->vt_work, vt_callback);
if (!admin_vt) {
admin_vt = vt;
@@ -1884,7 +1850,7 @@
current_vc += vc_count;
current_vt += 1;
if (vt->kmalloced) {
- vt_create_sysfs_dev_files(vt);
+ vt_init_device(vt);
#ifdef CONFIG_PROC_FS
vt_proc_attach(vt);
#endif
@@ -2011,7 +1977,7 @@
module_put(owner);
return -ENODEV;
}
- vt->display_desc = (char *)desc;
+ vt->desc = (char *)desc;
vt->vt_sw = csw;
/* Set the VC states to the new default mode */
@@ -2025,7 +1991,7 @@
vc->vc_origin = (unsigned long) vc->vc_screenbuf;
vc->vc_visible_origin = vc->vc_origin;
vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
- vc->vc_pos = vc->vc_origin + vc->vc_size_rows * vc->vc_y + 2 * vc->vc_x;
+ vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x;
INIT_WORK(&vc->SAK_work, vc_SAK);
visual_init(vc, 0);
set_origin(vc);
@@ -2063,7 +2029,7 @@
EXPORT_SYMBOL(vc_lock_resize);
EXPORT_SYMBOL(console_blank_hook);
EXPORT_SYMBOL(vt_list);
-EXPORT_SYMBOL(take_over_console);
+EXPORT_SYMBOL(bind_vt_driver);
EXPORT_SYMBOL(update_region);
EXPORT_SYMBOL(update_screen);
EXPORT_SYMBOL(vt_map_display);
Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_proc.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_proc.c 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_proc.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -6,8 +6,6 @@
* Aivils Stoss <>
*/
-#include <linux/config.h>
-
#ifdef CONFIG_PROC_FS
#include <linux/types.h>
#include <linux/kernel.h>
@@ -53,7 +51,7 @@
if(!vt) return 0;
- len = sprintf(page, "%s\n", vt->display_desc ? vt->display_desc : "");
+ len = sprintf(page, "%s\n", vt->desc ? vt->desc : "");
return generic_read(page, start, off, count, eof, len);
}
@@ -103,7 +101,7 @@
}
handle->private = vt;
printk("keyboard: [%s] bound to [%s] vc:%d-%d\n",
- handle->dev->name, vt->display_desc, vt->first_vc + 1,
+ handle->dev->name, vt->desc, vt->first_vc + 1,
vt->first_vc + vt->vc_count);
}
return count;
Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_sysfs.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_sysfs.c 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_sysfs.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -26,7 +26,7 @@
}
static ssize_t show_keyboard(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
+ char *buf)
{
struct vt_struct *vt = dev_get_drvdata(dev);
struct input_handle *handle = vt->keyboard;
@@ -45,7 +45,7 @@
if (bind)
vt_bind(vt);
else
- vt_unbind(con);
+ vt_unbind(vt);
return count;
}
@@ -74,41 +74,42 @@
__ATTR(name, S_IRUGO, show_name, NULL),
};
-static int vt_init_device(struct vt_struct *vt)
+int vt_init_device(struct vt_struct *vt)
{
int err = 0;
- vt->dev = device_create(vt_class, NULL, MKDEV(0, vt->count),
- "vtcon%i", vt->count);
+ vt->dev = device_create(vt_class, NULL, MKDEV(0, vt->vc_count),
+ "vtcon%i", vt->vc_count);
if (IS_ERR(vt->dev)) {
vt->flag &= ~CON_DRIVER_FLAG_ATTR;
vt->dev = NULL;
- error = -EINVAL;
+ err = -EINVAL;
} else {
dev_set_drvdata(vt->dev, vt);
- fb_info->flag |= CON_DRIVER_FLAG_ATTR;
+ vt->flag |= CON_DRIVER_FLAG_ATTR;
}
return err;
}
-static void vt_deinit_device(struct vt_struct *vt)
+void vt_deinit_device(struct vt_struct *vt)
{
vt->flag &= ~CON_DRIVER_FLAG_ATTR;
dev_set_drvdata(vt->dev, NULL);
- device_destroy(vt_class, MKDEV(0, vt->count));
+ device_destroy(vt_class, MKDEV(0, vt->vc_count));
}
-void __init vt_sysfs_init(void)
+int __init vt_sysfs_init(void)
{
/* we have only one boot time console - admin_vt*/
vt_class = class_create(THIS_MODULE, "vt");
if (IS_ERR(vt_class)) {
printk(KERN_WARNING "Unable to create vt console class; "
- "errno = %ld\n", PTR_ERR(vtconsole_class));
+ "errno = %ld\n", PTR_ERR(vt_class));
vt_class = NULL;
} else {
- vt_class->dev_attrs = vt_device_attrs
+ vt_class->dev_attrs = vt_device_attrs;
}
+ return 0;
}
-postcore_initcall(vtconsole_class_init);
+postcore_initcall(vt_sysfs_init);
Modified: branches/ruby-2.6.21/ruby-2.6/drivers/video/console/dummycon.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/drivers/video/console/dummycon.c 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/drivers/video/console/dummycon.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -32,10 +32,9 @@
#define MAX_DUMB_CONSOLES 16
-static const char *dummycon_startup(void)
-static unsigned long dumb_num = 0;
-static struct vt_struct dummy_vt;
static struct vc_data default_mode;
+static struct vt_struct dummy_vt;
+static unsigned long dumb_num;
static const char *dummycon_startup(struct vt_struct *vt, int init)
{
@@ -45,11 +44,6 @@
return "dummy device";
}
-static const char *dummycon_startup(void)
-{
- return "dummy device";
-}
-
static void dummycon_init(struct vc_data *vc, int init)
{
vc->vc_can_do_color = 1;
@@ -82,7 +76,7 @@
.con_putc = DUMMY,
.con_putcs = DUMMY,
.con_cursor = DUMMY,
- .con_scroll = DUMMY,
+ .con_scroll_region =DUMMY,
.con_bmove = DUMMY,
.con_switch = DUMMY,
.con_blank = DUMMY,
@@ -91,7 +85,7 @@
.con_font_default = DUMMY,
.con_font_copy = DUMMY,
.con_set_palette = DUMMY,
- .con_scrolldelta = DUMMY,
+ .con_scroll = DUMMY,
};
int __init dumbcon_init(void)
@@ -99,7 +93,7 @@
const char *display_desc = NULL;
memset(&dummy_vt, 0, sizeof(struct vt_struct));
- dummy_vt.vt_kmalloced = 0;
+ dummy_vt.kmalloced = 0;
dummy_vt.vt_sw = &dummy_con;
display_desc = vt_map_display(&dummy_vt, 1, MAX_NR_USER_CONSOLES);
if (!display_desc) return -ENODEV;
@@ -120,7 +114,7 @@
if (!vt) return -ENOMEM;
memset(vt, 0, sizeof(struct vt_struct));
- vt->vt_kmalloced = 1;
+ vt->kmalloced = 1;
vt->vt_sw = &dummy_con;
display_desc = vt_map_display(vt, 1, MIN_NR_CONSOLES);
if (!display_desc) {
Modified: branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -719,8 +719,6 @@
spin_lock_irqsave(&vga_lock, flags);
- vgacon_xres = width * VGA_FONTWIDTH;
- vgacon_yres = height * c->vc_font.height;
if (vga_video_type >= VIDEO_TYPE_VGAC) {
outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);
max_scan = inb_p(vga_video_port_val);
@@ -774,20 +772,23 @@
static int vgacon_switch(struct vc_data *c)
{
+ int y = c->vc_rows * c->vc_font.height;
+ int x = c->vc_cols = 8;
+
/* We can only copy out the size of the video buffer here,
* otherwise we get into VGA BIOS. We can only copy out
* the size of the video buffer here, otherwise we get
* into VGA BIOS */
if (!vga_is_gfx) {
+ struct winsize *ws = &c->vc_tty->winsize;
+
scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
c->vc_screenbuf_size > vga_vram_size ?
vga_vram_size : c->vc_screenbuf_size);
- if ((vgacon_xres != x || vgacon_yres != y) &&
- (!(vga_video_num_columns % 2) &&
- vga_video_num_columns <= ORIG_VIDEO_COLS &&
- vga_video_num_lines <= rows))
+ if ((ws->ws_xpixel != x || ws->ws_ypixel != y) &&
+ (!(c->vc_cols % 2) && c->vc_cols <= ORIG_VIDEO_COLS))
vgacon_doresize(c, c->vc_cols, c->vc_rows);
}
@@ -1242,17 +1243,17 @@
#endif
-static int vgacon_resize(struct vc_data *c, unsigned int width,
+static int vgacon_resize(struct vc_data *vc, unsigned int width,
unsigned int height)
{
if (width % 2 || width > ORIG_VIDEO_COLS ||
- height > (ORIG_VIDEO_LINES * vga_default_font_height)/
- c->vc_font.height)
+ height > (ORIG_VIDEO_LINES * vc->vc_font.height)/
+ vc->vc_font.height)
/* let svgatextmode tinker with video timings */
return 0;
if (IS_VISIBLE && !vga_is_gfx) /* who knows */
- vgacon_doresize(c, width, height);
+ vgacon_doresize(vc, width, height);
return 0;
}
@@ -1367,7 +1368,7 @@
const char *display_desc = NULL;
memset(&vga_vt, 0, sizeof(struct vt_struct));
- vga_vt.vt_kmalloced = 0;
+ vga_vt.kmalloced = 0;
vga_vt.vt_sw = &vga_con;
display_desc = vt_map_display(&vga_vt, 1, MAX_NR_USER_CONSOLES);
if (!display_desc) return -ENODEV;
Modified: branches/ruby-2.6.21/ruby-2.6/include/linux/kbd_kern.h
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/include/linux/kbd_kern.h 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/include/linux/kbd_kern.h 2007-04-15 14:13:12 UTC (rev 2376)
@@ -7,6 +7,27 @@
#include <linux/keyboard.h>
#include <linux/input.h>
+/*
+ * Exported functions/variables
+ */
+
+#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
+
+/*
+ * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
+ * This seems a good reason to start with NumLock off. On HIL keyboards
+ * of PARISC machines however there is no NumLock key and everyone expects the keypad
+ * to be used for numbers.
+ */
+
+#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
+#define KBD_DEFLEDS (1 << VC_NUMLOCK)
+#else
+#define KBD_DEFLEDS 0
+#endif
+
+#define KBD_DEFLOCK 0
+
extern struct tasklet_struct keyboard_tasklet;
extern int shift_state;
Modified: branches/ruby-2.6.21/ruby-2.6/include/linux/vt_kern.h
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/include/linux/vt_kern.h 2007-04-15 01:06:27 UTC (rev 2375)
+++ branches/ruby-2.6.21/ruby-2.6/include/linux/vt_kern.h 2007-04-15 14:13:12 UTC (rev 2376)
@@ -11,9 +11,10 @@
#include <linux/kbd_kern.h>
#include <linux/device.h>
-#define MIN_NR_CONSOLES 1 /* must be at least 1 */
-#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
-#define MAX_NR_USER_CONSOLES 16 /* number of VCs per VT */
+/* VT driver state */
+#define CON_DRIVER_FLAG_MODULE 1
+#define CON_DRIVER_FLAG_INIT 2
+#define CON_DRIVER_FLAG_ATTR 4
/* scroll */
#define SM_UP (1)
@@ -117,7 +118,7 @@
struct tty_struct *vc_tty; /* TTY we are attached to */
/* data for manual vt switching */
struct vt_mode vt_mode;
- int vt_pid;
+ struct pid *vt_pid;
int vt_newvt;
/* mode flags */
unsigned int vc_charset:1; /* Character set G0 / G1 */
@@ -192,6 +193,8 @@
unsigned char vc_saved_G2;
unsigned char vc_saved_G3;
unsigned char vc_saved_GS;
+
+ struct work_struct SAK_work; // Does it really belong here ?
};
struct consw {
@@ -229,6 +232,7 @@
struct vc_data *want_vc; /* VC we want to switch to */
int scrollback_delta;
int cursor_original;
+ int flag;
char kmalloced; /* Did we use kmalloced ? */
char vt_dont_switch; /* VC switching flag */
char vt_blanked; /* Is this display blanked */
@@ -261,8 +265,8 @@
struct proc_dir_entry *procdir;
unsigned char vt_ledstate;
unsigned char vt_ledioctl;
- char *display_desc;
- struct class_device dev; /* Generic device interface */
+ char *desc;
+ struct device *dev; /* Generic device interface */
};
extern struct list_head vt_list;
@@ -272,9 +276,9 @@
/* universal VT emulation functions */
void vte_ris(struct vc_data *vc, int do_clear);
-inline void vte_cr(struct vc_data *vc);
+void vte_cr(struct vc_data *vc);
void vte_lf(struct vc_data *vc);
-inline void vte_bs(struct vc_data *vc);
+void vte_bs(struct vc_data *vc);
void vte_ed(struct vc_data *vc, int vpar);
void vte_decsc(struct vc_data *vc);
void terminal_emulation(struct tty_struct *tty, int c);
@@ -296,16 +300,16 @@
void vt_map_input(struct vt_struct *vt);
struct vc_data *find_vc(int currcons);
struct vc_data *vc_allocate(unsigned int console);
-inline int set_console(struct vc_data *vc);
+int set_console(struct vc_data *vc);
int vc_resize(struct vc_data *vc, unsigned int lines, unsigned int cols);
int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines);
-int vc_disallocate(struct vc_data *vc);
+int vc_deallocate(struct vc_data *vc);
void reset_vc(struct vc_data *vc);
void add_softcursor(struct vc_data *vc);
void set_cursor(struct vc_data *vc);
void hide_cursor(struct vc_data *vc);
void gotoxy(struct vc_data *vc, int new_x, int new_y);
-inline void gotoxay(struct vc_data *vc, int new_x, int new_y);
+void gotoxay(struct vc_data *vc, int new_x, int new_y);
void reset_palette(struct vc_data *vc);
void set_palette(struct vc_data *vc);
void scroll_up(struct vc_data *vc, int);
@@ -319,7 +323,7 @@
void insert_line(struct vc_data *vc, unsigned int nr);
void delete_line(struct vc_data *vc, unsigned int nr);
void set_origin(struct vc_data *vc);
-inline void clear_region(struct vc_data *vc, int x, int y, int width, int height);
+void clear_region(struct vc_data *vc, int x, int y, int width, int height);
void do_update_region(struct vc_data *vc, unsigned long start, int count);
void update_region(struct vc_data *vc, unsigned long start, int count);
void update_screen(struct vc_data *vc);
@@ -357,13 +361,16 @@
void con_protect_unimap(struct vc_data *vc, int rdonly);
int con_copy_unimap(struct vc_data *dst, struct vc_data *src);
+/* keyboard.c */
+void puts_queue(struct vc_data *vc, char *cp);
+
/* vt_ioctl.c */
void complete_change_console(struct vc_data *new_vc, struct vc_data *old_vc);
void change_console(struct vc_data *new_vc, struct vc_data *old_vc);
/* vt_sysfs.c*/
-int __init vt_create_sysfs_dev_files (struct vt_struct *vt);
-void __init vt_sysfs_init(void);
+int __init vt_init_device(struct vt_struct *vt);
+int __init vt_sysfs_init(void);
/* vt_proc.c */
#ifdef CONFIG_PROC_FS
extern int vt_proc_attach(struct vt_struct *vt);
Added: branches/ruby-2.6.21/ruby-2.6/kernel/power/Makefile
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/kernel/power/Makefile (rev 0)
+++ branches/ruby-2.6.21/ruby-2.6/kernel/power/Makefile 2007-04-15 14:13:12 UTC (rev 2376)
@@ -0,0 +1,10 @@
+
+ifeq ($(CONFIG_PM_DEBUG),y)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+obj-y := main.o process.o
+obj-$(CONFIG_PM_LEGACY) += pm.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o snapshot.o swap.o user.o
+
+obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o
Added: branches/ruby-2.6.21/ruby-2.6/kernel/power/disk.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/kernel/power/disk.c (rev 0)
+++ branches/ruby-2.6.21/ruby-2.6/kernel/power/disk.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -0,0 +1,461 @@
+/*
+ * kernel/power/disk.c - Suspend-to-disk support.
+ *
+ * Copyright (c) 2003 Patrick Mochel
+ * Copyright (c) 2003 Open Source Development Lab
+ * Copyright (c) 2004 Pavel Machek <pa...@su...>
+ *
+ * This file is released under the GPLv2.
+ *
+ */
+
+#include <linux/suspend.h>
+#include <linux/syscalls.h>
+#include <linux/reboot.h>
+#include <linux/string.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/pm.h>
+#include <linux/console.h>
+#include <linux/cpu.h>
+#include <linux/freezer.h>
+
+#include "power.h"
+
+
+static int noresume = 0;
+char resume_file[256] = CONFIG_PM_STD_PARTITION;
+dev_t swsusp_resume_device;
+sector_t swsusp_resume_block;
+
+/**
+ * platform_prepare - prepare the machine for hibernation using the
+ * platform driver if so configured and return an error code if it fails
+ */
+
+static inline int platform_prepare(void)
+{
+ int error = 0;
+
+ if (pm_disk_mode == PM_DISK_PLATFORM) {
+ if (pm_ops && pm_ops->prepare)
+ error = pm_ops->prepare(PM_SUSPEND_DISK);
+ }
+ return error;
+}
+
+/**
+ * power_down - Shut machine down for hibernate.
+ * @mode: Suspend-to-disk mode
+ *
+ * Use the platform driver, if configured so, and return gracefully if it
+ * fails.
+ * Otherwise, try to power off and reboot. If they fail, halt the machine,
+ * there ain't no turning back.
+ */
+
+static void power_down(suspend_disk_method_t mode)
+{
+ switch(mode) {
+ case PM_DISK_PLATFORM:
+ if (pm_ops && pm_ops->enter) {
+ kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
+ pm_ops->enter(PM_SUSPEND_DISK);
+ break;
+ }
+ case PM_DISK_SHUTDOWN:
+ kernel_power_off();
+ break;
+ case PM_DISK_REBOOT:
+ kernel_restart(NULL);
+ break;
+ }
+ kernel_halt();
+ /* Valid image is on the disk, if we continue we risk serious data corruption
+ after resume. */
+ printk(KERN_CRIT "Please power me down manually\n");
+ while(1);
+}
+
+static inline void platform_finish(void)
+{
+ if (pm_disk_mode == PM_DISK_PLATFORM) {
+ if (pm_ops && pm_ops->finish)
+ pm_ops->finish(PM_SUSPEND_DISK);
+ }
+}
+
+static void unprepare_processes(void)
+{
+ thaw_processes();
+}
+
+static int prepare_processes(void)
+{
+ int error = 0;
+
+ if (freeze_processes()) {
+ error = -EBUSY;
+ unprepare_processes();
+ }
+ return error;
+}
+
+/**
+ * pm_suspend_disk - The granpappy of hibernation power management.
+ *
+ * If we're going through the firmware, then get it over with quickly.
+ *
+ * If not, then call swsusp to do its thing, then figure out how
+ * to power down the system.
+ */
+
+int pm_suspend_disk(void)
+{
+ int error;
+
+ error = prepare_processes();
+ if (error)
+ return error;
+
+ if (pm_disk_mode == PM_DISK_TESTPROC) {
+ printk("swsusp debug: Waiting for 5 seconds.\n");
+ mdelay(5000);
+ goto Thaw;
+ }
+ /* Free memory before shutting down devices. */
+ error = swsusp_shrink_memory();
+ if (error)
+ goto Thaw;
+
+ error = platform_prepare();
+ if (error)
+ goto Thaw;
+
+ error = device_suspend(PMSG_FREEZE);
+ if (error) {
+ printk(KERN_ERR "PM: Some devices failed to suspend\n");
+ goto Resume_devices;
+ }
+ error = disable_nonboot_cpus();
+ if (error)
+ goto Enable_cpus;
+
+ if (pm_disk_mode == PM_DISK_TEST) {
+ printk("swsusp debug: Waiting for 5 seconds.\n");
+ mdelay(5000);
+ goto Enable_cpus;
+ }
+
+ pr_debug("PM: snapshotting memory.\n");
+ in_suspend = 1;
+ error = swsusp_suspend();
+ if (error)
+ goto Enable_cpus;
+
+ if (in_suspend) {
+ enable_nonboot_cpus();
+ platform_finish();
+ device_resume();
+ resume_console();
+ pr_debug("PM: writing image.\n");
+ error = swsusp_write();
+ if (!error)
+ power_down(pm_disk_mode);
+ else {
+ swsusp_free();
+ goto Thaw;
+ }
+ } else {
+ pr_debug("PM: Image restored successfully.\n");
+ }
+
+ swsusp_free();
+ Enable_cpus:
+ enable_nonboot_cpus();
+ Resume_devices:
+ platform_finish();
+ device_resume();
+ resume_console();
+ Thaw:
+ unprepare_processes();
+ return error;
+}
+
+
+/**
+ * software_resume - Resume from a saved image.
+ *
+ * Called as a late_initcall (so all devices are discovered and
+ * initialized), we call swsusp to see if we have a saved image or not.
+ * If so, we quiesce devices, the restore the saved image. We will
+ * return above (in pm_suspend_disk() ) if everything goes well.
+ * Otherwise, we fail gracefully and return to the normally
+ * scheduled program.
+ *
+ */
+
+static int software_resume(void)
+{
+ int error;
+
+ mutex_lock(&pm_mutex);
+ if (!swsusp_resume_device) {
+ if (!strlen(resume_file)) {
+ mutex_unlock(&pm_mutex);
+ return -ENOENT;
+ }
+ swsusp_resume_device = name_to_dev_t(resume_file);
+ pr_debug("swsusp: Resume From Partition %s\n", resume_file);
+ } else {
+ pr_debug("swsusp: Resume From Partition %d:%d\n",
+ MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device));
+ }
+
+ if (noresume) {
+ /**
+ * FIXME: If noresume is specified, we need to find the partition
+ * and reset it back to normal swap space.
+ */
+ mutex_unlock(&pm_mutex);
+ return 0;
+ }
+
+ pr_debug("PM: Checking swsusp image.\n");
+
+ error = swsusp_check();
+ if (error)
+ goto Done;
+
+ pr_debug("PM: Preparing processes for restore.\n");
+
+ error = prepare_processes();
+ if (error) {
+ swsusp_close();
+ goto Done;
+ }
+
+ pr_debug("PM: Reading swsusp image.\n");
+
+ error = swsusp_read();
+ if (error) {
+ swsusp_free();
+ goto Thaw;
+ }
+
+ pr_debug("PM: Preparing devices for restore.\n");
+
+ error = device_suspend(PMSG_PRETHAW);
+ if (error)
+ goto Free;
+
+ error = disable_nonboot_cpus();
+ if (!error)
+ swsusp_resume();
+
+ enable_nonboot_cpus();
+ Free:
+ swsusp_free();
+ device_resume();
+ resume_console();
+ Thaw:
+ printk(KERN_ERR "PM: Restore failed, recovering.\n");
+ unprepare_processes();
+ Done:
+ /* For success case, the suspend path will release the lock */
+ mutex_unlock(&pm_mutex);
+ pr_debug("PM: Resume from disk failed.\n");
+ return 0;
+}
+
+late_initcall(software_resume);
+
+
+static const char * const pm_disk_modes[] = {
+ [PM_DISK_FIRMWARE] = "firmware",
+ [PM_DISK_PLATFORM] = "platform",
+ [PM_DISK_SHUTDOWN] = "shutdown",
+ [PM_DISK_REBOOT] = "reboot",
+ [PM_DISK_TEST] = "test",
+ [PM_DISK_TESTPROC] = "testproc",
+};
+
+/**
+ * disk - Control suspend-to-disk mode
+ *
+ * Suspend-to-disk can be handled in several ways. The greatest
+ * distinction is who writes memory to disk - the firmware or the OS.
+ * If the firmware does it, we assume that it also handles suspending
+ * the system.
+ * If the OS does it, then we have three options for putting the system
+ * to sleep - using the platform driver (e.g. ACPI or other PM registers),
+ * powering off the system or rebooting the system (for testing).
+ *
+ * The system will support either 'firmware' or 'platform', and that is
+ * known a priori (and encoded in pm_ops). But, the user may choose
+ * 'shutdown' or 'reboot' as alternatives.
+ *
+ * show() will display what the mode is currently set to.
+ * store() will accept one of
+ *
+ * 'firmware'
+ * 'platform'
+ * 'shutdown'
+ * 'reboot'
+ *
+ * It will only change to 'firmware' or 'platform' if the system
+ * supports it (as determined from pm_ops->pm_disk_mode).
+ */
+
+static ssize_t disk_show(struct subsystem * subsys, char * buf)
+{
+ return sprintf(buf, "%s\n", pm_disk_modes[pm_disk_mode]);
+}
+
+
+static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n)
+{
+ int error = 0;
+ int i;
+ int len;
+ char *p;
+ suspend_disk_method_t mode = 0;
+
+ p = memchr(buf, '\n', n);
+ len = p ? p - buf : n;
+
+ mutex_lock(&pm_mutex);
+ for (i = PM_DISK_FIRMWARE; i < PM_DISK_MAX; i++) {
+ if (!strncmp(buf, pm_disk_modes[i], len)) {
+ mode = i;
+ break;
+ }
+ }
+ if (mode) {
+ if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT ||
+ mode == PM_DISK_TEST || mode == PM_DISK_TESTPROC) {
+ pm_disk_mode = mode;
+ } else {
+ if (pm_ops && pm_ops->enter &&
+ (mode == pm_ops->pm_disk_mode))
+ pm_disk_mode = mode;
+ else
+ error = -EINVAL;
+ }
+ } else {
+ error = -EINVAL;
+ }
+
+ pr_debug("PM: suspend-to-disk mode set to '%s'\n",
+ pm_disk_modes[mode]);
+ mutex_unlock(&pm_mutex);
+ return error ? error : n;
+}
+
+power_attr(disk);
+
+static ssize_t resume_show(struct subsystem * subsys, char *buf)
+{
+ return sprintf(buf,"%d:%d\n", MAJOR(swsusp_resume_device),
+ MINOR(swsusp_resume_device));
+}
+
+static ssize_t resume_store(struct subsystem *subsys, const char *buf, size_t n)
+{
+ unsigned int maj, min;
+ dev_t res;
+ int ret = -EINVAL;
+
+ if (sscanf(buf, "%u:%u", &maj, &min) != 2)
+ goto out;
+
+ res = MKDEV(maj,min);
+ if (maj != MAJOR(res) || min != MINOR(res))
+ goto out;
+
+ mutex_lock(&pm_mutex);
+ swsusp_resume_device = res;
+ mutex_unlock(&pm_mutex);
+ printk("Attempting manual resume\n");
+ noresume = 0;
+ software_resume();
+ ret = n;
+ out:
+ return ret;
+}
+
+power_attr(resume);
+
+static ssize_t image_size_show(struct subsystem * subsys, char *buf)
+{
+ return sprintf(buf, "%lu\n", image_size);
+}
+
+static ssize_t image_size_store(struct subsystem * subsys, const char * buf, size_t n)
+{
+ unsigned long size;
+
+ if (sscanf(buf, "%lu", &size) == 1) {
+ image_size = size;
+ return n;
+ }
+
+ return -EINVAL;
+}
+
+power_attr(image_size);
+
+static struct attribute * g[] = {
+ &disk_attr.attr,
+ &resume_attr.attr,
+ &image_size_attr.attr,
+ NULL,
+};
+
+
+static struct attribute_group attr_group = {
+ .attrs = g,
+};
+
+
+static int __init pm_disk_init(void)
+{
+ return sysfs_create_group(&power_subsys.kset.kobj,&attr_group);
+}
+
+core_initcall(pm_disk_init);
+
+
+static int __init resume_setup(char *str)
+{
+ if (noresume)
+ return 1;
+
+ strncpy( resume_file, str, 255 );
+ return 1;
+}
+
+static int __init resume_offset_setup(char *str)
+{
+ unsigned long long offset;
+
+ if (noresume)
+ return 1;
+
+ if (sscanf(str, "%llu", &offset) == 1)
+ swsusp_resume_block = offset;
+
+ return 1;
+}
+
+static int __init noresume_setup(char *str)
+{
+ noresume = 1;
+ return 1;
+}
+
+__setup("noresume", noresume_setup);
+__setup("resume_offset=", resume_offset_setup);
+__setup("resume=", resume_setup);
Added: branches/ruby-2.6.21/ruby-2.6/kernel/power/main.c
===================================================================
--- branches/ruby-2.6.21/ruby-2.6/kernel/power/main.c (rev 0)
+++ branches/ruby-2.6.21/ruby-2.6/kernel/power/main.c 2007-04-15 14:13:12 UTC (rev 2376)
@@ -0,0 +1,338 @@
+/*
+ * kernel/power/main.c - PM subsystem core functionality.
+ *
+ * Copyright (c) 2003 Patrick Mochel
+ * Copyright (c) 2003 Open Source Development Lab
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/suspend.h>
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/console.h>
+#include <linux/cpu.h>
+#include <linux/resume-trace.h>
+#include <linux/freezer.h>
+#include <linux/vmstat.h>
+
+#include "power.h"
+
+/*This is just an arbitrary number */
+#define FREE_PAGE_NUMBER (100)
+
+DEFINE_MUTEX(pm_mutex);
+
+struct pm_ops *pm_ops;
+suspend_disk_method_t pm_disk_mode = PM_DISK_PLATFORM;
+
+/**
+ * pm_set_ops - Set the global power method table.
+ * @ops: Pointer to ops structure.
+ */
+
+void pm_set_ops(struct pm_ops * ops)
+{
+ mutex_lock(&pm_mutex);
+ pm_ops = ops;
+ mutex_unlock(&pm_mutex);
+}
+
+static inline void pm_finish(suspend_state_t state)
+{
+ if (pm_ops->finish)
+ pm_ops->finish(state);
+}
+
+/**
+ * suspend_prepare - Do prep work before entering low-power state.
+ * @state: State we're entering.
+ *
+ * This is common code that is called for each state that we're
+ * entering. Allocate a console, stop all processes, then make sure
+ * the platform can enter the requested state.
+ */
+
+static int suspend_prepare(suspend_state_t state)
+{
+ int error;
+ unsigned int free_pages;
+
+ if (!pm_ops || !pm_ops->enter)
+ return -EPERM;
+
+ if (freeze_processes()) {
+ error = -EAGAIN;
+ goto Thaw;
+ }
+
+ if ((free_pages = global_page_state(NR_FREE_PAGES))
+ < FREE_PAGE_NUMBER) {
+ pr_debug("PM: free some memory\n");
+ shrink_all_memory(FREE_PAGE_NUMBER - free_pages);
+ if (nr_free_pages() < FREE_PAGE_NUMBER) {
+ error = -ENOMEM;
+ printk(KERN_ERR "PM: No enough memory\n");
+ goto Thaw;
+ }
+ }
+
+ if (pm_ops->prepare) {
+ if ((error = pm_ops->prepare(state)))
+ goto Thaw;
+ }
+
+ error = device_suspend(PMSG_SUSPEND);
+ if (error) {
+ printk(KERN_ERR "Some devices failed to suspend\n");
+ goto Resume_devices;
+ }
+ error = disable_nonboot_cpus();
+ if (!error)
+ return 0;
+
+ enable_nonboot_cpus();
+ Resume_devices:
+ pm_finish(state);
+ device_resume();
+ resume_console();
+ Thaw:
+ thaw_processes();
+ return error;
+}
+
+
+int suspend_enter(suspend_state_t state)
+{
+ int error = 0;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ if ((error = device_power_down(PMSG_SUSPEND))) {
+ printk(KERN_ERR "Some devices failed to power down\n");
+ goto Done;
+ }
+ error = pm_ops->enter(state);
+ device_power_up();
+ Done:
+ local_irq_restore(flags);
+ return error;
+}
+
+
+/**
+ * suspend_finish - Do final work before exiting suspend sequence.
+ * @state: State we're coming out of.
+ *
+ * Call platform code to clean up, restart processes, and free the
+ * console that we've allocated. This is not called for suspend-to-disk.
+ */
+
+static void suspend_finish(suspend_state_t state)
+{
+ enable_nonboot_cpus();
+ pm_finish(state);
+ device_resume();
+ resume_console();
+ thaw_processes();
+}
+
+
+
+
+static const char * const pm_states[PM_SUSPEND_MAX] = {
+ [PM_SUSPEND_STANDBY] = "standby",
+ [PM_SUSPEND_MEM] = "mem",
+#ifdef CONFIG_SOFTWARE_SUSPEND
+ [PM_SUSPEND_DISK] = "disk",
+#endif
+};
+
+static inline int valid_state(suspend_state_t state)
+{
+ /* Suspend-to-disk does not really need low-level support.
+ * It can work with reboot if needed. */
+ if (state == PM_SUSPEND_DISK)
+ return 1;
+
+ /* all other states need lowlevel support and need to be
+ * valid to the lowlevel implementation, no valid callback
+ * implies that all are valid. */
+ if (!pm_ops || (pm_ops->valid && !pm_ops->valid(state)))
+ return 0;
+ return 1;
+}
+
+
+/**
+ * enter_state - Do common work of entering low-power state.
+ * @state: pm_state structure for state we're entering.
+ *
+ * Make sure we're the only ones trying to enter a sleep state. Fail
+ * if someone has beat us to it, since we don't want anything weird to
+ * happen when we wake up.
+ * Then, do the setup for suspend, enter the state, and cleaup (after
+ * we've woken up).
+ */
+
+static int enter_state(suspend_state_t state)
+{
+ int error;
+
+ if (!valid_state(state))
+ return -ENODEV;
+ if (!mutex_trylock(&pm_mutex))
+ return -EBUSY;
+
+ if (state == PM_SUSPEND_DISK) {
+ error = pm_suspend_disk();
+ goto Unlock;
+ }
+
+ pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]);
+ if ((error = suspend_prepare(state)))
+ goto Unlock;
+
+ pr_debug("PM: Entering %s sleep\n", pm_states[state]);
+ error = suspend_enter(state);
+
+ pr_debug("PM: Finishing wakeup.\n");
+ suspend_finish(state);
+ Unlock:
+ mutex_unlock(&pm_mutex);
+ return error;
+}
+
+/*
+ * This is main interface to the outside world. It needs to be
+ * called from process context.
+ */
+int software_suspend(void)
+{
+ return enter_state(PM_SUSPEND_DISK);
+}
+
+
+/**
+ * pm_suspend - Externally visible function for suspending system.
+ * @state: Enumarted value of state to enter.
+ *
+ * Determine whether or not value is within range, get state
+ * structure, and enter (above).
+ */
+
+int pm_suspend(suspend_state_t state)
+{
+ if (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX)
+ return enter_state(state);
+ return -EINVAL;
+}
+
+EXPORT_SYMBOL(pm_suspend);
+
+decl_subsys(power,NULL,NULL);
+
+
+/**
+ * state - control system power state.
+ *
+ * show() returns what states are supported, which is hard-coded to
+ * 'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and
+ * 'disk' (Suspend-to-Disk).
+ *
+ * store() accepts one of those strings, translates it into the
+ * proper enumerated value, and initiates a suspend transition.
+ */
+
+static ssize_t state_show(struct subsystem * subsys, char * buf)
+{
+ int i;
+ char * s = buf;
+
+ for (i = 0; i < PM_SUSPEND_MAX; i++) {
+ if (pm_states[i] && valid_state(i))
+ s += sprintf(s,"%s ", pm_states[i]);
+ }
+ s += sprintf(s,"\n");
+ return (s - buf);
+}
+
+static ssize_t state_store(struct subsystem * subsys, const char * buf, size_t n)
+{
+ suspend_state_t state = PM_SUSPEND_STANDBY;
+ const char * const *s;
+ char *p;
+ int error;
+ int len;
+
+ p = memchr(buf, '\n', n);
+ len = p ? p - buf : n;
+
+ for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) {
+ if (*s && !strncmp(buf, *s, len))
+ break;
+ }
+ if (state < PM_SUSPEND_MAX && *s)
+ error = enter_state(state);
+ else
+ error = -EINVAL;
+ return error ? error : n;
+}
+
+power_attr(state);
+
+#ifdef CONFIG_PM_TRACE
+int pm_trace_enabled;
+
+static ssize_t pm_trace_show(struct subsystem * subsys, char * buf)
+{
+ return sprintf(buf, "%d\n", pm_trace_enabled);
+}
+
+static ssize_t
+pm_trace_store(struct subsystem * subsys, const char * buf, size_t n)
+{
+ int val;
+
+ if (sscanf(buf, "%d", &val) == 1) {
+ pm_trace_enabled = !!val;
+ return n;
+ }
+ return -EINVAL;
+}
+
+power_attr(pm_trace);
+
+static struct attribute * g[] = {
+ &state_attr.attr,
+ &pm_trace_attr.attr,
+ NULL,
+};
+#else
+static struct attribute * g[] = {
+ &state_attr.attr,
+ NULL,
+};
+#endif /* CONFIG_PM_TRACE */
+
+static struct attribute_group attr_group = {
+ .attrs = g,
+};
+
+
+static int __init pm_init(void)
+{
+ int error = subsystem_register(&power_subsys);
+ if (!error)
+ error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group);
+ return error;
+}
+
+core_initcall(pm_init);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|