Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH 2/7] OMAP: RX51: Remove unused old omapfb stuff
From: Tomi Valkeinen @ 2011-05-04 12:27 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen
In-Reply-To: <1304512059-10372-1-git-send-email-tomi.valkeinen@ti.com>

RX51 uses the new DSS2 display driver, but the board file still
contained some code for the old omapfb driver. The old code can be
removed.

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

diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index e964895..116e19b 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -75,29 +75,6 @@ static struct cpuidle_params rx51_cpuidle_params[] = {
 	{1, 7505, 15274, 484329},
 };
 
-static struct omap_lcd_config rx51_lcd_config = {
-	.ctrl_name	= "internal",
-};
-
-static struct omap_fbmem_config rx51_fbmem0_config = {
-	.size = 752 * 1024,
-};
-
-static struct omap_fbmem_config rx51_fbmem1_config = {
-	.size = 752 * 1024,
-};
-
-static struct omap_fbmem_config rx51_fbmem2_config = {
-	.size = 752 * 1024,
-};
-
-static struct omap_board_config_kernel rx51_config[] = {
-	{ OMAP_TAG_FBMEM,	&rx51_fbmem0_config },
-	{ OMAP_TAG_FBMEM,	&rx51_fbmem1_config },
-	{ OMAP_TAG_FBMEM,	&rx51_fbmem2_config },
-	{ OMAP_TAG_LCD,		&rx51_lcd_config },
-};
-
 static void __init rx51_init_early(void)
 {
 	struct omap_sdrc_params *sdrc_params;
@@ -124,8 +101,6 @@ static struct omap_musb_board_data musb_board_data = {
 static void __init rx51_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-	omap_board_config = rx51_config;
-	omap_board_config_size = ARRAY_SIZE(rx51_config);
 	omap3_pm_init_cpuidle(rx51_cpuidle_params);
 	omap_serial_init();
 	usb_musb_init(&musb_board_data);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 3/7] OMAP: omap3touchbook: Remove unused lcd stuff
From: Tomi Valkeinen @ 2011-05-04 12:27 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen, Gregoire Gentil
In-Reply-To: <1304512059-10372-1-git-send-email-tomi.valkeinen@ti.com>

board-omap3touchbook.c adds an LCD device, but the kernel doesn't
contain a driver for the device. So let's remove the unneeded LCD
device.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Gregoire Gentil <gregoire@gentil.com>
---
 arch/arm/mach-omap2/board-omap3touchbook.c |   18 ------------------
 1 files changed, 0 insertions(+), 18 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 127cb17..1c717a4 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -115,15 +115,6 @@ static struct omap2_hsmmc_info mmc[] = {
 	{}	/* Terminator */
 };
 
-static struct platform_device omap3_touchbook_lcd_device = {
-	.name		= "omap3touchbook_lcd",
-	.id		= -1,
-};
-
-static struct omap_lcd_config omap3_touchbook_lcd_config __initdata = {
-	.ctrl_name	= "internal",
-};
-
 static struct regulator_consumer_supply touchbook_vmmc1_supply = {
 	.supply			= "vmmc",
 };
@@ -181,12 +172,10 @@ static struct twl4030_gpio_platform_data touchbook_gpio_data = {
 
 static struct regulator_consumer_supply touchbook_vdac_supply = {
 	.supply		= "vdac",
-	.dev		= &omap3_touchbook_lcd_device.dev,
 };
 
 static struct regulator_consumer_supply touchbook_vdvi_supply = {
 	.supply		= "vdvi",
-	.dev		= &omap3_touchbook_lcd_device.dev,
 };
 
 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card = max 220 mA) */
@@ -403,10 +392,6 @@ static struct platform_device keys_gpio = {
 	},
 };
 
-static struct omap_board_config_kernel omap3_touchbook_config[] __initdata = {
-	{ OMAP_TAG_LCD,		&omap3_touchbook_lcd_config },
-};
-
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
@@ -429,7 +414,6 @@ static void __init omap3_touchbook_init_irq(void)
 }
 
 static struct platform_device *omap3_touchbook_devices[] __initdata = {
-	&omap3_touchbook_lcd_device,
 	&leds_gpio,
 	&keys_gpio,
 };
@@ -510,8 +494,6 @@ static struct omap_musb_board_data musb_board_data = {
 static void __init omap3_touchbook_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-	omap_board_config = omap3_touchbook_config;
-	omap_board_config_size = ARRAY_SIZE(omap3_touchbook_config);
 
 	pm_power_off = omap3_touchbook_poweroff;
 
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 4/7] OMAP: 2420SDP: Port the display driver to new DSS2
From: Tomi Valkeinen @ 2011-05-04 12:27 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen, Hunyue Yau
In-Reply-To: <1304512059-10372-1-git-send-email-tomi.valkeinen@ti.com>

Port the old omapfb panel driver to DSS2 and change the board file
accordingly.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Hunyue Yau <hyau@mvista.com>
---
 arch/arm/mach-omap2/board-2430sdp.c              |   84 ++++++++--
 drivers/video/omap/Makefile                      |    2 -
 drivers/video/omap/lcd_2430sdp.c                 |  203 ----------------------
 drivers/video/omap2/displays/panel-generic-dpi.c |   21 +++
 4 files changed, 91 insertions(+), 219 deletions(-)
 delete mode 100644 drivers/video/omap/lcd_2430sdp.c

diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 1fa6bb8..9b6e987 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -38,6 +38,8 @@
 #include <plat/gpmc.h>
 #include <plat/usb.h>
 #include <plat/gpmc-smc91x.h>
+#include <plat/display.h>
+#include <plat/panel-generic-dpi.h>
 
 #include "mux.h"
 #include "hsmmc.h"
@@ -98,20 +100,79 @@ static struct platform_device sdp2430_flash_device = {
 	.resource	= &sdp2430_flash_resource,
 };
 
-static struct platform_device sdp2430_lcd_device = {
-	.name		= "sdp2430_lcd",
-	.id		= -1,
-};
-
 static struct platform_device *sdp2430_devices[] __initdata = {
 	&sdp2430_flash_device,
+};
+
+/* LCD */
+#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO	91
+#define SDP2430_LCD_PANEL_ENABLE_GPIO		154
+
+static int sdp2430_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+	gpio_direction_output(SDP2430_LCD_PANEL_ENABLE_GPIO, 1);
+	gpio_direction_output(SDP2430_LCD_PANEL_BACKLIGHT_GPIO, 1);
+
+	return 0;
+}
+
+static void sdp2430_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+	gpio_direction_output(SDP2430_LCD_PANEL_ENABLE_GPIO, 0);
+	gpio_direction_output(SDP2430_LCD_PANEL_BACKLIGHT_GPIO, 0);
+}
+
+static struct panel_generic_dpi_data sdp2430_panel_data = {
+	.name			= "2430sdp",
+	.platform_enable	= sdp2430_panel_enable_lcd,
+	.platform_disable	= sdp2430_panel_disable_lcd,
+};
+
+static struct omap_dss_device sdp2430_lcd_device = {
+	.name			= "lcd",
+	.driver_name		= "generic_dpi_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 16,
+	.data			= &sdp2430_panel_data,
+};
+
+static struct omap_dss_device *sdp2430_dss_devices[] = {
 	&sdp2430_lcd_device,
 };
 
-static struct omap_lcd_config sdp2430_lcd_config __initdata = {
-	.ctrl_name	= "internal",
+static struct omap_dss_board_info sdp2430_dss_data = {
+	.num_devices	= ARRAY_SIZE(sdp2430_dss_devices),
+	.devices	= sdp2430_dss_devices,
+	.default_device	= &sdp2430_lcd_device,
 };
 
+static void __init sdp2430_display_init(void)
+{
+	int r;
+
+	r = gpio_request_one(SDP2430_LCD_PANEL_ENABLE_GPIO,
+			GPIOF_OUT_INIT_LOW, "LCD reset");
+	if (r) {
+		printk(KERN_ERR "failed to get LCD reset GPIO\n");
+		goto err0;
+	}
+
+	r = gpio_request_one(SDP2430_LCD_PANEL_BACKLIGHT_GPIO,
+			GPIOF_OUT_INIT_LOW, "LCD Backlight");
+	if (r) {
+		printk(KERN_ERR "failed to get LCD backlight GPIO\n");
+		goto err1;
+	}
+
+	omap_display_init(&sdp2430_dss_data);
+
+	return;
+err1:
+	gpio_free(SDP2430_LCD_PANEL_ENABLE_GPIO);
+err0:
+	return;
+}
+
 #if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
 
 static struct omap_smc91x_platform_data board_smc91x_data = {
@@ -136,10 +197,6 @@ static inline void board_smc91x_init(void)
 
 #endif
 
-static struct omap_board_config_kernel sdp2430_config[] __initdata = {
-	{OMAP_TAG_LCD, &sdp2430_lcd_config},
-};
-
 static void __init omap_2430sdp_init_early(void)
 {
 	omap2_init_common_infrastructure();
@@ -244,9 +301,6 @@ static void __init omap_2430sdp_init(void)
 
 	omap2430_mux_init(board_mux, OMAP_PACKAGE_ZAC);
 
-	omap_board_config = sdp2430_config;
-	omap_board_config_size = ARRAY_SIZE(sdp2430_config);
-
 	omap2430_i2c_init();
 
 	platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
@@ -263,6 +317,8 @@ static void __init omap_2430sdp_init(void)
 	ret = gpio_request(SECONDARY_LCD_GPIO, "Secondary LCD backlight");
 	if (ret = 0)
 		gpio_direction_output(SECONDARY_LCD_GPIO, 0);
+
+	sdp2430_display_init();
 }
 
 static void __init omap_2430sdp_map_io(void)
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
index 8eec6d7..f654ba0 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/omap/Makefile
@@ -27,8 +27,6 @@ objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o
 objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
 
 objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
-objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o
-objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o
 objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o
 objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
 objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o
diff --git a/drivers/video/omap/lcd_2430sdp.c b/drivers/video/omap/lcd_2430sdp.c
deleted file mode 100644
index e3eccc9..0000000
--- a/drivers/video/omap/lcd_2430sdp.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * LCD panel support for the TI 2430SDP board
- *
- * Copyright (C) 2007 MontaVista
- * Author: Hunyue Yau <hyau@mvista.com>
- *
- * Derived from drivers/video/omap/lcd-apollon.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/i2c/twl.h>
-
-#include <plat/mux.h>
-#include <asm/mach-types.h>
-
-#include "omapfb.h"
-
-#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO	91
-#define SDP2430_LCD_PANEL_ENABLE_GPIO		154
-#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO	24
-#define SDP3430_LCD_PANEL_ENABLE_GPIO		28
-
-static unsigned backlight_gpio;
-static unsigned enable_gpio;
-
-#define LCD_PIXCLOCK_MAX		5400 /* freq 5.4 MHz */
-#define PM_RECEIVER             TWL4030_MODULE_PM_RECEIVER
-#define ENABLE_VAUX2_DEDICATED  0x09
-#define ENABLE_VAUX2_DEV_GRP    0x20
-#define ENABLE_VAUX3_DEDICATED	0x03
-#define ENABLE_VAUX3_DEV_GRP	0x20
-
-#define ENABLE_VPLL2_DEDICATED          0x05
-#define ENABLE_VPLL2_DEV_GRP            0xE0
-#define TWL4030_VPLL2_DEV_GRP           0x33
-#define TWL4030_VPLL2_DEDICATED         0x36
-
-#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v)
-
-
-static int sdp2430_panel_init(struct lcd_panel *panel,
-				struct omapfb_device *fbdev)
-{
-	if (machine_is_omap_3430sdp()) {
-		enable_gpio    = SDP3430_LCD_PANEL_ENABLE_GPIO;
-		backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO;
-	} else {
-		enable_gpio    = SDP2430_LCD_PANEL_ENABLE_GPIO;
-		backlight_gpio = SDP2430_LCD_PANEL_BACKLIGHT_GPIO;
-	}
-
-	gpio_request(enable_gpio, "LCD enable");	/* LCD panel */
-	gpio_request(backlight_gpio, "LCD bl");		/* LCD backlight */
-	gpio_direction_output(enable_gpio, 0);
-	gpio_direction_output(backlight_gpio, 0);
-
-	return 0;
-}
-
-static void sdp2430_panel_cleanup(struct lcd_panel *panel)
-{
-	gpio_free(backlight_gpio);
-	gpio_free(enable_gpio);
-}
-
-static int sdp2430_panel_enable(struct lcd_panel *panel)
-{
-	u8 ded_val, ded_reg;
-	u8 grp_val, grp_reg;
-
-	if (machine_is_omap_3430sdp()) {
-		ded_reg = TWL4030_VAUX3_DEDICATED;
-		ded_val = ENABLE_VAUX3_DEDICATED;
-		grp_reg = TWL4030_VAUX3_DEV_GRP;
-		grp_val = ENABLE_VAUX3_DEV_GRP;
-
-		if (omap_rev() > OMAP3430_REV_ES1_0) {
-			t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
-					TWL4030_VPLL2_DEDICATED);
-			t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
-					TWL4030_VPLL2_DEV_GRP);
-		}
-	} else {
-		ded_reg = TWL4030_VAUX2_DEDICATED;
-		ded_val = ENABLE_VAUX2_DEDICATED;
-		grp_reg = TWL4030_VAUX2_DEV_GRP;
-		grp_val = ENABLE_VAUX2_DEV_GRP;
-	}
-
-	gpio_set_value(enable_gpio, 1);
-	gpio_set_value(backlight_gpio, 1);
-
-	if (0 != t2_out(PM_RECEIVER, ded_val, ded_reg))
-		return -EIO;
-	if (0 != t2_out(PM_RECEIVER, grp_val, grp_reg))
-		return -EIO;
-
-	return 0;
-}
-
-static void sdp2430_panel_disable(struct lcd_panel *panel)
-{
-	gpio_set_value(enable_gpio, 0);
-	gpio_set_value(backlight_gpio, 0);
-	if (omap_rev() > OMAP3430_REV_ES1_0) {
-		t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
-		t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
-		msleep(4);
-	}
-}
-
-static unsigned long sdp2430_panel_get_caps(struct lcd_panel *panel)
-{
-	return 0;
-}
-
-struct lcd_panel sdp2430_panel = {
-	.name		= "sdp2430",
-	.config		= OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
-			  OMAP_LCDC_INV_HSYNC,
-
-	.bpp		= 16,
-	.data_lines	= 16,
-	.x_res		= 240,
-	.y_res		= 320,
-	.hsw		= 3,		/* hsync_len (4) - 1 */
-	.hfp		= 3,		/* right_margin (4) - 1 */
-	.hbp		= 39,		/* left_margin (40) - 1 */
-	.vsw		= 1,		/* vsync_len (2) - 1 */
-	.vfp		= 2,		/* lower_margin */
-	.vbp		= 7,		/* upper_margin (8) - 1 */
-
-	.pixel_clock	= LCD_PIXCLOCK_MAX,
-
-	.init		= sdp2430_panel_init,
-	.cleanup	= sdp2430_panel_cleanup,
-	.enable		= sdp2430_panel_enable,
-	.disable	= sdp2430_panel_disable,
-	.get_caps	= sdp2430_panel_get_caps,
-};
-
-static int sdp2430_panel_probe(struct platform_device *pdev)
-{
-	omapfb_register_panel(&sdp2430_panel);
-	return 0;
-}
-
-static int sdp2430_panel_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static int sdp2430_panel_suspend(struct platform_device *pdev,
-					pm_message_t mesg)
-{
-	return 0;
-}
-
-static int sdp2430_panel_resume(struct platform_device *pdev)
-{
-	return 0;
-}
-
-struct platform_driver sdp2430_panel_driver = {
-	.probe		= sdp2430_panel_probe,
-	.remove		= sdp2430_panel_remove,
-	.suspend	= sdp2430_panel_suspend,
-	.resume		= sdp2430_panel_resume,
-	.driver		= {
-		.name	= "sdp2430_lcd",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init sdp2430_panel_drv_init(void)
-{
-	return platform_driver_register(&sdp2430_panel_driver);
-}
-
-static void __exit sdp2430_panel_drv_exit(void)
-{
-	platform_driver_unregister(&sdp2430_panel_driver);
-}
-
-module_init(sdp2430_panel_drv_init);
-module_exit(sdp2430_panel_drv_exit);
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 4a9b9ff..2c1b093 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -181,6 +181,27 @@ static struct panel_config generic_dpi_panels[] = {
 		.power_off_delay	= 0,
 		.name			= "samsung_lte430wq_f0c",
 	},
+
+	/* Unknown panel used in OMAP 2430 SDP */
+	{
+		{
+			.x_res		= 240,
+			.y_res		= 320,
+
+			.pixel_clock	= 5400,
+
+			.hsw		= 3,
+			.hfp		= 3,
+			.hbp		= 39,
+
+			.vsw		= 1,
+			.vfp		= 2,
+			.vbp		= 7,
+		},
+		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+						OMAP_DSS_LCD_IHS,
+		.name			= "2430sdp",
+	},
 };
 
 struct panel_drv_data {
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 5/7] OMAP: LDP: Port the display driver to new DSS2
From: Tomi Valkeinen @ 2011-05-04 12:27 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen, Stanley Miao
In-Reply-To: <1304512059-10372-1-git-send-email-tomi.valkeinen@ti.com>

Port the old omapfb panel driver to DSS2 and change the board file
accordingly.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Stanley Miao <stanley.miao@windriver.com>
---
 arch/arm/mach-omap2/board-ldp.c |   73 ++++++++++++--
 drivers/video/omap/Makefile     |    1 -
 drivers/video/omap/lcd_ldp.c    |  201 ---------------------------------------
 3 files changed, 63 insertions(+), 212 deletions(-)
 delete mode 100644 drivers/video/omap/lcd_ldp.c

diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index e2ba779..2fdfd7f 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -43,6 +43,8 @@
 
 #include <asm/delay.h>
 #include <plat/usb.h>
+#include <plat/display.h>
+#include <plat/panel-generic-dpi.h>
 
 #include "board-flash.h"
 #include "mux.h"
@@ -275,19 +277,71 @@ static inline void __init ldp_init_smsc911x(void)
 	gpio_direction_input(eth_gpio);
 }
 
-static struct platform_device ldp_lcd_device = {
-	.name		= "ldp_lcd",
-	.id		= -1,
+/* LCD */
+
+#define LCD_PANEL_BACKLIGHT_GPIO	(15 + OMAP_MAX_GPIO_LINES)
+#define LCD_PANEL_ENABLE_GPIO		(7 + OMAP_MAX_GPIO_LINES)
+#define LCD_PANEL_RESET_GPIO		55
+#define LCD_PANEL_QVGA_GPIO		56
+
+static int ldp_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+	gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
+	gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 1);
+
+	return 0;
+}
+
+static void ldp_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+	gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
+	gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
+}
+
+static struct panel_generic_dpi_data ldp_panel_data = {
+	.name			= "2430sdp",
+	.platform_enable	= ldp_panel_enable_lcd,
+	.platform_disable	= ldp_panel_disable_lcd,
 };
 
-static struct omap_lcd_config ldp_lcd_config __initdata = {
-	.ctrl_name	= "internal",
+static struct omap_dss_device ldp_lcd_device = {
+	.name			= "lcd",
+	.driver_name		= "generic_dpi_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 16,
+	.data			= &ldp_panel_data,
 };
 
-static struct omap_board_config_kernel ldp_config[] __initdata = {
-	{ OMAP_TAG_LCD,		&ldp_lcd_config },
+static struct omap_dss_device *ldp_dss_devices[] = {
+	&ldp_lcd_device,
+};
+
+static struct omap_dss_board_info ldp_dss_data = {
+	.num_devices	= ARRAY_SIZE(ldp_dss_devices),
+	.devices	= ldp_dss_devices,
+	.default_device	= &ldp_lcd_device,
 };
 
+static void __init ldp_display_init(void)
+{
+	int r;
+
+	struct gpio gpios[] = {
+		{LCD_PANEL_RESET_GPIO, GPIOF_OUT_INIT_HIGH, "LCD RESET"},
+		{LCD_PANEL_QVGA_GPIO, GPIOF_OUT_INIT_HIGH, "LCD QVGA"},
+		{LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW, "LCD ENABLE"},
+		{LCD_PANEL_BACKLIGHT_GPIO, GPIOF_OUT_INIT_LOW, "LCD BACKLIGHT"},
+	};
+
+	r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+	if (r) {
+		pr_err("Cannot request LCD GPIOs, error %d\n", r);
+		return;
+	}
+
+	omap_display_init(&ldp_dss_data);
+}
+
 static void __init omap_ldp_init_early(void)
 {
 	omap2_init_common_infrastructure();
@@ -390,7 +444,6 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
 
 static struct platform_device *ldp_devices[] __initdata = {
 	&ldp_smsc911x_device,
-	&ldp_lcd_device,
 	&ldp_gpio_keys_device,
 };
 
@@ -441,8 +494,6 @@ static struct mtd_partition ldp_nand_partitions[] = {
 static void __init omap_ldp_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-	omap_board_config = ldp_config;
-	omap_board_config_size = ARRAY_SIZE(ldp_config);
 	ldp_init_smsc911x();
 	omap_i2c_init();
 	platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
@@ -459,6 +510,8 @@ static void __init omap_ldp_init(void)
 	omap2_hsmmc_init(mmc);
 	/* link regulators to MMC adapters */
 	ldp_vmmc1_supply.dev = mmc[0].dev;
+
+	ldp_display_init();
 }
 
 MACHINE_START(OMAP_LDP, "OMAP LDP board")
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
index f654ba0..43eb64a 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/omap/Makefile
@@ -27,7 +27,6 @@ objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o
 objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
 
 objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
-objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o
 objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
 objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o
 
diff --git a/drivers/video/omap/lcd_ldp.c b/drivers/video/omap/lcd_ldp.c
deleted file mode 100644
index 0f5952c..0000000
--- a/drivers/video/omap/lcd_ldp.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * LCD panel support for the TI LDP board
- *
- * Copyright (C) 2007 WindRiver
- * Author: Stanley Miao <stanley.miao@windriver.com>
- *
- * Derived from drivers/video/omap/lcd-2430sdp.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/i2c/twl.h>
-
-#include <mach/gpio.h>
-#include <plat/mux.h>
-#include <asm/mach-types.h>
-
-#include "omapfb.h"
-
-#define LCD_PANEL_BACKLIGHT_GPIO	(15 + OMAP_MAX_GPIO_LINES)
-#define LCD_PANEL_ENABLE_GPIO		(7 + OMAP_MAX_GPIO_LINES)
-
-#define LCD_PANEL_RESET_GPIO		55
-#define LCD_PANEL_QVGA_GPIO		56
-
-#ifdef CONFIG_FB_OMAP_LCD_VGA
-#define LCD_XRES		480
-#define LCD_YRES		640
-#define LCD_PIXCLOCK_MAX	41700
-#else
-#define LCD_XRES		240
-#define LCD_YRES		320
-#define LCD_PIXCLOCK_MAX	185186
-#endif
-
-#define PM_RECEIVER             TWL4030_MODULE_PM_RECEIVER
-#define ENABLE_VAUX2_DEDICATED  0x09
-#define ENABLE_VAUX2_DEV_GRP    0x20
-#define ENABLE_VAUX3_DEDICATED	0x03
-#define ENABLE_VAUX3_DEV_GRP	0x20
-
-#define ENABLE_VPLL2_DEDICATED          0x05
-#define ENABLE_VPLL2_DEV_GRP            0xE0
-#define TWL4030_VPLL2_DEV_GRP           0x33
-#define TWL4030_VPLL2_DEDICATED         0x36
-
-#define t2_out(c, r, v) twl_i2c_write_u8(c, r, v)
-
-
-static int ldp_panel_init(struct lcd_panel *panel,
-				struct omapfb_device *fbdev)
-{
-	gpio_request(LCD_PANEL_RESET_GPIO, "lcd reset");
-	gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga");
-	gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd panel");
-	gpio_request(LCD_PANEL_BACKLIGHT_GPIO, "lcd backlight");
-
-	gpio_direction_output(LCD_PANEL_QVGA_GPIO, 0);
-	gpio_direction_output(LCD_PANEL_RESET_GPIO, 0);
-	gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
-	gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
-
-#ifdef CONFIG_FB_OMAP_LCD_VGA
-	gpio_set_value(LCD_PANEL_QVGA_GPIO, 0);
-#else
-	gpio_set_value(LCD_PANEL_QVGA_GPIO, 1);
-#endif
-	gpio_set_value(LCD_PANEL_RESET_GPIO, 1);
-
-	return 0;
-}
-
-static void ldp_panel_cleanup(struct lcd_panel *panel)
-{
-	gpio_free(LCD_PANEL_BACKLIGHT_GPIO);
-	gpio_free(LCD_PANEL_ENABLE_GPIO);
-	gpio_free(LCD_PANEL_QVGA_GPIO);
-	gpio_free(LCD_PANEL_RESET_GPIO);
-}
-
-static int ldp_panel_enable(struct lcd_panel *panel)
-{
-	if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEDICATED,
-			TWL4030_VPLL2_DEDICATED))
-		return -EIO;
-	if (0 != t2_out(PM_RECEIVER, ENABLE_VPLL2_DEV_GRP,
-			TWL4030_VPLL2_DEV_GRP))
-		return -EIO;
-
-	gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
-	gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 1);
-
-	if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEDICATED,
-				TWL4030_VAUX3_DEDICATED))
-		return -EIO;
-	if (0 != t2_out(PM_RECEIVER, ENABLE_VAUX3_DEV_GRP,
-				TWL4030_VAUX3_DEV_GRP))
-		return -EIO;
-
-	return 0;
-}
-
-static void ldp_panel_disable(struct lcd_panel *panel)
-{
-	gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
-	gpio_direction_output(LCD_PANEL_BACKLIGHT_GPIO, 0);
-
-	t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEDICATED);
-	t2_out(PM_RECEIVER, 0x0, TWL4030_VPLL2_DEV_GRP);
-	msleep(4);
-}
-
-static unsigned long ldp_panel_get_caps(struct lcd_panel *panel)
-{
-	return 0;
-}
-
-struct lcd_panel ldp_panel = {
-	.name		= "ldp",
-	.config		= OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
-			  OMAP_LCDC_INV_HSYNC,
-
-	.bpp		= 16,
-	.data_lines	= 18,
-	.x_res		= LCD_XRES,
-	.y_res		= LCD_YRES,
-	.hsw		= 3,		/* hsync_len (4) - 1 */
-	.hfp		= 3,		/* right_margin (4) - 1 */
-	.hbp		= 39,		/* left_margin (40) - 1 */
-	.vsw		= 1,		/* vsync_len (2) - 1 */
-	.vfp		= 2,		/* lower_margin */
-	.vbp		= 7,		/* upper_margin (8) - 1 */
-
-	.pixel_clock	= LCD_PIXCLOCK_MAX,
-
-	.init		= ldp_panel_init,
-	.cleanup	= ldp_panel_cleanup,
-	.enable		= ldp_panel_enable,
-	.disable	= ldp_panel_disable,
-	.get_caps	= ldp_panel_get_caps,
-};
-
-static int ldp_panel_probe(struct platform_device *pdev)
-{
-	omapfb_register_panel(&ldp_panel);
-	return 0;
-}
-
-static int ldp_panel_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static int ldp_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
-	return 0;
-}
-
-static int ldp_panel_resume(struct platform_device *pdev)
-{
-	return 0;
-}
-
-struct platform_driver ldp_panel_driver = {
-	.probe		= ldp_panel_probe,
-	.remove		= ldp_panel_remove,
-	.suspend	= ldp_panel_suspend,
-	.resume		= ldp_panel_resume,
-	.driver		= {
-		.name	= "ldp_lcd",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init ldp_panel_drv_init(void)
-{
-	return platform_driver_register(&ldp_panel_driver);
-}
-
-static void __exit ldp_panel_drv_exit(void)
-{
-	platform_driver_unregister(&ldp_panel_driver);
-}
-
-module_init(ldp_panel_drv_init);
-module_exit(ldp_panel_drv_exit);
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 6/7] OMAP: H4: Port the display driver to new DSS2
From: Tomi Valkeinen @ 2011-05-04 12:27 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen, Imre Deak
In-Reply-To: <1304512059-10372-1-git-send-email-tomi.valkeinen@ti.com>

Port the old omapfb panel driver to DSS2 and change the board file
accordingly.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Imre Deak <imre.deak@nokia.com>
---
 arch/arm/mach-omap2/board-h4.c                   |   41 +++++---
 drivers/video/omap/Makefile                      |    1 -
 drivers/video/omap/lcd_h4.c                      |  117 ----------------------
 drivers/video/omap2/displays/panel-generic-dpi.c |   21 ++++
 4 files changed, 46 insertions(+), 134 deletions(-)
 delete mode 100644 drivers/video/omap/lcd_h4.c

diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index bac7933..991e71e 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -39,6 +39,8 @@
 #include <plat/menelaus.h>
 #include <plat/dma.h>
 #include <plat/gpmc.h>
+#include <plat/display.h>
+#include <plat/panel-generic-dpi.h>
 
 #include "mux.h"
 #include "control.h"
@@ -157,17 +159,33 @@ static struct platform_device h4_kp_device = {
 	},
 };
 
