Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH 03/16] OMAPDSS: Remove video SRAM support
From: Tomi Valkeinen @ 2012-01-24 10:00 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, tony, Tomi Valkeinen
In-Reply-To: <1327399231-20826-1-git-send-email-tomi.valkeinen@ti.com>

OMAP SRAM can be used as video memory on OMAP1 and 2. However, there
usually is very little SRAM available, thus limiting its use, and no
board supported by the kernel currently uses it.

This patch removes the use of SRAM as video ram for the omapdss driver
to simplify memory handling.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/plat-omap/include/plat/vram.h    |   21 +------
 drivers/video/omap2/dss/dispc.c           |    1 -
 drivers/video/omap2/omapfb/omapfb-ioctl.c |    2 +-
 drivers/video/omap2/omapfb/omapfb-main.c  |    4 +-
 drivers/video/omap2/vram.c                |   99 ++---------------------------
 5 files changed, 9 insertions(+), 118 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/vram.h b/arch/arm/plat-omap/include/plat/vram.h
index 0aa4ecd..4d65b7d 100644
--- a/arch/arm/plat-omap/include/plat/vram.h
+++ b/arch/arm/plat-omap/include/plat/vram.h
@@ -23,40 +23,21 @@
 
 #include <linux/types.h>
 
-#define OMAP_VRAM_MEMTYPE_SDRAM		0
-#define OMAP_VRAM_MEMTYPE_SRAM		1
-#define OMAP_VRAM_MEMTYPE_MAX		1
-
 extern int omap_vram_add_region(unsigned long paddr, size_t size);
 extern int omap_vram_free(unsigned long paddr, size_t size);
-extern int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr);
+extern int omap_vram_alloc(size_t size, unsigned long *paddr);
 extern int omap_vram_reserve(unsigned long paddr, size_t size);
 extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram,
 		unsigned long *largest_free_block);
 
 #ifdef CONFIG_OMAP2_VRAM
 extern void omap_vram_set_sdram_vram(u32 size, u32 start);
-extern void omap_vram_set_sram_vram(u32 size, u32 start);
 
 extern void omap_vram_reserve_sdram_memblock(void);
-extern unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
-					    unsigned long sram_vstart,
-					    unsigned long sram_size,
-					    unsigned long pstart_avail,
-					    unsigned long size_avail);
 #else
 static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
-static inline void omap_vram_set_sram_vram(u32 size, u32 start) { }
 
 static inline void omap_vram_reserve_sdram_memblock(void) { }
-static inline unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
-					    unsigned long sram_vstart,
-					    unsigned long sram_size,
-					    unsigned long pstart_avail,
-					    unsigned long size_avail)
-{
-	return 0;
-}
 #endif
 
 #endif
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a5ec7f3..b82789e 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -37,7 +37,6 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
-#include <plat/sram.h>
 #include <plat/clock.h>
 
 #include <video/omapdss.h>
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 16ba619..6a09ef8 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -215,7 +215,7 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
 	int r = 0, i;
 	size_t size;
 
-	if (mi->type > OMAPFB_MEMTYPE_MAX)
+	if (mi->type != OMAPFB_MEMTYPE_SDRAM)
 		return -EINVAL;
 
 	size = PAGE_ALIGN(mi->size);
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index ce15831..17e7320b 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1399,7 +1399,7 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
 
 	if (!paddr) {
 		DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
-		r = omap_vram_alloc(OMAP_VRAM_MEMTYPE_SDRAM, size, &paddr);
+		r = omap_vram_alloc(size, &paddr);
 	} else {
 		DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
 				ofbi->id);
@@ -1669,7 +1669,7 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
 	int old_type = rg->type;
 	int r;
 
-	if (type > OMAPFB_MEMTYPE_MAX)
+	if (type != OMAPFB_MEMTYPE_SDRAM)
 		return -EINVAL;
 
 	size = PAGE_ALIGN(size);
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 9441e2e..87e421e 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -33,7 +33,6 @@
 
 #include <asm/setup.h>
 
-#include <plat/sram.h>
 #include <plat/vram.h>
 #include <plat/dma.h>
 
@@ -43,10 +42,6 @@
 #define DBG(format, ...)
 #endif
 
-#define OMAP2_SRAM_START		0x40200000
-/* Maximum size, in reality this is smaller if SRAM is partially locked. */
-#define OMAP2_SRAM_SIZE			0xa0000		/* 640k */
-
 /* postponed regions are used to temporarily store region information at boot
  * time when we cannot yet allocate the region list */
 #define MAX_POSTPONED_REGIONS 10
@@ -74,15 +69,6 @@ struct vram_region {
 static DEFINE_MUTEX(region_mutex);
 static LIST_HEAD(region_list);
 
-static inline int region_mem_type(unsigned long paddr)
-{
-	if (paddr >= OMAP2_SRAM_START &&
-	    paddr < OMAP2_SRAM_START + OMAP2_SRAM_SIZE)
-		return OMAP_VRAM_MEMTYPE_SRAM;
-	else
-		return OMAP_VRAM_MEMTYPE_SDRAM;
-}
-
 static struct vram_region *omap_vram_create_region(unsigned long paddr,
 		unsigned pages)
 {
@@ -212,9 +198,6 @@ static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
 
 		DBG("checking region %lx %d\n", rm->paddr, rm->pages);
 
-		if (region_mem_type(rm->paddr) != region_mem_type(paddr))
-			continue;
-
 		start = rm->paddr;
 		end = start + (rm->pages << PAGE_SHIFT) - 1;
 		if (start > paddr || end < paddr + size - 1)
@@ -320,7 +303,7 @@ err:
 	return r;
 }
 
-static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr)
+static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
 {
 	struct vram_region *rm;
 	struct vram_alloc *alloc;
@@ -330,9 +313,6 @@ static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr)
 
 		DBG("checking region %lx %d\n", rm->paddr, rm->pages);
 
-		if (region_mem_type(rm->paddr) != mtype)
-			continue;
-
 		start = rm->paddr;
 
 		list_for_each_entry(alloc, &rm->alloc_list, list) {
@@ -365,21 +345,21 @@ found:
 	return -ENOMEM;
 }
 
-int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr)
+int omap_vram_alloc(size_t size, unsigned long *paddr)
 {
 	unsigned pages;
 	int r;
 
-	BUG_ON(mtype > OMAP_VRAM_MEMTYPE_MAX || !size);
+	BUG_ON(!size);
 
-	DBG("alloc mem type %d size %d\n", mtype, size);
+	DBG("alloc mem size %d\n", size);
 
 	size = PAGE_ALIGN(size);
 	pages = size >> PAGE_SHIFT;
 
 	mutex_lock(&region_mutex);
 
-	r = _omap_vram_alloc(mtype, pages, paddr);
+	r = _omap_vram_alloc(pages, paddr);
 
 	mutex_unlock(&region_mutex);
 
@@ -501,10 +481,6 @@ arch_initcall(omap_vram_init);
 /* boottime vram alloc stuff */
 
 /* set from board file */
-static u32 omap_vram_sram_start __initdata;
-static u32 omap_vram_sram_size __initdata;
-
-/* set from board file */
 static u32 omap_vram_sdram_start __initdata;
 static u32 omap_vram_sdram_size __initdata;
 
@@ -587,73 +563,8 @@ void __init omap_vram_reserve_sdram_memblock(void)
 	pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
 }
 
-/*
- * Called at sram init time, before anything is pushed to the SRAM stack.
- * Because of the stack scheme, we will allocate everything from the
- * start of the lowest address region to the end of SRAM. This will also
- * include padding for page alignment and possible holes between regions.
- *
- * As opposed to the SDRAM case, we'll also do any dynamic allocations at
- * this point, since the driver built as a module would have problem with
- * freeing / reallocating the regions.
- */
-unsigned long __init omap_vram_reserve_sram(unsigned long sram_pstart,
-				  unsigned long sram_vstart,
-				  unsigned long sram_size,
-				  unsigned long pstart_avail,
-				  unsigned long size_avail)
-{
-	unsigned long			pend_avail;
-	unsigned long			reserved;
-	u32 paddr;
-	u32 size;
-
-	paddr = omap_vram_sram_start;
-	size = omap_vram_sram_size;
-
-	if (!size)
-		return 0;
-
-	reserved = 0;
-	pend_avail = pstart_avail + size_avail;
-
-	if (!paddr) {
-		/* Dynamic allocation */
-		if ((size_avail & PAGE_MASK) < size) {
-			pr_err("Not enough SRAM for VRAM\n");
-			return 0;
-		}
-		size_avail = (size_avail - size) & PAGE_MASK;
-		paddr = pstart_avail + size_avail;
-	}
-
-	if (paddr < sram_pstart ||
-			paddr + size > sram_pstart + sram_size) {
-		pr_err("Illegal SRAM region for VRAM\n");
-		return 0;
-	}
-
-	/* Reserve everything above the start of the region. */
-	if (pend_avail - paddr > reserved)
-		reserved = pend_avail - paddr;
-	size_avail = pend_avail - reserved - pstart_avail;
-
-	omap_vram_add_region(paddr, size);
-
-	if (reserved)
-		pr_info("Reserving %lu bytes SRAM for VRAM\n", reserved);
-
-	return reserved;
-}
-
 void __init omap_vram_set_sdram_vram(u32 size, u32 start)
 {
 	omap_vram_sdram_start = start;
 	omap_vram_sdram_size = size;
 }
-
-void __init omap_vram_set_sram_vram(u32 size, u32 start)
-{
-	omap_vram_sram_start = start;
-	omap_vram_sram_size = size;
-}
-- 
1.7.4.1


^ permalink raw reply related

* =?UTF-8?q?=5BPATCH=2002/16=5D=20OMAPFB=3A=20Remove=20OMAP2/3=20support=20from=20old=20omapfb=20drive
From: Tomi Valkeinen @ 2012-01-24 10:00 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, tony, Tomi Valkeinen
In-Reply-To: <1327399231-20826-1-git-send-email-tomi.valkeinen@ti.com>

Old omapfb driver (drivers/video/omap/) is no longer used for OMAP2+
devices, and thus we can remove OMAP2+ support from it and make it an
OMAP1 omapfb driver.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap/Kconfig       |    9 +-
 drivers/video/omap/Makefile      |    5 +-
 drivers/video/omap/dispc.c       | 1547 --------------------------------------
 drivers/video/omap/dispc.h       |   46 --
 drivers/video/omap/omapfb.h      |    4 -
 drivers/video/omap/omapfb_main.c |   16 -
 drivers/video/omap/rfbi.c        |  598 ---------------
 7 files changed, 5 insertions(+), 2220 deletions(-)
 delete mode 100644 drivers/video/omap/dispc.c
 delete mode 100644 drivers/video/omap/dispc.h
 delete mode 100644 drivers/video/omap/rfbi.c

diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index ab234d5..1e7536d 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -1,11 +1,10 @@
 config FB_OMAP
 	tristate "OMAP frame buffer support (EXPERIMENTAL)"
-	depends on FB && (OMAP2_DSS = "n")
-	depends on ARCH_OMAP1 || ARCH_OMAP2 || ARCH_OMAP3
+	depends on FB
+	depends on ARCH_OMAP1
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
-	select TWL4030_CORE if MACH_OMAP_2430SDP
 	help
           Frame buffer driver for OMAP based boards.
 
@@ -42,7 +41,7 @@ config FB_OMAP_LCD_MIPID
 
 config FB_OMAP_BOOTLOADER_INIT
 	bool "Check bootloader initialization"
-	depends on FB_OMAP || FB_OMAP2
+	depends on FB_OMAP
 	help
 	  Say Y here if you want to enable checking if the bootloader has
 	  already initialized the display controller. In this case the
@@ -61,7 +60,7 @@ config FB_OMAP_CONSISTENT_DMA_SIZE
 
 config FB_OMAP_DMA_TUNE
         bool "Set DMA SDRAM access priority high"
-        depends on FB_OMAP && ARCH_OMAP1
+        depends on FB_OMAP
         help
           On systems in which video memory is in system memory
           (SDRAM) this will speed up graphics DMA operations.
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
index 7042a4a..7965375 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/omap/Makefile
@@ -1,5 +1,5 @@
 #
-# Makefile for the new OMAP framebuffer device driver
+# Makefile for the OMAP1 framebuffer device driver
 #
 
 obj-$(CONFIG_FB_OMAP) += omapfb.o
@@ -7,11 +7,8 @@ obj-$(CONFIG_FB_OMAP) += omapfb.o
 objs-yy := omapfb_main.o
 
 objs-y$(CONFIG_ARCH_OMAP1) += lcdc.o
-objs-y$(CONFIG_ARCH_OMAP2) += dispc.o
-objs-y$(CONFIG_ARCH_OMAP3) += dispc.o
 
 objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o
-objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o
 
 objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
 
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
deleted file mode 100644
index 6f61e78..0000000
--- a/drivers/video/omap/dispc.c
+++ /dev/null
@@ -1,1547 +0,0 @@
-/*
- * OMAP2 display controller support
- *
- * Copyright (C) 2005 Nokia Corporation
- * Author: Imre Deak <imre.deak@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <plat/sram.h>
-#include <plat/board.h>
-
-#include "omapfb.h"
-#include "dispc.h"
-
-#define MODULE_NAME			"dispc"
-
-#define DSS_BASE			0x48050000
-#define DSS_SYSCONFIG			0x0010
-
-#define DISPC_BASE			0x48050400
-
-/* DISPC common */
-#define DISPC_REVISION			0x0000
-#define DISPC_SYSCONFIG			0x0010
-#define DISPC_SYSSTATUS			0x0014
-#define DISPC_IRQSTATUS			0x0018
-#define DISPC_IRQENABLE			0x001C
-#define DISPC_CONTROL			0x0040
-#define DISPC_CONFIG			0x0044
-#define DISPC_CAPABLE			0x0048
-#define DISPC_DEFAULT_COLOR0		0x004C
-#define DISPC_DEFAULT_COLOR1		0x0050
-#define DISPC_TRANS_COLOR0		0x0054
-#define DISPC_TRANS_COLOR1		0x0058
-#define DISPC_LINE_STATUS		0x005C
-#define DISPC_LINE_NUMBER		0x0060
-#define DISPC_TIMING_H			0x0064
-#define DISPC_TIMING_V			0x0068
-#define DISPC_POL_FREQ			0x006C
-#define DISPC_DIVISOR			0x0070
-#define DISPC_SIZE_DIG			0x0078
-#define DISPC_SIZE_LCD			0x007C
-
-#define DISPC_DATA_CYCLE1		0x01D4
-#define DISPC_DATA_CYCLE2		0x01D8
-#define DISPC_DATA_CYCLE3		0x01DC
-
-/* DISPC GFX plane */
-#define DISPC_GFX_BA0			0x0080
-#define DISPC_GFX_BA1			0x0084
-#define DISPC_GFX_POSITION		0x0088
-#define DISPC_GFX_SIZE			0x008C
-#define DISPC_GFX_ATTRIBUTES		0x00A0
-#define DISPC_GFX_FIFO_THRESHOLD	0x00A4
-#define DISPC_GFX_FIFO_SIZE_STATUS	0x00A8
-#define DISPC_GFX_ROW_INC		0x00AC
-#define DISPC_GFX_PIXEL_INC		0x00B0
-#define DISPC_GFX_WINDOW_SKIP		0x00B4
-#define DISPC_GFX_TABLE_BA		0x00B8
-
-/* DISPC Video plane 1/2 */
-#define DISPC_VID1_BASE			0x00BC
-#define DISPC_VID2_BASE			0x014C
-
-/* Offsets into DISPC_VID1/2_BASE */
-#define DISPC_VID_BA0			0x0000
-#define DISPC_VID_BA1			0x0004
-#define DISPC_VID_POSITION		0x0008
-#define DISPC_VID_SIZE			0x000C
-#define DISPC_VID_ATTRIBUTES		0x0010
-#define DISPC_VID_FIFO_THRESHOLD	0x0014
-#define DISPC_VID_FIFO_SIZE_STATUS	0x0018
-#define DISPC_VID_ROW_INC		0x001C
-#define DISPC_VID_PIXEL_INC		0x0020
-#define DISPC_VID_FIR			0x0024
-#define DISPC_VID_PICTURE_SIZE		0x0028
-#define DISPC_VID_ACCU0			0x002C
-#define DISPC_VID_ACCU1			0x0030
-
-/* 8 elements in 8 byte increments */
-#define DISPC_VID_FIR_COEF_H0		0x0034
-/* 8 elements in 8 byte increments */
-#define DISPC_VID_FIR_COEF_HV0		0x0038
-/* 5 elements in 4 byte increments */
-#define DISPC_VID_CONV_COEF0		0x0074
-
-#define DISPC_IRQ_FRAMEMASK		0x0001
-#define DISPC_IRQ_VSYNC			0x0002
-#define DISPC_IRQ_EVSYNC_EVEN		0x0004
-#define DISPC_IRQ_EVSYNC_ODD		0x0008
-#define DISPC_IRQ_ACBIAS_COUNT_STAT	0x0010
-#define DISPC_IRQ_PROG_LINE_NUM		0x0020
-#define DISPC_IRQ_GFX_FIFO_UNDERFLOW	0x0040
-#define DISPC_IRQ_GFX_END_WIN		0x0080
-#define DISPC_IRQ_PAL_GAMMA_MASK	0x0100
-#define DISPC_IRQ_OCP_ERR		0x0200
-#define DISPC_IRQ_VID1_FIFO_UNDERFLOW	0x0400
-#define DISPC_IRQ_VID1_END_WIN		0x0800
-#define DISPC_IRQ_VID2_FIFO_UNDERFLOW	0x1000
-#define DISPC_IRQ_VID2_END_WIN		0x2000
-#define DISPC_IRQ_SYNC_LOST		0x4000
-
-#define DISPC_IRQ_MASK_ALL		0x7fff
-
-#define DISPC_IRQ_MASK_ERROR		(DISPC_IRQ_GFX_FIFO_UNDERFLOW |	\
-					     DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
-					     DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
-					     DISPC_IRQ_SYNC_LOST)
-
-#define RFBI_CONTROL			0x48050040
-
-#define MAX_PALETTE_SIZE		(256 * 16)
-
-#define FLD_MASK(pos, len)	(((1 << len) - 1) << pos)
-
-#define MOD_REG_FLD(reg, mask, val) \
-	dispc_write_reg((reg), (dispc_read_reg(reg) & ~(mask)) | (val));
-
-#define OMAP2_SRAM_START		0x40200000
-/* Maximum size, in reality this is smaller if SRAM is partially locked. */
-#define OMAP2_SRAM_SIZE			0xa0000		/* 640k */
-
-/* We support the SDRAM / SRAM types. See OMAPFB_PLANE_MEMTYPE_* in omapfb.h */
-#define DISPC_MEMTYPE_NUM		2
-
-#define RESMAP_SIZE(_page_cnt)						\
-	((_page_cnt + (sizeof(unsigned long) * 8) - 1) / 8)
-#define RESMAP_PTR(_res_map, _page_nr)					\
-	(((_res_map)->map) + (_page_nr) / (sizeof(unsigned long) * 8))
-#define RESMAP_MASK(_page_nr)						\
-	(1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1)))
-
-struct resmap {
-	unsigned long	start;
-	unsigned	page_cnt;
-	unsigned long	*map;
-};
-
-#define MAX_IRQ_HANDLERS            4
-
-static struct {
-	void __iomem	*base;
-
-	struct omapfb_mem_desc	mem_desc;
-	struct resmap		*res_map[DISPC_MEMTYPE_NUM];
-	atomic_t		map_count[OMAPFB_PLANE_NUM];
-
-	dma_addr_t	palette_paddr;
-	void		*palette_vaddr;
-
-	int		ext_mode;
-
-	struct {
-		u32	irq_mask;
-		void	(*callback)(void *);
-		void	*data;
-	} irq_handlers[MAX_IRQ_HANDLERS];
-	struct completion	frame_done;
-
-	int		fir_hinc[OMAPFB_PLANE_NUM];
-	int		fir_vinc[OMAPFB_PLANE_NUM];
-
-	struct clk	*dss_ick, *dss1_fck;
-	struct clk	*dss_54m_fck;
-
-	enum omapfb_update_mode	update_mode;
-	struct omapfb_device	*fbdev;
-
-	struct omapfb_color_key	color_key;
-} dispc;
-
-static void enable_lcd_clocks(int enable);
-
-static void inline dispc_write_reg(int idx, u32 val)
-{
-	__raw_writel(val, dispc.base + idx);
-}
-
-static u32 inline dispc_read_reg(int idx)
-{
-	u32 l = __raw_readl(dispc.base + idx);
-	return l;
-}
-
-/* Select RFBI or bypass mode */
-static void enable_rfbi_mode(int enable)
-{
-	void __iomem *rfbi_control;
-	u32 l;
-
-	l = dispc_read_reg(DISPC_CONTROL);
-	/* Enable RFBI, GPIO0/1 */
-	l &= ~((1 << 11) | (1 << 15) | (1 << 16));
-	l |= enable ? (1 << 11) : 0;
-	/* RFBI En: GPIO0/1\x10  RFBI Dis: GPIO0/1\x11 */
-	l |= 1 << 15;
-	l |= enable ? 0 : (1 << 16);
-	dispc_write_reg(DISPC_CONTROL, l);
-
-	/* Set bypass mode in RFBI module */
-	rfbi_control = ioremap(RFBI_CONTROL, SZ_1K);
-	if (!rfbi_control) {
-		pr_err("Unable to ioremap rfbi_control\n");
-		return;
-	}
-	l = __raw_readl(rfbi_control);
-	l |= enable ? 0 : (1 << 1);
-	__raw_writel(l, rfbi_control);
-	iounmap(rfbi_control);
-}
-
-static void set_lcd_data_lines(int data_lines)
-{
-	u32 l;
-	int code = 0;
-
-	switch (data_lines) {
-	case 12:
-		code = 0;
-		break;
-	case 16:
-		code = 1;
-		break;
-	case 18:
-		code = 2;
-		break;
-	case 24:
-		code = 3;
-		break;
-	default:
-		BUG();
-	}
-
-	l = dispc_read_reg(DISPC_CONTROL);
-	l &= ~(0x03 << 8);
-	l |= code << 8;
-	dispc_write_reg(DISPC_CONTROL, l);
-}
-
-static void set_load_mode(int mode)
-{
-	BUG_ON(mode & ~(DISPC_LOAD_CLUT_ONLY | DISPC_LOAD_FRAME_ONLY |
-			DISPC_LOAD_CLUT_ONCE_FRAME));
-	MOD_REG_FLD(DISPC_CONFIG, 0x03 << 1, mode << 1);
-}
-
-void omap_dispc_set_lcd_size(int x, int y)
-{
-	BUG_ON((x > (1 << 11)) || (y > (1 << 11)));
-	enable_lcd_clocks(1);
-	MOD_REG_FLD(DISPC_SIZE_LCD, FLD_MASK(16, 11) | FLD_MASK(0, 11),
-			((y - 1) << 16) | (x - 1));
-	enable_lcd_clocks(0);
-}
-EXPORT_SYMBOL(omap_dispc_set_lcd_size);
-
-void omap_dispc_set_digit_size(int x, int y)
-{
-	BUG_ON((x > (1 << 11)) || (y > (1 << 11)));
-	enable_lcd_clocks(1);
-	MOD_REG_FLD(DISPC_SIZE_DIG, FLD_MASK(16, 11) | FLD_MASK(0, 11),
-			((y - 1) << 16) | (x - 1));
-	enable_lcd_clocks(0);
-}
-EXPORT_SYMBOL(omap_dispc_set_digit_size);
-
-static void setup_plane_fifo(int plane, int ext_mode)
-{
-	const u32 ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD,
-				DISPC_VID1_BASE + DISPC_VID_FIFO_THRESHOLD,
-			        DISPC_VID2_BASE + DISPC_VID_FIFO_THRESHOLD };
-	const u32 fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS,
-				DISPC_VID1_BASE + DISPC_VID_FIFO_SIZE_STATUS,
-				DISPC_VID2_BASE + DISPC_VID_FIFO_SIZE_STATUS };
-	int low, high;
-	u32 l;
-
-	BUG_ON(plane > 2);
-
-	l = dispc_read_reg(fsz_reg[plane]);
-	l &= FLD_MASK(0, 11);
-	if (ext_mode) {
-		low = l * 3 / 4;
-		high = l;
-	} else {
-		low = l / 4;
-		high = l * 3 / 4;
-	}
-	MOD_REG_FLD(ftrs_reg[plane], FLD_MASK(16, 12) | FLD_MASK(0, 12),
-			(high << 16) | low);
-}
-
-void omap_dispc_enable_lcd_out(int enable)
-{
-	enable_lcd_clocks(1);
-	MOD_REG_FLD(DISPC_CONTROL, 1, enable ? 1 : 0);
-	enable_lcd_clocks(0);
-}
-EXPORT_SYMBOL(omap_dispc_enable_lcd_out);
-
-void omap_dispc_enable_digit_out(int enable)
-{
-	enable_lcd_clocks(1);
-	MOD_REG_FLD(DISPC_CONTROL, 1 << 1, enable ? 1 << 1 : 0);
-	enable_lcd_clocks(0);
-}
-EXPORT_SYMBOL(omap_dispc_enable_digit_out);
-
-static inline int _setup_plane(int plane, int channel_out,
-				  u32 paddr, int screen_width,
-				  int pos_x, int pos_y, int width, int height,
-				  int color_mode)
-{
-	const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES,
-				DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
-			        DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
-	const u32 ba_reg[] = { DISPC_GFX_BA0, DISPC_VID1_BASE + DISPC_VID_BA0,
-				DISPC_VID2_BASE + DISPC_VID_BA0 };
-	const u32 ps_reg[] = { DISPC_GFX_POSITION,
-				DISPC_VID1_BASE + DISPC_VID_POSITION,
-				DISPC_VID2_BASE + DISPC_VID_POSITION };
-	const u32 sz_reg[] = { DISPC_GFX_SIZE,
-				DISPC_VID1_BASE + DISPC_VID_PICTURE_SIZE,
-				DISPC_VID2_BASE + DISPC_VID_PICTURE_SIZE };
-	const u32 ri_reg[] = { DISPC_GFX_ROW_INC,
-				DISPC_VID1_BASE + DISPC_VID_ROW_INC,
-			        DISPC_VID2_BASE + DISPC_VID_ROW_INC };
-	const u32 vs_reg[] = { 0, DISPC_VID1_BASE + DISPC_VID_SIZE,
-				DISPC_VID2_BASE + DISPC_VID_SIZE };
-
-	int chout_shift, burst_shift;
-	int chout_val;
-	int color_code;
-	int bpp;
-	int cconv_en;
-	int set_vsize;
-	u32 l;
-
-#ifdef VERBOSE
-	dev_dbg(dispc.fbdev->dev, "plane %d channel %d paddr %#08x scr_width %d"
-		    " pos_x %d pos_y %d width %d height %d color_mode %d\n",
-		    plane, channel_out, paddr, screen_width, pos_x, pos_y,
-		    width, height, color_mode);
-#endif
-
-	set_vsize = 0;
-	switch (plane) {
-	case OMAPFB_PLANE_GFX:
-		burst_shift = 6;
-		chout_shift = 8;
-		break;
-	case OMAPFB_PLANE_VID1:
-	case OMAPFB_PLANE_VID2:
-		burst_shift = 14;
-		chout_shift = 16;
-		set_vsize = 1;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	switch (channel_out) {
-	case OMAPFB_CHANNEL_OUT_LCD:
-		chout_val = 0;
-		break;
-	case OMAPFB_CHANNEL_OUT_DIGIT:
-		chout_val = 1;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	cconv_en = 0;
-	switch (color_mode) {
-	case OMAPFB_COLOR_RGB565:
-		color_code = DISPC_RGB_16_BPP;
-		bpp = 16;
-		break;
-	case OMAPFB_COLOR_YUV422:
-		if (plane = 0)
-			return -EINVAL;
-		color_code = DISPC_UYVY_422;
-		cconv_en = 1;
-		bpp = 16;
-		break;
-	case OMAPFB_COLOR_YUY422:
-		if (plane = 0)
-			return -EINVAL;
-		color_code = DISPC_YUV2_422;
-		cconv_en = 1;
-		bpp = 16;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	l = dispc_read_reg(at_reg[plane]);
-
-	l &= ~(0x0f << 1);
-	l |= color_code << 1;
-	l &= ~(1 << 9);
-	l |= cconv_en << 9;
-
-	l &= ~(0x03 << burst_shift);
-	l |= DISPC_BURST_8x32 << burst_shift;
-
-	l &= ~(1 << chout_shift);
-	l |= chout_val << chout_shift;
-
-	dispc_write_reg(at_reg[plane], l);
-
-	dispc_write_reg(ba_reg[plane], paddr);
-	MOD_REG_FLD(ps_reg[plane],
-		    FLD_MASK(16, 11) | FLD_MASK(0, 11), (pos_y << 16) | pos_x);
-
-	MOD_REG_FLD(sz_reg[plane], FLD_MASK(16, 11) | FLD_MASK(0, 11),
-			((height - 1) << 16) | (width - 1));
-
-	if (set_vsize) {
-		/* Set video size if set_scale hasn't set it */
-		if (!dispc.fir_vinc[plane])
-			MOD_REG_FLD(vs_reg[plane],
-				FLD_MASK(16, 11), (height - 1) << 16);
-		if (!dispc.fir_hinc[plane])
-			MOD_REG_FLD(vs_reg[plane],
-				FLD_MASK(0, 11), width - 1);
-	}
-
-	dispc_write_reg(ri_reg[plane], (screen_width - width) * bpp / 8 + 1);
-
-	return height * screen_width * bpp / 8;
-}
-
-static int omap_dispc_setup_plane(int plane, int channel_out,
-				  unsigned long offset,
-				  int screen_width,
-				  int pos_x, int pos_y, int width, int height,
-				  int color_mode)
-{
-	u32 paddr;
-	int r;
-
-	if ((unsigned)plane > dispc.mem_desc.region_cnt)
-		return -EINVAL;
-	paddr = dispc.mem_desc.region[plane].paddr + offset;
-	enable_lcd_clocks(1);
-	r = _setup_plane(plane, channel_out, paddr,
-			screen_width,
-			pos_x, pos_y, width, height, color_mode);
-	enable_lcd_clocks(0);
-	return r;
-}
-
-static void write_firh_reg(int plane, int reg, u32 value)
-{
-	u32 base;
-
-	if (plane = 1)
-		base = DISPC_VID1_BASE + DISPC_VID_FIR_COEF_H0;
-	else
-		base = DISPC_VID2_BASE + DISPC_VID_FIR_COEF_H0;
-	dispc_write_reg(base + reg * 8,	value);
-}
-
-static void write_firhv_reg(int plane, int reg, u32 value)
-{
-	u32 base;
-
-	if (plane = 1)
-		base = DISPC_VID1_BASE + DISPC_VID_FIR_COEF_HV0;
-	else
-		base = DISPC_VID2_BASE + DISPC_VID_FIR_COEF_HV0;
-	dispc_write_reg(base + reg * 8,	value);
-}
-
-static void set_upsampling_coef_table(int plane)
-{
-	const u32 coef[][2] = {
-		{ 0x00800000, 0x00800000 },
-		{ 0x0D7CF800, 0x037B02FF },
-		{ 0x1E70F5FF, 0x0C6F05FE },
-		{ 0x335FF5FE, 0x205907FB },
-		{ 0xF74949F7, 0x00404000 },
-		{ 0xF55F33FB, 0x075920FE },
-		{ 0xF5701EFE, 0x056F0CFF },
-		{ 0xF87C0DFF, 0x027B0300 },
-	};
-	int i;
-
-	for (i = 0; i < 8; i++) {
-		write_firh_reg(plane, i, coef[i][0]);
-		write_firhv_reg(plane, i, coef[i][1]);
-	}
-}
-
-static int omap_dispc_set_scale(int plane,
-				int orig_width, int orig_height,
-				int out_width, int out_height)
-{
-	const u32 at_reg[]  = { 0, DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
-				DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
-	const u32 vs_reg[]  = { 0, DISPC_VID1_BASE + DISPC_VID_SIZE,
-				DISPC_VID2_BASE + DISPC_VID_SIZE };
-	const u32 fir_reg[] = { 0, DISPC_VID1_BASE + DISPC_VID_FIR,
-				DISPC_VID2_BASE + DISPC_VID_FIR };
-
-	u32 l;
-	int fir_hinc;
-	int fir_vinc;
-
-	if ((unsigned)plane > OMAPFB_PLANE_NUM)
-		return -ENODEV;
-
-	if (plane = OMAPFB_PLANE_GFX &&
-	    (out_width != orig_width || out_height != orig_height))
-		return -EINVAL;
-
-	enable_lcd_clocks(1);
-	if (orig_width < out_width) {
-		/*
-		 * Upsampling.
-		 * Currently you can only scale both dimensions in one way.
-		 */
-		if (orig_height > out_height ||
-		    orig_width * 8 < out_width ||
-		    orig_height * 8 < out_height) {
-			enable_lcd_clocks(0);
-			return -EINVAL;
-		}
-		set_upsampling_coef_table(plane);
-	} else if (orig_width > out_width) {
-		/* Downsampling not yet supported
-		*/
-
-		enable_lcd_clocks(0);
-		return -EINVAL;
-	}
-	if (!orig_width || orig_width = out_width)
-		fir_hinc = 0;
-	else
-		fir_hinc = 1024 * orig_width / out_width;
-	if (!orig_height || orig_height = out_height)
-		fir_vinc = 0;
-	else
-		fir_vinc = 1024 * orig_height / out_height;
-	dispc.fir_hinc[plane] = fir_hinc;
-	dispc.fir_vinc[plane] = fir_vinc;
-
-	MOD_REG_FLD(fir_reg[plane],
-		    FLD_MASK(16, 12) | FLD_MASK(0, 12),
-		    ((fir_vinc & 4095) << 16) |
-		    (fir_hinc & 4095));
-
-	dev_dbg(dispc.fbdev->dev, "out_width %d out_height %d orig_width %d "
-		"orig_height %d fir_hinc  %d fir_vinc %d\n",
-		out_width, out_height, orig_width, orig_height,
-		fir_hinc, fir_vinc);
-
-	MOD_REG_FLD(vs_reg[plane],
-		    FLD_MASK(16, 11) | FLD_MASK(0, 11),
-		    ((out_height - 1) << 16) | (out_width - 1));
-
-	l = dispc_read_reg(at_reg[plane]);
-	l &= ~(0x03 << 5);
-	l |= fir_hinc ? (1 << 5) : 0;
-	l |= fir_vinc ? (1 << 6) : 0;
-	dispc_write_reg(at_reg[plane], l);
-
-	enable_lcd_clocks(0);
-	return 0;
-}
-
-static int omap_dispc_enable_plane(int plane, int enable)
-{
-	const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES,
-				DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES,
-				DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES };
-	if ((unsigned int)plane > dispc.mem_desc.region_cnt)
-		return -EINVAL;
-
-	enable_lcd_clocks(1);
-	MOD_REG_FLD(at_reg[plane], 1, enable ? 1 : 0);
-	enable_lcd_clocks(0);
-
-	return 0;
-}
-
-static int omap_dispc_set_color_key(struct omapfb_color_key *ck)
-{
-	u32 df_reg, tr_reg;
-	int shift, val;
-
-	switch (ck->channel_out) {
-	case OMAPFB_CHANNEL_OUT_LCD:
-		df_reg = DISPC_DEFAULT_COLOR0;
-		tr_reg = DISPC_TRANS_COLOR0;
-		shift = 10;
-		break;
-	case OMAPFB_CHANNEL_OUT_DIGIT:
-		df_reg = DISPC_DEFAULT_COLOR1;
-		tr_reg = DISPC_TRANS_COLOR1;
-		shift = 12;
-		break;
-	default:
-		return -EINVAL;
-	}
-	switch (ck->key_type) {
-	case OMAPFB_COLOR_KEY_DISABLED:
-		val = 0;
-		break;
-	case OMAPFB_COLOR_KEY_GFX_DST:
-		val = 1;
-		break;
-	case OMAPFB_COLOR_KEY_VID_SRC:
-		val = 3;
-		break;
-	default:
-		return -EINVAL;
-	}
-	enable_lcd_clocks(1);
-	MOD_REG_FLD(DISPC_CONFIG, FLD_MASK(shift, 2), val << shift);
-
-	if (val != 0)
-		dispc_write_reg(tr_reg, ck->trans_key);
-	dispc_write_reg(df_reg, ck->background);
-	enable_lcd_clocks(0);
-
-	dispc.color_key = *ck;
-
-	return 0;
-}
-
-static int omap_dispc_get_color_key(struct omapfb_color_key *ck)
-{
-	*ck = dispc.color_key;
-	return 0;
-}
-
-static void load_palette(void)
-{
-}
-
-static int omap_dispc_set_update_mode(enum omapfb_update_mode mode)
-{
-	int r = 0;
-
-	if (mode != dispc.update_mode) {
-		switch (mode) {
-		case OMAPFB_AUTO_UPDATE:
-		case OMAPFB_MANUAL_UPDATE:
-			enable_lcd_clocks(1);
-			omap_dispc_enable_lcd_out(1);
-			dispc.update_mode = mode;
-			break;
-		case OMAPFB_UPDATE_DISABLED:
-			init_completion(&dispc.frame_done);
-			omap_dispc_enable_lcd_out(0);
-			if (!wait_for_completion_timeout(&dispc.frame_done,
-					msecs_to_jiffies(500))) {
-				dev_err(dispc.fbdev->dev,
-					 "timeout waiting for FRAME DONE\n");
-			}
-			dispc.update_mode = mode;
-			enable_lcd_clocks(0);
-			break;
-		default:
-			r = -EINVAL;
-		}
-	}
-
-	return r;
-}
-
-static void omap_dispc_get_caps(int plane, struct omapfb_caps *caps)
-{
-	caps->ctrl |= OMAPFB_CAPS_PLANE_RELOCATE_MEM;
-	if (plane > 0)
-		caps->ctrl |= OMAPFB_CAPS_PLANE_SCALE;
-	caps->plane_color |= (1 << OMAPFB_COLOR_RGB565) |
-			     (1 << OMAPFB_COLOR_YUV422) |
-			     (1 << OMAPFB_COLOR_YUY422);
-	if (plane = 0)
-		caps->plane_color |= (1 << OMAPFB_COLOR_CLUT_8BPP) |
-				     (1 << OMAPFB_COLOR_CLUT_4BPP) |
-				     (1 << OMAPFB_COLOR_CLUT_2BPP) |
-				     (1 << OMAPFB_COLOR_CLUT_1BPP) |
-				     (1 << OMAPFB_COLOR_RGB444);
-}
-
-static enum omapfb_update_mode omap_dispc_get_update_mode(void)
-{
-	return dispc.update_mode;
-}
-
-static void setup_color_conv_coef(void)
-{
-	u32 mask = FLD_MASK(16, 11) | FLD_MASK(0, 11);
-	int cf1_reg = DISPC_VID1_BASE + DISPC_VID_CONV_COEF0;
-	int cf2_reg = DISPC_VID2_BASE + DISPC_VID_CONV_COEF0;
-	int at1_reg = DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES;
-	int at2_reg = DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES;
-	const struct color_conv_coef {
-		int  ry,  rcr,  rcb,   gy,  gcr,  gcb,   by,  bcr,  bcb;
-		int  full_range;
-	}  ctbl_bt601_5 = {
-		    298,  409,    0,  298, -208, -100,  298,    0,  517, 0,
-	};
-	const struct color_conv_coef *ct;
-#define CVAL(x, y)	(((x & 2047) << 16) | (y & 2047))
-
-	ct = &ctbl_bt601_5;
-
-	MOD_REG_FLD(cf1_reg,		mask,	CVAL(ct->rcr, ct->ry));
-	MOD_REG_FLD(cf1_reg + 4,	mask,	CVAL(ct->gy,  ct->rcb));
-	MOD_REG_FLD(cf1_reg + 8,	mask,	CVAL(ct->gcb, ct->gcr));
-	MOD_REG_FLD(cf1_reg + 12,	mask,	CVAL(ct->bcr, ct->by));
-	MOD_REG_FLD(cf1_reg + 16,	mask,	CVAL(0,	      ct->bcb));
-
-	MOD_REG_FLD(cf2_reg,		mask,	CVAL(ct->rcr, ct->ry));
-	MOD_REG_FLD(cf2_reg + 4,	mask,	CVAL(ct->gy,  ct->rcb));
-	MOD_REG_FLD(cf2_reg + 8,	mask,	CVAL(ct->gcb, ct->gcr));
-	MOD_REG_FLD(cf2_reg + 12,	mask,	CVAL(ct->bcr, ct->by));
-	MOD_REG_FLD(cf2_reg + 16,	mask,	CVAL(0,	      ct->bcb));
-#undef CVAL
-
-	MOD_REG_FLD(at1_reg, (1 << 11), ct->full_range);
-	MOD_REG_FLD(at2_reg, (1 << 11), ct->full_range);
-}
-
-static void calc_ck_div(int is_tft, int pck, int *lck_div, int *pck_div)
-{
-	unsigned long fck, lck;
-
-	*lck_div = 1;
-	pck = max(1, pck);
-	fck = clk_get_rate(dispc.dss1_fck);
-	lck = fck;
-	*pck_div = (lck + pck - 1) / pck;
-	if (is_tft)
-		*pck_div = max(2, *pck_div);
-	else
-		*pck_div = max(3, *pck_div);
-	if (*pck_div > 255) {
-		*pck_div = 255;
-		lck = pck * *pck_div;
-		*lck_div = fck / lck;
-		BUG_ON(*lck_div < 1);
-		if (*lck_div > 255) {
-			*lck_div = 255;
-			dev_warn(dispc.fbdev->dev, "pixclock %d kHz too low.\n",
-				 pck / 1000);
-		}
-	}
-}
-
-static void set_lcd_tft_mode(int enable)
-{
-	u32 mask;
-
-	mask = 1 << 3;
-	MOD_REG_FLD(DISPC_CONTROL, mask, enable ? mask : 0);
-}
-
-static void set_lcd_timings(void)
-{
-	u32 l;
-	int lck_div, pck_div;
-	struct lcd_panel *panel = dispc.fbdev->panel;
-	int is_tft = panel->config & OMAP_LCDC_PANEL_TFT;
-	unsigned long fck;
-
-	l = dispc_read_reg(DISPC_TIMING_H);
-	l &= ~(FLD_MASK(0, 6) | FLD_MASK(8, 8) | FLD_MASK(20, 8));
-	l |= ( max(1, (min(64,  panel->hsw))) - 1 ) << 0;
-	l |= ( max(1, (min(256, panel->hfp))) - 1 ) << 8;
-	l |= ( max(1, (min(256, panel->hbp))) - 1 ) << 20;
-	dispc_write_reg(DISPC_TIMING_H, l);
-
-	l = dispc_read_reg(DISPC_TIMING_V);
-	l &= ~(FLD_MASK(0, 6) | FLD_MASK(8, 8) | FLD_MASK(20, 8));
-	l |= ( max(1, (min(64,  panel->vsw))) - 1 ) << 0;
-	l |= ( max(0, (min(255, panel->vfp))) - 0 ) << 8;
-	l |= ( max(0, (min(255, panel->vbp))) - 0 ) << 20;
-	dispc_write_reg(DISPC_TIMING_V, l);
-
-	l = dispc_read_reg(DISPC_POL_FREQ);
-	l &= ~FLD_MASK(12, 6);
-	l |= (panel->config & OMAP_LCDC_SIGNAL_MASK) << 12;
-	l |= panel->acb & 0xff;
-	dispc_write_reg(DISPC_POL_FREQ, l);
-
-	calc_ck_div(is_tft, panel->pixel_clock * 1000, &lck_div, &pck_div);
-
-	l = dispc_read_reg(DISPC_DIVISOR);
-	l &= ~(FLD_MASK(16, 8) | FLD_MASK(0, 8));
-	l |= (lck_div << 16) | (pck_div << 0);
-	dispc_write_reg(DISPC_DIVISOR, l);
-
-	/* update panel info with the exact clock */
-	fck = clk_get_rate(dispc.dss1_fck);
-	panel->pixel_clock = fck / lck_div / pck_div / 1000;
-}
-
-static void recalc_irq_mask(void)
-{
-	int i;
-	unsigned long irq_mask = DISPC_IRQ_MASK_ERROR;
-
-	for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
-		if (!dispc.irq_handlers[i].callback)
-			continue;
-
-		irq_mask |= dispc.irq_handlers[i].irq_mask;
-	}
-
-	enable_lcd_clocks(1);
-	MOD_REG_FLD(DISPC_IRQENABLE, 0x7fff, irq_mask);
-	enable_lcd_clocks(0);
-}
-
-int omap_dispc_request_irq(unsigned long irq_mask, void (*callback)(void *data),
-			   void *data)
-{
-	int i;
-
-	BUG_ON(callback = NULL);
-
-	for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
-		if (dispc.irq_handlers[i].callback)
-			continue;
-
-		dispc.irq_handlers[i].irq_mask = irq_mask;
-		dispc.irq_handlers[i].callback = callback;
-		dispc.irq_handlers[i].data = data;
-		recalc_irq_mask();
-
-		return 0;
-	}
-
-	return -EBUSY;
-}
-EXPORT_SYMBOL(omap_dispc_request_irq);
-
-void omap_dispc_free_irq(unsigned long irq_mask, void (*callback)(void *data),
-			 void *data)
-{
-	int i;
-
-	for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
-		if (dispc.irq_handlers[i].callback = callback &&
-		    dispc.irq_handlers[i].data = data) {
-			dispc.irq_handlers[i].irq_mask = 0;
-			dispc.irq_handlers[i].callback = NULL;
-			dispc.irq_handlers[i].data = NULL;
-			recalc_irq_mask();
-			return;
-		}
-	}
-
-	BUG();
-}
-EXPORT_SYMBOL(omap_dispc_free_irq);
-
-static irqreturn_t omap_dispc_irq_handler(int irq, void *dev)
-{
-	u32 stat;
-	int i = 0;
-
-	enable_lcd_clocks(1);
-
-	stat = dispc_read_reg(DISPC_IRQSTATUS);
-	if (stat & DISPC_IRQ_FRAMEMASK)
-		complete(&dispc.frame_done);
-
-	if (stat & DISPC_IRQ_MASK_ERROR) {
-		if (printk_ratelimit()) {
-			dev_err(dispc.fbdev->dev, "irq error status %04x\n",
-				stat & 0x7fff);
-		}
-	}
-
-	for (i = 0; i < MAX_IRQ_HANDLERS; i++) {
-		if (unlikely(dispc.irq_handlers[i].callback &&
-			     (stat & dispc.irq_handlers[i].irq_mask)))
-			dispc.irq_handlers[i].callback(
-						dispc.irq_handlers[i].data);
-	}
-
-	dispc_write_reg(DISPC_IRQSTATUS, stat);
-
-	enable_lcd_clocks(0);
-
-	return IRQ_HANDLED;
-}
-
-static int get_dss_clocks(void)
-{
-	dispc.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick");
-	if (IS_ERR(dispc.dss_ick)) {
-		dev_err(dispc.fbdev->dev, "can't get ick\n");
-		return PTR_ERR(dispc.dss_ick);
-	}
-
-	dispc.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "fck");
-	if (IS_ERR(dispc.dss1_fck)) {
-		dev_err(dispc.fbdev->dev, "can't get dss1_fck\n");
-		clk_put(dispc.dss_ick);
-		return PTR_ERR(dispc.dss1_fck);
-	}
-
-	dispc.dss_54m_fck = clk_get(&dispc.fbdev->dssdev->dev, "tv_clk");
-	if (IS_ERR(dispc.dss_54m_fck)) {
-		dev_err(dispc.fbdev->dev, "can't get tv_fck\n");
-		clk_put(dispc.dss_ick);
-		clk_put(dispc.dss1_fck);
-		return PTR_ERR(dispc.dss_54m_fck);
-	}
-
-	return 0;
-}
-
-static void put_dss_clocks(void)
-{
-	clk_put(dispc.dss_54m_fck);
-	clk_put(dispc.dss1_fck);
-	clk_put(dispc.dss_ick);
-}
-
-static void enable_lcd_clocks(int enable)
-{
-	if (enable) {
-		clk_enable(dispc.dss_ick);
-		clk_enable(dispc.dss1_fck);
-	} else {
-		clk_disable(dispc.dss1_fck);
-		clk_disable(dispc.dss_ick);
-	}
-}
-
-static void enable_digit_clocks(int enable)
-{
-	if (enable)
-		clk_enable(dispc.dss_54m_fck);
-	else
-		clk_disable(dispc.dss_54m_fck);
-}
-
-static void omap_dispc_suspend(void)
-{
-	if (dispc.update_mode = OMAPFB_AUTO_UPDATE) {
-		init_completion(&dispc.frame_done);
-		omap_dispc_enable_lcd_out(0);
-		if (!wait_for_completion_timeout(&dispc.frame_done,
-				msecs_to_jiffies(500))) {
-			dev_err(dispc.fbdev->dev,
-				"timeout waiting for FRAME DONE\n");
-		}
-		enable_lcd_clocks(0);
-	}
-}
-
-static void omap_dispc_resume(void)
-{
-	if (dispc.update_mode = OMAPFB_AUTO_UPDATE) {
-		enable_lcd_clocks(1);
-		if (!dispc.ext_mode) {
-			set_lcd_timings();
-			load_palette();
-		}
-		omap_dispc_enable_lcd_out(1);
-	}
-}
-
-
-static int omap_dispc_update_window(struct fb_info *fbi,
-				 struct omapfb_update_window *win,
-				 void (*complete_callback)(void *arg),
-				 void *complete_callback_data)
-{
-	return dispc.update_mode = OMAPFB_UPDATE_DISABLED ? -ENODEV : 0;
-}
-
-static int mmap_kern(struct omapfb_mem_region *region)
-{
-	struct vm_struct	*kvma;
-	struct vm_area_struct	vma;
-	pgprot_t		pgprot;
-	unsigned long		vaddr;
-
-	kvma = get_vm_area(region->size, VM_IOREMAP);
-	if (kvma = NULL) {
-		dev_err(dispc.fbdev->dev, "can't get kernel vm area\n");
-		return -ENOMEM;
-	}
-	vma.vm_mm = &init_mm;
-
-	vaddr = (unsigned long)kvma->addr;
-
-	pgprot = pgprot_writecombine(pgprot_kernel);
-	vma.vm_start = vaddr;
-	vma.vm_end = vaddr + region->size;
-	if (io_remap_pfn_range(&vma, vaddr, region->paddr >> PAGE_SHIFT,
-			   region->size, pgprot) < 0) {
-		dev_err(dispc.fbdev->dev, "kernel mmap for FBMEM failed\n");
-		return -EAGAIN;
-	}
-	region->vaddr = (void *)vaddr;
-
-	return 0;
-}
-
-static void mmap_user_open(struct vm_area_struct *vma)
-{
-	int plane = (int)vma->vm_private_data;
-
-	atomic_inc(&dispc.map_count[plane]);
-}
-
-static void mmap_user_close(struct vm_area_struct *vma)
-{
-	int plane = (int)vma->vm_private_data;
-
-	atomic_dec(&dispc.map_count[plane]);
-}
-
-static const struct vm_operations_struct mmap_user_ops = {
-	.open = mmap_user_open,
-	.close = mmap_user_close,
-};
-
-static int omap_dispc_mmap_user(struct fb_info *info,
-				struct vm_area_struct *vma)
-{
-	struct omapfb_plane_struct *plane = info->par;
-	unsigned long off;
-	unsigned long start;
-	u32 len;
-
-	if (vma->vm_end - vma->vm_start = 0)
-		return 0;
-	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-		return -EINVAL;
-	off = vma->vm_pgoff << PAGE_SHIFT;
-
-	start = info->fix.smem_start;
-	len = info->fix.smem_len;
-	if (off >= len)
-		return -EINVAL;
-	if ((vma->vm_end - vma->vm_start + off) > len)
-		return -EINVAL;
-	off += start;
-	vma->vm_pgoff = off >> PAGE_SHIFT;
-	vma->vm_flags |= VM_IO | VM_RESERVED;
-	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-	vma->vm_ops = &mmap_user_ops;
-	vma->vm_private_data = (void *)plane->idx;
-	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
-			     vma->vm_end - vma->vm_start, vma->vm_page_prot))
-		return -EAGAIN;
-	/* vm_ops.open won't be called for mmap itself. */
-	atomic_inc(&dispc.map_count[plane->idx]);
-	return 0;
-}
-
-static void unmap_kern(struct omapfb_mem_region *region)
-{
-	vunmap(region->vaddr);
-}
-
-static int alloc_palette_ram(void)
-{
-	dispc.palette_vaddr = dma_alloc_writecombine(dispc.fbdev->dev,
-		MAX_PALETTE_SIZE, &dispc.palette_paddr, GFP_KERNEL);
-	if (dispc.palette_vaddr = NULL) {
-		dev_err(dispc.fbdev->dev, "failed to alloc palette memory\n");
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static void free_palette_ram(void)
-{
-	dma_free_writecombine(dispc.fbdev->dev, MAX_PALETTE_SIZE,
-			dispc.palette_vaddr, dispc.palette_paddr);
-}
-
-static int alloc_fbmem(struct omapfb_mem_region *region)
-{
-	region->vaddr = dma_alloc_writecombine(dispc.fbdev->dev,
-			region->size, &region->paddr, GFP_KERNEL);
-
-	if (region->vaddr = NULL) {
-		dev_err(dispc.fbdev->dev, "unable to allocate FB DMA memory\n");
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static void free_fbmem(struct omapfb_mem_region *region)
-{
-	dma_free_writecombine(dispc.fbdev->dev, region->size,
-			      region->vaddr, region->paddr);
-}
-
-static struct resmap *init_resmap(unsigned long start, size_t size)
-{
-	unsigned page_cnt;
-	struct resmap *res_map;
-
-	page_cnt = PAGE_ALIGN(size) / PAGE_SIZE;
-	res_map -	    kzalloc(sizeof(struct resmap) + RESMAP_SIZE(page_cnt), GFP_KERNEL);
-	if (res_map = NULL)
-		return NULL;
-	res_map->start = start;
-	res_map->page_cnt = page_cnt;
-	res_map->map = (unsigned long *)(res_map + 1);
-	return res_map;
-}
-
-static void cleanup_resmap(struct resmap *res_map)
-{
-	kfree(res_map);
-}
-
-static inline int resmap_mem_type(unsigned long start)
-{
-	if (start >= OMAP2_SRAM_START &&
-	    start < OMAP2_SRAM_START + OMAP2_SRAM_SIZE)
-		return OMAPFB_MEMTYPE_SRAM;
-	else
-		return OMAPFB_MEMTYPE_SDRAM;
-}
-
-static inline int resmap_page_reserved(struct resmap *res_map, unsigned page_nr)
-{
-	return *RESMAP_PTR(res_map, page_nr) & RESMAP_MASK(page_nr) ? 1 : 0;
-}
-
-static inline void resmap_reserve_page(struct resmap *res_map, unsigned page_nr)
-{
-	BUG_ON(resmap_page_reserved(res_map, page_nr));
-	*RESMAP_PTR(res_map, page_nr) |= RESMAP_MASK(page_nr);
-}
-
-static inline void resmap_free_page(struct resmap *res_map, unsigned page_nr)
-{
-	BUG_ON(!resmap_page_reserved(res_map, page_nr));
-	*RESMAP_PTR(res_map, page_nr) &= ~RESMAP_MASK(page_nr);
-}
-
-static void resmap_reserve_region(unsigned long start, size_t size)
-{
-
-	struct resmap	*res_map;
-	unsigned	start_page;
-	unsigned	end_page;
-	int		mtype;
-	unsigned	i;
-
-	mtype = resmap_mem_type(start);
-	res_map = dispc.res_map[mtype];
-	dev_dbg(dispc.fbdev->dev, "reserve mem type %d start %08lx size %d\n",
-		mtype, start, size);
-	start_page = (start - res_map->start) / PAGE_SIZE;
-	end_page = start_page + PAGE_ALIGN(size) / PAGE_SIZE;
-	for (i = start_page; i < end_page; i++)
-		resmap_reserve_page(res_map, i);
-}
-
-static void resmap_free_region(unsigned long start, size_t size)
-{
-	struct resmap	*res_map;
-	unsigned	start_page;
-	unsigned	end_page;
-	unsigned	i;
-	int		mtype;
-
-	mtype = resmap_mem_type(start);
-	res_map = dispc.res_map[mtype];
-	dev_dbg(dispc.fbdev->dev, "free mem type %d start %08lx size %d\n",
-		mtype, start, size);
-	start_page = (start - res_map->start) / PAGE_SIZE;
-	end_page = start_page + PAGE_ALIGN(size) / PAGE_SIZE;
-	for (i = start_page; i < end_page; i++)
-		resmap_free_page(res_map, i);
-}
-
-static unsigned long resmap_alloc_region(int mtype, size_t size)
-{
-	unsigned i;
-	unsigned total;
-	unsigned start_page;
-	unsigned long start;
-	struct resmap *res_map = dispc.res_map[mtype];
-
-	BUG_ON(mtype >= DISPC_MEMTYPE_NUM || res_map = NULL || !size);
-
-	size = PAGE_ALIGN(size) / PAGE_SIZE;
-	start_page = 0;
-	total = 0;
-	for (i = 0; i < res_map->page_cnt; i++) {
-		if (resmap_page_reserved(res_map, i)) {
-			start_page = i + 1;
-			total = 0;
-		} else if (++total = size)
-			break;
-	}
-	if (total < size)
-		return 0;
-
-	start = res_map->start + start_page * PAGE_SIZE;
-	resmap_reserve_region(start, size * PAGE_SIZE);
-
-	return start;
-}
-
-/* Note that this will only work for user mappings, we don't deal with
- * kernel mappings here, so fbcon will keep using the old region.
- */
-static int omap_dispc_setup_mem(int plane, size_t size, int mem_type,
-				unsigned long *paddr)
-{
-	struct omapfb_mem_region *rg;
-	unsigned long new_addr = 0;
-
-	if ((unsigned)plane > dispc.mem_desc.region_cnt)
-		return -EINVAL;
-	if (mem_type >= DISPC_MEMTYPE_NUM)
-		return -EINVAL;
-	if (dispc.res_map[mem_type] = NULL)
-		return -ENOMEM;
-	rg = &dispc.mem_desc.region[plane];
-	if (size = rg->size && mem_type = rg->type)
-		return 0;
-	if (atomic_read(&dispc.map_count[plane]))
-		return -EBUSY;
-	if (rg->size != 0)
-		resmap_free_region(rg->paddr, rg->size);
-	if (size != 0) {
-		new_addr = resmap_alloc_region(mem_type, size);
-		if (!new_addr) {
-			/* Reallocate old region. */
-			resmap_reserve_region(rg->paddr, rg->size);
-			return -ENOMEM;
-		}
-	}
-	rg->paddr = new_addr;
-	rg->size = size;
-	rg->type = mem_type;
-
-	*paddr = new_addr;
-
-	return 0;
-}
-
-static int setup_fbmem(struct omapfb_mem_desc *req_md)
-{
-	struct omapfb_mem_region	*rg;
-	int i;
-	int r;
-	unsigned long			mem_start[DISPC_MEMTYPE_NUM];
-	unsigned long			mem_end[DISPC_MEMTYPE_NUM];
-
-	if (!req_md->region_cnt) {
-		dev_err(dispc.fbdev->dev, "no memory regions defined\n");
-		return -ENOENT;
-	}
-
-	rg = &req_md->region[0];
-	memset(mem_start, 0xff, sizeof(mem_start));
-	memset(mem_end, 0, sizeof(mem_end));
-
-	for (i = 0; i < req_md->region_cnt; i++, rg++) {
-		int mtype;
-		if (rg->paddr) {
-			rg->alloc = 0;
-			if (rg->vaddr = NULL) {
-				rg->map = 1;
-				if ((r = mmap_kern(rg)) < 0)
-					return r;
-			}
-		} else {
-			if (rg->type != OMAPFB_MEMTYPE_SDRAM) {
-				dev_err(dispc.fbdev->dev,
-					"unsupported memory type\n");
-				return -EINVAL;
-			}
-			rg->alloc = rg->map = 1;
-			if ((r = alloc_fbmem(rg)) < 0)
-				return r;
-		}
-		mtype = rg->type;
-
-		if (rg->paddr < mem_start[mtype])
-			mem_start[mtype] = rg->paddr;
-		if (rg->paddr + rg->size > mem_end[mtype])
-			mem_end[mtype] = rg->paddr + rg->size;
-	}
-
-	for (i = 0; i < DISPC_MEMTYPE_NUM; i++) {
-		unsigned long start;
-		size_t size;
-		if (mem_end[i] = 0)
-			continue;
-		start = mem_start[i];
-		size = mem_end[i] - start;
-		dispc.res_map[i] = init_resmap(start, size);
-		r = -ENOMEM;
-		if (dispc.res_map[i] = NULL)
-			goto fail;
-		/* Initial state is that everything is reserved. This
-		 * includes possible holes as well, which will never be
-		 * freed.
-		 */
-		resmap_reserve_region(start, size);
-	}
-
-	dispc.mem_desc = *req_md;
-
-	return 0;
-fail:
-	for (i = 0; i < DISPC_MEMTYPE_NUM; i++) {
-		if (dispc.res_map[i] != NULL)
-			cleanup_resmap(dispc.res_map[i]);
-	}
-	return r;
-}
-
-static void cleanup_fbmem(void)
-{
-	struct omapfb_mem_region *rg;
-	int i;
-
-	for (i = 0; i < DISPC_MEMTYPE_NUM; i++) {
-		if (dispc.res_map[i] != NULL)
-			cleanup_resmap(dispc.res_map[i]);
-	}
-	rg = &dispc.mem_desc.region[0];
-	for (i = 0; i < dispc.mem_desc.region_cnt; i++, rg++) {
-		if (rg->alloc)
-			free_fbmem(rg);
-		else {
-			if (rg->map)
-				unmap_kern(rg);
-		}
-	}
-}
-
-static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
-			   struct omapfb_mem_desc *req_vram)
-{
-	int r;
-	u32 l;
-	struct lcd_panel *panel = fbdev->panel;
-	void __iomem *ram_fw_base;
-	int tmo = 10000;
-	int skip_init = 0;
-	int i;
-
-	memset(&dispc, 0, sizeof(dispc));
-
-	dispc.base = ioremap(DISPC_BASE, SZ_1K);
-	if (!dispc.base) {
-		dev_err(fbdev->dev, "can't ioremap DISPC\n");
-		return -ENOMEM;
-	}
-
-	dispc.fbdev = fbdev;
-	dispc.ext_mode = ext_mode;
-
-	init_completion(&dispc.frame_done);
-
-	if ((r = get_dss_clocks()) < 0)
-		goto fail0;
-
-	enable_lcd_clocks(1);
-
-#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
-	l = dispc_read_reg(DISPC_CONTROL);
-	/* LCD enabled ? */
-	if (l & 1) {
-		pr_info("omapfb: skipping hardware initialization\n");
-		skip_init = 1;
-	}
-#endif
-
-	if (!skip_init) {
-		/* Reset monitoring works only w/ the 54M clk */
-		enable_digit_clocks(1);
-
-		/* Soft reset */
-		MOD_REG_FLD(DISPC_SYSCONFIG, 1 << 1, 1 << 1);
-
-		while (!(dispc_read_reg(DISPC_SYSSTATUS) & 1)) {
-			if (!--tmo) {
-				dev_err(dispc.fbdev->dev, "soft reset failed\n");
-				r = -ENODEV;
-				enable_digit_clocks(0);
-				goto fail1;
-			}
-		}
-
-		enable_digit_clocks(0);
-	}
-
-	/* Enable smart standby/idle, autoidle and wakeup */
-	l = dispc_read_reg(DISPC_SYSCONFIG);
-	l &= ~((3 << 12) | (3 << 3));
-	l |= (2 << 12) | (2 << 3) | (1 << 2) | (1 << 0);
-	dispc_write_reg(DISPC_SYSCONFIG, l);
-	omap_writel(1 << 0, DSS_BASE + DSS_SYSCONFIG);
-
-	/* Set functional clock autogating */
-	l = dispc_read_reg(DISPC_CONFIG);
-	l |= 1 << 9;
-	dispc_write_reg(DISPC_CONFIG, l);
-
-	l = dispc_read_reg(DISPC_IRQSTATUS);
-	dispc_write_reg(DISPC_IRQSTATUS, l);
-
-	recalc_irq_mask();
-
-	if ((r = request_irq(INT_24XX_DSS_IRQ, omap_dispc_irq_handler,
-			   0, MODULE_NAME, fbdev)) < 0) {
-		dev_err(dispc.fbdev->dev, "can't get DSS IRQ\n");
-		goto fail1;
-	}
-
-	/* L3 firewall setting: enable access to OCM RAM */
-	ram_fw_base = ioremap(0x68005000, SZ_1K);
-	if (!ram_fw_base) {
-		dev_err(dispc.fbdev->dev, "Cannot ioremap to enable OCM RAM\n");
-		goto fail1;
-	}
-	__raw_writel(0x402000b0, ram_fw_base + 0xa0);
-	iounmap(ram_fw_base);
-
-	if ((r = alloc_palette_ram()) < 0)
-		goto fail2;
-
-	if ((r = setup_fbmem(req_vram)) < 0)
-		goto fail3;
-
-	if (!skip_init) {
-		for (i = 0; i < dispc.mem_desc.region_cnt; i++) {
-			memset(dispc.mem_desc.region[i].vaddr, 0,
-				dispc.mem_desc.region[i].size);
-		}
-
-		/* Set logic clock to fck, pixel clock to fck/2 for now */
-		MOD_REG_FLD(DISPC_DIVISOR, FLD_MASK(16, 8), 1 << 16);
-		MOD_REG_FLD(DISPC_DIVISOR, FLD_MASK(0, 8), 2 << 0);
-
-		setup_plane_fifo(0, ext_mode);
-		setup_plane_fifo(1, ext_mode);
-		setup_plane_fifo(2, ext_mode);
-
-		setup_color_conv_coef();
-
-		set_lcd_tft_mode(panel->config & OMAP_LCDC_PANEL_TFT);
-		set_load_mode(DISPC_LOAD_FRAME_ONLY);
-
-		if (!ext_mode) {
-			set_lcd_data_lines(panel->data_lines);
-			omap_dispc_set_lcd_size(panel->x_res, panel->y_res);
-			set_lcd_timings();
-		} else
-			set_lcd_data_lines(panel->bpp);
-		enable_rfbi_mode(ext_mode);
-	}
-
-	l = dispc_read_reg(DISPC_REVISION);
-	pr_info("omapfb: DISPC version %d.%d initialized\n",
-		 l >> 4 & 0x0f, l & 0x0f);
-	enable_lcd_clocks(0);
-
-	return 0;
-fail3:
-	free_palette_ram();
-fail2:
-	free_irq(INT_24XX_DSS_IRQ, fbdev);
-fail1:
-	enable_lcd_clocks(0);
-	put_dss_clocks();
-fail0:
-	iounmap(dispc.base);
-	return r;
-}
-
-static void omap_dispc_cleanup(void)
-{
-	int i;
-
-	omap_dispc_set_update_mode(OMAPFB_UPDATE_DISABLED);
-	/* This will also disable clocks that are on */
-	for (i = 0; i < dispc.mem_desc.region_cnt; i++)
-		omap_dispc_enable_plane(i, 0);
-	cleanup_fbmem();
-	free_palette_ram();
-	free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
-	put_dss_clocks();
-	iounmap(dispc.base);
-}
-
-const struct lcd_ctrl omap2_int_ctrl = {
-	.name			= "internal",
-	.init			= omap_dispc_init,
-	.cleanup		= omap_dispc_cleanup,
-	.get_caps		= omap_dispc_get_caps,
-	.set_update_mode	= omap_dispc_set_update_mode,
-	.get_update_mode	= omap_dispc_get_update_mode,
-	.update_window		= omap_dispc_update_window,
-	.suspend		= omap_dispc_suspend,
-	.resume			= omap_dispc_resume,
-	.setup_plane		= omap_dispc_setup_plane,
-	.setup_mem		= omap_dispc_setup_mem,
-	.set_scale		= omap_dispc_set_scale,
-	.enable_plane		= omap_dispc_enable_plane,
-	.set_color_key		= omap_dispc_set_color_key,
-	.get_color_key		= omap_dispc_get_color_key,
-	.mmap			= omap_dispc_mmap_user,
-};
diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h
deleted file mode 100644
index c15ea77..0000000
--- a/drivers/video/omap/dispc.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef _DISPC_H
-#define _DISPC_H
-
-#include <linux/interrupt.h>
-
-#define DISPC_PLANE_GFX			0
-#define DISPC_PLANE_VID1		1
-#define DISPC_PLANE_VID2		2
-
-#define DISPC_RGB_1_BPP			0x00
-#define DISPC_RGB_2_BPP			0x01
-#define DISPC_RGB_4_BPP			0x02
-#define DISPC_RGB_8_BPP			0x03
-#define DISPC_RGB_12_BPP		0x04
-#define DISPC_RGB_16_BPP		0x06
-#define DISPC_RGB_24_BPP		0x08
-#define DISPC_RGB_24_BPP_UNPACK_32	0x09
-#define DISPC_YUV2_422			0x0a
-#define DISPC_UYVY_422			0x0b
-
-#define DISPC_BURST_4x32		0
-#define DISPC_BURST_8x32		1
-#define DISPC_BURST_16x32		2
-
-#define DISPC_LOAD_CLUT_AND_FRAME	0x00
-#define DISPC_LOAD_CLUT_ONLY		0x01
-#define DISPC_LOAD_FRAME_ONLY		0x02
-#define DISPC_LOAD_CLUT_ONCE_FRAME	0x03
-
-#define DISPC_TFT_DATA_LINES_12		0
-#define DISPC_TFT_DATA_LINES_16		1
-#define DISPC_TFT_DATA_LINES_18		2
-#define DISPC_TFT_DATA_LINES_24		3
-
-extern void omap_dispc_set_lcd_size(int width, int height);
-
-extern void omap_dispc_enable_lcd_out(int enable);
-extern void omap_dispc_enable_digit_out(int enable);
-
-extern int omap_dispc_request_irq(unsigned long irq_mask,
-				   void (*callback)(void *data), void *data);
-extern void omap_dispc_free_irq(unsigned long irq_mask,
-				 void (*callback)(void *data), void *data);
-
-extern const struct lcd_ctrl omap2_int_ctrl;
-#endif
diff --git a/drivers/video/omap/omapfb.h b/drivers/video/omap/omapfb.h
index af3c9e5..3a5ab13 100644
--- a/drivers/video/omap/omapfb.h
+++ b/drivers/video/omap/omapfb.h
@@ -207,11 +207,7 @@ struct omapfb_device {
 	struct platform_device	*dssdev;	/* dummy dev for clocks */
 };
 
-#ifdef CONFIG_ARCH_OMAP1
 extern struct lcd_ctrl omap1_lcd_ctrl;
-#else
-extern struct lcd_ctrl omap2_disp_ctrl;
-#endif
 
 extern void omapfb_register_panel(struct lcd_panel *panel);
 extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 440a5dd..73924bc 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -34,7 +34,6 @@
 
 #include "omapfb.h"
 #include "lcdc.h"
-#include "dispc.h"
 
 #define MODULE_NAME	"omapfb"
 
@@ -106,11 +105,7 @@ static struct platform_device omapdss_device = {
 extern struct lcd_ctrl hwa742_ctrl;
 
 static const struct lcd_ctrl *ctrls[] = {
-#ifdef CONFIG_ARCH_OMAP1
 	&omap1_int_ctrl,
-#else
-	&omap2_int_ctrl,
-#endif
 
 #ifdef CONFIG_FB_OMAP_LCDC_HWA742
 	&hwa742_ctrl,
@@ -118,11 +113,7 @@ static const struct lcd_ctrl *ctrls[] = {
 };
 
 #ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
-#ifdef CONFIG_ARCH_OMAP1
 extern struct lcd_ctrl_extif omap1_ext_if;
-#else
-extern struct lcd_ctrl_extif omap2_ext_if;
-#endif
 #endif
 
 static void omapfb_rqueue_lock(struct omapfb_device *fbdev)
@@ -1717,17 +1708,10 @@ static int omapfb_do_probe(struct platform_device *pdev,
 
 	mutex_init(&fbdev->rqueue_mutex);
 
-#ifdef CONFIG_ARCH_OMAP1
 	fbdev->int_ctrl = &omap1_int_ctrl;
 #ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
 	fbdev->ext_if = &omap1_ext_if;
 #endif
-#else	/* OMAP2 */
-	fbdev->int_ctrl = &omap2_int_ctrl;
-#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
-	fbdev->ext_if = &omap2_ext_if;
-#endif
-#endif
 	if (omapfb_find_ctrl(fbdev) < 0) {
 		dev_err(fbdev->dev,
 			"LCD controller not found, board not supported\n");
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
deleted file mode 100644
index 2c1a340..0000000
--- a/drivers/video/omap/rfbi.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- * OMAP2 Remote Frame Buffer Interface support
- *
- * Copyright (C) 2005 Nokia Corporation
- * Author: Juha Yrjölä <juha.yrjola@nokia.com>
- *	   Imre Deak <imre.deak@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-
-#include "omapfb.h"
-#include "dispc.h"
-
-/* To work around an RFBI transfer rate limitation */
-#define OMAP_RFBI_RATE_LIMIT	1
-
-#define RFBI_BASE		0x48050800
-#define RFBI_REVISION		0x0000
-#define RFBI_SYSCONFIG		0x0010
-#define RFBI_SYSSTATUS		0x0014
-#define RFBI_CONTROL		0x0040
-#define RFBI_PIXEL_CNT		0x0044
-#define RFBI_LINE_NUMBER	0x0048
-#define RFBI_CMD		0x004c
-#define RFBI_PARAM		0x0050
-#define RFBI_DATA		0x0054
-#define RFBI_READ		0x0058
-#define RFBI_STATUS		0x005c
-#define RFBI_CONFIG0		0x0060
-#define RFBI_ONOFF_TIME0	0x0064
-#define RFBI_CYCLE_TIME0	0x0068
-#define RFBI_DATA_CYCLE1_0	0x006c
-#define RFBI_DATA_CYCLE2_0	0x0070
-#define RFBI_DATA_CYCLE3_0	0x0074
-#define RFBI_VSYNC_WIDTH	0x0090
-#define RFBI_HSYNC_WIDTH	0x0094
-
-#define DISPC_BASE		0x48050400
-#define DISPC_CONTROL		0x0040
-#define DISPC_IRQ_FRAMEMASK     0x0001
-
-static struct {
-	void __iomem	*base;
-	void		(*lcdc_callback)(void *data);
-	void		*lcdc_callback_data;
-	unsigned long	l4_khz;
-	int		bits_per_cycle;
-	struct omapfb_device *fbdev;
-	struct clk	*dss_ick;
-	struct clk	*dss1_fck;
-	unsigned	tearsync_pin_cnt;
-	unsigned	tearsync_mode;
-} rfbi;
-
-static inline void rfbi_write_reg(int idx, u32 val)
-{
-	__raw_writel(val, rfbi.base + idx);
-}
-
-static inline u32 rfbi_read_reg(int idx)
-{
-	return __raw_readl(rfbi.base + idx);
-}
-
-static int rfbi_get_clocks(void)
-{
-	rfbi.dss_ick = clk_get(&rfbi.fbdev->dssdev->dev, "ick");
-	if (IS_ERR(rfbi.dss_ick)) {
-		dev_err(rfbi.fbdev->dev, "can't get ick\n");
-		return PTR_ERR(rfbi.dss_ick);
-	}
-
-	rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "fck");
-	if (IS_ERR(rfbi.dss1_fck)) {
-		dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n");
-		clk_put(rfbi.dss_ick);
-		return PTR_ERR(rfbi.dss1_fck);
-	}
-
-	return 0;
-}
-
-static void rfbi_put_clocks(void)
-{
-	clk_put(rfbi.dss1_fck);
-	clk_put(rfbi.dss_ick);
-}
-
-static void rfbi_enable_clocks(int enable)
-{
-	if (enable) {
-		clk_enable(rfbi.dss_ick);
-		clk_enable(rfbi.dss1_fck);
-	} else {
-		clk_disable(rfbi.dss1_fck);
-		clk_disable(rfbi.dss_ick);
-	}
-}
-
-
-#ifdef VERBOSE
-static void rfbi_print_timings(void)
-{
-	u32 l;
-	u32 time;
-
-	l = rfbi_read_reg(RFBI_CONFIG0);
-	time = 1000000000 / rfbi.l4_khz;
-	if (l & (1 << 4))
-		time *= 2;
-
-	dev_dbg(rfbi.fbdev->dev, "Tick time %u ps\n", time);
-	l = rfbi_read_reg(RFBI_ONOFF_TIME0);
-	dev_dbg(rfbi.fbdev->dev,
-		"CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
-		"REONTIME %d, REOFFTIME %d\n",
-		l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
-		(l >> 20) & 0x0f, (l >> 24) & 0x3f);
-
-	l = rfbi_read_reg(RFBI_CYCLE_TIME0);
-	dev_dbg(rfbi.fbdev->dev,
-		"WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
-		"ACCESSTIME %d\n",
-		(l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f,
-		(l >> 22) & 0x3f);
-}
-#else
-static void rfbi_print_timings(void) {}
-#endif
-
-static void rfbi_set_timings(const struct extif_timings *t)
-{
-	u32 l;
-
-	BUG_ON(!t->converted);
-
-	rfbi_enable_clocks(1);
-	rfbi_write_reg(RFBI_ONOFF_TIME0, t->tim[0]);
-	rfbi_write_reg(RFBI_CYCLE_TIME0, t->tim[1]);
-
-	l = rfbi_read_reg(RFBI_CONFIG0);
-	l &= ~(1 << 4);
-	l |= (t->tim[2] ? 1 : 0) << 4;
-	rfbi_write_reg(RFBI_CONFIG0, l);
-
-	rfbi_print_timings();
-	rfbi_enable_clocks(0);
-}
-
-static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
-{
-	*clk_period = 1000000000 / rfbi.l4_khz;
-	*max_clk_div = 2;
-}
-
-static int ps_to_rfbi_ticks(int time, int div)
-{
-	unsigned long tick_ps;
-	int ret;
-
-	/* Calculate in picosecs to yield more exact results */
-	tick_ps = 1000000000 / (rfbi.l4_khz) * div;
-
-	ret = (time + tick_ps - 1) / tick_ps;
-
-	return ret;
-}
-
-#ifdef OMAP_RFBI_RATE_LIMIT
-static unsigned long rfbi_get_max_tx_rate(void)
-{
-	unsigned long	l4_rate, dss1_rate;
-	int		min_l4_ticks = 0;
-	int		i;
-
-	/* According to TI this can't be calculated so make the
-	 * adjustments for a couple of known frequencies and warn for
-	 * others.
-	 */
-	static const struct {
-		unsigned long l4_clk;		/* HZ */
-		unsigned long dss1_clk;		/* HZ */
-		unsigned long min_l4_ticks;
-	} ftab[] = {
-		{ 55,	132,	7, },		/* 7.86 MPix/s */
-		{ 110,	110,	12, },		/* 9.16 MPix/s */
-		{ 110,	132,	10, },		/* 11   Mpix/s */
-		{ 120,	120,	10, },		/* 12   Mpix/s */
-		{ 133,	133,	10, },		/* 13.3 Mpix/s */
-	};
-
-	l4_rate = rfbi.l4_khz / 1000;
-	dss1_rate = clk_get_rate(rfbi.dss1_fck) / 1000000;
-
-	for (i = 0; i < ARRAY_SIZE(ftab); i++) {
-		/* Use a window instead of an exact match, to account
-		 * for different DPLL multiplier / divider pairs.
-		 */
-		if (abs(ftab[i].l4_clk - l4_rate) < 3 &&
-		    abs(ftab[i].dss1_clk - dss1_rate) < 3) {
-			min_l4_ticks = ftab[i].min_l4_ticks;
-			break;
-		}
-	}
-	if (i = ARRAY_SIZE(ftab)) {
-		/* Can't be sure, return anyway the maximum not
-		 * rate-limited. This might cause a problem only for the
-		 * tearing synchronisation.
-		 */
-		dev_err(rfbi.fbdev->dev,
-			"can't determine maximum RFBI transfer rate\n");
-		return rfbi.l4_khz * 1000;
-	}
-	return rfbi.l4_khz * 1000 / min_l4_ticks;
-}
-#else
-static int rfbi_get_max_tx_rate(void)
-{
-	return rfbi.l4_khz * 1000;
-}
-#endif
-
-
-static int rfbi_convert_timings(struct extif_timings *t)
-{
-	u32 l;
-	int reon, reoff, weon, weoff, cson, csoff, cs_pulse;
-	int actim, recyc, wecyc;
-	int div = t->clk_div;
-
-	if (div <= 0 || div > 2)
-		return -1;
-
-	/* Make sure that after conversion it still holds that:
-	 * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
-	 * csoff > cson, csoff >= max(weoff, reoff), actim > reon
-	 */
-	weon = ps_to_rfbi_ticks(t->we_on_time, div);
-	weoff = ps_to_rfbi_ticks(t->we_off_time, div);
-	if (weoff <= weon)
-		weoff = weon + 1;
-	if (weon > 0x0f)
-		return -1;
-	if (weoff > 0x3f)
-		return -1;
-
-	reon = ps_to_rfbi_ticks(t->re_on_time, div);
-	reoff = ps_to_rfbi_ticks(t->re_off_time, div);
-	if (reoff <= reon)
-		reoff = reon + 1;
-	if (reon > 0x0f)
-		return -1;
-	if (reoff > 0x3f)
-		return -1;
-
-	cson = ps_to_rfbi_ticks(t->cs_on_time, div);
-	csoff = ps_to_rfbi_ticks(t->cs_off_time, div);
-	if (csoff <= cson)
-		csoff = cson + 1;
-	if (csoff < max(weoff, reoff))
-		csoff = max(weoff, reoff);
-	if (cson > 0x0f)
-		return -1;
-	if (csoff > 0x3f)
-		return -1;
-
-	l =  cson;
-	l |= csoff << 4;
-	l |= weon  << 10;
-	l |= weoff << 14;
-	l |= reon  << 20;
-	l |= reoff << 24;
-
-	t->tim[0] = l;
-
-	actim = ps_to_rfbi_ticks(t->access_time, div);
-	if (actim <= reon)
-		actim = reon + 1;
-	if (actim > 0x3f)
-		return -1;
-
-	wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div);
-	if (wecyc < weoff)
-		wecyc = weoff;
-	if (wecyc > 0x3f)
-		return -1;
-
-	recyc = ps_to_rfbi_ticks(t->re_cycle_time, div);
-	if (recyc < reoff)
-		recyc = reoff;
-	if (recyc > 0x3f)
-		return -1;
-
-	cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div);
-	if (cs_pulse > 0x3f)
-		return -1;
-
-	l =  wecyc;
-	l |= recyc    << 6;
-	l |= cs_pulse << 12;
-	l |= actim    << 22;
-
-	t->tim[1] = l;
-
-	t->tim[2] = div - 1;
-
-	t->converted = 1;
-
-	return 0;
-}
-
-static int rfbi_setup_tearsync(unsigned pin_cnt,
-			       unsigned hs_pulse_time, unsigned vs_pulse_time,
-			       int hs_pol_inv, int vs_pol_inv, int extif_div)
-{
-	int hs, vs;
-	int min;
-	u32 l;
-
-	if (pin_cnt != 1 && pin_cnt != 2)
-		return -EINVAL;
-
-	hs = ps_to_rfbi_ticks(hs_pulse_time, 1);
-	vs = ps_to_rfbi_ticks(vs_pulse_time, 1);
-	if (hs < 2)
-		return -EDOM;
-	if (pin_cnt = 2)
-		min = 2;
-	else
-		min = 4;
-	if (vs < min)
-		return -EDOM;
-	if (vs = hs)
-		return -EINVAL;
-	rfbi.tearsync_pin_cnt = pin_cnt;
-	dev_dbg(rfbi.fbdev->dev,
-		"setup_tearsync: pins %d hs %d vs %d hs_inv %d vs_inv %d\n",
-		pin_cnt, hs, vs, hs_pol_inv, vs_pol_inv);
-
-	rfbi_enable_clocks(1);
-	rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
-	rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
-
-	l = rfbi_read_reg(RFBI_CONFIG0);
-	if (hs_pol_inv)
-		l &= ~(1 << 21);
-	else
-		l |= 1 << 21;
-	if (vs_pol_inv)
-		l &= ~(1 << 20);
-	else
-		l |= 1 << 20;
-	rfbi_enable_clocks(0);
-
-	return 0;
-}
-
-static int rfbi_enable_tearsync(int enable, unsigned line)
-{
-	u32 l;
-
-	dev_dbg(rfbi.fbdev->dev, "tearsync %d line %d mode %d\n",
-		enable, line, rfbi.tearsync_mode);
-	if (line > (1 << 11) - 1)
-		return -EINVAL;
-
-	rfbi_enable_clocks(1);
-	l = rfbi_read_reg(RFBI_CONFIG0);
-	l &= ~(0x3 << 2);
-	if (enable) {
-		rfbi.tearsync_mode = rfbi.tearsync_pin_cnt;
-		l |= rfbi.tearsync_mode << 2;
-	} else
-		rfbi.tearsync_mode = 0;
-	rfbi_write_reg(RFBI_CONFIG0, l);
-	rfbi_write_reg(RFBI_LINE_NUMBER, line);
-	rfbi_enable_clocks(0);
-
-	return 0;
-}
-
-static void rfbi_write_command(const void *buf, unsigned int len)
-{
-	rfbi_enable_clocks(1);
-	if (rfbi.bits_per_cycle = 16) {
-		const u16 *w = buf;
-		BUG_ON(len & 1);
-		for (; len; len -= 2)
-			rfbi_write_reg(RFBI_CMD, *w++);
-	} else {
-		const u8 *b = buf;
-		BUG_ON(rfbi.bits_per_cycle != 8);
-		for (; len; len--)
-			rfbi_write_reg(RFBI_CMD, *b++);
-	}
-	rfbi_enable_clocks(0);
-}
-
-static void rfbi_read_data(void *buf, unsigned int len)
-{
-	rfbi_enable_clocks(1);
-	if (rfbi.bits_per_cycle = 16) {
-		u16 *w = buf;
-		BUG_ON(len & ~1);
-		for (; len; len -= 2) {
-			rfbi_write_reg(RFBI_READ, 0);
-			*w++ = rfbi_read_reg(RFBI_READ);
-		}
-	} else {
-		u8 *b = buf;
-		BUG_ON(rfbi.bits_per_cycle != 8);
-		for (; len; len--) {
-			rfbi_write_reg(RFBI_READ, 0);
-			*b++ = rfbi_read_reg(RFBI_READ);
-		}
-	}
-	rfbi_enable_clocks(0);
-}
-
-static void rfbi_write_data(const void *buf, unsigned int len)
-{
-	rfbi_enable_clocks(1);
-	if (rfbi.bits_per_cycle = 16) {
-		const u16 *w = buf;
-		BUG_ON(len & 1);
-		for (; len; len -= 2)
-			rfbi_write_reg(RFBI_PARAM, *w++);
-	} else {
-		const u8 *b = buf;
-		BUG_ON(rfbi.bits_per_cycle != 8);
-		for (; len; len--)
-			rfbi_write_reg(RFBI_PARAM, *b++);
-	}
-	rfbi_enable_clocks(0);
-}
-
-static void rfbi_transfer_area(int width, int height,
-				void (callback)(void * data), void *data)
-{
-	u32 w;
-
-	BUG_ON(callback = NULL);
-
-	rfbi_enable_clocks(1);
-	omap_dispc_set_lcd_size(width, height);
-
-	rfbi.lcdc_callback = callback;
-	rfbi.lcdc_callback_data = data;
-
-	rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
-
-	w = rfbi_read_reg(RFBI_CONTROL);
-	w |= 1;				/* enable */
-	if (!rfbi.tearsync_mode)
-		w |= 1 << 4;		/* internal trigger, reset by HW */
-	rfbi_write_reg(RFBI_CONTROL, w);
-
-	omap_dispc_enable_lcd_out(1);
-}
-
-static inline void _stop_transfer(void)
-{
-	u32 w;
-
-	w = rfbi_read_reg(RFBI_CONTROL);
-	rfbi_write_reg(RFBI_CONTROL, w & ~(1 << 0));
-	rfbi_enable_clocks(0);
-}
-
-static void rfbi_dma_callback(void *data)
-{
-	_stop_transfer();
-	rfbi.lcdc_callback(rfbi.lcdc_callback_data);
-}
-
-static void rfbi_set_bits_per_cycle(int bpc)
-{
-	u32 l;
-
-	rfbi_enable_clocks(1);
-	l = rfbi_read_reg(RFBI_CONFIG0);
-	l &= ~(0x03 << 0);
-
-	switch (bpc) {
-	case 8:
-		break;
-	case 16:
-		l |= 3;
-		break;
-	default:
-		BUG();
-	}
-	rfbi_write_reg(RFBI_CONFIG0, l);
-	rfbi.bits_per_cycle = bpc;
-	rfbi_enable_clocks(0);
-}
-
-static int rfbi_init(struct omapfb_device *fbdev)
-{
-	u32 l;
-	int r;
-
-	rfbi.fbdev = fbdev;
-	rfbi.base = ioremap(RFBI_BASE, SZ_1K);
-	if (!rfbi.base) {
-		dev_err(fbdev->dev, "can't ioremap RFBI\n");
-		return -ENOMEM;
-	}
-
-	if ((r = rfbi_get_clocks()) < 0)
-		return r;
-	rfbi_enable_clocks(1);
-
-	rfbi.l4_khz = clk_get_rate(rfbi.dss_ick) / 1000;
-
-	/* Reset */
-	rfbi_write_reg(RFBI_SYSCONFIG, 1 << 1);
-	while (!(rfbi_read_reg(RFBI_SYSSTATUS) & (1 << 0)));
-
-	l = rfbi_read_reg(RFBI_SYSCONFIG);
-	/* Enable autoidle and smart-idle */
-	l |= (1 << 0) | (2 << 3);
-	rfbi_write_reg(RFBI_SYSCONFIG, l);
-
-	/* 16-bit interface, ITE trigger mode, 16-bit data */
-	l = (0x03 << 0) | (0x00 << 2) | (0x01 << 5) | (0x02 << 7);
-	l |= (0 << 9) | (1 << 20) | (1 << 21);
-	rfbi_write_reg(RFBI_CONFIG0, l);
-
-	rfbi_write_reg(RFBI_DATA_CYCLE1_0, 0x00000010);
-
-	l = rfbi_read_reg(RFBI_CONTROL);
-	/* Select CS0, clear bypass mode */
-	l = (0x01 << 2);
-	rfbi_write_reg(RFBI_CONTROL, l);
-
-	r = omap_dispc_request_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback,
-				   NULL);
-	if (r < 0) {
-		dev_err(fbdev->dev, "can't get DISPC irq\n");
-		rfbi_enable_clocks(0);
-		return r;
-	}
-
-	l = rfbi_read_reg(RFBI_REVISION);
-	pr_info("omapfb: RFBI version %d.%d initialized\n",
-		(l >> 4) & 0x0f, l & 0x0f);
-
-	rfbi_enable_clocks(0);
-
-	return 0;
-}
-
-static void rfbi_cleanup(void)
-{
-	omap_dispc_free_irq(DISPC_IRQ_FRAMEMASK, rfbi_dma_callback, NULL);
-	rfbi_put_clocks();
-	iounmap(rfbi.base);
-}
-
-const struct lcd_ctrl_extif omap2_ext_if = {
-	.init			= rfbi_init,
-	.cleanup		= rfbi_cleanup,
-	.get_clk_info		= rfbi_get_clk_info,
-	.get_max_tx_rate	= rfbi_get_max_tx_rate,
-	.set_bits_per_cycle	= rfbi_set_bits_per_cycle,
-	.convert_timings	= rfbi_convert_timings,
-	.set_timings		= rfbi_set_timings,
-	.write_command		= rfbi_write_command,
-	.read_data		= rfbi_read_data,
-	.write_data		= rfbi_write_data,
-	.transfer_area		= rfbi_transfer_area,
-	.setup_tearsync		= rfbi_setup_tearsync,
-	.enable_tearsync	= rfbi_enable_tearsync,
-
-	.max_transmit_size	= (u32) ~0,
-};
-
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 01/16] OMAPFB: remove old blizzard driver
From: Tomi Valkeinen @ 2012-01-24 10:00 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, tony, Tomi Valkeinen
In-Reply-To: <1327399231-20826-1-git-send-email-tomi.valkeinen@ti.com>

N8x0's blizzard driver has been ported to new omapdss driver, so we can
now remove the old blizzard driver.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/plat-omap/include/plat/blizzard.h |   12 -
 drivers/video/omap/Kconfig                 |    7 -
 drivers/video/omap/Makefile                |    1 -
 drivers/video/omap/blizzard.c              | 1648 ----------------------------
 drivers/video/omap/omapfb_main.c           |    4 -
 5 files changed, 0 insertions(+), 1672 deletions(-)
 delete mode 100644 arch/arm/plat-omap/include/plat/blizzard.h
 delete mode 100644 drivers/video/omap/blizzard.c

diff --git a/arch/arm/plat-omap/include/plat/blizzard.h b/arch/arm/plat-omap/include/plat/blizzard.h
deleted file mode 100644
index 56e7f2e..0000000
--- a/arch/arm/plat-omap/include/plat/blizzard.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _BLIZZARD_H
-#define _BLIZZARD_H
-
-struct blizzard_platform_data {
-	void		(*power_up)(struct device *dev);
-	void		(*power_down)(struct device *dev);
-	unsigned long	(*get_clock_rate)(struct device *dev);
-
-	unsigned	te_connected:1;
-};
-
-#endif
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 84ff232..ab234d5 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -23,13 +23,6 @@ config FB_OMAP_LCDC_HWA742
 	  Say Y here if you want to have support for the external
 	  Epson HWA742 LCD controller.
 
-config FB_OMAP_LCDC_BLIZZARD
-	bool "Epson Blizzard LCD controller support"
-	depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
-	help
-	  Say Y here if you want to have support for the external
-	  Epson Blizzard LCD controller.
-
 config FB_OMAP_MANUAL_UPDATE
 	bool "Default to manual update mode"
 	depends on FB_OMAP && FB_OMAP_LCDC_EXTERNAL
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
index ef78550..7042a4a 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/omap/Makefile
@@ -14,7 +14,6 @@ objs-$(CONFIG_ARCH_OMAP1)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o
 objs-$(CONFIG_ARCH_OMAP2)$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += rfbi.o
 
 objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
-objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o
 
 objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o
 objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o
diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
deleted file mode 100644
index c0504a8..0000000
--- a/drivers/video/omap/blizzard.c
+++ /dev/null
@@ -1,1648 +0,0 @@
-/*
- * Epson Blizzard LCD controller driver
- *
- * Copyright (C) 2004-2005 Nokia Corporation
- * Authors:     Juha Yrjola   <juha.yrjola@nokia.com>
- *	        Imre Deak     <imre.deak@nokia.com>
- * YUV support: Jussi Laako   <jussi.laako@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/fb.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-
-#include <plat/dma.h>
-#include <plat/blizzard.h>
-
-#include "omapfb.h"
-#include "dispc.h"
-
-#define MODULE_NAME				"blizzard"
-
-#define BLIZZARD_REV_CODE			0x00
-#define BLIZZARD_CONFIG				0x02
-#define BLIZZARD_PLL_DIV			0x04
-#define BLIZZARD_PLL_LOCK_RANGE			0x06
-#define BLIZZARD_PLL_CLOCK_SYNTH_0		0x08
-#define BLIZZARD_PLL_CLOCK_SYNTH_1		0x0a
-#define BLIZZARD_PLL_MODE			0x0c
-#define BLIZZARD_CLK_SRC			0x0e
-#define BLIZZARD_MEM_BANK0_ACTIVATE		0x10
-#define BLIZZARD_MEM_BANK0_STATUS		0x14
-#define BLIZZARD_PANEL_CONFIGURATION		0x28
-#define BLIZZARD_HDISP				0x2a
-#define BLIZZARD_HNDP				0x2c
-#define BLIZZARD_VDISP0				0x2e
-#define BLIZZARD_VDISP1				0x30
-#define BLIZZARD_VNDP				0x32
-#define BLIZZARD_HSW				0x34
-#define BLIZZARD_VSW				0x38
-#define BLIZZARD_DISPLAY_MODE			0x68
-#define BLIZZARD_INPUT_WIN_X_START_0		0x6c
-#define BLIZZARD_DATA_SOURCE_SELECT		0x8e
-#define BLIZZARD_DISP_MEM_DATA_PORT		0x90
-#define BLIZZARD_DISP_MEM_READ_ADDR0		0x92
-#define BLIZZARD_POWER_SAVE			0xE6
-#define BLIZZARD_NDISP_CTRL_STATUS		0xE8
-
-/* Data source select */
-/* For S1D13745 */
-#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND	0x00
-#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE	0x01
-#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE	0x04
-#define BLIZZARD_SRC_DISABLE_OVERLAY		0x05
-/* For S1D13744 */
-#define BLIZZARD_SRC_WRITE_LCD			0x00
-#define BLIZZARD_SRC_BLT_LCD			0x06
-
-#define BLIZZARD_COLOR_RGB565			0x01
-#define BLIZZARD_COLOR_YUV420			0x09
-
-#define BLIZZARD_VERSION_S1D13745		0x01	/* Hailstorm */
-#define BLIZZARD_VERSION_S1D13744		0x02	/* Blizzard */
-
-#define BLIZZARD_AUTO_UPDATE_TIME		(HZ / 20)
-
-/* Reserve 4 request slots for requests in irq context */
-#define REQ_POOL_SIZE			24
-#define IRQ_REQ_POOL_SIZE		4
-
-#define REQ_FROM_IRQ_POOL 0x01
-
-#define REQ_COMPLETE	0
-#define REQ_PENDING	1
-
-struct blizzard_reg_list {
-	int	start;
-	int	end;
-};
-
-/* These need to be saved / restored separately from the rest. */
-static const struct blizzard_reg_list blizzard_pll_regs[] = {
-	{
-		.start	= 0x04,		/* Don't save PLL ctrl (0x0C) */
-		.end	= 0x0a,
-	},
-	{
-		.start	= 0x0e,		/* Clock configuration */
-		.end	= 0x0e,
-	},
-};
-
-static const struct blizzard_reg_list blizzard_gen_regs[] = {
-	{
-		.start	= 0x18,		/* SDRAM control */
-		.end	= 0x20,
-	},
-	{
-		.start	= 0x28,		/* LCD Panel configuration */
-		.end	= 0x5a,		/* HSSI interface, TV configuration */
-	},
-};
-
-static u8 blizzard_reg_cache[0x5a / 2];
-
-struct update_param {
-	int	plane;
-	int	x, y, width, height;
-	int	out_x, out_y;
-	int	out_width, out_height;
-	int	color_mode;
-	int	bpp;
-	int	flags;
-};
-
-struct blizzard_request {
-	struct list_head entry;
-	unsigned int	 flags;
-
-	int		 (*handler)(struct blizzard_request *req);
-	void		 (*complete)(void *data);
-	void		 *complete_data;
-
-	union {
-		struct update_param	update;
-		struct completion	*sync;
-	} par;
-};
-
-struct plane_info {
-	unsigned long offset;
-	int pos_x, pos_y;
-	int width, height;
-	int out_width, out_height;
-	int scr_width;
-	int color_mode;
-	int bpp;
-};
-
-struct blizzard_struct {
-	enum omapfb_update_mode	update_mode;
-	enum omapfb_update_mode	update_mode_before_suspend;
-
-	struct timer_list	auto_update_timer;
-	int			stop_auto_update;
-	struct omapfb_update_window	auto_update_window;
-	int			enabled_planes;
-	int			vid_nonstd_color;
-	int			vid_scaled;
-	int			last_color_mode;
-	int			zoom_on;
-	int			zoom_area_gx1;
-	int			zoom_area_gx2;
-	int			zoom_area_gy1;
-	int			zoom_area_gy2;
-	int			screen_width;
-	int			screen_height;
-	unsigned		te_connected:1;
-	unsigned		vsync_only:1;
-
-	struct plane_info	plane[OMAPFB_PLANE_NUM];
-
-	struct blizzard_request	req_pool[REQ_POOL_SIZE];
-	struct list_head	pending_req_list;
-	struct list_head	free_req_list;
-	struct semaphore	req_sema;
-	spinlock_t		req_lock;
-
-	unsigned long		sys_ck_rate;
-	struct extif_timings	reg_timings, lut_timings;
-
-	u32			max_transmit_size;
-	u32			extif_clk_period;
-	int			extif_clk_div;
-	unsigned long		pix_tx_time;
-	unsigned long		line_upd_time;
-
-	struct omapfb_device	*fbdev;
-	struct lcd_ctrl_extif	*extif;
-	const struct lcd_ctrl	*int_ctrl;
-
-	void			(*power_up)(struct device *dev);
-	void			(*power_down)(struct device *dev);
-
-	int			version;
-} blizzard;
-
-struct lcd_ctrl blizzard_ctrl;
-
-static u8 blizzard_read_reg(u8 reg)
-{
-	u8 data;
-
-	blizzard.extif->set_bits_per_cycle(8);
-	blizzard.extif->write_command(&reg, 1);
-	blizzard.extif->read_data(&data, 1);
-
-	return data;
-}
-
-static void blizzard_write_reg(u8 reg, u8 val)
-{
-	blizzard.extif->set_bits_per_cycle(8);
-	blizzard.extif->write_command(&reg, 1);
-	blizzard.extif->write_data(&val, 1);
-}
-
-static void blizzard_restart_sdram(void)
-{
-	unsigned long tmo;
-
-	blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 0);
-	udelay(50);
-	blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 1);
-	tmo = jiffies + msecs_to_jiffies(200);
-	while (!(blizzard_read_reg(BLIZZARD_MEM_BANK0_STATUS) & 0x01)) {
-		if (time_after(jiffies, tmo)) {
-			dev_err(blizzard.fbdev->dev,
-					"s1d1374x: SDRAM not ready\n");
-			break;
-		}
-		msleep(1);
-	}
-}
-
-static void blizzard_stop_sdram(void)
-{
-	blizzard_write_reg(BLIZZARD_MEM_BANK0_ACTIVATE, 0);
-}
-
-/* Wait until the last window was completely written into the controllers
- * SDRAM and we can start transferring the next window.
- */
-static void blizzard_wait_line_buffer(void)
-{
-	unsigned long tmo = jiffies + msecs_to_jiffies(30);
-
-	while (blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS) & (1 << 7)) {
-		if (time_after(jiffies, tmo)) {
-			if (printk_ratelimit())
-				dev_err(blizzard.fbdev->dev,
-					"s1d1374x: line buffer not ready\n");
-			break;
-		}
-	}
-}
-
-/* Wait until the YYC color space converter is idle. */
-static void blizzard_wait_yyc(void)
-{
-	unsigned long tmo = jiffies + msecs_to_jiffies(30);
-
-	while (blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS) & (1 << 4)) {
-		if (time_after(jiffies, tmo)) {
-			if (printk_ratelimit())
-				dev_err(blizzard.fbdev->dev,
-					"s1d1374x: YYC not ready\n");
-			break;
-		}
-	}
-}
-
-static void disable_overlay(void)
-{
-	blizzard_write_reg(BLIZZARD_DATA_SOURCE_SELECT,
-				BLIZZARD_SRC_DISABLE_OVERLAY);
-}
-
-static void set_window_regs(int x_start, int y_start, int x_end, int y_end,
-			    int x_out_start, int y_out_start,
-			    int x_out_end, int y_out_end, int color_mode,
-			    int zoom_off, int flags)
-{
-	u8 tmp[18];
-	u8 cmd;
-
-	x_end--;
-	y_end--;
-	tmp[0] = x_start;
-	tmp[1] = x_start >> 8;
-	tmp[2] = y_start;
-	tmp[3] = y_start >> 8;
-	tmp[4] = x_end;
-	tmp[5] = x_end >> 8;
-	tmp[6] = y_end;
-	tmp[7] = y_end >> 8;
-
-	x_out_end--;
-	y_out_end--;
-	tmp[8]  = x_out_start;
-	tmp[9]  = x_out_start >> 8;
-	tmp[10] = y_out_start;
-	tmp[11] = y_out_start >> 8;
-	tmp[12] = x_out_end;
-	tmp[13] = x_out_end >> 8;
-	tmp[14] = y_out_end;
-	tmp[15] = y_out_end >> 8;
-
-	tmp[16] = color_mode;
-	if (zoom_off && blizzard.version = BLIZZARD_VERSION_S1D13745)
-		tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
-	else if (flags & OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY)
-		tmp[17] = BLIZZARD_SRC_WRITE_OVERLAY_ENABLE;
-	else
-		tmp[17] = blizzard.version = BLIZZARD_VERSION_S1D13744 ?
-				BLIZZARD_SRC_WRITE_LCD :
-				BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
-
-	blizzard.extif->set_bits_per_cycle(8);
-	cmd = BLIZZARD_INPUT_WIN_X_START_0;
-	blizzard.extif->write_command(&cmd, 1);
-	blizzard.extif->write_data(tmp, 18);
-}
-
-static void enable_tearsync(int y, int width, int height, int screen_height,
-			    int out_height, int force_vsync)
-{
-	u8 b;
-
-	b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
-	b |= 1 << 3;
-	blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);
-
-	if (likely(blizzard.vsync_only || force_vsync)) {
-		blizzard.extif->enable_tearsync(1, 0);
-		return;
-	}
-
-	if (width * blizzard.pix_tx_time < blizzard.line_upd_time) {
-		blizzard.extif->enable_tearsync(1, 0);
-		return;
-	}
-
-	if ((width * blizzard.pix_tx_time / 1000) * height <
-	    (y + out_height) * (blizzard.line_upd_time / 1000)) {
-		blizzard.extif->enable_tearsync(1, 0);
-		return;
-	}
-
-	blizzard.extif->enable_tearsync(1, y + 1);
-}
-
-static void disable_tearsync(void)
-{
-	u8 b;
-
-	blizzard.extif->enable_tearsync(0, 0);
-	b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
-	b &= ~(1 << 3);
-	blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);
-	b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
-}
-
-static inline void set_extif_timings(const struct extif_timings *t);
-
-static inline struct blizzard_request *alloc_req(void)
-{
-	unsigned long flags;
-	struct blizzard_request *req;
-	int req_flags = 0;
-
-	if (!in_interrupt())
-		down(&blizzard.req_sema);
-	else
-		req_flags = REQ_FROM_IRQ_POOL;
-
-	spin_lock_irqsave(&blizzard.req_lock, flags);
-	BUG_ON(list_empty(&blizzard.free_req_list));
-	req = list_entry(blizzard.free_req_list.next,
-			 struct blizzard_request, entry);
-	list_del(&req->entry);
-	spin_unlock_irqrestore(&blizzard.req_lock, flags);
-
-	INIT_LIST_HEAD(&req->entry);
-	req->flags = req_flags;
-
-	return req;
-}
-
-static inline void free_req(struct blizzard_request *req)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&blizzard.req_lock, flags);
-
-	list_move(&req->entry, &blizzard.free_req_list);
-	if (!(req->flags & REQ_FROM_IRQ_POOL))
-		up(&blizzard.req_sema);
-
-	spin_unlock_irqrestore(&blizzard.req_lock, flags);
-}
-
-static void process_pending_requests(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&blizzard.req_lock, flags);
-
-	while (!list_empty(&blizzard.pending_req_list)) {
-		struct blizzard_request *req;
-		void (*complete)(void *);
-		void *complete_data;
-
-		req = list_entry(blizzard.pending_req_list.next,
-				 struct blizzard_request, entry);
-		spin_unlock_irqrestore(&blizzard.req_lock, flags);
-
-		if (req->handler(req) = REQ_PENDING)
-			return;
-
-		complete = req->complete;
-		complete_data = req->complete_data;
-		free_req(req);
-
-		if (complete)
-			complete(complete_data);
-
-		spin_lock_irqsave(&blizzard.req_lock, flags);
-	}
-
-	spin_unlock_irqrestore(&blizzard.req_lock, flags);
-}
-
-static void submit_req_list(struct list_head *head)
-{
-	unsigned long flags;
-	int process = 1;
-
-	spin_lock_irqsave(&blizzard.req_lock, flags);
-	if (likely(!list_empty(&blizzard.pending_req_list)))
-		process = 0;
-	list_splice_init(head, blizzard.pending_req_list.prev);
-	spin_unlock_irqrestore(&blizzard.req_lock, flags);
-
-	if (process)
-		process_pending_requests();
-}
-
-static void request_complete(void *data)
-{
-	struct blizzard_request	*req = (struct blizzard_request *)data;
-	void			(*complete)(void *);
-	void			*complete_data;
-
-	complete = req->complete;
-	complete_data = req->complete_data;
-
-	free_req(req);
-
-	if (complete)
-		complete(complete_data);
-
-	process_pending_requests();
-}
-
-
-static int do_full_screen_update(struct blizzard_request *req)
-{
-	int i;
-	int flags;
-
-	for (i = 0; i < 3; i++) {
-		struct plane_info *p = &blizzard.plane[i];
-		if (!(blizzard.enabled_planes & (1 << i))) {
-			blizzard.int_ctrl->enable_plane(i, 0);
-			continue;
-		}
-		dev_dbg(blizzard.fbdev->dev, "pw %d ph %d\n",
-			p->width, p->height);
-		blizzard.int_ctrl->setup_plane(i,
-				OMAPFB_CHANNEL_OUT_LCD, p->offset,
-				p->scr_width, p->pos_x, p->pos_y,
-				p->width, p->height,
-				p->color_mode);
-		blizzard.int_ctrl->enable_plane(i, 1);
-	}
-
-	dev_dbg(blizzard.fbdev->dev, "sw %d sh %d\n",
-		blizzard.screen_width, blizzard.screen_height);
-	blizzard_wait_line_buffer();
-	flags = req->par.update.flags;
-	if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC)
-		enable_tearsync(0, blizzard.screen_width,
-				blizzard.screen_height,
-				blizzard.screen_height,
-				blizzard.screen_height,
-				flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC);
-	else
-		disable_tearsync();
-
-	set_window_regs(0, 0, blizzard.screen_width, blizzard.screen_height,
-			0, 0, blizzard.screen_width, blizzard.screen_height,
-			BLIZZARD_COLOR_RGB565, blizzard.zoom_on, flags);
-	blizzard.zoom_on = 0;
-
-	blizzard.extif->set_bits_per_cycle(16);
-	/* set_window_regs has left the register index at the right
-	 * place, so no need to set it here.
-	 */
-	blizzard.extif->transfer_area(blizzard.screen_width,
-				      blizzard.screen_height,
-				      request_complete, req);
-	return REQ_PENDING;
-}
-
-static int check_1d_intersect(int a1, int a2, int b1, int b2)
-{
-	if (a2 <= b1 || b2 <= a1)
-		return 0;
-	return 1;
-}
-
-/* Setup all planes with an overlapping area with the update window. */
-static int do_partial_update(struct blizzard_request *req, int plane,
-			     int x, int y, int w, int h,
-			     int x_out, int y_out, int w_out, int h_out,
-			     int wnd_color_mode, int bpp)
-{
-	int i;
-	int gx1, gy1, gx2, gy2;
-	int gx1_out, gy1_out, gx2_out, gy2_out;
-	int color_mode;
-	int flags;
-	int zoom_off;
-	int have_zoom_for_this_update = 0;
-
-	/* Global coordinates, relative to pixel 0,0 of the LCD */
-	gx1 = x + blizzard.plane[plane].pos_x;
-	gy1 = y + blizzard.plane[plane].pos_y;
-	gx2 = gx1 + w;
-	gy2 = gy1 + h;
-
-	flags = req->par.update.flags;
-	if (flags & OMAPFB_FORMAT_FLAG_DOUBLE) {
-		gx1_out = gx1;
-		gy1_out = gy1;
-		gx2_out = gx1 + w * 2;
-		gy2_out = gy1 + h * 2;
-	} else {
-		gx1_out = x_out + blizzard.plane[plane].pos_x;
-		gy1_out = y_out + blizzard.plane[plane].pos_y;
-		gx2_out = gx1_out + w_out;
-		gy2_out = gy1_out + h_out;
-	}
-
-	for (i = 0; i < OMAPFB_PLANE_NUM; i++) {
-		struct plane_info *p = &blizzard.plane[i];
-		int px1, py1;
-		int px2, py2;
-		int pw, ph;
-		int pposx, pposy;
-		unsigned long offset;
-
-		if (!(blizzard.enabled_planes & (1 << i))  ||
-		    (wnd_color_mode && i != plane)) {
-			blizzard.int_ctrl->enable_plane(i, 0);
-			continue;
-		}
-		/* Plane coordinates */
-		if (i = plane) {
-			/* Plane in which we are doing the update.
-			 * Local coordinates are the one in the update
-			 * request.
-			 */
-			px1 = x;
-			py1 = y;
-			px2 = x + w;
-			py2 = y + h;
-			pposx = 0;
-			pposy = 0;
-		} else {
-			/* Check if this plane has an overlapping part */
-			px1 = gx1 - p->pos_x;
-			py1 = gy1 - p->pos_y;
-			px2 = gx2 - p->pos_x;
-			py2 = gy2 - p->pos_y;
-			if (px1 >= p->width || py1 >= p->height ||
-			    px2 <= 0 || py2 <= 0) {
-				blizzard.int_ctrl->enable_plane(i, 0);
-				continue;
-			}
-			/* Calculate the coordinates for the overlapping
-			 * part in the plane's local coordinates.
-			 */
-			pposx = -px1;
-			pposy = -py1;
-			if (px1 < 0)
-				px1 = 0;
-			if (py1 < 0)
-				py1 = 0;
-			if (px2 > p->width)
-				px2 = p->width;
-			if (py2 > p->height)
-				py2 = p->height;
-			if (pposx < 0)
-				pposx = 0;
-			if (pposy < 0)
-				pposy = 0;
-		}
-		pw = px2 - px1;
-		ph = py2 - py1;
-		offset = p->offset + (p->scr_width * py1 + px1) * p->bpp / 8;
-		if (wnd_color_mode)
-			/* Window embedded in the plane with a differing
-			 * color mode / bpp. Calculate the number of DMA
-			 * transfer elements in terms of the plane's bpp.
-			 */
-			pw = (pw + 1) * bpp / p->bpp;
-#ifdef VERBOSE
-		dev_dbg(blizzard.fbdev->dev,
-			"plane %d offset %#08lx pposx %d pposy %d "
-			"px1 %d py1 %d pw %d ph %d\n",
-			i, offset, pposx, pposy, px1, py1, pw, ph);
-#endif
-		blizzard.int_ctrl->setup_plane(i,
-				OMAPFB_CHANNEL_OUT_LCD, offset,
-				p->scr_width,
-				pposx, pposy, pw, ph,
-				p->color_mode);
-
-		blizzard.int_ctrl->enable_plane(i, 1);
-	}
-
-	switch (wnd_color_mode) {
-	case OMAPFB_COLOR_YUV420:
-		color_mode = BLIZZARD_COLOR_YUV420;
-		/* Currently only the 16 bits/pixel cycle format is
-		 * supported on the external interface. Adjust the number
-		 * of transfer elements per line for 12bpp format.
-		 */
-		w = (w + 1) * 3 / 4;
-		break;
-	default:
-		color_mode = BLIZZARD_COLOR_RGB565;
-		break;
-	}
-
-	blizzard_wait_line_buffer();
-	if (blizzard.last_color_mode = BLIZZARD_COLOR_YUV420)
-		blizzard_wait_yyc();
-	blizzard.last_color_mode = color_mode;
-	if (flags & OMAPFB_FORMAT_FLAG_TEARSYNC)
-		enable_tearsync(gy1, w, h,
-				blizzard.screen_height,
-				h_out,
-				flags & OMAPFB_FORMAT_FLAG_FORCE_VSYNC);
-	else
-		disable_tearsync();
-
-	if ((gx2_out - gx1_out) != (gx2 - gx1) ||
-	    (gy2_out - gy1_out) != (gy2 - gy1))
-		have_zoom_for_this_update = 1;
-
-	/* 'background' type of screen update (as opposed to 'destructive')
-	   can be used to disable scaling if scaling is active */
-	zoom_off = blizzard.zoom_on && !have_zoom_for_this_update &&
-	    (gx1_out = 0) && (gx2_out = blizzard.screen_width) &&
-	    (gy1_out = 0) && (gy2_out = blizzard.screen_height) &&
-	    (gx1 = 0) && (gy1 = 0);
-
-	if (blizzard.zoom_on && !have_zoom_for_this_update && !zoom_off &&
-	    check_1d_intersect(blizzard.zoom_area_gx1, blizzard.zoom_area_gx2,
-			       gx1_out, gx2_out) &&
-	    check_1d_intersect(blizzard.zoom_area_gy1, blizzard.zoom_area_gy2,
-			       gy1_out, gy2_out)) {
-		/* Previous screen update was using scaling, current update
-		 * is not using it. Additionally, current screen update is
-		 * going to overlap with the scaled area. Scaling needs to be
-		 * disabled in order to avoid 'magnifying glass' effect.
-		 * Dummy setup of background window can be used for this.
-		 */
-		set_window_regs(0, 0, blizzard.screen_width,
-				blizzard.screen_height,
-				0, 0, blizzard.screen_width,
-				blizzard.screen_height,
-				BLIZZARD_COLOR_RGB565, 1, flags);
-		blizzard.zoom_on = 0;
-	}
-
-	/* remember scaling settings if we have scaled update */
-	if (have_zoom_for_this_update) {
-		blizzard.zoom_on = 1;
-		blizzard.zoom_area_gx1 = gx1_out;
-		blizzard.zoom_area_gx2 = gx2_out;
-		blizzard.zoom_area_gy1 = gy1_out;
-		blizzard.zoom_area_gy2 = gy2_out;
-	}
-
-	set_window_regs(gx1, gy1, gx2, gy2, gx1_out, gy1_out, gx2_out, gy2_out,
-			color_mode, zoom_off, flags);
-	if (zoom_off)
-		blizzard.zoom_on = 0;
-
-	blizzard.extif->set_bits_per_cycle(16);
-	/* set_window_regs has left the register index at the right
-	 * place, so no need to set it here.
-	 */
-	blizzard.extif->transfer_area(w, h, request_complete, req);
-
-	return REQ_PENDING;
-}
-
-static int send_frame_handler(struct blizzard_request *req)
-{
-	struct update_param *par = &req->par.update;
-	int plane = par->plane;
-
-#ifdef VERBOSE
-	dev_dbg(blizzard.fbdev->dev,
-		"send_frame: x %d y %d w %d h %d "
-		"x_out %d y_out %d w_out %d h_out %d "
-		"color_mode %04x flags %04x planes %01x\n",
-		par->x, par->y, par->width, par->height,
-		par->out_x, par->out_y, par->out_width, par->out_height,
-		par->color_mode, par->flags, blizzard.enabled_planes);
-#endif
-	if (par->flags & OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY)
-		disable_overlay();
-
-	if ((blizzard.enabled_planes & blizzard.vid_nonstd_color) ||
-	     (blizzard.enabled_planes & blizzard.vid_scaled))
-		return do_full_screen_update(req);
-
-	return do_partial_update(req, plane, par->x, par->y,
-				 par->width, par->height,
-				 par->out_x, par->out_y,
-				 par->out_width, par->out_height,
-				 par->color_mode, par->bpp);
-}
-
-static void send_frame_complete(void *data)
-{
-}
-
-#define ADD_PREQ(_x, _y, _w, _h, _x_out, _y_out, _w_out, _h_out) do {	\
-	req = alloc_req();			\
-	req->handler	= send_frame_handler;	\
-	req->complete	= send_frame_complete;	\
-	req->par.update.plane = plane_idx;	\
-	req->par.update.x = _x;			\
-	req->par.update.y = _y;			\
-	req->par.update.width  = _w;		\
-	req->par.update.height = _h;		\
-	req->par.update.out_x = _x_out;		\
-	req->par.update.out_y = _y_out;		\
-	req->par.update.out_width = _w_out;	\
-	req->par.update.out_height = _h_out;	\
-	req->par.update.bpp = bpp;		\
-	req->par.update.color_mode = color_mode;\
-	req->par.update.flags	  = flags;	\
-	list_add_tail(&req->entry, req_head);	\
-} while(0)
-
-static void create_req_list(int plane_idx,
-			    struct omapfb_update_window *win,
-			    struct list_head *req_head)
-{
-	struct blizzard_request *req;
-	int x = win->x;
-	int y = win->y;
-	int width = win->width;
-	int height = win->height;
-	int x_out = win->out_x;
-	int y_out = win->out_y;
-	int width_out = win->out_width;
-	int height_out = win->out_height;
-	int color_mode;
-	int bpp;
-	int flags;
-	unsigned int ystart = y;
-	unsigned int yspan = height;
-	unsigned int ystart_out = y_out;
-	unsigned int yspan_out = height_out;
-
-	flags = win->format & ~OMAPFB_FORMAT_MASK;
-	color_mode = win->format & OMAPFB_FORMAT_MASK;
-	switch (color_mode) {
-	case OMAPFB_COLOR_YUV420:
-		/* Embedded window with different color mode */
-		bpp = 12;
-		/* X, Y, height must be aligned at 2, width at 4 pixels */
-		x &= ~1;
-		y &= ~1;
-		height = yspan = height & ~1;
-		width = width & ~3;
-		break;
-	default:
-		/* Same as the plane color mode */
-		bpp = blizzard.plane[plane_idx].bpp;
-		break;
-	}
-	if (width * height * bpp / 8 > blizzard.max_transmit_size) {
-		yspan = blizzard.max_transmit_size / (width * bpp / 8);
-		yspan_out = yspan * height_out / height;
-		ADD_PREQ(x, ystart, width, yspan, x_out, ystart_out,
-			 width_out, yspan_out);
-		ystart += yspan;
-		ystart_out += yspan_out;
-		yspan = height - yspan;
-		yspan_out = height_out - yspan_out;
-		flags &= ~OMAPFB_FORMAT_FLAG_TEARSYNC;
-	}
-
-	ADD_PREQ(x, ystart, width, yspan, x_out, ystart_out,
-		 width_out, yspan_out);
-}
-
-static void auto_update_complete(void *data)
-{
-	if (!blizzard.stop_auto_update)
-		mod_timer(&blizzard.auto_update_timer,
-			  jiffies + BLIZZARD_AUTO_UPDATE_TIME);
-}
-
-static void blizzard_update_window_auto(unsigned long arg)
-{
-	LIST_HEAD(req_list);
-	struct blizzard_request *last;
-	struct omapfb_plane_struct *plane;
-
-	plane = blizzard.fbdev->fb_info[0]->par;
-	create_req_list(plane->idx,
-			&blizzard.auto_update_window, &req_list);
-	last = list_entry(req_list.prev, struct blizzard_request, entry);
-
-	last->complete = auto_update_complete;
-	last->complete_data = NULL;
-
-	submit_req_list(&req_list);
-}
-
-int blizzard_update_window_async(struct fb_info *fbi,
-				 struct omapfb_update_window *win,
-				 void (*complete_callback)(void *arg),
-				 void *complete_callback_data)
-{
-	LIST_HEAD(req_list);
-	struct blizzard_request *last;
-	struct omapfb_plane_struct *plane = fbi->par;
-
-	if (unlikely(blizzard.update_mode != OMAPFB_MANUAL_UPDATE))
-		return -EINVAL;
-	if (unlikely(!blizzard.te_connected &&
-		     (win->format & OMAPFB_FORMAT_FLAG_TEARSYNC)))
-		return -EINVAL;
-
-	create_req_list(plane->idx, win, &req_list);
-	last = list_entry(req_list.prev, struct blizzard_request, entry);
-
-	last->complete = complete_callback;
-	last->complete_data = (void *)complete_callback_data;
-
-	submit_req_list(&req_list);
-
-	return 0;
-}
-EXPORT_SYMBOL(blizzard_update_window_async);
-
-static int update_full_screen(void)
-{
-	return blizzard_update_window_async(blizzard.fbdev->fb_info[0],
-				     &blizzard.auto_update_window, NULL, NULL);
-
-}
-
-static int blizzard_setup_plane(int plane, int channel_out,
-				  unsigned long offset, int screen_width,
-				  int pos_x, int pos_y, int width, int height,
-				  int color_mode)
-{
-	struct plane_info *p;
-
-#ifdef VERBOSE
-	dev_dbg(blizzard.fbdev->dev,
-		    "plane %d ch_out %d offset %#08lx scr_width %d "
-		    "pos_x %d pos_y %d width %d height %d color_mode %d\n",
-		    plane, channel_out, offset, screen_width,
-		    pos_x, pos_y, width, height, color_mode);
-#endif
-	if ((unsigned)plane > OMAPFB_PLANE_NUM)
-		return -EINVAL;
-	p = &blizzard.plane[plane];
-
-	switch (color_mode) {
-	case OMAPFB_COLOR_YUV422:
-	case OMAPFB_COLOR_YUY422:
-		p->bpp = 16;
-		blizzard.vid_nonstd_color &= ~(1 << plane);
-		break;
-	case OMAPFB_COLOR_YUV420:
-		p->bpp = 12;
-		blizzard.vid_nonstd_color |= 1 << plane;
-		break;
-	case OMAPFB_COLOR_RGB565:
-		p->bpp = 16;
-		blizzard.vid_nonstd_color &= ~(1 << plane);
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	p->offset = offset;
-	p->pos_x = pos_x;
-	p->pos_y = pos_y;
-	p->width = width;
-	p->height = height;
-	p->scr_width = screen_width;
-	if (!p->out_width)
-		p->out_width = width;
-	if (!p->out_height)
-		p->out_height = height;
-
-	p->color_mode = color_mode;
-
-	return 0;
-}
-
-static int blizzard_set_scale(int plane, int orig_w, int orig_h,
-			      int out_w, int out_h)
-{
-	struct plane_info *p = &blizzard.plane[plane];
-	int r;
-
-	dev_dbg(blizzard.fbdev->dev,
-		"plane %d orig_w %d orig_h %d out_w %d out_h %d\n",
-		plane, orig_w, orig_h, out_w, out_h);
-	if ((unsigned)plane > OMAPFB_PLANE_NUM)
-		return -ENODEV;
-
-	r = blizzard.int_ctrl->set_scale(plane, orig_w, orig_h, out_w, out_h);
-	if (r < 0)
-		return r;
-
-	p->width = orig_w;
-	p->height = orig_h;
-	p->out_width = out_w;
-	p->out_height = out_h;
-	if (orig_w = out_w && orig_h = out_h)
-		blizzard.vid_scaled &= ~(1 << plane);
-	else
-		blizzard.vid_scaled |= 1 << plane;
-
-	return 0;
-}
-
-static int blizzard_set_rotate(int angle)
-{
-	u32 l;
-
-	l = blizzard_read_reg(BLIZZARD_PANEL_CONFIGURATION);
-	l &= ~0x03;
-
-	switch (angle) {
-	case 0:
-		l = l | 0x00;
-		break;
-	case 90:
-		l = l | 0x03;
-		break;
-	case 180:
-		l = l | 0x02;
-		break;
-	case 270:
-		l = l | 0x01;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	blizzard_write_reg(BLIZZARD_PANEL_CONFIGURATION, l);
-
-	return 0;
-}
-
-static int blizzard_enable_plane(int plane, int enable)
-{
-	if (enable)
-		blizzard.enabled_planes |= 1 << plane;
-	else
-		blizzard.enabled_planes &= ~(1 << plane);
-
-	return 0;
-}
-
-static int sync_handler(struct blizzard_request *req)
-{
-	complete(req->par.sync);
-	return REQ_COMPLETE;
-}
-
-static void blizzard_sync(void)
-{
-	LIST_HEAD(req_list);
-	struct blizzard_request *req;
-	struct completion comp;
-
-	req = alloc_req();
-
-	req->handler = sync_handler;
-	req->complete = NULL;
-	init_completion(&comp);
-	req->par.sync = &comp;
-
-	list_add(&req->entry, &req_list);
-	submit_req_list(&req_list);
-
-	wait_for_completion(&comp);
-}
-
-
-static void blizzard_bind_client(struct omapfb_notifier_block *nb)
-{
-	if (blizzard.update_mode = OMAPFB_MANUAL_UPDATE) {
-		omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_READY);
-	}
-}
-
-static int blizzard_set_update_mode(enum omapfb_update_mode mode)
-{
-	if (unlikely(mode != OMAPFB_MANUAL_UPDATE &&
-		     mode != OMAPFB_AUTO_UPDATE &&
-		     mode != OMAPFB_UPDATE_DISABLED))
-		return -EINVAL;
-
-	if (mode = blizzard.update_mode)
-		return 0;
-
-	dev_info(blizzard.fbdev->dev, "s1d1374x: setting update mode to %s\n",
-			mode = OMAPFB_UPDATE_DISABLED ? "disabled" :
-			(mode = OMAPFB_AUTO_UPDATE ? "auto" : "manual"));
-
-	switch (blizzard.update_mode) {
-	case OMAPFB_MANUAL_UPDATE:
-		omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_DISABLED);
-		break;
-	case OMAPFB_AUTO_UPDATE:
-		blizzard.stop_auto_update = 1;
-		del_timer_sync(&blizzard.auto_update_timer);
-		break;
-	case OMAPFB_UPDATE_DISABLED:
-		break;
-	}
-
-	blizzard.update_mode = mode;
-	blizzard_sync();
-	blizzard.stop_auto_update = 0;
-
-	switch (mode) {
-	case OMAPFB_MANUAL_UPDATE:
-		omapfb_notify_clients(blizzard.fbdev, OMAPFB_EVENT_READY);
-		break;
-	case OMAPFB_AUTO_UPDATE:
-		blizzard_update_window_auto(0);
-		break;
-	case OMAPFB_UPDATE_DISABLED:
-		break;
-	}
-
-	return 0;
-}
-
-static enum omapfb_update_mode blizzard_get_update_mode(void)
-{
-	return blizzard.update_mode;
-}
-
-static inline void set_extif_timings(const struct extif_timings *t)
-{
-	blizzard.extif->set_timings(t);
-}
-
-static inline unsigned long round_to_extif_ticks(unsigned long ps, int div)
-{
-	int bus_tick = blizzard.extif_clk_period * div;
-	return (ps + bus_tick - 1) / bus_tick * bus_tick;
-}
-
-static int calc_reg_timing(unsigned long sysclk, int div)
-{
-	struct extif_timings *t;
-	unsigned long systim;
-
-	/* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns,
-	 * AccessTime 2 ns + 12.2 ns (regs),
-	 * WEOffTime = WEOnTime + 1 ns,
-	 * REOffTime = REOnTime + 12 ns (regs),
-	 * CSOffTime = REOffTime + 1 ns
-	 * ReadCycle = 2ns + 2*SYSCLK  (regs),
-	 * WriteCycle = 2*SYSCLK + 2 ns,
-	 * CSPulseWidth = 10 ns */
-
-	systim = 1000000000 / (sysclk / 1000);
-	dev_dbg(blizzard.fbdev->dev,
-		  "Blizzard systim %lu ps extif_clk_period %u div %d\n",
-		  systim, blizzard.extif_clk_period, div);
-
-	t = &blizzard.reg_timings;
-	memset(t, 0, sizeof(*t));
-
-	t->clk_div = div;
-
-	t->cs_on_time = 0;
-	t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
-	t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
-	t->access_time = round_to_extif_ticks(t->re_on_time + 12200, div);
-	t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div);
-	t->re_off_time = round_to_extif_ticks(t->re_on_time + 13000, div);
-	t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div);
-	t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
-	if (t->we_cycle_time < t->we_off_time)
-		t->we_cycle_time = t->we_off_time;
-	t->re_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
-	if (t->re_cycle_time < t->re_off_time)
-		t->re_cycle_time = t->re_off_time;
-	t->cs_pulse_width = 0;
-
-	dev_dbg(blizzard.fbdev->dev, "[reg]cson %d csoff %d reon %d reoff %d\n",
-		 t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
-	dev_dbg(blizzard.fbdev->dev, "[reg]weon %d weoff %d recyc %d wecyc %d\n",
-		 t->we_on_time, t->we_off_time, t->re_cycle_time,
-		 t->we_cycle_time);
-	dev_dbg(blizzard.fbdev->dev, "[reg]rdaccess %d cspulse %d\n",
-		 t->access_time, t->cs_pulse_width);
-
-	return blizzard.extif->convert_timings(t);
-}
-
-static int calc_lut_timing(unsigned long sysclk, int div)
-{
-	struct extif_timings *t;
-	unsigned long systim;
-
-	/* CSOnTime 0, WEOnTime 2 ns, REOnTime 2 ns,
-	 * AccessTime 2 ns + 4 * SYSCLK + 26 (lut),
-	 * WEOffTime = WEOnTime + 1 ns,
-	 * REOffTime = REOnTime + 4*SYSCLK + 26 ns (lut),
-	 * CSOffTime = REOffTime + 1 ns
-	 * ReadCycle = 2ns + 4*SYSCLK + 26 ns (lut),
-	 * WriteCycle = 2*SYSCLK + 2 ns,
-	 * CSPulseWidth = 10 ns */
-
-	systim = 1000000000 / (sysclk / 1000);
-	dev_dbg(blizzard.fbdev->dev,
-		"Blizzard systim %lu ps extif_clk_period %u div %d\n",
-		systim, blizzard.extif_clk_period, div);
-
-	t = &blizzard.lut_timings;
-	memset(t, 0, sizeof(*t));
-
-	t->clk_div = div;
-
-	t->cs_on_time = 0;
-	t->we_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
-	t->re_on_time = round_to_extif_ticks(t->cs_on_time + 2000, div);
-	t->access_time = round_to_extif_ticks(t->re_on_time + 4 * systim +
-					      26000, div);
-	t->we_off_time = round_to_extif_ticks(t->we_on_time + 1000, div);
-	t->re_off_time = round_to_extif_ticks(t->re_on_time + 4 * systim +
-					      26000, div);
-	t->cs_off_time = round_to_extif_ticks(t->re_off_time + 1000, div);
-	t->we_cycle_time = round_to_extif_ticks(2 * systim + 2000, div);
-	if (t->we_cycle_time < t->we_off_time)
-		t->we_cycle_time = t->we_off_time;
-	t->re_cycle_time = round_to_extif_ticks(2000 + 4 * systim + 26000, div);
-	if (t->re_cycle_time < t->re_off_time)
-		t->re_cycle_time = t->re_off_time;
-	t->cs_pulse_width = 0;
-
-	dev_dbg(blizzard.fbdev->dev,
-		 "[lut]cson %d csoff %d reon %d reoff %d\n",
-		 t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
-	dev_dbg(blizzard.fbdev->dev,
-		 "[lut]weon %d weoff %d recyc %d wecyc %d\n",
-		 t->we_on_time, t->we_off_time, t->re_cycle_time,
-		 t->we_cycle_time);
-	dev_dbg(blizzard.fbdev->dev, "[lut]rdaccess %d cspulse %d\n",
-		 t->access_time, t->cs_pulse_width);
-
-	return blizzard.extif->convert_timings(t);
-}
-
-static int calc_extif_timings(unsigned long sysclk, int *extif_mem_div)
-{
-	int max_clk_div;
-	int div;
-
-	blizzard.extif->get_clk_info(&blizzard.extif_clk_period, &max_clk_div);
-	for (div = 1; div <= max_clk_div; div++) {
-		if (calc_reg_timing(sysclk, div) = 0)
-			break;
-	}
-	if (div > max_clk_div) {
-		dev_dbg(blizzard.fbdev->dev, "reg timing failed\n");
-		goto err;
-	}
-	*extif_mem_div = div;
-
-	for (div = 1; div <= max_clk_div; div++) {
-		if (calc_lut_timing(sysclk, div) = 0)
-			break;
-	}
-
-	if (div > max_clk_div)
-		goto err;
-
-	blizzard.extif_clk_div = div;
-
-	return 0;
-err:
-	dev_err(blizzard.fbdev->dev, "can't setup timings\n");
-	return -1;
-}
-
-static void calc_blizzard_clk_rates(unsigned long ext_clk,
-				unsigned long *sys_clk, unsigned long *pix_clk)
-{
-	int pix_clk_src;
-	int sys_div = 0, sys_mul = 0;
-	int pix_div;
-
-	pix_clk_src = blizzard_read_reg(BLIZZARD_CLK_SRC);
-	pix_div = ((pix_clk_src >> 3) & 0x1f) + 1;
-	if ((pix_clk_src & (0x3 << 1)) = 0) {
-		/* Source is the PLL */
-		sys_div = (blizzard_read_reg(BLIZZARD_PLL_DIV) & 0x3f) + 1;
-		sys_mul = blizzard_read_reg(BLIZZARD_PLL_CLOCK_SYNTH_0);
-		sys_mul |= ((blizzard_read_reg(BLIZZARD_PLL_CLOCK_SYNTH_1)
-				& 0x0f)	<< 11);
-		*sys_clk = ext_clk * sys_mul / sys_div;
-	} else	/* else source is ext clk, or oscillator */
-		*sys_clk = ext_clk;
-
-	*pix_clk = *sys_clk / pix_div;			/* HZ */
-	dev_dbg(blizzard.fbdev->dev,
-		"ext_clk %ld pix_src %d pix_div %d sys_div %d sys_mul %d\n",
-		ext_clk, pix_clk_src & (0x3 << 1), pix_div, sys_div, sys_mul);
-	dev_dbg(blizzard.fbdev->dev, "sys_clk %ld pix_clk %ld\n",
-		*sys_clk, *pix_clk);
-}
-
-static int setup_tearsync(unsigned long pix_clk, int extif_div)
-{
-	int hdisp, vdisp;
-	int hndp, vndp;
-	int hsw, vsw;
-	int hs, vs;
-	int hs_pol_inv, vs_pol_inv;
-	int use_hsvs, use_ndp;
-	u8  b;
-
-	hsw = blizzard_read_reg(BLIZZARD_HSW);
-	vsw = blizzard_read_reg(BLIZZARD_VSW);
-	hs_pol_inv = !(hsw & 0x80);
-	vs_pol_inv = !(vsw & 0x80);
-	hsw = hsw & 0x7f;
-	vsw = vsw & 0x3f;
-
-	hdisp = blizzard_read_reg(BLIZZARD_HDISP) * 8;
-	vdisp = blizzard_read_reg(BLIZZARD_VDISP0) +
-		((blizzard_read_reg(BLIZZARD_VDISP1) & 0x3) << 8);
-
-	hndp = blizzard_read_reg(BLIZZARD_HNDP) & 0x3f;
-	vndp = blizzard_read_reg(BLIZZARD_VNDP);
-
-	/* time to transfer one pixel (16bpp) in ps */
-	blizzard.pix_tx_time = blizzard.reg_timings.we_cycle_time;
-	if (blizzard.extif->get_max_tx_rate != NULL) {
-		/* The external interface might have a rate limitation,
-		 * if so, we have to maximize our transfer rate.
-		 */
-		unsigned long min_tx_time;
-		unsigned long max_tx_rate = blizzard.extif->get_max_tx_rate();
-
-		dev_dbg(blizzard.fbdev->dev, "max_tx_rate %ld HZ\n",
-			max_tx_rate);
-		min_tx_time = 1000000000 / (max_tx_rate / 1000);  /* ps */
-		if (blizzard.pix_tx_time < min_tx_time)
-			blizzard.pix_tx_time = min_tx_time;
-	}
-
-	/* time to update one line in ps */
-	blizzard.line_upd_time = (hdisp + hndp) * 1000000 / (pix_clk / 1000);
-	blizzard.line_upd_time *= 1000;
-	if (hdisp * blizzard.pix_tx_time > blizzard.line_upd_time)
-		/* transfer speed too low, we might have to use both
-		 * HS and VS */
-		use_hsvs = 1;
-	else
-		/* decent transfer speed, we'll always use only VS */
-		use_hsvs = 0;
-
-	if (use_hsvs && (hs_pol_inv || vs_pol_inv)) {
-		/* HS or'ed with VS doesn't work, use the active high
-		 * TE signal based on HNDP / VNDP */
-		use_ndp = 1;
-		hs_pol_inv = 0;
-		vs_pol_inv = 0;
-		hs = hndp;
-		vs = vndp;
-	} else {
-		/* Use HS or'ed with VS as a TE signal if both are needed
-		 * or VNDP if only vsync is needed. */
-		use_ndp = 0;
-		hs = hsw;
-		vs = vsw;
-		if (!use_hsvs) {
-			hs_pol_inv = 0;
-			vs_pol_inv = 0;
-		}
-	}
-
-	hs = hs * 1000000 / (pix_clk / 1000);		  /* ps */
-	hs *= 1000;
-
-	vs = vs * (hdisp + hndp) * 1000000 / (pix_clk / 1000); /* ps */
-	vs *= 1000;
-
-	if (vs <= hs)
-		return -EDOM;
-	/* set VS to 120% of HS to minimize VS detection time */
-	vs = hs * 12 / 10;
-	/* minimize HS too */
-	if (hs > 10000)
-		hs = 10000;
-
-	b = blizzard_read_reg(BLIZZARD_NDISP_CTRL_STATUS);
-	b &= ~0x3;
-	b |= use_hsvs ? 1 : 0;
-	b |= (use_ndp && use_hsvs) ? 0 : 2;
-	blizzard_write_reg(BLIZZARD_NDISP_CTRL_STATUS, b);
-
-	blizzard.vsync_only = !use_hsvs;
-
-	dev_dbg(blizzard.fbdev->dev,
-		"pix_clk %ld HZ pix_tx_time %ld ps line_upd_time %ld ps\n",
-		pix_clk, blizzard.pix_tx_time, blizzard.line_upd_time);
-	dev_dbg(blizzard.fbdev->dev,
-		"hs %d ps vs %d ps mode %d vsync_only %d\n",
-		hs, vs, b & 0x3, !use_hsvs);
-
-	return blizzard.extif->setup_tearsync(1, hs, vs,
-					      hs_pol_inv, vs_pol_inv,
-					      extif_div);
-}
-
-static void blizzard_get_caps(int plane, struct omapfb_caps *caps)
-{
-	blizzard.int_ctrl->get_caps(plane, caps);
-	caps->ctrl |= OMAPFB_CAPS_MANUAL_UPDATE |
-		OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE |
-		OMAPFB_CAPS_WINDOW_SCALE |
-		OMAPFB_CAPS_WINDOW_OVERLAY |
-		OMAPFB_CAPS_WINDOW_ROTATE;
-	if (blizzard.te_connected)
-		caps->ctrl |= OMAPFB_CAPS_TEARSYNC;
-	caps->wnd_color |= (1 << OMAPFB_COLOR_RGB565) |
-			   (1 << OMAPFB_COLOR_YUV420);
-}
-
-static void _save_regs(const struct blizzard_reg_list *list, int cnt)
-{
-	int i;
-
-	for (i = 0; i < cnt; i++, list++) {
-		int reg;
-		for (reg = list->start; reg <= list->end; reg += 2)
-			blizzard_reg_cache[reg / 2] = blizzard_read_reg(reg);
-	}
-}
-
-static void _restore_regs(const struct blizzard_reg_list *list, int cnt)
-{
-	int i;
-
-	for (i = 0; i < cnt; i++, list++) {
-		int reg;
-		for (reg = list->start; reg <= list->end; reg += 2)
-			blizzard_write_reg(reg, blizzard_reg_cache[reg / 2]);
-	}
-}
-
-static void blizzard_save_all_regs(void)
-{
-	_save_regs(blizzard_pll_regs, ARRAY_SIZE(blizzard_pll_regs));
-	_save_regs(blizzard_gen_regs, ARRAY_SIZE(blizzard_gen_regs));
-}
-
-static void blizzard_restore_pll_regs(void)
-{
-	_restore_regs(blizzard_pll_regs, ARRAY_SIZE(blizzard_pll_regs));
-}
-
-static void blizzard_restore_gen_regs(void)
-{
-	_restore_regs(blizzard_gen_regs, ARRAY_SIZE(blizzard_gen_regs));
-}
-
-static void blizzard_suspend(void)
-{
-	u32 l;
-	unsigned long tmo;
-
-	if (blizzard.last_color_mode) {
-		update_full_screen();
-		blizzard_sync();
-	}
-	blizzard.update_mode_before_suspend = blizzard.update_mode;
-	/* the following will disable clocks as well */
-	blizzard_set_update_mode(OMAPFB_UPDATE_DISABLED);
-
-	blizzard_save_all_regs();
-
-	blizzard_stop_sdram();
-
-	l = blizzard_read_reg(BLIZZARD_POWER_SAVE);
-	/* Standby, Sleep. We assume we use an external clock. */
-	l |= 0x03;
-	blizzard_write_reg(BLIZZARD_POWER_SAVE, l);
-
-	tmo = jiffies + msecs_to_jiffies(100);
-	while (!(blizzard_read_reg(BLIZZARD_PLL_MODE) & (1 << 1))) {
-		if (time_after(jiffies, tmo)) {
-			dev_err(blizzard.fbdev->dev,
-				"s1d1374x: sleep timeout, stopping PLL manually\n");
-			l = blizzard_read_reg(BLIZZARD_PLL_MODE);
-			l &= ~0x03;
-			/* Disable PLL, counter function */
-			l |= 0x2;
-			blizzard_write_reg(BLIZZARD_PLL_MODE, l);
-			break;
-		}
-		msleep(1);
-	}
-
-	if (blizzard.power_down != NULL)
-		blizzard.power_down(blizzard.fbdev->dev);
-}
-
-static void blizzard_resume(void)
-{
-	u32 l;
-
-	if (blizzard.power_up != NULL)
-		blizzard.power_up(blizzard.fbdev->dev);
-
-	l = blizzard_read_reg(BLIZZARD_POWER_SAVE);
-	/* Standby, Sleep */
-	l &= ~0x03;
-	blizzard_write_reg(BLIZZARD_POWER_SAVE, l);
-
-	blizzard_restore_pll_regs();
-	l = blizzard_read_reg(BLIZZARD_PLL_MODE);
-	l &= ~0x03;
-	/* Enable PLL, counter function */
-	l |= 0x1;
-	blizzard_write_reg(BLIZZARD_PLL_MODE, l);
-
-	while (!(blizzard_read_reg(BLIZZARD_PLL_DIV) & (1 << 7)))
-		msleep(1);
-
-	blizzard_restart_sdram();
-
-	blizzard_restore_gen_regs();
-
-	/* Enable display */
-	blizzard_write_reg(BLIZZARD_DISPLAY_MODE, 0x01);
-
-	/* the following will enable clocks as necessary */
-	blizzard_set_update_mode(blizzard.update_mode_before_suspend);
-
-	/* Force a background update */
-	blizzard.zoom_on = 1;
-	update_full_screen();
-	blizzard_sync();
-}
-
-static int blizzard_init(struct omapfb_device *fbdev, int ext_mode,
-			 struct omapfb_mem_desc *req_vram)
-{
-	int r = 0, i;
-	u8 rev, conf;
-	unsigned long ext_clk;
-	int extif_div;
-	unsigned long sys_clk, pix_clk;
-	struct omapfb_platform_data *omapfb_conf;
-	struct blizzard_platform_data *ctrl_conf;
-
-	blizzard.fbdev = fbdev;
-
-	BUG_ON(!fbdev->ext_if || !fbdev->int_ctrl);
-
-	blizzard.fbdev = fbdev;
-	blizzard.extif = fbdev->ext_if;
-	blizzard.int_ctrl = fbdev->int_ctrl;
-
-	omapfb_conf = fbdev->dev->platform_data;
-	ctrl_conf = omapfb_conf->ctrl_platform_data;
-	if (ctrl_conf = NULL || ctrl_conf->get_clock_rate = NULL) {
-		dev_err(fbdev->dev, "s1d1374x: missing platform data\n");
-		r = -ENOENT;
-		goto err1;
-	}
-
-	blizzard.power_down = ctrl_conf->power_down;
-	blizzard.power_up = ctrl_conf->power_up;
-
-	spin_lock_init(&blizzard.req_lock);
-
-	if ((r = blizzard.int_ctrl->init(fbdev, 1, req_vram)) < 0)
-		goto err1;
-
-	if ((r = blizzard.extif->init(fbdev)) < 0)
-		goto err2;
-
-	blizzard_ctrl.set_color_key = blizzard.int_ctrl->set_color_key;
-	blizzard_ctrl.get_color_key = blizzard.int_ctrl->get_color_key;
-	blizzard_ctrl.setup_mem = blizzard.int_ctrl->setup_mem;
-	blizzard_ctrl.mmap = blizzard.int_ctrl->mmap;
-
-	ext_clk = ctrl_conf->get_clock_rate(fbdev->dev);
-	if ((r = calc_extif_timings(ext_clk, &extif_div)) < 0)
-		goto err3;
-
-	set_extif_timings(&blizzard.reg_timings);
-
-	if (blizzard.power_up != NULL)
-		blizzard.power_up(fbdev->dev);
-
-	calc_blizzard_clk_rates(ext_clk, &sys_clk, &pix_clk);
-
-	if ((r = calc_extif_timings(sys_clk, &extif_div)) < 0)
-		goto err3;
-	set_extif_timings(&blizzard.reg_timings);
-
-	if (!(blizzard_read_reg(BLIZZARD_PLL_DIV) & 0x80)) {
-		dev_err(fbdev->dev,
-			"controller not initialized by the bootloader\n");
-		r = -ENODEV;
-		goto err3;
-	}
-
-	if (ctrl_conf->te_connected) {
-		if ((r = setup_tearsync(pix_clk, extif_div)) < 0)
-			goto err3;
-		blizzard.te_connected = 1;
-	}
-
-	rev = blizzard_read_reg(BLIZZARD_REV_CODE);
-	conf = blizzard_read_reg(BLIZZARD_CONFIG);
-
-	switch (rev & 0xfc) {
-	case 0x9c:
-		blizzard.version = BLIZZARD_VERSION_S1D13744;
-		pr_info("omapfb: s1d13744 LCD controller rev %d "
-			"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
-		break;
-	case 0xa4:
-		blizzard.version = BLIZZARD_VERSION_S1D13745;
-		pr_info("omapfb: s1d13745 LCD controller rev %d "
-			"initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
-		break;
-	default:
-		dev_err(fbdev->dev, "invalid s1d1374x revision %02x\n",
-			rev);
-		r = -ENODEV;
-		goto err3;
-	}
-
-	blizzard.max_transmit_size = blizzard.extif->max_transmit_size;
-
-	blizzard.update_mode = OMAPFB_UPDATE_DISABLED;
-
-	blizzard.auto_update_window.x = 0;
-	blizzard.auto_update_window.y = 0;
-	blizzard.auto_update_window.width = fbdev->panel->x_res;
-	blizzard.auto_update_window.height = fbdev->panel->y_res;
-	blizzard.auto_update_window.out_x = 0;
-	blizzard.auto_update_window.out_y = 0;
-	blizzard.auto_update_window.out_width = fbdev->panel->x_res;
-	blizzard.auto_update_window.out_height = fbdev->panel->y_res;
-	blizzard.auto_update_window.format = 0;
-
-	blizzard.screen_width = fbdev->panel->x_res;
-	blizzard.screen_height = fbdev->panel->y_res;
-
-	init_timer(&blizzard.auto_update_timer);
-	blizzard.auto_update_timer.function = blizzard_update_window_auto;
-	blizzard.auto_update_timer.data = 0;
-
-	INIT_LIST_HEAD(&blizzard.free_req_list);
-	INIT_LIST_HEAD(&blizzard.pending_req_list);
-	for (i = 0; i < ARRAY_SIZE(blizzard.req_pool); i++)
-		list_add(&blizzard.req_pool[i].entry, &blizzard.free_req_list);
-	BUG_ON(i <= IRQ_REQ_POOL_SIZE);
-	sema_init(&blizzard.req_sema, i - IRQ_REQ_POOL_SIZE);
-
-	return 0;
-err3:
-	if (blizzard.power_down != NULL)
-		blizzard.power_down(fbdev->dev);
-	blizzard.extif->cleanup();
-err2:
-	blizzard.int_ctrl->cleanup();
-err1:
-	return r;
-}
-
-static void blizzard_cleanup(void)
-{
-	blizzard_set_update_mode(OMAPFB_UPDATE_DISABLED);
-	blizzard.extif->cleanup();
-	blizzard.int_ctrl->cleanup();
-	if (blizzard.power_down != NULL)
-		blizzard.power_down(blizzard.fbdev->dev);
-}
-
-struct lcd_ctrl blizzard_ctrl = {
-	.name			= "blizzard",
-	.init			= blizzard_init,
-	.cleanup		= blizzard_cleanup,
-	.bind_client		= blizzard_bind_client,
-	.get_caps		= blizzard_get_caps,
-	.set_update_mode	= blizzard_set_update_mode,
-	.get_update_mode	= blizzard_get_update_mode,
-	.setup_plane		= blizzard_setup_plane,
-	.set_scale		= blizzard_set_scale,
-	.enable_plane		= blizzard_enable_plane,
-	.set_rotate		= blizzard_set_rotate,
-	.update_window		= blizzard_update_window_async,
-	.sync			= blizzard_sync,
-	.suspend		= blizzard_suspend,
-	.resume			= blizzard_resume,
-};
-
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index b291bfa..440a5dd 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -104,7 +104,6 @@ static struct platform_device omapdss_device = {
  * ---------------------------------------------------------------------------
  */
 extern struct lcd_ctrl hwa742_ctrl;
-extern struct lcd_ctrl blizzard_ctrl;
 
 static const struct lcd_ctrl *ctrls[] = {
 #ifdef CONFIG_ARCH_OMAP1
@@ -116,9 +115,6 @@ static const struct lcd_ctrl *ctrls[] = {
 #ifdef CONFIG_FB_OMAP_LCDC_HWA742
 	&hwa742_ctrl,
 #endif
-#ifdef CONFIG_FB_OMAP_LCDC_BLIZZARD
-	&blizzard_ctrl,
-#endif
 };
 
 #ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 00/16] OMAPDSS: old OMAPFB cleanup
From: Tomi Valkeinen @ 2012-01-24 10:00 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: archit, tony, Tomi Valkeinen

Now that all omap2+ boards have been changed to use the newer omapdss driver,
this patch series removes omap2+ support from the old omapfb driver
(drivers/video/omap), and thus makes it an omap1 dss/fb driver.

The use of SRAM for video ram had earlier been disabled by removing the SRAM
allocation (fee926bb0d399b1eaaf38f9f694bbf2747c4b8a2), and now this series also
removes the support from the omap fb drivers.

Also various cleanup patches allow us to remove remove OMAP_TAG_LCD and
OMAP_TAG_FBMEM.

All in all, the series removes quite a bit of unneeded code and cleans up the
links between the board files and the display drivers, and this should help
with device tree adaptation.

Some of the patches affect the newer omapdss and omapfb drivers, but mostly the
patches deal with omap1. I have compile tested the series for both omap1 and
omap2, but I have only tested this on OMAP3 and OMAP4 boards, as I don't have
OMAP1/2 boards. I think N770's display won't work after these patches, but
other OMAP1 boards should be ok. To fix N770's display requires knowledge of
the hardware setup, which is currently passed from the bootloader.

 Tomi

Tomi Valkeinen (16):
  OMAPFB: remove old blizzard driver
  OMAPFB: Remove OMAP2/3 support from old omapfb driver
  OMAPDSS: Remove video SRAM support
  OMAPFB: Remove video SRAM support (old omapfb)
  OMAP2+: remove unneeded #include omapfb.h
  OMAP: N770: remove HWA742 platform data
  OAMPFB: remove unused omapfb_set_ctrl_platform_data()
  OMAPFB: remove early mem alloc from old omapfb
  OMAPFB: remove mem info from platform_data
  OMAPFB: remove unused fb_format_to_dss_mode()
  OMAPFB: Move old omapfb private structs to a private include file
  OMAPFB: remove omapfb_set_platform_data()
  OMAP1: pass LCD config with omapfb_set_lcd_config()
  OMAP: Remove OMAP_TAG_LCD and OMAP_TAG_FBMEM
  OMAP1: Remove unused LCD devices from board files
  OMAPFB: remove remaining OMAP arch checks

 arch/arm/mach-omap1/board-ams-delta.c      |    9 +-
 arch/arm/mach-omap1/board-fsample.c        |   15 +-
 arch/arm/mach-omap1/board-h2.c             |   15 +-
 arch/arm/mach-omap1/board-h3.c             |    9 +-
 arch/arm/mach-omap1/board-htcherald.c      |    9 +-
 arch/arm/mach-omap1/board-innovator.c      |   11 +-
 arch/arm/mach-omap1/board-nokia770.c       |   19 +-
 arch/arm/mach-omap1/board-osk.c            |   14 +-
 arch/arm/mach-omap1/board-palmte.c         |   10 +-
 arch/arm/mach-omap1/board-palmtt.c         |   10 +-
 arch/arm/mach-omap1/board-palmz71.c        |   10 +-
 arch/arm/mach-omap1/board-perseus2.c       |   15 +-
 arch/arm/mach-omap1/board-sx1.c            |   16 +-
 arch/arm/mach-omap2/io.c                   |    1 -
 arch/arm/plat-omap/common.c                |    2 -
 arch/arm/plat-omap/fb.c                    |  336 +------
 arch/arm/plat-omap/fb.h                    |   10 -
 arch/arm/plat-omap/include/plat/blizzard.h |   12 -
 arch/arm/plat-omap/include/plat/board.h    |    2 -
 arch/arm/plat-omap/include/plat/hwa742.h   |    8 -
 arch/arm/plat-omap/include/plat/vram.h     |   21 +-
 drivers/video/omap/Kconfig                 |   16 +-
 drivers/video/omap/Makefile                |   12 +-
 drivers/video/omap/blizzard.c              | 1648 ----------------------------
 drivers/video/omap/dispc.c                 | 1547 --------------------------
 drivers/video/omap/dispc.h                 |   46 -
 drivers/video/omap/hwa742.c                |   21 +-
 drivers/video/omap/omapfb.h                |   25 +-
 drivers/video/omap/omapfb_main.c           |   30 +-
 drivers/video/omap/rfbi.c                  |  598 ----------
 drivers/video/omap2/dss/dispc.c            |    1 -
 drivers/video/omap2/omapfb/omapfb-ioctl.c  |    2 +-
 drivers/video/omap2/omapfb/omapfb-main.c   |  101 +--
 drivers/video/omap2/vram.c                 |   99 +--
 include/linux/omapfb.h                     |   32 +-
 35 files changed, 100 insertions(+), 4632 deletions(-)
 delete mode 100644 arch/arm/plat-omap/fb.h
 delete mode 100644 arch/arm/plat-omap/include/plat/blizzard.h
 delete mode 100644 arch/arm/plat-omap/include/plat/hwa742.h
 delete mode 100644 drivers/video/omap/blizzard.c
 delete mode 100644 drivers/video/omap/dispc.c
 delete mode 100644 drivers/video/omap/dispc.h
 delete mode 100644 drivers/video/omap/rfbi.c

-- 
1.7.4.1


^ permalink raw reply

* Re: [PATCH] fbdev: sh_mipi_dsi: add extra settings method for platform
From: Kuninori Morimoto @ 2012-01-24  0:48 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <874nvnhupd.wl%kuninori.morimoto.gx@renesas.com>


Hi Laurent
Cc Magnus, Guennadi

Thank you for checking patch

> > +	void (*set_dcs)(int handle,
> > +			int (*mipi_dcs)(int handle, u8 cmd),
> > +			int (*mipi_dcs_param)(int handle, u8 cmd, u8 param));
> 
> I don't think this is a good idea. First of all, we should reduce the number 
> of board code callbacks to make transition to the device tree easier. Then, 
> passing two functions to board code to read and write any device register 
> without the driver having any knowledge about that is a clear violation of the 
> device model, and will result in problems sooner or later.
> 
> What MIPI settings do platforms need to modify ? Can those settings be 
> expressed as data in the sh_mipi_dsi_info structure instead ?

Hmm... now I'm in dilemma.
Actually this is v2 patch for mipi display.
(v1 patch was dropped since merge window issue)

The v1 patch was data-table style for mipi display initialization.
(if platform had init data-table, driver used it)

But someone reviewed it and teach me that it is not-good idea.
So, I created this style in v2.

Now platform needs "backlight ON" and "memory write ON" command,
but I could not find these command on include/video/mipi_display.h.
So, I thought it is platform specific command.

Best regards
---
Kuninori Morimoto

^ permalink raw reply

* [PATCH v5] Resurrect Intel740 driver: i740fb
From: Ondrej Zary @ 2012-01-23 23:17 UTC (permalink / raw)
  To: linux-fbdev
  Cc: Andrey Ulanov, Florian Tobias Schandinat, Paul Mundt,
	Kernel development list

This is a resurrection of an old (like 2.4.19) out-of-tree driver for
Intel740 graphics cards and adaptation for recent kernels. The old driver by
Andrey Ulanov is located at: http://sourceforge.net/projects/i740fbdev/files/

This is a new driver based on skeletonfb, using most of the low level HW code
from the old driver. The DDC code is completely new.

The driver was tested on two 8MB cards: Protac AG240D and Diamond Stealth II
G460.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
---
Changes in v5:
 - fixed checkpatch problems
 - added Kconfig dependency on FB_DDC
 - cleaned up i740_calc_vclk()
 - fixed SDRAM/SGRAM detection
 - fixed wrong colors in 16bpp mode when neither 555 nor 565 specified

--- linux-3.2.1-orig/drivers/video/Kconfig	2012-01-12 20:42:45.000000000 +0100
+++ linux-3.2.1/drivers/video/Kconfig	2012-01-23 20:52:32.000000000 +0100
@@ -1123,6 +1123,18 @@ config FB_RIVA_BACKLIGHT
 	help
 	  Say Y here if you want to control the backlight of your display.
 
+config FB_I740
+	tristate "Intel740 support (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && FB && PCI
+	select FB_MODE_HELPERS
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	select VGASTATE
+	select FB_DDC
+	help
+	  This driver supports graphics cards based on Intel740 chip.
+
 config FB_I810
 	tristate "Intel 810/815 support (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && FB && PCI && X86_32 && AGP_INTEL
--- linux-3.2.1-orig/drivers/video/Makefile	2012-01-12 20:42:45.000000000 +0100
+++ linux-3.2.1/drivers/video/Makefile	2012-01-23 20:52:32.000000000 +0100
@@ -37,6 +37,7 @@ obj-$(CONFIG_FB_GRVGA)            += grv
 obj-$(CONFIG_FB_PM2)              += pm2fb.o
 obj-$(CONFIG_FB_PM3)		  += pm3fb.o
 
+obj-$(CONFIG_FB_I740)		  += i740fb.o
 obj-$(CONFIG_FB_MATROX)		  += matrox/
 obj-$(CONFIG_FB_RIVA)		  += riva/
 obj-$(CONFIG_FB_NVIDIA)		  += nvidia/
--- /dev/null	2012-01-24 00:06:39.330222901 +0100
+++ linux-3.2.1/drivers/video/i740fb.c	2012-01-24 00:01:54.000000000 +0100
@@ -0,0 +1,1337 @@
+/*
+ * i740fb - framebuffer driver for Intel740
+ * Copyright (c) 2011 Ondrej Zary
+ *
+ * Based on old i740fb driver (c) 2001-2002 Andrey Ulanov <drey@rt.mipt.ru>
+ * which was partially based on:
+ *  VGA 16-color framebuffer driver (c) 1999 Ben Pfaff <pfaffben@debian.org>
+ *	and Petr Vandrovec <VANDROVE@vc.cvut.cz>
+ *  i740 driver from XFree86 (c) 1998-1999 Precision Insight, Inc., Cedar Park,
+ *	Texas.
+ *  i740fb by Patrick LERDA, v0.9
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+#include <linux/console.h>
+#include <video/vga.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include "i740_reg.h"
+
+static char *mode_option __devinitdata;
+
+#ifdef CONFIG_MTRR
+static int mtrr __devinitdata = 1;
+#endif
+
+struct i740fb_par {
+	unsigned char __iomem *regs;
+	bool has_sgram;
+#ifdef CONFIG_MTRR
+	int mtrr_reg;
+#endif
+	bool ddc_registered;
+	struct i2c_adapter ddc_adapter;
+	struct i2c_algo_bit_data ddc_algo;
+	u32 pseudo_palette[16];
+	struct mutex open_lock;
+	unsigned int ref_count;
+
+	u8 crtc[VGA_CRT_C];
+	u8 atc[VGA_ATT_C];
+	u8 gdc[VGA_GFX_C];
+	u8 seq[VGA_SEQ_C];
+	u8 misc;
+	u8 vss;
+
+	/* i740 specific registers */
+	u8 display_cntl;
+	u8 pixelpipe_cfg0;
+	u8 pixelpipe_cfg1;
+	u8 pixelpipe_cfg2;
+	u8 video_clk2_m;
+	u8 video_clk2_n;
+	u8 video_clk2_mn_msbs;
+	u8 video_clk2_div_sel;
+	u8 pll_cntl;
+	u8 address_mapping;
+	u8 io_cntl;
+	u8 bitblt_cntl;
+	u8 ext_vert_total;
+	u8 ext_vert_disp_end;
+	u8 ext_vert_sync_start;
+	u8 ext_vert_blank_start;
+	u8 ext_horiz_total;
+	u8 ext_horiz_blank;
+	u8 ext_offset;
+	u8 interlace_cntl;
+	u32 lmi_fifo_watermark;
+	u8 ext_start_addr;
+	u8 ext_start_addr_hi;
+};
+
+#define DACSPEED8	203
+#define DACSPEED16	163
+#define DACSPEED24_SG	136
+#define DACSPEED24_SD	128
+#define DACSPEED32	86
+
+static struct fb_fix_screeninfo i740fb_fix __devinitdata = {
+	.id =		"i740fb",
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =	FB_VISUAL_TRUECOLOR,
+	.xpanstep =	8,
+	.ypanstep =	1,
+	.accel =	FB_ACCEL_NONE,
+};
+
+static inline void i740outb(struct i740fb_par *par, u16 port, u8 val)
+{
+	vga_mm_w(par->regs, port, val);
+}
+static inline u8 i740inb(struct i740fb_par *par, u16 port)
+{
+	return vga_mm_r(par->regs, port);
+}
+static inline void i740outreg(struct i740fb_par *par, u16 port, u8 reg, u8 val)
+{
+	vga_mm_w_fast(par->regs, port, reg, val);
+}
+static inline u8 i740inreg(struct i740fb_par *par, u16 port, u8 reg)
+{
+	vga_mm_w(par->regs, port, reg);
+	return vga_mm_r(par->regs, port+1);
+}
+static inline void i740outreg_mask(struct i740fb_par *par, u16 port, u8 reg,
+				   u8 val, u8 mask)
+{
+	vga_mm_w_fast(par->regs, port, reg, (val & mask)
+		| (i740inreg(par, port, reg) & ~mask));
+}
+
+#define REG_DDC_DRIVE	0x62
+#define REG_DDC_STATE	0x63
+#define DDC_SCL		(1 << 3)
+#define DDC_SDA		(1 << 2)
+
+static void i740fb_ddc_setscl(void *data, int val)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, DDC_SCL, DDC_SCL);
+	i740outreg_mask(par, XRX, REG_DDC_STATE, val ? DDC_SCL : 0, DDC_SCL);
+}
+
+static void i740fb_ddc_setsda(void *data, int val)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, DDC_SDA, DDC_SDA);
+	i740outreg_mask(par, XRX, REG_DDC_STATE, val ? DDC_SDA : 0, DDC_SDA);
+}
+
+static int i740fb_ddc_getscl(void *data)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, 0, DDC_SCL);
+
+	return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SCL);
+}
+
+static int i740fb_ddc_getsda(void *data)
+{
+	struct i740fb_par *par = data;
+
+	i740outreg_mask(par, XRX, REG_DDC_DRIVE, 0, DDC_SDA);
+
+	return !!(i740inreg(par, XRX, REG_DDC_STATE) & DDC_SDA);
+}
+
+static int __devinit i740fb_setup_ddc_bus(struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+
+	strlcpy(par->ddc_adapter.name, info->fix.id,
+		sizeof(par->ddc_adapter.name));
+	par->ddc_adapter.owner		= THIS_MODULE;
+	par->ddc_adapter.class		= I2C_CLASS_DDC;
+	par->ddc_adapter.algo_data	= &par->ddc_algo;
+	par->ddc_adapter.dev.parent	= info->device;
+	par->ddc_algo.setsda		= i740fb_ddc_setsda;
+	par->ddc_algo.setscl		= i740fb_ddc_setscl;
+	par->ddc_algo.getsda		= i740fb_ddc_getsda;
+	par->ddc_algo.getscl		= i740fb_ddc_getscl;
+	par->ddc_algo.udelay		= 10;
+	par->ddc_algo.timeout		= 20;
+	par->ddc_algo.data		= par;
+
+	i2c_set_adapdata(&par->ddc_adapter, par);
+
+	return i2c_bit_add_bus(&par->ddc_adapter);
+}
+
+static int i740fb_open(struct fb_info *info, int user)
+{
+	struct i740fb_par *par = info->par;
+
+	mutex_lock(&(par->open_lock));
+	par->ref_count++;
+	mutex_unlock(&(par->open_lock));
+
+	return 0;
+}
+
+static int i740fb_release(struct fb_info *info, int user)
+{
+	struct i740fb_par *par = info->par;
+
+	mutex_lock(&(par->open_lock));
+	if (par->ref_count = 0) {
+		printk(KERN_ERR "fb%d: release called with zero refcount\n",
+			info->node);
+		mutex_unlock(&(par->open_lock));
+		return -EINVAL;
+	}
+
+	par->ref_count--;
+	mutex_unlock(&(par->open_lock));
+
+	return 0;
+}
+
+static u32 i740_calc_fifo(struct i740fb_par *par, u32 freq, int bpp)
+{
+	/*
+	 * Would like to calculate these values automatically, but a generic
+	 * algorithm does not seem possible.  Note: These FIFO water mark
+	 * values were tested on several cards and seem to eliminate the
+	 * all of the snow and vertical banding, but fine adjustments will
+	 * probably be required for other cards.
+	 */
+
+	u32 wm;
+
+	switch (bpp) {
+	case 8:
+		if	(freq > 200)
+			wm = 0x18120000;
+		else if (freq > 175)
+			wm = 0x16110000;
+		else if (freq > 135)
+			wm = 0x120E0000;
+		else
+			wm = 0x100D0000;
+		break;
+	case 15:
+	case 16:
+		if (par->has_sgram) {
+			if	(freq > 140)
+				wm = 0x2C1D0000;
+			else if (freq > 120)
+				wm = 0x2C180000;
+			else if (freq > 100)
+				wm = 0x24160000;
+			else if (freq >  90)
+				wm = 0x18120000;
+			else if (freq >  50)
+				wm = 0x16110000;
+			else if (freq >  32)
+				wm = 0x13100000;
+			else
+				wm = 0x120E0000;
+		} else {
+			if	(freq > 160)
+				wm = 0x28200000;
+			else if (freq > 140)
+				wm = 0x2A1E0000;
+			else if (freq > 130)
+				wm = 0x2B1A0000;
+			else if (freq > 120)
+				wm = 0x2C180000;
+			else if (freq > 100)
+				wm = 0x24180000;
+			else if (freq >  90)
+				wm = 0x18120000;
+			else if (freq >  50)
+				wm = 0x16110000;
+			else if (freq >  32)
+				wm = 0x13100000;
+			else
+				wm = 0x120E0000;
+		}
+		break;
+	case 24:
+		if (par->has_sgram) {
+			if	(freq > 130)
+				wm = 0x31200000;
+			else if (freq > 120)
+				wm = 0x2E200000;
+			else if (freq > 100)
+				wm = 0x2C1D0000;
+			else if (freq >  80)
+				wm = 0x25180000;
+			else if (freq >  64)
+				wm = 0x24160000;
+			else if (freq >  49)
+				wm = 0x18120000;
+			else if (freq >  32)
+				wm = 0x16110000;
+			else
+				wm = 0x13100000;
+		} else {
+			if	(freq > 120)
+				wm = 0x311F0000;
+			else if (freq > 100)
+				wm = 0x2C1D0000;
+			else if (freq >  80)
+				wm = 0x25180000;
+			else if (freq >  64)
+				wm = 0x24160000;
+			else if (freq >  49)
+				wm = 0x18120000;
+			else if (freq >  32)
+				wm = 0x16110000;
+			else
+				wm = 0x13100000;
+		}
+		break;
+	case 32:
+		if (par->has_sgram) {
+			if	(freq >  80)
+				wm = 0x2A200000;
+			else if (freq >  60)
+				wm = 0x281A0000;
+			else if (freq >  49)
+				wm = 0x25180000;
+			else if (freq >  32)
+				wm = 0x18120000;
+			else
+				wm = 0x16110000;
+		} else {
+			if	(freq >  80)
+				wm = 0x29200000;
+			else if (freq >  60)
+				wm = 0x281A0000;
+			else if (freq >  49)
+				wm = 0x25180000;
+			else if (freq >  32)
+				wm = 0x18120000;
+			else
+				wm = 0x16110000;
+		}
+		break;
+	}
+
+	return wm;
+}
+
+/* clock calculation from i740fb by Patrick LERDA */
+
+#define I740_RFREQ		1000000
+#define TARGET_MAX_N		30
+#define I740_FFIX		(1 << 8)
+#define I740_RFREQ_FIX		(I740_RFREQ / I740_FFIX)
+#define I740_REF_FREQ		(6667 * I740_FFIX / 100)	/* 66.67 MHz */
+#define I740_MAX_VCO_FREQ	(450 * I740_FFIX)		/* 450 MHz */
+
+static void i740_calc_vclk(u32 freq, struct i740fb_par *par)
+{
+	const u32 err_max    = freq / (200  * I740_RFREQ / I740_FFIX);
+	const u32 err_target = freq / (1000 * I740_RFREQ / I740_FFIX);
+	u32 err_best = 512 * I740_FFIX;
+	u32 f_err, f_vco;
+	int m_best = 0, n_best = 0, p_best = 0, d_best = 0;
+	int m, n;
+
+	p_best = min(15, ilog2(I740_MAX_VCO_FREQ / (freq / I740_RFREQ_FIX)));
+	d_best = 0;
+	f_vco = (freq * (1 << p_best)) / I740_RFREQ_FIX;
+	freq = freq / I740_RFREQ_FIX;
+
+	n = 2;
+	do {
+		n++;
+		m = ((f_vco * n) / I740_REF_FREQ + 2) / 4;
+
+		if (m < 3)
+			m = 3;
+
+		{
+			u32 f_out = (((m * I740_REF_FREQ * (4 << 2 * d_best))
+				 / n) + ((1 << p_best) / 2)) / (1 << p_best);
+
+			f_err = (freq - f_out);
+
+			if (abs(f_err) < err_max) {
+				m_best = m;
+				n_best = n;
+				err_best = f_err;
+			}
+		}
+	} while ((abs(f_err) >= err_target) &&
+		 ((n <= TARGET_MAX_N) || (abs(err_best) > err_max)));
+
+	if (abs(f_err) < err_target) {
+		m_best = m;
+		n_best = n;
+	}
+
+	par->video_clk2_m = (m_best - 2) & 0xFF;
+	par->video_clk2_n = (n_best - 2) & 0xFF;
+	par->video_clk2_mn_msbs = ((((n_best - 2) >> 4) & VCO_N_MSBS)
+				 | (((m_best - 2) >> 8) & VCO_M_MSBS));
+	par->video_clk2_div_sel +		((p_best << 4) | (d_best ? 4 : 0) | REF_DIV_1);
+}
+
+static int i740fb_decode_var(const struct fb_var_screeninfo *var,
+			     struct i740fb_par *par, struct fb_info *info)
+{
+	/*
+	 * Get the video params out of 'var'.
+	 * If a value doesn't fit, round it up, if it's too big, return -EINVAL.
+	 */
+
+	u32 xres, right, hslen, left, xtotal;
+	u32 yres, lower, vslen, upper, ytotal;
+	u32 vxres, xoffset, vyres, yoffset;
+	u32 bpp, base, dacspeed24, mem;
+	u8 r7;
+	int i;
+
+	dev_dbg(info->device, "decode_var: xres: %i, yres: %i, xres_v: %i, xres_v: %i\n",
+		  var->xres, var->yres, var->xres_virtual, var->xres_virtual);
+	dev_dbg(info->device, "	xoff: %i, yoff: %i, bpp: %i, graysc: %i\n",
+		  var->xoffset, var->yoffset, var->bits_per_pixel,
+		  var->grayscale);
+	dev_dbg(info->device, "	activate: %i, nonstd: %i, vmode: %i\n",
+		  var->activate, var->nonstd, var->vmode);
+	dev_dbg(info->device, "	pixclock: %i, hsynclen:%i, vsynclen:%i\n",
+		  var->pixclock, var->hsync_len, var->vsync_len);
+	dev_dbg(info->device, "	left: %i, right: %i, up:%i, lower:%i\n",
+		  var->left_margin, var->right_margin, var->upper_margin,
+		  var->lower_margin);
+
+
+	bpp = var->bits_per_pixel;
+	switch (bpp) {
+	case 1 ... 8:
+		bpp = 8;
+		if ((1000000 / var->pixclock) > DACSPEED8) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 8bpp)\n",
+				1000000 / var->pixclock, DACSPEED8);
+			return -EINVAL;
+		}
+		break;
+	case 9 ... 15:
+		bpp = 15;
+	case 16:
+		if ((1000000 / var->pixclock) > DACSPEED16) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 15/16bpp)\n",
+				1000000 / var->pixclock, DACSPEED16);
+			return -EINVAL;
+		}
+		break;
+	case 17 ... 24:
+		bpp = 24;
+		dacspeed24 = par->has_sgram ? DACSPEED24_SG : DACSPEED24_SD;
+		if ((1000000 / var->pixclock) > dacspeed24) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 24bpp)\n",
+				1000000 / var->pixclock, dacspeed24);
+			return -EINVAL;
+		}
+		break;
+	case 25 ... 32:
+		bpp = 32;
+		if ((1000000 / var->pixclock) > DACSPEED32) {
+			dev_err(info->device, "requested pixclock %i MHz out of range (max. %i MHz at 32bpp)\n",
+				1000000 / var->pixclock, DACSPEED32);
+			return -EINVAL;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	xres = ALIGN(var->xres, 8);
+	vxres = ALIGN(var->xres_virtual, 16);
+	if (vxres < xres)
+		vxres = xres;
+
+	xoffset = ALIGN(var->xoffset, 8);
+	if (xres + xoffset > vxres)
+		xoffset = vxres - xres;
+
+	left = ALIGN(var->left_margin, 8);
+	right = ALIGN(var->right_margin, 8);
+	hslen = ALIGN(var->hsync_len, 8);
+
+	yres = var->yres;
+	vyres = var->yres_virtual;
+	if (yres > vyres)
+		vyres = yres;
+
+	yoffset = var->yoffset;
+	if (yres + yoffset > vyres)
+		yoffset = vyres - yres;
+
+	lower = var->lower_margin;
+	vslen = var->vsync_len;
+	upper = var->upper_margin;
+
+	mem = vxres * vyres * ((bpp + 1) / 8);
+	if (mem > info->screen_size) {
+		dev_err(info->device, "not enough video memory (%d KB requested, %ld KB avaliable)\n",
+			mem >> 10, info->screen_size >> 10);
+		return -ENOMEM;
+	}
+
+	if (yoffset + yres > vyres)
+		yoffset = vyres - yres;
+
+	xtotal = xres + right + hslen + left;
+	ytotal = yres + lower + vslen + upper;
+
+	par->crtc[VGA_CRTC_H_TOTAL] = (xtotal >> 3) - 5;
+	par->crtc[VGA_CRTC_H_DISP] = (xres >> 3) - 1;
+	par->crtc[VGA_CRTC_H_BLANK_START] = ((xres + right) >> 3) - 1;
+	par->crtc[VGA_CRTC_H_SYNC_START] = (xres + right) >> 3;
+	par->crtc[VGA_CRTC_H_SYNC_END] = (((xres + right + hslen) >> 3) & 0x1F)
+		| ((((xres + right + hslen) >> 3) & 0x20) << 2);
+	par->crtc[VGA_CRTC_H_BLANK_END] = ((xres + right + hslen) >> 3 & 0x1F)
+		| 0x80;
+
+	par->crtc[VGA_CRTC_V_TOTAL] = ytotal - 2;
+
+	r7 = 0x10;	/* disable linecompare */
+	if (ytotal & 0x100)
+		r7 |= 0x01;
+	if (ytotal & 0x200)
+		r7 |= 0x20;
+
+	par->crtc[VGA_CRTC_PRESET_ROW] = 0;
+	par->crtc[VGA_CRTC_MAX_SCAN] = 0x40;	/* 1 scanline, no linecmp */
+	if (var->vmode & FB_VMODE_DOUBLE)
+		par->crtc[VGA_CRTC_MAX_SCAN] |= 0x80;
+	par->crtc[VGA_CRTC_CURSOR_START] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_END] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_HI] = 0x00;
+	par->crtc[VGA_CRTC_CURSOR_LO] = 0x00;
+	par->crtc[VGA_CRTC_V_DISP_END] = yres-1;
+	if ((yres-1) & 0x100)
+		r7 |= 0x02;
+	if ((yres-1) & 0x200)
+		r7 |= 0x40;
+
+	par->crtc[VGA_CRTC_V_BLANK_START] = yres + lower - 1;
+	par->crtc[VGA_CRTC_V_SYNC_START] = yres + lower - 1;
+	if ((yres + lower - 1) & 0x100)
+		r7 |= 0x0C;
+	if ((yres + lower - 1) & 0x200) {
+		par->crtc[VGA_CRTC_MAX_SCAN] |= 0x20;
+		r7 |= 0x80;
+	}
+
+	/* disabled IRQ */
+	par->crtc[VGA_CRTC_V_SYNC_END] +		((yres + lower - 1 + vslen) & 0x0F) & ~0x10;
+	/* 0x7F for VGA, but some SVGA chips require all 8 bits to be set */
+	par->crtc[VGA_CRTC_V_BLANK_END] = (yres + lower - 1 + vslen) & 0xFF;
+
+	par->crtc[VGA_CRTC_UNDERLINE] = 0x00;
+	par->crtc[VGA_CRTC_MODE] = 0xC3 ;
+	par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF;
+	par->crtc[VGA_CRTC_OVERFLOW] = r7;
+
+	par->vss = 0x00;	/* 3DA */
+
+	for (i = 0x00; i < 0x10; i++)
+		par->atc[i] = i;
+	par->atc[VGA_ATC_MODE] = 0x81;
+	par->atc[VGA_ATC_OVERSCAN] = 0x00;	/* 0 for EGA, 0xFF for VGA */
+	par->atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
+	par->atc[VGA_ATC_COLOR_PAGE] = 0x00;
+
+	par->misc = 0xC3;
+	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+		par->misc &= ~0x40;
+	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+		par->misc &= ~0x80;
+
+	par->seq[VGA_SEQ_CLOCK_MODE] = 0x01;
+	par->seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
+	par->seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
+	par->seq[VGA_SEQ_MEMORY_MODE] = 0x06;
+
+	par->gdc[VGA_GFX_SR_VALUE] = 0x00;
+	par->gdc[VGA_GFX_SR_ENABLE] = 0x00;
+	par->gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
+	par->gdc[VGA_GFX_DATA_ROTATE] = 0x00;
+	par->gdc[VGA_GFX_PLANE_READ] = 0;
+	par->gdc[VGA_GFX_MODE] = 0x02;
+	par->gdc[VGA_GFX_MISC] = 0x05;
+	par->gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
+	par->gdc[VGA_GFX_BIT_MASK] = 0xFF;
+
+	base = (yoffset * vxres + (xoffset & ~7)) >> 2;
+	switch (bpp) {
+	case 8:
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 3;
+		par->ext_offset = vxres >> 11;
+		par->pixelpipe_cfg1 = DISPLAY_8BPP_MODE;
+		par->bitblt_cntl = COLEXP_8BPP;
+		break;
+	case 15: /* 0rrrrrgg gggbbbbb */
+	case 16: /* rrrrrggg gggbbbbb */
+		par->pixelpipe_cfg1 = (var->green.length = 6) ?
+			DISPLAY_16BPP_MODE : DISPLAY_15BPP_MODE;
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 2;
+		par->ext_offset = vxres >> 10;
+		par->bitblt_cntl = COLEXP_16BPP;
+		base *= 2;
+		break;
+	case 24:
+		par->crtc[VGA_CRTC_OFFSET] = (vxres * 3) >> 3;
+		par->ext_offset = (vxres * 3) >> 11;
+		par->pixelpipe_cfg1 = DISPLAY_24BPP_MODE;
+		par->bitblt_cntl = COLEXP_24BPP;
+		base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+		base *= 3;
+		break;
+	case 32:
+		par->crtc[VGA_CRTC_OFFSET] = vxres >> 1;
+		par->ext_offset = vxres >> 9;
+		par->pixelpipe_cfg1 = DISPLAY_32BPP_MODE;
+		par->bitblt_cntl = COLEXP_RESERVED; /* Unimplemented on i740 */
+		base *= 4;
+		break;
+	}
+
+	par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF;
+	par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >>  8;
+	par->ext_start_addr +		((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE;
+	par->ext_start_addr_hi = (base & 0x3FC00000) >> 22;
+
+	par->pixelpipe_cfg0 = DAC_8_BIT;
+
+	par->pixelpipe_cfg2 = DISPLAY_GAMMA_ENABLE | OVERLAY_GAMMA_ENABLE;
+	par->io_cntl = EXTENDED_CRTC_CNTL;
+	par->address_mapping = LINEAR_MODE_ENABLE | PAGE_MAPPING_ENABLE;
+	par->display_cntl = HIRES_MODE;
+
+	/* Set the MCLK freq */
+	par->pll_cntl = PLL_MEMCLK_100000KHZ; /* 100 MHz -- use as default */
+
+	/* Calculate the extended CRTC regs */
+	par->ext_vert_total = (ytotal - 2) >> 8;
+	par->ext_vert_disp_end = (yres - 1) >> 8;
+	par->ext_vert_sync_start = (yres + lower) >> 8;
+	par->ext_vert_blank_start = (yres + lower) >> 8;
+	par->ext_horiz_total = ((xtotal >> 3) - 5) >> 8;
+	par->ext_horiz_blank = (((xres + right) >> 3) & 0x40) >> 6;
+
+	par->interlace_cntl = INTERLACE_DISABLE;
+
+	/* Set the overscan color to 0. (NOTE: This only affects >8bpp mode) */
+	par->atc[VGA_ATC_OVERSCAN] = 0;
+
+	/* Calculate VCLK that most closely matches the requested dot clock */
+	i740_calc_vclk((((u32)1e9) / var->pixclock) * (u32)(1e3), par);
+
+	/* Since we program the clocks ourselves, always use VCLK2. */
+	par->misc |= 0x0C;
+
+	/* Calculate the FIFO Watermark and Burst Length. */
+	par->lmi_fifo_watermark +		i740_calc_fifo(par, 1000000 / var->pixclock, bpp);
+
+	return 0;
+}
+
+static int i740fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	switch (var->bits_per_pixel) {
+	case 8:
+		var->red.offset	= var->green.offset = var->blue.offset = 0;
+		var->red.length	= var->green.length = var->blue.length = 8;
+		break;
+	case 16:
+		switch (var->green.length) {
+		default:
+		case 5:
+			var->red.offset = 10;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->red.length	= 5;
+			var->green.length = 5;
+			var->blue.length = 5;
+			break;
+		case 6:
+			var->red.offset = 11;
+			var->green.offset = 5;
+			var->blue.offset = 0;
+			var->red.length = var->blue.length = 5;
+			break;
+		}
+		break;
+	case 24:
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length	= var->green.length = var->blue.length = 8;
+		break;
+	case 32:
+		var->transp.offset = 24;
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->transp.length = 8;
+		var->red.length = var->green.length = var->blue.length = 8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (var->xres > var->xres_virtual)
+		var->xres_virtual = var->xres;
+
+	if (var->yres > var->yres_virtual)
+		var->yres_virtual = var->yres;
+
+	if (info->monspecs.hfmax && info->monspecs.vfmax &&
+	    info->monspecs.dclkmax && fb_validate_mode(var, info) < 0)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void vga_protect(struct i740fb_par *par)
+{
+	/* disable the display */
+	i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0x20, 0x20);
+
+	i740inb(par, 0x3DA);
+	i740outb(par, VGA_ATT_W, 0x00);	/* enable pallete access */
+}
+
+static void vga_unprotect(struct i740fb_par *par)
+{
+	/* reenable display */
+	i740outreg_mask(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE, 0, 0x20);
+
+	i740inb(par, 0x3DA);
+	i740outb(par, VGA_ATT_W, 0x20);	/* disable pallete access */
+}
+
+static int i740fb_set_par(struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+	u32 itemp;
+	int i;
+
+	i = i740fb_decode_var(&info->var, par, info);
+	if (i)
+		return i;
+
+	memset(info->screen_base, 0, info->screen_size);
+
+	vga_protect(par);
+
+	i740outreg(par, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_DISABLE);
+
+	mdelay(1);
+
+	i740outreg(par, XRX, VCLK2_VCO_M, par->video_clk2_m);
+	i740outreg(par, XRX, VCLK2_VCO_N, par->video_clk2_n);
+	i740outreg(par, XRX, VCLK2_VCO_MN_MSBS, par->video_clk2_mn_msbs);
+	i740outreg(par, XRX, VCLK2_VCO_DIV_SEL, par->video_clk2_div_sel);
+
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0,
+			par->pixelpipe_cfg0 & DAC_8_BIT, 0x80);
+
+	i740inb(par, 0x3DA);
+	i740outb(par, 0x3C0, 0x00);
+
+	/* update misc output register */
+	i740outb(par, VGA_MIS_W, par->misc | 0x01);
+
+	/* synchronous reset on */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_RESET, 0x01);
+	/* write sequencer registers */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_CLOCK_MODE,
+			par->seq[VGA_SEQ_CLOCK_MODE] | 0x20);
+	for (i = 2; i < VGA_SEQ_C; i++)
+		i740outreg(par, VGA_SEQ_I, i, par->seq[i]);
+
+	/* synchronous reset off */
+	i740outreg(par, VGA_SEQ_I, VGA_SEQ_RESET, 0x03);
+
+	/* deprotect CRT registers 0-7 */
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_V_SYNC_END,
+			par->crtc[VGA_CRTC_V_SYNC_END]);
+
+	/* write CRT registers */
+	for (i = 0; i < VGA_CRT_C; i++)
+		i740outreg(par, VGA_CRT_IC, i, par->crtc[i]);
+
+	/* write graphics controller registers */
+	for (i = 0; i < VGA_GFX_C; i++)
+		i740outreg(par, VGA_GFX_I, i, par->gdc[i]);
+
+	/* write attribute controller registers */
+	for (i = 0; i < VGA_ATT_C; i++) {
+		i740inb(par, VGA_IS1_RC);		/* reset flip-flop */
+		i740outb(par, VGA_ATT_IW, i);
+		i740outb(par, VGA_ATT_IW, par->atc[i]);
+	}
+
+	i740inb(par, VGA_IS1_RC);
+	i740outb(par, VGA_ATT_IW, 0x20);
+
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_TOTAL, par->ext_vert_total);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_DISPLAY, par->ext_vert_disp_end);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_SYNC_START,
+			par->ext_vert_sync_start);
+	i740outreg(par, VGA_CRT_IC, EXT_VERT_BLANK_START,
+			par->ext_vert_blank_start);
+	i740outreg(par, VGA_CRT_IC, EXT_HORIZ_TOTAL, par->ext_horiz_total);
+	i740outreg(par, VGA_CRT_IC, EXT_HORIZ_BLANK, par->ext_horiz_blank);
+	i740outreg(par, VGA_CRT_IC, EXT_OFFSET, par->ext_offset);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI, par->ext_start_addr_hi);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR, par->ext_start_addr);
+
+	i740outreg_mask(par, VGA_CRT_IC, INTERLACE_CNTL,
+			par->interlace_cntl, INTERLACE_ENABLE);
+	i740outreg_mask(par, XRX, ADDRESS_MAPPING, par->address_mapping, 0x1F);
+	i740outreg_mask(par, XRX, BITBLT_CNTL, par->bitblt_cntl, COLEXP_MODE);
+	i740outreg_mask(par, XRX, DISPLAY_CNTL,
+			par->display_cntl, VGA_WRAP_MODE | GUI_MODE);
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_0, par->pixelpipe_cfg0, 0x9B);
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_2, par->pixelpipe_cfg2, 0x0C);
+
+	i740outreg(par, XRX, PLL_CNTL, par->pll_cntl);
+
+	i740outreg_mask(par, XRX, PIXPIPE_CONFIG_1,
+			par->pixelpipe_cfg1, DISPLAY_COLOR_MODE);
+
+	itemp = readl(par->regs + FWATER_BLC);
+	itemp &= ~(LMI_BURST_LENGTH | LMI_FIFO_WATERMARK);
+	itemp |= par->lmi_fifo_watermark;
+	writel(itemp, par->regs + FWATER_BLC);
+
+	i740outreg(par, XRX, DRAM_EXT_CNTL, DRAM_REFRESH_60HZ);
+
+	i740outreg_mask(par, MRX, COL_KEY_CNTL_1, 0, BLANK_DISP_OVERLAY);
+	i740outreg_mask(par, XRX, IO_CTNL,
+			par->io_cntl, EXTENDED_ATTR_CNTL | EXTENDED_CRTC_CNTL);
+
+	if (par->pixelpipe_cfg1 != DISPLAY_8BPP_MODE) {
+		i740outb(par, VGA_PEL_MSK, 0xFF);
+		i740outb(par, VGA_PEL_IW, 0x00);
+		for (i = 0; i < 256; i++) {
+			itemp = (par->pixelpipe_cfg0 & DAC_8_BIT) ? i : i >> 2;
+			i740outb(par, VGA_PEL_D, itemp);
+			i740outb(par, VGA_PEL_D, itemp);
+			i740outb(par, VGA_PEL_D, itemp);
+		}
+	}
+
+	/* Wait for screen to stabilize. */
+	mdelay(50);
+	vga_unprotect(par);
+
+	info->fix.line_length +			info->var.xres_virtual * info->var.bits_per_pixel / 8;
+	if (info->var.bits_per_pixel = 8)
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+	else
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+	return 0;
+}
+
+static int i740fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info)
+{
+	u32 r, g, b;
+
+	dev_dbg(info->device, "setcolreg: regno: %i, red=%d, green=%d, blue=%d, transp=%d, bpp=%d\n",
+		regno, red, green, blue, transp, info->var.bits_per_pixel);
+
+	switch (info->fix.visual) {
+	case FB_VISUAL_PSEUDOCOLOR:
+		if (regno >= 256)
+			return -EINVAL;
+		i740outb(info->par, VGA_PEL_IW, regno);
+		i740outb(info->par, VGA_PEL_D, red >> 8);
+		i740outb(info->par, VGA_PEL_D, green >> 8);
+		i740outb(info->par, VGA_PEL_D, blue >> 8);
+		break;
+	case FB_VISUAL_TRUECOLOR:
+		if (regno >= 16)
+			return -EINVAL;
+		r = (red >> (16 - info->var.red.length))
+			<< info->var.red.offset;
+		b = (blue >> (16 - info->var.blue.length))
+			<< info->var.blue.offset;
+		g = (green >> (16 - info->var.green.length))
+			<< info->var.green.offset;
+		((u32 *) info->pseudo_palette)[regno] = r | g | b;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int i740fb_pan_display(struct fb_var_screeninfo *var,
+				 struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+	u32 base = (var->yoffset * info->var.xres_virtual
+		 + (var->xoffset & ~7)) >> 2;
+
+	dev_dbg(info->device, "pan_display: xoffset: %i yoffset: %i base: %i\n",
+		var->xoffset, var->yoffset, base);
+
+	switch (info->var.bits_per_pixel) {
+	case 8:
+		break;
+	case 15:
+	case 16:
+		base *= 2;
+		break;
+	case 24:
+		/*
+		 * The last bit does not seem to have any effect on the start
+		 * address register in 24bpp mode, so...
+		 */
+		base &= 0xFFFFFFFE; /* ...ignore the last bit. */
+		base *= 3;
+		break;
+	case 32:
+		base *= 4;
+		break;
+	}
+
+	par->crtc[VGA_CRTC_START_LO] = base & 0x000000FF;
+	par->crtc[VGA_CRTC_START_HI] = (base & 0x0000FF00) >>  8;
+	par->ext_start_addr_hi = (base & 0x3FC00000) >> 22;
+	par->ext_start_addr +			((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE;
+
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_START_LO,  base & 0x000000FF);
+	i740outreg(par, VGA_CRT_IC, VGA_CRTC_START_HI,
+			(base & 0x0000FF00) >> 8);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR_HI,
+			(base & 0x3FC00000) >> 22);
+	i740outreg(par, VGA_CRT_IC, EXT_START_ADDR,
+			((base & 0x003F0000) >> 16) | EXT_START_ADDR_ENABLE);
+
+	return 0;
+}
+
+static int i740fb_blank(int blank_mode, struct fb_info *info)
+{
+	struct i740fb_par *par = info->par;
+
+	unsigned char SEQ01;
+	int DPMSSyncSelect;
+
+	switch (blank_mode) {
+	case FB_BLANK_UNBLANK:
+	case FB_BLANK_NORMAL:
+		SEQ01 = 0x00;
+		DPMSSyncSelect = HSYNC_ON | VSYNC_ON;
+		break;
+	case FB_BLANK_VSYNC_SUSPEND:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_ON | VSYNC_OFF;
+		break;
+	case FB_BLANK_HSYNC_SUSPEND:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_OFF | VSYNC_ON;
+		break;
+	case FB_BLANK_POWERDOWN:
+		SEQ01 = 0x20;
+		DPMSSyncSelect = HSYNC_OFF | VSYNC_OFF;
+		break;
+	default:
+		return -EINVAL;
+	}
+	/* Turn the screen on/off */
+	i740outb(par, SRX, 0x01);
+	SEQ01 |= i740inb(par, SRX + 1) & ~0x20;
+	i740outb(par, SRX, 0x01);
+	i740outb(par, SRX + 1, SEQ01);
+
+	/* Set the DPMS mode */
+	i740outreg(par, XRX, DPMS_SYNC_SELECT, DPMSSyncSelect);
+
+	/* Let fbcon do a soft blank for us */
+	return (blank_mode = FB_BLANK_NORMAL) ? 1 : 0;
+}
+
+static struct fb_ops i740fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_open	= i740fb_open,
+	.fb_release	= i740fb_release,
+	.fb_check_var	= i740fb_check_var,
+	.fb_set_par	= i740fb_set_par,
+	.fb_setcolreg	= i740fb_setcolreg,
+	.fb_blank	= i740fb_blank,
+	.fb_pan_display	= i740fb_pan_display,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+};
+
+/* ------------------------------------------------------------------------- */
+
+static int __devinit i740fb_probe(struct pci_dev *dev,
+				  const struct pci_device_id *ent)
+{
+	struct fb_info *info;
+	struct i740fb_par *par;
+	int ret, tmp;
+	bool found = false;
+	u8 *edid;
+
+	info = framebuffer_alloc(sizeof(struct i740fb_par), &(dev->dev));
+	if (!info) {
+		dev_err(&(dev->dev), "cannot allocate framebuffer\n");
+		return -ENOMEM;
+	}
+
+	par = info->par;
+	mutex_init(&par->open_lock);
+
+	info->var.activate = FB_ACTIVATE_NOW;
+	info->var.bits_per_pixel = 8;
+	info->fbops = &i740fb_ops;
+	info->pseudo_palette = par->pseudo_palette;
+
+	ret = pci_enable_device(dev);
+	if (ret) {
+		dev_err(info->device, "cannot enable PCI device\n");
+		goto err_enable_device;
+	}
+
+	ret = pci_request_regions(dev, info->fix.id);
+	if (ret) {
+		dev_err(info->device, "error requesting regions\n");
+		goto err_request_regions;
+	}
+
+	info->screen_base = pci_ioremap_bar(dev, 0);
+	if (!info->screen_base) {
+		dev_err(info->device, "error remapping base\n");
+		ret = -ENOMEM;
+		goto err_ioremap_1;
+	}
+
+	par->regs = pci_ioremap_bar(dev, 1);
+	if (!par->regs) {
+		dev_err(info->device, "error remapping MMIO\n");
+		ret = -ENOMEM;
+		goto err_ioremap_2;
+	}
+
+	/* detect memory size */
+	if ((i740inreg(par, XRX, DRAM_ROW_TYPE) & DRAM_ROW_1)
+							= DRAM_ROW_1_SDRAM)
+		i740outb(par, XRX, DRAM_ROW_BNDRY_1);
+	else
+		i740outb(par, XRX, DRAM_ROW_BNDRY_0);
+	info->screen_size = i740inb(par, XRX + 1) * 1024 * 1024;
+	/* detect memory type */
+	tmp = i740inreg(par, XRX, DRAM_ROW_CNTL_LO);
+	par->has_sgram = !((tmp & DRAM_RAS_TIMING) ||
+			   (tmp & DRAM_RAS_PRECHARGE));
+
+	printk(KERN_INFO "fb%d: Intel740 on %s, %ld KB %s\n", info->node,
+		pci_name(dev), info->screen_size >> 10,
+		par->has_sgram ? "SGRAM" : "SDRAM");
+
+	info->fix = i740fb_fix;
+	info->fix.mmio_start = pci_resource_start(dev, 1);
+	info->fix.mmio_len = pci_resource_len(dev, 1);
+	info->fix.smem_start = pci_resource_start(dev, 0);
+	info->fix.smem_len = info->screen_size;
+	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
+
+	if (i740fb_setup_ddc_bus(info) = 0) {
+		par->ddc_registered = true;
+		edid = fb_ddc_read(&par->ddc_adapter);
+		if (edid) {
+			fb_edid_to_monspecs(edid, &info->monspecs);
+			kfree(edid);
+			if (!info->monspecs.modedb)
+				dev_err(info->device,
+					"error getting mode database\n");
+			else {
+				const struct fb_videomode *m;
+
+				fb_videomode_to_modelist(
+					info->monspecs.modedb,
+					info->monspecs.modedb_len,
+					&info->modelist);
+				m = fb_find_best_display(&info->monspecs,
+							 &info->modelist);
+				if (m) {
+					fb_videomode_to_var(&info->var, m);
+					/* fill all other info->var's fields */
+					if (!i740fb_check_var(&info->var, info))
+						found = true;
+				}
+			}
+		}
+	}
+
+	if (!mode_option && !found)
+		mode_option = "640x480-8@60";
+
+	if (mode_option) {
+		ret = fb_find_mode(&info->var, info, mode_option,
+				   info->monspecs.modedb,
+				   info->monspecs.modedb_len,
+				   NULL, info->var.bits_per_pixel);
+		if (!ret || ret = 4) {
+			dev_err(info->device, "mode %s not found\n",
+				mode_option);
+			ret = -EINVAL;
+		}
+	}
+
+	fb_destroy_modedb(info->monspecs.modedb);
+	info->monspecs.modedb = NULL;
+
+	/* maximize virtual vertical size for fast scrolling */
+	info->var.yres_virtual = info->fix.smem_len * 8 /
+			(info->var.bits_per_pixel * info->var.xres_virtual);
+
+	if (ret = -EINVAL)
+		goto err_find_mode;
+
+	ret = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (ret) {
+		dev_err(info->device, "cannot allocate colormap\n");
+		goto err_alloc_cmap;
+	}
+
+	ret = register_framebuffer(info);
+	if (ret) {
+		dev_err(info->device, "error registering framebuffer\n");
+		goto err_reg_framebuffer;
+	}
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+		info->node, info->fix.id);
+	pci_set_drvdata(dev, info);
+#ifdef CONFIG_MTRR
+	if (mtrr) {
+		par->mtrr_reg = -1;
+		par->mtrr_reg = mtrr_add(info->fix.smem_start,
+				info->fix.smem_len, MTRR_TYPE_WRCOMB, 1);
+	}
+#endif
+	return 0;
+
+err_reg_framebuffer:
+	fb_dealloc_cmap(&info->cmap);
+err_alloc_cmap:
+err_find_mode:
+	if (par->ddc_registered)
+		i2c_del_adapter(&par->ddc_adapter);
+	pci_iounmap(dev, par->regs);
+err_ioremap_2:
+	pci_iounmap(dev, info->screen_base);
+err_ioremap_1:
+	pci_release_regions(dev);
+err_request_regions:
+/*	pci_disable_device(dev); */
+err_enable_device:
+	framebuffer_release(info);
+	return ret;
+}
+
+static void __devexit i740fb_remove(struct pci_dev *dev)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+
+	if (info) {
+#ifdef CONFIG_MTRR
+		struct i740fb_par *par = info->par;
+
+		if (par->mtrr_reg >= 0) {
+			mtrr_del(par->mtrr_reg, 0, 0);
+			par->mtrr_reg = -1;
+		}
+#endif
+		unregister_framebuffer(info);
+		fb_dealloc_cmap(&info->cmap);
+		if (par->ddc_registered)
+			i2c_del_adapter(&par->ddc_adapter);
+		pci_iounmap(dev, par->regs);
+		pci_iounmap(dev, info->screen_base);
+		pci_release_regions(dev);
+/*		pci_disable_device(dev); */
+		pci_set_drvdata(dev, NULL);
+		framebuffer_release(info);
+	}
+}
+
+#ifdef CONFIG_PM
+static int i740fb_suspend(struct pci_dev *dev, pm_message_t state)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+	struct i740fb_par *par = info->par;
+
+	/* don't disable console during hibernation and wakeup from it */
+	if (state.event = PM_EVENT_FREEZE || state.event = PM_EVENT_PRETHAW)
+		return 0;
+
+	console_lock();
+	mutex_lock(&(par->open_lock));
+
+	/* do nothing if framebuffer is not active */
+	if (par->ref_count = 0) {
+		mutex_unlock(&(par->open_lock));
+		console_unlock();
+		return 0;
+	}
+
+	fb_set_suspend(info, 1);
+
+	pci_save_state(dev);
+	pci_disable_device(dev);
+	pci_set_power_state(dev, pci_choose_state(dev, state));
+
+	mutex_unlock(&(par->open_lock));
+	console_unlock();
+
+	return 0;
+}
+
+static int i740fb_resume(struct pci_dev *dev)
+{
+	struct fb_info *info = pci_get_drvdata(dev);
+	struct i740fb_par *par = info->par;
+
+	console_lock();
+	mutex_lock(&(par->open_lock));
+
+	if (par->ref_count = 0)
+		goto fail;
+
+	pci_set_power_state(dev, PCI_D0);
+	pci_restore_state(dev);
+	if (pci_enable_device(dev))
+		goto fail;
+
+	i740fb_set_par(info);
+	fb_set_suspend(info, 0);
+
+fail:
+	mutex_unlock(&(par->open_lock));
+	console_unlock();
+	return 0;
+}
+#else
+#define i740fb_suspend NULL
+#define i740fb_resume NULL
+#endif /* CONFIG_PM */
+
+#define I740_ID_PCI 0x00d1
+#define I740_ID_AGP 0x7800
+
+static DEFINE_PCI_DEVICE_TABLE(i740fb_id_table) = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_PCI) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, I740_ID_AGP) },
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, i740fb_id_table);
+
+static struct pci_driver i740fb_driver = {
+	.name		= "i740fb",
+	.id_table	= i740fb_id_table,
+	.probe		= i740fb_probe,
+	.remove		= __devexit_p(i740fb_remove),
+	.suspend	= i740fb_suspend,
+	.resume		= i740fb_resume,
+};
+
+#ifndef MODULE
+static int  __init i740fb_setup(char *options)
+{
+	char *opt;
+
+	if (!options || !*options)
+		return 0;
+
+	while ((opt = strsep(&options, ",")) != NULL) {
+		if (!*opt)
+			continue;
+#ifdef CONFIG_MTRR
+		else if (!strncmp(opt, "mtrr:", 5))
+			mtrr = simple_strtoul(opt + 5, NULL, 0);
+#endif
+		else
+			mode_option = opt;
+	}
+
+	return 0;
+}
+#endif
+
+int __init i740fb_init(void)
+{
+#ifndef MODULE
+	char *option = NULL;
+
+	if (fb_get_options("i740fb", &option))
+		return -ENODEV;
+	i740fb_setup(option);
+#endif
+
+	return pci_register_driver(&i740fb_driver);
+}
+
+static void __exit i740fb_exit(void)
+{
+	pci_unregister_driver(&i740fb_driver);
+}
+
+module_init(i740fb_init);
+module_exit(i740fb_exit);
+
+MODULE_AUTHOR("(c) 2011 Ondrej Zary <linux@rainbow-software.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("fbdev driver for Intel740");
+
+module_param(mode_option, charp, 0444);
+MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
+
+#ifdef CONFIG_MTRR
+module_param(mtrr, int, 0444);
+MODULE_PARM_DESC(mtrr, "Enable write-combining with MTRR (1=enable, 0=disable, default=1)");
+#endif
--- /dev/null	2012-01-24 00:06:39.330222901 +0100
+++ linux-3.2.1/drivers/video/i740_reg.h	2012-01-23 22:55:57.000000000 +0100
@@ -0,0 +1,309 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <kevin@precisioninsight.com>
+ */
+
+/* I/O register offsets */
+#define SRX VGA_SEQ_I
+#define GRX VGA_GFX_I
+#define ARX VGA_ATT_IW
+#define XRX 0x3D6
+#define MRX 0x3D2
+
+/* VGA Color Palette Registers */
+#define DACMASK		0x3C6
+#define DACSTATE	0x3C7
+#define DACRX		0x3C7
+#define DACWX		0x3C8
+#define DACDATA		0x3C9
+
+/* CRT Controller Registers (CRX) */
+#define START_ADDR_HI		0x0C
+#define START_ADDR_LO		0x0D
+#define VERT_SYNC_END		0x11
+#define EXT_VERT_TOTAL		0x30
+#define EXT_VERT_DISPLAY	0x31
+#define EXT_VERT_SYNC_START	0x32
+#define EXT_VERT_BLANK_START	0x33
+#define EXT_HORIZ_TOTAL		0x35
+#define EXT_HORIZ_BLANK		0x39
+#define EXT_START_ADDR		0x40
+#define EXT_START_ADDR_ENABLE	0x80
+#define EXT_OFFSET		0x41
+#define EXT_START_ADDR_HI	0x42
+#define INTERLACE_CNTL		0x70
+#define INTERLACE_ENABLE	0x80
+#define INTERLACE_DISABLE	0x00
+
+/* Miscellaneous Output Register */
+#define MSR_R		0x3CC
+#define MSR_W		0x3C2
+#define IO_ADDR_SELECT	0x01
+
+#define MDA_BASE	0x3B0
+#define CGA_BASE	0x3D0
+
+/* System Configuration Extension Registers (XRX) */
+#define IO_CTNL		0x09
+#define EXTENDED_ATTR_CNTL	0x02
+#define EXTENDED_CRTC_CNTL	0x01
+
+#define ADDRESS_MAPPING	0x0A
+#define PACKED_MODE_ENABLE	0x04
+#define LINEAR_MODE_ENABLE	0x02
+#define PAGE_MAPPING_ENABLE	0x01
+
+#define BITBLT_CNTL	0x20
+#define COLEXP_MODE		0x30
+#define COLEXP_8BPP		0x00
+#define COLEXP_16BPP		0x10
+#define COLEXP_24BPP		0x20
+#define COLEXP_RESERVED		0x30
+#define CHIP_RESET		0x02
+#define BITBLT_STATUS		0x01
+
+#define DISPLAY_CNTL	0x40
+#define VGA_WRAP_MODE		0x02
+#define VGA_WRAP_AT_256KB	0x00
+#define VGA_NO_WRAP		0x02
+#define GUI_MODE		0x01
+#define STANDARD_VGA_MODE	0x00
+#define HIRES_MODE		0x01
+
+#define DRAM_ROW_TYPE	0x50
+#define DRAM_ROW_0		0x07
+#define DRAM_ROW_0_SDRAM	0x00
+#define DRAM_ROW_0_EMPTY	0x07
+#define DRAM_ROW_1		0x38
+#define DRAM_ROW_1_SDRAM	0x00
+#define DRAM_ROW_1_EMPTY	0x38
+#define DRAM_ROW_CNTL_LO 0x51
+#define DRAM_CAS_LATENCY	0x10
+#define DRAM_RAS_TIMING		0x08
+#define DRAM_RAS_PRECHARGE	0x04
+#define DRAM_ROW_CNTL_HI 0x52
+#define DRAM_EXT_CNTL	0x53
+#define DRAM_REFRESH_RATE	0x03
+#define DRAM_REFRESH_DISABLE	0x00
+#define DRAM_REFRESH_60HZ	0x01
+#define DRAM_REFRESH_FAST_TEST	0x02
+#define DRAM_REFRESH_RESERVED	0x03
+#define DRAM_TIMING	0x54
+#define DRAM_ROW_BNDRY_0 0x55
+#define DRAM_ROW_BNDRY_1 0x56
+
+#define DPMS_SYNC_SELECT 0x61
+#define VSYNC_CNTL		0x08
+#define VSYNC_ON		0x00
+#define VSYNC_OFF		0x08
+#define HSYNC_CNTL		0x02
+#define HSYNC_ON		0x00
+#define HSYNC_OFF		0x02
+
+#define PIXPIPE_CONFIG_0 0x80
+#define DAC_8_BIT		0x80
+#define DAC_6_BIT		0x00
+#define HW_CURSOR_ENABLE	0x10
+#define EXTENDED_PALETTE	0x01
+
+#define PIXPIPE_CONFIG_1 0x81
+#define DISPLAY_COLOR_MODE	0x0F
+#define DISPLAY_VGA_MODE	0x00
+#define DISPLAY_8BPP_MODE	0x02
+#define DISPLAY_15BPP_MODE	0x04
+#define DISPLAY_16BPP_MODE	0x05
+#define DISPLAY_24BPP_MODE	0x06
+#define DISPLAY_32BPP_MODE	0x07
+
+#define PIXPIPE_CONFIG_2 0x82
+#define DISPLAY_GAMMA_ENABLE	0x08
+#define DISPLAY_GAMMA_DISABLE	0x00
+#define OVERLAY_GAMMA_ENABLE	0x04
+#define OVERLAY_GAMMA_DISABLE	0x00
+
+#define CURSOR_CONTROL	0xA0
+#define CURSOR_ORIGIN_SCREEN	0x00
+#define CURSOR_ORIGIN_DISPLAY	0x10
+#define CURSOR_MODE		0x07
+#define CURSOR_MODE_DISABLE	0x00
+#define CURSOR_MODE_32_4C_AX	0x01
+#define CURSOR_MODE_128_2C	0x02
+#define CURSOR_MODE_128_1C	0x03
+#define CURSOR_MODE_64_3C	0x04
+#define CURSOR_MODE_64_4C_AX	0x05
+#define CURSOR_MODE_64_4C	0x06
+#define CURSOR_MODE_RESERVED	0x07
+#define CURSOR_BASEADDR_LO 0xA2
+#define CURSOR_BASEADDR_HI 0xA3
+#define CURSOR_X_LO	0xA4
+#define CURSOR_X_HI	0xA5
+#define CURSOR_X_POS		0x00
+#define CURSOR_X_NEG		0x80
+#define CURSOR_Y_LO	0xA6
+#define CURSOR_Y_HI	0xA7
+#define CURSOR_Y_POS		0x00
+#define CURSOR_Y_NEG		0x80
+
+#define VCLK2_VCO_M	0xC8
+#define VCLK2_VCO_N	0xC9
+#define VCLK2_VCO_MN_MSBS 0xCA
+#define VCO_N_MSBS		0x30
+#define VCO_M_MSBS		0x03
+#define VCLK2_VCO_DIV_SEL 0xCB
+#define POST_DIV_SELECT		0x70
+#define POST_DIV_1		0x00
+#define POST_DIV_2		0x10
+#define POST_DIV_4		0x20
+#define POST_DIV_8		0x30
+#define POST_DIV_16		0x40
+#define POST_DIV_32		0x50
+#define VCO_LOOP_DIV_BY_4M	0x00
+#define VCO_LOOP_DIV_BY_16M	0x04
+#define REF_CLK_DIV_BY_5	0x02
+#define REF_DIV_4		0x00
+#define REF_DIV_1		0x01
+
+#define PLL_CNTL	0xCE
+#define PLL_MEMCLK_SEL		0x03
+#define PLL_MEMCLK__66667KHZ	0x00
+#define PLL_MEMCLK__75000KHZ	0x01
+#define PLL_MEMCLK__88889KHZ	0x02
+#define PLL_MEMCLK_100000KHZ	0x03
+
+/* Multimedia Extension Registers (MRX) */
+#define ACQ_CNTL_1	0x02
+#define ACQ_CNTL_2	0x03
+#define FRAME_CAP_MODE		0x01
+#define CONT_CAP_MODE		0x00
+#define SINGLE_CAP_MODE		0x01
+#define ACQ_CNTL_3	0x04
+#define COL_KEY_CNTL_1		0x3C
+#define BLANK_DISP_OVERLAY	0x20
+
+/* FIFOs */
+#define LP_FIFO		0x1000
+#define HP_FIFO		0x2000
+#define INSTPNT		0x3040
+#define LP_FIFO_COUNT	0x3040
+#define HP_FIFO_COUNT	0x3041
+
+/* FIFO Commands */
+#define CLIENT		0xE0000000
+#define CLIENT_2D	0x60000000
+
+/* Command Parser Mode Register */
+#define COMPARS		0x3038
+#define TWO_D_INST_DISABLE		0x08
+#define THREE_D_INST_DISABLE		0x04
+#define STATE_VAR_UPDATE_DISABLE	0x02
+#define PAL_STIP_DISABLE		0x01
+
+/* Interrupt Control Registers */
+#define IER		0x3030
+#define IIR		0x3032
+#define IMR		0x3034
+#define ISR		0x3036
+#define VMIINTB_EVENT		0x2000
+#define GPIO4_INT		0x1000
+#define DISP_FLIP_EVENT		0x0800
+#define DVD_PORT_DMA		0x0400
+#define DISP_VBLANK		0x0200
+#define FIFO_EMPTY_DMA_DONE	0x0100
+#define INST_PARSER_ERROR	0x0080
+#define USER_DEFINED		0x0040
+#define BREAKPOINT		0x0020
+#define DISP_HORIZ_COUNT	0x0010
+#define DISP_VSYNC		0x0008
+#define CAPTURE_HORIZ_COUNT	0x0004
+#define CAPTURE_VSYNC		0x0002
+#define THREE_D_PIPE_FLUSHED	0x0001
+
+/* FIFO Watermark and Burst Length Control Register */
+#define FWATER_BLC	0x00006000
+#define LMI_BURST_LENGTH	0x7F000000
+#define LMI_FIFO_WATERMARK	0x003F0000
+#define AGP_BURST_LENGTH	0x00007F00
+#define AGP_FIFO_WATERMARK	0x0000003F
+
+/* BitBLT Registers */
+#define SRC_DST_PITCH	0x00040000
+#define DST_PITCH		0x1FFF0000
+#define SRC_PITCH		0x00001FFF
+#define COLEXP_BG_COLOR	0x00040004
+#define COLEXP_FG_COLOR	0x00040008
+#define MONO_SRC_CNTL	0x0004000C
+#define MONO_USE_COLEXP		0x00000000
+#define MONO_USE_SRCEXP		0x08000000
+#define MONO_DATA_ALIGN		0x07000000
+#define MONO_BIT_ALIGN		0x01000000
+#define MONO_BYTE_ALIGN		0x02000000
+#define MONO_WORD_ALIGN		0x03000000
+#define MONO_DWORD_ALIGN	0x04000000
+#define MONO_QWORD_ALIGN	0x05000000
+#define MONO_SRC_INIT_DSCRD	0x003F0000
+#define MONO_SRC_RIGHT_CLIP	0x00003F00
+#define MONO_SRC_LEFT_CLIP	0x0000003F
+#define BITBLT_CONTROL	0x00040010
+#define BLTR_STATUS		0x80000000
+#define DYN_DEPTH		0x03000000
+#define DYN_DEPTH_8BPP		0x00000000
+#define DYN_DEPTH_16BPP		0x01000000
+#define DYN_DEPTH_24BPP		0x02000000
+#define DYN_DEPTH_32BPP		0x03000000	/* Unimplemented on the i740 */
+#define DYN_DEPTH_ENABLE	0x00800000
+#define PAT_VERT_ALIGN		0x00700000
+#define SOLID_PAT_SELECT	0x00080000
+#define PAT_IS_IN_COLOR		0x00000000
+#define PAT_IS_MONO		0x00040000
+#define MONO_PAT_TRANSP		0x00020000
+#define COLOR_TRANSP_ROP	0x00000000
+#define COLOR_TRANSP_DST	0x00008000
+#define COLOR_TRANSP_EQ		0x00000000
+#define COLOR_TRANSP_NOT_EQ	0x00010000
+#define COLOR_TRANSP_ENABLE	0x00004000
+#define MONO_SRC_TRANSP		0x00002000
+#define SRC_IS_IN_COLOR		0x00000000
+#define SRC_IS_MONO		0x00001000
+#define SRC_USE_SRC_ADDR	0x00000000
+#define SRC_USE_BLTDATA		0x00000400
+#define BLT_TOP_TO_BOT		0x00000000
+#define BLT_BOT_TO_TOP		0x00000200
+#define BLT_LEFT_TO_RIGHT	0x00000000
+#define BLT_RIGHT_TO_LEFT	0x00000100
+#define BLT_ROP			0x000000FF
+#define BLT_PAT_ADDR	0x00040014
+#define BLT_SRC_ADDR	0x00040018
+#define BLT_DST_ADDR	0x0004001C
+#define BLT_DST_H_W	0x00040020
+#define BLT_DST_HEIGHT		0x1FFF0000
+#define BLT_DST_WIDTH		0x00001FFF
+#define SRCEXP_BG_COLOR	0x00040024
+#define SRCEXP_FG_COLOR	0x00040028
+#define BLTDATA		0x00050000



-- 
Ondrej Zary

^ permalink raw reply

* Re: [PATCH 3/3] OMAPDSS: use sync versions of pm_runtime_put
From: Kevin Hilman @ 2012-01-23 22:33 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: linux-omap, linux-fbdev, paul, archit, neilb, jean.pihet, jw
In-Reply-To: <1327320930-14550-4-git-send-email-tomi.valkeinen@ti.com>

Tomi Valkeinen <tomi.valkeinen@ti.com> writes:

> omapdss doesn't work properly on system suspend. The problem seems to be
> the fact that omapdss uses pm_runtime_put() functions when turning off
> the hardware, and when system suspend is in process only sync versions
> are allowed.
>
> Using non-sync versions normally and sync versions when suspending would
> need rather ugly hacks to convey the information of
> suspending/not-suspending to different functions. Optimally the driver
> wouldn't even need to care about this, and the PM layer would handle
> syncing when suspend is in process.
>
> This patch changes all omapdss's pm_runtime_put calls to
> pm_runtime_put_sync. This fixes the suspend problem, and probably the
> performance penalty of always using sync versions is negligible.
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

Acked-by: Kevin Hilman <khilman@ti.com>

^ permalink raw reply

* [PATCH 3/3] OMAPDSS: use sync versions of pm_runtime_put
From: Tomi Valkeinen @ 2012-01-23 12:15 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, paul
  Cc: archit, neilb, jean.pihet, khilman, jw, Tomi Valkeinen
In-Reply-To: <1327320930-14550-1-git-send-email-tomi.valkeinen@ti.com>

omapdss doesn't work properly on system suspend. The problem seems to be
the fact that omapdss uses pm_runtime_put() functions when turning off
the hardware, and when system suspend is in process only sync versions
are allowed.

Using non-sync versions normally and sync versions when suspending would
need rather ugly hacks to convey the information of
suspending/not-suspending to different functions. Optimally the driver
wouldn't even need to care about this, and the PM layer would handle
syncing when suspend is in process.

This patch changes all omapdss's pm_runtime_put calls to
pm_runtime_put_sync. This fixes the suspend problem, and probably the
performance penalty of always using sync versions is negligible.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/dss/dispc.c |    2 +-
 drivers/video/omap2/dss/dsi.c   |    2 +-
 drivers/video/omap2/dss/dss.c   |    2 +-
 drivers/video/omap2/dss/hdmi.c  |    2 +-
 drivers/video/omap2/dss/rfbi.c  |    2 +-
 drivers/video/omap2/dss/venc.c  |    2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a5ec7f3..e1626a1 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -401,7 +401,7 @@ void dispc_runtime_put(void)
 
 	DSSDBG("dispc_runtime_put\n");
 
-	r = pm_runtime_put(&dispc.pdev->dev);
+	r = pm_runtime_put_sync(&dispc.pdev->dev);
 	WARN_ON(r < 0);
 }
 
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index d4d676c..52f36ec 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1079,7 +1079,7 @@ void dsi_runtime_put(struct platform_device *dsidev)
 
 	DSSDBG("dsi_runtime_put\n");
 
-	r = pm_runtime_put(&dsi->pdev->dev);
+	r = pm_runtime_put_sync(&dsi->pdev->dev);
 	WARN_ON(r < 0);
 }
 
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 1703345..77c2b5a 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -720,7 +720,7 @@ void dss_runtime_put(void)
 
 	DSSDBG("dss_runtime_put\n");
 
-	r = pm_runtime_put(&dss.pdev->dev);
+	r = pm_runtime_put_sync(&dss.pdev->dev);
 	WARN_ON(r < 0);
 }
 
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index b4c270e..c39f9c3 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -176,7 +176,7 @@ static void hdmi_runtime_put(void)
 
 	DSSDBG("hdmi_runtime_put\n");
 
-	r = pm_runtime_put(&hdmi.pdev->dev);
+	r = pm_runtime_put_sync(&hdmi.pdev->dev);
 	WARN_ON(r < 0);
 }
 
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 814bb95..55f3980 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -140,7 +140,7 @@ static void rfbi_runtime_put(void)
 
 	DSSDBG("rfbi_runtime_put\n");
 
-	r = pm_runtime_put(&rfbi.pdev->dev);
+	r = pm_runtime_put_sync(&rfbi.pdev->dev);
 	WARN_ON(r < 0);
 }
 
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index b3e9f90..5c3d0f9 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -401,7 +401,7 @@ static void venc_runtime_put(void)
 
 	DSSDBG("venc_runtime_put\n");
 
