Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* [PATCH v2 0/5] ARM: dts: AM33XX: lcdc support
From: Afzal Mohammed @ 2013-01-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This series add DT sources for AM335x SoC as well as AM335x based
boards.

As compared to previous version, in this version, comment has been
added in dt source file about pinmux details so that user can easily
correlate to that mentioned in TRM. Also author of one of the patch
was actually "Manjunathappa, Prakash", here in this series, authorship
has been made proper.

As pinmux is an SoC specific detail rather than IP specific one,
addition of pin control has been done in a separate patch from
the one in which display timings are added. Also it may aid in
debugging in case of any issues.

This has been tested on AM335x based boards like AM335x EVM and
AM335x EVM-SK.

This series is based on v3.8-rc3.

This series has a dependency on,
1. Series v16 "of: add display helper" by,
	Steffen Trumtrar <s.trumtrar@pengutronix.de>
2. Series v3 "video: da8xx-fb: runtime timing configuration" by,
	me (Afzal Mohammed <afzal@ti.com>)
3. Series v2 "video: da8xx-fb: DT support" by,
	me (Afzal Mohammed <afzal@ti.com>)

To test on AM335x, in addition to the above, following changes,
1. Patch "ARM: AM33XX: clock: SET_RATE_PARENT in lcd path" by,
	me (Afzal Mohammed <afzal@ti.com>)
2. Patch "da8xx: Allow use by am33xx based devices" by,
	Pantelis Antoniou <panto@antoniou-consulting.com>
3. Series "HWMOD fixes for AM33xx PWM submodules and device tree nodes" by,
	Philip, Avinash <avinashphilip@ti.com>
would be required

All above dependencies along with those required for testing is available
 @git://gitorious.org/x0148406-public/linux-kernel.git tags/da8xx-fb-dt-v3.8-rc3

Regards
Afzal

v2: add pinmux comment in dtsi files, correct authorship of one of the
    patch.

Afzal Mohammed (4):
  ARM: dts: AM33XX: Add lcdc node
  ARM: dts: AM33XX: Add am335x-evm lcdc panel timings
  ARM: dts: AM33XX: Add am335x-evmsk lcdc panel timings
  ARM: dts: AM33XX: Add am335x-evmsk lcdc pincontrol info

Manjunathappa, Prakash (1):
  ARM: dts: AM33XX: Add am335x-evm lcdc pincontrol info

 arch/arm/boot/dts/am335x-evm.dts   |   55 +++++++++++++++++++++++++++++++++++-
 arch/arm/boot/dts/am335x-evmsk.dts |   55 +++++++++++++++++++++++++++++++++++-
 arch/arm/boot/dts/am33xx.dtsi      |    8 ++++++
 3 files changed, 116 insertions(+), 2 deletions(-)

-- 
1.7.9.5


^ permalink raw reply

* [PATCH v2 4/5] ARM: dts: AM33XX: Add am335x-evmsk lcdc panel timings
From: Afzal Mohammed @ 2013-01-15 13:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1358252955.git.afzal@ti.com>

Update lcdc node with panel timings (typical) for AM335X-EVMSK.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/boot/dts/am335x-evmsk.dts |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts
index f5a6162..a7e017b 100644
--- a/arch/arm/boot/dts/am335x-evmsk.dts
+++ b/arch/arm/boot/dts/am335x-evmsk.dts
@@ -248,3 +248,23 @@
 		};
 	};
 };
+
+&lcdc {
+	status = "okay";
+
+	display-timings {
+		480x272p57 {
+			clock-frequency = <9000000>;
+			hactive = <480>;
+			vactive = <272>;
+			hfront-porch = <8>;
+			hback-porch = <43>;
+			hsync-len = <4>;
+			vback-porch = <12>;
+			vfront-porch = <4>;
+			vsync-len = <10>;
+			hsync-active = <1>;
+			vsync-active = <1>;
+		};
+	};
+};
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 5/5] ARM: dts: AM33XX: Add am335x-evmsk lcdc pincontrol info
From: Afzal Mohammed @ 2013-01-15 13:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1358252955.git.afzal@ti.com>

Update pin mux information for lcd panel on AM335X-EVMSK.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---

v2: add comment on pinmux entries

 arch/arm/boot/dts/am335x-evmsk.dts |   35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts
index a7e017b..24dde1d 100644
--- a/arch/arm/boot/dts/am335x-evmsk.dts
+++ b/arch/arm/boot/dts/am335x-evmsk.dts
@@ -32,7 +32,7 @@
 
 	am33xx_pinmux: pinmux@44e10800 {
 		pinctrl-names = "default";
-		pinctrl-0 = <&user_leds_s0 &gpio_keys_s0>;
+		pinctrl-0 = <&user_leds_s0 &gpio_keys_s0 &lcd_pins_s0>;
 
 		user_leds_s0: user_leds_s0 {
 			pinctrl-single,pins = <
@@ -51,6 +51,39 @@
 				0x9c 0x27	/* gpmc_ben0_cle.gpio2_5, INPUT | MODE7 */
 			>;
 		};
+
+		lcd_pins_s0: lcd_pins_s0 {
+			pinctrl-single,pins = <
+				0x20 0x01	/* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */
+				0x24 0x01	/* gpmc_ad9.lcd_data17, OUTPUT | MODE1 */
+				0x28 0x01	/* gpmc_ad10.lcd_data18, OUTPUT | MODE1 */
+				0x2c 0x01	/* gpmc_ad11.lcd_data19, OUTPUT | MODE1 */
+				0x30 0x01	/* gpmc_ad12.lcd_data20, OUTPUT | MODE1 */
+				0x34 0x01	/* gpmc_ad13.lcd_data21, OUTPUT | MODE1 */
+				0x38 0x01	/* gpmc_ad14.lcd_data22, OUTPUT | MODE1 */
+				0x3c 0x01	/* gpmc_ad15.lcd_data23, OUTPUT | MODE1 */
+				0xa0 0x00	/* lcd_data0.lcd_data0, OUTPUT | MODE0 */
+				0xa4 0x00	/* lcd_data1.lcd_data1, OUTPUT | MODE0 */
+				0xa8 0x00	/* lcd_data2.lcd_data2, OUTPUT | MODE0 */
+				0xac 0x00	/* lcd_data3.lcd_data3, OUTPUT | MODE0 */
+				0xb0 0x00	/* lcd_data4.lcd_data4, OUTPUT | MODE0 */
+				0xb4 0x00	/* lcd_data5.lcd_data5, OUTPUT | MODE0 */
+				0xb8 0x00	/* lcd_data6.lcd_data6, OUTPUT | MODE0 */
+				0xbc 0x00	/* lcd_data7.lcd_data7, OUTPUT | MODE0 */
+				0xc0 0x00	/* lcd_data8.lcd_data8, OUTPUT | MODE0 */
+				0xc4 0x00	/* lcd_data9.lcd_data9, OUTPUT | MODE0 */
+				0xc8 0x00	/* lcd_data10.lcd_data10, OUTPUT | MODE0 */
+				0xcc 0x00	/* lcd_data11.lcd_data11, OUTPUT | MODE0 */
+				0xd0 0x00	/* lcd_data12.lcd_data12, OUTPUT | MODE0 */
+				0xd4 0x00	/* lcd_data13.lcd_data13, OUTPUT | MODE0 */
+				0xd8 0x00	/* lcd_data14.lcd_data14, OUTPUT | MODE0 */
+				0xdc 0x00	/* lcd_data15.lcd_data15, OUTPUT | MODE0 */
+				0xe0 0x00	/* lcd_vsync.lcd_vsync, OUTPUT | MODE0 */
+				0xe4 0x00	/* lcd_hsync.lcd_hsync, OUTPUT | MODE0 */
+				0xe8 0x00	/* lcd_pclk.lcd_pclk, OUTPUT | MODE0 */
+				0xec 0x00	/* lcd_ac_bias_en.lcd_ac_bias_en, OUTPUT | MODE0 */
+			>;
+		};
 	};
 
 	ocp {
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 3/5] ARM: dts: AM33XX: Add am335x-evm lcdc pincontrol info
From: Afzal Mohammed @ 2013-01-15 13:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1358252955.git.afzal@ti.com>

From: "Manjunathappa, Prakash" <prakash.pm@ti.com>

Update pin mux information for lcd panel on AM335X-EVM

[afzal@ti.com: comment specifying user understandable pinmux details]

Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---

v2: correct authorship, add comment on pinmux

 arch/arm/boot/dts/am335x-evm.dts |   35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index a4229aa..0527885 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -26,7 +26,7 @@
 
 	am33xx_pinmux: pinmux@44e10800 {
 		pinctrl-names = "default";
-		pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0>;
+		pinctrl-0 = <&matrix_keypad_s0 &volume_keys_s0 &lcd_pins_s0>;
 
 		matrix_keypad_s0: matrix_keypad_s0 {
 			pinctrl-single,pins = <
@@ -44,6 +44,39 @@
 				0x154 0x27	/* spi0_d0.gpio0_3, INPUT | MODE7 */
 			>;
 		};
+
+		lcd_pins_s0: lcd_pins_s0 {
+			pinctrl-single,pins = <
+				0x20 0x01	/* gpmc_ad8.lcd_data16, OUTPUT | MODE1 */
+				0x24 0x01	/* gpmc_ad9.lcd_data17, OUTPUT | MODE1 */
+				0x28 0x01	/* gpmc_ad10.lcd_data18, OUTPUT | MODE1 */
+				0x2c 0x01	/* gpmc_ad11.lcd_data19, OUTPUT | MODE1 */
+				0x30 0x01	/* gpmc_ad12.lcd_data20, OUTPUT | MODE1 */
+				0x34 0x01	/* gpmc_ad13.lcd_data21, OUTPUT | MODE1 */
+				0x38 0x01	/* gpmc_ad14.lcd_data22, OUTPUT | MODE1 */
+				0x3c 0x01	/* gpmc_ad15.lcd_data23, OUTPUT | MODE1 */
+				0xa0 0x00	/* lcd_data0.lcd_data0, OUTPUT | MODE0 */
+				0xa4 0x00	/* lcd_data1.lcd_data1, OUTPUT | MODE0 */
+				0xa8 0x00	/* lcd_data2.lcd_data2, OUTPUT | MODE0 */
+				0xac 0x00	/* lcd_data3.lcd_data3, OUTPUT | MODE0 */
+				0xb0 0x00	/* lcd_data4.lcd_data4, OUTPUT | MODE0 */
+				0xb4 0x00	/* lcd_data5.lcd_data5, OUTPUT | MODE0 */
+				0xb8 0x00	/* lcd_data6.lcd_data6, OUTPUT | MODE0 */
+				0xbc 0x00	/* lcd_data7.lcd_data7, OUTPUT | MODE0 */
+				0xc0 0x00	/* lcd_data8.lcd_data8, OUTPUT | MODE0 */
+				0xc4 0x00	/* lcd_data9.lcd_data9, OUTPUT | MODE0 */
+				0xc8 0x00	/* lcd_data10.lcd_data10, OUTPUT | MODE0 */
+				0xcc 0x00	/* lcd_data11.lcd_data11, OUTPUT | MODE0 */
+				0xd0 0x00	/* lcd_data12.lcd_data12, OUTPUT | MODE0 */
+				0xd4 0x00	/* lcd_data13.lcd_data13, OUTPUT | MODE0 */
+				0xd8 0x00	/* lcd_data14.lcd_data14, OUTPUT | MODE0 */
+				0xdc 0x00	/* lcd_data15.lcd_data15, OUTPUT | MODE0 */
+				0xe0 0x00	/* lcd_vsync.lcd_vsync, OUTPUT | MODE0 */
+				0xe4 0x00	/* lcd_hsync.lcd_hsync, OUTPUT | MODE0 */
+				0xe8 0x00	/* lcd_pclk.lcd_pclk, OUTPUT | MODE0 */
+				0xec 0x00	/* lcd_ac_bias_en.lcd_ac_bias_en, OUTPUT | MODE0 */
+			>;
+		};
 	};
 
 	ocp {
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 1/5] ARM: dts: AM33XX: Add lcdc node
From: Afzal Mohammed @ 2013-01-15 13:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1358252955.git.afzal@ti.com>

Add lcdc node.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/boot/dts/am33xx.dtsi |    8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index c2f14e8..432d4bb8 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -385,5 +385,13 @@
 				mac-address = [ 00 00 00 00 00 00 ];
 			};
 		};
+
+		lcdc: lcdc@4830e000 {
+			compatible = "ti,am3352-lcdc", "ti,da830-lcdc";
+			reg = <0x4830e000 0x1000>;
+			interrupts = <36>;
+			status = "disabled";
+			ti,hwmods = "lcdc";
+		};
 	};
 };
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 2/5] ARM: dts: AM33XX: Add am335x-evm lcdc panel timings
From: Afzal Mohammed @ 2013-01-15 13:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1358252955.git.afzal@ti.com>

Update lcdc node with panel timings (typical) for AM335X-EVM.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/boot/dts/am335x-evm.dts |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index d649644..a4229aa 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -244,3 +244,23 @@
 &cpsw_emac1 {
 	phy_id = <&davinci_mdio>, <1>;
 };
+
+&lcdc {
+	status = "okay";
+
+	display-timings {
+		800x480p62 {
+			clock-frequency = <30000000>;
+			hactive = <800>;
+			vactive = <480>;
+			hfront-porch = <39>;
+			hback-porch = <39>;
+			hsync-len = <47>;
+			vback-porch = <29>;
+			vfront-porch = <13>;
+			vsync-len = <2>;
+			hsync-active = <1>;
+			vsync-active = <1>;
+		};
+	};
+};
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 00/12] video: da8xx-fb: DT support
From: Afzal Mohammed @ 2013-01-15 13:53 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
	devicetree-discuss, linux-doc, linux-kernel

Hi,

This series adds DT support to da8xx-fb driver (device found on
DaVinci and AM335x SoC's). It does certain cleanup's in the process.

This series as compared to previous version handles configuration of
the LCDC input clock to required value if clock divider in IP cannot
take care of required pixel clock. In the case of AM335x (where there
is requirement of configuring input clock), it's clock tree has to be
updated with proper flags, relevant patch is,

"ARM: AM33XX: clock: SET_RATE_PARENT in lcd path".

There is an additional patch in this new series to make io operations
safe.

This makes use of Steffen Trumtrar's v16 of display timing DT support.

Testing has been done on AM335x SoC based boards like AM335x EVM and
AM335x EVM-SK. It has also been verified that display on DA850 EVM
(non-DT boot) works as earlier.

This series is based on v3.8-rc3,
 and is dependent on,
1. Series v16 "of: add display helper" by,
	Steffen Trumtrar <s.trumtrar@pengutronix.de>
2. Patch "da8xx: Allow use by am33xx based devices" by,
	Pantelis Antoniou <panto@antoniou-consulting.com>
3. Series v3 "video: da8xx-fb: runtime timing configuration" by,
	me (Afzal Mohammed <afzal@ti.com>)

To test this series on AM335x based boards,
1. Series v2 "ARM: dts: AM33XX: lcdc support" by,
	me (Afzal Mohammed <afzal@ti.com>),
2. Patch "ARM: AM33XX: clock: SET_RATE_PARENT in lcd path" by,
	me (Afzal Mohammed <afzal@ti.com>),
3. Series "HWMOD fixes for AM33xx PWM submodules and device tree nodes" by,
	Philip, Avinash <avinashphilip@ti.com>
would be needed.

All above dependencies along with those required for testing is available
 @git://gitorious.org/x0148406-public/linux-kernel.git tags/da8xx-fb-dt-v3.8-rc3

Regards
Afzal

v2: 2 new patches - one to configure clock rate properly (12/12)and
    other to make io operations safe (1/12)

Afzal Mohammed (11):
  video: da8xx-fb: make io operations safe
  video: da8xx-fb: enable sync lost intr for v2 ip
  video: da8xx-fb: use devres
  video: da8xx-fb: ensure non-null cfg in pdata
  video: da8xx-fb: reorganize panel detection
  video: da8xx-fb: minimal dt support
  video: da8xx-fb: invoke platform callback safely
  video: da8xx-fb: obtain fb_videomode info from dt
  video: da8xx-fb: ensure pdata only for non-dt
  video: da8xx-fb: setup struct lcd_ctrl_config for dt
  video: da8xx-fb: set upstream clock rate (if reqd)

Manjunathappa, Prakash (1):
  video: da8xx-fb: fix 24bpp raster configuration

 .../devicetree/bindings/video/fb-da8xx.txt         |   37 ++++
 drivers/video/da8xx-fb.c                           |  226 ++++++++++++++------
 2 files changed, 194 insertions(+), 69 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/video/fb-da8xx.txt

-- 
1.7.9.5


^ permalink raw reply

* [PATCH v2 01/12] video: da8xx-fb: make io operations safe
From: Afzal Mohammed @ 2013-01-15 13:53 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <cover.1358251447.git.afzal-l0cyMroinI0@public.gmane.org>

Replace __raw_readl/__raw_writel with readl/writel; this driver is
reused on ARMv7 (AM335x SoC).

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---

v2: new patch

 drivers/video/da8xx-fb.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 720604c..35a33ca 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -141,12 +141,12 @@ static int frame_done_flag;
 
 static inline unsigned int lcdc_read(unsigned int addr)
 {
-	return (unsigned int)__raw_readl(da8xx_fb_reg_base + (addr));
+	return (unsigned int)readl(da8xx_fb_reg_base + (addr));
 }
 
 static inline void lcdc_write(unsigned int val, unsigned int addr)
 {
-	__raw_writel(val, da8xx_fb_reg_base + (addr));
+	writel(val, da8xx_fb_reg_base + (addr));
 }
 
 struct da8xx_fb_par {
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 02/12] video: da8xx-fb: fix 24bpp raster configuration
From: Afzal Mohammed @ 2013-01-15 13:53 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
  Cc: Manjunathappa, Prakash
In-Reply-To: <cover.1358251447.git.afzal-l0cyMroinI0@public.gmane.org>

From: "Manjunathappa, Prakash" <prakash.pm@ti.com>

Set only LCD_V2_TFT_24BPP_MODE bit for 24bpp and LCD_V2_TFT_24BPP_UNPACK
bit along with LCD_V2_TFT_24BPP_MODE for 32bpp configuration.

Patch is tested on am335x-evm for 24bpp and da850-evm for 16bpp
configurations.

Signed-off-by: Manjunathappa, Prakash <prakash.pm@ti.com>
Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 drivers/video/da8xx-fb.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 35a33ca..7f92f37 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -550,10 +550,10 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height,
 	case 4:
 	case 16:
 		break;
-	case 24:
-		reg |= LCD_V2_TFT_24BPP_MODE;
 	case 32:
 		reg |= LCD_V2_TFT_24BPP_UNPACK;
+	case 24:
+		reg |= LCD_V2_TFT_24BPP_MODE;
 		break;
 
 	case 8:
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 03/12] video: da8xx-fb: enable sync lost intr for v2 ip
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
	devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>

interrupt handler is checking for sync lost interrupt, but it was not
enabled, enable it.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 drivers/video/da8xx-fb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 7f92f37..ca69e01 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -318,7 +318,7 @@ static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
 			reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
 				LCD_V2_END_OF_FRAME0_INT_ENA |
 				LCD_V2_END_OF_FRAME1_INT_ENA |
-				LCD_FRAME_DONE;
+				LCD_FRAME_DONE | LCD_SYNC_LOST;
 			lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
 		}
 		reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 04/12] video: da8xx-fb: use devres
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <cover.1358251447.git.afzal-l0cyMroinI0@public.gmane.org>

Replace existing resource handling in the driver with managed device
resource.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 drivers/video/da8xx-fb.c |   35 ++++++-----------------------------
 1 file changed, 6 insertions(+), 29 deletions(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index ca69e01..7a32e83 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1036,12 +1036,9 @@ static int fb_remove(struct platform_device *dev)
 				  par->p_palette_base);
 		dma_free_coherent(NULL, par->vram_size, par->vram_virt,
 				  par->vram_phys);
-		free_irq(par->irq, par);
 		pm_runtime_put_sync(&dev->dev);
 		pm_runtime_disable(&dev->dev);
 		framebuffer_release(info);
-		iounmap(da8xx_fb_reg_base);
-		release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
 
 	}
 	return 0;
@@ -1265,7 +1262,6 @@ static int fb_probe(struct platform_device *device)
 	struct fb_info *da8xx_fb_info;
 	struct clk *fb_clk = NULL;
 	struct da8xx_fb_par *par;
-	resource_size_t len;
 	int ret, i;
 	unsigned long ulcm;
 
@@ -1275,29 +1271,16 @@ static int fb_probe(struct platform_device *device)
 	}
 
 	lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
-	if (!lcdc_regs) {
-		dev_err(&device->dev,
-			"Can not get memory resource for LCD controller\n");
-		return -ENOENT;
-	}
-
-	len = resource_size(lcdc_regs);
-
-	lcdc_regs = request_mem_region(lcdc_regs->start, len, lcdc_regs->name);
-	if (!lcdc_regs)
-		return -EBUSY;
-
-	da8xx_fb_reg_base = ioremap(lcdc_regs->start, len);
+	da8xx_fb_reg_base = devm_request_and_ioremap(&device->dev, lcdc_regs);
 	if (!da8xx_fb_reg_base) {
-		ret = -EBUSY;
-		goto err_request_mem;
+		dev_err(&device->dev, "memory resource setup failed\n");
+		return -EADDRNOTAVAIL;
 	}
 
-	fb_clk = clk_get(&device->dev, "fck");
+	fb_clk = devm_clk_get(&device->dev, "fck");
 	if (IS_ERR(fb_clk)) {
 		dev_err(&device->dev, "Can not get device clock\n");
-		ret = -ENODEV;
-		goto err_ioremap;
+		return -ENODEV;
 	}
 
 	pm_runtime_enable(&device->dev);
@@ -1458,7 +1441,7 @@ static int fb_probe(struct platform_device *device)
 		lcdc_irq_handler = lcdc_irq_handler_rev02;
 	}
 
-	ret = request_irq(par->irq, lcdc_irq_handler, 0,
+	ret = devm_request_irq(&device->dev, par->irq, lcdc_irq_handler, 0,
 			DRIVER_NAME, par);
 	if (ret)
 		goto irq_freq;
@@ -1488,12 +1471,6 @@ err_pm_runtime_disable:
 	pm_runtime_put_sync(&device->dev);
 	pm_runtime_disable(&device->dev);
 
-err_ioremap:
-	iounmap(da8xx_fb_reg_base);
-
-err_request_mem:
-	release_mem_region(lcdc_regs->start, len);
-
 	return ret;
 }
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 05/12] video: da8xx-fb: ensure non-null cfg in pdata
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
	devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>

Ensure that platform data contains pointer for lcd_ctrl_config.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 drivers/video/da8xx-fb.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 7a32e83..3b146bc 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1320,6 +1320,11 @@ static int fb_probe(struct platform_device *device)
 
 	lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
 
+	if (!lcd_cfg) {
+		ret = -EINVAL;
+		goto err_pm_runtime_disable;
+	}
+
 	da8xx_fb_info = framebuffer_alloc(sizeof(struct da8xx_fb_par),
 					&device->dev);
 	if (!da8xx_fb_info) {
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 06/12] video: da8xx-fb: reorganize panel detection
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-fbdev-u79uwXL29TY76Z2rM5mHXA,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <cover.1358251447.git.afzal-l0cyMroinI0@public.gmane.org>

Move panel detection to a separate function, this helps in readability
as well as makes DT support cleaner.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 drivers/video/da8xx-fb.c |   42 ++++++++++++++++++++++++++----------------
 1 file changed, 26 insertions(+), 16 deletions(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 3b146bc..b6ea5e9 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1253,6 +1253,27 @@ static struct fb_ops da8xx_fb_ops = {
 	.fb_blank = cfb_blank,
 };
 
+static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
+{
+	struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data;
+	struct fb_videomode *lcdc_info;
+	int i;
+
+	for (i = 0, lcdc_info = known_lcd_panels;
+		i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) {
+		if (strcmp(fb_pdata->type, lcdc_info->name) = 0)
+			break;
+	}
+
+	if (i = ARRAY_SIZE(known_lcd_panels)) {
+		dev_err(&dev->dev, "no panel found\n");
+		return NULL;
+	}
+	dev_info(&dev->dev, "found %s panel\n", lcdc_info->name);
+
+	return lcdc_info;
+}
+
 static int fb_probe(struct platform_device *device)
 {
 	struct da8xx_lcdc_platform_data *fb_pdata @@ -1262,7 +1283,7 @@ static int fb_probe(struct platform_device *device)
 	struct fb_info *da8xx_fb_info;
 	struct clk *fb_clk = NULL;
 	struct da8xx_fb_par *par;
-	int ret, i;
+	int ret;
 	unsigned long ulcm;
 
 	if (fb_pdata = NULL) {
@@ -1270,6 +1291,10 @@ static int fb_probe(struct platform_device *device)
 		return -ENOENT;
 	}
 
+	lcdc_info = da8xx_fb_get_videomode(device);
+	if (lcdc_info = NULL)
+		return -ENODEV;
+
 	lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
 	da8xx_fb_reg_base = devm_request_and_ioremap(&device->dev, lcdc_regs);
 	if (!da8xx_fb_reg_base) {
@@ -1303,21 +1328,6 @@ static int fb_probe(struct platform_device *device)
 		break;
 	}
 
-	for (i = 0, lcdc_info = known_lcd_panels;
-		i < ARRAY_SIZE(known_lcd_panels);
-		i++, lcdc_info++) {
-		if (strcmp(fb_pdata->type, lcdc_info->name) = 0)
-			break;
-	}
-
-	if (i = ARRAY_SIZE(known_lcd_panels)) {
-		dev_err(&device->dev, "GLCD: No valid panel found\n");
-		ret = -ENODEV;
-		goto err_pm_runtime_disable;
-	} else
-		dev_info(&device->dev, "GLCD: Found %s panel\n",
-					fb_pdata->type);
-
 	lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
 
 	if (!lcd_cfg) {
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 07/12] video: da8xx-fb: minimal dt support
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
	devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>

Driver is provided a means to have the probe triggered by DT.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 .../devicetree/bindings/video/fb-da8xx.txt         |   16 ++++++++++++++++
 drivers/video/da8xx-fb.c                           |    7 +++++++
 2 files changed, 23 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/fb-da8xx.txt

diff --git a/Documentation/devicetree/bindings/video/fb-da8xx.txt b/Documentation/devicetree/bindings/video/fb-da8xx.txt
new file mode 100644
index 0000000..581e014
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/fb-da8xx.txt
@@ -0,0 +1,16 @@
+TI LCD Controller on DA830/DA850/AM335x SoC's
+
+Required properties:
+- compatible:
+	DA830 - "ti,da830-lcdc"
+	AM335x SoC's - "ti,am3352-lcdc", "ti,da830-lcdc"
+- reg: Address range of lcdc register set
+- interrupts: lcdc interrupt
+
+Example:
+
+lcdc@4830e000 {
+	compatible = "ti,am3352-lcdc", "ti,da830-lcdc";
+	reg =  <0x4830e000 0x1000>;
+	interrupts = <36>;
+};
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index b6ea5e9..08ee8eb 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1595,6 +1595,12 @@ static int fb_resume(struct platform_device *dev)
 #define fb_resume NULL
 #endif
 
+static const struct of_device_id da8xx_fb_of_match[] = {
+	{.compatible = "ti,da830-lcdc", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, da8xx_fb_of_match);
+
 static struct platform_driver da8xx_fb_driver = {
 	.probe = fb_probe,
 	.remove = fb_remove,
@@ -1603,6 +1609,7 @@ static struct platform_driver da8xx_fb_driver = {
 	.driver = {
 		   .name = DRIVER_NAME,
 		   .owner = THIS_MODULE,
+		   .of_match_table = of_match_ptr(da8xx_fb_of_match),
 		   },
 };
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 08/12] video: da8xx-fb: invoke platform callback safely
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
	devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>

Ensure that platform data is present before checking whether platform
callback is present (the one used to control backlight). So far this
was not an issue as driver was purely non-DT triggered, but now DT
support has been added.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 drivers/video/da8xx-fb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 08ee8eb..0beed20 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1347,7 +1347,7 @@ static int fb_probe(struct platform_device *device)
 	par->dev = &device->dev;
 	par->lcdc_clk = fb_clk;
 	par->lcd_fck_rate = clk_get_rate(fb_clk);
-	if (fb_pdata->panel_power_ctrl) {
+	if (fb_pdata && fb_pdata->panel_power_ctrl) {
 		par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
 		par->panel_power_ctrl(1);
 	}
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 09/12] video: da8xx-fb: obtain fb_videomode info from dt
From: Afzal Mohammed @ 2013-01-15 13:54 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
	devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>

Obtain fb_videomode details for the connected lcd panel using the
display timing details present in DT.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 .../devicetree/bindings/video/fb-da8xx.txt         |   21 ++++++++++++++++++++
 drivers/video/da8xx-fb.c                           |   17 ++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/Documentation/devicetree/bindings/video/fb-da8xx.txt b/Documentation/devicetree/bindings/video/fb-da8xx.txt
index 581e014..0741f78 100644
--- a/Documentation/devicetree/bindings/video/fb-da8xx.txt
+++ b/Documentation/devicetree/bindings/video/fb-da8xx.txt
@@ -6,6 +6,12 @@ Required properties:
 	AM335x SoC's - "ti,am3352-lcdc", "ti,da830-lcdc"
 - reg: Address range of lcdc register set
 - interrupts: lcdc interrupt
+- display-timings: typical videomode of lcd panel, represented as child.
+  Refer Documentation/devicetree/bindings/video/display-timing.txt for
+  display timing binding details. If multiple videomodes are mentioned
+  in display timings node, typical videomode has to be mentioned as the
+  native mode or it has to be first child (driver cares only for native
+  videomode).
 
 Example:
 
@@ -13,4 +19,19 @@ lcdc@4830e000 {
 	compatible = "ti,am3352-lcdc", "ti,da830-lcdc";
 	reg =  <0x4830e000 0x1000>;
 	interrupts = <36>;
+	display-timings {
+		800x480p62 {
+			clock-frequency = <30000000>;
+			hactive = <800>;
+			vactive = <480>;
+			hfront-porch = <39>;
+			hback-porch = <39>;
+			hsync-len = <47>;
+			vback-porch = <29>;
+			vfront-porch = <13>;
+			vsync-len = <2>;
+			hsync-active = <1>;
+			vsync-active = <1>;
+		};
+	};
 };
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 0beed20..0c68712 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -36,6 +36,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/lcm.h>
+#include <video/of_display_timing.h>
 #include <video/da8xx-fb.h>
 #include <asm/div64.h>
 
@@ -1257,8 +1258,24 @@ static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
 {
 	struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data;
 	struct fb_videomode *lcdc_info;
+	struct device_node *np = dev->dev.of_node;
 	int i;
 
+	if (np) {
+		lcdc_info = devm_kzalloc(&dev->dev,
+					 sizeof(struct fb_videomode),
+					 GFP_KERNEL);
+		if (!lcdc_info) {
+			dev_err(&dev->dev, "memory allocation failed\n");
+			return NULL;
+		}
+		if (of_get_fb_videomode(np, lcdc_info, OF_USE_NATIVE_MODE)) {
+			dev_err(&dev->dev, "timings not available in DT\n");
+			return NULL;
+		}
+		return lcdc_info;
+	}
+
 	for (i = 0, lcdc_info = known_lcd_panels;
 		i < ARRAY_SIZE(known_lcd_panels); i++, lcdc_info++) {
 		if (strcmp(fb_pdata->type, lcdc_info->name) = 0)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 10/12] video: da8xx-fb: ensure pdata only for non-dt
From: Afzal Mohammed @ 2013-01-15 13:55 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
	devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>

This driver is DT probe-able, hence ensure presence of platform data
only for non-DT boot.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 drivers/video/da8xx-fb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 0c68712..1c1a616 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1303,7 +1303,7 @@ static int fb_probe(struct platform_device *device)
 	int ret;
 	unsigned long ulcm;
 
-	if (fb_pdata = NULL) {
+	if (fb_pdata = NULL && !device->dev.of_node) {
 		dev_err(&device->dev, "Can not get platform data\n");
 		return -ENOENT;
 	}
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 11/12] video: da8xx-fb: setup struct lcd_ctrl_config for dt
From: Afzal Mohammed @ 2013-01-15 13:55 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Sekhar Nori, linux-omap, linux-fbdev,
	devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>

strcut lcd_ctrl_config information required for driver is currently
obtained via platform data. To handle DT probing, create
lcd_ctrl_config and populate it with default values, these values are
sufficient for the panels so far used with this controller to work.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 drivers/video/da8xx-fb.c |   34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 1c1a616..5455682 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1254,6 +1254,35 @@ static struct fb_ops da8xx_fb_ops = {
 	.fb_blank = cfb_blank,
 };
 
+static struct lcd_ctrl_config *da8xx_fb_create_cfg(struct platform_device *dev)
+{
+	struct lcd_ctrl_config *cfg;
+
+	cfg = devm_kzalloc(&dev->dev, sizeof(struct fb_videomode), GFP_KERNEL);
+	if (!cfg) {
+		dev_err(&dev->dev, "memory allocation failed\n");
+		return NULL;
+	}
+
+	/* default values */
+
+	if (lcd_revision = LCD_VERSION_1)
+		cfg->bpp = 16;
+	else
+		cfg->bpp = 32;
+
+	/*
+	 * For panels so far used with this LCDC, below statement is sufficient.
+	 * For new panels, if required, struct lcd_ctrl_cfg fields to be updated
+	 * with additional/modified values. Those values would have to be then
+	 * obtained from dt(requiring new dt bindings).
+	 */
+
+	cfg->panel_shade = COLOR_ACTIVE;
+
+	return cfg;
+}
+
 static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)
 {
 	struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data;
@@ -1345,7 +1374,10 @@ static int fb_probe(struct platform_device *device)
 		break;
 	}
 
-	lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
+	if (device->dev.of_node)
+		lcd_cfg = da8xx_fb_create_cfg(device);
+	else
+		lcd_cfg = (struct lcd_ctrl_config *)fb_pdata->controller_data;
 
 	if (!lcd_cfg) {
 		ret = -EINVAL;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2 12/12] video: da8xx-fb: set upstream clock rate (if reqd)
From: Afzal Mohammed @ 2013-01-15 13:56 UTC (permalink / raw)
  To: Florian Tobias Schandinat, Tomi Valkeinen, Grant Likely,
	Rob Herring, Rob Landley, Mike Turquette, Sekhar Nori, linux-omap,
	linux-fbdev, devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <cover.1358251447.git.afzal@ti.com>

LCDC IP has a clock divider to adjust pixel clock, this limits pixel
clock range to fck/255 - fck/2(fck - rate of input clock to LCDC IP).
In the case of AM335x, where this IP is present, default fck is not
sufficient to provide normal pixel clock rates, hence rendering this
driver unusable on AM335x.

If input clock too is configurable, allowable range of pixel clock
would increase. Here initially it is checked whether with present fck,
divider in IP could be configured to obtain required rate, if not,
fck is adjusted. This makes it usable on AM335x.

Note:
A better (if allowable) solution may be to represent clock divider in
LCDC IP as a basic divider clock - the one defined in common clock
framework. But for this to happen, all the platform's using this driver
should be using common clock framework (DaVinci is yet to be converted
to use common clock framework). And it has to be determined whether
common clock framework allows this kind of a clock modelling inside a
driver and for this to be part of clock tree. Advantage of doing so
would be better resolution for pixel clock, even though without this
existing use cases are working properly. Or another extreme alternative
would be to replicate clk-divider of common clock framework inside the
driver, but that probably is not preferred and not worth as it would be
duplication and without much advantage to existing users.

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---

v2: new patch

 drivers/video/da8xx-fb.c |   76 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 58 insertions(+), 18 deletions(-)

diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 5455682..09dfa12 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -133,6 +133,9 @@
 #define WSI_TIMEOUT	50
 #define PALETTE_SIZE	256
 
+#define	CLK_MIN_DIV	2
+#define	CLK_MAX_DIV	255
+
 static void __iomem *da8xx_fb_reg_base;
 static struct resource *lcdc_regs;
 static unsigned int lcd_revision;
@@ -683,23 +686,21 @@ static void da8xx_fb_lcd_reset(void)
 	}
 }
 
-static inline unsigned da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
-						 unsigned pixclock)
-{
-	return par->lcd_fck_rate / (PICOS2KHZ(pixclock) * 1000);
-}
-
-static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
-					  unsigned pixclock)
+static int da8xx_fb_config_clk_divider(struct da8xx_fb_par *par,
+					      unsigned div, unsigned rate)
 {
-	unsigned div;
+	int ret;
 
-	div = da8xx_fb_calc_clk_divider(par, pixclock);
-	return KHZ2PICOS(par->lcd_fck_rate / (1000 * div));
-}
+	if (par->lcd_fck_rate != rate) {
+		ret = clk_set_rate(par->lcdc_clk, rate);
+		if (IS_ERR_VALUE(ret)) {
+			dev_err(par->dev,
+				"unable to set clock rate at %u\n", rate);
+			return ret;
+		}
+		par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
+	}
 
-static inline void da8xx_fb_config_clk_divider(unsigned div)
-{
 	/* Configure the LCD clock divisor. */
 	lcdc_write(LCD_CLK_DIVISOR(div) |
 			(LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
@@ -707,14 +708,49 @@ static inline void da8xx_fb_config_clk_divider(unsigned div)
 	if (lcd_revision = LCD_VERSION_2)
 		lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
 				LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
+
+	return 0;
+}
+
+static unsigned int da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
+					      unsigned pixclock,
+					      unsigned *rate)
+{
+	unsigned div;
+
+	pixclock = PICOS2KHZ(pixclock) * 1000;
+
+	*rate = par->lcd_fck_rate;
+
+	if (pixclock < (*rate / CLK_MAX_DIV)) {
+		*rate = clk_round_rate(par->lcdc_clk, pixclock * CLK_MAX_DIV);
+		div = CLK_MAX_DIV;
+	} else if (pixclock > (*rate / CLK_MIN_DIV)) {
+		*rate = clk_round_rate(par->lcdc_clk, pixclock * CLK_MIN_DIV);
+		div = CLK_MIN_DIV;
+	} else {
+		div = *rate / pixclock;
+	}
+
+	return div;
 }
 
-static inline void da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
+static inline int da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
 						    struct fb_videomode *mode)
 {
-	unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock);
+	unsigned rate;
+	unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock, &rate);
 
-	da8xx_fb_config_clk_divider(div);
+	return da8xx_fb_config_clk_divider(par, div, rate);
+}
+
+static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
+					  unsigned pixclock)
+{
+	unsigned div, rate;
+
+	div = da8xx_fb_calc_clk_divider(par, pixclock, &rate);
+	return KHZ2PICOS(rate / (1000 * div));
 }
 
 static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
@@ -723,7 +759,11 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
 	u32 bpp;
 	int ret = 0;
 
-	da8xx_fb_calc_config_clk_divider(par, panel);
+	ret = da8xx_fb_calc_config_clk_divider(par, panel);
+	if (IS_ERR_VALUE(ret)) {
+		dev_err(par->dev, "unable to configure clock\n");
+		return ret;
+	}
 
 	if (panel->sync & FB_SYNC_CLK_INVERT)
 		lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
-- 
1.7.9.5


^ permalink raw reply related

* RE: [PATCH 08/10] video: da8xx-fb: obtain fb_videomode info from dt
From: Mohammed, Afzal @ 2013-01-15 13:59 UTC (permalink / raw)
  To: Steffen Trumtrar
  Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Florian Tobias Schandinat,
	devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
	linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Nori, Sekhar,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring,
	Valkeinen, Tomi,
	linux-omap-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <C8443D0743D26F4388EA172BF4E2A7A93EA7FC7A-Er742YJ7I/eIQmiDNMet8wC/G2K4zDHf@public.gmane.org>

SGkgU3RlZmZlbiwNCg0KT24gTW9uLCBKYW4gMDcsIDIwMTMgYXQgMTQ6NTE6MTUsIE1vaGFtbWVk
LCBBZnphbCB3cm90ZToNCj4gT24gTW9uLCBKYW4gMDcsIDIwMTMgYXQgMTQ6NDE6MzEsIFN0ZWZm
ZW4gVHJ1bXRyYXIgd3JvdGU6DQo+ID4gT24gTW9uLCBKYW4gMDcsIDIwMTMgYXQgMTA6NDE6MzBB
TSArMDUzMCwgQWZ6YWwgTW9oYW1tZWQgd3JvdGU6DQoNCj4gPiA+ICstIGRpc3BsYXktdGltaW5n
czogbGlzdCBvZiBkaWZmZXJlbnQgdmlkZW9tb2RlcyBzdXBwb3J0ZWQgYnkgdGhlIGxjZA0KPiA+
ID4gKyAgcGFuZWwsIHJlcHJlc2VudGVkIGFzIGNoaWxkcywgY2FuIGhhdmUgbXVsdGlwbGUgbW9k
ZXMgc3VwcG9ydGVkLCBpZg0KPiA+ID4gKyAgb25seSBvbmUsIHRoZW4gaXQgaXMgY29uc2lkZXJl
ZCBuYXRpdmUgbW9kZSwgaWYgbXVsdGlwbGUgbW9kZXMgYXJlDQo+ID4gPiArICBwcm92aWRlZCwg
bmF0aXZlIG1vZGUgY2FuIGJlIHNldCBleHBsaWNpdGx5LCBtb3JlIGRldGFpbHMgYXZhaWxhYmxl
DQo+ID4gPiArICBARG9jdW1lbnRhdGlvbi9kZXZpY2V0cmVlL2JpbmRpbmdzL3ZpZGVvL2Rpc3Bs
YXktdGltaW5nLnR4dA0KPiANCj4gPiBLZWVwIGluIG1pbmQgdGhhdCB0aGUgdGV4dCBjb21iaW5l
ZCB3aXRoLi4uDQo+IA0KPiA+ID4gKwkJaWYgKG9mX2dldF9mYl92aWRlb21vZGUobnAsIGxjZGNf
aW5mbywgMCkpIHsNCj4gPiA+ICsJCQlkZXZfZXJyKCZkZXYtPmRldiwgInRpbWluZ3Mgbm90IGF2
YWlsYWJsZSBpbiBEVFxuIik7DQo+ID4gPiArCQkJcmV0dXJuIE5VTEw7DQo+ID4gPiArCQl9DQo+
ID4gPiArCQlyZXR1cm4gbGNkY19pbmZvOw0KPiA+ID4gKwl9DQo+ID4gDQo+ID4gLi4uIHRoaXMg
aXMgbm90IGNvcnJlY3QuIFlvdSBhcmUganVzdCBzdXBwb3J0aW5nIHRoZSBmaXJzdCBkaXNwbGF5
LXRpbWluZ3MNCj4gPiBzdWJub2RlIChvZl9nZXRfZmJfdmlkZW9tb2RlKC4uLiwgMCkpLg0KPiAN
Cj4gDQo+IFllcyByaWdodCwgSSB3aWxsIG1vZGlmeSB0aGUgdGV4dCB0byByZWZsZWN0IHdoYXQg
dGhlIGRyaXZlciBkb2VzLg0KDQpUaGlua2luZyBhYm91dCBpdCBmdXJ0aGVyLCBpdCBzZWVtcyB0
aGUgcmlnaHQgdGhpbmcgdG8gZG8NCmluIHRoaXMgY2FzZSB3b3VsZCBiZSB0byBpbnZva2UgYXMs
DQoNCiJvZl9nZXRfZmJfdmlkZW9tb2RlKG5wLCBsY2RfaW5mbywgT0ZfVVNFX05BVElWRV9NT0RF
KSIuDQoNClVwZGF0ZWQgdmVyc2lvbiBoYXMgYmVlbiBwb3N0ZWQgdG8gdGhlIGxpc3RzIChmb3Jn
b3QgdG8gY2MgeW91KQ0KDQpSZWdhcmRzDQpBZnphbA0KDQo

^ permalink raw reply

* Re: 3.8-rc2 lockdep complains about console_lock vs. fb_notifier_list.rwsem
From: Takashi Iwai @ 2013-01-15 14:25 UTC (permalink / raw)
  To: sedat.dilek; +Cc: Jiri Kosina, linux-fbdev, LKML, alan, Andrew Morton
In-Reply-To: <CA+icZUUxgRsGkYAmZ=JxTwPvdhTzpGLcxm6+VSq9jnfYPVXj4Q@mail.gmail.com>

At Sat, 5 Jan 2013 13:13:27 +0100,
Sedat Dilek wrote:
> 
> Hi Jiri,
> 
> ...known issue (see thread in [1]), please feel free to test patches
> from Alan and Andrew (see [1], [2] and [3]) and report.
> 
> Regards,
> - Sedat -
> 
> [1] http://marc.info/?t\x135309396400003&r=1&w=2
> [2] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover.patch
> [3] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix.patch
> [4] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix-2.patch

I've hit this bug and tried the patch [2] ([3] and [4] are gone).
Unfortunately the deadlock is still reported, as seen below.

A similar fix for fbcon_unbind(), splitting an unlocked version of
unbind_con_driver() and call it?

(BTW, the patch [2] contains strange characters in the comments, and
 has a few coding issues easily detected by checkpatch.pl.)


thanks,

Takashi

=
[    3.228454] [drm] Initialized drm 1.1.0 20060810
[    3.317144] [drm] radeon defaulting to kernel modesetting.
[    3.330546] [drm] radeon kernel modesetting enabled.
[    3.343942] checking generic (c0000000 1000000) vs hw (c0000000 10000000)
[    3.343946] fb: conflicting fb hw usage radeondrmfb vs VESA VGA - removing generic driver
[    3.357376] 
[    3.357377] ===========================
[    3.357378] [ INFO: possible circular locking dependency detected ]
[    3.357380] 3.8.0-rc3-test+ #82 Not tainted
[    3.357381] -------------------------------------------------------
[    3.357383] udevd/137 is trying to acquire lock:
[    3.357394]  (console_lock){+.+.+.}, at: [<ffffffff8140385f>] unbind_con_driver+0x3f/0x200
[    3.357395] 
[    3.357395] but task is already holding lock:
[    3.357402]  ((fb_notifier_list).rwsem){.+.+.+}, at: [<ffffffff810799b1>] __blocking_notifier_call_chain+0x51/0xc0
[    3.357403] 
[    3.357403] which lock already depends on the new lock.
[    3.357403] 
[    3.357404] 
[    3.357404] the existing dependency chain (in reverse order) is:
[    3.357407] 
[    3.357407] -> #1 ((fb_notifier_list).rwsem){.+.+.+}:
[    3.357411]        [<ffffffff810b605a>] lock_acquire+0xaa/0x210
[    3.357417]        [<ffffffff81643dc2>] down_read+0x42/0x57
[    3.357419]        [<ffffffff810799b1>] __blocking_notifier_call_chain+0x51/0xc0
[    3.357422]        [<ffffffff81079a31>] blocking_notifier_call_chain+0x11/0x20
[    3.357426]        [<ffffffff8138cbe6>] fb_notifier_call_chain+0x16/0x20
[    3.357428]        [<ffffffff8138e302>] register_framebuffer+0x1c2/0x2f0
[    3.357433]        [<ffffffff81d1748e>] vesafb_probe+0x6e0/0x760
[    3.357437]        [<ffffffff8142afbe>] platform_drv_probe+0x3e/0x70
[    3.357440]        [<ffffffff81428d26>] driver_probe_device+0x86/0x390
[    3.357442]        [<ffffffff814290d3>] __driver_attach+0xa3/0xb0
[    3.357445]        [<ffffffff81426dbd>] bus_for_each_dev+0x4d/0x90
[    3.357447]        [<ffffffff814286a9>] driver_attach+0x19/0x20
[    3.357450]        [<ffffffff81428308>] bus_add_driver+0x1a8/0x290
[    3.357452]        [<ffffffff81429792>] driver_register+0x72/0x170
[    3.357455]        [<ffffffff8142a7e1>] platform_driver_register+0x41/0x50
[    3.357458]        [<ffffffff8142a806>] platform_driver_probe+0x16/0xa0
[    3.357460]        [<ffffffff81d16d6b>] vesafb_init+0x215/0x258
[    3.357464]        [<ffffffff810002e2>] do_one_initcall+0x122/0x180
[    3.357468]        [<ffffffff816258ec>] kernel_init+0x1fc/0x370
[    3.357471]        [<ffffffff8164e1fc>] ret_from_fork+0x7c/0xb0
[    3.357474] 
[    3.357474] -> #0 (console_lock){+.+.+.}:
[    3.357476]        [<ffffffff810b5055>] __lock_acquire+0x1385/0x1cc0
[    3.357478]        [<ffffffff810b605a>] lock_acquire+0xaa/0x210
[    3.357482]        [<ffffffff81048fbf>] console_lock+0x6f/0x80
[    3.357485]        [<ffffffff8140385f>] unbind_con_driver+0x3f/0x200
[    3.357489]        [<ffffffff8139aeb7>] fbcon_event_notify+0x447/0x8b0
[    3.357492]        [<ffffffff8164a225>] notifier_call_chain+0x55/0x110
[    3.357495]        [<ffffffff810799c7>] __blocking_notifier_call_chain+0x67/0xc0
[    3.357497]        [<ffffffff81079a31>] blocking_notifier_call_chain+0x11/0x20
[    3.357500]        [<ffffffff8138cbe6>] fb_notifier_call_chain+0x16/0x20
[    3.357502]        [<ffffffff8138debb>] do_unregister_framebuffer+0x5b/0x110
[    3.357505]        [<ffffffff8138e108>] do_remove_conflicting_framebuffers+0x158/0x190
[    3.357507]        [<ffffffff8138e46a>] remove_conflicting_framebuffers+0x3a/0x60
[    3.357532]        [<ffffffffa00df16b>] radeon_pci_probe+0x8b/0xd0 [radeon]
[    3.357536]        [<ffffffff8136d5a6>] local_pci_probe+0x46/0x80
[    3.357539]        [<ffffffff8136d7f1>] pci_device_probe+0x101/0x110
[    3.357542]        [<ffffffff81428d26>] driver_probe_device+0x86/0x390
[    3.357544]        [<ffffffff814290d3>] __driver_attach+0xa3/0xb0
[    3.357547]        [<ffffffff81426dbd>] bus_for_each_dev+0x4d/0x90
[    3.357549]        [<ffffffff814286a9>] driver_attach+0x19/0x20
[    3.357552]        [<ffffffff81428308>] bus_add_driver+0x1a8/0x290
[    3.357554]        [<ffffffff81429792>] driver_register+0x72/0x170
[    3.357557]        [<ffffffff8136c60f>] __pci_register_driver+0x5f/0x70
[    3.357577]        [<ffffffffa006ec3a>] drm_pci_init+0x11a/0x130 [drm]
[    3.357594]        [<ffffffffa01c20ec>] radeon_init+0xec/0x1000 [radeon]
[    3.357597]        [<ffffffff810002e2>] do_one_initcall+0x122/0x180
[    3.357600]        [<ffffffff810c4b53>] load_module+0x1043/0x1510
[    3.357603]        [<ffffffff810c50f7>] sys_init_module+0xd7/0x120
[    3.357605]        [<ffffffff8164e2ad>] system_call_fastpath+0x1a/0x1f
[    3.357606] 
[    3.357606] other info that might help us debug this:
[    3.357606] 
[    3.357607]  Possible unsafe locking scenario:
[    3.357607] 
[    3.357608]        CPU0                    CPU1
[    3.357609]        ----                    ----
[    3.357611]   lock((fb_notifier_list).rwsem);
[    3.357613]                                lock(console_lock);
[    3.357615]                                lock((fb_notifier_list).rwsem);
[    3.357616]   lock(console_lock);
[    3.357617] 
[    3.357617]  *** DEADLOCK ***
[    3.357617] 
[    3.357619] 5 locks held by udevd/137:
[    3.357624]  #0:  (&__lockdep_no_validate__){......}, at: [<ffffffff81429083>] __driver_attach+0x53/0xb0
[    3.357628]  #1:  (&__lockdep_no_validate__){......}, at: [<ffffffff81429091>] __driver_attach+0x61/0xb0
[    3.357633]  #2:  (registration_lock){+.+.+.}, at: [<ffffffff8138e45b>] remove_conflicting_framebuffers+0x2b/0x60
[    3.357637]  #3:  (&fb_info->lock){+.+.+.}, at: [<ffffffff8138d0c1>] lock_fb_info+0x21/0x60
[    3.357642]  #4:  ((fb_notifier_list).rwsem){.+.+.+}, at: [<ffffffff810799b1>] __blocking_notifier_call_chain+0x51/0xc0
[    3.357643] 
[    3.357643] stack backtrace:
[    3.357645] Pid: 137, comm: udevd Not tainted 3.8.0-rc3-test+ #82
[    3.357646] Call Trace:
[    3.357652]  [<ffffffff8163b136>] print_circular_bug+0x1fb/0x20c
[    3.357655]  [<ffffffff810b5055>] __lock_acquire+0x1385/0x1cc0
[    3.357658]  [<ffffffff810b605a>] lock_acquire+0xaa/0x210
[    3.357661]  [<ffffffff8140385f>] ? unbind_con_driver+0x3f/0x200
[    3.357664]  [<ffffffff810b2b0d>] ? trace_hardirqs_on+0xd/0x10
[    3.357667]  [<ffffffff81048fbf>] console_lock+0x6f/0x80
[    3.357670]  [<ffffffff8140385f>] ? unbind_con_driver+0x3f/0x200
[    3.357673]  [<ffffffff8140385f>] unbind_con_driver+0x3f/0x200
[    3.357676]  [<ffffffff8134c01e>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[    3.357680]  [<ffffffff8139aeb7>] fbcon_event_notify+0x447/0x8b0
[    3.357683]  [<ffffffff8164a225>] notifier_call_chain+0x55/0x110
[    3.357685]  [<ffffffff810799c7>] __blocking_notifier_call_chain+0x67/0xc0
[    3.357688]  [<ffffffff81079a31>] blocking_notifier_call_chain+0x11/0x20
[    3.357690]  [<ffffffff8138cbe6>] fb_notifier_call_chain+0x16/0x20
[    3.357693]  [<ffffffff8138debb>] do_unregister_framebuffer+0x5b/0x110
[    3.357696]  [<ffffffff8138e108>] do_remove_conflicting_framebuffers+0x158/0x190
[    3.357698]  [<ffffffff8138e46a>] remove_conflicting_framebuffers+0x3a/0x60
[    3.357717]  [<ffffffffa00df16b>] radeon_pci_probe+0x8b/0xd0 [radeon]
[    3.357721]  [<ffffffff8136d5a6>] local_pci_probe+0x46/0x80
[    3.357724]  [<ffffffff8136d7f1>] pci_device_probe+0x101/0x110
[    3.357727]  [<ffffffff81428d26>] driver_probe_device+0x86/0x390
[    3.357729]  [<ffffffff814290d3>] __driver_attach+0xa3/0xb0
[    3.357732]  [<ffffffff81429030>] ? driver_probe_device+0x390/0x390
[    3.357734]  [<ffffffff81426dbd>] bus_for_each_dev+0x4d/0x90
[    3.357737]  [<ffffffff814286a9>] driver_attach+0x19/0x20
[    3.357740]  [<ffffffff81428308>] bus_add_driver+0x1a8/0x290
[    3.357744]  [<ffffffffa01c2000>] ? 0xffffffffa01c1fff
[    3.357747]  [<ffffffff81429792>] driver_register+0x72/0x170
[    3.357749]  [<ffffffffa01c2000>] ? 0xffffffffa01c1fff
[    3.357752]  [<ffffffff8136c60f>] __pci_register_driver+0x5f/0x70
[    3.357762]  [<ffffffffa006ec3a>] drm_pci_init+0x11a/0x130 [drm]
[    3.357764]  [<ffffffffa01c2000>] ? 0xffffffffa01c1fff
[    3.357767]  [<ffffffffa01c2000>] ? 0xffffffffa01c1fff
[    3.357784]  [<ffffffffa01c20ec>] radeon_init+0xec/0x1000 [radeon]
[    3.357786]  [<ffffffff810002e2>] do_one_initcall+0x122/0x180
[    3.357789]  [<ffffffff810c4b53>] load_module+0x1043/0x1510
[    3.357792]  [<ffffffff8135d260>] ? ddebug_proc_open+0xb0/0xb0
[    3.357796]  [<ffffffff810c50f7>] sys_init_module+0xd7/0x120
[    3.357798]  [<ffffffff8164e2ad>] system_call_fastpath+0x1a/0x1f

^ permalink raw reply

* Re: 3.8-rc2 lockdep complains about console_lock vs. fb_notifier_list.rwsem
From: Takashi Iwai @ 2013-01-15 14:47 UTC (permalink / raw)
  To: Andrew Morton; +Cc: sedat.dilek, Jiri Kosina, linux-fbdev, LKML, alan
In-Reply-To: <s5hpq16zfox.wl%tiwai@suse.de>

At Tue, 15 Jan 2013 15:25:18 +0100,
Takashi Iwai wrote:
> 
> At Sat, 5 Jan 2013 13:13:27 +0100,
> Sedat Dilek wrote:
> > 
> > Hi Jiri,
> > 
> > ...known issue (see thread in [1]), please feel free to test patches
> > from Alan and Andrew (see [1], [2] and [3]) and report.
> > 
> > Regards,
> > - Sedat -
> > 
> > [1] http://marc.info/?t\x135309396400003&r=1&w=2
> > [2] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover.patch
> > [3] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix.patch
> > [4] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix-2.patch
> 
> I've hit this bug and tried the patch [2] ([3] and [4] are gone).
> Unfortunately the deadlock is still reported, as seen below.
> 
> A similar fix for fbcon_unbind(), splitting an unlocked version of
> unbind_con_driver() and call it?
> 
> (BTW, the patch [2] contains strange characters in the comments, and
>  has a few coding issues easily detected by checkpatch.pl.)

The fix patch for coding issue is below.
Feel free to fold into the original patch.


Takashi

=
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH] fb: Fix coding style and remove stray non-ascii chars

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 drivers/tty/vt/vt.c           | 4 ++--
 drivers/video/console/fbcon.c | 3 +--
 drivers/video/fbmem.c         | 4 ++--
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index f307196..1db1c8d 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3653,7 +3653,7 @@ int do_take_over_console(const struct consw *csw, int first, int last, int deflt
 	/*
 	 * If we get an busy error we still want to bind the console driver
 	 * and return success, as we may have unbound the console driver
-	 * but not unregistered it.
+	 * but not unregistered it.
 	 */
 	if (err = -EBUSY)
 		err = 0;
@@ -3679,7 +3679,7 @@ int take_over_console(const struct consw *csw, int first, int last, int deflt)
 	/*
 	 * If we get an busy error we still want to bind the console driver
 	 * and return success, as we may have unbound the console driver
-	 * but not unregistered it.
+	 * but not unregistered it.
 	 */
 	if (err = -EBUSY)
 		err = 0;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index c75f8ce..4bd7820 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -546,9 +546,8 @@ static int do_fbcon_takeover(int show_logo)
 				fbcon_is_default);
 
 	if (err) {
-		for (i = first_fb_vc; i <= last_fb_vc; i++) {
+		for (i = first_fb_vc; i <= last_fb_vc; i++)
 			con2fb_map[i] = -1;
-		}
 		info_idx = -1;
 	} else {
 		fbcon_has_console_bind = 1;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 564ebe9..d8d9831 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1650,9 +1650,9 @@ static int do_register_framebuffer(struct fb_info *fb_info)
 	event.info = fb_info;
 	if (!lock_fb_info(fb_info))
 		return -ENODEV;
-        console_lock();
+	console_lock();
 	fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event);
