* [PATCH] sysfs support for fbdev
@ 2005-03-01 10:00 Jon Smirl
2005-03-01 21:11 ` James Simmons
2005-03-01 23:49 ` Benjamin Herrenschmidt
0 siblings, 2 replies; 17+ messages in thread
From: Jon Smirl @ 2005-03-01 10:00 UTC (permalink / raw)
To: fbdev
[-- Attachment #1: Type: text/plain, Size: 812 bytes --]
Not finished yet but here's an update.
Merges Antonio's fbcon support
Creates monitor device inside of fbdev
Creates two fbdev devices for radeonfb
The changes in class.c are temporary GregKH promises a real fix soon.
Patch is 1000+ lines so I made it an attachment.
Making the monitor device inside of the fbdev allows hotplug to work
for monitors. Now all I need to do is hook up the radeon interrupt.
When finished, unplug the monitor, get interrupt, build monitor
device, get hotplug event, helper builds modelist, set modelist to
fbdev, this causes sysfs attribute change event, hal then dbus hears
this, X rebuilds the display. Still a few weeks of work to go.
If anyone wants to help implement some of the other attributes, send
me a patch and I will incorporate it.
--
Jon Smirl
jonsmirl@gmail.com
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: sysfs.patch --]
[-- Type: text/x-diff; name="sysfs.patch", Size: 32605 bytes --]
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c 2005-03-01 04:49:39 -05:00
+++ b/drivers/base/class.c 2005-03-01 04:49:39 -05:00
@@ -417,8 +417,9 @@
/* first, register with generic layer. */
kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
- if (parent)
+ if (parent && !class_dev->kobj.parent)
class_dev->kobj.parent = &parent->subsys.kset.kobj;
+ class_dev->kobj.parent = kobject_get(class_dev->kobj.parent);
if ((error = kobject_add(&class_dev->kobj)))
goto register_done;
@@ -467,6 +468,7 @@
class_device_driver_unlink(class_dev);
class_device_remove_attrs(class_dev);
+ kobject_put(class_dev->kobj.parent);
kobject_del(&class_dev->kobj);
if (parent)
diff -Nru a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
--- a/drivers/video/aty/radeon_base.c 2005-03-01 04:49:39 -05:00
+++ b/drivers/video/aty/radeon_base.c 2005-03-01 04:49:39 -05:00
@@ -1802,10 +1802,8 @@
};
-static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
+static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo, struct fb_info *info)
{
- struct fb_info *info = rinfo->info;
-
info->par = rinfo;
info->pseudo_palette = rinfo->pseudo_palette;
info->flags = FBINFO_DEFAULT
@@ -2147,13 +2145,12 @@
return count;
}
+#define to_class_device(x) container_of((x), struct class_device, kobj)
static ssize_t radeon_show_edid1(struct kobject *kobj, char *buf, loff_t off, size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct pci_dev *pdev = to_pci_dev(dev);
- struct fb_info *info = pci_get_drvdata(pdev);
- struct radeonfb_info *rinfo = info->par;
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(to_class_device(kobj));
+ struct radeonfb_info *rinfo = fb_info->par;
return radeon_show_one_edid(buf, off, count, rinfo->mon1_EDID);
}
@@ -2161,17 +2158,15 @@
static ssize_t radeon_show_edid2(struct kobject *kobj, char *buf, loff_t off, size_t count)
{
- struct device *dev = container_of(kobj, struct device, kobj);
- struct pci_dev *pdev = to_pci_dev(dev);
- struct fb_info *info = pci_get_drvdata(pdev);
- struct radeonfb_info *rinfo = info->par;
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(to_class_device(kobj));
+ struct radeonfb_info *rinfo = fb_info->par;
return radeon_show_one_edid(buf, off, count, rinfo->mon2_EDID);
}
static struct bin_attribute edid1_attr = {
.attr = {
- .name = "edid1",
+ .name = "edid",
.owner = THIS_MODULE,
.mode = 0444,
},
@@ -2181,7 +2176,7 @@
static struct bin_attribute edid2_attr = {
.attr = {
- .name = "edid2",
+ .name = "edid",
.owner = THIS_MODULE,
.mode = 0444,
},
@@ -2189,7 +2184,6 @@
.read = radeon_show_edid2,
};
-
static int radeonfb_pci_register (struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -2217,6 +2211,7 @@
rinfo = info->par;
rinfo->info = info;
rinfo->pdev = pdev;
+ rinfo->info2.device = &pdev->dev;
spin_lock_init(&rinfo->reg_lock);
init_timer(&rinfo->lvds_timer);
@@ -2339,7 +2334,8 @@
#endif
/* set all the vital stuff */
- radeon_set_fbinfo (rinfo);
+ radeon_set_fbinfo (rinfo, rinfo->info);
+ radeon_set_fbinfo (rinfo, &rinfo->info2);
/* Probe screen types */
radeon_probe_screens(rinfo, monitor_layout, ignore_edid);
@@ -2347,12 +2343,6 @@
/* Build mode list, check out panel native model */
radeon_check_modes(rinfo, mode_option);
- /* Register some sysfs stuff (should be done better) */
- if (rinfo->mon1_EDID)
- sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr);
- if (rinfo->mon2_EDID)
- sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr);
-
/* save current mode regs before we switch into the new one
* so we can restore this upon __exit
*/
@@ -2364,10 +2354,26 @@
/* Register with fbdev layer */
ret = register_framebuffer(info);
if (ret < 0) {
- printk (KERN_ERR "radeonfb (%s): could not register framebuffer\n",
+ printk (KERN_ERR "radeonfb (%s): could not register framebuffer 1\n",
pci_name(rinfo->pdev));
goto err_unmap_fb;
}
+ ret = register_framebuffer(&rinfo->info2);
+ if (ret < 0) {
+ printk (KERN_ERR "radeonfb (%s): could not register framebuffer 2\n",
+ pci_name(rinfo->pdev));
+ goto err_unmap_fb;
+ }
+
+ /* Register some sysfs stuff (should be done better) */
+ if (rinfo->mon1_EDID) {
+ rinfo->monitor1 = fb_add_child(info->class_device, info, "monitor");
+ class_device_create_bin_file(rinfo->monitor1, &edid1_attr);
+ }
+ if (rinfo->mon2_EDID) {
+ rinfo->monitor2 = fb_add_child(rinfo->info2.class_device, &rinfo->info2, "monitor");
+ class_device_create_bin_file(rinfo->monitor2, &edid2_attr);
+ }
/* Setup Power Management capabilities */
if (default_dynclk < -1) {
@@ -2424,8 +2430,6 @@
return ret;
}
-
-
static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
@@ -2452,8 +2456,15 @@
if (rinfo->mtrr_hdl >= 0)
mtrr_del(rinfo->mtrr_hdl, 0, 0);
#endif
-
- unregister_framebuffer(info);
+ if (rinfo->mon1_EDID)
+ class_device_remove_bin_file(rinfo->monitor1, &edid1_attr);
+ if (rinfo->mon2_EDID)
+ class_device_remove_bin_file(rinfo->monitor1, &edid2_attr);
+ class_device_unregister(rinfo->monitor1);
+ class_device_unregister(rinfo->monitor2);
+
+ unregister_framebuffer(info);
+ unregister_framebuffer(&rinfo->info2);
iounmap(rinfo->mmio_base);
iounmap(rinfo->fb_base);
diff -Nru a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
--- a/drivers/video/aty/radeonfb.h 2005-03-01 04:49:39 -05:00
+++ b/drivers/video/aty/radeonfb.h 2005-03-01 04:49:39 -05:00
@@ -270,7 +270,11 @@
};
struct radeonfb_info {
+ struct fb_info info2;
struct fb_info *info;
+
+ struct class_device *monitor1;
+ struct class_device *monitor2;
struct radeon_regs state;
struct radeon_regs init_state;
diff -Nru a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
--- a/drivers/video/console/bitblit.c 2005-03-01 04:49:39 -05:00
+++ b/drivers/video/console/bitblit.c 2005-03-01 04:49:39 -05:00
@@ -39,7 +39,7 @@
{
int attribute = 0;
- if (fb_get_color_depth(info) == 1) {
+ if (fb_get_color_depth(&info->var) == 1) {
if (attr_underline(c))
attribute |= FBCON_ATTRIBUTE_UNDERLINE;
if (attr_reverse(c))
diff -Nru a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
--- a/drivers/video/console/fbcon.c 2005-03-01 04:49:39 -05:00
+++ b/drivers/video/console/fbcon.c 2005-03-01 04:49:39 -05:00
@@ -182,8 +182,10 @@
static __inline__ void ypan_down(struct vc_data *vc, int count);
static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx,
int dy, int dx, int height, int width, u_int y_break);
-static void fbcon_set_disp(struct fb_info *info, struct vc_data *vc);
-static void fbcon_preset_disp(struct fb_info *info, int unit);
+static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
+ struct vc_data *vc);
+static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,
+ int unit);
static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
int line, int count, int dy);
@@ -209,7 +211,7 @@
static inline int get_color(struct vc_data *vc, struct fb_info *info,
u16 c, int is_fg)
{
- int depth = fb_get_color_depth(info);
+ int depth = fb_get_color_depth(&info->var);
int color = 0;
if (console_blanked) {
@@ -418,7 +420,7 @@
* remove underline attribute from erase character
* if black and white framebuffer.
*/
- if (fb_get_color_depth(info) == 1)
+ if (fb_get_color_depth(&info->var) == 1)
erase &= ~0x400;
logo_height = fb_prepare_logo(info);
logo_lines = (logo_height + vc->vc_font.height - 1) /
@@ -595,9 +597,9 @@
info->fbops->fb_set_par(info);
if (vc)
- fbcon_set_disp(info, vc);
+ fbcon_set_disp(info, &info->var, vc);
else
- fbcon_preset_disp(info, unit);
+ fbcon_preset_disp(info, &info->var, unit);
if (show_logo) {
struct vc_data *fg_vc = vc_cons[fg_console].d;
@@ -681,6 +683,8 @@
struct fb_var_screeninfo *var,
struct fb_info *info)
{
+ struct fb_videomode *mode;
+
disp->xres_virtual = var->xres_virtual;
disp->yres_virtual = var->yres_virtual;
disp->bits_per_pixel = var->bits_per_pixel;
@@ -693,10 +697,11 @@
disp->green = var->green;
disp->blue = var->blue;
disp->transp = var->transp;
- disp->mode = fb_match_mode(var, &info->modelist);
- if (disp->mode == NULL)
+ mode = fb_match_mode(var, &info->modelist);
+ if (mode == NULL)
/* This should not happen */
return -EINVAL;
+ disp->mode = mode;
return 0;
}
@@ -918,7 +923,7 @@
}
if (p->userfont)
charcnt = FNTCHARCNT(p->fontdata);
- vc->vc_can_do_color = (fb_get_color_depth(info) != 1);
+ vc->vc_can_do_color = (fb_get_color_depth(&info->var) != 1);
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
if (charcnt == 256) {
vc->vc_hi_font_mask = 0;
@@ -1124,13 +1129,14 @@
/*
* If no vc is existent yet, just set struct display
*/
-static void fbcon_preset_disp(struct fb_info *info, int unit)
+static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,
+ int unit)
{
struct display *p = &fb_display[unit];
struct display *t = &fb_display[fg_console];
- info->var.xoffset = info->var.yoffset = p->yscroll = 0;
- if (var_to_display(p, &info->var, info))
+ var->xoffset = var->yoffset = p->yscroll = 0;
+ if (var_to_display(p, var, info))
return;
p->fontdata = t->fontdata;
@@ -1139,7 +1145,8 @@
REFCOUNT(p->fontdata)++;
}
-static void fbcon_set_disp(struct fb_info *info, struct vc_data *vc)
+static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
+ struct vc_data *vc)
{
struct display *p = &fb_display[vc->vc_num], *t;
struct vc_data **default_mode = vc->vc_display_fg;
@@ -1147,8 +1154,8 @@
int display_fg = (*default_mode)->vc_num;
int rows, cols, charcnt = 256;
- info->var.xoffset = info->var.yoffset = p->yscroll = 0;
- if (var_to_display(p, &info->var, info))
+ var->xoffset = var->yoffset = p->yscroll = 0;
+ if (var_to_display(p, var, info))
return;
t = &fb_display[display_fg];
if (!vc->vc_font.data) {
@@ -1162,7 +1169,7 @@
if (p->userfont)
charcnt = FNTCHARCNT(p->fontdata);
- vc->vc_can_do_color = (fb_get_color_depth(info) != 1);
+ vc->vc_can_do_color = (fb_get_color_depth(var) != 1);
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
if (charcnt == 256) {
vc->vc_hi_font_mask = 0;
@@ -1177,8 +1184,8 @@
if (!*vc->vc_uni_pagedir_loc)
con_copy_unimap(vc->vc_num, display_fg);
- cols = info->var.xres / vc->vc_font.width;
- rows = info->var.yres / vc->vc_font.height;
+ cols = var->xres / vc->vc_font.width;
+ rows = var->yres / vc->vc_font.height;
vc_resize(vc->vc_num, cols, rows);
if (CON_IS_VISIBLE(vc)) {
update_screen(vc->vc_num);
@@ -1957,7 +1964,7 @@
set_blitting_type(vc, info, p);
((struct fbcon_ops *)info->fbcon_par)->cursor_reset = 1;
- vc->vc_can_do_color = (fb_get_color_depth(info) != 1);
+ vc->vc_can_do_color = (fb_get_color_depth(&info->var) != 1);
vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
updatescrollmode(p, info, vc);
@@ -2328,7 +2335,7 @@
if (fbcon_is_inactive(vc, info))
return -EINVAL;
- depth = fb_get_color_depth(info);
+ depth = fb_get_color_depth(&info->var);
if (depth > 3) {
for (i = j = 0; i < 16; i++) {
k = table[i];
@@ -2605,7 +2612,7 @@
if (fb_info != info)
continue;
p = &fb_display[i];
- if (!p || !p->mode)
+ if (!p)
continue;
if (fb_mode_is_equal(p->mode, mode)) {
found = 1;
@@ -2663,6 +2670,31 @@
}
}
+static void fbcon_new_modelist(struct fb_info *info)
+{
+ int i;
+ struct vc_data *vc;
+ struct fb_var_screeninfo var;
+ struct fb_videomode *mode;
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ if (registered_fb[con2fb_map[i]] != info)
+ continue;
+ if (!fb_display[i].mode)
+ continue;
+ vc = vc_cons[i].d;
+ display_to_var(&var, &fb_display[i]);
+ mode = fb_find_nearest_mode(&var, &info->modelist);
+ fb_videomode_to_var(&var, mode);
+
+ if (vc)
+ fbcon_set_disp(info, &var, vc);
+ else
+ fbcon_preset_disp(info, &var, i);
+
+ }
+}
+
static int fbcon_event_notify(struct notifier_block *self,
unsigned long action, void *data)
{
@@ -2700,6 +2732,9 @@
break;
case FB_EVENT_BLANK:
fbcon_fb_blanked(info, *(int *)event->data);
+ break;
+ case FB_EVENT_NEW_MODELIST:
+ fbcon_new_modelist(info);
break;
}
diff -Nru a/drivers/video/fbmem.c b/drivers/video/fbmem.c
--- a/drivers/video/fbmem.c 2005-03-01 04:49:39 -05:00
+++ b/drivers/video/fbmem.c 2005-03-01 04:49:39 -05:00
@@ -62,10 +62,8 @@
* Helpers
*/
-int fb_get_color_depth(struct fb_info *info)
+int fb_get_color_depth(struct fb_var_screeninfo *var)
{
- struct fb_var_screeninfo *var = &info->var;
-
if (var->green.length == var->blue.length &&
var->green.length == var->red.length &&
!var->green.offset && !var->blue.offset &&
@@ -300,7 +298,7 @@
const u8 *src = logo->data;
u8 d, xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0;
- if (fb_get_color_depth(info) == 3)
+ if (fb_get_color_depth(&info->var) == 3)
fg = 7;
switch (depth) {
@@ -365,7 +363,7 @@
int fb_prepare_logo(struct fb_info *info)
{
- int depth = fb_get_color_depth(info);
+ int depth = fb_get_color_depth(&info->var);
memset(&fb_logo, 0, sizeof(struct logo_data));
@@ -1042,7 +1040,7 @@
#endif
};
-static struct class_simple *fb_class;
+struct class *fb_class;
/**
* register_framebuffer - registers a frame buffer device
@@ -1058,7 +1056,6 @@
register_framebuffer(struct fb_info *fb_info)
{
int i;
- struct class_device *c;
struct fb_event event;
if (num_registered_fb == FB_MAX)
@@ -1069,13 +1066,13 @@
break;
fb_info->node = i;
- c = class_simple_device_add(fb_class, MKDEV(FB_MAJOR, i),
- fb_info->device, "fb%d", i);
- if (IS_ERR(c)) {
+ fb_info->class_device = fb_device_add(fb_class, fb_info);
+ if (IS_ERR(fb_info->class_device)) {
/* Not fatal */
- printk(KERN_WARNING "Unable to create class_device for framebuffer %d; errno = %ld\n", i, PTR_ERR(c));
+ printk(KERN_WARNING "Unable to create class_device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->class_device));
+ fb_info->class_device = NULL;
}
-
+
if (fb_info->pixmap.addr == NULL) {
fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
if (fb_info->pixmap.addr) {
@@ -1134,7 +1131,7 @@
fb_destroy_modelist(&fb_info->modelist);
registered_fb[i]=NULL;
num_registered_fb--;
- class_simple_device_remove(MKDEV(FB_MAJOR, i));
+ class_device_unregister(fb_info->class_device);
return 0;
}
@@ -1197,7 +1194,7 @@
if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
printk("unable to get major %d for fb devs\n", FB_MAJOR);
- fb_class = class_simple_create(THIS_MODULE, "graphics");
+ fb_class = fb_create_class(THIS_MODULE, "graphics");
if (IS_ERR(fb_class)) {
printk(KERN_WARNING "Unable to create fb class; errno = %ld\n", PTR_ERR(fb_class));
fb_class = NULL;
@@ -1208,7 +1205,7 @@
void __exit
fbmem_exit(void)
{
- class_simple_destroy(fb_class);
+ class_unregister(fb_class);
}
#ifdef MODULE
@@ -1221,6 +1218,40 @@
subsys_exitcall(fbmem_exit);
#endif
+int fb_new_modelist(struct fb_info *info)
+{
+ struct fb_event event;
+ struct fb_var_screeninfo var = info->var;
+ struct list_head *pos, *n;
+ struct fb_modelist *modelist;
+ struct fb_videomode *m, mode;
+ int err = 1;
+
+ list_for_each_safe(pos, n, &info->modelist) {
+ modelist = list_entry(pos, struct fb_modelist, list);
+ m = &modelist->mode;
+ fb_videomode_to_var(&var, m);
+ var.activate = FB_ACTIVATE_TEST;
+ err = fb_set_var(info, &var);
+ fb_var_to_videomode(&mode, &var);
+ if (err || !fb_mode_is_equal(m, &mode)) {
+ list_del(pos);
+ kfree(pos);
+ }
+ }
+
+ err = 1;
+
+ if (!list_empty(&info->modelist)) {
+ event.info = info;
+ err = notifier_call_chain(&fb_notifier_list,
+ FB_EVENT_NEW_MODELIST,
+ &event);
+ }
+
+ return err;
+}
+
static char *video_options[FB_MAX];
static int ofonly;
@@ -1332,5 +1363,6 @@
EXPORT_SYMBOL(fb_register_client);
EXPORT_SYMBOL(fb_unregister_client);
EXPORT_SYMBOL(fb_get_options);
+EXPORT_SYMBOL(fb_new_modelist);
MODULE_LICENSE("GPL");
diff -Nru a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
--- a/drivers/video/fbsysfs.c 2005-03-01 04:49:39 -05:00
+++ b/drivers/video/fbsysfs.c 2005-03-01 04:49:39 -05:00
@@ -2,6 +2,7 @@
* fbsysfs.c - framebuffer device class and attributes
*
* Copyright (c) 2004 James Simmons <jsimmons@infradead.org>
+ * Copyright (c) 2005 Jon Smirl <jonsmirl@gmail.com>
*
* This program is free software you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -17,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/fb.h>
+#include <linux/console.h>
/**
* framebuffer_alloc - creates a new frame buffer info structure
@@ -57,6 +59,7 @@
#undef PADDING
#undef BYTES_PER_LONG
}
+EXPORT_SYMBOL(framebuffer_alloc);
/**
* framebuffer_release - marks the structure available for freeing
@@ -71,6 +74,371 @@
{
kfree(info);
}
-
EXPORT_SYMBOL(framebuffer_release);
-EXPORT_SYMBOL(framebuffer_alloc);
+
+static int activate(struct fb_info *fb_info, struct fb_var_screeninfo *var)
+{
+ int err;
+
+ var->activate |= FB_ACTIVATE_FORCE;
+ acquire_console_sem();
+ fb_info->flags |= FBINFO_MISC_USEREVENT;
+ err = fb_set_var(fb_info, var);
+ fb_info->flags &= ~FBINFO_MISC_USEREVENT;
+ release_console_sem();
+ if (err)
+ return err;
+ return 0;
+}
+
+static int mode_string(char *buf, unsigned int offset, const struct fb_videomode *mode)
+{
+ char m = 'U';
+ if (mode->flag & FB_MODE_IS_DETAILED)
+ m = 'D';
+ if (mode->flag & FB_MODE_IS_VESA)
+ m = 'V';
+ if (mode->flag & FB_MODE_IS_STANDARD)
+ m = 'S';
+ return snprintf(&buf[offset], PAGE_SIZE - offset, "%c:%dx%d-%d\n", m, mode->xres, mode->yres, mode->refresh);
+}
+
+static ssize_t store_mode(struct class_device *class_device, const char * buf, size_t count)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ char mstr[100];
+ struct fb_var_screeninfo var;
+ struct fb_modelist *modelist;
+ struct fb_videomode *mode;
+ struct list_head *pos;
+ size_t i;
+ int err;
+
+ memset(&var, 0, sizeof(var));
+
+ list_for_each(pos, &fb_info->modelist) {
+ modelist = list_entry(pos, struct fb_modelist, list);
+ mode = &modelist->mode;
+ i = mode_string(mstr, 0, mode);
+ if (strncmp(mstr, buf, max(count, i)) == 0) {
+
+ var = fb_info->var;
+ fb_videomode_to_var(&var, mode);
+ if ((err = activate(fb_info, &var)))
+ return err;
+ fb_info->mode = mode;
+ return count;
+ }
+ }
+ return -EINVAL;
+}
+
+static ssize_t show_mode(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+
+ if (!fb_info->mode)
+ return 0;
+
+ return mode_string(buf, 0, fb_info->mode);
+}
+
+static ssize_t store_modes(struct class_device *class_device, const char * buf, size_t count)
+{
+ struct fb_info *fb_info =
+ (struct fb_info *)class_get_devdata(class_device);
+ LIST_HEAD(old_list);
+
+ int i = count / sizeof(struct fb_videomode);
+
+ if (i * sizeof(struct fb_videomode) != count)
+ return -EINVAL;
+
+ acquire_console_sem();
+ list_splice(&fb_info->modelist, &old_list);
+ fb_videomode_to_modelist((struct fb_videomode *)buf, i,
+ &fb_info->modelist);
+ if (fb_new_modelist(fb_info)) {
+ fb_destroy_modelist(&fb_info->modelist);
+ list_splice(&old_list, &fb_info->modelist);
+ } else
+ fb_destroy_modelist(&old_list);
+
+ release_console_sem();
+
+ return 0;
+}
+
+
+static ssize_t show_modes(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ unsigned int i;
+ struct list_head *pos;
+ struct fb_modelist *modelist;
+ const struct fb_videomode *mode;
+
+ i = 0;
+ list_for_each(pos, &fb_info->modelist) {
+ modelist = list_entry(pos, struct fb_modelist, list);
+ mode = &modelist->mode;
+ i += mode_string(buf, i, mode);
+ }
+ return i;
+}
+
+static ssize_t store_bpp(struct class_device *class_device, const char * buf, size_t count)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ struct fb_var_screeninfo var;
+ char ** last = NULL;
+ int err;
+
+ var = fb_info->var;
+ var.bits_per_pixel = simple_strtoul(buf, last, 0);
+ if ((err = activate(fb_info, &var)))
+ return err;
+ return count;
+}
+
+static ssize_t show_bpp(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->var.bits_per_pixel);
+}
+
+static ssize_t store_virtual(struct class_device *class_device, const char * buf, size_t count)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ struct fb_var_screeninfo var;
+ char *last = NULL;
+ int err;
+
+ var = fb_info->var;
+ var.xres_virtual = simple_strtoul(buf, &last, 0);
+ last++;
+ if (last - buf >= count)
+ return -EINVAL;
+ var.yres_virtual = simple_strtoul(last, &last, 0);
+ printk(KERN_ERR "fb: xres %d yres %d\n", var.xres_virtual, var.yres_virtual);
+
+ if ((err = activate(fb_info, &var)))
+ return err;
+ return count;
+}
+
+static ssize_t show_virtual(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual, fb_info->var.xres_virtual);
+}
+
+static ssize_t store_cmap(struct class_device *class_device, const char * buf, size_t count)
+{
+// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ return 0;
+}
+
+static ssize_t show_cmap(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ unsigned int offset = 0, i;
+
+ if (!fb_info->cmap.red || !fb_info->cmap.blue || fb_info->cmap.green || fb_info->cmap.transp)
+ return -EINVAL;
+
+ for (i = 0; i < fb_info->cmap.len; i++) {
+ offset += snprintf(buf, PAGE_SIZE - offset, "%d,%d,%d,%d,%d\n", i + fb_info->cmap.start,
+ fb_info->cmap.red[i], fb_info->cmap.blue[i], fb_info->cmap.green[i],
+ fb_info->cmap.transp[i]);
+ }
+ return offset;
+}
+
+static ssize_t store_blank(struct class_device *class_device, const char * buf, size_t count)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ char *last = NULL;
+ int err;
+
+ acquire_console_sem();
+ fb_info->flags |= FBINFO_MISC_USEREVENT;
+ err = fb_blank(fb_info, simple_strtoul(buf, &last, 0));
+ fb_info->flags &= ~FBINFO_MISC_USEREVENT;
+ release_console_sem();
+ if (err < 0)
+ return err;
+ return count;
+}
+
+static ssize_t show_blank(struct class_device *class_device, char *buf)
+{
+// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ return 0;
+}
+
+static ssize_t store_console(struct class_device *class_device, const char * buf, size_t count)
+{
+// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ return 0;
+}
+
+static ssize_t show_console(struct class_device *class_device, char *buf)
+{
+// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ return 0;
+}
+
+static ssize_t store_cursor(struct class_device *class_device, const char * buf, size_t count)
+{
+// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ return 0;
+}
+
+static ssize_t show_cursor(struct class_device *class_device, char *buf)
+{
+// struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ return 0;
+}
+
+static ssize_t store_pan(struct class_device *class_device, const char * buf, size_t count)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ struct fb_var_screeninfo var;
+ char *last = NULL;
+ int err;
+
+ var = fb_info->var;
+ var.xoffset = simple_strtoul(buf, &last, 0);
+ last++;
+ if (last - buf >= count)
+ return -EINVAL;
+ var.yoffset = simple_strtoul(last, &last, 0);
+
+ acquire_console_sem();
+ err = fb_pan_display(fb_info, &var);
+ release_console_sem();
+
+ if (err < 0)
+ return err;
+ return count;
+}
+
+static ssize_t show_pan(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, fb_info->var.xoffset);
+}
+
+static ssize_t show_dev(struct class_device *class_device, char *buf)
+{
+ struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+ return print_dev_t(buf, MKDEV(FB_MAJOR, fb_info->node));
+}
+
+struct class_device_attribute class_device_attrs[] = {
+ __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp),
+ __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank),
+ __ATTR(color_map, S_IRUGO|S_IWUSR, show_cmap, store_cmap),
+ __ATTR(console, S_IRUGO|S_IWUSR, show_console, store_console),
+ __ATTR(cursor, S_IRUGO|S_IWUSR, show_cursor, store_cursor),
+ __ATTR(mode, S_IRUGO|S_IWUSR, show_mode, store_mode),
+ __ATTR(modes, S_IRUGO|S_IWUSR, show_modes, store_modes),
+ __ATTR(pan, S_IRUGO|S_IWUSR, show_pan, store_pan),
+ __ATTR(virtual_size, S_IRUGO|S_IWUSR, show_virtual, store_virtual),
+ __ATTR(dev, S_IRUGO, show_dev, NULL),
+ __ATTR_NULL,
+};
+
+static void release_fb_dev(struct class_device *class_dev)
+{
+ kfree(class_dev);
+}
+
+static void class_fb_release(struct class *class)
+{
+ kfree(class);
+}
+
+struct class *fb_create_class(struct module *owner, char *name)
+{
+ struct class *cs;
+ int retval;
+
+ cs = kmalloc(sizeof(*cs), GFP_KERNEL);
+ if (!cs) {
+ retval = -ENOMEM;
+ goto error;
+ }
+ memset(cs, 0x00, sizeof(*cs));
+
+ cs->name = name;
+ cs->class_release = class_fb_release;
+ cs->release = release_fb_dev;
+ cs->class_dev_attrs = class_device_attrs;
+
+ retval = class_register(cs);
+ if (retval)
+ goto error;
+
+ return cs;
+
+error:
+ kfree(cs);
+ return ERR_PTR(retval);
+}
+
+struct class_device *fb_device_add(struct class *cs, struct fb_info *fb_info)
+{
+ struct class_device *s_dev = NULL;
+ int retval;
+
+ if ((cs == NULL) || (IS_ERR(cs))) {
+ retval = -ENODEV;
+ goto error;
+ }
+
+ s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL);
+ if (!s_dev) {
+ retval = -ENOMEM;
+ goto error;
+ }
+ memset(s_dev, 0x00, sizeof(*s_dev));
+
+ s_dev->dev = fb_info->device;
+ s_dev->class = cs;
+ class_set_devdata(s_dev, fb_info);
+
+ snprintf(s_dev->class_id, BUS_ID_SIZE, "fb%d", fb_info->node);
+
+ retval = class_device_register(s_dev);
+ if (retval)
+ goto error;
+
+ return s_dev;
+
+error:
+ kfree(s_dev);
+ return ERR_PTR(retval);
+}
+
+struct class_device *fb_add_child(struct class_device *class_device, struct fb_info *fb_info, const char *fmt, ...)
+{
+ va_list args;
+ struct class_device *fb_dev;
+ int ret;
+
+ fb_dev = kmalloc(sizeof(*fb_dev), GFP_KERNEL);
+ memset(fb_dev, 0, sizeof(*fb_dev));
+ fb_dev->class = class_device->class;
+ fb_dev->kobj.parent = &class_device->kobj;
+ class_set_devdata(fb_dev, fb_info);
+
+ va_start(args, fmt);
+ vsnprintf(fb_dev->class_id, sizeof(fb_dev->class_id), fmt, args);
+ va_end(args);
+
+ ret = class_device_register(fb_dev);
+ return fb_dev;
+}
+EXPORT_SYMBOL(fb_add_child);
diff -Nru a/drivers/video/modedb.c b/drivers/video/modedb.c
--- a/drivers/video/modedb.c 2005-03-01 04:49:39 -05:00
+++ b/drivers/video/modedb.c 2005-03-01 04:49:39 -05:00
@@ -722,6 +722,47 @@
}
/**
+ * fb_find_nearest_mode - find mode closest video mode
+ *
+ * @var: pointer to struct fb_var_screeninfo
+ * @head: pointer to modelist
+ *
+ * Finds best matching videomode, smaller or greater in dimension.
+ * If more than 1 videomode is found, will return the videomode with
+ * the closest refresh rate
+ */
+struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var,
+ struct list_head *head)
+{
+ struct list_head *pos;
+ struct fb_modelist *modelist;
+ struct fb_videomode *mode, *best = NULL;
+ u32 diff = -1, diff_refresh = -1;
+
+ list_for_each(pos, head) {
+ u32 d;
+
+ modelist = list_entry(pos, struct fb_modelist, list);
+ mode = &modelist->mode;
+
+ d = abs(mode->xres - var->xres) +
+ abs(mode->yres - var->yres);
+ if (diff > d) {
+ diff = d;
+ best = mode;
+ } else if (diff == d) {
+ d = abs(mode->refresh - best->refresh);
+ if (diff_refresh > d) {
+ diff_refresh = d;
+ best = mode;
+ }
+ }
+ }
+
+ return best;
+}
+
+/**
* fb_match_mode - find a videomode which exactly matches the timings in var
* @var: pointer to struct fb_var_screeninfo
* @head: pointer to struct list_head of modelist
@@ -846,5 +887,6 @@
EXPORT_SYMBOL(fb_destroy_modelist);
EXPORT_SYMBOL(fb_match_mode);
EXPORT_SYMBOL(fb_find_best_mode);
+EXPORT_SYMBOL(fb_find_nearest_mode);
EXPORT_SYMBOL(fb_videomode_to_modelist);
EXPORT_SYMBOL(fb_find_mode);
diff -Nru a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h 2005-03-01 04:49:39 -05:00
+++ b/include/linux/fb.h 2005-03-01 04:49:39 -05:00
@@ -490,6 +490,8 @@
#define FB_EVENT_SET_CONSOLE_MAP 0x07
/* A display blank is requested */
#define FB_EVENT_BLANK 0x08
+/* Private modelist is to be replaced */
+#define FB_EVENT_NEW_MODELIST 0x09
struct fb_event {
struct fb_info *info;
@@ -712,8 +714,10 @@
struct fb_pixmap sprite; /* Cursor hardware mapper */
struct fb_cmap cmap; /* Current cmap */
struct list_head modelist; /* mode list */
+ struct fb_videomode *mode; /* current mode */
struct fb_ops *fbops;
struct device *device;
+ struct class_device *class_device; /* sysfs per device attrs */
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops; /* Tile Blitting */
#endif
@@ -821,8 +825,9 @@
u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
u32 height);
extern void fb_set_suspend(struct fb_info *info, int state);
-extern int fb_get_color_depth(struct fb_info *info);
+extern int fb_get_color_depth(struct fb_var_screeninfo *var);
extern int fb_get_options(char *name, char **option);
+extern int fb_new_modelist(struct fb_info *info);
extern struct fb_info *registered_fb[FB_MAX];
extern int num_registered_fb;
@@ -830,6 +835,10 @@
/* drivers/video/fbsysfs.c */
extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
extern void framebuffer_release(struct fb_info *info);
+extern void fb_cleanup_class_device(struct fb_info *head);
+extern struct class *fb_create_class(struct module *owner, char *name);
+extern struct class_device *fb_device_add(struct class *cs, struct fb_info *fb_info);
+extern struct class_device *fb_add_child(struct class_device *class_device, struct fb_info *fb_info, const char *fmt, ...);
/* drivers/video/fbmon.c */
#define FB_MAXTIMINGS 0
@@ -875,6 +884,8 @@
struct list_head *head);
extern struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
struct list_head *head);
+extern struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var,
+ struct list_head *head);
extern void fb_destroy_modelist(struct list_head *head);
extern void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
struct list_head *head);
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-01 10:00 [PATCH] sysfs support for fbdev Jon Smirl
@ 2005-03-01 21:11 ` James Simmons
2005-03-02 18:13 ` Jon Smirl
2005-03-01 23:49 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 17+ messages in thread
From: James Simmons @ 2005-03-01 21:11 UTC (permalink / raw)
To: fbdev
> Not finished yet but here's an update.
Barf!!!! This patch is just nasty hack. Okay a run down on the fbdev api.
First struct xxx_par is your data structure representing your device.
There is one per video card. That is that hook in struct fb_info called
par. The idea was xxx_par could be independent of the fbdev layer and
could be used DRI. Now for the case of video cards with more than one
framebuffer then you have bothe struct fb_info's par point to the same
data structure. The verse works as well. Some systems allow multiple video
cards hooked up to one montior. Two framebuffers, one display. The
structure to deal with that is monspecs in struct fb_info. Now the problem
is it is not a pointer :-( I have to fix that with a patch in the near
future. If you are going to be messing with montiors work off of struct
fb_monspecs.
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-01 10:00 [PATCH] sysfs support for fbdev Jon Smirl
2005-03-01 21:11 ` James Simmons
@ 2005-03-01 23:49 ` Benjamin Herrenschmidt
2005-03-02 1:05 ` James Simmons
1 sibling, 1 reply; 17+ messages in thread
From: Benjamin Herrenschmidt @ 2005-03-01 23:49 UTC (permalink / raw)
To: Linux Fbdev development list
On Tue, 2005-03-01 at 05:00 -0500, Jon Smirl wrote:
> Not finished yet but here's an update.
>
> Merges Antonio's fbcon support
> Creates monitor device inside of fbdev
> Creates two fbdev devices for radeonfb
>
> The changes in class.c are temporary GregKH promises a real fix soon.
> Patch is 1000+ lines so I made it an attachment.
>
> Making the monitor device inside of the fbdev allows hotplug to work
> for monitors. Now all I need to do is hook up the radeon interrupt.
> When finished, unplug the monitor, get interrupt, build monitor
> device, get hotplug event, helper builds modelist, set modelist to
> fbdev, this causes sysfs attribute change event, hal then dbus hears
> this, X rebuilds the display. Still a few weeks of work to go.
>
> If anyone wants to help implement some of the other attributes, send
> me a patch and I will incorporate it.
I can already get some of the radeonfb bits in for 2.6.12, that will
make things easier. I'll let you know.
Ben.
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-01 23:49 ` Benjamin Herrenschmidt
@ 2005-03-02 1:05 ` James Simmons
0 siblings, 0 replies; 17+ messages in thread
From: James Simmons @ 2005-03-02 1:05 UTC (permalink / raw)
To: Linux Fbdev development list
> > If anyone wants to help implement some of the other attributes, send
> > me a patch and I will incorporate it.
>
> I can already get some of the radeonfb bits in for 2.6.12, that will
> make things easier. I'll let you know.
More testing first. Plus it should go into Andrews tree first.
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-01 21:11 ` James Simmons
@ 2005-03-02 18:13 ` Jon Smirl
2005-03-03 0:12 ` James Simmons
0 siblings, 1 reply; 17+ messages in thread
From: Jon Smirl @ 2005-03-02 18:13 UTC (permalink / raw)
To: linux-fbdev-devel, James Simmons
On Tue, 1 Mar 2005 21:11:20 +0000 (GMT), James Simmons
<jsimmons@www.infradead.org> wrote:
>
> > Not finished yet but here's an update.
>
> Barf!!!! This patch is just nasty hack. Okay a run down on the fbdev api.
> First struct xxx_par is your data structure representing your device.
> There is one per video card. That is that hook in struct fb_info called
> par. The idea was xxx_par could be independent of the fbdev layer and
> could be used DRI. Now for the case of video cards with more than one
> framebuffer then you have bothe struct fb_info's par point to the same
> data structure. The verse works as well. Some systems allow multiple video
> cards hooked up to one montior. Two framebuffers, one display. The
> structure to deal with that is monspecs in struct fb_info. Now the problem
> is it is not a pointer :-( I have to fix that with a patch in the near
> future. If you are going to be messing with montiors work off of struct
> fb_monspecs.
Have you considered moving all of the monitor support out into a
hotplug helper app? This will even work at boot time since early user
space is there when fbdev initializes. The helper app would be on
initrd just like the boot disk drivers.
--
Jon Smirl
jonsmirl@gmail.com
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-02 18:13 ` Jon Smirl
@ 2005-03-03 0:12 ` James Simmons
2005-03-03 0:57 ` Jon Smirl
2005-03-04 4:08 ` Jon Smirl
0 siblings, 2 replies; 17+ messages in thread
From: James Simmons @ 2005-03-03 0:12 UTC (permalink / raw)
To: Jon Smirl; +Cc: linux-fbdev-devel, James Simmons
> Have you considered moving all of the monitor support out into a
> hotplug helper app? This will even work at boot time since early user
> space is there when fbdev initializes. The helper app would be on
> initrd just like the boot disk drivers.
Consider the following case. I have high end server with fbcon running as
the console. One VC is at a different resolution than another. Now say the
system is under really heavy load. When I VC switch I would have to wait
until userland sets up the proper mode for me to VC switch. Consider also
if userland apps start getting killed. I'm limited to only VCs of the same
resolution if that helper app dies :-(
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-03 0:12 ` James Simmons
@ 2005-03-03 0:57 ` Jon Smirl
2005-03-07 18:05 ` James Simmons
2005-03-04 4:08 ` Jon Smirl
1 sibling, 1 reply; 17+ messages in thread
From: Jon Smirl @ 2005-03-03 0:57 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: James Simmons
On Thu, 3 Mar 2005 00:12:22 +0000 (GMT), James Simmons
<jsimmons@www.infradead.org> wrote:
>
> > Have you considered moving all of the monitor support out into a
> > hotplug helper app? This will even work at boot time since early user
> > space is there when fbdev initializes. The helper app would be on
> > initrd just like the boot disk drivers.
>
> Consider the following case. I have high end server with fbcon running as
> the console. One VC is at a different resolution than another. Now say the
> system is under really heavy load. When I VC switch I would have to wait
> until userland sets up the proper mode for me to VC switch. Consider also
> if userland apps start getting killed. I'm limited to only VCs of the same
> resolution if that helper app dies :-(
It is a helper app, not a daemon, it does not stay running. It also
only runs when the monitor is changed - not mode change, monitor
changed. On monitor change (loading fbdev counts as a monitor change)
the helper is called. The helper reads the DDC, parses it, merges in
any updates from /etc/fb.modes (or builds a modelist from fb.modes if
no DDC), and then sets this list of legal modes into the driver. After
the list is set a hal/dbus event is generated. Doing this is a root
only operation.
It can also happen in early user space when the kernel is first
booting. Early user space starts before fbcon currently starts. The
helper app would be loaded on to initrd or initramfs.
To change a mode, pick one of the mode names from the mode_list and
cat it to /sys/graphics/fbX/mode. This will cause the mode to be set
and a hal/dbus event to be generated. If you are just running console
the mode change event goes into fbcon. Any user can now safely set a
mode.
Changing modes does not require a user space helper, only changing
monitors (flipping a KVM switch for example).
I have working code for generating the interrupt on monitor change but
it isn't ready yet to send out.
This is the complete event sequence....
modprobe card driver
card driver checks if post needed, if so uses a new version of
request_firmware() to post
sys/graphics/fbX is added for each head
udev builds /dev/fbX for each head
1) driver locates monitors
creates sys/graphics/fbX/monitor(edid)
creating this causes a hotplug event
root priv hotplug event parses edid merges etc/mode file
sets legal modes back into sys/graphics/fbX(mode-list)
altering the modelist causes an event hal/dbus can see
user space mesa/X reads the mode-list, strings like 1024x768-60
set the one you want back into sys/graphics/fbX(mode)
this causes another hal/dbus event
If the card supports an interrupt on monitor change, flipping a KVM
switch will restart the process at #1.
Mode lists are generated at root priv.
Pam assigns ownership of mode variable to user
This allows a non-root user to safely set the mode
--
Jon Smirl
jonsmirl@gmail.com
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-03 0:12 ` James Simmons
2005-03-03 0:57 ` Jon Smirl
@ 2005-03-04 4:08 ` Jon Smirl
2005-03-04 18:26 ` James Simmons
2005-03-04 18:43 ` Sylvain Meyer
1 sibling, 2 replies; 17+ messages in thread
From: Jon Smirl @ 2005-03-04 4:08 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: James Simmons
On Thu, 3 Mar 2005 00:12:22 +0000 (GMT), James Simmons
<jsimmons@www.infradead.org> wrote:
>
> > Have you considered moving all of the monitor support out into a
> > hotplug helper app? This will even work at boot time since early user
> > space is there when fbdev initializes. The helper app would be on
> > initrd just like the boot disk drivers.
>
> Consider the following case. I have high end server with fbcon running as
> the console. One VC is at a different resolution than another. Now say the
> system is under really heavy load. When I VC switch I would have to wait
> until userland sets up the proper mode for me to VC switch. Consider also
> if userland apps start getting killed. I'm limited to only VCs of the same
> resolution if that helper app dies :-(
Doesn't the i830/i915/etc require a user space helper to change modes
since that part of the chip spec hasn't been released? The user space
helper would use Int10 VBIOS calls to list and set the modes. I
haven't worked with these chips, so this is just based off from what
has been posted to dri-devel. Is this why we don't have fbdev drivers
for these chips?
--
Jon Smirl
jonsmirl@gmail.com
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-04 4:08 ` Jon Smirl
@ 2005-03-04 18:26 ` James Simmons
2005-03-04 18:48 ` Jon Smirl
2005-03-04 18:43 ` Sylvain Meyer
1 sibling, 1 reply; 17+ messages in thread
From: James Simmons @ 2005-03-04 18:26 UTC (permalink / raw)
To: Jon Smirl; +Cc: linux-fbdev-devel, James Simmons
> Doesn't the i830/i915/etc require a user space helper to change modes
> since that part of the chip spec hasn't been released? The user space
> helper would use Int10 VBIOS calls to list and set the modes. I
> haven't worked with these chips, so this is just based off from what
> has been posted to dri-devel. Is this why we don't have fbdev drivers
> for these chips?
drivers/intel/*.[ch]
No user space helper there.
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-04 4:08 ` Jon Smirl
2005-03-04 18:26 ` James Simmons
@ 2005-03-04 18:43 ` Sylvain Meyer
2005-03-04 18:50 ` Jon Smirl
1 sibling, 1 reply; 17+ messages in thread
From: Sylvain Meyer @ 2005-03-04 18:43 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: James Simmons
Jon Smirl a écrit:
> Is this why we don't have fbdev drivers
>for these chips?
>
>
>
There is an intelfb fbdev driver. Not very actively maintained,
sorry for that, but i did a port to kernel 2.6 and try to get some spare
time to update it. The driver can change modes and i also did a driver
for TV-Out, not yet DFP/LFP (not in the kernel for now).
Sylvain
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-04 18:26 ` James Simmons
@ 2005-03-04 18:48 ` Jon Smirl
2005-03-04 18:50 ` Sylvain Meyer
0 siblings, 1 reply; 17+ messages in thread
From: Jon Smirl @ 2005-03-04 18:48 UTC (permalink / raw)
To: James Simmons; +Cc: linux-fbdev-devel, James Simmons
On Fri, 4 Mar 2005 18:26:57 +0000 (GMT), James Simmons
<jsimmons@www.infradead.org> wrote:
>
> > Doesn't the i830/i915/etc require a user space helper to change modes
> > since that part of the chip spec hasn't been released? The user space
> > helper would use Int10 VBIOS calls to list and set the modes. I
> > haven't worked with these chips, so this is just based off from what
> > has been posted to dri-devel. Is this why we don't have fbdev drivers
> > for these chips?
>
> drivers/intel/*.[ch]
>
> No user space helper there.
>
>
What about the i915? We don't seem to have a fbdev driver for it yet.
--
Jon Smirl
jonsmirl@gmail.com
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-04 18:43 ` Sylvain Meyer
@ 2005-03-04 18:50 ` Jon Smirl
2005-03-04 18:54 ` Sylvain Meyer
0 siblings, 1 reply; 17+ messages in thread
From: Jon Smirl @ 2005-03-04 18:50 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: James Simmons
On Fri, 04 Mar 2005 19:43:55 +0100, Sylvain Meyer
<sylvain.meyer@worldonline.fr> wrote:
>
>
> Jon Smirl a écrit:
>
> > Is this why we don't have fbdev drivers
> >for these chips?
> >
> >
> >
> There is an intelfb fbdev driver. Not very actively maintained,
> sorry for that, but i did a port to kernel 2.6 and try to get some spare
> time to update it. The driver can change modes and i also did a driver
> for TV-Out, not yet DFP/LFP (not in the kernel for now).
Has Intel released documentation for mode setting on these chips or
did you reverse engineer it?
>
> Sylvain
>
>
> -------------------------------------------------------
> SF email is sponsored by - The IT Product Guide
> Read honest & candid reviews on hundreds of IT Products from real users.
> Discover which products truly live up to the hype. Start reading now.
> http://ads.osdn.com/?ad_ide95&alloc_id\x14396&opclick
> _______________________________________________
> Linux-fbdev-devel mailing list
> Linux-fbdev-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel
>
--
Jon Smirl
jonsmirl@gmail.com
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-04 18:48 ` Jon Smirl
@ 2005-03-04 18:50 ` Sylvain Meyer
2005-03-04 19:48 ` Buttchereit, Axel (XL)
0 siblings, 1 reply; 17+ messages in thread
From: Sylvain Meyer @ 2005-03-04 18:50 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: James Simmons, James Simmons
Axel Buttchereit did a patch to implement it. It should be in the
latest mm tree.
Jon Smirl a écrit:
>On Fri, 4 Mar 2005 18:26:57 +0000 (GMT), James Simmons
><jsimmons@www.infradead.org> wrote:
>
>
>>>Doesn't the i830/i915/etc require a user space helper to change modes
>>>since that part of the chip spec hasn't been released? The user space
>>>helper would use Int10 VBIOS calls to list and set the modes. I
>>>haven't worked with these chips, so this is just based off from what
>>>has been posted to dri-devel. Is this why we don't have fbdev drivers
>>>for these chips?
>>>
>>>
>>drivers/intel/*.[ch]
>>
>>No user space helper there.
>>
>>
>>
>>
>What about the i915? We don't seem to have a fbdev driver for it yet.
>
>
>
>
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-04 18:50 ` Jon Smirl
@ 2005-03-04 18:54 ` Sylvain Meyer
0 siblings, 0 replies; 17+ messages in thread
From: Sylvain Meyer @ 2005-03-04 18:54 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: James Simmons
David Dawes did the original driver. I don't know if he had access
to the datasheet but Intel released documentation for i810/i815 and the
chips aren't very different.
Jon Smirl a écrit:
>On Fri, 04 Mar 2005 19:43:55 +0100, Sylvain Meyer
><sylvain.meyer@worldonline.fr> wrote:
>
>
>>Jon Smirl a écrit:
>>
>>
>>
>>>Is this why we don't have fbdev drivers
>>>for these chips?
>>>
>>>
>>>
>>>
>>>
>> There is an intelfb fbdev driver. Not very actively maintained,
>>sorry for that, but i did a port to kernel 2.6 and try to get some spare
>>time to update it. The driver can change modes and i also did a driver
>>for TV-Out, not yet DFP/LFP (not in the kernel for now).
>>
>>
>
>Has Intel released documentation for mode setting on these chips or
>did you reverse engineer it?
>
>
>
>>Sylvain
>>
>>
>>-------------------------------------------------------
>>SF email is sponsored by - The IT Product Guide
>>Read honest & candid reviews on hundreds of IT Products from real users.
>>Discover which products truly live up to the hype. Start reading now.
>>http://ads.osdn.com/?ad_ide95&alloc_id\x14396&opclick
>>_______________________________________________
>>Linux-fbdev-devel mailing list
>>Linux-fbdev-devel@lists.sourceforge.net
>>https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel
>>
>>
>>
>
>
>
>
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-04 18:50 ` Sylvain Meyer
@ 2005-03-04 19:48 ` Buttchereit, Axel (XL)
0 siblings, 0 replies; 17+ messages in thread
From: Buttchereit, Axel (XL) @ 2005-03-04 19:48 UTC (permalink / raw)
To: linux-fbdev-devel; +Cc: James Simmons, James Simmons, sylvain.meyer
Sylvain Meyer wrote:
> Axel Buttchereit did a patch to implement it. It should be in the
> latest mm tree.
>
> Jon Smirl a écrit:
>
>> On Fri, 4 Mar 2005 18:26:57 +0000 (GMT), James Simmons
>> <jsimmons@www.infradead.org> wrote:
>>
>>
>>>> Doesn't the i830/i915/etc require a user space helper to change modes
>>>> since that part of the chip spec hasn't been released? The user space
>>>> helper would use Int10 VBIOS calls to list and set the modes. I
>>>> haven't worked with these chips, so this is just based off from what
>>>> has been posted to dri-devel. Is this why we don't have fbdev drivers
>>>> for these chips?
>>>>
>>>
>>> drivers/intel/*.[ch]
>>>
>>> No user space helper there.
>>>
>>>
>>>
>>
>> What about the i915? We don't seem to have a fbdev driver for it yet.
>>
It is (intelfb-...). Including Tony's corresponding "modehelper" kernel-config
patch and -- since 2.6.11-rc5-mm1 -- with an additional patch from Andrew
that fixes some compiler warnings (missing type casts).
The driver is still not complete (no hardware cursor, ...) but it
does its job pretty good (at least on my machine).
Only a few changes are required to add support for i915 and they
can all easily be derived from the xorg/xfree-driver that already
(fully) supports the chipset.
Obviously there is someone at xfree/xorg that is either a "hell of a hacker"
or in the position to access the required documentation from intel.
Or both.
:-) Axel
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-03 0:57 ` Jon Smirl
@ 2005-03-07 18:05 ` James Simmons
2005-03-07 18:10 ` Jon Smirl
0 siblings, 1 reply; 17+ messages in thread
From: James Simmons @ 2005-03-07 18:05 UTC (permalink / raw)
To: Jon Smirl; +Cc: linux-fbdev-devel, James Simmons
> It is a helper app, not a daemon, it does not stay running. It also
> only runs when the monitor is changed - not mode change, monitor
> changed. On monitor change (loading fbdev counts as a monitor change)
> the helper is called. The helper reads the DDC, parses it, merges in
> any updates from /etc/fb.modes (or builds a modelist from fb.modes if
> no DDC), and then sets this list of legal modes into the driver. After
> the list is set a hal/dbus event is generated. Doing this is a root
> only operation.
>
> It can also happen in early user space when the kernel is first
> booting. Early user space starts before fbcon currently starts. The
> helper app would be loaded on to initrd or initramfs.
The question is will work on systems that have no space to write data.
Alot of embedded devices can store anything. The fb.modes is very limiting
in this case. Having a permanent RAM filesystem is expensive.
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] sysfs support for fbdev
2005-03-07 18:05 ` James Simmons
@ 2005-03-07 18:10 ` Jon Smirl
0 siblings, 0 replies; 17+ messages in thread
From: Jon Smirl @ 2005-03-07 18:10 UTC (permalink / raw)
To: James Simmons; +Cc: linux-fbdev-devel, James Simmons
On Mon, 7 Mar 2005 18:05:35 +0000 (GMT), James Simmons
<jsimmons@www.infradead.org> wrote:
> The question is will work on systems that have no space to write data.
> Alot of embedded devices can store anything. The fb.modes is very limiting
> in this case. Having a permanent RAM filesystem is expensive.
I doubt if a system that constrained needs to change modes at all. In
that case just build the mode into the driver and forget everything
else.
--
Jon Smirl
jonsmirl@gmail.com
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2005-03-07 18:10 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-01 10:00 [PATCH] sysfs support for fbdev Jon Smirl
2005-03-01 21:11 ` James Simmons
2005-03-02 18:13 ` Jon Smirl
2005-03-03 0:12 ` James Simmons
2005-03-03 0:57 ` Jon Smirl
2005-03-07 18:05 ` James Simmons
2005-03-07 18:10 ` Jon Smirl
2005-03-04 4:08 ` Jon Smirl
2005-03-04 18:26 ` James Simmons
2005-03-04 18:48 ` Jon Smirl
2005-03-04 18:50 ` Sylvain Meyer
2005-03-04 19:48 ` Buttchereit, Axel (XL)
2005-03-04 18:43 ` Sylvain Meyer
2005-03-04 18:50 ` Jon Smirl
2005-03-04 18:54 ` Sylvain Meyer
2005-03-01 23:49 ` Benjamin Herrenschmidt
2005-03-02 1:05 ` James Simmons
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).