-	r = pm_runtime_put(&venc.pdev->dev);
+	r = pm_runtime_put_sync(&venc.pdev->dev);
 	WARN_ON(r < 0);
 }
 
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 2/3] ARM: OMAP3: HWMOD: add SYSC_HAS_ENAWAKEUP for dispc
From: Tomi Valkeinen @ 2012-01-23 12:15 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, paul
  Cc: archit, neilb, jean.pihet, khilman, jw, Tomi Valkeinen
In-Reply-To: <1327320930-14550-1-git-send-email-tomi.valkeinen@ti.com>

dispc's sysc_flags is missing SYSC_HAS_ENAWAKEUP flag. This seems to
cause SYNC_LOST errors from the DSS when the power management is
enabled.

This patch adds the missing SYSC_HAS_ENAWAKEUP flag. Note that there are
other flags missing also (clock activity, DSI's sysc flags), but as they
are not critical, they will be fixed in the next merge window.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index c965309..b176d44 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -1490,7 +1490,8 @@ static struct omap_hwmod_class_sysconfig omap3_dispc_sysc = {
 	.sysc_offs	= 0x0010,
 	.syss_offs	= 0x0014,
 	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
-			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+			   SYSC_HAS_ENAWAKEUP),
 	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
 			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
 	.sysc_fields	= &omap_hwmod_sysc_type1,
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 1/3] ARM: OMAP: HWMOD: split omap2/3 dispc hwmod class
From: Tomi Valkeinen @ 2012-01-23 12:15 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, paul
  Cc: archit, neilb, jean.pihet, khilman, jw, Tomi Valkeinen
