Re: Boot Console on LCD (fbcon) second try...

From: Pattrick Hueper <pattyh_at_gmx.net>
Date: Mon, 01 Mar 2004 10:33:59 +0100

Hi,

i cvs updated and saw, that in fbcon.c there now is a event_notify
chain, i will try to adapt my changes to use the (newly) existing notify
chain in fbmem/fbcon and then resend the patch.

Cheers, Patty

Pattrick Hueper wrote:
> Hi,
>
> the last days i learned a lot about the kernel, trying to understand the
> initialization of drivers, devices, ... anyway, i tried to follow Andrews
> recommendation to use notifiers for fbcon initialization for LCD.
>
> Here is what i came up with, it's a larger patch, i hope its ok to send the
> patch as text in the mail, i dont know how to do it otherwise...
>
> Here are my thoughts:
>
> - i added fb_notify_chain in fbmem.c and fb.h to call when a new framebuffer
> is registered.
> - fb_console_init registers in the fb_notify_chain, if no framebuffers have
> registered before, and it is not already registered in the notify_chain
> - the notify_chain calls fbcon_notify and that in turn unregisters from the
> notify_chain and calls take_over_console...
> - another thing i found in my search is that fbmem.c calls all other
> framebuffers inits methods (e.g. pxafb), so i added mq1100fb... i dont think
> that is necessary, but since the other framebuffers are listed there, too...
> - since mq1100fb_init may be called multiple times, then i had to protect it
> too, using the driver_registered variable, otherwise the kernel hangs, i
> think thats a problem of the notify chains, it the same function is added
> twice to the notify_chain, it will "loop" endlessly... thats the reason for
> "protecting" mq1100fb_init() and fb_console_init() from registering twice. I
> dont know if the method using a static int is very elegant, but didnt find a
> method to check the notify chain for the same function.
>
> Anyway, i uploaded my zImage, initrd, .config and other files to
> http://patty-server.homeip.net/h2200-port/feb27 if anyone wants to try it...
>
> Davide, maybe this will help you try to figure out, why your ir console does
> not come up?
>
> And i am happy about any suggestions or comments from the more experienced
> kernel developers!
>
> Cheers, Patty
>
> Here come the diff(s):
>
> Index: arch/arm/mach-pxa/h2200_lcd.c
> ===================================================================
> RCS file: /cvs/linux/kernel26/arch/arm/mach-pxa/h2200_lcd.c,v
> retrieving revision 1.2
> diff -u -b -r1.2 h2200_lcd.c
> --- arch/arm/mach-pxa/h2200_lcd.c 22 Feb 2004 15:52:53 -0000 1.2
> +++ arch/arm/mach-pxa/h2200_lcd.c 27 Feb 2004 19:50:41 -0000
> @@ -309,7 +309,6 @@
> {
> debug_func ("\n");
> return soc_driver_register (&h2200_fp_soc_device_driver);
> - return 0;
> }
>
> static void __exit
> Index: drivers/video/fbmem.c
> ===================================================================
> RCS file: /cvs/linux/kernel26/drivers/video/fbmem.c,v
> retrieving revision 1.11
> diff -u -b -r1.11 fbmem.c
> --- drivers/video/fbmem.c 25 Nov 2003 17:29:58 -0000 1.11
> +++ drivers/video/fbmem.c 27 Feb 2004 19:51:07 -0000
> @@ -164,6 +164,7 @@
> extern int tcx_setup(char*);
> extern int leo_init(void);
> extern int leo_setup(char*);
> +extern int mq1100fb_init(void);
>
> static struct {
> const char *name;
> @@ -377,6 +378,9 @@
> #ifdef CONFIG_FB_VOODOO1
> { "sstfb", sstfb_init, sstfb_setup },
> #endif
> +#ifdef CONFIG_FB_MQ1100
> + { "mq1100fb", mq1100fb_init, NULL },
> +#endif
> /*
> * Generic drivers that don't use resource management (yet)
> */
> @@ -1222,6 +1226,10 @@
> #endif
> };
>
> +/* for notification of newly registered framebuffers*/
> +struct notifier_block *fb_notify_chain;
> +EXPORT_SYMBOL(fb_notify_chain);
> +
> /**
> * register_framebuffer - registers a frame buffer device
> * @fb_info: frame buffer info structure
> @@ -1265,6 +1273,9 @@
>
> devfs_mk_cdev(MKDEV(FB_MAJOR, i),
> S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i);
> +
> + notifier_call_chain (&fb_notify_chain, 0, fb_info);
> +
> return 0;
> }
>
> Index: drivers/video/mq1100fb.c
> ===================================================================
> RCS file: /cvs/linux/kernel26/drivers/video/mq1100fb.c,v
> retrieving revision 1.18
> diff -u -b -r1.18 mq1100fb.c
> --- drivers/video/mq1100fb.c 23 Feb 2004 13:05:46 -0000 1.18
> +++ drivers/video/mq1100fb.c 27 Feb 2004 19:51:08 -0000
> @@ -47,12 +47,10 @@
> /* The name of the LCD module to use */
> const char *lm_name;
> struct lcd_module *lm;
> - union {
> /* The RGB palette */
> struct mq1100fb_rgb palette[256];
> - /* Notifier block (used until init complete) */
> + /* Notifier block */
> struct notifier_block notify;
> - };
> /* The pseudo-palette */
> u32 pseudo_pal[16];
> /* Device instance number (0-7) */
> @@ -427,6 +425,14 @@
> return NOTIFY_DONE;
>
> info->lm = lm;
> +
> + /* if we dont have a backlight module yet, we try to find it once again
> */
> + if (!info->bm) {
> + info->bm =
> backlight_module_get(backlight_module_find(info->bm_name));
> + }
> +
> +
> +
> mq1100fb_power (info, 1);
> if (!info->active)
> return NOTIFY_DONE;
> @@ -437,7 +443,6 @@
> return NOTIFY_OK;
> }
>
> -
> static int mq1100fb_probe (struct device *dev, struct mediaq11xx_base *base)
> {
> struct mq1100fb_info *info;
> @@ -476,7 +481,6 @@
> /* Defer complete initialization if no LCD module */
> if (!info->active)
> {
> - /* Temporary use palette storage for notifier block */
> info->notify.notifier_call = mq1100fb_lcd_notify;
> info->notify.next = NULL;
> info->notify.priority = 0;
> @@ -496,10 +500,10 @@
>
> static void mq1100fb_soc_shutdown (struct device *dev)
> {
> + debug_func ("\n");
> struct mq1100fb_info *info =
> (struct mq1100fb_info *)dev_get_drvdata (dev);
>
> - debug_func ("\n");
>
> if (!info->initcomplete)
> notifier_chain_unregister (&lcd_module_chain, &info->notify);
> @@ -515,11 +519,10 @@
>
> static int mq1100fb_soc_suspend (struct device *dev, u32 state, u32 level)
> {
> + debug_func ("\n");
> struct mq1100fb_info *info =
> (struct mq1100fb_info *)dev_get_drvdata (dev);
>
> - debug_func ("\n");
> -
> mq1100fb_power (info, 0);
>
> return 0;
> @@ -527,11 +530,10 @@
>
> static int mq1100fb_soc_resume (struct device *dev, u32 level)
> {
> + debug_func ("\n");
> struct mq1100fb_info *info =
> (struct mq1100fb_info *)dev_get_drvdata (dev);
>
> - debug_func ("\n");
> -
> mq1100fb_power (info, 1);
>
> return 0;
> @@ -551,14 +553,24 @@
> }
> };
>
> -static int __init mq1100fb_init(void)
> +static int driver_registered = 0;
> +
> +int __init mq1100fb_init(void)
> {
> + debug_func("\n");
> + if (!driver_registered)
> + {
> + driver_registered = 1;
> return soc_driver_register (&mq1100fb_soc_device_driver);
> + }
> + return 0;
> }
>
> -static void __exit mq1100fb_exit(void)
> +void __exit mq1100fb_exit(void)
> {
> + debug_func("\n");
> soc_driver_unregister (&mq1100fb_soc_device_driver);
> + driver_registered = 0;
> }
>
> module_init(mq1100fb_init);
> Index: drivers/video/console/fbcon.c
> ===================================================================
> RCS file: /cvs/linux/kernel26/drivers/video/console/fbcon.c,v
> retrieving revision 1.1.1.1
> diff -u -b -r1.1.1.1 fbcon.c
> --- drivers/video/console/fbcon.c 14 Jul 2003 18:57:14 -0000
> 1.1.1.1
> +++ drivers/video/console/fbcon.c 27 Feb 2004 19:51:12 -0000
> @@ -2259,6 +2259,21 @@
> return 0;
> }
>
> +struct notifier_block notify;
> +
> +static int notify_registered = 0;
> +
> +int fbcon_notify (struct notifier_block *self,
> + unsigned long a, void *b)
> +{
> + DPRINTK("\n");
> + notifier_chain_unregister (&fb_notify_chain, self);
> + notify_registered = 0;
> + /* a framebuffer was registered, try to take over the console */
> + take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
> + return NOTIFY_OK;
> +}
> +
> /*
> * The console `switch' structure for the frame buffer based console
> */
> @@ -2287,8 +2302,19 @@
>
> int __init fb_console_init(void)
> {
> + /* Defer take over console, until a framebuffer has registered */
> if (!num_registered_fb)
> + {
> + if (!notify_registered)
> + {
> + notify_registered = 1;
> + notify.notifier_call = fbcon_notify;
> + notify.next = NULL;
> + notify.priority = 0;
> + notifier_chain_register (&fb_notify_chain, &notify);
> + }
> return -ENODEV;
> + }
> take_over_console(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default);
> return 0;
> }
> Index: include/linux/fb.h
> ===================================================================
> RCS file: /cvs/linux/kernel26/include/linux/fb.h,v
> retrieving revision 1.1.1.1
> diff -u -b -r1.1.1.1 fb.h
> --- include/linux/fb.h 14 Jul 2003 18:58:40 -0000 1.1.1.1
> +++ include/linux/fb.h 27 Feb 2004 19:51:28 -0000
> @@ -3,6 +3,7 @@
>
> #include <linux/tty.h>
> #include <linux/workqueue.h>
> +#include <linux/notifier.h>
> #include <asm/types.h>
> #include <asm/io.h>
>
> @@ -489,6 +490,8 @@
> u32 s_pitch, u32 height);
> extern struct fb_info *registered_fb[FB_MAX];
> extern int num_registered_fb;
> +extern struct notifier_block *fb_notify_chain;
> +
>
> /* drivers/video/fbmon.c */
> #define FB_MAXTIMINGS 0
>
> _______________________________________________
> H2200-port mailing list
> H2200-port_at_handhelds.org
> https://handhelds.org/mailman/listinfo/h2200-port
>
>
Received on Mon Mar 01 2004 - 09:34:04 EST

This archive was generated by hypermail 2.2.0 : Mon Jul 25 2005 - 17:19:25 EDT