Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH 2/6] media: davinci: vpbe: enable vpbe for fbdev addition
From: Prabhakar Lad @ 2013-04-24 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1366804808-22720-1-git-send-email-prabhakar.csengg@gmail.com>

From: Lad, Prabhakar <prabhakar.csengg@gmail.com>

enable the venc, osd and vpbe display driver for addition
of fbdev driver. Mainly includes fbdev ops structure inclusion,
palette and osd layer related functionality for OSD block.

Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
---
 drivers/media/platform/davinci/vpbe_display.c |    6 +
 drivers/media/platform/davinci/vpbe_osd.c     |  796 ++++++++++++++++++++++++-
 drivers/media/platform/davinci/vpbe_venc.c    |   43 ++
 include/media/davinci/vpbe_osd.h              |   62 ++
 include/media/davinci/vpbe_venc.h             |   21 +
 5 files changed, 920 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 1c4ba89..0341dcc 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -121,10 +121,12 @@ static void vpbe_isr_odd_field(struct vpbe_display *disp_obj,
 static irqreturn_t venc_isr(int irq, void *arg)
 {
 	struct vpbe_display *disp_dev = (struct vpbe_display *)arg;
+	struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
 	struct vpbe_layer *layer;
 	static unsigned last_event;
 	unsigned event = 0;
 	int fid;
+	int ret;
 	int i;
 
 	if ((NULL = arg) || (NULL = disp_dev->dev[0]))
@@ -195,6 +197,10 @@ static irqreturn_t venc_isr(int irq, void *arg)
 				vpbe_isr_odd_field(disp_dev, layer);
 		}
 	}
+	ret = v4l2_subdev_call(vpbe_dev->venc, core, ioctl, VENC_INTERRUPT,
+				&event);
+	if (ret < 0)
+		v4l2_err(&vpbe_dev->v4l2_dev, "Error in getting Field ID 0\n");
 
 	return IRQ_HANDLED;
 }
diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c
index 6ed82e8..455b0ca 100644
--- a/drivers/media/platform/davinci/vpbe_osd.c
+++ b/drivers/media/platform/davinci/vpbe_osd.c
@@ -175,6 +175,13 @@ static int _osd_dm6446_vid0_pingpong(struct osd_state *sd,
 	return 0;
 }
 
+static int osd_get_field_inversion(struct osd_state *sd)
+{
+	struct osd_state *osd = sd;
+
+	return osd->field_inversion;
+}
+
 static void _osd_set_field_inversion(struct osd_state *sd, int enable)
 {
 	unsigned fsinv = 0;
@@ -185,6 +192,365 @@ static void _osd_set_field_inversion(struct osd_state *sd, int enable)
 	osd_modify(sd, OSD_MODE_FSINV, fsinv, OSD_MODE);
 }
 
+static void osd_set_field_inversion(struct osd_state *sd, int enable)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->field_inversion = (enable != 0);
+	_osd_set_field_inversion(sd, enable);
+
+	osd->pingpong = _osd_dm6446_vid0_pingpong(sd, osd->field_inversion,
+					osd->win[WIN_VID0].fb_base_phys,
+						  &osd->win[WIN_VID0].lconfig);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void osd_get_background(struct osd_state *sd, enum osd_clut *clut,
+				 unsigned char *clut_index)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	*clut = osd->backg_clut;
+	*clut_index = osd->backg_clut_index;
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void _osd_set_background(struct osd_state *sd, enum osd_clut clut,
+				unsigned char clut_index)
+{
+	u32 mode = 0;
+
+	if (clut = RAM_CLUT)
+		mode |= OSD_MODE_BCLUT;
+	mode |= clut_index;
+	osd_modify(sd, OSD_MODE_BCLUT | OSD_MODE_CABG, mode, OSD_MODE);
+}
+
+static void osd_set_background(struct osd_state *sd, enum osd_clut clut,
+			       unsigned char clut_index)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->backg_clut = clut;
+	osd->backg_clut_index = clut_index;
+	_osd_set_background(sd, clut, clut_index);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static int osd_get_interpolation_filter(struct osd_state *sd)
+{
+	struct osd_state *osd = sd;
+
+	return osd->interpolation_filter;
+}
+
+static void _osd_set_interpolation_filter(struct osd_state *sd, int filter)
+{
+	struct osd_state *osd = sd;
+
+	if (osd->vpbe_type = VPBE_VERSION_3 ||
+	    osd->vpbe_type = VPBE_VERSION_2)
+		osd_clear(sd, OSD_EXTMODE_EXPMDSEL, OSD_EXTMODE);
+
+	osd_modify(sd, OSD_MODE_EF, filter ? OSD_MODE_EF : 0, OSD_MODE);
+}
+
+static void osd_set_interpolation_filter(struct osd_state *sd, int filter)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->interpolation_filter = (filter != 0);
+	_osd_set_interpolation_filter(sd, filter);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void osd_get_cursor_config(struct osd_state *sd,
+				  struct osd_cursor_config *cursor)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	*cursor = osd->cursor.config;
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void _osd_set_cursor_config(struct osd_state *sd,
+				   const struct osd_cursor_config *cursor)
+{
+	struct osd_state *osd = sd;
+	unsigned rectcur = 0;
+
+	osd_write(sd, cursor->xsize, OSD_CURXL);
+	osd_write(sd, cursor->xpos, OSD_CURXP);
+
+	if (cursor->interlaced) {
+		osd_write(sd, cursor->ypos >> 1, OSD_CURYP);
+		if (osd->vpbe_type = VPBE_VERSION_1)
+			/* Must add 1 to ysize due to device erratum. */
+			osd_write(sd, (cursor->ysize >> 1) + 1, OSD_CURYL);
+		else
+			osd_write(sd, cursor->ysize >> 1, OSD_CURYL);
+	} else {
+		osd_write(sd, cursor->ypos, OSD_CURYP);
+		if (osd->vpbe_type = VPBE_VERSION_1)
+			/* Must add 1 to ysize due to device erratum. */
+			osd_write(sd, cursor->ysize + 1, OSD_CURYL);
+		else
+			osd_write(sd, cursor->ysize, OSD_CURYL);
+	}
+
+	if (cursor->clut = RAM_CLUT)
+		rectcur |= OSD_RECTCUR_CLUTSR;
+
+	rectcur |= (cursor->clut_index << OSD_RECTCUR_RCAD_SHIFT);
+	rectcur |= (cursor->h_width << OSD_RECTCUR_RCHW_SHIFT);
+	rectcur |= (cursor->v_width << OSD_RECTCUR_RCVW_SHIFT);
+	osd_modify(sd, OSD_RECTCUR_RCAD | OSD_RECTCUR_CLUTSR |
+		   OSD_RECTCUR_RCHW | OSD_RECTCUR_RCVW, rectcur, OSD_RECTCUR);
+}
+
+static void osd_set_cursor_config(struct osd_state *sd,
+				  struct osd_cursor_config *cursor)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	cursor->xpos = min_t(unsigned, cursor->xpos, (unsigned)OSD_CURXP_RCSX);
+	cursor->ypos = min_t(unsigned, cursor->ypos, (unsigned)OSD_CURYP_RCSY);
+	cursor->xsize +		min_t(unsigned, cursor->xsize, (unsigned)OSD_CURXL_RCSW);
+	cursor->ysize +		min_t(unsigned, cursor->ysize, (unsigned)OSD_CURYL_RCSH);
+	cursor->interlaced = (cursor->interlaced != 0);
+	if (cursor->interlaced) {
+		cursor->ysize &= ~1;
+		cursor->ypos &= ~1;
+	}
+	cursor->h_width &= (OSD_RECTCUR_RCHW >> OSD_RECTCUR_RCHW_SHIFT);
+	cursor->v_width &= (OSD_RECTCUR_RCVW >> OSD_RECTCUR_RCVW_SHIFT);
+	cursor->clut = (cursor->clut = RAM_CLUT) ? RAM_CLUT : ROM_CLUT;
+
+	osd->cursor.config = *cursor;
+	_osd_set_cursor_config(sd, cursor);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static int osd_cursor_is_enabled(struct osd_state *sd)
+{
+	struct osd_state *osd = sd;
+
+	return osd->cursor.is_enabled;
+}
+
+static void _osd_cursor_disable(struct osd_state *sd)
+{
+	osd_clear(sd, OSD_RECTCUR_RCACT, OSD_RECTCUR);
+}
+
+static void osd_cursor_disable(struct osd_state *sd)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->cursor.is_enabled = 0;
+	_osd_cursor_disable(sd);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void _osd_cursor_enable(struct osd_state *sd)
+{
+	osd_set(sd, OSD_RECTCUR_RCACT, OSD_RECTCUR);
+}
+
+static void osd_cursor_enable(struct osd_state *sd)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->cursor.is_enabled = 1;
+	_osd_cursor_enable(sd);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void osd_get_vid_expansion(struct osd_state *sd,
+				  enum osd_h_exp_ratio *h_exp,
+				  enum osd_v_exp_ratio *v_exp)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	*h_exp = osd->vid_h_exp;
+	*v_exp = osd->vid_v_exp;
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void _osd_set_vid_expansion(struct osd_state *sd,
+				   enum osd_h_exp_ratio h_exp,
+				   enum osd_v_exp_ratio v_exp)
+{
+	struct osd_state *osd = sd;
+	u32 mode = 0;
+	u32 extmode = 0;
+
+	switch (h_exp) {
+	case H_EXP_OFF:
+		break;
+	case H_EXP_9_OVER_8:
+		mode |= OSD_MODE_VHRSZ;
+		break;
+	case H_EXP_3_OVER_2:
+		extmode |= OSD_EXTMODE_VIDHRSZ15;
+		break;
+	}
+
+	switch (v_exp) {
+	case V_EXP_OFF:
+		break;
+	case V_EXP_6_OVER_5:
+		mode |= OSD_MODE_VVRSZ;
+		break;
+	}
+
+	if (osd->vpbe_type = VPBE_VERSION_3 ||
+	    osd->vpbe_type = VPBE_VERSION_2)
+		osd_modify(sd, OSD_EXTMODE_VIDHRSZ15, extmode, OSD_EXTMODE);
+
+	osd_modify(sd, OSD_MODE_VHRSZ | OSD_MODE_VVRSZ, mode, OSD_MODE);
+}
+
+static int osd_set_vid_expansion(struct osd_state *sd,
+				 enum osd_h_exp_ratio h_exp,
+				 enum osd_v_exp_ratio v_exp)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	if (h_exp = H_EXP_3_OVER_2 && (osd->vpbe_type = VPBE_VERSION_1))
+		return -EINVAL;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->vid_h_exp = h_exp;
+	osd->vid_v_exp = v_exp;
+	_osd_set_vid_expansion(sd, h_exp, v_exp);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+	return 0;
+}
+
+static void osd_get_osd_expansion(struct osd_state *sd,
+				  enum osd_h_exp_ratio *h_exp,
+				  enum osd_v_exp_ratio *v_exp)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	*h_exp = osd->osd_h_exp;
+	*v_exp = osd->osd_v_exp;
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void _osd_set_osd_expansion(struct osd_state *sd,
+				   enum osd_h_exp_ratio h_exp,
+				   enum osd_v_exp_ratio v_exp)
+{
+	struct osd_state *osd = sd;
+	u32 mode = 0;
+	u32 extmode = 0;
+
+	switch (h_exp) {
+	case H_EXP_OFF:
+		break;
+	case H_EXP_9_OVER_8:
+		mode |= OSD_MODE_OHRSZ;
+		break;
+	case H_EXP_3_OVER_2:
+		extmode |= OSD_EXTMODE_OSDHRSZ15;
+		break;
+	}
+
+	switch (v_exp) {
+	case V_EXP_OFF:
+		break;
+	case V_EXP_6_OVER_5:
+		mode |= OSD_MODE_OVRSZ;
+		break;
+	}
+
+	if (osd->vpbe_type = VPBE_VERSION_3 ||
+	    osd->vpbe_type = VPBE_VERSION_2)
+		osd_modify(sd, OSD_EXTMODE_OSDHRSZ15, extmode, OSD_EXTMODE);
+
+	osd_modify(sd, OSD_MODE_OHRSZ | OSD_MODE_OVRSZ, mode, OSD_MODE);
+}
+
+static int osd_set_osd_expansion(struct osd_state *sd,
+				 enum osd_h_exp_ratio h_exp,
+				 enum osd_v_exp_ratio v_exp)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	if (h_exp = H_EXP_3_OVER_2 && (osd->vpbe_type = VPBE_VERSION_1))
+		return -EINVAL;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->osd_h_exp = h_exp;
+	osd->osd_v_exp = v_exp;
+	_osd_set_osd_expansion(sd, h_exp, v_exp);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+	return 0;
+}
+
+static void osd_get_blink_attribute(struct osd_state *sd, int *enable,
+				    enum osd_blink_interval *blink)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	*enable = osd->is_blinking;
+	*blink = osd->blink;
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
 static void _osd_set_blink_attribute(struct osd_state *sd, int enable,
 				     enum osd_blink_interval blink)
 {
@@ -199,6 +565,29 @@ static void _osd_set_blink_attribute(struct osd_state *sd, int enable,
 		  OSD_OSDATRMD);
 }
 
+static void osd_set_blink_attribute(struct osd_state *sd, int enable,
+				    enum osd_blink_interval blink)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->is_blinking = (enable != 0);
+	osd->blink = blink;
+	if (osd->win[WIN_OSD1].lconfig.pixfmt = PIXFMT_OSD_ATTR)
+		_osd_set_blink_attribute(sd, enable, blink);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static enum osd_rom_clut osd_get_rom_clut(struct osd_state *sd)
+{
+	struct osd_state *osd = sd;
+
+	return osd->rom_clut;
+}
+
 static void _osd_set_rom_clut(struct osd_state *sd,
 			      enum osd_rom_clut rom_clut)
 {
@@ -208,6 +597,150 @@ static void _osd_set_rom_clut(struct osd_state *sd,
 		osd_set(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL);
 }
 
+static void osd_set_rom_clut(struct osd_state *sd,
+			     enum osd_rom_clut rom_clut)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->rom_clut = rom_clut;
+	_osd_set_rom_clut(sd, rom_clut);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void _osd_set_clut_ycbcr(struct osd_state *sd,
+				unsigned char clut_index,
+				unsigned char y, unsigned char cb,
+				unsigned char cr)
+{
+	/* wait until any previous writes to the CLUT RAM have completed */
+	while (osd_read(sd, OSD_MISCCTL) & OSD_MISCCTL_CPBSY)
+		cpu_relax();
+
+	osd_write(sd, (y << OSD_CLUTRAMYCB_Y_SHIFT) | cb, OSD_CLUTRAMYCB);
+	osd_write(sd, (cr << OSD_CLUTRAMCR_CR_SHIFT) | clut_index,
+		  OSD_CLUTRAMCR);
+}
+
+static void osd_set_clut_ycbcr(struct osd_state *sd,
+			       unsigned char clut_index, unsigned char y,
+			       unsigned char cb, unsigned char cr)
+{
+	struct osd_state *osd = sd;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->clut_ram[clut_index][0] = y;
+	osd->clut_ram[clut_index][1] = cb;
+	osd->clut_ram[clut_index][2] = cr;
+	_osd_set_clut_ycbcr(sd, clut_index, y, cb, cr);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void _osd_rgb_to_ycbcr(const unsigned char rgb[3],
+			      unsigned char ycbcr[3])
+{
+	int y, cb, cr;
+	int r = rgb[0];
+	int g = rgb[1];
+	int b = rgb[2];
+	/*
+	 * This conversion matrix corresponds to the conversion matrix used
+	 * by the OSD to convert RGB values to YCbCr values.  All coefficients
+	 * have been scaled by a factor of 2^22.
+	 */
+	static const int rgb_to_ycbcr[3][3] = {
+		{1250330, 2453618, 490352},
+		{-726093, -1424868, 2150957},
+		{2099836, -1750086, -349759}
+	};
+
+	y = rgb_to_ycbcr[0][0] * r + rgb_to_ycbcr[0][1] * g +
+			rgb_to_ycbcr[0][2] * b;
+	cb = rgb_to_ycbcr[1][0] * r + rgb_to_ycbcr[1][1] * g +
+			rgb_to_ycbcr[1][2] * b;
+	cr = rgb_to_ycbcr[2][0] * r + rgb_to_ycbcr[2][1] * g +
+			rgb_to_ycbcr[2][2] * b;
+
+	/* round and scale */
+	y = ((y + (1 << 21)) >> 22);
+	cb = ((cb + (1 << 21)) >> 22) + 128;
+	cr = ((cr + (1 << 21)) >> 22) + 128;
+
+	/* clip */
+	y = (y < 0) ? 0 : y;
+	y = (y > 255) ? 255 : y;
+	cb = (cb < 0) ? 0 : cb;
+	cb = (cb > 255) ? 255 : cb;
+	cr = (cr < 0) ? 0 : cr;
+	cr = (cr > 255) ? 255 : cr;
+
+	ycbcr[0] = y;
+	ycbcr[1] = cb;
+	ycbcr[2] = cr;
+}
+
+static void osd_set_clut_rgb(struct osd_state *sd, unsigned char clut_index,
+			     unsigned char r, unsigned char g, unsigned char b)
+{
+	struct osd_state *osd = sd;
+	unsigned char rgb[3], ycbcr[3];
+	unsigned long flags;
+
+	rgb[0] = r;
+	rgb[1] = g;
+	rgb[2] = b;
+	_osd_rgb_to_ycbcr(rgb, ycbcr);
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osd->clut_ram[clut_index][0] = ycbcr[0];
+	osd->clut_ram[clut_index][1] = ycbcr[1];
+	osd->clut_ram[clut_index][2] = ycbcr[2];
+	_osd_set_clut_ycbcr(sd, clut_index, ycbcr[0], ycbcr[1], ycbcr[2]);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static unsigned char osd_get_palette_map(struct osd_state *sd,
+					 enum osd_win_layer osdwin,
+					 unsigned char pixel_value)
+{
+	struct osd_state *osd = sd;
+	enum osd_layer layer +	    (osdwin = OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1;
+	struct osd_window_state *win = &osd->win[layer];
+	struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin];
+	unsigned char clut_index;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	switch (win->lconfig.pixfmt) {
+	case PIXFMT_1BPP:
+		clut_index = osdwin_state->palette_map[pixel_value & 0x1];
+		break;
+	case PIXFMT_2BPP:
+		clut_index = osdwin_state->palette_map[pixel_value & 0x3];
+		break;
+	case PIXFMT_4BPP:
+		clut_index = osdwin_state->palette_map[pixel_value & 0xf];
+		break;
+	default:
+		clut_index = 0;
+		break;
+	}
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+
+	return clut_index;
+}
+
 static void _osd_set_palette_map(struct osd_state *sd,
 				 enum osd_win_layer osdwin,
 				 unsigned char pixel_value,
@@ -257,14 +790,55 @@ static void _osd_set_palette_map(struct osd_state *sd,
 	osd_modify(sd, bmp_mask, clut_index << bmp_shift, bmp_offset);
 }
 
+static void osd_set_palette_map(struct osd_state *sd,
+				enum osd_win_layer osdwin,
+				unsigned char pixel_value,
+				unsigned char clut_index)
+{
+	struct osd_state *osd = sd;
+	enum osd_layer layer +	    (osdwin = OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1;
+	struct osd_window_state *win = &osd->win[layer];
+	struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin];
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	switch (win->lconfig.pixfmt) {
+	case PIXFMT_1BPP:
+		osdwin_state->palette_map[pixel_value & 0x1] = clut_index;
+		break;
+	case PIXFMT_2BPP:
+		osdwin_state->palette_map[pixel_value & 0x3] = clut_index;
+		break;
+	case PIXFMT_4BPP:
+		osdwin_state->palette_map[pixel_value & 0xf] = clut_index;
+		break;
+	default:
+		spin_unlock_irqrestore(&osd->lock, flags);
+		return;
+	}
+
+	_osd_set_palette_map(sd, osdwin, pixel_value, clut_index,
+			     win->lconfig.pixfmt);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static int osd_get_rec601_attenuation(struct osd_state *sd,
+				      enum osd_win_layer osdwin)
+{
+	struct osd_state *osd = sd;
+	struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin];
+
+	return osdwin_state->rec601_attenuation;
+}
+
 static void _osd_set_rec601_attenuation(struct osd_state *sd,
 					enum osd_win_layer osdwin, int enable)
 {
 	switch (osdwin) {
 	case OSDWIN_OSD0:
-		osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
-			  enable ? OSD_OSDWIN0MD_ATN0E : 0,
-			  OSD_OSDWIN0MD);
 		if (sd->vpbe_type = VPBE_VERSION_1)
 			osd_modify(sd, OSD_OSDWIN0MD_ATN0E,
 				  enable ? OSD_OSDWIN0MD_ATN0E : 0,
@@ -276,9 +850,6 @@ static void _osd_set_rec601_attenuation(struct osd_state *sd,
 				  OSD_EXTMODE);
 		break;
 	case OSDWIN_OSD1:
-		osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
-			  enable ? OSD_OSDWIN1MD_ATN1E : 0,
-			  OSD_OSDWIN1MD);
 		if (sd->vpbe_type = VPBE_VERSION_1)
 			osd_modify(sd, OSD_OSDWIN1MD_ATN1E,
 				  enable ? OSD_OSDWIN1MD_ATN1E : 0,
@@ -292,6 +863,35 @@ static void _osd_set_rec601_attenuation(struct osd_state *sd,
 	}
 }
 
+static void osd_set_rec601_attenuation(struct osd_state *sd,
+				       enum osd_win_layer osdwin,
+				       int enable)
+{
+	struct osd_state *osd = sd;
+	enum osd_layer layer +	    (osdwin = OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1;
+	struct osd_window_state *win = &osd->win[layer];
+	struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin];
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osdwin_state->rec601_attenuation = (enable != 0);
+	if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR)
+		_osd_set_rec601_attenuation(sd, osdwin, enable);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static enum osd_blending_factor
+osd_get_blending_factor(struct osd_state *sd, enum osd_win_layer osdwin)
+{
+	struct osd_state *osd = sd;
+	struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin];
+
+	return osdwin_state->blend;
+}
+
 static void _osd_set_blending_factor(struct osd_state *sd,
 				     enum osd_win_layer osdwin,
 				     enum osd_blending_factor blend)
@@ -308,6 +908,25 @@ static void _osd_set_blending_factor(struct osd_state *sd,
 	}
 }
 
+static void osd_set_blending_factor(struct osd_state *sd,
+				    enum osd_win_layer osdwin,
+				    enum osd_blending_factor blend)
+{
+	struct osd_state *osd = sd;
+	enum osd_layer layer +	    (osdwin = OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1;
+	struct osd_window_state *win = &osd->win[layer];
+	struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin];
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osdwin_state->blend = blend;
+	if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR)
+		_osd_set_blending_factor(sd, osdwin, blend);
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
 static void _osd_enable_rgb888_pixblend(struct osd_state *sd,
 					enum osd_win_layer osdwin)
 {
@@ -388,6 +1007,28 @@ static void _osd_enable_color_key(struct osd_state *sd,
 	}
 }
 
+static void osd_enable_color_key(struct osd_state *sd,
+				 enum osd_win_layer osdwin,
+				 unsigned colorkey)
+{
+	struct osd_state *osd = sd;
+	enum osd_layer layer +	    (osdwin = OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1;
+	struct osd_window_state *win = &osd->win[layer];
+	struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin];
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osdwin_state->colorkey_blending = 1;
+	osdwin_state->colorkey = colorkey;
+	if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR)
+		_osd_enable_color_key(sd, osdwin, colorkey,
+				      win->lconfig.pixfmt);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
 static void _osd_disable_color_key(struct osd_state *sd,
 				   enum osd_win_layer osdwin)
 {
@@ -421,6 +1062,69 @@ static void _osd_set_osd_clut(struct osd_state *sd,
 	}
 }
 
+static void osd_disable_color_key(struct osd_state *sd,
+				  enum osd_win_layer osdwin)
+{
+	struct osd_state *osd = sd;
+	enum osd_layer layer +	    (osdwin = OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1;
+	struct osd_window_state *win = &osd->win[layer];
+	struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin];
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osdwin_state->colorkey_blending = 0;
+	if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR)
+		_osd_disable_color_key(sd, osdwin);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static void osd_set_osd_clut(struct osd_state *sd, enum osd_win_layer osdwin,
+			     enum osd_clut clut)
+{
+	struct osd_state *osd = sd;
+	enum osd_layer layer +	    (osdwin = OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1;
+	struct osd_window_state *win = &osd->win[layer];
+	struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin];
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	osdwin_state->clut = clut;
+	if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR)
+		_osd_set_osd_clut(sd, osdwin, clut);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+static enum osd_clut osd_get_osd_clut(struct osd_state *sd,
+				      enum osd_win_layer osdwin)
+{
+	struct osd_state *osd = sd;
+	struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin];
+
+	return osdwin_state->clut;
+}
+
+static void osd_get_zoom(struct osd_state *sd, enum osd_layer layer,
+			 enum osd_zoom_factor *h_zoom,
+			 enum osd_zoom_factor *v_zoom)
+{
+	struct osd_state *osd = sd;
+	struct osd_window_state *win = &osd->win[layer];
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	*h_zoom = win->h_zoom;
+	*v_zoom = win->v_zoom;
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
 static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer,
 			  enum osd_zoom_factor h_zoom,
 			  enum osd_zoom_factor v_zoom)
@@ -454,6 +1158,31 @@ static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer,
 		break;
 	}
 }
+static void osd_set_zoom(struct osd_state *sd, enum osd_layer layer,
+			 enum osd_zoom_factor h_zoom,
+			 enum osd_zoom_factor v_zoom)
+{
+	struct osd_state *osd = sd;
+	struct osd_window_state *win = &osd->win[layer];
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	win->h_zoom = h_zoom;
+	win->v_zoom = v_zoom;
+	_osd_set_zoom(sd, layer, h_zoom, v_zoom);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+}
+
+
+static int osd_layer_is_enabled(struct osd_state *sd, enum osd_layer layer)
+{
+	struct osd_state *osd = sd;
+	struct osd_window_state *win = &osd->win[layer];
+
+	return win->is_enabled;
+}
 
 static void _osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
 {
@@ -497,7 +1226,7 @@ static void osd_disable_layer(struct osd_state *sd, enum osd_layer layer)
 static void _osd_enable_attribute_mode(struct osd_state *sd)
 {
 	/* enable attribute mode for OSD1 */
-	osd_set(sd, OSD_OSDWIN1MD_OASW, OSD_OSDWIN1MD);
+	osd_set(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1, OSD_OSDWIN1MD);
 }
 
 static void _osd_enable_layer(struct osd_state *sd, enum osd_layer layer)
@@ -811,7 +1540,7 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
 	case PIXFMT_8BPP:
 	case PIXFMT_RGB565:
 		if (osd->vpbe_type = VPBE_VERSION_1)
-			bad_config = !is_vid_win(layer);
+			bad_config = !is_osd_win(layer);
 		break;
 	case PIXFMT_YCBCRI:
 	case PIXFMT_YCRCBI:
@@ -910,6 +1639,22 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
 	return 0;
 }
 
+static int osd_try_layer_config(struct osd_state *sd, enum osd_layer layer,
+				struct osd_layer_config *lconfig)
+{
+	struct osd_state *osd = sd;
+	int reject_config;
+	unsigned long flags;
+
+	spin_lock_irqsave(&osd->lock, flags);
+
+	reject_config = try_layer_config(sd, layer, lconfig);
+
+	spin_unlock_irqrestore(&osd->lock, flags);
+
+	return reject_config;
+}
+
 static void _osd_disable_vid_rgb888(struct osd_state *sd)
 {
 	/*
@@ -1530,16 +2275,51 @@ static int osd_initialize(struct osd_state *osd)
 }
 
 static const struct vpbe_osd_ops osd_ops = {
+	.set_clut_ycbcr = osd_set_clut_ycbcr,
+	.set_clut_rgb = osd_set_clut_rgb,
+	.set_osd_clut = osd_set_osd_clut,
+	.get_osd_clut = osd_get_osd_clut,
+	.enable_color_key = osd_enable_color_key,
+	.disable_color_key = osd_disable_color_key,
+	.set_blending_factor = osd_set_blending_factor,
+	.get_blending_factor = osd_get_blending_factor,
+	.set_rec601_attenuation = osd_set_rec601_attenuation,
+	.get_rec601_attenuation = osd_get_rec601_attenuation,
+	.set_palette_map = osd_set_palette_map,
+	.get_palette_map = osd_get_palette_map,
+	.set_blink_attribute = osd_set_blink_attribute,
+	.get_blink_attribute = osd_get_blink_attribute,
+	.cursor_enable = osd_cursor_enable,
+	.cursor_disable = osd_cursor_disable,
+	.cursor_is_enabled = osd_cursor_is_enabled,
+	.set_cursor_config = osd_set_cursor_config,
+	.get_cursor_config = osd_get_cursor_config,
+	.set_field_inversion = osd_set_field_inversion,
+	.get_field_inversion = osd_get_field_inversion,
 	.initialize = osd_initialize,
 	.request_layer = osd_request_layer,
 	.release_layer = osd_release_layer,
 	.enable_layer = osd_enable_layer,
 	.disable_layer = osd_disable_layer,
+	.layer_is_enabled = osd_layer_is_enabled,
 	.set_layer_config = osd_set_layer_config,
+	.try_layer_config = osd_try_layer_config,
 	.get_layer_config = osd_get_layer_config,
 	.start_layer = osd_start_layer,
 	.set_left_margin = osd_set_left_margin,
 	.set_top_margin = osd_set_top_margin,
+	.set_interpolation_filter = osd_set_interpolation_filter,
+	.get_interpolation_filter = osd_get_interpolation_filter,
+	.set_osd_expansion = osd_set_osd_expansion,
+	.get_osd_expansion = osd_get_osd_expansion,
+	.set_vid_expansion = osd_set_vid_expansion,
+	.get_vid_expansion = osd_get_vid_expansion,
+	.set_zoom = osd_set_zoom,
+	.get_zoom = osd_get_zoom,
+	.set_background = osd_set_background,
+	.get_background = osd_get_background,
+	.set_rom_clut = osd_set_rom_clut,
+	.get_rom_clut = osd_get_rom_clut,
 };
 
 static int osd_probe(struct platform_device *pdev)
diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c
index 87eef9b..787a3ca 100644
--- a/drivers/media/platform/davinci/vpbe_venc.c
+++ b/drivers/media/platform/davinci/vpbe_venc.c
@@ -24,6 +24,7 @@
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
 #include <linux/slab.h>
+#include <linux/v4l2-dv-timings.h>
 
 #include <mach/hardware.h>
 #include <mach/mux.h>
@@ -31,6 +32,7 @@
 
 #include <linux/io.h>
 
+#include <media/v4l2-mediabus.h>
 #include <media/davinci/vpbe_types.h>
 #include <media/davinci/vpbe_venc.h>
 #include <media/davinci/vpss.h>
@@ -66,6 +68,7 @@ struct venc_state {
 	struct v4l2_subdev sd;
 	struct venc_callback *callback;
 	struct venc_platform_data *pdata;
+	enum v4l2_mbus_pixelcode if_params;
 	struct device *pdev;
 	u32 output;
 	v4l2_std_id std;
@@ -539,6 +542,10 @@ static long venc_ioctl(struct v4l2_subdev *sd,
 			unsigned int cmd,
 			void *arg)
 {
+	struct venc_callback *next, *prev, *callback;
+	struct venc_state *venc = to_state(sd);
+	unsigned long flags;
+	unsigned event = 0;
 	u32 val;
 
 	switch (cmd) {
@@ -547,6 +554,42 @@ static long venc_ioctl(struct v4l2_subdev *sd,
 		*((int *)arg) = ((val & VENC_VSTAT_FIDST) =
 		VENC_VSTAT_FIDST);
 		break;
+	case VENC_REG_CALLBACK:
+		spin_lock_irqsave(&venc->lock, flags);
+		callback = (struct venc_callback *)arg;
+		next = venc->callback;
+		venc->callback = callback;
+		callback->next = next;
+		spin_unlock_irqrestore(&venc->lock, flags);
+		break;
+	case VENC_UNREG_CALLBACK:
+		spin_lock_irqsave(&venc->lock, flags);
+		callback = (struct venc_callback *)arg;
+		prev = venc->callback;
+		if (!prev)
+			return -EINVAL;
+
+		if (prev = callback) {
+			venc->callback = callback->next;
+		} else {
+			while (prev->next && (prev->next != callback))
+				prev = prev->next;
+			if (!prev->next)
+				return -EINVAL;
+			else
+				prev->next = callback->next;
+		}
+		spin_unlock_irqrestore(&venc->lock, flags);
+		break;
+	case VENC_INTERRUPT:
+		callback = venc->callback;
+		event = *((unsigned *)arg);
+		while (callback) {
+			if (callback->mask & event)
+				callback->handler(event, callback->arg);
+		callback = callback->next;
+		}
+		break;
 	default:
 		v4l2_err(sd, "Wrong IOCTL cmd\n");
 		break;
diff --git a/include/media/davinci/vpbe_osd.h b/include/media/davinci/vpbe_osd.h
index de59364..3df34c6 100644
--- a/include/media/davinci/vpbe_osd.h
+++ b/include/media/davinci/vpbe_osd.h
@@ -327,14 +327,59 @@ struct osd_cursor_state {
 struct osd_state;
 
 struct vpbe_osd_ops {
+	void (*set_clut_ycbcr)(struct osd_state *sd,
+			       unsigned char clut_index, unsigned char y,
+			       unsigned char cb, unsigned char cr);
+	void (*set_clut_rgb)(struct osd_state *sd, unsigned char clut_index,
+			     unsigned char r, unsigned char g,
+			     unsigned char b);
+	void (*set_osd_clut)(struct osd_state *sd, enum osd_win_layer osdwin,
+			     enum osd_clut clut);
+	enum osd_clut (*get_osd_clut)(struct osd_state *sd,
+				      enum osd_win_layer osdwin);
+	void (*enable_color_key)(struct osd_state *sd,
+				 enum osd_win_layer osdwin, unsigned colorkey);
+	void (*disable_color_key)(struct osd_state *sd,
+				  enum osd_win_layer osdwin);
+	void (*set_blending_factor)(struct osd_state *sd,
+				    enum osd_win_layer osdwin,
+				    enum osd_blending_factor blend);
+	enum osd_blending_factor (*get_blending_factor)(struct osd_state *sd,
+				  enum osd_win_layer osdwin);
+	void (*set_rec601_attenuation)(struct osd_state *sd,
+				  enum osd_win_layer osdwin, int enable);
+	int (*get_rec601_attenuation)(struct osd_state *sd,
+				  enum osd_win_layer osdwin);
+	void (*set_palette_map)(struct osd_state *sd,
+				enum osd_win_layer osdwin,
+				unsigned char pixel_value,
+				unsigned char clut_index);
+	unsigned char (*get_palette_map)(struct osd_state *sd,
+			enum osd_win_layer osdwin, unsigned char pixel_value);
+	void (*set_blink_attribute)(struct osd_state *sd, int enable,
+				    enum osd_blink_interval blink);
+	void (*get_blink_attribute)(struct osd_state *sd, int *enable,
+				    enum osd_blink_interval *blink);
+	void (*cursor_enable)(struct osd_state *sd);
+	void (*cursor_disable)(struct osd_state *sd);
+	int (*cursor_is_enabled)(struct osd_state *sd);
+	void (*set_cursor_config)(struct osd_state *sd,
+			  struct osd_cursor_config *cursor);
+	void (*get_cursor_config)(struct osd_state *sd,
+			  struct osd_cursor_config *cursor);
+	void (*set_field_inversion)(struct osd_state *sd, int enable);
+	int (*get_field_inversion)(struct osd_state *sd);
 	int (*initialize)(struct osd_state *sd);
 	int (*request_layer)(struct osd_state *sd, enum osd_layer layer);
 	void (*release_layer)(struct osd_state *sd, enum osd_layer layer);
 	int (*enable_layer)(struct osd_state *sd, enum osd_layer layer,
 			    int otherwin);
 	void (*disable_layer)(struct osd_state *sd, enum osd_layer layer);
+	int (*layer_is_enabled)(struct osd_state *sd, enum osd_layer layer);
 	int (*set_layer_config)(struct osd_state *sd, enum osd_layer layer,
 				struct osd_layer_config *lconfig);
+	int (*try_layer_config)(struct osd_state *sd, enum osd_layer layer,
+				struct osd_layer_config *lconfig);
 	void (*get_layer_config)(struct osd_state *sd, enum osd_layer layer,
 				 struct osd_layer_config *lconfig);
 	void (*start_layer)(struct osd_state *sd, enum osd_layer layer,
@@ -343,6 +388,13 @@ struct vpbe_osd_ops {
 	void (*set_left_margin)(struct osd_state *sd, u32 val);
 	void (*set_top_margin)(struct osd_state *sd, u32 val);
 	void (*set_interpolation_filter)(struct osd_state *sd, int filter);
+	int (*get_interpolation_filter)(struct osd_state *sd);
+	int (*set_osd_expansion)(struct osd_state *sd,
+				 enum osd_h_exp_ratio h_exp,
+				 enum osd_v_exp_ratio v_exp);
+	void (*get_osd_expansion)(struct osd_state *sd,
+				  enum osd_h_exp_ratio *h_exp,
+				  enum osd_v_exp_ratio *v_exp);
 	int (*set_vid_expansion)(struct osd_state *sd,
 					enum osd_h_exp_ratio h_exp,
 					enum osd_v_exp_ratio v_exp);
@@ -352,6 +404,16 @@ struct vpbe_osd_ops {
 	void (*set_zoom)(struct osd_state *sd, enum osd_layer layer,
 				enum osd_zoom_factor h_zoom,
 				enum osd_zoom_factor v_zoom);
+	void (*get_zoom)(struct osd_state *sd, enum osd_layer layer,
+			 enum osd_zoom_factor *h_zoom,
+			 enum osd_zoom_factor *v_zoom);
+	void (*set_background)(struct osd_state *sd, enum osd_clut clut,
+			       unsigned char clut_index);
+	void (*get_background)(struct osd_state *sd, enum osd_clut *clut,
+			      unsigned char *clut_index);
+	void (*set_rom_clut)(struct osd_state *sd,
+			     enum osd_rom_clut rom_clut);
+	enum osd_rom_clut (*get_rom_clut)(struct osd_state *sd);
 };
 
 struct osd_state {
diff --git a/include/media/davinci/vpbe_venc.h b/include/media/davinci/vpbe_venc.h
index 476fafc..98d73a9 100644
--- a/include/media/davinci/vpbe_venc.h
+++ b/include/media/davinci/vpbe_venc.h
@@ -29,6 +29,24 @@
 #define VENC_FIRST_FIELD	BIT(1)
 #define VENC_SECOND_FIELD	BIT(2)
 
+/**
+ * struct venc_callback
+ * @next: used internally by the venc driver to maintain a linked list of
+ *        callbacks
+ * @mask: a bitmask specifying the venc event(s) for which the
+ *        callback will be invoked
+ * @handler: the callback routine
+ * @arg: a null pointer that is passed as the second argument to the callback
+ *       routine
+ */
+struct venc_callback {
+	struct venc_callback *next;
+	char *owner;
+	unsigned mask;
+	void (*handler) (unsigned event, void *arg);
+	void *arg;
+};
+
 struct venc_platform_data {
 	int (*setup_pinmux)(enum v4l2_mbus_pixelcode if_type,
 			    int field);
@@ -42,6 +60,9 @@ struct venc_platform_data {
 
 enum venc_ioctls {
 	VENC_GET_FLD = 1,
+	VENC_REG_CALLBACK,
+	VENC_UNREG_CALLBACK,
+	VENC_INTERRUPT,
 };
 
 /* exported functions */
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 1/6] media: davinci: vpbe: fix checkpatch warning for CamelCase
From: Prabhakar Lad @ 2013-04-24 12:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1366804808-22720-1-git-send-email-prabhakar.csengg@gmail.com>

From: Lad, Prabhakar <prabhakar.csengg@gmail.com>

This patch fixes checkpatch warning to avoid CamelCase.

Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
---
 drivers/media/platform/davinci/vpbe_display.c |    2 +-
 drivers/media/platform/davinci/vpbe_osd.c     |   24 ++++++++++++------------
 include/media/davinci/vpbe_osd.h              |    4 ++--
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c
index 1802f11..1c4ba89 100644
--- a/drivers/media/platform/davinci/vpbe_display.c
+++ b/drivers/media/platform/davinci/vpbe_display.c
@@ -929,7 +929,7 @@ static int vpbe_display_s_fmt(struct file *file, void *priv,
 	cfg->interlaced = vpbe_dev->current_timings.interlaced;
 
 	if (V4L2_PIX_FMT_UYVY = pixfmt->pixelformat)
-		cfg->pixfmt = PIXFMT_YCbCrI;
+		cfg->pixfmt = PIXFMT_YCBCRI;
 
 	/* Change of the default pixel format for both video windows */
 	if (V4L2_PIX_FMT_NV12 = pixfmt->pixelformat) {
diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c
index 396a51c..6ed82e8 100644
--- a/drivers/media/platform/davinci/vpbe_osd.c
+++ b/drivers/media/platform/davinci/vpbe_osd.c
@@ -119,7 +119,7 @@ static inline u32 osd_modify(struct osd_state *sd, u32 mask, u32 val,
 #define is_rgb_pixfmt(pixfmt) \
 	(((pixfmt) = PIXFMT_RGB565) || ((pixfmt) = PIXFMT_RGB888))
 #define is_yc_pixfmt(pixfmt) \
-	(((pixfmt) = PIXFMT_YCbCrI) || ((pixfmt) = PIXFMT_YCrCbI) || \
+	(((pixfmt) = PIXFMT_YCBCRI) || ((pixfmt) = PIXFMT_YCRCBI) || \
 	((pixfmt) = PIXFMT_NV12))
 #define MAX_WIN_SIZE OSD_VIDWIN0XP_V0X
 #define MAX_LINE_LENGTH (OSD_VIDWIN0OFST_V0LO << 5)
@@ -360,8 +360,8 @@ static void _osd_enable_color_key(struct osd_state *sd,
 			osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL,
 				  OSD_TRANSPVALL);
 		break;
-	case PIXFMT_YCbCrI:
-	case PIXFMT_YCrCbI:
+	case PIXFMT_YCBCRI:
+	case PIXFMT_YCRCBI:
 		if (sd->vpbe_type = VPBE_VERSION_3)
 			osd_modify(sd, OSD_TRANSPVALU_Y, colorkey,
 				   OSD_TRANSPVALU);
@@ -813,8 +813,8 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer,
 		if (osd->vpbe_type = VPBE_VERSION_1)
 			bad_config = !is_vid_win(layer);
 		break;
-	case PIXFMT_YCbCrI:
-	case PIXFMT_YCrCbI:
+	case PIXFMT_YCBCRI:
+	case PIXFMT_YCRCBI:
 		bad_config = !is_vid_win(layer);
 		break;
 	case PIXFMT_RGB888:
@@ -950,9 +950,9 @@ static void _osd_set_cbcr_order(struct osd_state *sd,
 	 * The caller must ensure that all windows using YC pixfmt use the same
 	 * Cb/Cr order.
 	 */
-	if (pixfmt = PIXFMT_YCbCrI)
+	if (pixfmt = PIXFMT_YCBCRI)
 		osd_clear(sd, OSD_MODE_CS, OSD_MODE);
-	else if (pixfmt = PIXFMT_YCrCbI)
+	else if (pixfmt = PIXFMT_YCRCBI)
 		osd_set(sd, OSD_MODE_CS, OSD_MODE);
 }
 
@@ -981,8 +981,8 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
 				winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
 				_osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0);
 				break;
-			case PIXFMT_YCbCrI:
-			case PIXFMT_YCrCbI:
+			case PIXFMT_YCBCRI:
+			case PIXFMT_YCRCBI:
 				winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT);
 				break;
 			default:
@@ -1128,8 +1128,8 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer,
 					_osd_enable_rgb888_pixblend(sd,
 							OSDWIN_OSD1);
 					break;
-				case PIXFMT_YCbCrI:
-				case PIXFMT_YCrCbI:
+				case PIXFMT_YCBCRI:
+				case PIXFMT_YCRCBI:
 					winmd | 					    (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT);
 					break;
@@ -1508,7 +1508,7 @@ static int osd_initialize(struct osd_state *osd)
 	_osd_init(osd);
 
 	/* set default Cb/Cr order */
-	osd->yc_pixfmt = PIXFMT_YCbCrI;
+	osd->yc_pixfmt = PIXFMT_YCBCRI;
 
 	if (osd->vpbe_type = VPBE_VERSION_3) {
 		/*
diff --git a/include/media/davinci/vpbe_osd.h b/include/media/davinci/vpbe_osd.h
index 42628fc..de59364 100644
--- a/include/media/davinci/vpbe_osd.h
+++ b/include/media/davinci/vpbe_osd.h
@@ -82,9 +82,9 @@ enum osd_pix_format {
 	PIXFMT_4BPP,
 	PIXFMT_8BPP,
 	PIXFMT_RGB565,
-	PIXFMT_YCbCrI,
+	PIXFMT_YCBCRI,
 	PIXFMT_RGB888,
-	PIXFMT_YCrCbI,
+	PIXFMT_YCRCBI,
 	PIXFMT_NV12,
 	PIXFMT_OSD_ATTR,
 };
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 0/6] Davinci fbdev driver and enable it for DMx platform
From: Prabhakar Lad @ 2013-04-24 12:12 UTC (permalink / raw)
  To: linux-arm-kernel

From: Lad, Prabhakar <prabhakar.csengg@gmail.com>

This patch series adds an fbdev driver for Texas
Instruments Davinci SoC.The display subsystem consists
of OSD and VENC, with OSD supporting 2 RGb planes and 
2 video planes.
http://focus.ti.com/general/docs/lit/
getliterature.tsp?literatureNumber=sprue37d&fileType=pdf

A good amount of the OSD and VENC enabling code is
present in the kernel, and this patch series adds the 
fbdev interface.

The fbdev driver exports 4 nodes representing each
plane to the user - from fb0 to fb3.


Lad, Prabhakar (6):
  media: davinci: vpbe: fix checkpatch warning for CamelCase
  media: davinci: vpbe: enable vpbe for fbdev addition
  davinci: vpbe: add fbdev driver
  ARM: davinci: dm355: enable fbdev driver
  ARM: davinci: dm365: enable fbdev driver
  ARM: davinci: dm644x: enable fbdev driver

 arch/arm/mach-davinci/dm355.c                 |   24 +-
 arch/arm/mach-davinci/dm365.c                 |   10 +
 arch/arm/mach-davinci/dm644x.c                |   10 +
 drivers/media/platform/davinci/vpbe_display.c |    8 +-
 drivers/media/platform/davinci/vpbe_osd.c     |  820 ++++++++-
 drivers/media/platform/davinci/vpbe_venc.c    |   43 +
 drivers/video/Kconfig                         |   12 +
 drivers/video/Makefile                        |    1 +
 drivers/video/davincifb.c                     | 2523 +++++++++++++++++++++++++
 drivers/video/davincifb.h                     |  194 ++
 include/media/davinci/vpbe_osd.h              |   66 +-
 include/media/davinci/vpbe_venc.h             |   21 +
 12 files changed, 3702 insertions(+), 30 deletions(-)
 create mode 100644 drivers/video/davincifb.c
 create mode 100644 drivers/video/davincifb.h

-- 
1.7.4.1


^ permalink raw reply

* [PATCH V5 5/5] fbcon: queue work on power efficient wq
From: Viresh Kumar @ 2013-04-24 11:54 UTC (permalink / raw)
  To: tj
  Cc: davem, airlied, axboe, tglx, peterz, mingo, rostedt,
	linux-rt-users, linux-kernel, robin.randhawa, Steve.Bannister,
	Liviu.Dudau, charles.garcia-tobin, arvind.chauhan, linaro-kernel,
	patches, Viresh Kumar, linux-fbdev
In-Reply-To: <cover.1366803121.git.viresh.kumar@linaro.org>

fbcon uses workqueues and it has no real dependency of scheduling these on the
cpu which scheduled them.

On a idle system, it is observed that and idle cpu wakes up many times just to
service this work. It would be better if we can schedule it on a cpu which the
scheduler believes to be the most appropriate one.

This patch replaces system_wq with system_power_efficient_wq.

Cc: Dave Airlie <airlied@redhat.com>
Cc: linux-fbdev@vger.kernel.org
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/video/console/fbcon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 3cd6759..0cae83d 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -404,7 +404,7 @@ static void cursor_timer_handler(unsigned long dev_addr)
 	struct fb_info *info = (struct fb_info *) dev_addr;
 	struct fbcon_ops *ops = info->fbcon_par;
 
-	schedule_work(&info->queue);
+	queue_work(system_power_efficient_wq, &info->queue);
 	mod_timer(&ops->cursor_timer, jiffies + HZ/5);
 }
 
-- 
1.7.12.rc2.18.g61b472e


^ permalink raw reply related

* Re: [PATCH 0/2] drivers/video: mxs-fb: build fixes
From: Shawn Guo @ 2013-04-24 11:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1366790894-20426-1-git-send-email-mpa@pengutronix.de>

On Wed, Apr 24, 2013 at 10:08:12AM +0200, Markus Pargmann wrote:
> Hi,
> 
> mxs-fb commit
> 
> 669406534b4abb827d1bdc39bb5e2d5255818ae2 video: mxsfb: get display timings from device tree
> 
> creates a build failure together with those commits:
> 
> a38884f681a4d044befd30d9f3d19a0821bae63a videomode: simplify videomode Kconfig and Makefile
> 6cd2c7db41eab204b6474534df4ca68a7dc53d86 videomode: videomode_from_timing work
> 
> All of them are in linux-next, so mxs-fb fails to build there.

Fabio already had a patch [1] for that.  I will send it mainline during
3.10-rc.

Shawn

[1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/230938


^ permalink raw reply

* Re: [PATCH 0/2] drivers/video: mxs-fb: build fixes
From: Markus Pargmann @ 2013-04-24  9:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1366790894-20426-1-git-send-email-mpa@pengutronix.de>

On Wed, Apr 24, 2013 at 10:08:12AM +0200, Markus Pargmann wrote:
> Hi,
> 
> mxs-fb commit
> 
> 669406534b4abb827d1bdc39bb5e2d5255818ae2 video: mxsfb: get display timings from device tree
> 
> creates a build failure together with those commits:
> 
> a38884f681a4d044befd30d9f3d19a0821bae63a videomode: simplify videomode Kconfig and Makefile
> 6cd2c7db41eab204b6474534df4ca68a7dc53d86 videomode: videomode_from_timing work
> 
> All of them are in linux-next, so mxs-fb fails to build there.
> 
> Regards,
> 
> Markus
> 
> 
> 

Sorry for the noise. This was already fixed and queued for 3.10-rc.

Regards,

Markus

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCH 2/2] drivers/video: mxs-fb: Fix build, use renamed function
From: Markus Pargmann @ 2013-04-24  8:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1366791772-11133-1-git-send-email-mpa@pengutronix.de>

Kernel build fails with commit 669406534b4abb827d1bdc39bb5e2d5255818ae2

This patch renames videomode_from_timing to videomode_from_timings and
vm.data_flags to vm.flags.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 drivers/video/mxsfb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 1b2c26d..d78827e 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -777,16 +777,16 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
 		struct videomode vm;
 		struct fb_videomode fb_vm;
 
-		ret = videomode_from_timing(timings, &vm, i);
+		ret = videomode_from_timings(timings, &vm, i);
 		if (ret < 0)
 			goto put_timings_node;
 		ret = fb_videomode_from_videomode(&vm, &fb_vm);
 		if (ret < 0)
 			goto put_timings_node;
 
-		if (vm.data_flags & DISPLAY_FLAGS_DE_HIGH)
+		if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
 			host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
-		if (vm.data_flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
+		if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
 			host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT;
 		fb_add_videomode(&fb_vm, &fb_info->modelist);
 	}
-- 
1.8.1.5


^ permalink raw reply related

* [PATCH 1/2] drivers/video: Kconfig, fix mxsfb build
From: Markus Pargmann @ 2013-04-24  8:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1366791772-11133-1-git-send-email-mpa@pengutronix.de>

Kernel build fails with commit 669406534b4abb827d1bdc39bb5e2d5255818ae2

This patch replaces OF_VIDEOMODE symbol by VIDEOMODE_HELPERS.

Signed-off-by: Markus Pargmann <mpa@pengutronix.de>
---
 drivers/video/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d8ecc52..6246056 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2429,7 +2429,7 @@ config FB_MXS
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
 	select FB_MODE_HELPERS
-	select OF_VIDEOMODE
+	select VIDEOMODE_HELPERS
 	help
 	  Framebuffer support for the MXS SoC.
 
-- 
1.8.1.5


^ permalink raw reply related

* [PATCH 0/2] drivers/video: mxs-fb: build fixes
From: Markus Pargmann @ 2013-04-24  8:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1366790894-20426-1-git-send-email-mpa@pengutronix.de>

Sorry, I messed up the email addresses in the last two patches, the following
two are exactly the same just with the correct addresses.

Regards,

Markus


^ permalink raw reply

* [PATCH 2/2] drivers/video: mxs-fb: Fix build, use renamed function
From: Markus Pargmann @ 2013-04-24  8:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1366790894-20426-1-git-send-email-mpa@pengutronix.de>

From: Markus Pargmann <mpargmann@allfex.org>

Kernel build fails with commit 669406534b4abb827d1bdc39bb5e2d5255818ae2

This patch renames videomode_from_timing to videomode_from_timings and
vm.data_flags to vm.flags.

Signed-off-by: Markus Pargmann <mpargmann@allfex.org>
---
 drivers/video/mxsfb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 1b2c26d..d78827e 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -777,16 +777,16 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
 		struct videomode vm;
 		struct fb_videomode fb_vm;
 
-		ret = videomode_from_timing(timings, &vm, i);
+		ret = videomode_from_timings(timings, &vm, i);
 		if (ret < 0)
 			goto put_timings_node;
 		ret = fb_videomode_from_videomode(&vm, &fb_vm);
 		if (ret < 0)
 			goto put_timings_node;
 
-		if (vm.data_flags & DISPLAY_FLAGS_DE_HIGH)
+		if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
 			host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
-		if (vm.data_flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
+		if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
 			host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT;
 		fb_add_videomode(&fb_vm, &fb_info->modelist);
 	}
-- 
1.8.1.5


^ permalink raw reply related

* [PATCH 1/2] drivers/video: Kconfig, fix mxsfb build
From: Markus Pargmann @ 2013-04-24  8:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1366790894-20426-1-git-send-email-mpa@pengutronix.de>

From: Markus Pargmann <mpargmann@allfex.org>

Kernel build fails with commit 669406534b4abb827d1bdc39bb5e2d5255818ae2

This patch replaces OF_VIDEOMODE symbol by VIDEOMODE_HELPERS.

Signed-off-by: Markus Pargmann <mpargmann@allfex.org>
---
 drivers/video/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d8ecc52..6246056 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2429,7 +2429,7 @@ config FB_MXS
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
 	select FB_MODE_HELPERS
-	select OF_VIDEOMODE
+	select VIDEOMODE_HELPERS
 	help
 	  Framebuffer support for the MXS SoC.
 
-- 
1.8.1.5


^ permalink raw reply related

* [PATCH 0/2] drivers/video: mxs-fb: build fixes
From: Markus Pargmann @ 2013-04-24  8:08 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

mxs-fb commit

669406534b4abb827d1bdc39bb5e2d5255818ae2 video: mxsfb: get display timings from device tree

creates a build failure together with those commits:

a38884f681a4d044befd30d9f3d19a0821bae63a videomode: simplify videomode Kconfig and Makefile
6cd2c7db41eab204b6474534df4ca68a7dc53d86 videomode: videomode_from_timing work

All of them are in linux-next, so mxs-fb fails to build there.

Regards,

Markus



^ permalink raw reply

* Re: [PATCH 07/11] fbdev/sa1100fb: use vm_iomap_memory()
From: Russell King - ARM Linux @ 2013-04-23 18:53 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-fbdev, linux-kernel
In-Reply-To: <1366699018-5439-7-git-send-email-tomi.valkeinen@ti.com>

On Tue, Apr 23, 2013 at 09:36:54AM +0300, Tomi Valkeinen wrote:
> Use vm_iomap_memory() instead of [io_]remap_pfn_range().
> vm_iomap_memory() gives us much simpler API to map memory to userspace,
> and reduces possibilities for bugs.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: Russell King <rmk+kernel@arm.linux.org.uk>

Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>

Thanks.

^ permalink raw reply

* [PATCH] Handle efifb with no lfb_base better.
From: Peter Jones @ 2013-04-23 15:23 UTC (permalink / raw)
  To: Florian Tobias Schandinat
  Cc: Josh Boyer, linux-fbdev, linux-kernel, Peter Jones

Right now we get a WARN from platform_device_unregister() because our
platform_device has no ->release function.  This is clearly wrong, but
we should be warning so we can figure out what happened, as this failure
results in bug reports.  So WARN() about the real problem, and use the
registration function that gives us a default release() function.

This fixes the tracback reported at
https://bugzilla.redhat.com/show_bug.cgi?id„0621 , though it does not
fix the actual /problem/ the user is seeing.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
 drivers/video/efifb.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 50fe668..390b61b 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -285,6 +285,7 @@ static void efifb_destroy(struct fb_info *info)
 {
 	if (info->screen_base)
 		iounmap(info->screen_base);
+	fb_dealloc_cmap(&info->cmap);
 	if (request_mem_succeeded)
 		release_mem_region(info->apertures->ranges[0].base,
 				   info->apertures->ranges[0].size);
@@ -382,6 +383,8 @@ static int __init efifb_probe(struct platform_device *dev)
 	if (!screen_info.pages)
 		screen_info.pages = 1;
 	if (!screen_info.lfb_base) {
+		WARN(1, KERN_WARNING, "invalid framebuffer address for "
+				      "device '%s'\n", dev_name(dev));
 		printk(KERN_DEBUG "efifb: invalid framebuffer address\n");
 		return -ENODEV;
 	}
@@ -544,9 +547,7 @@ static struct platform_driver efifb_driver = {
 	},
 };
 
-static struct platform_device efifb_device = {
-	.name	= "efifb",
-};
+static struct platform_device *efifb_device;
 
 static int __init efifb_init(void)
 {
@@ -571,9 +572,9 @@ static int __init efifb_init(void)
 	if (!screen_info.lfb_linelength)
 		return -ENODEV;
 
-	ret = platform_device_register(&efifb_device);
-	if (ret)
-		return ret;
+	efifb_device = platform_device_register_simple("efifb", 0, NULL, 0);
+	if (IS_ERROR(efifb_device))
+		return PTR_ERR(efifb_device);
 
 	/*
 	 * This is not just an optimization.  We will interfere
@@ -582,7 +583,7 @@ static int __init efifb_init(void)
 	 */
 	ret = platform_driver_probe(&efifb_driver, efifb_probe);
 	if (ret) {
-		platform_device_unregister(&efifb_device);
+		platform_device_unregister(efifb_device);
 		return ret;
 	}
 
-- 
1.8.1.4


^ permalink raw reply related

* [PATCH 11/11] fbdev: improve fb_mmap bounds checks
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel
  Cc: Tomi Valkeinen, Steve Glendinning, Bernie Thompson
In-Reply-To: <1366699018-5439-1-git-send-email-tomi.valkeinen@ti.com>

Improve fb_mmap bounds checks in gbefb, smscufx, udlfb and vfb drivers to
prevent possible uint overflows.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Steve Glendinning <steve.glendinning@smsc.com>
Cc: Bernie Thompson <bernie@plugable.com>
---
 drivers/video/gbefb.c   |    4 +++-
 drivers/video/smscufx.c |    6 +++++-
 drivers/video/udlfb.c   |    6 +++++-
 drivers/video/vfb.c     |    7 +++++--
 4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index bda5e39..ceab370 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -1016,7 +1016,9 @@ static int gbefb_mmap(struct fb_info *info,
 	/* check range */
 	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
 		return -EINVAL;
-	if (offset + size > gbe_mem_size)
+	if (size > gbe_mem_size)
+		return -EINVAL;
+	if (offset > gbe_mem_size - size)
 		return -EINVAL;
 
 	/* remap using the fastest write-through mode on architecture */
diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c
index 97bd662..b2b33fc 100644
--- a/drivers/video/smscufx.c
+++ b/drivers/video/smscufx.c
@@ -782,7 +782,11 @@ static int ufx_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
 	unsigned long page, pos;
 
-	if (offset + size > info->fix.smem_len)
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+	if (size > info->fix.smem_len)
+		return -EINVAL;
+	if (offset > info->fix.smem_len - size)
 		return -EINVAL;
 
 	pos = (unsigned long)info->fix.smem_start + offset;
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 86d449e..ec03e72 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -324,7 +324,11 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
 	unsigned long page, pos;
 
-	if (offset + size > info->fix.smem_len)
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+	if (size > info->fix.smem_len)
+		return -EINVAL;
+	if (offset > info->fix.smem_len - size)
 		return -EINVAL;
 
 	pos = (unsigned long)info->fix.smem_start + offset;
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 8bc1f93..ee5985e 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -420,9 +420,12 @@ static int vfb_mmap(struct fb_info *info,
 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
 	unsigned long page, pos;
 
-	if (offset + size > info->fix.smem_len) {
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+	if (size > info->fix.smem_len)
+		return -EINVAL;
+	if (offset > info->fix.smem_len - size)
 		return -EINVAL;
-	}
 
 	pos = (unsigned long)info->fix.smem_start + offset;
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 10/11] fbdev/ps3fb: use vm_iomap_memory()
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel; +Cc: Tomi Valkeinen, Geert Uytterhoeven
In-Reply-To: <1366699018-5439-1-git-send-email-tomi.valkeinen@ti.com>

Use vm_iomap_memory() instead of [io_]remap_pfn_range().
vm_iomap_memory() gives us much simpler API to map memory to userspace,
and reduces possibilities for bugs.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
---
 drivers/video/ps3fb.c |   15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 920c27b..1bdeb08 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -705,21 +705,14 @@ static int ps3fb_pan_display(struct fb_var_screeninfo *var,
 
 static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
-	unsigned long size, offset;
+	int r;
 
-	size = vma->vm_end - vma->vm_start;
-	offset = vma->vm_pgoff << PAGE_SHIFT;
-	if (offset + size > info->fix.smem_len)
-		return -EINVAL;
-
-	offset += info->fix.smem_start;
-	if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
-			    size, vma->vm_page_prot))
-		return -EAGAIN;
+	r = vm_ioremap_memory(vma, info->fix.smem_start, info->fix.smem_len);
 
 	dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n",
 		offset, vma->vm_start);
-	return 0;
+
+	return r;
 }
 
     /*
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 09/11] fbdev/sgivwfb: use vm_iomap_memory()
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel; +Cc: Tomi Valkeinen
In-Reply-To: <1366699018-5439-1-git-send-email-tomi.valkeinen@ti.com>

Use vm_iomap_memory() instead of [io_]remap_pfn_range().
vm_iomap_memory() gives us much simpler API to map memory to userspace,
and reduces possibilities for bugs.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/sgivwfb.c |   20 +++++++-------------
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 2331fad..b2a8912 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -705,23 +705,17 @@ static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,
 static int sgivwfb_mmap(struct fb_info *info,
 			struct vm_area_struct *vma)
 {
-	unsigned long size = vma->vm_end - vma->vm_start;
-	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	int r;
 
-	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-		return -EINVAL;
-	if (offset + size > sgivwfb_mem_size)
-		return -EINVAL;
-	offset += sgivwfb_mem_phys;
 	pgprot_val(vma->vm_page_prot) -	    pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
-	vma->vm_flags |= VM_IO;
-	if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
-						size, vma->vm_page_prot))
-		return -EAGAIN;
+		pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
+
+	r = vm_iomap_memory(vma, sgivwfb_mem_phys, sgivwfb_mem_size);
+
 	printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n",
 	       offset, vma->vm_start);
-	return 0;
+
+	return r;
 }
 
 int __init sgivwfb_setup(char *options)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 08/11] fbdev/vermillion: use vm_iomap_memory()
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel; +Cc: Tomi Valkeinen, Alan Hourihane
In-Reply-To: <1366699018-5439-1-git-send-email-tomi.valkeinen@ti.com>

Use vm_iomap_memory() instead of [io_]remap_pfn_range().
vm_iomap_memory() gives us much simpler API to map memory to userspace,
and reduces possibilities for bugs.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Alan Hourihane <alanh@fairlite.demon.co.uk>
---
 drivers/video/vermilion/vermilion.c |   14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 0aa516f..09a1366 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -1003,24 +1003,18 @@ static int vmlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
 	struct vml_info *vinfo = container_of(info, struct vml_info, info);
-	unsigned long size = vma->vm_end - vma->vm_start;
 	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
 	int ret;
 
-	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-		return -EINVAL;
-	if (offset + size > vinfo->vram_contig_size)
-		return -EINVAL;
 	ret = vmlfb_vram_offset(vinfo, offset);
 	if (ret)
 		return -EINVAL;
-	offset += vinfo->vram_start;
+
 	pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
 	pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
-	if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
-						size, vma->vm_page_prot))
-		return -EAGAIN;
-	return 0;
+
+	return vm_iomap_memory(vma, vinfo->vram_start,
+			vinfo->vram_contig_size);
 }
 
 static int vmlfb_sync(struct fb_info *info)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 07/11] fbdev/sa1100fb: use vm_iomap_memory()
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel; +Cc: Tomi Valkeinen, Russell King
In-Reply-To: <1366699018-5439-1-git-send-email-tomi.valkeinen@ti.com>

Use vm_iomap_memory() instead of [io_]remap_pfn_range().
vm_iomap_memory() gives us much simpler API to map memory to userspace,
and reduces possibilities for bugs.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
---
 drivers/video/sa1100fb.c |   16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index cfbde5e..f34c858 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -556,7 +556,7 @@ static int sa1100fb_mmap(struct fb_info *info,
 			 struct vm_area_struct *vma)
 {
 	struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
-	unsigned long start, len, off = vma->vm_pgoff << PAGE_SHIFT;
+	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
 
 	if (off < info->fix.smem_len) {
 		vma->vm_pgoff += 1; /* skip over the palette */
@@ -564,19 +564,9 @@ static int sa1100fb_mmap(struct fb_info *info,
 					     fbi->map_dma, fbi->map_size);
 	}
 
-	start = info->fix.mmio_start;
-	len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
-
-	if ((vma->vm_end - vma->vm_start + off) > len)
-		return -EINVAL;
-
-	off += start & PAGE_MASK;
-	vma->vm_pgoff = off >> PAGE_SHIFT;
-	vma->vm_flags |= VM_IO;
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-	return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
-				   vma->vm_end - vma->vm_start,
-				   vma->vm_page_prot);
+
+	return vm_iomap_memory(vma, info->fix.mmio_start, info->fix.mmio_len);
 }
 
 static struct fb_ops sa1100fb_ops = {
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 06/11] fbdev/fb-puv3: use vm_iomap_memory()
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel; +Cc: Tomi Valkeinen, Guan Xuetao
In-Reply-To: <1366699018-5439-1-git-send-email-tomi.valkeinen@ti.com>

Use vm_iomap_memory() instead of [io_]remap_pfn_range().
vm_iomap_memory() gives us much simpler API to map memory to userspace,
and reduces possibilities for bugs.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
---
 drivers/video/fb-puv3.c |   14 +-------------
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/drivers/video/fb-puv3.c b/drivers/video/fb-puv3.c
index 7d106f1f..27fc956 100644
--- a/drivers/video/fb-puv3.c
+++ b/drivers/video/fb-puv3.c
@@ -640,21 +640,9 @@ static int unifb_pan_display(struct fb_var_screeninfo *var,
 int unifb_mmap(struct fb_info *info,
 		    struct vm_area_struct *vma)
 {
-	unsigned long size = vma->vm_end - vma->vm_start;
-	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-	unsigned long pos = info->fix.smem_start + offset;
-
-	if (offset + size > info->fix.smem_len)
-		return -EINVAL;
-
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
-	if (io_remap_pfn_range(vma, vma->vm_start, pos >> PAGE_SHIFT, size,
-				vma->vm_page_prot))
-		return -EAGAIN;
-
-	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
-	return 0;
+	return vm_iomap_memory(vma, info->fix.smem_start, info->fix.smem_len);
 }
 
 static struct fb_ops unifb_ops = {
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 05/11] fbdev/controlfb: use vm_iomap_memory()
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel; +Cc: Tomi Valkeinen
In-Reply-To: <1366699018-5439-1-git-send-email-tomi.valkeinen@ti.com>

Use vm_iomap_memory() instead of [io_]remap_pfn_range().
vm_iomap_memory() gives us much simpler API to map memory to userspace,
and reduces possibilities for bugs.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/controlfb.c |   50 ++++++++++++++++++---------------------------
 1 file changed, 20 insertions(+), 30 deletions(-)

diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 0c189b3..67b77b4 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -285,36 +285,26 @@ static int controlfb_pan_display(struct fb_var_screeninfo *var,
 static int controlfb_mmap(struct fb_info *info,
                        struct vm_area_struct *vma)
 {
-       unsigned long off, start;
-       u32 len;
-
-       off = vma->vm_pgoff << PAGE_SHIFT;
-
-       /* frame buffer memory */
-       start = info->fix.smem_start;
-       len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.smem_len);
-       if (off >= len) {
-               /* memory mapped io */
-               off -= len;
-               if (info->var.accel_flags)
-                       return -EINVAL;
-               start = info->fix.mmio_start;
-               len = PAGE_ALIGN((start & ~PAGE_MASK)+info->fix.mmio_len);
-	       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-       } else {
-               /* framebuffer */
-	       vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot);
-       }
-       start &= PAGE_MASK;
-       if ((vma->vm_end - vma->vm_start + off) > len)
-       		return -EINVAL;
-       off += start;
-       vma->vm_pgoff = off >> PAGE_SHIFT;
-       if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
-           vma->vm_end - vma->vm_start, vma->vm_page_prot))
-               return -EAGAIN;
-
-       return 0;
+	unsigned long mmio_pgoff;
+	unsigned long start;
+	u32 len;
+
+	start = info->fix.smem_start;
+	len = info->fix.smem_len;
+	mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
+	if (vma->vm_pgoff >= mmio_pgoff) {
+		if (info->var.accel_flags)
+			return -EINVAL;
+		vma->vm_pgoff -= mmio_pgoff;
+		start = info->fix.mmio_start;
+		len = info->fix.mmio_len;
+		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	} else {
+		/* framebuffer */
+		vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot);
+	}
+
+	return vm_iomap_memory(vma, start, len);
 }
 
 static int controlfb_blank(int blank_mode, struct fb_info *info)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 04/11] fbdev/au1200fb: use vm_iomap_memory()
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel; +Cc: Tomi Valkeinen, Ralf Baechle, Manuel Lauss
In-Reply-To: <1366699018-5439-1-git-send-email-tomi.valkeinen@ti.com>

Use vm_iomap_memory() instead of [io_]remap_pfn_range().
vm_iomap_memory() gives us much simpler API to map memory to userspace,
and reduces possibilities for bugs.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Manuel Lauss <manuel.lauss@googlemail.com>
---
 drivers/video/au1200fb.c |   26 +-------------------------
 1 file changed, 1 insertion(+), 25 deletions(-)

diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 1b59054..6ce6b83 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1235,36 +1235,12 @@ static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
 static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 
 {
-	unsigned int len;
-	unsigned long start=0, off;
 	struct au1200fb_device *fbdev = info->par;
 
-	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
-		return -EINVAL;
-	}
-
-	start = fbdev->fb_phys & PAGE_MASK;
-	len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
-
-	off = vma->vm_pgoff << PAGE_SHIFT;
-
-	if ((vma->vm_end - vma->vm_start + off) > len) {
-		return -EINVAL;
-	}
-
-	off += start;
-	vma->vm_pgoff = off >> PAGE_SHIFT;
-
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 	pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
 
-	vma->vm_flags |= VM_IO;
-
-	return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
-				  vma->vm_end - vma->vm_start,
-				  vma->vm_page_prot);
-
-	return 0;
+	return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);
 }
 
 static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 03/11] fbdev/au1100fb: use vm_iomap_memory()
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel; +Cc: Tomi Valkeinen
In-Reply-To: <1366699018-5439-1-git-send-email-tomi.valkeinen@ti.com>

Use vm_iomap_memory() instead of [io_]remap_pfn_range().
vm_iomap_memory() gives us much simpler API to map memory to userspace,
and reduces possibilities for bugs.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/au1100fb.c |   28 +---------------------------
 1 file changed, 1 insertion(+), 27 deletions(-)

diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index ddabaa8..0473b11 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -375,39 +375,13 @@ void au1100fb_fb_rotate(struct fb_info *fbi, int angle)
 int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
 {
 	struct au1100fb_device *fbdev;
-	unsigned int len;
-	unsigned long start=0, off;
 
 	fbdev = to_au1100fb_device(fbi);
 
-	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
-		return -EINVAL;
-	}
-
-	start = fbdev->fb_phys & PAGE_MASK;
-	len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
-
-	off = vma->vm_pgoff << PAGE_SHIFT;
-
-	if ((vma->vm_end - vma->vm_start + off) > len) {
-		return -EINVAL;
-	}
-
-	off += start;
-	vma->vm_pgoff = off >> PAGE_SHIFT;
-
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 	pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6
 
-	vma->vm_flags |= VM_IO;
-
-	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
-				vma->vm_end - vma->vm_start,
-				vma->vm_page_prot)) {
-		return -EAGAIN;
-	}
-
-	return 0;
+	return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);
 }
 
 static struct fb_ops au1100fb_ops -- 
1.7.10.4


^ permalink raw reply related

* [PATCH 02/11] fbdev/omapfb: use vm_iomap_memory()
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel; +Cc: Tomi Valkeinen
In-Reply-To: <1366699018-5439-1-git-send-email-tomi.valkeinen@ti.com>

Use vm_iomap_memory() instead of [io_]remap_pfn_range().
vm_iomap_memory() gives us much simpler API to map memory to userspace,
and reduces possibilities for bugs.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/omapfb/omapfb-main.c |   30 +++++++-----------------------
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index ca585ef..717f13a 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1101,41 +1101,25 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
 	struct omapfb_info *ofbi = FB2OFB(fbi);
 	struct fb_fix_screeninfo *fix = &fbi->fix;
 	struct omapfb2_mem_region *rg;
-	unsigned long off;
 	unsigned long start;
 	u32 len;
-	int r = -EINVAL;
-
-	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;
+	int r;
 
 	rg = omapfb_get_mem_region(ofbi->region);
 
 	start = omapfb_get_region_paddr(ofbi);
 	len = fix->smem_len;
-	if (off >= len)
-		goto error;
-	if ((vma->vm_end - vma->vm_start + off) > len)
-		goto error;
-
-	off += start;
 
-	DBG("user mmap region start %lx, len %d, off %lx\n", start, len, off);
+	DBG("user mmap region start %lx, len %d, off %lx\n", start, len,
+			vma->vm_pgoff << PAGE_SHIFT);
 
-	vma->vm_pgoff = off >> PAGE_SHIFT;
-	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
 	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 	vma->vm_ops = &mmap_user_ops;
 	vma->vm_private_data = rg;
-	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
-			       vma->vm_end - vma->vm_start,
-			       vma->vm_page_prot)) {
-		r = -EAGAIN;
+
+	r = vm_iomap_memory(vma, start, len);
+	if (r)
 		goto error;
-	}
 
 	/* vm_ops.open won't be called for mmap itself. */
 	atomic_inc(&rg->map_count);
@@ -1144,7 +1128,7 @@ static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
 
 	return 0;
 
- error:
+error:
 	omapfb_put_mem_region(ofbi->region);
 
 	return r;
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 01/11] fbdev/fbmem: use vm_iomap_memory()
From: Tomi Valkeinen @ 2013-04-23  6:36 UTC (permalink / raw)
  To: linux-fbdev, linux-kernel; +Cc: Tomi Valkeinen

Use vm_iomap_memory() instead of [io_]remap_pfn_range().
vm_iomap_memory() gives us much simpler API to map memory to userspace,
and reduces possibilities for bugs.

Original patch from Linus Torvalds <torvalds@linux-foundation.org>

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/fbmem.c |   36 ++++++++++++------------------------
 1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 7c25408..0598aa9 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1373,15 +1373,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
 {
 	struct fb_info *info = file_fb_info(file);
 	struct fb_ops *fb;
-	unsigned long off;
+	unsigned long mmio_pgoff;
 	unsigned long start;
 	u32 len;
 
 	if (!info)
 		return -ENODEV;
-	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
-		return -EINVAL;
-	off = vma->vm_pgoff << PAGE_SHIFT;
 	fb = info->fbops;
 	if (!fb)
 		return -ENODEV;
@@ -1393,32 +1390,23 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
 		return res;
 	}
 
-	/* frame buffer memory */
+	/* Map mmio if pgoff points past the fb */
 	start = info->fix.smem_start;
-	len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
-	if (off >= len) {
-		/* memory mapped io */
-		off -= len;
-		if (info->var.accel_flags) {
-			mutex_unlock(&info->mm_lock);
+	len = info->fix.smem_len;
+	mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
+	if (vma->vm_pgoff >= mmio_pgoff) {
+		if (info->var.accel_flags)
 			return -EINVAL;
-		}
+		vma->vm_pgoff -= mmio_pgoff;
 		start = info->fix.mmio_start;
-		len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
+		len = info->fix.mmio_len;
 	}
 	mutex_unlock(&info->mm_lock);
-	start &= PAGE_MASK;
-	if ((vma->vm_end - vma->vm_start + off) > len)
-		return -EINVAL;
-	off += start;
-	vma->vm_pgoff = off >> PAGE_SHIFT;
-	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by io_remap_pfn_range()*/
+
 	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
-	fb_pgprotect(file, vma, off);
-	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
-			     vma->vm_end - vma->vm_start, vma->vm_page_prot))
-		return -EAGAIN;
-	return 0;
+	fb_pgprotect(file, vma, start);
+
+	return vm_iomap_memory(vma, start, len);
 }
 
 static int
-- 
1.7.10.4


^ permalink raw reply related


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