// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Framebuffer driver for TI OMAP boards
 *
 * Copyright (C) 2004 Nokia Corporation
 * Author: Imre Deak <imre.deak@nokia.com>
 *
 * Acknowledgements:
 *   Alex McMains <aam@ridgerun.com>       - Original driver
 *   Juha Yrjola <juha.yrjola@nokia.com>   - Original driver and improvements
 *   Dirk Behme <dirk.behme@de.bosch.com>  - changes for 2.6 kernel API
 *   Texas Instruments                     - H3 support
 */
#include <linux/platform_device.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/module.h>

#include <linux/omap-dma.h>

#include <mach/hardware.h>

#include "omapfb.h"
#include "lcdc.h"

#define MODULE_NAME	"omapfb"

static unsigned int	def_accel;
static unsigned long	def_vram[OMAPFB_PLANE_NUM];
static unsigned int	def_vram_cnt;
static unsigned long	def_vxres;
static unsigned long	def_vyres;
static unsigned int	def_rotate;
static unsigned int	def_mirror;

#ifdef CONFIG_FB_OMAP_MANUAL_UPDATE
static bool		manual_update = 1;
#else
static bool		manual_update;
#endif

static struct platform_device	*fbdev_pdev;
static struct lcd_panel		*fbdev_panel;
static struct omapfb_device	*omapfb_dev;

struct caps_table_struct {
	unsigned long flag;
	const char *name;
};

static const struct caps_table_struct ctrl_caps[] = {
	{ OMAPFB_CAPS_MANUAL_UPDATE,  "manual update" },
	{ OMAPFB_CAPS_TEARSYNC,       "tearing synchronization" },
	{ OMAPFB_CAPS_PLANE_RELOCATE_MEM, "relocate plane memory" },
	{ OMAPFB_CAPS_PLANE_SCALE,    "scale plane" },
	{ OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE, "pixel double window" },
	{ OMAPFB_CAPS_WINDOW_SCALE,   "scale window" },
	{ OMAPFB_CAPS_WINDOW_OVERLAY, "overlay window" },
	{ OMAPFB_CAPS_WINDOW_ROTATE,  "rotate window" },
	{ OMAPFB_CAPS_SET_BACKLIGHT,  "backlight setting" },
};

static const struct caps_table_struct color_caps[] = {
	{ 1 << OMAPFB_COLOR_RGB565,	"RGB565", },
	{ 1 << OMAPFB_COLOR_YUV422,	"YUV422", },
	{ 1 << OMAPFB_COLOR_YUV420,	"YUV420", },
	{ 1 << OMAPFB_COLOR_CLUT_8BPP,	"CLUT8", },
	{ 1 << OMAPFB_COLOR_CLUT_4BPP,	"CLUT4", },
	{ 1 << OMAPFB_COLOR_CLUT_2BPP,	"CLUT2", },
	{ 1 << OMAPFB_COLOR_CLUT_1BPP,	"CLUT1", },
	{ 1 << OMAPFB_COLOR_RGB444,	"RGB444", },
	{ 1 << OMAPFB_COLOR_YUY422,	"YUY422", },
};

static void omapdss_release(struct device *dev)
{
}

/* dummy device for clocks */
static struct platform_device omapdss_device = {
	.name		= "omapdss_dss",
	.id		= -1,
	.dev            = {
		.release = omapdss_release,
	},
};

/*
 * ---------------------------------------------------------------------------
 * LCD panel
 * ---------------------------------------------------------------------------
 */
extern struct lcd_ctrl hwa742_ctrl;

static const struct lcd_ctrl *ctrls[] = {
	&omap1_int_ctrl,

#ifdef CONFIG_FB_OMAP_LCDC_HWA742
	&hwa742_ctrl,
#endif
};

#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
extern struct lcd_ctrl_extif omap1_ext_if;
#endif

static void omapfb_rqueue_lock(struct omapfb_device *fbdev)
{
	mutex_lock(&fbdev->rqueue_mutex);
}

static void omapfb_rqueue_unlock(struct omapfb_device *fbdev)
{
	mutex_unlock(&fbdev->rqueue_mutex);
}

/*
 * ---------------------------------------------------------------------------
 * LCD controller and LCD DMA
 * ---------------------------------------------------------------------------
 */
/*
 * Allocate resources needed for LCD controller and LCD DMA operations. Video
 * memory is allocated from system memory according to the virtual display
 * size, except if a bigger memory size is specified explicitly as a kernel
 * parameter.
 */
static int ctrl_init(struct omapfb_device *fbdev)
{
	int r;
	int i;

	/* kernel/module vram parameters override boot tags/board config */
	if (def_vram_cnt) {
		for (i = 0; i < def_vram_cnt; i++)
			fbdev->mem_desc.region[i].size =
				PAGE_ALIGN(def_vram[i]);
		fbdev->mem_desc.region_cnt = i;
	}

	if (!fbdev->mem_desc.region_cnt) {
		struct lcd_panel *panel = fbdev->panel;
		int def_size;
		int bpp = panel->bpp;

		/* 12 bpp is packed in 16 bits */
		if (bpp == 12)
			bpp = 16;
		def_size = def_vxres * def_vyres * bpp / 8;
		fbdev->mem_desc.region_cnt = 1;
		fbdev->mem_desc.region[0].size = PAGE_ALIGN(def_size);
	}
	r = fbdev->ctrl->init(fbdev, 0, &fbdev->mem_desc);
	if (r < 0) {
		dev_err(fbdev->dev, "controller initialization failed (%d)\n",
			r);
		return r;
	}

#ifdef DEBUG
	for (i = 0; i < fbdev->mem_desc.region_cnt; i++) {
		dev_dbg(fbdev->dev, "region%d phys %08x virt %p size=%lu\n",
			 i,
			 fbdev->mem_desc.region[i].paddr,
			 fbdev->mem_desc.region[i].vaddr,
			 fbdev->mem_desc.region[i].size);
	}
#endif
	return 0;
}

static void ctrl_cleanup(struct omapfb_device *fbdev)
{
	fbdev->ctrl->cleanup();
}

/* Must be called with fbdev->rqueue_mutex held. */
static int ctrl_change_mode(struct fb_info *fbi)
{
	int r;
	unsigned long offset;
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	struct fb_var_screeninfo *var = &fbi->var;

	offset = var->yoffset * fbi->fix.line_length +
		 var->xoffset * var->bits_per_pixel / 8;

	if (fbdev->ctrl->sync)
		fbdev->ctrl->sync();
	r = fbdev->ctrl->setup_plane(plane->idx, plane->info.channel_out,
				 offset, var->xres_virtual,
				 plane->info.pos_x, plane->info.pos_y,
				 var->xres, var->yres, plane->color_mode);
	if (r < 0)
		return r;

	if (fbdev->ctrl->set_rotate != NULL) {
		r = fbdev->ctrl->set_rotate(var->rotate);
		if (r < 0)
			return r;
	}

	if (fbdev->ctrl->set_scale != NULL)
		r = fbdev->ctrl->set_scale(plane->idx,
				   var->xres, var->yres,
				   plane->info.out_width,
				   plane->info.out_height);

	return r;
}

/*
 * ---------------------------------------------------------------------------
 * fbdev framework callbacks and the ioctl interface
 * ---------------------------------------------------------------------------
 */
/* Called each time the omapfb device is opened */
static int omapfb_open(struct fb_info *info, int user)
{
	return 0;
}

static void omapfb_sync(struct fb_info *info);

/* Called when the omapfb device is closed. We make sure that any pending
 * gfx DMA operations are ended, before we return. */
static int omapfb_release(struct fb_info *info, int user)
{
	omapfb_sync(info);
	return 0;
}

/* Store a single color palette entry into a pseudo palette or the hardware
 * palette if one is available. For now we support only 16bpp and thus store
 * the entry only to the pseudo palette.
 */
static int _setcolreg(struct fb_info *info, u_int regno, u_int red, u_int green,
			u_int blue, u_int transp, int update_hw_pal)
{
	struct omapfb_plane_struct *plane = info->par;
	struct omapfb_device *fbdev = plane->fbdev;
	struct fb_var_screeninfo *var = &info->var;
	int r = 0;

	switch (plane->color_mode) {
	case OMAPFB_COLOR_YUV422:
	case OMAPFB_COLOR_YUV420:
	case OMAPFB_COLOR_YUY422:
		r = -EINVAL;
		break;
	case OMAPFB_COLOR_CLUT_8BPP:
	case OMAPFB_COLOR_CLUT_4BPP:
	case OMAPFB_COLOR_CLUT_2BPP:
	case OMAPFB_COLOR_CLUT_1BPP:
		if (fbdev->ctrl->setcolreg)
			r = fbdev->ctrl->setcolreg(regno, red, green, blue,
							transp, update_hw_pal);
		/* Fallthrough */
	case OMAPFB_COLOR_RGB565:
	case OMAPFB_COLOR_RGB444:
		if (r != 0)
			break;

		if (regno < 16) {
			u16 pal;
			pal = ((red >> (16 - var->red.length)) <<
					var->red.offset) |
			      ((green >> (16 - var->green.length)) <<
					var->green.offset) |
			      (blue >> (16 - var->blue.length));
			((u32 *)(info->pseudo_palette))[regno] = pal;
		}
		break;
	default:
		BUG();
	}
	return r;
}

static int omapfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
			    u_int transp, struct fb_info *info)
{
	return _setcolreg(info, regno, red, green, blue, transp, 1);
}

static int omapfb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
{
	int count, index, r;
	u16 *red, *green, *blue, *transp;
	u16 trans = 0xffff;

	red     = cmap->red;
	green   = cmap->green;
	blue    = cmap->blue;
	transp  = cmap->transp;
	index   = cmap->start;

	for (count = 0; count < cmap->len; count++) {
		if (transp)
			trans = *transp++;
		r = _setcolreg(info, index++, *red++, *green++, *blue++, trans,
				count == cmap->len - 1);
		if (r != 0)
			return r;
	}

	return 0;
}

static int omapfb_update_full_screen(struct fb_info *fbi);

static int omapfb_blank(int blank, struct fb_info *fbi)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	int do_update = 0;
	int r = 0;

	omapfb_rqueue_lock(fbdev);
	switch (blank) {
	case FB_BLANK_UNBLANK:
		if (fbdev->state == OMAPFB_SUSPENDED) {
			if (fbdev->ctrl->resume)
				fbdev->ctrl->resume();
			if (fbdev->panel->enable)
				fbdev->panel->enable(fbdev->panel);
			fbdev->state = OMAPFB_ACTIVE;
			if (fbdev->ctrl->get_update_mode() ==
					OMAPFB_MANUAL_UPDATE)
				do_update = 1;
		}
		break;
	case FB_BLANK_POWERDOWN:
		if (fbdev->state == OMAPFB_ACTIVE) {
			if (fbdev->panel->disable)
				fbdev->panel->disable(fbdev->panel);
			if (fbdev->ctrl->suspend)
				fbdev->ctrl->suspend();
			fbdev->state = OMAPFB_SUSPENDED;
		}
		break;
	default:
		r = -EINVAL;
	}
	omapfb_rqueue_unlock(fbdev);

	if (r == 0 && do_update)
		r = omapfb_update_full_screen(fbi);

	return r;
}

static void omapfb_sync(struct fb_info *fbi)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;

	omapfb_rqueue_lock(fbdev);
	if (fbdev->ctrl->sync)
		fbdev->ctrl->sync();
	omapfb_rqueue_unlock(fbdev);
}

/*
 * Set fb_info.fix fields and also updates fbdev.
 * When calling this fb_info.var must be set up already.
 */
static void set_fb_fix(struct fb_info *fbi, int from_init)
{
	struct fb_fix_screeninfo *fix = &fbi->fix;
	struct fb_var_screeninfo *var = &fbi->var;
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_mem_region *rg;
	int bpp;

	rg = &plane->fbdev->mem_desc.region[plane->idx];
	fbi->screen_base	= rg->vaddr;

	if (!from_init) {
		mutex_lock(&fbi->mm_lock);
		fix->smem_start		= rg->paddr;
		fix->smem_len		= rg->size;
		mutex_unlock(&fbi->mm_lock);
	} else {
		fix->smem_start		= rg->paddr;
		fix->smem_len		= rg->size;
	}

	fix->type = FB_TYPE_PACKED_PIXELS;
	bpp = var->bits_per_pixel;
	if (var->nonstd)
		fix->visual = FB_VISUAL_PSEUDOCOLOR;
	else switch (var->bits_per_pixel) {
	case 16:
	case 12:
		fix->visual = FB_VISUAL_TRUECOLOR;
		/* 12bpp is stored in 16 bits */
		bpp = 16;
		break;
	case 1:
	case 2:
	case 4:
	case 8:
		fix->visual = FB_VISUAL_PSEUDOCOLOR;
		break;
	}
	fix->accel		= FB_ACCEL_OMAP1610;
	fix->line_length	= var->xres_virtual * bpp / 8;
}

static int set_color_mode(struct omapfb_plane_struct *plane,
			  struct fb_var_screeninfo *var)
{
	switch (var->nonstd) {
	case 0:
		break;
	case OMAPFB_COLOR_YUV422:
		var->bits_per_pixel = 16;
		plane->color_mode = var->nonstd;
		return 0;
	case OMAPFB_COLOR_YUV420:
		var->bits_per_pixel = 12;
		plane->color_mode = var->nonstd;
		return 0;
	case OMAPFB_COLOR_YUY422:
		var->bits_per_pixel = 16;
		plane->color_mode = var->nonstd;
		return 0;
	default:
		return -EINVAL;
	}

	switch (var->bits_per_pixel) {
	case 1:
		plane->color_mode = OMAPFB_COLOR_CLUT_1BPP;
		return 0;
	case 2:
		plane->color_mode = OMAPFB_COLOR_CLUT_2BPP;
		return 0;
	case 4:
		plane->color_mode = OMAPFB_COLOR_CLUT_4BPP;
		return 0;
	case 8:
		plane->color_mode = OMAPFB_COLOR_CLUT_8BPP;
		return 0;
	case 12:
		var->bits_per_pixel = 16;
		/* fall through */
	case 16:
		if (plane->fbdev->panel->bpp == 12)
			plane->color_mode = OMAPFB_COLOR_RGB444;
		else
			plane->color_mode = OMAPFB_COLOR_RGB565;
		return 0;
	default:
		return -EINVAL;
	}
}

/*
 * Check the values in var against our capabilities and in case of out of
 * bound values try to adjust them.
 */
static int set_fb_var(struct fb_info *fbi,
		      struct fb_var_screeninfo *var)
{
	int		bpp;
	unsigned long	max_frame_size;
	unsigned long	line_size;
	int		xres_min, xres_max;
	int		yres_min, yres_max;
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	struct lcd_panel *panel = fbdev->panel;

	if (set_color_mode(plane, var) < 0)
		return -EINVAL;

	bpp = var->bits_per_pixel;
	if (plane->color_mode == OMAPFB_COLOR_RGB444)
		bpp = 16;

	switch (var->rotate) {
	case 0:
	case 180:
		xres_min = OMAPFB_PLANE_XRES_MIN;
		xres_max = panel->x_res;
		yres_min = OMAPFB_PLANE_YRES_MIN;
		yres_max = panel->y_res;
		if (cpu_is_omap15xx()) {
			var->xres = panel->x_res;
			var->yres = panel->y_res;
		}
		break;
	case 90:
	case 270:
		xres_min = OMAPFB_PLANE_YRES_MIN;
		xres_max = panel->y_res;
		yres_min = OMAPFB_PLANE_XRES_MIN;
		yres_max = panel->x_res;
		if (cpu_is_omap15xx()) {
			var->xres = panel->y_res;
			var->yres = panel->x_res;
		}
		break;
	default:
		return -EINVAL;
	}

	if (var->xres < xres_min)
		var->xres = xres_min;
	if (var->yres < yres_min)
		var->yres = yres_min;
	if (var->xres > xres_max)
		var->xres = xres_max;
	if (var->yres > yres_max)
		var->yres = yres_max;

	if (var->xres_virtual < var->xres)
		var->xres_virtual = var->xres;
	if (var->yres_virtual < var->yres)
		var->yres_virtual = var->yres;
	max_frame_size = fbdev->mem_desc.region[plane->idx].size;
	line_size = var->xres_virtual * bpp / 8;
	if (line_size * var->yres_virtual > max_frame_size) {
		/* Try to keep yres_virtual first */
		line_size = max_frame_size / var->yres_virtual;
		var->xres_virtual = line_size * 8 / bpp;
		if (var->xres_virtual < var->xres) {
			/* Still doesn't fit. Shrink yres_virtual too */
			var->xres_virtual = var->xres;
			line_size = var->xres * bpp / 8;
			var->yres_virtual = max_frame_size / line_size;
		}
		/* Recheck this, as the virtual size changed. */
		if (var->xres_virtual < var->xres)
			var->xres = var->xres_virtual;
		if (var->yres_virtual < var->yres)
			var->yres = var->yres_virtual;
		if (var->xres < xres_min || var->yres < yres_min)
			return -EINVAL;
	}
	if (var->xres + var->xoffset > var->xres_virtual)
		var->xoffset = var->xres_virtual - var->xres;
	if (var->yres + var->yoffset > var->yres_virtual)
		var->yoffset = var->yres_virtual - var->yres;

	if (plane->color_mode == OMAPFB_COLOR_RGB444) {
		var->red.offset	  = 8; var->red.length	 = 4;
						var->red.msb_right   = 0;
		var->green.offset = 4; var->green.length = 4;
						var->green.msb_right = 0;
		var->blue.offset  = 0; var->blue.length  = 4;
						var->blue.msb_right  = 0;
	} else {
		var->red.offset	 = 11; var->red.length	 = 5;
						var->red.msb_right   = 0;
		var->green.offset = 5;  var->green.length = 6;
						var->green.msb_right = 0;
		var->blue.offset = 0;  var->blue.length  = 5;
						var->blue.msb_right  = 0;
	}

	var->height		= -1;
	var->width		= -1;
	var->grayscale		= 0;

	/* pixclock in ps, the rest in pixclock */
	var->pixclock		= 10000000 / (panel->pixel_clock / 100);
	var->left_margin	= panel->hfp;
	var->right_margin	= panel->hbp;
	var->upper_margin	= panel->vfp;
	var->lower_margin	= panel->vbp;
	var->hsync_len		= panel->hsw;
	var->vsync_len		= panel->vsw;

	/* TODO: get these from panel->config */
	var->vmode		= FB_VMODE_NONINTERLACED;
	var->sync		= 0;

	return 0;
}


/*
 * Set new x,y offsets in the virtual display for the visible area and switch
 * to the new mode.
 */
static int omapfb_pan_display(struct fb_var_screeninfo *var,
			       struct fb_info *fbi)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	int r = 0;

	omapfb_rqueue_lock(fbdev);
	if (var->xoffset != fbi->var.xoffset ||
	    var->yoffset != fbi->var.yoffset) {
		struct fb_var_screeninfo *new_var = &fbdev->new_var;

		memcpy(new_var, &fbi->var, sizeof(*new_var));
		new_var->xoffset = var->xoffset;
		new_var->yoffset = var->yoffset;
		if (set_fb_var(fbi, new_var))
			r = -EINVAL;
		else {
			memcpy(&fbi->var, new_var, sizeof(*new_var));
			ctrl_change_mode(fbi);
		}
	}
	omapfb_rqueue_unlock(fbdev);

	return r;
}

/* Set mirror to vertical axis and switch to the new mode. */
static int omapfb_mirror(struct fb_info *fbi, int mirror)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	int r = 0;

	omapfb_rqueue_lock(fbdev);
	mirror = mirror ? 1 : 0;
	if (cpu_is_omap15xx())
		r = -EINVAL;
	else if (mirror != plane->info.mirror) {
		plane->info.mirror = mirror;
		r = ctrl_change_mode(fbi);
	}
	omapfb_rqueue_unlock(fbdev);

	return r;
}

/*
 * Check values in var, try to adjust them in case of out of bound values if
 * possible, or return error.
 */
static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	int r;

	omapfb_rqueue_lock(fbdev);
	if (fbdev->ctrl->sync != NULL)
		fbdev->ctrl->sync();
	r = set_fb_var(fbi, var);
	omapfb_rqueue_unlock(fbdev);

	return r;
}

/*
 * Switch to a new mode. The parameters for it has been check already by
 * omapfb_check_var.
 */
static int omapfb_set_par(struct fb_info *fbi)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	int r = 0;

	omapfb_rqueue_lock(fbdev);
	set_fb_fix(fbi, 0);
	r = ctrl_change_mode(fbi);
	omapfb_rqueue_unlock(fbdev);

	return r;
}

int omapfb_update_window_async(struct fb_info *fbi,
				struct omapfb_update_window *win,
				void (*callback)(void *),
				void *callback_data)
{
	int xres, yres;
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	struct fb_var_screeninfo *var = &fbi->var;

	switch (var->rotate) {
	case 0:
	case 180:
		xres = fbdev->panel->x_res;
		yres = fbdev->panel->y_res;
		break;
	case 90:
	case 270:
		xres = fbdev->panel->y_res;
		yres = fbdev->panel->x_res;
		break;
	default:
		return -EINVAL;
	}

	if (win->x >= xres || win->y >= yres ||
	    win->out_x > xres || win->out_y > yres)
		return -EINVAL;

	if (!fbdev->ctrl->update_window ||
	    fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE)
		return -ENODEV;

	if (win->x + win->width > xres)
		win->width = xres - win->x;
	if (win->y + win->height > yres)
		win->height = yres - win->y;
	if (win->out_x + win->out_width > xres)
		win->out_width = xres - win->out_x;
	if (win->out_y + win->out_height > yres)
		win->out_height = yres - win->out_y;
	if (!win->width || !win->height || !win->out_width || !win->out_height)
		return 0;

	return fbdev->ctrl->update_window(fbi, win, callback, callback_data);
}
EXPORT_SYMBOL(omapfb_update_window_async);

static int omapfb_update_win(struct fb_info *fbi,
				struct omapfb_update_window *win)
{
	struct omapfb_plane_struct *plane = fbi->par;
	int ret;

	omapfb_rqueue_lock(plane->fbdev);
	ret = omapfb_update_window_async(fbi, win, NULL, NULL);
	omapfb_rqueue_unlock(plane->fbdev);

	return ret;
}

static int omapfb_update_full_screen(struct fb_info *fbi)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	struct omapfb_update_window win;
	int r;

	if (!fbdev->ctrl->update_window ||
	    fbdev->ctrl->get_update_mode() != OMAPFB_MANUAL_UPDATE)
		return -ENODEV;

	win.x = 0;
	win.y = 0;
	win.width = fbi->var.xres;
	win.height = fbi->var.yres;
	win.out_x = 0;
	win.out_y = 0;
	win.out_width = fbi->var.xres;
	win.out_height = fbi->var.yres;
	win.format = 0;

	omapfb_rqueue_lock(fbdev);
	r = fbdev->ctrl->update_window(fbi, &win, NULL, NULL);
	omapfb_rqueue_unlock(fbdev);

	return r;
}

static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	struct lcd_panel *panel = fbdev->panel;
	struct omapfb_plane_info old_info;
	int r = 0;

	if (pi->pos_x + pi->out_width > panel->x_res ||
	    pi->pos_y + pi->out_height > panel->y_res)
		return -EINVAL;

	omapfb_rqueue_lock(fbdev);
	if (pi->enabled && !fbdev->mem_desc.region[plane->idx].size) {
		/*
		 * This plane's memory was freed, can't enable it
		 * until it's reallocated.
		 */
		r = -EINVAL;
		goto out;
	}
	old_info = plane->info;
	plane->info = *pi;
	if (pi->enabled) {
		r = ctrl_change_mode(fbi);
		if (r < 0) {
			plane->info = old_info;
			goto out;
		}
	}
	r = fbdev->ctrl->enable_plane(plane->idx, pi->enabled);
	if (r < 0) {
		plane->info = old_info;
		goto out;
	}
out:
	omapfb_rqueue_unlock(fbdev);
	return r;
}

static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
{
	struct omapfb_plane_struct *plane = fbi->par;

	*pi = plane->info;
	return 0;
}

static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	struct omapfb_mem_region *rg = &fbdev->mem_desc.region[plane->idx];
	size_t size;
	int r = 0;

	if (fbdev->ctrl->setup_mem == NULL)
		return -ENODEV;
	if (mi->type != OMAPFB_MEMTYPE_SDRAM)
		return -EINVAL;

	size = PAGE_ALIGN(mi->size);
	omapfb_rqueue_lock(fbdev);
	if (plane->info.enabled) {
		r = -EBUSY;
		goto out;
	}
	if (rg->size != size || rg->type != mi->type) {
		struct fb_var_screeninfo *new_var = &fbdev->new_var;
		unsigned long old_size = rg->size;
		u8	      old_type = rg->type;
		unsigned long paddr;

		rg->size = size;
		rg->type = mi->type;
		/*
		 * size == 0 is a special case, for which we
		 * don't check / adjust the screen parameters.
		 * This isn't a problem since the plane can't
		 * be reenabled unless its size is > 0.
		 */
		if (old_size != size && size) {
			if (size) {
				memcpy(new_var, &fbi->var, sizeof(*new_var));
				r = set_fb_var(fbi, new_var);
				if (r < 0)
					goto out;
			}
		}

		if (fbdev->ctrl->sync)
			fbdev->ctrl->sync();
		r = fbdev->ctrl->setup_mem(plane->idx, size, mi->type, &paddr);
		if (r < 0) {
			/* Revert changes. */
			rg->size = old_size;
			rg->type = old_type;
			goto out;
		}
		rg->paddr = paddr;

		if (old_size != size) {
			if (size) {
				memcpy(&fbi->var, new_var, sizeof(fbi->var));
				set_fb_fix(fbi, 0);
			} else {
				/*
				 * Set these explicitly to indicate that the
				 * plane memory is dealloce'd, the other
				 * screen parameters in var / fix are invalid.
				 */
				mutex_lock(&fbi->mm_lock);
				fbi->fix.smem_start = 0;
				fbi->fix.smem_len = 0;
				mutex_unlock(&fbi->mm_lock);
			}
		}
	}
out:
	omapfb_rqueue_unlock(fbdev);

	return r;
}

static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device *fbdev = plane->fbdev;
	struct omapfb_mem_region *rg;

	rg = &fbdev->mem_desc.region[plane->idx];
	memset(mi, 0, sizeof(*mi));
	mi->size = rg->size;
	mi->type = rg->type;

	return 0;
}

static int omapfb_set_color_key(struct omapfb_device *fbdev,
				struct omapfb_color_key *ck)
{
	int r;

	if (!fbdev->ctrl->set_color_key)
		return -ENODEV;

	omapfb_rqueue_lock(fbdev);
	r = fbdev->ctrl->set_color_key(ck);
	omapfb_rqueue_unlock(fbdev);

	return r;
}

static int omapfb_get_color_key(struct omapfb_device *fbdev,
				struct omapfb_color_key *ck)
{
	int r;

	if (!fbdev->ctrl->get_color_key)
		return -ENODEV;

	omapfb_rqueue_lock(fbdev);
	r = fbdev->ctrl->get_color_key(ck);
	omapfb_rqueue_unlock(fbdev);

	return r;
}

static struct blocking_notifier_head omapfb_client_list[OMAPFB_PLANE_NUM];
static int notifier_inited;

static void omapfb_init_notifier(void)
{
	int i;

	for (i = 0; i < OMAPFB_PLANE_NUM; i++)
		BLOCKING_INIT_NOTIFIER_HEAD(&omapfb_client_list[i]);
}

int omapfb_register_client(struct omapfb_notifier_block *omapfb_nb,
				omapfb_notifier_callback_t callback,
				void *callback_data)
{
	int r;

	if ((unsigned)omapfb_nb->plane_idx >= OMAPFB_PLANE_NUM)
		return -EINVAL;

	if (!notifier_inited) {
		omapfb_init_notifier();
		notifier_inited = 1;
	}

	omapfb_nb->nb.notifier_call = (int (*)(struct notifier_block *,
					unsigned long, void *))callback;
	omapfb_nb->data = callback_data;
	r = blocking_notifier_chain_register(
				&omapfb_client_list[omapfb_nb->plane_idx],
				&omapfb_nb->nb);
	if (r)
		return r;
	if (omapfb_dev != NULL &&
	    omapfb_dev->ctrl && omapfb_dev->ctrl->bind_client) {
		omapfb_dev->ctrl->bind_client(omapfb_nb);
	}

	return 0;
}
EXPORT_SYMBOL(omapfb_register_client);

int omapfb_unregister_client(struct omapfb_notifier_block *omapfb_nb)
{
	return blocking_notifier_chain_unregister(
		&omapfb_client_list[omapfb_nb->plane_idx], &omapfb_nb->nb);
}
EXPORT_SYMBOL(omapfb_unregister_client);

void omapfb_notify_clients(struct omapfb_device *fbdev, unsigned long event)
{
	int i;

	if (!notifier_inited)
		/* no client registered yet */
		return;

	for (i = 0; i < OMAPFB_PLANE_NUM; i++)
		blocking_notifier_call_chain(&omapfb_client_list[i], event,
				    fbdev->fb_info[i]);
}
EXPORT_SYMBOL(omapfb_notify_clients);

static int omapfb_set_update_mode(struct omapfb_device *fbdev,
				   enum omapfb_update_mode mode)
{
	int r;

	omapfb_rqueue_lock(fbdev);
	r = fbdev->ctrl->set_update_mode(mode);
	omapfb_rqueue_unlock(fbdev);

	return r;
}

static enum omapfb_update_mode omapfb_get_update_mode(struct omapfb_device *fbdev)
{
	int r;

	omapfb_rqueue_lock(fbdev);
	r = fbdev->ctrl->get_update_mode();
	omapfb_rqueue_unlock(fbdev);

	return r;
}

static void omapfb_get_caps(struct omapfb_device *fbdev, int plane,
				     struct omapfb_caps *caps)
{
	memset(caps, 0, sizeof(*caps));
	fbdev->ctrl->get_caps(plane, caps);
	if (fbdev->panel->get_caps)
		caps->ctrl |= fbdev->panel->get_caps(fbdev->panel);
}

/* For lcd testing */
void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval)
{
	omapfb_rqueue_lock(fbdev);
	*(u16 *)fbdev->mem_desc.region[0].vaddr = pixval;
	if (fbdev->ctrl->get_update_mode() == OMAPFB_MANUAL_UPDATE) {
		struct omapfb_update_window win;

		memset(&win, 0, sizeof(win));
		win.width = 2;
		win.height = 2;
		win.out_width = 2;
		win.out_height = 2;
		fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, NULL);
	}
	omapfb_rqueue_unlock(fbdev);
}
EXPORT_SYMBOL(omapfb_write_first_pixel);

/*
 * Ioctl interface. Part of the kernel mode frame buffer API is duplicated
 * here to be accessible by user mode code.
 */
static int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd,
			unsigned long arg)
{
	struct omapfb_plane_struct *plane = fbi->par;
	struct omapfb_device	*fbdev = plane->fbdev;
	const struct fb_ops *ops = fbi->fbops;
	union {
		struct omapfb_update_window	update_window;
		struct omapfb_plane_info	plane_info;
		struct omapfb_mem_info		mem_info;
		struct omapfb_color_key		color_key;
		enum omapfb_update_mode		update_mode;
		struct omapfb_caps		caps;
		unsigned int		mirror;
		int			plane_out;
		int			enable_plane;
	} p;
	int r = 0;

	BUG_ON(!ops);
	switch (cmd) {
	case OMAPFB_MIRROR:
		if (get_user(p.mirror, (int __user *)arg))
			r = -EFAULT;
		else
			omapfb_mirror(fbi, p.mirror);
		break;
	case OMAPFB_SYNC_GFX:
		omapfb_sync(fbi);
		break;
	case OMAPFB_VSYNC:
		break;
	case OMAPFB_SET_UPDATE_MODE:
		if (get_user(p.update_mode, (int __user *)arg))
			r = -EFAULT;
		else
			r = omapfb_set_update_mode(fbdev, p.update_mode);
		break;
	case OMAPFB_GET_UPDATE_MODE:
		p.update_mode = omapfb_get_update_mode(fbdev);
		if (put_user(p.update_mode,
					(enum omapfb_update_mode __user *)arg))
			r = -EFAULT;
		break;
	case OMAPFB_UPDATE_WINDOW_OLD:
		if (copy_from_user(&p.update_window, (void __user *)arg,
				   sizeof(struct omapfb_update_window_old)))
			r = -EFAULT;
		else {
			struct omapfb_update_window *u = &p.update_window;
			u->out_x = u->x;
			u->out_y = u->y;
			u->out_width = u->width;
			u->out_height = u->height;
			memset(u->reserved, 0, sizeof(u->reserved));
			r = omapfb_update_win(fbi, u);
		}
		break;
	case OMAPFB_UPDATE_WINDOW:
		if (copy_from_user(&p.update_window, (void __user *)arg,
				   sizeof(p.update_window)))
			r = -EFAULT;
		else
			r = omapfb_update_win(fbi, &p.update_window);
		break;
	case OMAPFB_SETUP_PLANE:
		if (copy_from_user(&p.plane_info, (void __user *)arg,
				   sizeof(p.plane_info)))
			r = -EFAULT;
		else
			r = omapfb_setup_plane(fbi, &p.plane_info);
		break;
	case OMAPFB_QUERY_PLANE:
		if ((r = omapfb_query_plane(fbi, &p.plane_info)) < 0)
			break;
		if (copy_to_user((void __user *)arg, &p.plane_info,
				   sizeof(p.plane_info)))
			r = -EFAULT;
		break;
	case OMAPFB_SETUP_MEM:
		if (copy_from_user(&p.mem_info, (void __user *)arg,
				   sizeof(p.mem_info)))
			r = -EFAULT;
		else
			r = omapfb_setup_mem(fbi, &p.mem_info);
		break;
	case OMAPFB_QUERY_MEM:
		if ((r = omapfb_query_mem(fbi, &p.mem_info)) < 0)
			break;
		if (copy_to_user((void __user *)arg, &p.mem_info,
				   sizeof(p.mem_info)))
			r = -EFAULT;
		break;
	case OMAPFB_SET_COLOR_KEY:
		if (copy_from_user(&p.color_key, (void __user *)arg,
				   sizeof(p.color_key)))
			r = -EFAULT;
		else
			r = omapfb_set_color_key(fbdev, &p.color_key);
		break;
	case OMAPFB_GET_COLOR_KEY:
		if ((r = omapfb_get_color_key(fbdev, &p.color_key)) < 0)
			break;
		if (copy_to_user((void __user *)arg, &p.color_key,
				 sizeof(p.color_key)))
			r = -EFAULT;
		break;
	case OMAPFB_GET_CAPS:
		omapfb_get_caps(fbdev, plane->idx, &p.caps);
		if (copy_to_user((void __user *)arg, &p.caps, sizeof(p.caps)))
			r = -EFAULT;
		break;
	case OMAPFB_LCD_TEST:
		{
			int test_num;

			if (get_user(test_num, (int __user *)arg)) {
				r = -EFAULT;
				break;
			}
			if (!fbdev->panel->run_test) {
				r = -EINVAL;
				break;
			}
			r = fbdev->panel->run_test(fbdev->panel, test_num);
			break;
		}
	case OMAPFB_CTRL_TEST:
		{
			int test_num;

			if (get_user(test_num, (int __user *)arg)) {
				r = -EFAULT;
				break;
			}
			if (!fbdev->ctrl->run_test) {
				r = -EINVAL;
				break;
			}
			r = fbdev->ctrl->run_test(test_num);
			break;
		}
	default:
		r = -EINVAL;
	}

	return r;
}

static int omapfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
	struct omapfb_plane_struct *plane = info->par;
	struct omapfb_device *fbdev = plane->fbdev;
	int r;

	omapfb_rqueue_lock(fbdev);
	r = fbdev->ctrl->mmap(info, vma);
	omapfb_rqueue_unlock(fbdev);

	return r;
}

/*
 * Callback table for the frame buffer framework. Some of these pointers
 * will be changed according to the current setting of fb_info->accel_flags.
 */
static struct fb_ops omapfb_ops = {
	.owner		= THIS_MODULE,
	.fb_open        = omapfb_open,
	.fb_release     = omapfb_release,
	.fb_setcolreg	= omapfb_setcolreg,
	.fb_setcmap	= omapfb_setcmap,
	.fb_fillrect	= cfb_fillrect,
	.fb_copyarea	= cfb_copyarea,
	.fb_imageblit	= cfb_imageblit,
	.fb_blank       = omapfb_blank,
	.fb_ioctl	= omapfb_ioctl,
	.fb_check_var	= omapfb_check_var,
	.fb_set_par	= omapfb_set_par,
	.fb_pan_display = omapfb_pan_display,
};

/*
 * ---------------------------------------------------------------------------
 * Sysfs interface
 * ---------------------------------------------------------------------------
 */
/* omapfbX sysfs entries */
static ssize_t omapfb_show_caps_num(struct device *dev,
				    struct device_attribute *attr, char *buf)
{
	struct omapfb_device *fbdev = dev_get_drvdata(dev);
	int plane;
	size_t size;
	struct omapfb_caps caps;

	plane = 0;
	size = 0;
	while (size < PAGE_SIZE && plane < OMAPFB_PLANE_NUM) {
		omapfb_get_caps(fbdev, plane, &caps);
		size += snprintf(&buf[size], PAGE_SIZE - size,
			"plane#%d %#010x %#010x %#010x\n",
			plane, caps.ctrl, caps.plane_color, caps.wnd_color);
		plane++;
	}
	return size;
}

static ssize_t omapfb_show_caps_text(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct omapfb_device *fbdev = dev_get_drvdata(dev);
	int i;
	struct omapfb_caps caps;
	int plane;
	size_t size;

	plane = 0;
	size = 0;
	while (size < PAGE_SIZE && plane < OMAPFB_PLANE_NUM) {
		omapfb_get_caps(fbdev, plane, &caps);
		size += snprintf(&buf[size], PAGE_SIZE - size,
				 "plane#%d:\n", plane);
		for (i = 0; i < ARRAY_SIZE(ctrl_caps) &&
		     size < PAGE_SIZE; i++) {
			if (ctrl_caps[i].flag & caps.ctrl)
				size += snprintf(&buf[size], PAGE_SIZE - size,
					" %s\n", ctrl_caps[i].name);
		}
		size += snprintf(&buf[size], PAGE_SIZE - size,
				 " plane colors:\n");
		for (i = 0; i < ARRAY_SIZE(color_caps) &&
		     size < PAGE_SIZE; i++) {
			if (color_caps[i].flag & caps.plane_color)
				size += snprintf(&buf[size], PAGE_SIZE - size,
					"  %s\n", color_caps[i].name);
		}
		size += snprintf(&buf[size], PAGE_SIZE - size,
				 " window colors:\n");
		for (i = 0; i < ARRAY_SIZE(color_caps) &&
		     size < PAGE_SIZE; i++) {
			if (color_caps[i].flag & caps.wnd_color)
				size += snprintf(&buf[size], PAGE_SIZE - size,
					"  %s\n", color_caps[i].name);
		}

		plane++;
	}
	return size;
}

static DEVICE_ATTR(caps_num, 0444, omapfb_show_caps_num, NULL);
static DEVICE_ATTR(caps_text, 0444, omapfb_show_caps_text, NULL);

/* panel sysfs entries */
static ssize_t omapfb_show_panel_name(struct device *dev,
				      struct device_attribute *attr, char *buf)
{
	struct omapfb_device *fbdev = dev_get_drvdata(dev);

	return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->panel->name);
}

static ssize_t omapfb_show_bklight_level(struct device *dev,
					 struct device_attribute *attr,
					 char *buf)
{
	struct omapfb_device *fbdev = dev_get_drvdata(dev);
	int r;

	if (fbdev->panel->get_bklight_level) {
		r = snprintf(buf, PAGE_SIZE, "%d\n",
			     fbdev->panel->get_bklight_level(fbdev->panel));
	} else
		r = -ENODEV;
	return r;
}

static ssize_t omapfb_store_bklight_level(struct device *dev,
					  struct device_attribute *attr,
					  const char *buf, size_t size)
{
	struct omapfb_device *fbdev = dev_get_drvdata(dev);
	int r;

	if (fbdev->panel->set_bklight_level) {
		unsigned int level;

		if (sscanf(buf, "%10d", &level) == 1) {
			r = fbdev->panel->set_bklight_level(fbdev->panel,
							    level);
		} else
			r = -EINVAL;
	} else
		r = -ENODEV;
	return r ? r : size;
}

static ssize_t omapfb_show_bklight_max(struct device *dev,
				       struct device_attribute *attr, char *buf)
{
	struct omapfb_device *fbdev = dev_get_drvdata(dev);
	int r;

	if (fbdev->panel->get_bklight_level) {
		r = snprintf(buf, PAGE_SIZE, "%d\n",
			     fbdev->panel->get_bklight_max(fbdev->panel));
	} else
		r = -ENODEV;
	return r;
}

static struct device_attribute dev_attr_panel_name =
	__ATTR(name, 0444, omapfb_show_panel_name, NULL);
static DEVICE_ATTR(backlight_level, 0664,
		   omapfb_show_bklight_level, omapfb_store_bklight_level);
static DEVICE_ATTR(backlight_max, 0444, omapfb_show_bklight_max, NULL);

static struct attribute *panel_attrs[] = {
	&dev_attr_panel_name.attr,
	&dev_attr_backlight_level.attr,
	&dev_attr_backlight_max.attr,
	NULL,
};

static const struct attribute_group panel_attr_grp = {
	.name  = "panel",
	.attrs = panel_attrs,
};

/* ctrl sysfs entries */
static ssize_t omapfb_show_ctrl_name(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct omapfb_device *fbdev = dev_get_drvdata(dev);

	return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name);
}

static struct device_attribute dev_attr_ctrl_name =
	__ATTR(name, 0444, omapfb_show_ctrl_name, NULL);

static struct attribute *ctrl_attrs[] = {
	&dev_attr_ctrl_name.attr,
	NULL,
};

static const struct attribute_group ctrl_attr_grp = {
	.name  = "ctrl",
	.attrs = ctrl_attrs,
};

static int omapfb_register_sysfs(struct omapfb_device *fbdev)
{
	int r;

	if ((r = device_create_file(fbdev->dev, &dev_attr_caps_num)))
		goto fail0;

	if ((r = device_create_file(fbdev->dev, &dev_attr_caps_text)))
		goto fail1;

	if ((r = sysfs_create_group(&fbdev->dev->kobj, &panel_attr_grp)))
		goto fail2;

	if ((r = sysfs_create_group(&fbdev->dev->kobj, &ctrl_attr_grp)))
		goto fail3;

	return 0;
fail3:
	sysfs_remove_group(&fbdev->dev->kobj, &panel_attr_grp);
fail2:
	device_remove_file(fbdev->dev, &dev_attr_caps_text);
fail1:
	device_remove_file(fbdev->dev, &dev_attr_caps_num);
fail0:
	dev_err(fbdev->dev, "unable to register sysfs interface\n");
	return r;
}

static void omapfb_unregister_sysfs(struct omapfb_device *fbdev)
{
	sysfs_remove_group(&fbdev->dev->kobj, &ctrl_attr_grp);
	sysfs_remove_group(&fbdev->dev->kobj, &panel_attr_grp);
	device_remove_file(fbdev->dev, &dev_attr_caps_num);
	device_remove_file(fbdev->dev, &dev_attr_caps_text);
}

/*
 * ---------------------------------------------------------------------------
 * LDM callbacks
 * ---------------------------------------------------------------------------
 */
/* Initialize system fb_info object and set the default video mode.
 * The frame buffer memory already allocated by lcddma_init
 */
static int fbinfo_init(struct omapfb_device *fbdev, struct fb_info *info)
{
	struct fb_var_screeninfo	*var = &info->var;
	struct fb_fix_screeninfo	*fix = &info->fix;
	int				r = 0;

	info->fbops = &omapfb_ops;
	info->flags = FBINFO_FLAG_DEFAULT;

	strncpy(fix->id, MODULE_NAME, sizeof(fix->id));

	info->pseudo_palette = fbdev->pseudo_palette;

	var->accel_flags  = def_accel ? FB_ACCELF_TEXT : 0;
	var->xres = def_vxres;
	var->yres = def_vyres;
	var->xres_virtual = def_vxres;
	var->yres_virtual = def_vyres;
	var->rotate	  = def_rotate;
	var->bits_per_pixel = fbdev->panel->bpp;

	set_fb_var(info, var);
	set_fb_fix(info, 1);

	r = fb_alloc_cmap(&info->cmap, 16, 0);
	if (r != 0)
		dev_err(fbdev->dev, "unable to allocate color map memory\n");

	return r;
}

/* Release the fb_info object */
static void fbinfo_cleanup(struct omapfb_device *fbdev, struct fb_info *fbi)
{
	fb_dealloc_cmap(&fbi->cmap);
}

static void planes_cleanup(struct omapfb_device *fbdev)
{
	int i;

	for (i = 0; i < fbdev->mem_desc.region_cnt; i++) {
		if (fbdev->fb_info[i] == NULL)
			break;
		fbinfo_cleanup(fbdev, fbdev->fb_info[i]);
		framebuffer_release(fbdev->fb_info[i]);
	}
}

static int planes_init(struct omapfb_device *fbdev)
{
	struct fb_info *fbi;
	int i;
	int r;

	for (i = 0; i < fbdev->mem_desc.region_cnt; i++) {
		struct omapfb_plane_struct *plane;
		fbi = framebuffer_alloc(sizeof(struct omapfb_plane_struct),
					fbdev->dev);
		if (fbi == NULL) {
			planes_cleanup(fbdev);
			return -ENOMEM;
		}
		plane = fbi->par;
		plane->idx = i;
		plane->fbdev = fbdev;
		plane->info.mirror = def_mirror;
		fbdev->fb_info[i] = fbi;

		if ((r = fbinfo_init(fbdev, fbi)) < 0) {
			framebuffer_release(fbi);
			planes_cleanup(fbdev);
			return r;
		}
		plane->info.out_width = fbi->var.xres;
		plane->info.out_height = fbi->var.yres;
	}
	return 0;
}

/*
 * Free driver resources. Can be called to rollback an aborted initialization
 * sequence.
 */
static void omapfb_free_resources(struct omapfb_device *fbdev, int state)
{
	int i;

	switch (state) {
	case OMAPFB_ACTIVE:
		for (i = 0; i < fbdev->mem_desc.region_cnt; i++)
			unregister_framebuffer(fbdev->fb_info[i]);
		/* fall through */
	case 7:
		omapfb_unregister_sysfs(fbdev);
		/* fall through */
	case 6:
		if (fbdev->panel->disable)
			fbdev->panel->disable(fbdev->panel);
		/* fall through */
	case 5:
		omapfb_set_update_mode(fbdev, OMAPFB_UPDATE_DISABLED);
		/* fall through */
	case 4:
		planes_cleanup(fbdev);
		/* fall through */
	case 3:
		ctrl_cleanup(fbdev);
		/* fall through */
	case 2:
		if (fbdev->panel->cleanup)
			fbdev->panel->cleanup(fbdev->panel);
		/* fall through */
	case 1:
		dev_set_drvdata(fbdev->dev, NULL);
		kfree(fbdev);
	case 0:
		/* nothing to free */
		break;
	default:
		BUG();
	}
}

static int omapfb_find_ctrl(struct omapfb_device *fbdev)
{
	struct omapfb_platform_data *conf;
	char name[17];
	int i;

	conf = dev_get_platdata(fbdev->dev);

	fbdev->ctrl = NULL;

	strncpy(name, conf->lcd.ctrl_name, sizeof(name) - 1);
	name[sizeof(name) - 1] = '\0';

	if (strcmp(name, "internal") == 0) {
		fbdev->ctrl = fbdev->int_ctrl;
		return 0;
	}

	for (i = 0; i < ARRAY_SIZE(ctrls); i++) {
		dev_dbg(fbdev->dev, "ctrl %s\n", ctrls[i]->name);
		if (strcmp(ctrls[i]->name, name) == 0) {
			fbdev->ctrl = ctrls[i];
			break;
		}
	}

	if (fbdev->ctrl == NULL) {
		dev_dbg(fbdev->dev, "ctrl %s not supported\n", name);
		return -1;
	}

	return 0;
}

/*
 * Called by LDM binding to probe and attach a new device.
 * Initialization sequence:
 *   1. allocate system omapfb_device structure
 *   2. select controller type according to platform configuration
 *      init LCD panel
 *   3. init LCD controller and LCD DMA
 *   4. init system fb_info structure for all planes
 *   5. setup video mode for first plane and enable it
 *   6. enable LCD panel
 *   7. register sysfs attributes
 *   OMAPFB_ACTIVE: register system fb_info structure for all planes
 */
static int omapfb_do_probe(struct platform_device *pdev,
				struct lcd_panel *panel)
{
	struct omapfb_device	*fbdev = NULL;
	int			init_state;
	unsigned long		phz, hhz, vhz;
	unsigned long		vram;
	int			i;
	int			r = 0;

	init_state = 0;

	if (pdev->num_resources != 0) {
		dev_err(&pdev->dev, "probed for an unknown device\n");
		r = -ENODEV;
		goto cleanup;
	}

	if (dev_get_platdata(&pdev->dev) == NULL) {
		dev_err(&pdev->dev, "missing platform data\n");
		r = -ENOENT;
		goto cleanup;
	}

	fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
	if (fbdev == NULL) {
		dev_err(&pdev->dev,
			"unable to allocate memory for device info\n");
		r = -ENOMEM;
		goto cleanup;
	}
	init_state++;

	fbdev->dev = &pdev->dev;
	fbdev->panel = panel;
	fbdev->dssdev = &omapdss_device;
	platform_set_drvdata(pdev, fbdev);

	mutex_init(&fbdev->rqueue_mutex);

	fbdev->int_ctrl = &omap1_int_ctrl;
#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL
	fbdev->ext_if = &omap1_ext_if;
#endif
	if (omapfb_find_ctrl(fbdev) < 0) {
		dev_err(fbdev->dev,
			"LCD controller not found, board not supported\n");
		r = -ENODEV;
		goto cleanup;
	}

	if (fbdev->panel->init) {
		r = fbdev->panel->init(fbdev->panel, fbdev);
		if (r)
			goto cleanup;
	}

	pr_info("omapfb: configured for panel %s\n", fbdev->panel->name);

	def_vxres = def_vxres ? def_vxres : fbdev->panel->x_res;
	def_vyres = def_vyres ? def_vyres : fbdev->panel->y_res;

	init_state++;

	r = ctrl_init(fbdev);
	if (r)
		goto cleanup;
	if (fbdev->ctrl->mmap != NULL)
		omapfb_ops.fb_mmap = omapfb_mmap;
	init_state++;

	r = planes_init(fbdev);
	if (r)
		goto cleanup;
	init_state++;

#ifdef CONFIG_FB_OMAP_DMA_TUNE
	/* Set DMA priority for EMIFF access to highest */
	omap_set_dma_priority(0, OMAP_DMA_PORT_EMIFF, 15);
#endif

	r = ctrl_change_mode(fbdev->fb_info[0]);
	if (r) {
		dev_err(fbdev->dev, "mode setting failed\n");
		goto cleanup;
	}

	/* GFX plane is enabled by default */
	r = fbdev->ctrl->enable_plane(OMAPFB_PLANE_GFX, 1);
	if (r)
		goto cleanup;

	omapfb_set_update_mode(fbdev, manual_update ?
				   OMAPFB_MANUAL_UPDATE : OMAPFB_AUTO_UPDATE);
	init_state++;

	if (fbdev->panel->enable) {
		r = fbdev->panel->enable(fbdev->panel);
		if (r)
			goto cleanup;
	}
	init_state++;

	r = omapfb_register_sysfs(fbdev);
	if (r)
		goto cleanup;
	init_state++;

	vram = 0;
	for (i = 0; i < fbdev->mem_desc.region_cnt; i++) {
		r = register_framebuffer(fbdev->fb_info[i]);
		if (r != 0) {
			dev_err(fbdev->dev,
				"registering framebuffer %d failed\n", i);
			goto cleanup;
		}
		vram += fbdev->mem_desc.region[i].size;
	}

	fbdev->state = OMAPFB_ACTIVE;

	panel = fbdev->panel;
	phz = panel->pixel_clock * 1000;
	hhz = phz * 10 / (panel->hfp + panel->x_res + panel->hbp + panel->hsw);
	vhz = hhz / (panel->vfp + panel->y_res + panel->vbp + panel->vsw);

	omapfb_dev = fbdev;

	pr_info("omapfb: Framebuffer initialized. Total vram %lu planes %d\n",
			vram, fbdev->mem_desc.region_cnt);
	pr_info("omapfb: Pixclock %lu kHz hfreq %lu.%lu kHz "
			"vfreq %lu.%lu Hz\n",
			phz / 1000, hhz / 10000, hhz % 10, vhz / 10, vhz % 10);

	return 0;

cleanup:
	omapfb_free_resources(fbdev, init_state);

	return r;
}

static int omapfb_probe(struct platform_device *pdev)
{
	int r;

	BUG_ON(fbdev_pdev != NULL);

	r = platform_device_register(&omapdss_device);
	if (r) {
		dev_err(&pdev->dev, "can't register omapdss device\n");
		return r;
	}

	/* Delay actual initialization until the LCD is registered */
	fbdev_pdev = pdev;
	if (fbdev_panel != NULL)
		omapfb_do_probe(fbdev_pdev, fbdev_panel);
	return 0;
}

void omapfb_register_panel(struct lcd_panel *panel)
{
	BUG_ON(fbdev_panel != NULL);

	fbdev_panel = panel;
	if (fbdev_pdev != NULL)
		omapfb_do_probe(fbdev_pdev, fbdev_panel);
}
EXPORT_SYMBOL_GPL(omapfb_register_panel);

/* Called when the device is being detached from the driver */
static int omapfb_remove(struct platform_device *pdev)
{
	struct omapfb_device *fbdev = platform_get_drvdata(pdev);
	enum omapfb_state saved_state = fbdev->state;

	/* FIXME: wait till completion of pending events */

	fbdev->state = OMAPFB_DISABLED;
	omapfb_free_resources(fbdev, saved_state);

	platform_device_unregister(&omapdss_device);
	fbdev->dssdev = NULL;

	return 0;
}

/* PM suspend */
static int omapfb_suspend(struct platform_device *pdev, pm_message_t mesg)
{
	struct omapfb_device *fbdev = platform_get_drvdata(pdev);

	if (fbdev != NULL)
		omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]);
	return 0;
}

/* PM resume */
static int omapfb_resume(struct platform_device *pdev)
{
	struct omapfb_device *fbdev = platform_get_drvdata(pdev);

	if (fbdev != NULL)
		omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]);
	return 0;
}

static struct platform_driver omapfb_driver = {
	.probe		= omapfb_probe,
	.remove		= omapfb_remove,
	.suspend	= omapfb_suspend,
	.resume		= omapfb_resume,
	.driver		= {
		.name	= MODULE_NAME,
	},
};

#ifndef MODULE

/* Process kernel command line parameters */
static int __init omapfb_setup(char *options)
{
	char *this_opt = NULL;
	int r = 0;

	pr_debug("omapfb: options %s\n", options);

	if (!options || !*options)
		return 0;

	while (!r && (this_opt = strsep(&options, ",")) != NULL) {
		if (!strncmp(this_opt, "accel", 5))
			def_accel = 1;
		else if (!strncmp(this_opt, "vram:", 5)) {
			char *suffix;
			unsigned long vram;
			vram = (simple_strtoul(this_opt + 5, &suffix, 0));
			switch (suffix[0]) {
			case '\0':
				break;
			case 'm':
			case 'M':
				vram *= 1024;
				/* Fall through */
			case 'k':
			case 'K':
				vram *= 1024;
				break;
			default:
				pr_debug("omapfb: invalid vram suffix %c\n",
					 suffix[0]);
				r = -1;
			}
			def_vram[def_vram_cnt++] = vram;
		}
		else if (!strncmp(this_opt, "vxres:", 6))
			def_vxres = simple_strtoul(this_opt + 6, NULL, 0);
		else if (!strncmp(this_opt, "vyres:", 6))
			def_vyres = simple_strtoul(this_opt + 6, NULL, 0);
		else if (!strncmp(this_opt, "rotate:", 7))
			def_rotate = (simple_strtoul(this_opt + 7, NULL, 0));
		else if (!strncmp(this_opt, "mirror:", 7))
			def_mirror = (simple_strtoul(this_opt + 7, NULL, 0));
		else if (!strncmp(this_opt, "manual_update", 13))
			manual_update = 1;
		else {
			pr_debug("omapfb: invalid option\n");
			r = -1;
		}
	}

	return r;
}

#endif

/* Register both the driver and the device */
static int __init omapfb_init(void)
{
#ifndef MODULE
	char *option;

	if (fb_get_options("omapfb", &option))
		return -ENODEV;
	omapfb_setup(option);
#endif
	/* Register the driver with LDM */
	if (platform_driver_register(&omapfb_driver)) {
		pr_debug("failed to register omapfb driver\n");
		return -ENODEV;
	}

	return 0;
}

static void __exit omapfb_cleanup(void)
{
	platform_driver_unregister(&omapfb_driver);
}

module_param_named(accel, def_accel, uint, 0664);
module_param_array_named(vram, def_vram, ulong, &def_vram_cnt, 0664);
module_param_named(vxres, def_vxres, long, 0664);
module_param_named(vyres, def_vyres, long, 0664);
module_param_named(rotate, def_rotate, uint, 0664);
module_param_named(mirror, def_mirror, uint, 0664);
module_param_named(manual_update, manual_update, bool, 0664);

module_init(omapfb_init);
module_exit(omapfb_cleanup);

MODULE_DESCRIPTION("TI OMAP framebuffer driver");
MODULE_AUTHOR("Imre Deak <imre.deak@nokia.com>");
MODULE_LICENSE("GPL");
