Linux Framebuffer Layer development
 help / color / mirror / Atom feed
* Re: [PATCH 5/5] drm/i915: Kick out vga console
From: Tomi Valkeinen @ 2014-06-09 13:22 UTC (permalink / raw)
  To: Daniel Vetter, Intel Graphics Development
  Cc: Linux Fbdev development list, LKML, DRI Development,
	David Herrmann, Jean-Christophe Plagniol-Villard
In-Reply-To: <CAKMK7uH7GWspr03NBi7rVY+2UN-vdthMV7eixXA-xc3t2JdzPg@mail.gmail.com>

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

Hi,

On 06/06/14 18:20, Daniel Vetter wrote:
> Tomi/Jean can you please ack merging this through drm-intel trees? It
> just exports the vga and dummy consoles so that i915 can do what it
> needs to do.

Acked-by: Tomi Valkeinen <tomi.valkeinen@ti.com>

 Tomi



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* re: OMAPDSS: panel sharp-ls037v7dw01 DT support
From: Dan Carpenter @ 2014-06-10  9:04 UTC (permalink / raw)
  To: linux-fbdev

Hello Tony Lindgren,

This is a semi-automatic email about new static checker warnings.

The patch be88c16a22ed: "OMAPDSS: panel sharp-ls037v7dw01 DT support"
from May 16, 2014, leads to the following Smatch complaint:

drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c:113 sharp_ls_enable()
	 error: we previously assumed 'ddata->vcc' could be null (see line 105)

drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
   104	
   105		if (ddata->vcc) {
                    ^^^^^^^^^^
Patch introduces a check.

   106			r = regulator_enable(ddata->vcc);
   107			if (r != 0)
   108				return r;
   109		}
   110	
   111		r = in->ops.dpi->enable(in);
   112		if (r) {
   113			regulator_disable(ddata->vcc);
                                          ^^^^^^^^^^
Patch introduces a new dereference and I was too lazy to find out if
an error in ->enable() implies a non-null "ddata->vcc" because I am a
bad person.

   114			return r;
   115		}

regards,
dan carpenter

^ permalink raw reply

* Re: [PATCH v7][ 3/5] video: mx3fb: Introduce regulator support.
From: Denis Carikli @ 2014-06-10 13:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140317062026.GZ17250@pengutronix.de>

On 03/17/2014 07:20 AM, Sascha Hauer wrote:
> On Fri, Mar 14, 2014 at 10:12:47AM +0100, Denis Carikli wrote:
>>
>> +		of_property_read_string(display_np, "regulator-name",
>> +					&regulator_name);
>> +
>
> [...]
>
>> +	/* In dt mode,
>> +	 * using devm_regulator_get would require that the proprety referencing
>> +	 * the regulator phandle has to be inside the mx3fb node.
>> +	 */
>> +	if (np) {
>> +		if (regulator_name)
>> +			mx3fbi->reg_lcd = regulator_get(NULL, regulator_name);
>> +
>> +		if (IS_ERR(mx3fbi->reg_lcd))
>> +			return PTR_ERR(mx3fbi->reg_lcd);
>> +	} else {
>> +		/* Permit that driver without a regulator in non-dt mode */
>> +		mx3fbi->reg_lcd = regulator_get(dev, "lcd");
>> +	}
>
> This patch adds regulator support for the display of a i.MX3 IPU. The
> problem Denis has to solve here is that he needs to get the regulator,
> but the display devicenode doesn't have a struct device associated with
> it, so he cannot provide one to regulator_get(). One way out here could
> be a of_regulator_get(struct device_node *). Mark, would this be ok with
> you?

Here, the display devicenode has no struct device associated with it 
like mentioned above.
Because of that, retriving the regulator from the devicetree, for 
instance like regulator_dev_lookup() does, would require a different 
approach.

As I understand it, what happen in regulator_dev_lookup when 
regulator_get(NULL, regulator_name) is used is the following:

Since the struct device is NULL, it skips the struct device based 
lookup, but also the devicetree lookup (it uses dev->of_node for that)
At the end it falls back on a match on the regulator name to find it.

would keeping regulator_get(NULL, regulator_name); in the driver instead 
be better for now?

Denis.

^ permalink raw reply

* re: OMAPDSS: move 'compatible' converter to omapdss driver
From: Dan Carpenter @ 2014-06-10 19:00 UTC (permalink / raw)
  To: linux-fbdev

Hello Tomi Valkeinen,

The patch f2dd36ac9974: "OMAPDSS: move 'compatible' converter to
omapdss driver" from May 15, 2014, leads to the following static
checker warning:

	drivers/video/fbdev/omap2/dss/omapdss-boot-init.c:124 omapdss_add_to_list()
	error: potential null dereference 'n'. (kmalloc returns null)

drivers/video/fbdev/omap2/dss/omapdss-boot-init.c
   120  static void __init omapdss_add_to_list(struct device_node *node, bool root)
   121  {
   122          struct dss_conv_node *n = kmalloc(sizeof(struct dss_conv_node),
   123                  GFP_KERNEL);
   124          n->node = node;
   125          n->root = root;
   126          list_add(&n->list, &dss_conv_list);
   127  }
   128  

regards,
dan carpenter

^ permalink raw reply

* [patch] video/mbx: indent some if statements
From: Dan Carpenter @ 2014-06-11  6:45 UTC (permalink / raw)
  To: linux-fbdev

Checkpatch.pl worries that we have left off the conditional bit because
it isn't indented correctly.

WARNING: suspect code indent for conditional statements (24, 24)

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>

diff --git a/drivers/video/fbdev/mbx/mbxfb.c b/drivers/video/fbdev/mbx/mbxfb.c
index 2bd52ed..698df954 100644
--- a/drivers/video/fbdev/mbx/mbxfb.c
+++ b/drivers/video/fbdev/mbx/mbxfb.c
@@ -628,14 +628,14 @@ static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,
 		case MBXFB_IOCS_PLANEORDER:
 			if (copy_from_user(&porder, (void __user*)arg,
 					sizeof(struct mbxfb_planeorder)))
-			return -EFAULT;
+				return -EFAULT;
 
 			return mbxfb_ioctl_planeorder(&porder);
 
 		case MBXFB_IOCS_ALPHA:
 			if (copy_from_user(&alpha, (void __user*)arg,
 					sizeof(struct mbxfb_alphaCtl)))
-			return -EFAULT;
+				return -EFAULT;
 
 			return mbxfb_ioctl_alphactl(&alpha);
 

^ permalink raw reply related

* [PATCH] video: OF display-timings support for ocfb
From: Franck Jullien @ 2014-06-11 20:17 UTC (permalink / raw)
  To: linux-kernel, linux-fbdev
  Cc: tomi.valkeinen, plagnioj, stefan.kristiansson, Franck Jullien

Signed-off-by: Franck Jullien <franck.jullien@gmail.com>
---
 drivers/video/fbdev/Kconfig |    2 ++
 drivers/video/fbdev/ocfb.c  |   31 ++++++++++++++++++++++++++-----
 2 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index e1f4727..b4ac6bb 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -942,6 +942,8 @@ config FB_OPENCORES
 	select FB_CFB_FILLRECT
 	select FB_CFB_COPYAREA
 	select FB_CFB_IMAGEBLIT
+	select VIDEOMODE_HELPERS
+	select FB_MODE_HELPERS
 	help
 	  This enables support for the OpenCores VGA/LCD core.
 
diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c
index 7f9dc9b..6d15565 100644
--- a/drivers/video/fbdev/ocfb.c
+++ b/drivers/video/fbdev/ocfb.c
@@ -22,6 +22,8 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 
+#include <video/of_display_timing.h>
+
 /* OCFB register defines */
 #define OCFB_CTRL	0x000
 #define OCFB_STAT	0x004
@@ -310,11 +312,30 @@ static int ocfb_probe(struct platform_device *pdev)
 	fbdev->info.device = &pdev->dev;
 	fbdev->info.par = fbdev;
 
-	/* Video mode setup */
-	if (!fb_find_mode(&fbdev->info.var, &fbdev->info, mode_option,
-			  NULL, 0, &default_mode, 16)) {
-		dev_err(&pdev->dev, "No valid video modes found\n");
-		return -EINVAL;
+	if (!mode_option && IS_ENABLED(CONFIG_OF)) {
+		struct fb_videomode mode;
+		u32 bpp;
+
+		ret = of_get_fb_videomode(pdev->dev.of_node, &mode,
+					  OF_USE_NATIVE_MODE);
+		if (ret)
+			return ret;
+
+		fb_videomode_to_var(&fbdev->info.var, &mode);
+
+		ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel",
+					   &bpp);
+		if (ret)
+			return ret;
+
+		fbdev->info.var.bits_per_pixel = bpp;
+
+	} else {
+		if (!fb_find_mode(&fbdev->info.var, &fbdev->info, mode_option,
+				  NULL, 0, &default_mode, 16)) {
+			dev_err(&pdev->dev, "No valid video modes found\n");
+			return -EINVAL;
+		}
 	}
 	ocfb_init_var(fbdev);
 	ocfb_init_fix(fbdev);
-- 
1.7.1


^ permalink raw reply related

* [PATCH] video: fbdev: broadsheetfb.c: fix memory leak on sector_buffer
From: Colin King @ 2014-06-12 10:18 UTC (permalink / raw)
  To: linux-fbdev

From: Colin Ian King <colin.king@canonical.com>

static code analysis from cppcheck reports:

[drivers/video/fbdev/broadsheetfb.c:673]:
  (error) Memory leak: sector_buffer

sector_buffer is not being kfree'd on each call to
broadsheet_spiflash_rewrite_sector(), so free it.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 drivers/video/fbdev/broadsheetfb.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/video/fbdev/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c
index 8556264..235542f 100644
--- a/drivers/video/fbdev/broadsheetfb.c
+++ b/drivers/video/fbdev/broadsheetfb.c
@@ -636,7 +636,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par,
 		err = broadsheet_spiflash_read_range(par, start_sector_addr,
 						data_start_addr, sector_buffer);
 		if (err)
-			return err;
+			goto out;
 	}
 
 	/* now we copy our data into the right place in the sector buffer */
@@ -657,7 +657,7 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par,
 		err = broadsheet_spiflash_read_range(par, tail_start_addr,
 			tail_len, sector_buffer + tail_start_addr);
 		if (err)
-			return err;
+			goto out;
 	}
 
 	/* if we got here we have the full sector that we want to rewrite. */
@@ -665,11 +665,13 @@ static int broadsheet_spiflash_rewrite_sector(struct broadsheetfb_par *par,
 	/* first erase the sector */
 	err = broadsheet_spiflash_erase_sector(par, start_sector_addr);
 	if (err)
-		return err;
+		goto out;
 
 	/* now write it */
 	err = broadsheet_spiflash_write_sector(par, start_sector_addr,
 					sector_buffer, sector_size);
+out:
+	kfree(sector_buffer);
 	return err;
 }
 
-- 
2.0.0


^ permalink raw reply related

* console / fbdev: fbcon support for bits_per_pixel = 1?
From: Stefan Biereigel @ 2014-06-14  9:55 UTC (permalink / raw)
  To: linux-kernel@vger.kernel org; +Cc: linux-fbdev, linux-console, brian

CC: linux-console, linux-fbdev