In-Reply-To: <1327320930-14550-1-git-send-email-tomi.valkeinen@ti.com>

Currently OMAP2 and 3 share the same omap_hwmod_class and
omap_hwmod_class_sysconfig for dispc. However, OMAP3 has sysconfig
bits that OMAP2 doesn't have, so we need to split those structs into
OMAP2 and OMAP3 specific versions.

This patch only splits the structs, without changing the contents.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 .../mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c |   21 ------------------
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c |   22 +++++++++++++++++++
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c         |   23 +++++++++++++++++++-
 3 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
index c11273d..f08e442 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c
@@ -56,27 +56,6 @@ struct omap_hwmod_class omap2_dss_hwmod_class = {
 };
 
 /*
- * 'dispc' class
- * display controller
- */
-
-static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = {
-	.rev_offs	= 0x0000,
-	.sysc_offs	= 0x0010,
-	.syss_offs	= 0x0014,
-	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
-			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
-	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
-	.sysc_fields	= &omap_hwmod_sysc_type1,
-};
-
-struct omap_hwmod_class omap2_dispc_hwmod_class = {
-	.name	= "dispc",
-	.sysc	= &omap2_dispc_sysc,
-};
-
-/*
  * 'rfbi' class
  * remote frame buffer interface
  */
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 177dee2..2a67297 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -28,6 +28,28 @@ struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = {
 	{ .name = "dispc", .dma_req = 5 },
 	{ .dma_req = -1 }
 };
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2_dispc_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+struct omap_hwmod_class omap2_dispc_hwmod_class = {
+	.name	= "dispc",
+	.sysc	= &omap2_dispc_sysc,
+};
+
 /* OMAP2xxx Timer Common */
 static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = {
 	.rev_offs	= 0x0000,
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 5324e8d..c965309 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -1480,6 +1480,27 @@ static struct omap_hwmod omap3xxx_dss_core_hwmod = {
 	.masters_cnt	= ARRAY_SIZE(omap3xxx_dss_masters),
 };
 
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3_dispc_sysc = {
+	.rev_offs	= 0x0000,
+	.sysc_offs	= 0x0010,
+	.syss_offs	= 0x0014,
+	.sysc_flags	= (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+			   SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+	.idlemodes	= (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+			   MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+	.sysc_fields	= &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3_dispc_hwmod_class = {
+	.name	= "dispc",
+	.sysc	= &omap3_dispc_sysc,
+};
+
 /* l4_core -> dss_dispc */
 static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = {
 	.master		= &omap3xxx_l4_core_hwmod,
@@ -1503,7 +1524,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = {
 
 static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
 	.name		= "dss_dispc",
-	.class		= &omap2_dispc_hwmod_class,
+	.class		= &omap3_dispc_hwmod_class,
 	.mpu_irqs	= omap2_dispc_irqs,
 	.main_clk	= "dss1_alwon_fck",
 	.prcm		= {
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 0/3] OMAP: DSS PM fixes
From: Tomi Valkeinen @ 2012-01-23 12:15 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, paul
  Cc: archit, neilb, jean.pihet, khilman, jw, Tomi Valkeinen

Here are two fixes to get DSS work better with PM on OMAP3.

The first two patches fix the missing SYSC_HAS_ENAWAKEUP flag, which removes
the SYNC_LOST problem.

The third patch changes omapdss to use pm_runtime_put_sync functions, which
fixes the system suspend.

I've tested both only on v3.3-rc1, OMAP3 Overo. I get problems on system
suspend from TWL and MTD drivers (also without my patches =), but disabling MTD
and ignoring TWL errors shows that the warning from omapdss has disappeared,
and I get an image on the screen on resume.

The two fixes are independent, so either I can take them through dss tree (with
appropriate Acks), or the hwmod patches can go through some other tree.

The fixes should also work directly on v3.2, even though I haven't tested them
yet.

 Tomi

Tomi Valkeinen (3):
  ARM: OMAP: HWMOD: split omap2/3 dispc hwmod class
  ARM: OMAP3: HWMOD: add SYSC_HAS_ENAWAKEUP for dispc
  OMAPDSS: use sync versions of pm_runtime_put

 .../mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c |   21 -----------------
 arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c |   22 ++++++++++++++++++
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c         |   24 +++++++++++++++++++-
 drivers/video/omap2/dss/dispc.c                    |    2 +-
 drivers/video/omap2/dss/dsi.c                      |    2 +-
 drivers/video/omap2/dss/dss.c                      |    2 +-
 drivers/video/omap2/dss/hdmi.c                     |    2 +-
 drivers/video/omap2/dss/rfbi.c                     |    2 +-
 drivers/video/omap2/dss/venc.c                     |    2 +-
 9 files changed, 51 insertions(+), 28 deletions(-)

-- 
1.7.4.1


^ permalink raw reply

* Re: [PATCH] fbdev: sh_mipi_dsi: add extra settings method for platform
From: Laurent Pinchart @ 2012-01-23 10:36 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <874nvnhupd.wl%kuninori.morimoto.gx@renesas.com>

Hello Morimoto-san,

Thank you for the patch.

On Monday 23 January 2012 06:08:34 Kuninori Morimoto wrote:
> Some platform needs extra MIPI settings.
> This patch add support it.
> 
> Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
> ---
>  drivers/video/sh_mipi_dsi.c |    8 ++++++++
>  include/video/sh_mipi_dsi.h |    3 +++
>  2 files changed, 11 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
> index 05151b8..1532894 100644
> --- a/drivers/video/sh_mipi_dsi.c
> +++ b/drivers/video/sh_mipi_dsi.c
> @@ -386,6 +386,14 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
>  			  pixfmt << 4);
>  	sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON);
> 
> +	/*
> +	 * extra dcs settings for platform
> +	 */
> +	if (pdata->set_dcs)
> +		pdata->set_dcs(ch->chan,
> +			       sh_mipi_dcs,
> +			       sh_mipi_dcs_param);
> +
>  	/* Enable timeout counters */
>  	iowrite32(0x00000f00, base + DSICTRL);
> 
> diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h
> index 434d56b..6e1f7bc 100644
> --- a/include/video/sh_mipi_dsi.h
> +++ b/include/video/sh_mipi_dsi.h
> @@ -52,6 +52,9 @@ struct sh_mipi_dsi_info {
>  	unsigned long			flags;
>  	u32				clksrc;
>  	unsigned int			vsynw_offset;
> +	void (*set_dcs)(int handle,
> +			int (*mipi_dcs)(int handle, u8 cmd),
> +			int (*mipi_dcs_param)(int handle, u8 cmd, u8 param));

I don't think this is a good idea. First of all, we should reduce the number 
of board code callbacks to make transition to the device tree easier. Then, 
passing two functions to board code to read and write any device register 
without the driver having any knowledge about that is a clear violation of the 
device model, and will result in problems sooner or later.

What MIPI settings do platforms need to modify ? Can those settings be 
expressed as data in the sh_mipi_dsi_info structure instead ?

>  	int	(*set_dot_clock)(struct platform_device *pdev,
>  				 void __iomem *base,
>  				 int enable);

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH 4/4] drivers/video/backlight/adp5520_bl.c: use devm_ functions
From: Michael Hennerich @ 2012-01-23  8:32 UTC (permalink / raw)
  To: Julia Lawall
  Cc: kernel-janitors@vger.kernel.org, Richard Purdie,
	Florian Tobias Schandinat,
	device-drivers-devel@blackfin.uclinux.org,
	linux-fbdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <1327094732-9050-5-git-send-email-Julia.Lawall@lip6.fr>

On 01/20/2012 10:25 PM, Julia Lawall wrote:
> From: Julia Lawall<Julia.Lawall@lip6.fr>
>
> The various devm_ functions allocate memory that is released when a driver
> detaches.  This patch uses these functions for data that is allocated in
> the probe function of a platform device and is only freed in the remove
> function.
>
> Signed-off-by: Julia Lawall<Julia.Lawall@lip6.fr>
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
> ---
>   drivers/video/backlight/adp5520_bl.c |    6 +-----
>   1 file changed, 1 insertion(+), 5 deletions(-)
>
> diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c
> index 2e630bf..4911ea7 100644
> --- a/drivers/video/backlight/adp5520_bl.c
> +++ b/drivers/video/backlight/adp5520_bl.c
> @@ -289,7 +289,7 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
>   	struct adp5520_bl *data;
>   	int ret = 0;
>
> -	data = kzalloc(sizeof(*data), GFP_KERNEL);
> +	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
>   	if (data = NULL)
>   		return -ENOMEM;
>
> @@ -298,7 +298,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
>
>   	if (data->pdata  = NULL) {
>   		dev_err(&pdev->dev, "missing platform data\n");
> -		kfree(data);
>   		return -ENODEV;
>   	}
>
> @@ -314,7 +313,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
>   				&adp5520_bl_ops,&props);
>   	if (IS_ERR(bl)) {
>   		dev_err(&pdev->dev, "failed to register backlight\n");
> -		kfree(data);
>   		return PTR_ERR(bl);
>   	}
>
> @@ -326,7 +324,6 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
>   	if (ret) {
>   		dev_err(&pdev->dev, "failed to register sysfs\n");
>   		backlight_device_unregister(bl);
> -		kfree(data);
>   	}
>
>   	platform_set_drvdata(pdev, bl);
> @@ -348,7 +345,6 @@ static int __devexit adp5520_bl_remove(struct platform_device *pdev)
>   				&adp5520_bl_attr_group);
>
>   	backlight_device_unregister(bl);
> -	kfree(data);
>
>   	return 0;
>   }
>
>


-- 
Greetings,
Michael

--
Analog Devices GmbH      Wilhelm-Wagenfeld-Str. 6      80807 Muenchen
Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368;
Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin,
Margaret Seif



^ permalink raw reply

* [PATCH] fbdev: sh_mipi_dsi: add extra settings method for platform
From: Kuninori Morimoto @ 2012-01-23  5:08 UTC (permalink / raw)
  To: linux-fbdev

Some platform needs extra MIPI settings.
This patch add support it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
---
 drivers/video/sh_mipi_dsi.c |    8 ++++++++
 include/video/sh_mipi_dsi.h |    3 +++
 2 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 05151b8..1532894 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -386,6 +386,14 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
 			  pixfmt << 4);
 	sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON);
 