-static struct platform_device h4_lcd_device = {
-	.name		= "lcd_h4",
-	.id		= -1,
-};
-
 static struct platform_device *h4_devices[] __initdata = {
 	&h4_flash_device,
 	&h4_kp_device,
+};
+
+static struct panel_generic_dpi_data h4_panel_data = {
+	.name			= "h4",
+};
+
+static struct omap_dss_device h4_lcd_device = {
+	.name			= "lcd",
+	.driver_name		= "generic_dpi_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 16,
+	.data			= &h4_panel_data,
+};
+
+static struct omap_dss_device *h4_dss_devices[] = {
 	&h4_lcd_device,
 };
 
+static struct omap_dss_board_info h4_dss_data = {
+	.num_devices	= ARRAY_SIZE(h4_dss_devices),
+	.devices	= h4_dss_devices,
+	.default_device	= &h4_lcd_device,
+};
+
 /* 2420 Sysboot setup (2430 is different) */
 static u32 get_sysboot_value(void)
 {
@@ -271,10 +289,6 @@ static void __init h4_init_flash(void)
 	h4_flash_resource.end	= base + SZ_64M - 1;
 }
 
-static struct omap_lcd_config h4_lcd_config __initdata = {
-	.ctrl_name	= "internal",
-};
-
 static struct omap_usb_config h4_usb_config __initdata = {
 	/* S1.10 OFF -- usb "download port"
 	 * usb0 switched to Mini-B port and isp1105 transceiver;
@@ -286,10 +300,6 @@ static struct omap_usb_config h4_usb_config __initdata = {
 	.hmc_mode	= 0x00,		/* 0:dev|otg 1:disable 2:disable */
 };
 
-static struct omap_board_config_kernel h4_config[] __initdata = {
-	{ OMAP_TAG_LCD,		&h4_lcd_config },
-};
-
 static void __init omap_h4_init_early(void)
 {
 	omap2_init_common_infrastructure();
@@ -331,9 +341,6 @@ static void __init omap_h4_init(void)
 {
 	omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAF);
 
-	omap_board_config = h4_config;
-	omap_board_config_size = ARRAY_SIZE(h4_config);
-
 	/*
 	 * Make sure the serial ports are muxed on at this point.
 	 * You have to mux them off in device drivers later on
@@ -372,6 +379,8 @@ static void __init omap_h4_init(void)
 	omap2_usbfs_init(&h4_usb_config);
 	omap_serial_init();
 	h4_init_flash();
+
+	omap_display_init(&h4_dss_data);
 }
 
 static void __init omap_h4_map_io(void)
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
index 43eb64a..22fef61 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/omap/Makefile
@@ -17,7 +17,6 @@ objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o
 objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o
 
 objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o
-objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o
 objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o
 objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o
 objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o
diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c
deleted file mode 100644
index 03a06a9..0000000
--- a/drivers/video/omap/lcd_h4.c
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * LCD panel support for the TI OMAP H4 board
- *
- * Copyright (C) 2004 Nokia Corporation
- * Author: Imre Deak <imre.deak@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include "omapfb.h"
-
-static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
-{
-	return 0;
-}
-
-static void h4_panel_cleanup(struct lcd_panel *panel)
-{
-}
-
-static int h4_panel_enable(struct lcd_panel *panel)
-{
-	return 0;
-}
-
-static void h4_panel_disable(struct lcd_panel *panel)
-{
-}
-
-static unsigned long h4_panel_get_caps(struct lcd_panel *panel)
-{
-	return 0;
-}
-
-static struct lcd_panel h4_panel = {
-	.name		= "h4",
-	.config		= OMAP_LCDC_PANEL_TFT,
-
-	.bpp		= 16,
-	.data_lines	= 16,
-	.x_res		= 240,
-	.y_res		= 320,
-	.pixel_clock	= 6250,
-	.hsw		= 15,
-	.hfp		= 15,
-	.hbp		= 60,
-	.vsw		= 1,
-	.vfp		= 1,
-	.vbp		= 1,
-
-	.init		= h4_panel_init,
-	.cleanup	= h4_panel_cleanup,
-	.enable		= h4_panel_enable,
-	.disable	= h4_panel_disable,
-	.get_caps	= h4_panel_get_caps,
-};
-
-static int h4_panel_probe(struct platform_device *pdev)
-{
-	omapfb_register_panel(&h4_panel);
-	return 0;
-}
-
-static int h4_panel_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static int h4_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
-	return 0;
-}
-
-static int h4_panel_resume(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static struct platform_driver h4_panel_driver = {
-	.probe		= h4_panel_probe,
-	.remove		= h4_panel_remove,
-	.suspend	= h4_panel_suspend,
-	.resume		= h4_panel_resume,
-	.driver		= {
-		.name	= "lcd_h4",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init h4_panel_drv_init(void)
-{
-	return platform_driver_register(&h4_panel_driver);
-}
-
-static void __exit h4_panel_drv_cleanup(void)
-{
-	platform_driver_unregister(&h4_panel_driver);
-}
-
-module_init(h4_panel_drv_init);
-module_exit(h4_panel_drv_cleanup);
-
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 2c1b093..92bf63e 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -202,6 +202,27 @@ static struct panel_config generic_dpi_panels[] = {
 						OMAP_DSS_LCD_IHS,
 		.name			= "2430sdp",
 	},
+
+	/* Unknown panel used in OMAP H4 */
+	{
+		{
+			.x_res		= 240,
+			.y_res		= 320,
+
+			.pixel_clock	= 6250,
+
+			.hsw		= 15,
+			.hfp		= 15,
+			.hbp		= 60,
+
+			.vsw		= 1,
+			.vfp		= 1,
+			.vbp		= 1,
+		},
+		.config			= OMAP_DSS_LCD_TFT,
+
+		.name			= "h4",
+	},
 };
 
 struct panel_drv_data {
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 7/7] OMAP: Apollon: Port the display driver to new DSS2
From: Tomi Valkeinen @ 2011-05-04 12:27 UTC (permalink / raw)
  To: linux-omap, linux-fbdev; +Cc: Tomi Valkeinen, Kyungmin Park
In-Reply-To: <1304512059-10372-1-git-send-email-tomi.valkeinen@ti.com>

Port the old omapfb panel driver to DSS2 and change the board file
accordingly.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/mach-omap2/board-apollon.c              |   34 ++++--
 drivers/video/omap/Makefile                      |    1 -
 drivers/video/omap/lcd_apollon.c                 |  136 ----------------------
 drivers/video/omap2/displays/panel-generic-dpi.c |   22 ++++
 4 files changed, 44 insertions(+), 149 deletions(-)
 delete mode 100644 drivers/video/omap/lcd_apollon.c

diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index f4f8374..0414c17 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -39,6 +39,8 @@
 #include <plat/board.h>
 #include <plat/common.h>
 #include <plat/gpmc.h>
+#include <plat/display.h>
+#include <plat/panel-generic-dpi.h>
 
 #include "mux.h"
 #include "control.h"
@@ -149,11 +151,6 @@ static struct platform_device apollon_smc91x_device = {
 	.resource	= apollon_smc91x_resources,
 };
 
-static struct platform_device apollon_lcd_device = {
-	.name		= "apollon_lcd",
-	.id		= -1,
-};
-
 static struct omap_led_config apollon_led_config[] = {
 	{
 		.cdev	= {
@@ -191,7 +188,6 @@ static struct platform_device apollon_led_device = {
 static struct platform_device *apollon_devices[] __initdata = {
 	&apollon_onenand_device,
 	&apollon_smc91x_device,
-	&apollon_lcd_device,
 	&apollon_led_device,
 };
 
@@ -266,12 +262,26 @@ static struct omap_usb_config apollon_usb_config __initdata = {
 	.pins[0]	= 6,
 };
 
-static struct omap_lcd_config apollon_lcd_config __initdata = {
-	.ctrl_name	= "internal",
+static struct panel_generic_dpi_data apollon_panel_data = {
+	.name			= "apollon",
+};
+
+static struct omap_dss_device apollon_lcd_device = {
+	.name			= "lcd",
+	.driver_name		= "generic_dpi_panel",
+	.type			= OMAP_DISPLAY_TYPE_DPI,
+	.phy.dpi.data_lines	= 18,
+	.data			= &apollon_panel_data,
 };
 
-static struct omap_board_config_kernel apollon_config[] __initdata = {
-	{ OMAP_TAG_LCD,		&apollon_lcd_config },
+static struct omap_dss_device *apollon_dss_devices[] = {
+	&apollon_lcd_device,
+};
+
+static struct omap_dss_board_info apollon_dss_data = {
+	.num_devices	= ARRAY_SIZE(apollon_dss_devices),
+	.devices	= apollon_dss_devices,
+	.default_device	= &apollon_lcd_device,
 };
 
 static void __init omap_apollon_init_early(void)
@@ -317,8 +327,6 @@ static void __init omap_apollon_init(void)
 	u32 v;
 
 	omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
-	omap_board_config = apollon_config;
-	omap_board_config_size = ARRAY_SIZE(apollon_config);
 
 	apollon_init_smc91x();
 	apollon_led_init();
@@ -343,6 +351,8 @@ static void __init omap_apollon_init(void)
 	 */
 	platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
 	omap_serial_init();
+
+	omap_display_init(&apollon_dss_data);
 }
 
 static void __init omap_apollon_map_io(void)
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
index 22fef61..ef78550 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/omap/Makefile
@@ -25,7 +25,6 @@ objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o
 objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o
 objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
 
-objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
 objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
 objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o
 
diff --git a/drivers/video/omap/lcd_apollon.c b/drivers/video/omap/lcd_apollon.c
deleted file mode 100644
index 10459d8..0000000
--- a/drivers/video/omap/lcd_apollon.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * LCD panel support for the Samsung OMAP2 Apollon board
- *
- * Copyright (C) 2005,2006 Samsung Electronics
- * Author: Kyungmin Park <kyungmin.park@samsung.com>
- *
- * Derived from drivers/video/omap/lcd-h4.c
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-
-#include <mach/gpio.h>
-
-#include "omapfb.h"
-
-/* #define USE_35INCH_LCD 1 */
-
-static int apollon_panel_init(struct lcd_panel *panel,
-				struct omapfb_device *fbdev)
-{
-	return 0;
-}
-
-static void apollon_panel_cleanup(struct lcd_panel *panel)
-{
-}
-
-static int apollon_panel_enable(struct lcd_panel *panel)
-{
-	return 0;
-}
-
-static void apollon_panel_disable(struct lcd_panel *panel)
-{
-}
-
-static unsigned long apollon_panel_get_caps(struct lcd_panel *panel)
-{
-	return 0;
-}
-
-struct lcd_panel apollon_panel = {
-	.name		= "apollon",
-	.config		= OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
-			  OMAP_LCDC_INV_HSYNC,
-
-	.bpp		= 16,
-	.data_lines	= 18,
-#ifdef USE_35INCH_LCD
-	.x_res		= 240,
-	.y_res		= 320,
-	.hsw		= 2,
-	.hfp		= 3,
-	.hbp		= 9,
-	.vsw		= 4,
-	.vfp		= 3,
-	.vbp		= 5,
-#else
-	.x_res		= 480,
-	.y_res		= 272,
-	.hsw		= 41,
-	.hfp		= 2,
-	.hbp		= 2,
-	.vsw		= 10,
-	.vfp		= 2,
-	.vbp		= 2,
-#endif
-	.pixel_clock	= 6250,
-
-	.init		= apollon_panel_init,
-	.cleanup	= apollon_panel_cleanup,
-	.enable		= apollon_panel_enable,
-	.disable	= apollon_panel_disable,
-	.get_caps	= apollon_panel_get_caps,
-};
-
-static int apollon_panel_probe(struct platform_device *pdev)
-{
-	omapfb_register_panel(&apollon_panel);
-	return 0;
-}
-
-static int apollon_panel_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static int apollon_panel_suspend(struct platform_device *pdev,
-				  pm_message_t mesg)
-{
-	return 0;
-}
-
-static int apollon_panel_resume(struct platform_device *pdev)
-{
-	return 0;
-}
-
-struct platform_driver apollon_panel_driver = {
-	.probe		= apollon_panel_probe,
-	.remove		= apollon_panel_remove,
-	.suspend	= apollon_panel_suspend,
-	.resume		= apollon_panel_resume,
-	.driver		= {
-		.name	= "apollon_lcd",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init apollon_panel_drv_init(void)
-{
-	return platform_driver_register(&apollon_panel_driver);
-}
-
-static void __exit apollon_panel_drv_exit(void)
-{
-	platform_driver_unregister(&apollon_panel_driver);
-}
-
-module_init(apollon_panel_drv_init);
-module_exit(apollon_panel_drv_exit);
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 92bf63e..5b8ef3e 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -223,6 +223,28 @@ static struct panel_config generic_dpi_panels[] = {
 
 		.name			= "h4",
 	},
+
+	/* Unknown panel used in Samsung OMAP2 Apollon */
+	{
+		{
+			.x_res		= 480,
+			.y_res		= 272,
+
+			.pixel_clock	= 6250,
+
+			.hsw		= 41,
+			.hfp		= 2,
+			.hbp		= 2,
+
+			.vsw		= 10,
+			.vfp		= 2,
+			.vbp		= 2,
+		},
+		.config			= OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+						OMAP_DSS_LCD_IHS,
+
+		.name			= "apollon",
+	},
 };
 
 struct panel_drv_data {
-- 
1.7.4.1


^ permalink raw reply related

* Re: [PATCH 1/7] OMAP: OMAPFB: Remove unused lcd drivers
From: Steve Sakoman @ 2011-05-04 12:44 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, Arun C, Koen Kooi
In-Reply-To: <1304512059-10372-2-git-send-email-tomi.valkeinen@ti.com>

On Wed, May 4, 2011 at 5:27 AM, Tomi Valkeinen <tomi.valkeinen@ti.com> wrote:
> drivers/video/omap/ contains some lcd drivers which are not used by any
> board. They can be removed.
>
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: Arun C <arunedarath@mistralsolutions.com>
> Cc: Koen Kooi <koen@openembedded.org>
> Cc: Steve Sakoman <steve@sakoman.com>
> ---
>  drivers/video/omap/Makefile          |    4 -
>  drivers/video/omap/lcd_omap2evm.c    |  192 ---------------------------------
>  drivers/video/omap/lcd_omap3beagle.c |  130 -----------------------
>  drivers/video/omap/lcd_omap3evm.c    |  193 ----------------------------------
>  drivers/video/omap/lcd_overo.c       |  180 -------------------------------
>  5 files changed, 0 insertions(+), 699 deletions(-)
>  delete mode 100644 drivers/video/omap/lcd_omap2evm.c
>  delete mode 100644 drivers/video/omap/lcd_omap3beagle.c
>  delete mode 100644 drivers/video/omap/lcd_omap3evm.c
>  delete mode 100644 drivers/video/omap/lcd_overo.c

Acked-by: Steve Sakoman <steve@sakoman.com>

Steve

^ permalink raw reply

* Re: [PATCH 1/7] OMAP: OMAPFB: Remove unused lcd drivers
From: Koen Kooi @ 2011-05-04 13:43 UTC (permalink / raw)
  To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, Arun C, Koen Kooi, Steve Sakoman
In-Reply-To: <1304512059-10372-2-git-send-email-tomi.valkeinen@ti.com>


Op 4 mei 2011, om 14:27 heeft Tomi Valkeinen het volgende geschreven:

> drivers/video/omap/ contains some lcd drivers which are not used by any
> board. They can be removed.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
> Cc: Arun C <arunedarath@mistralsolutions.com>
> Cc: Koen Kooi <koen@openembedded.org>
> Cc: Steve Sakoman <steve@sakoman.com>

Acked-by: Koen Kooi <koen@openembedded.org>

> ---
> drivers/video/omap/Makefile          |    4 -
> drivers/video/omap/lcd_omap2evm.c    |  192 ---------------------------------
> drivers/video/omap/lcd_omap3beagle.c |  130 -----------------------
> drivers/video/omap/lcd_omap3evm.c    |  193 ----------------------------------
> drivers/video/omap/lcd_overo.c       |  180 -------------------------------
> 5 files changed, 0 insertions(+), 699 deletions(-)
> delete mode 100644 drivers/video/omap/lcd_omap2evm.c
> delete mode 100644 drivers/video/omap/lcd_omap3beagle.c
> delete mode 100644 drivers/video/omap/lcd_omap3evm.c
> delete mode 100644 drivers/video/omap/lcd_overo.c
> 
> diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
> index 49226a1..8eec6d7 100644
> --- a/drivers/video/omap/Makefile
> +++ b/drivers/video/omap/Makefile
> @@ -30,11 +30,7 @@ objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
> objs-y$(CONFIG_MACH_OMAP_2430SDP) += lcd_2430sdp.o
> objs-y$(CONFIG_MACH_OMAP_3430SDP) += lcd_2430sdp.o
> objs-y$(CONFIG_MACH_OMAP_LDP) += lcd_ldp.o
> -objs-y$(CONFIG_MACH_OMAP2EVM) += lcd_omap2evm.o
> -objs-y$(CONFIG_MACH_OMAP3EVM) += lcd_omap3evm.o
> -objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o
> objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
> -objs-y$(CONFIG_MACH_OVERO) += lcd_overo.o
> objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o
> 
> omapfb-objs := $(objs-yy)
> diff --git a/drivers/video/omap/lcd_omap2evm.c b/drivers/video/omap/lcd_omap2evm.c
> deleted file mode 100644
> index 7e7a65c..0000000
> --- a/drivers/video/omap/lcd_omap2evm.c
> +++ /dev/null
> @@ -1,192 +0,0 @@
> -/*
> - * LCD panel support for the MISTRAL OMAP2EVM board
> - *
> - * Author: Arun C <arunedarath@mistralsolutions.com>
> - *
> - * Derived from drivers/video/omap/lcd_omap3evm.c
> - * Derived from drivers/video/omap/lcd-apollon.c
> - *
> - * This program is free software; you can redistribute it and/or modify it
> - * under the terms of the GNU General Public License as published by the
> - * Free Software Foundation; either version 2 of the License, or (at your
> - * option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License along
> - * with this program; if not, write to the Free Software Foundation, Inc.,
> - * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
> - */
> -
> -#include <linux/module.h>
> -#include <linux/platform_device.h>
> -#include <linux/gpio.h>
> -#include <linux/i2c/twl.h>
> -
> -#include <plat/mux.h>
> -#include <asm/mach-types.h>
> -
> -#include "omapfb.h"
> -
> -#define LCD_PANEL_ENABLE_GPIO	154
> -#define LCD_PANEL_LR		128
> -#define LCD_PANEL_UD		129
> -#define LCD_PANEL_INI		152
> -#define LCD_PANEL_QVGA		148
> -#define LCD_PANEL_RESB		153
> -
> -#define TWL_LED_LEDEN		0x00
> -#define TWL_PWMA_PWMAON		0x00
> -#define TWL_PWMA_PWMAOFF	0x01
> -
> -static unsigned int bklight_level;
> -
> -static int omap2evm_panel_init(struct lcd_panel *panel,
> -				struct omapfb_device *fbdev)
> -{
> -	gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable");
> -	gpio_request(LCD_PANEL_LR, "LCD lr");
> -	gpio_request(LCD_PANEL_UD, "LCD ud");
> -	gpio_request(LCD_PANEL_INI, "LCD ini");
> -	gpio_request(LCD_PANEL_QVGA, "LCD qvga");
> -	gpio_request(LCD_PANEL_RESB, "LCD resb");
> -
> -	gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
> -	gpio_direction_output(LCD_PANEL_RESB, 1);
> -	gpio_direction_output(LCD_PANEL_INI, 1);
> -	gpio_direction_output(LCD_PANEL_QVGA, 0);
> -	gpio_direction_output(LCD_PANEL_LR, 1);
> -	gpio_direction_output(LCD_PANEL_UD, 1);
> -
> -	twl_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN);
> -	twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON);
> -	twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF);
> -	bklight_level = 100;
> -
> -	return 0;
> -}
> -
> -static void omap2evm_panel_cleanup(struct lcd_panel *panel)
> -{
> -	gpio_free(LCD_PANEL_RESB);
> -	gpio_free(LCD_PANEL_QVGA);
> -	gpio_free(LCD_PANEL_INI);
> -	gpio_free(LCD_PANEL_UD);
> -	gpio_free(LCD_PANEL_LR);
> -	gpio_free(LCD_PANEL_ENABLE_GPIO);
> -}
> -
> -static int omap2evm_panel_enable(struct lcd_panel *panel)
> -{
> -	gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
> -	return 0;
> -}
> -
> -static void omap2evm_panel_disable(struct lcd_panel *panel)
> -{
> -	gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
> -}
> -
> -static unsigned long omap2evm_panel_get_caps(struct lcd_panel *panel)
> -{
> -	return 0;
> -}
> -
> -static int omap2evm_bklight_setlevel(struct lcd_panel *panel,
> -						unsigned int level)
> -{
> -	u8 c;
> -	if ((level >= 0) && (level <= 100)) {
> -		c = (125 * (100 - level)) / 100 + 2;
> -		twl_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF);
> -		bklight_level = level;
> -	}
> -	return 0;
> -}
> -
> -static unsigned int omap2evm_bklight_getlevel(struct lcd_panel *panel)
> -{
> -	return bklight_level;
> -}
> -
> -static unsigned int omap2evm_bklight_getmaxlevel(struct lcd_panel *panel)
> -{
> -	return 100;
> -}
> -
> -struct lcd_panel omap2evm_panel = {
> -	.name		= "omap2evm",
> -	.config		= OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
> -			  OMAP_LCDC_INV_HSYNC,
> -
> -	.bpp		= 16,
> -	.data_lines	= 18,
> -	.x_res		= 480,
> -	.y_res		= 640,
> -	.hsw		= 3,
> -	.hfp		= 0,
> -	.hbp		= 28,
> -	.vsw		= 2,
> -	.vfp		= 1,
> -	.vbp		= 0,
> -
> -	.pixel_clock	= 20000,
> -
> -	.init		= omap2evm_panel_init,
> -	.cleanup	= omap2evm_panel_cleanup,
> -	.enable		= omap2evm_panel_enable,
> -	.disable	= omap2evm_panel_disable,
> -	.get_caps	= omap2evm_panel_get_caps,
> -	.set_bklight_level      = omap2evm_bklight_setlevel,
> -	.get_bklight_level      = omap2evm_bklight_getlevel,
> -	.get_bklight_max        = omap2evm_bklight_getmaxlevel,
> -};
> -
> -static int omap2evm_panel_probe(struct platform_device *pdev)
> -{
> -	omapfb_register_panel(&omap2evm_panel);
> -	return 0;
> -}
> -
> -static int omap2evm_panel_remove(struct platform_device *pdev)
> -{
> -	return 0;
> -}
> -
> -static int omap2evm_panel_suspend(struct platform_device *pdev,
> -				   pm_message_t mesg)
> -{
> -	return 0;
> -}
> -
> -static int omap2evm_panel_resume(struct platform_device *pdev)
> -{
> -	return 0;
> -}
> -
> -struct platform_driver omap2evm_panel_driver = {
> -	.probe		= omap2evm_panel_probe,
> -	.remove		= omap2evm_panel_remove,
> -	.suspend	= omap2evm_panel_suspend,
> -	.resume		= omap2evm_panel_resume,
> -	.driver		= {
> -		.name	= "omap2evm_lcd",
> -		.owner	= THIS_MODULE,
> -	},
> -};
> -
> -static int __init omap2evm_panel_drv_init(void)
> -{
> -	return platform_driver_register(&omap2evm_panel_driver);
> -}
> -
> -static void __exit omap2evm_panel_drv_exit(void)
> -{
> -	platform_driver_unregister(&omap2evm_panel_driver);
> -}
> -
> -module_init(omap2evm_panel_drv_init);
> -module_exit(omap2evm_panel_drv_exit);
> diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
> deleted file mode 100644
> index d7c6c3e..0000000
> --- a/drivers/video/omap/lcd_omap3beagle.c
> +++ /dev/null
> @@ -1,130 +0,0 @@
> -/*
> - * LCD panel support for the TI OMAP3 Beagle board
> - *
> - * Author: Koen Kooi <koen@openembedded.org>
> - *
> - * Derived from drivers/video/omap/lcd-omap3evm.c
> - *
> - * This program is free software; you can redistribute it and/or modify it
> - * under the terms of the GNU General Public License as published by the
> - * Free Software Foundation; either version 2 of the License, or (at your
> - * option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License along
> - * with this program; if not, write to the Free Software Foundation, Inc.,
> - * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
> - */
> -
> -#include <linux/module.h>
> -#include <linux/platform_device.h>
> -#include <linux/gpio.h>
> -#include <linux/i2c/twl.h>
> -
> -#include <asm/mach-types.h>
> -
> -#include "omapfb.h"
> -
> -#define LCD_PANEL_ENABLE_GPIO       170
> -
> -static int omap3beagle_panel_init(struct lcd_panel *panel,
> -				struct omapfb_device *fbdev)
> -{
> -	gpio_request(LCD_PANEL_ENABLE_GPIO, "LCD enable");
> -	return 0;
> -}
> -
> -static void omap3beagle_panel_cleanup(struct lcd_panel *panel)
> -{
> -	gpio_free(LCD_PANEL_ENABLE_GPIO);
> -}
> -
> -static int omap3beagle_panel_enable(struct lcd_panel *panel)
> -{
> -	gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
> -	return 0;
> -}
> -
> -static void omap3beagle_panel_disable(struct lcd_panel *panel)
> -{
> -	gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
> -}
> -
> -static unsigned long omap3beagle_panel_get_caps(struct lcd_panel *panel)
> -{
> -	return 0;
> -}
> -
> -struct lcd_panel omap3beagle_panel = {
> -	.name		= "omap3beagle",
> -	.config		= OMAP_LCDC_PANEL_TFT,
> -
> -	.bpp		= 16,
> -	.data_lines	= 24,
> -	.x_res		= 1024,
> -	.y_res		= 768,
> -	.hsw		= 3,		/* hsync_len (4) - 1 */
> -	.hfp		= 3,		/* right_margin (4) - 1 */
> -	.hbp		= 39,		/* left_margin (40) - 1 */
> -	.vsw		= 1,		/* vsync_len (2) - 1 */
> -	.vfp		= 2,		/* lower_margin */
> -	.vbp		= 7,		/* upper_margin (8) - 1 */
> -
> -	.pixel_clock	= 64000,
> -
> -	.init		= omap3beagle_panel_init,
> -	.cleanup	= omap3beagle_panel_cleanup,
> -	.enable		= omap3beagle_panel_enable,
> -	.disable	= omap3beagle_panel_disable,
> -	.get_caps	= omap3beagle_panel_get_caps,
> -};
> -
> -static int omap3beagle_panel_probe(struct platform_device *pdev)
> -{
> -	omapfb_register_panel(&omap3beagle_panel);
> -	return 0;
> -}
> -
> -static int omap3beagle_panel_remove(struct platform_device *pdev)
> -{
> -	return 0;
> -}
> -
> -static int omap3beagle_panel_suspend(struct platform_device *pdev,
> -				   pm_message_t mesg)
> -{
> -	return 0;
> -}
> -
> -static int omap3beagle_panel_resume(struct platform_device *pdev)
> -{
> -	return 0;
> -}
> -
> -struct platform_driver omap3beagle_panel_driver = {
> -	.probe		= omap3beagle_panel_probe,
> -	.remove		= omap3beagle_panel_remove,
> -	.suspend	= omap3beagle_panel_suspend,
> -	.resume		= omap3beagle_panel_resume,
> -	.driver		= {
> -		.name	= "omap3beagle_lcd",
> -		.owner	= THIS_MODULE,
> -	},
> -};
> -
> -static int __init omap3beagle_panel_drv_init(void)
> -{
> -	return platform_driver_register(&omap3beagle_panel_driver);
> -}
> -
> -static void __exit omap3beagle_panel_drv_exit(void)
> -{
> -	platform_driver_unregister(&omap3beagle_panel_driver);
> -}
> -
> -module_init(omap3beagle_panel_drv_init);
> -module_exit(omap3beagle_panel_drv_exit);
> diff --git a/drivers/video/omap/lcd_omap3evm.c b/drivers/video/omap/lcd_omap3evm.c
> deleted file mode 100644
> index 06840da..0000000
> --- a/drivers/video/omap/lcd_omap3evm.c
> +++ /dev/null
> @@ -1,193 +0,0 @@
> -/*
> - * LCD panel support for the TI OMAP3 EVM board
> - *
> - * Author: Steve Sakoman <steve@sakoman.com>
> - *
> - * Derived from drivers/video/omap/lcd-apollon.c
> - *
> - * This program is free software; you can redistribute it and/or modify it
> - * under the terms of the GNU General Public License as published by the
> - * Free Software Foundation; either version 2 of the License, or (at your
> - * option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License along
> - * with this program; if not, write to the Free Software Foundation, Inc.,
> - * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
> - */
> -
> -#include <linux/module.h>
> -#include <linux/platform_device.h>
> -#include <linux/gpio.h>
> -#include <linux/i2c/twl.h>
> -
> -#include <plat/mux.h>
> -#include <asm/mach-types.h>
> -
> -#include "omapfb.h"
> -
> -#define LCD_PANEL_ENABLE_GPIO       153
> -#define LCD_PANEL_LR                2
> -#define LCD_PANEL_UD                3
> -#define LCD_PANEL_INI               152
> -#define LCD_PANEL_QVGA              154
> -#define LCD_PANEL_RESB              155
> -
> -#define ENABLE_VDAC_DEDICATED	0x03
> -#define ENABLE_VDAC_DEV_GRP	0x20
> -#define ENABLE_VPLL2_DEDICATED	0x05
> -#define ENABLE_VPLL2_DEV_GRP	0xE0
> -
> -#define TWL_LED_LEDEN		0x00
> -#define TWL_PWMA_PWMAON		0x00
> -#define TWL_PWMA_PWMAOFF	0x01
> -
> -static unsigned int bklight_level;
> -
> -static int omap3evm_panel_init(struct lcd_panel *panel,
> -				struct omapfb_device *fbdev)
> -{
> -	gpio_request(LCD_PANEL_LR, "LCD lr");
> -	gpio_request(LCD_PANEL_UD, "LCD ud");
> -	gpio_request(LCD_PANEL_INI, "LCD ini");
> -	gpio_request(LCD_PANEL_RESB, "LCD resb");
> -	gpio_request(LCD_PANEL_QVGA, "LCD qvga");
> -
> -	gpio_direction_output(LCD_PANEL_RESB, 1);
> -	gpio_direction_output(LCD_PANEL_INI, 1);
> -	gpio_direction_output(LCD_PANEL_QVGA, 0);
> -	gpio_direction_output(LCD_PANEL_LR, 1);
> -	gpio_direction_output(LCD_PANEL_UD, 1);
> -
> -	twl_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN);
> -	twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON);
> -	twl_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF);
> -	bklight_level = 100;
> -
> -	return 0;
> -}
> -
> -static void omap3evm_panel_cleanup(struct lcd_panel *panel)
> -{
> -	gpio_free(LCD_PANEL_QVGA);
> -	gpio_free(LCD_PANEL_RESB);
> -	gpio_free(LCD_PANEL_INI);
> -	gpio_free(LCD_PANEL_UD);
> -	gpio_free(LCD_PANEL_LR);
> -}
> -
> -static int omap3evm_panel_enable(struct lcd_panel *panel)
> -{
> -	gpio_set_value(LCD_PANEL_ENABLE_GPIO, 0);
> -	return 0;
> -}
> -
> -static void omap3evm_panel_disable(struct lcd_panel *panel)
> -{
> -	gpio_set_value(LCD_PANEL_ENABLE_GPIO, 1);
> -}
> -
> -static unsigned long omap3evm_panel_get_caps(struct lcd_panel *panel)
> -{
> -	return 0;
> -}
> -
> -static int omap3evm_bklight_setlevel(struct lcd_panel *panel,
> -						unsigned int level)
> -{
> -	u8 c;
> -	if ((level >= 0) && (level <= 100)) {
> -		c = (125 * (100 - level)) / 100 + 2;
> -		twl_i2c_write_u8(TWL4030_MODULE_PWMA, c, TWL_PWMA_PWMAOFF);
> -		bklight_level = level;
> -	}
> -	return 0;
> -}
> -
> -static unsigned int omap3evm_bklight_getlevel(struct lcd_panel *panel)
> -{
> -	return bklight_level;
> -}
> -
> -static unsigned int omap3evm_bklight_getmaxlevel(struct lcd_panel *panel)
> -{
> -	return 100;
> -}
> -
> -struct lcd_panel omap3evm_panel = {
> -	.name		= "omap3evm",
> -	.config		= OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
> -			  OMAP_LCDC_INV_HSYNC,
> -
> -	.bpp		= 16,
> -	.data_lines	= 18,
> -	.x_res		= 480,
> -	.y_res		= 640,
> -	.hsw		= 3,		/* hsync_len (4) - 1 */
> -	.hfp		= 3,		/* right_margin (4) - 1 */
> -	.hbp		= 39,		/* left_margin (40) - 1 */
> -	.vsw		= 1,		/* vsync_len (2) - 1 */
> -	.vfp		= 2,		/* lower_margin */
> -	.vbp		= 7,		/* upper_margin (8) - 1 */
> -
> -	.pixel_clock	= 26000,
> -
> -	.init		= omap3evm_panel_init,
> -	.cleanup	= omap3evm_panel_cleanup,
> -	.enable		= omap3evm_panel_enable,
> -	.disable	= omap3evm_panel_disable,
> -	.get_caps	= omap3evm_panel_get_caps,
> -	.set_bklight_level      = omap3evm_bklight_setlevel,
> -	.get_bklight_level      = omap3evm_bklight_getlevel,
> -	.get_bklight_max        = omap3evm_bklight_getmaxlevel,
> -};
> -
> -static int omap3evm_panel_probe(struct platform_device *pdev)
> -{
> -	omapfb_register_panel(&omap3evm_panel);
> -	return 0;
> -}
> -
> -static int omap3evm_panel_remove(struct platform_device *pdev)
> -{
> -	return 0;
> -}
> -
> -static int omap3evm_panel_suspend(struct platform_device *pdev,
> -				   pm_message_t mesg)
> -{
> -	return 0;
> -}
> -
> -static int omap3evm_panel_resume(struct platform_device *pdev)
> -{
> -	return 0;
> -}
> -
> -struct platform_driver omap3evm_panel_driver = {
> -	.probe		= omap3evm_panel_probe,
> -	.remove		= omap3evm_panel_remove,
> -	.suspend	= omap3evm_panel_suspend,
> -	.resume		= omap3evm_panel_resume,
> -	.driver		= {
> -		.name	= "omap3evm_lcd",
> -		.owner	= THIS_MODULE,
> -	},
> -};
> -
> -static int __init omap3evm_panel_drv_init(void)
> -{
> -	return platform_driver_register(&omap3evm_panel_driver);
> -}
> -
> -static void __exit omap3evm_panel_drv_exit(void)
> -{
> -	platform_driver_unregister(&omap3evm_panel_driver);
> -}
> -
> -module_init(omap3evm_panel_drv_init);
> -module_exit(omap3evm_panel_drv_exit);
> diff --git a/drivers/video/omap/lcd_overo.c b/drivers/video/omap/lcd_overo.c
> deleted file mode 100644
> index 564933f..0000000
> --- a/drivers/video/omap/lcd_overo.c
> +++ /dev/null
> @@ -1,180 +0,0 @@
> -/*
> - * LCD panel support for the Gumstix Overo
> - *
> - * Author: Steve Sakoman <steve@sakoman.com>
> - *
> - * This program is free software; you can redistribute it and/or modify it
> - * under the terms of the GNU General Public License as published by the
> - * Free Software Foundation; either version 2 of the License, or (at your
> - * option) any later version.
> - *
> - * This program is distributed in the hope that it will be useful, but
> - * WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> - * General Public License for more details.
> - *
> - * You should have received a copy of the GNU General Public License along
> - * with this program; if not, write to the Free Software Foundation, Inc.,
> - * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
> - *
> - */
> -
> -#include <linux/module.h>
> -#include <linux/platform_device.h>
> -#include <linux/i2c/twl.h>
> -
> -#include <mach/gpio.h>
> -#include <plat/mux.h>
> -#include <asm/mach-types.h>
> -
> -#include "omapfb.h"
> -
> -#define LCD_ENABLE       144
> -
> -static int overo_panel_init(struct lcd_panel *panel,
> -				struct omapfb_device *fbdev)
> -{
> -	if ((gpio_request(LCD_ENABLE, "LCD_ENABLE") = 0) &&
> -	    (gpio_direction_output(LCD_ENABLE, 1) = 0))
> -		gpio_export(LCD_ENABLE, 0);
> -	else
> -		printk(KERN_ERR "could not obtain gpio for LCD_ENABLE\n");
> -
> -	return 0;
> -}
> -
> -static void overo_panel_cleanup(struct lcd_panel *panel)
> -{
> -	gpio_free(LCD_ENABLE);
> -}
> -
> -static int overo_panel_enable(struct lcd_panel *panel)
> -{
> -	gpio_set_value(LCD_ENABLE, 1);
> -	return 0;
> -}
> -
> -static void overo_panel_disable(struct lcd_panel *panel)
> -{
> -	gpio_set_value(LCD_ENABLE, 0);
> -}
> -
> -static unsigned long overo_panel_get_caps(struct lcd_panel *panel)
> -{
> -	return 0;
> -}
> -
> -struct lcd_panel overo_panel = {
> -	.name		= "overo",
> -	.config		= OMAP_LCDC_PANEL_TFT,
> -	.bpp		= 16,
> -	.data_lines	= 24,
> -
> -#if defined CONFIG_FB_OMAP_031M3R
> -
> -	/* 640 x 480 @ 60 Hz  Reduced blanking VESA CVT 0.31M3-R */
> -	.x_res		= 640,
> -	.y_res		= 480,
> -	.hfp		= 48,
> -	.hsw		= 32,
> -	.hbp		= 80,
> -	.vfp		= 3,
> -	.vsw		= 4,
> -	.vbp		= 7,
> -	.pixel_clock	= 23500,
> -
> -#elif defined CONFIG_FB_OMAP_048M3R
> -
> -	/* 800 x 600 @ 60 Hz  Reduced blanking VESA CVT 0.48M3-R */
> -	.x_res		= 800,
> -	.y_res		= 600,
> -	.hfp		= 48,
> -	.hsw		= 32,
> -	.hbp		= 80,
> -	.vfp		= 3,
> -	.vsw		= 4,
> -	.vbp		= 11,
> -	.pixel_clock	= 35500,
> -
> -#elif defined CONFIG_FB_OMAP_079M3R
> -
> -	/* 1024 x 768 @ 60 Hz  Reduced blanking VESA CVT 0.79M3-R */
> -	.x_res		= 1024,
> -	.y_res		= 768,
> -	.hfp		= 48,
> -	.hsw		= 32,
> -	.hbp		= 80,
> -	.vfp		= 3,
> -	.vsw		= 4,
> -	.vbp		= 15,
> -	.pixel_clock	= 56000,
> -
> -#elif defined CONFIG_FB_OMAP_092M9R
> -
> -	/* 1280 x 720 @ 60 Hz  Reduced blanking VESA CVT 0.92M9-R */
> -	.x_res		= 1280,
> -	.y_res		= 720,
> -	.hfp		= 48,
> -	.hsw		= 32,
> -	.hbp		= 80,
> -	.vfp		= 3,
> -	.vsw		= 5,
> -	.vbp		= 13,
> -	.pixel_clock	= 64000,
> -
> -#else
> -
> -	/* use 640 x 480 if no config option */
> -	/* 640 x 480 @ 60 Hz  Reduced blanking VESA CVT 0.31M3-R */
> -	.x_res		= 640,
> -	.y_res		= 480,
> -	.hfp		= 48,
> -	.hsw		= 32,
> -	.hbp		= 80,
> -	.vfp		= 3,
> -	.vsw		= 4,
> -	.vbp		= 7,
> -	.pixel_clock	= 23500,
> -
> -#endif
> -
> -	.init		= overo_panel_init,
> -	.cleanup	= overo_panel_cleanup,
> -	.enable		= overo_panel_enable,
> -	.disable	= overo_panel_disable,
> -	.get_caps	= overo_panel_get_caps,
> -};
> -
> -static int overo_panel_probe(struct platform_device *pdev)
> -{
> -	omapfb_register_panel(&overo_panel);
> -	return 0;
> -}
> -
> -static int overo_panel_remove(struct platform_device *pdev)
> -{
> -	/* omapfb does not have unregister_panel */
> -	return 0;
> -}
> -
> -static struct platform_driver overo_panel_driver = {
> -	.probe		= overo_panel_probe,
> -	.remove		= overo_panel_remove,
> -	.driver		= {
> -		.name	= "overo_lcd",
> -		.owner	= THIS_MODULE,
> -	},
> -};
> -
> -static int __init overo_panel_drv_init(void)
> -{
> -	return platform_driver_register(&overo_panel_driver);
> -}
> -
> -static void __exit overo_panel_drv_exit(void)
> -{
> -	platform_driver_unregister(&overo_panel_driver);
> -}
> -
> -module_init(overo_panel_drv_init);
> -module_exit(overo_panel_drv_exit);
> -- 
> 1.7.4.1
> 


^ permalink raw reply

* [PATCH] fbdev: sh_mobile_lcdc: reduce scope of a variable
From: Guennadi Liakhovetski @ 2011-05-05 16:32 UTC (permalink / raw)
  To: linux-fbdev

The "ret" variable in sh_mobile_lcdc_start() is only used at one
location, move its definition to the inner-most scope.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/video/sh_mobile_lcdcfb.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 9bcc61b..466834c 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -469,7 +469,6 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
 	int bpp = 0;
 	unsigned long ldddsr;
 	int k, m;
-	int ret = 0;
 
 	/* enable clocks before accessing the hardware */
 	for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
@@ -538,11 +537,12 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
 		lcdc_write_chan(ch, LDPMR, 0);
 
 		board_cfg = &ch->cfg.board_cfg;
-		if (board_cfg->setup_sys)
-			ret = board_cfg->setup_sys(board_cfg->board_data, ch,
-						   &sh_mobile_lcdc_sys_bus_ops);
-		if (ret)
-			return ret;
+		if (board_cfg->setup_sys) {
+			int ret = board_cfg->setup_sys(board_cfg->board_data,
+						ch, &sh_mobile_lcdc_sys_bus_ops);
+			if (ret)
+				return ret;
+		}
 	}
 
 	/* word and long word swap */
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] fbdev: sh_mobile_lcdc: remove runtime PM calls from the
From: Guennadi Liakhovetski @ 2011-05-05 16:33 UTC (permalink / raw)
  To: linux-fbdev

The notifier function calls sh_mobile_lcdc_stop() and
sh_mobile_lcdc_start(), which already take care about the runtime PM
state. Remove redundant calls.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/video/sh_mobile_lcdcfb.c |    6 +-----
 1 files changed, 1 insertions(+), 5 deletions(-)

diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 466834c..04f2260 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1288,7 +1288,6 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
 	struct fb_info *info = event->info;
 	struct sh_mobile_lcdc_chan *ch = info->par;
 	struct sh_mobile_lcdc_board_cfg	*board_cfg = &ch->cfg.board_cfg;
-	int ret;
 
 	if (&ch->lcdc->notifier != nb)
 		return NOTIFY_DONE;
@@ -1302,7 +1301,6 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
 			board_cfg->display_off(board_cfg->board_data);
 			module_put(board_cfg->owner);
 		}
-		pm_runtime_put(info->device);
 		sh_mobile_lcdc_stop(ch->lcdc);
 		break;
 	case FB_EVENT_RESUME:
@@ -1316,9 +1314,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
 			module_put(board_cfg->owner);
 		}
 
-		ret = sh_mobile_lcdc_start(ch->lcdc);
-		if (!ret)
-			pm_runtime_get_sync(info->device);
+		sh_mobile_lcdc_start(ch->lcdc);
 	}
 
 	return NOTIFY_OK;
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH] fbdev: sh_mobile_hdmi: runtime suspend HDMI on error and
From: Guennadi Liakhovetski @ 2011-05-05 16:35 UTC (permalink / raw)
  To: linux-fbdev

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 drivers/video/sh_mobile_hdmi.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
index 2b9e56a..6ae40b6 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/sh_mobile_hdmi.c
@@ -1131,15 +1131,19 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
 		pm_runtime_get_sync(hdmi->dev);
 
 		ret = sh_hdmi_read_edid(hdmi, &hdmi_rate, &parent_rate);
-		if (ret < 0)
+		if (ret < 0) {
+			pm_runtime_put(hdmi->dev);
 			goto out;
+		}
 
 		hdmi->hp_state = HDMI_HOTPLUG_EDID_DONE;
 
 		/* Reconfigure the clock */
 		ret = sh_hdmi_clk_configure(hdmi, hdmi_rate, parent_rate);
-		if (ret < 0)
+		if (ret < 0) {
+			pm_runtime_put(hdmi->dev);
 			goto out;
+		}
 
 		msleep(10);
 		sh_hdmi_configure(hdmi);
@@ -1336,6 +1340,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)
 ecodec:
 	free_irq(irq, hdmi);
 ereqirq:
+	pm_runtime_suspend(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	iounmap(hdmi->base);
 emap:
@@ -1372,6 +1377,7 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)
 	free_irq(irq, hdmi);
 	/* Wait for already scheduled work */
 	cancel_delayed_work_sync(&hdmi->edid_work);
+	pm_runtime_suspend(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	clk_disable(hdmi->hdmi_clk);
 	clk_put(hdmi->hdmi_clk);
-- 
1.7.2.5


^ permalink raw reply related

* [PATCH 0/1] fbcon -- fix race between open and removal of framebuffers
From: tim.gardner @ 2011-05-05 17:41 UTC (permalink / raw)
  To: linux-fbdev; +Cc: lethal, linux-kernel


I'm sending this out for Andy since he is a bit busy this week and has been
gone for the past several weeks. Its been on our todo list to get this
upstreamed, but release pressures have intervened. Mea culpa. I've also had
a couple of requests recently which have served to remind me to get off my butt.

https://lists.ubuntu.com/archives/kernel-team/2011-May/015544.html

rtg

^ permalink raw reply

* [PATCH] fbcon -- fix race between open and removal of framebuffers
From: tim.gardner @ 2011-05-05 17:41 UTC (permalink / raw)
  To: linux-fbdev
  Cc: lethal, linux-kernel, Andy Whitcroft, Leann Ogasawara,
	Tim Gardner
In-Reply-To: <1304617307-7389-1-git-send-email-tim.gardner@canonical.com>

From: Andy Whitcroft <apw@canonical.com>

Currently there is no locking for updates to the registered_fb list.
This allows an open through /dev/fbN to pick up a registered framebuffer
pointer in parallel with it being released, as happens when a conflicting
framebuffer is ejected or on module unload.  There is also no reference
counting on the framebuffer descriptor which is referenced from all open
files, leading to references to released or reused memory to persist on
these open files.

This patch adds a reference count to the framebuffer descriptor to prevent
it from being released until after all pending opens are closed.  This
allows the pending opens to detect the closed status and unmap themselves.
It also adds locking to the framebuffer lookup path, locking it against
the removal path such that it is possible to atomically lookup and take a
reference to the descriptor.  It also adds locking to the read and write
paths which currently could access the framebuffer descriptor after it
has been freed.  Finally it moves the device to FBINFO_STATE_REMOVED to
indicate that all access should be errored for this device.

Signed-off-by: Andy Whitcroft <apw@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---
 drivers/video/fbmem.c |  132 ++++++++++++++++++++++++++++++++++++++-----------
 include/linux/fb.h    |    2 +
 2 files changed, 105 insertions(+), 29 deletions(-)

diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index e0c2284..c8562c1 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -42,6 +42,8 @@
 
 #define FBPIXMAPSIZE	(1024 * 8)
 
+/* Protects the registered framebuffer list and count. */
+static DEFINE_SPINLOCK(registered_lock);
 struct fb_info *registered_fb[FB_MAX] __read_mostly;
 int num_registered_fb __read_mostly;
 
@@ -694,9 +696,7 @@ static ssize_t
 fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
-	struct inode *inode = file->f_path.dentry->d_inode;
-	int fbidx = iminor(inode);
-	struct fb_info *info = registered_fb[fbidx];
+	struct fb_info *info = file->private_data;
 	u8 *buffer, *dst;
 	u8 __iomem *src;
 	int c, cnt = 0, err = 0;
@@ -705,19 +705,28 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 	if (!info || ! info->screen_base)
 		return -ENODEV;
 
-	if (info->state != FBINFO_STATE_RUNNING)
-		return -EPERM;
+	if (!lock_fb_info(info))
+		return -ENODEV;
+
+	if (info->state != FBINFO_STATE_RUNNING) {
+		err = -EPERM;
+		goto out_fb_info;
+	}
 
-	if (info->fbops->fb_read)
-		return info->fbops->fb_read(info, buf, count, ppos);
+	if (info->fbops->fb_read) {
+		err = info->fbops->fb_read(info, buf, count, ppos);
+		goto out_fb_info;
+	}
 	
 	total_size = info->screen_size;
 
 	if (total_size = 0)
 		total_size = info->fix.smem_len;
 
-	if (p >= total_size)
-		return 0;
+	if (p >= total_size) {
+		err = 0;
+		goto out_fb_info;
+	}
 
 	if (count >= total_size)
 		count = total_size;
@@ -727,8 +736,10 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 
 	buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
 			 GFP_KERNEL);
-	if (!buffer)
-		return -ENOMEM;
+	if (!buffer) {
+		err = -ENOMEM;
+		goto out_fb_info;
+	}
 
 	src = (u8 __iomem *) (info->screen_base + p);
 
@@ -751,19 +762,21 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 		cnt += c;
 		count -= c;
 	}
+	if (!err)
+		err = cnt;
 
 	kfree(buffer);
+out_fb_info:
+	unlock_fb_info(info);
 
-	return (err) ? err : cnt;
+	return err;
 }
 
 static ssize_t
 fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
-	struct inode *inode = file->f_path.dentry->d_inode;
-	int fbidx = iminor(inode);
-	struct fb_info *info = registered_fb[fbidx];
+	struct fb_info *info = file->private_data;
 	u8 *buffer, *src;
 	u8 __iomem *dst;
 	int c, cnt = 0, err = 0;
@@ -772,8 +785,13 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 	if (!info || !info->screen_base)
 		return -ENODEV;
 
-	if (info->state != FBINFO_STATE_RUNNING)
-		return -EPERM;
+	if (!lock_fb_info(info))
+		return -ENODEV;
+
+	if (info->state != FBINFO_STATE_RUNNING) {
+		err = -EPERM;
+		goto out_fb_info;
+	}
 
 	if (info->fbops->fb_write)
 		return info->fbops->fb_write(info, buf, count, ppos);
@@ -783,8 +801,10 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 	if (total_size = 0)
 		total_size = info->fix.smem_len;
 
-	if (p > total_size)
-		return -EFBIG;
+	if (p > total_size) {
+		err = -EFBIG;
+		goto out_fb_info;
+	}
 
 	if (count > total_size) {
 		err = -EFBIG;
@@ -800,8 +820,10 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 
 	buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
 			 GFP_KERNEL);
-	if (!buffer)
-		return -ENOMEM;
+	if (!buffer) {
+		err = -ENOMEM;
+		goto out_fb_info;
+	}
 
 	dst = (u8 __iomem *) (info->screen_base + p);
 
@@ -825,10 +847,14 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 		cnt += c;
 		count -= c;
 	}
+	if (cnt)
+		err = cnt;
 
 	kfree(buffer);
+out_fb_info:
+	unlock_fb_info(info);
 
-	return (cnt) ? cnt : err;
+	return err;
 }
 
 int
@@ -1303,8 +1329,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd,
 static int
 fb_mmap(struct file *file, struct vm_area_struct * vma)
 {
-	int fbidx = iminor(file->f_path.dentry->d_inode);
-	struct fb_info *info = registered_fb[fbidx];
+	struct fb_info * const info = file->private_data;
 	struct fb_ops *fb = info->fbops;
 	unsigned long off;
 	unsigned long start;
@@ -1316,6 +1341,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
 	if (!fb)
 		return -ENODEV;
 	mutex_lock(&info->mm_lock);
+	if (info->state = FBINFO_STATE_REMOVED) {
+		mutex_unlock(&info->mm_lock);
+		return -ENODEV;
+	}
+
 	if (fb->fb_mmap) {
 		int res;
 		res = fb->fb_mmap(info, vma);
@@ -1352,6 +1382,34 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
 	return 0;
 }
 
+static struct fb_info *get_framebuffer_info(int idx)
+__acquires(&registered_lock)
+__releases(&registered_lock)
+{
+	struct fb_info *fb_info;
+
+	spin_lock(&registered_lock);
+	fb_info = registered_fb[idx];
+	fb_info->ref_count++;
+	spin_unlock(&registered_lock);
+
+	return fb_info;
+}
+
+static void put_framebuffer_info(struct fb_info *fb_info)
+__acquires(&registered_lock)
+__releases(&registered_lock)
+{
+	int keep;
+
+	spin_lock(&registered_lock);
+	keep = --fb_info->ref_count;
+	spin_unlock(&registered_lock);
+
+	if (!keep && fb_info->fbops->fb_destroy)
+		fb_info->fbops->fb_destroy(fb_info);
+}
+
 static int
 fb_open(struct inode *inode, struct file *file)
 __acquires(&info->lock)
@@ -1363,13 +1421,17 @@ __releases(&info->lock)
 
 	if (fbidx >= FB_MAX)
 		return -ENODEV;
-	info = registered_fb[fbidx];
+	info = get_framebuffer_info(fbidx);
 	if (!info)
 		request_module("fb%d", fbidx);
-	info = registered_fb[fbidx];
+	info = get_framebuffer_info(fbidx);
 	if (!info)
 		return -ENODEV;
 	mutex_lock(&info->lock);
+	if (info->state = FBINFO_STATE_REMOVED) {
+		res = -ENODEV;
+		goto out;
+	}
 	if (!try_module_get(info->fbops->owner)) {
 		res = -ENODEV;
 		goto out;
@@ -1386,6 +1448,8 @@ __releases(&info->lock)
 #endif
 out:
 	mutex_unlock(&info->lock);
+	if (res)
+		put_framebuffer_info(info);
 	return res;
 }
 
@@ -1401,6 +1465,7 @@ __releases(&info->lock)
 		info->fbops->fb_release(info,1);
 	module_put(info->fbops->owner);
 	mutex_unlock(&info->lock);
+	put_framebuffer_info(info);
 	return 0;
 }
 
@@ -1549,6 +1614,7 @@ register_framebuffer(struct fb_info *fb_info)
 	fb_info->node = i;
 	mutex_init(&fb_info->lock);
 	mutex_init(&fb_info->mm_lock);
+	fb_info->ref_count = 1;
 
 	fb_info->dev = device_create(fb_class, fb_info->device,
 				     MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
@@ -1592,7 +1658,6 @@ register_framebuffer(struct fb_info *fb_info)
 	return 0;
 }
 
-
 /**
  *	unregister_framebuffer - releases a frame buffer device
  *	@fb_info: frame buffer info structure
@@ -1627,6 +1692,16 @@ unregister_framebuffer(struct fb_info *fb_info)
 		return -ENODEV;
 	event.info = fb_info;
 	ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
+	if (!ret) {
+		mutex_lock(&fb_info->mm_lock);
+		/*
+		 * We must prevent any operations for this transition, we
+		 * already have info->lock so grab the info->mm_lock to hold
+		 * the remainder.
+		 */
+		fb_info->state = FBINFO_STATE_REMOVED;
+		mutex_unlock(&fb_info->mm_lock);
+	}
 	unlock_fb_info(fb_info);
 
 	if (ret) {
@@ -1646,8 +1721,7 @@ unregister_framebuffer(struct fb_info *fb_info)
 	fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
 
 	/* this may free fb info */
-	if (fb_info->fbops->fb_destroy)
-		fb_info->fbops->fb_destroy(fb_info);
+	put_framebuffer_info(fb_info);
 done:
 	return ret;
 }
diff --git a/include/linux/fb.h b/include/linux/fb.h
index df728c1..60de3fa 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -834,6 +834,7 @@ struct fb_tile_ops {
 struct fb_info {
 	int node;
 	int flags;
+	int ref_count;
 	struct mutex lock;		/* Lock for open/release/ioctl funcs */
 	struct mutex mm_lock;		/* Lock for fb_mmap and smem_* fields */
 	struct fb_var_screeninfo var;	/* Current var */
@@ -873,6 +874,7 @@ struct fb_info {
 	void *pseudo_palette;		/* Fake palette of 16 colors */ 
 #define FBINFO_STATE_RUNNING	0
 #define FBINFO_STATE_SUSPENDED	1
+#define FBINFO_STATE_REMOVED	2
 	u32 state;			/* Hardware state i.e suspend */
 	void *fbcon_par;                /* fbcon use-only private area */
 	/* From here on everything is device dependent */
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] fbcon -- fix race between open and removal of
From: Bruno Prémont @ 2011-05-05 18:30 UTC (permalink / raw)
  To: tim.gardner
  Cc: linux-fbdev, lethal, linux-kernel, Andy Whitcroft,
	Leann Ogasawara
In-Reply-To: <1304617307-7389-2-git-send-email-tim.gardner@canonical.com>

On Thu, 05 May 2011 tim.gardner@canonical.com wrote:
> From: Andy Whitcroft <apw@canonical.com>
> 
> Currently there is no locking for updates to the registered_fb list.
> This allows an open through /dev/fbN to pick up a registered framebuffer
> pointer in parallel with it being released, as happens when a conflicting
> framebuffer is ejected or on module unload.  There is also no reference
> counting on the framebuffer descriptor which is referenced from all open
> files, leading to references to released or reused memory to persist on
> these open files.
> 
> This patch adds a reference count to the framebuffer descriptor to prevent
> it from being released until after all pending opens are closed.  This
> allows the pending opens to detect the closed status and unmap themselves.
> It also adds locking to the framebuffer lookup path, locking it against
> the removal path such that it is possible to atomically lookup and take a
> reference to the descriptor.  It also adds locking to the read and write
> paths which currently could access the framebuffer descriptor after it
> has been freed.  Finally it moves the device to FBINFO_STATE_REMOVED to
> indicate that all access should be errored for this device.

Is there a good reason to not use kref for the refcounting? Except for
(un)registering framebuffers this would avoid the need for taking
registered_lock.

Unfortunately fbcon also accesses registered_fb (quite a lot!) but it
probably is save enough through use of the notifiers.

> Signed-off-by: Andy Whitcroft <apw@canonical.com>
> Acked-by: Stefan Bader <stefan.bader@canonical.com>
> Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
>  drivers/video/fbmem.c |  132 ++++++++++++++++++++++++++++++++++++++-----------
>  include/linux/fb.h    |    2 +
>  2 files changed, 105 insertions(+), 29 deletions(-)
> 

...

> diff --git a/include/linux/fb.h b/include/linux/fb.h
> index df728c1..60de3fa 100644
> --- a/include/linux/fb.h
> +++ b/include/linux/fb.h
> @@ -834,6 +834,7 @@ struct fb_tile_ops {
>  struct fb_info {
>  	int node;
>  	int flags;
> +	int ref_count;
>  	struct mutex lock;		/* Lock for open/release/ioctl funcs */
>  	struct mutex mm_lock;		/* Lock for fb_mmap and smem_* fields */
>  	struct fb_var_screeninfo var;	/* Current var */
> @@ -873,6 +874,7 @@ struct fb_info {
>  	void *pseudo_palette;		/* Fake palette of 16 colors */ 
>  #define FBINFO_STATE_RUNNING	0
>  #define FBINFO_STATE_SUSPENDED	1
> +#define FBINFO_STATE_REMOVED	2
>  	u32 state;			/* Hardware state i.e suspend */
>  	void *fbcon_par;                /* fbcon use-only private area */
>  	/* From here on everything is device dependent */

^ permalink raw reply

* Re: [PATCH] fbcon -- fix race between open and removal of framebuffers
From: Jack Stone @ 2011-05-05 21:00 UTC (permalink / raw)
  To: tim.gardner
  Cc: linux-fbdev, lethal, linux-kernel, Andy Whitcroft,
	Leann Ogasawara
In-Reply-To: <1304617307-7389-2-git-send-email-tim.gardner@canonical.com>

On 05/05/2011 18:41, tim.gardner@canonical.com wrote:
> +static struct fb_info *get_framebuffer_info(int idx)
> +__acquires(&registered_lock)
> +__releases(&registered_lock)
> +{
> +	struct fb_info *fb_info;
> +
> +	spin_lock(&registered_lock);
> +	fb_info = registered_fb[idx];
> +	fb_info->ref_count++;
> +	spin_unlock(&registered_lock);
> +
> +	return fb_info;
> +}
> +
>  static int
>  fb_open(struct inode *inode, struct file *file)
>  __acquires(&info->lock)
> @@ -1363,13 +1421,17 @@ __releases(&info->lock)
>  
>  	if (fbidx >= FB_MAX)
>  		return -ENODEV;
> -	info = registered_fb[fbidx];
> +	info = get_framebuffer_info(fbidx);
>  	if (!info)
>  		request_module("fb%d", fbidx);
> -	info = registered_fb[fbidx];
> +	info = get_framebuffer_info(fbidx);
>  	if (!info)
>  		return -ENODEV;

If the first get_framebuffer_info succeeds don't you up the ref count
twice? Shouldn't this be:

info = get_framebuffer_info(fbidx);
if (!info) {
	request_module("fb%d", fbidx);
	info = get_framebuffer_info(fbidx);
}
if (!info)
	return -ENODEV;

Thanks,

Jack

^ permalink raw reply

* Re: [PATCH] fbcon -- fix race between open and removal of framebuffers
From: Anca Emanuel @ 2011-05-06  0:21 UTC (permalink / raw)
  To: tim.gardner
  Cc: linux-fbdev, lethal, linux-kernel, Andy Whitcroft,
	Leann Ogasawara
In-Reply-To: <1304617307-7389-2-git-send-email-tim.gardner@canonical.com>

On Thu, May 5, 2011 at 8:41 PM,  <tim.gardner@canonical.com> wrote:
> From: Andy Whitcroft <apw@canonical.com>
>
> Currently there is no locking for updates to the registered_fb list.
> This allows an open through /dev/fbN to pick up a registered framebuffer
> pointer in parallel with it being released, as happens when a conflicting
> framebuffer is ejected or on module unload.  There is also no reference
> counting on the framebuffer descriptor which is referenced from all open
> files, leading to references to released or reused memory to persist on
> these open files.
>
> This patch adds a reference count to the framebuffer descriptor to prevent
> it from being released until after all pending opens are closed.  This
> allows the pending opens to detect the closed status and unmap themselves.
> It also adds locking to the framebuffer lookup path, locking it against
> the removal path such that it is possible to atomically lookup and take a
> reference to the descriptor.  It also adds locking to the read and write
> paths which currently could access the framebuffer descriptor after it
> has been freed.  Finally it moves the device to FBINFO_STATE_REMOVED to
> indicate that all access should be errored for this device.
>
> Signed-off-by: Andy Whitcroft <apw@canonical.com>
> Acked-by: Stefan Bader <stefan.bader@canonical.com>
> Signed-off-by: Leann Ogasawara <leann.ogasawara@canonical.com>
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
>  drivers/video/fbmem.c |  132 ++++++++++++++++++++++++++++++++++++++-----------
>  include/linux/fb.h    |    2 +
>  2 files changed, 105 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
> index e0c2284..c8562c1 100644
> --- a/drivers/video/fbmem.c
> +++ b/drivers/video/fbmem.c
> @@ -42,6 +42,8 @@
>
>  #define FBPIXMAPSIZE   (1024 * 8)
>
> +/* Protects the registered framebuffer list and count. */
> +static DEFINE_SPINLOCK(registered_lock);
>  struct fb_info *registered_fb[FB_MAX] __read_mostly;
>  int num_registered_fb __read_mostly;
>
> @@ -694,9 +696,7 @@ static ssize_t
>  fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
>  {
>        unsigned long p = *ppos;
> -       struct inode *inode = file->f_path.dentry->d_inode;
> -       int fbidx = iminor(inode);
> -       struct fb_info *info = registered_fb[fbidx];
> +       struct fb_info *info = file->private_data;
>        u8 *buffer, *dst;
>        u8 __iomem *src;
>        int c, cnt = 0, err = 0;
> @@ -705,19 +705,28 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
>        if (!info || ! info->screen_base)
>                return -ENODEV;
>
> -       if (info->state != FBINFO_STATE_RUNNING)
> -               return -EPERM;
> +       if (!lock_fb_info(info))
> +               return -ENODEV;
> +
> +       if (info->state != FBINFO_STATE_RUNNING) {
> +               err = -EPERM;
> +               goto out_fb_info;
> +       }
>
> -       if (info->fbops->fb_read)
> -               return info->fbops->fb_read(info, buf, count, ppos);
> +       if (info->fbops->fb_read) {
> +               err = info->fbops->fb_read(info, buf, count, ppos);
> +               goto out_fb_info;
> +       }
>
>        total_size = info->screen_size;
>
>        if (total_size = 0)
>                total_size = info->fix.smem_len;
>
> -       if (p >= total_size)
> -               return 0;
> +       if (p >= total_size) {
> +               err = 0;
> +               goto out_fb_info;
> +       }
>
>        if (count >= total_size)
>                count = total_size;
> @@ -727,8 +736,10 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
>
>        buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
>                         GFP_KERNEL);
> -       if (!buffer)
> -               return -ENOMEM;
> +       if (!buffer) {
> +               err = -ENOMEM;
> +               goto out_fb_info;
> +       }
>
>        src = (u8 __iomem *) (info->screen_base + p);
>
> @@ -751,19 +762,21 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
>                cnt += c;
>                count -= c;
>        }
> +       if (!err)
> +               err = cnt;
>
>        kfree(buffer);
> +out_fb_info:
> +       unlock_fb_info(info);
>
> -       return (err) ? err : cnt;
> +       return err;
>  }
>
>  static ssize_t
>  fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
>  {
>        unsigned long p = *ppos;
> -       struct inode *inode = file->f_path.dentry->d_inode;
> -       int fbidx = iminor(inode);
> -       struct fb_info *info = registered_fb[fbidx];
> +       struct fb_info *info = file->private_data;
>        u8 *buffer, *src;
>        u8 __iomem *dst;
>        int c, cnt = 0, err = 0;
> @@ -772,8 +785,13 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
>        if (!info || !info->screen_base)
>                return -ENODEV;
>
> -       if (info->state != FBINFO_STATE_RUNNING)
> -               return -EPERM;
> +       if (!lock_fb_info(info))
> +               return -ENODEV;
> +
> +       if (info->state != FBINFO_STATE_RUNNING) {
> +               err = -EPERM;
> +               goto out_fb_info;
> +       }
>
>        if (info->fbops->fb_write)
>                return info->fbops->fb_write(info, buf, count, ppos);
> @@ -783,8 +801,10 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
>        if (total_size = 0)
>                total_size = info->fix.smem_len;
>
> -       if (p > total_size)
> -               return -EFBIG;
> +       if (p > total_size) {
> +               err = -EFBIG;
> +               goto out_fb_info;
> +       }
>
>        if (count > total_size) {
>                err = -EFBIG;
> @@ -800,8 +820,10 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
>
>        buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
>                         GFP_KERNEL);
> -       if (!buffer)
> -               return -ENOMEM;
> +       if (!buffer) {
> +               err = -ENOMEM;
> +               goto out_fb_info;
> +       }
>
>        dst = (u8 __iomem *) (info->screen_base + p);
>
> @@ -825,10 +847,14 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
>                cnt += c;
>                count -= c;
>        }
> +       if (cnt)
> +               err = cnt;
>
>        kfree(buffer);
> +out_fb_info:
> +       unlock_fb_info(info);
>
> -       return (cnt) ? cnt : err;
> +       return err;
>  }
>
>  int
> @@ -1303,8 +1329,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd,
>  static int
>  fb_mmap(struct file *file, struct vm_area_struct * vma)
>  {
> -       int fbidx = iminor(file->f_path.dentry->d_inode);
> -       struct fb_info *info = registered_fb[fbidx];
> +       struct fb_info * const info = file->private_data;
>        struct fb_ops *fb = info->fbops;
>        unsigned long off;
>        unsigned long start;
> @@ -1316,6 +1341,11 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
>        if (!fb)
>                return -ENODEV;
>        mutex_lock(&info->mm_lock);
> +       if (info->state = FBINFO_STATE_REMOVED) {
> +               mutex_unlock(&info->mm_lock);
> +               return -ENODEV;
> +       }
> +
>        if (fb->fb_mmap) {
>                int res;
>                res = fb->fb_mmap(info, vma);
> @@ -1352,6 +1382,34 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
>        return 0;
>  }
>
> +static struct fb_info *get_framebuffer_info(int idx)
> +__acquires(&registered_lock)
> +__releases(&registered_lock)
> +{
> +       struct fb_info *fb_info;
> +
> +       spin_lock(&registered_lock);
> +       fb_info = registered_fb[idx];
> +       fb_info->ref_count++;
> +       spin_unlock(&registered_lock);
> +
> +       return fb_info;
> +}
> +
> +static void put_framebuffer_info(struct fb_info *fb_info)
> +__acquires(&registered_lock)
> +__releases(&registered_lock)
> +{
> +       int keep;
> +
> +       spin_lock(&registered_lock);
> +       keep = --fb_info->ref_count;
> +       spin_unlock(&registered_lock);
> +
> +       if (!keep && fb_info->fbops->fb_destroy)
> +               fb_info->fbops->fb_destroy(fb_info);
> +}
> +
>  static int
>  fb_open(struct inode *inode, struct file *file)
>  __acquires(&info->lock)
> @@ -1363,13 +1421,17 @@ __releases(&info->lock)
>
>        if (fbidx >= FB_MAX)
>                return -ENODEV;
> -       info = registered_fb[fbidx];
> +       info = get_framebuffer_info(fbidx);
>        if (!info)
>                request_module("fb%d", fbidx);
> -       info = registered_fb[fbidx];
> +       info = get_framebuffer_info(fbidx);
>        if (!info)
>                return -ENODEV;
>        mutex_lock(&info->lock);
> +       if (info->state = FBINFO_STATE_REMOVED) {
> +               res = -ENODEV;
> +               goto out;
> +       }
>        if (!try_module_get(info->fbops->owner)) {
>                res = -ENODEV;
>                goto out;
> @@ -1386,6 +1448,8 @@ __releases(&info->lock)
>  #endif
>  out:
>        mutex_unlock(&info->lock);
> +       if (res)
> +               put_framebuffer_info(info);
>        return res;
>  }
>
> @@ -1401,6 +1465,7 @@ __releases(&info->lock)
>                info->fbops->fb_release(info,1);
>        module_put(info->fbops->owner);
>        mutex_unlock(&info->lock);
> +       put_framebuffer_info(info);
>        return 0;
>  }
>
> @@ -1549,6 +1614,7 @@ register_framebuffer(struct fb_info *fb_info)
>        fb_info->node = i;
>        mutex_init(&fb_info->lock);
>        mutex_init(&fb_info->mm_lock);
> +       fb_info->ref_count = 1;
>
>        fb_info->dev = device_create(fb_class, fb_info->device,
>                                     MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
> @@ -1592,7 +1658,6 @@ register_framebuffer(struct fb_info *fb_info)
>        return 0;
>  }
>
> -
>  /**
>  *     unregister_framebuffer - releases a frame buffer device
>  *     @fb_info: frame buffer info structure
> @@ -1627,6 +1692,16 @@ unregister_framebuffer(struct fb_info *fb_info)
>                return -ENODEV;
>        event.info = fb_info;
>        ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
> +       if (!ret) {
> +               mutex_lock(&fb_info->mm_lock);
> +               /*
> +                * We must prevent any operations for this transition, we
> +                * already have info->lock so grab the info->mm_lock to hold
> +                * the remainder.
> +                */
> +               fb_info->state = FBINFO_STATE_REMOVED;
> +               mutex_unlock(&fb_info->mm_lock);
> +       }
>        unlock_fb_info(fb_info);
>
>        if (ret) {
> @@ -1646,8 +1721,7 @@ unregister_framebuffer(struct fb_info *fb_info)
>        fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
>
>        /* this may free fb info */
> -       if (fb_info->fbops->fb_destroy)
> -               fb_info->fbops->fb_destroy(fb_info);
> +       put_framebuffer_info(fb_info);
>  done:
>        return ret;
>  }
> diff --git a/include/linux/fb.h b/include/linux/fb.h
> index df728c1..60de3fa 100644
> --- a/include/linux/fb.h
> +++ b/include/linux/fb.h
> @@ -834,6 +834,7 @@ struct fb_tile_ops {
>  struct fb_info {
>        int node;
>        int flags;
> +       int ref_count;
>        struct mutex lock;              /* Lock for open/release/ioctl funcs */
>        struct mutex mm_lock;           /* Lock for fb_mmap and smem_* fields */
>        struct fb_var_screeninfo var;   /* Current var */
> @@ -873,6 +874,7 @@ struct fb_info {
>        void *pseudo_palette;           /* Fake palette of 16 colors */
>  #define FBINFO_STATE_RUNNING   0
>  #define FBINFO_STATE_SUSPENDED 1
> +#define FBINFO_STATE_REMOVED   2
>        u32 state;                      /* Hardware state i.e suspend */
>        void *fbcon_par;                /* fbcon use-only private area */
>        /* From here on everything is device dependent */
> --
> 1.7.0.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

Tested-by: Anca Emanuel <anca.emanuel.gmail.com>

I can not use S3 resume without this.
[   21.964367] BUG: unable to handle kernel paging request at 0000010a00000010
[   21.964396] IP: [<ffffffff8130abe0>] fb_release+0x30/0x70
[   21.964410] PGD 0
[   21.964416] Oops: 0000 [#1] SMP
[   21.964424] last sysfs file: /sys/devices/virtual/vtconsole/vtcon1/uevent
[   21.964434] CPU 1
[   21.964438] Modules linked in: parport_pc ppdev
snd_hda_codec_realtek snd_hda_intel snd_hda_codec snd_hwdep snd_pcm
adt7475 hwmon_vid snd_seq_midi snd_rawmidi snd_seq_midi_event nouveau
snd_seq snd_timer snd_seq_device ttm drm_kms_helper snd intel_agp
psmouse soundcore serio_raw intel_gtt snd_page_alloc drm i2c_algo_bit
video lp parport pata_marvell ahci libahci r8169 mii
[   21.964528]
[   21.964533] Pid: 221, comm: plymouthd Not tainted 2.6.39-rc6 #7
MICRO-STAR INTERNATIONAL CO.,LTD MS-7360/MS-7360
[   21.964548] RIP: 0010:[<ffffffff8130abe0>]  [<ffffffff8130abe0>]
fb_release+0x30/0x70
[   21.964560] RSP: 0018:ffff880037211eb8  EFLAGS: 00010286
[   21.964566] RAX: ffff880037210000 RBX: ffff88007f817000 RCX: 0000000000000001
[   21.964573] RDX: 0000010a00000000 RSI: ffff8800370f5540 RDI: ffff88007f817008
[   21.964580] RBP: ffff880037211ec8 R08: 0000000000000000 R09: 0000000000000000
[   21.964588] R10: ffff8800370f5550 R11: 0000000000000246 R12: ffff88007f817008
[   21.964595] R13: ffff88007d3db540 R14: ffff88007be34d90 R15: ffff88007be34d90
[   21.964604] FS:  00007fb335025720(0000) GS:ffff88007fc80000(0000)
knlGS:0000000000000000
[   21.964739] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   21.964746] CR2: 0000010a00000010 CR3: 000000007b41a000 CR4: 00000000000006e0
[   21.964754] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   21.964762] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[   21.964770] Process plymouthd (pid: 221, threadinfo
ffff880037210000, task ffff880036cd16c0)
[   21.964778] Stack:
[   21.964782]  ffff8800370f5540 0000000000000008 ffff880037211f18
ffffffff8115cfaa
[   21.964797]  ffff8800370f5550 ffff8800793c7b00 ffff88006744fcd0
ffff8800370f5540
[   21.964811]  ffff88007c3b9080 0000000000000000 000000000000000b
0000000000000000
[   21.964825] Call Trace:
[   21.964834]  [<ffffffff8115cfaa>] fput+0xea/0x220
[   21.964842]  [<ffffffff811591f6>] filp_close+0x66/0x90
[   21.964849]  [<ffffffff811597c7>] sys_close+0xb7/0x120
[   21.964858]  [<ffffffff815b3002>] system_call_fastpath+0x16/0x1b
[   21.964865] Code: 83 ec 10 48 89 1c 24 4c 89 64 24 08 0f 1f 44 00
00 48 8b 9e a0 00 00 00 4c 8d 63 08 4c 89 e7 e8 d7 ea 29 00 48 8b 93
b8 03 00 00
[   21.964944]  8b 42 10 48 85 c0 74 11 be 01 00 00 00 48 89 df ff d0 48 8b
[   21.964983] RIP  [<ffffffff8130abe0>] fb_release+0x30/0x70
[   21.964992]  RSP <ffff880037211eb8>
[   21.964997] CR2: 0000010a00000010

^ permalink raw reply

* Re: [PATCH] fbcon -- fix race between open and removal of framebuffers
From: Anca Emanuel @ 2011-05-06  1:09 UTC (permalink / raw)
  To: Jack Stone
  Cc: tim.gardner, linux-fbdev, lethal, linux-kernel, Andy Whitcroft,
	Leann Ogasawara, Greg KH, Greg KH
In-Reply-To: <4DC30FFA.9030708@fastmail.fm>

@Greg: This is stable material for 2.6.38
link to the patch: http://is.gd/otIfGc

^ permalink raw reply

* Re: [PATCH] fbcon -- fix race between open and removal of
From: Greg KH @ 2011-05-06  1:44 UTC (permalink / raw)
  To: Anca Emanuel
  Cc: Jack Stone, tim.gardner, linux-fbdev, lethal, linux-kernel,
	Andy Whitcroft, Leann Ogasawara, Greg KH
In-Reply-To: <BANLkTikG=6xyFg--u=M6HwH8yQExAauA8w@mail.gmail.com>

On Fri, May 06, 2011 at 04:09:44AM +0300, Anca Emanuel wrote:
> @Greg: This is stable material for 2.6.38
> link to the patch: http://is.gd/otIfGc

<form_letter>

This is not the correct way to submit patches for inclusion in the
stable kernel tree.  Please read Documentation/stable_kernel_rules.txt
for how to do this properly.

thanks,

greg k-h

</form_letter>

^ permalink raw reply

* Re: [2.6.39-rc2, framebuffer] use after free oops
From: Daniel J Blueman @ 2011-05-06  2:38 UTC (permalink / raw)
  To: Alan Cox, Bruno Prémont, Paul Mundt, linux-fbdev,
	Linux Kernel
In-Reply-To: <20110420105631.70695dfa@lxorguk.ukuu.org.uk>

On 20 April 2011 17:56, Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
> On Wed, 20 Apr 2011 08:05:35 +0200
> Bruno Prémont <bonbons@linux-vserver.org> wrote:
>
>> On Wed, 20 Apr 2011 13:50:10 Daniel J Blueman <daniel.blueman@gmail.com> wrote:
>> > Any ideas on how best to address this issue [0], since it causes
>> > silent corruption, or at best crashes?
>>
>> There is probably no easy short-term fix to this...
>
> The short term fix would be to deliberately leak the buffer. That should
> go into 2.6.39-rc right now with a comment explaining the situation.
> Otherwise who knows what corruption may occur to user data if unlucky.
>
> The other 'cheat' might be to tweak the API so the removal API isn't a
> 'destroy' interface but a 'shut down' and has a matching 'restart' one
> for when the intelfb unloads at which point vga16fb can carry on with the
> original fb_info 8)

It looks like Andy Whitcroft addressed this issue some time ago, but
forgot to send the fix upstream:

http://kernel.ubuntu.com/git?p=ubuntu/ubuntu-natty.git;a=patch;hÅa742b5f78e161d6a13853a7e3e6e1dfa429e69;hp&a1443f67eea17d4b78ef75df701782cc8bf35b

Let's hope it can hit -rc7 since it's been in Ubuntu's kernel tree for
considerable time, and fixes a silent corrupter:

http://groups.google.com/group/linux.kernel/browse_thread/thread/fc9083f6f380ed5b/f801112b840785cb?show_docidø01112b840785cb

Thanks,
  Daniel
-- 
Daniel J Blueman

^ permalink raw reply

* Re: [2.6.39-rc2, framebuffer] use after free oops
From: Anca Emanuel @ 2011-05-07 15:24 UTC (permalink / raw)
  To: Daniel J Blueman
  Cc: Alan Cox, Bruno Prémont, Paul Mundt, linux-fbdev,
	Linux Kernel, Dave Airlie
In-Reply-To: <BANLkTikF5YL8tJ_f5510yy1Ywm69rOUK2A@mail.gmail.com>

Hi, Daniel J Blueman.

Did you test https://lkml.org/lkml/2011/5/5/208 ? And it works for you ?
Then please reply with your error and an Tested-by.

And CC: "Dave Airlie" <airlied@redhat.com>

^ permalink raw reply

* Re: [2.6.39-rc2, framebuffer] use after free oops
From: Daniel J Blueman @ 2011-05-08 11:25 UTC (permalink / raw)
  To: linux-fbdev, Linux Kernel, Dave Airlie, Paul Mundt
  Cc: Alan Cox, Bruno Prémont, Anca Emanuel
In-Reply-To: <BANLkTi=x76zkTpZxaHUnSUeP+_O0SsK0Zw@mail.gmail.com>

On 7 May 2011 23:24, Anca Emanuel <anca.emanuel@gmail.com> wrote:
> Hi, Daniel J Blueman.
>
> Did you test https://lkml.org/lkml/2011/5/5/208 ? And it works for you ?
> Then please reply with your error and an Tested-by.
>
> And CC: "Dave Airlie" <airlied@redhat.com>

Tested against 2.6.39-rc6. Instrumentation and debug catches the
(silent without debug) use-after-free case, which now doesn't show up
with this patch, so looks good. Probably good sense to get into
-stable too.

Tested-by: Daniel J Blueman <daniel.blueman@gmail.com>

Thanks,
  Daniel
-- 
Daniel J Blueman

^ permalink raw reply

* Re: [RFC][PATCH 0/3] MERAM support for LCDC
From: Damian Hobson-Garcia @ 2011-05-09  7:03 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1301369758-18394-1-git-send-email-dhobsong@igel.co.jp>

Hi Magnus,

> Please add Runtime PM support to the MERAM driver. The MSTP113 bit of
> SMSTPCR1 should be dynamically controlled using pm_runtime_get_sync()
> and pm_runtime_put_sync().

So one thing that I noticed while adding in the runtime PM support is
that the MERAM bit in RMSTPCR1 seems to be enabled as a power on default
on the chip. (I determined this by dumping the register from u-boot and
poking around in the u-boot code to verify that u-boot doesn't seem to
be enabling this).

Even if pm_runtime_get_sync() and pm_runtime_put_sync() correctly enable
and disable the SMSTPCR1, with the RMSTPCR1 enabled, the clock doesn't
actually turn off.

While I still think that its a good idea to add the
pm_runtime_get_sync() and pm_runtime_put_sync() calls to do their thing
on the SMSTPCR1 side, with the current configuration we won't actually
be saving any power.

Damian

^ permalink raw reply

* [PATCH] OMAP2: avoid descending into disabled framebuffer dirs
From: Mike Frysinger @ 2011-05-09 14:40 UTC (permalink / raw)
  To: linux-fbdev, Paul Mundt, linux-omap, Tomi Valkeinen

Rather than always add the omap2 dirs to the build list (and thus
force everyone to generate a useless built-in.o), bind the dirs to
their relevant kconfig symbol.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 drivers/video/omap2/Makefile |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
index d853d05..5ddef12 100644
--- a/drivers/video/omap2/Makefile
+++ b/drivers/video/omap2/Makefile
@@ -1,6 +1,6 @@
 obj-$(CONFIG_OMAP2_VRAM) += vram.o
 obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
 
-obj-y += dss/
-obj-y += omapfb/
+obj-$(CONFIG_OMAP2_DSS) += dss/
+obj-$(CONFIG_FB_OMAP2) += omapfb/
 obj-y += displays/
-- 
1.7.5.rc3


^ permalink raw reply related

* Re: [PATCH] OMAP2: avoid descending into disabled framebuffer dirs
From: Tomi Valkeinen @ 2011-05-09 16:06 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: linux-fbdev, Paul Mundt, linux-omap
In-Reply-To: <1304952024-28296-1-git-send-email-vapier@gentoo.org>

On Mon, 2011-05-09 at 10:40 -0400, Mike Frysinger wrote:
> Rather than always add the omap2 dirs to the build list (and thus
> force everyone to generate a useless built-in.o), bind the dirs to
> their relevant kconfig symbol.
> 
> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
> ---
>  drivers/video/omap2/Makefile |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
> index d853d05..5ddef12 100644
> --- a/drivers/video/omap2/Makefile
> +++ b/drivers/video/omap2/Makefile
> @@ -1,6 +1,6 @@
>  obj-$(CONFIG_OMAP2_VRAM) += vram.o
>  obj-$(CONFIG_OMAP2_VRFB) += vrfb.o
>  
> -obj-y += dss/
> -obj-y += omapfb/
> +obj-$(CONFIG_OMAP2_DSS) += dss/
> +obj-$(CONFIG_FB_OMAP2) += omapfb/
>  obj-y += displays/

Looks fine to me, applying to DSS tree. Thanks!

 Tomi



^ permalink raw reply

* Re: [RFC][PATCH 0/3] MERAM support for LCDC
From: Magnus Damm @ 2011-05-09 16:22 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1301369758-18394-1-git-send-email-dhobsong@igel.co.jp>

Hi Damian,

On Mon, May 9, 2011 at 4:03 PM, Damian Hobson-Garcia
<dhobsong@igel.co.jp> wrote:
> Hi Magnus,
>
>> Please add Runtime PM support to the MERAM driver. The MSTP113 bit of
>> SMSTPCR1 should be dynamically controlled using pm_runtime_get_sync()
>> and pm_runtime_put_sync().
>
> So one thing that I noticed while adding in the runtime PM support is
> that the MERAM bit in RMSTPCR1 seems to be enabled as a power on default
> on the chip. (I determined this by dumping the register from u-boot and
> poking around in the u-boot code to verify that u-boot doesn't seem to
> be enabling this).
>
> Even if pm_runtime_get_sync() and pm_runtime_put_sync() correctly enable
> and disable the SMSTPCR1, with the RMSTPCR1 enabled, the clock doesn't
> actually turn off.
>
> While I still think that its a good idea to add the
> pm_runtime_get_sync() and pm_runtime_put_sync() calls to do their thing
> on the SMSTPCR1 side, with the current configuration we won't actually
> be saving any power.

Good catch, yes, the MSTP bits need to be disabled on both sides for
the clocks to be stopped. I recall the default state of each MSTP bit
to vary somehow. I think we simply should add code to initialize all
SH-side MSTP bits as disabled, that's the easiest.

Thanks,

/ magnus

^ permalink raw reply


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