Hello Kernel Developers,
for a university assignment we are developing a frame buffer driver for a monochrome
display. We succeeded so far in making a simple "RAM frame buffer" module, which is needed
as the basis (we don't have read access to the RAM in the LCD).
We are using the system-default fb_ops (fb_sys_{read,write},
sys_{fillrect,copyarea,imageblit), and all is well when we use bits_per_pixel = 8. When we
map a console to the RAM frame buffer (con2fbmap 1 1), do strg-alt-F1, type some
characters there, we can then 'cat /dev/fb1' and plot the ram contents in Matlab
(reshaping the data to be our display geometry first), where our typed characters and the
console appear.

If we however change bits_per_pixel to 1, and divide line_length by 8 (as it should
represent the line length in bytes), this suddenly stops working: echo and cat to fb1 work
as intended: We change our Matlab-Script to interpret every byte as 8 pixels, bytes
written into /dev/fb1 can be read out correctly. If we however map the console to fb1, no
console output can be seen in RAM - it is (seemingly) filled with garbage.

We're using fbcon as the console driver, and the first frame buffer for me is intelfb. I
see, that the bitblitting-calls for every typed character are depth 1 and have correct
geometry, but the whole bitblitting-builtin seems not to work for bits_per_pixel = 1, i
tried it with a simple test image after the initialisation...

Is this behavior intended or are we triggering a bug here (that no one noticed, because
who in the world uses monochrome framebuffers these days..). I can't see any comments that
monochrome consoles should not work with 1 bit per pixel. See the code below if you spot
some errors (ignore some missing error handling and mediocre style for now, please).

Thank you for any help and input.
Best regards,
Stefan Biereigel

8<--- testfb.c

#include <linux/init.h>
#include <linux/module.h>

#include <linux/fb.h>
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/errno.h>
#include <linux/platform_device.h>

#define DISPLAY_WIDTH	240
#define DISPLAY_HEIGHT	64
#define FB_MEM_SIZE 	(DISPLAY_WIDTH * DISPLAY_HEIGHT)/8

static struct platform_device *testfb_device;

static struct fb_ops fbops = {
	.owner		= THIS_MODULE,
	.fb_fillrect	= sys_fillrect,
	.fb_copyarea	= sys_copyarea,
	.fb_imageblit	= sys_imageblit,
	.fb_read	= fb_sys_read,
	.fb_write	= fb_sys_write,
	.fb_sync	= NULL,
};

static int __init testfb_probe (struct platform_device *pdev) {
	void *fb_mem = NULL;
	struct fb_info *fbinfo = NULL;

	fb_mem = kzalloc(FB_MEM_SIZE, GFP_KERNEL);

	if (!fb_mem) {
		pr_err("testfb: memory allocation for framebuffer failed\n");
		return(-ENOMEM);
	}
	else
		pr_debug("testfb: allocated framebuffer memory successfully\n");

	fbinfo = framebuffer_alloc(0, &pdev->dev);

	if (!fbinfo) {
		pr_err("testfb: framebuffer_alloc() failed\n");
		kfree(fb_mem);
		return(-1);
	}
	else
		pr_debug("testfb: framebuffer_alloc was successful\n");

	fbinfo->fix.smem_start = (unsigned long) fb_mem;
	fbinfo->screen_base = (char __iomem *) fb_mem;
	fbinfo->fix.smem_len = FB_MEM_SIZE;
	fbinfo->fbops = &fbops;

	fbinfo->node			= 0;				/* ?int */
	fbinfo->device			= &pdev->dev;
	fbinfo->flags			= FBINFO_DEFAULT;		/*  */
	fbinfo->var.xres		= DISPLAY_WIDTH;		/* visible resolution */
	fbinfo->var.yres		= DISPLAY_HEIGHT;		/* visible resolution */
	fbinfo->var.xres_virtual	= DISPLAY_WIDTH;		/* virtual resolution */
	fbinfo->var.yres_virtual	= DISPLAY_HEIGHT;		/* virtual resolution */
	fbinfo->var.bits_per_pixel	= 1;				/* bits per pixel */
	fbinfo->var.activate		= FB_ACTIVATE_NOW;		/* set values immediately (or vbl) */
	fbinfo->var.sync		= 0;				/* ?see FB_SYNC_* */
	fbinfo->var.vmode		= FB_VMODE_NONINTERLACED;	/* non interlaced, see FB_VMODE_* */
	fbinfo->var.left_margin 	= 0;
	fbinfo->var.right_margin 	= 0;
	fbinfo->var.upper_margin 	= 0;
	fbinfo->var.lower_margin 	= 0;
	fbinfo->var.red.offset 		= 0;
	fbinfo->var.red.length 		= fbinfo->var.bits_per_pixel;
	fbinfo->var.green 		= fbinfo->var.red;
	fbinfo->var.blue  		= fbinfo->var.red;
	fbinfo->var.grayscale		= 1;
	strcpy(fbinfo->fix.id, "testfb");				/* identifier, 16 byte */
	fbinfo->fix.type		= FB_TYPE_PACKED_PIXELS;	/* pack pixels to avoid overhead */
	fbinfo->fix.visual		= FB_VISUAL_MONO10;		/* Monochr. 1=Black 0=White */
	fbinfo->fix.line_length		= DISPLAY_WIDTH/8;		/* length of a line in bytes */
	fbinfo->fix.accel		= FB_ACCEL_NONE;		/* no hardware accelerator */
	fbinfo->fix.xpanstep 		= 0;
	fbinfo->fix.ypanstep		= 0;
	fbinfo->fix.ywrapstep 		= 0;

	if (register_framebuffer(fbinfo) < 0) {
		pr_err("testfb: registering framebuffer failed\n");
		kfree((void *) fbinfo->fix.smem_start);
		framebuffer_release(fbinfo);
		return(-1);
	}
	else
		pr_debug("testfb: registered framebuffer\n");

	platform_set_drvdata(pdev, fbinfo);

	return 0;
}

static int testfb_remove(struct platform_device *pdev) {
	struct fb_info *fbinfo = NULL;

	fbinfo = platform_get_drvdata(pdev);

	if (!fbinfo) {
		pr_err("testfb: unable to get fbinfo from pdev\n");
		return(-1);
	}

	if (unregister_framebuffer(fbinfo) < 0)
		pr_err("testfb: unregistering framebuffer failed\n");
	else
		pr_debug("testfb: unregistered framebuffer\n");

	kfree((void *) fbinfo->fix.smem_start);

	framebuffer_release(fbinfo);

	return 0;
}

static struct platform_driver testfb_driver = {
	.probe = testfb_probe,
	.remove = testfb_remove,
	.driver = {
		.name = "testfb",
	},
};

static int __init testfb_init(void)
{
	int ret;

	ret = platform_driver_register(&testfb_driver);
	if (!ret) {
		testfb_device = platform_device_register_simple("testfb", 0,
								NULL, 0);

		if (IS_ERR(testfb_device)) {
			platform_driver_unregister(&testfb_driver);
			ret = PTR_ERR(testfb_device);
		} else {
			pr_info("testfb: platform_device registered\n");
		}

	}

	pr_info("testfb: module loaded\n");
	
	return 0;
}

static void __exit testfb_exit(void)
{
	platform_device_unregister(testfb_device);
	platform_driver_unregister(&testfb_driver);

	pr_info("testfb: module unloaded\n");
}

module_init(testfb_init);
module_exit(testfb_exit);

MODULE_LICENSE("GPL v2");
MODULE_ALIAS("testfb");
MODULE_AUTHOR("Brian Fonfara");
MODULE_DESCRIPTION("Ein Modul zum Test der Linux Framebuffer-Programmierung");
MODULE_DESCRIPTION("version 0.1");

^ permalink raw reply

* Re: console / fbdev: fbcon support for bits_per_pixel = 1?
From: Bruno Prémont @ 2014-06-14 12:35 UTC (permalink / raw)
  To: Stefan Biereigel; +Cc: linux-fbdev, linux-kernel, linux-console, brian
In-Reply-To: <539C1C1F.5060904@biereigel.de>

Hi Stefan,

On Sat, 14 June 2014 Stefan Biereigel <stefan@biereigel.de> wrote:
> CC: linux-console, linux-fbdev
> 
> Hello Kernel Developers,
> for a university assignment we are developing a frame buffer driver for a monochrome
> display. We succeeded so far in making a simple "RAM frame buffer" module, which is needed
> as the basis (we don't have read access to the RAM in the LCD).
> We are using the system-default fb_ops (fb_sys_{read,write},
> sys_{fillrect,copyarea,imageblit), and all is well when we use bits_per_pixel = 8. When we
> map a console to the RAM frame buffer (con2fbmap 1 1), do strg-alt-F1, type some
> characters there, we can then 'cat /dev/fb1' and plot the ram contents in Matlab
> (reshaping the data to be our display geometry first), where our typed characters and the
> console appear.
> 
> If we however change bits_per_pixel to 1, and divide line_length by 8 (as it should
> represent the line length in bytes), this suddenly stops working: echo and cat to fb1 work
> as intended: We change our Matlab-Script to interpret every byte as 8 pixels, bytes
> written into /dev/fb1 can be read out correctly. If we however map the console to fb1, no
> console output can be seen in RAM - it is (seemingly) filled with garbage.
> 
> We're using fbcon as the console driver, and the first frame buffer for me is intelfb. I
> see, that the bitblitting-calls for every typed character are depth 1 and have correct
> geometry, but the whole bitblitting-builtin seems not to work for bits_per_pixel = 1, i
> tried it with a simple test image after the initialisation...
> 
> Is this behavior intended or are we triggering a bug here (that no one noticed, because
> who in the world uses monochrome framebuffers these days..). I can't see any comments that
> monochrome consoles should not work with 1 bit per pixel. See the code below if you spot
> some errors (ignore some missing error handling and mediocre style for now, please).

fbcon on 1bpp frambuffer worked for me with picoLCD (though I have found no userspace
framebuffer application willing to operate at 1bpp).
Thus I allow for 1bpp or 8bpp and convert 8bpp to 1bpp for the picolcd. As for your case,
picoLCD is "write-only" monochrome LCD backed by in-RAM shadow framebuffer.

(see drivers/hid/hid-picolcd_fb.c)

Bruno

> Thank you for any help and input.
> Best regards,
> Stefan Biereigel
> 
> 8<--- testfb.c
> 
> #include <linux/init.h>
> #include <linux/module.h>
> 
> #include <linux/fb.h>
> #include <linux/slab.h>
> #include <linux/wait.h>
> #include <linux/errno.h>
> #include <linux/platform_device.h>
> 
> #define DISPLAY_WIDTH	240
> #define DISPLAY_HEIGHT	64
> #define FB_MEM_SIZE 	(DISPLAY_WIDTH * DISPLAY_HEIGHT)/8
> 
> static struct platform_device *testfb_device;
> 
> static struct fb_ops fbops = {
> 	.owner		= THIS_MODULE,
> 	.fb_fillrect	= sys_fillrect,
> 	.fb_copyarea	= sys_copyarea,
> 	.fb_imageblit	= sys_imageblit,
> 	.fb_read	= fb_sys_read,
> 	.fb_write	= fb_sys_write,
> 	.fb_sync	= NULL,
> };
> 
> static int __init testfb_probe (struct platform_device *pdev) {
> 	void *fb_mem = NULL;
> 	struct fb_info *fbinfo = NULL;
> 
> 	fb_mem = kzalloc(FB_MEM_SIZE, GFP_KERNEL);
> 
> 	if (!fb_mem) {
> 		pr_err("testfb: memory allocation for framebuffer failed\n");
> 		return(-ENOMEM);
> 	}
> 	else
> 		pr_debug("testfb: allocated framebuffer memory successfully\n");
> 
> 	fbinfo = framebuffer_alloc(0, &pdev->dev);
> 
> 	if (!fbinfo) {
> 		pr_err("testfb: framebuffer_alloc() failed\n");
> 		kfree(fb_mem);
> 		return(-1);
> 	}
> 	else
> 		pr_debug("testfb: framebuffer_alloc was successful\n");
> 
> 	fbinfo->fix.smem_start = (unsigned long) fb_mem;
> 	fbinfo->screen_base = (char __iomem *) fb_mem;
> 	fbinfo->fix.smem_len = FB_MEM_SIZE;
> 	fbinfo->fbops = &fbops;
> 
> 	fbinfo->node			= 0;				/* ?int */
> 	fbinfo->device			= &pdev->dev;
> 	fbinfo->flags			= FBINFO_DEFAULT;		/*  */
> 	fbinfo->var.xres		= DISPLAY_WIDTH;		/* visible resolution */
> 	fbinfo->var.yres		= DISPLAY_HEIGHT;		/* visible resolution */
> 	fbinfo->var.xres_virtual	= DISPLAY_WIDTH;		/* virtual resolution */
> 	fbinfo->var.yres_virtual	= DISPLAY_HEIGHT;		/* virtual resolution */
> 	fbinfo->var.bits_per_pixel	= 1;				/* bits per pixel */
> 	fbinfo->var.activate		= FB_ACTIVATE_NOW;		/* set values immediately (or vbl) */
> 	fbinfo->var.sync		= 0;				/* ?see FB_SYNC_* */
> 	fbinfo->var.vmode		= FB_VMODE_NONINTERLACED;	/* non interlaced, see FB_VMODE_* */
> 	fbinfo->var.left_margin 	= 0;
> 	fbinfo->var.right_margin 	= 0;
> 	fbinfo->var.upper_margin 	= 0;
> 	fbinfo->var.lower_margin 	= 0;
> 	fbinfo->var.red.offset 		= 0;
> 	fbinfo->var.red.length 		= fbinfo->var.bits_per_pixel;
> 	fbinfo->var.green 		= fbinfo->var.red;
> 	fbinfo->var.blue  		= fbinfo->var.red;
> 	fbinfo->var.grayscale		= 1;
> 	strcpy(fbinfo->fix.id, "testfb");				/* identifier, 16 byte */
> 	fbinfo->fix.type		= FB_TYPE_PACKED_PIXELS;	/* pack pixels to avoid overhead */
> 	fbinfo->fix.visual		= FB_VISUAL_MONO10;		/* Monochr. 1=Black 0=White */
> 	fbinfo->fix.line_length		= DISPLAY_WIDTH/8;		/* length of a line in bytes */
> 	fbinfo->fix.accel		= FB_ACCEL_NONE;		/* no hardware accelerator */
> 	fbinfo->fix.xpanstep 		= 0;
> 	fbinfo->fix.ypanstep		= 0;
> 	fbinfo->fix.ywrapstep 		= 0;
> 
> 	if (register_framebuffer(fbinfo) < 0) {
> 		pr_err("testfb: registering framebuffer failed\n");
> 		kfree((void *) fbinfo->fix.smem_start);
> 		framebuffer_release(fbinfo);
> 		return(-1);
> 	}
> 	else
> 		pr_debug("testfb: registered framebuffer\n");
> 
> 	platform_set_drvdata(pdev, fbinfo);
> 
> 	return 0;
> }
> 
> static int testfb_remove(struct platform_device *pdev) {
> 	struct fb_info *fbinfo = NULL;
> 
> 	fbinfo = platform_get_drvdata(pdev);
> 
> 	if (!fbinfo) {
> 		pr_err("testfb: unable to get fbinfo from pdev\n");
> 		return(-1);
> 	}
> 
> 	if (unregister_framebuffer(fbinfo) < 0)
> 		pr_err("testfb: unregistering framebuffer failed\n");
> 	else
> 		pr_debug("testfb: unregistered framebuffer\n");
> 
> 	kfree((void *) fbinfo->fix.smem_start);
> 
> 	framebuffer_release(fbinfo);
> 
> 	return 0;
> }
> 
> static struct platform_driver testfb_driver = {
> 	.probe = testfb_probe,
> 	.remove = testfb_remove,
> 	.driver = {
> 		.name = "testfb",
> 	},
> };
> 
> static int __init testfb_init(void)
> {
> 	int ret;
> 
> 	ret = platform_driver_register(&testfb_driver);
> 	if (!ret) {
> 		testfb_device = platform_device_register_simple("testfb", 0,
> 								NULL, 0);
> 
> 		if (IS_ERR(testfb_device)) {
> 			platform_driver_unregister(&testfb_driver);
> 			ret = PTR_ERR(testfb_device);
> 		} else {
> 			pr_info("testfb: platform_device registered\n");
> 		}
> 
> 	}
> 
> 	pr_info("testfb: module loaded\n");
> 	
> 	return 0;
> }
> 
> static void __exit testfb_exit(void)
> {
> 	platform_device_unregister(testfb_device);
> 	platform_driver_unregister(&testfb_driver);
> 
> 	pr_info("testfb: module unloaded\n");
> }
> 
> module_init(testfb_init);
> module_exit(testfb_exit);
> 
> MODULE_LICENSE("GPL v2");
> MODULE_ALIAS("testfb");
> MODULE_AUTHOR("Brian Fonfara");
> MODULE_DESCRIPTION("Ein Modul zum Test der Linux Framebuffer-Programmierung");
> MODULE_DESCRIPTION("version 0.1");
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH RESEND v2] console: Add persistent scrollback buffers for all VGA consoles
From: Manuel Schölling @ 2014-06-14 23:15 UTC (permalink / raw)
  To: plagnioj
  Cc: tomi.valkeinen, geert, broonie, rdunlap, hans.verkuil,
	dh.herrmann, tiwai, gregkh, airlied, mtosatti, linux-fbdev,
	linux-kernel, Manuel Schölling
In-Reply-To: <1401533856-4067-1-git-send-email-manuel.schoelling@gmx.de>

Add a scrollback buffers for each VGA console. The benefit is that
the scrollback history is not flushed when switching between consoles
but is persistent.
The buffers are allocated on demand when a new console is opened.

Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
---
 drivers/video/console/Kconfig  |   19 ++++-
 drivers/video/console/vgacon.c |  159 +++++++++++++++++++++++++++-------------
 2 files changed, 124 insertions(+), 54 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index fe1cd01..05fdc2c 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -43,9 +43,22 @@ config VGACON_SOFT_SCROLLBACK_SIZE
        range 1 1024
        default "64"
        help
-         Enter the amount of System RAM to allocate for the scrollback
-	 buffer.  Each 64KB will give you approximately 16 80x25
-	 screenfuls of scrollback buffer
+	  Enter the amount of System RAM to allocate for scrollback
+	  buffers of VGA consoles. Each 64KB will give you approximately
+	  16 80x25 screenfuls of scrollback buffer.
+
+config VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
+	bool "Persistent Scrollback History for each console"
+	depends on VGACON_SOFT_SCROLLBACK
+	default y
+	help
+	  Say Y here if for each VGA console a scrollback buffer should
+	  be allocated. The scrollback history will persist when switching
+	  between consoles. If you say N here, scrollback is only supported
+	  for the active VGA console and scrollback history will be flushed
+	  when switching between consoles.
+
+	  If you use a RAM-constrained system, say N here.
 
 config MDA_CONSOLE
 	depends on !M68K && !PARISC && ISA
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 9d8feac..652131d 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -181,70 +181,126 @@ static inline void vga_set_mem_top(struct vc_data *c)
 
 #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
 /* software scrollback */
-static void *vgacon_scrollback;
-static int vgacon_scrollback_tail;
-static int vgacon_scrollback_size;
-static int vgacon_scrollback_rows;
-static int vgacon_scrollback_cnt;
-static int vgacon_scrollback_cur;
-static int vgacon_scrollback_save;
-static int vgacon_scrollback_restore;
-
-static void vgacon_scrollback_init(int pitch)
+struct vgacon_scrollback_info {
+	void *data;
+	int tail;
+	int size;
+	int rows;
+	int cnt;
+	int cur;
+	int save;
+	int restore;
+};
+static struct vgacon_scrollback_info *vgacon_scrollback_cur;
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
+static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
+#else
+static struct vgacon_scrollback_info vgacon_scrollbacks[1];
+#endif
+
+static void vgacon_scrollback_reset(size_t reset_size)
 {
-	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
-
-	if (vgacon_scrollback) {
-		vgacon_scrollback_cnt  = 0;
-		vgacon_scrollback_tail = 0;
-		vgacon_scrollback_cur  = 0;
-		vgacon_scrollback_rows = rows - 1;
-		vgacon_scrollback_size = rows * pitch;
+	if (vgacon_scrollback_cur->data && reset_size > 0)
+		memset(vgacon_scrollback_cur->data, 0, reset_size);
+
+	vgacon_scrollback_cur->cnt  = 0;
+	vgacon_scrollback_cur->tail = 0;
+	vgacon_scrollback_cur->cur  = 0;
+}
+
+static void vgacon_scrollback_init(int vc_num)
+{
+	int pitch = vga_video_num_columns * 2;
+	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+	int rows = size/pitch;
+	void *data;
+
+	data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
+	if (data) {
+		vgacon_scrollbacks[vc_num].data = data;
+		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+
+		vgacon_scrollback_cur->rows = rows - 1;
+		vgacon_scrollback_cur->size = rows * pitch;
+
+		vgacon_scrollback_reset(0);
+	} else {
+		pr_warn("VGAcon: failed to allocate memory for scrollback. Trying to reuse previous buffer.\n");
+		/* leave vgacon_scrollback_cur untouched
+		   but reset its content */
+		vgacon_scrollback_reset(size);
 	}
 }
 
+static void vgacon_switch_scrollback(int vc_num)
+{
+#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
+	if (!vgacon_scrollbacks[vc_num].data)
+		vgacon_scrollback_init(vc_num);
+	else
+		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
+#else
+	vc_num = 0;
+
+	if (!vgacon_scrollbacks[vc_num].data)
+		vgacon_scrollback_init(vc_num);
+	else {
+		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
+
+		vgacon_scrollback_reset(size);
+	}
+#endif
+}
+
 static void vgacon_scrollback_startup(void)
 {
-	vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
-	vgacon_scrollback_init(vga_video_num_columns * 2);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vgacon_scrollbacks); ++i)
+		vgacon_scrollbacks[i].data = NULL;
+
+	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
+	vgacon_scrollback_init(0);
 }
 
 static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
 {
 	void *p;
 
-	if (!vgacon_scrollback_size || c->vc_num != fg_console)
+	if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size)
 		return;
 
 	p = (void *) (c->vc_origin + t * c->vc_size_row);
 
 	while (count--) {
-		scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
+		scr_memcpyw(vgacon_scrollback_cur->data +
+			    vgacon_scrollback_cur->tail,
 			    p, c->vc_size_row);
-		vgacon_scrollback_cnt++;
+
+		vgacon_scrollback_cur->cnt++;
 		p += c->vc_size_row;
-		vgacon_scrollback_tail += c->vc_size_row;
+		vgacon_scrollback_cur->tail += c->vc_size_row;
 
-		if (vgacon_scrollback_tail >= vgacon_scrollback_size)
-			vgacon_scrollback_tail = 0;
+		if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
+			vgacon_scrollback_cur->tail = 0;
 
-		if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
-			vgacon_scrollback_cnt = vgacon_scrollback_rows;
+		if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
+			vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
 
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
-	vgacon_scrollback_save = 0;
+	vgacon_scrollback_cur->save = 0;
 
-	if (!vga_is_gfx && !vgacon_scrollback_restore) {
+	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 			    vga_vram_size : c->vc_screenbuf_size);
-		vgacon_scrollback_restore = 1;
-		vgacon_scrollback_cur = vgacon_scrollback_cnt;
+		vgacon_scrollback_cur->restore = 1;
+		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
 	}
 }
 
@@ -258,41 +314,41 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
 		return 1;
 	}
 
-	if (!vgacon_scrollback)
+	if (!vgacon_scrollback_cur->data)
 		return 1;
 
-	if (!vgacon_scrollback_save) {
+	if (!vgacon_scrollback_cur->save) {
 		vgacon_cursor(c, CM_ERASE);
 		vgacon_save_screen(c);
-		vgacon_scrollback_save = 1;
+		vgacon_scrollback_cur->save = 1;
 	}
 
-	vgacon_scrollback_restore = 0;
-	start = vgacon_scrollback_cur + lines;
+	vgacon_scrollback_cur->restore = 0;
+	start = vgacon_scrollback_cur->cur + lines;
 	end = start + abs(lines);
 
 	if (start < 0)
 		start = 0;
 
-	if (start > vgacon_scrollback_cnt)
-		start = vgacon_scrollback_cnt;
+	if (start > vgacon_scrollback_cur->cnt)
+		start = vgacon_scrollback_cur->cnt;
 
 	if (end < 0)
 		end = 0;
 
-	if (end > vgacon_scrollback_cnt)
-		end = vgacon_scrollback_cnt;
+	if (end > vgacon_scrollback_cur->cnt)
+		end = vgacon_scrollback_cur->cnt;
 
-	vgacon_scrollback_cur = start;
+	vgacon_scrollback_cur->cur = start;
 	count = end - start;
-	soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
-					 c->vc_size_row);
+	soff = vgacon_scrollback_cur->tail -
+		((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
 	soff -= count * c->vc_size_row;
 
 	if (soff < 0)
-		soff += vgacon_scrollback_size;
+		soff += vgacon_scrollback_cur->size;
 
-	count = vgacon_scrollback_cnt - start;
+	count = vgacon_scrollback_cur->cnt - start;
 
 	if (count > c->vc_rows)
 		count = c->vc_rows;
@@ -306,13 +362,13 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
 
 		count *= c->vc_size_row;
 		/* how much memory to end of buffer left? */
-		copysize = min(count, vgacon_scrollback_size - soff);
-		scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+		copysize = min(count, vgacon_scrollback_cur->size - soff);
+		scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
 		d += copysize;
 		count -= copysize;
 
 		if (count) {
-			scr_memcpyw(d, vgacon_scrollback, count);
+			scr_memcpyw(d, vgacon_scrollback_cur->data, count);
 			d += count;
 		}
 
@@ -327,6 +383,7 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
 #define vgacon_scrollback_startup(...) do { } while (0)
 #define vgacon_scrollback_init(...)    do { } while (0)
 #define vgacon_scrollback_update(...)  do { } while (0)
+#define vgacon_switch_scrollback(...)  do { } while (0)
 
 static void vgacon_restore_screen(struct vc_data *c)
 {
@@ -842,7 +899,7 @@ static int vgacon_switch(struct vc_data *c)
 			vgacon_doresize(c, c->vc_cols, c->vc_rows);
 	}
 
-	vgacon_scrollback_init(c->vc_size_row);
+	vgacon_switch_scrollback(c->vc_num);
 	return 0;		/* Redrawing not needed */
 }
 
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH RESEND v2] console: Add persistent scrollback buffers for all VGA consoles
From: Manuel Schoelling @ 2014-06-14 23:24 UTC (permalink / raw)
  To: plagnioj
  Cc: tomi.valkeinen, geert, broonie, rdunlap, hans.verkuil,
	dh.herrmann, tiwai, gregkh, airlied, mtosatti, linux-fbdev,
	linux-kernel
In-Reply-To: <1402787715-26007-1-git-send-email-manuel.schoelling@gmx.de>

This version reuses an "old" scrollback buffer of the previous console
if memory allocation fails.

However, the issue of clearing the console using the 'clear_console'
commnad [1,2] is still unsolved. I'd prefer implementing it using a
ioctl() call but it's open for discussion ;)

[1] https://sources.debian.net/src/bash/4.2%
2Bdfsg-0.1/debian/clear_console.c
[2] http://manpages.debian.org/cgi-bin/man.cgi?query=clear_console

On So, 2014-06-15 at 01:15 +0200, Manuel Schölling wrote:
> Add a scrollback buffers for each VGA console. The benefit is that
> the scrollback history is not flushed when switching between consoles
> but is persistent.
> The buffers are allocated on demand when a new console is opened.
> 
> Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de>
> ---
>  drivers/video/console/Kconfig  |   19 ++++-
>  drivers/video/console/vgacon.c |  159 +++++++++++++++++++++++++++-------------
>  2 files changed, 124 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
> index fe1cd01..05fdc2c 100644
> --- a/drivers/video/console/Kconfig
> +++ b/drivers/video/console/Kconfig
> @@ -43,9 +43,22 @@ config VGACON_SOFT_SCROLLBACK_SIZE
>         range 1 1024
>         default "64"
>         help
> -         Enter the amount of System RAM to allocate for the scrollback
> -	 buffer.  Each 64KB will give you approximately 16 80x25
> -	 screenfuls of scrollback buffer
> +	  Enter the amount of System RAM to allocate for scrollback
> +	  buffers of VGA consoles. Each 64KB will give you approximately
> +	  16 80x25 screenfuls of scrollback buffer.
> +
> +config VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
> +	bool "Persistent Scrollback History for each console"
> +	depends on VGACON_SOFT_SCROLLBACK
> +	default y
> +	help
> +	  Say Y here if for each VGA console a scrollback buffer should
> +	  be allocated. The scrollback history will persist when switching
> +	  between consoles. If you say N here, scrollback is only supported
> +	  for the active VGA console and scrollback history will be flushed
> +	  when switching between consoles.
> +
> +	  If you use a RAM-constrained system, say N here.
>  
>  config MDA_CONSOLE
>  	depends on !M68K && !PARISC && ISA
> diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
> index 9d8feac..652131d 100644
> --- a/drivers/video/console/vgacon.c
> +++ b/drivers/video/console/vgacon.c
> @@ -181,70 +181,126 @@ static inline void vga_set_mem_top(struct vc_data *c)
>  
>  #ifdef CONFIG_VGACON_SOFT_SCROLLBACK
>  /* software scrollback */
> -static void *vgacon_scrollback;
> -static int vgacon_scrollback_tail;
> -static int vgacon_scrollback_size;
> -static int vgacon_scrollback_rows;
> -static int vgacon_scrollback_cnt;
> -static int vgacon_scrollback_cur;
> -static int vgacon_scrollback_save;
> -static int vgacon_scrollback_restore;
> -
> -static void vgacon_scrollback_init(int pitch)
> +struct vgacon_scrollback_info {
> +	void *data;
> +	int tail;
> +	int size;
> +	int rows;
> +	int cnt;
> +	int cur;
> +	int save;
> +	int restore;
> +};
> +static struct vgacon_scrollback_info *vgacon_scrollback_cur;
> +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
> +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
> +#else
> +static struct vgacon_scrollback_info vgacon_scrollbacks[1];
> +#endif
> +
> +static void vgacon_scrollback_reset(size_t reset_size)
>  {
> -	int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch;
> -
> -	if (vgacon_scrollback) {
> -		vgacon_scrollback_cnt  = 0;
> -		vgacon_scrollback_tail = 0;
> -		vgacon_scrollback_cur  = 0;
> -		vgacon_scrollback_rows = rows - 1;
> -		vgacon_scrollback_size = rows * pitch;
> +	if (vgacon_scrollback_cur->data && reset_size > 0)
> +		memset(vgacon_scrollback_cur->data, 0, reset_size);
> +
> +	vgacon_scrollback_cur->cnt  = 0;
> +	vgacon_scrollback_cur->tail = 0;
> +	vgacon_scrollback_cur->cur  = 0;
> +}
> +
> +static void vgacon_scrollback_init(int vc_num)
> +{
> +	int pitch = vga_video_num_columns * 2;
> +	size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
> +	int rows = size/pitch;
> +	void *data;
> +
> +	data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
> +	if (data) {
> +		vgacon_scrollbacks[vc_num].data = data;
> +		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
> +
> +		vgacon_scrollback_cur->rows = rows - 1;
> +		vgacon_scrollback_cur->size = rows * pitch;
> +
> +		vgacon_scrollback_reset(0);
> +	} else {
> +		pr_warn("VGAcon: failed to allocate memory for scrollback. Trying to reuse previous buffer.\n");
> +		/* leave vgacon_scrollback_cur untouched
> +		   but reset its content */
> +		vgacon_scrollback_reset(size);
>  	}
>  }
>  
> +static void vgacon_switch_scrollback(int vc_num)
> +{
> +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE
> +	if (!vgacon_scrollbacks[vc_num].data)
> +		vgacon_scrollback_init(vc_num);
> +	else
> +		vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num];
> +#else
> +	vc_num = 0;
> +
> +	if (!vgacon_scrollbacks[vc_num].data)
> +		vgacon_scrollback_init(vc_num);
> +	else {
> +		size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
> +
> +		vgacon_scrollback_reset(size);
> +	}
> +#endif
> +}
> +
>  static void vgacon_scrollback_startup(void)
>  {
> -	vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
> -	vgacon_scrollback_init(vga_video_num_columns * 2);
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(vgacon_scrollbacks); ++i)
> +		vgacon_scrollbacks[i].data = NULL;
> +
> +	vgacon_scrollback_cur = &vgacon_scrollbacks[0];
> +	vgacon_scrollback_init(0);
>  }
>  
>  static void vgacon_scrollback_update(struct vc_data *c, int t, int count)
>  {
>  	void *p;
>  
> -	if (!vgacon_scrollback_size || c->vc_num != fg_console)
> +	if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size)
>  		return;
>  
>  	p = (void *) (c->vc_origin + t * c->vc_size_row);
>  
>  	while (count--) {
> -		scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail,
> +		scr_memcpyw(vgacon_scrollback_cur->data +
> +			    vgacon_scrollback_cur->tail,
>  			    p, c->vc_size_row);
> -		vgacon_scrollback_cnt++;
> +
> +		vgacon_scrollback_cur->cnt++;
>  		p += c->vc_size_row;
> -		vgacon_scrollback_tail += c->vc_size_row;
> +		vgacon_scrollback_cur->tail += c->vc_size_row;
>  
> -		if (vgacon_scrollback_tail >= vgacon_scrollback_size)
> -			vgacon_scrollback_tail = 0;
> +		if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
> +			vgacon_scrollback_cur->tail = 0;
>  
> -		if (vgacon_scrollback_cnt > vgacon_scrollback_rows)
> -			vgacon_scrollback_cnt = vgacon_scrollback_rows;
> +		if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
> +			vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
>  
> -		vgacon_scrollback_cur = vgacon_scrollback_cnt;
> +		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
>  	}
>  }
>  
>  static void vgacon_restore_screen(struct vc_data *c)
>  {
> -	vgacon_scrollback_save = 0;
> +	vgacon_scrollback_cur->save = 0;
>  
> -	if (!vga_is_gfx && !vgacon_scrollback_restore) {
> +	if (!vga_is_gfx && !vgacon_scrollback_cur->restore) {
>  		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
>  			    c->vc_screenbuf_size > vga_vram_size ?
>  			    vga_vram_size : c->vc_screenbuf_size);
> -		vgacon_scrollback_restore = 1;
> -		vgacon_scrollback_cur = vgacon_scrollback_cnt;
> +		vgacon_scrollback_cur->restore = 1;
> +		vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
>  	}
>  }
>  
> @@ -258,41 +314,41 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
>  		return 1;
>  	}
>  
> -	if (!vgacon_scrollback)
> +	if (!vgacon_scrollback_cur->data)
>  		return 1;
>  
> -	if (!vgacon_scrollback_save) {
> +	if (!vgacon_scrollback_cur->save) {
>  		vgacon_cursor(c, CM_ERASE);
>  		vgacon_save_screen(c);
> -		vgacon_scrollback_save = 1;
> +		vgacon_scrollback_cur->save = 1;
>  	}
>  
> -	vgacon_scrollback_restore = 0;
> -	start = vgacon_scrollback_cur + lines;
> +	vgacon_scrollback_cur->restore = 0;
> +	start = vgacon_scrollback_cur->cur + lines;
>  	end = start + abs(lines);
>  
>  	if (start < 0)
>  		start = 0;
>  
> -	if (start > vgacon_scrollback_cnt)
> -		start = vgacon_scrollback_cnt;
> +	if (start > vgacon_scrollback_cur->cnt)
> +		start = vgacon_scrollback_cur->cnt;
>  
>  	if (end < 0)
>  		end = 0;
>  
> -	if (end > vgacon_scrollback_cnt)
> -		end = vgacon_scrollback_cnt;
> +	if (end > vgacon_scrollback_cur->cnt)
> +		end = vgacon_scrollback_cur->cnt;
>  
> -	vgacon_scrollback_cur = start;
> +	vgacon_scrollback_cur->cur = start;
>  	count = end - start;
> -	soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) *
> -					 c->vc_size_row);
> +	soff = vgacon_scrollback_cur->tail -
> +		((vgacon_scrollback_cur->cnt - end) * c->vc_size_row);
>  	soff -= count * c->vc_size_row;
>  
>  	if (soff < 0)
> -		soff += vgacon_scrollback_size;
> +		soff += vgacon_scrollback_cur->size;
>  
> -	count = vgacon_scrollback_cnt - start;
> +	count = vgacon_scrollback_cur->cnt - start;
>  
>  	if (count > c->vc_rows)
>  		count = c->vc_rows;
> @@ -306,13 +362,13 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
>  
>  		count *= c->vc_size_row;
>  		/* how much memory to end of buffer left? */
> -		copysize = min(count, vgacon_scrollback_size - soff);
> -		scr_memcpyw(d, vgacon_scrollback + soff, copysize);
> +		copysize = min(count, vgacon_scrollback_cur->size - soff);
> +		scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize);
>  		d += copysize;
>  		count -= copysize;
>  
>  		if (count) {
> -			scr_memcpyw(d, vgacon_scrollback, count);
> +			scr_memcpyw(d, vgacon_scrollback_cur->data, count);
>  			d += count;
>  		}
>  
> @@ -327,6 +383,7 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
>  #define vgacon_scrollback_startup(...) do { } while (0)
>  #define vgacon_scrollback_init(...)    do { } while (0)
>  #define vgacon_scrollback_update(...)  do { } while (0)
> +#define vgacon_switch_scrollback(...)  do { } while (0)
>  
>  static void vgacon_restore_screen(struct vc_data *c)
>  {
> @@ -842,7 +899,7 @@ static int vgacon_switch(struct vc_data *c)
>  			vgacon_doresize(c, c->vc_cols, c->vc_rows);
>  	}
>  
> -	vgacon_scrollback_init(c->vc_size_row);
> +	vgacon_switch_scrollback(c->vc_num);
>  	return 0;		/* Redrawing not needed */
>  }
>  



^ permalink raw reply

* Re: console / fbdev: fbcon support for bits_per_pixel = 1?
From: Stefan Biereigel @ 2014-06-15  7:47 UTC (permalink / raw)
  To: Bruno Prémont, Stefan Biereigel
  Cc: linux-fbdev, linux-kernel, linux-console, brian
In-Reply-To: <20140614143550.59367463@neptune.home>

Hello Bruno,

are you sure that fbcon really uses the 1bpp mode and that it works correctly? I tried to
match all var-settings to yours, and 1bpp support still seems broken. Well, a workaround
would be doing it like you are: using 8bpp shadow memory and translating it to packed
pixels (8px per byte) when doing LCD updates. I guess, for now that will be the way to go.
I'll be there to investigate further if needed.

Thank you,
Stefan

Am 14.06.2014 14:35, schrieb Bruno Prémont:
> Hi Stefan,
> 
> On Sat, 14 June 2014 Stefan Biereigel <stefan@biereigel.de> wrote:
>> CC: linux-console, linux-fbdev
>>
>> Hello Kernel Developers,
>> for a university assignment we are developing a frame buffer driver for a monochrome
>> display. We succeeded so far in making a simple "RAM frame buffer" module, which is needed
>> as the basis (we don't have read access to the RAM in the LCD).
>> We are using the system-default fb_ops (fb_sys_{read,write},
>> sys_{fillrect,copyarea,imageblit), and all is well when we use bits_per_pixel = 8. When we
>> map a console to the RAM frame buffer (con2fbmap 1 1), do strg-alt-F1, type some
>> characters there, we can then 'cat /dev/fb1' and plot the ram contents in Matlab
>> (reshaping the data to be our display geometry first), where our typed characters and the
>> console appear.
>>
>> If we however change bits_per_pixel to 1, and divide line_length by 8 (as it should
>> represent the line length in bytes), this suddenly stops working: echo and cat to fb1 work
>> as intended: We change our Matlab-Script to interpret every byte as 8 pixels, bytes
>> written into /dev/fb1 can be read out correctly. If we however map the console to fb1, no
>> console output can be seen in RAM - it is (seemingly) filled with garbage.
>>
>> We're using fbcon as the console driver, and the first frame buffer for me is intelfb. I
>> see, that the bitblitting-calls for every typed character are depth 1 and have correct
>> geometry, but the whole bitblitting-builtin seems not to work for bits_per_pixel = 1, i
>> tried it with a simple test image after the initialisation...
>>
>> Is this behavior intended or are we triggering a bug here (that no one noticed, because
>> who in the world uses monochrome framebuffers these days..). I can't see any comments that
>> monochrome consoles should not work with 1 bit per pixel. See the code below if you spot
>> some errors (ignore some missing error handling and mediocre style for now, please).
> 
> fbcon on 1bpp frambuffer worked for me with picoLCD (though I have found no userspace
> framebuffer application willing to operate at 1bpp).
> Thus I allow for 1bpp or 8bpp and convert 8bpp to 1bpp for the picolcd. As for your case,
> picoLCD is "write-only" monochrome LCD backed by in-RAM shadow framebuffer.
> 
> (see drivers/hid/hid-picolcd_fb.c)
> 
> Bruno
> 
>> Thank you for any help and input.
>> Best regards,
>> Stefan Biereigel
>>
>> 8<--- testfb.c
>>
>> #include <linux/init.h>
>> #include <linux/module.h>
>>
>> #include <linux/fb.h>
>> #include <linux/slab.h>
>> #include <linux/wait.h>
>> #include <linux/errno.h>
>> #include <linux/platform_device.h>
>>
>> #define DISPLAY_WIDTH	240
>> #define DISPLAY_HEIGHT	64
>> #define FB_MEM_SIZE 	(DISPLAY_WIDTH * DISPLAY_HEIGHT)/8
>>
>> static struct platform_device *testfb_device;
>>
>> static struct fb_ops fbops = {
>> 	.owner		= THIS_MODULE,
>> 	.fb_fillrect	= sys_fillrect,
>> 	.fb_copyarea	= sys_copyarea,
>> 	.fb_imageblit	= sys_imageblit,
>> 	.fb_read	= fb_sys_read,
>> 	.fb_write	= fb_sys_write,
>> 	.fb_sync	= NULL,
>> };
>>
>> static int __init testfb_probe (struct platform_device *pdev) {
>> 	void *fb_mem = NULL;
>> 	struct fb_info *fbinfo = NULL;
>>
>> 	fb_mem = kzalloc(FB_MEM_SIZE, GFP_KERNEL);
>>
>> 	if (!fb_mem) {
>> 		pr_err("testfb: memory allocation for framebuffer failed\n");
>> 		return(-ENOMEM);
>> 	}
>> 	else
>> 		pr_debug("testfb: allocated framebuffer memory successfully\n");
>>
>> 	fbinfo = framebuffer_alloc(0, &pdev->dev);
>>
>> 	if (!fbinfo) {
>> 		pr_err("testfb: framebuffer_alloc() failed\n");
>> 		kfree(fb_mem);
>> 		return(-1);
>> 	}
>> 	else
>> 		pr_debug("testfb: framebuffer_alloc was successful\n");
>>
>> 	fbinfo->fix.smem_start = (unsigned long) fb_mem;
>> 	fbinfo->screen_base = (char __iomem *) fb_mem;
>> 	fbinfo->fix.smem_len = FB_MEM_SIZE;
>> 	fbinfo->fbops = &fbops;
>>
>> 	fbinfo->node			= 0;				/* ?int */
>> 	fbinfo->device			= &pdev->dev;
>> 	fbinfo->flags			= FBINFO_DEFAULT;		/*  */
>> 	fbinfo->var.xres		= DISPLAY_WIDTH;		/* visible resolution */
>> 	fbinfo->var.yres		= DISPLAY_HEIGHT;		/* visible resolution */
>> 	fbinfo->var.xres_virtual	= DISPLAY_WIDTH;		/* virtual resolution */
>> 	fbinfo->var.yres_virtual	= DISPLAY_HEIGHT;		/* virtual resolution */
>> 	fbinfo->var.bits_per_pixel	= 1;				/* bits per pixel */
>> 	fbinfo->var.activate		= FB_ACTIVATE_NOW;		/* set values immediately (or vbl) */
>> 	fbinfo->var.sync		= 0;				/* ?see FB_SYNC_* */
>> 	fbinfo->var.vmode		= FB_VMODE_NONINTERLACED;	/* non interlaced, see FB_VMODE_* */
>> 	fbinfo->var.left_margin 	= 0;
>> 	fbinfo->var.right_margin 	= 0;
>> 	fbinfo->var.upper_margin 	= 0;
>> 	fbinfo->var.lower_margin 	= 0;
>> 	fbinfo->var.red.offset 		= 0;
>> 	fbinfo->var.red.length 		= fbinfo->var.bits_per_pixel;
>> 	fbinfo->var.green 		= fbinfo->var.red;
>> 	fbinfo->var.blue  		= fbinfo->var.red;
>> 	fbinfo->var.grayscale		= 1;
>> 	strcpy(fbinfo->fix.id, "testfb");				/* identifier, 16 byte */
>> 	fbinfo->fix.type		= FB_TYPE_PACKED_PIXELS;	/* pack pixels to avoid overhead */
>> 	fbinfo->fix.visual		= FB_VISUAL_MONO10;		/* Monochr. 1=Black 0=White */
>> 	fbinfo->fix.line_length		= DISPLAY_WIDTH/8;		/* length of a line in bytes */
>> 	fbinfo->fix.accel		= FB_ACCEL_NONE;		/* no hardware accelerator */
>> 	fbinfo->fix.xpanstep 		= 0;
>> 	fbinfo->fix.ypanstep		= 0;
>> 	fbinfo->fix.ywrapstep 		= 0;
>>
>> 	if (register_framebuffer(fbinfo) < 0) {
>> 		pr_err("testfb: registering framebuffer failed\n");
>> 		kfree((void *) fbinfo->fix.smem_start);
>> 		framebuffer_release(fbinfo);
>> 		return(-1);
>> 	}
>> 	else
>> 		pr_debug("testfb: registered framebuffer\n");
>>
>> 	platform_set_drvdata(pdev, fbinfo);
>>
>> 	return 0;
>> }
>>
>> static int testfb_remove(struct platform_device *pdev) {
>> 	struct fb_info *fbinfo = NULL;
>>
>> 	fbinfo = platform_get_drvdata(pdev);
>>
>> 	if (!fbinfo) {
>> 		pr_err("testfb: unable to get fbinfo from pdev\n");
>> 		return(-1);
>> 	}
>>
>> 	if (unregister_framebuffer(fbinfo) < 0)
>> 		pr_err("testfb: unregistering framebuffer failed\n");
>> 	else
>> 		pr_debug("testfb: unregistered framebuffer\n");
>>
>> 	kfree((void *) fbinfo->fix.smem_start);
>>
>> 	framebuffer_release(fbinfo);
>>
>> 	return 0;
>> }
>>
>> static struct platform_driver testfb_driver = {
>> 	.probe = testfb_probe,
>> 	.remove = testfb_remove,
>> 	.driver = {
>> 		.name = "testfb",
>> 	},
>> };
>>
>> static int __init testfb_init(void)
>> {
>> 	int ret;
>>
>> 	ret = platform_driver_register(&testfb_driver);
>> 	if (!ret) {
>> 		testfb_device = platform_device_register_simple("testfb", 0,
>> 								NULL, 0);
>>
>> 		if (IS_ERR(testfb_device)) {
>> 			platform_driver_unregister(&testfb_driver);
>> 			ret = PTR_ERR(testfb_device);
>> 		} else {
>> 			pr_info("testfb: platform_device registered\n");
>> 		}
>>
>> 	}
>>
>> 	pr_info("testfb: module loaded\n");
>> 	
>> 	return 0;
>> }
>>
>> static void __exit testfb_exit(void)
>> {
>> 	platform_device_unregister(testfb_device);
>> 	platform_driver_unregister(&testfb_driver);
>>
>> 	pr_info("testfb: module unloaded\n");
>> }
>>
>> module_init(testfb_init);
>> module_exit(testfb_exit);
>>
>> MODULE_LICENSE("GPL v2");
>> MODULE_ALIAS("testfb");
>> MODULE_AUTHOR("Brian Fonfara");
>> MODULE_DESCRIPTION("Ein Modul zum Test der Linux Framebuffer-Programmierung");
>> MODULE_DESCRIPTION("version 0.1");
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> --
> 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/
> 

^ permalink raw reply

* Re: console / fbdev: fbcon support for bits_per_pixel = 1?
From: Geert Uytterhoeven @ 2014-06-15  8:57 UTC (permalink / raw)
  To: Bruno Prémont
  Cc: Stefan Biereigel, Linux Fbdev development list,
	linux-kernel@vger.kernel.org, linux-console, brian
In-Reply-To: <20140614143550.59367463@neptune.home>

On Sat, Jun 14, 2014 at 2:35 PM, Bruno Prémont
<bonbons@linux-vserver.org> wrote:
>> Is this behavior intended or are we triggering a bug here (that no one noticed, because
>> who in the world uses monochrome framebuffers these days..). I can't see any comments that
>> monochrome consoles should not work with 1 bit per pixel. See the code below if you spot
>> some errors (ignore some missing error handling and mediocre style for now, please).
>
> fbcon on 1bpp frambuffer worked for me with picoLCD (though I have found no userspace

I'm not aware of 1 bpp frame buffer consoles being broken.

> framebuffer application willing to operate at 1bpp).

Xfbdev does. I revived support for monochrome (and Atari/Amiga-style
bitplanes) last year.

And of course
https://git.kernel.org/cgit/linux/kernel/git/geert/fbtest.git/

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* [PATCH -next 00/26] treewide: Use dma_zalloc_coherent
From: Joe Perches @ 2014-06-15 20:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: linuxppc-dev, linux-sh, linux-ide, linux-nvme, linux-crypto,
	dmaengine, dri-devel, linux-rdma, linux-arm-msm, linux-mmc,
	netdev, e1000-devel, ath10k, linux-wireless, wcn36xx, users,
	linux-scsi, linux-usb, linux-fbdev, alsa-devel

Use the zeroing function instead of dma_alloc_coherent & memset(,0,)

Joe Perches (26):
  powerpc: Use dma_zalloc_coherent
  sh: Use dma_zalloc_coherent
  ata: Use dma_zalloc_coherent
  block: Use dma_zalloc_coherent
  crypto: Use dma_zalloc_coherent
  dma: Use dma_zalloc_coherent
  gpu: Use dma_zalloc_coherent
  infiniband: Use dma_zalloc_coherent
  mmc: Use dma_zalloc_coherent
  broadcom: Use dma_zalloc_coherent
  hisilicon: Use dma_zalloc_coherent
  intel: Use dma_zalloc_coherent
  ath: Use dma_zalloc_coherent
  rt2x00: Use dma_zalloc_coherent
  bfa: Use dma_zalloc_coherent
  bnx2fc: Use dma_zalloc_coherent
  bnx2i: Use dma_zalloc_coherent
  dpt_i2o: Use dma_zalloc_coherent
  lpfc: Use dma_zalloc_coherent
  megaraid: Use dma_zalloc_coherent
  mvsas: Use dma_zalloc_coherent
  qla2xxx: Use dma_zalloc_coherent
  qla4xxx: Use dma_zalloc_coherent
  usb: Use dma_zalloc_coherent
  fbdev: Use dma_zalloc_coherent
  sound: Use dma_zalloc_coherent

 arch/powerpc/platforms/pasemi/dma_lib.c       |  8 ++--
 arch/powerpc/sysdev/fsl_rmu.c                 |  9 ++--
 arch/sh/mm/consistent.c                       |  4 +-
 drivers/ata/sata_fsl.c                        |  5 +--
 drivers/block/nvme-core.c                     |  5 +--
 drivers/crypto/amcc/crypto4xx_core.c          |  8 ++--
 drivers/crypto/ixp4xx_crypto.c                |  8 ++--
 drivers/dma/imx-sdma.c                        |  5 +--
 drivers/dma/mxs-dma.c                         |  8 ++--
 drivers/gpu/drm/drm_pci.c                     |  6 +--
 drivers/infiniband/hw/cxgb3/cxio_hal.c        |  7 ++--
 drivers/infiniband/hw/mthca/mthca_memfree.c   |  5 +--
 drivers/infiniband/hw/ocrdma/ocrdma_hw.c      | 20 ++++-----
 drivers/infiniband/hw/ocrdma/ocrdma_stats.c   |  6 +--
 drivers/infiniband/hw/ocrdma/ocrdma_verbs.c   |  8 ++--
 drivers/mmc/host/msm_sdcc.c                   |  8 ++--
 drivers/net/ethernet/broadcom/bcm63xx_enet.c  |  6 +--
 drivers/net/ethernet/hisilicon/hix5hd2_gmac.c |  5 +--
 drivers/net/ethernet/intel/ixgb/ixgb_main.c   |  6 +--
 drivers/net/wireless/ath/ath10k/pci.c         |  8 +---
 drivers/net/wireless/ath/ath10k/wmi.c         |  8 +---
 drivers/net/wireless/ath/wcn36xx/dxe.c        |  6 +--
 drivers/net/wireless/rt2x00/rt2x00mmio.c      |  8 ++--
 drivers/scsi/bfa/bfad_bsg.c                   |  6 +--
 drivers/scsi/bnx2fc/bnx2fc_hwi.c              | 59 ++++++++++++---------------
 drivers/scsi/bnx2fc/bnx2fc_tgt.c              | 51 ++++++++++-------------
 drivers/scsi/bnx2i/bnx2i_hwi.c                | 14 +++----
 drivers/scsi/dpt_i2o.c                        | 19 ++++-----
 drivers/scsi/lpfc/lpfc_bsg.c                  |  5 +--
 drivers/scsi/lpfc/lpfc_init.c                 | 22 ++++------
 drivers/scsi/lpfc/lpfc_mbox.c                 |  6 +--
 drivers/scsi/lpfc/lpfc_sli.c                  | 14 +++----
 drivers/scsi/megaraid/megaraid_sas_fusion.c   |  9 ++--
 drivers/scsi/mvsas/mv_init.c                  | 26 +++++-------
 drivers/scsi/qla2xxx/qla_init.c               | 10 ++---
 drivers/scsi/qla4xxx/ql4_init.c               |  5 +--
 drivers/scsi/qla4xxx/ql4_mbx.c                | 21 ++++------
 drivers/scsi/qla4xxx/ql4_nx.c                 |  5 +--
 drivers/scsi/qla4xxx/ql4_os.c                 | 12 +++---
 drivers/usb/dwc2/hcd_ddma.c                   | 20 ++++-----
 drivers/usb/host/uhci-hcd.c                   |  7 ++--
 drivers/video/fbdev/da8xx-fb.c                |  9 ++--
 sound/aoa/soundbus/i2sbus/core.c              | 12 ++----
 sound/sparc/dbri.c                            |  6 +--
 44 files changed, 197 insertions(+), 308 deletions(-)

-- 
1.8.1.2.459.gbcd45b4.dirty


^ permalink raw reply

* [PATCH -next 25/26] fbdev: Use dma_zalloc_coherent
From: Joe Perches @ 2014-06-15 20:37 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, linux-fbdev
In-Reply-To: <cover.1402863904.git.joe@perches.com>

Use the zeroing function instead of dma_alloc_coherent & memset(,0,)

Signed-off-by: Joe Perches <joe@perches.com>
---
 drivers/video/fbdev/da8xx-fb.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
index a8484f7..788f6b3 100644
--- a/drivers/video/fbdev/da8xx-fb.c
+++ b/drivers/video/fbdev/da8xx-fb.c
@@ -1447,18 +1447,15 @@ static int fb_probe(struct platform_device *device)
 		da8xx_fb_fix.line_length - 1;
 
 	/* allocate palette buffer */
-	par->v_palette_base = dma_alloc_coherent(NULL,
-					       PALETTE_SIZE,
-					       (resource_size_t *)
-					       &par->p_palette_base,
-					       GFP_KERNEL | GFP_DMA);
+	par->v_palette_base = dma_zalloc_coherent(NULL, PALETTE_SIZE,
+						  (resource_size_t *)&par->p_palette_base,
+						  GFP_KERNEL | GFP_DMA);
 	if (!par->v_palette_base) {
 		dev_err(&device->dev,
 			"GLCD: kmalloc for palette buffer failed\n");
 		ret = -EINVAL;
 		goto err_release_fb_mem;
 	}
-	memset(par->v_palette_base, 0, PALETTE_SIZE);
 
 	par->irq = platform_get_irq(device, 0);
 	if (par->irq < 0) {
-- 
1.8.1.2.459.gbcd45b4.dirty


^ permalink raw reply related

* [PATCH] video: fbdev: sis: init301.c:  Cleaning up useless if statement
From: Rickard Strandqvist @ 2014-06-15 21:52 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen
  Cc: Rickard Strandqvist, Jingoo Han, Laurent Pinchart, Rob Clark,
	linux-fbdev, linux-kernel

The same code regardless of the outcome of the if statement. This may of
course be a miss and there should be a difference in the code.
And sets a variable that is missed, a probable cut and paste mistake.

This was partly found using a static code analysis program called cppcheck.

Rickard Strandqvist (1):
  video: fbdev: sis: init301.c:  Cleaning up useless if statement

 drivers/video/fbdev/sis/init301.c |   19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

-- 
1.7.10.4


^ permalink raw reply

* [PATCH] video: fbdev: sis: init301.c:  Cleaning up useless if statement
From: Rickard Strandqvist @ 2014-06-15 21:52 UTC (permalink / raw)
  To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen
  Cc: Rickard Strandqvist, Jingoo Han, Laurent Pinchart, Rob Clark,
	linux-fbdev, linux-kernel
In-Reply-To: <1402869130-4962-1-git-send-email-rickard_strandqvist@spectrumdigital.se>

Same code is run regardless of the outcome of the if statement.
And sets a variable that is missed, a probable cut and paste mistake.

Signed-off-by: Rickard Strandqvist <rickard_strandqvist@spectrumdigital.se>
---
 drivers/video/fbdev/sis/init301.c |   19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/drivers/video/fbdev/sis/init301.c b/drivers/video/fbdev/sis/init301.c
index a89e3ca..008ab4a 100644
--- a/drivers/video/fbdev/sis/init301.c
+++ b/drivers/video/fbdev/sis/init301.c
@@ -1714,7 +1714,7 @@ SiS_GetLCDResInfo(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned sh
 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315; /* ? */
 			    } else {
 			       SiS_Pr->PanelHT   = 1688; SiS_Pr->PanelVT   =  802;
-			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRS  =  112;
+			       SiS_Pr->PanelHRS  =   48; SiS_Pr->PanelHRE  =  112;
 			       SiS_Pr->PanelVRS  =    3; SiS_Pr->PanelVRE  =    6;
 			       SiS_Pr->PanelVCLKIdx300 = VCLK81_300;
 			       SiS_Pr->PanelVCLKIdx315 = VCLK81_315;
@@ -6850,11 +6850,9 @@ SiS_SetGroup2(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
 	   if(SiS_Pr->SiS_VGAHDE >= 1280) {
               tempch = 20;
               tempbx &= ~0x20;
-           } else if(SiS_Pr->SiS_VGAHDE >= 1024) {
-              tempch = 25;
            } else {
-	      tempch = 25; /* OK */
-	   }
+              tempch = 25; /* OK */
+          }
         }
      }
   }
@@ -7971,13 +7969,8 @@ SiS_SetCHTVReg(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short
          }
       } else {						/* ---- PAL ---- */
          /* We don't play around with FSCI in PAL mode */
-         if(resindex = 0x04) {
-            SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
-            SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on */
-         } else {
-            SiS_SetCH70xxANDOR(SiS_Pr,0x20,0x00,0xEF);	/* loop filter off */
-            SiS_SetCH70xxANDOR(SiS_Pr,0x21,0x01,0xFE);	/* ACIV on */
-         }
+         SiS_SetCH70xxANDOR(SiS_Pr, 0x20, 0x00, 0xEF);	/* loop filter off */
+         SiS_SetCH70xxANDOR(SiS_Pr, 0x21, 0x01, 0xFE);	/* ACIV on */
       }
 
 #endif  /* 300 */
@@ -9663,8 +9656,6 @@ SetDelayComp(struct SiS_Private *SiS_Pr, unsigned short ModeNo)
 	      delay = 0x0a;
 	   } else if(IS_SIS740) {
 	      delay = 0x00;
-	   } else if(SiS_Pr->ChipType < SIS_330) {
-	      delay = 0x0c;
 	   } else {
 	      delay = 0x0c;
 	   }
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH -next 25/26] fbdev: Use dma_zalloc_coherent
From: Geert Uytterhoeven @ 2014-06-15 22:16 UTC (permalink / raw)
  To: Joe Perches
  Cc: linux-kernel@vger.kernel.org, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, Linux Fbdev development list
In-Reply-To: <881b8f8d85c96b6e9d8735aa10bbf18468688b9d.1402863905.git.joe@perches.com>

On Sun, Jun 15, 2014 at 10:37 PM, Joe Perches <joe@perches.com> wrote:
> diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
> index a8484f7..788f6b3 100644
> --- a/drivers/video/fbdev/da8xx-fb.c
> +++ b/drivers/video/fbdev/da8xx-fb.c
> @@ -1447,18 +1447,15 @@ static int fb_probe(struct platform_device *device)
>                 da8xx_fb_fix.line_length - 1;
>
>         /* allocate palette buffer */
> -       par->v_palette_base = dma_alloc_coherent(NULL,
> -                                              PALETTE_SIZE,
> -                                              (resource_size_t *)
> -                                              &par->p_palette_base,
> -                                              GFP_KERNEL | GFP_DMA);
> +       par->v_palette_base = dma_zalloc_coherent(NULL, PALETTE_SIZE,
> +                                                 (resource_size_t *)&par->p_palette_base,

Suggestion for further cleanup: It seems this cast is no longer needed.

> +                                                 GFP_KERNEL | GFP_DMA);

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH -next 25/26] fbdev: Use dma_zalloc_coherent
From: Joe Perches @ 2014-06-15 23:32 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: linux-kernel@vger.kernel.org, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, Linux Fbdev development list
In-Reply-To: <CAMuHMdWHJ1LY0r1aMZViQW_ZZYrbGkHb4Hpkt+YZfRbERfyE3Q@mail.gmail.com>

On Mon, 2014-06-16 at 00:16 +0200, Geert Uytterhoeven wrote:
> On Sun, Jun 15, 2014 at 10:37 PM, Joe Perches <joe@perches.com> wrote:
> > diff --git a/drivers/video/fbdev/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
[]
> > @@ -1447,18 +1447,15 @@ static int fb_probe(struct platform_device *device)
> >                 da8xx_fb_fix.line_length - 1;
> >
> >         /* allocate palette buffer */
> > -       par->v_palette_base = dma_alloc_coherent(NULL,
> > -                                              PALETTE_SIZE,
> > -                                              (resource_size_t *)
> > -                                              &par->p_palette_base,
> > -                                              GFP_KERNEL | GFP_DMA);
> > +       par->v_palette_base = dma_zalloc_coherent(NULL, PALETTE_SIZE,
> > +                                                 (resource_size_t *)&par->p_palette_base,
> 
> Suggestion for further cleanup: It seems this cast is no longer needed.

Sure, but after this is applied.


^ permalink raw reply

* [RFC 0/2]  backlight: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-16  2:17 UTC (permalink / raw)
  To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
  Cc: Daniel Jeong, linux-kernel, linux-fbdev, devicetree, linux-doc,
	Daniel Jeong

This driver a general version for tps611xx backlgiht chips of TI.
It supports tps61158, tps61161, tps61163 and tps61165 backlight driver
based on EasyScale protocol.

Daniel Jeong (2):
  backlight: add new tps611xx backlight driver
  backlight: add new tps611xx backlight device tree support

 .../video/backlight/tps611xx-backlight.txt         |   16 +
 drivers/video/backlight/Kconfig                    |    7 +
 drivers/video/backlight/Makefile                   |    1 +
 drivers/video/backlight/tps611xx_bl.c              |  486 ++++++++++++++++++++
 include/linux/platform_data/tps611xx_bl.h          |   30 ++
 5 files changed, 540 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
 create mode 100644 drivers/video/backlight/tps611xx_bl.c
 create mode 100644 include/linux/platform_data/tps611xx_bl.h

-- 
1.7.9.5


^ permalink raw reply

* [RFC 1/2] backlight: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-16  2:17 UTC (permalink / raw)
  To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
  Cc: Daniel Jeong, linux-kernel, linux-fbdev, devicetree, linux-doc,
	Daniel Jeong
In-Reply-To: <1402885043-3626-1-git-send-email-gshark.jeong@gmail.com>

This driver a general version for tps611xx backlgiht chips of TI.
It supports tps61158, tps61161, tps61163 and tps61165 backlight driver
based on EasyScale protocol.

Signed-off-by: Daniel Jeong <gshark.jeong@gmail.com>
---
 drivers/video/backlight/Kconfig           |    7 +
 drivers/video/backlight/Makefile          |    1 +
 drivers/video/backlight/tps611xx_bl.c     |  486 +++++++++++++++++++++++++++++
 include/linux/platform_data/tps611xx_bl.h |   30 ++
 4 files changed, 524 insertions(+)
 create mode 100644 drivers/video/backlight/tps611xx_bl.c
 create mode 100644 include/linux/platform_data/tps611xx_bl.h

diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 5a3eb2e..c779a85 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -418,6 +418,13 @@ config BACKLIGHT_TPS65217
 	  If you have a Texas Instruments TPS65217 say Y to enable the
 	  backlight driver.
 
+config BACKLIGHT_TPS611xx
+	tristate "TPS611xx Backlight"
+	depends on BACKLIGHT_CLASS_DEVICE && GPIOLIB
+	help
+	  This supports TI TPS61158, TPS61161, TPS61163 and TPS61165
+	  backlight driver based on EasyScale Protocol.
+
 config BACKLIGHT_AS3711
 	tristate "AS3711 Backlight"
 	depends on BACKLIGHT_CLASS_DEVICE && MFD_AS3711
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index bb82002..44f1641 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -52,4 +52,5 @@ obj-$(CONFIG_BACKLIGHT_PWM)		+= pwm_bl.o
 obj-$(CONFIG_BACKLIGHT_SAHARA)		+= kb3886_bl.o
 obj-$(CONFIG_BACKLIGHT_TOSA)		+= tosa_bl.o
 obj-$(CONFIG_BACKLIGHT_TPS65217)	+= tps65217_bl.o
+obj-$(CONFIG_BACKLIGHT_TPS611xx)	+= tps611xx_bl.o
 obj-$(CONFIG_BACKLIGHT_WM831X)		+= wm831x_bl.o
diff --git a/drivers/video/backlight/tps611xx_bl.c b/drivers/video/backlight/tps611xx_bl.c
new file mode 100644
index 0000000..4b76cdd
--- /dev/null
+++ b/drivers/video/backlight/tps611xx_bl.c
@@ -0,0 +1,486 @@
+/*
+ * Simple driver for Texas Instruments TPS611XX Backlight driver chip
+ *        using EasyScale Interface. It supports TPS61158, TPS61161,
+ *        TPS61163 and TPS61165.
+ *
+ * Copyright (C) 2014 Texas Instruments
+ * Author: Daniel Jeong  <gshark.jeong@gmail.com>
+ *	       Ldd Mlp <ldd-mlp@list.ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_data/tps611xx_bl.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define CMD_FORWARD 0
+#define CMD_BACKWARD 1
+
+enum tps611xx_id {
+	TPS61158_ID = 0,
+	TPS61161_ID,
+	TPS61163_ID,
+	TPS61165_ID,
+};
+
+/*
+ * easyscale time spec
+ * @es_delay : es delay time(ns)
+ * @es_det   : es detection time(ns)
+ * @start    : start time of data stream(ns)
+ * @eos      : end time of data stream(ns)
+ * @reset    : ic shutdown time(ms)
+ * @logic_1_low : low time high bit(ns)
+ * @logic_0_low : low time low bit(ns)
+ * @ackn        : duation of ack condistion(ns)
+ * @ack_poll    : ack polling duration(ns)
+ */
+struct tps611xx_time {
+	unsigned int es_delay;
+	unsigned int es_det;
+	unsigned int start;
+	unsigned int eos;
+	unsigned int reset;
+	unsigned int logic_1_low;
+	unsigned int logic_0_low;
+	unsigned int ackn;
+	unsigned int ack_poll;
+};
+
+/*
+ * @seq : sequence of data transfer
+ * @size: size of data
+ * @brt_max : max brightness
+ * @brt_bmask : bit mask of dimming bits
+ * @rfa_bmask : bit mask of request of ack
+ */
+struct tps611xx_command {
+	int seq;
+	int size;
+	int brt_max;
+	int brt_bmask;
+	int rfa_bmask;
+};
+
+/*
+ * @id : product id
+ * @name : product name
+ * @addr : device address
+ * @cmd  : es command info
+ * @time : es time info
+ */
+struct tps611xx_esdata {
+	enum tps611xx_id id;
+	char *name;
+	int addr;
+	struct tps611xx_command cmd;
+	struct tps611xx_time time;
+};
+
+struct tps611xx_bl_data {
+	struct device *dev;
+	struct backlight_device *bled;
+	struct tps611xx_platform_data *pdata;
+
+	/*
+	 * @rfa_en : acknowlege request enable
+	 * @en_gpio: enable pin gpio no.
+	 * @esdata : easyscale data
+	 */
+	int rfa_en;
+	unsigned int en_gpio;
+	const struct tps611xx_esdata *esdata;
+};
+
+static struct tps611xx_esdata tps611xx_info[] = {
+	[TPS61158_ID] = {
+			 .id = TPS61158_ID,
+			 .name = "tps61158",
+			 .addr = 0x5800,
+			 .cmd = {
+				 .seq = CMD_FORWARD,
+				 .size = 16,
+				 .brt_max = 31,
+				 .brt_bmask = 0x1f,
+				 .rfa_bmask = 0x80},
+			 .time = {
+				  .es_delay = 100000,
+				  .es_det = 450000,
+				  .start = 3500,
+				  .eos = 3500,
+				  .reset = 4,
+				  .logic_1_low = 5000,
+				  .logic_0_low = 15000,
+				  .ackn = 900000,
+				  .ack_poll = 2000},
+			 },
+
+	[TPS61161_ID] = {
+			 .id = TPS61161_ID,
+			 .name = "tps61161",
+			 .addr = 0x7200,
+			 .cmd = {
+				 .seq = CMD_FORWARD,
+				 .size = 16,
+				 .brt_max = 31,
+				 .brt_bmask = 0x1f,
+				 .rfa_bmask = 0x80},
+			 .time = {
+				  .es_delay = 120000,
+				  .es_det = 280000,
+				  .start = 2000,
+				  .eos = 2000,
+				  .reset = 3,
+				  .logic_1_low = 3000,
+				  .logic_0_low = 7000,
+				  .ackn = 512000,
+				  .ack_poll = 2000},
+			 },
+
+	[TPS61163_ID] = {
+			 .id = TPS61163_ID,
+			 .name = "tps61163",
+			 .addr = 0x8F0000,
+			 .cmd = {
+				 .seq = CMD_BACKWARD,
+				 .size = 24,
+				 .brt_max = 511,
+				 .brt_bmask = 0x1ff,
+				 .rfa_bmask = 0x400},
+			 .time = {
+				  .es_delay = 100000,
+				  .es_det = 260000,
+				  .start = 2000,
+				  .eos = 2000,
+				  .reset = 3,
+				  .logic_1_low = 3000,
+				  .logic_0_low = 7000,
+				  .ackn = 512000,
+				  .ack_poll = 2000},
+			 },
+
+	[TPS61165_ID] = {
+			 .id = TPS61165_ID,
+			 .name = "tps61165",
+			 .addr = 0x7200,
+			 .cmd = {
+				 .seq = CMD_FORWARD,
+				 .size = 16,
+				 .brt_max = 31,
+				 .brt_bmask = 0x1f,
+				 .rfa_bmask = 0x80},
+			 .time = {
+				  .es_delay = 120000,
+				  .es_det = 280000,
+				  .start = 4000,
+				  .eos = 4000,
+				  .reset = 3,
+				  .logic_1_low = 3000,
+				  .logic_0_low = 7000,
+				  .ackn = 512000,
+				  .ack_poll = 2000},
+			 },
+};
+
+static int tps611xx_bl_update_status(struct backlight_device *bl)
+{
+	struct tps611xx_bl_data *pchip = bl_get_data(bl);
+	const struct tps611xx_esdata *esdata = pchip->esdata;
+	int data_in, t_low, t_logic, max_bmask;
+	unsigned long flags;
+
+	data_in = esdata->addr | (bl->props.brightness & esdata->cmd.brt_bmask);
+	if (pchip->rfa_en)
+		data_in |= esdata->cmd.rfa_bmask;
+
+	max_bmask = 0x1 << esdata->cmd.size;
+	t_logic = esdata->time.logic_1_low + esdata->time.logic_0_low;
+
+	local_irq_save(flags);
+	/* t_start : 2us high before data byte */
+	gpio_direction_output(pchip->en_gpio, 1);
+	ndelay(esdata->time.start);
+
+	/* forward command transfer */
+	if (esdata->cmd.seq = CMD_FORWARD) {
+		int addr_bmask = max_bmask >> 8;
+
+		for (max_bmask >>= 1; max_bmask > 0x0; max_bmask >>= 1) {
+			if (data_in & max_bmask)
+				t_low = esdata->time.logic_1_low;
+			else
+				t_low = esdata->time.logic_0_low;
+
+			gpio_direction_output(pchip->en_gpio, 0);
+			ndelay(t_low);
+			gpio_direction_output(pchip->en_gpio, 1);
+			ndelay(t_logic - t_low);
+
+			if (max_bmask = addr_bmask) {
+				gpio_direction_output(pchip->en_gpio, 0);
+				/* t_eos : low after address byte */
+				ndelay(esdata->time.eos);
+				gpio_direction_output(pchip->en_gpio, 1);
+				/* t_start : high before data byte */
+				ndelay(esdata->time.start);
+			}
+		}
+	} else {
+		/* backward command tansfer */
+		int bmask;
+
+		for (bmask = 0x01; bmask < max_bmask; bmask <<= 1) {
+			if (data_in & bmask)
+				t_low = esdata->time.logic_1_low;
+			else
+				t_low = esdata->time.logic_0_low;
+
+			gpio_direction_output(pchip->en_gpio, 0);
+			ndelay(t_low);
+			gpio_direction_output(pchip->en_gpio, 1);
+			ndelay(t_logic - t_low);
+		}
+	}
+
+	/*
+	 * t_eos : low after address byte
+	 * t_ackVal is also t_eos
+	 */
+	gpio_direction_output(pchip->en_gpio, 0);
+	ndelay(esdata->time.eos);
+
+	/* RFA management  */
+	if (pchip->rfa_en) {
+		int max_ack_time = esdata->time.ackn;
+		/* set input */
+		gpio_direction_input(pchip->en_gpio);
+		/* read acknowledge from chip */
+		while (max_ack_time > 0) {
+			if (gpio_get_value(pchip->en_gpio) = 0)
+				break;
+			max_ack_time -= esdata->time.ack_poll;
+		}
+		if (max_ack_time <= 0)
+			dev_err(pchip->dev,
+				"easyscale : no ack from %s\n", esdata->name);
+		else
+			ndelay(max_ack_time);
+	}
+	gpio_direction_output(pchip->en_gpio, 1);
+	local_irq_restore(flags);
+
+	return bl->props.brightness;
+}
+
+static int tps611xx_bl_get_brightness(struct backlight_device *bl)
+{
+	return bl->props.brightness;
+}
+
+static const struct backlight_ops tps611xx_bl_ops = {
+	.update_status = tps611xx_bl_update_status,
+	.get_brightness = tps611xx_bl_get_brightness,
+};
+
+static ssize_t tps611xx_enable_store(struct device *dev,
+				     struct device_attribute *devAttr,
+				     const char *buf, size_t size)
+{
+	struct tps611xx_bl_data *pchip = dev_get_drvdata(dev);
+	const struct tps611xx_esdata *esdata = pchip->esdata;
+	unsigned long flags;
+	unsigned int input;
+	int ret;
+
+	ret = kstrtouint(buf, 10, &input);
+	if (ret)
+		return -EINVAL;
+
+	local_irq_save(flags);
+	if (input = 0) {
+		/* chip disable */
+		gpio_direction_output(pchip->en_gpio, 0);
+		/* low more than reset ms to reset */
+		mdelay(esdata->time.reset);
+	} else {
+		/* easyscale detection window */
+		gpio_direction_output(pchip->en_gpio, 1);
+		ndelay(esdata->time.es_delay);
+		gpio_direction_output(pchip->en_gpio, 0);
+		ndelay(esdata->time.es_det);
+		gpio_direction_output(pchip->en_gpio, 1);
+	}
+	local_irq_restore(flags);
+
+	return size;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR, NULL, tps611xx_enable_store);
+
+#ifdef CONFIG_OF
+static struct of_device_id tps611xx_backlight_of_match[] = {
+	{.compatible = "ti,tps61158_bl", .data = &tps611xx_info[TPS61158_ID]},
+	{.compatible = "ti,tps61161_bl", .data = &tps611xx_info[TPS61161_ID]},
+	{.compatible = "ti,tps61163_bl", .data = &tps611xx_info[TPS61163_ID]},
+	{.compatible = "ti,tps61165_bl", .data = &tps611xx_info[TPS61165_ID]},
+	{}
+};
+
+MODULE_DEVICE_TABLE(of, tps611xx_backlight_of_match);
+
+static int tps611xx_backlight_parse_dt(struct tps611xx_bl_data *pchip)
+{
+	struct device *dev = pchip->dev;
+	struct device_node *node = dev->of_node;
+	const struct of_device_id *of_id +	    of_match_device(tps611xx_backlight_of_match, dev);
+	u32 value;
+	int ret;
+
+	if (!node)
+		return -ENODEV;
+
+	if (!of_id || !of_id->data) {
+		dev_err(dev, "Failed to find tps611xx chip id\n");
+		return -EFAULT;
+	}
+	pchip->esdata = of_id->data;
+
+	ret = of_property_read_u32(node, "en_gpio_num", &value);
+	if (ret < 0)
+		return ret;
+	pchip->en_gpio = value;
+	ret = of_property_read_u32(node, "rfa_en", &value);
+	if (ret < 0)
+		return ret;
+	pchip->rfa_en = value;
+
+	return 0;
+}
+#else
+static int tps611xx_backlight_parse_dt(struct tps611xx_bl_data *pchip)
+{
+	return -ENODEV;
+}
+#endif
+
+static int tps611xx_backlight_probe(struct platform_device *pdev)
+{
+	struct tps611xx_bl_data *pchip;
+	struct backlight_properties props;
+	const struct tps611xx_esdata *esdata;
+	struct tps611xx_platform_data *pdata = dev_get_platdata(&pdev->dev);
+	unsigned long flags;
+	int ret;
+
+	pchip = devm_kzalloc(&pdev->dev,
+			     sizeof(struct tps611xx_bl_data), GFP_KERNEL);
+	if (pchip = NULL)
+		return -ENOMEM;
+	pchip->dev = &pdev->dev;
+
+	if (pdata = NULL) {
+		ret = tps611xx_backlight_parse_dt(pchip);
+		if (ret < 0)
+			return ret;
+	} else {
+		pchip->rfa_en = pdata->rfa_en;
+		pchip->en_gpio = pdata->en_gpio_num;
+		pchip->esdata = (const struct tps611xx_esdata *)
+		    platform_get_device_id(pdev)->driver_data;
+	}
+	esdata = pchip->esdata;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.brightness = esdata->cmd.brt_max;
+	props.max_brightness = esdata->cmd.brt_max;
+	props.type = BACKLIGHT_RAW;
+	pchip->bled +	    devm_backlight_device_register(pchip->dev, TPS611XX_NAME,
+					   pchip->dev, pchip,
+					   &tps611xx_bl_ops, &props);
+	if (IS_ERR(pchip->bled))
+		return PTR_ERR(pchip->bled);
+
+	/* for enable/disable */
+	ret = device_create_file(&(pchip->bled->dev), &dev_attr_enable);
+	if (ret < 0) {
+		dev_err(pchip->dev, "failed : add sysfs entries\n");
+		return ret;
+	}
+	platform_set_drvdata(pdev, pchip);
+
+	/* EasyScale init */
+	ret = gpio_request_one(pchip->en_gpio, GPIOF_OUT_INIT_HIGH, "tps611xx");
+	if (ret) {
+		device_remove_file(&(pchip->bled->dev), &dev_attr_enable);
+		dev_err(pchip->dev, "failed : get gpio %d\n", pchip->en_gpio);
+		return ret;
+	}
+
+	/*
+	 * ES Detection Window
+	 *   - ES detect delay
+	 *   - ES detect time
+	 */
+	local_irq_save(flags);
+	gpio_direction_output(pchip->en_gpio, 1);
+	ndelay(esdata->time.es_delay);
+	gpio_direction_output(pchip->en_gpio, 0);
+	ndelay(esdata->time.es_det);
+	gpio_direction_output(pchip->en_gpio, 1);
+	local_irq_restore(flags);
+	dev_info(pchip->dev,
+		 "%s EasyScale is initialized\n", pchip->esdata->name);
+	return 0;
+}
+
+static int tps611xx_backlight_remove(struct platform_device *pdev)
+{
+	struct tps611xx_bl_data *pchip = platform_get_drvdata(pdev);
+	const struct tps611xx_esdata *esdata = pchip->esdata;
+
+	device_remove_file(&(pchip->bled->dev), &dev_attr_enable);
+	gpio_direction_output(pchip->en_gpio, 0);
+	mdelay(esdata->time.reset);
+	return 0;
+}
+
+static const struct platform_device_id tps611xx_id_table[] = {
+	{TPS61158_NAME, (unsigned long)&tps611xx_info[TPS61158_ID]},
+	{TPS61161_NAME, (unsigned long)&tps611xx_info[TPS61161_ID]},
+	{TPS61163_NAME, (unsigned long)&tps611xx_info[TPS61163_ID]},
+	{TPS61165_NAME, (unsigned long)&tps611xx_info[TPS61165_ID]},
+	{}
+};
+
+static struct platform_driver tps611xx_backlight_driver = {
+	.driver = {
+		   .name = TPS611XX_NAME,
+		   .owner = THIS_MODULE,
+		   .of_match_table = of_match_ptr(tps611xx_backlight_of_match),
+		   },
+	.probe = tps611xx_backlight_probe,
+	.remove = tps611xx_backlight_remove,
+	.id_table = tps611xx_id_table,
+};
+
+module_platform_driver(tps611xx_backlight_driver);
+
+MODULE_DESCRIPTION("EasyScale based tps611xx Backlight Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:tps611xx_bl");
diff --git a/include/linux/platform_data/tps611xx_bl.h b/include/linux/platform_data/tps611xx_bl.h
new file mode 100644
index 0000000..b7c4504
--- /dev/null
+++ b/include/linux/platform_data/tps611xx_bl.h
@@ -0,0 +1,30 @@
+/*
+ * Simple driver for Texas Instruments TPS61163a Backlight driver chip
+ * Copyright (C) 2014 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __TPS611XX_H
+#define __TPS611XX_H
+
+#define TPS611XX_NAME "tps611xx_bl"
+#define TPS61158_NAME "tps61158_bl"
+#define TPS61161_NAME "tps61161_bl"
+#define TPS61163_NAME "tps61163_bl"
+#define TPS61165_NAME "tps61165_bl"
+
+/* struct tps61163a platform data
+ * @rfa_en : request for acknowledge
+ * @en_gpio_num : gpio number for en_pin
+ */
+struct tps611xx_platform_data {
+
+	int rfa_en;
+	unsigned int en_gpio_num;
+};
+
+#endif /* __TPS61163A_H */
-- 
1.7.9.5


^ permalink raw reply related

* [RFC 2/2] backlight: device tree: add new tps611xx backlight driver
From: Daniel Jeong @ 2014-06-16  2:17 UTC (permalink / raw)
  To: Jingoo Han, Bryan Wu, Lee Jones, Jean-Christophe Plagniol-Villard,
	Tomi Valkeinen, Grant Likely, Rob Herring, Randy Dunlap
  Cc: Daniel Jeong, linux-kernel, linux-fbdev, devicetree, linux-doc,
	Daniel Jeong
In-Reply-To: <1402885043-3626-1-git-send-email-gshark.jeong@gmail.com>

This commit is about tps611xx device tree documentation.

Signed-off-by: Daniel Jeong <gshark.jeong@gmail.com>
---
 .../video/backlight/tps611xx-backlight.txt         |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt

diff --git a/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt b/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
new file mode 100644
index 0000000..8a0935d
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/backlight/tps611xx-backlight.txt
@@ -0,0 +1,16 @@
+TPS611xx family of backlight driver based on EasyScale.
+
+It supports tps61158, tps61161, tps61163 and tps61165.
+
+Required properties:
+- compatible: "ti,tps61158_bl", "ti,tps61161_bl", "ti,tps61163_bl", "ti,tps61165_bl"
+- rfa_en: enable request for acknowledge.
+- en_gpio_num: gpio number for en pin.
+
+Example:
+
+	backlight {
+		compatible = "ti,tps61163_bl";
+		rfa_en = <1>;
+		en_gpio_num = <45>;
+	};
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH] offb: Fix little-endian support
From: Benjamin Herrenschmidt @ 2014-06-16  7:23 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Cedric Le Goater, Dinar Valeev, Tomi Valkeinen,
	Jean-Christophe Plagniol-Villard, linux-fbdev, linux-kernel
In-Reply-To: <s5h8uq4qm3h.wl%tiwai@suse.de>


On Wed, 2014-05-14 at 19:57 +0200, Takashi Iwai wrote:
> 
> Hm, so it actually regressed on BE?
> 
> It's strange because fb_math_be() should be true and the patch won't
> change the values in that case...

Shouldn't the patch be based on foreign endian being set rather than
just "be" anyway ?

IE. If the fb is LE and the host is LE we *also* don't want to change
the ordering, which will be the case when we fix qemu...

Cheers,
Ben.




^ permalink raw reply

* Re: [PATCH] offb: Fix little-endian support
From: Benjamin Herrenschmidt @ 2014-06-16  7:32 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Cedric Le Goater, Dinar Valeev, Tomi Valkeinen,
	Jean-Christophe Plagniol-Villard, linux-fbdev, linux-kernel
In-Reply-To: <s5h8uq4qm3h.wl%tiwai@suse.de>


On Wed, 2014-05-14 at 19:57 +0200, Takashi Iwai wrote:
> 
> Hm, so it actually regressed on BE?
> 
> It's strange because fb_math_be() should be true and the patch won't
> change the values in that case...

Shouldn't the patch be based on foreign endian being set rather than
just "be" anyway ?

IE. If the fb is LE and the host is LE we *also* don't want to change
the ordering, which will be the case when we fix qemu...

Cheers,
Ben.




^ permalink raw reply

* Re: [PATCH] offb: Fix little-endian support
From: Benjamin Herrenschmidt @ 2014-06-16  7:35 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: Tomi Valkeinen, Jean-Christophe Plagniol-Villard,
	Cedric Le Goater, linux-fbdev, linux-kernel
In-Reply-To: <1400073709-15012-1-git-send-email-tiwai@suse.de>

On Wed, 2014-05-14 at 15:21 +0200, Takashi Iwai wrote:
>         case 16:                /* RGB 565 */
>                 var->bits_per_pixel = 16;
> -               var->red.offset = 11;
> +               if (fb_be_math(info)) {
> +                       var->red.offset = 11;
> +                       var->green.offset = 5;
> +                       var->blue.offset = 0;
> +               } else {
> +                       var->red.offset = 0;
> +                       var->green.offset = 5;
> +                       var->blue.offset = 11;
> +               }
>                 var->red.length = 5;
> -               var->green.offset = 5;
>                 var->green.length = 6;
> -               var->blue.offset = 0;
>                 var->blue.length = 5;
>                 var->transp.offset = 0;
>                 var->transp.length = 0;
>                 break;

I somewhat doubt that this (and 5:5:5) actually work, do they ? the
green gets split into two separate fields, which we can't express
properly here...

Cheers,
Ben.



^ 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