-        console_unlock();
+	console_unlock();
 	unlock_fb_info(fb_info);
 	return 0;
 }
-- 
1.8.1


^ permalink raw reply related

* Re: [PATCH v2 12/12] video: da8xx-fb: set upstream clock rate (if reqd)
From: Mike Turquette @ 2013-01-15 15:32 UTC (permalink / raw)
  To: Afzal Mohammed, Florian Tobias Schandinat, Tomi Valkeinen,
	Grant Likely, Rob Herring, Rob Landley, Sekhar Nori, linux-omap,
	linux-fbdev, devicetree-discuss, linux-doc, linux-kernel
In-Reply-To: <26e787b021cda89a080f80657c2094b9ff2decaf.1358251448.git.afzal@ti.com>

Quoting Afzal Mohammed (2013-01-15 05:44:36)
> LCDC IP has a clock divider to adjust pixel clock, this limits pixel
> clock range to fck/255 - fck/2(fck - rate of input clock to LCDC IP).
> In the case of AM335x, where this IP is present, default fck is not
> sufficient to provide normal pixel clock rates, hence rendering this
> driver unusable on AM335x.
> 
> If input clock too is configurable, allowable range of pixel clock
> would increase. Here initially it is checked whether with present fck,
> divider in IP could be configured to obtain required rate, if not,
> fck is adjusted. This makes it usable on AM335x.
> 
> Note:
> A better (if allowable) solution may be to represent clock divider in
> LCDC IP as a basic divider clock - the one defined in common clock
> framework. But for this to happen, all the platform's using this driver
> should be using common clock framework (DaVinci is yet to be converted
> to use common clock framework). And it has to be determined whether
> common clock framework allows this kind of a clock modelling inside a
> driver and for this to be part of clock tree. Advantage of doing so
> would be better resolution for pixel clock, even though without this
> existing use cases are working properly. Or another extreme alternative
> would be to replicate clk-divider of common clock framework inside the
> driver, but that probably is not preferred and not worth as it would be
> duplication and without much advantage to existing users.
> 

Afzal,

Modeling the divider inside your IP block as a clock is supported in the
common clock framework.  Linking up these sorts of clocks to the clock
tree was one of the original design goals of CCF.

Regarding DaVinci: converting that platform over to use CCF would be the
best approach.  An alternative would be that you could break
single-image boot for AM335x and DaVinci, by having AM335x use CCF and
DaVinci use the legacy clock framework.  From the LCDC driver's
perspective this should not matter and is indeed the purpose of the
clk.h api and clkdev interfaces, however looking at this driver I can
see there would still be a lot ifdef-ery going on... better to just
convert everything over to CCF.

Regards,
Mike

> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
> 
> v2: new patch
> 
>  drivers/video/da8xx-fb.c |   76 +++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 58 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
> index 5455682..09dfa12 100644
> --- a/drivers/video/da8xx-fb.c
> +++ b/drivers/video/da8xx-fb.c
> @@ -133,6 +133,9 @@
>  #define WSI_TIMEOUT    50
>  #define PALETTE_SIZE   256
>  
> +#define        CLK_MIN_DIV     2
> +#define        CLK_MAX_DIV     255
> +
>  static void __iomem *da8xx_fb_reg_base;
>  static struct resource *lcdc_regs;
>  static unsigned int lcd_revision;
> @@ -683,23 +686,21 @@ static void da8xx_fb_lcd_reset(void)
>         }
>  }
>  
> -static inline unsigned da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
> -                                                unsigned pixclock)
> -{
> -       return par->lcd_fck_rate / (PICOS2KHZ(pixclock) * 1000);
> -}
> -
> -static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
> -                                         unsigned pixclock)
> +static int da8xx_fb_config_clk_divider(struct da8xx_fb_par *par,
> +                                             unsigned div, unsigned rate)
>  {
> -       unsigned div;
> +       int ret;
>  
> -       div = da8xx_fb_calc_clk_divider(par, pixclock);
> -       return KHZ2PICOS(par->lcd_fck_rate / (1000 * div));
> -}
> +       if (par->lcd_fck_rate != rate) {
> +               ret = clk_set_rate(par->lcdc_clk, rate);
> +               if (IS_ERR_VALUE(ret)) {
> +                       dev_err(par->dev,
> +                               "unable to set clock rate at %u\n", rate);
> +                       return ret;
> +               }
> +               par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
> +       }
>  
> -static inline void da8xx_fb_config_clk_divider(unsigned div)
> -{
>         /* Configure the LCD clock divisor. */
>         lcdc_write(LCD_CLK_DIVISOR(div) |
>                         (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG);
> @@ -707,14 +708,49 @@ static inline void da8xx_fb_config_clk_divider(unsigned div)
>         if (lcd_revision = LCD_VERSION_2)
>                 lcdc_write(LCD_V2_DMA_CLK_EN | LCD_V2_LIDD_CLK_EN |
>                                 LCD_V2_CORE_CLK_EN, LCD_CLK_ENABLE_REG);
> +
> +       return 0;
> +}
> +
> +static unsigned int da8xx_fb_calc_clk_divider(struct da8xx_fb_par *par,
> +                                             unsigned pixclock,
> +                                             unsigned *rate)
> +{
> +       unsigned div;
> +
> +       pixclock = PICOS2KHZ(pixclock) * 1000;
> +
> +       *rate = par->lcd_fck_rate;
> +
> +       if (pixclock < (*rate / CLK_MAX_DIV)) {
> +               *rate = clk_round_rate(par->lcdc_clk, pixclock * CLK_MAX_DIV);
> +               div = CLK_MAX_DIV;
> +       } else if (pixclock > (*rate / CLK_MIN_DIV)) {
> +               *rate = clk_round_rate(par->lcdc_clk, pixclock * CLK_MIN_DIV);
> +               div = CLK_MIN_DIV;
> +       } else {
> +               div = *rate / pixclock;
> +       }
> +
> +       return div;
>  }
>  
> -static inline void da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
> +static inline int da8xx_fb_calc_config_clk_divider(struct da8xx_fb_par *par,
>                                                     struct fb_videomode *mode)
>  {
> -       unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock);
> +       unsigned rate;
> +       unsigned div = da8xx_fb_calc_clk_divider(par, mode->pixclock, &rate);
>  
> -       da8xx_fb_config_clk_divider(div);
> +       return da8xx_fb_config_clk_divider(par, div, rate);
> +}
> +
> +static inline unsigned da8xx_fb_round_clk(struct da8xx_fb_par *par,
> +                                         unsigned pixclock)
> +{
> +       unsigned div, rate;
> +
> +       div = da8xx_fb_calc_clk_divider(par, pixclock, &rate);
> +       return KHZ2PICOS(rate / (1000 * div));
>  }
>  
>  static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
> @@ -723,7 +759,11 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg,
>         u32 bpp;
>         int ret = 0;
>  
> -       da8xx_fb_calc_config_clk_divider(par, panel);
> +       ret = da8xx_fb_calc_config_clk_divider(par, panel);
> +       if (IS_ERR_VALUE(ret)) {
> +               dev_err(par->dev, "unable to configure clock\n");
> +               return ret;
> +       }
>  
>         if (panel->sync & FB_SYNC_CLK_INVERT)
>                 lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) |
> -- 
> 1.7.9.5

^ permalink raw reply

* Re: [PATCH] ARM: AM33XX: clock: SET_RATE_PARENT in lcd path
From: Mike Turquette @ 2013-01-15 16:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1358256897-26275-1-git-send-email-afzal@ti.com>

