* Re: [PATCH] efifb: Fix call to wrong unregister function
From: Maarten Lankhorst @ 2011-06-13 7:51 UTC (permalink / raw)
To: Andy Lutomirski; +Cc: wanlong.gao, linux-kernel, linux-fbdev, Peter Jones
In-Reply-To: <4DF57C29.4070601@mit.edu>
Hi Andy,
2011/6/13 Andy Lutomirski <luto@mit.edu>:
> On 06/12/2011 06:52 AM, wanlong.gao wrote:
>>
>> <snip>
>>
>> Hi Maarten:
>> It registered efifb_device but try to unregistered efifb_driver,
>> so I think you should fix it like this?
>>
>> Signed-off-by: Wanlong Gao<wanlong.gao@gmail.com>
>> ---
>> drivers/video/efifb.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
>> index 69c49df..784139a 100644
>> --- a/drivers/video/efifb.c
>> +++ b/drivers/video/efifb.c
>> @@ -541,7 +541,7 @@ static int __init efifb_init(void)
>> */
>> ret = platform_driver_probe(&efifb_driver, efifb_probe);
>> if (ret) {
>> - platform_device_unregister(&efifb_driver);
>> + platform_device_unregister(&efifb_device);
>> return ret;
>> }
>>
>
> Acked-by: Andy Lutomirski <luto@mit.edu>
>
> That's my bug. Sorry. I'm not sure why it compiled, though.
It compiled, but threw a warning. :)
~Maarten
^ permalink raw reply
* Re: [PATCH] fb.h: ARM uses __raw_{read/write}
From: Paul Mundt @ 2011-06-13 4:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201106101731.08578.hartleys@visionengravers.com>
On Fri, Jun 10, 2011 at 05:31:08PM -0700, H Hartley Sweeten wrote:
> ARM provides __raw_{read/write}* functions for memory access. These
> should be used instead of the default '(*(volatile' stuff to make sure the
> memory accesses are typesafe (void __iomem *).
>
> This also fixes a number of sparse warning like:
>
> warning: cast removes address space of expression
>
> Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
> Cc: Paul Mundt <lethal@linux-sh.org>
> Cc: Russell King <linux@arm.linux.org.uk>
>
I'm not sure what semantics are desirable for ARM here, so I'll wait for
Russell to reply.
This wrapping will basically mean that the fb_read/write ops are using
__raw_xxx variants while the memset and memcpy wrappers will be using the
regular read/write[bwl] routines which contain __iormb() calls. Given
that ioread/write and friends all wrap in to the normal versions with the
barriers, I would suppose that this is the default behaviour that is
desired, as opposed to wrapping in to the __raw_xxx variants directly.
^ permalink raw reply
* Re: [PATCH] efifb: Fix call to wrong unregister function
From: Andy Lutomirski @ 2011-06-13 2:55 UTC (permalink / raw)
To: wanlong.gao; +Cc: linux-kernel, linux-fbdev, Maarten Lankhorst, Peter Jones
In-Reply-To: <1307875953.1859.6.camel@Tux>
On 06/12/2011 06:52 AM, wanlong.gao wrote:
> <snip>
>
> Hi Maarten:
> It registered efifb_device but try to unregistered efifb_driver,
> so I think you should fix it like this?
>
> Signed-off-by: Wanlong Gao<wanlong.gao@gmail.com>
> ---
> drivers/video/efifb.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
> index 69c49df..784139a 100644
> --- a/drivers/video/efifb.c
> +++ b/drivers/video/efifb.c
> @@ -541,7 +541,7 @@ static int __init efifb_init(void)
> */
> ret = platform_driver_probe(&efifb_driver, efifb_probe);
> if (ret) {
> - platform_device_unregister(&efifb_driver);
> + platform_device_unregister(&efifb_device);
> return ret;
> }
>
Acked-by: Andy Lutomirski <luto@mit.edu>
That's my bug. Sorry. I'm not sure why it compiled, though.
--Andy
^ permalink raw reply
* Re: [PATCH] efifb: Fix call to wrong unregister function
From: Wanlong Gao @ 2011-06-12 23:36 UTC (permalink / raw)
To: Maarten Lankhorst; +Cc: linux-kernel, linux-fbdev, Peter Jones
In-Reply-To: <BANLkTimXALxHwNMSODXujT4pT-C+m3rcaQ@mail.gmail.com>
On æ—¥, 2011-06-12 at 19:48 +0200, Maarten Lankhorst wrote:
> Hey,
>
> 2011/6/12 wanlong.gao <wanlong.gao@gmail.com>:
> > <snip>
> >
> > Hi Maarten:
> > It registered efifb_device but try to unregistered efifb_driver,
> > so I think you should fix it like this?
> Ah yes, that seems to be the correct one, platform_driver_register was
> removed. Not 100% sure if acked by or signed-off-by is appropriate
> here.
I think signed-off-by is OK.
>
> Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com>
>
> ~Maarten
^ permalink raw reply
* Re: [PATCH] efifb: Fix call to wrong unregister function
From: Maarten Lankhorst @ 2011-06-12 17:48 UTC (permalink / raw)
To: wanlong.gao; +Cc: linux-kernel, linux-fbdev, Peter Jones
In-Reply-To: <1307875953.1859.6.camel@Tux>
Hey,
2011/6/12 wanlong.gao <wanlong.gao@gmail.com>:
> <snip>
>
> Hi Maarten:
> It registered efifb_device but try to unregistered efifb_driver,
> so I think you should fix it like this?
Ah yes, that seems to be the correct one, platform_driver_register was
removed. Not 100% sure if acked by or signed-off-by is appropriate
here.
Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com>
~Maarten
^ permalink raw reply
* [PATCH] au1200fb: fix hardcoded IRQ
From: Manuel Lauss @ 2011-06-12 17:15 UTC (permalink / raw)
To: linux-fbdev
Use the IRQ provided by platform resource information.
Required for Au1300 support.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
---
applies on top of the other 3 au1200fb patches sent earlier.
drivers/video/au1200fb.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index e018373..e6d3478 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1631,7 +1631,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
struct au1200fb_device *fbdev;
struct fb_info *fbi = NULL;
unsigned long page;
- int bpp, plane, ret;
+ int bpp, plane, ret, irq;
/* shut gcc up */
ret = 0;
@@ -1707,10 +1707,12 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
}
/* Now hook interrupt too */
- if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
- IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev)) < 0) {
+ irq = platform_get_irq(dev, 0);
+ ret = request_irq(irq, au1200fb_handle_irq,
+ IRQF_DISABLED | IRQF_SHARED, "lcd", (void *)dev);
+ if (ret) {
print_err("fail to request interrupt line %d (err: %d)",
- AU1200_LCD_INT, ret);
+ irq, ret);
goto failed;
}
@@ -1758,7 +1760,7 @@ static int __devexit au1200fb_drv_remove(struct platform_device *dev)
_au1200fb_infos[plane] = NULL;
}
- free_irq(AU1200_LCD_INT, (void *)dev);
+ free_irq(platform_get_irq(dev, 0), (void *)dev);
return 0;
}
--
1.7.5.3
^ permalink raw reply related
* re:[PATCH] efifb: Fix call to wrong unregister function
From: wanlong.gao @ 2011-06-12 10:52 UTC (permalink / raw)
To: linux-kernel, linux-fbdev; +Cc: Maarten Lankhorst
In-Reply-To: <1307868301-1773-1-git-send-email-m.b.lankhorst@gmail.com>
<snip>
Hi Maarten:
It registered efifb_device but try to unregistered efifb_driver,
so I think you should fix it like this?
Signed-off-by: Wanlong Gao <wanlong.gao@gmail.com>
---
drivers/video/efifb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 69c49df..784139a 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -541,7 +541,7 @@ static int __init efifb_init(void)
*/
ret = platform_driver_probe(&efifb_driver, efifb_probe);
if (ret) {
- platform_device_unregister(&efifb_driver);
+ platform_device_unregister(&efifb_device);
return ret;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH] efifb: Fix call to wrong unregister function
From: Maarten Lankhorst @ 2011-06-12 8:45 UTC (permalink / raw)
To: Peter Jones; +Cc: linux-fbdev, linux-kernel, Maarten Lankhorst
Seems like driver_unregister must be called instead of device_unregister.
Signed-off-by: Maarten Lankhorst <m.b.lankhorst@gmail.com>
---
drivers/video/efifb.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 69c49df..d8717a6 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -541,7 +541,7 @@ static int __init efifb_init(void)
*/
ret = platform_driver_probe(&efifb_driver, efifb_probe);
if (ret) {
- platform_device_unregister(&efifb_driver);
+ platform_driver_unregister(&efifb_driver);
return ret;
}
--
1.7.4.1
^ permalink raw reply related
* [PATCH] fb.h: ARM uses __raw_{read/write}
From: H Hartley Sweeten @ 2011-06-11 0:31 UTC (permalink / raw)
To: linux-arm-kernel
ARM provides __raw_{read/write}* functions for memory access. These
should be used instead of the default '(*(volatile' stuff to make sure the
memory accesses are typesafe (void __iomem *).
This also fixes a number of sparse warning like:
warning: cast removes address space of expression
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Russell King <linux@arm.linux.org.uk>
---
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 6a82748..a040e92e 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -937,7 +937,7 @@ static inline struct apertures_struct *alloc_apertures(unsigned int max_num) {
#define fb_memcpy_fromfb sbus_memcpy_fromio
#define fb_memcpy_tofb sbus_memcpy_toio
-#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__)
+#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) || defined(__arm__)
#define fb_readb __raw_readb
#define fb_readw __raw_readw
^ permalink raw reply related
* Re: [PATCH 15/29] mx3fb: use display information in info not in var for panning
From: Laurent Pinchart @ 2011-06-10 17:01 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1306364301-8195-16-git-send-email-laurent.pinchart@ideasonboard.com>
Hi Guennadi,
On Friday 10 June 2011 11:01:46 Guennadi Liakhovetski wrote:
> On Thu, 26 May 2011, Laurent Pinchart wrote:
> > We must not use any information in the passed var besides xoffset,
> > yoffset and vmode as otherwise applications might abuse it. Also use the
> > aligned fix.line_length and not the (possible) unaligned xres_virtual.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > ---
> >
> > drivers/video/mx3fb.c | 6 +++---
> > 1 files changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
> > index 7e3a490..759e244 100644
> > --- a/drivers/video/mx3fb.c
> > +++ b/drivers/video/mx3fb.c
> > @@ -1062,15 +1062,15 @@ static int mx3fb_pan_display(struct
> > fb_var_screeninfo *var,
> >
> > y_bottom = var->yoffset;
> >
> > if (!(var->vmode & FB_VMODE_YWRAP))
> >
> > - y_bottom += var->yres;
> > + y_bottom += fbi->var.yres;
> >
> > if (y_bottom > fbi->var.yres_virtual)
> >
> > return -EINVAL;
> >
> > mutex_lock(&mx3_fbi->mutex);
> >
> > - offset = (var->yoffset * var->xres_virtual + var->xoffset) *
> > - (var->bits_per_pixel / 8);
> > + offset = var->yoffset * fbi->fix.line_length
> > + + var->xoffset * (var->bits_per_pixel / 8);
>
> Didn't you mean
>
> + + var->xoffset * (fbi->var.bits_per_pixel / 8);
Yes, my bad. Thank you.
> With this fix:
>
> Tested-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
>
> (tested using http://git.ideasonboard.org/?pûdev-test.git;a=summary)
Thanks.
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH 4/4] au1200fb: switch to FB_SYS helpers
From: Manuel Lauss @ 2011-06-10 15:23 UTC (permalink / raw)
To: linux-fbdev
Since all video memory is in system ram, use FB_SYS helpers.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
---
drivers/video/Kconfig | 7 ++++---
drivers/video/au1200fb.c | 8 +++++---
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 549b960..5e19de9 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1756,9 +1756,10 @@ config FB_AU1100
config FB_AU1200
bool "Au1200 LCD Driver"
depends on (FB = y) && MIPS && SOC_AU1200
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
help
This is the framebuffer driver for the AMD Au1200 SOC. It can drive
various panels and CRTs by passing in kernel cmd line option
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 4b58f7b..b1b16d9 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1502,9 +1502,11 @@ static struct fb_ops au1200fb_fb_ops = {
.fb_set_par = au1200fb_fb_set_par,
.fb_setcolreg = au1200fb_fb_setcolreg,
.fb_blank = au1200fb_fb_blank,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
+ .fb_fillrect = sys_fillrect,
+ .fb_copyarea = sys_copyarea,
+ .fb_imageblit = sys_imageblit,
+ .fb_read = fb_sys_read,
+ .fb_write = fb_sys_write,
.fb_sync = NULL,
.fb_ioctl = au1200fb_ioctl,
.fb_mmap = au1200fb_fb_mmap,
--
1.7.5.3
^ permalink raw reply related
* [PATCH 3/4] au1200fb: make number of windows configurable at load time.
From: Manuel Lauss @ 2011-06-10 15:23 UTC (permalink / raw)
To: linux-fbdev
Make the number of framebuffer windows and the window configuration
selectable at the kernel commandline instead of hardcoding it
in the kernel config.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
---
drivers/video/au1200fb.c | 53 +++++++++++++++++++++++++++++++++------------
1 files changed, 39 insertions(+), 14 deletions(-)
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 480ecb1..4b58f7b 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -46,10 +46,6 @@
#include <asm/mach-au1x00/au1000.h>
#include "au1200fb.h"
-#ifndef CONFIG_FB_AU1200_DEVS
-#define CONFIG_FB_AU1200_DEVS 4
-#endif
-
#define DRIVER_NAME "au1200fb"
#define DRIVER_DESC "LCD controller driver for AU1200 processors"
@@ -154,7 +150,6 @@ struct au1200fb_device {
dma_addr_t fb_phys;
};
-static struct fb_info *_au1200fb_infos[CONFIG_FB_AU1200_DEVS];
/********************************************************************/
/* LCD controller restrictions */
@@ -167,10 +162,18 @@ static struct fb_info *_au1200fb_infos[CONFIG_FB_AU1200_DEVS];
/* Default number of visible screen buffer to allocate */
#define AU1200FB_NBR_VIDEO_BUFFERS 1
+/* Default maximum number of fb devices to create */
+#define MAX_DEVICE_COUNT 4
+
+/* Default window configuration entry to use (see windows[]) */
+#define DEFAULT_WINDOW_INDEX 2
+
/********************************************************************/
+static struct fb_info *_au1200fb_infos[MAX_DEVICE_COUNT];
static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
-static int window_index = 2; /* default is zero */
+static int device_count = MAX_DEVICE_COUNT;
+static int window_index = DEFAULT_WINDOW_INDEX; /* default is zero */
static int panel_index = 2; /* default is zero */
static struct window_settings *win;
static struct panel_settings *panel;
@@ -683,7 +686,7 @@ static int fbinfo2index (struct fb_info *fb_info)
{
int i;
- for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
+ for (i = 0; i < device_count; ++i) {
if (fb_info = _au1200fb_infos[i])
return i;
}
@@ -1599,7 +1602,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
/* Kickstart the panel */
au1200_setpanel(panel);
- for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
+ for (plane = 0; plane < device_count; ++plane) {
bpp = winbpp(win->w[plane].mode_winctrl1);
if (win->w[plane].xres = 0)
win->w[plane].xres = panel->Xres;
@@ -1699,7 +1702,7 @@ static int __devexit au1200fb_drv_remove(struct platform_device *dev)
/* Turn off the panel */
au1200_setpanel(NULL);
- for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
+ for (plane = 0; plane < device_count; ++plane) {
fbi = _au1200fb_infos[plane];
fbdev = fbi->par;
@@ -1741,7 +1744,7 @@ static int au1200fb_drv_resume(struct device *dev)
/* Kickstart the panel */
au1200_setpanel(panel);
- for (i = 0; i < CONFIG_FB_AU1200_DEVS; i++) {
+ for (i = 0; i < device_count; i++) {
fbi = _au1200fb_infos[i];
au1200fb_fb_set_par(fbi);
}
@@ -1776,10 +1779,10 @@ static struct platform_driver au1200fb_driver = {
/* Kernel driver */
-static void au1200fb_setup(void)
+static int au1200fb_setup(void)
{
- char* options = NULL;
- char* this_opt;
+ char *options = NULL;
+ char *this_opt, *endptr;
int num_panels = ARRAY_SIZE(known_lcd_panels);
int panel_idx = -1;
@@ -1824,12 +1827,33 @@ static void au1200fb_setup(void)
nohwcursor = 1;
}
+ else if (strncmp(this_opt, "devices:", 8) = 0) {
+ this_opt += 8;
+ device_count = simple_strtol(this_opt,
+ &endptr, 0);
+ if ((device_count < 0) ||
+ (device_count > MAX_DEVICE_COUNT))
+ device_count = MAX_DEVICE_COUNT;
+ }
+
+ else if (strncmp(this_opt, "wincfg:", 7) = 0) {
+ this_opt += 7;
+ window_index = simple_strtol(this_opt,
+ &endptr, 0);
+ if ((window_index < 0) ||
+ (window_index >= ARRAY_SIZE(windows)))
+ window_index = DEFAULT_WINDOW_INDEX;
+ }
+
+ else if (strncmp(this_opt, "off", 3) = 0)
+ return 1;
/* Unsupported option */
else {
print_warn("Unsupported option \"%s\"", this_opt);
}
}
}
+ return 0;
}
static int __init au1200fb_init(void)
@@ -1837,7 +1861,8 @@ static int __init au1200fb_init(void)
print_info("" DRIVER_DESC "");
/* Setup driver with options */
- au1200fb_setup();
+ if (au1200fb_setup())
+ return -ENODEV;
/* Point to the panel selected */
panel = &known_lcd_panels[panel_index];
--
1.7.5.3
^ permalink raw reply related
* [PATCH 2/4] au1200fb: fixup PM
From: Manuel Lauss @ 2011-06-10 15:23 UTC (permalink / raw)
To: linux-fbdev
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1252", Size: 7076 bytes --]
Remove last traces of the unused custom Alchemy PM code, implement
suspend/resume callbacks.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
---
drivers/video/au1200fb.c | 154 ++++++++++++----------------------------------
1 files changed, 39 insertions(+), 115 deletions(-)
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 442d005..480ecb1 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -46,10 +46,6 @@
#include <asm/mach-au1x00/au1000.h>
#include "au1200fb.h"
-#ifdef CONFIG_PM
-#include <asm/mach-au1x00/au1xxx_pm.h>
-#endif
-
#ifndef CONFIG_FB_AU1200_DEVS
#define CONFIG_FB_AU1200_DEVS 4
#endif
@@ -205,12 +201,6 @@ struct window_settings {
extern int board_au1200fb_panel_init (void);
extern int board_au1200fb_panel_shutdown (void);
-#ifdef CONFIG_PM
-int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
- au1xxx_request_t request, void *data);
-au1xxx_power_dev_t *LCD_pm_dev;
-#endif
-
/*
* Default window configurations
*/
@@ -652,25 +642,6 @@ static struct panel_settings known_lcd_panels[]
/********************************************************************/
-#ifdef CONFIG_PM
-static int set_brightness(unsigned int brightness)
-{
- unsigned int hi1, divider;
-
- /* limit brightness pwm duty to >= 30/1600 */
- if (brightness < 30) {
- brightness = 30;
- }
- divider = (lcd->pwmdiv & 0x3FFFF) + 1;
- hi1 = (lcd->pwmhi >> 16) + 1;
- hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
- lcd->pwmhi &= 0xFFFF;
- lcd->pwmhi |= (hi1 << 16);
-
- return brightness;
-}
-#endif /* CONFIG_PM */
-
static int winbpp (unsigned int winctrl1)
{
int bits = 0;
@@ -1248,10 +1219,6 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
unsigned long start=0, off;
struct au1200fb_device *fbdev = info->par;
-#ifdef CONFIG_PM
- au1xxx_pm_access(LCD_pm_dev);
-#endif
-
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
return -EINVAL;
}
@@ -1461,10 +1428,6 @@ static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
int plane;
int val;
-#ifdef CONFIG_PM
- au1xxx_pm_access(LCD_pm_dev);
-#endif
-
plane = fbinfo2index(info);
print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
@@ -1622,7 +1585,7 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
/* AU1200 LCD controller device driver */
-static int au1200fb_drv_probe(struct platform_device *dev)
+static int __devinit au1200fb_drv_probe(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
struct fb_info *fbi = NULL;
@@ -1633,6 +1596,9 @@ static int au1200fb_drv_probe(struct platform_device *dev)
ret = 0;
fbdev = NULL;
+ /* Kickstart the panel */
+ au1200_setpanel(panel);
+
for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
bpp = winbpp(win->w[plane].mode_winctrl1);
if (win->w[plane].xres = 0)
@@ -1724,15 +1690,12 @@ failed:
return ret;
}
-static int au1200fb_drv_remove(struct platform_device *dev)
+static int __devexit au1200fb_drv_remove(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
struct fb_info *fbi;
int plane;
- if (!dev)
- return -ENODEV;
-
/* Turn off the panel */
au1200_setpanel(NULL);
@@ -1760,31 +1723,53 @@ static int au1200fb_drv_remove(struct platform_device *dev)
}
#ifdef CONFIG_PM
-static int au1200fb_drv_suspend(struct platform_device *dev,
- pm_message_t state)
+static int au1200fb_drv_suspend(struct device *dev)
{
- /* TODO */
+ au1200_setpanel(NULL);
+
+ lcd->outmask = 0;
+ au_sync();
+
return 0;
}
-static int au1200fb_drv_resume(struct platform_device *dev)
+static int au1200fb_drv_resume(struct device *dev)
{
- /* TODO */
+ struct fb_info *fbi;
+ int i;
+
+ /* Kickstart the panel */
+ au1200_setpanel(panel);
+
+ for (i = 0; i < CONFIG_FB_AU1200_DEVS; i++) {
+ fbi = _au1200fb_infos[i];
+ au1200fb_fb_set_par(fbi);
+ }
+
return 0;
}
+
+static const struct dev_pm_ops au1200fb_pmops = {
+ .suspend = au1200fb_drv_suspend,
+ .resume = au1200fb_drv_resume,
+ .freeze = au1200fb_drv_suspend,
+ .thaw = au1200fb_drv_resume,
+};
+
+#define AU1200FB_PMOPS (&au1200fb_pmops)
+
+#else
+#define AU1200FB_PMOPS NULL
#endif /* CONFIG_PM */
static struct platform_driver au1200fb_driver = {
.driver = {
- .name = "au1200-lcd",
- .owner = THIS_MODULE,
+ .name = "au1200-lcd",
+ .owner = THIS_MODULE,
+ .pm = AU1200FB_PMOPS,
},
.probe = au1200fb_drv_probe,
- .remove = au1200fb_drv_remove,
-#ifdef CONFIG_PM
- .suspend = au1200fb_drv_suspend,
- .resume = au1200fb_drv_resume,
-#endif
+ .remove = __devexit_p(au1200fb_drv_remove),
};
/*-------------------------------------------------------------------------*/
@@ -1847,56 +1832,6 @@ static void au1200fb_setup(void)
}
}
-#ifdef CONFIG_PM
-static int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
- au1xxx_request_t request, void *data) {
- int retval = -1;
- unsigned int d = 0;
- unsigned int brightness = 0;
-
- if (request = AU1XXX_PM_SLEEP) {
- board_au1200fb_panel_shutdown();
- }
- else if (request = AU1XXX_PM_WAKEUP) {
- if(dev->prev_state = SLEEP_STATE)
- {
- int plane;
- au1200_setpanel(panel);
- for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
- struct au1200fb_device *fbdev;
- fbdev = &_au1200fb_devices[plane];
- au1200fb_fb_set_par(&fbdev->fb_info);
- }
- }
-
- d = *((unsigned int*)data);
- if(d <\x10) brightness = 26;
- else if(d< ) brightness = 51;
- else if(d<0) brightness = 77;
- else if(d<@) brightness = 102;
- else if(d<P) brightness = 128;
- else if(d<`) brightness = 153;
- else if(d<p) brightness = 179;
- else if(d<) brightness = 204;
- else if(d<) brightness = 230;
- else brightness = 255;
- set_brightness(brightness);
- } else if (request = AU1XXX_PM_GETSTATUS) {
- return dev->cur_state;
- } else if (request = AU1XXX_PM_ACCESS) {
- if (dev->cur_state != SLEEP_STATE)
- return retval;
- else {
- au1200_setpanel(panel);
- }
- } else if (request = AU1XXX_PM_IDLE) {
- } else if (request = AU1XXX_PM_CLEANUP) {
- }
-
- return retval;
-}
-#endif
-
static int __init au1200fb_init(void)
{
print_info("" DRIVER_DESC "");
@@ -1911,17 +1846,6 @@ static int __init au1200fb_init(void)
printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
- /* Kickstart the panel, the framebuffers/windows come soon enough */
- au1200_setpanel(panel);
-
- #ifdef CONFIG_PM
- LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
- if ( LCD_pm_dev = NULL)
- printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
- else
- printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
- #endif
-
return platform_driver_register(&au1200fb_driver);
}
--
1.7.5.3
^ permalink raw reply related
* [PATCH 1/4] au1200fb: use framebuffer_alloc()
From: Manuel Lauss @ 2011-06-10 15:23 UTC (permalink / raw)
To: linux-fbdev
Convert to use framebuffer_alloc() instead of using fb_info embedded
into device context (which broke the driver in the past due to un-
initialized elements).
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
---
drivers/video/au1200fb.c | 80 ++++++++++++++++++++++++++-------------------
1 files changed, 46 insertions(+), 34 deletions(-)
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 5dff32a..442d005 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -150,7 +150,7 @@ struct au1200_lcd_iodata_t {
/* Private, per-framebuffer management information (independent of the panel itself) */
struct au1200fb_device {
- struct fb_info fb_info; /* FB driver info record */
+ struct fb_info *fb_info; /* FB driver info record */
int plane;
unsigned char* fb_mem; /* FrameBuffer memory map */
@@ -158,7 +158,7 @@ struct au1200fb_device {
dma_addr_t fb_phys;
};
-static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
+static struct fb_info *_au1200fb_infos[CONFIG_FB_AU1200_DEVS];
/********************************************************************/
/* LCD controller restrictions */
@@ -713,7 +713,7 @@ static int fbinfo2index (struct fb_info *fb_info)
int i;
for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
- if (fb_info = (struct fb_info *)(&_au1200fb_devices[i].fb_info))
+ if (fb_info = _au1200fb_infos[i])
return i;
}
printk("au1200fb: ERROR: fbinfo2index failed!\n");
@@ -962,7 +962,7 @@ static void au1200_setmode(struct au1200fb_device *fbdev)
lcd->window[plane].winctrl2 = ( 0
| LCD_WINCTRL2_CKMODE_00
| LCD_WINCTRL2_DBM
- | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length)
+ | LCD_WINCTRL2_BX_N(fbdev->fb_info->fix.line_length)
| LCD_WINCTRL2_SCX_1
| LCD_WINCTRL2_SCY_1
) ;
@@ -1050,7 +1050,7 @@ static void au1200fb_update_fbinfo(struct fb_info *fbi)
static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
struct fb_info *fbi)
{
- struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
+ struct au1200fb_device *fbdev = fbi->par;
u32 pixclock;
int screen_size, plane;
@@ -1142,7 +1142,7 @@ static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
*/
static int au1200fb_fb_set_par(struct fb_info *fbi)
{
- struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
+ struct au1200fb_device *fbdev = fbi->par;
au1200fb_update_fbinfo(fbi);
au1200_setmode(fbdev);
@@ -1246,7 +1246,7 @@ static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
unsigned int len;
unsigned long start=0, off;
- struct au1200fb_device *fbdev = (struct au1200fb_device *) info;
+ struct au1200fb_device *fbdev = info->par;
#ifdef CONFIG_PM
au1xxx_pm_access(LCD_pm_dev);
@@ -1561,10 +1561,9 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
{
- struct fb_info *fbi = &fbdev->fb_info;
+ struct fb_info *fbi = fbdev->fb_info;
int bpp;
- memset(fbi, 0, sizeof(struct fb_info));
fbi->fbops = &au1200fb_fb_ops;
bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
@@ -1626,11 +1625,13 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
static int au1200fb_drv_probe(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
+ struct fb_info *fbi = NULL;
unsigned long page;
int bpp, plane, ret;
- if (!dev)
- return -EINVAL;
+ /* shut gcc up */
+ ret = 0;
+ fbdev = NULL;
for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
bpp = winbpp(win->w[plane].mode_winctrl1);
@@ -1639,8 +1640,15 @@ static int au1200fb_drv_probe(struct platform_device *dev)
if (win->w[plane].yres = 0)
win->w[plane].yres = panel->Yres;
- fbdev = &_au1200fb_devices[plane];
- memset(fbdev, 0, sizeof(struct au1200fb_device));
+ fbi = framebuffer_alloc(sizeof(struct au1200fb_device),
+ &dev->dev);
+ if (!fbi)
+ goto failed;
+
+ _au1200fb_infos[plane] = fbi;
+ fbdev = fbi->par;
+ fbdev->fb_info = fbi;
+
fbdev->plane = plane;
/* Allocate the framebuffer to the maximum screen size */
@@ -1673,21 +1681,20 @@ static int au1200fb_drv_probe(struct platform_device *dev)
goto failed;
/* Register new framebuffer */
- if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) {
+ ret = register_framebuffer(fbi);
+ if (ret < 0) {
print_err("cannot register new framebuffer");
goto failed;
}
- au1200fb_fb_set_par(&fbdev->fb_info);
+ au1200fb_fb_set_par(fbi);
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
if (plane = 0)
- if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) {
+ if (fb_prepare_logo(fbi, FB_ROTATE_UR)) {
/* Start display and show logo on boot */
- fb_set_cmap(&fbdev->fb_info.cmap,
- &fbdev->fb_info);
-
- fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
+ fb_set_cmap(&fbi->cmap, fbi);
+ fb_show_logo(fbi, FB_ROTATE_UR);
}
#endif
}
@@ -1705,12 +1712,13 @@ static int au1200fb_drv_probe(struct platform_device *dev)
failed:
/* NOTE: This only does the current plane/window that failed; others are still active */
if (fbdev->fb_mem)
- dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
+ dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
fbdev->fb_mem, fbdev->fb_phys);
- if (fbdev->fb_info.cmap.len != 0)
- fb_dealloc_cmap(&fbdev->fb_info.cmap);
- if (fbdev->fb_info.pseudo_palette)
- kfree(fbdev->fb_info.pseudo_palette);
+ if (fbi) {
+ if (fbi->cmap.len != 0)
+ fb_dealloc_cmap(&fbi->cmap);
+ kfree(fbi->pseudo_palette);
+ }
if (plane = 0)
free_irq(AU1200_LCD_INT, (void*)dev);
return ret;
@@ -1719,6 +1727,7 @@ failed:
static int au1200fb_drv_remove(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
+ struct fb_info *fbi;
int plane;
if (!dev)
@@ -1727,20 +1736,22 @@ static int au1200fb_drv_remove(struct platform_device *dev)
/* Turn off the panel */
au1200_setpanel(NULL);
- for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)
- {
- fbdev = &_au1200fb_devices[plane];
+ for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
+ fbi = _au1200fb_infos[plane];
+ fbdev = fbi->par;
/* Clean up all probe data */
- unregister_framebuffer(&fbdev->fb_info);
+ unregister_framebuffer(fbi);
if (fbdev->fb_mem)
dma_free_noncoherent(&dev->dev,
PAGE_ALIGN(fbdev->fb_len),
fbdev->fb_mem, fbdev->fb_phys);
- if (fbdev->fb_info.cmap.len != 0)
- fb_dealloc_cmap(&fbdev->fb_info.cmap);
- if (fbdev->fb_info.pseudo_palette)
- kfree(fbdev->fb_info.pseudo_palette);
+ if (fbi->cmap.len != 0)
+ fb_dealloc_cmap(&fbi->cmap);
+ kfree(fbi->pseudo_palette);
+
+ framebuffer_release(fbi);
+ _au1200fb_infos[plane] = NULL;
}
free_irq(AU1200_LCD_INT, (void *)dev);
@@ -1749,7 +1760,8 @@ static int au1200fb_drv_remove(struct platform_device *dev)
}
#ifdef CONFIG_PM
-static int au1200fb_drv_suspend(struct platform_device *dev, u32 state)
+static int au1200fb_drv_suspend(struct platform_device *dev,
+ pm_message_t state)
{
/* TODO */
return 0;
--
1.7.5.3
^ permalink raw reply related
* [PATCH 0/4] fbdev: au1200fb updates
From: Manuel Lauss @ 2011-06-10 15:23 UTC (permalink / raw)
To: linux-fbdev
Here are 4 updates to the au1200fb codebase to get it to work and compile
again, also with PM enabled.
Run and PM-tested on DB1200 and DB1300.
Manuel Lauss (4):
au1200fb: use framebuffer_alloc()
au1200fb: fixup PM
au1200fb: make number of windows configurable at load time.
au1200fb: switch to FB_SYS helpers
drivers/video/Kconfig | 7 +-
drivers/video/au1200fb.c | 285 ++++++++++++++++++++--------------------------
2 files changed, 128 insertions(+), 164 deletions(-)
--
1.7.5.3
^ permalink raw reply
* Re: [PATCH 1/3] printk: Release console_sem after logbuf_lock
From: Peter Zijlstra @ 2011-06-10 12:42 UTC (permalink / raw)
To: Ingo Molnar
Cc: Hugh Dickins, Andrew Morton, Linus Torvalds, Thomas Gleixner,
linux-kernel, efault, Arne Jansen, PaulMundt, linux-fbdev
In-Reply-To: <1307709714.3941.140.camel@twins>
On Fri, 2011-06-10 at 14:41 +0200, Peter Zijlstra wrote:
> On Fri, 2011-06-10 at 14:34 +0200, Ingo Molnar wrote:
> > * Peter Zijlstra <peterz@infradead.org> wrote:
> >
> > > thinking that that would have my printk stmts appear on both the
> > > fbcon as well as the serial line. But they fail to appear on the
> > > latency tracer (current max was 165us waking an idle cpu).
> >
> > Have you removed this bit:
> >
> > spin_unlock(&logbuf_lock);
> > stop_critical_timings(); /* don't trace print latency */
> > call_console_drivers(_con_start, _log_end);
> > start_critical_timings();
> > local_irq_restore(flags);
> >
> > which hides the latencies from the latency tracer?
>
> it shouldn't those flags come from spin_lock_irqsave(), which already
> has IRQs disabled, so the restore shouldn't re-enable them.
>
> Hmm,. that might actually already be true for mainline too, yeah, looks
> like we call vprintk()->console_unlock() with IRQs-disabled.
>
> Hohumm..
Also, I used the preemptirqoff tracer, so even if it did re-enable
interrupts we should still have preemption disabled and still catch the
latency.
^ permalink raw reply
* Re: [PATCH 1/3] printk: Release console_sem after logbuf_lock
From: Peter Zijlstra @ 2011-06-10 12:41 UTC (permalink / raw)
To: Ingo Molnar
Cc: Hugh Dickins, Andrew Morton, Linus Torvalds, Thomas Gleixner,
linux-kernel, efault, Arne Jansen, PaulMundt, linux-fbdev
In-Reply-To: <20110610123416.GA12451@elte.hu>
On Fri, 2011-06-10 at 14:34 +0200, Ingo Molnar wrote:
> * Peter Zijlstra <peterz@infradead.org> wrote:
>
> > thinking that that would have my printk stmts appear on both the
> > fbcon as well as the serial line. But they fail to appear on the
> > latency tracer (current max was 165us waking an idle cpu).
>
> Have you removed this bit:
>
> spin_unlock(&logbuf_lock);
> stop_critical_timings(); /* don't trace print latency */
> call_console_drivers(_con_start, _log_end);
> start_critical_timings();
> local_irq_restore(flags);
>
> which hides the latencies from the latency tracer?
it shouldn't those flags come from spin_lock_irqsave(), which already
has IRQs disabled, so the restore shouldn't re-enable them.
Hmm,. that might actually already be true for mainline too, yeah, looks
like we call vprintk()->console_unlock() with IRQs-disabled.
Hohumm..
^ permalink raw reply
* Re: [PATCH 1/3] printk: Release console_sem after logbuf_lock
From: Ingo Molnar @ 2011-06-10 12:34 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Hugh Dickins, Andrew Morton, Linus Torvalds, Thomas Gleixner,
linux-kernel, efault, Arne Jansen, PaulMundt, linux-fbdev
In-Reply-To: <1307709030.3941.134.camel@twins>
* Peter Zijlstra <peterz@infradead.org> wrote:
> thinking that that would have my printk stmts appear on both the
> fbcon as well as the serial line. But they fail to appear on the
> latency tracer (current max was 165us waking an idle cpu).
Have you removed this bit:
spin_unlock(&logbuf_lock);
stop_critical_timings(); /* don't trace print latency */
call_console_drivers(_con_start, _log_end);
start_critical_timings();
local_irq_restore(flags);
which hides the latencies from the latency tracer?
Thanks,
Ingo
^ permalink raw reply
* Re: [PATCH 1/3] printk: Release console_sem after logbuf_lock
From: Peter Zijlstra @ 2011-06-10 12:30 UTC (permalink / raw)
To: Hugh Dickins
Cc: Andrew Morton, Ingo Molnar, Linus Torvalds, Thomas Gleixner,
linux-kernel, efault, Arne Jansen, PaulMundt, linux-fbdev
In-Reply-To: <1307705311.3941.118.camel@twins>
On Fri, 2011-06-10 at 13:28 +0200, Peter Zijlstra wrote:
> On Thu, 2011-06-09 at 16:57 -0700, Hugh Dickins wrote:
> >
> > All console-related activity curently happens under spin_lock_irqsave(&console_lock).
> > This causes interrutps to be blocked for 1-2 milliseconds with vgacon, and for
> > hundreds of milliseconds with fbdevs. This results in network overruns, audio
> > dropouts, dropped characters on serial ports and other such nice things.
>
> Hmm, with these proposed patches we're actually back to that. I wonder
> if fbdev is still that crappy..
So I tried adding a fbcon to my test box (not that it actually has a
display, but who cares) and disabled lockdep (otherwise that's all I can
catch on the latency tracer) to see if I could see whopping horrid
latencies there, but I'm afraid I either failed to set things up
properly or my fbcon isn't sucky enough.
What I did was enable:
CONFIG_FB=y
CONFIG_FB_SIS=y
CONFIG_FB_SIS_315=y (the board has XGI z7)
and
CONFIG_FRAMEBUFFER_CONSOLE=y
And used:
debug ignore_loglevel sysrq_always_enabled console=tty0
console=ttyS0,115200 earlyprintk=serial,ttyS0,115200
thinking that that would have my printk stmts appear on both the fbcon
as well as the serial line. But they fail to appear on the latency
tracer (current max was 165us waking an idle cpu).
Paul (and fellow fbcon folks), was my setup above correct, and what's
the current status of suckyness wrt fbcon output?
The idea is to keep IRQs disabled over all of printk() including the
con->write() calls, Andrew seems to be responsible removing that in the
early 2.4 time-frame due to some consoles being waaay crap and taking
like hundreds of ms to write things out, can that still happen or has
stuff improved and is using background flusher threads to write to slow
devices?
^ permalink raw reply
* Re: [PATCH 15/29] mx3fb: use display information in info not in var
From: Guennadi Liakhovetski @ 2011-06-10 9:01 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1306364301-8195-16-git-send-email-laurent.pinchart@ideasonboard.com>
On Thu, 26 May 2011, Laurent Pinchart wrote:
> We must not use any information in the passed var besides xoffset,
> yoffset and vmode as otherwise applications might abuse it. Also use the
> aligned fix.line_length and not the (possible) unaligned xres_virtual.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
> drivers/video/mx3fb.c | 6 +++---
> 1 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
> index 7e3a490..759e244 100644
> --- a/drivers/video/mx3fb.c
> +++ b/drivers/video/mx3fb.c
> @@ -1062,15 +1062,15 @@ static int mx3fb_pan_display(struct fb_var_screeninfo *var,
> y_bottom = var->yoffset;
>
> if (!(var->vmode & FB_VMODE_YWRAP))
> - y_bottom += var->yres;
> + y_bottom += fbi->var.yres;
>
> if (y_bottom > fbi->var.yres_virtual)
> return -EINVAL;
>
> mutex_lock(&mx3_fbi->mutex);
>
> - offset = (var->yoffset * var->xres_virtual + var->xoffset) *
> - (var->bits_per_pixel / 8);
> + offset = var->yoffset * fbi->fix.line_length
> + + var->xoffset * (var->bits_per_pixel / 8);
Didn't you mean
+ + var->xoffset * (fbi->var.bits_per_pixel / 8);
With this fix:
Tested-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
(tested using http://git.ideasonboard.org/?pûdev-test.git;a=summary)
Thanks
Guennadi
> base = fbi->fix.smem_start + offset;
>
> dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n",
> --
> 1.7.3.4
>
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
^ permalink raw reply
* Re: [PATCHv2 20/28] OMAP: DSS2: Use PM runtime & HWMOD support
From: Paul Mundt @ 2011-06-10 7:24 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, b-cousson, paul, khilman
In-Reply-To: <1307688729.1823.12.camel@lappyti>
On Fri, Jun 10, 2011 at 09:52:09AM +0300, Tomi Valkeinen wrote:
> On Fri, 2011-06-10 at 05:03 +0900, Paul Mundt wrote:
> > the use in the error paths and so on you will definitely need to be using
> > pm_runtime_put_sync() at least some of the time.
>
> Hmm, why is that? When the user of, say, dispc, has finished with it and
> calls dispc_runtime_put(), the caller shouldn't care if the HW is
> actually turned off now or later.
>
Ah, I forgot that pm_runtime_disable() already does the synchronous bits
for you, so you get lucky that way. I was concerned about the race
between the work queue and the device pointer going away, but this is
already handled by the subsystem via __pm_runtime_barrier() in the
disable path.
> pm_runtime_put() can return an error value, but my wrappers discard it,
> as I don't know in which situations it could happen, and what could the
> driver do about it. If the HW cannot be turned off now, why could it be
> turned off later, and when would that be?
>
The return value is primarily aimed at informing you whether it was able
to idle the device, whether there were already pending requests, etc. If
you're in an exit path you're probably not too concerned with this.
If you have some alternate means of cutting power to the block unrelated
to runtime pm based clock control you can use the return value as a
sanity measure to error out before inadvertently cutting power out
underneath another user.
^ permalink raw reply
* Re: [PATCHv2 20/28] OMAP: DSS2: Use PM runtime & HWMOD support
From: Tomi Valkeinen @ 2011-06-10 6:52 UTC (permalink / raw)
To: Paul Mundt; +Cc: linux-omap, linux-fbdev, b-cousson, paul, khilman
In-Reply-To: <20110609200335.GD26006@linux-sh.org>
On Fri, 2011-06-10 at 05:03 +0900, Paul Mundt wrote:
> On Thu, Jun 09, 2011 at 04:56:42PM +0300, Tomi Valkeinen wrote:
> > +int dispc_runtime_get(void)
> > +{
> > + int r;
> > +
> > + DSSDBG("dispc_runtime_get\n");
> > +
> > + r = pm_runtime_get_sync(&dispc.pdev->dev);
> > + WARN_ON(r < 0);
> > + return r < 0 ? r : 0;
> > +}
> > +
> > +void dispc_runtime_put(void)
> > +{
> > + int r;
> > +
> > + DSSDBG("dispc_runtime_put\n");
> > +
> > + r = pm_runtime_put(&dispc.pdev->dev);
> > + WARN_ON(r < 0);
> > }
> >
> This seems a bit odd. Your runtime_get wrapper is explicitly synchronous
> while your put wrapper is explicitly asynchronous, although these details
> (if intentional) are not at all obvious from the wrapper naming. From
Yes, the naming could be improved to make the (a)synchronousness obvious
to the caller. The functions are internal to DSS, but still.
> the use in the error paths and so on you will definitely need to be using
> pm_runtime_put_sync() at least some of the time.
Hmm, why is that? When the user of, say, dispc, has finished with it and
calls dispc_runtime_put(), the caller shouldn't care if the HW is
actually turned off now or later.
pm_runtime_put() can return an error value, but my wrappers discard it,
as I don't know in which situations it could happen, and what could the
driver do about it. If the HW cannot be turned off now, why could it be
turned off later, and when would that be?
> In the interest of avoiding confusion, I would in general just get rid of
> these wrappers and use the pm_runtime calls openly, as you already do for
> some of the other parts of the API. The runtime PM framework has pretty
> verbose debugging already that goes well beyond what you presently have,
> too.
Yes, my main reason for the wrapper is to hide the device pointer from
the users. So when, say, DSI block needs to use DISPC, it can just call
dispc_runtime_get(), instead of having a mechanism to get the dispc
device (dispc_get_dev() perhaps), and then using pm_runtime directly.
Not a big difference, but I'd like to keep the dispc device pointer
internal to dispc, as there's no real need to access it directly from
elsewhere.
Some of the wrappers are actually private to the file already, like for
dsi. These wrappers could be removed without exposing any device
pointers, but having them keeps the pattern consistent in all parts of
the dss. And it allows me to have the WARN_ONs there easily.
> You seem to have adopted this sync/async pattern for all of the users:
Yes, I think the pattern is similar all around: when you get the device,
you want it to be up and running immediately. When you put the device,
you don't care when it's actually disabled.
Tomi
^ permalink raw reply
* Re: [PATCHv2 20/28] OMAP: DSS2: Use PM runtime & HWMOD support
From: Paul Mundt @ 2011-06-09 20:03 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, b-cousson, paul, khilman
In-Reply-To: <1307627810-3768-21-git-send-email-tomi.valkeinen@ti.com>
On Thu, Jun 09, 2011 at 04:56:42PM +0300, Tomi Valkeinen wrote:
> +int dispc_runtime_get(void)
> +{
> + int r;
> +
> + DSSDBG("dispc_runtime_get\n");
> +
> + r = pm_runtime_get_sync(&dispc.pdev->dev);
> + WARN_ON(r < 0);
> + return r < 0 ? r : 0;
> +}
> +
> +void dispc_runtime_put(void)
> +{
> + int r;
> +
> + DSSDBG("dispc_runtime_put\n");
> +
> + r = pm_runtime_put(&dispc.pdev->dev);
> + WARN_ON(r < 0);
> }
>
This seems a bit odd. Your runtime_get wrapper is explicitly synchronous
while your put wrapper is explicitly asynchronous, although these details
(if intentional) are not at all obvious from the wrapper naming. From
the use in the error paths and so on you will definitely need to be using
pm_runtime_put_sync() at least some of the time.
In the interest of avoiding confusion, I would in general just get rid of
these wrappers and use the pm_runtime calls openly, as you already do for
some of the other parts of the API. The runtime PM framework has pretty
verbose debugging already that goes well beyond what you presently have,
too.
You seem to have adopted this sync/async pattern for all of the users:
> +int dsi_runtime_get(struct platform_device *dsidev)
> {
> - if (enable)
> - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
> - else
> - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
> + int r;
> + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
> +
> + DSSDBG("dsi_runtime_get\n");
> +
> + r = pm_runtime_get_sync(&dsi->pdev->dev);
> + WARN_ON(r < 0);
> + return r < 0 ? r : 0;
> +}
> +
> +void dsi_runtime_put(struct platform_device *dsidev)
> +{
> + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
> + int r;
> +
> + DSSDBG("dsi_runtime_put\n");
> +
> + r = pm_runtime_put(&dsi->pdev->dev);
> + WARN_ON(r < 0);
> }
>
Here.
> -void dss_clk_disable(enum dss_clock clks)
> -{
..
> - dss_clk_disable_no_ctx(clks);
> + r = pm_runtime_get_sync(&dss.pdev->dev);
> + WARN_ON(r < 0);
> + return r < 0 ? r : 0;
> }
>
> -static void dss_clk_enable_all_no_ctx(void)
> +void dss_runtime_put(void)
> {
..
> + r = pm_runtime_put(&dss.pdev->dev);
> + WARN_ON(r < 0);
> }
>
And here.
> +static int hdmi_runtime_get(void)
> +{
> + int r;
> +
> + DSSDBG("hdmi_runtime_get\n");
> +
> + r = pm_runtime_get_sync(&hdmi.pdev->dev);
> + WARN_ON(r < 0);
> + return r < 0 ? r : 0;
> +}
> +
> +static void hdmi_runtime_put(void)
> +{
> + int r;
> +
> + DSSDBG("hdmi_runtime_put\n");
> +
> + r = pm_runtime_put(&hdmi.pdev->dev);
> + WARN_ON(r < 0);
> +}
> +
And here.
> -static void rfbi_enable_clocks(bool enable)
> +static int rfbi_runtime_get(void)
> {
> - if (enable)
> - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
> - else
> - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
> + int r;
> +
> + DSSDBG("rfbi_runtime_get\n");
> +
> + r = pm_runtime_get_sync(&rfbi.pdev->dev);
> + WARN_ON(r < 0);
> + return r < 0 ? r : 0;
> +}
> +
> +static void rfbi_runtime_put(void)
> +{
> + int r;
> +
> + DSSDBG("rfbi_runtime_put\n");
> +
> + r = pm_runtime_put(&rfbi.pdev->dev);
> + WARN_ON(r < 0);
> }
>
And here.
> +static int venc_runtime_get(void)
> {
> - if (enable) {
> - dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK);
> - if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK))
> - dss_clk_enable(DSS_CLK_VIDFCK);
> - } else {
> - dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK);
> - if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK))
> - dss_clk_disable(DSS_CLK_VIDFCK);
> - }
> + int r;
> +
> + DSSDBG("venc_runtime_get\n");
> +
> + r = pm_runtime_get_sync(&venc.pdev->dev);
> + WARN_ON(r < 0);
> + return r < 0 ? r : 0;
> +}
> +
> +static void venc_runtime_put(void)
> +{
> + int r;
> +
> + DSSDBG("venc_runtime_put\n");
> +
> + r = pm_runtime_put(&venc.pdev->dev);
> + WARN_ON(r < 0);
> }
>
And here.
^ permalink raw reply
* Re: [PATCHv2 00/28] OMAP DSS runtime PM adaptation
From: Tomi Valkeinen @ 2011-06-09 14:27 UTC (permalink / raw)
To: linux-omap; +Cc: linux-fbdev, b-cousson, paul, khilman
In-Reply-To: <1307627810-3768-1-git-send-email-tomi.valkeinen@ti.com>
On Thu, 2011-06-09 at 16:56 +0300, Tomi Valkeinen wrote:
> Hi,
>
> This patch set implements runtime PM adaptation for OMAP DSS driver.
> These patches can be found from:
>
> git://gitorious.org/linux-omap-dss2/linux.git pmruntime
The branch is actually "pmruntime-v2", my mistake.
Tomi
^ permalink raw reply
* [PATCHv2 28/28] OMAP: DSS2: DSS: Fix context save/restore
From: Tomi Valkeinen @ 2011-06-09 13:56 UTC (permalink / raw)
To: linux-omap, linux-fbdev; +Cc: b-cousson, paul, khilman, Tomi Valkeinen
In-Reply-To: <1307627810-3768-1-git-send-email-tomi.valkeinen@ti.com>
The current method of saving and restoring the context could cause a
restore before saving, effectively "restoring" zero values to registers.
Add ctx_valid field to indicate if the saved context is valid and can be
restored.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
drivers/video/omap2/dss/dss.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 21c8389..5c6499a 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -74,6 +74,7 @@ static struct {
enum omap_dss_clk_source dispc_clk_source;
enum omap_dss_clk_source lcd_clk_source[MAX_DSS_LCD_MANAGERS];
+ bool ctx_valid;
u32 ctx[DSS_SZ_REGS / sizeof(u32)];
} dss;
@@ -109,12 +110,19 @@ static void dss_save_context(void)
SR(SDI_CONTROL);
SR(PLL_CONTROL);
}
+
+ dss.ctx_valid = true;
+
+ DSSDBG("context saved\n");
}
static void dss_restore_context(void)
{
DSSDBG("dss_restore_context\n");
+ if (!dss.ctx_valid)
+ return;
+
RR(CONTROL);
if (dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_LCD) &
@@ -122,6 +130,8 @@ static void dss_restore_context(void)
RR(SDI_CONTROL);
RR(PLL_CONTROL);
}
+
+ DSSDBG("context restored\n");
}
#undef SR
--
1.7.4.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox