Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* Re: [PATCHv2 01/28] OMAP: change get_context_loss_count ret value
From: Paul Walmsley @ 2011-06-14  7:13 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, b-cousson, khilman, linux-omap mailing list
In-Reply-To: <1307958710.1847.56.camel@deskari>

Hi Tomi

On Mon, 13 Jun 2011, Tomi Valkeinen wrote:

> Paul, can you take this patch and queue it for an rc?

Generally I only queue regressions or fixes for major problems (crashes, 
corruption, etc.) for -rc series.  So probably this one should go in via 
the normal merge window, unless it's been causing major disruptions?


- Paul

^ permalink raw reply

* Re: [PATCH] au1200fb: fix hardcoded IRQ
From: Paul Mundt @ 2011-06-14  7:10 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1307898929-12365-1-git-send-email-manuel.lauss@googlemail.com>

On Sun, Jun 12, 2011 at 07:15:29PM +0200, Manuel Lauss wrote:
> 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;
>  	}
>  
A minor nit, but if you're passing along IRQ information via the platform
data already you could take that a step further and also fetch the IRQ
flags. This would at least allow you to avoid an unconditional
IRQF_SHARED.

^ permalink raw reply

* [PATCH] fbdev/atyfb: Fix 2 defined-but-not-used warnings
From: Geert Uytterhoeven @ 2011-06-13 18:12 UTC (permalink / raw)
  To: Paul Mundt, Ville Syrjala
  Cc: linux-fbdev, linux-kernel, linux-m68k, Geert Uytterhoeven

If CONFIG_FB_ATY_BACKLIGHT=y but CONFIG_PCI=n:

drivers/video/aty/atyfb_base.c:2272: warning: ‘aty_bl_exit’ defined but not used

If CONFIG_ATARI=y for a modular build:

drivers/video/aty/atyfb_base.c:2794: warning: ‘store_video_par’ defined but not
used

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 drivers/video/aty/atyfb_base.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index ebb893c..d7aaec5 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -248,10 +248,6 @@ static int atyfb_sync(struct fb_info *info);
 
 static int aty_init(struct fb_info *info);
 
-#ifdef CONFIG_ATARI
-static int store_video_par(char *videopar, unsigned char m64_num);
-#endif
-
 static void aty_get_crtc(const struct atyfb_par *par, struct crtc *crtc);
 
 static void aty_set_crtc(const struct atyfb_par *par, const struct crtc *crtc);
@@ -2268,11 +2264,13 @@ error:
 	return;
 }
 
+#ifdef CONFIG_PCI
 static void aty_bl_exit(struct backlight_device *bd)
 {
 	backlight_device_unregister(bd);
 	printk("aty: Backlight unloaded\n");
 }
+#endif /* CONFIG_PCI */
 
 #endif /* CONFIG_FB_ATY_BACKLIGHT */
 
@@ -2789,7 +2787,7 @@ aty_init_exit:
 	return ret;
 }
 
-#ifdef CONFIG_ATARI
+#if defined(CONFIG_ATARI) && !defined(MODULE)
 static int __devinit store_video_par(char *video_str, unsigned char m64_num)
 {
 	char *p;
@@ -2818,7 +2816,7 @@ static int __devinit store_video_par(char *video_str, unsigned char m64_num)
 	phys_vmembase[m64_num] = 0;
 	return -1;
 }
-#endif /* CONFIG_ATARI */
+#endif /* CONFIG_ATARI && !MODULE */
 
 /*
  * Blank the display.
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCHv2 01/28] OMAP: change get_context_loss_count ret value
From: Tomi Valkeinen @ 2011-06-13 16:45 UTC (permalink / raw)
  To: Ghongdemath, Girish
  Cc: paul, linux-fbdev, b-cousson, khilman, linux-omap mailing list
In-Reply-To: <BANLkTimi0RZ8Fe7VpY9J7dMPH6tpVzf=dw@mail.gmail.com>

On Mon, 2011-06-13 at 11:37 -0500, Ghongdemath, Girish wrote:
> Tomi,
> Couple of queries,
> 
> On Mon, Jun 13, 2011 at 4:51 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> > Paul, can you take this patch and queue it for an rc?
> >
> >  Tomi
> >
> > On Thu, 2011-06-09 at 16:56 +0300, Tomi Valkeinen wrote:
> >> get_context_loss_count functions return context loss count as u32, and
> >> zero means an error. However, zero is also returned when context has
> >> never been lost and could also be returned when the context loss count
> >> has wrapped and goes to zero.
> >>
> >> Change the functions to return an int, with negative value meaning an
> >> error.
> >>
> 
> >> +             if (off_mode_enabled) {
> 
> - why have a check for off_mode_enabled? As this only detects valid
> next state for MPU/CORE. Other pwrdm can still
> hit OFF.

It does what the code did previously, without changing the logic. And
this doesn't detect anything, it's just an dummy emulation for context
loss to test the drivers.

> >> +                     count++;
> >> +                     /*
> >> +                      * Context loss count has to be a non-negative value.
> >> +                      * Clear the sign bit to get a value range from 0 to
> >> +                      * INT_MAX.
> >> +                      */
> >> +                     count &= INT_MAX;
> >> +                     dummy_context_loss_counter = count;
> >> +             }
> >>       }
> 
> - Why not use u32 instead?

So that we can return error values. That was the whole point of this
patch.

 Tomi



^ permalink raw reply

* Re: [PATCHv2 01/28] OMAP: change get_context_loss_count ret value to int
From: Ghongdemath, Girish @ 2011-06-13 16:37 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: paul, linux-fbdev, b-cousson, khilman, linux-omap mailing list
In-Reply-To: <1307958710.1847.56.camel@deskari>

Tomi,
Couple of queries,

On Mon, Jun 13, 2011 at 4:51 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> Paul, can you take this patch and queue it for an rc?
>
>  Tomi
>
> On Thu, 2011-06-09 at 16:56 +0300, Tomi Valkeinen wrote:
>> get_context_loss_count functions return context loss count as u32, and
>> zero means an error. However, zero is also returned when context has
>> never been lost and could also be returned when the context loss count
>> has wrapped and goes to zero.
>>
>> Change the functions to return an int, with negative value meaning an
>> error.
>>