Quoting Afzal Mohammed (2013-01-15 05:34:57)
> LCDC clock node is a one that does not have set rate capability. It
> just passes on the rate that is sent downstream by it's parent. While
> lcdc clock parent and it's grand parent - dpll_disp_m2_ck and
> dpll_disp_ck has the capability to configure rate.
> 
> And the default rates provided by LCDC clock's ancestors are not
> sufficient to obtain pixel clock for current LCDC use cases, hence
> currently display would not work on AM335x SoC's (with driver
> modifications in platfrom independent way).
> 
> Hence inform clock framework to propogate set rate for LCDC clock as
> well as it's parent - dpll_disp_m2_ck. With this change, set rate on
> LCDC clock would get propogated till dpll_disp_ck via dpll_disp_m2_ck,
> hence allowing the driver (same driver is used in DaVinci too) to set
> rates using LCDC clock without worrying about platform dependent clock
> details.
> 
> Signed-off-by: Afzal Mohammed <afzal@ti.com>
> ---
> 
> Based on v3.8-rc3
> 
>  arch/arm/mach-omap2/cclock33xx_data.c |    9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/cclock33xx_data.c b/arch/arm/mach-omap2/cclock33xx_data.c
> index ea64ad6..b731216 100644
> --- a/arch/arm/mach-omap2/cclock33xx_data.c
> +++ b/arch/arm/mach-omap2/cclock33xx_data.c
> @@ -284,9 +284,10 @@ DEFINE_STRUCT_CLK(dpll_disp_ck, dpll_core_ck_parents, dpll_ddr_ck_ops);
>   * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2
>   * and ALT_CLK1/2)
>   */
> -DEFINE_CLK_DIVIDER(dpll_disp_m2_ck, "dpll_disp_ck", &dpll_disp_ck, 0x0,
> -                  AM33XX_CM_DIV_M2_DPLL_DISP, AM33XX_DPLL_CLKOUT_DIV_SHIFT,
> -                  AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL);
> +DEFINE_CLK_DIVIDER(dpll_disp_m2_ck, "dpll_disp_ck", &dpll_disp_ck,
> +                  CLK_SET_RATE_PARENT, AM33XX_CM_DIV_M2_DPLL_DISP,
> +                  AM33XX_DPLL_CLKOUT_DIV_SHIFT, AM33XX_DPLL_CLKOUT_DIV_WIDTH,
> +                  CLK_DIVIDER_ONE_BASED, NULL);
>  
>  /* DPLL_PER */
>  static struct dpll_data dpll_per_dd = {
> @@ -932,6 +933,8 @@ int __init am33xx_clk_init(void)
>                 cpu_clkflg = CK_AM33XX;
>         }
>  
> +       lcd_gclk.flags |= CLK_SET_RATE_PARENT;
> +

Afzal,

This is a bit hacky.  Someone looking at the definition of struct
lcd_gclk above cannot easily tell that CLK_SET_RATE_PARENT is set below.
Also if other clocks need flags set at a later date then this will
become a big ugly block of flag setting.

I hope to move away from these macros some day, but in the mean time it
might be good to have a DEFINE_STRUCT_CLK_FLAGS macro which adds in an
argument struct clk->flags.

Paul, any thoughts on yet another macro?

Thanks,
Mike

>         for (c = am33xx_clks; c < am33xx_clks + ARRAY_SIZE(am33xx_clks); c++) {
>                 if (c->cpu & cpu_clkflg) {
>                         clkdev_add(&c->lk);
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: 3.8-rc2 lockdep complains about console_lock vs. fb_notifier_list.rwsem
From: Takashi Iwai @ 2013-01-15 16:46 UTC (permalink / raw)
  To: Andrew Morton; +Cc: sedat.dilek, Jiri Kosina, linux-fbdev, LKML, alan
In-Reply-To: <s5hip6yzeo9.wl%tiwai@suse.de>

At Tue, 15 Jan 2013 15:47:18 +0100,
Takashi Iwai wrote:
> 
> At Tue, 15 Jan 2013 15:25:18 +0100,
> Takashi Iwai wrote:
> > 
> > At Sat, 5 Jan 2013 13:13:27 +0100,
> > Sedat Dilek wrote:
> > > 
> > > Hi Jiri,
> > > 
> > > ...known issue (see thread in [1]), please feel free to test patches
> > > from Alan and Andrew (see [1], [2] and [3]) and report.
> > > 
> > > Regards,
> > > - Sedat -
> > > 
> > > [1] http://marc.info/?t\x135309396400003&r=1&w=2
> > > [2] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover.patch
> > > [3] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix.patch
> > > [4] http://ozlabs.org/~akpm/mmots/broken-out/fb-rework-locking-to-fix-lock-ordering-on-takeover-fix-2.patch
> > 
> > I've hit this bug and tried the patch [2] ([3] and [4] are gone).
> > Unfortunately the deadlock is still reported, as seen below.
> > 
> > A similar fix for fbcon_unbind(), splitting an unlocked version of
> > unbind_con_driver() and call it?
> > 
> > (BTW, the patch [2] contains strange characters in the comments, and
> >  has a few coding issues easily detected by checkpatch.pl.)
> 
> The fix patch for coding issue is below.
> Feel free to fold into the original patch.

... and the additional patch below fixed the lockdep warning on my
machine.


Takashi

=
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH] fb: Yet another band-aid for fixing lockdep mess

I've still got lockdep warnings even after Alan's patch, and it seems
that yet more band aids are required to paper over similar paths for
unbind_con_driver() and unregister_con_driver().  After this hack,
lockdep warnings are finally gone.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 drivers/tty/vt/vt.c           | 43 ++++++++++++++++++++++++++++---------------
 drivers/video/console/fbcon.c |  4 ++--
 drivers/video/fbmem.c         |  4 ++++
 include/linux/console.h       |  1 +
 include/linux/vt_kern.h       |  2 ++
 5 files changed, 37 insertions(+), 17 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 1db1c8d..3947e8d 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3135,6 +3135,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last)
  */
 int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
 {
+	int retval;
+
+	console_lock();
+	retval = do_unbind_con_driver(csw, first, last, deflt);
+	console_unlock();
+	return retval;
+}
+EXPORT_SYMBOL(unbind_con_driver);
+
+/* unlocked version of unbind_con_driver() */
+int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
+{
 	struct module *owner = csw->owner;
 	const struct consw *defcsw = NULL;
 	struct con_driver *con_driver = NULL, *con_back = NULL;
@@ -3143,7 +3155,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
 	if (!try_module_get(owner))
 		return -ENODEV;
 
-	console_lock();
+	WARN_CONSOLE_UNLOCKED();
 
 	/* check if driver is registered and if it is unbindable */
 	for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3156,10 +3168,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
 		}
 	}
 
-	if (retval) {
-		console_unlock();
+	if (retval)
 		goto err;
-	}
 
 	retval = -ENODEV;
 
@@ -3175,15 +3185,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
 		}
 	}
 
-	if (retval) {
-		console_unlock();
+	if (retval)
 		goto err;
-	}
 
-	if (!con_is_bound(csw)) {
-		console_unlock();
+	if (!con_is_bound(csw))
 		goto err;
-	}
 
 	first = max(first, con_driver->first);
 	last = min(last, con_driver->last);
@@ -3212,13 +3218,12 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
 
 	/* ignore return value, binding should not fail */
 	do_bind_con_driver(defcsw, first, last, deflt);
-	console_unlock();
 err:
 	module_put(owner);
 	return retval;
 
 }
-EXPORT_SYMBOL(unbind_con_driver);
+EXPORT_SYMBOL_GPL(do_unbind_con_driver);
 
 static int vt_bind(struct con_driver *con)
 {
@@ -3605,9 +3610,18 @@ EXPORT_SYMBOL(register_con_driver);
  */
 int unregister_con_driver(const struct consw *csw)
 {
-	int i, retval = -ENODEV;
+	int retval;
 
 	console_lock();
+	retval = do_unregister_con_driver(csw);
+	console_unlock();
+	return retval;
+}
+EXPORT_SYMBOL(unregister_con_driver);
+
+int do_unregister_con_driver(const struct consw *csw)
+{
+	int i, retval = -ENODEV;
 
 	/* cannot unregister a bound driver */
 	if (con_is_bound(csw))
@@ -3633,10 +3647,9 @@ int unregister_con_driver(const struct consw *csw)
 		}
 	}
 err:
-	console_unlock();
 	return retval;
 }
-EXPORT_SYMBOL(unregister_con_driver);
+EXPORT_SYMBOL_GPL(do_unregister_con_driver);
 
 /*
  *	If we support more console drivers, this function is used
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 4bd7820..2aef9ca 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -3004,7 +3004,7 @@ static int fbcon_unbind(void)
 {
 	int ret;
 
-	ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
+	ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc,
 				fbcon_is_default);
 
 	if (!ret)
@@ -3077,7 +3077,7 @@ static int fbcon_fb_unregistered(struct fb_info *info)
 		primary_device = -1;
 
 	if (!num_registered_fb)
-		unregister_con_driver(&fb_con);
+		do_unregister_con_driver(&fb_con);
 
 	return 0;
 }
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index d8d9831..070b9a1 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1668,8 +1668,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
 
 	if (!lock_fb_info(fb_info))
 		return -ENODEV;
+	console_lock();
 	event.info = fb_info;
 	ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event);
+	console_unlock();
 	unlock_fb_info(fb_info);
 
 	if (ret)
@@ -1684,7 +1686,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
 	num_registered_fb--;
 	fb_cleanup_device(fb_info);
 	event.info = fb_info;
+	console_lock();
 	fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
+	console_unlock();
 
 	/* this may free fb info */
 	put_fb_info(fb_info);
diff --git a/include/linux/console.h b/include/linux/console.h
index 4ef4307..47b858c 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -77,6 +77,7 @@ extern const struct consw prom_con;	/* SPARC PROM console */
 int con_is_bound(const struct consw *csw);
 int register_con_driver(const struct consw *csw, int first, int last);
 int unregister_con_driver(const struct consw *csw);
+int do_unregister_con_driver(const struct consw *csw);
 int take_over_console(const struct consw *sw, int first, int last, int deflt);
 int do_take_over_console(const struct consw *sw, int first, int last, int deflt);
 void give_up_console(const struct consw *sw);
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index 50ae7d0..dbbc6bf 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -130,6 +130,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
 int vt_waitactive(int n);
 void change_console(struct vc_data *new_vc);
 void reset_vc(struct vc_data *vc);
+extern int do_unbind_con_driver(const struct consw *csw, int first, int last,
+			     int deflt);
 extern int unbind_con_driver(const struct consw *csw, int first, int last,
 			     int deflt);
 int vty_init(const struct file_operations *console_fops);
-- 
1.8.1


^ permalink raw reply related


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