+	/*
+	 * extra dcs settings for platform
+	 */
+	if (pdata->set_dcs)
+		pdata->set_dcs(ch->chan,
+			       sh_mipi_dcs,
+			       sh_mipi_dcs_param);
+
 	/* Enable timeout counters */
 	iowrite32(0x00000f00, base + DSICTRL);
 
diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h
index 434d56b..6e1f7bc 100644
--- a/include/video/sh_mipi_dsi.h
+++ b/include/video/sh_mipi_dsi.h
@@ -52,6 +52,9 @@ struct sh_mipi_dsi_info {
 	unsigned long			flags;
 	u32				clksrc;
 	unsigned int			vsynw_offset;
+	void (*set_dcs)(int handle,
+			int (*mipi_dcs)(int handle, u8 cmd),
+			int (*mipi_dcs_param)(int handle, u8 cmd, u8 param));
 	int	(*set_dot_clock)(struct platform_device *pdev,
 				 void __iomem *base,
 				 int enable);
-- 
1.7.5.4


^ permalink raw reply related

* Re: [PATCH 2/4] drivers/video/au*fb.c: use devm_ functions
From: Julia Lawall @ 2012-01-21 15:01 UTC (permalink / raw)
  To: Manuel Lauss
  Cc: Florian Tobias Schandinat, Julia Lawall, kernel-janitors,
	linux-fbdev, LKML
In-Reply-To: <CAOLZvyGujvpnCFxe7x82Y91kRRNM1-P165jMXXWryFqY3g-RXw@mail.gmail.com>

The various devm_ functions allocate memory that is released when a driver
detaches.  This patch uses these functions for data that is allocated in
the probe function of a platform device and is only freed in the remove
function.

In au1100fb.c, the probe function now returns -ENODEV on failure.

Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>

---
In the case of au1200fb.c, should the error-handling code under the new
call to dma_alloc_noncoherent jump to failed, like the other error handling
code?  I was not sure that there was actually anything for failed to do at
this point in the function.

Added return of -ENODEV.

  drivers/video/au1100fb.c |   32 ++++++++++++--------------------
  drivers/video/au1200fb.c |    9 +--------
  2 files changed, 13 insertions(+), 28 deletions(-)

diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 04e4479..3e9a773 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1724,7 +1724,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
  		/* Allocate the framebuffer to the maximum screen size */
  		fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;

-		fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev,
+		fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev,
  				PAGE_ALIGN(fbdev->fb_len),
  				&fbdev->fb_phys, GFP_KERNEL);
  		if (!fbdev->fb_mem) {
@@ -1788,9 +1788,6 @@ static int __devinit 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->dev, PAGE_ALIGN(fbdev->fb_len),
-				fbdev->fb_mem, fbdev->fb_phys);
  	if (fbi) {
  		if (fbi->cmap.len != 0)
  			fb_dealloc_cmap(&fbi->cmap);
@@ -1817,10 +1814,6 @@ static int __devexit au1200fb_drv_remove(struct platform_device *dev)

  		/* Clean up all probe data */
  		unregister_framebuffer(fbi);
-		if (fbdev->fb_mem)
-			dma_free_noncoherent(&dev->dev,
-					PAGE_ALIGN(fbdev->fb_len),
-					fbdev->fb_mem, fbdev->fb_phys);
  		if (fbi->cmap.len != 0)
  			fb_dealloc_cmap(&fbi->cmap);
  		kfree(fbi->pseudo_palette);
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index de9da67..befcbd8 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -477,7 +477,8 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
  	u32 sys_clksrc;

  	/* Allocate new device private */
-	fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL);
+	fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device),
+			     GFP_KERNEL);
  	if (!fbdev) {
  		print_err("fail to allocate device private record");
  		return -ENOMEM;
@@ -498,8 +499,9 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
  	au1100fb_fix.mmio_start = regs_res->start;
  	au1100fb_fix.mmio_len = resource_size(regs_res);

-	if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len,
-				DRIVER_NAME)) {
+	if (!devm_request_mem_region(au1100fb_fix.mmio_start,
+				     au1100fb_fix.mmio_len,
+				     DRIVER_NAME)) {
  		print_err("fail to lock memory region at 0x%08lx",
  				au1100fb_fix.mmio_start);
  		return -EBUSY;
@@ -514,8 +516,9 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
  	fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
  		  	(fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;

-	fbdev->fb_mem = dma_alloc_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
-					&fbdev->fb_phys, GFP_KERNEL);
+	fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev,
+					    PAGE_ALIGN(fbdev->fb_len),
+					    &fbdev->fb_phys, GFP_KERNEL);
  	if (!fbdev->fb_mem) {
  		print_err("fail to allocate frambuffer (size: %dK))",
  			  fbdev->fb_len / 1024);
@@ -557,14 +560,14 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
  	fbdev->info.fbops = &au1100fb_ops;
  	fbdev->info.fix = au1100fb_fix;

-	if (!(fbdev->info.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL))) {
+	fbdev->info.pseudo_palette +		devm_kzalloc(&dev->dev, sizeof(u32) * 16, GFP_KERNEL);
+	if (!fbdev->info.pseudo_palette)
  		return -ENOMEM;
-	}

  	if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
  		print_err("Fail to allocate colormap (%d entries)",
  			   AU1100_LCD_NBR_PALETTE_ENTRIES);
-		kfree(fbdev->info.pseudo_palette);
  		return -EFAULT;
  	}