>> +             if (off_mode_enabled) {

- why have a check for off_mode_enabled? As this only detects valid
next state for MPU/CORE. Other pwrdm can still
hit OFF.


>> +                     count++;
>> +                     /*
>> +                      * Context loss count has to be a non-negative value.
>> +                      * Clear the sign bit to get a value range from 0 to
>> +                      * INT_MAX.
>> +                      */
>> +                     count &= INT_MAX;
>> +                     dummy_context_loss_counter = count;
>> +             }
>>       }

- Why not use u32 instead?


Regards,
Girish

>>
>>       pr_debug("OMAP PM: context loss count for dev %s = %d\n",
>> @@ -337,7 +347,7 @@ u32 omap_pm_get_dev_context_loss_count(struct device *dev)
>>
>>  #else
>>
>> -u32 omap_pm_get_dev_context_loss_count(struct device *dev)
>> +int omap_pm_get_dev_context_loss_count(struct device *dev)
>>  {
>>       return dummy_context_loss_counter;
>>  }
>> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
>> index 9bbda9a..9753f71 100644
>> --- a/arch/arm/plat-omap/omap_device.c
>> +++ b/arch/arm/plat-omap/omap_device.c
>> @@ -310,7 +310,7 @@ static void _add_optional_clock_clkdev(struct omap_device *od,
>>   * return the context loss counter for that hwmod, otherwise return
>>   * zero.
>>   */
>> -u32 omap_device_get_context_loss_count(struct platform_device *pdev)
>> +int omap_device_get_context_loss_count(struct platform_device *pdev)
>>  {
>>       struct omap_device *od;
>>       u32 ret = 0;
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: [PATCH] fb.h: ARM uses __raw_{read/write}
From: Russell King - ARM Linux @ 2011-06-13 13:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201106131537.10698.arnd@arndb.de>

On Mon, Jun 13, 2011 at 03:37:10PM +0200, Arnd Bergmann wrote:
> On Monday 13 June 2011 12:08:19 Catalin Marinas wrote:
> > The change proposed by Hartley wouldn't make much difference from the
> > current volatile accesses (__raw_* accessors are implemented as volatile
> > on ARM).
> 
> I guess it would mainly make a difference if we get a platform where
> the PCI bus window is not in the same address space as the regular
> physical memory and the accessors actually need to do a computation
> on the address. AFAICT, ARM does not currently have any such platform
> and I would hope that it says that way.

Actually we do.

Footbridge has this situation: PCI memory space is 0 to 4GB, and appears
in physical space at 2GB-4GB physical, and can be switched between the
low and high 2GB of PCI space.

Non-PCI peripherals are located at 0 to 2GB physical.

We handle this by having pcibios_bus_to_resource() and
pcibios_resource_to_bus(), which translates from the bus space to a
cookie suitable for ioremap() and /proc/iomem.  This cookie happens to
be the physical address.

We avoid the obvious problem with the upper 2GB of PCI memory space by
placing the system RAM at 0xe0000000 on the PCI bus, and not allocating
any peripherals in the upper 2GB of PCI memory space.

So, I rather wish that people would stop saying that "ioremap takes the
PCI bus address".  It doesn't - it takes a platform specific cookie to
allow a mapping to be setup, which in the case of pci will be a cookie
provided from the PCI bus address by the pcibios_bus_to_resource()
platform code.

And the final thing to note on this is that fbmem/fbcon does work - see
the Cyber2000/CyberPro VGA driver which has been - and still is - used
on Netwinder (footbridge).

^ permalink raw reply

* Re: [PATCH] fb.h: ARM uses __raw_{read/write}
From: Arnd Bergmann @ 2011-06-13 13:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110613100819.GA26914@1n450.cable.virginmedia.net>

On Monday 13 June 2011 12:08:19 Catalin Marinas wrote:
> The change proposed by Hartley wouldn't make much difference from the
> current volatile accesses (__raw_* accessors are implemented as volatile
> on ARM).

I guess it would mainly make a difference if we get a platform where
the PCI bus window is not in the same address space as the regular
physical memory and the accessors actually need to do a computation
on the address. AFAICT, ARM does not currently have any such platform
and I would hope that it says that way.

> I think the memcpy_(from|to)io could be optimised on ARM to only add a
> barrier before or after he copying loop.

Agreed, good idea.

	Arnd

^ permalink raw reply

* Re: [PATCH] fb.h: ARM uses __raw_{read/write}
From: Catalin Marinas @ 2011-06-13 10:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20110613040003.GA29731@linux-sh.org>

On Mon, Jun 13, 2011 at 01:00:04PM +0900, Paul Mundt wrote:
> 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.

The intention for the __iormb/__iowmb calls is in relation to DMA
transfers where a buffer in normal RAM is filled in with data and the
transfer started by a writel() to a device. We need to make sure that
the normal RAM writing completes before the writel().

The change proposed by Hartley wouldn't make much difference from the
current volatile accesses (__raw_* accessors are implemented as volatile
on ARM).

I think the memcpy_(from|to)io could be optimised on ARM to only add a
barrier before or after he copying loop.

-- 
Catalin

^ permalink raw reply

* Re: [PATCHv2 01/28] OMAP: change get_context_loss_count ret value
From: Tomi Valkeinen @ 2011-06-13  9:51 UTC (permalink / raw)
  To: paul; +Cc: linux-fbdev, b-cousson, khilman, linux-omap mailing list
In-Reply-To: <1307627810-3768-2-git-send-email-tomi.valkeinen@ti.com>

Paul, can you take this patch and queue it for an rc?

 Tomi

On Thu, 2011-06-09 at 16:56 +0300, Tomi Valkeinen wrote:
> get_context_loss_count functions return context loss count as u32, and
> zero means an error. However, zero is also returned when context has
> never been lost and could also be returned when the context loss count
> has wrapped and goes to zero.
> 
> Change the functions to return an int, with negative value meaning an
> error.
> 
> OMAP HSMMC code uses omap_pm_get_dev_context_loss_count(), but as the
> hsmmc code handles the returned value as an int, with negative value
> meaning an error, this patch actually fixes hsmmc code also.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Acked-by: Kevin Hilman <khilman@ti.com>
> ---
>  arch/arm/mach-omap2/omap_hwmod.c              |    2 +-
>  arch/arm/mach-omap2/powerdomain.c             |   14 ++++++++++----
>  arch/arm/mach-omap2/powerdomain.h             |    2 +-
>  arch/arm/plat-omap/include/plat/omap-pm.h     |    4 ++--
>  arch/arm/plat-omap/include/plat/omap_device.h |    2 +-
>  arch/arm/plat-omap/include/plat/omap_hwmod.h  |    2 +-
>  arch/arm/plat-omap/omap-pm-noop.c             |   24 +++++++++++++++++-------
>  arch/arm/plat-omap/omap_device.c              |    2 +-
>  8 files changed, 34 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
> index e034294..4f0d554 100644
> --- a/arch/arm/mach-omap2/omap_hwmod.c
> +++ b/arch/arm/mach-omap2/omap_hwmod.c
> @@ -2332,7 +2332,7 @@ ohsps_unlock:
>   * Returns the context loss count of the powerdomain assocated with @oh
>   * upon success, or zero if no powerdomain exists for @oh.
>   */
> -u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
> +int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
>  {
>  	struct powerdomain *pwrdm;
>  	int ret = 0;
> diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
> index 9af0847..9d53a34 100644
> --- a/arch/arm/mach-omap2/powerdomain.c
> +++ b/arch/arm/mach-omap2/powerdomain.c
> @@ -935,16 +935,16 @@ int pwrdm_post_transition(void)
>   * @pwrdm: struct powerdomain * to wait for
>   *
>   * Context loss count is the sum of powerdomain off-mode counter, the
> - * logic off counter and the per-bank memory off counter.  Returns 0
> + * logic off counter and the per-bank memory off counter.  Returns negative
>   * (and WARNs) upon error, otherwise, returns the context loss count.
>   */
> -u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
> +int pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
>  {
>  	int i, count;
>  
>  	if (!pwrdm) {
>  		WARN(1, "powerdomain: %s: pwrdm is null\n", __func__);
> -		return 0;
> +		return -ENODEV;
>  	}
>  
>  	count = pwrdm->state_counter[PWRDM_POWER_OFF];
> @@ -953,7 +953,13 @@ u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm)
>  	for (i = 0; i < pwrdm->banks; i++)
>  		count += pwrdm->ret_mem_off_counter[i];
>  
> -	pr_debug("powerdomain: %s: context loss count = %u\n",
> +	/*
> +	 * Context loss count has to be a non-negative value. Clear the sign
> +	 * bit to get a value range from 0 to INT_MAX.
> +	 */
> +	count &= INT_MAX;
> +
> +	pr_debug("powerdomain: %s: context loss count = %d\n",
>  		 pwrdm->name, count);
>  
>  	return count;
> diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
> index d23d979..012827f 100644
> --- a/arch/arm/mach-omap2/powerdomain.h
> +++ b/arch/arm/mach-omap2/powerdomain.h
> @@ -207,7 +207,7 @@ int pwrdm_clkdm_state_switch(struct clockdomain *clkdm);
>  int pwrdm_pre_transition(void);
>  int pwrdm_post_transition(void);
>  int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
> -u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
> +int pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
>  bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
>  
>  extern void omap2xxx_powerdomains_init(void);
> diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
> index c0a7520..68df031 100644
> --- a/arch/arm/plat-omap/include/plat/omap-pm.h
> +++ b/arch/arm/plat-omap/include/plat/omap-pm.h
> @@ -350,9 +350,9 @@ unsigned long omap_pm_cpu_get_freq(void);
>   * driver must restore device context.   If the number of context losses
>   * exceeds the maximum positive integer, the function will wrap to 0 and
>   * continue counting.  Returns the number of context losses for this device,
> - * or zero upon error.
> + * or negative value upon error.
>   */
> -u32 omap_pm_get_dev_context_loss_count(struct device *dev);
> +int omap_pm_get_dev_context_loss_count(struct device *dev);
>  
>  void omap_pm_enable_off_mode(void);
>  void omap_pm_disable_off_mode(void);
> diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
> index e4c349f..70d31d0 100644
> --- a/arch/arm/plat-omap/include/plat/omap_device.h
> +++ b/arch/arm/plat-omap/include/plat/omap_device.h
> @@ -107,7 +107,7 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od);
>  int omap_device_align_pm_lat(struct platform_device *pdev,
>  			     u32 new_wakeup_lat_limit);
>  struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
> -u32 omap_device_get_context_loss_count(struct platform_device *pdev);
> +int omap_device_get_context_loss_count(struct platform_device *pdev);
>  
>  /* Other */
>  
> diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> index 1adea9c..8658e2d 100644
> --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
> +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
> @@ -598,7 +598,7 @@ int omap_hwmod_for_each_by_class(const char *classname,
>  				 void *user);
>  
>  int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
> -u32 omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
> +int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
>  
>  int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
>  
> diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
> index b0471bb2..3dc3801 100644
> --- a/arch/arm/plat-omap/omap-pm-noop.c
> +++ b/arch/arm/plat-omap/omap-pm-noop.c
> @@ -27,7 +27,7 @@
>  #include <plat/omap_device.h>
>  
>  static bool off_mode_enabled;
> -static u32 dummy_context_loss_counter;
> +static int dummy_context_loss_counter;
>  
>  /*
>   * Device-driver-originated constraints (via board-*.c files)
> @@ -311,22 +311,32 @@ void omap_pm_disable_off_mode(void)
>  
>  #ifdef CONFIG_ARCH_OMAP2PLUS
>  
> -u32 omap_pm_get_dev_context_loss_count(struct device *dev)
> +int omap_pm_get_dev_context_loss_count(struct device *dev)
>  {
>  	struct platform_device *pdev = to_platform_device(dev);
> -	u32 count;
> +	int count;
>  
>  	if (WARN_ON(!dev))
> -		return 0;
> +		return -ENODEV;
>  
>  	if (dev->parent = &omap_device_parent) {
>  		count = omap_device_get_context_loss_count(pdev);
>  	} else {
>  		WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device",
>  			  dev_name(dev));
> -		if (off_mode_enabled)
> -			dummy_context_loss_counter++;
> +
>  		count = dummy_context_loss_counter;
> +
> +		if (off_mode_enabled) {
> +			count++;
> +			/*
> +			 * Context loss count has to be a non-negative value.
> +			 * Clear the sign bit to get a value range from 0 to
> +			 * INT_MAX.
> +			 */
> +			count &= INT_MAX;
> +			dummy_context_loss_counter = count;
> +		}
>  	}
>  
>  	pr_debug("OMAP PM: context loss count for dev %s = %d\n",
> @@ -337,7 +347,7 @@ u32 omap_pm_get_dev_context_loss_count(struct device *dev)
>  
>  #else
>  
> -u32 omap_pm_get_dev_context_loss_count(struct device *dev)
> +int omap_pm_get_dev_context_loss_count(struct device *dev)
>  {
>  	return dummy_context_loss_counter;
>  }
> diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
> index 9bbda9a..9753f71 100644
> --- a/arch/arm/plat-omap/omap_device.c
> +++ b/arch/arm/plat-omap/omap_device.c
> @@ -310,7 +310,7 @@ static void _add_optional_clock_clkdev(struct omap_device *od,
>   * return the context loss counter for that hwmod, otherwise return
>   * zero.
>   */
> -u32 omap_device_get_context_loss_count(struct platform_device *pdev)
> +int omap_device_get_context_loss_count(struct platform_device *pdev)
>  {
>  	struct omap_device *od;
>  	u32 ret = 0;



^ permalink raw reply

* [PATCH 3/3] OMAP: DSS2: remove update_mode from omapdss
From: Tomi Valkeinen @ 2011-06-13  9:12 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1307956374-1107-1-git-send-email-tomi.valkeinen@ti.com>

Remove the whole update_mode stuff from omapdss driver. If automatic
update for manual update displays is needed, it's better implemented in
higher layers.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/displays/panel-taal.c |   17 --------
 drivers/video/omap2/dss/display.c         |   45 ----------------------
 drivers/video/omap2/dss/manager.c         |   59 +++++++----------------------
 drivers/video/omap2/dss/venc.c            |   17 --------
 include/video/omapdss.h                   |   11 -----
 5 files changed, 14 insertions(+), 135 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index fdd5d4ae..221579f 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -1897,20 +1897,6 @@ err:
 	mutex_unlock(&td->lock);
 }
 
-static int taal_set_update_mode(struct omap_dss_device *dssdev,
-		enum omap_dss_update_mode mode)
-{
-	if (mode != OMAP_DSS_UPDATE_MANUAL)
-		return -EINVAL;
-	return 0;
-}
-
-static enum omap_dss_update_mode taal_get_update_mode(
-		struct omap_dss_device *dssdev)
-{
-	return OMAP_DSS_UPDATE_MANUAL;
-}
-
 static struct omap_dss_driver taal_driver = {
 	.probe		= taal_probe,
 	.remove		= __exit_p(taal_remove),
@@ -1920,9 +1906,6 @@ static struct omap_dss_driver taal_driver = {
 	.suspend	= taal_suspend,
 	.resume		= taal_resume,
 
-	.set_update_mode = taal_set_update_mode,
-	.get_update_mode = taal_get_update_mode,
-
 	.update		= taal_update,
 	.sync		= taal_sync,
 
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index c2dfc8c..a0bbdf6 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -65,48 +65,6 @@ static ssize_t display_enabled_store(struct device *dev,
 	return size;
 }
 
-static ssize_t display_upd_mode_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
-	if (dssdev->driver->get_update_mode)
-		mode = dssdev->driver->get_update_mode(dssdev);
-	return snprintf(buf, PAGE_SIZE, "%d\n", mode);
-}
-
-static ssize_t display_upd_mode_store(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf, size_t size)
-{
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	int val, r;
-	enum omap_dss_update_mode mode;
-
-	if (!dssdev->driver->set_update_mode)
-		return -EINVAL;
-
-	r = kstrtoint(buf, 0, &val);
-	if (r)
-		return r;
-
-	switch (val) {
-	case OMAP_DSS_UPDATE_DISABLED:
-	case OMAP_DSS_UPDATE_AUTO:
-	case OMAP_DSS_UPDATE_MANUAL:
-		mode = (enum omap_dss_update_mode)val;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	r = dssdev->driver->set_update_mode(dssdev, mode);
-	if (r)
-		return r;
-
-	return size;
-}
-
 static ssize_t display_tear_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
@@ -294,8 +252,6 @@ static ssize_t display_wss_store(struct device *dev,
 
 static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
 		display_enabled_show, display_enabled_store);
-static DEVICE_ATTR(update_mode, S_IRUGO|S_IWUSR,
-		display_upd_mode_show, display_upd_mode_store);
 static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
 		display_tear_show, display_tear_store);
 static DEVICE_ATTR(timings, S_IRUGO|S_IWUSR,
@@ -309,7 +265,6 @@ static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
 
 static struct device_attribute *display_sysfs_attrs[] = {
 	&dev_attr_enabled,
-	&dev_attr_update_mode,
 	&dev_attr_tear_elim,
 	&dev_attr_timings,
 	&dev_attr_rotate,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 9aeea50..18a1b92 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -416,8 +416,6 @@ struct overlay_cache_data {
 	enum omap_burst_size burst_size;
 	u32 fifo_low;
 	u32 fifo_high;
-
-	bool manual_update;
 };
 
 struct manager_cache_data {
@@ -437,7 +435,6 @@ struct manager_cache_data {
 
 	bool alpha_enabled;
 
-	bool manual_upd_display;
 	bool manual_update;
 	bool do_manual_update;
 
@@ -539,24 +536,15 @@ static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
 	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
+		return 0;
+
 	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
 			|| dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
 		irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
 	} else {
-		if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
-			enum omap_dss_update_mode mode;
-			mode = dssdev->driver->get_update_mode(dssdev);
-			if (mode != OMAP_DSS_UPDATE_AUTO)
-				return 0;
-
-			irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
-				DISPC_IRQ_FRAMEDONE
-				: DISPC_IRQ_FRAMEDONE2;
-		} else {
-			irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
-				DISPC_IRQ_VSYNC
-				: DISPC_IRQ_VSYNC2;
-		}
+		irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
+			DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
 	}
 
 	mc = &dss_cache.manager_cache[mgr->id];
@@ -617,24 +605,15 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
 	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
+		return 0;
+
 	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
 			|| dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
 		irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
 	} else {
-		if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
-			enum omap_dss_update_mode mode;
-			mode = dssdev->driver->get_update_mode(dssdev);
-			if (mode != OMAP_DSS_UPDATE_AUTO)
-				return 0;
-
-			irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
-				DISPC_IRQ_FRAMEDONE
-				: DISPC_IRQ_FRAMEDONE2;
-		} else {
-			irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
-				DISPC_IRQ_VSYNC
-				: DISPC_IRQ_VSYNC2;
-		}
+		irq = (dssdev->manager->id = OMAP_DSS_CHANNEL_LCD) ?
+			DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
 	}
 
 	oc = &dss_cache.overlay_cache[ovl->id];
@@ -763,7 +742,7 @@ static int configure_overlay(enum omap_plane plane)
 	orig_outw = outw;
 	orig_outh = outh;
 
-	if (c->manual_update && mc->do_manual_update) {
+	if (mc->manual_update && mc->do_manual_update) {
 		unsigned bpp;
 		unsigned scale_x_m = w, scale_x_d = outw;
 		unsigned scale_y_m = h, scale_y_d = outh;
@@ -928,7 +907,7 @@ static int configure_dispc(void)
 		if (!oc->dirty)
 			continue;
 
-		if (oc->manual_update && !mc->do_manual_update)
+		if (mc->manual_update && !mc->do_manual_update)
 			continue;
 
 		if (mgr_busy[oc->channel]) {
@@ -976,7 +955,7 @@ static int configure_dispc(void)
 		/* We don't need GO with manual update display. LCD iface will
 		 * always be turned off after frame, and new settings will be
 		 * taken in to use at next update */
-		if (!mc->manual_upd_display)
+		if (!mc->manual_update)
 			dispc_go(i);
 	}
 
@@ -1302,11 +1281,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
 
 		oc->enabled = true;
 
-		oc->manual_update -			dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
-			dssdev->driver->get_update_mode(dssdev) !-				OMAP_DSS_UPDATE_AUTO;
-
 		++num_planes_enabled;
 	}
 
@@ -1341,13 +1315,8 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
 		mc->trans_enabled = mgr->info.trans_enabled;
 		mc->alpha_enabled = mgr->info.alpha_enabled;
 
-		mc->manual_upd_display -			dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
-
 		mc->manual_update -			dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
-			dssdev->driver->get_update_mode(dssdev) !-				OMAP_DSS_UPDATE_AUTO;
+			dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
 	}
 
 	/* XXX TODO: Try to get fifomerge working. The problem is that it
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 980f919..e7485fc 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -538,20 +538,6 @@ static int venc_panel_resume(struct omap_dss_device *dssdev)
 	return venc_panel_enable(dssdev);
 }
 
-static enum omap_dss_update_mode venc_get_update_mode(
-		struct omap_dss_device *dssdev)
-{
-	return OMAP_DSS_UPDATE_AUTO;
-}
-
-static int venc_set_update_mode(struct omap_dss_device *dssdev,
-		enum omap_dss_update_mode mode)
-{
-	if (mode != OMAP_DSS_UPDATE_AUTO)
-		return -EINVAL;
-	return 0;
-}
-
 static void venc_get_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings)
 {
@@ -632,9 +618,6 @@ static struct omap_dss_driver venc_driver = {
 	.get_resolution	= omapdss_default_get_resolution,
 	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
 
-	.set_update_mode = venc_set_update_mode,
-	.get_update_mode = venc_get_update_mode,
-
 	.get_timings	= venc_get_timings,
 	.set_timings	= venc_set_timings,
 	.check_timings	= venc_check_timings,
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index bb39738..388577d 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -134,12 +134,6 @@ enum omap_display_caps {
 	OMAP_DSS_DISPLAY_CAP_TEAR_ELIM		= 1 << 1,
 };
 
-enum omap_dss_update_mode {
-	OMAP_DSS_UPDATE_DISABLED = 0,
-	OMAP_DSS_UPDATE_AUTO,
-	OMAP_DSS_UPDATE_MANUAL,
-};
-
 enum omap_dss_display_state {
 	OMAP_DSS_DISPLAY_DISABLED = 0,
 	OMAP_DSS_DISPLAY_ACTIVE,
@@ -524,11 +518,6 @@ struct omap_dss_driver {
 	int (*resume)(struct omap_dss_device *display);
 	int (*run_test)(struct omap_dss_device *display, int test);
 
-	int (*set_update_mode)(struct omap_dss_device *dssdev,
-			enum omap_dss_update_mode);
-	enum omap_dss_update_mode (*get_update_mode)(
-			struct omap_dss_device *dssdev);
-
 	int (*update)(struct omap_dss_device *dssdev,
 			       u16 x, u16 y, u16 w, u16 h);
 	int (*sync)(struct omap_dss_device *dssdev);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 2/3] OMAP: DSS2: OMAPFB: Implement auto-update mode
From: Tomi Valkeinen @ 2011-06-13  9:12 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1307956374-1107-1-git-send-email-tomi.valkeinen@ti.com>

Implement auto-update mode for manual-update displays. omapfb driver
uses a delayed work to update the display with a constant rate.

The update mode can be changed via OMAPFB_SET_UPDATE_MODE ioctl, which
previously called omapdss but is now handled inside omapfb, and a new
sysfs file, "update_mode".

The update interval is by default 20 times per second, but can be
changed via "auto_update_freq" module parameter. There is also a new
module parameter "auto_update", which will make omapfb start manual
update displays in auto-update mode.

This auto-update mode can be used for testing if the userspace does not
support manual update displays properly. However, it is a very
inefficient solution, and should be considered more as a hack for
testing than something that could be used as a long term solution.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/omapfb/omapfb-ioctl.c |   72 ++++++++--------
 drivers/video/omap2/omapfb/omapfb-main.c  |  130 ++++++++++++++++++++++++----
 drivers/video/omap2/omapfb/omapfb-sysfs.c |   34 ++++++++
 drivers/video/omap2/omapfb/omapfb.h       |   13 +++
 4 files changed, 194 insertions(+), 55 deletions(-)

diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index cff4503..6b1ac23 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -316,67 +316,67 @@ int omapfb_update_window(struct fb_info *fbi,
 }
 EXPORT_SYMBOL(omapfb_update_window);
 
-static int omapfb_set_update_mode(struct fb_info *fbi,
+int omapfb_set_update_mode(struct fb_info *fbi,
 				   enum omapfb_update_mode mode)
 {
 	struct omap_dss_device *display = fb2display(fbi);
-	enum omap_dss_update_mode um;
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omapfb_display_data *d;
 	int r;
 
-	if (!display || !display->driver->set_update_mode)
+	if (!display)
 		return -EINVAL;
 
-	switch (mode) {
-	case OMAPFB_UPDATE_DISABLED:
-		um = OMAP_DSS_UPDATE_DISABLED;
-		break;
+	if (mode != OMAPFB_AUTO_UPDATE && mode != OMAPFB_MANUAL_UPDATE)
+		return -EINVAL;
 
-	case OMAPFB_AUTO_UPDATE:
-		um = OMAP_DSS_UPDATE_AUTO;
-		break;
+	omapfb_lock(fbdev);
 
-	case OMAPFB_MANUAL_UPDATE:
-		um = OMAP_DSS_UPDATE_MANUAL;
-		break;
+	d = get_display_data(fbdev, display);
 
-	default:
-		return -EINVAL;
+	if (d->update_mode = mode) {
+		omapfb_unlock(fbdev);
+		return 0;
 	}
 
-	r = display->driver->set_update_mode(display, um);
+	r = 0;
+
+	if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
+		if (mode = OMAPFB_AUTO_UPDATE)
+			omapfb_start_auto_update(fbdev, display);
+		else /* MANUAL_UPDATE */
+			omapfb_stop_auto_update(fbdev, display);
+
+		d->update_mode = mode;
+	} else { /* AUTO_UPDATE */
+		if (mode = OMAPFB_MANUAL_UPDATE)
+			r = -EINVAL;
+	}
+
+	omapfb_unlock(fbdev);
 
 	return r;
 }
 
-static int omapfb_get_update_mode(struct fb_info *fbi,
+int omapfb_get_update_mode(struct fb_info *fbi,
 		enum omapfb_update_mode *mode)
 {
 	struct omap_dss_device *display = fb2display(fbi);
-	enum omap_dss_update_mode m;
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omapfb_display_data *d;
 
 	if (!display)
 		return -EINVAL;
 
-	if (!display->driver->get_update_mode) {
-		*mode = OMAPFB_AUTO_UPDATE;
-		return 0;
-	}
+	omapfb_lock(fbdev);
 
-	m = display->driver->get_update_mode(display);
+	d = get_display_data(fbdev, display);
 
-	switch (m) {
-	case OMAP_DSS_UPDATE_DISABLED:
-		*mode = OMAPFB_UPDATE_DISABLED;
-		break;
-	case OMAP_DSS_UPDATE_AUTO:
-		*mode = OMAPFB_AUTO_UPDATE;
-		break;
-	case OMAP_DSS_UPDATE_MANUAL:
-		*mode = OMAPFB_MANUAL_UPDATE;
-		break;
-	default:
-		BUG();
-	}
+	*mode = d->update_mode;
+
+	omapfb_unlock(fbdev);
 
 	return 0;
 }
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 44eb666..c2514a2 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -46,6 +46,10 @@ static char *def_vram;
 static int def_vrfb;
 static int def_rotate;
 static int def_mirror;
+static bool auto_update;
+static unsigned int auto_update_freq;
+module_param(auto_update, bool, 0);
+module_param(auto_update_freq, uint, 0644);
 
 #ifdef DEBUG
 unsigned int omapfb_debug;
@@ -1242,6 +1246,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
 	struct omapfb_info *ofbi = FB2OFB(fbi);
 	struct omapfb2_device *fbdev = ofbi->fbdev;
 	struct omap_dss_device *display = fb2display(fbi);
+	struct omapfb_display_data *d;
 	int r = 0;
 
 	if (!display)
@@ -1249,6 +1254,8 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
 
 	omapfb_lock(fbdev);
 
+	d = get_display_data(fbdev, display);
+
 	switch (blank) {
 	case FB_BLANK_UNBLANK:
 		if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
@@ -1257,6 +1264,11 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
 		if (display->driver->resume)
 			r = display->driver->resume(display);
 
+		if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) &&
+				d->update_mode = OMAPFB_AUTO_UPDATE &&
+				!d->auto_update_work_enabled)
+			omapfb_start_auto_update(fbdev, display);
+
 		break;
 
 	case FB_BLANK_NORMAL:
@@ -1268,6 +1280,9 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
 		if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
 			goto exit;
 
+		if (d->auto_update_work_enabled)
+			omapfb_stop_auto_update(fbdev, display);
+
 		if (display->driver->suspend)
 			r = display->driver->suspend(display);
 
@@ -1724,6 +1739,78 @@ err:
 	return r;
 }
 
+static void omapfb_auto_update_work(struct work_struct *work)
+{
+	struct omap_dss_device *dssdev;
+	struct omap_dss_driver *dssdrv;
+	struct omapfb_display_data *d;
+	u16 w, h;
+	unsigned int freq;
+	struct omapfb2_device *fbdev;
+
+	d = container_of(work, struct omapfb_display_data,
+			auto_update_work.work);
+
+	dssdev = d->dssdev;
+	dssdrv = dssdev->driver;
+	fbdev = d->fbdev;
+
+	if (!dssdrv || !dssdrv->update)
+		return;
+
+	if (dssdrv->sync)
+		dssdrv->sync(dssdev);
+
+	dssdrv->get_resolution(dssdev, &w, &h);
+	dssdrv->update(dssdev, 0, 0, w, h);
+
+	freq = auto_update_freq;
+	if (freq = 0)
+		freq = 20;
+	queue_delayed_work(fbdev->auto_update_wq,
+			&d->auto_update_work, HZ / freq);
+}
+
+void omapfb_start_auto_update(struct omapfb2_device *fbdev,
+		struct omap_dss_device *display)
+{
+	struct omapfb_display_data *d;
+
+	if (fbdev->auto_update_wq = NULL) {
+		struct workqueue_struct *wq;
+
+		wq = create_singlethread_workqueue("omapfb_auto_update");
+
+		if (wq = NULL) {
+			dev_err(fbdev->dev, "Failed to create workqueue for "
+					"auto-update\n");
+			return;
+		}
+
+		fbdev->auto_update_wq = wq;
+	}
+
+	d = get_display_data(fbdev, display);
+
+	INIT_DELAYED_WORK(&d->auto_update_work, omapfb_auto_update_work);
+
+	d->auto_update_work_enabled = true;
+
+	omapfb_auto_update_work(&d->auto_update_work.work);
+}
+
+void omapfb_stop_auto_update(struct omapfb2_device *fbdev,
+		struct omap_dss_device *display)
+{
+	struct omapfb_display_data *d;
+
+	d = get_display_data(fbdev, display);
+
+	cancel_delayed_work_sync(&d->auto_update_work);
+
+	d->auto_update_work_enabled = false;
+}
+
 /* initialize fb_info, var, fix to something sane based on the display */
 static int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
 {
@@ -1859,12 +1946,22 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
 
 	for (i = 0; i < fbdev->num_displays; i++) {
 		struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
+
+		if (fbdev->displays[i].auto_update_work_enabled)
+			omapfb_stop_auto_update(fbdev, dssdev);
+
 		if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
 			dssdev->driver->disable(dssdev);
 
 		omap_dss_put_device(dssdev);
 	}
 
+	if (fbdev->auto_update_wq != NULL) {
+		flush_workqueue(fbdev->auto_update_wq);
+		destroy_workqueue(fbdev->auto_update_wq);
+		fbdev->auto_update_wq = NULL;
+	}
+
 	dev_set_drvdata(fbdev->dev, NULL);
 	kfree(fbdev);
 }
@@ -2183,6 +2280,7 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
 		struct omap_dss_device *dssdev)
 {
 	struct omap_dss_driver *dssdrv = dssdev->driver;
+	struct omapfb_display_data *d;
 	int r;
 
 	r = dssdrv->enable(dssdev);
@@ -2192,8 +2290,20 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
 		return r;
 	}
 
+	d = get_display_data(fbdev, dssdev);
+
+	d->fbdev = fbdev;
+
 	if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
 		u16 w, h;
+
+		if (auto_update) {
+			omapfb_start_auto_update(fbdev, dssdev);
+			d->update_mode = OMAPFB_AUTO_UPDATE;
+		} else {
+			d->update_mode = OMAPFB_MANUAL_UPDATE;
+		}
+
 		if (dssdrv->enable_te) {
 			r = dssdrv->enable_te(dssdev, 1);
 			if (r) {
@@ -2202,16 +2312,6 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
 			}
 		}
 
-		if (dssdrv->set_update_mode) {
-			r = dssdrv->set_update_mode(dssdev,
-					OMAP_DSS_UPDATE_MANUAL);
-			if (r) {
-				dev_err(fbdev->dev,
-						"Failed to set update mode\n");
-				return r;
-			}
-		}
-
 		dssdrv->get_resolution(dssdev, &w, &h);
 		r = dssdrv->update(dssdev, 0, 0, w, h);
 		if (r) {
@@ -2220,15 +2320,7 @@ static int omapfb_init_display(struct omapfb2_device *fbdev,
 			return r;
 		}
 	} else {
-		if (dssdrv->set_update_mode) {
-			r = dssdrv->set_update_mode(dssdev,
-					OMAP_DSS_UPDATE_AUTO);
-			if (r) {
-				dev_err(fbdev->dev,
-						"Failed to set update mode\n");
-				return r;
-			}
-		}
+		d->update_mode = OMAPFB_AUTO_UPDATE;
 	}
 
 	return 0;
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 2f5e817..153bf1a 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -518,6 +518,39 @@ static ssize_t show_virt(struct device *dev,
 	return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region->vaddr);
 }
 
