[GIT PULL] Staging/IIO driver fixes for 5.0-rc6

2019-02-08 Thread Greg KH
The following changes since commit f17b5f06cb92ef2250513a1e154c47b78df07d40:

  Linux 5.0-rc4 (2019-01-27 15:18:05 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 
tags/staging-5.0-rc6

for you to fetch changes up to 6d923f8fe821c0c6b5378635cbcc9da5f5ec520a:

  Merge tag 'iio-fixes-5.0a' of 
git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus 
(2019-02-03 13:10:41 +0100)


Staging/IIO driver fixes for 5.0-rc6

Here are some small iio and staging driver fixes for 5.0-rc6.

Nothing big, just resolve some reported IIO driver issues, and one
staging driver bug.  One staging driver patch was added and then
reverted as well.

All of these have been in linux-next for a while with no reported
issues.

Signed-off-by: Greg Kroah-Hartman 


Aaro Koskinen (1):
  staging: octeon: fix broken phylib usage

Dan Murphy (1):
  iio: ti-ads8688: Update buffer allocation for timestamps

Gao Xiang (1):
  staging: erofs: keep corrupted fs from crashing kernel in erofs_namei()

Greg Kroah-Hartman (2):
  Revert "staging: erofs: keep corrupted fs from crashing kernel in 
erofs_namei()"
  Merge tag 'iio-fixes-5.0a' of git://git.kernel.org/.../jic23/iio into 
staging-linus

Hans de Goede (1):
  iio: adc: axp288: Fix TS-pin handling

Martin Kelly (1):
  tools: iio: iio_generic_buffer: make num_loops signed

Matt Ranostay (1):
  iio: chemical: atlas-ph-sensor: correct IIO_TEMP values to millicelsius

 drivers/iio/adc/axp288_adc.c   | 76 +++---
 drivers/iio/adc/ti-ads8688.c   |  3 +-
 drivers/iio/chemical/atlas-ph-sensor.c |  7 ++--
 drivers/staging/octeon/ethernet-mdio.c |  2 +-
 tools/iio/iio_generic_buffer.c |  2 +-
 5 files changed, 67 insertions(+), 23 deletions(-)
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v2 0/7] binder: eliminate use of vmalloc space for binder buffers

2019-02-08 Thread Greg KH
On Wed, Jan 30, 2019 at 02:46:48PM -0800, Todd Kjos wrote:
> Binder buffers have always been mapped into kernel space
> via map_kernel_range_noflush() to allow the binder driver
> to modify the buffer before posting to userspace for
> processing.
> 
> In recent Android releases, the number of long-running
> binder processes has increased to the point that for
> 32-bit systems, there is a risk of running out of
> vmalloc space.
> 
> This patch set removes the persistent mapping of the
> binder buffers into kernel space. Instead, the binder
> driver creates temporary mappings with kmap() or
> kmap_atomic() to copy to or from the buffer only when
> necessary.

This patch series blows up when I apply it to my char-misc-next branch:

drivers/android/binder_alloc_selftest.c: In function 
‘check_buffer_pages_allocated’:
drivers/android/binder_alloc_selftest.c:108:44: error: ‘struct binder_buffer’ 
has no member named ‘data’
  end = (void *)PAGE_ALIGN((uintptr_t)buffer->data + size);
^~
Did you forget to enable CONFIG_ANDROID_BINDER_IPC_SELFTEST when doing your
builds?

thanks,

greg k-h
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] staging: android: ashmem: Don't allow range_alloc() to fail.

2019-02-08 Thread Joel Fernandes
On Wed, Feb 06, 2019 at 08:45:32AM +0900, Tetsuo Handa wrote:
> Joel Fernandes wrote:
> > On Tue, Feb 05, 2019 at 07:28:41PM +0900, Tetsuo Handa wrote:
> > > ashmem_pin() is calling range_shrink() without checking whether
> > > range_alloc() succeeded. Since memory allocation fault injection might
> > > force range_alloc() to fail while range_alloc() is called for only once
> > > for one ioctl() request, make range_alloc() not to fail.
> > 
> > Why does this not need to fail? I am worried your change will introduce
> > unwanted endless looping in the kernel instead of gracefully failing a
> > pin/unpin request.
> 
> This patch won't introduce endless looping in the kernel, due to a rule called
> 
>   The "too small to fail" memory-allocation rule
>   https://lwn.net/Articles/627419/
> 
> . In short, memory allocation by range_alloc() might fail only if current 
> thread
> was killed by the OOM killer or memory allocation fault injection mechanism
> forced it to fail. And this patch helps doing fuzzing test with minimal 
> changes.
> 
> > 
> > Unless there is a good reason, I suggest to drop this patch from the series;
> > but let us discuss more if you want.
> 
> We can allocate memory for range_alloc() before holding ashmem_mutex at
> ashmem_pin_unpin() if you don't want to use __GFP_NOFAIL. It is better to
> avoid memory allocation with ashmem_mutex because ashmem_mutex is held by
> shrinker function. But given that this module is going to be replaced shortly,
> does it worth moving the memory allocation to the caller?

Even if memory allocation does not fail right now, I still want to return the
error code correctly via ashmem_pin_unpin() so that if in the future there
are changes to the allocator algorithm, then a silent success isn't reported
when a failure should be reported..

It doesn't make sense to return success when an allocation failed.. even if
you are asking this code to rely on the allocator's "too small to fail"
behavior.. can we guarantee this allocator behavior will always exist?
Probably not.

thanks,

 - Joel

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/3] gpu: ipu-v3: ipu-ic: Add support for BT.709 encoding

2019-02-08 Thread Tim Harvey
On Sun, Feb 3, 2019 at 11:48 AM Steve Longerbeam  wrote:
>
> Pass v4l2 encoding enum to the ipu_ic task init functions, and add
> support for the BT.709 encoding and inverse encoding matrices.
>
> Reported-by: Tim Harvey 
> Signed-off-by: Steve Longerbeam 
> ---
>  drivers/gpu/ipu-v3/ipu-ic.c | 67 ++---
>  drivers/gpu/ipu-v3/ipu-image-convert.c  |  1 +
>  drivers/staging/media/imx/imx-ic-prpencvf.c |  4 +-
>  include/video/imx-ipu-v3.h  |  5 +-
>  4 files changed, 67 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/ipu-v3/ipu-ic.c
> index 35ae86ff0585..63362b4fff81 100644
> --- a/drivers/gpu/ipu-v3/ipu-ic.c
> +++ b/drivers/gpu/ipu-v3/ipu-ic.c
> @@ -199,6 +199,23 @@ static const struct ic_csc_params ic_csc_rgb2ycbcr_bt601 
> = {
> .scale = 1,
>  };
>
> +/*
> + * BT.709 encoding from RGB full range to YUV limited range:
> + *
> + * Y = R *  .2126 + G *  .7152 + B *  .0722;
> + * U = R * -.1146 + G * -.3854 + B *  .5000 + 128.;
> + * V = R *  .5000 + G * -.4542 + B * -.0458 + 128.;
> + */
> +static const struct ic_csc_params ic_csc_rgb2ycbcr_bt709 = {
> +   .coeff = {
> +   { 54, 183, 18 },
> +   { 483, 413, 128 },
> +   { 128, 396, 500 },
> +   },
> +   .offset = { 0, 512, 512 },
> +   .scale = 1,
> +};
> +
>  /* transparent RGB->RGB matrix for graphics combining */
>  static const struct ic_csc_params ic_csc_rgb2rgb = {
> .coeff = {
> @@ -226,12 +243,31 @@ static const struct ic_csc_params 
> ic_csc_ycbcr2rgb_bt601 = {
> .scale = 2,
>  };
>
> +/*
> + * Inverse BT.709 encoding from YUV limited range to RGB full range:
> + *
> + * R = (1. * (Y - 16)) + (1.5748 * (Cr - 128));
> + * G = (1. * (Y - 16)) - (0.1873 * (Cb - 128)) - (0.4681 * (Cr - 128));
> + * B = (1. * (Y - 16)) + (1.8556 * (Cb - 128);
> + */
> +static const struct ic_csc_params ic_csc_ycbcr2rgb_bt709 = {
> +   .coeff = {
> +   { 128, 0, 202 },
> +   { 128, 488, 452 },
> +   { 128, 238, 0 },
> +   },
> +   .offset = { -435, 136, -507 },
> +   .scale = 2,
> +};
> +
>  static int init_csc(struct ipu_ic *ic,
> enum ipu_color_space inf,
> enum ipu_color_space outf,
> +   enum v4l2_ycbcr_encoding encoding,
> int csc_index)
>  {
> struct ipu_ic_priv *priv = ic->priv;
> +   const struct ic_csc_params *params_rgb2yuv, *params_yuv2rgb;
> const struct ic_csc_params *params;
> u32 __iomem *base;
> const u16 (*c)[3];
> @@ -241,10 +277,24 @@ static int init_csc(struct ipu_ic *ic,
> base = (u32 __iomem *)
> (priv->tpmem_base + ic->reg->tpmem_csc[csc_index]);
>
> +   switch (encoding) {
> +   case V4L2_YCBCR_ENC_601:
> +   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt601;
> +   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt601;
> +   break;
> +   case V4L2_YCBCR_ENC_709:
> +   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt709;
> +   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt709;
> +   break;
> +   default:
> +   dev_err(priv->ipu->dev, "Unsupported YCbCr encoding\n");
> +   return -EINVAL;
> +   }
> +

Steve,

This will fail for RGB to RGB with 'Unsupported YCbCr encoding. We
need to account for the RGB->RGB case.

How about something like:

 static int init_csc(struct ipu_ic *ic,
enum ipu_color_space inf,
enum ipu_color_space outf,
+   enum v4l2_ycbcr_encoding encoding,
int csc_index)
 {
struct ipu_ic_priv *priv = ic->priv;
-   const struct ic_csc_params *params;
+   const struct ic_csc_params *params = NULL;
u32 __iomem *base;
const u16 (*c)[3];
const u16 *a;
@@ -241,13 +276,18 @@ static int init_csc(struct ipu_ic *ic,
base = (u32 __iomem *)
(priv->tpmem_base + ic->reg->tpmem_csc[csc_index]);

-   if (inf == IPUV3_COLORSPACE_YUV && outf == IPUV3_COLORSPACE_RGB)
-   params = &ic_csc_ycbcr2rgb_bt601;
-   else if (inf == IPUV3_COLORSPACE_RGB && outf == IPUV3_COLORSPACE_YUV)
-   params = &ic_csc_rgb2ycbcr_bt601;
+   if (inf == IPUV3_COLORSPACE_YUV && outf == IPUV3_COLORSPACE_RGB) {
+   params = (encoding == V4L2_YCBCR_ENC_601) ?
+   &ic_csc_ycbcr2rgb_bt601 : &ic_csc_ycbcr2rgb_bt709;
+   }
+   else if (inf == IPUV3_COLORSPACE_RGB && outf == IPUV3_COLORSPACE_YUV) {
+   params = (encoding == V4L2_YCBCR_ENC_601) ?
+   &ic_csc_rgb2ycbcr_bt601 : &ic_csc_rgb2ycbcr_bt709;
+   }
else if (inf == IPUV3_COLORSPACE_RGB && outf == IPUV3_COLORSPACE_RGB)
params = &ic_csc_rgb2rgb;
-   else {
+
+   if (!params) {
dev_err(priv->ipu->dev, "Unsupported co

Re: [PATCH v2 0/7] binder: eliminate use of vmalloc space for binder buffers

2019-02-08 Thread Todd Kjos
On Fri, Feb 8, 2019 at 3:26 AM Greg KH  wrote:
>
> On Wed, Jan 30, 2019 at 02:46:48PM -0800, Todd Kjos wrote:
> > Binder buffers have always been mapped into kernel space
> > via map_kernel_range_noflush() to allow the binder driver
> > to modify the buffer before posting to userspace for
> > processing.
> >
> > In recent Android releases, the number of long-running
> > binder processes has increased to the point that for
> > 32-bit systems, there is a risk of running out of
> > vmalloc space.
> >
> > This patch set removes the persistent mapping of the
> > binder buffers into kernel space. Instead, the binder
> > driver creates temporary mappings with kmap() or
> > kmap_atomic() to copy to or from the buffer only when
> > necessary.
>
> This patch series blows up when I apply it to my char-misc-next branch:
>
> drivers/android/binder_alloc_selftest.c: In function 
> ‘check_buffer_pages_allocated’:
> drivers/android/binder_alloc_selftest.c:108:44: error: ‘struct binder_buffer’ 
> has no member named ‘data’
>   end = (void *)PAGE_ALIGN((uintptr_t)buffer->data + size);
> ^~
> Did you forget to enable CONFIG_ANDROID_BINDER_IPC_SELFTEST when doing your
> builds?

I did forget. Thanks for catching this. I'll repost with the fix.

-Todd

>
> thanks,
>
> greg k-h
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 2/7] binder: add functions to copy to/from binder buffers

2019-02-08 Thread Todd Kjos
Avoid vm_area when copying to or from binder buffers.
Instead, new copy functions are added that copy from
kernel space to binder buffer space. These use
kmap_atomic() and kunmap_atomic() to create temporary
mappings and then memcpy() is used to copy within
that page.

Also, kmap_atomic() / kunmap_atomic() use the appropriate
cache flushing to support VIVT cache architectures.
Allow binder to build if CPU_CACHE_VIVT is defined.

Several uses of the new functions are added here. More
to follow in subsequent patches.

Signed-off-by: Todd Kjos 
---
v2: remove casts as suggested by Dan Carpenter

 drivers/android/Kconfig|   2 +-
 drivers/android/binder.c   | 119 +
 drivers/android/binder_alloc.c |  59 
 drivers/android/binder_alloc.h |  12 
 4 files changed, 147 insertions(+), 45 deletions(-)

diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig
index 4c190f8d1f4c6..6fdf2abe4598a 100644
--- a/drivers/android/Kconfig
+++ b/drivers/android/Kconfig
@@ -10,7 +10,7 @@ if ANDROID
 
 config ANDROID_BINDER_IPC
bool "Android Binder IPC Driver"
-   depends on MMU && !CPU_CACHE_VIVT
+   depends on MMU
default n
---help---
  Binder is used in Android for both communication between processes,
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index ab0b3eec363bc..74d0c1ff874e2 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2244,14 +2244,22 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
off_end = (void *)off_start + buffer->offsets_size;
for (offp = off_start; offp < off_end; offp++) {
struct binder_object_header *hdr;
-   size_t object_size = binder_validate_object(buffer, *offp);
-
+   size_t object_size;
+   binder_size_t object_offset;
+   binder_size_t buffer_offset = (uintptr_t)offp -
+   (uintptr_t)buffer->data;
+
+   binder_alloc_copy_from_buffer(&proc->alloc, &object_offset,
+ buffer, buffer_offset,
+ sizeof(object_offset));
+   object_size = binder_validate_object(buffer, object_offset);
if (object_size == 0) {
pr_err("transaction release %d bad object at offset 
%lld, size %zd\n",
-  debug_id, (u64)*offp, buffer->data_size);
+  debug_id, (u64)object_offset, buffer->data_size);
continue;
}
-   hdr = (struct binder_object_header *)(buffer->data + *offp);
+   hdr = (struct binder_object_header *)
+   (buffer->data + object_offset);
switch (hdr->type) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER: {
@@ -2359,8 +2367,20 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
continue;
}
fd_array = (u32 *)(parent_buffer + 
(uintptr_t)fda->parent_offset);
-   for (fd_index = 0; fd_index < fda->num_fds; fd_index++)
-   binder_deferred_fd_close(fd_array[fd_index]);
+   for (fd_index = 0; fd_index < fda->num_fds;
+fd_index++) {
+   u32 fd;
+   binder_size_t offset =
+   (uintptr_t)&fd_array[fd_index] -
+   (uintptr_t)buffer->data;
+
+   binder_alloc_copy_from_buffer(&proc->alloc,
+ &fd,
+ buffer,
+ offset,
+ sizeof(fd));
+   binder_deferred_fd_close(fd);
+   }
} break;
default:
pr_err("transaction release %d bad object type %x\n",
@@ -2496,7 +2516,7 @@ static int binder_translate_handle(struct 
flat_binder_object *fp,
return ret;
 }
 
-static int binder_translate_fd(u32 *fdp,
+static int binder_translate_fd(u32 fd, binder_size_t fd_offset,
   struct binder_transaction *t,
   struct binder_thread *thread,
   struct binder_transaction *in_reply_to)
@@ -2507,7 +2527,6 @@ static int binder_translate_fd(u32 *fdp,
struct file *file;
int ret = 0;
bool target_allows_fd;
-   int fd = *fdp;
 
if (in_reply_to)
target_allows_fd = !!(in_reply_to->flags & TF_ACCEPT_FDS);
@@ -2546,7 +2

[PATCH v3 3/7] binder: add function to copy binder object from buffer

2019-02-08 Thread Todd Kjos
When creating or tearing down a transaction, the binder driver
examines objects in the buffer and takes appropriate action.
To do this without needing to dereference pointers into the
buffer, the local copies of the objects are needed. This patch
introduces a function to validate and copy binder objects
from the buffer to a local structure.

Signed-off-by: Todd Kjos 
---
v2: remove casts as suggested by Dan Carpenter

 drivers/android/binder.c | 75 +++-
 1 file changed, 58 insertions(+), 17 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 74d0c1ff874e2..8063b405e4fa1 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -628,6 +628,26 @@ struct binder_transaction {
spinlock_t lock;
 };
 
+/**
+ * struct binder_object - union of flat binder object types
+ * @hdr:   generic object header
+ * @fbo:   binder object (nodes and refs)
+ * @fdo:   file descriptor object
+ * @bbo:   binder buffer pointer
+ * @fdao:  file descriptor array
+ *
+ * Used for type-independent object copies
+ */
+struct binder_object {
+   union {
+   struct binder_object_header hdr;
+   struct flat_binder_object fbo;
+   struct binder_fd_object fdo;
+   struct binder_buffer_object bbo;
+   struct binder_fd_array_object fdao;
+   };
+};
+
 /**
  * binder_proc_lock() - Acquire outer lock for given binder_proc
  * @proc: struct binder_proc to acquire
@@ -2017,26 +2037,33 @@ static void binder_cleanup_transaction(struct 
binder_transaction *t,
 }
 
 /**
- * binder_validate_object() - checks for a valid metadata object in a buffer.
+ * binder_get_object() - gets object and checks for valid metadata
+ * @proc:  binder_proc owning the buffer
  * @buffer:binder_buffer that we're parsing.
- * @offset:offset in the buffer at which to validate an object.
+ * @offset:offset in the @buffer at which to validate an object.
+ * @object:struct binder_object to read into
  *
  * Return: If there's a valid metadata object at @offset in @buffer, the
- * size of that object. Otherwise, it returns zero.
+ * size of that object. Otherwise, it returns zero. The object
+ * is read into the struct binder_object pointed to by @object.
  */
-static size_t binder_validate_object(struct binder_buffer *buffer, u64 offset)
+static size_t binder_get_object(struct binder_proc *proc,
+   struct binder_buffer *buffer,
+   unsigned long offset,
+   struct binder_object *object)
 {
-   /* Check if we can read a header first */
+   size_t read_size;
struct binder_object_header *hdr;
size_t object_size = 0;
 
-   if (buffer->data_size < sizeof(*hdr) ||
-   offset > buffer->data_size - sizeof(*hdr) ||
-   !IS_ALIGNED(offset, sizeof(u32)))
+   read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset);
+   if (read_size < sizeof(*hdr))
return 0;
+   binder_alloc_copy_from_buffer(&proc->alloc, object, buffer,
+ offset, read_size);
 
-   /* Ok, now see if we can read a complete object. */
-   hdr = (struct binder_object_header *)(buffer->data + offset);
+   /* Ok, now see if we read a complete object. */
+   hdr = &object->hdr;
switch (hdr->type) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER:
@@ -2245,6 +2272,7 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
for (offp = off_start; offp < off_end; offp++) {
struct binder_object_header *hdr;
size_t object_size;
+   struct binder_object object;
binder_size_t object_offset;
binder_size_t buffer_offset = (uintptr_t)offp -
(uintptr_t)buffer->data;
@@ -2252,14 +2280,14 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
binder_alloc_copy_from_buffer(&proc->alloc, &object_offset,
  buffer, buffer_offset,
  sizeof(object_offset));
-   object_size = binder_validate_object(buffer, object_offset);
+   object_size = binder_get_object(proc, buffer,
+   object_offset, &object);
if (object_size == 0) {
pr_err("transaction release %d bad object at offset 
%lld, size %zd\n",
   debug_id, (u64)object_offset, buffer->data_size);
continue;
}
-   hdr = (struct binder_object_header *)
-   (buffer->data + object_offset);
+   hdr = &object.hdr;
switch (hdr->type) {
case

[PATCH v3 5/7] binder: remove kernel vm_area for buffer space

2019-02-08 Thread Todd Kjos
Remove the kernel's vm_area and the code that maps
buffer pages into it.

Signed-off-by: Todd Kjos 
---
 drivers/android/binder_alloc.c | 40 ++
 1 file changed, 2 insertions(+), 38 deletions(-)

diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index 2eebff4be83e0..d4cbe4b3947a6 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -265,16 +265,6 @@ static int binder_update_page_range(struct binder_alloc 
*alloc, int allocate,
page->alloc = alloc;
INIT_LIST_HEAD(&page->lru);
 
-   ret = map_kernel_range_noflush((unsigned long)page_addr,
-  PAGE_SIZE, PAGE_KERNEL,
-  &page->page_ptr);
-   flush_cache_vmap((unsigned long)page_addr,
-   (unsigned long)page_addr + PAGE_SIZE);
-   if (ret != 1) {
-   pr_err("%d: binder_alloc_buf failed to map page at %pK 
in kernel\n",
-  alloc->pid, page_addr);
-   goto err_map_kernel_failed;
-   }
user_page_addr =
(uintptr_t)page_addr + alloc->user_buffer_offset;
ret = vm_insert_page(vma, user_page_addr, page[0].page_ptr);
@@ -314,8 +304,6 @@ static int binder_update_page_range(struct binder_alloc 
*alloc, int allocate,
continue;
 
 err_vm_insert_page_failed:
-   unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE);
-err_map_kernel_failed:
__free_page(page->page_ptr);
page->page_ptr = NULL;
 err_alloc_page_failed:
@@ -695,7 +683,6 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
  struct vm_area_struct *vma)
 {
int ret;
-   struct vm_struct *area;
const char *failure_string;
struct binder_buffer *buffer;
 
@@ -706,28 +693,10 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
goto err_already_mapped;
}
 
-   area = get_vm_area(vma->vm_end - vma->vm_start, VM_ALLOC);
-   if (area == NULL) {
-   ret = -ENOMEM;
-   failure_string = "get_vm_area";
-   goto err_get_vm_area_failed;
-   }
-   alloc->buffer = area->addr;
-   alloc->user_buffer_offset =
-   vma->vm_start - (uintptr_t)alloc->buffer;
+   alloc->buffer = (void *)vma->vm_start;
+   alloc->user_buffer_offset = 0;
mutex_unlock(&binder_alloc_mmap_lock);
 
-#ifdef CONFIG_CPU_CACHE_VIPT
-   if (cache_is_vipt_aliasing()) {
-   while (CACHE_COLOUR(
-   (vma->vm_start ^ (uint32_t)alloc->buffer))) {
-   pr_info("%s: %d %lx-%lx maps %pK bad alignment\n",
-   __func__, alloc->pid, vma->vm_start,
-   vma->vm_end, alloc->buffer);
-   vma->vm_start += PAGE_SIZE;
-   }
-   }
-#endif
alloc->pages = kcalloc((vma->vm_end - vma->vm_start) / PAGE_SIZE,
   sizeof(alloc->pages[0]),
   GFP_KERNEL);
@@ -760,9 +729,7 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
alloc->pages = NULL;
 err_alloc_pages_failed:
mutex_lock(&binder_alloc_mmap_lock);
-   vfree(alloc->buffer);
alloc->buffer = NULL;
-err_get_vm_area_failed:
 err_already_mapped:
mutex_unlock(&binder_alloc_mmap_lock);
binder_alloc_debug(BINDER_DEBUG_USER_ERROR,
@@ -821,12 +788,10 @@ void binder_alloc_deferred_release(struct binder_alloc 
*alloc)
 "%s: %d: page %d at %pK %s\n",
 __func__, alloc->pid, i, page_addr,
 on_lru ? "on lru" : "active");
-   unmap_kernel_range((unsigned long)page_addr, PAGE_SIZE);
__free_page(alloc->pages[i].page_ptr);
page_count++;
}
kfree(alloc->pages);
-   vfree(alloc->buffer);
}
mutex_unlock(&alloc->mutex);
if (alloc->vma_vm_mm)
@@ -988,7 +953,6 @@ enum lru_status binder_alloc_free_page(struct list_head 
*item,
 
trace_binder_unmap_kernel_start(alloc, index);
 
-   unmap_kernel_range(page_addr, PAGE_SIZE);
__free_page(page->page_ptr);
page->page_ptr = NULL;
 
-- 
2.20.1.791.gb4d0f1c61a-goog

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 6/7] binder: remove user_buffer_offset

2019-02-08 Thread Todd Kjos
Remove user_buffer_offset since there is no kernel
buffer pointer anymore.

Signed-off-by: Todd Kjos 
---
v2: remove casts as suggested by Dan Carpenter

 drivers/android/binder.c   | 39 ++
 drivers/android/binder_alloc.c | 16 ++
 drivers/android/binder_alloc.h | 23 
 3 files changed, 13 insertions(+), 65 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 98163bf5f35c7..b3d609b5935a6 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2380,7 +2380,6 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
struct binder_fd_array_object *fda;
struct binder_buffer_object *parent;
struct binder_object ptr_object;
-   uintptr_t parent_buffer;
u32 *fd_array;
size_t fd_index;
binder_size_t fd_buf_size;
@@ -2405,14 +2404,6 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
   debug_id);
continue;
}
-   /*
-* Since the parent was already fixed up, convert it
-* back to kernel address space to access it
-*/
-   parent_buffer = parent->buffer -
-   binder_alloc_get_user_buffer_offset(
-   &proc->alloc);
-
fd_buf_size = sizeof(u32) * fda->num_fds;
if (fda->num_fds >= SIZE_MAX / sizeof(u32)) {
pr_err("transaction release %d invalid number 
of fds (%lld)\n",
@@ -2426,7 +2417,8 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
   debug_id, (u64)fda->num_fds);
continue;
}
-   fd_array = (u32 *)(parent_buffer + 
(uintptr_t)fda->parent_offset);
+   fd_array = (u32 *)(uintptr_t)
+   (parent->buffer + fda->parent_offset);
for (fd_index = 0; fd_index < fda->num_fds;
 fd_index++) {
u32 fd;
@@ -2646,7 +2638,6 @@ static int binder_translate_fd_array(struct 
binder_fd_array_object *fda,
 struct binder_transaction *in_reply_to)
 {
binder_size_t fdi, fd_buf_size;
-   uintptr_t parent_buffer;
u32 *fd_array;
struct binder_proc *proc = thread->proc;
struct binder_proc *target_proc = t->to_proc;
@@ -2664,13 +2655,7 @@ static int binder_translate_fd_array(struct 
binder_fd_array_object *fda,
  proc->pid, thread->pid, (u64)fda->num_fds);
return -EINVAL;
}
-   /*
-* Since the parent was already fixed up, convert it
-* back to the kernel address space to access it
-*/
-   parent_buffer = parent->buffer -
-   binder_alloc_get_user_buffer_offset(&target_proc->alloc);
-   fd_array = (u32 *)(parent_buffer + (uintptr_t)fda->parent_offset);
+   fd_array = (u32 *)(uintptr_t)(parent->buffer + fda->parent_offset);
if (!IS_ALIGNED((unsigned long)fd_array, sizeof(u32))) {
binder_user_error("%d:%d parent offset not aligned 
correctly.\n",
  proc->pid, thread->pid);
@@ -2703,7 +2688,6 @@ static int binder_fixup_parent(struct binder_transaction 
*t,
   binder_size_t last_fixup_min_off)
 {
struct binder_buffer_object *parent;
-   u8 *parent_buffer;
struct binder_buffer *b = t->buffer;
struct binder_proc *proc = thread->proc;
struct binder_proc *target_proc = t->to_proc;
@@ -2739,11 +2723,8 @@ static int binder_fixup_parent(struct binder_transaction 
*t,
  proc->pid, thread->pid);
return -EINVAL;
}
-   parent_buffer = (u8 *)((uintptr_t)parent->buffer -
-   binder_alloc_get_user_buffer_offset(
-   &target_proc->alloc));
buffer_offset = bp->parent_offset +
-   (uintptr_t)parent_buffer - (uintptr_t)b->data;
+   (uintptr_t)parent->buffer - (uintptr_t)b->data;
binder_alloc_copy_to_buffer(&target_proc->alloc, b, buffer_offset,
&bp->buffer, sizeof(bp->buffer));
 
@@ -3159,10 +3140,8 @@ static void binder_transaction(struct binder_proc *proc,
ALIGN(tr->offsets_size, sizeof(void *)) +
ALIGN(extra_buffers_size, sizeof(void *)) -
AL

[PATCH v3 1/7] binder: create userspace-to-binder-buffer copy function

2019-02-08 Thread Todd Kjos
The binder driver uses a vm_area to map the per-process
binder buffer space. For 32-bit android devices, this is
now taking too much vmalloc space. This patch removes
the use of vm_area when copying the transaction data
from the sender to the buffer space. Instead of using
copy_from_user() for multi-page copies, it now uses
binder_alloc_copy_user_to_buffer() which uses kmap()
and kunmap() to map each page, and uses copy_from_user()
for copying to that page.

Signed-off-by: Todd Kjos 
---
v2: remove casts as suggested by Dan Carpenter

 drivers/android/binder.c   |  29 +++--
 drivers/android/binder_alloc.c | 113 +
 drivers/android/binder_alloc.h |   8 +++
 3 files changed, 143 insertions(+), 7 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 5f6ef5e63b91e..ab0b3eec363bc 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3078,8 +3078,12 @@ static void binder_transaction(struct binder_proc *proc,
  ALIGN(tr->data_size, sizeof(void *)));
offp = off_start;
 
-   if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
-  tr->data.ptr.buffer, tr->data_size)) {
+   if (binder_alloc_copy_user_to_buffer(
+   &target_proc->alloc,
+   t->buffer, 0,
+   (const void __user *)
+   (uintptr_t)tr->data.ptr.buffer,
+   tr->data_size)) {
binder_user_error("%d:%d got transaction with invalid data 
ptr\n",
proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
@@ -3087,8 +3091,13 @@ static void binder_transaction(struct binder_proc *proc,
return_error_line = __LINE__;
goto err_copy_data_failed;
}
-   if (copy_from_user(offp, (const void __user *)(uintptr_t)
-  tr->data.ptr.offsets, tr->offsets_size)) {
+   if (binder_alloc_copy_user_to_buffer(
+   &target_proc->alloc,
+   t->buffer,
+   ALIGN(tr->data_size, sizeof(void *)),
+   (const void __user *)
+   (uintptr_t)tr->data.ptr.offsets,
+   tr->offsets_size)) {
binder_user_error("%d:%d got transaction with invalid offsets 
ptr\n",
proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
@@ -3217,6 +3226,8 @@ static void binder_transaction(struct binder_proc *proc,
struct binder_buffer_object *bp =
to_binder_buffer_object(hdr);
size_t buf_left = sg_buf_end - sg_bufp;
+   binder_size_t sg_buf_offset = (uintptr_t)sg_bufp -
+   (uintptr_t)t->buffer->data;
 
if (bp->length > buf_left) {
binder_user_error("%d:%d got transaction with 
too large buffer\n",
@@ -3226,9 +3237,13 @@ static void binder_transaction(struct binder_proc *proc,
return_error_line = __LINE__;
goto err_bad_offset;
}
-   if (copy_from_user(sg_bufp,
-  (const void __user *)(uintptr_t)
-  bp->buffer, bp->length)) {
+   if (binder_alloc_copy_user_to_buffer(
+   &target_proc->alloc,
+   t->buffer,
+   sg_buf_offset,
+   (const void __user *)
+   (uintptr_t)bp->buffer,
+   bp->length)) {
binder_user_error("%d:%d got transaction with 
invalid offsets ptr\n",
  proc->pid, thread->pid);
return_error_param = -EFAULT;
diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c
index 022cd80e80cc3..94c0d85c4e75b 100644
--- a/drivers/android/binder_alloc.c
+++ b/drivers/android/binder_alloc.c
@@ -29,6 +29,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include "binder_alloc.h"
 #include "binder_trace.h"
 
@@ -1053,3 +1055,114 @@ int binder_alloc_shrinker_init(void)
}
return ret;
 }
+
+/**
+ * check_buffer() - verify that buffer/offset is safe to access
+ * @alloc: binder_alloc for this proc
+ * @buffer: binder buffer to be accessed
+ * @offset: offset into @buffer data
+ * @bytes: bytes to access from offset
+ *
+ * Check

[PATCH v3 4/7] binder: avoid kernel vm_area for buffer fixups

2019-02-08 Thread Todd Kjos
Refactor the functions to validate and fixup struct
binder_buffer pointer objects to avoid using vm_area
pointers. Instead copy to/from kernel space using
binder_alloc_copy_to_buffer() and
binder_alloc_copy_from_buffer(). The following
functions were refactored:

refactor binder_validate_ptr()
binder_validate_fixup()
binder_fixup_parent()

Signed-off-by: Todd Kjos 
---
 drivers/android/binder.c | 146 ++-
 1 file changed, 97 insertions(+), 49 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 8063b405e4fa1..98163bf5f35c7 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2092,10 +2092,13 @@ static size_t binder_get_object(struct binder_proc 
*proc,
 
 /**
  * binder_validate_ptr() - validates binder_buffer_object in a binder_buffer.
+ * @proc:  binder_proc owning the buffer
  * @b: binder_buffer containing the object
+ * @object:struct binder_object to read into
  * @index: index in offset array at which the binder_buffer_object is
  * located
- * @start: points to the start of the offset array
+ * @start_offset: points to the start of the offset array
+ * @object_offsetp: offset of @object read from @b
  * @num_valid: the number of valid offsets in the offset array
  *
  * Return: If @index is within the valid range of the offset array
@@ -2106,34 +2109,46 @@ static size_t binder_get_object(struct binder_proc 
*proc,
  * Note that the offset found in index @index itself is not
  * verified; this function assumes that @num_valid elements
  * from @start were previously verified to have valid offsets.
+ * If @object_offsetp is non-NULL, then the offset within
+ * @b is written to it.
  */
-static struct binder_buffer_object *binder_validate_ptr(struct binder_buffer 
*b,
-   binder_size_t index,
-   binder_size_t *start,
-   binder_size_t num_valid)
+static struct binder_buffer_object *binder_validate_ptr(
+   struct binder_proc *proc,
+   struct binder_buffer *b,
+   struct binder_object *object,
+   binder_size_t index,
+   binder_size_t start_offset,
+   binder_size_t *object_offsetp,
+   binder_size_t num_valid)
 {
-   struct binder_buffer_object *buffer_obj;
-   binder_size_t *offp;
+   size_t object_size;
+   binder_size_t object_offset;
+   unsigned long buffer_offset;
 
if (index >= num_valid)
return NULL;
 
-   offp = start + index;
-   buffer_obj = (struct binder_buffer_object *)(b->data + *offp);
-   if (buffer_obj->hdr.type != BINDER_TYPE_PTR)
+   buffer_offset = start_offset + sizeof(binder_size_t) * index;
+   binder_alloc_copy_from_buffer(&proc->alloc, &object_offset,
+ b, buffer_offset, sizeof(object_offset));
+   object_size = binder_get_object(proc, b, object_offset, object);
+   if (!object_size || object->hdr.type != BINDER_TYPE_PTR)
return NULL;
+   if (object_offsetp)
+   *object_offsetp = object_offset;
 
-   return buffer_obj;
+   return &object->bbo;
 }
 
 /**
  * binder_validate_fixup() - validates pointer/fd fixups happen in order.
+ * @proc:  binder_proc owning the buffer
  * @b: transaction buffer
- * @objects_start  start of objects buffer
- * @buffer:binder_buffer_object in which to fix up
- * @offset:start offset in @buffer to fix up
- * @last_obj:  last binder_buffer_object that we fixed up in
- * @last_min_offset:   minimum fixup offset in @last_obj
+ * @objects_start_offset: offset to start of objects buffer
+ * @buffer_obj_offset: offset to binder_buffer_object in which to fix up
+ * @fixup_offset:  start offset in @buffer to fix up
+ * @last_obj_offset:   offset to last binder_buffer_object that we fixed
+ * @last_min_offset:   minimum fixup offset in object at @last_obj_offset
  *
  * Return: %true if a fixup in buffer @buffer at offset @offset is
  * allowed.
@@ -2164,28 +2179,41 @@ static struct binder_buffer_object 
*binder_validate_ptr(struct binder_buffer *b,
  *   C (parent = A, offset = 16)
  * D (parent = B, offset = 0) // B is not A or any of A's parents
  */
-static bool binder_validate_fixup(struct binder_buffer *b,
- binder_size_t *objects_start,
- struct binder_buffer_object *buffer

[PATCH v3 7/7] binder: use userspace pointer as base of buffer space

2019-02-08 Thread Todd Kjos
Now that alloc->buffer points to the userspace vm_area
rename buffer->data to buffer->user_data and rename
local pointers that hold user addresses. Also use the
"__user" tag to annotate all user pointers so sparse
can flag cases where user pointer vaues  are copied to
kernel pointers. Refactor code to use offsets instead
of user pointers.

Signed-off-by: Todd Kjos 
---
v2: remove casts as suggested by Dan Carpenter
v3: fix build-break when CONFIG_ANDROID_BINDER_IPC_SELFTEST enabled

 drivers/android/binder.c| 118 ++--
 drivers/android/binder_alloc.c  |  87 -
 drivers/android/binder_alloc.h  |   6 +-
 drivers/android/binder_alloc_selftest.c |   4 +-
 drivers/android/binder_trace.h  |   2 +-
 5 files changed, 118 insertions(+), 99 deletions(-)

diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index b3d609b5935a6..25491eceb7503 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -2278,33 +2278,30 @@ static void binder_deferred_fd_close(int fd)
 
 static void binder_transaction_buffer_release(struct binder_proc *proc,
  struct binder_buffer *buffer,
- binder_size_t *failed_at)
+ binder_size_t failed_at,
+ bool is_failure)
 {
-   binder_size_t *offp, *off_start, *off_end;
int debug_id = buffer->debug_id;
-   binder_size_t off_start_offset;
+   binder_size_t off_start_offset, buffer_offset, off_end_offset;
 
binder_debug(BINDER_DEBUG_TRANSACTION,
-"%d buffer release %d, size %zd-%zd, failed at %pK\n",
+"%d buffer release %d, size %zd-%zd, failed at %llx\n",
 proc->pid, buffer->debug_id,
-buffer->data_size, buffer->offsets_size, failed_at);
+buffer->data_size, buffer->offsets_size,
+(unsigned long long)failed_at);
 
if (buffer->target_node)
binder_dec_node(buffer->target_node, 1, 0);
 
off_start_offset = ALIGN(buffer->data_size, sizeof(void *));
-   off_start = (binder_size_t *)(buffer->data + off_start_offset);
-   if (failed_at)
-   off_end = failed_at;
-   else
-   off_end = (void *)off_start + buffer->offsets_size;
-   for (offp = off_start; offp < off_end; offp++) {
+   off_end_offset = is_failure ? failed_at :
+   off_start_offset + buffer->offsets_size;
+   for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
+buffer_offset += sizeof(binder_size_t)) {
struct binder_object_header *hdr;
size_t object_size;
struct binder_object object;
binder_size_t object_offset;
-   binder_size_t buffer_offset = (uintptr_t)offp -
-   (uintptr_t)buffer->data;
 
binder_alloc_copy_from_buffer(&proc->alloc, &object_offset,
  buffer, buffer_offset,
@@ -2380,9 +2377,10 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
struct binder_fd_array_object *fda;
struct binder_buffer_object *parent;
struct binder_object ptr_object;
-   u32 *fd_array;
+   binder_size_t fda_offset;
size_t fd_index;
binder_size_t fd_buf_size;
+   binder_size_t num_valid;
 
if (proc->tsk != current->group_leader) {
/*
@@ -2393,12 +2391,14 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
continue;
}
 
+   num_valid = (buffer_offset - off_start_offset) /
+   sizeof(binder_size_t);
fda = to_binder_fd_array_object(hdr);
parent = binder_validate_ptr(proc, buffer, &ptr_object,
 fda->parent,
 off_start_offset,
 NULL,
-offp - off_start);
+num_valid);
if (!parent) {
pr_err("transaction release %d bad parent 
offset\n",
   debug_id);
@@ -2417,14 +2417,21 @@ static void binder_transaction_buffer_release(struct 
binder_proc *proc,
   debug_id, (u64)fda->num_fds);
continue;
   

[PATCH v3 0/7] binder: eliminate use of vmalloc space for binder buffers

2019-02-08 Thread Todd Kjos
Binder buffers have always been mapped into kernel space
via map_kernel_range_noflush() to allow the binder driver
to modify the buffer before posting to userspace for
processing.

In recent Android releases, the number of long-running
binder processes has increased to the point that for
32-bit systems, there is a risk of running out of
vmalloc space.

This patch set removes the persistent mapping of the
binder buffers into kernel space. Instead, the binder
driver creates temporary mappings with kmap() or
kmap_atomic() to copy to or from the buffer only when
necessary.

Todd Kjos (7):
binder: create userspace-to-binder-buffer copy function
binder: add functions to copy to/from binder buffers
binder: add function to copy binder object from buffer
binder: avoid kernel vm_area for buffer fixups
binder: remove kernel vm_area for buffer space
binder: remove user_buffer_offset
binder: use userspace pointer as base of buffer space

v2: remove casts as suggested by Dan Carpenter
v3: fix build-break when CONFIG_ANDROID_BINDER_IPC_SELFTEST enabled

 drivers/android/Kconfig |   2 +-
 drivers/android/binder.c| 460 
++
 drivers/android/binder_alloc.c  | 299 
+--
 drivers/android/binder_alloc.h  |  47 
 drivers/android/binder_alloc_selftest.c |   4 +-
 drivers/android/binder_trace.h  |   2 +-
 6 files changed, 536 insertions(+), 278 deletions(-)
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/3] gpu: ipu-v3: ipu-ic: Add support for BT.709 encoding

2019-02-08 Thread Steve Longerbeam




On 2/8/19 8:24 AM, Tim Harvey wrote:

On Sun, Feb 3, 2019 at 11:48 AM Steve Longerbeam  wrote:

Pass v4l2 encoding enum to the ipu_ic task init functions, and add
support for the BT.709 encoding and inverse encoding matrices.

Reported-by: Tim Harvey 
Signed-off-by: Steve Longerbeam 
---
  drivers/gpu/ipu-v3/ipu-ic.c | 67 ++---
  drivers/gpu/ipu-v3/ipu-image-convert.c  |  1 +
  drivers/staging/media/imx/imx-ic-prpencvf.c |  4 +-
  include/video/imx-ipu-v3.h  |  5 +-
  4 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/ipu-v3/ipu-ic.c
index 35ae86ff0585..63362b4fff81 100644
--- a/drivers/gpu/ipu-v3/ipu-ic.c
+++ b/drivers/gpu/ipu-v3/ipu-ic.c
@@ -199,6 +199,23 @@ static const struct ic_csc_params ic_csc_rgb2ycbcr_bt601 = 
{
 .scale = 1,
  };

+/*
+ * BT.709 encoding from RGB full range to YUV limited range:
+ *
+ * Y = R *  .2126 + G *  .7152 + B *  .0722;
+ * U = R * -.1146 + G * -.3854 + B *  .5000 + 128.;
+ * V = R *  .5000 + G * -.4542 + B * -.0458 + 128.;
+ */
+static const struct ic_csc_params ic_csc_rgb2ycbcr_bt709 = {
+   .coeff = {
+   { 54, 183, 18 },
+   { 483, 413, 128 },
+   { 128, 396, 500 },
+   },
+   .offset = { 0, 512, 512 },
+   .scale = 1,
+};
+
  /* transparent RGB->RGB matrix for graphics combining */
  static const struct ic_csc_params ic_csc_rgb2rgb = {
 .coeff = {
@@ -226,12 +243,31 @@ static const struct ic_csc_params ic_csc_ycbcr2rgb_bt601 
= {
 .scale = 2,
  };

+/*
+ * Inverse BT.709 encoding from YUV limited range to RGB full range:
+ *
+ * R = (1. * (Y - 16)) + (1.5748 * (Cr - 128));
+ * G = (1. * (Y - 16)) - (0.1873 * (Cb - 128)) - (0.4681 * (Cr - 128));
+ * B = (1. * (Y - 16)) + (1.8556 * (Cb - 128);
+ */
+static const struct ic_csc_params ic_csc_ycbcr2rgb_bt709 = {
+   .coeff = {
+   { 128, 0, 202 },
+   { 128, 488, 452 },
+   { 128, 238, 0 },
+   },
+   .offset = { -435, 136, -507 },
+   .scale = 2,
+};
+
  static int init_csc(struct ipu_ic *ic,
 enum ipu_color_space inf,
 enum ipu_color_space outf,
+   enum v4l2_ycbcr_encoding encoding,
 int csc_index)
  {
 struct ipu_ic_priv *priv = ic->priv;
+   const struct ic_csc_params *params_rgb2yuv, *params_yuv2rgb;
 const struct ic_csc_params *params;
 u32 __iomem *base;
 const u16 (*c)[3];
@@ -241,10 +277,24 @@ static int init_csc(struct ipu_ic *ic,
 base = (u32 __iomem *)
 (priv->tpmem_base + ic->reg->tpmem_csc[csc_index]);

+   switch (encoding) {
+   case V4L2_YCBCR_ENC_601:
+   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt601;
+   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt601;
+   break;
+   case V4L2_YCBCR_ENC_709:
+   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt709;
+   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt709;
+   break;
+   default:
+   dev_err(priv->ipu->dev, "Unsupported YCbCr encoding\n");
+   return -EINVAL;
+   }
+

Steve,

This will fail for RGB to RGB with 'Unsupported YCbCr encoding. We
need to account for the RGB->RGB case.

How about something like:



Thanks for reporting Tim

I rather keep the check for supported encoding, and instead get rid of 
"Unsupported color space conversion" error, because that is the YUV->YUV 
case which can be allowed using the identity matrix.


Steve



  static int init_csc(struct ipu_ic *ic,
 enum ipu_color_space inf,
 enum ipu_color_space outf,
+   enum v4l2_ycbcr_encoding encoding,
 int csc_index)
  {
 struct ipu_ic_priv *priv = ic->priv;
-   const struct ic_csc_params *params;
+   const struct ic_csc_params *params = NULL;
 u32 __iomem *base;
 const u16 (*c)[3];
 const u16 *a;
@@ -241,13 +276,18 @@ static int init_csc(struct ipu_ic *ic,
 base = (u32 __iomem *)
 (priv->tpmem_base + ic->reg->tpmem_csc[csc_index]);

-   if (inf == IPUV3_COLORSPACE_YUV && outf == IPUV3_COLORSPACE_RGB)
-   params = &ic_csc_ycbcr2rgb_bt601;
-   else if (inf == IPUV3_COLORSPACE_RGB && outf == IPUV3_COLORSPACE_YUV)
-   params = &ic_csc_rgb2ycbcr_bt601;
+   if (inf == IPUV3_COLORSPACE_YUV && outf == IPUV3_COLORSPACE_RGB) {
+   params = (encoding == V4L2_YCBCR_ENC_601) ?
+   &ic_csc_ycbcr2rgb_bt601 : &ic_csc_ycbcr2rgb_bt709;
+   }
+   else if (inf == IPUV3_COLORSPACE_RGB && outf == IPUV3_COLORSPACE_YUV) {
+   params = (encoding == V4L2_YCBCR_ENC_601) ?
+   &ic_csc_rgb2ycbcr_bt601 : &ic_csc_rgb2ycbcr_bt709;
+   }
 else if (inf == IPUV3_COLORSPACE_RGB && outf == IPUV3_COLORSPACE_RGB)
  

[PATCH v2 4/4] media: imx: Allow BT.709 encoding for IC routes

2019-02-08 Thread Steve Longerbeam
From: Steve Longerbeam 

The IC now supports BT.709 Y'CbCr encoding, in addition to existing BT.601
encoding, so allow both, for pipelines that route through the IC.

Reported-by: Tim Harvey 
Signed-off-by: Steve Longerbeam 
---
Changes in v2:
- move ic_route check above default colorimetry checks, and fill default
  colorimetry for ic_route, otherwise it's not possible to set BT.709
  encoding for ic routes.
---
 drivers/staging/media/imx/imx-media-utils.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-utils.c 
b/drivers/staging/media/imx/imx-media-utils.c
index 5f110d90a4ef..dde0e47550d7 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -544,6 +544,19 @@ void imx_media_fill_default_mbus_fields(struct 
v4l2_mbus_framefmt *tryfmt,
if (tryfmt->field == V4L2_FIELD_ANY)
tryfmt->field = fmt->field;
 
+   if (ic_route) {
+   if (tryfmt->colorspace == V4L2_COLORSPACE_DEFAULT)
+   tryfmt->colorspace = fmt->colorspace;
+
+   tryfmt->quantization = is_rgb ?
+   V4L2_QUANTIZATION_FULL_RANGE :
+   V4L2_QUANTIZATION_LIM_RANGE;
+
+   if (tryfmt->ycbcr_enc != V4L2_YCBCR_ENC_601 &&
+   tryfmt->ycbcr_enc != V4L2_YCBCR_ENC_709)
+   tryfmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
+   }
+
/* fill colorimetry if necessary */
if (tryfmt->colorspace == V4L2_COLORSPACE_DEFAULT) {
tryfmt->colorspace = fmt->colorspace;
@@ -566,13 +579,6 @@ void imx_media_fill_default_mbus_fields(struct 
v4l2_mbus_framefmt *tryfmt,
tryfmt->ycbcr_enc);
}
}
-
-   if (ic_route) {
-   tryfmt->quantization = is_rgb ?
-   V4L2_QUANTIZATION_FULL_RANGE :
-   V4L2_QUANTIZATION_LIM_RANGE;
-   tryfmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
-   }
 }
 EXPORT_SYMBOL_GPL(imx_media_fill_default_mbus_fields);
 
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 3/4] gpu: ipu-v3: ipu-ic: Add support for BT.709 encoding

2019-02-08 Thread Steve Longerbeam
From: Steve Longerbeam 

Pass v4l2 encoding enum to the ipu_ic task init functions, and add
support for the BT.709 encoding and inverse encoding matrices.

Reported-by: Tim Harvey 
Signed-off-by: Steve Longerbeam 
---
Changes in v2:
- only return "Unsupported YCbCr encoding" error if inf != outf,
  since if inf == outf, the identity matrix can be used. Reported
  by Tim Harvey.
---
 drivers/gpu/ipu-v3/ipu-ic.c | 71 +++--
 drivers/gpu/ipu-v3/ipu-image-convert.c  |  1 +
 drivers/staging/media/imx/imx-ic-prpencvf.c |  4 +-
 include/video/imx-ipu-v3.h  |  5 +-
 4 files changed, 71 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/ipu-v3/ipu-ic.c
index e459615a49a1..0d57ca7ba18e 100644
--- a/drivers/gpu/ipu-v3/ipu-ic.c
+++ b/drivers/gpu/ipu-v3/ipu-ic.c
@@ -212,6 +212,23 @@ static const struct ic_csc_params ic_csc_identity = {
.scale = 2,
 };
 
+/*
+ * BT.709 encoding from RGB full range to YUV limited range:
+ *
+ * Y = R *  .2126 + G *  .7152 + B *  .0722;
+ * U = R * -.1146 + G * -.3854 + B *  .5000 + 128.;
+ * V = R *  .5000 + G * -.4542 + B * -.0458 + 128.;
+ */
+static const struct ic_csc_params ic_csc_rgb2ycbcr_bt709 = {
+   .coeff = {
+   { 54, 183, 18 },
+   { 483, 413, 128 },
+   { 128, 396, 500 },
+   },
+   .offset = { 0, 512, 512 },
+   .scale = 1,
+};
+
 /*
  * Inverse BT.601 encoding from YUV limited range to RGB full range:
  *
@@ -229,12 +246,31 @@ static const struct ic_csc_params ic_csc_ycbcr2rgb_bt601 
= {
.scale = 2,
 };
 
+/*
+ * Inverse BT.709 encoding from YUV limited range to RGB full range:
+ *
+ * R = (1. * (Y - 16)) + (1.5748 * (Cr - 128));
+ * G = (1. * (Y - 16)) - (0.1873 * (Cb - 128)) - (0.4681 * (Cr - 128));
+ * B = (1. * (Y - 16)) + (1.8556 * (Cb - 128);
+ */
+static const struct ic_csc_params ic_csc_ycbcr2rgb_bt709 = {
+   .coeff = {
+   { 128, 0, 202 },
+   { 128, 488, 452 },
+   { 128, 238, 0 },
+   },
+   .offset = { -435, 136, -507 },
+   .scale = 2,
+};
+
 static int init_csc(struct ipu_ic *ic,
enum ipu_color_space inf,
enum ipu_color_space outf,
+   enum v4l2_ycbcr_encoding encoding,
int csc_index)
 {
struct ipu_ic_priv *priv = ic->priv;
+   const struct ic_csc_params *params_rgb2yuv, *params_yuv2rgb;
const struct ic_csc_params *params;
u32 __iomem *base;
const u16 (*c)[3];
@@ -244,12 +280,30 @@ static int init_csc(struct ipu_ic *ic,
base = (u32 __iomem *)
(priv->tpmem_base + ic->reg->tpmem_csc[csc_index]);
 
+   switch (encoding) {
+   case V4L2_YCBCR_ENC_601:
+   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt601;
+   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt601;
+   break;
+   case V4L2_YCBCR_ENC_709:
+   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt709;
+   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt709;
+   break;
+   default:
+   if (inf != outf) {
+   dev_err(priv->ipu->dev,
+   "Unsupported YCbCr encoding\n");
+   return -EINVAL;
+   }
+   break;
+   }
+
if (inf == outf)
params = &ic_csc_identity;
else if (inf == IPUV3_COLORSPACE_YUV)
-   params = &ic_csc_ycbcr2rgb_bt601;
+   params = &ic_csc_ycbcr2rgb;
else
-   params = &ic_csc_rgb2ycbcr_bt601;
+   params = &ic_csc_rgb2ycbcr;
 
/* Cast to unsigned */
c = (const u16 (*)[3])params->coeff;
@@ -390,6 +444,7 @@ EXPORT_SYMBOL_GPL(ipu_ic_task_disable);
 
 int ipu_ic_task_graphics_init(struct ipu_ic *ic,
  enum ipu_color_space in_g_cs,
+ enum v4l2_ycbcr_encoding encoding,
  bool galpha_en, u32 galpha,
  bool colorkey_en, u32 colorkey)
 {
@@ -408,7 +463,7 @@ int ipu_ic_task_graphics_init(struct ipu_ic *ic,
if (!(ic_conf & ic->bit->ic_conf_csc1_en)) {
/* need transparent CSC1 conversion */
ret = init_csc(ic, IPUV3_COLORSPACE_RGB,
-  IPUV3_COLORSPACE_RGB, 0);
+  IPUV3_COLORSPACE_RGB, encoding, 0);
if (ret)
goto unlock;
}
@@ -416,7 +471,7 @@ int ipu_ic_task_graphics_init(struct ipu_ic *ic,
ic->g_in_cs = in_g_cs;
 
if (ic->g_in_cs != ic->out_cs) {
-   ret = init_csc(ic, ic->g_in_cs, ic->out_cs, 1);
+   ret = init_csc(ic, ic->g_in_cs, ic->out_cs, encoding, 1);
if (ret)
goto unlock;
}
@@ -450,6 +505,7 @@ int ipu_ic_task_init_rsc(struct ipu_ic *ic,
 int out_widt

[PATCH v3 4/4] media: imx: Allow BT.709 encoding for IC routes

2019-02-08 Thread Steve Longerbeam
The IC now supports BT.709 Y'CbCr encoding, in addition to existing BT.601
encoding, so allow both, for pipelines that route through the IC.

Reported-by: Tim Harvey 
Signed-off-by: Steve Longerbeam 
---
Changes in v2:
- move ic_route check above default colorimetry checks, and fill default
  colorimetry for ic_route, otherwise it's not possible to set BT.709
  encoding for ic routes.
---
 drivers/staging/media/imx/imx-media-utils.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-utils.c 
b/drivers/staging/media/imx/imx-media-utils.c
index 5f110d90a4ef..dde0e47550d7 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -544,6 +544,19 @@ void imx_media_fill_default_mbus_fields(struct 
v4l2_mbus_framefmt *tryfmt,
if (tryfmt->field == V4L2_FIELD_ANY)
tryfmt->field = fmt->field;
 
+   if (ic_route) {
+   if (tryfmt->colorspace == V4L2_COLORSPACE_DEFAULT)
+   tryfmt->colorspace = fmt->colorspace;
+
+   tryfmt->quantization = is_rgb ?
+   V4L2_QUANTIZATION_FULL_RANGE :
+   V4L2_QUANTIZATION_LIM_RANGE;
+
+   if (tryfmt->ycbcr_enc != V4L2_YCBCR_ENC_601 &&
+   tryfmt->ycbcr_enc != V4L2_YCBCR_ENC_709)
+   tryfmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
+   }
+
/* fill colorimetry if necessary */
if (tryfmt->colorspace == V4L2_COLORSPACE_DEFAULT) {
tryfmt->colorspace = fmt->colorspace;
@@ -566,13 +579,6 @@ void imx_media_fill_default_mbus_fields(struct 
v4l2_mbus_framefmt *tryfmt,
tryfmt->ycbcr_enc);
}
}
-
-   if (ic_route) {
-   tryfmt->quantization = is_rgb ?
-   V4L2_QUANTIZATION_FULL_RANGE :
-   V4L2_QUANTIZATION_LIM_RANGE;
-   tryfmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
-   }
 }
 EXPORT_SYMBOL_GPL(imx_media_fill_default_mbus_fields);
 
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 3/4] gpu: ipu-v3: ipu-ic: Add support for BT.709 encoding

2019-02-08 Thread Steve Longerbeam
Pass v4l2 encoding enum to the ipu_ic task init functions, and add
support for the BT.709 encoding and inverse encoding matrices.

Reported-by: Tim Harvey 
Signed-off-by: Steve Longerbeam 
---
Changes in v2:
- only return "Unsupported YCbCr encoding" error if inf != outf,
  since if inf == outf, the identity matrix can be used. Reported
  by Tim Harvey.
---
 drivers/gpu/ipu-v3/ipu-ic.c | 71 +++--
 drivers/gpu/ipu-v3/ipu-image-convert.c  |  1 +
 drivers/staging/media/imx/imx-ic-prpencvf.c |  4 +-
 include/video/imx-ipu-v3.h  |  5 +-
 4 files changed, 71 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/ipu-v3/ipu-ic.c
index e459615a49a1..0d57ca7ba18e 100644
--- a/drivers/gpu/ipu-v3/ipu-ic.c
+++ b/drivers/gpu/ipu-v3/ipu-ic.c
@@ -212,6 +212,23 @@ static const struct ic_csc_params ic_csc_identity = {
.scale = 2,
 };
 
+/*
+ * BT.709 encoding from RGB full range to YUV limited range:
+ *
+ * Y = R *  .2126 + G *  .7152 + B *  .0722;
+ * U = R * -.1146 + G * -.3854 + B *  .5000 + 128.;
+ * V = R *  .5000 + G * -.4542 + B * -.0458 + 128.;
+ */
+static const struct ic_csc_params ic_csc_rgb2ycbcr_bt709 = {
+   .coeff = {
+   { 54, 183, 18 },
+   { 483, 413, 128 },
+   { 128, 396, 500 },
+   },
+   .offset = { 0, 512, 512 },
+   .scale = 1,
+};
+
 /*
  * Inverse BT.601 encoding from YUV limited range to RGB full range:
  *
@@ -229,12 +246,31 @@ static const struct ic_csc_params ic_csc_ycbcr2rgb_bt601 
= {
.scale = 2,
 };
 
+/*
+ * Inverse BT.709 encoding from YUV limited range to RGB full range:
+ *
+ * R = (1. * (Y - 16)) + (1.5748 * (Cr - 128));
+ * G = (1. * (Y - 16)) - (0.1873 * (Cb - 128)) - (0.4681 * (Cr - 128));
+ * B = (1. * (Y - 16)) + (1.8556 * (Cb - 128);
+ */
+static const struct ic_csc_params ic_csc_ycbcr2rgb_bt709 = {
+   .coeff = {
+   { 128, 0, 202 },
+   { 128, 488, 452 },
+   { 128, 238, 0 },
+   },
+   .offset = { -435, 136, -507 },
+   .scale = 2,
+};
+
 static int init_csc(struct ipu_ic *ic,
enum ipu_color_space inf,
enum ipu_color_space outf,
+   enum v4l2_ycbcr_encoding encoding,
int csc_index)
 {
struct ipu_ic_priv *priv = ic->priv;
+   const struct ic_csc_params *params_rgb2yuv, *params_yuv2rgb;
const struct ic_csc_params *params;
u32 __iomem *base;
const u16 (*c)[3];
@@ -244,12 +280,30 @@ static int init_csc(struct ipu_ic *ic,
base = (u32 __iomem *)
(priv->tpmem_base + ic->reg->tpmem_csc[csc_index]);
 
+   switch (encoding) {
+   case V4L2_YCBCR_ENC_601:
+   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt601;
+   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt601;
+   break;
+   case V4L2_YCBCR_ENC_709:
+   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt709;
+   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt709;
+   break;
+   default:
+   if (inf != outf) {
+   dev_err(priv->ipu->dev,
+   "Unsupported YCbCr encoding\n");
+   return -EINVAL;
+   }
+   break;
+   }
+
if (inf == outf)
params = &ic_csc_identity;
else if (inf == IPUV3_COLORSPACE_YUV)
-   params = &ic_csc_ycbcr2rgb_bt601;
+   params = &ic_csc_ycbcr2rgb;
else
-   params = &ic_csc_rgb2ycbcr_bt601;
+   params = &ic_csc_rgb2ycbcr;
 
/* Cast to unsigned */
c = (const u16 (*)[3])params->coeff;
@@ -390,6 +444,7 @@ EXPORT_SYMBOL_GPL(ipu_ic_task_disable);
 
 int ipu_ic_task_graphics_init(struct ipu_ic *ic,
  enum ipu_color_space in_g_cs,
+ enum v4l2_ycbcr_encoding encoding,
  bool galpha_en, u32 galpha,
  bool colorkey_en, u32 colorkey)
 {
@@ -408,7 +463,7 @@ int ipu_ic_task_graphics_init(struct ipu_ic *ic,
if (!(ic_conf & ic->bit->ic_conf_csc1_en)) {
/* need transparent CSC1 conversion */
ret = init_csc(ic, IPUV3_COLORSPACE_RGB,
-  IPUV3_COLORSPACE_RGB, 0);
+  IPUV3_COLORSPACE_RGB, encoding, 0);
if (ret)
goto unlock;
}
@@ -416,7 +471,7 @@ int ipu_ic_task_graphics_init(struct ipu_ic *ic,
ic->g_in_cs = in_g_cs;
 
if (ic->g_in_cs != ic->out_cs) {
-   ret = init_csc(ic, ic->g_in_cs, ic->out_cs, 1);
+   ret = init_csc(ic, ic->g_in_cs, ic->out_cs, encoding, 1);
if (ret)
goto unlock;
}
@@ -450,6 +505,7 @@ int ipu_ic_task_init_rsc(struct ipu_ic *ic,
 int out_width, int out_height,
  

Re: [GIT PULL] Staging/IIO driver fixes for 5.0-rc6

2019-02-08 Thread pr-tracker-bot
The pull request you sent on Fri, 8 Feb 2019 09:38:35 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git 
> tags/staging-5.0-rc6

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/e464f50c057a1fbefae6c6078f9bd5511f84f199

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.wiki.kernel.org/userdoc/prtracker
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/2] Drivers: hv: vmbus: Fix sysfs functions that display monitor id and page data

2019-02-08 Thread Kimberly Brown
Some of the monitor id and monitor page data sysfs files display
incorrect data. This patchset provides the following changes:

1) Change the monitor_pages index in server_monitor_pending_show() to
'0', which is the correct index for the server.

2) If monitor pages are not allocated to a channel, display nothing in
the channel's monitor id and monitor page data sysfs files. The data
that is currently shown in sysfs is incorrect.


Kimberly Brown (2):
  Drivers: hv: vmbus: Change server monitor_pages index to 0
  Drivers: hv: vmbus: Display nothing in sysfs if monitor_allocated not
set

 Documentation/ABI/stable/sysfs-bus-vmbus |  9 --
 drivers/hv/vmbus_drv.c   | 39 +++-
 2 files changed, 44 insertions(+), 4 deletions(-)

-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/2] Drivers: hv: vmbus: Change server monitor_pages index to 0

2019-02-08 Thread Kimberly Brown
Change the monitor_pages index in server_monitor_pending_show() to '0'.
'0' is the correct monitor_pages index for the server. A comment for the
monitor_pages field in the vmbus_connection struct definition indicates
that the 1st page is for parent->child notifications. In addition, the
server_monitor_latency_show() and server_monitor_conn_id_show()
functions use monitor_pages index '0'.

Signed-off-by: Kimberly Brown 
---
 drivers/hv/vmbus_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 403fee01572c..f2a79f5129d7 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -234,7 +234,7 @@ static ssize_t server_monitor_pending_show(struct device 
*dev,
return -ENODEV;
return sprintf(buf, "%d\n",
   channel_pending(hv_dev->channel,
-  vmbus_connection.monitor_pages[1]));
+  vmbus_connection.monitor_pages[0]));
 }
 static DEVICE_ATTR_RO(server_monitor_pending);
 
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/2] Drivers: hv: vmbus: Display nothing in sysfs if monitor_allocated not set

2019-02-08 Thread Kimberly Brown
If monitor pages are not allocated to a channel, the channel does not
have a valid monitor id or valid monitor page data. In these cases, some
of the "_show" functions display incorrect data. The "_show" functions
that display monitor page data access and display data that is beyond
the bounds of the hv_monitor_page array fields, which is obviously
incorrect. The "_show" functions that display the monitor id display an
invalid monitor id.

The "channel->offermsg.monitor_allocated" value can be used to determine
whether monitor pages have been allocated to a channel. In the affected
"_show" functions, verify that "channel->offermsg.monitor_allocated" is
set before accessing the monitor id or the monitor_page data. If
"channel->offermsg.monitor_allocated" is not set, display nothing.

Signed-off-by: Kimberly Brown 
---
 Documentation/ABI/stable/sysfs-bus-vmbus |  9 --
 drivers/hv/vmbus_drv.c   | 37 
 2 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/stable/sysfs-bus-vmbus 
b/Documentation/ABI/stable/sysfs-bus-vmbus
index 3fed8fdb873d..af52be4ffc5d 100644
--- a/Documentation/ABI/stable/sysfs-bus-vmbus
+++ b/Documentation/ABI/stable/sysfs-bus-vmbus
@@ -81,7 +81,8 @@ What: 
/sys/bus/vmbus/devices//channels//latency
 Date:  September. 2017
 KernelVersion: 4.14
 Contact:   Stephen Hemminger 
-Description:   Channel signaling latency
+Description:   Channel signaling latency. If monitor pages are not allocated
+   to the channel, nothing is displayed.
 Users: Debugging tools
 
 What:  /sys/bus/vmbus/devices//channels//out_mask
@@ -95,7 +96,8 @@ What: 
/sys/bus/vmbus/devices//channels//pending
 Date:  September. 2017
 KernelVersion: 4.14
 Contact:   Stephen Hemminger 
-Description:   Channel interrupt pending state
+Description:   Channel interrupt pending state. If monitor pages are not
+   allocated to the channel, nothing is displayed.
 Users: Debugging tools
 
 What:  /sys/bus/vmbus/devices//channels//read_avail
@@ -137,7 +139,8 @@ What:   
/sys/bus/vmbus/devices//channels//monitor_id
 Date:  January. 2018
 KernelVersion: 4.16
 Contact:   Stephen Hemminger 
-Description:   Monitor bit associated with channel
+Description:   Monitor bit associated with channel. If monitor pages are not
+   allocated to the channel, nothing is displayed.
 Users: Debugging tools and userspace drivers
 
 What:  /sys/bus/vmbus/devices//channels//ring
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f2a79f5129d7..c88a3623be56 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -171,6 +171,10 @@ static ssize_t monitor_id_show(struct device *dev,
 
if (!hv_dev->channel)
return -ENODEV;
+
+   if (!hv_dev->channel->offermsg.monitor_allocated)
+   return sprintf(buf, "\n");
+
return sprintf(buf, "%d\n", hv_dev->channel->offermsg.monitorid);
 }
 static DEVICE_ATTR_RO(monitor_id);
@@ -232,6 +236,10 @@ static ssize_t server_monitor_pending_show(struct device 
*dev,
 
if (!hv_dev->channel)
return -ENODEV;
+
+   if (!hv_dev->channel->offermsg.monitor_allocated)
+   return sprintf(buf, "\n");
+
return sprintf(buf, "%d\n",
   channel_pending(hv_dev->channel,
   vmbus_connection.monitor_pages[0]));
@@ -246,6 +254,10 @@ static ssize_t client_monitor_pending_show(struct device 
*dev,
 
if (!hv_dev->channel)
return -ENODEV;
+
+   if (!hv_dev->channel->offermsg.monitor_allocated)
+   return sprintf(buf, "\n");
+
return sprintf(buf, "%d\n",
   channel_pending(hv_dev->channel,
   vmbus_connection.monitor_pages[1]));
@@ -260,6 +272,10 @@ static ssize_t server_monitor_latency_show(struct device 
*dev,
 
if (!hv_dev->channel)
return -ENODEV;
+
+   if (!hv_dev->channel->offermsg.monitor_allocated)
+   return sprintf(buf, "\n");
+
return sprintf(buf, "%d\n",
   channel_latency(hv_dev->channel,
   vmbus_connection.monitor_pages[0]));
@@ -274,6 +290,10 @@ static ssize_t client_monitor_latency_show(struct device 
*dev,
 
if (!hv_dev->channel)
return -ENODEV;
+
+   if (!hv_dev->channel->offermsg.monitor_allocated)
+   return sprintf(buf, "\n");
+
return sprintf(buf, "%d\n",
   channel_latency(hv_dev->channel,
   vmbus_connection.monitor_pages[1]));
@@ -288,6 +308,10 @@ static ssize_t server_monitor_conn_id_show(struct device 
*dev,
 
if (!hv_dev->channel)
return -ENODEV;
+
+   if (!hv_dev->channel->offermsg.monitor_allocated)

Re: [PATCH 1/2] Drivers: hv: vmbus: Change server monitor_pages index to 0

2019-02-08 Thread Stephen Hemminger
On Fri, 8 Feb 2019 04:58:52 -0500
Kimberly Brown  wrote:

> Change the monitor_pages index in server_monitor_pending_show() to '0'.
> '0' is the correct monitor_pages index for the server. A comment for the
> monitor_pages field in the vmbus_connection struct definition indicates
> that the 1st page is for parent->child notifications. In addition, the
> server_monitor_latency_show() and server_monitor_conn_id_show()
> functions use monitor_pages index '0'.
> 
> Signed-off-by: Kimberly Brown 
> ---
>  drivers/hv/vmbus_drv.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
> index 403fee01572c..f2a79f5129d7 100644
> --- a/drivers/hv/vmbus_drv.c
> +++ b/drivers/hv/vmbus_drv.c
> @@ -234,7 +234,7 @@ static ssize_t server_monitor_pending_show(struct device 
> *dev,
>   return -ENODEV;
>   return sprintf(buf, "%d\n",
>  channel_pending(hv_dev->channel,
> -vmbus_connection.monitor_pages[1]));
> +vmbus_connection.monitor_pages[0]));
>  }
>  static DEVICE_ATTR_RO(server_monitor_pending);


Looks good.

I wonder if ever gets used though since it returned incorrect data...

Acked-by: Stephen Hemminger 
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 2/2] Drivers: hv: vmbus: Display nothing in sysfs if monitor_allocated not set

2019-02-08 Thread Stephen Hemminger
On Fri, 8 Feb 2019 05:01:12 -0500
Kimberly Brown  wrote:

You are right, the current behavior is broken.
It would be good to add a description of under what conditions
monitor is not used. Is this some part of a project emulating
Hyper-V?


> +
> + if (!hv_dev->channel->offermsg.monitor_allocated)
> + return sprintf(buf, "\n");

If monitor is not used, why not return an error instead of empty
data. Any program (or user) would have to handle that already.
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 3/4] gpu: ipu-v3: ipu-ic: Add support for BT.709 encoding

2019-02-08 Thread Tim Harvey
On Fri, Feb 8, 2019 at 11:28 AM Steve Longerbeam  wrote:
>
> Pass v4l2 encoding enum to the ipu_ic task init functions, and add
> support for the BT.709 encoding and inverse encoding matrices.
>
> Reported-by: Tim Harvey 
> Signed-off-by: Steve Longerbeam 
> ---
> Changes in v2:
> - only return "Unsupported YCbCr encoding" error if inf != outf,
>   since if inf == outf, the identity matrix can be used. Reported
>   by Tim Harvey.
> ---
>  drivers/gpu/ipu-v3/ipu-ic.c | 71 +++--
>  drivers/gpu/ipu-v3/ipu-image-convert.c  |  1 +
>  drivers/staging/media/imx/imx-ic-prpencvf.c |  4 +-
>  include/video/imx-ipu-v3.h  |  5 +-
>  4 files changed, 71 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/ipu-v3/ipu-ic.c
> index e459615a49a1..0d57ca7ba18e 100644
> --- a/drivers/gpu/ipu-v3/ipu-ic.c
> +++ b/drivers/gpu/ipu-v3/ipu-ic.c
> @@ -212,6 +212,23 @@ static const struct ic_csc_params ic_csc_identity = {
> .scale = 2,
>  };
>
> +/*
> + * BT.709 encoding from RGB full range to YUV limited range:
> + *
> + * Y = R *  .2126 + G *  .7152 + B *  .0722;
> + * U = R * -.1146 + G * -.3854 + B *  .5000 + 128.;
> + * V = R *  .5000 + G * -.4542 + B * -.0458 + 128.;
> + */
> +static const struct ic_csc_params ic_csc_rgb2ycbcr_bt709 = {
> +   .coeff = {
> +   { 54, 183, 18 },
> +   { 483, 413, 128 },
> +   { 128, 396, 500 },
> +   },
> +   .offset = { 0, 512, 512 },
> +   .scale = 1,
> +};
> +
>  /*
>   * Inverse BT.601 encoding from YUV limited range to RGB full range:
>   *
> @@ -229,12 +246,31 @@ static const struct ic_csc_params 
> ic_csc_ycbcr2rgb_bt601 = {
> .scale = 2,
>  };
>
> +/*
> + * Inverse BT.709 encoding from YUV limited range to RGB full range:
> + *
> + * R = (1. * (Y - 16)) + (1.5748 * (Cr - 128));
> + * G = (1. * (Y - 16)) - (0.1873 * (Cb - 128)) - (0.4681 * (Cr - 128));
> + * B = (1. * (Y - 16)) + (1.8556 * (Cb - 128);
> + */
> +static const struct ic_csc_params ic_csc_ycbcr2rgb_bt709 = {
> +   .coeff = {
> +   { 128, 0, 202 },
> +   { 128, 488, 452 },
> +   { 128, 238, 0 },
> +   },
> +   .offset = { -435, 136, -507 },
> +   .scale = 2,
> +};
> +
>  static int init_csc(struct ipu_ic *ic,
> enum ipu_color_space inf,
> enum ipu_color_space outf,
> +   enum v4l2_ycbcr_encoding encoding,
> int csc_index)
>  {
> struct ipu_ic_priv *priv = ic->priv;
> +   const struct ic_csc_params *params_rgb2yuv, *params_yuv2rgb;
> const struct ic_csc_params *params;
> u32 __iomem *base;
> const u16 (*c)[3];
> @@ -244,12 +280,30 @@ static int init_csc(struct ipu_ic *ic,
> base = (u32 __iomem *)
> (priv->tpmem_base + ic->reg->tpmem_csc[csc_index]);
>
> +   switch (encoding) {
> +   case V4L2_YCBCR_ENC_601:
> +   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt601;
> +   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt601;
> +   break;
> +   case V4L2_YCBCR_ENC_709:
> +   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt709;
> +   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt709;
> +   break;
> +   default:
> +   if (inf != outf) {
> +   dev_err(priv->ipu->dev,
> +   "Unsupported YCbCr encoding\n");
> +   return -EINVAL;
> +   }
> +   break;
> +   }
> +
> if (inf == outf)
> params = &ic_csc_identity;
> else if (inf == IPUV3_COLORSPACE_YUV)
> -   params = &ic_csc_ycbcr2rgb_bt601;
> +   params = &ic_csc_ycbcr2rgb;


Steve,

compile issue...

params = params_yuv2rgb;

> else
> -   params = &ic_csc_rgb2ycbcr_bt601;
> +   params = &ic_csc_rgb2ycbcr;

params = params_rgb2yuv;

But, I'm still failing when using the mem2mem element (gst-launch-1.0
v4l2src device=/dev/video4 ! v4l2video8convert
output-io-mode=dmabuf-import ! fbdevsink) with 'Unsupported YCbCr
encoding' because of inf=IPU_COLORSPACE_YCBCR outf=IPU_COLORSPACE_RGB
and a seemingly unset encoding being passed in.

It looks like maybe something in the mem2mem driver isn't defaulting
encoding. The call path is (v4l2_m2m_streamon -> device_run ->
ipu_image_convert_queue -> convert_start -> ipu_ic_task_init_rsc ->
init_csc).

Tim
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 00/16] net: Remove switchdev_ops

2019-02-08 Thread Florian Fainelli
Hi all,

This patch series finishes by the removal of switchdev_ops. To get there
we need to do a few things:

- get rid of the one and only call to switchdev_port_attr_get() which is
  used to fetch the device's bridge port flags capabilities, instead we
  can just check what flags are being programmed during the prepare
  phase

- once we get rid of getting switchdev port attributes we convert the
  setting of such attributes using a blocking notifier

And then remove switchdev_ops completely.

Please review and let me know what you think!

Florian Fainelli (16):
  Documentation: networking: switchdev: Update port parent ID section
  mlxsw: spectrum: Check bridge flags during prepare phase
  staging: fsl-dpaa2: ethsw: Check bridge port flags during set
  net: dsa: Add setter for SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS
  rocker: Check bridge flags during prepare phase
  net: bridge: Stop calling switchdev_port_attr_get()
  net: Remove SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT
  net: Get rid of switchdev_port_attr_get()
  switchdev: Add SWITCHDEV_PORT_ATTR_SET
  rocker: Handle SWITCHDEV_PORT_ATTR_SET
  net: dsa: Handle SWITCHDEV_PORT_ATTR_SET
  mlxsw: spectrum_switchdev: Handle SWITCHDEV_PORT_ATTR_SET
  net: mscc: ocelot: Handle SWITCHDEV_PORT_ATTR_SET
  staging: fsl-dpaa2: ethsw: Handle SWITCHDEV_PORT_ATTR_SET
  net: switchdev: Replace port attr set SDO with a notification
  net: Remove switchdev_ops

 Documentation/networking/switchdev.txt| 15 ++-
 .../net/ethernet/mellanox/mlxsw/spectrum.c| 12 ---
 .../net/ethernet/mellanox/mlxsw/spectrum.h|  2 -
 .../mellanox/mlxsw/spectrum_switchdev.c   | 72 +-
 drivers/net/ethernet/mscc/ocelot.c| 25 -
 drivers/net/ethernet/rocker/rocker_main.c | 99 +--
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c   | 52 +-
 include/linux/netdevice.h |  3 -
 include/net/switchdev.h   | 37 ++-
 net/bridge/br_switchdev.c | 20 +---
 net/dsa/dsa_priv.h|  3 +
 net/dsa/port.c| 10 ++
 net/dsa/slave.c   | 44 +
 net/switchdev/switchdev.c | 92 +
 14 files changed, 190 insertions(+), 296 deletions(-)

-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 04/16] net: dsa: Add setter for SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS

2019-02-08 Thread Florian Fainelli
In preparation for removing SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
add support for a function that processes the
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS attribute and returns not supported
for any flag set, since DSA does not currently support toggling those
bridge port attributes (yet).

Signed-off-by: Florian Fainelli 
---
 net/dsa/dsa_priv.h |  3 +++
 net/dsa/port.c | 10 ++
 net/dsa/slave.c|  4 
 3 files changed, 17 insertions(+)

diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 1f4972dab9f2..97594f0b6efb 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -150,6 +150,9 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool 
vlan_filtering,
struct switchdev_trans *trans);
 int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
 struct switchdev_trans *trans);
+int dsa_port_bridge_port_flags_set(struct dsa_port *dp,
+  unsigned long brport_flags,
+  struct switchdev_trans *trans);
 int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
 u16 vid);
 int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 2d7e01b23572..2ce3752203cf 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -177,6 +177,16 @@ int dsa_port_ageing_time(struct dsa_port *dp, clock_t 
ageing_clock,
return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
 }
 
+int dsa_port_bridge_port_flags_set(struct dsa_port *dp,
+  unsigned long brport_flags,
+  struct switchdev_trans *trans)
+{
+   if (brport_flags)
+   return -EOPNOTSUPP;
+
+   return 0;
+}
+
 int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
 u16 vid)
 {
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 70395a0ae52e..212fc1cc27fc 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -292,6 +292,10 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
ret = dsa_port_ageing_time(dp, attr->u.ageing_time, trans);
break;
+   case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
+   ret = dsa_port_bridge_port_flags_set(dp, attr->u.brport_flags,
+trans);
+   break;
default:
ret = -EOPNOTSUPP;
break;
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 06/16] net: bridge: Stop calling switchdev_port_attr_get()

2019-02-08 Thread Florian Fainelli
Now that all switchdev drivers have been converted to checking the
bridge port flags during the prepare phase of the
switchdev_port_attr_set(), we can move straight to trying to set the
desired flag through SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS.

Signed-off-by: Florian Fainelli 
---
 net/bridge/br_switchdev.c | 20 +++-
 1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c
index db9e8ab96d48..939f300522c5 100644
--- a/net/bridge/br_switchdev.c
+++ b/net/bridge/br_switchdev.c
@@ -64,29 +64,15 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
 {
struct switchdev_attr attr = {
.orig_dev = p->dev,
-   .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
+   .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
+   .flags = SWITCHDEV_F_DEFER,
+   .u.brport_flags = flags,
};
int err;
 
if (mask & ~BR_PORT_FLAGS_HW_OFFLOAD)
return 0;
 
-   err = switchdev_port_attr_get(p->dev, &attr);
-   if (err == -EOPNOTSUPP)
-   return 0;
-   if (err)
-   return err;
-
-   /* Check if specific bridge flag attribute offload is supported */
-   if (!(attr.u.brport_flags_support & mask)) {
-   br_warn(p->br, "bridge flag offload is not supported %u(%s)\n",
-   (unsigned int)p->port_no, p->dev->name);
-   return -EOPNOTSUPP;
-   }
-
-   attr.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS;
-   attr.flags = SWITCHDEV_F_DEFER;
-   attr.u.brport_flags = flags;
err = switchdev_port_attr_set(p->dev, &attr);
if (err) {
br_warn(p->br, "error setting offload flag on port %u(%s)\n",
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 05/16] rocker: Check bridge flags during prepare phase

2019-02-08 Thread Florian Fainelli
In preparation for getting rid of switchdev_port_attr_get(), have rocker
check for the bridge flags being set through switchdev_port_attr_set()
with the SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS attribute identifier.

Signed-off-by: Florian Fainelli 
---
 drivers/net/ethernet/rocker/rocker_main.c | 40 ++-
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/rocker/rocker_main.c 
b/drivers/net/ethernet/rocker/rocker_main.c
index 66f72f8c46e5..8657313b6f30 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -1565,18 +1565,42 @@ static int rocker_world_port_attr_stp_state_set(struct 
rocker_port *rocker_port,
return wops->port_attr_stp_state_set(rocker_port, state);
 }
 
+static int
+rocker_world_port_attr_bridge_flags_support_get(const struct rocker_port *
+   rocker_port,
+   unsigned long *
+   p_brport_flags_support)
+{
+   struct rocker_world_ops *wops = rocker_port->rocker->wops;
+
+   if (!wops->port_attr_bridge_flags_support_get)
+   return -EOPNOTSUPP;
+   return wops->port_attr_bridge_flags_support_get(rocker_port,
+   p_brport_flags_support);
+}
+
 static int
 rocker_world_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
unsigned long brport_flags,
struct switchdev_trans *trans)
 {
struct rocker_world_ops *wops = rocker_port->rocker->wops;
+   unsigned long brport_flags_s;
+   int err;
 
if (!wops->port_attr_bridge_flags_set)
return -EOPNOTSUPP;
 
-   if (switchdev_trans_ph_prepare(trans))
+   if (switchdev_trans_ph_prepare(trans)) {
+   err = 
rocker_world_port_attr_bridge_flags_support_get(rocker_port,
+ &brport_flags_s);
+   if (err)
+   return err;
+
+   if (brport_flags & ~brport_flags_s)
+   return -EOPNOTSUPP;
return 0;
+   }
 
return wops->port_attr_bridge_flags_set(rocker_port, brport_flags,
trans);
@@ -1593,20 +1617,6 @@ rocker_world_port_attr_bridge_flags_get(const struct 
rocker_port *rocker_port,
return wops->port_attr_bridge_flags_get(rocker_port, p_brport_flags);
 }
 
-static int
-rocker_world_port_attr_bridge_flags_support_get(const struct rocker_port *
-   rocker_port,
-   unsigned long *
-   p_brport_flags_support)
-{
-   struct rocker_world_ops *wops = rocker_port->rocker->wops;
-
-   if (!wops->port_attr_bridge_flags_support_get)
-   return -EOPNOTSUPP;
-   return wops->port_attr_bridge_flags_support_get(rocker_port,
-   p_brport_flags_support);
-}
-
 static int
 rocker_world_port_attr_bridge_ageing_time_set(struct rocker_port *rocker_port,
  u32 ageing_time,
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 02/16] mlxsw: spectrum: Check bridge flags during prepare phase

2019-02-08 Thread Florian Fainelli
In preparation for getting rid of switchdev_port_attr_get(), have mlxsw
check for the bridge flags being set through switchdev_port_attr_set()
with the SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS attribute identifier.

Signed-off-by: Florian Fainelli 
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 95e37de3e48f..468a6d513074 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -623,8 +623,11 @@ static int mlxsw_sp_port_attr_br_flags_set(struct 
mlxsw_sp_port *mlxsw_sp_port,
struct mlxsw_sp_bridge_port *bridge_port;
int err;
 
-   if (switchdev_trans_ph_prepare(trans))
+   if (switchdev_trans_ph_prepare(trans)) {
+   if (brport_flags & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD))
+   return -EOPNOTSUPP;
return 0;
+   }
 
bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp_port->mlxsw_sp->bridge,
orig_dev);
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 03/16] staging: fsl-dpaa2: ethsw: Check bridge port flags during set

2019-02-08 Thread Florian Fainelli
In preparation for removing SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
have ethsw check that the bridge port flags that are being set are
supported.

Signed-off-by: Florian Fainelli 
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c 
b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index e559f4c25cf7..6228c4375835 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -680,8 +680,11 @@ static int port_attr_br_flags_set(struct net_device 
*netdev,
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
int err = 0;
 
-   if (switchdev_trans_ph_prepare(trans))
+   if (switchdev_trans_ph_prepare(trans)) {
+   if (flags & ~(BR_LEARNING | BR_FLOOD))
+   return -EOPNOTSUPP;
return 0;
+   }
 
/* Learning is enabled per switch */
err = ethsw_set_learning(port_priv->ethsw_data, flags & BR_LEARNING);
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 09/16] switchdev: Add SWITCHDEV_PORT_ATTR_SET

2019-02-08 Thread Florian Fainelli
In preparation for allowing switchdev enabled drivers to veto specific
attribute settings from within the context of the caller, introduce a
new switchdev notifier type for port attributes.

Suggested-by: Ido Schimmel 
Signed-off-by: Florian Fainelli 
---
 include/net/switchdev.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 96cd3e795f7f..4c5f7e5430cf 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -141,6 +141,8 @@ enum switchdev_notifier_type {
SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE,
SWITCHDEV_VXLAN_FDB_DEL_TO_DEVICE,
SWITCHDEV_VXLAN_FDB_OFFLOADED,
+
+   SWITCHDEV_PORT_ATTR_SET, /* Blocking. */
 };
 
 struct switchdev_notifier_info {
@@ -163,6 +165,13 @@ struct switchdev_notifier_port_obj_info {
bool handled;
 };
 
+struct switchdev_notifier_port_attr_info {
+   struct switchdev_notifier_info info; /* must be first */
+   const struct switchdev_attr *attr;
+   struct switchdev_trans *trans;
+   bool handled;
+};
+
 static inline struct net_device *
 switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
 {
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 08/16] net: Get rid of switchdev_port_attr_get()

2019-02-08 Thread Florian Fainelli
With the bridge no longer calling switchdev_port_attr_get() to obtain
the supported bridge port flags from a driver but instead trying to set
the bridge port flags directly and relying on driver to reject
unsupported configurations, we can effectively get rid of
switchdev_port_attr_get() entirely since this was the only place where
it was called.

Signed-off-by: Florian Fainelli 
---
 Documentation/networking/switchdev.txt|  5 ++-
 .../mellanox/mlxsw/spectrum_switchdev.c   | 32 ---
 drivers/net/ethernet/rocker/rocker_main.c | 30 -
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c   | 19 ---
 include/net/switchdev.h   |  8 -
 net/dsa/slave.c   |  7 
 6 files changed, 2 insertions(+), 99 deletions(-)

diff --git a/Documentation/networking/switchdev.txt 
b/Documentation/networking/switchdev.txt
index 2842f63ad47b..0d9530bf745b 100644
--- a/Documentation/networking/switchdev.txt
+++ b/Documentation/networking/switchdev.txt
@@ -233,9 +233,8 @@ the bridge's FDB.  It's possible, but not optimal, to 
enable learning on the
 device port and on the bridge port, and disable learning_sync.
 
 To support learning and learning_sync port attributes, the driver implements
-switchdev op switchdev_port_attr_get/set for
-SWITCHDEV_ATTR_PORT_ID_BRIDGE_FLAGS. The driver should initialize the 
attributes
-to the hardware defaults.
+switchdev op switchdev_port_attr_set for SWITCHDEV_ATTR_PORT_ID_BRIDGE_FLAGS.
+The driver should initialize the attributes to the hardware defaults.
 
 FDB Ageing
 ^^
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 8242a373f6e7..6b09d68671cf 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -431,37 +431,6 @@ static void mlxsw_sp_bridge_vlan_put(struct 
mlxsw_sp_bridge_vlan *bridge_vlan)
mlxsw_sp_bridge_vlan_destroy(bridge_vlan);
 }
 
-static void mlxsw_sp_port_bridge_flags_get(struct mlxsw_sp_bridge *bridge,
-  struct net_device *dev,
-  unsigned long *brport_flags)
-{
-   struct mlxsw_sp_bridge_port *bridge_port;
-
-   bridge_port = mlxsw_sp_bridge_port_find(bridge, dev);
-   if (WARN_ON(!bridge_port))
-   return;
-
-   memcpy(brport_flags, &bridge_port->flags, sizeof(*brport_flags));
-}
-
-static int mlxsw_sp_port_attr_get(struct net_device *dev,
- struct switchdev_attr *attr)
-{
-   struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
-   struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-
-   switch (attr->id) {
-   case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
-   mlxsw_sp_port_bridge_flags_get(mlxsw_sp->bridge, attr->orig_dev,
-  &attr->u.brport_flags);
-   break;
-   default:
-   return -EOPNOTSUPP;
-   }
-
-   return 0;
-}
-
 static int
 mlxsw_sp_port_bridge_vlan_stp_set(struct mlxsw_sp_port *mlxsw_sp_port,
  struct mlxsw_sp_bridge_vlan *bridge_vlan,
@@ -1957,7 +1926,6 @@ static struct mlxsw_sp_port *mlxsw_sp_lag_rep_port(struct 
mlxsw_sp *mlxsw_sp,
 }
 
 static const struct switchdev_ops mlxsw_sp_port_switchdev_ops = {
-   .switchdev_port_attr_get= mlxsw_sp_port_attr_get,
.switchdev_port_attr_set= mlxsw_sp_port_attr_set,
 };
 
diff --git a/drivers/net/ethernet/rocker/rocker_main.c 
b/drivers/net/ethernet/rocker/rocker_main.c
index 375c4c908bea..ff3f14504f4f 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -1606,17 +1606,6 @@ rocker_world_port_attr_bridge_flags_set(struct 
rocker_port *rocker_port,
trans);
 }
 
-static int
-rocker_world_port_attr_bridge_flags_get(const struct rocker_port *rocker_port,
-   unsigned long *p_brport_flags)
-{
-   struct rocker_world_ops *wops = rocker_port->rocker->wops;
-
-   if (!wops->port_attr_bridge_flags_get)
-   return -EOPNOTSUPP;
-   return wops->port_attr_bridge_flags_get(rocker_port, p_brport_flags);
-}
-
 static int
 rocker_world_port_attr_bridge_ageing_time_set(struct rocker_port *rocker_port,
  u32 ageing_time,
@@ -2064,24 +2053,6 @@ static const struct net_device_ops 
rocker_port_netdev_ops = {
  * swdev interface
  /
 
-static int rocker_port_attr_get(struct net_device *dev,
-   struct switchdev_attr *attr)
-{
-   const struct rocker_port *rocker_port = netdev_priv(dev);
-   int err = 0;
-
-   switch (attr->id) {
-   case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
-   er

[PATCH net-next 01/16] Documentation: networking: switchdev: Update port parent ID section

2019-02-08 Thread Florian Fainelli
Update the section about switchdev drivers having to implement a
switchdev_port_attr_get() function to return
SWITCHDEV_ATTR_ID_PORT_PARENT_ID since that is no longer valid after
commit bccb30254a4a ("net: Get rid of
SWITCHDEV_ATTR_ID_PORT_PARENT_ID").

Fixes: bccb30254a4a ("net: Get rid of SWITCHDEV_ATTR_ID_PORT_PARENT_ID")
Signed-off-by: Florian Fainelli 
---
 Documentation/networking/switchdev.txt | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/networking/switchdev.txt 
b/Documentation/networking/switchdev.txt
index f3244d87512a..2842f63ad47b 100644
--- a/Documentation/networking/switchdev.txt
+++ b/Documentation/networking/switchdev.txt
@@ -92,11 +92,11 @@ device.
 Switch ID
 ^
 
-The switchdev driver must implement the switchdev op switchdev_port_attr_get
-for SWITCHDEV_ATTR_ID_PORT_PARENT_ID for each port netdev, returning the same
-physical ID for each port of a switch.  The ID must be unique between switches
-on the same system.  The ID does not need to be unique between switches on
-different systems.
+The switchdev driver must implement the net_device operation
+ndo_get_port_parent_id for each port netdev,  returning the same physical ID
+for each port of a switch. The ID must be unique between switches on the same
+system. The ID does not need to be unique between switches on different
+systems.
 
 The switch ID is used to locate ports on a switch and to know if aggregated
 ports belong to the same switch.
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 14/16] staging: fsl-dpaa2: ethsw: Handle SWITCHDEV_PORT_ATTR_SET

2019-02-08 Thread Florian Fainelli
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.

Prepare ethsw to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_SET and simply translate that into the existing
swdev_port_attr_set() call.

Signed-off-by: Florian Fainelli 
---
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c 
b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index b195b09e0d1d..d40bdcadd569 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -1092,6 +1092,24 @@ ethsw_switchdev_port_obj_event(unsigned long event, 
struct net_device *netdev,
return notifier_from_errno(err);
 }
 
+static int
+ethsw_switchdev_port_attr_event(unsigned long event,
+   struct net_device *netdev,
+   struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+   int err = -EOPNOTSUPP;
+
+   switch (event) {
+   case SWITCHDEV_PORT_ATTR_SET:
+   err = swdev_port_attr_set(netdev, port_attr_info->attr,
+ port_attr_info->trans);
+   break;
+   }
+
+   port_attr_info->handled = true;
+   return notifier_from_errno(err);
+}
+
 static int port_switchdev_blocking_event(struct notifier_block *unused,
 unsigned long event, void *ptr)
 {
@@ -1104,6 +1122,8 @@ static int port_switchdev_blocking_event(struct 
notifier_block *unused,
case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
case SWITCHDEV_PORT_OBJ_DEL:
return ethsw_switchdev_port_obj_event(event, dev, ptr);
+   case SWITCHDEV_PORT_ATTR_SET:
+   return ethsw_switchdev_port_attr_event(event, dev, ptr);
}
 
return NOTIFY_DONE;
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 07/16] net: Remove SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT

2019-02-08 Thread Florian Fainelli
Now that we have converted the bridge code and the drivers to check for
bridge port(s) flags at the time we try to set them, there is no need
for a get() -> set() sequence anymore and
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT therefore becomes unused.

Signed-off-by: Florian Fainelli 
---
 .../net/ethernet/mellanox/mlxsw/spectrum_switchdev.c   |  4 
 drivers/net/ethernet/rocker/rocker_main.c  |  4 
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c|  3 ---
 include/net/switchdev.h|  2 --
 net/dsa/slave.c| 10 +-
 5 files changed, 1 insertion(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 468a6d513074..8242a373f6e7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -455,10 +455,6 @@ static int mlxsw_sp_port_attr_get(struct net_device *dev,
mlxsw_sp_port_bridge_flags_get(mlxsw_sp->bridge, attr->orig_dev,
   &attr->u.brport_flags);
break;
-   case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
-   attr->u.brport_flags_support = BR_LEARNING | BR_FLOOD |
-  BR_MCAST_FLOOD;
-   break;
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/rocker/rocker_main.c 
b/drivers/net/ethernet/rocker/rocker_main.c
index 8657313b6f30..375c4c908bea 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2075,10 +2075,6 @@ static int rocker_port_attr_get(struct net_device *dev,
err = rocker_world_port_attr_bridge_flags_get(rocker_port,
  
&attr->u.brport_flags);
break;
-   case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
-   err = 
rocker_world_port_attr_bridge_flags_support_get(rocker_port,
- 
&attr->u.brport_flags_support);
-   break;
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c 
b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
index 6228c4375835..79635d1091df 100644
--- a/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/ethsw.c
@@ -651,9 +651,6 @@ static int swdev_port_attr_get(struct net_device *netdev,
(port_priv->ethsw_data->learning ? BR_LEARNING : 0) |
(port_priv->flood ? BR_FLOOD : 0);
break;
-   case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
-   attr->u.brport_flags_support = BR_LEARNING | BR_FLOOD;
-   break;
default:
return -EOPNOTSUPP;
}
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 5e87b54c5dc5..e2083824e577 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -45,7 +45,6 @@ enum switchdev_attr_id {
SWITCHDEV_ATTR_ID_UNDEFINED,
SWITCHDEV_ATTR_ID_PORT_STP_STATE,
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
-   SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
SWITCHDEV_ATTR_ID_PORT_MROUTER,
SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
@@ -62,7 +61,6 @@ struct switchdev_attr {
union {
u8 stp_state;   /* PORT_STP_STATE */
unsigned long brport_flags; /* PORT_BRIDGE_FLAGS */
-   unsigned long brport_flags_support; /* 
PORT_BRIDGE_FLAGS_SUPPORT */
bool mrouter;   /* PORT_MROUTER */
clock_t ageing_time;/* BRIDGE_AGEING_TIME */
bool vlan_filtering;/* 
BRIDGE_VLAN_FILTERING */
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 212fc1cc27fc..5797da954e77 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -382,15 +382,7 @@ static int dsa_slave_get_port_parent_id(struct net_device 
*dev,
 static int dsa_slave_port_attr_get(struct net_device *dev,
   struct switchdev_attr *attr)
 {
-   switch (attr->id) {
-   case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
-   attr->u.brport_flags_support = 0;
-   break;
-   default:
-   return -EOPNOTSUPP;
-   }
-
-   return 0;
+   return -EOPNOTSUPP;
 }
 
 static inline netdev_tx_t dsa_slave_netpoll_send_skb(struct net_device *dev,
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 12/16] mlxsw: spectrum_switchdev: Handle SWITCHDEV_PORT_ATTR_SET

2019-02-08 Thread Florian Fainelli
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.

Prepare mlxsw to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_SET and simply translate that into the existing
mlxsw_sp_port_attr_set() call.

Signed-off-by: Florian Fainelli 
---
 .../mellanox/mlxsw/spectrum_switchdev.c   | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 6b09d68671cf..29ffb5cac777 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -3410,6 +3410,23 @@ mlxsw_sp_switchdev_handle_vxlan_obj_del(struct 
net_device *vxlan_dev,
}
 }
 
+static int
+mlxsw_sp_switchdev_port_attr_event(unsigned long event, struct net_device *dev,
+   struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+   int err = -EOPNOTSUPP;
+
+   switch (event) {
+   case SWITCHDEV_PORT_ATTR_SET:
+   err = mlxsw_sp_port_attr_set(dev, port_attr_info->attr,
+port_attr_info->trans);
+   break;
+   }
+
+   port_attr_info->handled = true;
+   return notifier_from_errno(err);
+}
+
 static int mlxsw_sp_switchdev_blocking_event(struct notifier_block *unused,
 unsigned long event, void *ptr)
 {
@@ -3433,6 +3450,8 @@ static int mlxsw_sp_switchdev_blocking_event(struct 
notifier_block *unused,
mlxsw_sp_port_dev_check,
mlxsw_sp_port_obj_del);
return notifier_from_errno(err);
+   case SWITCHDEV_PORT_ATTR_SET:
+   return mlxsw_sp_switchdev_port_attr_event(event, dev, ptr);
}
 
return NOTIFY_DONE;
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 10/16] rocker: Handle SWITCHDEV_PORT_ATTR_SET

2019-02-08 Thread Florian Fainelli
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.

Prepare rocker to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_SET and simply translate that into the existing
rocker_port_attr_set call.

Signed-off-by: Florian Fainelli 
---
 drivers/net/ethernet/rocker/rocker_main.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/net/ethernet/rocker/rocker_main.c 
b/drivers/net/ethernet/rocker/rocker_main.c
index ff3f14504f4f..f10e4888ecff 100644
--- a/drivers/net/ethernet/rocker/rocker_main.c
+++ b/drivers/net/ethernet/rocker/rocker_main.c
@@ -2811,6 +2811,24 @@ rocker_switchdev_port_obj_event(unsigned long event, 
struct net_device *netdev,
return notifier_from_errno(err);
 }
 
+static int
+rocker_switchdev_port_attr_event(unsigned long event, struct net_device 
*netdev,
+struct switchdev_notifier_port_attr_info
+*port_attr_info)
+{
+   int err = -EOPNOTSUPP;
+
+   switch (event) {
+   case SWITCHDEV_PORT_ATTR_SET:
+   err = rocker_port_attr_set(netdev, port_attr_info->attr,
+  port_attr_info->trans);
+   break;
+   }
+
+   port_attr_info->handled = true;
+   return notifier_from_errno(err);
+}
+
 static int rocker_switchdev_blocking_event(struct notifier_block *unused,
   unsigned long event, void *ptr)
 {
@@ -2823,6 +2841,8 @@ static int rocker_switchdev_blocking_event(struct 
notifier_block *unused,
case SWITCHDEV_PORT_OBJ_ADD:
case SWITCHDEV_PORT_OBJ_DEL:
return rocker_switchdev_port_obj_event(event, dev, ptr);
+   case SWITCHDEV_PORT_ATTR_SET:
+   return rocker_switchdev_port_attr_event(event, dev, ptr);
}
 
return NOTIFY_DONE;
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 13/16] net: mscc: ocelot: Handle SWITCHDEV_PORT_ATTR_SET

2019-02-08 Thread Florian Fainelli
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.

Prepare ocelot to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_SET and simply translate that into the existing
ocelot_port_attr_set() call.

Signed-off-by: Florian Fainelli 
---
 drivers/net/ethernet/mscc/ocelot.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot.c 
b/drivers/net/ethernet/mscc/ocelot.c
index 195306d05bcd..adab478d36f1 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -1324,10 +1324,6 @@ static int ocelot_port_obj_del(struct net_device *dev,
return ret;
 }
 
-static const struct switchdev_ops ocelot_port_switchdev_ops = {
-   .switchdev_port_attr_set= ocelot_port_attr_set,
-};
-
 static int ocelot_port_bridge_join(struct ocelot_port *ocelot_port,
   struct net_device *bridge)
 {
@@ -1582,6 +1578,24 @@ struct notifier_block ocelot_netdevice_nb __read_mostly 
= {
 };
 EXPORT_SYMBOL(ocelot_netdevice_nb);
 
+static int
+ocelot_switchdev_port_attr_event(unsigned long event,
+   struct net_device *netdev,
+   struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+   int err = -EOPNOTSUPP;
+
+   switch (event) {
+   case SWITCHDEV_PORT_ATTR_SET:
+   err = ocelot_port_attr_set(netdev, port_attr_info->attr,
+  port_attr_info->trans);
+   break;
+   }
+
+   port_attr_info->handled = true;
+   return notifier_from_errno(err);
+}
+
 static int ocelot_switchdev_blocking_event(struct notifier_block *unused,
   unsigned long event, void *ptr)
 {
@@ -1600,6 +1614,8 @@ static int ocelot_switchdev_blocking_event(struct 
notifier_block *unused,
ocelot_netdevice_dev_check,
ocelot_port_obj_del);
return notifier_from_errno(err);
+   case SWITCHDEV_PORT_ATTR_SET:
+   return ocelot_switchdev_port_attr_event(event, dev, ptr);
}
 
return NOTIFY_DONE;
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 15/16] net: switchdev: Replace port attr set SDO with a notification

2019-02-08 Thread Florian Fainelli
Drop switchdev_ops.switchdev_port_attr_set. Drop the uses of this field
from all clients, which were migrated to use switchdev notification in
the previous patches.

Add a new function switchdev_port_attr_notify() that sends the switchdev
notifications SWITCHDEV_PORT_ATTR_SET.

Drop __switchdev_port_attr_set() and update switchdev_port_attr_set()
likewise.

Signed-off-by: Florian Fainelli 
---
 include/net/switchdev.h   | 18 
 net/switchdev/switchdev.c | 92 ++-
 2 files changed, 22 insertions(+), 88 deletions(-)

diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index 4c5f7e5430cf..5387ff6f41c5 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -111,21 +111,6 @@ void *switchdev_trans_item_dequeue(struct switchdev_trans 
*trans);
 
 typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
 
-/**
- * struct switchdev_ops - switchdev operations
- *
- * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
- *
- * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
- */
-struct switchdev_ops {
-   int (*switchdev_port_attr_get)(struct net_device *dev,
-  struct switchdev_attr *attr);
-   int (*switchdev_port_attr_set)(struct net_device *dev,
-  const struct switchdev_attr *attr,
-  struct switchdev_trans *trans);
-};
-
 enum switchdev_notifier_type {
SWITCHDEV_FDB_ADD_TO_BRIDGE = 1,
SWITCHDEV_FDB_DEL_TO_BRIDGE,
@@ -224,7 +209,6 @@ int switchdev_handle_port_obj_del(struct net_device *dev,
int (*del_cb)(struct net_device *dev,
  const struct switchdev_obj *obj));
 
-#define SWITCHDEV_SET_OPS(netdev, ops) ((netdev)->switchdev_ops = (ops))
 #else
 
 static inline void switchdev_deferred_process(void)
@@ -311,8 +295,6 @@ switchdev_handle_port_obj_del(struct net_device *dev,
return 0;
 }
 
-#define SWITCHDEV_SET_OPS(netdev, ops) do {} while (0)
-
 #endif
 
 #endif /* _LINUX_SWITCHDEV_H_ */
diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
index 7e1357db33d7..5a053e20363e 100644
--- a/net/switchdev/switchdev.c
+++ b/net/switchdev/switchdev.c
@@ -174,81 +174,31 @@ static int switchdev_deferred_enqueue(struct net_device 
*dev,
return 0;
 }
 
-/**
- * switchdev_port_attr_get - Get port attribute
- *
- * @dev: port device
- * @attr: attribute to get
- */
-int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr 
*attr)
+static int switchdev_port_attr_notify(enum switchdev_notifier_type nt,
+ struct net_device *dev,
+ struct switchdev_attr *attr,
+ struct switchdev_trans *trans)
 {
-   const struct switchdev_ops *ops = dev->switchdev_ops;
-   struct net_device *lower_dev;
-   struct list_head *iter;
-   struct switchdev_attr first = {
-   .id = SWITCHDEV_ATTR_ID_UNDEFINED
-   };
-   int err = -EOPNOTSUPP;
+   int err;
+   int rc;
 
-   if (ops && ops->switchdev_port_attr_get)
-   return ops->switchdev_port_attr_get(dev, attr);
+   struct switchdev_notifier_port_attr_info attr_info = {
+   .attr = attr,
+   .trans = trans,
+   .handled = false,
+   };
 
-   if (attr->flags & SWITCHDEV_F_NO_RECURSE)
+   rc = call_switchdev_blocking_notifiers(nt, dev, &attr_info.info, NULL);
+   err = notifier_to_errno(rc);
+   if (err) {
+   WARN_ON(!attr_info.handled);
return err;
-
-   /* Switch device port(s) may be stacked under
-* bond/team/vlan dev, so recurse down to get attr on
-* each port.  Return -ENODATA if attr values don't
-* compare across ports.
-*/
-
-   netdev_for_each_lower_dev(dev, lower_dev, iter) {
-   err = switchdev_port_attr_get(lower_dev, attr);
-   if (err)
-   break;
-   if (first.id == SWITCHDEV_ATTR_ID_UNDEFINED)
-   first = *attr;
-   else if (memcmp(&first, attr, sizeof(*attr)))
-   return -ENODATA;
}
 
-   return err;
-}
-EXPORT_SYMBOL_GPL(switchdev_port_attr_get);
-
-static int __switchdev_port_attr_set(struct net_device *dev,
-const struct switchdev_attr *attr,
-struct switchdev_trans *trans)
-{
-   const struct switchdev_ops *ops = dev->switchdev_ops;
-   struct net_device *lower_dev;
-   struct list_head *iter;
-   int err = -EOPNOTSUPP;
-
-   if (ops && ops->switchdev_port_attr_set) {
-   err = ops->switchdev_port_attr_set(dev, attr, trans);
-   goto done;
-   }
-
-   if (attr->flags & SWITCH

[PATCH net-next 11/16] net: dsa: Handle SWITCHDEV_PORT_ATTR_SET

2019-02-08 Thread Florian Fainelli
Following patches will change the way we communicate getting or setting
a port's attribute and use a blocking notifier to perform those tasks.

Prepare DSA to support receiving notifier events targeting
SWITCHDEV_PORT_ATTR_SET and simply translate that into the existing
dsa_slave_port_attr_set() call.

Signed-off-by: Florian Fainelli 
---
 net/dsa/slave.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index ae34be949d79..f8c7c1b2cd2f 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1544,6 +1544,24 @@ dsa_slave_switchdev_port_obj_event(unsigned long event,
return notifier_from_errno(err);
 }
 
+static int
+dsa_slave_switchdev_port_attr_event(unsigned long event,
+   struct net_device *netdev,
+   struct switchdev_notifier_port_attr_info *port_attr_info)
+{
+   int err = -EOPNOTSUPP;
+
+   switch (event) {
+   case SWITCHDEV_PORT_ATTR_SET:
+   err = dsa_slave_port_attr_set(netdev, port_attr_info->attr,
+ port_attr_info->trans);
+   break;
+   }
+
+   port_attr_info->handled = true;
+   return notifier_from_errno(err);
+}
+
 static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
  unsigned long event, void *ptr)
 {
@@ -1556,6 +1574,8 @@ static int dsa_slave_switchdev_blocking_event(struct 
notifier_block *unused,
case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
case SWITCHDEV_PORT_OBJ_DEL:
return dsa_slave_switchdev_port_obj_event(event, dev, ptr);
+   case SWITCHDEV_PORT_ATTR_SET: /* fallthrough */
+   return dsa_slave_switchdev_port_attr_event(event, dev, ptr);
}
 
return NOTIFY_DONE;
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH net-next 16/16] net: Remove switchdev_ops

2019-02-08 Thread Florian Fainelli
Now that we have converted all possible callers to using a switchdev
notifier for attributes we do not have a need for implementing
switchdev_ops anymore, and this can be removed from all drivers the
net_device structure.

Signed-off-by: Florian Fainelli 
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c   | 12 
 drivers/net/ethernet/mellanox/mlxsw/spectrum.h   |  2 --
 .../net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 12 
 drivers/net/ethernet/mscc/ocelot.c   |  1 -
 drivers/net/ethernet/rocker/rocker_main.c|  5 -
 drivers/staging/fsl-dpaa2/ethsw/ethsw.c  |  5 -
 include/linux/netdevice.h|  3 ---
 net/dsa/slave.c  |  5 -
 8 files changed, 45 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 8dd808b7f931..18b56afbd5d7 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3220,7 +3220,6 @@ static int mlxsw_sp_port_create(struct mlxsw_sp 
*mlxsw_sp, u8 local_port,
}
mlxsw_sp_port->default_vlan = mlxsw_sp_port_vlan;
 
-   mlxsw_sp_port_switchdev_init(mlxsw_sp_port);
mlxsw_sp->ports[local_port] = mlxsw_sp_port;
err = register_netdev(dev);
if (err) {
@@ -3237,7 +3236,6 @@ static int mlxsw_sp_port_create(struct mlxsw_sp 
*mlxsw_sp, u8 local_port,
 
 err_register_netdev:
mlxsw_sp->ports[local_port] = NULL;
-   mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
mlxsw_sp_port_vlan_destroy(mlxsw_sp_port_vlan);
 err_port_vlan_create:
 err_port_pvid_set:
@@ -3280,7 +3278,6 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp 
*mlxsw_sp, u8 local_port)
mlxsw_core_port_clear(mlxsw_sp->core, local_port, mlxsw_sp);
unregister_netdev(mlxsw_sp_port->dev); /* This calls ndo_stop */
mlxsw_sp->ports[local_port] = NULL;
-   mlxsw_sp_port_switchdev_fini(mlxsw_sp_port);
mlxsw_sp_port_vlan_flush(mlxsw_sp_port, true);
mlxsw_sp_port_nve_fini(mlxsw_sp_port);
mlxsw_sp_tc_qdisc_fini(mlxsw_sp_port);
@@ -4001,12 +3998,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
goto err_span_init;
}
 
-   err = mlxsw_sp_switchdev_init(mlxsw_sp);
-   if (err) {
-   dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize 
switchdev\n");
-   goto err_switchdev_init;
-   }
-
err = mlxsw_sp_counter_pool_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to init counter 
pool\n");
@@ -4077,8 +4068,6 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
 err_afa_init:
mlxsw_sp_counter_pool_fini(mlxsw_sp);
 err_counter_pool_init:
-   mlxsw_sp_switchdev_fini(mlxsw_sp);
-err_switchdev_init:
mlxsw_sp_span_fini(mlxsw_sp);
 err_span_init:
mlxsw_sp_lag_fini(mlxsw_sp);
@@ -4141,7 +4130,6 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
mlxsw_sp_nve_fini(mlxsw_sp);
mlxsw_sp_afa_fini(mlxsw_sp);
mlxsw_sp_counter_pool_fini(mlxsw_sp);
-   mlxsw_sp_switchdev_fini(mlxsw_sp);
mlxsw_sp_span_fini(mlxsw_sp);
mlxsw_sp_lag_fini(mlxsw_sp);
mlxsw_sp_buffers_fini(mlxsw_sp);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index 4fe0996c7cdd..76f51087e35a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -375,8 +375,6 @@ u32 mlxsw_sp_bytes_cells(const struct mlxsw_sp *mlxsw_sp, 
u32 bytes);
 /* spectrum_switchdev.c */
 int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp);
 void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp);
-void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port);
-void mlxsw_sp_port_switchdev_fini(struct mlxsw_sp_port *mlxsw_sp_port);
 int mlxsw_sp_rif_fdb_op(struct mlxsw_sp *mlxsw_sp, const char *mac, u16 fid,
bool adding);
 void
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index 29ffb5cac777..9951cfe0b244 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -1925,10 +1925,6 @@ static struct mlxsw_sp_port 
*mlxsw_sp_lag_rep_port(struct mlxsw_sp *mlxsw_sp,
return NULL;
 }
 
-static const struct switchdev_ops mlxsw_sp_port_switchdev_ops = {
-   .switchdev_port_attr_set= mlxsw_sp_port_attr_set,
-};
-
 static int
 mlxsw_sp_bridge_8021q_port_join(struct mlxsw_sp_bridge_device *bridge_device,
struct mlxsw_sp_bridge_port *bridge_port,
@@ -3539,11 +3535,3 @@ void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp)
kfree(mlxsw_sp->bridge);
 }
 
-void mlxsw_sp_port_swi

Re: [PATCH net-next 15/16] net: switchdev: Replace port attr set SDO with a notification

2019-02-08 Thread Florian Fainelli
On 2/8/19 4:32 PM, Florian Fainelli wrote:
> Drop switchdev_ops.switchdev_port_attr_set. Drop the uses of this field
> from all clients, which were migrated to use switchdev notification in
> the previous patches.
> 
> Add a new function switchdev_port_attr_notify() that sends the switchdev
> notifications SWITCHDEV_PORT_ATTR_SET.
> 
> Drop __switchdev_port_attr_set() and update switchdev_port_attr_set()
> likewise.
> 
> Signed-off-by: Florian Fainelli 
> ---
>  include/net/switchdev.h   | 18 
>  net/switchdev/switchdev.c | 92 ++-
>  2 files changed, 22 insertions(+), 88 deletions(-)
> 
> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> index 4c5f7e5430cf..5387ff6f41c5 100644
> --- a/include/net/switchdev.h
> +++ b/include/net/switchdev.h
> @@ -111,21 +111,6 @@ void *switchdev_trans_item_dequeue(struct 
> switchdev_trans *trans);
>  
>  typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
>  
> -/**
> - * struct switchdev_ops - switchdev operations
> - *
> - * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
> - *
> - * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
> - */
> -struct switchdev_ops {
> - int (*switchdev_port_attr_get)(struct net_device *dev,
> -struct switchdev_attr *attr);
> - int (*switchdev_port_attr_set)(struct net_device *dev,
> -const struct switchdev_attr *attr,
> -struct switchdev_trans *trans);
> -};
> -

This and the hunk below bisection, I will move that into patch #16 after
receiving feedback on this.
-- 
Florian
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 3/4] gpu: ipu-v3: ipu-ic: Add support for BT.709 encoding

2019-02-08 Thread Steve Longerbeam




On 2/8/19 4:20 PM, Tim Harvey wrote:

On Fri, Feb 8, 2019 at 11:28 AM Steve Longerbeam  wrote:

 if (inf == outf)
 params = &ic_csc_identity;
 else if (inf == IPUV3_COLORSPACE_YUV)
-   params = &ic_csc_ycbcr2rgb_bt601;
+   params = &ic_csc_ycbcr2rgb;


Steve,

compile issue...

params = params_yuv2rgb;


 else
-   params = &ic_csc_rgb2ycbcr_bt601;
+   params = &ic_csc_rgb2ycbcr;

params = params_rgb2yuv;


Wow, did I not even compile test that? Must be my head cold :-/
Sending v4.



But, I'm still failing when using the mem2mem element (gst-launch-1.0
v4l2src device=/dev/video4 ! v4l2video8convert
output-io-mode=dmabuf-import ! fbdevsink) with 'Unsupported YCbCr
encoding' because of inf=IPU_COLORSPACE_YCBCR outf=IPU_COLORSPACE_RGB
and a seemingly unset encoding being passed in.

It looks like maybe something in the mem2mem driver isn't defaulting
encoding. The call path is (v4l2_m2m_streamon -> device_run ->
ipu_image_convert_queue -> convert_start -> ipu_ic_task_init_rsc ->
init_csc).


Looking at v7 of the mem2mem driver, it will set ycbcr_enc at the output 
side to V4L2_YCBCR_ENC_DEFAULT if colorspace is default. So colorspace 
will need to be set to something non-default in addition to setting 
ycbcr_enc, at the output side. I don't know whether gstreamer 
v4l2videoNconvertelement will do this, but you could hack the driver for 
now to get around it, and let Philipp know this may need a workaround in 
mem2mem for v8.


Steve
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 4/4] media: imx: Allow BT.709 encoding for IC routes

2019-02-08 Thread Steve Longerbeam
The IC now supports BT.709 Y'CbCr encoding, in addition to existing BT.601
encoding, so allow both, for pipelines that route through the IC.

Reported-by: Tim Harvey 
Signed-off-by: Steve Longerbeam 
---
Changes in v2:
- move ic_route check above default colorimetry checks, and fill default
  colorimetry for ic_route, otherwise it's not possible to set BT.709
  encoding for ic routes.
---
 drivers/staging/media/imx/imx-media-utils.c | 20 +---
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/media/imx/imx-media-utils.c 
b/drivers/staging/media/imx/imx-media-utils.c
index 5f110d90a4ef..dde0e47550d7 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -544,6 +544,19 @@ void imx_media_fill_default_mbus_fields(struct 
v4l2_mbus_framefmt *tryfmt,
if (tryfmt->field == V4L2_FIELD_ANY)
tryfmt->field = fmt->field;
 
+   if (ic_route) {
+   if (tryfmt->colorspace == V4L2_COLORSPACE_DEFAULT)
+   tryfmt->colorspace = fmt->colorspace;
+
+   tryfmt->quantization = is_rgb ?
+   V4L2_QUANTIZATION_FULL_RANGE :
+   V4L2_QUANTIZATION_LIM_RANGE;
+
+   if (tryfmt->ycbcr_enc != V4L2_YCBCR_ENC_601 &&
+   tryfmt->ycbcr_enc != V4L2_YCBCR_ENC_709)
+   tryfmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
+   }
+
/* fill colorimetry if necessary */
if (tryfmt->colorspace == V4L2_COLORSPACE_DEFAULT) {
tryfmt->colorspace = fmt->colorspace;
@@ -566,13 +579,6 @@ void imx_media_fill_default_mbus_fields(struct 
v4l2_mbus_framefmt *tryfmt,
tryfmt->ycbcr_enc);
}
}
-
-   if (ic_route) {
-   tryfmt->quantization = is_rgb ?
-   V4L2_QUANTIZATION_FULL_RANGE :
-   V4L2_QUANTIZATION_LIM_RANGE;
-   tryfmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
-   }
 }
 EXPORT_SYMBOL_GPL(imx_media_fill_default_mbus_fields);
 
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 3/4] gpu: ipu-v3: ipu-ic: Add support for BT.709 encoding

2019-02-08 Thread Steve Longerbeam
Pass v4l2 encoding enum to the ipu_ic task init functions, and add
support for the BT.709 encoding and inverse encoding matrices.

Reported-by: Tim Harvey 
Signed-off-by: Steve Longerbeam 
---
Changes in v4:
- fix compile error.
Chnges in v3:
- none.
Changes in v2:
- only return "Unsupported YCbCr encoding" error if inf != outf,
  since if inf == outf, the identity matrix can be used. Reported
  by Tim Harvey.
---
 drivers/gpu/ipu-v3/ipu-ic.c | 71 +++--
 drivers/gpu/ipu-v3/ipu-image-convert.c  |  1 +
 drivers/staging/media/imx/imx-ic-prpencvf.c |  4 +-
 include/video/imx-ipu-v3.h  |  5 +-
 4 files changed, 71 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-ic.c b/drivers/gpu/ipu-v3/ipu-ic.c
index e459615a49a1..c5f83d7e357f 100644
--- a/drivers/gpu/ipu-v3/ipu-ic.c
+++ b/drivers/gpu/ipu-v3/ipu-ic.c
@@ -212,6 +212,23 @@ static const struct ic_csc_params ic_csc_identity = {
.scale = 2,
 };
 
+/*
+ * BT.709 encoding from RGB full range to YUV limited range:
+ *
+ * Y = R *  .2126 + G *  .7152 + B *  .0722;
+ * U = R * -.1146 + G * -.3854 + B *  .5000 + 128.;
+ * V = R *  .5000 + G * -.4542 + B * -.0458 + 128.;
+ */
+static const struct ic_csc_params ic_csc_rgb2ycbcr_bt709 = {
+   .coeff = {
+   { 54, 183, 18 },
+   { 483, 413, 128 },
+   { 128, 396, 500 },
+   },
+   .offset = { 0, 512, 512 },
+   .scale = 1,
+};
+
 /*
  * Inverse BT.601 encoding from YUV limited range to RGB full range:
  *
@@ -229,12 +246,31 @@ static const struct ic_csc_params ic_csc_ycbcr2rgb_bt601 
= {
.scale = 2,
 };
 
+/*
+ * Inverse BT.709 encoding from YUV limited range to RGB full range:
+ *
+ * R = (1. * (Y - 16)) + (1.5748 * (Cr - 128));
+ * G = (1. * (Y - 16)) - (0.1873 * (Cb - 128)) - (0.4681 * (Cr - 128));
+ * B = (1. * (Y - 16)) + (1.8556 * (Cb - 128);
+ */
+static const struct ic_csc_params ic_csc_ycbcr2rgb_bt709 = {
+   .coeff = {
+   { 128, 0, 202 },
+   { 128, 488, 452 },
+   { 128, 238, 0 },
+   },
+   .offset = { -435, 136, -507 },
+   .scale = 2,
+};
+
 static int init_csc(struct ipu_ic *ic,
enum ipu_color_space inf,
enum ipu_color_space outf,
+   enum v4l2_ycbcr_encoding encoding,
int csc_index)
 {
struct ipu_ic_priv *priv = ic->priv;
+   const struct ic_csc_params *params_rgb2yuv, *params_yuv2rgb;
const struct ic_csc_params *params;
u32 __iomem *base;
const u16 (*c)[3];
@@ -244,12 +280,30 @@ static int init_csc(struct ipu_ic *ic,
base = (u32 __iomem *)
(priv->tpmem_base + ic->reg->tpmem_csc[csc_index]);
 
+   switch (encoding) {
+   case V4L2_YCBCR_ENC_601:
+   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt601;
+   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt601;
+   break;
+   case V4L2_YCBCR_ENC_709:
+   params_rgb2yuv =  &ic_csc_rgb2ycbcr_bt709;
+   params_yuv2rgb = &ic_csc_ycbcr2rgb_bt709;
+   break;
+   default:
+   if (inf != outf) {
+   dev_err(priv->ipu->dev,
+   "Unsupported YCbCr encoding\n");
+   return -EINVAL;
+   }
+   break;
+   }
+
if (inf == outf)
params = &ic_csc_identity;
else if (inf == IPUV3_COLORSPACE_YUV)
-   params = &ic_csc_ycbcr2rgb_bt601;
+   params = params_yuv2rgb;
else
-   params = &ic_csc_rgb2ycbcr_bt601;
+   params = params_rgb2yuv;
 
/* Cast to unsigned */
c = (const u16 (*)[3])params->coeff;
@@ -390,6 +444,7 @@ EXPORT_SYMBOL_GPL(ipu_ic_task_disable);
 
 int ipu_ic_task_graphics_init(struct ipu_ic *ic,
  enum ipu_color_space in_g_cs,
+ enum v4l2_ycbcr_encoding encoding,
  bool galpha_en, u32 galpha,
  bool colorkey_en, u32 colorkey)
 {
@@ -408,7 +463,7 @@ int ipu_ic_task_graphics_init(struct ipu_ic *ic,
if (!(ic_conf & ic->bit->ic_conf_csc1_en)) {
/* need transparent CSC1 conversion */
ret = init_csc(ic, IPUV3_COLORSPACE_RGB,
-  IPUV3_COLORSPACE_RGB, 0);
+  IPUV3_COLORSPACE_RGB, encoding, 0);
if (ret)
goto unlock;
}
@@ -416,7 +471,7 @@ int ipu_ic_task_graphics_init(struct ipu_ic *ic,
ic->g_in_cs = in_g_cs;
 
if (ic->g_in_cs != ic->out_cs) {
-   ret = init_csc(ic, ic->g_in_cs, ic->out_cs, 1);
+   ret = init_csc(ic, ic->g_in_cs, ic->out_cs, encoding, 1);
if (ret)
goto unlock;
}
@@ -450,6 +505,7 @@ int ipu_ic_task_init_rsc(struct ipu_ic *ic,
  

Re: [PATCH 2/2] staging: android: ashmem: Don't allow range_alloc() to fail.

2019-02-08 Thread Tetsuo Handa
On 2019/02/08 23:45, Joel Fernandes wrote:
> On Wed, Feb 06, 2019 at 08:45:32AM +0900, Tetsuo Handa wrote:
>> Joel Fernandes wrote:
>>> On Tue, Feb 05, 2019 at 07:28:41PM +0900, Tetsuo Handa wrote:
 ashmem_pin() is calling range_shrink() without checking whether
 range_alloc() succeeded. Since memory allocation fault injection might
 force range_alloc() to fail while range_alloc() is called for only once
 for one ioctl() request, make range_alloc() not to fail.
>>>
>>> Why does this not need to fail? I am worried your change will introduce
>>> unwanted endless looping in the kernel instead of gracefully failing a
>>> pin/unpin request.
>>
>> This patch won't introduce endless looping in the kernel, due to a rule 
>> called
>>
>>   The "too small to fail" memory-allocation rule
>>   https://lwn.net/Articles/627419/
>>
>> . In short, memory allocation by range_alloc() might fail only if current 
>> thread
>> was killed by the OOM killer or memory allocation fault injection mechanism
>> forced it to fail. And this patch helps doing fuzzing test with minimal 
>> changes.
>>
>>>
>>> Unless there is a good reason, I suggest to drop this patch from the series;
>>> but let us discuss more if you want.
>>
>> We can allocate memory for range_alloc() before holding ashmem_mutex at
>> ashmem_pin_unpin() if you don't want to use __GFP_NOFAIL. It is better to
>> avoid memory allocation with ashmem_mutex because ashmem_mutex is held by
>> shrinker function. But given that this module is going to be replaced 
>> shortly,
>> does it worth moving the memory allocation to the caller?
> 
> Even if memory allocation does not fail right now, I still want to return the
> error code correctly via ashmem_pin_unpin() so that if in the future there
> are changes to the allocator algorithm, then a silent success isn't reported
> when a failure should be reported..
> 
> It doesn't make sense to return success when an allocation failed.. even if
> you are asking this code to rely on the allocator's "too small to fail"
> behavior.. can we guarantee this allocator behavior will always exist?
> Probably not.
> 

Does always exist. Small GFP_KERNEL allocation without __GFP_NORETRY or
__GFP_RETRY_MAYFAIL won't fail unless current thread was killed by the OOM
killer or memory allocation fault injection mechanism forced it to fail.
Failing such allocation instead of invoking the OOM killer is effectively
equivalent to sending SIGKILL to current thread. If current thread got
SIGKILL, current thread can't receive the error code of ioctl() from
ashmem_pin_unpin() because userspace code is no longer executed.

MM people want to make !GFP_KERNEL memory allocations fail rather than
retry forever. But failing small GFP_KERNEL memory allocations is such
a horrible idea. Anyway, here is an updated patch...



>From f2c8a098ebf69122fc440d9e9ca3c9cd786cce8a Mon Sep 17 00:00:00 2001
From: Tetsuo Handa 
Date: Sat, 9 Feb 2019 11:07:07 +0900
Subject: [PATCH] staging: android: ashmem: Avoid range_alloc() allocation with
 ashmem_mutex held.

ashmem_pin() is calling range_shrink() without checking whether
range_alloc() succeeded. Also, doing memory allocation with ashmem_mutex
held should be avoided because ashmem_shrink_scan() tries to hold it.

Therefore, move memory allocation for range_alloc() to ashmem_pin_unpin()
and make range_alloc() not to fail.

Signed-off-by: Tetsuo Handa 
---
 drivers/staging/android/ashmem.c | 42 +++-
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index ade8438..910826d 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -171,19 +171,15 @@ static inline void lru_del(struct ashmem_range *range)
  * @end:  The ending page (inclusive)
  *
  * This function is protected by ashmem_mutex.
- *
- * Return: 0 if successful, or -ENOMEM if there is an error
  */
-static int range_alloc(struct ashmem_area *asma,
-  struct ashmem_range *prev_range, unsigned int purged,
-  size_t start, size_t end)
+static void range_alloc(struct ashmem_area *asma,
+   struct ashmem_range *prev_range, unsigned int purged,
+   size_t start, size_t end,
+   struct ashmem_range **new_range)
 {
-   struct ashmem_range *range;
-
-   range = kmem_cache_zalloc(ashmem_range_cachep, GFP_KERNEL);
-   if (!range)
-   return -ENOMEM;
+   struct ashmem_range *range = *new_range;
 
+   *new_range = NULL;
range->asma = asma;
range->pgstart = start;
range->pgend = end;
@@ -193,8 +189,6 @@ static int range_alloc(struct ashmem_area *asma,
 
if (range_on_lru(range))
lru_add(range);
-
-   return 0;
 }
 
 /**
@@ -596,7 +590,8 @@ static int get_name(struct ashmem_area *asma, void __user 
*name)
  *
  * Caller must hold ashm