* [PATCH 0/3] Use dma_mmap_coherent to support IOMMU mapper
From: Hideki EIRAKU @ 2012-07-25 6:29 UTC (permalink / raw)
To: linux-arm-kernel
There is a dma_mmap_coherent() API in some architectures. This API
provides a mmap function for memory allocated by dma_alloc_coherent().
Some drivers mmap a dma_addr_t returned by dma_alloc_coherent() as a
physical address. But such drivers do not work correctly when IOMMU
mapper is used.
Hideki EIRAKU (3):
ARM: dma-mapping: define ARCH_HAS_DMA_MMAP_COHERENT
media: videobuf2-dma-contig: use dma_mmap_coherent if available
fbdev: sh_mobile_lcdc: use dma_mmap_coherent if available
arch/arm/include/asm/dma-mapping.h | 1 +
drivers/media/video/videobuf2-dma-contig.c | 18 ++++++++++++++++++
drivers/video/sh_mobile_lcdcfb.c | 14 ++++++++++++++
3 files changed, 33 insertions(+), 0 deletions(-)
^ permalink raw reply
* [PATCH 1/3] ARM: dma-mapping: define ARCH_HAS_DMA_MMAP_COHERENT
From: Hideki EIRAKU @ 2012-07-25 6:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1343197764-13659-1-git-send-email-hdk@igel.co.jp>
ARCH_HAS_DMA_MMAP_COHERENT indicates that there is dma_mmap_coherent() API
in this architecture. The name is already defined in PowerPC.
Signed-off-by: Hideki EIRAKU <hdk@igel.co.jp>
---
arch/arm/include/asm/dma-mapping.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index bbef15d..f41cd30 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -187,6 +187,7 @@ extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
struct dma_attrs *attrs);
#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
+#define ARCH_HAS_DMA_MMAP_COHERENT
static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr,
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/3] media: videobuf2-dma-contig: use dma_mmap_coherent if available
From: Hideki EIRAKU @ 2012-07-25 6:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1343197764-13659-1-git-send-email-hdk@igel.co.jp>
Previously the vb2_dma_contig_mmap() function was using a dma_addr_t as a
physical address. The two addressses are not necessarily the same.
For example, when using the IOMMU funtion on certain platforms, dma_addr_t
addresses are not directly mappable physical address.
dma_mmap_coherent() maps the address correctly.
It is available on ARM platforms.
Signed-off-by: Hideki EIRAKU <hdk@igel.co.jp>
---
drivers/media/video/videobuf2-dma-contig.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c
index 4b71326..4dc85ab 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -101,14 +101,32 @@ static unsigned int vb2_dma_contig_num_users(void *buf_priv)
static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
{
struct vb2_dc_buf *buf = buf_priv;
+#ifdef ARCH_HAS_DMA_MMAP_COHERENT
+ int ret;
+#endif
if (!buf) {
printk(KERN_ERR "No buffer to map\n");
return -EINVAL;
}
+#ifdef ARCH_HAS_DMA_MMAP_COHERENT
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ ret = dma_mmap_coherent(buf->conf->dev, vma, buf->vaddr, buf->dma_addr,
+ buf->size);
+ if (ret) {
+ pr_err("Remapping memory failed, error: %d\n", ret);
+ return ret;
+ }
+ vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+ vma->vm_private_data = &buf->handler;
+ vma->vm_ops = &vb2_common_vm_ops;
+ vma->vm_ops->open(vma);
+ return 0;
+#else
return vb2_mmap_pfn_range(vma, buf->dma_addr, buf->size,
&vb2_common_vm_ops, &buf->handler);
+#endif
}
static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
--
1.7.0.4
^ permalink raw reply related
* [PATCH 3/3] fbdev: sh_mobile_lcdc: use dma_mmap_coherent if available
From: Hideki EIRAKU @ 2012-07-25 6:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1343197764-13659-1-git-send-email-hdk@igel.co.jp>
fb_mmap() implemented in fbmem.c uses smem_start as the physical
address of the frame buffer. In the sh_mobile_lcdc driver, the
smem_start is a dma_addr_t that is not a physical address when IOMMU is
enabled. dma_mmap_coherent() maps the address correctly. It is
available on ARM platforms.
Signed-off-by: Hideki EIRAKU <hdk@igel.co.jp>
---
drivers/video/sh_mobile_lcdcfb.c | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index e672698..65732c4 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1393,6 +1393,17 @@ static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
return 0;
}
+#ifdef ARCH_HAS_DMA_MMAP_COHERENT
+static int
+sh_mobile_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct sh_mobile_lcdc_chan *ch = info->par;
+
+ return dma_mmap_coherent(ch->lcdc->dev, vma, ch->fb_mem,
+ ch->dma_handle, ch->fb_size);
+}
+#endif
+
static struct fb_ops sh_mobile_lcdc_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = sh_mobile_lcdc_setcolreg,
@@ -1408,6 +1419,9 @@ static struct fb_ops sh_mobile_lcdc_ops = {
.fb_release = sh_mobile_release,
.fb_check_var = sh_mobile_check_var,
.fb_set_par = sh_mobile_set_par,
+#ifdef ARCH_HAS_DMA_MMAP_COHERENT
+ .fb_mmap = sh_mobile_fb_mmap,
+#endif
};
static void
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 3/3] fbdev: sh_mobile_lcdc: use dma_mmap_coherent if available
From: Laurent Pinchart @ 2012-07-25 11:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1343197764-13659-4-git-send-email-hdk@igel.co.jp>
Hi Eiraku-san,
Thank you for the patch.
On Wednesday 25 July 2012 15:29:24 Hideki EIRAKU wrote:
> fb_mmap() implemented in fbmem.c uses smem_start as the physical
> address of the frame buffer. In the sh_mobile_lcdc driver, the
> smem_start is a dma_addr_t that is not a physical address when IOMMU is
> enabled. dma_mmap_coherent() maps the address correctly. It is
> available on ARM platforms.
This looks good to me, but will need to be rebased on top of the
sh_mobile_lcdc patches currently queued for v3.6. You can find them in the
fbdev-next branch of git://github.com/schandinat/linux-2.6.git.
In particular, these patches add support for overlays exported through
additional fbdev devices. You will need to initialize .fb_mmap in both
sh_mobile_lcdc_overlay_ops and sh_mobile_lcdc_ops.
> Signed-off-by: Hideki EIRAKU <hdk@igel.co.jp>
> ---
> drivers/video/sh_mobile_lcdcfb.c | 14 ++++++++++++++
> 1 files changed, 14 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/video/sh_mobile_lcdcfb.c
> b/drivers/video/sh_mobile_lcdcfb.c index e672698..65732c4 100644
> --- a/drivers/video/sh_mobile_lcdcfb.c
> +++ b/drivers/video/sh_mobile_lcdcfb.c
> @@ -1393,6 +1393,17 @@ static int sh_mobile_lcdc_blank(int blank, struct
> fb_info *info) return 0;
> }
>
> +#ifdef ARCH_HAS_DMA_MMAP_COHERENT
> +static int
> +sh_mobile_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
> +{
> + struct sh_mobile_lcdc_chan *ch = info->par;
> +
> + return dma_mmap_coherent(ch->lcdc->dev, vma, ch->fb_mem,
> + ch->dma_handle, ch->fb_size);
> +}
> +#endif
> +
> static struct fb_ops sh_mobile_lcdc_ops = {
> .owner = THIS_MODULE,
> .fb_setcolreg = sh_mobile_lcdc_setcolreg,
> @@ -1408,6 +1419,9 @@ static struct fb_ops sh_mobile_lcdc_ops = {
> .fb_release = sh_mobile_release,
> .fb_check_var = sh_mobile_check_var,
> .fb_set_par = sh_mobile_set_par,
> +#ifdef ARCH_HAS_DMA_MMAP_COHERENT
> + .fb_mmap = sh_mobile_fb_mmap,
> +#endif
> };
>
> static void
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH 4/4] fbcon: optimize parameters parsing loop.
From: paul @ 2012-07-25 14:13 UTC (permalink / raw)
To: Paul Cercueil; +Cc: florianschandinat, linux-kernel, linux-fbdev
In-Reply-To: <1343091626-11435-4-git-send-email-paul@crapouillou.net>
Oh, I'm really sorry, I truely am.
It looks like that 4th patch is an old version, not the one that should
have been sent.
Next message will be the correct patch. My apologies about that.
^ permalink raw reply
* Re: [PATCH 4/4] fbcon: optimize parameters parsing loop.
From: paul @ 2012-07-25 14:14 UTC (permalink / raw)
To: Paul Cercueil; +Cc: florianschandinat, linux-kernel, linux-fbdev
In-Reply-To: <1343091626-11435-4-git-send-email-paul@crapouillou.net>
From 67cecd09d850542e00a1d9a29567232d1224cf23 Mon Sep 17 00:00:00 2001
From: Paul Cercueil <paul@crapouillou.net>
Date: Thu, 12 Jan 2012 19:40:24 +0100
Subject: [PATCH 4/4] fbcon: optimize parameters parsing loop.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
---
drivers/video/console/fbcon.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/video/console/fbcon.c
b/drivers/video/console/fbcon.c
index 9b83b75..1ecaf68 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -441,8 +441,10 @@ static int __init fb_console_setup(char *this_opt)
return 1;
while ((options = strsep(&this_opt, ",")) != NULL) {
- if (!strncmp(options, "font:", 5))
+ if (!strncmp(options, "font:", 5)) {
strlcpy(fontname, options + 5, sizeof(fontname));
+ continue;
+ }
if (!strncmp(options, "scrollback:", 11)) {
char *k;
@@ -468,6 +470,7 @@ static int __init fb_console_setup(char *this_opt)
/* (k && *k): Check for garbage after the suffix */
if (ret || (k && *k))
pr_warn("fbcon: scrollback: incorrect value.\n");
+ continue;
}
if (!strncmp(options, "map:", 4)) {
@@ -484,6 +487,7 @@ static int __init fb_console_setup(char *this_opt)
} else {
pr_warn("fbcon: map: incorrect value.\n");
}
+ continue;
}
if (!strncmp(options, "vc:", 3)) {
@@ -513,6 +517,7 @@ static int __init fb_console_setup(char *this_opt)
fbcon_is_default = 0;
else
pr_warn("fbcon: vc: incorrect value.\n");
+ continue;
}
if (!strncmp(options, "rotate:", 7)) {
@@ -525,6 +530,7 @@ static int __init fb_console_setup(char *this_opt)
} else {
pr_warn("fbcon: rotate: incorrect value.\n");
}
+ continue;
}
}
return 1;
--
1.7.10.4
^ permalink raw reply related
* [PATCH] ALSA: pcm - Don't define ARCH_HAS_DMA_MMAP_COHERENT privately for ARM
From: Laurent Pinchart @ 2012-07-25 16:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1343197764-13659-1-git-send-email-hdk@igel.co.jp>
The ARM architecture now defines ARCH_HAS_DMA_MMAP_COHERENT, there's no
need to define it privately anymore.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
sound/core/pcm_native.c | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)
Hi Eiraku-san,
Could you please add this cleanup patch to your "Use dma_mmap_coherent to
support IOMMU mapper" series ?
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 53b5ada..84ead60 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3156,13 +3156,6 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
.fault = snd_pcm_mmap_data_fault,
};
-#ifndef ARCH_HAS_DMA_MMAP_COHERENT
-/* This should be defined / handled globally! */
-#ifdef CONFIG_ARM
-#define ARCH_HAS_DMA_MMAP_COHERENT
-#endif
-#endif
-
/*
* mmap the DMA buffer on RAM
*/
--
Regards,
Laurent Pinchart
^ permalink raw reply related
* [PATCH v2 0/4] Use dma_mmap_coherent to support IOMMU mapper
From: Hideki EIRAKU @ 2012-07-26 11:13 UTC (permalink / raw)
To: Russell King, Pawel Osciak, Marek Szyprowski, Kyungmin Park,
Mauro Carvalho Chehab, Florian Tobias Schandinat, Jaroslav Kysela,
Takashi Iwai
Cc: linux-arm-kernel, linux-kernel, linux-media, linux-fbdev,
alsa-devel, Katsuya MATSUBARA, Hideki EIRAKU
There is a dma_mmap_coherent() API in some architectures. This API
provides a mmap function for memory allocated by dma_alloc_coherent().
Some drivers mmap a dma_addr_t returned by dma_alloc_coherent() as a
physical address. But such drivers do not work correctly when IOMMU
mapper is used.
v2:
- Rebase on fbdev-next branch of
git://github.com/schandinat/linux-2.6.git.
- Initialize .fb_mmap in both sh_mobile_lcdc_overlay_ops and
sh_mobile_lcdc_ops.
- Add Laurent's clean up patch.
Hideki EIRAKU (3):
ARM: dma-mapping: define ARCH_HAS_DMA_MMAP_COHERENT
media: videobuf2-dma-contig: use dma_mmap_coherent if available
fbdev: sh_mobile_lcdc: use dma_mmap_coherent if available
Laurent Pinchart (1):
ALSA: pcm - Don't define ARCH_HAS_DMA_MMAP_COHERENT privately for ARM
arch/arm/include/asm/dma-mapping.h | 1 +
drivers/media/video/videobuf2-dma-contig.c | 18 ++++++++++++++++++
drivers/video/sh_mobile_lcdcfb.c | 28 ++++++++++++++++++++++++++++
sound/core/pcm_native.c | 7 -------
4 files changed, 47 insertions(+), 7 deletions(-)
^ permalink raw reply
* [PATCH v2 1/4] ARM: dma-mapping: define ARCH_HAS_DMA_MMAP_COHERENT
From: Hideki EIRAKU @ 2012-07-26 11:13 UTC (permalink / raw)
To: Russell King, Pawel Osciak, Marek Szyprowski, Kyungmin Park,
Mauro Carvalho Chehab, Florian Tobias Schandinat, Jaroslav Kysela,
Takashi Iwai
Cc: linux-arm-kernel, linux-kernel, linux-media, linux-fbdev,
alsa-devel, Katsuya MATSUBARA, Hideki EIRAKU
In-Reply-To: <1343301191-26001-1-git-send-email-hdk@igel.co.jp>
ARCH_HAS_DMA_MMAP_COHERENT indicates that there is dma_mmap_coherent() API
in this architecture. The name is already defined in PowerPC.
Signed-off-by: Hideki EIRAKU <hdk@igel.co.jp>
---
arch/arm/include/asm/dma-mapping.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index bbef15d..f41cd30 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -187,6 +187,7 @@ extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
struct dma_attrs *attrs);
#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
+#define ARCH_HAS_DMA_MMAP_COHERENT
static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr,
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 2/4] ALSA: pcm - Don't define ARCH_HAS_DMA_MMAP_COHERENT privately for ARM
From: Hideki EIRAKU @ 2012-07-26 11:13 UTC (permalink / raw)
To: Russell King, Pawel Osciak, Marek Szyprowski, Kyungmin Park,
Mauro Carvalho Chehab, Florian Tobias Schandinat, Jaroslav Kysela,
Takashi Iwai
Cc: linux-arm-kernel, linux-kernel, linux-media, linux-fbdev,
alsa-devel, Katsuya MATSUBARA, Laurent Pinchart
In-Reply-To: <1343301191-26001-1-git-send-email-hdk@igel.co.jp>
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
The ARM architecture now defines ARCH_HAS_DMA_MMAP_COHERENT, there's no
need to define it privately anymore.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
sound/core/pcm_native.c | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 53b5ada..84ead60 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3156,13 +3156,6 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
.fault = snd_pcm_mmap_data_fault,
};
-#ifndef ARCH_HAS_DMA_MMAP_COHERENT
-/* This should be defined / handled globally! */
-#ifdef CONFIG_ARM
-#define ARCH_HAS_DMA_MMAP_COHERENT
-#endif
-#endif
-
/*
* mmap the DMA buffer on RAM
*/
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 3/4] media: videobuf2-dma-contig: use dma_mmap_coherent if available
From: Hideki EIRAKU @ 2012-07-26 11:13 UTC (permalink / raw)
To: Russell King, Pawel Osciak, Marek Szyprowski, Kyungmin Park,
Mauro Carvalho Chehab, Florian Tobias Schandinat, Jaroslav Kysela,
Takashi Iwai
Cc: linux-arm-kernel, linux-kernel, linux-media, linux-fbdev,
alsa-devel, Katsuya MATSUBARA, Hideki EIRAKU
In-Reply-To: <1343301191-26001-1-git-send-email-hdk@igel.co.jp>
Previously the vb2_dma_contig_mmap() function was using a dma_addr_t as a
physical address. The two addressses are not necessarily the same.
For example, when using the IOMMU funtion on certain platforms, dma_addr_t
addresses are not directly mappable physical address.
dma_mmap_coherent() maps the address correctly.
It is available on ARM platforms.
Signed-off-by: Hideki EIRAKU <hdk@igel.co.jp>
---
drivers/media/video/videobuf2-dma-contig.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c
index 4b71326..4dc85ab 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -101,14 +101,32 @@ static unsigned int vb2_dma_contig_num_users(void *buf_priv)
static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
{
struct vb2_dc_buf *buf = buf_priv;
+#ifdef ARCH_HAS_DMA_MMAP_COHERENT
+ int ret;
+#endif
if (!buf) {
printk(KERN_ERR "No buffer to map\n");
return -EINVAL;
}
+#ifdef ARCH_HAS_DMA_MMAP_COHERENT
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ ret = dma_mmap_coherent(buf->conf->dev, vma, buf->vaddr, buf->dma_addr,
+ buf->size);
+ if (ret) {
+ pr_err("Remapping memory failed, error: %d\n", ret);
+ return ret;
+ }
+ vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+ vma->vm_private_data = &buf->handler;
+ vma->vm_ops = &vb2_common_vm_ops;
+ vma->vm_ops->open(vma);
+ return 0;
+#else
return vb2_mmap_pfn_range(vma, buf->dma_addr, buf->size,
&vb2_common_vm_ops, &buf->handler);
+#endif
}
static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 4/4] fbdev: sh_mobile_lcdc: use dma_mmap_coherent if available
From: Hideki EIRAKU @ 2012-07-26 11:13 UTC (permalink / raw)
To: Russell King, Pawel Osciak, Marek Szyprowski, Kyungmin Park,
Mauro Carvalho Chehab, Florian Tobias Schandinat, Jaroslav Kysela,
Takashi Iwai
Cc: linux-arm-kernel, linux-kernel, linux-media, linux-fbdev,
alsa-devel, Katsuya MATSUBARA, Hideki EIRAKU
In-Reply-To: <1343301191-26001-1-git-send-email-hdk@igel.co.jp>
fb_mmap() implemented in fbmem.c uses smem_start as the physical
address of the frame buffer. In the sh_mobile_lcdc driver, the
smem_start is a dma_addr_t that is not a physical address when IOMMU is
enabled. dma_mmap_coherent() maps the address correctly. It is
available on ARM platforms.
Signed-off-by: Hideki EIRAKU <hdk@igel.co.jp>
---
drivers/video/sh_mobile_lcdcfb.c | 28 ++++++++++++++++++++++++++++
1 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 8cb653b..c8cba7a 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1614,6 +1614,17 @@ static int sh_mobile_lcdc_overlay_blank(int blank, struct fb_info *info)
return 1;
}
+#ifdef ARCH_HAS_DMA_MMAP_COHERENT
+static int
+sh_mobile_lcdc_overlay_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct sh_mobile_lcdc_overlay *ovl = info->par;
+
+ return dma_mmap_coherent(ovl->channel->lcdc->dev, vma, ovl->fb_mem,
+ ovl->dma_handle, ovl->fb_size);
+}
+#endif
+
static struct fb_ops sh_mobile_lcdc_overlay_ops = {
.owner = THIS_MODULE,
.fb_read = fb_sys_read,
@@ -1626,6 +1637,9 @@ static struct fb_ops sh_mobile_lcdc_overlay_ops = {
.fb_ioctl = sh_mobile_lcdc_overlay_ioctl,
.fb_check_var = sh_mobile_lcdc_overlay_check_var,
.fb_set_par = sh_mobile_lcdc_overlay_set_par,
+#ifdef ARCH_HAS_DMA_MMAP_COHERENT
+ .fb_mmap = sh_mobile_lcdc_overlay_mmap,
+#endif
};
static void
@@ -2093,6 +2107,17 @@ static int sh_mobile_lcdc_blank(int blank, struct fb_info *info)
return 0;
}
+#ifdef ARCH_HAS_DMA_MMAP_COHERENT
+static int
+sh_mobile_lcdc_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+ struct sh_mobile_lcdc_chan *ch = info->par;
+
+ return dma_mmap_coherent(ch->lcdc->dev, vma, ch->fb_mem,
+ ch->dma_handle, ch->fb_size);
+}
+#endif
+
static struct fb_ops sh_mobile_lcdc_ops = {
.owner = THIS_MODULE,
.fb_setcolreg = sh_mobile_lcdc_setcolreg,
@@ -2108,6 +2133,9 @@ static struct fb_ops sh_mobile_lcdc_ops = {
.fb_release = sh_mobile_lcdc_release,
.fb_check_var = sh_mobile_lcdc_check_var,
.fb_set_par = sh_mobile_lcdc_set_par,
+#ifdef ARCH_HAS_DMA_MMAP_COHERENT
+ .fb_mmap = sh_mobile_lcdc_mmap,
+#endif
};
static void
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH v2 4/4] fbdev: sh_mobile_lcdc: use dma_mmap_coherent if available
From: Laurent Pinchart @ 2012-07-26 11:20 UTC (permalink / raw)
To: Hideki EIRAKU
Cc: alsa-devel, Katsuya MATSUBARA, linux-fbdev, Russell King,
linux-media, Pawel Osciak, Florian Tobias Schandinat,
Takashi Iwai, linux-kernel, Mauro Carvalho Chehab, Kyungmin Park,
linux-arm-kernel, Marek Szyprowski
In-Reply-To: <1343301191-26001-5-git-send-email-hdk@igel.co.jp>
Hi Eiraku-san,
On Thursday 26 July 2012 20:13:11 Hideki EIRAKU wrote:
> fb_mmap() implemented in fbmem.c uses smem_start as the physical
> address of the frame buffer. In the sh_mobile_lcdc driver, the
> smem_start is a dma_addr_t that is not a physical address when IOMMU is
> enabled. dma_mmap_coherent() maps the address correctly. It is
> available on ARM platforms.
>
> Signed-off-by: Hideki EIRAKU <hdk@igel.co.jp>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
--
Regards,
Laurent Pinchart
^ permalink raw reply
* [PATCH] fbdev: sh_mobile_lcdc: Fix vertical panning step
From: Laurent Pinchart @ 2012-07-26 12:36 UTC (permalink / raw)
To: linux-fbdev
Commit 15dede882e564601947f2ce4b647742c0351be6d added support for
horizontal panning but accidentally computes the Y pan step value
incorrectly for NV12/21 and NV16/61 formats. Fix this.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/video/sh_mobile_lcdcfb.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 8cb653b..699487c 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -1716,11 +1716,11 @@ sh_mobile_lcdc_overlay_fb_init(struct sh_mobile_lcdc_overlay *ovl)
info->fix.visual = FB_VISUAL_TRUECOLOR;
switch (ovl->format->fourcc) {
- case V4L2_PIX_FMT_NV16:
- case V4L2_PIX_FMT_NV61:
- info->fix.ypanstep = 2;
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
+ info->fix.ypanstep = 2;
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
info->fix.xpanstep = 2;
}
@@ -2215,11 +2215,11 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch,
info->fix.visual = FB_VISUAL_TRUECOLOR;
switch (ch->format->fourcc) {
- case V4L2_PIX_FMT_NV16:
- case V4L2_PIX_FMT_NV61:
- info->fix.ypanstep = 2;
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
+ info->fix.ypanstep = 2;
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
info->fix.xpanstep = 2;
}
--
Regards,
Laurent Pinchart
^ permalink raw reply related
* Re: [GIT PULL] SH Mobile LCDC and MERAM patches
From: Florian Tobias Schandinat @ 2012-07-26 17:14 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <2980452.38e8VA4mF5@avalon>
Hi Laurent,
On 07/24/2012 09:16 AM, Laurent Pinchart wrote:
> Hi Florian,
>
> The following changes since commit 6fcdbc0c3a683003a00f383fceac80da1b7852ff:
>
> s3fb: Add Virge/MX (86C260) (2012-07-08 14:03:50 +0000)
>
> are available in the git repository at:
> git://linuxtv.org/pinchartl/fbdev.git for-next
Merged. Should I also apply your followup patch
"[PATCH] fbdev: sh_mobile_lcdc: Fix vertical panning step"
?
Best regards,
Florian Tobias Schandinat
>
> Laurent Pinchart (9):
> sh_mobile_meram: Rename operations to cache_[alloc|free|update]
> sh_mobile_meram: Use direct function calls for the public API
> sh_mobile_meram: Add direct MERAM allocation API
> fbdev: sh_mobile_lcdc: Destroy mutex at remove time
> fbdev: sh_mobile_lcdc: Fix line pitch computation
> fbdev: sh_mobile_lcdc: Use channel configuration to initialize fb device
> fbdev: sh_mobile_lcdc: Support horizontal panning
> fbdev: sh_mobile_lcdc: Fix overlay registers update during pan operation
> fbdev: sh_mobile_lcdc: Fix pan offset computation in YUV mode
>
> drivers/video/sh_mobile_lcdcfb.c | 209 +++++++++++++++++----------------
> drivers/video/sh_mobile_lcdcfb.h | 5 +-
> drivers/video/sh_mobile_meram.c | 235 ++++++++++++++++++++-----------------
> include/video/sh_mobile_meram.h | 71 ++++++++----
> 4 files changed, 293 insertions(+), 227 deletions(-)
>
^ permalink raw reply
* Re: [GIT PULL] OMAP DSS for v3.6
From: Florian Tobias Schandinat @ 2012-07-26 17:20 UTC (permalink / raw)
To: Tomi Valkeinen; +Cc: linux-omap, linux-fbdev, Tony Lindgren, Archit Taneja
In-Reply-To: <1342980836.2284.20.camel@deskari>
Hi Tomi,
On 07/22/2012 06:13 PM, Tomi Valkeinen wrote:
> Hi Florian,
>
> Here are OMAP DSS changes for 3.6. The main changes are:
>
> - Patches from Archit, which reorganize the output side of omapdss. This
> is much cleaner in itself, but will also help us in the future to
> implement the missing omap4 features and omap5+ features.
>
> - LCD3 patches from Chandrabhanu, which implement the support for LCD3
> overlay manager (for omap5). His patches also generalize the code which
> accesses the overlay manager related registers.
>
> There hasn't been new patches applied to the DSS tree for 3 weeks, as
> I'm on vacation. The tree has been in linux-next for that period, and I
> haven't received any complaints so I hope the stuff works quite well.
> Archit also reported that he has tested the linux-next, and it seems to
> work fine.
>
> There is a small conflict, though. This was caused by the two fixes
> "OMAPDSS: fix warnings if CONFIG_PM_RUNTIME=n" and "OMAPDSS: Use PM
> notifiers for system suspend", as I had already applied them into my
> master branch before Archit sent them for you. And as you fixed the code
> formatting issue (sorry about that), we have a small conflict there.
>
> The conflict is trivial to resolve, and I also pushed for-florian-merged
> branch to the same git tree below, which has the conflict resolved.
>
> I'm still on vacation for the next week, but I'll check my email every
> now and then to see if there are any issues.
>
> Tomi
>
>
> The following changes since commit cfaf025112d3856637ff34a767ef785ef5cf2ca9:
>
> Linux 3.5-rc2 (2012-06-08 18:40:09 -0700)
>
> are available in the git repository at:
>
> git://gitorious.org/linux-omap-dss2/linux.git for-florian
Merged.
Thanks,
Florian Tobias Schandinat
>
> for you to fetch changes up to 974a65825e0b5fbda49605f0416a2c975d66e9e6:
>
> Merge "Apply LCD manager related parameters" from Archit (2012-06-29 14:13:07 +0300)
>
> ----------------------------------------------------------------
>
> Archit Taneja (27):
> OMAPDSS: Remove passive matrix LCD support (part 1)
> OMAPDSS: Remove passive matrix LCD support (part 2)
> OMAPDSS: Remove passive matrix LCD support (part 3)
> OMAPDSS: Remove passive matrix LCD support (part 4)
> OMAPDSS: Add some new fields to omap_video_timings
> OMAPDSS: DISPLAY: Ignore newly added omap_video_timings fields for display timings sysfs file
> OMAPDSS: DISPC: Configure newly added omap_video_timing fields
> OMAPDSS: DISPC: Remove dispc_mgr_set_pol_freq()
> OMAPFB: Map the newly added omap_video_timings fields with fb sync flags
> OMAPDSS: Remove omap_panel_config enum from omap_dss_device
> OMAPDSS: Add interlace parameter to omap_video_timings
> OMAPDSS: DISPC/APPLY: Use interlace info in manager timings for dispc_ovl_setup()
> OMAPFB: Map interlace field in omap_video_timings with fb vmode flags
> OMAPDSS: HDMI: Remove custom hdmi_video_timings struct
> OMAPDSS: DSI: Fix HSYNC, VSYNC and DE polarities between DISPC and DSI
> OMAPDSS: DISPC: Change return type of dispc_mgr_set_clock_div()
> OMAPDSS: Add struct to hold LCD overlay manager configuration
> OMAPDSS: DPI: Configure dss_lcd_mgr_config struct with lcd manager parameters
> OMAPDSS: RFBI: Configure dss_lcd_mgr_config struct with lcd manager parameters
> OMAPDSS: DSI: Configure dss_lcd_mgr_config struct with lcd manager parameters
> OMAPDSS: SDI: Configure dss_lcd_mgr_config struct with lcd manager parameters
> OMAPDSS: APPLY: Remove DISPC writes to manager's lcd parameters in interface drivers
> OMAPDSS: MANAGER: Check LCD related overlay manager parameters
> OMAPDSS: APPLY: Remove usage of omap_dss_device from manual/auto update checks
> OMAPDSS: DISPC: Remove a redundant function
> OMAPDSS: RFBI: Use dss_mgr_enable to enable the overlay manager
> OMAPDSS: OVERLAY: Clean up replication checking
>
> Chandrabhanu Mahapatra (5):
> OMAPDSS: Cleanup implementation of LCD channels
> OMAPDSS: Add support for LCD3 channel
> OMAPDSS: Add LCD3 overlay manager and Clock and IRQ support
> OMAPDSS: Add dump and debug support for LCD3
> ARM: OMAP2PLUS: DSS: Disable LCD3 output when resetting DSS
>
> Jassi Brar (2):
> OMAPDSS: HDMI: Discard phy_tx_enabled member
> OMAPDSS: HDMI: Replace spinlock with mutex in hdmi_check_hpd_state
>
> Peter Meerwald (1):
> OMAPDSS: fix specification spelling in Kconfig
>
> Rajendra Nayak (1):
> OMAPDSS: add clk_prepare_enable and clk_disable_unprepare
>
> Tomi Valkeinen (6):
> Merge tag 'v3.5-rc2'
> OMAPDSS: remove enum omap_dss_overlay_managers
> OMAPDSS: Use PM notifiers for system suspend
> OMAPDSS: fix warnings if CONFIG_PM_RUNTIME=n
> Merge Misc DSS clean ups from Archit
> Merge "Apply LCD manager related parameters" from Archit
>
> arch/arm/mach-omap2/display.c | 29 +-
> drivers/video/omap2/displays/panel-acx565akm.c | 10 +-
> drivers/video/omap2/displays/panel-generic-dpi.c | 179 ++++---
> .../omap2/displays/panel-lgphilips-lb035q02.c | 8 +-
> drivers/video/omap2/displays/panel-n8x0.c | 1 -
> .../omap2/displays/panel-nec-nl8048hl11-01b.c | 9 +-
> drivers/video/omap2/displays/panel-picodlp.c | 9 +-
> .../video/omap2/displays/panel-sharp-ls037v7dw01.c | 9 +-
> drivers/video/omap2/displays/panel-taal.c | 3 +-
> drivers/video/omap2/displays/panel-tfp410.c | 7 +-
> .../video/omap2/displays/panel-tpo-td043mtea1.c | 8 +-
> drivers/video/omap2/dss/Kconfig | 4 +-
> drivers/video/omap2/dss/apply.c | 91 +++-
> drivers/video/omap2/dss/core.c | 48 +-
> drivers/video/omap2/dss/dispc.c | 496 ++++++++++----------
> drivers/video/omap2/dss/dispc.h | 28 ++
> drivers/video/omap2/dss/display.c | 40 +-
> drivers/video/omap2/dss/dpi.c | 64 +--
> drivers/video/omap2/dss/dsi.c | 156 +++---
> drivers/video/omap2/dss/dss.c | 21 +-
> drivers/video/omap2/dss/dss.h | 54 ++-
> drivers/video/omap2/dss/dss_features.h | 5 +-
> drivers/video/omap2/dss/hdmi.c | 248 ++++++++--
> drivers/video/omap2/dss/hdmi_panel.c | 9 +-
> drivers/video/omap2/dss/manager.c | 51 +-
> drivers/video/omap2/dss/overlay.c | 33 +-
> drivers/video/omap2/dss/rfbi.c | 42 +-
> drivers/video/omap2/dss/sdi.c | 42 +-
> drivers/video/omap2/dss/ti_hdmi.h | 21 +-
> drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 26 +-
> drivers/video/omap2/dss/venc.c | 10 +-
> drivers/video/omap2/omapfb/omapfb-main.c | 51 +-
> include/video/omapdss.h | 51 +-
> 33 files changed, 1172 insertions(+), 691 deletions(-)
>
^ permalink raw reply
* Re: [PATCH] video: exynos_dp: use usleep_range instead of delay
From: Florian Tobias Schandinat @ 2012-07-26 17:22 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <002201cd64ca$d5bbabb0$81330310$%han@samsung.com>
On 07/18/2012 09:50 AM, Jingoo Han wrote:
> This patch replaces udelay and mdelay with usleep_range to remove
> the busy loop waiting.
>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/exynos/exynos_dp_core.c | 14 +++++++-------
> drivers/video/exynos/exynos_dp_reg.c | 4 ++--
> 2 files changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> index 9db7b9f..25907f4 100644
> --- a/drivers/video/exynos/exynos_dp_core.c
> +++ b/drivers/video/exynos/exynos_dp_core.c
> @@ -47,7 +47,7 @@ static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
>
> exynos_dp_init_hpd(dp);
>
> - udelay(200);
> + usleep_range(200, 210);
>
> while (exynos_dp_get_plug_in_status(dp) != 0) {
> timeout_loop++;
> @@ -55,7 +55,7 @@ static int exynos_dp_detect_hpd(struct exynos_dp_device *dp)
> dev_err(dp->dev, "failed to get hpd plug status\n");
> return -ETIMEDOUT;
> }
> - udelay(10);
> + usleep_range(10, 11);
> }
>
> return 0;
> @@ -486,7 +486,7 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
> u8 pre_emphasis;
> u8 training_lane;
>
> - udelay(100);
> + usleep_range(100, 101);
>
> exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
> 6, link_status);
> @@ -571,7 +571,7 @@ static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
>
> u8 adjust_request[2];
>
> - udelay(400);
> + usleep_range(400, 401);
>
> exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
> 6, link_status);
> @@ -739,7 +739,7 @@ static int exynos_dp_set_link_train(struct exynos_dp_device *dp,
> if (retval = 0)
> break;
>
> - udelay(100);
> + usleep_range(100, 110);
> }
>
> return retval;
> @@ -773,7 +773,7 @@ static int exynos_dp_config_video(struct exynos_dp_device *dp,
> return -ETIMEDOUT;
> }
>
> - udelay(1);
> + usleep_range(1, 2);
> }
>
> /* Set to use the register calculated M/N video */
> @@ -807,7 +807,7 @@ static int exynos_dp_config_video(struct exynos_dp_device *dp,
> return -ETIMEDOUT;
> }
>
> - mdelay(1);
> + usleep_range(1000, 1001);
> }
>
> if (retval != 0)
> diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
> index 6ce76d5..ce401c8 100644
> --- a/drivers/video/exynos/exynos_dp_reg.c
> +++ b/drivers/video/exynos/exynos_dp_reg.c
> @@ -122,7 +122,7 @@ void exynos_dp_reset(struct exynos_dp_device *dp)
> LS_CLK_DOMAIN_FUNC_EN_N;
> writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2);
>
> - udelay(20);
> + usleep_range(20, 30);
>
> exynos_dp_lane_swap(dp, 0);
>
> @@ -988,7 +988,7 @@ void exynos_dp_reset_macro(struct exynos_dp_device *dp)
> writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
>
> /* 10 us is the minimum reset time. */
> - udelay(10);
> + usleep_range(10, 20);
>
> reg &= ~MACRO_RST;
> writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
^ permalink raw reply
* Re: [PATCH] video: exynos_dp: check the only INTERLANE_ALIGN_DONE bit during Link Training
From: Florian Tobias Schandinat @ 2012-07-26 17:22 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <000c01cd63f8$57550000$05ff0000$%han@samsung.com>
On 07/17/2012 08:44 AM, Jingoo Han wrote:
> The only INTERLANE_ALIGN_DONE bit should be checked for channel equalization
> during Link Training. Previously, the other bits such as LINK_STATUS_UPDATED
> were checked, and channel equalization procedure was repeated unnecessarily.
>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/exynos/exynos_dp_core.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> index 9db7b9f..6ca8043 100644
> --- a/drivers/video/exynos/exynos_dp_core.c
> +++ b/drivers/video/exynos/exynos_dp_core.c
> @@ -336,7 +336,7 @@ static int exynos_dp_channel_eq_ok(u8 link_status[6], int lane_count)
> u8 lane_status;
>
> lane_align = link_status[2];
> - if ((lane_align = DPCD_INTERLANE_ALIGN_DONE) = 0)
> + if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) = 0)
> return -EINVAL;
>
> for (lane = 0; lane < lane_count; lane++) {
^ permalink raw reply
* Re: [PATCH] fb: epson1355fb: Fix section mismatch
From: Florian Tobias Schandinat @ 2012-07-26 17:23 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1342337558-9912-1-git-send-email-shc_work@mail.ru>
On 07/15/2012 07:32 AM, Alexander Shiyan wrote:
> This patch fixes "section mismatch" warning in the epson1355fb driver.
>
> WARNING: vmlinux.o(.devinit.text+0x184): Section mismatch in reference from the function epson1355fb_probe() to the function .init.text:fetch_hw_state()
> The function __devinit epson1355fb_probe() references
> a function __init fetch_hw_state().
> If fetch_hw_state is only used by epson1355fb_probe then
> annotate fetch_hw_state with a matching annotation.
>
> Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/epson1355fb.c | 8 ++++----
> 1 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
> index a268cbf..68b9b51 100644
> --- a/drivers/video/epson1355fb.c
> +++ b/drivers/video/epson1355fb.c
> @@ -477,11 +477,11 @@ static __init unsigned int get_fb_size(struct fb_info *info)
> return size;
> }
>
> -static int epson1355_width_tab[2][4] __initdata > +static int epson1355_width_tab[2][4] __devinitdata > { {4, 8, 16, -1}, {9, 12, 16, -1} };
> -static int epson1355_bpp_tab[8] __initdata = { 1, 2, 4, 8, 15, 16 };
> +static int epson1355_bpp_tab[8] __devinitdata = { 1, 2, 4, 8, 15, 16 };
>
> -static void __init fetch_hw_state(struct fb_info *info, struct epson1355_par *par)
> +static void __devinit fetch_hw_state(struct fb_info *info, struct epson1355_par *par)
> {
> struct fb_var_screeninfo *var = &info->var;
> struct fb_fix_screeninfo *fix = &info->fix;
> @@ -601,7 +601,7 @@ static int epson1355fb_remove(struct platform_device *dev)
> return 0;
> }
>
> -int __devinit epson1355fb_probe(struct platform_device *dev)
> +static int __devinit epson1355fb_probe(struct platform_device *dev)
> {
> struct epson1355_par *default_par;
> struct fb_info *info;
^ permalink raw reply
* Re: [PATCH] video: exynos_dp: fix wrong DPCD address during Link Training
From: Florian Tobias Schandinat @ 2012-07-26 17:23 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <000901cd5ff4$fa2ffbc0$ee8ff340$%han@samsung.com>
On 07/12/2012 06:10 AM, Jingoo Han wrote:
> Wrong DPCD addresses were used for clock recovery during Link Training.
> The training pattern should be set by TRAINING_PATTERN_SET (0x102), while
> voltage swing and pre-emphasis should be set by TRAINING_LANE0_SET (0x103).
>
> Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Applied.
Thanks,
Florian Tobias Schandinat
> ---
> drivers/video/exynos/exynos_dp_core.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
> index 9db7b9f..bf55e51 100644
> --- a/drivers/video/exynos/exynos_dp_core.c
> +++ b/drivers/video/exynos/exynos_dp_core.c
> @@ -304,7 +304,7 @@ static void exynos_dp_link_start(struct exynos_dp_device *dp)
> buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
> DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0;
> exynos_dp_write_bytes_to_dpcd(dp,
> - DPCD_ADDR_TRAINING_PATTERN_SET,
> + DPCD_ADDR_TRAINING_LANE0_SET,
> lane_count, buf);
> }
>
> @@ -504,7 +504,7 @@ static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
> buf[0] = DPCD_SCRAMBLING_DISABLED |
> DPCD_TRAINING_PATTERN_2;
> exynos_dp_write_byte_to_dpcd(dp,
> - DPCD_ADDR_TRAINING_LANE0_SET,
> + DPCD_ADDR_TRAINING_PATTERN_SET,
> buf[0]);
>
> for (lane = 0; lane < lane_count; lane++) {
^ permalink raw reply
* Re: [GIT PULL] SH Mobile LCDC and MERAM patches
From: Laurent Pinchart @ 2012-07-26 17:26 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <2980452.38e8VA4mF5@avalon>
Hi Florian,
On Thursday 26 July 2012 17:14:33 Florian Tobias Schandinat wrote:
> On 07/24/2012 09:16 AM, Laurent Pinchart wrote:
> > Hi Florian,
> >
> > The following changes since commit
6fcdbc0c3a683003a00f383fceac80da1b7852ff:
> > s3fb: Add Virge/MX (86C260) (2012-07-08 14:03:50 +0000)
> >
> > are available in the git repository at:
> > git://linuxtv.org/pinchartl/fbdev.git for-next
>
> Merged. Should I also apply your followup patch
> "[PATCH] fbdev: sh_mobile_lcdc: Fix vertical panning step"
> ?
I was planning to send a pull request for that one, but yes, please merge it
:-)
--
Regards,
Laurent Pinchart
^ permalink raw reply
* Re: [PATCH] video/smscufx: fix line counting in fb_write
From: Florian Tobias Schandinat @ 2012-07-26 17:26 UTC (permalink / raw)
To: Alexander Holler; +Cc: linux-kernel, linux-fbdev
In-Reply-To: <4FF211BD.8060203@ahsoftware.de>
On 07/02/2012 09:25 PM, Alexander Holler wrote:
> Hi Florian,
>
> sorry for the late answer.
>
> Am 13.05.2012 14:47, schrieb Florian Tobias Schandinat:
>> Hi Alexander,
>>
>> On 04/21/2012 11:26 AM, Alexander Holler wrote:
>>> Hello,
>>>
>>> as for the patch for udlfb, I forgot to mention that this is a candidate
>>> for all stable trees 3.2 and above.
>>>
>>> Btw., the address of the maintainer doesn't seem to be valid anymore.
>>
>> it is better to cc me on patches to the framebuffer subsystem for such
>> cases. I don't have much free time so it's rare that I come around to
>> dig in the mailing list.
>>
>>>
>>> Regards,
>>>
>>> Alexander
>>>
>>> Am 21.04.2012 00:11, schrieb Alexander Holler:
>>>> Line 0 and 1 were both written to line 0 (on the display) and all
>>>> subsequent
>>>> lines had an offset of -1. The result was that the last line on the
>>>> display
>>>> was never overwritten by writes to /dev/fbN.
>>>>
>>>> The origin of this bug seems to have been udlfb.
>>>>
>>>> Signed-off-by: Alexander Holler<holler@ahsoftware.de>
>>>
>>> Cc: stable@vger.kernel.org
>>
>> Patch looks good to me but can be made simpler.
>>
>>>
>>>> ---
>>>> drivers/video/smscufx.c | 2 +-
>>>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>>>
>>>> diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c
>>>> index ccbfef5..1e1e2d2 100644
>>>> --- a/drivers/video/smscufx.c
>>>> +++ b/drivers/video/smscufx.c
>>>> @@ -904,7 +904,7 @@ static ssize_t ufx_ops_write(struct fb_info *info,
>>>> const char __user *buf,
>>>> result = fb_sys_write(info, buf, count, ppos);
>>>>
>>>> if (result> 0) {
>>>> - int start = max((int)(offset / info->fix.line_length) - 1, 0);
>>>> + int start = max((int)(offset / info->fix.line_length), 0);
>>
>> the cast to int as well as the max is superfluous without the -1 as the
>> value can no longer be negative.
>
> I had that impression too, but I wanted to change as less as possible,
> so I didn't had the need to check types and (their) sizes for possible
> overflows or such. I was lazy and just wanted to fix that one bug. ;)
Well, as this patch fixes a bug I applied it as is.
>
>>
>>>> int lines = min((u32)((result / info->fix.line_length) + 1),
>>>> (u32)info->var.yres);
>>>>
Best regards,
Florian Tobias Schandinat
^ permalink raw reply
* [RFC][PATCH v3 0/3] Power sequences with PWM and DT support
From: Alexandre Courbot @ 2012-07-27 12:05 UTC (permalink / raw)
To: Stephen Warren, Thierry Reding, Simon Glass, Grant Likely,
Rob Herring, Greg Kroah-Hartman, Mark Brown, Arnd Bergmann
Cc: linux-tegra, linux-kernel, linux-fbdev, devicetree-discuss,
Alexandre Courbot
Widening audience for this version.
The issue addressed is that the power sequences for backlights (and probably
other devices), which were implemented using board-specific callbacks so far,
could not be used with the device tree. This series of patches adds a small
power sequence interpreter that allows to acquire and control regulators, GPIOs,
and PWMs during sequences defined in the device tree or as platform data. It is
easy to use, low-footprint, and takes care of managing the resources it
acquires. This should help making the kernel less board-dependant.
Comments are especially welcome about the DT bindings proposal, which most
certainly needs to be refined, if not completely redesigned. Documentation is
still incomplete and will consolidate once the implementation reaches a stable
state.
The tegra device tree nodes of patch 3 are just here as an example usage.
Changelog:
v3:
- Move to driver to base/
- Use sub-nodes to describe steps in the DT as suggested by Simon Glass
- Write some documentation
- Make the DT support optional
Alexandre Courbot (3):
runtime interpreted power sequences
pwm_backlight: use power sequences
tegra: add pwm backlight device tree nodes
.../bindings/video/backlight/pwm-backlight.txt | 55 +++-
Documentation/power/power_seq.txt | 120 +++++++++
arch/arm/boot/dts/tegra20-ventana.dts | 53 ++++
arch/arm/boot/dts/tegra20.dtsi | 2 +-
drivers/base/Kconfig | 4 +
drivers/base/Makefile | 1 +
drivers/base/power_seq.c | 300 +++++++++++++++++++++
drivers/video/backlight/Kconfig | 1 +
drivers/video/backlight/pwm_bl.c | 213 +++++++++++----
include/linux/power_seq.h | 139 ++++++++++
include/linux/pwm_backlight.h | 18 +-
11 files changed, 843 insertions(+), 63 deletions(-)
create mode 100644 Documentation/power/power_seq.txt
create mode 100644 drivers/base/power_seq.c
create mode 100644 include/linux/power_seq.h
--
1.7.11.3
^ permalink raw reply
* [RFC][PATCH v3 1/3] runtime interpreted power sequences
From: Alexandre Courbot @ 2012-07-27 12:05 UTC (permalink / raw)
To: Stephen Warren, Thierry Reding, Simon Glass, Grant Likely,
Rob Herring, Greg Kroah-Hartman, Mark Brown, Arnd Bergmann
Cc: linux-tegra, linux-kernel, linux-fbdev, devicetree-discuss,
Alexandre Courbot
In-Reply-To: <1343390750-3642-1-git-send-email-acourbot@nvidia.com>
Some device drivers (panel backlights especially) need to follow precise
sequences for powering on and off, involving gpios, regulators, PWMs
with a precise powering order and delays to respect between each steps.
These sequences are board-specific, and do not belong to a particular
driver - therefore they have been performed by board-specific hook
functions to far.
With the advent of the device tree and of ARM kernels that are not
board-tied, we cannot rely on these board-specific hooks anymore but
need a way to implement these sequences in a portable manner. This patch
introduces a simple interpreter that can execute such power sequences
encoded either as platform data or within the device tree.
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
Documentation/power/power_seq.txt | 120 +++++++++++++++
drivers/base/Kconfig | 4 +
drivers/base/Makefile | 1 +
drivers/base/power_seq.c | 300 ++++++++++++++++++++++++++++++++++++++
include/linux/power_seq.h | 139 ++++++++++++++++++
5 files changed, 564 insertions(+)
create mode 100644 Documentation/power/power_seq.txt
create mode 100644 drivers/base/power_seq.c
create mode 100644 include/linux/power_seq.h
diff --git a/Documentation/power/power_seq.txt b/Documentation/power/power_seq.txt
new file mode 100644
index 0000000..aa2ceb5
--- /dev/null
+++ b/Documentation/power/power_seq.txt
@@ -0,0 +1,120 @@
+Runtime Interpreted Power Sequences
+-----------------------------------
+
+Problem
+-------
+One very common board-dependent code is the out-of-driver code that is used to
+turn a device on or off. For instance, SoC boards very commonly use a GPIO
+(abstracted to a regulator or not) to control the power supply of a backlight,
+disabling it when the backlight is not used in order to save power. The GPIO
+that should be used, however, as well as the exact power sequence that may
+involve different resources, is board-dependent and thus unknown of the driver.
+
+This has been addressed so far by using hooks in the device's platform data that
+are called whenever the state of the device might reflect a power change. This
+approach, however, introduces board-dependant code into the kernel and is not
+compatible with the device tree.
+
+The Runtime Interpreted Power Sequences (or power sequences for short) aim at
+turning this code into platform data or device tree nodes. Power sequences are
+described using a simple format and run by a simple interpreter whenever needed.
+This allows to remove the callback mechanism and makes the kernel less
+board-dependant.
+
+Sequences Format
+----------------
+Power sequences are a series of sequential steps during which an action is
+performed on a resource. The supported resources so far are:
+- GPIOs
+- Regulators
+- PWMs
+
+Each step designates a resource and the following parameters:
+- Whether the step should enable or disable the resource,
+- Delay to wait before performing the action,
+- Delay to wait after performing the action.
+
+Both new resources and parameters can be introduced, but the goal is of course
+to keep things as simple and compact as possible.
+
+The platform data is a simple array of platform_power_seq_step instances, each
+instance describing a step. The type as well as one of id or gpio members
+(depending on the type) must be specified. The last step must be of type
+POWER_SEQ_STOP. Regulator and PWM resources are identified by name. GPIO are
+identified by number. For example, the following sequence will turn on the
+"power" regulator of the device, wait 10ms, and set GPIO number 110 to 1:
+
+struct platform_power_seq_step power_on_seq[] = {
+ {
+ .type = POWER_SEQ_REGULATOR,
+ .id = "power",
+ .params = {
+ .enable = 1,
+ .post_delay = 10,
+ },
+ },
+ {
+ .type = POWER_SEQ_GPIO,
+ .gpio = 110,
+ .params = {
+ .enable = 1,
+ },
+ },
+ {
+ .type = POWER_SEQ_STOP,
+ },
+};
+
+Usage by Drivers and Resources Management
+-----------------------------------------
+Power sequences make use of resources that must be properly allocated and
+managed. The power_seq_build() function takes care of resolving the resources as
+they are met in the sequence and to allocate them if needed:
+
+power_seq *power_seq_build(struct device *dev, power_seq_resources *ress,
+ platform_power_seq *pseq);
+
+You will need an instance of power_seq_resources to keep track of the resources
+that are already allocated. On success, the function returns a devm allocated
+resolved sequence that is ready to be passed to power_seq_run(). In case of
+failure, and error code is returned.
+
+A resolved power sequence returned by power_seq_build can be run by
+power_run_run():
+
+int power_seq_run(struct device *dev, power_seq *seq);
+
+It returns 0 if the sequence has successfully been run, or an error code if a
+problem occured.
+
+Finally, some resources that cannot be allocated through devm need to be freed
+manually. Therefore, be sure to call power_seq_free_resources() in your device
+remove function:
+
+void power_seq_free_resources(power_seq_resources *ress);
+
+Device tree
+-----------
+All the same, power sequences can be encoded as device tree nodes. The following
+properties and nodes are equivalent to the platform data defined previously:
+
+ power-supply = <&mydevice_reg>;
+ enable-gpio = <&gpio 6 0>;
+
+ power-on-sequence {
+ regulator@0 {
+ id = "power";
+ enable;
+ post-delay = <10>;
+ };
+ gpio@1 {
+ id = "enable-gpio";
+ enable;
+ };
+ };
+
+Note that first, the phandles of the regulator and gpio used in the sequences
+are defined as properties. Then the sequence references them through the id
+property of every step. The name of sub-properties defines the type of the step.
+Valid names are "regulator", "gpio" and "pwm". Steps must be numbered
+sequentially.
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 08b4c52..65bebfe 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -282,4 +282,8 @@ config CMA_AREAS
endif
+config POWER_SEQ
+ bool
+ default n
+
endmenu
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 5aa2d70..4c498c1 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o
ifeq ($(CONFIG_SYSFS),y)
obj-$(CONFIG_MODULES) += module.o
endif
+obj-$(CONFIG_POWER_SEQ) += power_seq.o
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
obj-$(CONFIG_REGMAP) += regmap/
obj-$(CONFIG_SOC_BUS) += soc.o
diff --git a/drivers/base/power_seq.c b/drivers/base/power_seq.c
new file mode 100644
index 0000000..6ccefa1
--- /dev/null
+++ b/drivers/base/power_seq.c
@@ -0,0 +1,300 @@
+/*
+ * power_seq.c - A simple power sequence interpreter for platform devices
+ * and device tree.
+ *
+ * Author: Alexandre Courbot <acourbot@nvidia.com>
+ *
+ * Copyright (c) 2012 NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <linux/power_seq.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/pwm.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio.h>
+
+#ifdef CONFIG_OF
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#endif
+
+static int power_seq_step_run(struct power_seq_step *step)
+{
+ int err = 0;
+
+ if (step->params.pre_delay)
+ mdelay(step->params.pre_delay);
+
+ switch (step->resource->type) {
+#ifdef CONFIG_REGULATOR
+ case POWER_SEQ_REGULATOR:
+ if (step->params.enable)
+ err = regulator_enable(step->resource->regulator);
+ else
+ err = regulator_disable(step->resource->regulator);
+ break;
+#endif
+#ifdef CONFIG_PWM
+ case POWER_SEQ_PWM:
+ if (step->params.enable)
+ err = pwm_enable(step->resource->pwm);
+ else
+ pwm_disable(step->resource->pwm);
+ break;
+#endif
+#ifdef CONFIG_GPIOLIB
+ case POWER_SEQ_GPIO:
+ gpio_set_value_cansleep(step->resource->gpio,
+ step->params.enable);
+ break;
+#endif
+ /*
+ * should never happen unless the sequence includes a step which
+ * type does not have support compiled in
+ */
+ default:
+ return -EINVAL;
+ }
+
+ if (err < 0)
+ return err;
+
+ if (step->params.post_delay)
+ mdelay(step->params.post_delay);
+
+ return 0;
+}
+
+int power_seq_run(struct device *dev, power_seq *seq)
+{
+ int err;
+
+ if (!seq) return 0;
+
+ while (seq->resource) {
+ if ((err = power_seq_step_run(seq++))) {
+ dev_err(dev, "error %d while running power sequence!\n",
+ err);
+ return err;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(power_seq_run);
+
+#ifdef CONFIG_OF
+static int of_parse_power_seq_step(struct device *dev, struct device_node *node,
+ struct platform_power_seq_step *step)
+{
+ if (of_property_read_string(node, "id", &step->id)) {
+ dev_err(dev, "missing id property!\n");
+ return -EINVAL;
+ }
+
+ if (!strcmp(node->name, "regulator")) {
+ step->type = POWER_SEQ_REGULATOR;
+#ifdef CONFIG_OF_GPIO
+ } else if (!strcmp(node->name, "gpio")) {
+ int gpio;
+
+ step->type = POWER_SEQ_GPIO;
+ gpio = of_get_named_gpio(dev->of_node, step->id, 0);
+ if (gpio < 0) {
+ dev_err(dev, "cannot resolve gpio \"%s\"\n", step->id);
+ return gpio;
+ }
+ step->gpio = gpio;
+#endif /* CONFIG_OF_GPIO */
+ } else if (!strcmp(node->name, "pwm")) {
+ step->type = POWER_SEQ_PWM;
+ } else {
+ dev_err(dev, "invalid power seq step type!\n");
+ return -EINVAL;
+ }
+
+ if (of_find_property(node, "enable", NULL)) {
+ step->params.enable = 1;
+ } else if (!of_find_property(node, "disable", NULL)) {
+ dev_err(dev, "missing enable or disable property!\n");
+ return -EINVAL;
+ }
+
+ of_property_read_u32(node, "pre-delay", &step->params.pre_delay);
+ of_property_read_u32(node, "post-delay", &step->params.post_delay);
+
+ return 0;
+}
+
+platform_power_seq *of_parse_power_seq(struct device *dev,
+ struct device_node *node)
+{
+ struct device_node *child = NULL;
+ platform_power_seq *ret;
+ int cpt = 0;
+ int err;
+
+ if (!node) return NULL;
+
+ while ((child = of_get_next_child(node, child)))
+ cpt++;
+
+ /* allocate one more step to signal end of sequence */
+ ret = devm_kzalloc(dev, sizeof(*ret) * (cpt + 1), GFP_KERNEL);
+ if (!ret)
+ return ERR_PTR(-ENOMEM);
+
+ cpt = 0;
+ while ((child = of_get_next_child(node, child))) {
+ if ((err = of_parse_power_seq_step(dev, child, &ret[cpt++])))
+ return ERR_PTR(err);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(of_parse_power_seq);
+#endif /* CONFIG_OF */
+
+static
+struct power_seq_resource * power_seq_find_resource(power_seq_resources *ress,
+ struct platform_power_seq_step *res)
+{
+ struct power_seq_resource *step;
+
+ list_for_each_entry(step, ress, list) {
+ if (step->type != res->type) continue;
+ switch (res->type) {
+ case POWER_SEQ_GPIO:
+ if (step->gpio = res->gpio)
+ return step;
+ break;
+ default:
+ if (!strcmp(step->id, res->id))
+ return step;
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+static int power_seq_allocate_resource(struct device *dev,
+ struct power_seq_resource *res)
+{
+ int err;
+
+ switch (res->type) {
+#ifdef CONFIG_REGULATOR
+ case POWER_SEQ_REGULATOR:
+ res->regulator = devm_regulator_get(dev, res->id);
+ if (IS_ERR(res->regulator)) {
+ dev_err(dev, "cannot get regulator \"%s\"\n", res->id);
+ return PTR_ERR(res->regulator);
+ }
+ break;
+#endif
+#ifdef CONFIG_PWM
+ case POWER_SEQ_PWM:
+ res->pwm = pwm_get(dev, res->id);
+ if (IS_ERR(res->pwm)) {
+ dev_err(dev, "cannot get pwm \"%s\"\n", res->id);
+ return PTR_ERR(res->pwm);
+ }
+ break;
+#endif
+#ifdef CONFIG_GPIOLIB
+ case POWER_SEQ_GPIO:
+ err = devm_gpio_request_one(dev, res->gpio, GPIOF_OUT_INIT_HIGH,
+ "backlight_gpio");
+ if (err) {
+ dev_err(dev, "cannot get gpio %d\n", res->gpio);
+ return err;
+ }
+ break;
+#endif
+ default:
+ dev_err(dev, "invalid resource type %d\n", res->type);
+ return -EINVAL;
+ break;
+ }
+
+ return 0;
+}
+
+power_seq *power_seq_build(struct device *dev, power_seq_resources *ress,
+ platform_power_seq *pseq)
+{
+ struct power_seq_step *seq = NULL, *ret;
+ struct power_seq_resource *res;
+ int cpt, err;
+
+ /* first pass to count the number of steps to allocate */
+ for (cpt = 0; pseq[cpt].type != POWER_SEQ_STOP; cpt++);
+
+ if (!cpt)
+ return seq;
+
+ /* 1 more for the STOP step */
+ ret = seq = devm_kzalloc(dev, sizeof(*seq) * (cpt + 1), GFP_KERNEL);
+ if (!seq)
+ return ERR_PTR(-ENOMEM);
+
+ for (; pseq->type != POWER_SEQ_STOP; pseq++, seq++) {
+ /* create resource node if not referenced already */
+ if (!(res = power_seq_find_resource(ress, pseq))) {
+ res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
+ if (!res)
+ return ERR_PTR(-ENOMEM);
+ res->type = pseq->type;
+
+ if (res->type = POWER_SEQ_GPIO)
+ res->gpio = pseq->gpio;
+ else
+ res->id = pseq->id;
+
+ if ((err = power_seq_allocate_resource(dev, res)) < 0)
+ return ERR_PTR(err);
+
+ list_add(&res->list, ress);
+ }
+ seq->resource = res;
+ memcpy(&seq->params, &pseq->params, sizeof(seq->params));
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(power_seq_build);
+
+void power_seq_free_resources(power_seq_resources *ress) {
+ struct power_seq_resource *res;
+
+#ifdef CONFIG_PWM
+ list_for_each_entry(res, ress, list) {
+ if (res->type = POWER_SEQ_PWM)
+ pwm_put(res->pwm);
+ }
+#endif
+}
+EXPORT_SYMBOL_GPL(power_seq_free_resources);
+
+MODULE_AUTHOR("Alexandre Courbot <acourbot@nvidia.com>");
+MODULE_DESCRIPTION("Runtime Interpreted Power Sequences");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/power_seq.h b/include/linux/power_seq.h
new file mode 100644
index 0000000..da0593a
--- /dev/null
+++ b/include/linux/power_seq.h
@@ -0,0 +1,139 @@
+/*
+ * power_seq.h
+ *
+ * Simple interpreter for defining power sequences as platform data or device
+ * tree properties. Initially designed for use with backlight drivers.
+ *
+ * Power sequences are designed to replace the callbacks typically used in
+ * board-specific files that implement board-specific power sequences of devices
+ * such as backlights. A power sequence is an array of resources (which can a
+ * regulator, a GPIO, a PWM, ...) with an action to perform on it (enable or
+ * disable) and optional pre and post step delays. By having them interpreted
+ * instead of arbitrarily executed, it is possible to describe these in the
+ * device tree and thus remove board-specific code from the kernel.
+ *
+ * Author: Alexandre Courbot <acourbot@nvidia.com>
+ *
+ * Copyright (c) 2012 NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef __LINUX_POWER_SEQ_H
+#define __LINUX_POWER_SEQ_H
+
+#include <linux/types.h>
+
+struct device;
+struct regulator;
+struct pwm_device;
+struct device_node;
+
+/**
+ * The different kinds of resources that can be controlled during the sequences.
+ */
+typedef enum {
+ POWER_SEQ_STOP = 0,
+ POWER_SEQ_REGULATOR,
+ POWER_SEQ_PWM,
+ POWER_SEQ_GPIO,
+ POWER_SEQ_MAX,
+} power_res_type;
+
+struct power_seq_resource {
+ power_res_type type;
+ /* name to resolve for resources with a name (regulator, pwm) */
+ const char *id;
+ /* resolved resource */
+ union {
+ struct regulator *regulator;
+ struct pwm_device *pwm;
+ int gpio;
+ };
+ /* used to maintain the list of resources used by the driver */
+ struct list_head list;
+};
+typedef struct list_head power_seq_resources;
+
+struct power_step_params {
+ /* enable the resource if 1, disable if 0 */
+ bool enable;
+ /* delay (in ms) to wait before executing the step */
+ int pre_delay;
+ /* delay (in ms) to wait after executing the step */
+ int post_delay;
+};
+
+/**
+ * Platform definition of power sequences. A sequence is an array of these,
+ * terminated by a STOP instance.
+ */
+struct platform_power_seq_step {
+ power_res_type type;
+ union {
+ /* Used by REGULATOR and PWM types to name the resource */
+ const char *id;
+ /* Used by GPIO */
+ int gpio;
+ };
+ struct power_step_params params;
+};
+typedef struct platform_power_seq_step platform_power_seq;
+
+/**
+ * Power sequence steps resolved against their resource. Built by
+ * power_seq_build and used to run the sequence.
+ */
+struct power_seq_step {
+ struct power_seq_resource *resource;
+ struct power_step_params params;
+};
+typedef struct power_seq_step power_seq;
+
+#ifdef CONFIG_OF
+/**
+ * Build a platform data sequence from a device tree node. Memory for the
+ * sequence is allocated using devm_kzalloc on dev.
+ */
+platform_power_seq *of_parse_power_seq(struct device *dev,
+ struct device_node *node);
+#else
+platform_power_seq *of_parse_power_seq(struct device *dev,
+ struct device_node *node)
+{
+ return NULL;
+}
+#endif
+
+/**
+ * Build a runnable power sequence from platform data, and add the resources
+ * it uses into ress. Memory for the sequence is allocated using devm_kzalloc
+ * on dev.
+ */
+power_seq *power_seq_build(struct device *dev, power_seq_resources *ress,
+ platform_power_seq *pseq);
+
+/**
+ * Free all the resources previously allocated by power_seq_allocate_resources.
+ */
+void power_seq_free_resources(power_seq_resources *ress);
+
+/**
+ * Run the given power sequence. Returns 0 on success, error code in case of
+ * failure.
+ */
+int power_seq_run(struct device *dev, power_seq *seq);
+
+#endif
--
1.7.11.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox