Re: [PATCH v2 1/4] media i.MX27 camera: migrate driver to videobuf2

2012-01-30 Thread javier Martin
Hi Guennadi,
thank you for your time.

On 27 January 2012 16:25, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote:
 A general question for mx2-camera: does it now after removal of legacy
 i.MX27 support only support i.MX25 (state: unknown) and i.MX27 in eMMA
 mode?

I understand so.

I'll send a v3 of this patch fixing what you've pointed out.

Regards.
-- 
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.com
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 2/4] media i.MX27 camera: add start_stream and stop_stream callbacks.

2012-01-30 Thread javier Martin
Hi,

On 27 January 2012 16:53, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote:
 On Thu, 26 Jan 2012, Javier Martin wrote:

 Add start_stream and stop_stream callback in order to enable
 and disable the eMMa-PrP properly and save CPU usage avoiding
 IRQs when the device is not streaming. This also makes the driver
 return 0 as the sequence number of the first frame.

 Signed-off-by: Javier Martin javier.mar...@vista-silicon.com
 ---
  Merge media i.MX27 camera: properly detect frame loss

 ---
  drivers/media/video/mx2_camera.c |  104 
 +-
  1 files changed, 79 insertions(+), 25 deletions(-)

 diff --git a/drivers/media/video/mx2_camera.c 
 b/drivers/media/video/mx2_camera.c
 index 898f98f..045c018 100644
 --- a/drivers/media/video/mx2_camera.c
 +++ b/drivers/media/video/mx2_camera.c
 @@ -377,7 +377,7 @@ static int mx2_camera_add_device(struct 
 soc_camera_device *icd)
       writel(pcdev-csicr1, pcdev-base_csi + CSICR1);

       pcdev-icd = icd;
 -     pcdev-frame_count = 0;
 +     pcdev-frame_count = -1;

       dev_info(icd-parent, Camera driver attached to camera %d\n,
                icd-devnum);
 @@ -647,11 +647,83 @@ static void mx2_videobuf_release(struct vb2_buffer *vb)
       spin_unlock_irqrestore(pcdev-lock, flags);
  }

 +static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
 +{
 +     struct soc_camera_device *icd = soc_camera_from_vb2q(q);
 +     struct soc_camera_host *ici =
 +             to_soc_camera_host(icd-parent);
 +     struct mx2_camera_dev *pcdev = ici-priv;
 +     struct mx2_fmt_cfg *prp = pcdev-emma_prp;
 +     unsigned long flags;
 +     int ret = 0;
 +
 +     spin_lock_irqsave(pcdev-lock, flags);
 +     if (mx27_camera_emma(pcdev)) {
 +             if (count  2) {
 +                     ret = -EINVAL;
 +                     goto err;
 +             }

 How about:

        if (mx27_camera_emma(pcdev)) {
                unsigned long flags;
                if (count  2)
                        return -EINVAL;

                spin_lock_irqsave(pcdev-lock, flags);
                ...
                spin_unlock_irqrestore(pcdev-lock, flags);
        }

        return 0;

OK, this is definitely cleaner. I'll do it for v3.

 Another point: in v1 of this patch you also removed goto out from
 mx2_videobuf_queue(). I understand this is probably unrelated to this
 patch now. Anyway, if you don't find a patch out of your 4 now, where it
 logically would fit, you could either make an additional patch, or I could
 do it myself, if I don't forget:-)

Don't worry,
I'll send a new series including that patch after this one gets merged.

Regards.
-- 
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.com
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Linaro-mm-sig] [PATCH 12/15] drivers: add Contiguous Memory Allocator

2012-01-30 Thread Ohad Ben-Cohen
Hi Marek,

On Mon, Jan 30, 2012 at 9:43 AM, Marek Szyprowski
m.szyprow...@samsung.com wrote:
 Did you managed to fix this issue?

Yes -- the recent increase in the vmalloc region triggered a bigger
truncation in the system RAM than we had before, and therefore
conflicted with the previous hardcoded region we were using.

Long term, our plan is to get rid of those hardcoded values, but for
the moment our remote RTOS still needs to know the physical address in
advance.

 Right, thanks for spotting it, I will squash it to the next release.

Thanks. With that hunk squashed in, feel free to add my Tested-by tag
to the patches.

Thanks!
Ohad.
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH][media] s5p-g2d: Add HFLIP and VFLIP support

2012-01-30 Thread Sachin Kamat
This patch adds support for flipping the image horizontally and vertically.

Signed-off-by: Sachin Kamat sachin.ka...@linaro.org
---
 drivers/media/video/s5p-g2d/g2d-hw.c |5 +++
 drivers/media/video/s5p-g2d/g2d.c|   47 +++--
 drivers/media/video/s5p-g2d/g2d.h|3 ++
 3 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c 
b/drivers/media/video/s5p-g2d/g2d-hw.c
index 39937cf..5b86cbe 100644
--- a/drivers/media/video/s5p-g2d/g2d-hw.c
+++ b/drivers/media/video/s5p-g2d/g2d-hw.c
@@ -77,6 +77,11 @@ void g2d_set_rop4(struct g2d_dev *d, u32 r)
w(r, ROP4_REG);
 }
 
+void g2d_set_flip(struct g2d_dev *d, u32 r)
+{
+   w(r, SRC_MSK_DIRECT_REG);
+}
+
 u32 g2d_cmd_stretch(u32 e)
 {
e = 1;
diff --git a/drivers/media/video/s5p-g2d/g2d.c 
b/drivers/media/video/s5p-g2d/g2d.c
index febaa67..dea9701 100644
--- a/drivers/media/video/s5p-g2d/g2d.c
+++ b/drivers/media/video/s5p-g2d/g2d.c
@@ -178,6 +178,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
 {
struct g2d_ctx *ctx = container_of(ctrl-handler, struct g2d_ctx,
ctrl_handler);
+
switch (ctrl-id) {
case V4L2_CID_COLORFX:
if (ctrl-val == V4L2_COLORFX_NEGATIVE)
@@ -185,6 +186,21 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
else
ctx-rop = ROP4_COPY;
break;
+
+   case V4L2_CID_HFLIP:
+   if (ctrl-val == 1)
+   ctx-hflip = 1;
+   else
+   ctx-hflip = 0;
+   break;
+
+   case V4L2_CID_VFLIP:
+   if (ctrl-val == 1)
+   ctx-vflip = (1  1);
+   else
+   ctx-vflip = 0;
+   break;
+
default:
v4l2_err(ctx-dev-v4l2_dev, unknown control\n);
return -EINVAL;
@@ -200,11 +216,9 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
 {
struct g2d_dev *dev = ctx-dev;
 
-   v4l2_ctrl_handler_init(ctx-ctrl_handler, 1);
-   if (ctx-ctrl_handler.error) {
-   v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
-   return ctx-ctrl_handler.error;
-   }
+   v4l2_ctrl_handler_init(ctx-ctrl_handler, 3);
+   if (ctx-ctrl_handler.error)
+   goto error;
 
v4l2_ctrl_new_std_menu(
ctx-ctrl_handler,
@@ -214,12 +228,25 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
~((1  V4L2_COLORFX_NONE) | (1  V4L2_COLORFX_NEGATIVE)),
V4L2_COLORFX_NONE);
 
-   if (ctx-ctrl_handler.error) {
-   v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
-   return ctx-ctrl_handler.error;
-   }
+   if (ctx-ctrl_handler.error)
+   goto error;
+
+   v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops,
+   V4L2_CID_HFLIP, 0, 1, 1, 0);
+   if (ctx-ctrl_handler.error)
+   goto error;
+
+   v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops,
+   V4L2_CID_VFLIP, 0, 1, 1, 0);
+   if (ctx-ctrl_handler.error)
+   goto error;
 
return 0;
+
+error:
+   v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
+   return ctx-ctrl_handler.error;
+
 }
 
 static int g2d_open(struct file *file)
@@ -564,6 +591,8 @@ static void device_run(void *prv)
g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));
 
g2d_set_rop4(dev, ctx-rop);
+   g2d_set_flip(dev, ctx-hflip | ctx-vflip);
+
if (ctx-in.c_width != ctx-out.c_width ||
ctx-in.c_height != ctx-out.c_height)
cmd |= g2d_cmd_stretch(1);
diff --git a/drivers/media/video/s5p-g2d/g2d.h 
b/drivers/media/video/s5p-g2d/g2d.h
index 5eae901..b3be3c8 100644
--- a/drivers/media/video/s5p-g2d/g2d.h
+++ b/drivers/media/video/s5p-g2d/g2d.h
@@ -59,6 +59,8 @@ struct g2d_ctx {
struct g2d_frameout;
struct v4l2_ctrl_handler ctrl_handler;
u32 rop;
+   u32 hflip;
+   u32 vflip;
 };
 
 struct g2d_fmt {
@@ -77,6 +79,7 @@ void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a);
 void g2d_start(struct g2d_dev *d);
 void g2d_clear_int(struct g2d_dev *d);
 void g2d_set_rop4(struct g2d_dev *d, u32 r);
+void g2d_set_flip(struct g2d_dev *d, u32 r);
 u32 g2d_cmd_stretch(u32 e);
 void g2d_set_cmd(struct g2d_dev *d, u32 c);
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] Format and frame rate configuration in subdev video and pad ops

2012-01-30 Thread Laurent Pinchart
Hi Sakari,

On Sunday 29 January 2012 11:28:16 Sakari Ailus wrote:
 Hi all,
 
 We have now two type of subdev drivers, those which use the Media
 controller framework and those which do not. The former group implements
 v4l2_subdev_pad_ops for the purpose whereas the latter uses
 v4l2_subdev_video_ops. In practice the two implement essentially the
 same feature set.
 
 Same goes for simple bus receiver drivers (also called bridge) whereas
 all the more complex ISP drivers rightly use the pad ops.
 
 The two groups of drivers are currently mostly not mixable, and the
 reason is mostly the above, as far as I understand.
 
 To improve interoperability, it would be relatively easy to provide
 wrapper functions for either groups of the ISP / bus receiver drivers so
 they do need not to be changed to support both.

This is something I've proposed a couple of months ago. I still stand by my 
proposal, it's a good idea.

 More complex sensor drivers, for example the SMIA++ exports more than
 one subdev for the configuration of sensor's image processing --- there
 is functionality which is present in ISPs only: cropping in three
 different locations and scaling in two. Many of the decisions in the
 configuration are policy decisions and thus belong to user space. This
 kind of drivers cannot be utilised without Media controller support, and
 thus I believe it is right for even simple bus receiver drivers to
 implement Media controller support to allow all bridge / ISP drivers to
 use them.
 
 While not all the user space is not yet in place to support such drivers
 I have not forgotten work on this library --- it just takes time.
 
 There are two sets of wrappers that can be implemented to improve the
 current situation. After the full transition to pad ops (should it ever
 happen is to be decided, I guess) these wrappers could be removed.
 
 Wrappers for sensor drivers to implement pad ops using video ops.
 There's one pad on such subdevs and a few other restrictions: try
 formats cannot be supported since there is no v4l2_fh support in video ops.
 
 How should the try operations requiring v4l2_fh behave in this case?
 Should they just return the current ACTIVE format (or crop) or should
 they behave as ACTIVE version of the same op does? I might pick the
 first option as it's less wrong. Complete support is not possible due to
 lack of functionality in the interface.

I'm not sure I would implement such wrappers. I think we should instead 
convert the sensor drivers to pad ops, and use the video ops through pad ops 
wrapper if the sensor is used with an ISP that doesn't support pad ops yet.

 Wrappers for sensor drivers to implement video ops using pad ops. This
 is trivial: all the information is available through the pad ops,  with
 v4l2_subdev_format fields which == V4L2_SUBDEV_FORMAT_ACTIVE and pad == 0.
 
 The same mostly goes for crop: v4l2_crop contains a subset of
 information in v4l2_subdev_crop.
 
 Conclusion: to achieve maximum compatibility with bridge / ISP drivers
 using the two sets of ops, sensor / tuner etc. drivers should use pad
 ops to implement format, crop and frame rate configuration and
 enumeration. What is missing is a set of wrappers for sensor drivers to
 allow bridge and ISP drivers using either set of ops to use these sensor
 drivers.
 
 Comments, questions?
 
 relevant video ops:
 
 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index,
  enum v4l2_mbus_pixelcode *code);
 int (*enum_mbus_fsizes)(struct v4l2_subdev *sd,
  struct v4l2_frmsizeenum *fsize);
 int (*g_mbus_fmt)(struct v4l2_subdev *sd,
   struct v4l2_mbus_framefmt *fmt);
 int (*try_mbus_fmt)(struct v4l2_subdev *sd,
 struct v4l2_mbus_framefmt *fmt);
 int (*s_mbus_fmt)(struct v4l2_subdev *sd,
   struct v4l2_mbus_framefmt *fmt);
 
 relevant pad ops:
 
 int (*enum_mbus_code)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh
   struct v4l2_subdev_mbus_code_enum *code);
 int (*enum_frame_size)(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh,
struct v4l2_subdev_frame_size_enum *fse);
 int (*enum_frame_interval)(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh,
struct v4l2_subdev_frame_interval_enum *fie)
 int (*get_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
struct v4l2_subdev_format *format);
 int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
struct v4l2_subdev_format *format);
 
 /**
  * struct v4l2_mbus_framefmt - frame format on the media bus
  * @width:  frame width
  * @height: frame height
  * @code:   data format code (from enum v4l2_mbus_pixelcode)
  * @field:  used interlacing type (from enum v4l2_field)
  * @colorspace: colorspace of the data (from enum v4l2_colorspace)
  */
 struct v4l2_mbus_framefmt {
 __u32  

Re: [PATCH 01/15] mm: page_alloc: remove trailing whitespace

2012-01-30 Thread Mel Gorman
On Thu, Jan 26, 2012 at 10:00:43AM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 
 Signed-off-by: Michal Nazarewicz min...@mina86.com
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com

Ordinarily, I do not like these sort of patches because they can
interfere with git blame but as it is comments that are affected;

Acked-by: Mel Gorman m...@csn.ul.ie

Thanks

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/15] mm: page_alloc: update migrate type of pages on pcp when isolating

2012-01-30 Thread Mel Gorman
On Thu, Jan 26, 2012 at 10:00:44AM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 
 This commit changes set_migratetype_isolate() so that it updates
 migrate type of pages on pcp list which is saved in their
 page_private.
 
 Signed-off-by: Michal Nazarewicz min...@mina86.com
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 ---
  include/linux/page-isolation.h |6 ++
  mm/page_alloc.c|1 +
  mm/page_isolation.c|   24 
  3 files changed, 31 insertions(+), 0 deletions(-)
 
 diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
 index 051c1b1..8c02c2b 100644
 --- a/include/linux/page-isolation.h
 +++ b/include/linux/page-isolation.h
 @@ -27,6 +27,12 @@ extern int
  test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn);
  
  /*
 + * Check all pages in pageblock, find the ones on pcp list, and set
 + * their page_private to MIGRATE_ISOLATE.
 + */
 +extern void update_pcp_isolate_block(unsigned long pfn);
 +
 +/*
   * Internal funcs.Changes pageblock's migrate type.
   * Please use make_pagetype_isolated()/make_pagetype_movable().
   */
 diff --git a/mm/page_alloc.c b/mm/page_alloc.c
 index e1c5656..70709e7 100644
 --- a/mm/page_alloc.c
 +++ b/mm/page_alloc.c
 @@ -5465,6 +5465,7 @@ out:
   if (!ret) {
   set_pageblock_migratetype(page, MIGRATE_ISOLATE);
   move_freepages_block(zone, page, MIGRATE_ISOLATE);
 + update_pcp_isolate_block(pfn);
   }
  
   spin_unlock_irqrestore(zone-lock, flags);
 diff --git a/mm/page_isolation.c b/mm/page_isolation.c
 index 4ae42bb..9ea2f6e 100644
 --- a/mm/page_isolation.c
 +++ b/mm/page_isolation.c
 @@ -139,3 +139,27 @@ int test_pages_isolated(unsigned long start_pfn, 
 unsigned long end_pfn)
   spin_unlock_irqrestore(zone-lock, flags);
   return ret ? 0 : -EBUSY;
  }
 +
 +/* must hold zone-lock */
 +void update_pcp_isolate_block(unsigned long pfn)
 +{
 + unsigned long end_pfn = pfn + pageblock_nr_pages;
 + struct page *page;
 +
 + while (pfn  end_pfn) {
 + if (!pfn_valid_within(pfn)) {
 + ++pfn;
 + continue;
 + }
 +

There is a potential problem here that you need to be aware of.
set_pageblock_migratetype() is called from start_isolate_page_range().
I do not think there is a guarantee that pfn + pageblock_nr_pages is
not in a different block of MAX_ORDER_NR_PAGES. If that is right then
your options are to add a check like this;

if ((pfn  (MAX_ORDER_NR_PAGES - 1)) == 0  !pfn_valid(pfn))
break;

or else ensure that end_pfn is always MAX_ORDER_NR_PAGES aligned and in
the same block as pfn and relying on the caller to have called
pfn_valid.

 + page = pfn_to_page(pfn);
 + if (PageBuddy(page)) {
 + pfn += 1  page_order(page);
 + } else if (page_count(page) == 0) {
 + set_page_private(page, MIGRATE_ISOLATE);
 + ++pfn;

This is dangerous for two reasons. If the page_count is 0, it could
be because the page is in the process of being freed and is not
necessarily on the per-cpu lists yet and you cannot be sure if the
contents of page-private are important. Second, there is nothing to
prevent another CPU allocating this page from its per-cpu list while
the private field is getting updated from here which might lead to
some interesting races.

I recognise that what you are trying to do is respond to Gilad's
request that you really check if an IPI here is necessary. I think what
you need to do is check if a page with a count of 0 is encountered
and if it is, then a draining of the per-cpu lists is necessary. To
address Gilad's concerns, be sure to only this this once per attempt at
CMA rather than for every page encountered with a count of 0 to avoid a
storm of IPIs.

 + } else {
 + ++pfn;
 + }
 + }
 +}

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/15] mm: compaction: introduce isolate_migratepages_range().

2012-01-30 Thread Mel Gorman
On Thu, Jan 26, 2012 at 10:00:45AM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 
 This commit introduces isolate_migratepages_range() function which
 extracts functionality from isolate_migratepages() so that it can be
 used on arbitrary PFN ranges.
 
 isolate_migratepages() function is implemented as a simple wrapper
 around isolate_migratepages_range().
 
 Signed-off-by: Michal Nazarewicz min...@mina86.com
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com

Super, this is much easier to read. I have just one nit below but once
that is fixed;

Acked-by: Mel Gorman m...@csn.ul.ie

 @@ -313,7 +316,7 @@ static isolate_migrate_t isolate_migratepages(struct zone 
 *zone,
   } else if (!locked)
   spin_lock_irq(zone-lru_lock);
  
 - if (!pfn_valid_within(low_pfn))
 + if (!pfn_valid(low_pfn))
   continue;
   nr_scanned++;
  

This chunk looks unrelated to the rest of the patch.

I think what you are doing is patching around a bug that CMA exposed
which is very similar to the bug report at
http://www.spinics.net/lists/linux-mm/msg29260.html . Is this true?

If so, I posted a fix that only calls pfn_valid() when necessary. Can
you check if that works for you and if so, drop this hunk please? If
the patch does not work for you, then this hunk still needs to be
in a separate patch and handled separately as it would also be a fix
for -stable.

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/15] mm: compaction: introduce isolate_freepages_range()

2012-01-30 Thread Mel Gorman
On Thu, Jan 26, 2012 at 10:00:46AM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 
 This commit introduces isolate_freepages_range() function which
 generalises isolate_freepages_block() so that it can be used on
 arbitrary PFN ranges.
 
 isolate_freepages_block() is left with only minor changes.
 

The minor changes to isolate_freepages_block() look fine in
terms of how current compaction works. I have a minor comment on
isolate_freepages_range() but it is up to you whether to address them
or not. Whether you alter isolate_freepages_range() or not;

Acked-by: Mel Gorman m...@csn.ul.ie

 SNIP
 @@ -105,6 +109,80 @@ static unsigned long isolate_freepages_block(struct zone 
 *zone,
   return total_isolated;
  }
  
 +/**
 + * isolate_freepages_range() - isolate free pages.
 + * @start_pfn: The first PFN to start isolating.
 + * @end_pfn:   The one-past-last PFN.
 + *
 + * Non-free pages, invalid PFNs, or zone boundaries within the
 + * [start_pfn, end_pfn) range are considered errors, cause function to
 + * undo its actions and return zero.
 + *
 + * Otherwise, function returns one-past-the-last PFN of isolated page
 + * (which may be greater then end_pfn if end fell in a middle of
 + * a free page).
 + */
 +static unsigned long
 +isolate_freepages_range(unsigned long start_pfn, unsigned long end_pfn)
 +{
 + unsigned long isolated, pfn, block_end_pfn, flags;
 + struct zone *zone = NULL;
 + LIST_HEAD(freelist);
 + struct page *page;
 +
 + for (pfn = start_pfn; pfn  end_pfn; pfn += isolated) {
 + if (!pfn_valid(pfn))
 + break;
 +
 + if (!zone)
 + zone = page_zone(pfn_to_page(pfn));
 + else if (zone != page_zone(pfn_to_page(pfn)))
 + break;
 +

So what you are checking for here is if you straddle zones.
You could just initialise zone outside of the for loop. You can
then check outside the loop if end_pfn is in a different zone to
start_pfn. If it is, either adjust end_pfn accordingly or bail the
entire operation avoiding the need for release_freepages() later. This
will be a little cheaper.

 + /*
 +  * On subsequent iterations round_down() is actually not
 +  * needed, but we keep it that we not to complicate the code.
 +  */
 + block_end_pfn = round_down(pfn, pageblock_nr_pages)
 + + pageblock_nr_pages;

Seems a little more involved than it needs to be. Something like
this might suit and be a bit nicer?

block_end_pfn = ALIGN(pfn+1, pageblock_nr_pages);

 + block_end_pfn = min(block_end_pfn, end_pfn);
 +
 + spin_lock_irqsave(zone-lock, flags);
 + isolated = isolate_freepages_block(pfn, block_end_pfn,
 +freelist, true);
 + spin_unlock_irqrestore(zone-lock, flags);
 +
 + /*
 +  * In strict mode, isolate_freepages_block() returns 0 if
 +  * there are any holes in the block (ie. invalid PFNs or
 +  * non-free pages).
 +  */
 + if (!isolated)
 + break;
 +
 + /*
 +  * If we managed to isolate pages, it is always (1  n) *
 +  * pageblock_nr_pages for some non-negative n.  (Max order
 +  * page may span two pageblocks).
 +  */
 + }
 +
 + /* split_free_page does not map the pages */
 + list_for_each_entry(page, freelist, lru) {
 + arch_alloc_page(page, 0);
 + kernel_map_pages(page, 1, 1);
 + }
 +

This block is copied in two places - isolate_freepages and
isolate_freepages_range() so sharing a common helper would be nice. I
suspect you didn't because it would interfere with existing code more
than was strictly necessary which I complained about previously as
it made review harder. If that was your thinking, then just create
this helper in a separate patch. It's not critical though.

 + if (pfn  end_pfn) {
 + /* Loop terminated early, cleanup. */
 + release_freepages(freelist);
 + return 0;
 + }
 +
 + /* We don't use freelists for anything. */
 + return pfn;
 +}
 +
  /* Returns true if the page is within a block suitable for migration to */
  static bool suitable_migration_target(struct page *page)
  {

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[GIT PULL FOR v3.3] OMAP3 ISP fix

2012-01-30 Thread Laurent Pinchart
Hi Mauro,

Here's one patch for v3.3 that fixes a regression. The patch was included in 
v3.2, but a merge conflict coupled with a bad conflict resolution removed it 
from v3.3.

The following changes since commit dcd6c92267155e70a94b3927bce681ce74b80d1f:

  Linux 3.3-rc1 (2012-01-19 15:04:48 -0800)

are available in the git repository at:
  git://linuxtv.org/pinchartl/media.git omap3isp-omap3isp-stable

Laurent Pinchart (1):
  omap3isp: Fix crash caused by subdevs now having a pointer to devnodes

 drivers/media/video/omap3isp/ispccdc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/15] mm: compaction: introduce isolate_freepages_range()

2012-01-30 Thread Mel Gorman
On Mon, Jan 30, 2012 at 11:48:20AM +, Mel Gorman wrote:
  +   if (!zone)
  +   zone = page_zone(pfn_to_page(pfn));
  +   else if (zone != page_zone(pfn_to_page(pfn)))
  +   break;
  +
 
 So what you are checking for here is if you straddle zones.
 You could just initialise zone outside of the for loop. You can
 then check outside the loop if end_pfn is in a different zone to
 start_pfn. If it is, either adjust end_pfn accordingly or bail the
 entire operation avoiding the need for release_freepages() later. This
 will be a little cheaper.
 

Whoops, silly me! You are watching for overlapping zones which can
happen in some rare configurations and for that checking page_zone()
like this is necessary. You can still initialise zone outside the loop
but the page_zone() check is still necessary.

My bad.

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 05/15] mm: compaction: export some of the functions

2012-01-30 Thread Mel Gorman
On Thu, Jan 26, 2012 at 10:00:47AM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 
 This commit exports some of the functions from compaction.c file
 outside of it adding their declaration into internal.h header
 file so that other mm related code can use them.
 
 This forced compaction.c to always be compiled (as opposed to being
 compiled only if CONFIG_COMPACTION is defined) but as to avoid
 introducing code that user did not ask for, part of the compaction.c
 is now wrapped in on #ifdef.
 
 Signed-off-by: Michal Nazarewicz min...@mina86.com
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 ---
  mm/Makefile |3 +-
  mm/compaction.c |  314 
 ++-
  mm/internal.h   |   33 ++
  3 files changed, 184 insertions(+), 166 deletions(-)
 
 diff --git a/mm/Makefile b/mm/Makefile
 index 50ec00e..8aada89 100644
 --- a/mm/Makefile
 +++ b/mm/Makefile
 @@ -13,7 +13,7 @@ obj-y   := filemap.o mempool.o 
 oom_kill.o fadvise.o \
  readahead.o swap.o truncate.o vmscan.o shmem.o \
  prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
  page_isolation.o mm_init.o mmu_context.o percpu.o \
 -$(mmu-y)
 +compaction.o $(mmu-y)
  obj-y += init-mm.o
  
  ifdef CONFIG_NO_BOOTMEM
 @@ -32,7 +32,6 @@ obj-$(CONFIG_NUMA)  += mempolicy.o
  obj-$(CONFIG_SPARSEMEM)  += sparse.o
  obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o
  obj-$(CONFIG_SLOB) += slob.o
 -obj-$(CONFIG_COMPACTION) += compaction.o
  obj-$(CONFIG_MMU_NOTIFIER) += mmu_notifier.o
  obj-$(CONFIG_KSM) += ksm.o
  obj-$(CONFIG_PAGE_POISONING) += debug-pagealloc.o
 diff --git a/mm/compaction.c b/mm/compaction.c
 index 63f82be..3e21d28 100644
 --- a/mm/compaction.c
 +++ b/mm/compaction.c
 @@ -16,30 +16,11 @@
  #include linux/sysfs.h
  #include internal.h
  
 +#if defined CONFIG_COMPACTION || defined CONFIG_CMA
 +

This is pedantic but you reference CONFIG_CMA before the patch that
declares it. The only time this really matters is when it breaks
bisection but I do not think that is the case here.

Whether you fix this or not by moving the CONFIG_CMA check to the same
patch that declares it in Kconfig

Acked-by: Mel Gorman m...@csn.ul.ie

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [media] omap3isp: ccdc: Fix crash in HS/VS interrupt handler

2012-01-30 Thread Laurent Pinchart
The HS/VS interrupt handler needs to access the pipeline object. It
erronously tries to get it from the CCDC output video node, which isn't
necessarily included in the pipeline. This leads to a NULL pointer
dereference.

Fix the bug by getting the pipeline object from the CCDC subdev entity.

Reported-by: Gary Thomas g...@mlbassoc.com
Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Sakari Ailus sakari.ai...@iki.fi
Signed-off-by: Mauro Carvalho Chehab mche...@redhat.com
CC: sta...@kernel.org
---
 drivers/media/video/omap3isp/ispccdc.c |3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

This patch fixes a crash in v3.2 and is included in v3.3-rc1. It isn't
applicable to previous kernel versions.

diff --git a/drivers/media/video/omap3isp/ispccdc.c 
b/drivers/media/video/omap3isp/ispccdc.c
index b0b0fa5..9012b57 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1406,8 +1406,7 @@ static int __ccdc_handle_stopping(struct isp_ccdc_device 
*ccdc, u32 event)
 
 static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
 {
-   struct isp_pipeline *pipe =
-   to_isp_pipeline(ccdc-video_out.video.entity);
+   struct isp_pipeline *pipe = to_isp_pipeline(ccdc-subdev.entity);
struct video_device *vdev = ccdc-subdev.devnode;
struct v4l2_event event;
 
-- 
Regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] More on subdev selections API: composition

2012-01-30 Thread Sylwester Nawrocki
Hi Sakari,

On 01/29/2012 07:06 PM, Sakari Ailus wrote:
 The problem with multiple sink pads is that which one you're referring to
 when you're configuring the first processing step on the source. Without
 composition there are no issues.
 
 What I can think of is to create a special composition target which is not
 bound to any pad, but reflects the size of the rectangle on which streams
 may be composed from source pad. Cropping on source pad refers to the
 coordinates of the composition rectangle. Composition target on sink pad in
 the original proposal would be renamed as the scaling target. There would

I would prefer to stick with CROP and COMPOSE target names on both video and
subdev nodes, not to add unnecessary confusion. 

 also be no composition on source pads as it does not make that much sense.

 To make configuration simple, accessing any unsupported rectangles should
 return EINVAL. So devices not supporting composition would work as proposed
 earlier: the compose rectangle would be omitted and the sink crop (if
 supported) would refer to either scaling or crop targets or even the sink
 format directly.
 
 URL:http://www.retiisi.org.uk/v4l2/tmp/format2.eps
 
 Alternatively I think we could as well drop composition support at this
 point as we have no drivers using it. We still need to plan ahead how it

No, that's not true there is no drivers supporting composition. On S5P FIMC
I currently use crop on source pad to configure composition rectangle on the
output buffers. The drivers forms following pipeline:

/dev/subdev?   /dev/subdev?/dev/video? 
++  ++  +-+
| sensor |oo| scaler |oo| DMA |
++  ++  +-+
pads: S0   SC0  SC1D0

Physically the scaler and DMA are tightly coupled in one platform device, hence
SC1 - D0 link is immutable.
Format on D0 link is currently always same as configured with VIDIOC_S_FMT on
/dev/video?.

What is needed here seems just crop on sink pad (SC0) and compose on source pad
(SC1). But I'm not so sure about it, given your interpretation and after short
(well, not so) discussion with Tomasz.

TBH all functionality of the device could be exposed with the scaler subdev
removed and VIDIOC_S/G_SELECTION used on /dev/video?. It is getting overly
complicated with all the subdevs as above in place and your guys interpretation
of the subdev selection.

 could be supported as the need likely arises at some point. As far as I see
 the current interface proposal is compatible with composition.
 
 Should we discuss this further on #v4l-meeting, I propose Tuesday 2012-01-31
 15:00 Finnish time (13:00 GMT).


Regards,
-- 
Sylwester Nawrocki
Samsung Poland RD Center
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/4] media i.MX27 camera: improve discard buffer handling.

2012-01-30 Thread javier Martin
Hi Guennadi,

On 27 January 2012 19:02, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote:
 (removing bar...@tkos.co.il - it bounces)

 On Thu, 26 Jan 2012, javier Martin wrote:

 Hi Guennadi,

 On 25 January 2012 13:12, Guennadi Liakhovetski g.liakhovet...@gmx.de 
 wrote:
  On Fri, 20 Jan 2012, Javier Martin wrote:
 
  The way discard buffer was previously handled lead
  to possible races that made a buffer that was not
  yet ready to be overwritten by new video data. This
  is easily detected at 25fps just adding #define DEBUG
  to enable the memset check and seeing how the image
  is corrupted.
 
  A new discard queue and two discard buffers have
  been added to make them flow trough the pipeline
  of queues and thus provide suitable event ordering.
 
  Hmm, do I understand it right, that the problem is, that while the first
  frame went to the discard buffer, the second one went already to a user
  buffer, while it wasn't ready yet?

 The problem is not only related to the discard buffer but also the way
 valid buffers were handled in an unsafe basis.
 For instance, the buf-bufnum = !bufnum issue. If you receive and
 IRQ from bufnum = 0 you have to update buffer 0, not buffer 1.

 And you solve this by adding one more
  discard buffer? Wouldn't it be possible to either not start capture until
  .start_streaming() is issued, which should also be the case after your
  patch 2/4, or, at least, just reuse one discard buffer multiple times
  until user buffers are available?
 
  If I understand right, you don't really introduce two discard buffers,
  there's still only one data buffer, but you add two discard data objects
  and a list to keep them on. TBH, this seems severely over-engineered to
  me. What's wrong with just keeping one DMA data buffer and using it as
  long, as needed, and checking in your ISR, whether a proper buffer is
  present, by looking for list_empty(active)?
 
  I added a couple of comments below, but my biggest question really is -
  why are these two buffer objects needed? Please, consider getting rid of
  them. So, this is not a full review, if the objects get removed, most of
  this patch will change anyway.

 1. Why a discard buffer is needed?

 When I first took a look at the code it only supported CH1 of the PrP
 (i.e. RGB formats) and a discard buffer was used. My first reaction
 was trying to get rid of that trick. Both CH1 and CH2 of the PrP have
 two pointers that the engine uses to write video frames in a ping-pong
 basis. However, there is a big difference between both channels: if
 you want to detect frame loss in CH1 you have to continually feed the
 two pointers with valid memory areas because the engine is always
 writing and you can't stop it, and this is where the discard buffer
 function is required, but CH2 has a mechanism to stop capturing and
 keep counting loss frames, thus a discard buffer wouldn't be needed.

 To sum up: the driver would be much cleaner without this discard
 buffer trick but we would have to drop support for CH1 (RGB format).
 Being respectful to CH1 support I decided to add CH2 by extending the
 discard buffer strategy to both channels, since the code is cleaner
 this way and doesn't make sense to manage both channels differently.

 2. Why two discard buffer objects are needed?

 After enabling the DEBUG functionality that writes the buffers with
 0xaa before they are filled with video data, I discovered some of them
 were being corrupted. When I tried to find the reason I found that we
 really have a pipeline here:

 ---               ---
   capture (n) |   active_bufs (2)|
 ---              

 where
 capture has buffers that are queued and ready to be written into
 active_bufs represents those buffers that are assigned to a pointer
 in the PrP and has a maximum of 2 since there are two pointers that
 are written in a ping-pong fashion

 Ok, I understand what the discard memory is used for and why you need to
 write it twice to the hardware - to those two pointers. And I can kindof
 agree, that using them uniformly with user buffers on the active list
 simplifies handling. I just don't think it's a good idea to keep two
 struct vb2_buffer instances around with no use. Maybe you could use
 something like

 struct mx2_buf_internal {
        struct list_head                queue;
        int                             bufnum;
        bool                            discard;
 };

 struct mx2_buffer {
        struct vb2_buffer               vb;
        enum mx2_buffer_state           state;
        struct mx2_buf_internal         internal;
 };

 and only use struct mx2_buf_internal for your discard buffers.

You are right, the approach you suggest is more efficient.
What I purpose is that you accept my following v3 patch series and
allow me to send a further cleanup series with the following changes:

1. Remove goto out from mx2_videobuf_queue.
2. Use 

Re: [PATCH v2 3/4] media i.MX27 camera: improve discard buffer handling.

2012-01-30 Thread javier Martin
On 27 January 2012 19:13, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote:
 On Thu, 26 Jan 2012, Javier Martin wrote:

 The way discard buffer was previously handled lead
 to possible races that made a buffer that was not
 yet ready to be overwritten by new video data. This
 is easily detected at 25fps just adding #define DEBUG
 to enable the memset check and seeing how the image
 is corrupted.

 A new discard queue and two discard buffers have
 been added to make them flow trough the pipeline
 of queues and thus provide suitable event ordering.

 Signed-off-by: Javier Martin javier.mar...@vista-silicon.com
 ---
  Changes since v1:
  - Don't allocate discard buffer on every set_fmt.

 ---
  drivers/media/video/mx2_camera.c |  261 
 +-
  1 files changed, 144 insertions(+), 117 deletions(-)

 diff --git a/drivers/media/video/mx2_camera.c 
 b/drivers/media/video/mx2_camera.c
 index 045c018..71054ab 100644
 --- a/drivers/media/video/mx2_camera.c
 +++ b/drivers/media/video/mx2_camera.c
 @@ -237,7 +237,8 @@ struct mx2_buffer {
       struct list_head                queue;
       enum mx2_buffer_state           state;

 -     int bufnum;
 +     int                             bufnum;
 +     bool                            discard;
  };

  struct mx2_camera_dev {
 @@ -256,6 +257,7 @@ struct mx2_camera_dev {

       struct list_head        capture;
       struct list_head        active_bufs;
 +     struct list_head        discard;

       spinlock_t              lock;

 @@ -268,6 +270,7 @@ struct mx2_camera_dev {

       u32                     csicr1;

 +     struct mx2_buffer       buf_discard[2];
       void                    *discard_buffer;
       dma_addr_t              discard_buffer_dma;
       size_t                  discard_size;
 @@ -329,6 +332,30 @@ static struct mx2_fmt_cfg *mx27_emma_prp_get_format(
       return mx27_emma_prp_table[0];
  };

 +static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev,
 +                              unsigned long phys, int bufnum)
 +{
 +     struct mx2_fmt_cfg *prp = pcdev-emma_prp;
 +
 +     if (prp-cfg.channel == 1) {
 +             writel(phys, pcdev-base_emma +
 +                             PRP_DEST_RGB1_PTR + 4 * bufnum);
 +     } else {
 +             writel(phys, pcdev-base_emma +
 +                     PRP_DEST_Y_PTR - 0x14 * bufnum);
 +             if (prp-out_fmt == V4L2_PIX_FMT_YUV420) {
 +                     u32 imgsize = pcdev-icd-user_height *
 +                                     pcdev-icd-user_width;
 +
 +                     writel(phys + imgsize,
 +                     pcdev-base_emma + PRP_DEST_CB_PTR -
 +                     0x14 * bufnum);
 +                     writel(phys + ((5 * imgsize) / 4), pcdev-base_emma +
 +                     PRP_DEST_CR_PTR - 0x14 * bufnum);

 Please fix indentation.

OK, will do in v3.

 +             }
 +     }
 +}
 +
  static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
  {
       unsigned long flags;
 @@ -377,7 +404,7 @@ static int mx2_camera_add_device(struct 
 soc_camera_device *icd)
       writel(pcdev-csicr1, pcdev-base_csi + CSICR1);

       pcdev-icd = icd;
 -     pcdev-frame_count = -1;
 +     pcdev-frame_count = 0;

       dev_info(icd-parent, Camera driver attached to camera %d\n,
                icd-devnum);
 @@ -631,7 +658,7 @@ static void mx2_videobuf_release(struct vb2_buffer *vb)

       spin_lock_irqsave(pcdev-lock, flags);
       if (mx27_camera_emma(pcdev)) {
 -             list_del_init(buf-queue);
 +             INIT_LIST_HEAD(buf-queue);

 The buffer had to be deleted from the queue to clean up the queue. The
 _init was actually not needed. Now, that you do
 INIT_LIST_HEAD(pcdev-capture); and INIT_LIST_HEAD(pcdev-active_bufs);
 in .stop_streaming(), you don't need to do anything about your individual
 buffers. You never test list_empty(buf-queue), so, it doesn't matter
 what they contain.

Fine, v3 will solve this.

       } else if (cpu_is_mx25()  buf-state == MX2_STATE_ACTIVE) {
               if (pcdev-fb1_active == buf) {
                       pcdev-csicr1 = ~CSICR1_FB1_DMA_INTEN;
 @@ -647,6 +674,34 @@ static void mx2_videobuf_release(struct vb2_buffer *vb)
       spin_unlock_irqrestore(pcdev-lock, flags);
  }

 +static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
 +             int bytesperline)
 +{
 +     struct soc_camera_host *ici =
 +             to_soc_camera_host(icd-parent);
 +     struct mx2_camera_dev *pcdev = ici-priv;
 +     struct mx2_fmt_cfg *prp = pcdev-emma_prp;
 +
 +     writel((icd-user_width  16) | icd-user_height,
 +            pcdev-base_emma + PRP_SRC_FRAME_SIZE);
 +     writel(prp-cfg.src_pixel,
 +            pcdev-base_emma + PRP_SRC_PIXEL_FORMAT_CNTL);
 +     if (prp-cfg.channel == 1) {
 +             writel((icd-user_width  16) | icd-user_height,
 +                     pcdev-base_emma + PRP_CH1_OUT_IMAGE_SIZE);
 +             writel(bytesperline,
 +                     pcdev-base_emma + 

Re: [PATCH v2 4/4] media i.MX27 camera: handle overflows properly.

2012-01-30 Thread javier Martin
On 27 January 2012 19:16, Guennadi Liakhovetski g.liakhovet...@gmx.de wrote:
 (removed bar...@tkos.co.il - it bounces)

 On Thu, 26 Jan 2012, Javier Martin wrote:


 Signed-off-by: Javier Martin javier.mar...@vista-silicon.com
 ---
  Changes since v1:
  - Make ifs in irq callback mutually exclusive.
  - Add new argument to mx27_camera_frame_done_emma() to handle errors.

 ---
  drivers/media/video/mx2_camera.c |   38 
 --
  1 files changed, 16 insertions(+), 22 deletions(-)

 diff --git a/drivers/media/video/mx2_camera.c 
 b/drivers/media/video/mx2_camera.c
 index 71054ab..1759673 100644
 --- a/drivers/media/video/mx2_camera.c
 +++ b/drivers/media/video/mx2_camera.c
 @@ -1213,7 +1213,7 @@ static struct soc_camera_host_ops 
 mx2_soc_camera_host_ops = {
  };

  static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
 -             int bufnum)
 +             int bufnum, bool err)
  {
       struct mx2_buffer *buf;
       struct vb2_buffer *vb;
 @@ -1262,7 +1262,10 @@ static void mx27_camera_frame_done_emma(struct 
 mx2_camera_dev *pcdev,
               list_del_init(buf-queue);
               do_gettimeofday(vb-v4l2_buf.timestamp);
               vb-v4l2_buf.sequence = pcdev-frame_count;
 -             vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
 +             if (err)
 +                     vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
 +             else
 +                     vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
       }

       pcdev-frame_count++;
 @@ -1297,21 +1300,12 @@ static irqreturn_t mx27_camera_emma_irq(int 
 irq_emma, void *data)
       struct mx2_buffer *buf;

       if (status  (1  7)) { /* overflow */
 -             u32 cntl;
 -             /*
 -              * We only disable channel 1 here since this is the only
 -              * enabled channel
 -              *
 -              * FIXME: the correct DMA overflow handling should be resetting
 -              * the buffer, returning an error frame, and continuing with
 -              * the next one.
 -              */
 -             cntl = readl(pcdev-base_emma + PRP_CNTL);
 -             writel(cntl  ~(PRP_CNTL_CH1EN | PRP_CNTL_CH2EN),
 -                    pcdev-base_emma + PRP_CNTL);
 -             writel(cntl, pcdev-base_emma + PRP_CNTL);
 -     }
 -     if status  (3  5)) == (3  5)) ||
 +             buf = list_entry(pcdev-active_bufs.next,
 +                     struct mx2_buffer, queue);
 +             mx27_camera_frame_done_emma(pcdev,
 +                                     buf-bufnum, 1);

 use true for bool variables.

 +             status = ~(1  7);
 +     } else if status  (3  5)) == (3  5)) ||
               ((status  (3  3)) == (3  3)))
                        !list_empty(pcdev-active_bufs)) {
               /*
 @@ -1320,13 +1314,13 @@ static irqreturn_t mx27_camera_emma_irq(int 
 irq_emma, void *data)
                */
               buf = list_entry(pcdev-active_bufs.next,
                       struct mx2_buffer, queue);
 -             mx27_camera_frame_done_emma(pcdev, buf-bufnum);
 +             mx27_camera_frame_done_emma(pcdev, buf-bufnum, 0);

 false

               status = ~(1  (6 - buf-bufnum)); /* mark processed */
 +     } else if ((status  (1  6)) || (status  (1  4))) {
 +             mx27_camera_frame_done_emma(pcdev, 0, 0);

 false

 +     } else if ((status  (1  5)) || (status  (1  3))) {
 +             mx27_camera_frame_done_emma(pcdev, 1, 0);

 false

       }
 -     if ((status  (1  6)) || (status  (1  4)))
 -             mx27_camera_frame_done_emma(pcdev, 0);
 -     if ((status  (1  5)) || (status  (1  3)))
 -             mx27_camera_frame_done_emma(pcdev, 1);

       writel(status, pcdev-base_emma + PRP_INTRSTATUS);


Don't worry, this will be fixed in v3.



-- 
Javier Martin
Vista Silicon S.L.
CDTUC - FASE C - Oficina S-345
Avda de los Castros s/n
39005- Santander. Cantabria. Spain
+34 942 25 32 60
www.vista-silicon.com
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 06/15] mm: page_alloc: introduce alloc_contig_range()

2012-01-30 Thread Mel Gorman
On Thu, Jan 26, 2012 at 10:00:48AM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 
 This commit adds the alloc_contig_range() function which tries
 to allocate given range of pages.  It tries to migrate all
 already allocated pages that fall in the range thus freeing them.
 Once all pages in the range are freed they are removed from the
 buddy system thus allocated for the caller to use.
 
 Signed-off-by: Michal Nazarewicz min...@mina86.com
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 ---
  include/linux/page-isolation.h |7 ++
  mm/page_alloc.c|  183 
 
  2 files changed, 190 insertions(+), 0 deletions(-)
 
 diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
 index 8c02c2b..430cf61 100644
 --- a/include/linux/page-isolation.h
 +++ b/include/linux/page-isolation.h
 @@ -39,5 +39,12 @@ extern void update_pcp_isolate_block(unsigned long pfn);
  extern int set_migratetype_isolate(struct page *page);
  extern void unset_migratetype_isolate(struct page *page);
  
 +#ifdef CONFIG_CMA
 +
 +/* The below functions must be run on a range from a single zone. */
 +extern int alloc_contig_range(unsigned long start, unsigned long end);
 +extern void free_contig_range(unsigned long pfn, unsigned nr_pages);
 +
 +#endif
  

Did you really mean page-isolation.h? I would have thought gfp.h
would be a more suitable fit.

  #endif
 diff --git a/mm/page_alloc.c b/mm/page_alloc.c
 index 70709e7..b4f50532 100644
 --- a/mm/page_alloc.c
 +++ b/mm/page_alloc.c
 @@ -57,6 +57,7 @@
  #include linux/ftrace_event.h
  #include linux/memcontrol.h
  #include linux/prefetch.h
 +#include linux/migrate.h
  #include linux/page-debug-flags.h
  
  #include asm/tlbflush.h
 @@ -5488,6 +5489,188 @@ out:
   spin_unlock_irqrestore(zone-lock, flags);
  }
  
 +#ifdef CONFIG_CMA
 +
 +static unsigned long pfn_align_to_maxpage_down(unsigned long pfn)
 +{
 + return pfn  ~(MAX_ORDER_NR_PAGES - 1);
 +}
 +
 +static unsigned long pfn_align_to_maxpage_up(unsigned long pfn)
 +{
 + return ALIGN(pfn, MAX_ORDER_NR_PAGES);
 +}
 +
 +static struct page *
 +__alloc_contig_migrate_alloc(struct page *page, unsigned long private,
 +  int **resultp)
 +{
 + return alloc_page(GFP_HIGHUSER_MOVABLE);
 +}
 +
 +/* [start, end) must belong to a single zone. */
 +static int __alloc_contig_migrate_range(unsigned long start, unsigned long 
 end)
 +{
 + /* This function is based on compact_zone() from compaction.c. */
 +
 + unsigned long pfn = start;
 + unsigned int tries = 0;
 + int ret = 0;
 +
 + struct compact_control cc = {
 + .nr_migratepages = 0,
 + .order = -1,
 + .zone = page_zone(pfn_to_page(start)),
 + .sync = true,
 + };
 + INIT_LIST_HEAD(cc.migratepages);
 +
 + migrate_prep_local();
 +
 + while (pfn  end || !list_empty(cc.migratepages)) {
 + if (fatal_signal_pending(current)) {
 + ret = -EINTR;
 + break;
 + }
 +
 + if (list_empty(cc.migratepages)) {
 + cc.nr_migratepages = 0;
 + pfn = isolate_migratepages_range(cc.zone, cc,
 +  pfn, end);
 + if (!pfn) {
 + ret = -EINTR;
 + break;
 + }
 + tries = 0;
 + } else if (++tries == 5) {
 + ret = ret  0 ? ret : -EBUSY;
 + break;
 + }
 +
 + ret = migrate_pages(cc.migratepages,
 + __alloc_contig_migrate_alloc,
 + 0, false, true);
 + }
 +
 + putback_lru_pages(cc.migratepages);
 + return ret;
 +}
 +
 +/**
 + * alloc_contig_range() -- tries to allocate given range of pages
 + * @start:   start PFN to allocate
 + * @end: one-past-the-last PFN to allocate
 + *
 + * The PFN range does not have to be pageblock or MAX_ORDER_NR_PAGES
 + * aligned, however it's the caller's responsibility to guarantee that
 + * we are the only thread that changes migrate type of pageblocks the
 + * pages fall in.
 + *
 + * The PFN range must belong to a single zone.
 + *
 + * Returns zero on success or negative error code.  On success all
 + * pages which PFN is in [start, end) are allocated for the caller and
 + * need to be freed with free_contig_range().
 + */
 +int alloc_contig_range(unsigned long start, unsigned long end)
 +{
 + unsigned long outer_start, outer_end;
 + int ret = 0, order;
 +
 + /*
 +  * What we do here is we mark all pageblocks in range as
 +  * MIGRATE_ISOLATE.  Because of the way page allocator work, we
 +  * align the range to MAX_ORDER pages so that page allocator
 +  * won't try to merge buddies from different pageblocks and
 +   

Re: [PATCH][media] s5p-g2d: Add HFLIP and VFLIP support

2012-01-30 Thread Laurent Pinchart
Hi Sashin,

Thanks for the patch.

On Monday 30 January 2012 10:58:43 Sachin Kamat wrote:
 This patch adds support for flipping the image horizontally and vertically.
 
 Signed-off-by: Sachin Kamat sachin.ka...@linaro.org
 ---
  drivers/media/video/s5p-g2d/g2d-hw.c |5 +++
  drivers/media/video/s5p-g2d/g2d.c|   47 +--
  drivers/media/video/s5p-g2d/g2d.h|3 ++
  3 files changed, 46 insertions(+), 9 deletions(-)

[snip]

 diff --git a/drivers/media/video/s5p-g2d/g2d.c
 b/drivers/media/video/s5p-g2d/g2d.c index febaa67..dea9701 100644
 --- a/drivers/media/video/s5p-g2d/g2d.c
 +++ b/drivers/media/video/s5p-g2d/g2d.c
 @@ -178,6 +178,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
  {
   struct g2d_ctx *ctx = container_of(ctrl-handler, struct g2d_ctx,
   ctrl_handler);
 +
   switch (ctrl-id) {
   case V4L2_CID_COLORFX:
   if (ctrl-val == V4L2_COLORFX_NEGATIVE)
 @@ -185,6 +186,21 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
   else
   ctx-rop = ROP4_COPY;
   break;
 +
 + case V4L2_CID_HFLIP:
 + if (ctrl-val == 1)
 + ctx-hflip = 1;
 + else
 + ctx-hflip = 0;
 + break;
 +
 + case V4L2_CID_VFLIP:
 + if (ctrl-val == 1)
 + ctx-vflip = (1  1);
 + else
 + ctx-vflip = 0;
 + break;
 +
   default:
   v4l2_err(ctx-dev-v4l2_dev, unknown control\n);
   return -EINVAL;
 @@ -200,11 +216,9 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
  {
   struct g2d_dev *dev = ctx-dev;
 
 - v4l2_ctrl_handler_init(ctx-ctrl_handler, 1);
 - if (ctx-ctrl_handler.error) {
 - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
 - return ctx-ctrl_handler.error;
 - }
 + v4l2_ctrl_handler_init(ctx-ctrl_handler, 3);
 + if (ctx-ctrl_handler.error)
 + goto error;

There's not need to verify ctx-ctrl_handler.error after every call to 
v4l2_ctrl_handler_init() or v4l2_ctrl_new_*(). You can verify it once only 
after initialization all controls.

 
   v4l2_ctrl_new_std_menu(
   ctx-ctrl_handler,
 @@ -214,12 +228,25 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
   ~((1  V4L2_COLORFX_NONE) | (1  V4L2_COLORFX_NEGATIVE)),
   V4L2_COLORFX_NONE);
 
 - if (ctx-ctrl_handler.error) {
 - v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
 - return ctx-ctrl_handler.error;
 - }
 + if (ctx-ctrl_handler.error)
 + goto error;
 +
 + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops,
 + V4L2_CID_HFLIP, 0, 1, 1, 0);
 + if (ctx-ctrl_handler.error)
 + goto error;
 +
 + v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops,
 + V4L2_CID_VFLIP, 0, 1, 1, 0);

As a single register controls hflip and vflip, you should group the two 
controls in a cluster.

 + if (ctx-ctrl_handler.error)
 + goto error;
 
   return 0;
 +
 +error:
 + v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
 + return ctx-ctrl_handler.error;
 +
  }
 
  static int g2d_open(struct file *file)
 @@ -564,6 +591,8 @@ static void device_run(void *prv)
   g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));
 
   g2d_set_rop4(dev, ctx-rop);
 + g2d_set_flip(dev, ctx-hflip | ctx-vflip);
 +

Is this called for every frame, or once at stream start only ? In the later 
case, this means that hflip and vflip won't be changeable during streaming. Is 
that on purpose ?

   if (ctx-in.c_width != ctx-out.c_width ||
   ctx-in.c_height != ctx-out.c_height)
   cmd |= g2d_cmd_stretch(1);
 diff --git a/drivers/media/video/s5p-g2d/g2d.h
 b/drivers/media/video/s5p-g2d/g2d.h index 5eae901..b3be3c8 100644
 --- a/drivers/media/video/s5p-g2d/g2d.h
 +++ b/drivers/media/video/s5p-g2d/g2d.h
 @@ -59,6 +59,8 @@ struct g2d_ctx {
   struct g2d_frameout;
   struct v4l2_ctrl_handler ctrl_handler;
   u32 rop;
 + u32 hflip;
 + u32 vflip;
  };
 
  struct g2d_fmt {
 @@ -77,6 +79,7 @@ void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a);
  void g2d_start(struct g2d_dev *d);
  void g2d_clear_int(struct g2d_dev *d);
  void g2d_set_rop4(struct g2d_dev *d, u32 r);
 +void g2d_set_flip(struct g2d_dev *d, u32 r);
  u32 g2d_cmd_stretch(u32 e);
  void g2d_set_cmd(struct g2d_dev *d, u32 c);

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 07/15] mm: page_alloc: change fallbacks array handling

2012-01-30 Thread Mel Gorman
On Thu, Jan 26, 2012 at 10:00:49AM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 
 This commit adds a row for MIGRATE_ISOLATE type to the fallbacks array
 which was missing from it.  It also, changes the array traversal logic
 a little making MIGRATE_RESERVE an end marker.  The letter change,
 removes the implicit MIGRATE_UNMOVABLE from the end of each row which
 was read by __rmqueue_fallback() function.
 
 Signed-off-by: Michal Nazarewicz min...@mina86.com
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com

Acked-by: Mel Gorman m...@csn.ul.ie

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 1/4] media i.MX27 camera: migrate driver to videobuf2

2012-01-30 Thread Javier Martin

Signed-off-by: Javier Martin javier.mar...@vista-silicon.com
---
Changes since v2:
 - Return ENOTTY for VIDIOC_CREATE_BUFS
 - Check buffer size properly.
 - Do not remove unfixed FIXME.
 - Remove mx25 queued buffers from the queue list at release.

---
 drivers/media/video/mx2_camera.c |  289 +-
 1 files changed, 127 insertions(+), 162 deletions(-)

diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index ca76dd2..ae7cae6 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2008, Sascha Hauer, Pengutronix
  * Copyright (C) 2010, Baruch Siach, Orex Computed Radiography
+ * Copyright (C) 2012, Javier Martin, Vista Silicon S.L.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,8 +31,8 @@
 
 #include media/v4l2-common.h
 #include media/v4l2-dev.h
-#include media/videobuf-core.h
-#include media/videobuf-dma-contig.h
+#include media/videobuf2-core.h
+#include media/videobuf2-dma-contig.h
 #include media/soc_camera.h
 #include media/soc_mediabus.h
 
@@ -223,6 +224,22 @@ struct mx2_fmt_cfg {
struct mx2_prp_cfg  cfg;
 };
 
+enum mx2_buffer_state {
+   MX2_STATE_QUEUED,
+   MX2_STATE_ACTIVE,
+   MX2_STATE_DONE,
+};
+
+/* buffer for one video frame */
+struct mx2_buffer {
+   /* common v4l buffer stuff -- must be first */
+   struct vb2_buffer   vb;
+   struct list_headqueue;
+   enum mx2_buffer_state   state;
+
+   int bufnum;
+};
+
 struct mx2_camera_dev {
struct device   *dev;
struct soc_camera_host  soc_host;
@@ -256,16 +273,7 @@ struct mx2_camera_dev {
size_t  discard_size;
struct mx2_fmt_cfg  *emma_prp;
u32 frame_count;
-};
-
-/* buffer for one video frame */
-struct mx2_buffer {
-   /* common v4l buffer stuff -- must be first */
-   struct videobuf_buffer  vb;
-
-   enum v4l2_mbus_pixelcodecode;
-
-   int bufnum;
+   struct vb2_alloc_ctx*alloc_ctx;
 };
 
 static struct mx2_fmt_cfg mx27_emma_prp_table[] = {
@@ -407,7 +415,7 @@ static irqreturn_t mx27_camera_irq(int irq_csi, void *data)
 static void mx25_camera_frame_done(struct mx2_camera_dev *pcdev, int fb,
int state)
 {
-   struct videobuf_buffer *vb;
+   struct vb2_buffer *vb;
struct mx2_buffer *buf;
struct mx2_buffer **fb_active = fb == 1 ? pcdev-fb1_active :
pcdev-fb2_active;
@@ -420,25 +428,24 @@ static void mx25_camera_frame_done(struct mx2_camera_dev 
*pcdev, int fb,
goto out;
 
vb = (*fb_active)-vb;
-   dev_dbg(pcdev-dev, %s (vb=0x%p) 0x%08lx %d\n, __func__,
-   vb, vb-baddr, vb-bsize);
+   dev_dbg(pcdev-dev, %s (vb=0x%p) 0x%p %lu\n, __func__,
+   vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
 
-   vb-state = state;
-   do_gettimeofday(vb-ts);
-   vb-field_count++;
-
-   wake_up(vb-done);
+   do_gettimeofday(vb-v4l2_buf.timestamp);
+   vb-v4l2_buf.sequence++;
+   vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
 
if (list_empty(pcdev-capture)) {
buf = NULL;
writel(0, pcdev-base_csi + fb_reg);
} else {
buf = list_entry(pcdev-capture.next, struct mx2_buffer,
-   vb.queue);
+   queue);
vb = buf-vb;
-   list_del(vb-queue);
-   vb-state = VIDEOBUF_ACTIVE;
-   writel(videobuf_to_dma_contig(vb), pcdev-base_csi + fb_reg);
+   list_del(buf-queue);
+   buf-state = MX2_STATE_ACTIVE;
+   writel(vb2_dma_contig_plane_dma_addr(vb, 0),
+  pcdev-base_csi + fb_reg);
}
 
*fb_active = buf;
@@ -453,9 +460,9 @@ static irqreturn_t mx25_camera_irq(int irq_csi, void *data)
u32 status = readl(pcdev-base_csi + CSISR);
 
if (status  CSISR_DMA_TSF_FB1_INT)
-   mx25_camera_frame_done(pcdev, 1, VIDEOBUF_DONE);
+   mx25_camera_frame_done(pcdev, 1, MX2_STATE_DONE);
else if (status  CSISR_DMA_TSF_FB2_INT)
-   mx25_camera_frame_done(pcdev, 2, VIDEOBUF_DONE);
+   mx25_camera_frame_done(pcdev, 2, MX2_STATE_DONE);
 
/* FIXME: handle CSISR_RFF_OR_INT */
 
@@ -467,59 +474,50 @@ static irqreturn_t mx25_camera_irq(int irq_csi, void 
*data)
 /*
  *  Videobuf operations
  */
-static int mx2_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
- unsigned int *size)
+static int mx2_videobuf_setup(struct vb2_queue *vq,
+   const struct v4l2_format *fmt,
+   unsigned int *count, unsigned int *num_planes,
+  

[PATCH v3 2/4] media i.MX27 camera: add start_stream and stop_stream callbacks.

2012-01-30 Thread Javier Martin
Add start_stream and stop_stream callback in order to enable
and disable the eMMa-PrP properly and save CPU usage avoiding
IRQs when the device is not streaming. This also makes the driver
return 0 as the sequence number of the first frame.

Signed-off-by: Javier Martin javier.mar...@vista-silicon.com
---
 - Make start_streaming cleaner.

---
 drivers/media/video/mx2_camera.c |  100 -
 1 files changed, 75 insertions(+), 25 deletions(-)

diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index ae7cae6..35ab971 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -377,7 +377,7 @@ static int mx2_camera_add_device(struct soc_camera_device 
*icd)
writel(pcdev-csicr1, pcdev-base_csi + CSICR1);
 
pcdev-icd = icd;
-   pcdev-frame_count = 0;
+   pcdev-frame_count = -1;
 
dev_info(icd-parent, Camera driver attached to camera %d\n,
 icd-devnum);
@@ -656,11 +656,79 @@ static void mx2_videobuf_release(struct vb2_buffer *vb)
spin_unlock_irqrestore(pcdev-lock, flags);
 }
 
+static int mx2_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+   struct soc_camera_device *icd = soc_camera_from_vb2q(q);
+   struct soc_camera_host *ici =
+   to_soc_camera_host(icd-parent);
+   struct mx2_camera_dev *pcdev = ici-priv;
+   struct mx2_fmt_cfg *prp = pcdev-emma_prp;
+
+   if (mx27_camera_emma(pcdev)) {
+   unsigned long flags;
+   if (count  2)
+   return -EINVAL;
+
+   spin_lock_irqsave(pcdev-lock, flags);
+   if (prp-cfg.channel == 1) {
+   writel(PRP_CNTL_CH1EN |
+   PRP_CNTL_CSIEN |
+   prp-cfg.in_fmt |
+   prp-cfg.out_fmt |
+   PRP_CNTL_CH1_LEN |
+   PRP_CNTL_CH1BYP |
+   PRP_CNTL_CH1_TSKIP(0) |
+   PRP_CNTL_IN_TSKIP(0),
+   pcdev-base_emma + PRP_CNTL);
+   } else {
+   writel(PRP_CNTL_CH2EN |
+   PRP_CNTL_CSIEN |
+   prp-cfg.in_fmt |
+   prp-cfg.out_fmt |
+   PRP_CNTL_CH2_LEN |
+   PRP_CNTL_CH2_TSKIP(0) |
+   PRP_CNTL_IN_TSKIP(0),
+   pcdev-base_emma + PRP_CNTL);
+   }
+   spin_unlock_irqrestore(pcdev-lock, flags);
+   }
+
+   return 0;
+}
+
+static int mx2_stop_streaming(struct vb2_queue *q)
+{
+   struct soc_camera_device *icd = soc_camera_from_vb2q(q);
+   struct soc_camera_host *ici =
+   to_soc_camera_host(icd-parent);
+   struct mx2_camera_dev *pcdev = ici-priv;
+   struct mx2_fmt_cfg *prp = pcdev-emma_prp;
+   unsigned long flags;
+   u32 cntl;
+
+   spin_lock_irqsave(pcdev-lock, flags);
+   if (mx27_camera_emma(pcdev)) {
+   cntl = readl(pcdev-base_emma + PRP_CNTL);
+   if (prp-cfg.channel == 1) {
+   writel(cntl  ~PRP_CNTL_CH1EN,
+  pcdev-base_emma + PRP_CNTL);
+   } else {
+   writel(cntl  ~PRP_CNTL_CH2EN,
+  pcdev-base_emma + PRP_CNTL);
+   }
+   }
+   spin_unlock_irqrestore(pcdev-lock, flags);
+
+   return 0;
+}
+
 static struct vb2_ops mx2_videobuf_ops = {
-   .queue_setup= mx2_videobuf_setup,
-   .buf_prepare= mx2_videobuf_prepare,
-   .buf_queue  = mx2_videobuf_queue,
-   .buf_cleanup= mx2_videobuf_release,
+   .queue_setup = mx2_videobuf_setup,
+   .buf_prepare = mx2_videobuf_prepare,
+   .buf_queue   = mx2_videobuf_queue,
+   .buf_cleanup = mx2_videobuf_release,
+   .start_streaming = mx2_start_streaming,
+   .stop_streaming  = mx2_stop_streaming,
 };
 
 static int mx2_camera_init_videobuf(struct vb2_queue *q,
@@ -718,16 +786,6 @@ static void mx27_camera_emma_buf_init(struct 
soc_camera_device *icd,
writel(pcdev-discard_buffer_dma,
pcdev-base_emma + PRP_DEST_RGB2_PTR);
 
-   writel(PRP_CNTL_CH1EN |
-   PRP_CNTL_CSIEN |
-   prp-cfg.in_fmt |
-   prp-cfg.out_fmt |
-   PRP_CNTL_CH1_LEN |
-   PRP_CNTL_CH1BYP |
-   PRP_CNTL_CH1_TSKIP(0) |
-   PRP_CNTL_IN_TSKIP(0),
-   pcdev-base_emma + PRP_CNTL);
-
writel((icd-user_width  16) | icd-user_height,
pcdev-base_emma + 

[PATCH v3 3/4] media i.MX27 camera: improve discard buffer handling.

2012-01-30 Thread Javier Martin
The way discard buffer was previously handled lead
to possible races that made a buffer that was not
yet ready to be overwritten by new video data. This
is easily detected at 25fps just adding #define DEBUG
to enable the memset check and seeing how the image
is corrupted.

A new discard queue and two discard buffers have
been added to make them flow trough the pipeline
of queues and thus provide suitable event ordering.

Signed-off-by: Javier Martin javier.mar...@vista-silicon.com
---
 Changes since v2:
 - Remove BUG_ON when active list is empty.
 - Replace empty list checks with warnings.

---
 drivers/media/video/mx2_camera.c |  280 +-
 1 files changed, 153 insertions(+), 127 deletions(-)

diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index 35ab971..e7ccd97 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -237,7 +237,8 @@ struct mx2_buffer {
struct list_headqueue;
enum mx2_buffer_state   state;
 
-   int bufnum;
+   int bufnum;
+   booldiscard;
 };
 
 struct mx2_camera_dev {
@@ -256,6 +257,7 @@ struct mx2_camera_dev {
 
struct list_headcapture;
struct list_headactive_bufs;
+   struct list_headdiscard;
 
spinlock_t  lock;
 
@@ -268,6 +270,7 @@ struct mx2_camera_dev {
 
u32 csicr1;
 
+   struct mx2_buffer   buf_discard[2];
void*discard_buffer;
dma_addr_t  discard_buffer_dma;
size_t  discard_size;
@@ -329,6 +332,29 @@ static struct mx2_fmt_cfg *mx27_emma_prp_get_format(
return mx27_emma_prp_table[0];
 };
 
+static void mx27_update_emma_buf(struct mx2_camera_dev *pcdev,
+unsigned long phys, int bufnum)
+{
+   struct mx2_fmt_cfg *prp = pcdev-emma_prp;
+
+   if (prp-cfg.channel == 1) {
+   writel(phys, pcdev-base_emma +
+   PRP_DEST_RGB1_PTR + 4 * bufnum);
+   } else {
+   writel(phys, pcdev-base_emma +
+   PRP_DEST_Y_PTR - 0x14 * bufnum);
+   if (prp-out_fmt == V4L2_PIX_FMT_YUV420) {
+   u32 imgsize = pcdev-icd-user_height *
+   pcdev-icd-user_width;
+
+   writel(phys + imgsize, pcdev-base_emma +
+   PRP_DEST_CB_PTR - 0x14 * bufnum);
+   writel(phys + ((5 * imgsize) / 4), pcdev-base_emma +
+   PRP_DEST_CR_PTR - 0x14 * bufnum);
+   }
+   }
+}
+
 static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
 {
unsigned long flags;
@@ -377,7 +403,7 @@ static int mx2_camera_add_device(struct soc_camera_device 
*icd)
writel(pcdev-csicr1, pcdev-base_csi + CSICR1);
 
pcdev-icd = icd;
-   pcdev-frame_count = -1;
+   pcdev-frame_count = 0;
 
dev_info(icd-parent, Camera driver attached to camera %d\n,
 icd-devnum);
@@ -397,13 +423,6 @@ static void mx2_camera_remove_device(struct 
soc_camera_device *icd)
 
mx2_camera_deactivate(pcdev);
 
-   if (pcdev-discard_buffer) {
-   dma_free_coherent(ici-v4l2_dev.dev, pcdev-discard_size,
-   pcdev-discard_buffer,
-   pcdev-discard_buffer_dma);
-   pcdev-discard_buffer = NULL;
-   }
-
pcdev-icd = NULL;
 }
 
@@ -640,7 +659,6 @@ static void mx2_videobuf_release(struct vb2_buffer *vb)
 */
 
spin_lock_irqsave(pcdev-lock, flags);
-   list_del_init(buf-queue);
if (cpu_is_mx25()  buf-state == MX2_STATE_ACTIVE) {
if (pcdev-fb1_active == buf) {
pcdev-csicr1 = ~CSICR1_FB1_DMA_INTEN;
@@ -656,6 +674,34 @@ static void mx2_videobuf_release(struct vb2_buffer *vb)
spin_unlock_irqrestore(pcdev-lock, flags);
 }
 
+static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
+   int bytesperline)
+{
+   struct soc_camera_host *ici =
+   to_soc_camera_host(icd-parent);
+   struct mx2_camera_dev *pcdev = ici-priv;
+   struct mx2_fmt_cfg *prp = pcdev-emma_prp;
+
+   writel((icd-user_width  16) | icd-user_height,
+  pcdev-base_emma + PRP_SRC_FRAME_SIZE);
+   writel(prp-cfg.src_pixel,
+  pcdev-base_emma + PRP_SRC_PIXEL_FORMAT_CNTL);
+   if (prp-cfg.channel == 1) {
+   writel((icd-user_width  16) | icd-user_height,
+   pcdev-base_emma + PRP_CH1_OUT_IMAGE_SIZE);
+   writel(bytesperline,
+   pcdev-base_emma + PRP_DEST_CH1_LINE_STRIDE);
+   writel(prp-cfg.ch1_pixel,
+   pcdev-base_emma + PRP_CH1_PIXEL_FORMAT_CNTL);
+ 

[PATCH v3 4/4] media i.MX27 camera: handle overflows properly.

2012-01-30 Thread Javier Martin

Signed-off-by: Javier Martin javier.mar...@vista-silicon.com
---
 Changes since v2:
 - Use true and false for bool variables.

---
 drivers/media/video/mx2_camera.c |   38 --
 1 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index e7ccd97..09bcfe0 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -1210,7 +1210,7 @@ static struct soc_camera_host_ops mx2_soc_camera_host_ops 
= {
 };
 
 static void mx27_camera_frame_done_emma(struct mx2_camera_dev *pcdev,
-   int bufnum)
+   int bufnum, bool err)
 {
struct mx2_fmt_cfg *prp = pcdev-emma_prp;
struct mx2_buffer *buf;
@@ -1258,7 +1258,10 @@ static void mx27_camera_frame_done_emma(struct 
mx2_camera_dev *pcdev,
list_del_init(buf-queue);
do_gettimeofday(vb-v4l2_buf.timestamp);
vb-v4l2_buf.sequence = pcdev-frame_count;
-   vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
+   if (err)
+   vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+   else
+   vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
}
 
pcdev-frame_count++;
@@ -1302,21 +1305,12 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, 
void *data)
__func__);
 
if (status  (1  7)) { /* overflow */
-   u32 cntl;
-   /*
-* We only disable channel 1 here since this is the only
-* enabled channel
-*
-* FIXME: the correct DMA overflow handling should be resetting
-* the buffer, returning an error frame, and continuing with
-* the next one.
-*/
-   cntl = readl(pcdev-base_emma + PRP_CNTL);
-   writel(cntl  ~(PRP_CNTL_CH1EN | PRP_CNTL_CH2EN),
-  pcdev-base_emma + PRP_CNTL);
-   writel(cntl, pcdev-base_emma + PRP_CNTL);
-   }
-   if (((status  (3  5)) == (3  5)) ||
+   buf = list_entry(pcdev-active_bufs.next,
+   struct mx2_buffer, queue);
+   mx27_camera_frame_done_emma(pcdev,
+   buf-bufnum, true);
+   status = ~(1  7);
+   } else if (((status  (3  5)) == (3  5)) ||
((status  (3  3)) == (3  3))) {
/*
 * Both buffers have triggered, process the one we're expecting
@@ -1324,13 +1318,13 @@ static irqreturn_t mx27_camera_emma_irq(int irq_emma, 
void *data)
 */
buf = list_entry(pcdev-active_bufs.next,
struct mx2_buffer, queue);
-   mx27_camera_frame_done_emma(pcdev, buf-bufnum);
+   mx27_camera_frame_done_emma(pcdev, buf-bufnum, false);
status = ~(1  (6 - buf-bufnum)); /* mark processed */
+   } else if ((status  (1  6)) || (status  (1  4))) {
+   mx27_camera_frame_done_emma(pcdev, 0, false);
+   } else if ((status  (1  5)) || (status  (1  3))) {
+   mx27_camera_frame_done_emma(pcdev, 1, false);
}
-   if ((status  (1  6)) || (status  (1  4)))
-   mx27_camera_frame_done_emma(pcdev, 0);
-   if ((status  (1  5)) || (status  (1  3)))
-   mx27_camera_frame_done_emma(pcdev, 1);
 
writel(status, pcdev-base_emma + PRP_INTRSTATUS);
 
-- 
1.7.0.4

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3] omap3isp: Prevent pipelines that contain a crashed entity from starting

2012-01-30 Thread Laurent Pinchart
The OMAP3 ISP preview engine will violate the L4 bus protocol if we try
to write some of its internal registers after it failed to stop
properly. This generates an external abort on non-linefetch fault,
triggering a fatal kernel oops.

We can't always prevent preview engine stop failures (they can for
instance be caused by a sensor crash), but we can improve the system
reliability by refusing to start streaming on a pipeline that contains
the preview engine if it failed to stop. The driver will then eventually
reset the ISP (when all applications will have closed their file handles
related to OMAP3 ISP device nodes), making the ISP usable again.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
Acked-by: Sakari Ailus sakari.ai...@iki.fi
---
 drivers/media/video/omap3isp/isp.c  |   27 +--
 drivers/media/video/omap3isp/isp.h  |3 ++-
 drivers/media/video/omap3isp/ispvideo.c |4 
 drivers/media/video/omap3isp/ispvideo.h |2 ++
 4 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/drivers/media/video/omap3isp/isp.c 
b/drivers/media/video/omap3isp/isp.c
index 12d5f92..3db8583 100644
--- a/drivers/media/video/omap3isp/isp.c
+++ b/drivers/media/video/omap3isp/isp.c
@@ -739,6 +739,17 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
unsigned long flags;
int ret;
 
+   /* If the preview engine crashed it might not respond to read/write
+* operations on the L4 bus. This would result in a bus fault and a
+* kernel oops. Refuse to start streaming in that case. This check must
+* be performed before the loop below to avoid starting entities if the
+* pipeline won't start anyway (those entities would then likely fail to
+* stop, making the problem worse).
+*/
+   if ((pipe-entities  isp-crashed) 
+   (1U  isp-isp_prev.subdev.entity.id))
+   return -EIO;
+
spin_lock_irqsave(pipe-lock, flags);
pipe-state = ~(ISP_PIPELINE_IDLE_INPUT | ISP_PIPELINE_IDLE_OUTPUT);
spin_unlock_irqrestore(pipe-lock, flags);
@@ -879,13 +890,15 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
 
if (ret) {
dev_info(isp-dev, Unable to stop %s\n, subdev-name);
+   /* If the entity failed to stopped, assume it has
+* crashed. Mark it as such, the ISP will be reset when
+* applications will release it.
+*/
+   isp-crashed |= 1U  subdev-entity.id;
failure = -ETIMEDOUT;
}
}
 
-   if (failure  0)
-   isp-needs_reset = true;
-
return failure;
 }
 
@@ -1069,6 +1082,7 @@ static int isp_reset(struct isp_device *isp)
udelay(1);
}
 
+   isp-crashed = 0;
return 0;
 }
 
@@ -1496,10 +1510,11 @@ void omap3isp_put(struct isp_device *isp)
if (--isp-ref_count == 0) {
isp_disable_interrupts(isp);
isp_save_ctx(isp);
-   if (isp-needs_reset) {
+   /* Reset the ISP if an entity has failed to stop. This is the
+* only way to recover from such conditions.
+*/
+   if (isp-crashed)
isp_reset(isp);
-   isp-needs_reset = false;
-   }
isp_disable_clocks(isp);
}
mutex_unlock(isp-isp_mutex);
diff --git a/drivers/media/video/omap3isp/isp.h 
b/drivers/media/video/omap3isp/isp.h
index d96603e..f8d1f10 100644
--- a/drivers/media/video/omap3isp/isp.h
+++ b/drivers/media/video/omap3isp/isp.h
@@ -145,6 +145,7 @@ struct isp_platform_callback {
  * @raw_dmamask: Raw DMA mask
  * @stat_lock: Spinlock for handling statistics
  * @isp_mutex: Mutex for serializing requests to ISP.
+ * @crashed: Bitmask of crashed entities (indexed by entity ID)
  * @has_context: Context has been saved at least once and can be restored.
  * @ref_count: Reference count for handling multiple ISP requests.
  * @cam_ick: Pointer to camera interface clock structure.
@@ -184,7 +185,7 @@ struct isp_device {
/* ISP Obj */
spinlock_t stat_lock;   /* common lock for statistic drivers */
struct mutex isp_mutex; /* For handling ref_count field */
-   bool needs_reset;
+   u32 crashed;
int has_context;
int ref_count;
unsigned int autoidle;
diff --git a/drivers/media/video/omap3isp/ispvideo.c 
b/drivers/media/video/omap3isp/ispvideo.c
index b020700..2107d99 100644
--- a/drivers/media/video/omap3isp/ispvideo.c
+++ b/drivers/media/video/omap3isp/ispvideo.c
@@ -292,6 +292,7 @@ static int isp_video_validate_pipeline(struct isp_pipeline 
*pipe)
int ret;
 
pipe-max_rate = pipe-l3_ick;
+   pipe-entities = 0;
 
subdev = isp_video_remote_subdev(pipe-output, NULL);
if (subdev == NULL)

[PATCH] mt9p031: Remove unused xskip and yskip fields in struct mt9p031

2012-01-30 Thread Laurent Pinchart
The fields are set but never used, remove them.

Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com
---
 drivers/media/video/mt9p031.c |4 
 1 files changed, 0 insertions(+), 4 deletions(-)

diff --git a/drivers/media/video/mt9p031.c b/drivers/media/video/mt9p031.c
index 93c3ec7..0bdddbb 100644
--- a/drivers/media/video/mt9p031.c
+++ b/drivers/media/video/mt9p031.c
@@ -115,8 +115,6 @@ struct mt9p031 {
struct mt9p031_platform_data *pdata;
struct mutex power_lock; /* lock to protect power_count */
int power_count;
-   u16 xskip;
-   u16 yskip;
 
const struct mt9p031_pll_divs *pll;
 
@@ -785,8 +783,6 @@ static int mt9p031_open(struct v4l2_subdev *subdev, struct 
v4l2_subdev_fh *fh)
format-field = V4L2_FIELD_NONE;
format-colorspace = V4L2_COLORSPACE_SRGB;
 
-   mt9p031-xskip = 1;
-   mt9p031-yskip = 1;
return mt9p031_set_power(subdev, 1);
 }
 
-- 
Regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 05/15] mm: compaction: export some of the functions

2012-01-30 Thread Michal Nazarewicz

On Thu, Jan 26, 2012 at 10:00:47AM +0100, Marek Szyprowski wrote:

From: Michal Nazarewicz min...@mina86.com
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -16,30 +16,11 @@
 #include linux/sysfs.h
 #include internal.h

+#if defined CONFIG_COMPACTION || defined CONFIG_CMA
+


On Mon, 30 Jan 2012 12:57:26 +0100, Mel Gorman m...@csn.ul.ie wrote:

This is pedantic but you reference CONFIG_CMA before the patch that
declares it. The only time this really matters is when it breaks
bisection but I do not think that is the case here.


I think I'll choose to be lazy on this one. ;) I actually tried to move
some commits around to resolve this future-reference, but this resulted
in quite a few conflicts during rebase and after several minutes I decided
that it's not worth the effort.


Whether you fix this or not by moving the CONFIG_CMA check to the same
patch that declares it in Kconfig

Acked-by: Mel Gorman m...@csn.ul.ie


--
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz(o o)
ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo--
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 08/15] mm: mmzone: MIGRATE_CMA migration type added

2012-01-30 Thread Mel Gorman
On Thu, Jan 26, 2012 at 10:00:50AM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 
 The MIGRATE_CMA migration type has two main characteristics:
 (i) only movable pages can be allocated from MIGRATE_CMA
 pageblocks and (ii) page allocator will never change migration
 type of MIGRATE_CMA pageblocks.
 
 This guarantees (to some degree) that page in a MIGRATE_CMA page
 block can always be migrated somewhere else (unless there's no
 memory left in the system).
 
 It is designed to be used for allocating big chunks (eg. 10MiB)
 of physically contiguous memory.  Once driver requests
 contiguous memory, pages from MIGRATE_CMA pageblocks may be
 migrated away to create a contiguous block.
 
 To minimise number of migrations, MIGRATE_CMA migration type
 is the last type tried when page allocator falls back to other
 migration types then requested.
 
 Signed-off-by: Michal Nazarewicz min...@mina86.com
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
 ---
  include/linux/mmzone.h |   43 +
  include/linux/page-isolation.h |3 ++
  mm/Kconfig |2 +-
  mm/compaction.c|   11 +--
  mm/page_alloc.c|   68 
 +---
  mm/vmstat.c|3 ++
  6 files changed, 107 insertions(+), 23 deletions(-)
 
 diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
 index 650ba2f..fcd4a14 100644
 --- a/include/linux/mmzone.h
 +++ b/include/linux/mmzone.h
 @@ -35,13 +35,37 @@
   */
  #define PAGE_ALLOC_COSTLY_ORDER 3
  
 -#define MIGRATE_UNMOVABLE 0
 -#define MIGRATE_RECLAIMABLE   1
 -#define MIGRATE_MOVABLE   2
 -#define MIGRATE_PCPTYPES  3 /* the number of types on the pcp lists */
 -#define MIGRATE_RESERVE   3
 -#define MIGRATE_ISOLATE   4 /* can't allocate from here */
 -#define MIGRATE_TYPES 5
 +enum {
 + MIGRATE_UNMOVABLE,
 + MIGRATE_RECLAIMABLE,
 + MIGRATE_MOVABLE,
 + MIGRATE_PCPTYPES,   /* the number of types on the pcp lists */
 + MIGRATE_RESERVE = MIGRATE_PCPTYPES,
 +#ifdef CONFIG_CMA
 + /*
 +  * MIGRATE_CMA migration type is designed to mimic the way
 +  * ZONE_MOVABLE works.  Only movable pages can be allocated
 +  * from MIGRATE_CMA pageblocks and page allocator never
 +  * implicitly change migration type of MIGRATE_CMA pageblock.
 +  *
 +  * The way to use it is to change migratetype of a range of
 +  * pageblocks to MIGRATE_CMA which can be done by
 +  * __free_pageblock_cma() function.  What is important though
 +  * is that a range of pageblocks must be aligned to
 +  * MAX_ORDER_NR_PAGES should biggest page be bigger then
 +  * a single pageblock.
 +  */
 + MIGRATE_CMA,
 +#endif
 + MIGRATE_ISOLATE,/* can't allocate from here */
 + MIGRATE_TYPES
 +};
 +
 +#ifdef CONFIG_CMA
 +#  define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
 +#else
 +#  define is_migrate_cma(migratetype) false
 +#endif
  
  #define for_each_migratetype_order(order, type) \
   for (order = 0; order  MAX_ORDER; order++) \
 @@ -54,6 +78,11 @@ static inline int get_pageblock_migratetype(struct page 
 *page)
   return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end);
  }
  
 +static inline bool is_pageblock_cma(struct page *page)
 +{
 + return is_migrate_cma(get_pageblock_migratetype(page));
 +}
 +
  struct free_area {
   struct list_headfree_list[MIGRATE_TYPES];
   unsigned long   nr_free;
 diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
 index 430cf61..454dd29 100644
 --- a/include/linux/page-isolation.h
 +++ b/include/linux/page-isolation.h
 @@ -45,6 +45,9 @@ extern void unset_migratetype_isolate(struct page *page);
  extern int alloc_contig_range(unsigned long start, unsigned long end);
  extern void free_contig_range(unsigned long pfn, unsigned nr_pages);
  
 +/* CMA stuff */
 +extern void init_cma_reserved_pageblock(struct page *page);
 +
  #endif
  
  #endif
 diff --git a/mm/Kconfig b/mm/Kconfig
 index e338407..3922002 100644
 --- a/mm/Kconfig
 +++ b/mm/Kconfig
 @@ -198,7 +198,7 @@ config COMPACTION
  config MIGRATION
   bool Page migration
   def_bool y
 - depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION
 + depends on NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION || CMA
   help
 Allows the migration of the physical location of pages of processes
 while the virtual addresses are not changed. This is useful in
 diff --git a/mm/compaction.c b/mm/compaction.c
 index 3e21d28..a075b43 100644
 --- a/mm/compaction.c
 +++ b/mm/compaction.c
 @@ -35,6 +35,11 @@ static unsigned long release_freepages(struct list_head 
 *freelist)
   return count;
  }
  
 +static inline bool migrate_async_suitable(int migratetype)
 +{
 + return 

Re: [PATCH 10/15] mm: extract reclaim code from __alloc_pages_direct_reclaim()

2012-01-30 Thread Mel Gorman
On Thu, Jan 26, 2012 at 10:00:52AM +0100, Marek Szyprowski wrote:
 This patch extracts common reclaim code from __alloc_pages_direct_reclaim()
 function to separate function: __perform_reclaim() which can be later used
 by alloc_contig_range().
 
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
 CC: Michal Nazarewicz min...@mina86.com
 ---
  mm/page_alloc.c |   30 +-
  1 files changed, 21 insertions(+), 9 deletions(-)
 
 diff --git a/mm/page_alloc.c b/mm/page_alloc.c
 index 4e60c0b..e35d06b 100644
 --- a/mm/page_alloc.c
 +++ b/mm/page_alloc.c
 @@ -2094,16 +2094,13 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned 
 int order,
  }
  #endif /* CONFIG_COMPACTION */
  
 -/* The really slow allocator path where we enter direct reclaim */
 -static inline struct page *
 -__alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order,
 - struct zonelist *zonelist, enum zone_type high_zoneidx,
 - nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone,
 - int migratetype, unsigned long *did_some_progress)
 +/* Perform direct synchronous page reclaim */
 +static inline int
 +__perform_reclaim(gfp_t gfp_mask, unsigned int order, struct zonelist 
 *zonelist,
 +   nodemask_t *nodemask)

This function is too large to be inlined. Make it a static int. Once
that is fixed add a

Acked-by: Mel Gorman m...@csn.ul.ie

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/15] mm: compaction: introduce isolate_migratepages_range().

2012-01-30 Thread Michal Nazarewicz

On Thu, Jan 26, 2012 at 10:00:45AM +0100, Marek Szyprowski wrote:

From: Michal Nazarewicz min...@mina86.com
@@ -313,7 +316,7 @@ static isolate_migrate_t isolate_migratepages(struct zone 
*zone,
} else if (!locked)
spin_lock_irq(zone-lru_lock);

-   if (!pfn_valid_within(low_pfn))
+   if (!pfn_valid(low_pfn))
continue;
nr_scanned++;



On Mon, 30 Jan 2012 12:24:28 +0100, Mel Gorman m...@csn.ul.ie wrote:

This chunk looks unrelated to the rest of the patch.

I think what you are doing is patching around a bug that CMA exposed
which is very similar to the bug report at
http://www.spinics.net/lists/linux-mm/msg29260.html . Is this true?

If so, I posted a fix that only calls pfn_valid() when necessary. Can
you check if that works for you and if so, drop this hunk please? If
the patch does not work for you, then this hunk still needs to be
in a separate patch and handled separately as it would also be a fix
for -stable.


I'll actually never encountered this bug myself and CMA is unlikely to
expose it, since it always operates on continuous memory regions with
no holes.

I've made this change because looking at the code it seemed like this
may cause problems in some cases.  The crash that you linked to looks
like the kind of problem I was thinking about.

I'll drop this hunk and let you resolve this independently of CMA.

--
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz(o o)
ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo--
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH][media] s5p-g2d: Add HFLIP and VFLIP support

2012-01-30 Thread Sylwester Nawrocki
On 01/30/2012 01:11 PM, Laurent Pinchart wrote:
  static int g2d_open(struct file *file)
 @@ -564,6 +591,8 @@ static void device_run(void *prv)
  g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));

  g2d_set_rop4(dev, ctx-rop);
 +g2d_set_flip(dev, ctx-hflip | ctx-vflip);
 +
 
 Is this called for every frame, or once at stream start only ? In the later 
 case, this means that hflip and vflip won't be changeable during streaming. 
 Is 
 that on purpose ?

The device_run() callback is called per each frame, i.e. per each single
buffer pair. Hence it should be possible to reconfigure flipping when
streaming is on.

Thanks,
-- 
Sylwester Nawrocki
Samsung Poland RD Center
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 11/15] mm: trigger page reclaim in alloc_contig_range() to stabilize watermarks

2012-01-30 Thread Mel Gorman
On Thu, Jan 26, 2012 at 10:00:53AM +0100, Marek Szyprowski wrote:
 alloc_contig_range() performs memory allocation so it also should keep
 track on keeping the correct level of memory watermarks. This commit adds
 a call to *_slowpath style reclaim to grab enough pages to make sure that
 the final collection of contiguous pages from freelists will not starve
 the system.
 
 Signed-off-by: Marek Szyprowski m.szyprow...@samsung.com
 Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
 CC: Michal Nazarewicz min...@mina86.com
 ---
  mm/page_alloc.c |   36 
  1 files changed, 36 insertions(+), 0 deletions(-)
 
 diff --git a/mm/page_alloc.c b/mm/page_alloc.c
 index e35d06b..05eaa82 100644
 --- a/mm/page_alloc.c
 +++ b/mm/page_alloc.c
 @@ -5613,6 +5613,34 @@ static int __alloc_contig_migrate_range(unsigned long 
 start, unsigned long end)
   return ret;
  }
  
 +/*
 + * Trigger memory pressure bump to reclaim some pages in order to be able to
 + * allocate 'count' pages in single page units. Does similar work as
 + *__alloc_pages_slowpath() function.
 + */
 +static int __reclaim_pages(struct zone *zone, gfp_t gfp_mask, int count)
 +{
 + enum zone_type high_zoneidx = gfp_zone(gfp_mask);
 + struct zonelist *zonelist = node_zonelist(0, gfp_mask);
 + int did_some_progress = 0;
 + int order = 1;
 + unsigned long watermark;
 +
 + /* Obey watermarks as if the page was being allocated */
 + watermark = low_wmark_pages(zone) + count;
 + while (!zone_watermark_ok(zone, 0, watermark, 0, 0)) {
 + wake_all_kswapd(order, zonelist, high_zoneidx, zone_idx(zone));
 +
 + did_some_progress = __perform_reclaim(gfp_mask, order, zonelist,
 +   NULL);
 + if (!did_some_progress) {
 + /* Exhausted what can be done so it's blamo time */
 + out_of_memory(zonelist, gfp_mask, order, NULL);
 + }

There are three problems here

1. CMA can trigger the OOM killer.

That seems like overkill to me but as I do not know the consequences
of CMA failing, it's your call.

2. You cannot guarantee that try_to_free_pages will free pages from the
   zone you care about or that kswapd will do anything

You check the watermarks and take into account the size of the pending
CMA allocation. kswapd in vmscan.c on the other hand will simply check
the watermarks and probably go back to sleep. You should be aware of
this in case you ever get bugs that CMA takes too long and that it
appears to be stuck in this loop with kswapd staying asleep.

3. You reclaim from zones other than your target zone

try_to_free_pages is not necessarily going to free pages in the
zone you are checking for. It'll work on ARM in many cases because
there will be only one zone but on other arches, this logic will
be problematic and will potentially livelock. You need to pass in
a zonelist that only contains the zone that CMA cares about. If it
cannot reclaim, did_some_progress == 0 and it'll exit. Otherwise
there is a possibility that this will loop forever reclaiming pages
from the wrong zones.

I won't ack this particular patch but I am not going to insist that
you fix these prior to merging either. If you leave problem 3 as it
is, I would really like to see a comment explaning the problem for
future users of CMA on other arches (if they exist).

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 08/15] mm: mmzone: MIGRATE_CMA migration type added

2012-01-30 Thread Michal Nazarewicz

On Thu, Jan 26, 2012 at 10:00:50AM +0100, Marek Szyprowski wrote:

From: Michal Nazarewicz min...@mina86.com
@@ -875,10 +895,15 @@ struct page *__rmqueue_smallest(struct zone *zone, 
unsigned int order,
  * This array describes the order lists are fallen back to when
  * the free lists for the desirable migrate type are depleted
  */
-static int fallbacks[MIGRATE_TYPES][3] = {
+static int fallbacks[MIGRATE_TYPES][4] = {
[MIGRATE_UNMOVABLE]   = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE,   
MIGRATE_RESERVE },
[MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE,   MIGRATE_MOVABLE,   
MIGRATE_RESERVE },
+#ifdef CONFIG_CMA
+   [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, 
MIGRATE_CMA, MIGRATE_RESERVE },


On Mon, 30 Jan 2012 13:35:42 +0100, Mel Gorman m...@csn.ul.ie wrote:

This is a curious choice. MIGRATE_CMA is allowed to contain movable
pages. By using MIGRATE_RECLAIMABLE and MIGRATE_UNMOVABLE for movable
pages instead of MIGRATE_CMA, you increase the changes that unmovable
pages will need to use MIGRATE_MOVABLE in the future which impacts
fragmentation avoidance. I would recommend that you change this to

{ MIGRATE_CMA, MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE }


At the beginning the idea was to try hard not to get pages from MIGRATE_CMA
allocated at all, thus it was put at the end of the fallbacks list, but on
a busy system this probably won't help anyway, so I'll change it per your
suggestion.


@@ -1017,11 +1049,14 @@ __rmqueue_fallback(struct zone *zone, int order, int 
start_migratetype)
rmv_page_order(page);

/* Take ownership for orders = pageblock_order */
-   if (current_order = pageblock_order)
+   if (current_order = pageblock_order 
+   !is_pageblock_cma(page))
change_pageblock_range(page, current_order,
start_migratetype);

-   expand(zone, page, order, current_order, area, 
migratetype);
+   expand(zone, page, order, current_order, area,
+  is_migrate_cma(start_migratetype)
+? start_migratetype : migratetype);



What is this check meant to be doing?

start_migratetype is determined by allocflags_to_migratetype() and
that never will be MIGRATE_CMA so is_migrate_cma(start_migratetype)
should always be false.


Right, thanks!  This should be the other way around, ie.:

+   expand(zone, page, order, current_order, area,
+  is_migrate_cma(migratetype)
+? migratetype : start_migratetype);

I'll fix this and the calls to is_pageblock_cma().

--
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz(o o)
ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo--
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv19 00/15] Contiguous Memory Allocator

2012-01-30 Thread Mel Gorman
On Fri, Jan 27, 2012 at 04:26:24PM -0800, Andrew Morton wrote:
 On Thu, 26 Jan 2012 15:31:40 +
 Arnd Bergmann a...@arndb.de wrote:
 
  On Thursday 26 January 2012, Marek Szyprowski wrote:
   Welcome everyone!
   
   Yes, that's true. This is yet another release of the Contiguous Memory
   Allocator patches. This version mainly includes code cleanups requested
   by Mel Gorman and a few minor bug fixes.
  
  Hi Marek,
  
  Thanks for keeping up this work! I really hope it works out for the
  next merge window.
 
 Someone please tell me when it's time to start paying attention
 again ;)
 
 These patches don't seem to have as many acked-bys and reviewed-bys as
 I'd expect. 

I reviewed the core MM changes and I've acked most of them so the
next release should have a few acks where you expect them. I did not
add a reviewed-by because I did not build and test the thing.

For me, Patch 2 is the only one that must be fixed prior to merging
as it can interfere with pages on a remote per-cpu list which is
dangerous. I know your suggestion will be to delete the per-cpu lists
and be done with it but I am a bit away from doing that just yet.

Patch 8 could do with a bit more care too but it is not a
potential hand grenade like patch 2 and could be fixed as part of
a follow-up. Even if you don't see an ack from me there, it should not
be treated as a show stopper.

I highlighted some issues on how CMA interacts with reclaim but I
think this is a problem specific to CMA and should not prevent it being
merged. I just wanted to be sure that the CMA people were aware of the
potential issues so they will recognise the class of bug if it occurs.

 Given the scope and duration of this, it would be useful
 to gather these up.  But please ensure they are real ones - people
 sometimes like to ack things without showing much sign of having
 actually read them.
 

FWIW, the acks I put on the core MM changes are real acks :)

 The patches do seem to have been going round in ever-decreasing circles
 lately and I think we have decided to merge them (yes?) so we may as well
 get on and do that and sort out remaining issues in-tree.
 

I'm a lot happier with the core MM patches than I was when I reviewed
this first around last September or October.

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 03/15] mm: compaction: introduce isolate_migratepages_range().

2012-01-30 Thread Mel Gorman
On Mon, Jan 30, 2012 at 01:42:50PM +0100, Michal Nazarewicz wrote:
 On Thu, Jan 26, 2012 at 10:00:45AM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 @@ -313,7 +316,7 @@ static isolate_migrate_t isolate_migratepages(struct 
 zone *zone,
 } else if (!locked)
 spin_lock_irq(zone-lru_lock);
 
 -   if (!pfn_valid_within(low_pfn))
 +   if (!pfn_valid(low_pfn))
 continue;
 nr_scanned++;
 
 
 On Mon, 30 Jan 2012 12:24:28 +0100, Mel Gorman m...@csn.ul.ie wrote:
 This chunk looks unrelated to the rest of the patch.
 
 I think what you are doing is patching around a bug that CMA exposed
 which is very similar to the bug report at
 http://www.spinics.net/lists/linux-mm/msg29260.html . Is this true?
 
 If so, I posted a fix that only calls pfn_valid() when necessary. Can
 you check if that works for you and if so, drop this hunk please? If
 the patch does not work for you, then this hunk still needs to be
 in a separate patch and handled separately as it would also be a fix
 for -stable.
 
 I'll actually never encountered this bug myself and CMA is unlikely to
 expose it, since it always operates on continuous memory regions with
 no holes.
 
 I've made this change because looking at the code it seemed like this
 may cause problems in some cases.  The crash that you linked to looks
 like the kind of problem I was thinking about.
 
 I'll drop this hunk and let you resolve this independently of CMA.
 

Ok, thanks.

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH][media] s5p-g2d: Add HFLIP and VFLIP support

2012-01-30 Thread Kamil Debski
Hi Laurent and Sachin,

Thanks for the patch and for your comments.

 From: Laurent Pinchart [mailto:laurent.pinch...@ideasonboard.com]
 Sent: 30 January 2012 13:12
 
 Hi Sashin,
 
 Thanks for the patch.
 
 On Monday 30 January 2012 10:58:43 Sachin Kamat wrote:
  This patch adds support for flipping the image horizontally and vertically.
 
  Signed-off-by: Sachin Kamat sachin.ka...@linaro.org
  ---
   drivers/media/video/s5p-g2d/g2d-hw.c |5 +++
   drivers/media/video/s5p-g2d/g2d.c|   47 +
 --
   drivers/media/video/s5p-g2d/g2d.h|3 ++
   3 files changed, 46 insertions(+), 9 deletions(-)
 
 [snip]
 
  diff --git a/drivers/media/video/s5p-g2d/g2d.c
  b/drivers/media/video/s5p-g2d/g2d.c index febaa67..dea9701 100644
  --- a/drivers/media/video/s5p-g2d/g2d.c
  +++ b/drivers/media/video/s5p-g2d/g2d.c
  @@ -178,6 +178,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
   {
  struct g2d_ctx *ctx = container_of(ctrl-handler, struct g2d_ctx,
  ctrl_handler);
  +
  switch (ctrl-id) {
  case V4L2_CID_COLORFX:
  if (ctrl-val == V4L2_COLORFX_NEGATIVE)
  @@ -185,6 +186,21 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
  else
  ctx-rop = ROP4_COPY;
  break;
  +
  +   case V4L2_CID_HFLIP:
  +   if (ctrl-val == 1)
  +   ctx-hflip = 1;
  +   else
  +   ctx-hflip = 0;
  +   break;
  +
  +   case V4L2_CID_VFLIP:
  +   if (ctrl-val == 1)
  +   ctx-vflip = (1  1);
  +   else
  +   ctx-vflip = 0;
  +   break;

I think that 

case V4L2_CID_HFLIP:
ctx-hflip = ctrl-val;
break;

case V4L2_CID_VFLIP:
ctx-vflip = (ctrl-val  1);
break;

will be sufficient, as flip controls have min=0 and max=1 which makes
them safe to use.

  +
  default:
  v4l2_err(ctx-dev-v4l2_dev, unknown control\n);
  return -EINVAL;
  @@ -200,11 +216,9 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
   {
  struct g2d_dev *dev = ctx-dev;
 
  -   v4l2_ctrl_handler_init(ctx-ctrl_handler, 1);
  -   if (ctx-ctrl_handler.error) {
  -   v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
  -   return ctx-ctrl_handler.error;
  -   }
  +   v4l2_ctrl_handler_init(ctx-ctrl_handler, 3);
  +   if (ctx-ctrl_handler.error)
  +   goto error;
 
 There's not need to verify ctx-ctrl_handler.error after every call to
 v4l2_ctrl_handler_init() or v4l2_ctrl_new_*(). You can verify it once only
 after initialization all controls.

I agree.
 
 
  v4l2_ctrl_new_std_menu(
  ctx-ctrl_handler,
  @@ -214,12 +228,25 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
  ~((1  V4L2_COLORFX_NONE) | (1  V4L2_COLORFX_NEGATIVE)),
  V4L2_COLORFX_NONE);
 
  -   if (ctx-ctrl_handler.error) {
  -   v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
  -   return ctx-ctrl_handler.error;
  -   }
  +   if (ctx-ctrl_handler.error)
  +   goto error;
  +
  +   v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops,
  +   V4L2_CID_HFLIP, 0, 1, 1, 0);
  +   if (ctx-ctrl_handler.error)
  +   goto error;
  +
  +   v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops,
  +   V4L2_CID_VFLIP, 0, 1, 1, 0);
 
 As a single register controls hflip and vflip, you should group the two
 controls in a cluster.

I think it doesn't matter in this use case. As register are not written
in the g2d_s_ctrl. Because the driver uses multiple context it modifies
the appropriate values in its context structure and registers are written
when the transaction is run.

Also there is no logical connection between horizontal and vertical flip.
I think this is the case when using clusters. Here one is independent from
another.

 
  +   if (ctx-ctrl_handler.error)
  +   goto error;
 
  return 0;
  +
  +error:
  +   v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
  +   return ctx-ctrl_handler.error;
  +
   }
 
   static int g2d_open(struct file *file)
  @@ -564,6 +591,8 @@ static void device_run(void *prv)
  g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));
 
  g2d_set_rop4(dev, ctx-rop);
  +   g2d_set_flip(dev, ctx-hflip | ctx-vflip);
  +
 
 Is this called for every frame, or once at stream start only ? In the later
 case, this means that hflip and vflip won't be changeable during streaming.
 Is
 that on purpose ?
 
  if (ctx-in.c_width != ctx-out.c_width ||
  ctx-in.c_height != ctx-out.c_height)
  cmd |= g2d_cmd_stretch(1);
  diff --git a/drivers/media/video/s5p-g2d/g2d.h
  b/drivers/media/video/s5p-g2d/g2d.h index 5eae901..b3be3c8 100644
  --- a/drivers/media/video/s5p-g2d/g2d.h
  +++ b/drivers/media/video/s5p-g2d/g2d.h
  @@ -59,6 +59,8 @@ struct g2d_ctx {
  struct 

Re: [PATCH v2 1/1] omap3isp: Prevent crash at module unload

2012-01-30 Thread Laurent Pinchart
Hi Sakari,

Thanks for the patch.

On Friday 27 January 2012 11:18:51 Sakari Ailus wrote:
 iommu_domain_free() was called in isp_remove() before omap3isp_put().
 omap3isp_put() must not save the context if the IOMMU no longer is there.
 Fix this.
 
 Signed-off-by: Sakari Ailus sakari.ai...@iki.fi

Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com

Applied to my tree.

 ---
 Compared to v1, neither the ISP context is saved.
 
  drivers/media/video/omap3isp/isp.c |4 +++-
  1 files changed, 3 insertions(+), 1 deletions(-)
 
 diff --git a/drivers/media/video/omap3isp/isp.c
 b/drivers/media/video/omap3isp/isp.c index 12d5f92..d4e0905 100644
 --- a/drivers/media/video/omap3isp/isp.c
 +++ b/drivers/media/video/omap3isp/isp.c
 @@ -1495,7 +1495,8 @@ void omap3isp_put(struct isp_device *isp)
   BUG_ON(isp-ref_count == 0);
   if (--isp-ref_count == 0) {
   isp_disable_interrupts(isp);
 - isp_save_ctx(isp);
 + if (isp-domain)
 + isp_save_ctx(isp);
   if (isp-needs_reset) {
   isp_reset(isp);
   isp-needs_reset = false;
 @@ -1981,6 +1982,7 @@ static int isp_remove(struct platform_device *pdev)
   omap3isp_get(isp);
   iommu_detach_device(isp-domain, pdev-dev);
   iommu_domain_free(isp-domain);
 + isp-domain = NULL;
   omap3isp_put(isp);
 
   free_irq(isp-irq_num, isp);

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Linaro-mm-sig] [PATCH 05/10] v4l: add buffer exporting via dmabuf

2012-01-30 Thread Laurent Pinchart
Hi Subash,

On Friday 27 January 2012 14:40:34 Subash Patel wrote:
 On 01/24/2012 05:36 PM, Tomasz Stanislawski wrote:
  On 01/24/2012 12:07 PM, Subash Patel wrote:
  
  Instead of adding another IOCTL to query the file-descriptor in
  user-space, why dont we extend the existing ones in v4l2/vb2?
  
  When the memory type set is V4L2_MEMORY_DMABUF, call to VIDIOC_REQBUFS
  /VIDIOC_QUERYBUF from driver can take/return the fd. We will need to add
  another attribute to struct v4l2_requestbuffers for this.
  
  struct v4l2_requestbuffers {
  ...
  __u32 buf_fd;
  };
  
  The application requesting buffer would set it to -1, and will receive
  the fd's when it calls the vb2_querybuf. In the same way, application
  which is trying to attach to already allocated buffer will set this to
  valid fd when it calls vidioc_reqbuf, and in vb2_reqbuf depending on the
  memory type, this can be checked and used to attach with the dma_buf for
  the respective buffer.
  
  Ofcourse, this requires changes in vb2_reqbufs and vb2_querybuf similar
  to what you did in vb2_expbufs.
  
  Will there be any issues in such an approach?
  
  I like your idea but IMO there are some issues which this approach.
  
  The VIDIOC_REQBUF is used to create a collection of buffers (i.e. 5
  frames). Every frame is a separate buffer therefore it should have
  separate dmabuf file descriptor. This way you should add buffer index to
  v4l2_request_buffers. Of course but one could reuse count field but
  there is still problem with multiplane buffers (see below).
 
 I agree.
 
  Please note that dmabuf file could be create only for buffers with MMAP
  memory type. The DMABUF memory type for VIDIOC_REQBUFS indicate that a
  buffer is imported from DMABUF file descriptor. Similar way like content
  of USERPTR buffers is taken from user pointer.
  
  Therefore only MMAP buffers can be exported as DMABUF file descriptor.
 
 I think for time being, mmap is best way we can share buffers between
 IP's, like MM and GPU.
 
  If VIDIOC_REQUBUF is used for buffer exporting, how to request a bunch
  of buffers that are dedicated to obtain memory from DMABUF file
  descriptors?
 
 I am not sure if I understand this question. But what I meant is,
 VIDIOC_REQBUF with memory type V4L2_MEMORY_DMABUF will ask the driver to
 allocate MMAP type memory and create the dmabuf handles for those. In
 the next call to VIDIOC_QUERYBUF (which you do on each of the buffers
 infact), driver will return the dmabuf file descriptors to user space.
 This can be used by the user space to mmap(when dmabuf supports) or pass
 it onto another process to share the buffers.

That would be nice, but VIDIOC_REQBUFS(DMABUF) is already used to allocate 
buffers that will be imported using dma-buf. We need to handle both the 
importer use case and the exporter use case, we can't handle both with just 
VIDIOC_REQBUFS(DMABUF).

 The recipient user process can now pass these dmabuf file descriptors in
 VIDIOC_REQBUF itself to its driver (say another v4l2 based). In the
 driver, when the user space calls VIDIOC_QUERYBUF for those buffers, we
 can call dmabuf's attach() to actually link to the buffer. Does it make
 sense?
 
  The second problem is VIDIOC_QUERYBUF. According to V4L2 spec, the
  memory type field is read only. The driver returns the same memory type
  as it was used in VIDIOC_REQBUFS. Therefore VIDIOC_QUERYBUF can only be
  used for MMAP buffers to obtain memoffset. For DMABUF it may return
  fd=-1 or most recently used file descriptor. As I remember, it was not
  defined yet.
 
 I was thinking why not the memory type move out from enum to an int? In
 that case, we can send ORed types, like
 V4L2_MEMORY_MMAP|V4L2_MEMORY_DMABUF etc. Does it help?

That would break our API, so we can't do that (although we could still OR enum 
types).

  The third reason are multiplane buffers. This API was introduced if V4L2
  buffer (IMO it should be called a frame) consist of multiple memory
  buffers. Every plane can be mmapped separately. Therefore it should be
  possible to export every plane as separate DMABUF descriptor.
 
 Do we require to export every plane as separate dmabuf? I think dmabuf
 should cover entire multi-plane buffer instead of individual planes.

It depends on the drivers you use. Some drivers require planes to be 
contiguous in memory, in which case a single dma-buf will likely be used. 
Other drivers can allocate the planes in separate memory regions. Several dma-
buf objects then make sense.

 How to calculate individual plane offsets should be the property of the
 driver depending on its need for it.

  After some research it was found that memoffset is good identifier of a
  plane in a buffers. This id is also available in the userspace without
  any API extensions.
  
  VIDIOC_EXPBUF was used to export a buffer by id, similar way as mmap
  uses this identifier to map a buffer to userspace. It seams to be the
  simplest solution.
 
 Ok. Then dont you think when dmabuf 

Re: [PATCH] dma-buf: add dma_data_direction to unmap dma_buf_op

2012-01-30 Thread Laurent Pinchart
Hi Sumit,

On Friday 27 January 2012 10:43:28 Sumit Semwal wrote:
 Some exporters may use DMA map/unmap APIs in dma-buf ops, which require
 enum dma_data_direction for both map and unmap operations.
 
 Thus, the unmap dma_buf_op also needs to have enum dma_data_direction as
 a parameter.
 
 Reported-by: Tomasz Stanislawski t.stanisl...@samsung.com
 Signed-off-by: Sumit Semwal sumit.sem...@ti.com
 ---
  drivers/base/dma-buf.c  |7 +--
  include/linux/dma-buf.h |8 +---
  2 files changed, 10 insertions(+), 5 deletions(-)
 
 diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
 index 8afe2dd..c9a945f 100644
 --- a/drivers/base/dma-buf.c
 +++ b/drivers/base/dma-buf.c
 @@ -271,16 +271,19 @@ EXPORT_SYMBOL_GPL(dma_buf_map_attachment);
   * dma_buf_ops.
   * @attach:  [in]attachment to unmap buffer from
   * @sg_table:[in]scatterlist info of the buffer to unmap
 + * @direction:  [in]direction of DMA transfer
   *
   */
  void dma_buf_unmap_attachment(struct dma_buf_attachment *attach,
 - struct sg_table *sg_table)
 + struct sg_table *sg_table,
 + enum dma_data_direction direction)
  {
   if (WARN_ON(!attach || !attach-dmabuf || !sg_table))
   return;
 
   mutex_lock(attach-dmabuf-lock);
 - attach-dmabuf-ops-unmap_dma_buf(attach, sg_table);
 + attach-dmabuf-ops-unmap_dma_buf(attach, sg_table,
 + direction);
   mutex_unlock(attach-dmabuf-lock);
 
  }
 diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
 index 86f6241..847b026 100644
 --- a/include/linux/dma-buf.h
 +++ b/include/linux/dma-buf.h
 @@ -63,7 +63,8 @@ struct dma_buf_ops {
   struct sg_table * (*map_dma_buf)(struct dma_buf_attachment *,
   enum dma_data_direction);
   void (*unmap_dma_buf)(struct dma_buf_attachment *,
 - struct sg_table *);
 + struct sg_table *,
 + enum dma_data_direction);
   /* TODO: Add try_map_dma_buf version, to return immed with -EBUSY
* if the call would block.
*/
 @@ -122,7 +123,8 @@ void dma_buf_put(struct dma_buf *dmabuf);
 
  struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *,
   enum dma_data_direction);
 -void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table
 *); +void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct
 sg_table *, + enum dma_data_direction);
  #else
 
  static inline struct dma_buf_attachment *dma_buf_attach(struct dma_buf
 *dmabuf, @@ -166,7 +168,7 @@ static inline struct sg_table
 *dma_buf_map_attachment( }
 
  static inline void dma_buf_unmap_attachment(struct dma_buf_attachment
 *attach, -struct sg_table *sg)
 + struct sg_table *sg, enum dma_data_direction write)

s/write/dir/ (or direction) ?

  {
   return;
  }

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFCv1 2/4] v4l:vb2: add support for shared buffer (dma_buf)

2012-01-30 Thread Laurent Pinchart
Hi Daniel,

On Sunday 29 January 2012 14:03:40 Daniel Vetter wrote:
 On Sun, Jan 29, 2012 at 01:03:39PM +0200, Sakari Ailus wrote:
  Daniel Vetter wrote:
   On Thu, Jan 26, 2012 at 01:28:16AM +0200, Sakari Ailus wrote:
   Why you should not hang onto mappings forever? This is currently
   done by virtually all V4L2 drivers where such mappings are relevant.
   Not doing so would really kill the performance i.e. it's infeasible.
   Same goes to (m)any other multimedia devices dealing with buffers
   containing streaming video data.
   
   Because I want dynamic memory managemt simple because everything else
   does not make sense. I know that in v4l things don't work that way,
   but in drm they _do_. And if you share tons of buffers with drm
   drivers and don't follow the rules, the OOM killer will come around
   and shot at your apps. Because at least in i915 we do slurp in as much
   memory as we can until the oom killer starts growling, at which point
   we kick out stuff.
   
   I know that current dma_buf isn't there and for many use-cases
   discussed here we can get away without that complexity. So you
   actually can just map your dma_buf and never ever let go of that
   mapping again in many cases.
   
   The only reason I'm such a stuborn bastard about all this is that drm/*
   will do dynamic bo management even with dma_buf sooner or later and you
   should better know that and why and the implications if you choose to
   ignore it.
   
   And obviously, the generic dma_buf interface needs to be able to
   support it.
  
  I do not think we should completely ignore this issue, but I think we
  might want to at least postpone the implementation for non-DRM
  subsystems to an unknown future date. The reason is simply that it's
  currently unfeasible for various reasons.
  
  Sharing large buffers with GPUs (where you might want to manage them
  independently of the user space) is uncommon; typically you're sharing
  buffers for viewfinder that tend to be around few megabytes in size and
  there may be typically up to five of them. Also, we're still far from
  getting things working in the first place. Let's not complicate them
  more than we have to.
  
  The very reason why we're pre-allocating these large buffers in
  applications is that you can readily use them when you need them.
  Consider camera, for example: a common use case is to have a set of 24
  MB buffers (for 12 Mp images) prepared while the viewfinder is running.
  These buffers must be immediately usable when the user presses the
  shutter button.
  
  We don't want to continuously map and unmap buffers in viewfinder
  either: that adds a significan CPU load for no technical reason
  whatsoever. Typically viewfinder also involves running software
  algorithms that consume much of the available CPU time, so adding an
  unnecessary CPU hog to the picture doesn't sound that enticing.
  
  If the performance of memory management can be improved to such an
  extent it really takes much less than a millisecond or so to perform all
  the pinning-to-memory, IOMMU mapping and so on systems for 24 MB buffers
  on regular embedded systems I think I wouldn't have much against doing
  so. Currently I think we're talking about numbers that are at least
  100-fold.
  
  If you want to do this to buffers used only in DRM I'm fine with that.
 
 A few things:
 - I do understand that there are use cases where allocate, pin  forget
   works.

I don't like the forget part :-)

As a V4L2 developer, I'm not advocating for keeping mappings around forever, 
but to keep them for as long as possible. Without such a feature, dma-buf 
support in V4L2 will just be a proof-of-concept, with little use in real 
products.

 - I'm perfectly fine if you do this in your special embedded product. Or
   the entire v4l subsystem, I don't care much about that one, either.

I thought the point of these discussions was to start caring about each-
other's subsystems :-)

 But:
 - I'm fully convinced that all these special purpose single use-case
   scenarios will show up sooner or later on a more general purpose
   platform.
 - And as soon as your on a general purpose platform, you _want_ dynamic
   memory management.

I'm pretty sure we want dynamic memory management in special-purpose platforms 
as well.

 I mean the entire reason people are pushing CMA is that preallocating gobs
 of memory statically really isn't that great an idea ...
 
 So to summarize I understand your constraints - gpu drivers have worked like
 v4l a few years ago. The thing I'm trying to achieve with this constant
 yelling is just to raise awereness for these issues so that people aren't
 suprised when drm starts pulling tricks on dma_bufs.

Once again, our constraints is not that we need to keep mappings around 
forever, but that we want to keep them for as long as possible. I don't think 
DRM is an issue here, I'm perfectly fine with releasing the mapping when DRM 
(or any other subsystem) needs 

Re: [RFCv1 2/4] v4l:vb2: add support for shared buffer (dma_buf)

2012-01-30 Thread Laurent Pinchart
Hi Daniel,

On Tuesday 24 January 2012 14:03:22 Daniel Vetter wrote:
 On Mon, Jan 23, 2012 at 11:54:20AM +0100, Laurent Pinchart wrote:
  On Monday 23 January 2012 11:35:01 Daniel Vetter wrote:
   See my other mail, dma_buf v1 does not support cpu access.
  
  v1 is in the kernel now, let's start discussing v2 ;-)
 
 Ok, I'm in ;-)
 
 I've thought a bit about this, and I think a reasonable next step would be
 to enable cpu access from kernelspace. Userspace and mmap support is a hole
 different beast altogether and I think we should postpone that until we've
 got the kernel part hashed out.

Userspace access through mmap can already be handled by the subsystem that 
exports the buffer, so I'm fine with postponing implementing this inside dma-
buf.

 I'm thinking about adding 3 pairs of function to dma_buf (not to
 dma_buf_attachment).
 
 dma_buf_get_backing_storage/put_backing_storage
 This will be used before/after kernel cpu access to ensure that the
 backing storage is in memory. E.g. gem objects can be swapped out, so
 they need to be pinned before we can access them. For exporters with
 static allocations this would be a no-op.
 
 I think a start, length range would make sense, but the exporter is free
 to just swap in the entire object unconditionally. The range is specified
 in multiples of PAGE_SIZE - I don't think there's any usescase for a
 get/put_backing_storage which deals in smaller units.
 
 The get/put functions are allowed to block and grab all kinds of looks.
 get is allowed to fail with e.g. -ENOMEM.
 
 dma_buf_kmap/kunmap
 This maps _one_ page into the kernels address space and out of it. This
 function also flushes/invalidates any caches required. Importers are not
 allowed to map more than 2 pages at the same time in total (to allow
 copies). This is because at least for gem objects the backing storage can
 be in high-mem.
 
 Importers are allowed to sleep while holding such a kernel mapping.
 
 These functions are not allowed to fail (like kmap/kunmap).
 
 dma_buf_kmap_atomic/kunmap_atomic
 For performance we want to also allow atomic mappigns. Only difference is
 that importers are not allowed to sleep while holding an atomic mapping.
 
 These functions are again not allowed to fail.
 
 Comments, flames?

Before commenting (I don't plan on flaming :-)), I'd like to take a small step 
back. Could you describe the use case(s) you think of for kernel mappings ?

 If this sounds sensible I'll throw together a quick rfc over the next few
 days.
 
 Cheers, Daniel
 
 PS: Imo the next step after this would be adding userspace mmap support.
 This has the funky requirement that the exporter needs to be able to shot
 down any ptes before it moves around the buffer. I think solving that nice
 little problem is a good exercise to prepare us for solving similar get
 of this buffer, now issues with permanent device address space mappings
 ...

-- 
Regards,

Laurent Pinchart
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 08/15] mm: mmzone: MIGRATE_CMA migration type added

2012-01-30 Thread Mel Gorman
On Mon, Jan 30, 2012 at 02:06:50PM +0100, Michal Nazarewicz wrote:
 @@ -1017,11 +1049,14 @@ __rmqueue_fallback(struct zone *zone, int order, 
 int start_migratetype)
 rmv_page_order(page);
 
 /* Take ownership for orders = pageblock_order */
 -   if (current_order = pageblock_order)
 +   if (current_order = pageblock_order 
 +   !is_pageblock_cma(page))
 change_pageblock_range(page, current_order,
 start_migratetype);
 
 -   expand(zone, page, order, current_order, area, 
 migratetype);
 +   expand(zone, page, order, current_order, area,
 +  is_migrate_cma(start_migratetype)
 +? start_migratetype : migratetype);
 
 
 What is this check meant to be doing?
 
 start_migratetype is determined by allocflags_to_migratetype() and
 that never will be MIGRATE_CMA so is_migrate_cma(start_migratetype)
 should always be false.
 
 Right, thanks!  This should be the other way around, ie.:
 
 + expand(zone, page, order, current_order, area,
 +is_migrate_cma(migratetype)
 +  ? migratetype : start_migratetype);
 
 I'll fix this and the calls to is_pageblock_cma().
 

That makes a lot more sense. Thanks.

I have a vague recollection that there was a problem with finding
unmovable pages in MIGRATE_CMA regions. This might have been part of
the problem.

-- 
Mel Gorman
SUSE Labs
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/15] mm: page_alloc: update migrate type of pages on pcp when isolating

2012-01-30 Thread Michal Nazarewicz

On Mon, 30 Jan 2012 12:15:22 +0100, Mel Gorman m...@csn.ul.ie wrote:


On Thu, Jan 26, 2012 at 10:00:44AM +0100, Marek Szyprowski wrote:

From: Michal Nazarewicz min...@mina86.com
@@ -139,3 +139,27 @@ int test_pages_isolated(unsigned long start_pfn, unsigned 
long end_pfn)
spin_unlock_irqrestore(zone-lock, flags);
return ret ? 0 : -EBUSY;
 }
+
+/* must hold zone-lock */
+void update_pcp_isolate_block(unsigned long pfn)
+{
+   unsigned long end_pfn = pfn + pageblock_nr_pages;
+   struct page *page;
+
+   while (pfn  end_pfn) {
+   if (!pfn_valid_within(pfn)) {
+   ++pfn;
+   continue;
+   }
+


On Mon, 30 Jan 2012 12:15:22 +0100, Mel Gorman m...@csn.ul.ie wrote:

There is a potential problem here that you need to be aware of.
set_pageblock_migratetype() is called from start_isolate_page_range().
I do not think there is a guarantee that pfn + pageblock_nr_pages is
not in a different block of MAX_ORDER_NR_PAGES. If that is right then
your options are to add a check like this;

if ((pfn  (MAX_ORDER_NR_PAGES - 1)) == 0  !pfn_valid(pfn))
break;

or else ensure that end_pfn is always MAX_ORDER_NR_PAGES aligned and in
the same block as pfn and relying on the caller to have called
pfn_valid.


pfn = round_down(pfn, pageblock_nr_pages);
end_pfn = pfn + pageblock_nr_pages;

should do the trick as well, right?  move_freepages_block() seem to be
doing the same thing.


+   page = pfn_to_page(pfn);
+   if (PageBuddy(page)) {
+   pfn += 1  page_order(page);
+   } else if (page_count(page) == 0) {
+   set_page_private(page, MIGRATE_ISOLATE);
+   ++pfn;


This is dangerous for two reasons. If the page_count is 0, it could
be because the page is in the process of being freed and is not
necessarily on the per-cpu lists yet and you cannot be sure if the
contents of page-private are important. Second, there is nothing to
prevent another CPU allocating this page from its per-cpu list while
the private field is getting updated from here which might lead to
some interesting races.

I recognise that what you are trying to do is respond to Gilad's
request that you really check if an IPI here is necessary. I think what
you need to do is check if a page with a count of 0 is encountered
and if it is, then a draining of the per-cpu lists is necessary. To
address Gilad's concerns, be sure to only this this once per attempt at
CMA rather than for every page encountered with a count of 0 to avoid a
storm of IPIs.


It's actually more then that.

This is the same issue that I first fixed with a change to free_pcppages_bulk()
function[1].  At the time of positing, you said you'd like me to try and find
a different solution which would not involve paying the price of calling
get_pageblock_migratetype().  Later I also realised that this solution is
not enough.

[1] http://article.gmane.org/gmane.linux.kernel.mm/70314

My next attempt was to run drain PCP list while holding zone-lock[2], but that
quickly proven to be broken approach when Marek started testing it on an SMP
system.

[2] http://article.gmane.org/gmane.linux.kernel.mm/72016

This patch is yet another attempt of solving this old issue.  Even though it has
a potential race condition we came to conclusion that the actual chances of
causing any problems are slim.  Various stress tests did not, in fact, show
the race to be an issue.

The problem is that if a page is on a PCP list, and it's underlaying pageblocks'
migrate type is changed to MIGRATE_ISOLATE, the page (i) will still remain on 
PCP
list and thus someone can allocate it, and (ii) when removed from PCP list, the
page will be put on freelist of migrate type it had prior to change.

(i) is actually not such a big issue since the next thing that happens after
isolation is migration so all the pages will get freed.  (ii) is actual problem
and if [1] is not an acceptable solution I really don't have a good fix for 
that.

One things that comes to mind is calling drain_all_pages() prior to acquiring
zone-lock in set_migratetype_isolate().  This is however prone to races since
after the drain and before the zone-lock is acquired, pages might get moved
back to PCP list.

Draining PCP list after acquiring zone-lock is not possible because
smp_call_function_many() cannot be called with interrupts disabled, and changing
spin_lock_irqsave() to spin_lock() followed by local_irq_save() causes a dead
lock (that's what [2] attempted to do).

Any suggestions are welcome!


+   } else {
+   ++pfn;
+   }
+   }
+}


--
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz(o o)
ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo--
--
To unsubscribe 

Re: [PATCHv19 00/15] Contiguous Memory Allocator

2012-01-30 Thread Michal Nazarewicz

On Mon, 30 Jan 2012 14:25:12 +0100, Mel Gorman m...@csn.ul.ie wrote:

I reviewed the core MM changes and I've acked most of them so the
next release should have a few acks where you expect them. I did not
add a reviewed-by because I did not build and test the thing.


Thanks!

I've either replied to your comments or applied suggested changes.
If anyone cares, not-tested changes are available at
git://github.com/mina86/linux-2.6.git cma

--
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz(o o)
ooo +email/xmpp: m...@google.com--ooO--(_)--Ooo--
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/15] mm: page_alloc: update migrate type of pages on pcp when isolating

2012-01-30 Thread Mel Gorman
On Mon, Jan 30, 2012 at 04:41:22PM +0100, Michal Nazarewicz wrote:
 On Mon, 30 Jan 2012 12:15:22 +0100, Mel Gorman m...@csn.ul.ie wrote:
 
 On Thu, Jan 26, 2012 at 10:00:44AM +0100, Marek Szyprowski wrote:
 From: Michal Nazarewicz min...@mina86.com
 @@ -139,3 +139,27 @@ int test_pages_isolated(unsigned long start_pfn, 
 unsigned long end_pfn)
 spin_unlock_irqrestore(zone-lock, flags);
 return ret ? 0 : -EBUSY;
  }
 +
 +/* must hold zone-lock */
 +void update_pcp_isolate_block(unsigned long pfn)
 +{
 +   unsigned long end_pfn = pfn + pageblock_nr_pages;
 +   struct page *page;
 +
 +   while (pfn  end_pfn) {
 +   if (!pfn_valid_within(pfn)) {
 +   ++pfn;
 +   continue;
 +   }
 +
 
 On Mon, 30 Jan 2012 12:15:22 +0100, Mel Gorman m...@csn.ul.ie wrote:
 There is a potential problem here that you need to be aware of.
 set_pageblock_migratetype() is called from start_isolate_page_range().
 I do not think there is a guarantee that pfn + pageblock_nr_pages is
 not in a different block of MAX_ORDER_NR_PAGES. If that is right then
 your options are to add a check like this;
 
 if ((pfn  (MAX_ORDER_NR_PAGES - 1)) == 0  !pfn_valid(pfn))
  break;
 
 or else ensure that end_pfn is always MAX_ORDER_NR_PAGES aligned and in
 the same block as pfn and relying on the caller to have called
 pfn_valid.
 
   pfn = round_down(pfn, pageblock_nr_pages);
   end_pfn = pfn + pageblock_nr_pages;
 
 should do the trick as well, right?  move_freepages_block() seem to be
 doing the same thing.
 

That would also do it the trick.

 +   page = pfn_to_page(pfn);
 +   if (PageBuddy(page)) {
 +   pfn += 1  page_order(page);
 +   } else if (page_count(page) == 0) {
 +   set_page_private(page, MIGRATE_ISOLATE);
 +   ++pfn;
 
 This is dangerous for two reasons. If the page_count is 0, it could
 be because the page is in the process of being freed and is not
 necessarily on the per-cpu lists yet and you cannot be sure if the
 contents of page-private are important. Second, there is nothing to
 prevent another CPU allocating this page from its per-cpu list while
 the private field is getting updated from here which might lead to
 some interesting races.
 
 I recognise that what you are trying to do is respond to Gilad's
 request that you really check if an IPI here is necessary. I think what
 you need to do is check if a page with a count of 0 is encountered
 and if it is, then a draining of the per-cpu lists is necessary. To
 address Gilad's concerns, be sure to only this this once per attempt at
 CMA rather than for every page encountered with a count of 0 to avoid a
 storm of IPIs.
 
 It's actually more then that.
 
 This is the same issue that I first fixed with a change to 
 free_pcppages_bulk()
 function[1].  At the time of positing, you said you'd like me to try and find
 a different solution which would not involve paying the price of calling
 get_pageblock_migratetype().  Later I also realised that this solution is
 not enough.
 
 [1] http://article.gmane.org/gmane.linux.kernel.mm/70314
 

Yes. I had forgotten the history but looking at that patch again,
I would reach the conclusion that this was adding a new call to
get_pageblock_migratetype() in the bulk free path. That would affect
everybody whether they were using CMA or not.

 My next attempt was to run drain PCP list while holding zone-lock[2], but 
 that
 quickly proven to be broken approach when Marek started testing it on an SMP
 system.
 
 [2] http://article.gmane.org/gmane.linux.kernel.mm/72016
 
 This patch is yet another attempt of solving this old issue.  Even though it 
 has
 a potential race condition we came to conclusion that the actual chances of
 causing any problems are slim.  Various stress tests did not, in fact, show
 the race to be an issue.
 

It is a really small race. To cause a problem CPU 1 must find a page
with count 0, CPU 2 must then allocate the page and set page-private
before CPU 1 overwrites that value but it's there.

 The problem is that if a page is on a PCP list, and it's underlaying 
 pageblocks'
 migrate type is changed to MIGRATE_ISOLATE, the page (i) will still remain on 
 PCP
 list and thus someone can allocate it, and (ii) when removed from PCP list, 
 the
 page will be put on freelist of migrate type it had prior to change.
 
 (i) is actually not such a big issue since the next thing that happens after
 isolation is migration so all the pages will get freed.  (ii) is actual 
 problem
 and if [1] is not an acceptable solution I really don't have a good fix for 
 that.
 
 One things that comes to mind is calling drain_all_pages() prior to acquiring
 zone-lock in set_migratetype_isolate().  This is however prone to races since
 after the drain and before the zone-lock is acquired, pages might get moved
 back to PCP list.
 
 Draining PCP list after acquiring zone-lock is not possible because
 

Re: [RFCv1 2/4] v4l:vb2: add support for shared buffer (dma_buf)

2012-01-30 Thread Daniel Vetter
On Mon, Jan 30, 2012 at 03:44:20PM +0100, Laurent Pinchart wrote:
 Hi Daniel,
 
 On Tuesday 24 January 2012 14:03:22 Daniel Vetter wrote:
  On Mon, Jan 23, 2012 at 11:54:20AM +0100, Laurent Pinchart wrote:
   On Monday 23 January 2012 11:35:01 Daniel Vetter wrote:
See my other mail, dma_buf v1 does not support cpu access.
   
   v1 is in the kernel now, let's start discussing v2 ;-)
  
  Ok, I'm in ;-)
  
  I've thought a bit about this, and I think a reasonable next step would be
  to enable cpu access from kernelspace. Userspace and mmap support is a hole
  different beast altogether and I think we should postpone that until we've
  got the kernel part hashed out.
 
 Userspace access through mmap can already be handled by the subsystem that 
 exports the buffer, so I'm fine with postponing implementing this inside dma-
 buf.

Actually I think the interface for mmap won't be that horribly. If we add
a bit of magic clue so that the exporter can intercept pagefaults we
should be able to fake coherent mmaps in all cases. And hence avoid
exposing importers and userspace to a lot of ugly things.

  I'm thinking about adding 3 pairs of function to dma_buf (not to
  dma_buf_attachment).
  
  dma_buf_get_backing_storage/put_backing_storage
  This will be used before/after kernel cpu access to ensure that the
  backing storage is in memory. E.g. gem objects can be swapped out, so
  they need to be pinned before we can access them. For exporters with
  static allocations this would be a no-op.
  
  I think a start, length range would make sense, but the exporter is free
  to just swap in the entire object unconditionally. The range is specified
  in multiples of PAGE_SIZE - I don't think there's any usescase for a
  get/put_backing_storage which deals in smaller units.
  
  The get/put functions are allowed to block and grab all kinds of looks.
  get is allowed to fail with e.g. -ENOMEM.
  
  dma_buf_kmap/kunmap
  This maps _one_ page into the kernels address space and out of it. This
  function also flushes/invalidates any caches required. Importers are not
  allowed to map more than 2 pages at the same time in total (to allow
  copies). This is because at least for gem objects the backing storage can
  be in high-mem.
  
  Importers are allowed to sleep while holding such a kernel mapping.
  
  These functions are not allowed to fail (like kmap/kunmap).
  
  dma_buf_kmap_atomic/kunmap_atomic
  For performance we want to also allow atomic mappigns. Only difference is
  that importers are not allowed to sleep while holding an atomic mapping.
  
  These functions are again not allowed to fail.
  
  Comments, flames?
 
 Before commenting (I don't plan on flaming :-)), I'd like to take a small 
 step 
 back. Could you describe the use case(s) you think of for kernel mappings ?

One is simply for devices where the kernel has to shove around the data -
I've heard some complaints in the v4l dma_buf threads that this seems to
be dearly in need. E.g. when the v4l devices is attached to usb or behind
another slow(er) bus where direct dma is not possible.

The other is that currently importers are 2nd class citizens and can't do
any cpu access. Making kernel cpu access would be the first step
(afterswards getting mmap working for userspace cpu access). Now for some
simple use-case we can just say use the access paths provided by the
exporter. But for gpu drivers this gets really ugly because the
upload/download paths aren't standardized within drm/* and they're all
highly optimized. So to make buffer sharing possible among gpu's we need
this - the current gem prime code just grabs the underlying struct page
with sg_page and horribly fails if that doesn't work ;-)

On my proposal itself I think I'll change get/put_backing_storage to
begin/end_cpu_access - these functions must also do any required flushing
to ensure coherency (besides actually grabbing the backing storage). So I
think that's a better name.
-Daniel
-- 
Daniel Vetter
Mail: dan...@ffwll.ch
Mobile: +41 (0)79 365 57 48
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Adding YUV input support for OMAP3ISP driver

2012-01-30 Thread Gary Thomas

On 2012-01-20 05:19, Laurent Pinchart wrote:

Hi Enrico,

On Thursday 19 January 2012 15:17:57 Enrico wrote:

On Thu, Jan 19, 2012 at 2:52 PM, Gary Thomasg...@mlbassoc.com  wrote:

On 2012-01-19 06:35, Gary Thomas wrote:

My camera init code is attached. In the previous kernel, the I2C bus was
probed implicitly when I initialized the OMAP3ISP. I thought I
remembered some discussion about how that worked (maybe changing), so
this is probably
where the problem starts.

If you have an example, I can check my setup against it.


Note: I reworked how the sensor+I2C was initialized to be
omap3_init_camera(cobra3530p73_isp_platform_data);

  omap_register_i2c_bus(cobra3530p73_isp_platform_data.subdevs-subdevs[0]
.i2c_adapter_id, 400,

  cobra3530p73_isp_platform_data.subdevs-subdevs[0].board_info, 1);

The TVP5150 is now found, but 'media-ctl -p' still dies :-(


Have a look at [1] (the linux_3.2.bb file to see the list of
patches,inside linux-3.2 directory for the actual patches), it's based
on mainline kernel 3.2 and the bt656 patches i submitted months ago,
it should be easy to adapt it for you board.

rant
Really, there are patches for all these problems since months (from
me, Javier, TI), but because no maintainer cared (apart from Laurent)
they were never reviewed/applied and there is always someone who comes
back with all the usual problems (additional yuv format, bt656 mode,
tvp5150 that doesn't work...).
/rant


I totally understand your feeling.

I'd like to get YUV support integrated in the OMAP3 ISP driver. However, I
have no YUV image source hardware, so I can only review the patches but not
test them.

If someone can rebase the existing patches on top of
http://git.linuxtv.org/pinchartl/media.git/shortlog/refs/heads/omap3isp-
omap3isp-yuv and test them, then I'll review the result.



The attached patches produce a working setup against Laurent's tree above.
That said, I don't recall exactly where which changes came from (I'm old
school and not very git savvy, sorry).  I've CC'd all the folks I think
provided at least part of these changes.  Perhaps we can all work together
to come up with a proper set of patches which can be pushed upstream
for this, once and for all?

Thanks

--

Gary Thomas |  Consulting for the
MLB Associates  |Embedded world

From 2ab6c0c7b481d116c9d7faf120efcff1ef2a732f Mon Sep 17 00:00:00 2001
From: Gary Thomas g...@mlbassoc.com
Date: Wed, 25 Jan 2012 07:57:21 -0700
Subject: [PATCH 1/2] Merge working driver for TVP5150

---
 drivers/media/video/tvp5150.c |  419 -
 include/media/tvp5150.h   |6 +
 2 files changed, 375 insertions(+), 50 deletions(-)

diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 6be9910..a472ebe 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -5,15 +5,17 @@
  * This code is placed under the terms of the GNU General Public License v2
  */
 
+#include linux/module.h
 #include linux/i2c.h
 #include linux/slab.h
 #include linux/videodev2.h
 #include linux/delay.h
-#include linux/module.h
 #include media/v4l2-device.h
 #include media/tvp5150.h
 #include media/v4l2-chip-ident.h
 #include media/v4l2-ctrls.h
+#include media/v4l2-subdev.h
+#include media/v4l2-mediabus.h
 
 #include tvp5150_reg.h
 
@@ -26,11 +28,79 @@ static int debug;
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, Debug level (0-2));
 
+/* enum tvp515x_std - enum for supported standards */
+enum tvp515x_std {
+	STD_PAL_BDGHIN = 0,
+	STD_NTSC_MJ,
+	STD_INVALID
+};
+
+/**
+ * struct tvp515x_std_info - Structure to store standard informations
+ * @width: Line width in pixels
+ * @height:Number of active lines
+ * @video_std: Value to write in REG_VIDEO_STD register
+ * @standard: v4l2 standard structure information
+ */
+struct tvp515x_std_info {
+	u8 video_std;
+	struct v4l2_standard standard;
+	struct v4l2_mbus_framefmt format;
+};
+
+/**
+ * Supported standards -
+ *
+ * Currently supports two standards only, need to add support for rest of the
+ * modes, like SECAM, etc...
+ */
+static struct tvp515x_std_info tvp515x_std_list[] = {
+	/* Standard: STD_NTSC_MJ */
+	/* Standard: STD_PAL_BDGHIN */
+	[STD_PAL_BDGHIN] = {
+		.video_std = VIDEO_STD_PAL_BDGHIN_BIT,
+		.standard = {
+			.index = 1,
+			.id = V4L2_STD_PAL,
+			.name = PAL,
+			.frameperiod = {1, 25},
+			.framelines = 625
+		},
+		.format = {
+			.width = PAL_NUM_ACTIVE_PIXELS,
+			.height = PAL_NUM_ACTIVE_LINES,
+			.code = V4L2_MBUS_FMT_UYVY8_2X8,
+			.field = V4L2_FIELD_INTERLACED,
+			.colorspace = V4L2_COLORSPACE_SMPTE170M,
+		},
+	},
+	[STD_NTSC_MJ] = {
+		.video_std = VIDEO_STD_NTSC_MJ_BIT,
+		.standard = {
+			.index = 0,
+			.id = V4L2_STD_NTSC,
+			.name = NTSC,
+			.frameperiod = {1001, 3},
+			.framelines = 525
+		},
+		.format = {
+			.width = 

Please tag proof-of-concept patches as RFC

2012-01-30 Thread Pawel Osciak
Hi All,
There's been a lot of proof-of-concept patch series posted recently. I
think it's great, but I would just like to suggest the RFC tag is used
in the topic of such patches. I feel this would be helpful not only
for Mauro, but for all of us.
Thanks!
Pawel
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


cron job: media_tree daily build: WARNINGS

2012-01-30 Thread Hans Verkuil
This message is generated daily by a cron job that builds media_tree for
the kernels and architectures in the list below.

Results of the daily build of media_tree:

date:Mon Jan 30 19:00:18 CET 2012
git hash:59b30294e14fa6a370fdd2bc2921cca1f977ef16
gcc version:  i686-linux-gcc (GCC) 4.6.2
host hardware:x86_64
host os:  3.1-2.slh.1-amd64

linux-git-arm-eabi-enoxys: WARNINGS
linux-git-arm-eabi-omap: WARNINGS
linux-git-armv5-ixp: WARNINGS
linux-git-i686: WARNINGS
linux-git-m32r: WARNINGS
linux-git-mips: WARNINGS
linux-git-powerpc64: WARNINGS
linux-git-x86_64: WARNINGS
linux-2.6.31.12-i686: WARNINGS
linux-2.6.32.6-i686: WARNINGS
linux-2.6.33-i686: WARNINGS
linux-2.6.34-i686: WARNINGS
linux-2.6.35.3-i686: WARNINGS
linux-2.6.36-i686: WARNINGS
linux-2.6.37-i686: WARNINGS
linux-2.6.38.2-i686: WARNINGS
linux-2.6.39.1-i686: WARNINGS
linux-3.0-i686: WARNINGS
linux-3.1-i686: WARNINGS
linux-3.2.1-i686: WARNINGS
linux-3.3-rc1-i686: WARNINGS
linux-2.6.31.12-x86_64: WARNINGS
linux-2.6.32.6-x86_64: WARNINGS
linux-2.6.33-x86_64: WARNINGS
linux-2.6.34-x86_64: WARNINGS
linux-2.6.35.3-x86_64: WARNINGS
linux-2.6.36-x86_64: WARNINGS
linux-2.6.37-x86_64: WARNINGS
linux-2.6.38.2-x86_64: WARNINGS
linux-2.6.39.1-x86_64: WARNINGS
linux-3.0-x86_64: WARNINGS
linux-3.1-x86_64: WARNINGS
linux-3.2.1-x86_64: WARNINGS
linux-3.3-rc1-x86_64: WARNINGS
apps: WARNINGS
spec-git: WARNINGS
sparse: ERRORS

Detailed results are available here:

http://www.xs4all.nl/~hverkuil/logs/Monday.log

Full logs are available here:

http://www.xs4all.nl/~hverkuil/logs/Monday.tar.bz2

The V4L-DVB specification from this daily build is here:

http://www.xs4all.nl/~hverkuil/spec/media.html
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFCv1 2/4] v4l:vb2: add support for shared buffer (dma_buf)

2012-01-30 Thread Sakari Ailus
Hi Daniel,

On Sun, Jan 29, 2012 at 02:03:40PM +0100, Daniel Vetter wrote:
 On Sun, Jan 29, 2012 at 01:03:39PM +0200, Sakari Ailus wrote:
  Daniel Vetter wrote:
   On Thu, Jan 26, 2012 at 01:28:16AM +0200, Sakari Ailus wrote:
   Why you should not hang onto mappings forever? This is currently done 
   by
   virtually all V4L2 drivers where such mappings are relevant. Not doing so
   would really kill the performance i.e. it's infeasible. Same goes to 
   (m)any
   other multimedia devices dealing with buffers containing streaming video
   data.
   
   Because I want dynamic memory managemt simple because everything else does
   not make sense. I know that in v4l things don't work that way, but in drm
   they _do_. And if you share tons of buffers with drm drivers and don't
   follow the rules, the OOM killer will come around and shot at your apps.
   Because at least in i915 we do slurp in as much memory as we can until the
   oom killer starts growling, at which point we kick out stuff.
   
   I know that current dma_buf isn't there and for many use-cases discussed
   here we can get away without that complexity. So you actually can just map
   your dma_buf and never ever let go of that mapping again in many cases.
   
   The only reason I'm such a stuborn bastard about all this is that drm/*
   will do dynamic bo management even with dma_buf sooner or later and you
   should better know that and why and the implications if you choose to
   ignore it.
   
   And obviously, the generic dma_buf interface needs to be able to support
   it.
  
  I do not think we should completely ignore this issue, but I think we
  might want to at least postpone the implementation for non-DRM
  subsystems to an unknown future date. The reason is simply that it's
  currently unfeasible for various reasons.
  
  Sharing large buffers with GPUs (where you might want to manage them
  independently of the user space) is uncommon; typically you're sharing
  buffers for viewfinder that tend to be around few megabytes in size and
  there may be typically up to five of them. Also, we're still far from
  getting things working in the first place. Let's not complicate them
  more than we have to.
  
  The very reason why we're pre-allocating these large buffers in
  applications is that you can readily use them when you need them.
  Consider camera, for example: a common use case is to have a set of 24
  MB buffers (for 12 Mp images) prepared while the viewfinder is running.
  These buffers must be immediately usable when the user presses the
  shutter button.
  
  We don't want to continuously map and unmap buffers in viewfinder
  either: that adds a significan CPU load for no technical reason
  whatsoever. Typically viewfinder also involves running software
  algorithms that consume much of the available CPU time, so adding an
  unnecessary CPU hog to the picture doesn't sound that enticing.
  
  If the performance of memory management can be improved to such an
  extent it really takes much less than a millisecond or so to perform all
  the pinning-to-memory, IOMMU mapping and so on systems for 24 MB buffers
  on regular embedded systems I think I wouldn't have much against doing
  so. Currently I think we're talking about numbers that are at least
  100-fold.
  
  If you want to do this to buffers used only in DRM I'm fine with that.
 
 A few things:
 - I do understand that there are use cases where allocate, pin  forget
   works.

It's not so much about forgetting it; if the buffers could be considered to
be paged out at any point I think almost all users would prefer to perform
mlock(2) to them. Buffers allocated since they're needed for streaming, not
so much for single use pruposes.

There are also very few of those buffers compared to DRM.

 - I'm perfectly fine if you do this in your special embedded product. Or
   the entire v4l subsystem, I don't care much about that one, either.

It's not so special; this is done on desktop PCs as well and I don't think
this is going to change any time soon.

 But:
 - I'm fully convinced that all these special purpose single use-case
   scenarios will show up sooner or later on a more general purpose
   platform.

They already do show on PCs. What PCs have been able to afford and still can
is to add extra data copies at any part of the stream processing to overcome
any minor technical obstacle for which other more memory bus friendly
solutions can be used for.

 - And as soon as your on a general purpose platform, you _want_ dynamic
   memory management.

V4L2 has been like this for some 10 years, embedded or not. When the
performance of memory management improves enough we can reconsider this.

 I mean the entire reason people are pushing CMA is that preallocating gobs
 of memory statically really isn't that great an idea ...

There's a huge difference allocating things statically and an application
deciding what it needs to allocate and when; you don't want to keep the
buffers around 

[PATCH 05/16] cx18: fix handling of 'radio' module parameter

2012-01-30 Thread Danny Kukawka
Fixed handling of 'radio' module parameter from module_param_array
to module_param_named to fix these compiler warnings in cx18-driver.c:

In function ‘__check_radio’:
113:1: warning: return from incompatible pointer type [enabled by default]
At top level:
113:1: warning: initialization from incompatible pointer type [enabled by 
default]
113:1: warning: (near initialization for ‘__param_arr_radio.num’) [enabled by 
default]

Signed-off-by: Danny Kukawka danny.kuka...@bisect.de
---
 drivers/media/video/cx18/cx18-driver.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/cx18/cx18-driver.c 
b/drivers/media/video/cx18/cx18-driver.c
index 349bd9c..27b5330 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -110,7 +110,7 @@ static int retry_mmio = 1;
 int cx18_debug;
 
 module_param_array(tuner, int, tuner_c, 0644);
-module_param_array(radio, bool, radio_c, 0644);
+module_param_named(radio, radio_c, bool, 0644);
 module_param_array(cardtype, int, cardtype_c, 0644);
 module_param_string(pal, pal, sizeof(pal), 0644);
 module_param_string(secam, secam, sizeof(secam), 0644);
-- 
1.7.7.3

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 02/16] max2165: trival fix for some -Wuninitialized warning

2012-01-30 Thread Danny Kukawka
Fix for some -Wuninitialized compiler warnings.

Signed-off-by: Danny Kukawka danny.kuka...@bisect.de
---
 drivers/media/common/tuners/max2165.c |9 ++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/media/common/tuners/max2165.c 
b/drivers/media/common/tuners/max2165.c
index cb2c98f..ba84936 100644
--- a/drivers/media/common/tuners/max2165.c
+++ b/drivers/media/common/tuners/max2165.c
@@ -168,7 +168,7 @@ int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, 
u32 *fraction)
int i;
 
if (0 == divisor)
-   return -1;
+   return -EINVAL;
 
q = dividend / divisor;
remainder = dividend - q * divisor;
@@ -194,10 +194,13 @@ static int max2165_set_rf(struct max2165_priv *priv, u32 
freq)
u8 tf_ntch;
u32 t;
u32 quotient, fraction;
+   int ret;
 
/* Set PLL divider according to RF frequency */
-   fixpt_div32(freq / 1000, priv-config-osc_clk * 1000,
-   quotient, fraction);
+   ret = fixpt_div32(freq / 1000, priv-config-osc_clk * 1000,
+quotient, fraction);
+   if (ret != 0)
+   return ret;
 
/* 20-bit fraction */
fraction = 12;
-- 
1.7.7.3

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH 0/4] Add some new camera controls

2012-01-30 Thread Sakari Ailus
Hi Sylwester,

On Sat, Jan 28, 2012 at 06:01:59PM +0100, Sylwester Nawrocki wrote:
 On 01/04/2012 10:07 PM, Sakari Ailus wrote:
  On Fri, Dec 30, 2011 at 12:18:40PM +0100, Sylwester Nawrocki wrote:
  Thus we would three levels of controls for camera,
1) image source class (lowest possible level), dealing mostly with 
  hardware
   registers;
  
  I intended the image source class for controls which only deal with the a/d
  conversion itself. Other controls would be elsewhere.
  
  There hasn't been a final decision on this yet, but an alternative which has
  been also discussed is just to call this a low level control class.
  
2) normal camera controls (V4L2_CID_CAMERA_CLASS) [2];
3) high level camera controls (for camera software algorithms)
 ...
  
  I'm afraid a little it might be hard to distinguish if some control should
  belong to 2) or 3), as sensors' logic complexity and advancement varies.
  
  I can see two main use cases:
  
  1. V4L2 / V4L2 subdev / MC as the low level API for camera control and
  
  2. Regular V4L2 applications.
  
  For most controls it's clear which of the two classes they belong to.
 
 Have you any ideas on what the class' name could be ? I thought about 
 V4L2_CTRL_CLASS_HIGH_LEVEL_CAMERA or V4L2_CTRL_CLASS_CAMERA_USER although 
 I'm not too happy with any of them and it seems hard to make up some 
 reasonable name, when we already have V4L2_CTRL_CLASS_CAMERA.

I might continue to use the current V4L2_CTRL_CLASS_CAMERA to that --- as
far I understand most are quite high level controls. We could create a new
class for the low level controls instead.

Should the new class be for camera controls only or for any low level
controls? I'd perhaps vote for a camera, or even sensor low level class. (I
actually call it image source class in the patchset.)

Another question is how should we call the class for low level controls
which may or may not be implemented in sensor. Digital gain, for example.

  Although I can see an advantage of logically separating controls which have
  influence on one or more other (lower level) controls. And separate control
  class would be helpful in that.
 
  The candidates to such control class might be:
 
  * V4L2_CID_METERING_MODE,
  * V4L2_CID_EXPOSURE_BIAS,
  * V4L2_CID_ISO,
  * V4L2_CID_WHITE_BALANCE_PRESET,
  * V4L2_CID_SCENEMODE,
  * V4L2_CID_WDR,
  * V4L2_CID_ANTISHAKE,
  
  The list looks good to me.

Cheers,

-- 
Sakari Ailus
e-mail: sakari.ai...@iki.fi jabber/XMPP/Gmail: sai...@retiisi.org.uk
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH][media] s5p-g2d: Add HFLIP and VFLIP support

2012-01-30 Thread Sachin Kamat
Hi Laurent, Sylwester and Kamil,

Thank you for your comments and suggestions.
I will re-send the patch with the following 2 changes:

1. Error checking done only once at the end of the init call.
2. Modification in switch case as suggested by Kamil.

Regards
Sachin

On 30 January 2012 19:09, Kamil Debski k.deb...@samsung.com wrote:
 Hi Laurent and Sachin,

 Thanks for the patch and for your comments.

 From: Laurent Pinchart [mailto:laurent.pinch...@ideasonboard.com]
 Sent: 30 January 2012 13:12

 Hi Sashin,

 Thanks for the patch.

 On Monday 30 January 2012 10:58:43 Sachin Kamat wrote:
  This patch adds support for flipping the image horizontally and vertically.
 
  Signed-off-by: Sachin Kamat sachin.ka...@linaro.org
  ---
   drivers/media/video/s5p-g2d/g2d-hw.c |    5 +++
   drivers/media/video/s5p-g2d/g2d.c    |   47 +
 --
   drivers/media/video/s5p-g2d/g2d.h    |    3 ++
   3 files changed, 46 insertions(+), 9 deletions(-)

 [snip]

  diff --git a/drivers/media/video/s5p-g2d/g2d.c
  b/drivers/media/video/s5p-g2d/g2d.c index febaa67..dea9701 100644
  --- a/drivers/media/video/s5p-g2d/g2d.c
  +++ b/drivers/media/video/s5p-g2d/g2d.c
  @@ -178,6 +178,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
   {
      struct g2d_ctx *ctx = container_of(ctrl-handler, struct g2d_ctx,
                                                              ctrl_handler);
  +
      switch (ctrl-id) {
      case V4L2_CID_COLORFX:
              if (ctrl-val == V4L2_COLORFX_NEGATIVE)
  @@ -185,6 +186,21 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
              else
                      ctx-rop = ROP4_COPY;
              break;
  +
  +   case V4L2_CID_HFLIP:
  +           if (ctrl-val == 1)
  +                   ctx-hflip = 1;
  +           else
  +                   ctx-hflip = 0;
  +           break;
  +
  +   case V4L2_CID_VFLIP:
  +           if (ctrl-val == 1)
  +                   ctx-vflip = (1  1);
  +           else
  +                   ctx-vflip = 0;
  +           break;

 I think that

 case V4L2_CID_HFLIP:
        ctx-hflip = ctrl-val;
        break;

 case V4L2_CID_VFLIP:
        ctx-vflip = (ctrl-val  1);
        break;

 will be sufficient, as flip controls have min=0 and max=1 which makes
 them safe to use.

  +
      default:
              v4l2_err(ctx-dev-v4l2_dev, unknown control\n);
              return -EINVAL;
  @@ -200,11 +216,9 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
   {
      struct g2d_dev *dev = ctx-dev;
 
  -   v4l2_ctrl_handler_init(ctx-ctrl_handler, 1);
  -   if (ctx-ctrl_handler.error) {
  -           v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
  -           return ctx-ctrl_handler.error;
  -   }
  +   v4l2_ctrl_handler_init(ctx-ctrl_handler, 3);
  +   if (ctx-ctrl_handler.error)
  +           goto error;

 There's not need to verify ctx-ctrl_handler.error after every call to
 v4l2_ctrl_handler_init() or v4l2_ctrl_new_*(). You can verify it once only
 after initialization all controls.

 I agree.

 
      v4l2_ctrl_new_std_menu(
              ctx-ctrl_handler,
  @@ -214,12 +228,25 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
              ~((1  V4L2_COLORFX_NONE) | (1  V4L2_COLORFX_NEGATIVE)),
              V4L2_COLORFX_NONE);
 
  -   if (ctx-ctrl_handler.error) {
  -           v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
  -           return ctx-ctrl_handler.error;
  -   }
  +   if (ctx-ctrl_handler.error)
  +           goto error;
  +
  +   v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops,
  +                                           V4L2_CID_HFLIP, 0, 1, 1, 0);
  +   if (ctx-ctrl_handler.error)
  +           goto error;
  +
  +   v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops,
  +                                           V4L2_CID_VFLIP, 0, 1, 1, 0);

 As a single register controls hflip and vflip, you should group the two
 controls in a cluster.

 I think it doesn't matter in this use case. As register are not written
 in the g2d_s_ctrl. Because the driver uses multiple context it modifies
 the appropriate values in its context structure and registers are written
 when the transaction is run.

 Also there is no logical connection between horizontal and vertical flip.
 I think this is the case when using clusters. Here one is independent from
 another.


  +   if (ctx-ctrl_handler.error)
  +           goto error;
 
      return 0;
  +
  +error:
  +   v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
  +   return ctx-ctrl_handler.error;
  +
   }
 
   static int g2d_open(struct file *file)
  @@ -564,6 +591,8 @@ static void device_run(void *prv)
      g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));
 
      g2d_set_rop4(dev, ctx-rop);
  +   g2d_set_flip(dev, ctx-hflip | ctx-vflip);
  +

 Is this called for every frame, or once at stream start only ? In the later
 case, this means that hflip and vflip won't be changeable during streaming.
 Is
 that on purpose ?

      if (ctx-in.c_width != ctx-out.c_width ||
      

[PATCH v2] [media] s5p-g2d: Add HFLIP and VFLIP support

2012-01-30 Thread Sachin Kamat
This patch adds support for flipping the image horizontally and vertically.

Signed-off-by: Sachin Kamat sachin.ka...@linaro.org
---
 drivers/media/video/s5p-g2d/g2d-hw.c |5 +
 drivers/media/video/s5p-g2d/g2d.c|   25 -
 drivers/media/video/s5p-g2d/g2d.h|3 +++
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/drivers/media/video/s5p-g2d/g2d-hw.c 
b/drivers/media/video/s5p-g2d/g2d-hw.c
index 39937cf..5b86cbe 100644
--- a/drivers/media/video/s5p-g2d/g2d-hw.c
+++ b/drivers/media/video/s5p-g2d/g2d-hw.c
@@ -77,6 +77,11 @@ void g2d_set_rop4(struct g2d_dev *d, u32 r)
w(r, ROP4_REG);
 }
 
+void g2d_set_flip(struct g2d_dev *d, u32 r)
+{
+   w(r, SRC_MSK_DIRECT_REG);
+}
+
 u32 g2d_cmd_stretch(u32 e)
 {
e = 1;
diff --git a/drivers/media/video/s5p-g2d/g2d.c 
b/drivers/media/video/s5p-g2d/g2d.c
index febaa67..185e5b5 100644
--- a/drivers/media/video/s5p-g2d/g2d.c
+++ b/drivers/media/video/s5p-g2d/g2d.c
@@ -178,6 +178,7 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
 {
struct g2d_ctx *ctx = container_of(ctrl-handler, struct g2d_ctx,
ctrl_handler);
+
switch (ctrl-id) {
case V4L2_CID_COLORFX:
if (ctrl-val == V4L2_COLORFX_NEGATIVE)
@@ -185,6 +186,15 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
else
ctx-rop = ROP4_COPY;
break;
+
+   case V4L2_CID_HFLIP:
+   ctx-hflip = ctrl-val;
+   break;
+
+   case V4L2_CID_VFLIP:
+   ctx-vflip = (ctrl-val  1);
+   break;
+
default:
v4l2_err(ctx-dev-v4l2_dev, unknown control\n);
return -EINVAL;
@@ -200,11 +210,7 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
 {
struct g2d_dev *dev = ctx-dev;
 
-   v4l2_ctrl_handler_init(ctx-ctrl_handler, 1);
-   if (ctx-ctrl_handler.error) {
-   v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
-   return ctx-ctrl_handler.error;
-   }
+   v4l2_ctrl_handler_init(ctx-ctrl_handler, 3);
 
v4l2_ctrl_new_std_menu(
ctx-ctrl_handler,
@@ -214,6 +220,13 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
~((1  V4L2_COLORFX_NONE) | (1  V4L2_COLORFX_NEGATIVE)),
V4L2_COLORFX_NONE);
 
+
+   v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops,
+   V4L2_CID_HFLIP, 0, 1, 1, 0);
+
+   v4l2_ctrl_new_std(ctx-ctrl_handler, g2d_ctrl_ops,
+   V4L2_CID_VFLIP, 0, 1, 1, 0);
+
if (ctx-ctrl_handler.error) {
v4l2_err(dev-v4l2_dev, v4l2_ctrl_handler_init failed\n);
return ctx-ctrl_handler.error;
@@ -564,6 +577,8 @@ static void device_run(void *prv)
g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));
 
g2d_set_rop4(dev, ctx-rop);
+   g2d_set_flip(dev, ctx-hflip | ctx-vflip);
+
if (ctx-in.c_width != ctx-out.c_width ||
ctx-in.c_height != ctx-out.c_height)
cmd |= g2d_cmd_stretch(1);
diff --git a/drivers/media/video/s5p-g2d/g2d.h 
b/drivers/media/video/s5p-g2d/g2d.h
index 5eae901..b3be3c8 100644
--- a/drivers/media/video/s5p-g2d/g2d.h
+++ b/drivers/media/video/s5p-g2d/g2d.h
@@ -59,6 +59,8 @@ struct g2d_ctx {
struct g2d_frameout;
struct v4l2_ctrl_handler ctrl_handler;
u32 rop;
+   u32 hflip;
+   u32 vflip;
 };
 
 struct g2d_fmt {
@@ -77,6 +79,7 @@ void g2d_set_dst_addr(struct g2d_dev *d, dma_addr_t a);
 void g2d_start(struct g2d_dev *d);
 void g2d_clear_int(struct g2d_dev *d);
 void g2d_set_rop4(struct g2d_dev *d, u32 r);
+void g2d_set_flip(struct g2d_dev *d, u32 r);
 u32 g2d_cmd_stretch(u32 e);
 void g2d_set_cmd(struct g2d_dev *d, u32 c);
 
-- 
1.7.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html