+static ssize_t show_upd_mode(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	enum omapfb_update_mode mode;
+	int r;
+
+	r = omapfb_get_update_mode(fbi, &mode);
+
+	if (r)
+		return r;
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", (unsigned)mode);
+}
+
+static ssize_t store_upd_mode(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	struct fb_info *fbi = dev_get_drvdata(dev);
+	unsigned mode;
+	int r;
+
+	r = kstrtouint(buf, 0, &mode);
+	if (r)
+		return r;
+
+	r = omapfb_set_update_mode(fbi, mode);
+	if (r)
+		return r;
+
+	return count;
+}
+
 static struct device_attribute omapfb_attrs[] = {
 	__ATTR(rotate_type, S_IRUGO | S_IWUSR, show_rotate_type,
 			store_rotate_type),
@@ -528,6 +561,7 @@ static struct device_attribute omapfb_attrs[] = {
 			store_overlays_rotate),
 	__ATTR(phys_addr, S_IRUGO, show_phys, NULL),
 	__ATTR(virt_addr, S_IRUGO, show_virt, NULL),
+	__ATTR(update_mode, S_IRUGO | S_IWUSR, show_upd_mode, store_upd_mode),
 };
 
 int omapfb_create_sysfs(struct omapfb2_device *fbdev)
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index f07dbbb..fdf0ede 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -74,8 +74,12 @@ struct omapfb_info {
 };
 
 struct omapfb_display_data {
+	struct omapfb2_device *fbdev;
 	struct omap_dss_device *dssdev;
 	u8 bpp_override;
+	enum omapfb_update_mode update_mode;
+	bool auto_update_work_enabled;
+	struct delayed_work auto_update_work;
 };
 
 struct omapfb2_device {
@@ -96,6 +100,8 @@ struct omapfb2_device {
 	struct omap_overlay *overlays[10];
 	unsigned num_managers;
 	struct omap_overlay_manager *managers[10];
+
+	struct workqueue_struct *auto_update_wq;
 };
 
 struct omapfb_colormode {
@@ -127,6 +133,13 @@ int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
 int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
 		u16 posx, u16 posy, u16 outw, u16 outh);
 
+void omapfb_start_auto_update(struct omapfb2_device *fbdev,
+		struct omap_dss_device *display);
+void omapfb_stop_auto_update(struct omapfb2_device *fbdev,
+		struct omap_dss_device *display);
+int omapfb_get_update_mode(struct fb_info *fbi, enum omapfb_update_mode *mode);
+int omapfb_set_update_mode(struct fb_info *fbi, enum omapfb_update_mode mode);
+
 /* find the display connected to this fb, if any */
 static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
 {
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 1/3] OMAP: DSS2: OMAPFB: Add struct to store per-display data
From: Tomi Valkeinen @ 2011-06-13  9:12 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1307956374-1107-1-git-send-email-tomi.valkeinen@ti.com>

Create a new struct omapfb_display_data to contain omapfb's private
per-display data. Move the bpp override there.

This struct will be used to hold auto/manual update state of a display
in the following patches.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/omapfb/omapfb-main.c |   29 +++++++++++++++--------------
 drivers/video/omap2/omapfb/omapfb.h      |   26 +++++++++++++++++++-------
 2 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 505bc12..44eb666 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1858,10 +1858,11 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
 	}
 
 	for (i = 0; i < fbdev->num_displays; i++) {
-		if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED)
-			fbdev->displays[i]->driver->disable(fbdev->displays[i]);
+		struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
+		if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
+			dssdev->driver->disable(dssdev);
 
-		omap_dss_put_device(fbdev->displays[i]);
+		omap_dss_put_device(dssdev);
 	}
 
 	dev_set_drvdata(fbdev->dev, NULL);
@@ -2084,14 +2085,14 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
 	int r;
 	u8 bpp;
 	struct omap_video_timings timings, temp_timings;
+	struct omapfb_display_data *d;
 
 	r = omapfb_mode_to_timings(mode_str, &timings, &bpp);
 	if (r)
 		return r;
 
-	fbdev->bpp_overrides[fbdev->num_bpp_overrides].dssdev = display;
-	fbdev->bpp_overrides[fbdev->num_bpp_overrides].bpp = bpp;
-	++fbdev->num_bpp_overrides;
+	d = get_display_data(fbdev, display);
+	d->bpp_override = bpp;
 
 	if (display->driver->check_timings) {
 		r = display->driver->check_timings(display, &timings);
@@ -2117,14 +2118,14 @@ static int omapfb_set_def_mode(struct omapfb2_device *fbdev,
 static int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev,
 		struct omap_dss_device *dssdev)
 {
-	int i;
+	struct omapfb_display_data *d;
 
 	BUG_ON(dssdev->driver->get_recommended_bpp = NULL);
 
-	for (i = 0; i < fbdev->num_bpp_overrides; ++i) {
-		if (dssdev = fbdev->bpp_overrides[i].dssdev)
-			return fbdev->bpp_overrides[i].bpp;
-	}
+	d = get_display_data(fbdev, dssdev);
+
+	if (d->bpp_override != 0)
+		return d->bpp_override;
 
 	return dssdev->driver->get_recommended_bpp(dssdev);
 }
@@ -2156,9 +2157,9 @@ static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
 
 		display = NULL;
 		for (i = 0; i < fbdev->num_displays; ++i) {
-			if (strcmp(fbdev->displays[i]->name,
+			if (strcmp(fbdev->displays[i].dssdev->name,
 						display_str) = 0) {
-				display = fbdev->displays[i];
+				display = fbdev->displays[i].dssdev;
 				break;
 			}
 		}
@@ -2282,7 +2283,7 @@ static int omapfb_probe(struct platform_device *pdev)
 			r = -ENODEV;
 		}
 
-		fbdev->displays[fbdev->num_displays++] = dssdev;
+		fbdev->displays[fbdev->num_displays++].dssdev = dssdev;
 	}
 
 	if (r)
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index aa1b1d9..f07dbbb 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -73,6 +73,11 @@ struct omapfb_info {
 	bool mirror;
 };
 
+struct omapfb_display_data {
+	struct omap_dss_device *dssdev;
+	u8 bpp_override;
+};
+
 struct omapfb2_device {
 	struct device *dev;
 	struct mutex  mtx;
@@ -86,17 +91,11 @@ struct omapfb2_device {
 	struct omapfb2_mem_region regions[10];
 
 	unsigned num_displays;
-	struct omap_dss_device *displays[10];
+	struct omapfb_display_data displays[10];
 	unsigned num_overlays;
 	struct omap_overlay *overlays[10];
 	unsigned num_managers;
 	struct omap_overlay_manager *managers[10];
-
-	unsigned num_bpp_overrides;
-	struct {
-		struct omap_dss_device *dssdev;
-		u8 bpp;
-	} bpp_overrides[10];
 };
 
 struct omapfb_colormode {
@@ -143,6 +142,19 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
 	return NULL;
 }
 
+static inline struct omapfb_display_data *get_display_data(
+		struct omapfb2_device *fbdev, struct omap_dss_device *dssdev)
+{
+	int i;
+
+	for (i = 0; i < fbdev->num_displays; ++i)
+		if (fbdev->displays[i].dssdev = dssdev)
+			return &fbdev->displays[i];
+
+	/* This should never happen */
+	BUG();
+}
+
 static inline void omapfb_lock(struct omapfb2_device *fbdev)
 {
 	mutex_lock(&fbdev->mtx);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 0/3] OMAPFB: Move auto-update to omapfb
From: Tomi Valkeinen @ 2011-06-13  9:12 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen

OMAP DSS driver has currently support to change the display's update mode from
manual to auto, but it's up to the display to implement support for this.
Normally displays only support one update mode.

As the the update mode support adds extra code to a place where it doesn't
really belong, this patch set removes update mode support from omapdss, and
implements a simple version of it in omapfb.

This will:
* Clean up omapdss
* Keep the omapfb's ioctl interface intact with functional update-mode ioctls
* Allow us to support auto-update for manual update displays for testing
* Allow us to do the above with the code in single place, for all manual-update
  displays, without any changes needed in display drivers

Auto-update for manual-update displays should be considered a hack, used only
for testing or temporarily running a userspace that doesn't properly support
manual-update displays. It should not be used in production systems.

The patches create a private workqueue for the update work to minimize impact
on other parts of the system. As this auto-update feature is not normally used,
the workqueue is only created when needed.

 Tomi

Tomi Valkeinen (3):
  OMAP: DSS2: OMAPFB: Add struct to store per-display data
  OMAP: DSS2: OMAPFB: Implement auto-update mode
  OMAP: DSS2: remove update_mode from omapdss

 drivers/video/omap2/displays/panel-taal.c |   17 ---
 drivers/video/omap2/dss/display.c         |   45 --------
 drivers/video/omap2/dss/manager.c         |   59 +++--------
 drivers/video/omap2/dss/venc.c            |   17 ---
 drivers/video/omap2/omapfb/omapfb-ioctl.c |   72 +++++++-------
 drivers/video/omap2/omapfb/omapfb-main.c  |  159 +++++++++++++++++++++++------
 drivers/video/omap2/omapfb/omapfb-sysfs.c |   34 ++++++
 drivers/video/omap2/omapfb/omapfb.h       |   37 ++++++-
 include/video/omapdss.h                   |   11 --
 9 files changed, 241 insertions(+), 210 deletions(-)

-- 
1.7.4.1


^ permalink raw reply

* 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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox