Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH 08/17] OMAPDSS: TFP410: use devm_gpio_request_one
From: Tomi Valkeinen @ 2012-09-05  8:25 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, archit; +Cc: Tomi Valkeinen
In-Reply-To: <1346833555-31258-1-git-send-email-tomi.valkeinen@ti.com>

Use devm_ version instead of the regular gpio_request_one to simplify
the error handling.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/displays/panel-tfp410.c |   14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 4be9a59..383811c 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -119,8 +119,8 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
 	}
 
 	if (gpio_is_valid(ddata->pd_gpio)) {
-		r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW,
-				"tfp410 pd");
+		r = devm_gpio_request_one(&dssdev->dev, ddata->pd_gpio,
+				GPIOF_OUT_INIT_LOW, "tfp410 pd");
 		if (r) {
 			dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n",
 					ddata->pd_gpio);
@@ -135,8 +135,7 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
 		if (!adapter) {
 			dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
 					i2c_bus_num);
-			r = -EINVAL;
-			goto err_i2c;
+			return -EINVAL;
 		}
 
 		ddata->i2c_adapter = adapter;
@@ -145,10 +144,6 @@ static int tfp410_probe(struct omap_dss_device *dssdev)
 	dev_set_drvdata(&dssdev->dev, ddata);
 
 	return 0;
-err_i2c:
-	if (gpio_is_valid(ddata->pd_gpio))
-		gpio_free(ddata->pd_gpio);
-	return r;
 }
 
 static void __exit tfp410_remove(struct omap_dss_device *dssdev)
@@ -160,9 +155,6 @@ static void __exit tfp410_remove(struct omap_dss_device *dssdev)
 	if (ddata->i2c_adapter)
 		i2c_put_adapter(ddata->i2c_adapter);
 
-	if (gpio_is_valid(ddata->pd_gpio))
-		gpio_free(ddata->pd_gpio);
-
 	dev_set_drvdata(&dssdev->dev, NULL);
 
 	mutex_unlock(&ddata->lock);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 07/17] OMAPDSS: Taal: Reogranize for device tree
From: Tomi Valkeinen @ 2012-09-05  8:25 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, archit; +Cc: Tomi Valkeinen
In-Reply-To: <1346833555-31258-1-git-send-email-tomi.valkeinen@ti.com>

Reorganize taal driver to make it easier to integrate device tree code.
Instead of storing the panel's platform data, we'll "parse" the platform
data and store the required information in driver's own data. This way
adding device tree data parsing is simple.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/displays/panel-taal.c |  127 +++++++++++++++++------------
 1 file changed, 74 insertions(+), 53 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 1255864..4cf9416 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -121,6 +121,18 @@ struct taal_data {
 
 	struct omap_dss_device *dssdev;
 
+	/* panel specific HW info */
+	struct panel_config *panel_config;
+
+	/* panel HW configuration from DT or platform data */
+	int reset_gpio;
+	int ext_te_gpio;
+
+	bool use_dsi_backlight;
+
+	struct omap_dsi_pin_config pin_config;
+
+	/* runtime variables */
 	bool enabled;
 	u8 rotate;
 	bool mirror;
@@ -145,16 +157,8 @@ struct taal_data {
 	bool ulps_enabled;
 	unsigned ulps_timeout;
 	struct delayed_work ulps_work;
-
-	struct panel_config *panel_config;
 };
 
-static inline struct nokia_dsi_panel_data
-*get_panel_data(const struct omap_dss_device *dssdev)
-{
-	return (struct nokia_dsi_panel_data *) dssdev->data;
-}
-
 static void taal_esd_work(struct work_struct *work);
 static void taal_ulps_work(struct work_struct *work);
 
@@ -371,7 +375,6 @@ static void taal_cancel_ulps_work(struct omap_dss_device *dssdev)
 static int taal_enter_ulps(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	int r;
 
 	if (td->ulps_enabled)
@@ -383,7 +386,8 @@ static int taal_enter_ulps(struct omap_dss_device *dssdev)
 	if (r)
 		goto err;
 
-	disable_irq(gpio_to_irq(panel_data->ext_te_gpio));
+	if (gpio_is_valid(td->ext_te_gpio))
+		disable_irq(gpio_to_irq(td->ext_te_gpio));
 
 	omapdss_dsi_display_disable(dssdev, false, true);
 
@@ -405,7 +409,6 @@ err:
 static int taal_exit_ulps(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	int r;
 
 	if (!td->ulps_enabled)
@@ -425,7 +428,8 @@ static int taal_exit_ulps(struct omap_dss_device *dssdev)
 		goto err2;
 	}
 
-	enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
+	if (gpio_is_valid(td->ext_te_gpio))
+		enable_irq(gpio_to_irq(td->ext_te_gpio));
 
 	taal_queue_ulps_work(dssdev);
 
@@ -438,7 +442,8 @@ err2:
 
 	r = taal_panel_reset(dssdev);
 	if (!r) {
-		enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
+		if (gpio_is_valid(td->ext_te_gpio))
+			enable_irq(gpio_to_irq(td->ext_te_gpio));
 		td->ulps_enabled = false;
 	}
 err1:
@@ -835,71 +840,93 @@ static struct attribute_group taal_attr_group = {
 static void taal_hw_reset(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 
-	if (panel_data->reset_gpio = -1)
+	if (!gpio_is_valid(td->reset_gpio))
 		return;
 
-	gpio_set_value(panel_data->reset_gpio, 1);
+	gpio_set_value(td->reset_gpio, 1);
 	if (td->panel_config->reset_sequence.high)
 		udelay(td->panel_config->reset_sequence.high);
 	/* reset the panel */
-	gpio_set_value(panel_data->reset_gpio, 0);
+	gpio_set_value(td->reset_gpio, 0);
 	/* assert reset */
 	if (td->panel_config->reset_sequence.low)
 		udelay(td->panel_config->reset_sequence.low);
-	gpio_set_value(panel_data->reset_gpio, 1);
+	gpio_set_value(td->reset_gpio, 1);
 	/* wait after releasing reset */
 	if (td->panel_config->sleep.hw_reset)
 		msleep(td->panel_config->sleep.hw_reset);
 }
 
+static void taal_probe_pdata(struct taal_data *td,
+		const struct nokia_dsi_panel_data *pdata)
+{
+	td->reset_gpio = pdata->reset_gpio;
+
+	if (pdata->use_ext_te)
+		td->ext_te_gpio = pdata->ext_te_gpio;
+	else
+		td->ext_te_gpio = -1;
+
+	td->esd_interval = pdata->esd_interval;
+	td->ulps_timeout = pdata->ulps_timeout;
+
+	td->use_dsi_backlight = pdata->use_dsi_backlight;
+
+	td->pin_config = pdata->pin_config;
+}
+
 static int taal_probe(struct omap_dss_device *dssdev)
 {
 	struct backlight_properties props;
 	struct taal_data *td;
 	struct backlight_device *bldev = NULL;
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
-	struct panel_config *panel_config = NULL;
 	int r, i;
+	const char *panel_name;
 
 	dev_dbg(&dssdev->dev, "probe\n");
 
-	if (!panel_data || !panel_data->name)
+	td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL);
+	if (!td)
+		return -ENOMEM;
+
+	dev_set_drvdata(&dssdev->dev, td);
+	td->dssdev = dssdev;
+
+	if (dssdev->data) {
+		const struct nokia_dsi_panel_data *pdata = dssdev->data;
+
+		taal_probe_pdata(td, pdata);
+
+		panel_name = pdata->name;
+	} else {
+		return -ENODEV;
+	}
+
+	if (panel_name = NULL)
 		return -EINVAL;
 
 	for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
-		if (strcmp(panel_data->name, panel_configs[i].name) = 0) {
-			panel_config = &panel_configs[i];
+		if (strcmp(panel_name, panel_configs[i].name) = 0) {
+			td->panel_config = &panel_configs[i];
 			break;
 		}
 	}
 
-	if (!panel_config)
+	if (!td->panel_config)
 		return -EINVAL;
 
-	dssdev->panel.timings = panel_config->timings;
+	dssdev->panel.timings = td->panel_config->timings;
 	dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
 	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
 		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
 
-	td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL);
-	if (!td)
-		return -ENOMEM;
-	td->dssdev = dssdev;
-	td->panel_config = panel_config;
-	td->esd_interval = panel_data->esd_interval;
-	td->ulps_enabled = false;
-	td->ulps_timeout = panel_data->ulps_timeout;
-
 	mutex_init(&td->lock);
 
 	atomic_set(&td->do_update, 0);
 
-	dev_set_drvdata(&dssdev->dev, td);
-
-	if (gpio_is_valid(panel_data->reset_gpio)) {
-		r = devm_gpio_request_one(&dssdev->dev, panel_data->reset_gpio,
+	if (gpio_is_valid(td->reset_gpio)) {
+		r = devm_gpio_request_one(&dssdev->dev, td->reset_gpio,
 				GPIOF_OUT_INIT_LOW, "taal rst");
 		if (r) {
 			dev_err(&dssdev->dev, "failed to request reset gpio\n");
@@ -907,17 +934,15 @@ static int taal_probe(struct omap_dss_device *dssdev)
 		}
 	}
 
-	if (panel_data->use_ext_te) {
-		int gpio = panel_data->ext_te_gpio;
-
-		r = devm_gpio_request_one(&dssdev->dev, gpio, GPIOF_IN,
-				"taal irq");
+	if (gpio_is_valid(td->ext_te_gpio)) {
+		r = devm_gpio_request_one(&dssdev->dev, td->ext_te_gpio,
+				GPIOF_IN, "taal irq");
 		if (r) {
 			dev_err(&dssdev->dev, "GPIO request failed\n");
 			return r;
 		}
 
-		r = devm_request_irq(&dssdev->dev, gpio_to_irq(gpio),
+		r = devm_request_irq(&dssdev->dev, gpio_to_irq(td->ext_te_gpio),
 				taal_te_isr,
 				IRQF_TRIGGER_RISING,
 				"taal vsync", dssdev);
@@ -943,7 +968,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
 	taal_hw_reset(dssdev);
 
-	if (panel_data->use_dsi_backlight) {
+	if (td->use_dsi_backlight) {
 		memset(&props, 0, sizeof(struct backlight_properties));
 		props.max_brightness = 255;
 
@@ -1022,11 +1047,10 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
 static int taal_power_on(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	u8 id1, id2, id3;
 	int r;
 
-	r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config);
+	r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to configure DSI pins\n");
 		goto err0;
@@ -1339,7 +1363,6 @@ static int taal_update(struct omap_dss_device *dssdev,
 				    u16 x, u16 y, u16 w, u16 h)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	int r;
 
 	dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
@@ -1363,7 +1386,7 @@ static int taal_update(struct omap_dss_device *dssdev,
 	if (r)
 		goto err;
 
-	if (td->te_enabled && panel_data->use_ext_te) {
+	if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
 		schedule_delayed_work(&td->te_timeout_work,
 				msecs_to_jiffies(250));
 		atomic_set(&td->do_update, 1);
@@ -1402,7 +1425,6 @@ static int taal_sync(struct omap_dss_device *dssdev)
 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	int r;
 
 	if (enable)
@@ -1410,7 +1432,7 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 	else
 		r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
 
-	if (!panel_data->use_ext_te)
+	if (!gpio_is_valid(td->ext_te_gpio))
 		omapdss_dsi_enable_te(dssdev, enable);
 
 	if (td->panel_config->sleep.enable_te)
@@ -1720,7 +1742,6 @@ static void taal_esd_work(struct work_struct *work)
 	struct taal_data *td = container_of(work, struct taal_data,
 			esd_work.work);
 	struct omap_dss_device *dssdev = td->dssdev;
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	u8 state1, state2;
 	int r;
 
@@ -1767,7 +1788,7 @@ static void taal_esd_work(struct work_struct *work)
 	}
 	/* Self-diagnostics result is also shown on TE GPIO line. We need
 	 * to re-enable TE after self diagnostics */
-	if (td->te_enabled && panel_data->use_ext_te) {
+	if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
 		r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
 		if (r)
 			goto err;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 06/17] OMAPDSS: VRAM: Remove clearing with sDMA
From: Tomi Valkeinen @ 2012-09-05  8:25 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, archit; +Cc: Tomi Valkeinen, Russell King - ARM Linux
In-Reply-To: <1346833555-31258-1-git-send-email-tomi.valkeinen@ti.com>

Currently vram.c clears the allocated memory automatically using OMAP
system DMA. In an effort to reduce OMAP dependencies, we'll do the
memory clear with CPU from now on.

The previous patch implemented memory clear in the omapfb driver, and
this patch removes the now obsolete clear functionality from vram.c.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
---
 drivers/video/omap2/vram.c |   56 --------------------------------------------
 1 file changed, 56 deletions(-)

diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 87e421e..f2b15c4 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -34,7 +34,6 @@
 #include <asm/setup.h>
 
 #include <plat/vram.h>
-#include <plat/dma.h>
 
 #ifdef DEBUG
 #define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
@@ -250,59 +249,6 @@ int omap_vram_reserve(unsigned long paddr, size_t size)
 }
 EXPORT_SYMBOL(omap_vram_reserve);
 
-static void _omap_vram_dma_cb(int lch, u16 ch_status, void *data)
-{
-	struct completion *compl = data;
-	complete(compl);
-}
-
-static int _omap_vram_clear(u32 paddr, unsigned pages)
-{
-	struct completion compl;
-	unsigned elem_count;
-	unsigned frame_count;
-	int r;
-	int lch;
-
-	init_completion(&compl);
-
-	r = omap_request_dma(OMAP_DMA_NO_DEVICE, "VRAM DMA",
-			_omap_vram_dma_cb,
-			&compl, &lch);
-	if (r) {
-		pr_err("VRAM: request_dma failed for memory clear\n");
-		return -EBUSY;
-	}
-
-	elem_count = pages * PAGE_SIZE / 4;
-	frame_count = 1;
-
-	omap_set_dma_transfer_params(lch, OMAP_DMA_DATA_TYPE_S32,
-			elem_count, frame_count,
-			OMAP_DMA_SYNC_ELEMENT,
-			0, 0);
-
-	omap_set_dma_dest_params(lch, 0, OMAP_DMA_AMODE_POST_INC,
-			paddr, 0, 0);
-
-	omap_set_dma_color_mode(lch, OMAP_DMA_CONSTANT_FILL, 0x000000);
-
-	omap_start_dma(lch);
-
-	if (wait_for_completion_timeout(&compl, msecs_to_jiffies(1000)) = 0) {
-		omap_stop_dma(lch);
-		pr_err("VRAM: dma timeout while clearing memory\n");
-		r = -EIO;
-		goto err;
-	}
-
-	r = 0;
-err:
-	omap_free_dma(lch);
-
-	return r;
-}
-
 static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
 {
 	struct vram_region *rm;
@@ -337,8 +283,6 @@ found:
 
 		*paddr = start;
 
-		_omap_vram_clear(start, pages);
-
 		return 0;
 	}
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 05/17] OMAPFB: clear framebuffers with CPU
From: Tomi Valkeinen @ 2012-09-05  8:25 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, archit; +Cc: Tomi Valkeinen
In-Reply-To: <1346833555-31258-1-git-send-email-tomi.valkeinen@ti.com>

Currently vram.c clears the allocated memory automatically using OMAP
system DMA. In an effort to reduce OMAP dependencies, we'll do the
memory clear with CPU from now on.

This patch implements clearing of the framebuffer in omapfb, using
cfb_fillrect() to do the actual clear.

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

diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index fc671d3..7afdfcf 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1592,6 +1592,20 @@ static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
 	return 0;
 }
 
+static void omapfb_clear_fb(struct fb_info *fbi)
+{
+	const struct fb_fillrect rect = {
+		.dx = 0,
+		.dy = 0,
+		.width = fbi->var.xres_virtual,
+		.height = fbi->var.yres_virtual,
+		.color = 0,
+		.rop = ROP_COPY,
+	};
+
+	cfb_fillrect(fbi, &rect);
+}
+
 int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
 {
 	struct omapfb_info *ofbi = FB2OFB(fbi);
@@ -1661,6 +1675,8 @@ int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
 			goto err;
 	}
 
+	omapfb_clear_fb(fbi);
+
 	return 0;
 err:
 	omapfb_free_fbmem(fbi);
@@ -1972,6 +1988,16 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
 		}
 	}
 
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		struct fb_info *fbi = fbdev->fbs[i];
+		struct omapfb_info *ofbi = FB2OFB(fbi);
+
+		if (ofbi->region->size = 0)
+			continue;
+
+		omapfb_clear_fb(fbi);
+	}
+
 	/* Enable fb0 */
 	if (fbdev->num_fbs > 0) {
 		struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 04/17] OMAPDSS: remove unnecessary includes
From: Tomi Valkeinen @ 2012-09-05  8:25 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, archit; +Cc: Tomi Valkeinen
In-Reply-To: <1346833555-31258-1-git-send-email-tomi.valkeinen@ti.com>

Remove unnecessary includes from omapdss.

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

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 0de9a7e..e934abb 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -37,8 +37,6 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 
-#include <plat/clock.h>
-
 #include <video/omapdss.h>
 
 #include "dss.h"
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 25fb895..99b9851 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -31,7 +31,6 @@
 #include <linux/regulator/consumer.h>
 
 #include <video/omapdss.h>
-#include <plat/cpu.h>
 
 #include "dss.h"
 #include "dss_features.h"
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 254666f..8d815e3 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -41,7 +41,6 @@
 
 #include <video/omapdss.h>
 #include <video/mipi_display.h>
-#include <plat/clock.h>
 
 #include "dss.h"
 #include "dss_features.h"
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 31a553a..759dbee 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -36,7 +36,6 @@
 #include <video/omapdss.h>
 
 #include <plat/cpu.h>
-#include <plat/clock.h>
 
 #include "dss.h"
 #include "dss_features.h"
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 952c6fa..94e74be 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -32,7 +32,6 @@
 #include <linux/slab.h>
 
 #include <video/omapdss.h>
-#include <plat/cpu.h>
 
 #include "dss.h"
 #include "dss_features.h"
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 4a6caf9..45252cf 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -36,7 +36,6 @@
 #include <linux/pm_runtime.h>
 
 #include <video/omapdss.h>
-#include <plat/cpu.h>
 
 #include "dss.h"
 #include "dss_features.h"
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 03/17] OMAPFB1: remove a non-used table
From: Tomi Valkeinen @ 2012-09-05  8:25 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, archit; +Cc: Tomi Valkeinen
In-Reply-To: <1346833555-31258-1-git-send-email-tomi.valkeinen@ti.com>

The old omapfb driver contains a table for DMA element types, which is
not used. Remove it.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap/omapfb_main.c |    9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index f54b463..4351c43 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -131,15 +131,6 @@ static void omapfb_rqueue_unlock(struct omapfb_device *fbdev)
  * LCD controller and LCD DMA
  * ---------------------------------------------------------------------------
  */
-/* Lookup table to map elem size to elem type. */
-static const int dma_elem_type[] = {
-	0,
-	OMAP_DMA_DATA_TYPE_S8,
-	OMAP_DMA_DATA_TYPE_S16,
-	0,
-	OMAP_DMA_DATA_TYPE_S32,
-};
-
 /*
  * Allocate resources needed for LCD controller and LCD DMA operations. Video
  * memory is allocated from system memory according to the virtual display
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 02/17] OMAPFB1: remove unnecessary includes
From: Tomi Valkeinen @ 2012-09-05  8:25 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, archit; +Cc: Tomi Valkeinen
In-Reply-To: <1346833555-31258-1-git-send-email-tomi.valkeinen@ti.com>

Remove unnecessary includes from the old omapfb driver.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap/hwa742.c        |    1 -
 drivers/video/omap/lcd_ams_delta.c |    1 -
 drivers/video/omap/lcd_palmte.c    |    1 -
 3 files changed, 3 deletions(-)

diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 9f1d23c..f349ee6 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -27,7 +27,6 @@
 #include <linux/clk.h>
 #include <linux/interrupt.h>
 
-#include <plat/dma.h>
 #include "omapfb.h"
 
 #define HWA742_REV_CODE_REG       0x0
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index d3a3113..5cca6b3 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -28,7 +28,6 @@
 #include <linux/gpio.h>
 
 #include <plat/board-ams-delta.h>
-#include <mach/hardware.h>
 
 #include "omapfb.h"
 
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c
index 88c31eb..ff4fb62 100644
--- a/drivers/video/omap/lcd_palmte.c
+++ b/drivers/video/omap/lcd_palmte.c
@@ -23,7 +23,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
-#include <plat/fpga.h>
 #include "omapfb.h"
 
 static int palmte_panel_init(struct lcd_panel *panel,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 01/17] OMAPDSS: Taal: use devm_* functions
From: Tomi Valkeinen @ 2012-09-05  8:25 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, archit; +Cc: Tomi Valkeinen
In-Reply-To: <1346833555-31258-1-git-send-email-tomi.valkeinen@ti.com>

Use devm_ functions in panel-taal.c's probe when possible. Also reorder
the initialization sequence so that devm_ allocations are done before
things that require explicit freeing. This simplifies the probe and
remove functions.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
---
 drivers/video/omap2/displays/panel-taal.c |  118 +++++++++++------------------
 1 file changed, 44 insertions(+), 74 deletions(-)

diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 7b2d7bb..1255864 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -865,10 +865,8 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
 	dev_dbg(&dssdev->dev, "probe\n");
 
-	if (!panel_data || !panel_data->name) {
-		r = -EINVAL;
-		goto err;
-	}
+	if (!panel_data || !panel_data->name)
+		return -EINVAL;
 
 	for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
 		if (strcmp(panel_data->name, panel_configs[i].name) = 0) {
@@ -877,21 +875,17 @@ static int taal_probe(struct omap_dss_device *dssdev)
 		}
 	}
 
-	if (!panel_config) {
-		r = -EINVAL;
-		goto err;
-	}
+	if (!panel_config)
+		return -EINVAL;
 
 	dssdev->panel.timings = panel_config->timings;
 	dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
 	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
 		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
 
-	td = kzalloc(sizeof(*td), GFP_KERNEL);
-	if (!td) {
-		r = -ENOMEM;
-		goto err;
-	}
+	td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL);
+	if (!td)
+		return -ENOMEM;
 	td->dssdev = dssdev;
 	td->panel_config = panel_config;
 	td->esd_interval = panel_data->esd_interval;
@@ -902,26 +896,51 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
 	atomic_set(&td->do_update, 0);
 
-	td->workqueue = create_singlethread_workqueue("taal_esd");
-	if (td->workqueue = NULL) {
-		dev_err(&dssdev->dev, "can't create ESD workqueue\n");
-		r = -ENOMEM;
-		goto err_wq;
-	}
-	INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
-	INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
-
 	dev_set_drvdata(&dssdev->dev, td);
 
 	if (gpio_is_valid(panel_data->reset_gpio)) {
-		r = gpio_request_one(panel_data->reset_gpio, GPIOF_OUT_INIT_LOW,
-				"taal rst");
+		r = devm_gpio_request_one(&dssdev->dev, panel_data->reset_gpio,
+				GPIOF_OUT_INIT_LOW, "taal rst");
 		if (r) {
 			dev_err(&dssdev->dev, "failed to request reset gpio\n");
-			goto err_rst_gpio;
+			return r;
 		}
 	}
 
+	if (panel_data->use_ext_te) {
+		int gpio = panel_data->ext_te_gpio;
+
+		r = devm_gpio_request_one(&dssdev->dev, gpio, GPIOF_IN,
+				"taal irq");
+		if (r) {
+			dev_err(&dssdev->dev, "GPIO request failed\n");
+			return r;
+		}
+
+		r = devm_request_irq(&dssdev->dev, gpio_to_irq(gpio),
+				taal_te_isr,
+				IRQF_TRIGGER_RISING,
+				"taal vsync", dssdev);
+
+		if (r) {
+			dev_err(&dssdev->dev, "IRQ request failed\n");
+			return r;
+		}
+
+		INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work,
+					taal_te_timeout_work_callback);
+
+		dev_dbg(&dssdev->dev, "Using GPIO TE\n");
+	}
+
+	td->workqueue = create_singlethread_workqueue("taal_esd");
+	if (td->workqueue = NULL) {
+		dev_err(&dssdev->dev, "can't create ESD workqueue\n");
+		return -ENOMEM;
+	}
+	INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work);
+	INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
+
 	taal_hw_reset(dssdev);
 
 	if (panel_data->use_dsi_backlight) {
@@ -945,31 +964,6 @@ static int taal_probe(struct omap_dss_device *dssdev)
 		taal_bl_update_status(bldev);
 	}
 
-	if (panel_data->use_ext_te) {
-		int gpio = panel_data->ext_te_gpio;
-
-		r = gpio_request_one(gpio, GPIOF_IN, "taal irq");
-		if (r) {
-			dev_err(&dssdev->dev, "GPIO request failed\n");
-			goto err_gpio;
-		}
-
-		r = request_irq(gpio_to_irq(gpio), taal_te_isr,
-				IRQF_TRIGGER_RISING,
-				"taal vsync", dssdev);
-
-		if (r) {
-			dev_err(&dssdev->dev, "IRQ request failed\n");
-			gpio_free(gpio);
-			goto err_irq;
-		}
-
-		INIT_DELAYED_WORK_DEFERRABLE(&td->te_timeout_work,
-					taal_te_timeout_work_callback);
-
-		dev_dbg(&dssdev->dev, "Using GPIO TE\n");
-	}
-
 	r = omap_dsi_request_vc(dssdev, &td->channel);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to get virtual channel\n");
@@ -993,29 +987,16 @@ static int taal_probe(struct omap_dss_device *dssdev)
 err_vc_id:
 	omap_dsi_release_vc(dssdev, td->channel);
 err_req_vc:
-	if (panel_data->use_ext_te)
-		free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
-err_irq:
-	if (panel_data->use_ext_te)
-		gpio_free(panel_data->ext_te_gpio);
-err_gpio:
 	if (bldev != NULL)
 		backlight_device_unregister(bldev);
 err_bl:
-	if (gpio_is_valid(panel_data->reset_gpio))
-		gpio_free(panel_data->reset_gpio);
-err_rst_gpio:
 	destroy_workqueue(td->workqueue);
-err_wq:
-	kfree(td);
-err:
 	return r;
 }
 
 static void __exit taal_remove(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	struct backlight_device *bldev;
 
 	dev_dbg(&dssdev->dev, "remove\n");
@@ -1023,12 +1004,6 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
 	sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
 	omap_dsi_release_vc(dssdev, td->channel);
 
-	if (panel_data->use_ext_te) {
-		int gpio = panel_data->ext_te_gpio;
-		free_irq(gpio_to_irq(gpio), dssdev);
-		gpio_free(gpio);
-	}
-
 	bldev = td->bldev;
 	if (bldev != NULL) {
 		bldev->props.power = FB_BLANK_POWERDOWN;
@@ -1042,11 +1017,6 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
 
 	/* reset, to be sure that the panel is in a valid state */
 	taal_hw_reset(dssdev);
-
-	if (gpio_is_valid(panel_data->reset_gpio))
-		gpio_free(panel_data->reset_gpio);
-
-	kfree(td);
 }
 
 static int taal_power_on(struct omap_dss_device *dssdev)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 00/17] Misc OMAP DSS patches part 2
From: Tomi Valkeinen @ 2012-09-05  8:25 UTC (permalink / raw)
  To: linux-omap, linux-fbdev, archit; +Cc: Tomi Valkeinen

This series contains miscellaneous patches for omapdss. These are based on the
previous misc patches series
(http://www.mail-archive.com/linux-omap@vger.kernel.org/msg74279.html).

Some cleanups, but three a bit more important things:

* vram.c no longer uses OMAP's sDMA to clear the memory
* fifomerge has been reverted
* Swap GFX and WB fifos to avoid underflows

 Tomi

Tomi Valkeinen (17):
  OMAPDSS: Taal: use devm_* functions
  OMAPFB1: remove unnecessary includes
  OMAPFB1: remove a non-used table
  OMAPDSS: remove unnecessary includes
  OMAPFB: clear framebuffers with CPU
  OMAPDSS: VRAM: Remove clearing with sDMA
  OMAPDSS: Taal: Reogranize for device tree
  OMAPDSS: TFP410: use devm_gpio_request_one
  OMAPDSS: split overlay sysfs code
  OMAPDSS: split manager sysfs code
  OMAPDSS: clean up dss_mgr_set_lcd_config
  OMAPDSS: clean up dss_mgr_set_timings
  Revert "OMAPDSS: APPLY: add fifo-merge support"
  Revert "OMAPDSS: APPLY: add fifo merge support funcs"
  OMAPDSS: remove extra_info completion code
  OMAPDSS: Improve fifo management code
  OMAPDSS: Use WB fifo for GFX overlay

 drivers/video/omap/hwa742.c                 |    1 -
 drivers/video/omap/lcd_ams_delta.c          |    1 -
 drivers/video/omap/lcd_palmte.c             |    1 -
 drivers/video/omap/omapfb_main.c            |    9 -
 drivers/video/omap2/displays/panel-taal.c   |  215 ++++++------
 drivers/video/omap2/displays/panel-tfp410.c |   14 +-
 drivers/video/omap2/dss/Makefile            |    2 +-
 drivers/video/omap2/dss/apply.c             |  298 +---------------
 drivers/video/omap2/dss/dispc.c             |   68 +++-
 drivers/video/omap2/dss/dispc.h             |    4 +
 drivers/video/omap2/dss/dpi.c               |    1 -
 drivers/video/omap2/dss/dsi.c               |    1 -
 drivers/video/omap2/dss/dss.c               |    1 -
 drivers/video/omap2/dss/dss.h               |    7 +
 drivers/video/omap2/dss/manager-sysfs.c     |  499 +++++++++++++++++++++++++++
 drivers/video/omap2/dss/manager.c           |  462 +------------------------
 drivers/video/omap2/dss/overlay-sysfs.c     |  456 ++++++++++++++++++++++++
 drivers/video/omap2/dss/overlay.c           |  421 +---------------------
 drivers/video/omap2/dss/venc.c              |    1 -
 drivers/video/omap2/omapfb/omapfb-main.c    |   26 ++
 drivers/video/omap2/vram.c                  |   56 ---
 include/video/omapdss.h                     |    1 +
 22 files changed, 1180 insertions(+), 1365 deletions(-)
 create mode 100644 drivers/video/omap2/dss/manager-sysfs.c
 create mode 100644 drivers/video/omap2/dss/overlay-sysfs.c

-- 
1.7.9.5


^ permalink raw reply

* [PATCH] vmlfb: use list_move_tail instead of list_del/list_add_tail
From: Wei Yongjun @ 2012-09-05  6:40 UTC (permalink / raw)
  To: linux-fbdev

From: Wei Yongjun <yongjun_wei@trendmicro.com.cn>

Using list_move_tail() instead of list_del() + list_add_tail().

spatch with a semantic match is used to found this problem.
(http://coccinelle.lip6.fr/)

Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
---
 drivers/video/vermilion/vermilion.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 970e43d..083f0c8 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -1168,8 +1168,7 @@ void vmlfb_unregister_subsys(struct vml_sys *sys)
 	list_for_each_entry_safe(entry, next, &global_has_mode, head) {
 		printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n");
 		vmlfb_disable_pipe(entry);
-		list_del(&entry->head);
-		list_add_tail(&entry->head, &global_no_mode);
+		list_move_tail(&entry->head, &global_no_mode);
 	}
 	mutex_unlock(&vml_mutex);
 }



^ permalink raw reply related

* video: exynos_dp: Add device tree based discovery support
From: ~ @ 2012-09-05  4:51 UTC (permalink / raw)
  To: linux-samsung-soc, linux-fbdev, jg1.han; +Cc: FlorianSchandinat

From: Ajay Kumar <ajaykumar.rs@samsung.com>

Add device tree match table for Exynos DP
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
---
 drivers/video/exynos/exynos_dp_core.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index c6c016a..3bccd6b 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/of.h>
 
 #include <video/exynos_dp.h>
 
@@ -1019,6 +1020,14 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id exynos_dp_match[] = {
+	{ .compatible = "samsung,exynos5-dp" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+#endif
+
 static struct platform_driver exynos_dp_driver = {
 	.probe		= exynos_dp_probe,
 	.remove		= __devexit_p(exynos_dp_remove),
@@ -1026,6 +1035,7 @@ static struct platform_driver exynos_dp_driver = {
 		.name	= "exynos-dp",
 		.owner	= THIS_MODULE,
 		.pm	= &exynos_dp_pm_ops,
+		.of_match_table = of_match_ptr(exynos_dp_match),
 	},
 };
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] viafb: don't touch clock state on OLPC XO-1.5
From: Daniel Drake @ 2012-09-04 15:45 UTC (permalink / raw)
  To: linux-fbdev

As detailed in the thread titled "viafb PLL/clock tweaking causes XO-1.5
instability," enabling or disabling the IGA1/IGA2 clocks causes occasional
stability problems during suspend/resume cycles on this platform.

This is rather odd, as the documentation suggests that clocks have two
states (on/off) and the default (stable) configuration is configured to
enable the clock only when it is needed. However, explicitly enabling *or*
disabling the clock triggers this system instability, suggesting that there
is a 3rd state at play here.

Leaving the clock enable/disable registers alone solves this problem.
This fixes spurious reboots during suspend/resume behaviour introduced by
commit b692a63a.

Signed-off-by: Daniel Drake <dsd@laptop.org>
---
 drivers/video/via/via_clock.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c
index af8f26b..db1e392 100644
--- a/drivers/video/via/via_clock.c
+++ b/drivers/video/via/via_clock.c
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/via-core.h>
+#include <asm/olpc.h>
 #include "via_clock.h"
 #include "global.h"
 #include "debug.h"
@@ -289,6 +290,10 @@ static void dummy_set_pll(struct via_pll_config config)
 	printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap);
 }
 
+static void noop_set_clock_state(u8 state)
+{
+}
+
 void via_clock_init(struct via_clock *clock, int gfx_chip)
 {
 	switch (gfx_chip) {
@@ -346,4 +351,18 @@ void via_clock_init(struct via_clock *clock, int gfx_chip)
 		break;
 
 	}
+
+	if (machine_is_olpc()) {
+		/* The OLPC XO-1.5 cannot suspend/resume reliably if the
+		 * IGA1/IGA2 clocks are set as on or off (memory rot
+		 * occasionally happens during suspend under such
+		 * configurations).
+		 *
+		 * The only known stable scenario is to leave this bits as-is,
+		 * which in their default states are documented to enable the
+		 * clock only when it is needed.
+		 */
+		clock->set_primary_clock_state = noop_set_clock_state;
+		clock->set_secondary_clock_state = noop_set_clock_state;
+	}
 }
-- 
1.7.11.4


^ permalink raw reply related

* [GIT PULL] fbdev fixes for 3.6
From: Florian Tobias Schandinat @ 2012-09-04 10:30 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: LKML, linux-fbdev@vger.kernel.org

Hi Linus,

please pull the fixes below.


Thanks,

Florian Tobias Schandinat


The following changes since commit fea7a08acb13524b47711625eebea40a0ede69a0:

  Linux 3.6-rc3 (2012-08-22 13:29:06 -0700)

are available in the git repository at:

  git://github.com/schandinat/linux-2.6.git fbdev-fixes-for-3.6-1

for you to fetch changes up to c1c52848cef52e157468b8879fc3cae23b6f3a99:

  OMAPFB: fix framebuffer console colors (2012-08-23 12:37:22 +0000)

----------------------------------------------------------------
fbdev fixes for 3.6

- a fix by Paul Cercueil to prevent a possible buffer overflow
- a fix by Bruno Prémont to prevent a rare sleep in invalid context
- a fix by Julia Lawall for a double free in auo_k190x
- a fix by Dan Carpenter to prevent a division by zero in mb862xxfb
- a regression fix by Tomi Valkeinen for the SDI output in OMAP
- a fix by Grazvydas Ignotas to fix the console colors in OMAP

----------------------------------------------------------------
Bruno Prémont (1):
      fbcon: Fix bit_putcs() call to kmalloc(s, GFP_KERNEL)

Dan Carpenter (1):
      video: mb862xxfb: prevent divide by zero bug

Grazvydas Ignotas (1):
      OMAPFB: fix framebuffer console colors

Julia Lawall (1):
      drivers/video/auo_k190x.c: drop kfree of devm_kzalloc's data

Paul Cercueil (1):
      fbcon: prevent possible buffer overflow.

Tomi Valkeinen (1):
      OMAPDSS: Fix SDI PLL locking

 drivers/video/auo_k190x.c                |    2 --
 drivers/video/console/bitblit.c          |    2 +-
 drivers/video/console/fbcon.c            |    2 +-
 drivers/video/mb862xx/mb862xxfbdrv.c     |    2 ++
 drivers/video/omap2/dss/sdi.c            |   14 ++++++++++++++
 drivers/video/omap2/omapfb/omapfb-main.c |    2 +-
 6 files changed, 19 insertions(+), 5 deletions(-)

^ permalink raw reply

* Re: [RFC 1/5] video: Add generic display panel core
From: Sascha Hauer @ 2012-09-04  9:24 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: linux-fbdev, dri-devel, linux-leds, linux-media, Bryan Wu,
	Richard Purdie, Tomi Valkeinen, Marcus Lorentzon, Sumit Semwal,
	Archit Taneja, Sebastien Guiriec, Inki Dae, Kyungmin Park
In-Reply-To: <1345164583-18924-2-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Laurent,

On Fri, Aug 17, 2012 at 02:49:39AM +0200, Laurent Pinchart wrote:
> +/**
> + * panel_get_modes - Get video modes supported by the panel
> + * @panel: The panel
> + * @modes: Pointer to an array of modes
> + *
> + * Fill the modes argument with a pointer to an array of video modes. The array
> + * is owned by the panel.
> + *
> + * Return the number of supported modes on success (including 0 if no mode is
> + * supported) or a negative error code otherwise.
> + */
> +int panel_get_modes(struct panel *panel, const struct fb_videomode **modes)
> +{
> +	if (!panel->ops || !panel->ops->get_modes)
> +		return 0;
> +
> +	return panel->ops->get_modes(panel, modes);
> +}
> +EXPORT_SYMBOL_GPL(panel_get_modes);

You have seen my of videomode helper proposal. One result there was that
we want to have ranges for the margin/synclen fields. Does it make sense
to base this new panel framework on a more sophisticated internal
reprentation of the panel parameters? This could then be converted to
struct fb_videomode / struct drm_display_mode as needed. This would also
make it more suitable for drm drivers which are not interested in struct
fb_videomode.

Related to this I suggest to change the API to be able to iterate over
the different modes, like:

struct videomode *panel_get_mode(struct panel *panel, int num);

This was we do not have to have an array of modes in memory, which may
be a burden for some panel drivers.

Sascha


-- 
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

* Re: [RFC 0/5] Generic panel framework
From: Zhou Zhu @ 2012-09-04  8:20 UTC (permalink / raw)
  To: Jun Nie, Laurent Pinchart
  Cc: Tomi Valkeinen, linux-fbdev, dri-devel, linux-leds, linux-media,
	Bryan Wu, Richard Purdie, Marcus Lorentzon, Sumit Semwal,
	Archit Taneja, Sebastien Guiriec, Inki Dae, Kyungmin Park
In-Reply-To: <CAGA24MLnW-i0koFuAsnFQ2mNnrLupkmbxW5T8WYiV3QuoA2vig@mail.gmail.com>

Hi Laurent,

Basically I agree that we need a common panel framework. I just have
some questions:
1.  I think we should add color format in videomode - if we use such
common video mode structure shared across subsystems.
In HDMI, colors are bind with timings tightly. We need a combined
videomode with timing and color format together.
2. I think we should add "set_videomode" interface. It helps HDMI
monitors to set EDIDs.

-- 
Thanks,
-Zhou

^ permalink raw reply

* Re: [PATCH 0/8] OMAPDSS: Misc improvements
From: Tomi Valkeinen @ 2012-09-04  7:22 UTC (permalink / raw)
  To: Tony Lindgren; +Cc: linux-omap, linux-fbdev, archit
In-Reply-To: <1345729514-2441-1-git-send-email-tomi.valkeinen@ti.com>

[-- Attachment #1: Type: text/plain, Size: 2063 bytes --]

Hi Tony,

Can you check the arch/arm patches below, and suggest how you'd like to
go forward with them?

 Tomi

On Thu, 2012-08-23 at 16:45 +0300, Tomi Valkeinen wrote:
> Hi,
> 
> This series contains miscellaneous improvements for omapdss, which I've made
> while implementing device tree support for omapdss. This includes some changes
> to arch/arm/:
> 
> * remove OMAP4 HDMI gpio handling from board files
> * add vdda_hdmi_dac supply for HDMI to twl-common.c
> * remove DSS clock dividers from 4430sdp board file
> 
> Tony, omapdss has dependencies to those changes, and the first change also has
> a dependency to omapdss header file. Is it ok to merge them with other omapdss
> changes?
> 
> Chances for conflict are probably pretty small, 1st and 3rd change are
> pure display stuff, and the 2nd adds the supply to a regulator not used by
> anyone else than DSS.
> 
>  Tomi
> 
> Tomi Valkeinen (8):
>   OMAPDSS: HDMI: Move GPIO handling to HDMI driver
>   OMAPDSS: HDMI: Add delay to wait for 5V power
>   OMAP4: TWL: add vdda_hdmi_dac regulator supply
>   OMAPDSS: HDMI: use vdda_hdmi_dac
>   OMAPDSS: Add DSI fclk maximum to dss_features
>   OMAPDSS: DSI: calculate dsi clock
>   OMAP: 4430SDP: remove DSI clock config from board file
>   OMAPDSS: fix use of dssdev->caps
> 
>  arch/arm/mach-omap2/board-4430sdp.c       |   73 +---------------
>  arch/arm/mach-omap2/board-omap4panda.c    |   27 +-----
>  arch/arm/mach-omap2/twl-common.c          |    6 ++
>  drivers/video/omap2/displays/panel-n8x0.c |    1 +
>  drivers/video/omap2/displays/panel-taal.c |    8 ++
>  drivers/video/omap2/dss/dsi.c             |  131 +++++++++++++++++++++++++++--
>  drivers/video/omap2/dss/dss_features.c    |    2 +
>  drivers/video/omap2/dss/dss_features.h    |    1 +
>  drivers/video/omap2/dss/hdmi.c            |  101 +++++++++++++++++-----
>  drivers/video/omap2/dss/rfbi.c            |    1 -
>  include/video/omapdss.h                   |    4 +
>  11 files changed, 233 insertions(+), 122 deletions(-)
> 


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* RE: [PATCH v5] da8xx-fb: allow frame to complete after disabling LCDC
From: Manjunathappa, Prakash @ 2012-09-04  3:20 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1345813980-14758-1-git-send-email-prakash.pm@ti.com>

Hi Florian Tobias Schandinat,

If you do not have any review comments, could you please accept this patch?

Thanks,
Prakash

On Fri, Aug 24, 2012 at 18:43:00, Manjunathappa, Prakash wrote:
> Wait for active frame transfer to complete after disabling LCDC.
> At the same this wait is not be required when there are sync and
> underflow errors.
> Patch applies for revision 2 of LCDC present am335x.
> More information on disable and reset sequence can be found in
> section 13.4.6 of AM335x TRM @www.ti.com/am335x.
> 
> Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
> ---
> Applies on top of fbdev-next of Florian Tobias Schandinat's tree.
> Since v4:
> Minor nit, removed extra line.
> Since v3:
> Rely on frame done interrupt instead of polling for it.
> Since v2:
> Optimized the lcd_disable_raster function.
> Since v1:
> Changed the commit message, also added link to hardware specification.
>  drivers/video/da8xx-fb.c |   52 +++++++++++++++++++++++++++++++++++----------
>  1 files changed, 40 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 7ae9d53..32f0d06 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -27,6 +27,7 @@
>  #include <linux/platform_device.h>
>  #include <linux/uaccess.h>
>  #include <linux/interrupt.h>
> +#include <linux/wait.h>
>  #include <linux/clk.h>
>  #include <linux/cpufreq.h>
>  #include <linux/console.h>
> @@ -48,6 +49,7 @@
>  #define LCD_PL_LOAD_DONE		BIT(6)
>  #define LCD_FIFO_UNDERFLOW		BIT(5)
>  #define LCD_SYNC_LOST			BIT(2)
> +#define LCD_FRAME_DONE			BIT(0)
>  
>  /* LCD DMA Control Register */
>  #define LCD_DMA_BURST_SIZE(x)		((x) << 4)
> @@ -135,6 +137,8 @@ static resource_size_t da8xx_fb_reg_base;
>  static struct resource *lcdc_regs;
>  static unsigned int lcd_revision;
>  static irq_handler_t lcdc_irq_handler;
> +static wait_queue_head_t frame_done_wq;
> +static int frame_done_flag;
>  
>  static inline unsigned int lcdc_read(unsigned int addr)
>  {
> @@ -288,13 +292,26 @@ static inline void lcd_enable_raster(void)
>  }
>  
>  /* Disable the Raster Engine of the LCD Controller */
> -static inline void lcd_disable_raster(void)
> +static inline void lcd_disable_raster(bool wait_for_frame_done)
>  {
>  	u32 reg;
> +	int ret;
>  
>  	reg = lcdc_read(LCD_RASTER_CTRL_REG);
>  	if (reg & LCD_RASTER_ENABLE)
>  		lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
> +	else
> +		/* return if already disabled */
> +		return;
> +
> +	if ((wait_for_frame_done = true) && (lcd_revision = LCD_VERSION_2)) {
> +		frame_done_flag = 0;
> +		ret = wait_event_interruptible_timeout(frame_done_wq,
> +				frame_done_flag != 0,
> +				msecs_to_jiffies(50));
> +		if (ret = 0)
> +			pr_err("LCD Controller timed out\n");
> +	}
>  }
>  
>  static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
> @@ -321,7 +338,8 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
>  		} else {
>  			reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
>  				LCD_V2_END_OF_FRAME0_INT_ENA |
> -				LCD_V2_END_OF_FRAME1_INT_ENA;
> +				LCD_V2_END_OF_FRAME1_INT_ENA |
> +				LCD_FRAME_DONE;
>  			lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
>  		}
>  		reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
> @@ -638,7 +656,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
>  static void lcd_reset(struct da8xx_fb_par *par)
>  {
>  	/* Disable the Raster if previously Enabled */
> -	lcd_disable_raster();
> +	lcd_disable_raster(false);
>  
>  	/* DMA has to be disabled */
>  	lcdc_write(0, LCD_DMA_CTRL_REG);
> @@ -734,7 +752,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
>  	u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
>  
>  	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
> -		lcd_disable_raster();
> +		lcd_disable_raster(false);
>  		lcdc_write(stat, LCD_MASKED_STAT_REG);
>  		lcd_enable_raster();
>  	} else if (stat & LCD_PL_LOAD_DONE) {
> @@ -744,7 +762,7 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
>  		 * interrupt via the following write to the status register. If
>  		 * this is done after then one gets multiple PL done interrupts.
>  		 */
> -		lcd_disable_raster();
> +		lcd_disable_raster(false);
>  
>  		lcdc_write(stat, LCD_MASKED_STAT_REG);
>  
> @@ -775,6 +793,14 @@ static irqreturn_t lcdc_irq_handler_rev02(int irq, void *arg)
>  			par->vsync_flag = 1;
>  			wake_up_interruptible(&par->vsync_wait);
>  		}
> +
> +		/* Set only when controller is disabled and at the end of
> +		 * active frame
> +		 */
> +		if (stat & BIT(0)) {
> +			frame_done_flag = 1;
> +			wake_up_interruptible(&frame_done_wq);
> +		}
>  	}
>  
>  	lcdc_write(0, LCD_END_OF_INT_IND_REG);
> @@ -789,7 +815,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
>  	u32 reg_ras;
>  
>  	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
> -		lcd_disable_raster();
> +		lcd_disable_raster(false);
>  		lcdc_write(stat, LCD_STAT_REG);
>  		lcd_enable_raster();
>  	} else if (stat & LCD_PL_LOAD_DONE) {
> @@ -799,7 +825,7 @@ static irqreturn_t lcdc_irq_handler_rev01(int irq, void *arg)
>  		 * interrupt via the following write to the status register. If
>  		 * this is done after then one gets multiple PL done interrupts.
>  		 */
> -		lcd_disable_raster();
> +		lcd_disable_raster(false);
>  
>  		lcdc_write(stat, LCD_STAT_REG);
>  
> @@ -898,7 +924,7 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb,
>  	if (val = CPUFREQ_POSTCHANGE) {
>  		if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
>  			par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
> -			lcd_disable_raster();
> +			lcd_disable_raster(true);
>  			lcd_calc_clk_divider(par);
>  			lcd_enable_raster();
>  		}
> @@ -935,7 +961,7 @@ static int __devexit fb_remove(struct platform_device *dev)
>  		if (par->panel_power_ctrl)
>  			par->panel_power_ctrl(0);
>  
> -		lcd_disable_raster();
> +		lcd_disable_raster(true);
>  		lcdc_write(0, LCD_RASTER_CTRL_REG);
>  
>  		/* disable DMA  */
> @@ -1051,7 +1077,7 @@ static int cfb_blank(int blank, struct fb_info *info)
>  		if (par->panel_power_ctrl)
>  			par->panel_power_ctrl(0);
>  
> -		lcd_disable_raster();
> +		lcd_disable_raster(true);
>  		break;
>  	default:
>  		ret = -EINVAL;
> @@ -1356,8 +1382,10 @@ static int __devinit fb_probe(struct platform_device *device)
>  
>  	if (lcd_revision = LCD_VERSION_1)
>  		lcdc_irq_handler = lcdc_irq_handler_rev01;
> -	else
> +	else {
> +		init_waitqueue_head(&frame_done_wq);
>  		lcdc_irq_handler = lcdc_irq_handler_rev02;
> +	}
>  
>  	ret = request_irq(par->irq, lcdc_irq_handler, 0,
>  			DRIVER_NAME, par);
> @@ -1411,7 +1439,7 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
>  		par->panel_power_ctrl(0);
>  
>  	fb_set_suspend(info, 1);
> -	lcd_disable_raster();
> +	lcd_disable_raster(true);
>  	clk_disable(par->lcdc_clk);
>  	console_unlock();
>  
> -- 
> 1.7.1
> 
> 


^ permalink raw reply

* Re: [PATCHv2 1/4] video: mmp display subsystem
From: Zhou Zhu @ 2012-09-04  2:55 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1346293222-13692-1-git-send-email-zzhu3@marvell.com>

Hi, Florian,

Would you please help to review my patches?
Also would you please help to apply them if no more issue.
Thank you very much!

On Thu, Aug 30, 2012 at 10:20 AM, Zhou Zhu <zzhu3@marvell.com> wrote:
> Added mmp display subsystem to support Marvell MMP display controllers.
>
> This subsystem contains 4 parts:
> --fb folder
> --core.c
> --hw folder
> --panel folder
>
> 1. fb folder contains implementation of fb.
> fb get path and ovly from common interface and operates on these structures.
>
> 2. core.c provides common interface for a hardware abstraction.
> Major parts of this interface are:
> a) Path: path is a output device connected to a panel or HDMI TV.
> Main operations of the path is set/get timing/output color.
> fb operates output device through path structure.
> b) Ovly: Ovly is a buffer shown on the path.
> Ovly describes frame buffer and its source/destination size, offset, input
> color, buffer address, z-order, and so on.
> Each fb device maps to one ovly.
>
> 3. hw folder contains implementation of hardware operations defined by core.c.
> It registers paths for fb use.
>
> 4. panel folder contains implementation of panels.
> It's connected to path. Panel drivers would also regiester panels and linked
> to path when probe.
>
> Signed-off-by: Zhou Zhu <zzhu3@marvell.com>
> Signed-off-by: Lisa Du <cldu@marvell.com>

-- 
Thanks,
-Zhou

^ permalink raw reply

* Re: [PATCHv2 1/4] video: mmp display subsystem
From: Zhou Zhu @ 2012-09-04  1:50 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1346293222-13692-1-git-send-email-zzhu3@marvell.com>

Hi, Laurent,

On Sat, Sep 1, 2012 at 2:25 PM, Laurent Pinchart
<laurent.pinchart@ideasonboard.com> wrote:
> Hi Zhou,
>
> On Thursday 30 August 2012 10:20:22 Zhou Zhu wrote:
>> Added mmp display subsystem to support Marvell MMP display controllers.
>>
>> This subsystem contains 4 parts:
>> --fb folder
>> --core.c
>> --hw folder
>> --panel folder
>>
>> 1. fb folder contains implementation of fb.
>> fb get path and ovly from common interface and operates on these structures.
>>
>> 2. core.c provides common interface for a hardware abstraction.
>> Major parts of this interface are:
>> a) Path: path is a output device connected to a panel or HDMI TV.
>> Main operations of the path is set/get timing/output color.
>> fb operates output device through path structure.
>> b) Ovly: Ovly is a buffer shown on the path.
>> Ovly describes frame buffer and its source/destination size, offset, input
>> color, buffer address, z-order, and so on.
>> Each fb device maps to one ovly.
>>
>> 3. hw folder contains implementation of hardware operations defined by
>> core.c. It registers paths for fb use.
>>
>> 4. panel folder contains implementation of panels.
>> It's connected to path. Panel drivers would also regiester panels and linked
>> to path when probe.
>
> You might want to look at the generic panel framework RFC that I have posted
> recently (http://lwn.net/Articles/512363/).
>

I am very interesting in your idea of generic panel framework. I will
review it soon.
Also I will update my drivers to support this generic panel interface
later after your patch is merged.

-- 
Thanks,
-Zhou

^ permalink raw reply

* [PATCH] fbdev: move EXPORT_SYMBOL statements to the functions
From: Jingoo Han @ 2012-09-04  1:35 UTC (permalink / raw)
  To: linux-fbdev

This patch moves the EXPORT_SYMBOL statements to the functions
they belong to.

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 drivers/video/fbcmap.c |   17 +++++------------
 drivers/video/fbcvt.c  |    1 +
 drivers/video/fbmem.c  |   26 ++++++++++++++------------
 drivers/video/fbmon.c  |   22 +++++++++++++++-------
 drivers/video/modedb.c |   20 +++++++++-----------
 5 files changed, 44 insertions(+), 42 deletions(-)

diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 5c3960d..8b25bcd 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -132,6 +132,7 @@ int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp)
 {
 	return fb_alloc_cmap_gfp(cmap, len, transp, GFP_ATOMIC);
 }
+EXPORT_SYMBOL(fb_alloc_cmap);
 
 /**
  *      fb_dealloc_cmap - deallocate a colormap
@@ -152,6 +153,7 @@ void fb_dealloc_cmap(struct fb_cmap *cmap)
 	cmap->red = cmap->green = cmap->blue = cmap->transp = NULL;
 	cmap->len = 0;
 }
+EXPORT_SYMBOL(fb_dealloc_cmap);
 
 /**
  *	fb_copy_cmap - copy a colormap
@@ -184,6 +186,7 @@ int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to)
 		memcpy(to->transp+tooff, from->transp+fromoff, size);
 	return 0;
 }
+EXPORT_SYMBOL(fb_copy_cmap);
 
 int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to)
 {
@@ -259,6 +262,7 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
 
 	return rc;
 }
+EXPORT_SYMBOL(fb_set_cmap);
 
 int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info)
 {
@@ -319,7 +323,7 @@ const struct fb_cmap *fb_default_cmap(int len)
 	return &default_8_colors;
     return &default_16_colors;
 }
-
+EXPORT_SYMBOL(fb_default_cmap);
 
 /**
  *	fb_invert_cmaps - invert all defaults colormaps
@@ -353,15 +357,4 @@ void fb_invert_cmaps(void)
 	blue16[i] = ~blue16[i];
     }
 }
-
-
-    /*
-     *  Visible symbols for modules
-     */
-
-EXPORT_SYMBOL(fb_alloc_cmap);
-EXPORT_SYMBOL(fb_dealloc_cmap);
-EXPORT_SYMBOL(fb_copy_cmap);
-EXPORT_SYMBOL(fb_set_cmap);
-EXPORT_SYMBOL(fb_default_cmap);
 EXPORT_SYMBOL(fb_invert_cmaps);
diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c
index 7cb715d..319b5c4 100644
--- a/drivers/video/fbcvt.c
+++ b/drivers/video/fbcvt.c
@@ -377,3 +377,4 @@ int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb)
 
 	return 0;
 }
+EXPORT_SYMBOL(fb_find_mode_cvt);
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 3ff0105..e11ac80 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -43,8 +43,12 @@
 #define FBPIXMAPSIZE	(1024 * 8)
 
 static DEFINE_MUTEX(registration_lock);
+
 struct fb_info *registered_fb[FB_MAX] __read_mostly;
+EXPORT_SYMBOL(registered_fb);
+
 int num_registered_fb __read_mostly;
+EXPORT_SYMBOL(num_registered_fb);
 
 static struct fb_info *get_fb_info(unsigned int idx)
 {
@@ -182,6 +186,7 @@ char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size
 
 	return addr;
 }
+EXPORT_SYMBOL(fb_get_buffer_offset);
 
 #ifdef CONFIG_LOGO
 
@@ -665,9 +670,11 @@ int fb_show_logo(struct fb_info *info, int rotate)
 
 	return y;
 }
+EXPORT_SYMBOL(fb_show_logo);
 #else
 int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }
 int fb_show_logo(struct fb_info *info, int rotate) { return 0; }
+EXPORT_SYMBOL(fb_show_logo);
 #endif /* CONFIG_LOGO */
 
 static void *fb_seq_start(struct seq_file *m, loff_t *pos)
@@ -909,6 +916,7 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
 		info->var.vmode &= ~FB_VMODE_YWRAP;
 	return 0;
 }
+EXPORT_SYMBOL(fb_pan_display);
 
 static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var,
 			 u32 activate)
@@ -1042,6 +1050,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
  done:
 	return ret;
 }
+EXPORT_SYMBOL(fb_set_var);
 
 int
 fb_blank(struct fb_info *info, int blank)
@@ -1073,6 +1082,7 @@ fb_blank(struct fb_info *info, int blank)
 
  	return ret;
 }
+EXPORT_SYMBOL(fb_blank);
 
 static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
 			unsigned long arg)
@@ -1734,6 +1744,7 @@ register_framebuffer(struct fb_info *fb_info)
 
 	return ret;
 }
+EXPORT_SYMBOL(register_framebuffer);
 
 /**
  *	unregister_framebuffer - releases a frame buffer device
@@ -1762,6 +1773,7 @@ unregister_framebuffer(struct fb_info *fb_info)
 
 	return ret;
 }
+EXPORT_SYMBOL(unregister_framebuffer);
 
 /**
  *	fb_set_suspend - low level driver signals suspend
@@ -1785,6 +1797,7 @@ void fb_set_suspend(struct fb_info *info, int state)
 		fb_notifier_call_chain(FB_EVENT_RESUME, &event);
 	}
 }
+EXPORT_SYMBOL(fb_set_suspend);
 
 /**
  *	fbmem_init - init frame buffer subsystem
@@ -1904,6 +1917,7 @@ int fb_get_options(char *name, char **option)
 
 	return retval;
 }
+EXPORT_SYMBOL(fb_get_options);
 
 #ifndef MODULE
 /**
@@ -1955,16 +1969,4 @@ __setup("video=", video_setup);
      *  Visible symbols for modules
      */
 
-EXPORT_SYMBOL(register_framebuffer);
-EXPORT_SYMBOL(unregister_framebuffer);
-EXPORT_SYMBOL(num_registered_fb);
-EXPORT_SYMBOL(registered_fb);
-EXPORT_SYMBOL(fb_show_logo);
-EXPORT_SYMBOL(fb_set_var);
-EXPORT_SYMBOL(fb_blank);
-EXPORT_SYMBOL(fb_pan_display);
-EXPORT_SYMBOL(fb_get_buffer_offset);
-EXPORT_SYMBOL(fb_set_suspend);
-EXPORT_SYMBOL(fb_get_options);
-
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index cef6557..9af9202 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -675,6 +675,7 @@ void fb_destroy_modedb(struct fb_videomode *modedb)
 {
 	kfree(modedb);
 }
+EXPORT_SYMBOL(fb_destroy_modedb);
 
 static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs)
 {
@@ -917,6 +918,7 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
 	}
 	return 1;
 }
+EXPORT_SYMBOL(fb_parse_edid);
 
 void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
 {
@@ -981,6 +983,7 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
 
 	DPRINTK("====================\n");
 }
+EXPORT_SYMBOL(fb_edid_to_monspecs);
 
 /**
  * fb_edid_add_monspecs() - add monitor video modes from E-EDID data
@@ -1065,6 +1068,7 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
 	specs->modedb = m;
 	specs->modedb_len = specs->modedb_len + num + svd_n;
 }
+EXPORT_SYMBOL(fb_edid_add_monspecs);
 
 /*
  * VESA Generalized Timing Formula (GTF)
@@ -1373,26 +1377,36 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf
 	kfree(timings);
 	return err;
 }
+EXPORT_SYMBOL(fb_get_mode);
 #else
 int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
 {
 	return 1;
 }
+EXPORT_SYMBOL(fb_parse_edid);
+
 void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
 {
 	specs = NULL;
 }
+EXPORT_SYMBOL(fb_edid_to_monspecs);
+
 void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)
 {
 }
+EXPORT_SYMBOL(fb_edid_add_monspecs);
+
 void fb_destroy_modedb(struct fb_videomode *modedb)
 {
 }
+EXPORT_SYMBOL(fb_destroy_modedb);
+
 int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var,
 		struct fb_info *info)
 {
 	return -EINVAL;
 }
+EXPORT_SYMBOL(fb_get_mode);
 #endif /* CONFIG_FB_MODE_HELPERS */
 
 /*
@@ -1457,6 +1471,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info)
 		pixclock < dclkmin || pixclock > dclkmax) ?
 		-EINVAL : 0;
 }
+EXPORT_SYMBOL(fb_validate_mode);
 
 #if defined(CONFIG_FIRMWARE_EDID) && defined(CONFIG_X86)
 
@@ -1489,10 +1504,3 @@ const unsigned char *fb_firmware_edid(struct device *device)
 }
 #endif
 EXPORT_SYMBOL(fb_firmware_edid);
-
-EXPORT_SYMBOL(fb_parse_edid);
-EXPORT_SYMBOL(fb_edid_to_monspecs);
-EXPORT_SYMBOL(fb_edid_add_monspecs);
-EXPORT_SYMBOL(fb_get_mode);
-EXPORT_SYMBOL(fb_validate_mode);
-EXPORT_SYMBOL(fb_destroy_modedb);
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index a9a907c..b803677 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -765,6 +765,7 @@ done:
 	DPRINTK("No valid mode found\n");
 	return 0;
 }
+EXPORT_SYMBOL(fb_find_mode);
 
 /**
  * fb_var_to_videomode - convert fb_var_screeninfo to fb_videomode
@@ -809,6 +810,7 @@ void fb_var_to_videomode(struct fb_videomode *mode,
 	hfreq = pixclock/htotal;
 	mode->refresh = hfreq/vtotal;
 }
+EXPORT_SYMBOL(fb_var_to_videomode);
 
 /**
  * fb_videomode_to_var - convert fb_videomode to fb_var_screeninfo
@@ -834,6 +836,7 @@ void fb_videomode_to_var(struct fb_var_screeninfo *var,
 	var->sync = mode->sync;
 	var->vmode = mode->vmode & FB_VMODE_MASK;
 }
+EXPORT_SYMBOL(fb_videomode_to_var);
 
 /**
  * fb_mode_is_equal - compare 2 videomodes
@@ -858,6 +861,7 @@ int fb_mode_is_equal(const struct fb_videomode *mode1,
 		mode1->sync         = mode2->sync &&
 		mode1->vmode        = mode2->vmode);
 }
+EXPORT_SYMBOL(fb_mode_is_equal);
 
 /**
  * fb_find_best_mode - find best matching videomode
@@ -903,6 +907,7 @@ const struct fb_videomode *fb_find_best_mode(const struct fb_var_screeninfo *var
 	}
 	return best;
 }
+EXPORT_SYMBOL(fb_find_best_mode);
 
 /**
  * fb_find_nearest_mode - find closest videomode
@@ -945,6 +950,7 @@ const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode,
 
 	return best;
 }
+EXPORT_SYMBOL(fb_find_nearest_mode);
 
 /**
  * fb_match_mode - find a videomode which exactly matches the timings in var
@@ -970,6 +976,7 @@ const struct fb_videomode *fb_match_mode(const struct fb_var_screeninfo *var,
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(fb_match_mode);
 
 /**
  * fb_add_videomode - adds videomode entry to modelist
@@ -1005,6 +1012,7 @@ int fb_add_videomode(const struct fb_videomode *mode, struct list_head *head)
 	}
 	return 0;
 }
+EXPORT_SYMBOL(fb_add_videomode);
 
 /**
  * fb_delete_videomode - removed videomode entry from modelist
@@ -1064,6 +1072,7 @@ void fb_videomode_to_modelist(const struct fb_videomode *modedb, int num,
 			return;
 	}
 }
+EXPORT_SYMBOL(fb_videomode_to_modelist);
 
 const struct fb_videomode *fb_find_best_display(const struct fb_monspecs *specs,
 					        struct list_head *head)
@@ -1124,14 +1133,3 @@ finished:
 	return best;
 }
 EXPORT_SYMBOL(fb_find_best_display);
-
-EXPORT_SYMBOL(fb_videomode_to_var);
-EXPORT_SYMBOL(fb_var_to_videomode);
-EXPORT_SYMBOL(fb_mode_is_equal);
-EXPORT_SYMBOL(fb_add_videomode);
-EXPORT_SYMBOL(fb_match_mode);
-EXPORT_SYMBOL(fb_find_best_mode);
-EXPORT_SYMBOL(fb_find_nearest_mode);
-EXPORT_SYMBOL(fb_videomode_to_modelist);
-EXPORT_SYMBOL(fb_find_mode);
-EXPORT_SYMBOL(fb_find_mode_cvt);
-- 
1.7.1



^ permalink raw reply related

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
From: Archit Taneja @ 2012-09-03  9:38 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: rob, linux-omap, linux-fbdev
In-Reply-To: <1346425698.16067.52.camel@deskari>

On Friday 31 August 2012 08:38 PM, Tomi Valkeinen wrote:
> On Fri, 2012-08-31 at 17:45 +0300, Tomi Valkeinen wrote:
>
>> So I'm not really against having the enum. It just would've been neat to
>> have the output type and instance number encoded into this enum, so that
>> it'd be easy to extract either one. But that kinda ruins the possibility
>> to use it in a bit mask.
>
> Hmm, this is just a non-finished idea (and it's late Friday... =) that
> came to my mind:
>
> I had a brief look at TRMs for different OMAPs (omap4/5/6), and it looks
> like the maximum output options for one manager is 4 (LCD2 on omap4460).
> Usually there are just 2 or 3.
>
> So, we could trust that the above holds and do this so that we use a u32
> field to hold four 8 bit output options. In 8 bits we can combine two
> values from 0 to 15. 15 should be more than enough for output display
> types and output instances.
>
> Then with helpers like these:
>
> /* second DSI instance */
> #define DSI1 ((1 << 4) | DISPLAY_TYPE_DSI)
> /* first DPI instance */
> #define DPI0 ((0 << 4) | DISPLAY_TYPE_DPI)

Okay, so DISPLAY_TYPE_DSI / DPI can't be a number left shifted any 
more(that would limit us to have only 4 types of output display types), 
like we have right now, they would need to be 0, 1, 2, 3 and so on. So 
with this approach, we could extract the instance number quickly, but we 
may not be able to check if the manager supports the output display type 
in constant time.

>
> an example output options for a manager that can be connected to DSI1
> and DPI0 could be:
>
> (DSI1 << 8) | (DPI0)
>
> This could be parsed with a for loop, going though the 4 bytes of the
> u32 value. This would allow us to avoid managing a real list, and we
> could extract the instance and the type from the value. Of course we
> could also extend the field to u64 to hold 8 outputs if need be.

Probably we could have a u64, and 2 bytes for each output, and a bit 
mask for both output instance and output display type. We could have 
display type enums as:

DISPLAY_TYPE_DPI	1 << 5
DISPLAY_TYPE_DSI	1 << 6
DISPLAY_TYPE_VENC	1 << 7
DISPLAY_TYPE_HDMI	1 << 8
DISPLAY_TYPE_SDI	1 << 9
DISPLAY_TYPE_RFBI	1 << 10
...

>
> Whether this would be worth it compared to simple bitmask, I'm not sure
> =). Depends how much we need to extract the ID and type.

Anyway, I don't think I'll try to implement this in this series. I'll 
stick to the output instance enums for now.

Archit


^ permalink raw reply

* Re: [PATCH v2 09/23] OMAPDSS: Create links between managers, outputs and devices
From: Tomi Valkeinen @ 2012-09-03  9:35 UTC (permalink / raw)
  To: Archit Taneja; +Cc: rob, linux-omap, linux-fbdev
In-Reply-To: <504477CD.10901@ti.com>

[-- Attachment #1: Type: text/plain, Size: 3090 bytes --]

On Mon, 2012-09-03 at 14:56 +0530, Archit Taneja wrote:
> On Friday 31 August 2012 08:38 PM, Tomi Valkeinen wrote:
> > On Fri, 2012-08-31 at 17:45 +0300, Tomi Valkeinen wrote:
> >
> >> So I'm not really against having the enum. It just would've been neat to
> >> have the output type and instance number encoded into this enum, so that
> >> it'd be easy to extract either one. But that kinda ruins the possibility
> >> to use it in a bit mask.
> >
> > Hmm, this is just a non-finished idea (and it's late Friday... =) that
> > came to my mind:
> >
> > I had a brief look at TRMs for different OMAPs (omap4/5/6), and it looks
> > like the maximum output options for one manager is 4 (LCD2 on omap4460).
> > Usually there are just 2 or 3.
> >
> > So, we could trust that the above holds and do this so that we use a u32
> > field to hold four 8 bit output options. In 8 bits we can combine two
> > values from 0 to 15. 15 should be more than enough for output display
> > types and output instances.
> >
> > Then with helpers like these:
> >
> > /* second DSI instance */
> > #define DSI1 ((1 << 4) | DISPLAY_TYPE_DSI)
> > /* first DPI instance */
> > #define DPI0 ((0 << 4) | DISPLAY_TYPE_DPI)
> 
> Okay, so DISPLAY_TYPE_DSI / DPI can't be a number left shifted any 
> more(that would limit us to have only 4 types of output display types), 
> like we have right now, they would need to be 0, 1, 2, 3 and so on. So 
> with this approach, we could extract the instance number quickly, but we 
> may not be able to check if the manager supports the output display type 
> in constant time.

True, it wouldn't be constant. But it'd be checking between one to four
bytes, so I think it's quite fast =).

> > an example output options for a manager that can be connected to DSI1
> > and DPI0 could be:
> >
> > (DSI1 << 8) | (DPI0)
> >
> > This could be parsed with a for loop, going though the 4 bytes of the
> > u32 value. This would allow us to avoid managing a real list, and we
> > could extract the instance and the type from the value. Of course we
> > could also extend the field to u64 to hold 8 outputs if need be.
> 
> Probably we could have a u64, and 2 bytes for each output, and a bit 
> mask for both output instance and output display type. We could have 
> display type enums as:
> 
> DISPLAY_TYPE_DPI	1 << 5
> DISPLAY_TYPE_DSI	1 << 6
> DISPLAY_TYPE_VENC	1 << 7
> DISPLAY_TYPE_HDMI	1 << 8
> DISPLAY_TYPE_SDI	1 << 9
> DISPLAY_TYPE_RFBI	1 << 10
> ...
> 
> >
> > Whether this would be worth it compared to simple bitmask, I'm not sure
> > =). Depends how much we need to extract the ID and type.
> 
> Anyway, I don't think I'll try to implement this in this series. I'll 
> stick to the output instance enums for now.

Sure. And as I said, I'm not sure if it's worth it. We currently have
multiple instances only for DSI, and only two instances there. And I
think we need to handle the instance number only in a few places. It's
not too much to do:

if (type == DSI1) ... else if (type == DSI2) ...

 Tomi


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* [PATCH] video: exynos_dp: replace link_status with link_align to check channel equalization
From: Jingoo Han @ 2012-09-03  8:50 UTC (permalink / raw)
  To: linux-fbdev

To check channel equalization, the value of LANE_ALIGN_STATUS_UPDATED is
necessary in exynos_dp_channel_eq_ok(). Also, link_align includes this value.
However, link_status does not include this value, so it makes the problem
that channel equalization is failed during link training.

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
---
 drivers/video/exynos/exynos_dp_core.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index f57c915..cdc1398 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -587,7 +587,7 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 			dp->link_train.training_lane[lane] = training_lane;
 		}
 
-		if (exynos_dp_channel_eq_ok(link_status, lane_count) = 0) {
+		if (exynos_dp_channel_eq_ok(link_align, lane_count) = 0) {
 			/* traing pattern Set to Normal */
 			exynos_dp_training_pattern_dis(dp);
 
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH] video: s3c2410fb: Use pr_* and dev_* instead of printk
From: Jingoo Han @ 2012-09-03  0:54 UTC (permalink / raw)
  To: linux-fbdev

On Friday, August 31, 2012 8:50 PM Sachin Kamat wrote:
> 
> printk calls are replaced by pr_* and dev_* calls to silence
> checkpatch warnings.
> 
> Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
> ---
>  drivers/video/s3c2410fb.c |   18 ++++++++++--------
>  1 files changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
> index 77f34c6..a54e3f9 100644
> --- a/drivers/video/s3c2410fb.c
> +++ b/drivers/video/s3c2410fb.c
> @@ -11,6 +11,8 @@
>   * Driver based on skeletonfb.c, sa1100fb.c and others.
>  */
> 
> +#define pr_fmt(fmt) "s3c2410fb: " fmt
> +

Hi Sachin Kamat,

How about using KBUILD_MODNAME instead of "s3c2410fb: "?
It is because prefix is the same with module name.

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt


Best regards,
Jingoo Han

>  #include <linux/module.h>
>  #include <linux/kernel.h>
>  #include <linux/err.h>
> @@ -48,7 +50,7 @@ static int debug	= 1;
>  static int debug;
>  #endif
> 
> -#define dprintk(msg...)	if (debug) printk(KERN_DEBUG "s3c2410fb: " msg);
> +#define dprintk(msg...)	if (debug) pr_debug(msg);
> 
>  /* useful functions */
> 
> @@ -598,11 +600,11 @@ static int s3c2410fb_debug_store(struct device *dev,
>  	if (strnicmp(buf, "on", 2) = 0 ||
>  	    strnicmp(buf, "1", 1) = 0) {
>  		debug = 1;
> -		printk(KERN_DEBUG "s3c2410fb: Debug On");
> +		dev_dbg(dev, "s3c2410fb: Debug On");
>  	} else if (strnicmp(buf, "off", 3) = 0 ||
>  		   strnicmp(buf, "0", 1) = 0) {
>  		debug = 0;
> -		printk(KERN_DEBUG "s3c2410fb: Debug Off");
> +		dev_dbg(dev, "s3c2410fb: Debug Off");
>  	} else {
>  		return -EINVAL;
>  	}
> @@ -921,7 +923,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
> 
>  	info->clk = clk_get(NULL, "lcd");
>  	if (IS_ERR(info->clk)) {
> -		printk(KERN_ERR "failed to get lcd clock source\n");
> +		dev_err(&pdev->dev, "failed to get lcd clock source\n");
>  		ret = PTR_ERR(info->clk);
>  		goto release_irq;
>  	}
> @@ -947,7 +949,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
>  	/* Initialize video memory */
>  	ret = s3c2410fb_map_video_memory(fbinfo);
>  	if (ret) {
> -		printk(KERN_ERR "Failed to allocate video RAM: %d\n", ret);
> +		dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
>  		ret = -ENOMEM;
>  		goto release_clock;
>  	}
> @@ -970,7 +972,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
> 
>  	ret = register_framebuffer(fbinfo);
>  	if (ret < 0) {
> -		printk(KERN_ERR "Failed to register framebuffer device: %d\n",
> +		dev_err(&pdev->dev, "Failed to register framebuffer device: %d\n",
>  			ret);
>  		goto free_cpufreq;
>  	}
> @@ -978,9 +980,9 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
>  	/* create device files */
>  	ret = device_create_file(&pdev->dev, &dev_attr_debug);
>  	if (ret)
> -		printk(KERN_ERR "failed to add debug attribute\n");
> +		dev_err(&pdev->dev, "failed to add debug attribute\n");
> 
> -	printk(KERN_INFO "fb%d: %s frame buffer device\n",
> +	dev_info(&pdev->dev, "fb%d: %s frame buffer device\n",
>  		fbinfo->node, fbinfo->fix.id);
> 
>  	return 0;
> --
> 1.7.4.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply

* [RFC PATCH] OMAPDSS: DISPC: Fix IRQ unregister race
From: Dimitar Dimitrov @ 2012-09-02 19:12 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Dimitar Dimitrov

Very rare kernel crashes are reported on a custom OMAP4 board. Kernel
panics due to corrupted completion structure while executing
dispc_irq_wait_handler(). Excerpt from kernel log:

  Internal error: Oops - undefined instruction: 0 [#1] PREEMPT SMP
  Unable to handle kernel paging request at virtual address 00400130
  ...
  PC is at 0xebf205bc
  LR is at __wake_up_common+0x54/0x94
  ...
  (__wake_up_common+0x0/0x94)
  (complete+0x0/0x60)
  (dispc_irq_wait_handler.36902+0x0/0x14)
  (omap_dispc_irq_handler+0x0/0x354)
  (handle_irq_event_percpu+0x0/0x188)
  (handle_irq_event+0x0/0x64)
  (handle_fasteoi_irq+0x0/0x10c)
  (generic_handle_irq+0x0/0x48)
  (asm_do_IRQ+0x0/0xc0)

DISPC IRQ executes callbacks with dispc.irq_lock released. Hence
unregister_isr() and DISPC IRQ might be running in parallel on different
CPUs. So there is a chance that a callback is executed even though it
has been unregistered. As omap_dispc_wait_for_irq_timeout() declares a
completion on stack, the dispc_irq_wait_handler() callback might try to
access a completion structure that is invalid. This leads to crashes and
hangs.

Solution is to divide unregister calls into two sets:
  1. Non-strict unregistering of callbacks. Callbacks could safely be
     executed after unregistering them. This is the case with unregister
     calls from the IRQ handler itself.
  2. Strict (synchronized) unregistering. Callbacks are not allowed
     after unregistering. This is the case with completion waiting.

The above solution should satisfy one of the original intentions of the
driver: callbacks should be able to unregister themselves.

Signed-off-by: Dimitar Dimitrov <dinuxbg@gmail.com>
---

WARNING: This bug is quite old. The patch has been tested on v3.0. No testing
has been done after rebasing to v3.6. Hence the RFC tag. Hopefully someone
will beat me in testing with latest linux-omap/master.

 drivers/media/video/omap/omap_vout.c |    4 +--
 drivers/staging/omapdrm/omap_plane.c |    2 +-
 drivers/video/omap2/dss/apply.c      |    2 +-
 drivers/video/omap2/dss/dispc.c      |   47 +++++++++++++++++++++++++++++-----
 drivers/video/omap2/dss/dsi.c        |    4 +--
 drivers/video/omap2/dss/rfbi.c       |    2 +-
 include/video/omapdss.h              |    3 ++-
 7 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 88cf9d9..d06896e 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -976,7 +976,7 @@ static int omap_vout_release(struct file *file)
 
 		mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN |
 			DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2;
-		omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
+		omap_dispc_unregister_isr_sync(omap_vout_isr, vout, mask);
 		vout->streaming = 0;
 
 		videobuf_streamoff(q);
@@ -1722,7 +1722,7 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
 	mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD
 		| DISPC_IRQ_VSYNC2;
 
-	omap_dispc_unregister_isr(omap_vout_isr, vout, mask);
+	omap_dispc_unregister_isr_sync(omap_vout_isr, vout, mask);
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
diff --git a/drivers/staging/omapdrm/omap_plane.c b/drivers/staging/omapdrm/omap_plane.c
index 7997be7..8d8aa5b 100644
--- a/drivers/staging/omapdrm/omap_plane.c
+++ b/drivers/staging/omapdrm/omap_plane.c
@@ -82,7 +82,7 @@ static void dispc_isr(void *arg, uint32_t mask)
 	struct omap_plane *omap_plane = to_omap_plane(plane);
 	struct omap_drm_private *priv = plane->dev->dev_private;
 
-	omap_dispc_unregister_isr(dispc_isr, plane,
+	omap_dispc_unregister_isr_nosync(dispc_isr, plane,
 			id2irq[omap_plane->ovl->id]);
 
 	queue_work(priv->wq, &omap_plane->work);
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 0fefc68..9386834 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -847,7 +847,7 @@ static void dss_unregister_vsync_isr(void)
 	for (i = 0; i < num_mgrs; ++i)
 		mask |= dispc_mgr_get_framedone_irq(i);
 
-	r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
+	r = omap_dispc_unregister_isr_nosync(dss_apply_irq_handler, NULL, mask);
 	WARN_ON(r);
 
 	dss_data.irq_enabled = false;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5b289c5..23d5881 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2351,7 +2351,7 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
 					msecs_to_jiffies(100)))
 			DSSERR("timeout waiting for FRAME DONE\n");
 
-		r = omap_dispc_unregister_isr(dispc_disable_isr,
+		r = omap_dispc_unregister_isr_sync(dispc_disable_isr,
 				&frame_done_completion, irq);
 
 		if (r)
@@ -2420,8 +2420,8 @@ static void dispc_mgr_enable_digit_out(bool enable)
 					enable ? "start" : "stop");
 	}
 
-	r = omap_dispc_unregister_isr(dispc_disable_isr, &frame_done_completion,
-			irq_mask);
+	r = omap_dispc_unregister_isr_sync(dispc_disable_isr,
+			&frame_done_completion, irq_mask);
 	if (r)
 		DSSERR("failed to unregister %x isr\n", irq_mask);
 
@@ -3319,7 +3319,8 @@ err:
 }
 EXPORT_SYMBOL(omap_dispc_register_isr);
 
-int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
+/* WARNING: callback might be executed even after this function returns! */
+int omap_dispc_unregister_isr_nosync(omap_dispc_isr_t isr, void *arg, u32 mask)
 {
 	int i;
 	unsigned long flags;
@@ -3351,7 +3352,37 @@ int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
 
 	return ret;
 }
-EXPORT_SYMBOL(omap_dispc_unregister_isr);
+EXPORT_SYMBOL(omap_dispc_unregister_isr_nosync);
+
+/*
+ * Ensure that callback <isr> will NOT be executed after this function
+ * returns. Must be called from sleepable context, though!
+ */
+int omap_dispc_unregister_isr_sync(omap_dispc_isr_t isr, void *arg, u32 mask)
+{
+	int ret;
+
+	ret = omap_dispc_unregister_isr_nosync(isr, arg, mask);
+
+	/* Task context is not really needed. But if we're called from atomic
+	 * context, it is probably from DISPC IRQ, where we will deadlock.
+	 * So use might_sleep() to catch potential deadlocks.
+	 */
+	might_sleep();
+
+#if defined(CONFIG_SMP)
+	/* DISPC IRQ executes callbacks with dispc.irq_lock released. Hence
+	 * unregister_isr() and DISPC IRQ might be running in parallel on
+	 * different CPUs. So there is a chance that a callback is executed
+	 * even though it has been unregistered. Add a barrier, in order to
+	 * ensure that after returning from this function, the new DISPC IRQ
+	 * will use an updated callback array, and NOT its cached copy.
+	 */
+	synchronize_irq(dispc.irq);
+#endif
+
+	return ret;
+}
 
 #ifdef DEBUG
 static void print_irq_status(u32 status)
@@ -3566,7 +3597,8 @@ int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout)
 
 	timeout = wait_for_completion_timeout(&completion, timeout);
 
-	omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
+	omap_dispc_unregister_isr_sync(dispc_irq_wait_handler, &completion,
+			irqmask);
 
 	if (timeout = 0)
 		return -ETIMEDOUT;
@@ -3597,7 +3629,8 @@ int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
 	timeout = wait_for_completion_interruptible_timeout(&completion,
 			timeout);
 
-	omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
+	omap_dispc_unregister_isr_sync(dispc_irq_wait_handler, &completion,
+			irqmask);
 
 	if (timeout = 0)
 		return -ETIMEDOUT;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index b07e886..46f6c6c 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -4430,7 +4430,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
 	return 0;
 err1:
 	if (dssdev->panel.dsi_mode = OMAP_DSS_DSI_CMD_MODE)
-		omap_dispc_unregister_isr(dsi_framedone_irq_callback,
+		omap_dispc_unregister_isr_sync(dsi_framedone_irq_callback,
 			(void *) dssdev, irq);
 err:
 	return r;
@@ -4443,7 +4443,7 @@ static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
 
 		irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
 
-		omap_dispc_unregister_isr(dsi_framedone_irq_callback,
+		omap_dispc_unregister_isr_sync(dsi_framedone_irq_callback,
 			(void *) dssdev, irq);
 	}
 }
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 7c08742..31d167c 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -930,7 +930,7 @@ EXPORT_SYMBOL(omapdss_rfbi_display_enable);
 
 void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
 {
-	omap_dispc_unregister_isr(framedone_callback, NULL,
+	omap_dispc_unregister_isr_sync(framedone_callback, NULL,
 			DISPC_IRQ_FRAMEDONE);
 	omap_dss_stop_device(dssdev);
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a6267a2..2287368 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -707,7 +707,8 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
 
 typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
 int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
-int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
+int omap_dispc_unregister_isr_sync(omap_dispc_isr_t isr, void *arg, u32 mask);
+int omap_dispc_unregister_isr_nosync(omap_dispc_isr_t isr, void *arg, u32 mask);
 
 int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout);
 int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
-- 
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