From 82e8b54229fb121946151b82e8ff3c3284bd723f Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 19 Jun 2009 10:50:54 +0200 Subject: backlight: fix pwm_bl.c to notify platform code when suspending When suspending, pwm-bl sets duty cycle to 0, and shuts down the pwm device. This patch ensure that the platform code is called before that (through the notify callback_, leaving a chance for the platform code to configure GPIOs (shutting off the backlight, for example), much like it is done during normal operations. Signed-off-by: Marc Zyngier Signed-off-by: Eric Miao --- drivers/video/backlight/pwm_bl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index e641584e212..88716626744 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -145,6 +145,8 @@ static int pwm_backlight_suspend(struct platform_device *pdev, struct backlight_device *bl = platform_get_drvdata(pdev); struct pwm_bl_data *pb = dev_get_drvdata(&bl->dev); + if (pb->notify) + pb->notify(0); pwm_config(pb->pwm, 0, pb->period); pwm_disable(pb->pwm); return 0; -- cgit v1.2.3 From 405f55712dfe464b3240d7816cc4fe4174831be2 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 11 Jul 2009 22:08:37 +0400 Subject: headers: smp_lock.h redux * Remove smp_lock.h from files which don't need it (including some headers!) * Add smp_lock.h to files which do need it * Make smp_lock.h include conditional in hardirq.h It's needed only for one kernel_locked() usage which is under CONFIG_PREEMPT This will make hardirq.h inclusion cheaper for every PREEMPT=n config (which includes allmodconfig/allyesconfig, BTW) Signed-off-by: Alexey Dobriyan Signed-off-by: Linus Torvalds --- drivers/video/fbmem.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 53ea05645ff..a85c818be94 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From 5e9a8bd65761bf0c1ee26d8514ef3e9ff22ee465 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 23 Jun 2009 08:31:46 -0700 Subject: omap: video: remove direct access of driver_data dev_set/get_drvdata() should be used instead, as driver_data is going away. Cc: Imre Deak Cc: Russell King Cc: Andrew Morton Acked-by: Trilok Soni Cc: Tony Lindgren Cc: Felipe Contreras Signed-off-by: Greg Kroah-Hartman --- drivers/video/omap/omapfb_main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 4ea99bfc37b..8862233d57b 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -1254,7 +1254,7 @@ static struct fb_ops omapfb_ops = { static ssize_t omapfb_show_caps_num(struct device *dev, struct device_attribute *attr, char *buf) { - struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; + struct omapfb_device *fbdev = dev_get_drvdata(dev); int plane; size_t size; struct omapfb_caps caps; @@ -1274,7 +1274,7 @@ static ssize_t omapfb_show_caps_num(struct device *dev, static ssize_t omapfb_show_caps_text(struct device *dev, struct device_attribute *attr, char *buf) { - struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; + struct omapfb_device *fbdev = dev_get_drvdata(dev); int i; struct omapfb_caps caps; int plane; @@ -1321,7 +1321,7 @@ static DEVICE_ATTR(caps_text, 0444, omapfb_show_caps_text, NULL); static ssize_t omapfb_show_panel_name(struct device *dev, struct device_attribute *attr, char *buf) { - struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; + struct omapfb_device *fbdev = dev_get_drvdata(dev); return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->panel->name); } @@ -1330,7 +1330,7 @@ static ssize_t omapfb_show_bklight_level(struct device *dev, struct device_attribute *attr, char *buf) { - struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; + struct omapfb_device *fbdev = dev_get_drvdata(dev); int r; if (fbdev->panel->get_bklight_level) { @@ -1345,7 +1345,7 @@ static ssize_t omapfb_store_bklight_level(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { - struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; + struct omapfb_device *fbdev = dev_get_drvdata(dev); int r; if (fbdev->panel->set_bklight_level) { @@ -1364,7 +1364,7 @@ static ssize_t omapfb_store_bklight_level(struct device *dev, static ssize_t omapfb_show_bklight_max(struct device *dev, struct device_attribute *attr, char *buf) { - struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; + struct omapfb_device *fbdev = dev_get_drvdata(dev); int r; if (fbdev->panel->get_bklight_level) { @@ -1397,7 +1397,7 @@ static struct attribute_group panel_attr_grp = { static ssize_t omapfb_show_ctrl_name(struct device *dev, struct device_attribute *attr, char *buf) { - struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; + struct omapfb_device *fbdev = dev_get_drvdata(dev); return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name); } -- cgit v1.2.3 From ba0ab82358a12e7a7f2872d6b65c437157c6888f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 3 Jul 2009 11:24:46 -0700 Subject: fb/intelfb: conflict with DRM_I915 and hide by default Users get confused by this driver. It's really a special purpose embedded driver, and causes a lot of problems if enabled. So hide it under EMBEDDED by default, and make sure it doesn't get enabled with the i915 DRM driver. Dave, I'm hoping you can feed this to Linus through your tree. It's appropriate for 2.6.31 I think. Signed-off-by: Jesse Barnes Signed-off-by: Dave Airlie --- drivers/video/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 8afcf08eba9..3b54b394017 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1119,12 +1119,13 @@ config FB_CARILLO_RANCH config FB_INTEL tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support (EXPERIMENTAL)" - depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL + depends on EXPERIMENTAL && FB && PCI && X86 && AGP_INTEL && EMBEDDED select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_BOOT_VESA_SUPPORT if FB_INTEL = y + depends on !DRM_I915 help This driver supports the on-board graphics built in to the Intel 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. -- cgit v1.2.3 From 3730793d457fed79a6d49bae72996d458c8e4f2d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 22 Jul 2009 08:49:22 -0700 Subject: fbmon: work around compiler bug in gcc-2.4.2 There's some odd bug in gcc-4.2 where it miscompiles a simple loop whent he loop counter is of type 'unsigned char' and it should count to 128. The compiler will incorrectly decide that a trivial loop like this: unsigned char i, ... for (i = 0; i < 128; i++) { .. is endless, and will compile it to a single instruction that just branches to itself. This was triggered by the addition of '-fno-strict-overflow', and we could play games with compiler versions and go back to '-fwrapv' instead, but the trivial way to avoid it is to just make the loop induction variable be an 'int' instead. Thanks to Krzysztof Oledzki for reporting and testing and to Troy Moure for digging through assembler differences and finding it. Reported-and-tested-by: Krzysztof Oledzki Found-by: Troy Moure Gcc-bug-acked-by: Ian Lance Taylor Cc: stable@kernel.org Signed-off-by: Linus Torvalds --- drivers/video/fbmon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 5c1a2c01778..9ae9cd32bd0 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -256,8 +256,8 @@ static void fix_edid(unsigned char *edid, int fix) static int edid_checksum(unsigned char *edid) { - unsigned char i, csum = 0, all_null = 0; - int err = 0, fix = check_edid(edid); + unsigned char csum = 0, all_null = 0; + int i, err = 0, fix = check_edid(edid); if (fix) fix_edid(edid, fix); -- cgit v1.2.3 From c42b110caeb128819104d057acdaa1ae564b7c8d Mon Sep 17 00:00:00 2001 From: Pawel Osciak Date: Wed, 29 Jul 2009 15:02:10 -0700 Subject: s3c-fb: fix off-by-one bug in loop indexes Fixed off-by-one bug in loop indexes - some elements beyond windows' array were accessed, which might result in memory access violations when removing/suspending the device. Signed-off-by: Pawel Osciak Reviewed-by: Kyungmin Park Signed-off-by: Marek Szyprowski Cc: Krzysztof Helt Cc: Ben Dooks Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/s3c-fb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index bb63c07e13d..5a72083dc67 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -964,7 +964,7 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) struct s3c_fb *sfb = platform_get_drvdata(pdev); int win; - for (win = 0; win <= S3C_FB_MAX_WIN; win++) + for (win = 0; win < S3C_FB_MAX_WIN; win++) if (sfb->windows[win]) s3c_fb_release_win(sfb, sfb->windows[win]); @@ -988,7 +988,7 @@ static int s3c_fb_suspend(struct platform_device *pdev, pm_message_t state) struct s3c_fb_win *win; int win_no; - for (win_no = S3C_FB_MAX_WIN; win_no >= 0; win_no--) { + for (win_no = S3C_FB_MAX_WIN - 1; win_no >= 0; win_no--) { win = sfb->windows[win_no]; if (!win) continue; -- cgit v1.2.3 From b317c833211b7fbf902163de766f09554090e0bf Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Wed, 29 Jul 2009 15:04:03 -0700 Subject: drivers/video/backlight/jornada720_bl.c: fix build Signed-off-by: Kristoffer Ericson Cc: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/backlight/jornada720_bl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c index c3ebb6b41ce..7aed2565c1b 100644 --- a/drivers/video/backlight/jornada720_bl.c +++ b/drivers/video/backlight/jornada720_bl.c @@ -72,7 +72,7 @@ static int jornada_bl_update_status(struct backlight_device *bd) if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) { printk(KERN_INFO "bl : failed to set brightness\n"); ret = -ETIMEDOUT; - goto out + goto out; } /* at this point we expect that the mcu has accepted -- cgit v1.2.3 From f497d0153a6b53b4cfd004de5f10b14bf630d852 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 18 Mar 2009 11:29:31 +0100 Subject: imxfb: calculate bpix value from bits_per_pixel Signed-off-by: Sascha Hauer --- drivers/video/imxfb.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 15a0ee6d8e2..a8c41cb60ff 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -33,6 +33,7 @@ #include #include +#include /* * Complain if VAR is out of range. @@ -530,8 +531,24 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf lcd_clk / pcr); } + switch (var->bits_per_pixel) { + case 32: + pcr |= PCR_BPIX_18; + break; + case 16: + default: + if (cpu_is_mx1()) + pcr |= PCR_BPIX_12; + else + pcr |= PCR_BPIX_16; + break; + case 8: + pcr |= PCR_BPIX_8; + break; + } + /* add sync polarities */ - pcr |= fbi->pcr & ~0x3F; + pcr |= fbi->pcr & ~(0x3f | (7 << 25)); writel(pcr, fbi->regs + LCDC_PCR); writel(fbi->pwmr, fbi->regs + LCDC_PWMR); -- cgit v1.2.3 From d6b515028863a912d051d371b6d71e09f2a9ff19 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 29 Jun 2009 11:41:09 +0200 Subject: imxfb: use resource_size() macro This fixes an off-by-one error. Also, use dev_err instead of printk in probe() function. Signed-off-by: Sascha Hauer --- drivers/video/imxfb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index a8c41cb60ff..330857a8b31 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -661,7 +661,7 @@ static int __init imxfb_probe(struct platform_device *pdev) struct resource *res; int ret; - printk("i.MX Framebuffer driver\n"); + dev_info(&pdev->dev, "i.MX Framebuffer driver\n"); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) @@ -701,7 +701,7 @@ static int __init imxfb_probe(struct platform_device *pdev) fbi->regs = ioremap(res->start, resource_size(res)); if (fbi->regs == NULL) { - printk(KERN_ERR"Cannot map frame buffer registers\n"); + dev_err(&pdev->dev, "Cannot map frame buffer registers\n"); goto failed_ioremap; } @@ -771,7 +771,7 @@ failed_map: failed_getclock: iounmap(fbi->regs); failed_ioremap: - release_mem_region(res->start, res->end - res->start); + release_mem_region(res->start, resource_size(res)); failed_req: kfree(info->pseudo_palette); failed_init: @@ -802,7 +802,7 @@ static int __devexit imxfb_remove(struct platform_device *pdev) framebuffer_release(info); iounmap(fbi->regs); - release_mem_region(res->start, res->end - res->start + 1); + release_mem_region(res->start, resource_size(res)); clk_disable(fbi->clk); clk_put(fbi->clk); -- cgit v1.2.3 From 343684ffb793a3c371579b7bbc16724713ee5ac7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 19 Mar 2009 08:25:41 +0100 Subject: imxfb: Add support for multiple displays Signed-off-by: Sascha Hauer --- drivers/video/imxfb.c | 191 +++++++++++++++++++++++++++++++------------------- 1 file changed, 120 insertions(+), 71 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 330857a8b31..30ae3022f63 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -130,6 +130,10 @@ #define LCDISR_EOF (1<<1) #define LCDISR_BOF (1<<0) +/* Used fb-mode. Can be set on kernel command line, therefore file-static. */ +static const char *fb_mode; + + /* * These are the bitfields for each * display depth that we support. @@ -146,10 +150,6 @@ struct imxfb_info { void __iomem *regs; struct clk *clk; - u_int max_bpp; - u_int max_xres; - u_int max_yres; - /* * These are the addresses we mapped * the framebuffer memory region to. @@ -173,6 +173,9 @@ struct imxfb_info { cmap_static:1, unused:30; + struct imx_fb_videomode *mode; + int num_modes; + void (*lcd_power)(int); void (*backlight_power)(int); }; @@ -299,6 +302,18 @@ static int imxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, return ret; } +static const struct imx_fb_videomode *imxfb_find_mode(struct imxfb_info *fbi) +{ + struct imx_fb_videomode *m; + int i; + + for (i = 0, m = &fbi->mode[0]; i < fbi->num_modes; i++, m++) { + if (!strcmp(m->mode.name, fb_mode)) + return m; + } + return NULL; +} + /* * imxfb_check_var(): * Round up in the following order: bits_per_pixel, xres, @@ -309,35 +324,81 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct imxfb_info *fbi = info->par; struct imxfb_rgb *rgb; + const struct imx_fb_videomode *imxfb_mode; + unsigned long lcd_clk; + unsigned long long tmp; + u32 pcr = 0; if (var->xres < MIN_XRES) var->xres = MIN_XRES; if (var->yres < MIN_YRES) var->yres = MIN_YRES; - if (var->xres > fbi->max_xres) - var->xres = fbi->max_xres; - if (var->yres > fbi->max_yres) - var->yres = fbi->max_yres; - var->xres_virtual = max(var->xres_virtual, var->xres); - var->yres_virtual = max(var->yres_virtual, var->yres); + + imxfb_mode = imxfb_find_mode(fbi); + if (!imxfb_mode) + return -EINVAL; + + var->xres = imxfb_mode->mode.xres; + var->yres = imxfb_mode->mode.yres; + var->bits_per_pixel = imxfb_mode->bpp; + var->pixclock = imxfb_mode->mode.pixclock; + var->hsync_len = imxfb_mode->mode.hsync_len; + var->left_margin = imxfb_mode->mode.left_margin; + var->right_margin = imxfb_mode->mode.right_margin; + var->vsync_len = imxfb_mode->mode.vsync_len; + var->upper_margin = imxfb_mode->mode.upper_margin; + var->lower_margin = imxfb_mode->mode.lower_margin; + var->sync = imxfb_mode->mode.sync; + var->xres_virtual = max(var->xres_virtual, var->xres); + var->yres_virtual = max(var->yres_virtual, var->yres); pr_debug("var->bits_per_pixel=%d\n", var->bits_per_pixel); + + lcd_clk = clk_get_rate(fbi->clk); + + tmp = var->pixclock * (unsigned long long)lcd_clk; + + do_div(tmp, 1000000); + + if (do_div(tmp, 1000000) > 500000) + tmp++; + + pcr = (unsigned int)tmp; + + if (--pcr > 0x3F) { + pcr = 0x3F; + printk(KERN_WARNING "Must limit pixel clock to %luHz\n", + lcd_clk / pcr); + } + switch (var->bits_per_pixel) { case 32: + pcr |= PCR_BPIX_18; rgb = &def_rgb_18; break; case 16: default: - if (fbi->pcr & PCR_TFT) + if (cpu_is_mx1()) + pcr |= PCR_BPIX_12; + else + pcr |= PCR_BPIX_16; + + if (imxfb_mode->pcr & PCR_TFT) rgb = &def_rgb_16_tft; else rgb = &def_rgb_16_stn; break; case 8: + pcr |= PCR_BPIX_8; rgb = &def_rgb_8; break; } + /* add sync polarities */ + pcr |= imxfb_mode->pcr & ~(0x3f | (7 << 25)); + + fbi->pcr = pcr; + /* * Copy the RGB parameters for this display * from the machine specific parameters. @@ -394,10 +455,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi) writel(fbi->screen_dma, fbi->regs + LCDC_SSA); - /* physical screen start address */ - writel(VPW_VPW(fbi->max_xres * fbi->max_bpp / 8 / 4), - fbi->regs + LCDC_VPW); - /* panning offset 0 (0 pixel offset) */ writel(0x00000000, fbi->regs + LCDC_POS); @@ -469,8 +526,6 @@ static struct fb_ops imxfb_ops = { static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct imxfb_info *fbi = info->par; - unsigned int pcr, lcd_clk; - unsigned long long tmp; pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", var->xres, var->hsync_len, @@ -506,6 +561,10 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf info->fix.id, var->lower_margin); #endif + /* physical screen start address */ + writel(VPW_VPW(var->xres * var->bits_per_pixel / 8 / 4), + fbi->regs + LCDC_VPW); + writel(HCR_H_WIDTH(var->hsync_len - 1) | HCR_H_WAIT_1(var->right_margin - 1) | HCR_H_WAIT_2(var->left_margin - 3), @@ -519,38 +578,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres), fbi->regs + LCDC_SIZE); - lcd_clk = clk_get_rate(fbi->clk); - tmp = var->pixclock * (unsigned long long)lcd_clk; - do_div(tmp, 1000000); - if (do_div(tmp, 1000000) > 500000) - tmp++; - pcr = (unsigned int)tmp; - if (--pcr > 0x3F) { - pcr = 0x3F; - printk(KERN_WARNING "Must limit pixel clock to %uHz\n", - lcd_clk / pcr); - } - - switch (var->bits_per_pixel) { - case 32: - pcr |= PCR_BPIX_18; - break; - case 16: - default: - if (cpu_is_mx1()) - pcr |= PCR_BPIX_12; - else - pcr |= PCR_BPIX_16; - break; - case 8: - pcr |= PCR_BPIX_8; - break; - } - - /* add sync polarities */ - pcr |= fbi->pcr & ~(0x3f | (7 << 25)); - - writel(pcr, fbi->regs + LCDC_PCR); + writel(fbi->pcr, fbi->regs + LCDC_PCR); writel(fbi->pwmr, fbi->regs + LCDC_PWMR); writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); writel(fbi->dmacr, fbi->regs + LCDC_DMACR); @@ -592,6 +620,8 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev) struct imx_fb_platform_data *pdata = pdev->dev.platform_data; struct fb_info *info = dev_get_drvdata(&pdev->dev); struct imxfb_info *fbi = info->par; + struct imx_fb_videomode *m; + int i; pr_debug("%s\n",__func__); @@ -620,35 +650,18 @@ static int __init imxfb_init_fbinfo(struct platform_device *pdev) info->fbops = &imxfb_ops; info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST; - - fbi->max_xres = pdata->xres; - info->var.xres = pdata->xres; - info->var.xres_virtual = pdata->xres; - fbi->max_yres = pdata->yres; - info->var.yres = pdata->yres; - info->var.yres_virtual = pdata->yres; - fbi->max_bpp = pdata->bpp; - info->var.bits_per_pixel = pdata->bpp; - info->var.nonstd = pdata->nonstd; - info->var.pixclock = pdata->pixclock; - info->var.hsync_len = pdata->hsync_len; - info->var.left_margin = pdata->left_margin; - info->var.right_margin = pdata->right_margin; - info->var.vsync_len = pdata->vsync_len; - info->var.upper_margin = pdata->upper_margin; - info->var.lower_margin = pdata->lower_margin; - info->var.sync = pdata->sync; info->var.grayscale = pdata->cmap_greyscale; fbi->cmap_inverse = pdata->cmap_inverse; fbi->cmap_static = pdata->cmap_static; - fbi->pcr = pdata->pcr; fbi->lscr1 = pdata->lscr1; fbi->dmacr = pdata->dmacr; fbi->pwmr = pdata->pwmr; fbi->lcd_power = pdata->lcd_power; fbi->backlight_power = pdata->backlight_power; - info->fix.smem_len = fbi->max_xres * fbi->max_yres * - fbi->max_bpp / 8; + + for (i = 0, m = &pdata->mode[0]; i < pdata->num_modes; i++, m++) + info->fix.smem_len = max_t(size_t, info->fix.smem_len, + m->mode.xres * m->mode.yres * m->bpp / 8); return 0; } @@ -659,7 +672,7 @@ static int __init imxfb_probe(struct platform_device *pdev) struct fb_info *info; struct imx_fb_platform_data *pdata; struct resource *res; - int ret; + int ret, i; dev_info(&pdev->dev, "i.MX Framebuffer driver\n"); @@ -679,6 +692,9 @@ static int __init imxfb_probe(struct platform_device *pdev) fbi = info->par; + if (!fb_mode) + fb_mode = pdata->mode[0].mode.name; + platform_set_drvdata(pdev, info); ret = imxfb_init_fbinfo(pdev); @@ -736,6 +752,13 @@ static int __init imxfb_probe(struct platform_device *pdev) goto failed_platform_init; } + fbi->mode = pdata->mode; + fbi->num_modes = pdata->num_modes; + + INIT_LIST_HEAD(&info->modelist); + for (i = 0; i < pdata->num_modes; i++) + fb_add_videomode(&pdata->mode[i].mode, &info->modelist); + /* * This makes sure that our colour bitfield * descriptors are correctly initialised. @@ -828,8 +851,34 @@ static struct platform_driver imxfb_driver = { }, }; +static int imxfb_setup(void) +{ +#ifndef MODULE + char *opt, *options = NULL; + + if (fb_get_options("imxfb", &options)) + return -ENODEV; + + if (!options || !*options) + return 0; + + while ((opt = strsep(&options, ",")) != NULL) { + if (!*opt) + continue; + else + fb_mode = opt; + } +#endif + return 0; +} + int __init imxfb_init(void) { + int ret = imxfb_setup(); + + if (ret < 0) + return ret; + return platform_driver_probe(&imxfb_driver, imxfb_probe); } -- cgit v1.2.3