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. |