@@ -582,9 +585,6 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
  	return 0;

  failed:
-	if (fbdev->regs) {
-		release_mem_region(fbdev->regs_phys, fbdev->regs_len);
-	}
  	if (fbdev->fb_mem) {
  		dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem,
  				     fbdev->fb_phys);
@@ -592,10 +592,9 @@ failed:
  	if (fbdev->info.cmap.len != 0) {
  		fb_dealloc_cmap(&fbdev->info.cmap);
  	}
-	kfree(fbdev);
  	platform_set_drvdata(dev, NULL);

-	return 0;
+	return -ENODEV;
  }

  int au1100fb_drv_remove(struct platform_device *dev)
@@ -615,14 +614,7 @@ int au1100fb_drv_remove(struct platform_device *dev)
  	/* Clean up all probe data */
  	unregister_framebuffer(&fbdev->info);

-	release_mem_region(fbdev->regs_phys, fbdev->regs_len);
-
-	dma_free_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem,
-			  fbdev->fb_phys);
-
  	fb_dealloc_cmap(&fbdev->info.cmap);
-	kfree(fbdev->info.pseudo_palette);
-	kfree((void*)fbdev);

  	return 0;
  }

^ permalink raw reply related

* Re: udlfb: remove sysfs framebuffer device with USB .disconnect()
From: Kay Sievers @ 2012-01-21 14:32 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1327090686.1555.2.camel@mop>

On Sat, 2012-01-21 at 14:13 +0000, Florian Tobias Schandinat wrote:
> On 01/21/2012 01:57 PM, Kay Sievers wrote:

> > That's true. If one calls the current _unregister() *before* calling
> > _unlink(), the _unlink() is a NOP. But that's intentional.
> 
> I don't think you got me right. My complaint was that after your patch
> do_unregister_framebuffer itself calls unlink_framebuffer _after_ it set
> registered_fb[i] = NULL;
> So for any framebuffer that does not call unlink_framebuffer directly the line
> device_destroy(fb_class, MKDEV(FB_MAJOR, i));
> will no longer be executed. Do you agree?

Yes, I absolutely agree. :)

Thanks,
Kay


From: Kay Sievers <kay.sievers@vrfy.org>
Subject: udlfb: remove sysfs framebuffer device with USB .disconnect()

The USB graphics card driver delays the unregistering of the framebuffer
device to a workqueue, which breaks the userspace visible remove uevent
sequence. Recent userspace tools started to support USB graphics card
hotplug out-of-the-box and rely on proper events sent by the kernel.

The framebuffer device is a direct child of the USB interface which is
removed immediately after the USB .disconnect() callback. But the fb device
in /sys stays around until its final cleanup, at a time where all the parent
devices have been removed already.

To work around that, we remove the sysfs fb device directly in the USB
.disconnect() callback and leave only the cleanup of the internal fb
data to the delayed work.

Before:
 add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
 add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
 add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb0 (graphics)
 remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
 remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
 remove   /2-1.2:1.0/graphics/fb0 (graphics)

After:
 add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
 add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
 add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics)
 remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics)
 remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
 remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)

Cc: stable@vger.kernel.org
Tested-By: Bernie Thompson <bernie@plugable.com>
Acked-By: Bernie Thompson <bernie@plugable.com>
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
---
 drivers/video/fbmem.c |   18 +++++++++++++++++-
 drivers/video/udlfb.c |    2 +-
 include/linux/fb.h    |    1 +
 3 files changed, 19 insertions(+), 2 deletions(-)

--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1665,6 +1665,7 @@ static int do_unregister_framebuffer(str
 	if (ret)
 		return -EINVAL;
 
+	unlink_framebuffer(fb_info);
 	if (fb_info->pixmap.addr &&
 	    (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
 		kfree(fb_info->pixmap.addr);
@@ -1672,7 +1673,6 @@ static int do_unregister_framebuffer(str
 	registered_fb[i] = NULL;
 	num_registered_fb--;
 	fb_cleanup_device(fb_info);
-	device_destroy(fb_class, MKDEV(FB_MAJOR, i));
 	event.info = fb_info;
 	fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
 
@@ -1681,6 +1681,22 @@ static int do_unregister_framebuffer(str
 	return 0;
 }
 
+int unlink_framebuffer(struct fb_info *fb_info)
+{
+	int i;
+
+	i = fb_info->node;
+	if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
+		return -EINVAL;
+
+	if (fb_info->dev) {
+		device_destroy(fb_class, MKDEV(FB_MAJOR, i));
+		fb_info->dev = NULL;
+	}
+	return 0;
+}
+EXPORT_SYMBOL(unlink_framebuffer);
+
 void remove_conflicting_framebuffers(struct apertures_struct *a,
 				     const char *name, bool primary)
 {
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -1739,7 +1739,7 @@ static void dlfb_usb_disconnect(struct u
 	for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
 		device_remove_file(info->dev, &fb_device_attrs[i]);
 	device_remove_bin_file(info->dev, &edid_attr);
-
+	unlink_framebuffer(info);
 	usb_set_intfdata(interface, NULL);
 
 	/* if clients still have us open, will be freed on last close */
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -1003,6 +1003,7 @@ extern ssize_t fb_sys_write(struct fb_in
 /* drivers/video/fbmem.c */
 extern int register_framebuffer(struct fb_info *fb_info);
 extern int unregister_framebuffer(struct fb_info *fb_info);
+extern int unlink_framebuffer(struct fb_info *fb_info);
 extern void remove_conflicting_framebuffers(struct apertures_struct *a,
 				const char *name, bool primary);
 extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);



^ permalink raw reply

* Re: udlfb: remove sysfs framebuffer device with USB .disconnect()
From: Florian Tobias Schandinat @ 2012-01-21 14:13 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1327090686.1555.2.camel@mop>

On 01/21/2012 01:57 PM, Kay Sievers wrote:
> On Sat, Jan 21, 2012 at 14:44, Florian Tobias Schandinat
> <FlorianSchandinat@gmx.de> wrote:
>> On 01/20/2012 08:18 PM, Kay Sievers wrote:
> 
>>> +++ b/drivers/video/fbmem.c
>>> @@ -1672,7 +1672,7 @@ static int do_unregister_framebuffer(str
>>>       registered_fb[i] = NULL;
>>
>> Here registered_fb[fb_info->node] is set to NULL...
> 
>>> +int unlink_framebuffer(struct fb_info *fb_info)
>>> +{
>>> +     int i;
>>> +
>>> +     i = fb_info->node;
>>> +     if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
>>> +             return -EINVAL;
>>
>> ...and here you check whether it is still valid (did you copy the check from the
>> do_unregister_framebuffer?). So the code below would be never executed, when
>> called in this context.
> 
> That's true. If one calls the current _unregister() *before* calling
> _unlink(), the _unlink() is a NOP. But that's intentional.

I don't think you got me right. My complaint was that after your patch
do_unregister_framebuffer itself calls unlink_framebuffer _after_ it set
registered_fb[i] = NULL;
So for any framebuffer that does not call unlink_framebuffer directly the line
device_destroy(fb_class, MKDEV(FB_MAJOR, i));
will no longer be executed. Do you agree?


Best regards,

Florian Tobias Schandinat

> 
> The _unlink() is only needed for stuff needs to be called when we are
> required to 'orphan' the device before cleaning up. Normal,
> non-hotpluggable devices do not need this, they can continue what they
> do today.
> 
> The _unlink() call *can* be called before _unregister() if needed for
> disconnecting it from the driver core parent and remove its userspace
> visibility. If _unlink() is called before _unregister(), it passes the
> check, the later _unregister() will also pass the check but get rid of
> the entire device.
> 
> Kay
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" 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 0/4] use devm_ functions
From: Florian Tobias Schandinat @ 2012-01-21 14:02 UTC (permalink / raw)
  To: Julia Lawall, Andrew Morton; +Cc: kernel-janitors, linux-fbdev, linux-kernel
In-Reply-To: <1327094732-9050-1-git-send-email-Julia.Lawall@lip6.fr>

Hi Andrew,

can you please take care of the backlight patches (1, 3, 4) of this series?


Thank you,

Florian Tobias Schandinat


On 01/20/2012 09:25 PM, Julia Lawall wrote:
> The semantic patch (http://coccinelle.lip6.fr/) used in generating this
> patch is as follows.  Some manual cleanup was required.
> 
> // requires -in_place
> virtual after_start
> virtual returned
> virtual arg
> virtual get
> 
> virtual drop_labels
> 
> // ---------------------------------------------------------------------
> // find functions
> 
> @plat depends on !after_start@
> identifier i,pfn,rfn;
> position p;
> @@
> 
> struct platform_driver i@p = {
>   .probe = pfn,
>   .remove = (<+...rfn...+>),
> };
> 
> // ---------------------------------------------------------------------
> // set up iteration
> 
> @initialize:ocaml@
> 
> let drop_labels = ref false
> 
> type ret = UseReturned | UseReturned2 of string | UseArg | UseGet
> 
> let add pfn rfn alloc free devm_alloc file rule >    let it = new iteration() in
>    it#set_files [file];
>    it#add_virtual_rule After_start;
>    (if !drop_labels then it#add_virtual_rule Drop_labels);
>    (match rule with
>       UseReturned -> it#add_virtual_rule Returned
>     | UseReturned2(free) -> it#add_virtual_rule Returned;
>       it#add_virtual_identifier Second_free free
>     | UseArg -> it#add_virtual_rule Arg
>     | UseGet -> it#add_virtual_rule Get);
>    it#add_virtual_identifier Pfn pfn;
>    it#add_virtual_identifier Rfn rfn;
>    it#add_virtual_identifier Alloc alloc;
>    it#add_virtual_identifier Free free;
>    it#add_virtual_identifier Devm_alloc devm_alloc;
>    it#register()
> 
> @script:ocaml depends on drop_labels@
> @@
> 
> drop_labels := true
> 
> @script:ocaml@
> pfn << plat.pfn;
> rfn << plat.rfn;
> p << plat.p;
> @@
> 
> let file = (List.hd p).file in
> add pfn rfn "kmalloc" "kfree" "devm_kzalloc" file UseReturned;
> add pfn rfn "kzalloc" "kfree" "devm_kzalloc" file UseReturned;
> add pfn rfn "ioremap" "iounmap" "devm_ioremap" file UseReturned;
> add pfn rfn "ioremap_nocache" "iounmap" "devm_ioremap_nocache" file
>    UseReturned;
> 
> add pfn rfn "request_irq" "free_irq" "devm_request_irq" file UseArg;
> add pfn rfn "request_threaded_irq" "free_irq" "devm_request_threaded_irq" file
>   UseArg;
> add pfn rfn "dma_alloc_coherent" "dma_free_coherent" "dmam_alloc_coherent"
>   file UseArg;
> add pfn rfn "dma_alloc_noncoherent" "dma_free_noncoherent"
>   "dmam_alloc_noncoherent" file UseArg;
> 
> (* several possibilities... *)
> add pfn rfn "request_region" "release_region" "devm_request_region" file
>   UseGet;
> add pfn rfn "request_mem_region" "release_mem_region"
>   "devm_request_mem_region" file UseGet;
> add pfn rfn "request_region" "release_region" "devm_request_region" file
>   UseArg;
> add pfn rfn "request_mem_region" "release_mem_region"
>   "devm_request_mem_region" file UseArg;
> (* fix a bug at the same time *)
> add pfn rfn "request_region" "release_resource" "devm_request_region" file
>   (UseReturned2("kfree"));
> add pfn rfn "request_mem_region" "release_resource"
>   "devm_request_mem_region" file (UseReturned2("kfree"));
> add pfn rfn "ioport_map" "ioport_unmap" "devm_ioport_map" file UseReturned
> 
> // ---------------------------------------------------------------------
> // transform functions where free uses the result
> 
> @prb depends on returned exists@
> identifier virtual.pfn,pdev,virtual.alloc,virtual.free,virtual.second_free;
> expression x;
> expression list args;
> position p1,p2,p3;
> type T1,T2,T3;
> @@
> 
> pfn(struct platform_device *pdev) { ... when any
> x = (T1)alloc@p1(args)
> <... when strict
>      when any
>      when forall
> (
> free@p2((T2)x,...);
> ... when != x
> second_free@p3((T3)x,...);
> |
> free@p2((T2)x,...);
> )
> ...>
> }
> 
> @reme exists@
> identifier virtual.rfn,virtual.free;
> expression prb.x;
> type T;
> @@
> 
> rfn(...) { ... free((T)x,...); ... }
> 
> @rem depends on reme@
> identifier virtual.rfn,virtual.free,virtual.second_free;
> expression prb.x;
> position p4,p5;
> type T,T1;
> @@
> 
> rfn(...) {
> <... when strict
> (
> free@p4((T)x,...);
> ... when != x
> second_free@p5((T1)x,...);
> |
> free@p4((T)x,...);
> )
> ...>
> }
> 
> @bad@
> identifier virtual.free;
> expression prb.x;
> position p != {prb.p2,rem.p4};
> type T;
> @@
> 
> free@p((T)x,...)
> 
> @modif depends on rem && !bad@
> expression x;
> identifier prb.pdev,virtual.alloc,virtual.free,virtual.devm_alloc;
> identifier virtual.second_free;
> expression list args;
> position prb.p1,prb.p2,prb.p3,rem.p4,rem.p5;
> type T;
> @@
> 
> (
> - free@p2(...);
> |
> - second_free@p3(...);
> |
> - free@p4(...);
> |
> - second_free@p5(...);
> |
>   x > - alloc@p1(
> + devm_alloc(&pdev->dev,
>     args)
> |
>   x = 
> - (T)alloc@p1(
> + (T)devm_alloc(&pdev->dev,
>     args)
> )
> 
> // ---------------------------------------------------------------------
> // transform functions where free uses the first argument
> 
> @prbx depends on arg exists@
> identifier virtual.pfn,pdev,virtual.alloc,virtual.free;
> expression x;
> expression list args;
> position p1,p2;
> @@
> 
> pfn(struct platform_device *pdev) { ... when any
> alloc@p1(x,args)
> <... when strict
>      when any
>      when forall
> free@p2(x,...)
> ...>
> }
> 
> @remxe exists@
> identifier virtual.rfn, virtual.free;
> expression prbx.x;
> @@
> 
> rfn(...) { ... free(x,...); ... }
> 
> @remx depends on remxe@
> identifier virtual.rfn, virtual.free;
> expression prbx.x;
> position p3;
> @@
> 
> rfn(...) {
> <... when strict
> free@p3(x,...)
> ...>
> }
> 
> @badx@
> identifier virtual.free;
> expression prbx.x;
> position p != {prbx.p2,remx.p3};
> @@
> 
> free@p(x,...)
> 
> @modifx depends on remx && !badx@
> expression x;
> identifier prbx.pdev,virtual.alloc,virtual.free,virtual.devm_alloc;
> expression list args;
> position prbx.p1,prbx.p2,remx.p3;
> @@
> 
> (
> - free@p2(...);
> |
> - free@p3(...);
> |
> - alloc@p1(
> + devm_alloc(&pdev->dev,
>    x,args)
> )
> 
> // ---------------------------------------------------------------------
> // transform functions where free uses the result of platform_get_resource
> 
> @prbg depends on get exists@
> identifier virtual.pfn,pdev,virtual.alloc,virtual.free;
> expression x;
> expression list args;
> position p1,p2;
> @@
> 
> pfn(struct platform_device *pdev) { ... when any
> alloc@p1(x,args)
> <... when strict
>      when any
>      when forall
> free@p2(x,...)
> ...>
> }
> 
> @remge exists@
> identifier virtual.rfn, virtual.free;
> identifier y;
> identifier pdev;
> @@
> 
> rfn(struct platform_device *pdev) { ... when any
> y = platform_get_resource(pdev, IORESOURCE_MEM, 0)
> ...
> free(y->start,...)
> ...
> }
> 
> @remg depends on remge@
> identifier virtual.rfn, virtual.free;
> identifier y;
> identifier pdev;
> position p3;
> @@
> 
> rfn(struct platform_device *pdev) {
> <... when strict
> y = platform_get_resource(pdev, IORESOURCE_MEM, 0)
> ... when strict
> free@p3(y->start,...)
> ...>
> }
> 
> @badg@
> identifier virtual.free;
> position p != {prbg.p2,remg.p3};
> @@
> 
> free@p(...)
> 
> @modifg depends on remg && !badg@
> expression x;
> identifier prbg.pdev,virtual.alloc,virtual.free,virtual.devm_alloc;
> expression list args;
> position prbg.p1,prbg.p2,remg.p3;
> @@
> 
> (
> - free@p2(...);
> |
> - free@p3(...);
> |
> - alloc@p1(
> + devm_alloc(&pdev->dev,
>    x,args)
> )
> 
> // ---------------------------------------------------------------------
> // cleanup, if the drvdata was only used to enable the free
> // probably only relevant for kmalloc/kzalloc
> 
> @dclean depends on modif || modifx || modifg@
> identifier virtual.rfn, pdev, i;
> type T;
> @@
> 
> rfn(struct platform_device *pdev) { ...
> (
> - T i = platform_get_drvdata(pdev);
> |
> - T i = dev_get_drvdata(&pdev->drv);
> |
> - T i;
>   ... when != i
> (
> - i = platform_get_drvdata(pdev);
> |
> - i = dev_get_drvdata(&pdev->drv);
> )
> )
> ... when != i
> }
> 
> @rclean depends on modif || modifx || modifg@
> identifier virtual.rfn, pdev, i;
> type T;
> @@
> 
> rfn(struct platform_device *pdev) { ...
> (
> - T i = platform_get_resource(pdev,...);
> |
> - T i;
>   ... when != i
> - i = platform_get_resource(pdev,...);
> )
> ... when != i
> }
> 
> // ---------------------------------------------------------------------
> // cleanup empty ifs, etc
> 
> @depends on modif || modifx || modifg@
> identifier virtual.pfn;
> @@
> 
> pfn(...) { <...
> - if (...) {}
> ...> }
> 
> @depends on modif || modifx || modifg@
> identifier virtual.rfn;
> @@
> 
> rfn(...) { <...
> - if (...) {}
> ...> }
> 
> @depends on modif || modifx || modifg@
> identifier virtual.pfn;
> expression ret,e;
> @@
> 
> pfn(...) { <...
> + return
> - ret >  e;
> - return ret;
> ...> }
> 
> @depends on modif || modifx || modifg@
> identifier virtual.rfn;
> expression ret,e;
> @@
> 
> rfn(...) { <...
> + return
> - ret >  e;
> - return ret;
> ...> }
> 
> // ---------------------------------------------------------------------
> 
> // this is likely to leave dead code, if l: is preceded by a return
> // because we are control-flow based, there is no way to match on that
> @r depends on drop_labels && (modif || modifx || modifg)@
> identifier l,l1,l2;
> expression e;
> statement S;
> identifier virtual.pfn;
> identifier i;
> statement S1,S2;
> @@
> 
> pfn(...) { <...
> (
> - goto l;
> + goto l2;
> ...
> -l:
> <... when != S
>      when any
> l1:
> ...>
> l2:
> (
>  (<+...i...+>);
> |
>  if (...) S1 else S2
> |
>  while (...) S1
> |
>  for (...;...;...) S1
> )
> |
> - goto l;
> + return e;
> ...
> -l:
> <... when != S
>      when any
> l1:
> ...>
> return e;
> )
> ...> }
> 
> 


^ permalink raw reply

* Re: [PATCH 2/4] drivers/video/au*fb.c: use devm_ functions
From: Manuel Lauss @ 2012-01-21 14:00 UTC (permalink / raw)
  To: Florian Tobias Schandinat
  Cc: Julia Lawall, kernel-janitors, linux-fbdev, LKML
In-Reply-To: <4F1AC33E.90405@gmx.de>

Hello,

On Sat, Jan 21, 2012 at 2:53 PM, Florian Tobias Schandinat
<FlorianSchandinat@gmx.de> wrote:
> [CC'ing Manuel Lauss as he knows those drivers better than I do]
>
> On 01/20/2012 09:25 PM, Julia Lawall wrote:
>> From: Julia Lawall <Julia.Lawall@lip6.fr>
>>
>> The various devm_ functions allocate memory that is released when a driver
>> detaches.  This patch uses these functions for data that is allocated in
>> the probe function of a platform device and is only freed in the remove
>> function.
>>
>> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
>>
>> ---
>> In the case of au1100fb.c, should the failed label return something other
>> than 0?
>> In the case of au1200fb.c, should the error-handling code under the new
>> call to dma_alloc_noncoherent jump to failed, like the other error handling
>> code?  I was not sure that there was actually anything for failed to do at
>> this point in the function.
>
> Maybe Manuel is able to answer these questions. I've queued this patch and if he
> doesn't respond I'll apply it after some time.

au1100fb:  Yes, a -ENODEV instead of 0 in the error case is probably a
good idea.
au1200fb:  The error path(s) are buggy; they don't free all windows if
creation of
                      the 4th fails for example. It has been this way
since the driver appeared
                      but for all current use cases (demoboards and in
the field) it actually works.
                      I'm working on a rewrite which is however
progressing rather slowly.


>>  drivers/video/au1100fb.c |   30 +++++++++++-------------------
>>  drivers/video/au1200fb.c |    9 +--------
>>  2 files changed, 12 insertions(+), 27 deletions(-)

Acked-by: Manuel Lauss <manuel.lauss@googlemail.com>

[...]

Thanks!
      Manuel Lauss

^ permalink raw reply

* Re: udlfb: remove sysfs framebuffer device with USB .disconnect()
From: Kay Sievers @ 2012-01-21 13:57 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1327090686.1555.2.camel@mop>

On Sat, Jan 21, 2012 at 14:44, Florian Tobias Schandinat
<FlorianSchandinat@gmx.de> wrote:
> On 01/20/2012 08:18 PM, Kay Sievers wrote:

>> +++ b/drivers/video/fbmem.c
>> @@ -1672,7 +1672,7 @@ static int do_unregister_framebuffer(str
>>       registered_fb[i] = NULL;
>
> Here registered_fb[fb_info->node] is set to NULL...

>> +int unlink_framebuffer(struct fb_info *fb_info)
>> +{
>> +     int i;
>> +
>> +     i = fb_info->node;
>> +     if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
>> +             return -EINVAL;
>
> ...and here you check whether it is still valid (did you copy the check from the
> do_unregister_framebuffer?). So the code below would be never executed, when
> called in this context.

That's true. If one calls the current _unregister() *before* calling
_unlink(), the _unlink() is a NOP. But that's intentional.

The _unlink() is only needed for stuff needs to be called when we are
required to 'orphan' the device before cleaning up. Normal,
non-hotpluggable devices do not need this, they can continue what they
do today.

The _unlink() call *can* be called before _unregister() if needed for
disconnecting it from the driver core parent and remove its userspace
visibility. If _unlink() is called before _unregister(), it passes the
check, the later _unregister() will also pass the check but get rid of
the entire device.

Kay

^ permalink raw reply

* Re: [PATCH 2/4] drivers/video/au*fb.c: use devm_ functions
From: Florian Tobias Schandinat @ 2012-01-21 13:53 UTC (permalink / raw)
  To: Julia Lawall; +Cc: kernel-janitors, linux-fbdev, LKML, Manuel Lauss
In-Reply-To: <1327094732-9050-3-git-send-email-Julia.Lawall@lip6.fr>

[CC'ing Manuel Lauss as he knows those drivers better than I do]

On 01/20/2012 09:25 PM, Julia Lawall wrote:
> From: Julia Lawall <Julia.Lawall@lip6.fr>
> 
> The various devm_ functions allocate memory that is released when a driver
> detaches.  This patch uses these functions for data that is allocated in
> the probe function of a platform device and is only freed in the remove
> function.
> 
> Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
> 
> ---
> In the case of au1100fb.c, should the failed label return something other
> than 0?
> In the case of au1200fb.c, should the error-handling code under the new
> call to dma_alloc_noncoherent jump to failed, like the other error handling
> code?  I was not sure that there was actually anything for failed to do at
> this point in the function.

Maybe Manuel is able to answer these questions. I've queued this patch and if he
doesn't respond I'll apply it after some time.


Best regards,

Florian Tobias Schandinat

> 
>  drivers/video/au1100fb.c |   30 +++++++++++-------------------
>  drivers/video/au1200fb.c |    9 +--------
>  2 files changed, 12 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
> index de9da67..8f7b7d7 100644
> --- a/drivers/video/au1100fb.c
> +++ b/drivers/video/au1100fb.c
> @@ -477,7 +477,8 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
>  	u32 sys_clksrc;
>  
>  	/* Allocate new device private */
> -	fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL);
> +	fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device),
> +			     GFP_KERNEL);
>  	if (!fbdev) {
>  		print_err("fail to allocate device private record");
>  		return -ENOMEM;
> @@ -498,8 +499,9 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
>  	au1100fb_fix.mmio_start = regs_res->start;
>  	au1100fb_fix.mmio_len = resource_size(regs_res);
>  
> -	if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len,
> -				DRIVER_NAME)) {
> +	if (!devm_request_mem_region(au1100fb_fix.mmio_start,
> +				     au1100fb_fix.mmio_len,
> +				     DRIVER_NAME)) {
>  		print_err("fail to lock memory region at 0x%08lx",
>  				au1100fb_fix.mmio_start);
>  		return -EBUSY;
> @@ -514,8 +516,9 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
>  	fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres *
>  		  	(fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS;
>  
> -	fbdev->fb_mem = dma_alloc_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len),
> -					&fbdev->fb_phys, GFP_KERNEL);
> +	fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev,
> +					    PAGE_ALIGN(fbdev->fb_len),
> +					    &fbdev->fb_phys, GFP_KERNEL);
>  	if (!fbdev->fb_mem) {
>  		print_err("fail to allocate frambuffer (size: %dK))",
>  			  fbdev->fb_len / 1024);
> @@ -557,14 +560,14 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
>  	fbdev->info.fbops = &au1100fb_ops;
>  	fbdev->info.fix = au1100fb_fix;
>  
> -	if (!(fbdev->info.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL))) {
> +	fbdev->info.pseudo_palette > +		devm_kzalloc(&dev->dev, sizeof(u32) * 16, GFP_KERNEL);
> +	if (!fbdev->info.pseudo_palette)
>  		return -ENOMEM;
> -	}
>  
>  	if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
>  		print_err("Fail to allocate colormap (%d entries)",
>  			   AU1100_LCD_NBR_PALETTE_ENTRIES);
> -		kfree(fbdev->info.pseudo_palette);
>  		return -EFAULT;
>  	}
>  
> @@ -582,9 +585,6 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev)
>  	return 0;
>  
>  failed:
> -	if (fbdev->regs) {
> -		release_mem_region(fbdev->regs_phys, fbdev->regs_len);
> -	}
>  	if (fbdev->fb_mem) {
>  		dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem,
>  				     fbdev->fb_phys);
> @@ -592,7 +592,6 @@ failed:
>  	if (fbdev->info.cmap.len != 0) {
>  		fb_dealloc_cmap(&fbdev->info.cmap);
>  	}
> -	kfree(fbdev);
>  	platform_set_drvdata(dev, NULL);
>  
>  	return 0;
> @@ -615,14 +614,7 @@ int au1100fb_drv_remove(struct platform_device *dev)
>  	/* Clean up all probe data */
>  	unregister_framebuffer(&fbdev->info);
>  
> -	release_mem_region(fbdev->regs_phys, fbdev->regs_len);
> -
> -	dma_free_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem,
> -			  fbdev->fb_phys);
> -
>  	fb_dealloc_cmap(&fbdev->info.cmap);
> -	kfree(fbdev->info.pseudo_palette);
> -	kfree((void*)fbdev);
>  
>  	return 0;
>  }
> diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
> index 04e4479..3e9a773 100644
> --- a/drivers/video/au1200fb.c
> +++ b/drivers/video/au1200fb.c
> @@ -1724,7 +1724,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
>  		/* Allocate the framebuffer to the maximum screen size */
>  		fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
>  
> -		fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev,
> +		fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev,
>  				PAGE_ALIGN(fbdev->fb_len),
>  				&fbdev->fb_phys, GFP_KERNEL);
>  		if (!fbdev->fb_mem) {
> @@ -1788,9 +1788,6 @@ static int __devinit 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->dev, PAGE_ALIGN(fbdev->fb_len),
> -				fbdev->fb_mem, fbdev->fb_phys);
>  	if (fbi) {
>  		if (fbi->cmap.len != 0)
>  			fb_dealloc_cmap(&fbi->cmap);
> @@ -1817,10 +1814,6 @@ static int __devexit au1200fb_drv_remove(struct platform_device *dev)
>  
>  		/* Clean up all probe data */
>  		unregister_framebuffer(fbi);
> -		if (fbdev->fb_mem)
> -			dma_free_noncoherent(&dev->dev,
> -					PAGE_ALIGN(fbdev->fb_len),
> -					fbdev->fb_mem, fbdev->fb_phys);
>  		if (fbi->cmap.len != 0)
>  			fb_dealloc_cmap(&fbi->cmap);
>  		kfree(fbi->pseudo_palette);
> 


^ permalink raw reply

* Re: udlfb: remove sysfs framebuffer device with USB .disconnect()
From: Florian Tobias Schandinat @ 2012-01-21 13:44 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1327090686.1555.2.camel@mop>

Hi Kay,

On 01/20/2012 08:18 PM, Kay Sievers wrote:
> From: Kay Sievers <kay.sievers@vrfy.org>
> Subject: udlfb: remove sysfs framebuffer device with USB .disconnect()
> 
> The USB graphics card driver delays the unregistering of the framebuffer
> device to a workqueue, which breaks the userspace visible remove uevent
> sequence. Recent userspace tools started to support USB graphics card
> hotplug out-of-the-box and rely on proper events sent by the kernel.
> 
> The framebuffer device is a direct child of the USB interface which is
> removed immediately after the USB .disconnect() callback. But the fb device
> in /sys stays around until its final cleanup, at a time where all the parent
> devices have been removed already.
> 
> To work around that, we remove the sysfs fb device directly in the USB
> .disconnect() callback and leave only the cleanup of the internal fb
> data to the delayed work.
> 
> Before:
>   add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
>   add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
>   add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb0 (graphics)
>   remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
>   remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
>   remove   /2-1.2:1.0/graphics/fb0 (graphics)
> 
> After:
>   add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
>   add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
>   add      /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics)
>   remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics)
>   remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb)
>   remove   /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb)
> 
> Cc: stable@vger.kernel.org
> Tested-By: Bernie Thompson <bernie@plugable.com>
> Acked-By: Bernie Thompson <bernie@plugable.com>
> Signed-off-by: Kay Sievers <kay.sievers@vrfy.org>
> ---
>  drivers/video/fbmem.c |   18 +++++++++++++++++-
>  drivers/video/udlfb.c |    2 +-
>  include/linux/fb.h    |    1 +
>  3 files changed, 19 insertions(+), 2 deletions(-)
> 
> --- a/drivers/video/fbmem.c
> +++ b/drivers/video/fbmem.c
> @@ -1672,7 +1672,7 @@ static int do_unregister_framebuffer(str
>  	registered_fb[i] = NULL;

Here registered_fb[fb_info->node] is set to NULL...

>  	num_registered_fb--;
>  	fb_cleanup_device(fb_info);
> -	device_destroy(fb_class, MKDEV(FB_MAJOR, i));
> +	unlink_framebuffer(fb_info);
>  	event.info = fb_info;
>  	fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
>  
> @@ -1681,6 +1681,22 @@ static int do_unregister_framebuffer(str
>  	return 0;
>  }
>  
> +int unlink_framebuffer(struct fb_info *fb_info)
> +{
> +	int i;
> +
> +	i = fb_info->node;
> +	if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
> +		return -EINVAL;

...and here you check whether it is still valid (did you copy the check from the
do_unregister_framebuffer?). So the code below would be never executed, when
called in this context.

> +
> +	if (fb_info->dev) {
> +		device_destroy(fb_class, MKDEV(FB_MAJOR, i));
> +		fb_info->dev = NULL;
> +	}
> +	return 0;
> +}
> +EXPORT_SYMBOL(unlink_framebuffer);
> +
>  void remove_conflicting_framebuffers(struct apertures_struct *a,
>  				     const char *name, bool primary)
>  {
> --- a/drivers/video/udlfb.c
> +++ b/drivers/video/udlfb.c
> @@ -1739,7 +1739,7 @@ static void dlfb_usb_disconnect(struct u
>  	for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
>  		device_remove_file(info->dev, &fb_device_attrs[i]);
>  	device_remove_bin_file(info->dev, &edid_attr);
> -
> +	unlink_framebuffer(info);
>  	usb_set_intfdata(interface, NULL);
>  
>  	/* if clients still have us open, will be freed on last close */
> --- a/include/linux/fb.h
> +++ b/include/linux/fb.h
> @@ -1003,6 +1003,7 @@ extern ssize_t fb_sys_write(struct fb_in
>  /* drivers/video/fbmem.c */
>  extern int register_framebuffer(struct fb_info *fb_info);
>  extern int unregister_framebuffer(struct fb_info *fb_info);
> +extern int unlink_framebuffer(struct fb_info *fb_info);
>  extern void remove_conflicting_framebuffers(struct apertures_struct *a,
>  				const char *name, bool primary);
>  extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
> 
> 
> 


Best regards,

Florian Tobias Schandinat



^ permalink raw reply

* [PATCH] video: s3c-fb: Convert to devm style allocation
From: Mark Brown @ 2012-01-21 13:11 UTC (permalink / raw)
  To: linux-fbdev

Saves some code, especially useful as the code saved is mostly in the
infrequently tested error paths.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
---

devm_request_and_ioremap() is now in Linus' tree.

 drivers/video/s3c-fb.c |   32 +++++---------------------------
 1 files changed, 5 insertions(+), 27 deletions(-)

diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 0c63b69..7c5158d 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -186,7 +186,6 @@ struct s3c_fb_vsync {
  * struct s3c_fb - overall hardware state of the hardware
  * @slock: The spinlock protection for this data sturcture.
  * @dev: The device that we bound to, for printing, etc.
- * @regs_res: The resource we claimed for the IO registers.
  * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
  * @lcd_clk: The clk (sclk) feeding pixclk.
  * @regs: The mapped hardware registers.
@@ -202,7 +201,6 @@ struct s3c_fb_vsync {
 struct s3c_fb {
 	spinlock_t		slock;
 	struct device		*dev;
-	struct resource		*regs_res;
 	struct clk		*bus_clk;
 	struct clk		*lcd_clk;
 	void __iomem		*regs;
@@ -1361,7 +1359,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL);
+	sfb = devm_kzalloc(dev, sizeof(struct s3c_fb), GFP_KERNEL);
 	if (!sfb) {
 		dev_err(dev, "no memory for framebuffers\n");
 		return -ENOMEM;
@@ -1404,33 +1402,25 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
 		goto err_lcd_clk;
 	}
 
-	sfb->regs_res = request_mem_region(res->start, resource_size(res),
-					   dev_name(dev));
-	if (!sfb->regs_res) {
-		dev_err(dev, "failed to claim register region\n");
-		ret = -ENOENT;
-		goto err_lcd_clk;
-	}
-
-	sfb->regs = ioremap(res->start, resource_size(res));
+	sfb->regs = devm_request_and_ioremap(dev, res);
 	if (!sfb->regs) {
 		dev_err(dev, "failed to map registers\n");
 		ret = -ENXIO;
-		goto err_req_region;
+		goto err_lcd_clk;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
 		dev_err(dev, "failed to acquire irq resource\n");
 		ret = -ENOENT;
-		goto err_ioremap;
+		goto err_lcd_clk;
 	}
 	sfb->irq_no = res->start;
 	ret = request_irq(sfb->irq_no, s3c_fb_irq,
 			  0, "s3c_fb", sfb);
 	if (ret) {
 		dev_err(dev, "irq request failed\n");
-		goto err_ioremap;
+		goto err_lcd_clk;
 	}
 
 	dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs);
@@ -1486,12 +1476,6 @@ err_pm_runtime:
 	pm_runtime_put_sync(sfb->dev);
 	free_irq(sfb->irq_no, sfb);
 
-err_ioremap:
-	iounmap(sfb->regs);
-
-err_req_region:
-	release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
-
 err_lcd_clk:
 	pm_runtime_disable(sfb->dev);
 
@@ -1505,7 +1489,6 @@ err_bus_clk:
 	clk_put(sfb->bus_clk);
 
 err_sfb:
-	kfree(sfb);
 	return ret;
 }
 
@@ -1529,8 +1512,6 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
 
 	free_irq(sfb->irq_no, sfb);
 
-	iounmap(sfb->regs);
-
 	if (!sfb->variant.has_clksel) {
 		clk_disable(sfb->lcd_clk);
 		clk_put(sfb->lcd_clk);
@@ -1539,12 +1520,9 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
 	clk_disable(sfb->bus_clk);
 	clk_put(sfb->bus_clk);
 
-	release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
-
 	pm_runtime_put_sync(sfb->dev);
 	pm_runtime_disable(sfb->dev);
 
-	kfree(sfb);
 	return 0;
 }
 
-- 
1.7.7.3


^ permalink raw reply related

* Re: [PATCH 1/4] drivers/video/backlight/wm831x_bl.c: use devm_ functions
From: Mark Brown @ 2012-01-21 12:33 UTC (permalink / raw)
  To: Julia Lawall
  Cc: kernel-janitors, Ian Lartey, Dimitris Papastamos, Richard Purdie,
	Florian Tobias Schandinat, linux-fbdev, linux-kernel
In-Reply-To: <1327094732-9050-2-git-send-email-Julia.Lawall@lip6.fr>

On Fri, Jan 20, 2012 at 10:25:29PM +0100, Julia Lawall wrote:
> From: Julia Lawall <Julia.Lawall@lip6.fr>
> 
> The various devm_ functions allocate memory that is released when a driver
> detaches.  This patch uses these functions for data that is allocated in
> the probe function of a platform device and is only freed in the remove
> function.

Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

^ permalink raw reply

* Re: [PATCH v7 1/2] video: support MIPI-DSI controller driver
From: Andrew Morton @ 2012-01-20 23:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4F182ACF.8010302@ti.com>

On Thu, 19 Jan 2012 20:08:07 +0530
Archit <a0393947@ti.com> wrote:

> On Thursday 19 January 2012 10:58 AM, Donghwa Lee wrote:
> > Samsung S5PC210 and EXYNOS SoC platform has MIPI-DSI controller and MIPI-DSI
> > based LCD Panel could be used with it. This patch supports MIPI-DSI driver
> > based Samsung SoC chip.
> > 
> > LCD panel driver based MIPI-DSI should be registered to MIPI-DSI driver at
> > machine code and LCD panel driver specific function registered to mipi_dsim_ddi
> > structure at lcd panel init function called system init.
> > In the MIPI-DSI driver, find lcd panel driver by using registered
> > lcd panel name, and then initialize lcd panel driver.
> > 
> > Changes since v6:
> > 	- remove obscure compile problems.
> > 	- remove useless codes.
> > 	- modify return errno codes properly
> 
> One more comment about 'mipi_dsim.h', it would be better to put it in
> include/video and not 'include/linux'.

Yes, that is desirable.

> > ---
> >   drivers/video/Kconfig                 |    6 +
> >   drivers/video/Makefile                |    2 +
> >   drivers/video/s5p_mipi_dsi.c          |  599 ++++++++++++++++++++++
> >   drivers/video/s5p_mipi_dsi_common.c   |  896 +++++++++++++++++++++++++++++++++
> >   drivers/video/s5p_mipi_dsi_common.h   |   46 ++
> >   drivers/video/s5p_mipi_dsi_lowlevel.c |  617 +++++++++++++++++++++++
> >   drivers/video/s5p_mipi_dsi_lowlevel.h |  112 ++++
> >   drivers/video/s5p_mipi_dsi_regs.h     |  149 ++++++
> >   include/linux/mipi_dsim.h             |  359 +++++++++++++
> >   9 files changed, 2786 insertions(+), 0 deletions(-)

or we could put it in drivers/video/.  It all depends on which other
drivers we expect will need access to this header.


^ permalink raw reply


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