Re: [PATCH 06/14] vrange: Add basic functions to purge volatile pages

2013-10-03 Thread Krzysztof Kozlowski
On śro, 2013-10-02 at 17:51 -0700, John Stultz wrote:
> +static void try_to_discard_one(struct vrange_root *vroot, struct page *page,
> + struct vm_area_struct *vma, unsigned long addr)
> +{
> + struct mm_struct *mm = vma->vm_mm;
> + pte_t *pte;
> + pte_t pteval;
> + spinlock_t *ptl;
> +
> + VM_BUG_ON(!PageLocked(page));
> +
> + pte = page_check_address(page, mm, addr, &ptl, 0);
> + if (!pte)
> + return;
> +
> + BUG_ON(vma->vm_flags & (VM_SPECIAL|VM_LOCKED|VM_MIXEDMAP|VM_HUGETLB));
> +
> + flush_cache_page(vma, addr, page_to_pfn(page));

It seems that this patch is different in your GIT repo
(git://git.linaro.org/people/jstultz/android-dev.git dev/vrange-v9). In
GIT it is missing the fix: s/address/addr.

Best regards,
Krzysztof



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 0/5] mm: migrate zbud pages

2013-10-03 Thread Krzysztof Kozlowski
On wto, 2013-10-01 at 16:04 -0500, Seth Jennings wrote:
> Yes, it is very similar.  I'm beginning to like aspects of this patch
> more as I explore this issue more.
> 
> At first, I balked at the idea of yet another abstraction layer, but it
> is very hard to avoid unless you want to completely collapse zswap and
> zbud into one another and dissolve the layering.  Then you could do a
> direct swap_offset -> address mapping.

After discussion with Tomasz Stanislawski we had an idea of merging the
trees (zswap's rb and zbud's radix added in these patches) into one tree
in zbud layer.

This would simplify the design (if migration was added, of course).

The idea looks like:
1. Get rid of the red-black tree in zswap.
2. Add radix tree to zbud (or use radix tree from address space).
 - Use offset (from swp_entry) as index to radix tree.
 - zbud page (struct page) stored in tree.
4. With both buddies filled one zbud page would be put in radix tree
twice.
5. zbud API would look like:
zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp, pgoff_t offset)
zbud_free(struct zbud_pool *pool, pgoff_t offset)
zbud_map(struct zbud_pool *pool, pgoff_t offset)
etc.

6. zbud_map/unmap() would be a little more complex than now as it would
took over some code from zswap (finding offset in tree).

7. The radix tree would be used for:
 - finding entry by offset (for zswap_frontswap_load() and others),
 - migration.

8. In case of migration colliding with zbud_map/unmap() the locking
could be limited (in comparison to my patch). Calling zbud_map() would
mark a page "dirty". During migration if page was "dirtied" then
migration would fail with EAGAIN. Of course migration won't start if
zbud buddy was mapped.


What do you think about this?


Best regards,
Krzysztof

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 1/4] zbud: use page ref counter for zbud pages

2013-09-08 Thread Krzysztof Kozlowski
Hi Bob,


On nie, 2013-09-08 at 17:04 +0800, Bob Liu wrote:
> Hi Krzysztof,
> 
> On 08/30/2013 04:42 PM, Krzysztof Kozlowski wrote:
> > Use page reference counter for zbud pages. The ref counter replaces
> > zbud_header.under_reclaim flag and ensures that zbud page won't be freed
> > when zbud_free() is called during reclaim. It allows implementation of
> > additional reclaim paths.
> > 
> > The page count is incremented when:
> >  - a handle is created and passed to zswap (in zbud_alloc()),
> >  - user-supplied eviction callback is called (in zbud_reclaim_page()).
> > 
> > Signed-off-by: Krzysztof Kozlowski 
> > Signed-off-by: Tomasz Stanislawski 
> > Reviewed-by: Bob Liu 
> 
> AFAIR, the previous version you sent out has a function  called
> rebalance_lists() which I think is a good clean up.
> But I didn't see that function any more in this version.

Yes, that function was added because similar code was present in
zbud_free/zbud_alloc/zbud_reclaim_page. I removed it because it turned
out that there is no benefit in generalizing this code. Seth found an
issue in this function (zbud page was re-inserted in to LRU when
zbud_free() was called on one buddy). Fixing this issue added more if-s
and more code thus enlarging the rebalance_lists() function.

Best regards,
Krzysztof

> Thanks,
> -Bob
> 
> 
> > ---
> >  mm/zbud.c |   97 
> > +
> >  1 file changed, 52 insertions(+), 45 deletions(-)
> > 
> > diff --git a/mm/zbud.c b/mm/zbud.c
> > index ad1e781..aa9a15c 100644
> > --- a/mm/zbud.c
> > +++ b/mm/zbud.c
> > @@ -109,7 +109,6 @@ struct zbud_header {
> > struct list_head lru;
> > unsigned int first_chunks;
> > unsigned int last_chunks;
> > -   bool under_reclaim;
> >  };
> >  
> >  /*
> > @@ -138,16 +137,9 @@ static struct zbud_header *init_zbud_page(struct page 
> > *page)
> > zhdr->last_chunks = 0;
> > INIT_LIST_HEAD(&zhdr->buddy);
> > INIT_LIST_HEAD(&zhdr->lru);
> > -   zhdr->under_reclaim = 0;
> > return zhdr;
> >  }
> >  
> > -/* Resets the struct page fields and frees the page */
> > -static void free_zbud_page(struct zbud_header *zhdr)
> > -{
> > -   __free_page(virt_to_page(zhdr));
> > -}
> > -
> >  /*
> >   * Encodes the handle of a particular buddy within a zbud page
> >   * Pool lock should be held as this function accesses first|last_chunks
> > @@ -188,6 +180,31 @@ static int num_free_chunks(struct zbud_header *zhdr)
> > return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks - 1;
> >  }
> >  
> > +/*
> > + * Increases ref count for zbud page.
> > + */
> > +static void get_zbud_page(struct zbud_header *zhdr)
> > +{
> > +   get_page(virt_to_page(zhdr));
> > +}
> > +
> > +/*
> > + * Decreases ref count for zbud page and frees the page if it reaches 0
> > + * (no external references, e.g. handles).
> > + *
> > + * Returns 1 if page was freed and 0 otherwise.
> > + */
> > +static int put_zbud_page(struct zbud_header *zhdr)
> > +{
> > +   struct page *page = virt_to_page(zhdr);
> > +   if (put_page_testzero(page)) {
> > +   free_hot_cold_page(page, 0);
> > +   return 1;
> > +   }
> > +   return 0;
> > +}
> > +
> > +
> >  /*
> >   * API Functions
> >  */
> > @@ -250,7 +267,7 @@ void zbud_destroy_pool(struct zbud_pool *pool)
> >  int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
> > unsigned long *handle)
> >  {
> > -   int chunks, i, freechunks;
> > +   int chunks, i;
> > struct zbud_header *zhdr = NULL;
> > enum buddy bud;
> > struct page *page;
> > @@ -273,6 +290,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t 
> > gfp,
> > bud = FIRST;
> > else
> > bud = LAST;
> > +   get_zbud_page(zhdr);
> > goto found;
> > }
> > }
> > @@ -284,6 +302,10 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t 
> > gfp,
> > return -ENOMEM;
> > spin_lock(&pool->lock);
> > pool->pages_nr++;
> > +   /*
> > +* We will be using zhdr instead of page, so
> > +* don't increase the page count.
> > +*/
> > zhdr = init_zbud_page(page);
> >

Re: [RFC PATCH 0/4] mm: migrate zbud pages

2013-09-08 Thread Krzysztof Kozlowski
On pią, 2013-09-06 at 12:30 -0500, Seth Jennings wrote:
> On Fri, Aug 30, 2013 at 10:42:52AM +0200, Krzysztof Kozlowski wrote:
> > Hi,
> > 
> > Currently zbud pages are not movable and they cannot be allocated from CMA
> > region. These patches add migration of zbud pages.
> 
> Hey Krzysztof,
> 
> Thanks for the patches.  I haven't had time to look at them yet but wanted to
> let you know that I plan to early next week.
> 
> Seth

Great, thanks! Patches rebase and builds cleanly on current
mainline (v3.11-7890-ge5c832d).


Best regards,
Krzysztof


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 1/4] zbud: use page ref counter for zbud pages

2013-09-10 Thread Krzysztof Kozlowski
Hi,

On pon, 2013-09-09 at 14:47 -0500, Seth Jennings wrote:
> On Fri, Aug 30, 2013 at 10:42:53AM +0200, Krzysztof Kozlowski wrote:
> > Use page reference counter for zbud pages. The ref counter replaces
> > zbud_header.under_reclaim flag and ensures that zbud page won't be freed
> > when zbud_free() is called during reclaim. It allows implementation of
> > additional reclaim paths.
> 
> I like this idea.
> 
> > 
> > The page count is incremented when:
> >  - a handle is created and passed to zswap (in zbud_alloc()),
> >  - user-supplied eviction callback is called (in zbud_reclaim_page()).
> > 
> > Signed-off-by: Krzysztof Kozlowski 
> > Signed-off-by: Tomasz Stanislawski 
> > Reviewed-by: Bob Liu 
> > ---
> >  mm/zbud.c |   97 
> > +
> >  1 file changed, 52 insertions(+), 45 deletions(-)
> > 
> > diff --git a/mm/zbud.c b/mm/zbud.c
> > index ad1e781..aa9a15c 100644
> > --- a/mm/zbud.c
> > +++ b/mm/zbud.c
> > @@ -109,7 +109,6 @@ struct zbud_header {
> > struct list_head lru;
> > unsigned int first_chunks;
> > unsigned int last_chunks;
> > -   bool under_reclaim;
> >  };
> > 
> >  /*
> > @@ -138,16 +137,9 @@ static struct zbud_header *init_zbud_page(struct page 
> > *page)
> > zhdr->last_chunks = 0;
> > INIT_LIST_HEAD(&zhdr->buddy);
> > INIT_LIST_HEAD(&zhdr->lru);
> > -   zhdr->under_reclaim = 0;
> > return zhdr;
> >  }
> > 
> > -/* Resets the struct page fields and frees the page */
> > -static void free_zbud_page(struct zbud_header *zhdr)
> > -{
> > -   __free_page(virt_to_page(zhdr));
> > -}
> > -
> >  /*
> >   * Encodes the handle of a particular buddy within a zbud page
> >   * Pool lock should be held as this function accesses first|last_chunks
> > @@ -188,6 +180,31 @@ static int num_free_chunks(struct zbud_header *zhdr)
> > return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks - 1;
> >  }
> > 
> > +/*
> > + * Increases ref count for zbud page.
> > + */
> > +static void get_zbud_page(struct zbud_header *zhdr)
> > +{
> > +   get_page(virt_to_page(zhdr));
> > +}
> > +
> > +/*
> > + * Decreases ref count for zbud page and frees the page if it reaches 0
> > + * (no external references, e.g. handles).
> > + *
> > + * Returns 1 if page was freed and 0 otherwise.
> > + */
> > +static int put_zbud_page(struct zbud_header *zhdr)
> > +{
> > +   struct page *page = virt_to_page(zhdr);
> > +   if (put_page_testzero(page)) {
> > +   free_hot_cold_page(page, 0);
> > +   return 1;
> > +   }
> > +   return 0;
> > +}
> > +
> > +
> >  /*
> >   * API Functions
> >  */
> > @@ -250,7 +267,7 @@ void zbud_destroy_pool(struct zbud_pool *pool)
> >  int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
> > unsigned long *handle)
> >  {
> > -   int chunks, i, freechunks;
> > +   int chunks, i;
> 
> This change (make freechunks a block local variable) is unrelated to the
> patch description and should be its own patch.

Sure, I will split this into 2 patches.


[...]
> > list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
> > }
> > 
> > +   put_zbud_page(zhdr);
> > spin_unlock(&pool->lock);
> >  }
> > 
> > @@ -400,7 +414,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long 
> > handle)
> >   */
> >  int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries)
> >  {
> > -   int i, ret, freechunks;
> > +   int i, ret;
> > struct zbud_header *zhdr;
> > unsigned long first_handle = 0, last_handle = 0;
> > 
> > @@ -411,11 +425,24 @@ int zbud_reclaim_page(struct zbud_pool *pool, 
> > unsigned int retries)
> > return -EINVAL;
> > }
> > for (i = 0; i < retries; i++) {
> > +   if (list_empty(&pool->lru)) {
> > +   /*
> > +* LRU was emptied during evict calls in previous
> > +* iteration but put_zbud_page() returned 0 meaning
> > +* that someone still holds the page. This may
> > +* happen when some other mm mechanism increased
> > +* the page count.
> > +* In such case we succedded with recl

[PATCH v2 3/5] mm: use mapcount for identifying zbud pages

2013-09-11 Thread Krzysztof Kozlowski
Currently zbud pages do not have any flags set so it is not possible to
identify them during migration or compaction.

Implement PageZbud() by comparing page->_mapcount to -127 to distinguish
pages allocated by zbud. Just like PageBuddy() is implemented.

Signed-off-by: Krzysztof Kozlowski 
Reviewed-by: Seth Jennings 
---
 include/linux/mm.h |   23 +++
 mm/zbud.c  |4 
 2 files changed, 27 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index f022460..b9ae6f2 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -440,6 +440,7 @@ static inline void init_page_count(struct page *page)
  * efficiently by most CPU architectures.
  */
 #define PAGE_BUDDY_MAPCOUNT_VALUE (-128)
+#define PAGE_ZBUD_MAPCOUNT_VALUE (-127)
 
 static inline int PageBuddy(struct page *page)
 {
@@ -458,6 +459,28 @@ static inline void __ClearPageBuddy(struct page *page)
atomic_set(&page->_mapcount, -1);
 }
 
+#ifdef CONFIG_ZBUD
+static inline int PageZbud(struct page *page)
+{
+   return atomic_read(&page->_mapcount) == PAGE_ZBUD_MAPCOUNT_VALUE;
+}
+
+static inline void SetPageZbud(struct page *page)
+{
+   VM_BUG_ON(atomic_read(&page->_mapcount) != -1);
+   atomic_set(&page->_mapcount, PAGE_ZBUD_MAPCOUNT_VALUE);
+}
+
+static inline void ClearPageZbud(struct page *page)
+{
+   VM_BUG_ON(!PageZbud(page));
+   atomic_set(&page->_mapcount, -1);
+}
+#else
+PAGEFLAG_FALSE(Zbud)
+#endif
+
+
 void put_page(struct page *page);
 void put_pages_list(struct list_head *pages);
 
diff --git a/mm/zbud.c b/mm/zbud.c
index 1d5b26b..9be160c 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -197,7 +197,10 @@ static void get_zbud_page(struct zbud_header *zhdr)
 static int put_zbud_page(struct zbud_header *zhdr)
 {
struct page *page = virt_to_page(zhdr);
+   VM_BUG_ON(!PageZbud(page));
+
if (put_page_testzero(page)) {
+   ClearPageZbud(page);
free_hot_cold_page(page, 0);
return 1;
}
@@ -307,6 +310,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
 * don't increase the page count.
 */
zhdr = init_zbud_page(page);
+   SetPageZbud(page);
bud = FIRST;
 
 found:
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 2/5] zbud: make freechunks a block local variable

2013-09-11 Thread Krzysztof Kozlowski
Move freechunks variable in zbud_free() and zbud_alloc() to block-level
scope (from function scope).

Signed-off-by: Krzysztof Kozlowski 
---
 mm/zbud.c |7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/mm/zbud.c b/mm/zbud.c
index 3f4be72..1d5b26b 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -267,7 +267,7 @@ void zbud_destroy_pool(struct zbud_pool *pool)
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
unsigned long *handle)
 {
-   int chunks, i, freechunks;
+   int chunks, i;
struct zbud_header *zhdr = NULL;
enum buddy bud;
struct page *page;
@@ -317,7 +317,7 @@ found:
 
if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0) {
/* Add to unbuddied list */
-   freechunks = num_free_chunks(zhdr);
+   int freechunks = num_free_chunks(zhdr);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
} else {
/* Add to buddied list */
@@ -349,7 +349,6 @@ found:
 void zbud_free(struct zbud_pool *pool, unsigned long handle)
 {
struct zbud_header *zhdr;
-   int freechunks;
 
spin_lock(&pool->lock);
zhdr = handle_to_zbud_header(handle);
@@ -368,7 +367,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
pool->pages_nr--;
} else {
/* Add to unbuddied list */
-   freechunks = num_free_chunks(zhdr);
+   int freechunks = num_free_chunks(zhdr);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
}
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/5] mm: migrate zbud pages

2013-09-11 Thread Krzysztof Kozlowski
Hi,

Currently zbud pages are not movable and they cannot be allocated from CMA
(Contiguous Memory Allocator) region. These patches add migration of zbud pages.

The zbud migration code utilizes mapping so many exceptions to migrate
code were added. This can be replaced for example with pin page
control subsystem:
http://article.gmane.org/gmane.linux.kernel.mm/105308
In such case the zbud migration code (zbud_migrate_page()) can be safely
re-used.


Patch "[PATCH 3/5] mm: use mapcount for identifying zbud pages" introduces
PageZbud() function which identifies zbud pages by page->_mapcount.
Dave Hansen proposed aliasing PG_zbud=PG_slab but in such case patch
would be more intrusive.

Any ideas for a better solution are welcome.


Patch "[PATCH 4/5] mm: use indirect zbud handle and radix tree" changes zbud
handle to support migration. Now the handle is an index in radix tree and
zbud_map() maps it to a proper virtual address. This exposes race conditions,
some of them are discussed already here:
http://article.gmane.org/gmane.linux.kernel.mm/105988

Races are fixed by adding internal map count for each zbud handle.
The map count is increased on each zbud_map() call.

Some races between writeback and invalidate still exist. In such case a message
can be seen in logs:
  zbud: error: could not lookup handle 13810 in tree
Patches from discussion above may resolve this.

I have considered using "pgoff_t offset" as handle but it prevented storing
duplicate pages in zswap.


This patch set is based on v3.11.


Changes since v1:
-
1. Rebased against v3.11.
2. Updated documentation of zbud_reclaim_page() to match usage of zbud page
   reference counters.
3. Split from patch 2/4 trivial change of scope of freechunks var to separate
   patch (3/5) (suggested by Seth Jennings).


Changes and relation to patches "reclaiming zbud pages on migration and
compaction":
-
This is continuation of my previous work: reclaiming zbud pages on migration
and compaction. However current solution is completely different so I am not
attaching previous changelog.
Previous patches can be found here:
 * [RFC PATCH v2 0/4] mm: reclaim zbud pages on migration and compaction
   http://article.gmane.org/gmane.linux.kernel.mm/105153
 * [RFC PATCH 0/4] mm: reclaim zbud pages on migration and compaction
   http://article.gmane.org/gmane.linux.kernel.mm/104801

One patch from previous work is re-used along with minor changes:
"[PATCH 1/4] zbud: use page ref counter for zbud pages"
 * Add missing spin_unlock in zbud_reclaim_page().
 * Decrease pool->pages_nr in zbud_free(), not when putting page. This also
removes the need of holding lock while call to put_zbud_page().


Best regards,
Krzysztof Kozlowski


Krzysztof Kozlowski (5):
  zbud: use page ref counter for zbud pages
  zbud: make freechunks a block local variable
  mm: use mapcount for identifying zbud pages
  mm: use indirect zbud handle and radix tree
  mm: migrate zbud pages

 include/linux/mm.h   |   23 ++
 include/linux/zbud.h |3 +-
 mm/compaction.c  |7 +
 mm/migrate.c |   17 +-
 mm/zbud.c|  573 --
 mm/zswap.c   |   28 ++-
 6 files changed, 537 insertions(+), 114 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 4/5] mm: use indirect zbud handle and radix tree

2013-09-11 Thread Krzysztof Kozlowski
Add radix tree to zbud pool and use indirect zbud handle as radix tree
index.

This allows migration of zbud pages while the handle used by zswap
remains untouched. Previously zbud handles were virtual addresses. This
imposed problem when page was migrated.

This change also exposes and fixes race condition between:
 - zbud_reclaim_page() (called from zswap_frontswap_store())
and
 - zbud_free() (called from zswap_frontswap_invalidate_page()).
This race was present already but additional locking and in-direct use
handle makes it frequent during high memory pressure.

Race typically looks like:
 - thread 1: zbud_reclaim_page()
   - thread 1: zswap_writeback_entry()
 - zbud_map()
 - thread 0: zswap_frontswap_invalidate_page()
   - zbud_free()
 - thread 1: read zswap_entry from memory or call zbud_unmap(), now on
   invalid memory address

The zbud_reclaim_page() calls evict handler (zswap_writeback_entry())
without holding pool lock. The zswap_writeback_entry() reads
zswap_header from memory obtained from zbud_map() without holding
tree's lock. If invalidate happens during this time the zbud_free()
will remove handle from the tree.

The new map_count fields in zbud_header try to address this problem by
protecting handles from freeing.
Also the call to zbud_unmap() in zswap_writeback_entry() was moved
further - when the tree's lock could be obtained.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/zbud.h |2 +-
 mm/zbud.c|  313 +-
 mm/zswap.c   |   24 +++-
 3 files changed, 280 insertions(+), 59 deletions(-)

diff --git a/include/linux/zbud.h b/include/linux/zbud.h
index 2571a5c..12d72df 100644
--- a/include/linux/zbud.h
+++ b/include/linux/zbud.h
@@ -16,7 +16,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
 void zbud_free(struct zbud_pool *pool, unsigned long handle);
 int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries);
 void *zbud_map(struct zbud_pool *pool, unsigned long handle);
-void zbud_unmap(struct zbud_pool *pool, unsigned long handle);
+int zbud_unmap(struct zbud_pool *pool, unsigned long handle);
 u64 zbud_get_pool_size(struct zbud_pool *pool);
 
 #endif /* _ZBUD_H_ */
diff --git a/mm/zbud.c b/mm/zbud.c
index 9be160c..795d56a 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -69,6 +70,9 @@
 #define NCHUNKS(PAGE_SIZE >> CHUNK_SHIFT)
 #define ZHDR_SIZE_ALIGNED CHUNK_SIZE
 
+/* Empty handle, not yet allocated */
+#define HANDLE_EMPTY   0
+
 /**
  * struct zbud_pool - stores metadata for each zbud pool
  * @lock:  protects all pool fields and first|last_chunk fields of any
@@ -83,6 +87,10 @@
  * @pages_nr:  number of zbud pages in the pool.
  * @ops:   pointer to a structure of user defined operations specified at
  * pool creation time.
+ * @page_tree: mapping handle->zbud_header for zbud_map and migration;
+ * many pools may exist so do not use the mapping->page_tree
+ * @last_handle: last handle calculated; used as starting point when searching
+ * for next handle in page_tree in zbud_alloc().
  *
  * This structure is allocated at pool creation time and maintains metadata
  * pertaining to a particular zbud pool.
@@ -94,6 +102,8 @@ struct zbud_pool {
struct list_head lru;
u64 pages_nr;
struct zbud_ops *ops;
+   struct radix_tree_root page_tree;
+   unsigned long last_handle;
 };
 
 /*
@@ -103,12 +113,23 @@ struct zbud_pool {
  * @lru:   links the zbud page into the lru list in the pool
  * @first_chunks:  the size of the first buddy in chunks, 0 if free
  * @last_chunks:   the size of the last buddy in chunks, 0 if free
+ * @first_handle:  handle to page stored in first buddy
+ * @last_handle:   handle to page stored in last buddy
+ * @first_map_count:   mapped count of page stored in first buddy
+ * @last_map_count:mapped count of page stored in last buddy
+ *
+ * When map count reaches zero the corresponding handle is removed
+ * from radix tree and cannot be used any longer.
  */
 struct zbud_header {
struct list_head buddy;
struct list_head lru;
+   unsigned long first_handle;
+   unsigned long last_handle;
unsigned int first_chunks;
unsigned int last_chunks;
+   short int first_map_count;
+   short int last_map_count;
 };
 
 /*
@@ -135,38 +156,34 @@ static struct zbud_header *init_zbud_page(struct page 
*page)
struct zbud_header *zhdr = page_address(page);
zhdr->first_chunks = 0;
zhdr->last_chunks = 0;
+   zhdr->first_handle = HANDLE_EMPTY;
+   zhdr->last_handle = HANDLE_EMPTY;
+   zhdr->first_map_count = 0;
+   zhdr->last_map_count = 0;
INIT_LIST_HEAD(&zhdr->buddy);
INIT_LIST_HEAD(&zhdr->lru);
return

[PATCH v2 1/5] zbud: use page ref counter for zbud pages

2013-09-11 Thread Krzysztof Kozlowski
Use page reference counter for zbud pages. The ref counter replaces
zbud_header.under_reclaim flag and ensures that zbud page won't be freed
when zbud_free() is called during reclaim. It allows implementation of
additional reclaim paths.

The page count is incremented when:
 - a handle is created and passed to zswap (in zbud_alloc()),
 - user-supplied eviction callback is called (in zbud_reclaim_page()).

Signed-off-by: Krzysztof Kozlowski 
Signed-off-by: Tomasz Stanislawski 
Reviewed-by: Bob Liu 
---
 mm/zbud.c |  117 +
 1 file changed, 64 insertions(+), 53 deletions(-)

diff --git a/mm/zbud.c b/mm/zbud.c
index ad1e781..3f4be72 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -109,7 +109,6 @@ struct zbud_header {
struct list_head lru;
unsigned int first_chunks;
unsigned int last_chunks;
-   bool under_reclaim;
 };
 
 /*
@@ -138,16 +137,9 @@ static struct zbud_header *init_zbud_page(struct page 
*page)
zhdr->last_chunks = 0;
INIT_LIST_HEAD(&zhdr->buddy);
INIT_LIST_HEAD(&zhdr->lru);
-   zhdr->under_reclaim = 0;
return zhdr;
 }
 
-/* Resets the struct page fields and frees the page */
-static void free_zbud_page(struct zbud_header *zhdr)
-{
-   __free_page(virt_to_page(zhdr));
-}
-
 /*
  * Encodes the handle of a particular buddy within a zbud page
  * Pool lock should be held as this function accesses first|last_chunks
@@ -188,6 +180,31 @@ static int num_free_chunks(struct zbud_header *zhdr)
return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks - 1;
 }
 
+/*
+ * Increases ref count for zbud page.
+ */
+static void get_zbud_page(struct zbud_header *zhdr)
+{
+   get_page(virt_to_page(zhdr));
+}
+
+/*
+ * Decreases ref count for zbud page and frees the page if it reaches 0
+ * (no external references, e.g. handles).
+ *
+ * Returns 1 if page was freed and 0 otherwise.
+ */
+static int put_zbud_page(struct zbud_header *zhdr)
+{
+   struct page *page = virt_to_page(zhdr);
+   if (put_page_testzero(page)) {
+   free_hot_cold_page(page, 0);
+   return 1;
+   }
+   return 0;
+}
+
+
 /*
  * API Functions
 */
@@ -273,6 +290,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
bud = FIRST;
else
bud = LAST;
+   get_zbud_page(zhdr);
goto found;
}
}
@@ -284,6 +302,10 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
return -ENOMEM;
spin_lock(&pool->lock);
pool->pages_nr++;
+   /*
+* We will be using zhdr instead of page, so
+* don't increase the page count.
+*/
zhdr = init_zbud_page(page);
bud = FIRST;
 
@@ -318,10 +340,11 @@ found:
  * @pool:  pool in which the allocation resided
  * @handle:handle associated with the allocation returned by zbud_alloc()
  *
- * In the case that the zbud page in which the allocation resides is under
- * reclaim, as indicated by the PG_reclaim flag being set, this function
- * only sets the first|last_chunks to 0.  The page is actually freed
- * once both buddies are evicted (see zbud_reclaim_page() below).
+ * This function sets first|last_chunks to 0, removes zbud header from
+ * appropriate lists (LRU, buddied/unbuddied) and puts the reference count
+ * for it. The page is actually freed once both buddies are evicted
+ * (zbud_free() called on both handles or page reclaim in zbud_reclaim_page()
+ * below).
  */
 void zbud_free(struct zbud_pool *pool, unsigned long handle)
 {
@@ -337,19 +360,11 @@ void zbud_free(struct zbud_pool *pool, unsigned long 
handle)
else
zhdr->first_chunks = 0;
 
-   if (zhdr->under_reclaim) {
-   /* zbud page is under reclaim, reclaim will free */
-   spin_unlock(&pool->lock);
-   return;
-   }
-
/* Remove from existing buddy list */
list_del(&zhdr->buddy);
 
if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) {
-   /* zbud page is empty, free */
list_del(&zhdr->lru);
-   free_zbud_page(zhdr);
pool->pages_nr--;
} else {
/* Add to unbuddied list */
@@ -357,6 +372,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
}
 
+   put_zbud_page(zhdr);
spin_unlock(&pool->lock);
 }
 
@@ -378,21 +394,23 @@ void zbud_free(struct zbud_pool *pool, unsigned long 
handle)
  * To avoid these, this is how zbud_reclaim_page() should be called:
 
  * The user detects a page should be reclaimed and calls zbud_recla

[PATCH v2 5/5] mm: migrate zbud pages

2013-09-11 Thread Krzysztof Kozlowski
Add migration support for zbud. This allows adding __GFP_MOVABLE flag
when allocating zbud pages and effectively CMA pool can be used for
zswap.

zbud pages are not movable and are not stored under any LRU (except
zbud's LRU). PageZbud flag is used in isolate_migratepages_range() to
grab zbud pages and pass them later for migration.

page->private field is used for storing pointer to zbud_pool.
This pointer to zbud_pool is needed during migration for locking the
pool and accessing radix tree.

The zbud migration code utilizes mapping so many exceptions to migrate
code was added. It can be replaced for example with pin page control
subsystem:
http://article.gmane.org/gmane.linux.kernel.mm/105308
In such case the zbud migration code (zbud_migrate_page()) can be safely
re-used.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/zbud.h |1 +
 mm/compaction.c  |7 +++
 mm/migrate.c |   17 +-
 mm/zbud.c|  164 +++---
 mm/zswap.c   |4 +-
 5 files changed, 179 insertions(+), 14 deletions(-)

diff --git a/include/linux/zbud.h b/include/linux/zbud.h
index 12d72df..3bc2e38 100644
--- a/include/linux/zbud.h
+++ b/include/linux/zbud.h
@@ -11,6 +11,7 @@ struct zbud_ops {
 
 struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops);
 void zbud_destroy_pool(struct zbud_pool *pool);
+int zbud_put_page(struct page *page);
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
unsigned long *handle);
 void zbud_free(struct zbud_pool *pool, unsigned long handle);
diff --git a/mm/compaction.c b/mm/compaction.c
index 05ccb4c..8acd198 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -534,6 +534,12 @@ isolate_migratepages_range(struct zone *zone, struct 
compact_control *cc,
goto next_pageblock;
}
 
+   if (PageZbud(page)) {
+   BUG_ON(PageLRU(page));
+   get_page(page);
+   goto isolated;
+   }
+
/*
 * Check may be lockless but that's ok as we recheck later.
 * It's possible to migrate LRU pages and balloon pages
@@ -601,6 +607,7 @@ isolate_migratepages_range(struct zone *zone, struct 
compact_control *cc,
/* Successfully isolated */
cc->finished_update_migrate = true;
del_page_from_lru_list(page, lruvec, page_lru(page));
+isolated:
list_add(&page->lru, migratelist);
cc->nr_migratepages++;
nr_isolated++;
diff --git a/mm/migrate.c b/mm/migrate.c
index 6f0c244..5254eb2 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -105,6 +106,8 @@ void putback_movable_pages(struct list_head *l)
page_is_file_cache(page));
if (unlikely(balloon_page_movable(page)))
balloon_page_putback(page);
+   else if (unlikely(PageZbud(page)))
+   zbud_put_page(page);
else
putback_lru_page(page);
}
@@ -832,6 +835,10 @@ static int __unmap_and_move(struct page *page, struct page 
*newpage,
goto skip_unmap;
}
 
+   if (unlikely(PageZbud(page))) {
+   remap_swapcache = 0;
+   goto skip_unmap;
+   }
/* Establish migration ptes or remove ptes */
try_to_unmap(page, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);
 
@@ -902,13 +909,19 @@ out:
list_del(&page->lru);
dec_zone_page_state(page, NR_ISOLATED_ANON +
page_is_file_cache(page));
-   putback_lru_page(page);
+   if (unlikely(PageZbud(page)))
+   zbud_put_page(page);
+   else
+   putback_lru_page(page);
}
/*
 * Move the new page to the LRU. If migration was not successful
 * then this will free the page.
 */
-   putback_lru_page(newpage);
+   if (unlikely(PageZbud(newpage)))
+   zbud_put_page(newpage);
+   else
+   putback_lru_page(newpage);
if (result) {
if (rc)
*result = rc;
diff --git a/mm/zbud.c b/mm/zbud.c
index 795d56a..de8132d 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -51,6 +51,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 /*
@@ -211,17 +213,9 @@ static void get_zbud_page(struct zbud_header *zhdr)
  *
  * Returns 1 if page was freed and 0 otherwise.
  */
-static int put_zbud_page(struct zbud_header *zhdr)
+static inline int put_zbud_page(struct zbud_header *zhdr)
 {
-   struct page *page = virt_to_page(zhdr);
-   VM_BUG_ON(!PageZbud(page));
-
-   if (put_page_testzero(page)

[PATCH] frontswap: enable call to invalidate area on swapoff

2013-10-07 Thread Krzysztof Kozlowski
During swapoff the frontswap_map was NULL-ified before calling
frontswap_invalidate_area(). However the frontswap_invalidate_area()
exits early if frontswap_map is NULL. Invalidate was never called during
swapoff.

This patch moves frontswap_map_set() in swapoff just after calling
frontswap_invalidate_area() so outside of locks
(swap_lock and swap_info_struct->lock). This shouldn't be a problem as
during swapon the frontswap_map_set() is called also outside of any
locks.

Signed-off-by: Krzysztof Kozlowski 
---
 mm/swapfile.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/swapfile.c b/mm/swapfile.c
index 3963fc2..3a4896b 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1922,10 +1922,10 @@ SYSCALL_DEFINE1(swapoff, const char __user *, 
specialfile)
p->cluster_info = NULL;
p->flags = 0;
frontswap_map = frontswap_map_get(p);
-   frontswap_map_set(p, NULL);
spin_unlock(&p->lock);
spin_unlock(&swap_lock);
frontswap_invalidate_area(type);
+   frontswap_map_set(p, NULL);
mutex_unlock(&swapon_mutex);
free_percpu(p->percpu_cluster);
p->percpu_cluster = NULL;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] frontswap: enable call to invalidate area on swapoff

2013-10-08 Thread Krzysztof Kozlowski
On pon, 2013-10-07 at 15:03 -0700, Andrew Morton wrote:
> On Mon, 07 Oct 2013 17:25:41 +0200 Krzysztof Kozlowski 
>  wrote:
> 
> > During swapoff the frontswap_map was NULL-ified before calling
> > frontswap_invalidate_area(). However the frontswap_invalidate_area()
> > exits early if frontswap_map is NULL. Invalidate was never called during
> > swapoff.
> > 
> > This patch moves frontswap_map_set() in swapoff just after calling
> > frontswap_invalidate_area() so outside of locks
> > (swap_lock and swap_info_struct->lock). This shouldn't be a problem as
> > during swapon the frontswap_map_set() is called also outside of any
> > locks.
> > 
> 
> Ahem.  So there's a bunch of code in __frontswap_invalidate_area()
> which hasn't ever been executed and nobody noticed it.  So perhaps that
> code isn't actually needed?
> 
> More seriously, this patch looks like it enables code which hasn't been
> used or tested before.  How well tested was this?
> 
> Are there any runtime-visible effects from this change?

I tested zswap on x86 and x86-64 and there was no difference. This is
good as there shouldn't be visible anything because swapoff is unusing
all pages anyway:
    try_to_unuse(type, false, 0); /* force all pages to be unused */

I haven't tested other frontswap users.


Best regards,
Krzysztof Kozlowski



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 0/6] mm: migrate zbud pages

2013-10-08 Thread Krzysztof Kozlowski
Hi,

This is third version of patches adding migration of zbud pages with changes
after discussions with Seth:
http://article.gmane.org/gmane.linux.kernel.mm/107695

In patch [PATCH 5/6] I removed the red-black tree in zswap and instead added
a radix tree in zbud. This also lead to removal of the "handle" concept and
to usage of offset as radix tree's index.

This particular change (5/6) still needs some improvements:
1. Accept storing of duplicated pages (as it was in original zswap).
2. Use RCU for radix tree reads and updates.
3. Optimize locking in zbud_free_all().
4. Iterate over LRU list instead of radix tree in zbud_free_all().


Description of patches:
-
Currently zbud pages are not movable and they cannot be allocated from CMA
(Contiguous Memory Allocator) region. These patches add migration of zbud pages.

The zbud migration code utilizes mapping so many exceptions to migrate
code were added. This can be replaced for example with pin page
control subsystem:
http://article.gmane.org/gmane.linux.kernel.mm/105308
In such case the zbud migration code (zbud_migrate_page()) can be safely
re-used.

 * [PATCH 1/6] adds a reference counter to zbud pages.
 * [PATCH 2/6] is a trivial change of scope of local variable.
 * [PATCH 3/6] introduces PageZbud() function which identifies zbud pages by
   page->_mapcount. Dave Hansen proposed aliasing PG_zbud=PG_slab but in such
   case patch would be more intrusive.
   Any ideas for a better solution are welcome.
 * [PATCH 4/6] replaces direct initialization of zbud_header with memset.
 * [PATCH 5/6] replaces zswap's red-black tree with a new radix tree in zbud.
   Offset is used as index to this tree.
 * [PATCH 6/6] implements migration of zbud pages.


This patch set is based on v3.12-rc4-19-g8b5ede6.


Changes since v2:
-
1. Rebased against v3.12-rc4-19-g8b5ede6.
2. Replace zswap's red-black tree with a new radix tree in zbud. Use
   offset as tree's index. Many zbud API changes.
3. Add patch 4/6.

Changes since v1:
-
1. Rebased against v3.11.
2. Updated documentation of zbud_reclaim_page() to match usage of zbud page
   reference counters.
3. Split from patch 2/4 trivial change of scope of freechunks var to separate
   patch (3/5) (suggested by Seth Jennings).


Best regards,
Krzysztof Kozlowski


Krzysztof Kozlowski (6):
  zbud: use page ref counter for zbud pages
  zbud: make freechunks a block local variable
  mm: use mapcount for identifying zbud pages
  zbud: memset zbud_header to 0 during init
  zswap: replace tree in zswap with radix tree in zbud
  mm: migrate zbud pages

 include/linux/mm.h   |   23 ++
 include/linux/zbud.h |   28 ++-
 mm/compaction.c  |7 +
 mm/migrate.c |   17 +-
 mm/zbud.c|  644 +++---
 mm/zswap.c   |  419 ++--
 6 files changed, 643 insertions(+), 495 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 2/6] zbud: make freechunks a block local variable

2013-10-08 Thread Krzysztof Kozlowski
Move freechunks variable in zbud_free() and zbud_alloc() to block-level
scope (from function scope).

Signed-off-by: Krzysztof Kozlowski 
---
 mm/zbud.c |7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/mm/zbud.c b/mm/zbud.c
index 7574289..e19f36a 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -267,7 +267,7 @@ void zbud_destroy_pool(struct zbud_pool *pool)
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
unsigned long *handle)
 {
-   int chunks, i, freechunks;
+   int chunks, i;
struct zbud_header *zhdr = NULL;
enum buddy bud;
struct page *page;
@@ -317,7 +317,7 @@ found:
 
if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0) {
/* Add to unbuddied list */
-   freechunks = num_free_chunks(zhdr);
+   int freechunks = num_free_chunks(zhdr);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
} else {
/* Add to buddied list */
@@ -349,7 +349,6 @@ found:
 void zbud_free(struct zbud_pool *pool, unsigned long handle)
 {
struct zbud_header *zhdr;
-   int freechunks;
 
spin_lock(&pool->lock);
zhdr = handle_to_zbud_header(handle);
@@ -368,7 +367,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
pool->pages_nr--;
} else {
/* Add to unbuddied list */
-   freechunks = num_free_chunks(zhdr);
+   int freechunks = num_free_chunks(zhdr);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
}
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 3/6] mm: use mapcount for identifying zbud pages

2013-10-08 Thread Krzysztof Kozlowski
Currently zbud pages do not have any flags set so it is not possible to
identify them during migration or compaction.

Implement PageZbud() by comparing page->_mapcount to -127 to distinguish
pages allocated by zbud. Just like PageBuddy() is implemented.

Signed-off-by: Krzysztof Kozlowski 
Reviewed-by: Seth Jennings 
---
 include/linux/mm.h |   23 +++
 mm/zbud.c  |4 
 2 files changed, 27 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index 8b6e55e..4307429 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -447,6 +447,7 @@ static inline void init_page_count(struct page *page)
  * efficiently by most CPU architectures.
  */
 #define PAGE_BUDDY_MAPCOUNT_VALUE (-128)
+#define PAGE_ZBUD_MAPCOUNT_VALUE (-127)
 
 static inline int PageBuddy(struct page *page)
 {
@@ -465,6 +466,28 @@ static inline void __ClearPageBuddy(struct page *page)
atomic_set(&page->_mapcount, -1);
 }
 
+#ifdef CONFIG_ZBUD
+static inline int PageZbud(struct page *page)
+{
+   return atomic_read(&page->_mapcount) == PAGE_ZBUD_MAPCOUNT_VALUE;
+}
+
+static inline void SetPageZbud(struct page *page)
+{
+   VM_BUG_ON(atomic_read(&page->_mapcount) != -1);
+   atomic_set(&page->_mapcount, PAGE_ZBUD_MAPCOUNT_VALUE);
+}
+
+static inline void ClearPageZbud(struct page *page)
+{
+   VM_BUG_ON(!PageZbud(page));
+   atomic_set(&page->_mapcount, -1);
+}
+#else
+PAGEFLAG_FALSE(Zbud)
+#endif
+
+
 void put_page(struct page *page);
 void put_pages_list(struct list_head *pages);
 
diff --git a/mm/zbud.c b/mm/zbud.c
index e19f36a..6db0557 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -197,7 +197,10 @@ static void get_zbud_page(struct zbud_header *zhdr)
 static int put_zbud_page(struct zbud_header *zhdr)
 {
struct page *page = virt_to_page(zhdr);
+   VM_BUG_ON(!PageZbud(page));
+
if (put_page_testzero(page)) {
+   ClearPageZbud(page);
free_hot_cold_page(page, 0);
return 1;
}
@@ -307,6 +310,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
 * don't increase the page count.
 */
zhdr = init_zbud_page(page);
+   SetPageZbud(page);
bud = FIRST;
 
 found:
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 6/6] mm: migrate zbud pages

2013-10-08 Thread Krzysztof Kozlowski
Add migration support for zbud. This allows adding __GFP_MOVABLE flag
when allocating zbud pages and effectively CMA pool can be used for
zswap.

zbud pages are not movable and are not stored under any LRU (except
zbud's LRU). PageZbud flag is used in isolate_migratepages_range() to
grab zbud pages and pass them later for migration.

page->private field is used for storing pointer to zbud_pool.
This pointer to zbud_pool is needed during migration for locking the
pool and accessing radix tree.

The zbud migration code utilizes mapping so many exceptions to migrate
code was added. It can be replaced for example with pin page control
subsystem:
http://article.gmane.org/gmane.linux.kernel.mm/105308
In such case the zbud migration code (zbud_migrate_page()) can be safely
re-used.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/zbud.h |1 +
 mm/compaction.c  |7 +++
 mm/migrate.c |   17 -
 mm/zbud.c|  168 +++---
 mm/zswap.c   |4 +-
 5 files changed, 183 insertions(+), 14 deletions(-)

diff --git a/include/linux/zbud.h b/include/linux/zbud.h
index c4e091a..2ac00da 100644
--- a/include/linux/zbud.h
+++ b/include/linux/zbud.h
@@ -23,6 +23,7 @@ struct zbud_mapped_entry {
 
 struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops);
 void zbud_destroy_pool(struct zbud_pool *pool);
+int zbud_put_page(struct page *page);
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
pgoff_t offset);
 int zbud_free(struct zbud_pool *pool, pgoff_t offset);
diff --git a/mm/compaction.c b/mm/compaction.c
index b5326b1..1806a0b 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -534,6 +534,12 @@ isolate_migratepages_range(struct zone *zone, struct 
compact_control *cc,
goto next_pageblock;
}
 
+   if (PageZbud(page)) {
+   BUG_ON(PageLRU(page));
+   get_page(page);
+   goto isolated;
+   }
+
/*
 * Check may be lockless but that's ok as we recheck later.
 * It's possible to migrate LRU pages and balloon pages
@@ -601,6 +607,7 @@ isolate_migratepages_range(struct zone *zone, struct 
compact_control *cc,
/* Successfully isolated */
cc->finished_update_migrate = true;
del_page_from_lru_list(page, lruvec, page_lru(page));
+isolated:
list_add(&page->lru, migratelist);
cc->nr_migratepages++;
nr_isolated++;
diff --git a/mm/migrate.c b/mm/migrate.c
index a26bccd..40e9ae4 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -109,6 +110,8 @@ void putback_movable_pages(struct list_head *l)
page_is_file_cache(page));
if (unlikely(isolated_balloon_page(page)))
balloon_page_putback(page);
+   else if (unlikely(PageZbud(page)))
+   zbud_put_page(page);
else
putback_lru_page(page);
}
@@ -836,6 +839,10 @@ static int __unmap_and_move(struct page *page, struct page 
*newpage,
goto skip_unmap;
}
 
+   if (unlikely(PageZbud(page))) {
+   remap_swapcache = 0;
+   goto skip_unmap;
+   }
/* Establish migration ptes or remove ptes */
try_to_unmap(page, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);
 
@@ -906,13 +913,19 @@ out:
list_del(&page->lru);
dec_zone_page_state(page, NR_ISOLATED_ANON +
page_is_file_cache(page));
-   putback_lru_page(page);
+   if (unlikely(PageZbud(page)))
+   zbud_put_page(page);
+   else
+   putback_lru_page(page);
}
/*
 * Move the new page to the LRU. If migration was not successful
 * then this will free the page.
 */
-   putback_lru_page(newpage);
+   if (unlikely(PageZbud(newpage)))
+   zbud_put_page(newpage);
+   else
+   putback_lru_page(newpage);
if (result) {
if (rc)
*result = rc;
diff --git a/mm/zbud.c b/mm/zbud.c
index 1b2496e..7c07683 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -51,6 +51,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 /*
@@ -202,17 +204,9 @@ static void get_zbud_page(struct zbud_header *zhdr)
  *
  * Returns 1 if page was freed and 0 otherwise.
  */
-static int put_zbud_page(struct zbud_header *zhdr)
+static inline int put_zbud_page(struct zbud_header *zhdr)
 {
-   struct page *page = virt_to_page(zhdr);
-   VM_BUG_ON(!PageZbud(page));
-
-   if (put_page_testzero(page)

[PATCH v3 4/6] zbud: memset zbud_header to 0 during init

2013-10-08 Thread Krzysztof Kozlowski
memset zbud_header to 0 during init instead of manually assigning 0 to
members. Currently only two members needs to be initialized to 0 but
further patches will add more of them.

Signed-off-by: Krzysztof Kozlowski 
---
 mm/zbud.c |3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/mm/zbud.c b/mm/zbud.c
index 6db0557..0edd880 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -133,8 +133,7 @@ static int size_to_chunks(int size)
 static struct zbud_header *init_zbud_page(struct page *page)
 {
struct zbud_header *zhdr = page_address(page);
-   zhdr->first_chunks = 0;
-   zhdr->last_chunks = 0;
+   memset(zhdr, 0, sizeof(*zhdr));
INIT_LIST_HEAD(&zhdr->buddy);
INIT_LIST_HEAD(&zhdr->lru);
return zhdr;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 5/6] zswap: replace tree in zswap with radix tree in zbud

2013-10-08 Thread Krzysztof Kozlowski
This allows migration of zbud pages.

Add radix tree to zbud replacing the red-black tree in zswap. Use
offset as index to this tree so effectively the handle concept is not
needed anymore. Zswap uses only offset to access data stored in zbud.

Functionality of red-black tree from zswap was merged into zbud's radix
tree.

The patch changes the way of storing duplicated pages. Now zswap refused
to store them.

This change also exposes and fixes race condition between:
 - zbud_reclaim_page() (called from zswap_frontswap_store())
and
 - zbud_free() (called from zswap_frontswap_invalidate_page()).
This race was present already but additional locking and in-direct use
of handle makes it frequent during high memory pressure.

Race typically looks like:
 - thread 1: zbud_reclaim_page()
   - thread 1: zswap_writeback_entry()
 - zbud_map()
 - thread 0: zswap_frontswap_invalidate_page()
   - zbud_free()
 - thread 1: read zswap_entry from memory or call zbud_unmap(), now on
   invalid memory address

The zbud_reclaim_page() calls evict handler (zswap_writeback_entry())
without holding pool lock. The zswap_writeback_entry() reads
memory under address obtained from zbud_map() without any lock held.
If invalidate happens during this time the zbud_free() will remove handle
from the tree and zbud_unmap() won't succeed.

The new map_count fields in zbud_header try to address this problem by
protecting handles from freeing.

Still are some things to do in this patch:
1. Accept storing of duplicated pages (as it was in original zswap).
2. Use RCU for radix tree reads and updates.
3. Optimize locking in zbud_free_all().
4. Iterate over LRU list instead of radix tree in zbud_free_all().

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/zbud.h |   27 +++-
 mm/zbud.c|  387 +++---
 mm/zswap.c   |  419 +-
 3 files changed, 388 insertions(+), 445 deletions(-)

diff --git a/include/linux/zbud.h b/include/linux/zbud.h
index 2571a5c..c4e091a 100644
--- a/include/linux/zbud.h
+++ b/include/linux/zbud.h
@@ -6,17 +6,32 @@
 struct zbud_pool;
 
 struct zbud_ops {
-   int (*evict)(struct zbud_pool *pool, unsigned long handle);
+   int (*evict)(struct zbud_pool *pool, pgoff_t offset, unsigned int type);
+};
+
+/*
+ * One entry stored in zbud, mapped and valid only between
+ * zbud_map() and zbud_unmap() calls.
+ *
+ * length  - length of stored data (compressed)
+ * addr- mapped address where compressed data resides
+ */
+struct zbud_mapped_entry {
+   unsigned int length;
+   void *addr;
 };
 
 struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops);
 void zbud_destroy_pool(struct zbud_pool *pool);
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
-   unsigned long *handle);
-void zbud_free(struct zbud_pool *pool, unsigned long handle);
-int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries);
-void *zbud_map(struct zbud_pool *pool, unsigned long handle);
-void zbud_unmap(struct zbud_pool *pool, unsigned long handle);
+   pgoff_t offset);
+int zbud_free(struct zbud_pool *pool, pgoff_t offset);
+int zbud_free_all(struct zbud_pool *pool);
+int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries,
+   unsigned int type);
+int zbud_map(struct zbud_pool *pool, pgoff_t offset,
+   struct zbud_mapped_entry *entry);
+int zbud_unmap(struct zbud_pool *pool, pgoff_t offset);
 u64 zbud_get_pool_size(struct zbud_pool *pool);
 
 #endif /* _ZBUD_H_ */
diff --git a/mm/zbud.c b/mm/zbud.c
index 0edd880..1b2496e 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -34,10 +34,10 @@
  * zbud page.
  *
  * The zbud API differs from that of conventional allocators in that the
- * allocation function, zbud_alloc(), returns an opaque handle to the user,
- * not a dereferenceable pointer.  The user must map the handle using
+ * allocation function, zbud_alloc(), allocates memory for given offset and
+ * does not return dereferenceable pointer. The user must map the offset using
  * zbud_map() in order to get a usable pointer by which to access the
- * allocation data and unmap the handle with zbud_unmap() when operations
+ * allocation data and unmap the offset with zbud_unmap() when operations
  * on the allocation data are complete.
  */
 
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -83,6 +84,8 @@
  * @pages_nr:  number of zbud pages in the pool.
  * @ops:   pointer to a structure of user defined operations specified at
  * pool creation time.
+ * @tree:  mapping offset->zbud_header for zbud_map and migration;
+ * many pools may exist so do not use the mapping->page_tree
  *
  * This structure is allocated at pool creation time and maintains metadata
  * pertaining to a particular zbud pool.
@@ -94,6 +97,7 @@ struct zbud_pool {
struct list_head lru;
u64 pages_nr

[PATCH v3 1/6] zbud: use page ref counter for zbud pages

2013-10-08 Thread Krzysztof Kozlowski
Use page reference counter for zbud pages. The ref counter replaces
zbud_header.under_reclaim flag and ensures that zbud page won't be freed
when zbud_free() is called during reclaim. It allows implementation of
additional reclaim paths.

The page count is incremented when:
 - a handle is created and passed to zswap (in zbud_alloc()),
 - user-supplied eviction callback is called (in zbud_reclaim_page()).

Signed-off-by: Krzysztof Kozlowski 
Signed-off-by: Tomasz Stanislawski 
Reviewed-by: Bob Liu 
---
 mm/zbud.c |  117 +
 1 file changed, 64 insertions(+), 53 deletions(-)

diff --git a/mm/zbud.c b/mm/zbud.c
index 9451361..7574289 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -109,7 +109,6 @@ struct zbud_header {
struct list_head lru;
unsigned int first_chunks;
unsigned int last_chunks;
-   bool under_reclaim;
 };
 
 /*
@@ -138,16 +137,9 @@ static struct zbud_header *init_zbud_page(struct page 
*page)
zhdr->last_chunks = 0;
INIT_LIST_HEAD(&zhdr->buddy);
INIT_LIST_HEAD(&zhdr->lru);
-   zhdr->under_reclaim = 0;
return zhdr;
 }
 
-/* Resets the struct page fields and frees the page */
-static void free_zbud_page(struct zbud_header *zhdr)
-{
-   __free_page(virt_to_page(zhdr));
-}
-
 /*
  * Encodes the handle of a particular buddy within a zbud page
  * Pool lock should be held as this function accesses first|last_chunks
@@ -188,6 +180,31 @@ static int num_free_chunks(struct zbud_header *zhdr)
return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks - 1;
 }
 
+/*
+ * Increases ref count for zbud page.
+ */
+static void get_zbud_page(struct zbud_header *zhdr)
+{
+   get_page(virt_to_page(zhdr));
+}
+
+/*
+ * Decreases ref count for zbud page and frees the page if it reaches 0
+ * (no external references, e.g. handles).
+ *
+ * Returns 1 if page was freed and 0 otherwise.
+ */
+static int put_zbud_page(struct zbud_header *zhdr)
+{
+   struct page *page = virt_to_page(zhdr);
+   if (put_page_testzero(page)) {
+   free_hot_cold_page(page, 0);
+   return 1;
+   }
+   return 0;
+}
+
+
 /*
  * API Functions
 */
@@ -273,6 +290,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
bud = FIRST;
else
bud = LAST;
+   get_zbud_page(zhdr);
goto found;
}
}
@@ -284,6 +302,10 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
return -ENOMEM;
spin_lock(&pool->lock);
pool->pages_nr++;
+   /*
+* We will be using zhdr instead of page, so
+* don't increase the page count.
+*/
zhdr = init_zbud_page(page);
bud = FIRST;
 
@@ -318,10 +340,11 @@ found:
  * @pool:  pool in which the allocation resided
  * @handle:handle associated with the allocation returned by zbud_alloc()
  *
- * In the case that the zbud page in which the allocation resides is under
- * reclaim, as indicated by the PG_reclaim flag being set, this function
- * only sets the first|last_chunks to 0.  The page is actually freed
- * once both buddies are evicted (see zbud_reclaim_page() below).
+ * This function sets first|last_chunks to 0, removes zbud header from
+ * appropriate lists (LRU, buddied/unbuddied) and puts the reference count
+ * for it. The page is actually freed once both buddies are evicted
+ * (zbud_free() called on both handles or page reclaim in zbud_reclaim_page()
+ * below).
  */
 void zbud_free(struct zbud_pool *pool, unsigned long handle)
 {
@@ -337,19 +360,11 @@ void zbud_free(struct zbud_pool *pool, unsigned long 
handle)
else
zhdr->first_chunks = 0;
 
-   if (zhdr->under_reclaim) {
-   /* zbud page is under reclaim, reclaim will free */
-   spin_unlock(&pool->lock);
-   return;
-   }
-
/* Remove from existing buddy list */
list_del(&zhdr->buddy);
 
if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) {
-   /* zbud page is empty, free */
list_del(&zhdr->lru);
-   free_zbud_page(zhdr);
pool->pages_nr--;
} else {
/* Add to unbuddied list */
@@ -357,6 +372,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
}
 
+   put_zbud_page(zhdr);
spin_unlock(&pool->lock);
 }
 
@@ -378,21 +394,23 @@ void zbud_free(struct zbud_pool *pool, unsigned long 
handle)
  * To avoid these, this is how zbud_reclaim_page() should be called:
 
  * The user detects a page should be reclaimed and calls zbud_recla

Re: [PATCH v3 1/6] zbud: use page ref counter for zbud pages

2013-10-09 Thread Krzysztof Kozlowski
On wto, 2013-10-08 at 15:43 -0500, Seth Jennings wrote:
> On Tue, Oct 08, 2013 at 03:29:35PM +0200, Krzysztof Kozlowski wrote:
> > Use page reference counter for zbud pages. The ref counter replaces
> > zbud_header.under_reclaim flag and ensures that zbud page won't be freed
> > when zbud_free() is called during reclaim. It allows implementation of
> > additional reclaim paths.
> > 
> > The page count is incremented when:
> >  - a handle is created and passed to zswap (in zbud_alloc()),
> >  - user-supplied eviction callback is called (in zbud_reclaim_page()).
> > 
> > Signed-off-by: Krzysztof Kozlowski 
> > Signed-off-by: Tomasz Stanislawski 
> > Reviewed-by: Bob Liu 
> 
> Other than the nit below:
> 
> Acked-by: Seth Jennings 
Thank you for ACK-s (here and in other patches).


> > ---
> >  mm/zbud.c |  117 
> > +
> >  1 file changed, 64 insertions(+), 53 deletions(-)
> > 
> > diff --git a/mm/zbud.c b/mm/zbud.c
> > index 9451361..7574289 100644
> > --- a/mm/zbud.c
> > +++ b/mm/zbud.c
> > @@ -109,7 +109,6 @@ struct zbud_header {
> > struct list_head lru;
> > unsigned int first_chunks;
> > unsigned int last_chunks;
> > -   bool under_reclaim;
> >  };
> > 
> >  /*
> > @@ -138,16 +137,9 @@ static struct zbud_header *init_zbud_page(struct page 
> > *page)
> > zhdr->last_chunks = 0;
> > INIT_LIST_HEAD(&zhdr->buddy);
> > INIT_LIST_HEAD(&zhdr->lru);
> > -   zhdr->under_reclaim = 0;
> > return zhdr;
> >  }
> > 
> > -/* Resets the struct page fields and frees the page */
> > -static void free_zbud_page(struct zbud_header *zhdr)
> > -{
> > -   __free_page(virt_to_page(zhdr));
> > -}
> > -
> >  /*
> >   * Encodes the handle of a particular buddy within a zbud page
> >   * Pool lock should be held as this function accesses first|last_chunks
> > @@ -188,6 +180,31 @@ static int num_free_chunks(struct zbud_header *zhdr)
> > return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks - 1;
> >  }
> > 
> > +/*
> > + * Increases ref count for zbud page.
> > + */
> > +static void get_zbud_page(struct zbud_header *zhdr)
> > +{
> > +   get_page(virt_to_page(zhdr));
> > +}
> > +
> > +/*
> > + * Decreases ref count for zbud page and frees the page if it reaches 0
> > + * (no external references, e.g. handles).
> > + *
> > + * Returns 1 if page was freed and 0 otherwise.
> > + */
> > +static int put_zbud_page(struct zbud_header *zhdr)
> > +{
> > +   struct page *page = virt_to_page(zhdr);
> > +   if (put_page_testzero(page)) {
> > +   free_hot_cold_page(page, 0);
> > +   return 1;
> > +   }
> > +   return 0;
> > +}
> > +
> > +
> >  /*
> >   * API Functions
> >  */
> > @@ -273,6 +290,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t 
> > gfp,
> > bud = FIRST;
> > else
> > bud = LAST;
> > +   get_zbud_page(zhdr);
> > goto found;
> > }
> > }
> > @@ -284,6 +302,10 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t 
> > gfp,
> > return -ENOMEM;
> > spin_lock(&pool->lock);
> > pool->pages_nr++;
> > +   /*
> > +* We will be using zhdr instead of page, so
> > +* don't increase the page count.
> > +*/
> 
> This comment isn't very clear.  I think what you mean to say is that
> we already have the page ref'ed for this entry because of the initial
> ref count done by alloc_page().
> 
> So maybe:
> 
> /*
>  * Page count is incremented by alloc_page() for the initial
>  * reference so no need to call zbud_get_page() here.
>  */

Good point. I'll change it.

Best regards,
Krzysztof

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 5/6] zswap: replace tree in zswap with radix tree in zbud

2013-10-10 Thread Krzysztof Kozlowski
On Wed, 2013-10-09 at 12:16 -0500, Seth Jennings wrote:
> On Wed, Oct 09, 2013 at 10:30:22AM -0500, Seth Jennings wrote:
> > In my approach, I was also looking at allowing the zbud pools to use
> > HIGHMEM pages, since the handle is no longer an address.  This requires
> > the pages that are being mapped to be kmapped (atomic) which will
> > disable preemption.  This isn't an additional overhead since the
> > map/unmap corresponds with a compress/decompress operation at the zswap
> > level which uses per-cpu variables that disable preemption already.
> 
> On second though, lets not mess with the HIGHMEM page support for now.
> Turns out it is tricker than I thought since the unbuddied lists are
> linked through the zbud header stored in the page.  But we can still
> disable preemption to allow per-cpu tracking of the current mapping and
> avoid a lookup (and races) in zbud_unmap().

This tracking of current mapping could solve another problem I
encountered with new one-radix-tree approach with storage of duplicated
entries.

The problem is in zbud_unmap() API using offset to unmap (if duplicated
entries are overwritten):
 - thread 1: zswap_fronstwap_load() of some offset
   - zbud_map() maps this offset -> zhdr1
 - thread 2: zswap_frontswap_store() stores new data for this offset 
   - zbud_alloc() allocated new zhdr2 and replaces zhdr1 in radix tree 
 under this offset
   - new compressed data is stored by zswap
 - thread 1: tries to zbud_unmap() of this offset, but now the old
   zhdr1 is not present in radix tree so unmap will either fail or use
   zhdr2 which is wrong

To solve this issue I experimented with unmapping by zbud_mapped_entry
instead of offset (so zbud_unmap() won't search zbud_header in radix
tree at all):
##
int zbud_unmap(struct zbud_pool *pool, pgoff_t offset,
struct zbud_mapped_entry *entry)
{
struct zbud_header *zhdr = handle_to_zbud_header((unsigned
long)entry->addr);

VM_BUG_ON((offset != zhdr->first_offset) && (offset !=
zhdr->last_offset));
spin_lock(&pool->lock);
if (put_map_count(zhdr, offset)) {
/* Racing zbud_free() could not free the offset because
 * it was still mapped so it is our job to free. */
zbud_header_free(pool, zhdr, offset);
spin_unlock(&pool->lock);
return -EFAULT;
}
put_zbud_page(zhdr);
spin_unlock(&pool->lock);
return 0;
}
##

However getting rid of first/last_map_count seems much more simpler! 

Best regards,
Krzysztof


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 0/4] mm: migrate zbud pages

2013-08-30 Thread Krzysztof Kozlowski
Hi,

Currently zbud pages are not movable and they cannot be allocated from CMA
region. These patches add migration of zbud pages.

The zbud migration code utilizes mapping so many exceptions to migrate
code was added. It can be replaced for example with pin page
control subsystem:
http://article.gmane.org/gmane.linux.kernel.mm/105308
In such case the zbud migration code (zbud_migrate_page()) can be safely
re-used.


Patch "[PATCH 3/4] mm: use indirect zbud handle and radix tree" changes zbud
handle to support migration. Now the handle is an index in radix tree and
zbud_map() maps it to proper virtual address. This exposes race conditions,
some of them are discussed already here:
http://article.gmane.org/gmane.linux.kernel.mm/105988

Races are fixed by adding internal map count for each zbud handle.
The map count is increased on zbud_map() call.

Some races between writeback and invalidate still exist. In such case a message
can be seen in logs:
  zbud: error: could not lookup handle 13810 in tree
Patches from discussion above may resolve it.

I have considered using "pgoff_t offset" as handle but it prevented storing
duplicate pages in zswap.


Patch "[PATCH 2/4] mm: use mapcount for identifying zbud pages" introduces
PageZbud() function which identifies zbud pages by page->_mapcount.
Dave Hansen proposed aliasing PG_zbud=PG_slab but in such case patch
would be more intrusive.

Any ideas for a better solution are welcome.


This patch set is based on v3.11-rc7-30-g41615e8.


This is continuation of my previous work: reclaiming zbud pages on migration
and compaction. However it current solution is completely different so I am not
attaching previous changelog.
Previous patches can be found here:
 * [RFC PATCH v2 0/4] mm: reclaim zbud pages on migration and compaction
   http://article.gmane.org/gmane.linux.kernel.mm/105153
 * [RFC PATCH 0/4] mm: reclaim zbud pages on migration and compaction
   http://article.gmane.org/gmane.linux.kernel.mm/104801

One patch from previous work is re-used along with minor changes:
"[PATCH 1/4] zbud: use page ref counter for zbud pages"
 * Add missing spin_unlock in zbud_reclaim_page().
 * Decrease pool->pages_nr in zbud_free(), not when putting page. This also
removes the need of holding lock while call to put_zbud_page().


Best regards,
Krzysztof Kozlowski


Krzysztof Kozlowski (4):
  zbud: use page ref counter for zbud pages
  mm: use mapcount for identifying zbud pages
  mm: use indirect zbud handle and radix tree
  mm: migrate zbud pages

 include/linux/mm.h   |   23 +++
 include/linux/zbud.h |3 +-
 mm/compaction.c  |7 +
 mm/migrate.c |   17 +-
 mm/zbud.c|  552 +-
 mm/zswap.c   |   28 ++-
 6 files changed, 525 insertions(+), 105 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 2/4] mm: use mapcount for identifying zbud pages

2013-08-30 Thread Krzysztof Kozlowski
Currently zbud pages do not have any flags set so it is not possible to
identify them during migration or compaction.

Implement PageZbud() by comparing page->_mapcount to -127 to distinguish
pages allocated by zbud. Just like PageBuddy() is implemented.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/mm.h |   23 +++
 mm/zbud.c  |4 
 2 files changed, 27 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index f022460..b9ae6f2 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -440,6 +440,7 @@ static inline void init_page_count(struct page *page)
  * efficiently by most CPU architectures.
  */
 #define PAGE_BUDDY_MAPCOUNT_VALUE (-128)
+#define PAGE_ZBUD_MAPCOUNT_VALUE (-127)
 
 static inline int PageBuddy(struct page *page)
 {
@@ -458,6 +459,28 @@ static inline void __ClearPageBuddy(struct page *page)
atomic_set(&page->_mapcount, -1);
 }
 
+#ifdef CONFIG_ZBUD
+static inline int PageZbud(struct page *page)
+{
+   return atomic_read(&page->_mapcount) == PAGE_ZBUD_MAPCOUNT_VALUE;
+}
+
+static inline void SetPageZbud(struct page *page)
+{
+   VM_BUG_ON(atomic_read(&page->_mapcount) != -1);
+   atomic_set(&page->_mapcount, PAGE_ZBUD_MAPCOUNT_VALUE);
+}
+
+static inline void ClearPageZbud(struct page *page)
+{
+   VM_BUG_ON(!PageZbud(page));
+   atomic_set(&page->_mapcount, -1);
+}
+#else
+PAGEFLAG_FALSE(Zbud)
+#endif
+
+
 void put_page(struct page *page);
 void put_pages_list(struct list_head *pages);
 
diff --git a/mm/zbud.c b/mm/zbud.c
index aa9a15c..9267cd9 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -197,7 +197,10 @@ static void get_zbud_page(struct zbud_header *zhdr)
 static int put_zbud_page(struct zbud_header *zhdr)
 {
struct page *page = virt_to_page(zhdr);
+   VM_BUG_ON(!PageZbud(page));
+
if (put_page_testzero(page)) {
+   ClearPageZbud(page);
free_hot_cold_page(page, 0);
return 1;
}
@@ -307,6 +310,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
 * don't increase the page count.
 */
zhdr = init_zbud_page(page);
+   SetPageZbud(page);
bud = FIRST;
 
 found:
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 4/4] mm: migrate zbud pages

2013-08-30 Thread Krzysztof Kozlowski
Add migration support for zbud. This allows adding __GFP_MOVABLE flag
when allocating zbud pages and effectively CMA pool can be used for
zswap.

zbud pages are not movable and are not stored under any LRU (except
zbud's LRU). PageZbud flag is used in isolate_migratepages_range() to
grab zbud pages and pass them later for migration.

page->private field is used for storing pointer to zbud_pool.
The zbud_pool is needed during migration for locking the pool and
accessing radix tree.

The zbud migration code utilizes mapping so many exceptions to migrate
code was added. It can be replaced for example with pin page control
subsystem:
http://article.gmane.org/gmane.linux.kernel.mm/105308
In such case the zbud migration code (zbud_migrate_page()) can be safely
re-used.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/zbud.h |1 +
 mm/compaction.c  |7 +++
 mm/migrate.c |   17 +-
 mm/zbud.c|  164 +++---
 mm/zswap.c   |4 +-
 5 files changed, 179 insertions(+), 14 deletions(-)

diff --git a/include/linux/zbud.h b/include/linux/zbud.h
index 12d72df..3bc2e38 100644
--- a/include/linux/zbud.h
+++ b/include/linux/zbud.h
@@ -11,6 +11,7 @@ struct zbud_ops {
 
 struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops);
 void zbud_destroy_pool(struct zbud_pool *pool);
+int zbud_put_page(struct page *page);
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
unsigned long *handle);
 void zbud_free(struct zbud_pool *pool, unsigned long handle);
diff --git a/mm/compaction.c b/mm/compaction.c
index 05ccb4c..8acd198 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -534,6 +534,12 @@ isolate_migratepages_range(struct zone *zone, struct 
compact_control *cc,
goto next_pageblock;
}
 
+   if (PageZbud(page)) {
+   BUG_ON(PageLRU(page));
+   get_page(page);
+   goto isolated;
+   }
+
/*
 * Check may be lockless but that's ok as we recheck later.
 * It's possible to migrate LRU pages and balloon pages
@@ -601,6 +607,7 @@ isolate_migratepages_range(struct zone *zone, struct 
compact_control *cc,
/* Successfully isolated */
cc->finished_update_migrate = true;
del_page_from_lru_list(page, lruvec, page_lru(page));
+isolated:
list_add(&page->lru, migratelist);
cc->nr_migratepages++;
nr_isolated++;
diff --git a/mm/migrate.c b/mm/migrate.c
index 6f0c244..5254eb2 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -105,6 +106,8 @@ void putback_movable_pages(struct list_head *l)
page_is_file_cache(page));
if (unlikely(balloon_page_movable(page)))
balloon_page_putback(page);
+   else if (unlikely(PageZbud(page)))
+   zbud_put_page(page);
else
putback_lru_page(page);
}
@@ -832,6 +835,10 @@ static int __unmap_and_move(struct page *page, struct page 
*newpage,
goto skip_unmap;
}
 
+   if (unlikely(PageZbud(page))) {
+   remap_swapcache = 0;
+   goto skip_unmap;
+   }
/* Establish migration ptes or remove ptes */
try_to_unmap(page, TTU_MIGRATION|TTU_IGNORE_MLOCK|TTU_IGNORE_ACCESS);
 
@@ -902,13 +909,19 @@ out:
list_del(&page->lru);
dec_zone_page_state(page, NR_ISOLATED_ANON +
page_is_file_cache(page));
-   putback_lru_page(page);
+   if (unlikely(PageZbud(page)))
+   zbud_put_page(page);
+   else
+   putback_lru_page(page);
}
/*
 * Move the new page to the LRU. If migration was not successful
 * then this will free the page.
 */
-   putback_lru_page(newpage);
+   if (unlikely(PageZbud(newpage)))
+   zbud_put_page(newpage);
+   else
+   putback_lru_page(newpage);
if (result) {
if (rc)
*result = rc;
diff --git a/mm/zbud.c b/mm/zbud.c
index 5ff4ffa..63f0a91 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -51,6 +51,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 /*
@@ -211,17 +213,9 @@ static void get_zbud_page(struct zbud_header *zhdr)
  *
  * Returns 1 if page was freed and 0 otherwise.
  */
-static int put_zbud_page(struct zbud_header *zhdr)
+static inline int put_zbud_page(struct zbud_header *zhdr)
 {
-   struct page *page = virt_to_page(zhdr);
-   VM_BUG_ON(!PageZbud(page));
-
-   if (put_page_testzero(page)

[RFC PATCH 3/4] mm: use indirect zbud handle and radix tree

2013-08-30 Thread Krzysztof Kozlowski
Add radix tree to zbud pool and use indirect zbud handle as radix tree
index.

This allows migration of zbud pages while the handle used by zswap
remains untouched. Previously zbud handles were virtual addresses. This
imposed problem when page was migrated.

This change also exposes and fixes race condition between:
 - zbud_reclaim_page() (called from zswap_frontswap_store())
and
 - zbud_free() (called from zswap_frontswap_invalidate_page()).
This race was present already but additional locking and in-direct use
handle makes it frequent during high memory pressure.

Race typically looks like:
 - thread 1: zbud_reclaim_page()
   - thread 1: zswap_writeback_entry()
 - zbud_map()
 - thread 0: zswap_frontswap_invalidate_page()
   - zbud_free()
 - thread 1: read zswap_entry from memory or call zbud_unmap(), now on
   invalid memory address

The zbud_reclaim_page() calls evict function (zswap_writeback_entry())
without holding pool lock. The zswap_writeback_entry() reads
zswap_header from memory obtained from zbud_map() without holding
tree's lock. If invalidate happens during this time the zbud_free()
will remove handle from the tree.

The new map_count fields in zbud_header try to address this problem by
protecting handles from freeing.
Also the call to zbud_unmap() in zswap_writeback_entry() was moved
further - when the tree's lock could be obtained.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/zbud.h |2 +-
 mm/zbud.c|  313 +-
 mm/zswap.c   |   24 +++-
 3 files changed, 280 insertions(+), 59 deletions(-)

diff --git a/include/linux/zbud.h b/include/linux/zbud.h
index 2571a5c..12d72df 100644
--- a/include/linux/zbud.h
+++ b/include/linux/zbud.h
@@ -16,7 +16,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
 void zbud_free(struct zbud_pool *pool, unsigned long handle);
 int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries);
 void *zbud_map(struct zbud_pool *pool, unsigned long handle);
-void zbud_unmap(struct zbud_pool *pool, unsigned long handle);
+int zbud_unmap(struct zbud_pool *pool, unsigned long handle);
 u64 zbud_get_pool_size(struct zbud_pool *pool);
 
 #endif /* _ZBUD_H_ */
diff --git a/mm/zbud.c b/mm/zbud.c
index 9267cd9..5ff4ffa 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /*
@@ -69,6 +70,9 @@
 #define NCHUNKS(PAGE_SIZE >> CHUNK_SHIFT)
 #define ZHDR_SIZE_ALIGNED CHUNK_SIZE
 
+/* Empty handle, not yet allocated */
+#define HANDLE_EMPTY   0
+
 /**
  * struct zbud_pool - stores metadata for each zbud pool
  * @lock:  protects all pool fields and first|last_chunk fields of any
@@ -83,6 +87,10 @@
  * @pages_nr:  number of zbud pages in the pool.
  * @ops:   pointer to a structure of user defined operations specified at
  * pool creation time.
+ * @page_tree: mapping handle->zbud_header for zbud_map and migration;
+ * many pools may exist so do not use the mapping->page_tree
+ * @last_handle: last handle calculated; used as starting point when searching
+ * for next handle in page_tree in zbud_alloc.
  *
  * This structure is allocated at pool creation time and maintains metadata
  * pertaining to a particular zbud pool.
@@ -94,6 +102,8 @@ struct zbud_pool {
struct list_head lru;
u64 pages_nr;
struct zbud_ops *ops;
+   struct radix_tree_root page_tree;
+   unsigned long last_handle;
 };
 
 /*
@@ -103,12 +113,23 @@ struct zbud_pool {
  * @lru:   links the zbud page into the lru list in the pool
  * @first_chunks:  the size of the first buddy in chunks, 0 if free
  * @last_chunks:   the size of the last buddy in chunks, 0 if free
+ * @first_handle:  handle to page stored in first buddy
+ * @last_handle:   handle to page stored in last buddy
+ * @first_map_count:   mapped count of page stored in first buddy
+ * @last_map_count:mapped count of page stored in last buddy
+ *
+ * When map count reaches zero the corresponding handle is removed
+ * from radix tree and cannot be used any longer.
  */
 struct zbud_header {
struct list_head buddy;
struct list_head lru;
+   unsigned long first_handle;
+   unsigned long last_handle;
unsigned int first_chunks;
unsigned int last_chunks;
+   short int first_map_count;
+   short int last_map_count;
 };
 
 /*
@@ -135,38 +156,34 @@ static struct zbud_header *init_zbud_page(struct page 
*page)
struct zbud_header *zhdr = page_address(page);
zhdr->first_chunks = 0;
zhdr->last_chunks = 0;
+   zhdr->first_handle = HANDLE_EMPTY;
+   zhdr->last_handle = HANDLE_EMPTY;
+   zhdr->first_map_count = 0;
+   zhdr->last_map_count = 0;
INIT_LIST_HEAD(&zhdr->buddy);
INIT_LIST_HEAD(&zhdr->lru);
return

[RFC PATCH 1/4] zbud: use page ref counter for zbud pages

2013-08-30 Thread Krzysztof Kozlowski
Use page reference counter for zbud pages. The ref counter replaces
zbud_header.under_reclaim flag and ensures that zbud page won't be freed
when zbud_free() is called during reclaim. It allows implementation of
additional reclaim paths.

The page count is incremented when:
 - a handle is created and passed to zswap (in zbud_alloc()),
 - user-supplied eviction callback is called (in zbud_reclaim_page()).

Signed-off-by: Krzysztof Kozlowski 
Signed-off-by: Tomasz Stanislawski 
Reviewed-by: Bob Liu 
---
 mm/zbud.c |   97 +
 1 file changed, 52 insertions(+), 45 deletions(-)

diff --git a/mm/zbud.c b/mm/zbud.c
index ad1e781..aa9a15c 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -109,7 +109,6 @@ struct zbud_header {
struct list_head lru;
unsigned int first_chunks;
unsigned int last_chunks;
-   bool under_reclaim;
 };
 
 /*
@@ -138,16 +137,9 @@ static struct zbud_header *init_zbud_page(struct page 
*page)
zhdr->last_chunks = 0;
INIT_LIST_HEAD(&zhdr->buddy);
INIT_LIST_HEAD(&zhdr->lru);
-   zhdr->under_reclaim = 0;
return zhdr;
 }
 
-/* Resets the struct page fields and frees the page */
-static void free_zbud_page(struct zbud_header *zhdr)
-{
-   __free_page(virt_to_page(zhdr));
-}
-
 /*
  * Encodes the handle of a particular buddy within a zbud page
  * Pool lock should be held as this function accesses first|last_chunks
@@ -188,6 +180,31 @@ static int num_free_chunks(struct zbud_header *zhdr)
return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks - 1;
 }
 
+/*
+ * Increases ref count for zbud page.
+ */
+static void get_zbud_page(struct zbud_header *zhdr)
+{
+   get_page(virt_to_page(zhdr));
+}
+
+/*
+ * Decreases ref count for zbud page and frees the page if it reaches 0
+ * (no external references, e.g. handles).
+ *
+ * Returns 1 if page was freed and 0 otherwise.
+ */
+static int put_zbud_page(struct zbud_header *zhdr)
+{
+   struct page *page = virt_to_page(zhdr);
+   if (put_page_testzero(page)) {
+   free_hot_cold_page(page, 0);
+   return 1;
+   }
+   return 0;
+}
+
+
 /*
  * API Functions
 */
@@ -250,7 +267,7 @@ void zbud_destroy_pool(struct zbud_pool *pool)
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
unsigned long *handle)
 {
-   int chunks, i, freechunks;
+   int chunks, i;
struct zbud_header *zhdr = NULL;
enum buddy bud;
struct page *page;
@@ -273,6 +290,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
bud = FIRST;
else
bud = LAST;
+   get_zbud_page(zhdr);
goto found;
}
}
@@ -284,6 +302,10 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
return -ENOMEM;
spin_lock(&pool->lock);
pool->pages_nr++;
+   /*
+* We will be using zhdr instead of page, so
+* don't increase the page count.
+*/
zhdr = init_zbud_page(page);
bud = FIRST;
 
@@ -295,7 +317,7 @@ found:
 
if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0) {
/* Add to unbuddied list */
-   freechunks = num_free_chunks(zhdr);
+   int freechunks = num_free_chunks(zhdr);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
} else {
/* Add to buddied list */
@@ -326,7 +348,6 @@ found:
 void zbud_free(struct zbud_pool *pool, unsigned long handle)
 {
struct zbud_header *zhdr;
-   int freechunks;
 
spin_lock(&pool->lock);
zhdr = handle_to_zbud_header(handle);
@@ -337,26 +358,19 @@ void zbud_free(struct zbud_pool *pool, unsigned long 
handle)
else
zhdr->first_chunks = 0;
 
-   if (zhdr->under_reclaim) {
-   /* zbud page is under reclaim, reclaim will free */
-   spin_unlock(&pool->lock);
-   return;
-   }
-
/* Remove from existing buddy list */
list_del(&zhdr->buddy);
 
if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) {
-   /* zbud page is empty, free */
list_del(&zhdr->lru);
-   free_zbud_page(zhdr);
pool->pages_nr--;
} else {
/* Add to unbuddied list */
-   freechunks = num_free_chunks(zhdr);
+   int freechunks = num_free_chunks(zhdr);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
}
 
+   put_zbud_page(zhdr);
spin_unlock(&pool->lock);
 }
 
@@ -400,7 +414,7 @@ void zbud_free(struct zbud_pool *pool, unsigned lo

Re: [PATCH v2 0/5] mm: migrate zbud pages

2013-09-30 Thread Krzysztof Kozlowski
On pią, 2013-09-27 at 17:00 -0500, Seth Jennings wrote:
> I have to say that when I first came up with the idea, I was thinking
> the address space would be at the zswap layer and the radix slots would
> hold zbud handles, not struct page pointers.
> 
> However, as I have discovered today, this is problematic when it comes
> to reclaim and migration and serializing access.
> 
> I wanted to do as much as possible in the zswap layer since anything
> done in the zbud layer would need to be duplicated in any other future
> allocator that zswap wanted to support.
> 
> Unfortunately, zbud abstracts away the struct page and that visibility
> is needed to properly do what we are talking about.
> 
> So maybe it is inevitable that this will need to be in the zbud code
> with the radix tree slots pointing to struct pages after all.

To me it looks very similar to the solution proposed in my patches. The
difference is that you wish to use offset as radix tree index.
I thought about this earlier but it imposed two problems:

1. A generalized handle (instead of offset) may be more suitable when
zbud will be used in other drivers (e.g. zram).

2. It requires redesigning of zswap architecture around
zswap_frontswap_store() in case of duplicated insertion. Currently when
storing a page the zswap:
 - allocates zbud page,
 - stores new data in it,
 - checks whether it is a duplicated page (same offset present in
rbtree),
 - if yes (duplicated) then zswap frees previous entry.
The problem here lies in allocating zbud page under the same offset.
This step would replace old data (because we are using the same offset
in radix tree).

In my opinion using zbud handle is in this case more flexible.


Best regards,
Krzysztof

> I like the idea of masking the bit into the struct page pointer to
> indicate which buddy maps to the offset.
> 
> There is a twist here in that, unlike a normal page cache tree, we can
> have two offsets pointing at different buddies in the same frame
> which means we'll have to do some custom stuff for migration.
> 
> The rabbit hole I was going down today has come to an end so I'll take a
> fresh look next week.
> 
> Thanks for your ideas and discussion! Maybe we can make zswap/zbud an
> upstanding MM citizen yet!
> 
> Seth
> 
> > 
> > >>
> > >> In case of zbud, there are two swap offset pointing to
> > >> the same page. There might be more if zsmalloc is used.
> > >> What is worse it is possible that one swap entry could
> > >> point to data that cross a page boundary.
> > > 
> > > We just won't set page->index since it doesn't have a good meaning in
> > > our case.  Swap cache pages also don't use index, although is seems to
> > > me that they could since there is a 1:1 mapping of a swap cache page to
> > > a swap offset and the index field isn't being used for anything else.
> > > But I digress...
> > 
> > OK.
> > 
> > > 
> > >>
> > >> Of course, one could try to modify MM to support
> > >> multiple mapping of a page in the radix tree.
> > >> But I think that MM guys will consider this as a hack
> > >> and they will not accept it.
> > > 
> > > Yes, it will require some changes to the MM to handle zbud pages on the
> > > LRU.  I'm thinking that it won't be too intrusive, depending on how we
> > > choose to mark zbud pages.
> > > 
> > 
> > Anyway, I think that zswap should use two index engines.
> > I mean index in Data Base meaning.
> > One index is used to translate swap_entry to compressed page.
> > And another one to be used by reclaim and migration by MM,
> > probably address_space is a best choice.
> > Zbud would responsible for keeping consistency
> > between mentioned indexes.
> > 
> > Regards,
> > Tomasz Stanislawski
> > 
> > > Seth
> > > 
> > >>
> > >> Regards,
> > >> Tomasz Stanislawski
> > >>
> > >>
> > >>> --
> > >>> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> > >>> the body to majord...@kvack.org.  For more info on Linux MM,
> > >>> see: http://www.linux-mm.org/ .
> > >>> Don't email: mailto:"d...@kvack.org";> em...@kvack.org 
> > >>>
> > >>
> > > 
> > > --
> > > To unsubscribe, send a message with 'unsubscribe linux-mm' in
> > > the body to majord...@kvack.org.  For more info on Linux MM,
> > > see: http://www.linux-mm.org/ .
> > > Don't email: mailto:"d...@kvack.org";> em...@kvack.org 
> > > 
> > 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 0/5] mm: migrate zbud pages

2013-09-24 Thread Krzysztof Kozlowski
Hi,

On pon, 2013-09-23 at 17:07 -0500, Seth Jennings wrote:
> On Tue, Sep 17, 2013 at 02:59:24PM +0800, Bob Liu wrote:
> > Mel mentioned several problems about zswap/zbud in thread "[PATCH v6
> > 0/5] zram/zsmalloc promotion".
> > 
> > Like "it's clunky as hell and the layering between zswap and zbud is
> > twisty" and "I think I brought up its stalling behaviour during review
> > when it was being merged. It would have been preferable if writeback
> > could be initiated in batches and then waited on at the very least..
> >  It's worse that it uses _swap_writepage directly instead of going
> > through a writepage ops.  It would have been better if zbud pages
> > existed on the LRU and written back with an address space ops and
> > properly handled asynchonous writeback."
> > 
> > So I think it would be better if we can address those issues at first
> > and it would be easier to address these issues before adding more new
> > features. Welcome any ideas.
> 
> I just had an idea this afternoon to potentially kill both these birds with 
> one
> stone: Replace the rbtree in zswap with an address_space.
> 
> Each swap type would have its own page_tree to organize the compressed objects
> by type and offset (radix tree is more suited for this anyway) and a_ops that
> could be called by shrink_page_list() (writepage) or the migration code
> (migratepage).
> 
> Then zbud pages could be put on the normal LRU list, maybe at the beginning of
> the inactive LRU so they would live for another cycle through the list, then 
> be
> reclaimed in the normal way with the mapping->a_ops->writepage() pointing to a
> zswap_writepage() function that would decompress the pages and call
> __swap_writepage() on them.

How exactly the address space can be used here? Do you want to point to
zbud pages in address_space.page_tree? If yes then which index should be
used?


Best regards,
Krzysztof



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 1/4] zbud: use page ref counter for zbud pages

2013-08-05 Thread Krzysztof Kozlowski
Use page reference counter for zbud pages. The ref counter replaces
zbud_header.under_reclaim flag and ensures that zbud page won't be freed
when zbud_free() is called during reclaim. It allows implementation of
additional reclaim paths.

The page count is incremented when:
 - a handle is created and passed to zswap (in zbud_alloc()),
 - user-supplied eviction callback is called (in zbud_reclaim_page()).

Signed-off-by: Krzysztof Kozlowski 
Signed-off-by: Tomasz Stanislawski 
---
 mm/zbud.c |  150 +++--
 1 file changed, 86 insertions(+), 64 deletions(-)

diff --git a/mm/zbud.c b/mm/zbud.c
index ad1e781..a8e986f 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -109,7 +109,6 @@ struct zbud_header {
struct list_head lru;
unsigned int first_chunks;
unsigned int last_chunks;
-   bool under_reclaim;
 };
 
 /*
@@ -138,16 +137,9 @@ static struct zbud_header *init_zbud_page(struct page 
*page)
zhdr->last_chunks = 0;
INIT_LIST_HEAD(&zhdr->buddy);
INIT_LIST_HEAD(&zhdr->lru);
-   zhdr->under_reclaim = 0;
return zhdr;
 }
 
-/* Resets the struct page fields and frees the page */
-static void free_zbud_page(struct zbud_header *zhdr)
-{
-   __free_page(virt_to_page(zhdr));
-}
-
 /*
  * Encodes the handle of a particular buddy within a zbud page
  * Pool lock should be held as this function accesses first|last_chunks
@@ -188,6 +180,65 @@ static int num_free_chunks(struct zbud_header *zhdr)
return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks - 1;
 }
 
+/*
+ * Called after zbud_free() or zbud_alloc().
+ * Checks whether given zbud page has to be:
+ *  - removed from buddied/unbuddied/LRU lists completetely (zbud_free).
+ *  - moved from buddied to unbuddied list
+ *and to beginning of LRU (zbud_alloc, zbud_free),
+ *  - added to buddied list and LRU (zbud_alloc),
+ *
+ * The page must be already removed from buddied/unbuddied lists.
+ * Must be called under pool->lock.
+ */
+static void rebalance_lists(struct zbud_pool *pool, struct zbud_header *zhdr)
+{
+   if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) {
+   /* zbud_free() */
+   list_del(&zhdr->lru);
+   return;
+   } else if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0) {
+   /* zbud_free() or zbud_alloc() */
+   int freechunks = num_free_chunks(zhdr);
+   list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
+   } else {
+   /* zbud_alloc() */
+   list_add(&zhdr->buddy, &pool->buddied);
+   }
+   /* Add/move zbud page to beginning of LRU */
+   if (!list_empty(&zhdr->lru))
+   list_del(&zhdr->lru);
+   list_add(&zhdr->lru, &pool->lru);
+}
+
+/*
+ * Increases ref count for zbud page.
+ */
+static void get_zbud_page(struct zbud_header *zhdr)
+{
+   get_page(virt_to_page(zhdr));
+}
+
+/*
+ * Decreases ref count for zbud page and frees the page if it reaches 0
+ * (no external references, e.g. handles).
+ *
+ * Must be called under pool->lock.
+ *
+ * Returns 1 if page was freed and 0 otherwise.
+ */
+static int put_zbud_page(struct zbud_pool *pool, struct zbud_header *zhdr)
+{
+   struct page *page = virt_to_page(zhdr);
+   if (put_page_testzero(page)) {
+   free_hot_cold_page(page, 0);
+   pool->pages_nr--;
+   return 1;
+   }
+   return 0;
+}
+
+
 /*
  * API Functions
 */
@@ -250,7 +301,7 @@ void zbud_destroy_pool(struct zbud_pool *pool)
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
unsigned long *handle)
 {
-   int chunks, i, freechunks;
+   int chunks, i;
struct zbud_header *zhdr = NULL;
enum buddy bud;
struct page *page;
@@ -273,6 +324,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
bud = FIRST;
else
bud = LAST;
+   get_zbud_page(zhdr);
goto found;
}
}
@@ -284,6 +336,10 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
return -ENOMEM;
spin_lock(&pool->lock);
pool->pages_nr++;
+   /*
+* We will be using zhdr instead of page, so
+* don't increase the page count.
+*/
zhdr = init_zbud_page(page);
bud = FIRST;
 
@@ -293,19 +349,7 @@ found:
else
zhdr->last_chunks = chunks;
 
-   if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0) {
-   /* Add to unbuddied list */
-   freechunks = num_free_chunks(zhdr);
-   list_add(&zhdr->buddy, &pool->unbu

[RFC PATCH 2/4] mm: split code for unusing swap entries from try_to_unuse

2013-08-05 Thread Krzysztof Kozlowski
Move out the code for unusing swap entries from loop in try_to_unuse()
to separate function: try_to_unuse_swp_entry(). Export this new function
in swapfile.h just like try_to_unuse() is exported.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/swapfile.h |2 +
 mm/swapfile.c|  354 --
 2 files changed, 187 insertions(+), 169 deletions(-)

diff --git a/include/linux/swapfile.h b/include/linux/swapfile.h
index e282624..68c24a7 100644
--- a/include/linux/swapfile.h
+++ b/include/linux/swapfile.h
@@ -9,5 +9,7 @@ extern spinlock_t swap_lock;
 extern struct swap_list_t swap_list;
 extern struct swap_info_struct *swap_info[];
 extern int try_to_unuse(unsigned int, bool, unsigned long);
+extern int try_to_unuse_swp_entry(struct mm_struct **start_mm,
+   struct swap_info_struct *si, swp_entry_t entry);
 
 #endif /* _LINUX_SWAPFILE_H */
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 36af6ee..331d0b8 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1100,6 +1100,189 @@ static unsigned int find_next_to_unuse(struct 
swap_info_struct *si,
 }
 
 /*
+ * Returns:
+ *  - negative on error,
+ *  - 0 on success (entry unused)
+ */
+int try_to_unuse_swp_entry(struct mm_struct **start_mm,
+   struct swap_info_struct *si, swp_entry_t entry)
+{
+   pgoff_t offset = swp_offset(entry);
+   unsigned char *swap_map;
+   unsigned char swcount;
+   struct page *page;
+   int retval = 0;
+
+   if (signal_pending(current)) {
+   retval = -EINTR;
+   goto out;
+   }
+
+   /*
+* Get a page for the entry, using the existing swap
+* cache page if there is one.  Otherwise, get a clean
+* page and read the swap into it.
+*/
+   swap_map = &si->swap_map[offset];
+   page = read_swap_cache_async(entry,
+   GFP_HIGHUSER_MOVABLE, NULL, 0);
+   if (!page) {
+   /*
+* Either swap_duplicate() failed because entry
+* has been freed independently, and will not be
+* reused since sys_swapoff() already disabled
+* allocation from here, or alloc_page() failed.
+*/
+   if (!*swap_map)
+   retval = 0;
+   else
+   retval = -ENOMEM;
+   goto out;
+   }
+
+   /*
+* Don't hold on to start_mm if it looks like exiting.
+*/
+   if (atomic_read(&(*start_mm)->mm_users) == 1) {
+   mmput(*start_mm);
+   *start_mm = &init_mm;
+   atomic_inc(&init_mm.mm_users);
+   }
+
+   /*
+* Wait for and lock page.  When do_swap_page races with
+* try_to_unuse, do_swap_page can handle the fault much
+* faster than try_to_unuse can locate the entry.  This
+* apparently redundant "wait_on_page_locked" lets try_to_unuse
+* defer to do_swap_page in such a case - in some tests,
+* do_swap_page and try_to_unuse repeatedly compete.
+*/
+   wait_on_page_locked(page);
+   wait_on_page_writeback(page);
+   lock_page(page);
+   wait_on_page_writeback(page);
+
+   /*
+* Remove all references to entry.
+*/
+   swcount = *swap_map;
+   if (swap_count(swcount) == SWAP_MAP_SHMEM) {
+   retval = shmem_unuse(entry, page);
+   VM_BUG_ON(retval > 0);
+   /* page has already been unlocked and released */
+   goto out;
+   }
+   if (swap_count(swcount) && *start_mm != &init_mm)
+   retval = unuse_mm(*start_mm, entry, page);
+
+   if (swap_count(*swap_map)) {
+   int set_start_mm = (*swap_map >= swcount);
+   struct list_head *p = &(*start_mm)->mmlist;
+   struct mm_struct *new_start_mm = *start_mm;
+   struct mm_struct *prev_mm = *start_mm;
+   struct mm_struct *mm;
+
+   atomic_inc(&new_start_mm->mm_users);
+   atomic_inc(&prev_mm->mm_users);
+   spin_lock(&mmlist_lock);
+   while (swap_count(*swap_map) && !retval &&
+   (p = p->next) != &(*start_mm)->mmlist) {
+   mm = list_entry(p, struct mm_struct, mmlist);
+   if (!atomic_inc_not_zero(&mm->mm_users))
+   continue;
+   spin_unlock(&mmlist_lock);
+   mmput(prev_mm);
+   prev_mm = mm;
+
+   cond_resched();
+
+   swcount = *swap_map;
+   if (!swap_count(swcount)) /* any usage ? */
+   ;
+   else if (mm == &init_mm)
+  

[RFC PATCH 0/4] mm: reclaim zbud pages on migration and compaction

2013-08-05 Thread Krzysztof Kozlowski
Hi,

Currently zbud pages are not movable and they cannot be allocated from CMA
region. These patches try to address the problem by:
1. Adding a new form of reclaim of zbud pages.
2. Reclaiming zbud pages during migration and compaction.
3. Allocating zbud pages with __GFP_RECLAIMABLE flag.

This reclaim process is different than zbud_reclaim_page(). It acts more
like swapoff() by trying to unuse pages stored in zbud page and bring
them back to memory. The standard zbud_reclaim_page() on the other hand
tries to write them back.

One of patches introduces a new flag: PageZbud. This flag is used in
isolate_migratepages_range() to grab zbud pages and pass them later
for reclaim. Probably this could be replaced with something
smarter than a flag used only in one case.
Any ideas for a better solution are welcome.

This patch set is based on Linux 3.11-rc4.

TODOs:
1. Replace PageZbud flag with other solution.

Best regards,
Krzysztof Kozlowski


Krzysztof Kozlowski (4):
  zbud: use page ref counter for zbud pages
  mm: split code for unusing swap entries from try_to_unuse
  mm: add zbud flag to page flags
  mm: reclaim zbud pages on migration and compaction

 include/linux/page-flags.h |   12 ++
 include/linux/swapfile.h   |2 +
 include/linux/zbud.h   |   11 +-
 mm/compaction.c|   20 ++-
 mm/internal.h  |1 +
 mm/page_alloc.c|9 ++
 mm/swapfile.c  |  354 +++-
 mm/zbud.c  |  301 +
 mm/zswap.c |   57 ++-
 9 files changed, 499 insertions(+), 268 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 3/4] mm: add zbud flag to page flags

2013-08-05 Thread Krzysztof Kozlowski
Add PageZbud flag to page flags to distinguish pages allocated in zbud.
Currently these pages do not have any flags set.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/page-flags.h |   12 
 mm/page_alloc.c|3 +++
 mm/zbud.c  |4 
 3 files changed, 19 insertions(+)

diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 6d53675..5b8b61a6 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -109,6 +109,12 @@ enum pageflags {
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
PG_compound_lock,
 #endif
+#ifdef CONFIG_ZBUD
+   /* Allocated by zbud. Flag is necessary to find zbud pages to unuse
+* during migration/compaction.
+*/
+   PG_zbud,
+#endif
__NR_PAGEFLAGS,
 
/* Filesystems */
@@ -275,6 +281,12 @@ PAGEFLAG_FALSE(HWPoison)
 #define __PG_HWPOISON 0
 #endif
 
+#ifdef CONFIG_ZBUD
+PAGEFLAG(Zbud, zbud)
+#else
+PAGEFLAG_FALSE(Zbud)
+#endif
+
 u64 stable_page_flags(struct page *page);
 
 static inline int PageUptodate(struct page *page)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index b100255..1a120fb 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6345,6 +6345,9 @@ static const struct trace_print_flags pageflag_names[] = {
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
{1UL << PG_compound_lock,   "compound_lock" },
 #endif
+#ifdef CONFIG_ZBUD
+   {1UL << PG_zbud,"zbud"  },
+#endif
 };
 
 static void dump_page_flags(unsigned long flags)
diff --git a/mm/zbud.c b/mm/zbud.c
index a8e986f..a452949 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -230,7 +230,10 @@ static void get_zbud_page(struct zbud_header *zhdr)
 static int put_zbud_page(struct zbud_pool *pool, struct zbud_header *zhdr)
 {
struct page *page = virt_to_page(zhdr);
+   BUG_ON(!PageZbud(page));
+
if (put_page_testzero(page)) {
+   ClearPageZbud(page);
free_hot_cold_page(page, 0);
pool->pages_nr--;
return 1;
@@ -341,6 +344,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
 * don't increase the page count.
 */
zhdr = init_zbud_page(page);
+   SetPageZbud(page);
bud = FIRST;
 
 found:
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH 4/4] mm: reclaim zbud pages on migration and compaction

2013-08-05 Thread Krzysztof Kozlowski
Reclaim zbud pages during migration and compaction by unusing stored
data. This allows adding__GFP_RECLAIMABLE flag when allocating zbud
pages and effectively CMA pool can be used for zswap.

zbud pages are not movable and are not stored under any LRU (except
zbud's LRU). PageZbud flag is used in isolate_migratepages_range() to
grab zbud pages and pass them later for reclaim.

This reclaim process is different than zbud_reclaim_page(). It acts more
like swapoff() by trying to unuse pages stored in zbud page and bring
them back to memory. The standard zbud_reclaim_page() on the other hand
tries to write them back.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/zbud.h |   11 +++-
 mm/compaction.c  |   20 ++-
 mm/internal.h|1 +
 mm/page_alloc.c  |6 ++
 mm/zbud.c|  163 +++---
 mm/zswap.c   |   57 --
 6 files changed, 215 insertions(+), 43 deletions(-)

diff --git a/include/linux/zbud.h b/include/linux/zbud.h
index 2571a5c..57ee85d 100644
--- a/include/linux/zbud.h
+++ b/include/linux/zbud.h
@@ -5,8 +5,14 @@
 
 struct zbud_pool;
 
+/**
+ * Template for functions called during reclaim.
+ */
+typedef int (*evict_page_t)(struct zbud_pool *pool, unsigned long handle);
+
 struct zbud_ops {
-   int (*evict)(struct zbud_pool *pool, unsigned long handle);
+   evict_page_t evict; /* callback for zbud_reclaim_lru_page() */
+   evict_page_t unuse; /* callback for zbud_reclaim_pages() */
 };
 
 struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops);
@@ -14,7 +20,8 @@ void zbud_destroy_pool(struct zbud_pool *pool);
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
unsigned long *handle);
 void zbud_free(struct zbud_pool *pool, unsigned long handle);
-int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries);
+int zbud_reclaim_lru_page(struct zbud_pool *pool, unsigned int retries);
+void zbud_reclaim_pages(struct list_head *zbud_pages);
 void *zbud_map(struct zbud_pool *pool, unsigned long handle);
 void zbud_unmap(struct zbud_pool *pool, unsigned long handle);
 u64 zbud_get_pool_size(struct zbud_pool *pool);
diff --git a/mm/compaction.c b/mm/compaction.c
index 05ccb4c..9bbf412 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "internal.h"
 
 #ifdef CONFIG_COMPACTION
@@ -534,6 +535,17 @@ isolate_migratepages_range(struct zone *zone, struct 
compact_control *cc,
goto next_pageblock;
}
 
+   if (PageZbud(page)) {
+   /*
+* Zbud pages do not exist in LRU so we must
+* check for Zbud flag before PageLRU() below.
+*/
+   BUG_ON(PageLRU(page));
+   get_page(page);
+   list_add(&page->lru, &cc->zbudpages);
+   continue;
+   }
+
/*
 * Check may be lockless but that's ok as we recheck later.
 * It's possible to migrate LRU pages and balloon pages
@@ -810,7 +822,10 @@ static isolate_migrate_t isolate_migratepages(struct zone 
*zone,
low_pfn = isolate_migratepages_range(zone, cc, low_pfn, end_pfn, false);
if (!low_pfn || cc->contended)
return ISOLATE_ABORT;
-
+#ifdef CONFIG_ZBUD
+   if (!list_empty(&cc->zbudpages))
+   zbud_reclaim_pages(&cc->zbudpages);
+#endif
cc->migrate_pfn = low_pfn;
 
return ISOLATE_SUCCESS;
@@ -1023,11 +1038,13 @@ static unsigned long compact_zone_order(struct zone 
*zone,
};
INIT_LIST_HEAD(&cc.freepages);
INIT_LIST_HEAD(&cc.migratepages);
+   INIT_LIST_HEAD(&cc.zbudpages);
 
ret = compact_zone(zone, &cc);
 
VM_BUG_ON(!list_empty(&cc.freepages));
VM_BUG_ON(!list_empty(&cc.migratepages));
+   VM_BUG_ON(!list_empty(&cc.zbudpages));
 
*contended = cc.contended;
return ret;
@@ -1105,6 +1122,7 @@ static void __compact_pgdat(pg_data_t *pgdat, struct 
compact_control *cc)
cc->zone = zone;
INIT_LIST_HEAD(&cc->freepages);
INIT_LIST_HEAD(&cc->migratepages);
+   INIT_LIST_HEAD(&cc->zbudpages);
 
if (cc->order == -1 || !compaction_deferred(zone, cc->order))
compact_zone(zone, cc);
diff --git a/mm/internal.h b/mm/internal.h
index 4390ac6..eaf5c884 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -119,6 +119,7 @@ struct compact_control {
unsigned long nr_migratepages;  /* Number of pages to migrate */
unsigned long free_pfn; /* isolate_freepages search base */
unsigned long migrate_pfn;  /* isolate_migrat

Re: [RFC PATCH 1/4] zbud: use page ref counter for zbud pages

2013-08-06 Thread Krzysztof Kozlowski
Hi Bob,

Thank you for review.

On wto, 2013-08-06 at 17:00 +0800, Bob Liu wrote:
> Nit picker, how about change the name to adjust_lists() or something
> like this because we don't do any rebalancing.

OK, I'll change it.

Best regards,
Krzysztof


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 0/4] mm: reclaim zbud pages on migration and compaction

2013-08-06 Thread Krzysztof Kozlowski
On wto, 2013-08-06 at 17:16 +0800, Bob Liu wrote:
> On 08/06/2013 02:42 PM, Krzysztof Kozlowski wrote:
> > This reclaim process is different than zbud_reclaim_page(). It acts more
> > like swapoff() by trying to unuse pages stored in zbud page and bring
> > them back to memory. The standard zbud_reclaim_page() on the other hand
> > tries to write them back.
> 
> I prefer to migrate zbud pages directly if it's possible than reclaiming
> them during compaction.

I think it is possible however it would be definitely more complex. In
case of migration the zswap handles should be updated as they are just
virtual addresses. Am I right?

Best regards,
Krzysztof


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] [TRIVIAL] ARM: msm: fix compilation error in gpiomux

2013-08-06 Thread Krzysztof Kozlowski
Fix compilation error in gpiomux (CONFIG_MSM_GPIOMUX=y):
arch/arm/mach-msm/gpiomux.c:24:13: error: static declaration of
‘__msm_gpiomux_write’ follows non-static declaration
arch/arm/mach-msm/gpiomux.h:85:6: note: previous declaration of
‘__msm_gpiomux_write’ was here

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/mach-msm/gpiomux.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
index 2b8e2d2..4110b82 100644
--- a/arch/arm/mach-msm/gpiomux.c
+++ b/arch/arm/mach-msm/gpiomux.c
@@ -21,7 +21,7 @@
 
 static DEFINE_SPINLOCK(gpiomux_lock);
 
-static void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
+void __msm_gpiomux_write(unsigned gpio, gpiomux_config_t val)
 {
unsigned tlmm_config  = (val & ~GPIOMUX_CTL_MASK) |
((gpio & 0x3ff) << 4);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 3/4] mm: add zbud flag to page flags

2013-08-07 Thread Krzysztof Kozlowski
On wto, 2013-08-06 at 09:58 -0700, Dave Hansen wrote:
> On 08/05/2013 11:42 PM, Krzysztof Kozlowski wrote:
> > +#ifdef CONFIG_ZBUD
> > +   /* Allocated by zbud. Flag is necessary to find zbud pages to unuse
> > +* during migration/compaction.
> > +*/
> > +   PG_zbud,
> > +#endif
> 
> Do you _really_ need an absolutely new, unshared page flag?
> The zbud code doesn't really look like it uses any of the space in
> 'struct page'.
> 
> I think you could pretty easily alias PG_zbud=PG_slab, then use the
> page->{private,slab_cache} (or some other unused field) in 'struct page'
> to store a cookie to differentiate slab and zbud pages.

Thanks for idea, I will try that.

Best regards,
Krzysztof


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 1/4] zbud: use page ref counter for zbud pages

2013-08-07 Thread Krzysztof Kozlowski
Hi Seth,

On wto, 2013-08-06 at 13:51 -0500, Seth Jennings wrote:
> I like the idea.  I few things below.  Also agree with Bob the
> s/rebalance/adjust/ for rebalance_lists().
OK.

> s/else if/if/ since the if above returns if true.
Sure.

> > +   /* zbud_free() or zbud_alloc() */
> > +   int freechunks = num_free_chunks(zhdr);
> > +   list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
> > +   } else {
> > +   /* zbud_alloc() */
> > +   list_add(&zhdr->buddy, &pool->buddied);
> > +   }
> > +   /* Add/move zbud page to beginning of LRU */
> > +   if (!list_empty(&zhdr->lru))
> > +   list_del(&zhdr->lru);
> 
> We don't want to reinsert to the LRU list if we have called zbud_free()
> on a zbud page that previously had two buddies.  This code causes the
> zbud page to move to the front of the LRU list which is not what we want.

Right, I'll fix it.


> > @@ -326,10 +370,10 @@ found:
> >  void zbud_free(struct zbud_pool *pool, unsigned long handle)
> >  {
> > struct zbud_header *zhdr;
> > -   int freechunks;
> > 
> > spin_lock(&pool->lock);
> > zhdr = handle_to_zbud_header(handle);
> > +   BUG_ON(zhdr->last_chunks == 0 && zhdr->first_chunks == 0);
> 
> Not sure we need this.  Maybe, at most, VM_BUG_ON()?

Actually it is somehow a leftover after debugging so I don't mind
removing it completely.


> > @@ -411,11 +438,24 @@ int zbud_reclaim_page(struct zbud_pool *pool, 
> > unsigned int retries)
> > return -EINVAL;
> > }
> > for (i = 0; i < retries; i++) {
> > +   if (list_empty(&pool->lru)) {
> > +   /*
> > +* LRU was emptied during evict calls in previous
> > +* iteration but put_zbud_page() returned 0 meaning
> > +* that someone still holds the page. This may
> > +* happen when some other mm mechanism increased
> > +* the page count.
> > +* In such case we succedded with reclaim.
> > +*/
> > +   return 0;
> > +   }
> > zhdr = list_tail_entry(&pool->lru, struct zbud_header, lru);
> > +   BUG_ON(zhdr->first_chunks == 0 && zhdr->last_chunks == 0);
> 
> Again here.
I agree.


Thanks for comments,
Krzysztof


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] [TRIVIAL] ARM: msm: fix compilation error in gpiomux

2013-08-07 Thread Krzysztof Kozlowski
On śro, 2013-08-07 at 14:08 -0700, Stephen Boyd wrote:
> On 08/07, David Brown wrote:
> > On Wed, Aug 07, 2013 at 08:34:39AM +0200, Krzysztof Kozlowski wrote:
> > >Fix compilation error in gpiomux (CONFIG_MSM_GPIOMUX=y):
> > >arch/arm/mach-msm/gpiomux.c:24:13: error: static declaration of
> > >   ???__msm_gpiomux_write??? follows non-static declaration
> > >arch/arm/mach-msm/gpiomux.h:85:6: note: previous declaration of
> > >   ???__msm_gpiomux_write??? was here
> > >
> > >Signed-off-by: Krzysztof Kozlowski 
> > 
> > Thanks, I'll pull this in.
> > 
> >  <https://patchwork.kernel.org/patch/2839921/>
> > 
> 
> I believe this is fixed by Rohit's patch that has already been
> taken in a pull request?
> 
> https://lkml.org/lkml/2013/7/26/608

Yes, Rohit's patch fixes the problem so this is already in linux-msm
tree.


Best regards,
Krzysztof


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 3/4] mm: add zbud flag to page flags

2013-08-08 Thread Krzysztof Kozlowski
Hi,

On wto, 2013-08-06 at 09:58 -0700, Dave Hansen wrote:
> On 08/05/2013 11:42 PM, Krzysztof Kozlowski wrote:
> > +#ifdef CONFIG_ZBUD
> > +   /* Allocated by zbud. Flag is necessary to find zbud pages to unuse
> > +* during migration/compaction.
> > +*/
> > +   PG_zbud,
> > +#endif
> 
> Do you _really_ need an absolutely new, unshared page flag?
> The zbud code doesn't really look like it uses any of the space in
> 'struct page'.
> 
> I think you could pretty easily alias PG_zbud=PG_slab, then use the
> page->{private,slab_cache} (or some other unused field) in 'struct page'
> to store a cookie to differentiate slab and zbud pages.

How about using page->_mapcount with negative value (-129)? Just like
PageBuddy()?


Best regards,
Krzysztof

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH v2 0/4] mm: reclaim zbud pages on migration and compaction

2013-08-09 Thread Krzysztof Kozlowski
Hi,

Currently zbud pages are not movable and they cannot be allocated from CMA
region. These patches try to address the problem by:
1. Adding a new form of reclaim of zbud pages.
2. Reclaiming zbud pages during migration and compaction.
3. Allocating zbud pages with __GFP_RECLAIMABLE flag.

This reclaim process is different than zbud_reclaim_page(). It acts more
like swapoff() by trying to unuse pages stored in zbud page and bring
them back to memory. The standard zbud_reclaim_page() on the other hand
tries to write them back.

One of patches introduces PageZbud() function which identifies zbud pages
my page->_mapcount. Dave Hansen proposed aliasing PG_zbud=PG_slab but in
such case patch would be more intrusive.

Any ideas for a better solution are welcome.

TODO-s:
1. Migrate zbud pages directly instead of reclaiming.

Changes since v1:
1. Rebased against v3.11-rc4-103-g6c2580c.
2. Remove rebalance_lists() to fix reinserting zbud page after zbud_free.
   This function was added because similar code was present in
   zbud_free/zbud_alloc/zbud_reclaim_page but it turns out that there
   is no benefit in generalizing this code.
   (suggested by Seth Jennings)
3. Remove BUG_ON checks for first/last chunks during free and reclaim.
   (suggested by Seth Jennings)
4. Use page->_mapcount==-127 instead of new PG_zbud flag.
   (suggested by Dave Hansen)
5. Fix invalid dereference of pointer to compact_control in page_alloc.c.
6. Fix lost return value in try_to_unuse() in swapfile.c (this fixes
   hang when swapoff was interrupted e.g. by CTRL+C).


Best regards,
Krzysztof Kozlowski


Krzysztof Kozlowski (4):
  zbud: use page ref counter for zbud pages
  mm: split code for unusing swap entries from try_to_unuse
  mm: use mapcount for identifying zbud pages
  mm: reclaim zbud pages on migration and compaction

 include/linux/mm.h   |   23 +++
 include/linux/swapfile.h |2 +
 include/linux/zbud.h |   11 +-
 mm/compaction.c  |   20 ++-
 mm/internal.h|1 +
 mm/page_alloc.c  |6 +
 mm/swapfile.c|  356 --
 mm/zbud.c|  247 +++-
 mm/zswap.c   |   57 +++-
 9 files changed, 476 insertions(+), 247 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH v2 2/4] mm: split code for unusing swap entries from try_to_unuse

2013-08-09 Thread Krzysztof Kozlowski
Move out the code for unusing swap entries from loop in try_to_unuse()
to separate function: try_to_unuse_swp_entry(). Export this new function
in swapfile.h just like try_to_unuse() is exported.

This new function will be used for unusing swap entries from subsystems
(e.g. zswap).

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/swapfile.h |2 +
 mm/swapfile.c|  356 --
 2 files changed, 189 insertions(+), 169 deletions(-)

diff --git a/include/linux/swapfile.h b/include/linux/swapfile.h
index e282624..68c24a7 100644
--- a/include/linux/swapfile.h
+++ b/include/linux/swapfile.h
@@ -9,5 +9,7 @@ extern spinlock_t swap_lock;
 extern struct swap_list_t swap_list;
 extern struct swap_info_struct *swap_info[];
 extern int try_to_unuse(unsigned int, bool, unsigned long);
+extern int try_to_unuse_swp_entry(struct mm_struct **start_mm,
+   struct swap_info_struct *si, swp_entry_t entry);
 
 #endif /* _LINUX_SWAPFILE_H */
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 36af6ee..4ba21ec 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -1100,6 +1100,190 @@ static unsigned int find_next_to_unuse(struct 
swap_info_struct *si,
 }
 
 /*
+ * Returns:
+ *  - negative on error,
+ *  - 0 on success (entry unused, freed independently or shmem entry
+ * already released)
+ */
+int try_to_unuse_swp_entry(struct mm_struct **start_mm,
+   struct swap_info_struct *si, swp_entry_t entry)
+{
+   pgoff_t offset = swp_offset(entry);
+   unsigned char *swap_map;
+   unsigned char swcount;
+   struct page *page;
+   int retval = 0;
+
+   if (signal_pending(current)) {
+   retval = -EINTR;
+   goto out;
+   }
+
+   /*
+* Get a page for the entry, using the existing swap
+* cache page if there is one.  Otherwise, get a clean
+* page and read the swap into it.
+*/
+   swap_map = &si->swap_map[offset];
+   page = read_swap_cache_async(entry,
+   GFP_HIGHUSER_MOVABLE, NULL, 0);
+   if (!page) {
+   /*
+* Either swap_duplicate() failed because entry
+* has been freed independently, and will not be
+* reused since sys_swapoff() already disabled
+* allocation from here, or alloc_page() failed.
+*/
+   if (!*swap_map)
+   retval = 0;
+   else
+   retval = -ENOMEM;
+   goto out;
+   }
+
+   /*
+* Don't hold on to start_mm if it looks like exiting.
+*/
+   if (atomic_read(&(*start_mm)->mm_users) == 1) {
+   mmput(*start_mm);
+   *start_mm = &init_mm;
+   atomic_inc(&init_mm.mm_users);
+   }
+
+   /*
+* Wait for and lock page.  When do_swap_page races with
+* try_to_unuse, do_swap_page can handle the fault much
+* faster than try_to_unuse can locate the entry.  This
+* apparently redundant "wait_on_page_locked" lets try_to_unuse
+* defer to do_swap_page in such a case - in some tests,
+* do_swap_page and try_to_unuse repeatedly compete.
+*/
+   wait_on_page_locked(page);
+   wait_on_page_writeback(page);
+   lock_page(page);
+   wait_on_page_writeback(page);
+
+   /*
+* Remove all references to entry.
+*/
+   swcount = *swap_map;
+   if (swap_count(swcount) == SWAP_MAP_SHMEM) {
+   retval = shmem_unuse(entry, page);
+   VM_BUG_ON(retval > 0);
+   /* page has already been unlocked and released */
+   goto out;
+   }
+   if (swap_count(swcount) && *start_mm != &init_mm)
+   retval = unuse_mm(*start_mm, entry, page);
+
+   if (swap_count(*swap_map)) {
+   int set_start_mm = (*swap_map >= swcount);
+   struct list_head *p = &(*start_mm)->mmlist;
+   struct mm_struct *new_start_mm = *start_mm;
+   struct mm_struct *prev_mm = *start_mm;
+   struct mm_struct *mm;
+
+   atomic_inc(&new_start_mm->mm_users);
+   atomic_inc(&prev_mm->mm_users);
+   spin_lock(&mmlist_lock);
+   while (swap_count(*swap_map) && !retval &&
+   (p = p->next) != &(*start_mm)->mmlist) {
+   mm = list_entry(p, struct mm_struct, mmlist);
+   if (!atomic_inc_not_zero(&mm->mm_users))
+   continue;
+   spin_unlock(&mmlist_lock);
+   mmput(prev_mm);
+   prev_mm = mm;
+
+   cond_resched();
+
+   swcount = *swap_map;
+   

[RFC PATCH v2 4/4] mm: reclaim zbud pages on migration and compaction

2013-08-09 Thread Krzysztof Kozlowski
Reclaim zbud pages during migration and compaction by unusing stored
data. This allows adding__GFP_RECLAIMABLE flag when allocating zbud
pages and effectively CMA pool can be used for zswap.

zbud pages are not movable and are not stored under any LRU (except
zbud's LRU). PageZbud flag is used in isolate_migratepages_range() to
grab zbud pages and pass them later for reclaim.

This reclaim process is different than zbud_reclaim_page(). It acts more
like swapoff() by trying to unuse pages stored in zbud page and bring
them back to memory. The standard zbud_reclaim_page() on the other hand
tries to write them back.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/zbud.h |   11 +++-
 mm/compaction.c  |   20 ++-
 mm/internal.h|1 +
 mm/page_alloc.c  |6 ++
 mm/zbud.c|  161 +++---
 mm/zswap.c   |   57 --
 6 files changed, 214 insertions(+), 42 deletions(-)

diff --git a/include/linux/zbud.h b/include/linux/zbud.h
index 2571a5c..57ee85d 100644
--- a/include/linux/zbud.h
+++ b/include/linux/zbud.h
@@ -5,8 +5,14 @@
 
 struct zbud_pool;
 
+/**
+ * Template for functions called during reclaim.
+ */
+typedef int (*evict_page_t)(struct zbud_pool *pool, unsigned long handle);
+
 struct zbud_ops {
-   int (*evict)(struct zbud_pool *pool, unsigned long handle);
+   evict_page_t evict; /* callback for zbud_reclaim_lru_page() */
+   evict_page_t unuse; /* callback for zbud_reclaim_pages() */
 };
 
 struct zbud_pool *zbud_create_pool(gfp_t gfp, struct zbud_ops *ops);
@@ -14,7 +20,8 @@ void zbud_destroy_pool(struct zbud_pool *pool);
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
unsigned long *handle);
 void zbud_free(struct zbud_pool *pool, unsigned long handle);
-int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries);
+int zbud_reclaim_lru_page(struct zbud_pool *pool, unsigned int retries);
+void zbud_reclaim_pages(struct list_head *zbud_pages);
 void *zbud_map(struct zbud_pool *pool, unsigned long handle);
 void zbud_unmap(struct zbud_pool *pool, unsigned long handle);
 u64 zbud_get_pool_size(struct zbud_pool *pool);
diff --git a/mm/compaction.c b/mm/compaction.c
index 05ccb4c..9bbf412 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "internal.h"
 
 #ifdef CONFIG_COMPACTION
@@ -534,6 +535,17 @@ isolate_migratepages_range(struct zone *zone, struct 
compact_control *cc,
goto next_pageblock;
}
 
+   if (PageZbud(page)) {
+   /*
+* Zbud pages do not exist in LRU so we must
+* check for Zbud flag before PageLRU() below.
+*/
+   BUG_ON(PageLRU(page));
+   get_page(page);
+   list_add(&page->lru, &cc->zbudpages);
+   continue;
+   }
+
/*
 * Check may be lockless but that's ok as we recheck later.
 * It's possible to migrate LRU pages and balloon pages
@@ -810,7 +822,10 @@ static isolate_migrate_t isolate_migratepages(struct zone 
*zone,
low_pfn = isolate_migratepages_range(zone, cc, low_pfn, end_pfn, false);
if (!low_pfn || cc->contended)
return ISOLATE_ABORT;
-
+#ifdef CONFIG_ZBUD
+   if (!list_empty(&cc->zbudpages))
+   zbud_reclaim_pages(&cc->zbudpages);
+#endif
cc->migrate_pfn = low_pfn;
 
return ISOLATE_SUCCESS;
@@ -1023,11 +1038,13 @@ static unsigned long compact_zone_order(struct zone 
*zone,
};
INIT_LIST_HEAD(&cc.freepages);
INIT_LIST_HEAD(&cc.migratepages);
+   INIT_LIST_HEAD(&cc.zbudpages);
 
ret = compact_zone(zone, &cc);
 
VM_BUG_ON(!list_empty(&cc.freepages));
VM_BUG_ON(!list_empty(&cc.migratepages));
+   VM_BUG_ON(!list_empty(&cc.zbudpages));
 
*contended = cc.contended;
return ret;
@@ -1105,6 +1122,7 @@ static void __compact_pgdat(pg_data_t *pgdat, struct 
compact_control *cc)
cc->zone = zone;
INIT_LIST_HEAD(&cc->freepages);
INIT_LIST_HEAD(&cc->migratepages);
+   INIT_LIST_HEAD(&cc->zbudpages);
 
if (cc->order == -1 || !compaction_deferred(zone, cc->order))
compact_zone(zone, cc);
diff --git a/mm/internal.h b/mm/internal.h
index 4390ac6..eaf5c884 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -119,6 +119,7 @@ struct compact_control {
unsigned long nr_migratepages;  /* Number of pages to migrate */
unsigned long free_pfn; /* isolate_freepages search base */
unsigned long migrate_pfn;  /* isolate_migrat

[RFC PATCH v2 3/4] mm: use mapcount for identifying zbud pages

2013-08-09 Thread Krzysztof Kozlowski
Currently zbud pages do not have any flags set so it is not possible to
identify them during migration or compaction.

Implement PageZbud() by comparing page->_mapcount to -127 to distinguish
pages allocated by zbud. Just like PageBuddy() is implemented.

Signed-off-by: Krzysztof Kozlowski 
---
 include/linux/mm.h |   23 +++
 mm/zbud.c  |4 
 2 files changed, 27 insertions(+)

diff --git a/include/linux/mm.h b/include/linux/mm.h
index f022460..b9ae6f2 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -440,6 +440,7 @@ static inline void init_page_count(struct page *page)
  * efficiently by most CPU architectures.
  */
 #define PAGE_BUDDY_MAPCOUNT_VALUE (-128)
+#define PAGE_ZBUD_MAPCOUNT_VALUE (-127)
 
 static inline int PageBuddy(struct page *page)
 {
@@ -458,6 +459,28 @@ static inline void __ClearPageBuddy(struct page *page)
atomic_set(&page->_mapcount, -1);
 }
 
+#ifdef CONFIG_ZBUD
+static inline int PageZbud(struct page *page)
+{
+   return atomic_read(&page->_mapcount) == PAGE_ZBUD_MAPCOUNT_VALUE;
+}
+
+static inline void SetPageZbud(struct page *page)
+{
+   VM_BUG_ON(atomic_read(&page->_mapcount) != -1);
+   atomic_set(&page->_mapcount, PAGE_ZBUD_MAPCOUNT_VALUE);
+}
+
+static inline void ClearPageZbud(struct page *page)
+{
+   VM_BUG_ON(!PageZbud(page));
+   atomic_set(&page->_mapcount, -1);
+}
+#else
+PAGEFLAG_FALSE(Zbud)
+#endif
+
+
 void put_page(struct page *page);
 void put_pages_list(struct list_head *pages);
 
diff --git a/mm/zbud.c b/mm/zbud.c
index 52f6ba1..24c9ba0 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -199,7 +199,10 @@ static void get_zbud_page(struct zbud_header *zhdr)
 static int put_zbud_page(struct zbud_pool *pool, struct zbud_header *zhdr)
 {
struct page *page = virt_to_page(zhdr);
+   BUG_ON(!PageZbud(page));
+
if (put_page_testzero(page)) {
+   ClearPageZbud(page);
free_hot_cold_page(page, 0);
pool->pages_nr--;
return 1;
@@ -310,6 +313,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
 * don't increase the page count.
 */
zhdr = init_zbud_page(page);
+   SetPageZbud(page);
bud = FIRST;
 
 found:
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[RFC PATCH v2 1/4] zbud: use page ref counter for zbud pages

2013-08-09 Thread Krzysztof Kozlowski
Use page reference counter for zbud pages. The ref counter replaces
zbud_header.under_reclaim flag and ensures that zbud page won't be freed
when zbud_free() is called during reclaim. It allows implementation of
additional reclaim paths.

The page count is incremented when:
 - a handle is created and passed to zswap (in zbud_alloc()),
 - user-supplied eviction callback is called (in zbud_reclaim_page()).

Signed-off-by: Krzysztof Kozlowski 
Signed-off-by: Tomasz Stanislawski 
Reviewed-by: Bob Liu 
---
 mm/zbud.c |   96 ++---
 1 file changed, 53 insertions(+), 43 deletions(-)

diff --git a/mm/zbud.c b/mm/zbud.c
index ad1e781..52f6ba1 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -109,7 +109,6 @@ struct zbud_header {
struct list_head lru;
unsigned int first_chunks;
unsigned int last_chunks;
-   bool under_reclaim;
 };
 
 /*
@@ -138,16 +137,9 @@ static struct zbud_header *init_zbud_page(struct page 
*page)
zhdr->last_chunks = 0;
INIT_LIST_HEAD(&zhdr->buddy);
INIT_LIST_HEAD(&zhdr->lru);
-   zhdr->under_reclaim = 0;
return zhdr;
 }
 
-/* Resets the struct page fields and frees the page */
-static void free_zbud_page(struct zbud_header *zhdr)
-{
-   __free_page(virt_to_page(zhdr));
-}
-
 /*
  * Encodes the handle of a particular buddy within a zbud page
  * Pool lock should be held as this function accesses first|last_chunks
@@ -188,6 +180,34 @@ static int num_free_chunks(struct zbud_header *zhdr)
return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks - 1;
 }
 
+/*
+ * Increases ref count for zbud page.
+ */
+static void get_zbud_page(struct zbud_header *zhdr)
+{
+   get_page(virt_to_page(zhdr));
+}
+
+/*
+ * Decreases ref count for zbud page and frees the page if it reaches 0
+ * (no external references, e.g. handles).
+ *
+ * Must be called under pool->lock.
+ *
+ * Returns 1 if page was freed and 0 otherwise.
+ */
+static int put_zbud_page(struct zbud_pool *pool, struct zbud_header *zhdr)
+{
+   struct page *page = virt_to_page(zhdr);
+   if (put_page_testzero(page)) {
+   free_hot_cold_page(page, 0);
+   pool->pages_nr--;
+   return 1;
+   }
+   return 0;
+}
+
+
 /*
  * API Functions
 */
@@ -250,7 +270,7 @@ void zbud_destroy_pool(struct zbud_pool *pool)
 int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
unsigned long *handle)
 {
-   int chunks, i, freechunks;
+   int chunks, i;
struct zbud_header *zhdr = NULL;
enum buddy bud;
struct page *page;
@@ -273,6 +293,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
bud = FIRST;
else
bud = LAST;
+   get_zbud_page(zhdr);
goto found;
}
}
@@ -284,6 +305,10 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
return -ENOMEM;
spin_lock(&pool->lock);
pool->pages_nr++;
+   /*
+* We will be using zhdr instead of page, so
+* don't increase the page count.
+*/
zhdr = init_zbud_page(page);
bud = FIRST;
 
@@ -295,7 +320,7 @@ found:
 
if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0) {
/* Add to unbuddied list */
-   freechunks = num_free_chunks(zhdr);
+   int freechunks = num_free_chunks(zhdr);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
} else {
/* Add to buddied list */
@@ -326,7 +351,6 @@ found:
 void zbud_free(struct zbud_pool *pool, unsigned long handle)
 {
struct zbud_header *zhdr;
-   int freechunks;
 
spin_lock(&pool->lock);
zhdr = handle_to_zbud_header(handle);
@@ -337,26 +361,18 @@ void zbud_free(struct zbud_pool *pool, unsigned long 
handle)
else
zhdr->first_chunks = 0;
 
-   if (zhdr->under_reclaim) {
-   /* zbud page is under reclaim, reclaim will free */
-   spin_unlock(&pool->lock);
-   return;
-   }
-
/* Remove from existing buddy list */
list_del(&zhdr->buddy);
 
if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) {
-   /* zbud page is empty, free */
list_del(&zhdr->lru);
-   free_zbud_page(zhdr);
-   pool->pages_nr--;
} else {
/* Add to unbuddied list */
-   freechunks = num_free_chunks(zhdr);
+   int freechunks = num_free_chunks(zhdr);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
}
 
+   put_zbud_page(pool,

Re: [RFC 0/3] Pin page control subsystem

2013-08-13 Thread Krzysztof Kozlowski
Hi Minchan,

On wto, 2013-08-13 at 16:04 +0900, Minchan Kim wrote:
> patch 2 introduce pinpage control
> subsystem. So, subsystems want to control pinpage should implement own
> pinpage_xxx functions because each subsystem would have other character
> so what kinds of data structure for managing pinpage information depends
> on them. Otherwise, they can use general functions defined in pinpage
> subsystem. patch 3 hacks migration.c so that migration is
> aware of pinpage now and migrate them with pinpage subsystem.

I wonder why don't we use page->mapping and a_ops? Is there any
disadvantage of such mapping/a_ops?

Best regards,
Krzysztof

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ARM: exynos_defconfig: Enable bus frequency scaling with DEVFREQ/DEVFREQ-Event

2016-07-21 Thread Krzysztof Kozlowski
On 07/21/2016 10:34 AM, Chanwoo Choi wrote:
> Hi Krzysztof,
> 
> Could you please pick this patch?
> 
> Regards,
> Chanwoo Choi

Hi,

The patchset looks good, only the commit message needs some minor
improvements (I can do that while applying). However it came too late
for this cycle - after my last pull request for v4.8 ten days ago. I
won't be able to push anything more so it has to wait for v4.9. I'll
pick it up after merge window.

For the record:
Reviewed-by: Krzysztof Kozlowski 

Best regards,
Krzysztof




Re: [PATCH] ASoC: samsung: make audio interface/controller explicitly

2016-09-19 Thread Krzysztof Kozlowski
On Mon, Sep 19, 2016 at 09:21:54AM +0800, Ayaka wrote:
> 
> 
> 從我的 iPad 傳送
> 
> > Krzysztof Kozlowski  於 2016年9月19日 上午2:09 寫道:
> > 
> >> On Sun, Sep 18, 2016 at 11:12:34PM +0800, ayaka wrote:
> >> 
> >> 
> >>> On 09/18/2016 10:42 PM, Krzysztof Kozlowski wrote:
> >>>> On Sun, Sep 18, 2016 at 10:09:11PM +0800, Randy Li wrote:
> >>>> It is simple sound card time, we could assign different codec
> >>>> to a interface without making a specific driver for it.
> >>> The description does not convince me and I do not see an example using
> >>> this. Could you provide one?
> >> Sorry, the board TOPEET iTop 4412 for exynos 4412 I posted supported codec
> >> with I2S interface using the simple sound card. Anyway, it is no harm to
> >> make them explicitly right?
> > 
> > kbuild gave you the answer...
> Not sure how comes, even time I sent patches to you, I at lease build and run 
> it once.

Building only one ARM config may be sufficient for trivial changes but
for more complex stuff (especially when dealing with Kconfig) needs more
build coverage. 

On Ubuntu you can easily cross compile for x86, x86_64,
arm, arm64 and powerpc. You can also use this cross-compiler collection:
https://www.kernel.org/pub/tools/crosstool


> > 
> >> Or I have to enabled those codec support for
> >> SMDK, which is not needed for the other board.
> > 
> > If I understand correctly, the i2s/pcm etc are still needed but not
> > built in config choosing only simple-audio-card? I tried now such
> > configuration on Odroid XU and indeed the audio is missing.
> > 
> > The patch looks like needed but:
> > 1. You need to describe the rationale in commit message, why it is
> > needed.
> Sorry about English.
> > 2. You need to fix it... kbuild pointed build issues.
> I would check that.
> > 
> > Other solution would be to add a user-selectable option for generic
> > sound on Samsung using simple audio card. The option would then select
> > appropriate SND_SAMSUNG* options, just like specific drivers do. I see
> > that sh does like this. Personally this approach seems simpler to me -
> > the defconfig could just choose this generic sound instead of many
> > SND_SAMSUNG_* sub-options.
> I would just what  Freescale did. It included those options entries in a 
> sub-menu.
> I don't those options should be bound either, as a board may only use one of 
> interface or controller(like TOPEET iTOP would only use i2s. No place for 
> SPDIF, AC97 nor PCM.)

OK, sounds good for me. Thanks for explanation.


Best regards,
Krzysztof



Re: [GIT PULL 1/3] ARM: soc: exynos: Drivers for v4.9

2016-09-19 Thread Krzysztof Kozlowski
On Mon, Sep 19, 2016 at 05:02:40PM +0200, Arnd Bergmann wrote:
> On Sunday, September 18, 2016 6:39:46 PM CEST Krzysztof Kozlowski wrote:
> > Samsung drivers/soc update for v4.9:
> > 1. Allow compile testing of exynos-mct clocksource driver on ARM64.
> > 2. Document Exynos5433 PMU compatible (already used by clkout driver and 
> > more
> >will be coming soon).
> 
> Pulled into next/drivers, thanks
> 
> Just for my understanding: why do we need the exynos-mct driver on ARM64
> but not the delay-timer portion of it?

I think we want all of it but Doug's optimization 3252a646aa2c
("clocksource: exynos_mct: Only use 32-bits where possible") is not
ARM64 friendly. One way of dealing with it would be to prepare two
versions of exynos4_read_current_timer(). One reading only lower 32-bit
value for ARMv7 and second (slow) reading lower and upper for ARMv8.

> 
> Is there an advantage in using MCT over the architected timer on these
> chips? If so, should we also have a way to use it as the delay timer?

No, there is no real advantage... except that the SoC has some
interesting "characteristics"... The timers are tightly coupled. Very
tightly. I spent a lot of time and failed to boot my ARMv8 board without
some MCT magic.

Best regards,
Krzysztof


Re: Re: linux-next: build failure after merge of the pm tree

2016-09-19 Thread Krzysztof Kozlowski
On Mon, Sep 19, 2016 at 07:37:24AM +, MyungJoo Ham wrote:
> > On Wednesday, September 14, 2016 02:27:47 PM Stephen Rothwell wrote:
> > > Hi Rafael,
> > > 
> > > After merging the pm tree, today's linux-next build (powerpc allyesconfig)
> > > failed like this:
> > > 
> > > drivers/devfreq/tegra-devfreq.c: In function 'tegra_devfreq_target':
> > > drivers/devfreq/tegra-devfreq.c:500:2: error: implicit declaration of 
> > > function 'clk_set_min_rate' [-Werror=implicit-function-declaration]
> > >   clk_set_min_rate(tegra->emc_clock, rate);
> > >   ^
> > > 
> > > Caused by commit
> > > 
> > >   797da5598f3a ("PM / devfreq: Add COMPILE_TEST for build coverage")
> 
> @Rafael: Thank you!
> 
> 
> @Kozlowski:
> 
> It looks like COMMON_CLK is required to be "selected" for TEGRA.
> 
> Although COMMON_CLK is supposed to be widely used by most ARM platforms
> especially if "Multiple platfrom selection" for ARMv7 is used,
> COMPILE_TEST won't recognize it.
> 
> Adding COMMON_CLK for TEGRA will solve this instance of issue; however,
> for COMPILE_TEST to be reasonably robust, each "COMPILE_TEST"ed item
> should "select" every required item. How do you want to proceed with
> COMPILE_TEST on SoC-specific device drivers?

I think drivers should depend on COMMON_CLK in such case. This tegra
driver probably does not require strict ARCH_TEGRA_124_SOC dependency
because it does not use any SoC-specific data/functions etc. However it
uses common clock framework so explicit dependency looks proper to me.

In fact this is already seen in kernel like SND_SOC_TEGRA, SND_MXS_SOC,
PWM_IMG(with compile test), SND_SOC_RCAR (even without compile test).

Best regards,
Krzysztof


Re: [PATCH] ASoC: samsung: make audio interface/controller explicitly

2016-09-19 Thread Krzysztof Kozlowski
On Mon, Sep 19, 2016 at 11:51:58PM +0800, Randy Li wrote:
> It is simple sound card time, we could assign different codec
> to a interface without making a specific driver for it. The SPDIF
> and I2S interface for Samsung would be possible used by simple-sound-card,
> but not sure about the PCM.
> 
> Signed-off-by: Randy Li 
> ---
>  sound/soc/samsung/Kconfig | 16 +---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
> index 7b722b0..210ce38 100644
> --- a/sound/soc/samsung/Kconfig
> +++ b/sound/soc/samsung/Kconfig
> @@ -1,3 +1,7 @@
> +menu "SoC Audio for Samsung CPUs"

This adds a new empty layer. One have to choose this menu and then
SND_SOC_SAMSUNG to access specific options. Instead of new menu, the
SND_SOC_SAMSUNG should be menuconfig. The existing "depends on" and the
one you added below won't be needed then, I think. Just have to be sure
that nothing selects particular drivers without selecting
SND_SOC_SAMSUNG first.


Best regards,
Krzysztof


> +
> +comment "Common SoC Audio options for Samsung CPUs:"
> +
>  config SND_SOC_SAMSUNG
>   tristate "ASoC support for Samsung"
>   depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
> @@ -18,18 +22,22 @@ config SND_S3C2412_SOC_I2S
>   select SND_S3C_I2SV2_SOC
>  
>  config SND_SAMSUNG_PCM
> - tristate
> + tristate "Samsung PCM interface support"
> + depends on SND_SOC_SAMSUNG
>  
>  config SND_SAMSUNG_AC97
>   tristate
>   select SND_SOC_AC97_BUS
> + depends on SND_SOC_SAMSUNG
>  
>  config SND_SAMSUNG_SPDIF
> - tristate
> + tristate "Samsung SPDIF transmitter support"
> + depends on SND_SOC_SAMSUNG
>   select SND_SOC_SPDIF
>  
>  config SND_SAMSUNG_I2S
> - tristate
> + tristate "Samsung I2S interface support"
> + depends on I2C && SND_SOC_SAMSUNG
>  
>  config SND_SOC_SAMSUNG_NEO1973_WM8753
>   tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)"
> @@ -229,3 +237,5 @@ config SND_SOC_ARNDALE_RT5631_ALC5631
>  depends on SND_SOC_SAMSUNG && I2C
>  select SND_SAMSUNG_I2S
>  select SND_SOC_RT5631
> +
> +endmenu
> -- 
> 2.7.4
> 


Re: [PATCH v3] ASoC: exynos: organize the asoc audio into a menu

2016-09-20 Thread Krzysztof Kozlowski
On Tue, Sep 20, 2016 at 02:57:50AM +0800, Randy Li wrote:
> It is simple sound card time, we could assign different codec
> to a interface without making a specific driver for it. The SPDIF
> and I2S interface for Samsung would be possible used by
> simple-sound-card, but not sure about the PCM.
> 
> Those S3C time entries are left alone as I don't think any new board
> would need them.
> 
> Signed-off-by: Randy Li 
> ---
>  sound/soc/samsung/Kconfig | 57 
> ---
>  1 file changed, 29 insertions(+), 28 deletions(-)
> 

Reviewed-by: Krzysztof Kozlowski 

Best regards,
Krzysztof



Re: [PATCH 5/6] memory: samsung/exynos-srom: make it explicitly non-modular

2016-06-20 Thread Krzysztof Kozlowski
On 06/17/2016 02:37 AM, Paul Gortmaker wrote:
> The Kconfig currently controlling compilation of this code is:
> 
> memory/samsung/Kconfig:config EXYNOS_SROM
> memory/samsung/Kconfig: bool "Exynos SROM controller driver" if COMPILE_TEST
> 
> ...meaning that it currently is not being built as a module by anyone.
> 
> Lets remove the modular code that is essentially orphaned, so that
> when reading the driver there is no doubt it is builtin-only.
> 
> We explicitly disallow a driver unbind, since that doesn't have a
> sensible use case anyway, and it allows us to drop the ".remove"
> code for non-modular drivers.
> 
> Since module_platform_driver() uses the same init level priority as
> builtin_platform_driver() the init ordering remains unchanged with
> this commit.
> 
> Also note that MODULE_DEVICE_TABLE is a no-op for non-modular code.
> 
> We also delete the MODULE_LICENSE tag etc. since all that information
> is already contained at the top of the file in the comments.
> 
> Cc: Pankaj Dubey 
> Cc: Kukjin Kim 
> Cc: Krzysztof Kozlowski 
> Cc: linux-samsung-...@vger.kernel.org
> Signed-off-by: Paul Gortmaker 
> ---
>  drivers/memory/samsung/exynos-srom.c | 21 +++--
>  1 file changed, 3 insertions(+), 18 deletions(-)

Thanks, applied for v4.8.

Best regards,
Krzysztof



Re: [PATCH v9 2/4] power: reset: add reboot mode driver

2016-06-20 Thread Krzysztof Kozlowski
On 06/20/2016 08:38 AM, Andy Yan wrote:
> This driver parses the reboot commands like "reboot bootloader"
> and "reboot recovery" to get a boot mode described in the
> device tree , then call the write interfae to store the boot
> mode in some place like special register or sram, which can
> be read by the bootloader after system reboot, then the bootloader
> can take different action according to the mode stored.
> 
> This is commonly used on Android based devices, in order to
> reboot the device into fastboot or recovery mode.
> 
> Reviewed-by: Matthias Brugger 
> Reviewed-by: Moritz Fischer 
> Tested-by: John Stultz 
> Acked-by: John Stultz 
> Signed-off-by: Andy Yan 
> 
> ---
> 
> Changes in v9:
> - select MFD_SYSCON when syscon-reboot-mode driver enabled
> - refactoring error handling in reboot_mode_register
> 
> Changes in v8:
> - do some cleanup when driver ubind
> 
> Changes in v7:
> - address some suggestions from Krzysztof, make syscon-reboot-mode driver 
> data self-contained.
> 
> Changes in v6: None
> Changes in v5:
> - use two blank space under help in Kconfig
> - use unsigned int instead of int for member magic in struct mode_info
> 
> Changes in v4:
> - make this driver depends on OF to avoid kbuild test error
> 
> Changes in v3:
> - scan multi properities
> - add mask value for some platform which only use some bits of the register
>   to store boot mode magic value
> 
> Changes in v2:
> - move to dir drivers/power/reset/
> - make syscon-reboot-mode a generic driver
> 
> Changes in v1:
> - fix the embarrassed compile warning
> - correct the maskrom magic number
> - check for the normal reboot
> 
>  drivers/power/reset/Kconfig  |  14 
>  drivers/power/reset/Makefile |   2 +
>  drivers/power/reset/reboot-mode.c| 128 
> +++
>  drivers/power/reset/reboot-mode.h|  14 
>  drivers/power/reset/syscon-reboot-mode.c | 100 
>  5 files changed, 258 insertions(+)
>  create mode 100644 drivers/power/reset/reboot-mode.c
>  create mode 100644 drivers/power/reset/reboot-mode.h
>  create mode 100644 drivers/power/reset/syscon-reboot-mode.c
> 
> diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
> index 9bb2622..4ceaf74 100644
> --- a/drivers/power/reset/Kconfig
> +++ b/drivers/power/reset/Kconfig
> @@ -183,5 +183,19 @@ config POWER_RESET_ZX
>   help
> Reboot support for ZTE SoCs.
>  
> +config REBOOT_MODE
> + tristate
> +
> +config SYSCON_REBOOT_MODE
> + bool "Generic SYSCON regmap reboot mode driver"

Why not tristate?

Beside that the patch looks good.

Best regards,
Krzysztof

> + depends on OF
> + select REBOOT_MODE
> + select MFD_SYSCON
> + help
> +   Say y here will enable reboot mode driver. This will
> +   get reboot mode arguments and store it in SYSCON mapped
> +   register, then the bootloader can read it to take different
> +   action according to the mode.
> +



Re: [PATCH v4 3/7] max8903: cleans up confusing relationship between dc_valid, dok and dcm.

2016-06-20 Thread Krzysztof Kozlowski
On 06/20/2016 12:27 AM, Chris Lapa wrote:
> From: Chris Lapa 
> 
> The max8903_charger.h file indicated that dcm and dok were not optional
> when dc_valid is set.
> 
> It makes sense to have dok as a compulsory pin when dc_valid is given.
> However dcm can be optionally wired to a fixed level especially when the
> circuit is configured for dc power exclusively.
> 
> The previous implementation already allowed for this somewhat, however no
> error was given if dok wasn't given whilst dc_valid was.
> 
> The new implementation enforces dok presence when dc_valid is given. Whilst
> allowing dcm to be optional.
> 
> Signed-off-by: Chris Lapa 

Reviewed-by: Krzysztof Kozlowski 

BR.
Krzysztof



Re: [PATCH v4 2/7] max8903: store pointer to pdata instead of copying it.

2016-06-20 Thread Krzysztof Kozlowski
On 06/20/2016 12:27 AM, Chris Lapa wrote:
> From: Chris Lapa 
> 
> Stores pointer to pdata because it easily allows pdata to reference
> either platform data or in the future device tree data.
> 
> Signed-off-by: Chris Lapa 
> ---
>  drivers/power/max8903_charger.c | 20 +---
>  1 file changed, 13 insertions(+), 7 deletions(-)

The same as in #1. For the record:
Reviewed-by: Krzysztof Kozlowski 

BR.
Krzysztof



Re: [PATCH v4 1/7] max8903: adds documentation for device tree bindings.

2016-06-20 Thread Krzysztof Kozlowski
On 06/20/2016 12:27 AM, Chris Lapa wrote:
> From: Chris Lapa 
> 
> Signed-off-by: Chris Lapa 

I already reviewed this patch. When resubmitting please include gathered
tags (reviewed, acked, tested) after your signed-off-by. Just put them
in chronological order:

Signed-off-by: Chris Lapa 
Reviewed-by: ...
...
etc


For the record:
Reviewed-by: Krzysztof Kozlowski 

Best regards,
Krzysztof


Re: [PATCH v4 4/7] max8903: adds requesting of gpios.

2016-06-20 Thread Krzysztof Kozlowski
On 06/20/2016 12:27 AM, Chris Lapa wrote:
> From: Chris Lapa 
> 
> This change ensures all gpios are available for the driver to use and also
> splits off gpio setup into its own function for readability.
> 
> Signed-off-by: Chris Lapa 
> ---
>  drivers/power/max8903_charger.c | 136 
> ++--
>  1 file changed, 102 insertions(+), 34 deletions(-)
> 

Reviewed-by: Krzysztof Kozlowski 

Best regards,
Krzysztof



Re: [PATCH v4 6/7] max8903: remove unnecessary 'out of memory' error message.

2016-06-20 Thread Krzysztof Kozlowski
On 06/20/2016 12:27 AM, Chris Lapa wrote:
> From: Chris Lapa 
> 
> Remove the 'out of memory' error message as it is printed by the core.
> 
> Signed-off-by: Chris Lapa 

The same as in #1, I already reviewed it. For the record:
Reviewed-by: Krzysztof Kozlowski 

BR.
Krzysztof



Re: [PATCH v4 5/7] max8903: removes non zero validity checks on gpios.

2016-06-20 Thread Krzysztof Kozlowski
On 06/20/2016 12:27 AM, Chris Lapa wrote:
> From: Chris Lapa 
> 
> Prior to this commit a zero gpio was treated as invalid. Whereas
> gpio_is_valid() will treat a zero gpio as valid.
> 
> This commit removes the confusion and explicitly uses gpio_is_valid()
> throughout. Which in turn results in several of the error messages becoming
> redundant and thus removed.
> 
> Signed-off-by: Chris Lapa 

The same as in #1, I already reviewed it. For the record:
Reviewed-by: Krzysztof Kozlowski 

BR.
Krzysztof




Re: [PATCH v4 7/7] max8903: adds support for initiation via device tree

2016-06-20 Thread Krzysztof Kozlowski
On 06/20/2016 12:27 AM, Chris Lapa wrote:
> From: Chris Lapa 
> 
> Adds support for device tree to setup a max8903 battery charger. DC and USB
> validity are determined by looking the presence of the dok and uok gpios.
> 
> Signed-off-by: Chris Lapa 

Reviewed-by: Krzysztof Kozlowski 

BR,
Krzysztof



Re: [PATCH v9 2/4] power: reset: add reboot mode driver

2016-06-20 Thread Krzysztof Kozlowski
On 06/20/2016 10:28 AM, Andy Yan wrote:
> Hi Krzysztof:
> 
> On 2016年06月20日 16:09, Krzysztof Kozlowski wrote:
>> On 06/20/2016 08:38 AM, Andy Yan wrote:
>>> This driver parses the reboot commands like "reboot bootloader"
>>> and "reboot recovery" to get a boot mode described in the
>>> device tree , then call the write interfae to store the boot
>>> mode in some place like special register or sram, which can
>>> be read by the bootloader after system reboot, then the bootloader
>>> can take different action according to the mode stored.
>>>
>>> This is commonly used on Android based devices, in order to
>>> reboot the device into fastboot or recovery mode.
>>>
>>> Reviewed-by: Matthias Brugger 
>>> Reviewed-by: Moritz Fischer 
>>> Tested-by: John Stultz 
>>> Acked-by: John Stultz 
>>> Signed-off-by: Andy Yan 
>>>
>>> ---
>>>
>>> Changes in v9:
>>> - select MFD_SYSCON when syscon-reboot-mode driver enabled
>>> - refactoring error handling in reboot_mode_register
>>>
>>> Changes in v8:
>>> - do some cleanup when driver ubind
>>>
>>> Changes in v7:
>>> - address some suggestions from Krzysztof, make syscon-reboot-mode
>>> driver data self-contained.
>>>
>>> Changes in v6: None
>>> Changes in v5:
>>> - use two blank space under help in Kconfig
>>> - use unsigned int instead of int for member magic in struct mode_info
>>>
>>> Changes in v4:
>>> - make this driver depends on OF to avoid kbuild test error
>>>
>>> Changes in v3:
>>> - scan multi properities
>>> - add mask value for some platform which only use some bits of the
>>> register
>>>to store boot mode magic value
>>>
>>> Changes in v2:
>>> - move to dir drivers/power/reset/
>>> - make syscon-reboot-mode a generic driver
>>>
>>> Changes in v1:
>>> - fix the embarrassed compile warning
>>> - correct the maskrom magic number
>>> - check for the normal reboot
>>>
>>>   drivers/power/reset/Kconfig  |  14 
>>>   drivers/power/reset/Makefile |   2 +
>>>   drivers/power/reset/reboot-mode.c| 128
>>> +++
>>>   drivers/power/reset/reboot-mode.h|  14 
>>>   drivers/power/reset/syscon-reboot-mode.c | 100
>>> 
>>>   5 files changed, 258 insertions(+)
>>>   create mode 100644 drivers/power/reset/reboot-mode.c
>>>   create mode 100644 drivers/power/reset/reboot-mode.h
>>>   create mode 100644 drivers/power/reset/syscon-reboot-mode.c
>>>
>>> diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
>>> index 9bb2622..4ceaf74 100644
>>> --- a/drivers/power/reset/Kconfig
>>> +++ b/drivers/power/reset/Kconfig
>>> @@ -183,5 +183,19 @@ config POWER_RESET_ZX
>>>   help
>>> Reboot support for ZTE SoCs.
>>>   +config REBOOT_MODE
>>> +tristate
>>> +
>>> +config SYSCON_REBOOT_MODE
>>> +bool "Generic SYSCON regmap reboot mode driver"
>> Why not tristate?
> 
>I see many reset drivers in this directories  use bool, so I follow
> them.

+Cc Paul,

I don't mind that although I don't see any particular objections for
making it module-capable. In the same time I just reminded myself about
Paul Gortmaker's long effort (like [1] [2]) about removing module
capability from non-modular drivers.

Following his rationale, I think either this should be a tristate or the
module stuff should be removed.

Best regards,
Krzysztof

[1] https://lkml.org/lkml/2016/2/21/180
[2] https://lkml.org/lkml/2016/6/13/682




Re: [PATCH v9 2/4] power: reset: add reboot mode driver

2016-06-21 Thread Krzysztof Kozlowski
On 06/21/2016 08:16 AM, Andy Yan wrote:
>   I will remove the module related stuff in the next version.
>>> Following his rationale, I think either this should be a tristate or the
>>> module stuff should be removed.

How about making it tristate? I think there isn't any obstacles for this
driver being a module. Some distros like modules.

Best regards.
Krzysztof



Re: [PATCH v6 2/4] power: reset: add reboot mode driver

2016-06-21 Thread Krzysztof Kozlowski
On 06/21/2016 01:01 PM, Andy Yan wrote:

(...)

>>> +MODULE_AUTHOR("Andy Yan >> +MODULE_DESCRIPTION("System reboot mode driver");
>>> +MODULE_LICENSE("GPL v2");
>>> diff --git a/drivers/power/reset/reboot-mode.h
>>> b/drivers/power/reset/reboot-mode.h
>>> new file mode 100644
>>> index 000..44ed34f
>>> --- /dev/null
>>> +++ b/drivers/power/reset/reboot-mode.h
>>> @@ -0,0 +1,6 @@
>>> +#ifndef __REBOOT_MODE_H__
>>> +#define __REBOOT_MODE_H__
>>> +
>>> +int reboot_mode_register(struct device *dev, int (*write)(int));
>> Documentation would be appreciated. Although it is local header but
>> you decoupled them and you are exporting the function.
> 
>You want this driver being a module in V9, so you may also want
>  I document this function when a exporting it. Where I should write the
>  documentation, and would you please give me some example?

Follow kernel-doc (kernel-doc-nano-HOWTO.txt). There is an example. Put
the documentation of functions next to them in source file (not header).

Best regards,
Krzysztof


Re: [PATCH] ARM: dts: exynos: Add reboot reason support for Trats2

2016-09-22 Thread Krzysztof Kozlowski
Hi,

Thanks for the patch, it is nice that someone did this! When I saw the
syscon reboot mode driver, I though about such feature but never had
time or will to implement it. Great job!

Few comments below.

On Thu, Sep 22, 2016 at 06:48:35PM +0200, Wolfgang Wiedmeyer wrote:
> This allows to reboot the device into recovery mode and into the download
> mode of the bootloader.

Which bootloader? Probably UBoot... or Samsung stock one? Could you put
that information here?

> 
> Signed-off-by: Wolfgang Wiedmeyer 
> ---
>  arch/arm/boot/dts/exynos4412-trats2.dts | 14 ++
>  arch/arm/boot/dts/exynos4x12.dtsi   |  2 +-
>  2 files changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts 
> b/arch/arm/boot/dts/exynos4412-trats2.dts
> index 129e973..a38d1e3 100644
> --- a/arch/arm/boot/dts/exynos4412-trats2.dts
> +++ b/arch/arm/boot/dts/exynos4412-trats2.dts
> @@ -1294,3 +1294,17 @@
>   vtmu-supply = <&ldo10_reg>;
>   status = "okay";
>  };
> +
> +&pmu {
> + compatible = "syscon", "simple-mfd";
> +
> + reboot-mode {
> + compatible = "syscon-reboot-mode";
> + offset = <0x80c>;
> +
> + mode-normal = <0x12345670>;
> + mode-bootloader = <0x12345671>;
> + mode-download   = <0x12345671>;
> + mode-recovery   = <0x12345674>;

Hmmm, how did you get these values? Are they already supported?

It would be nice to document them:
1. In Documentation/arm/Samsung/Bootloader-interface.txt
2. In header. I hate such magic numbers... you could add new header next
   to existing rockchip one:
   include/dt-bindings/soc/samsung,boot-mode.h
   (and update maintainers entry :) )


Best regards,
Krzysztof


> + };
> +};
> diff --git a/arch/arm/boot/dts/exynos4x12.dtsi 
> b/arch/arm/boot/dts/exynos4x12.dtsi
> index c452499..b58c14e 100644
> --- a/arch/arm/boot/dts/exynos4x12.dtsi
> +++ b/arch/arm/boot/dts/exynos4x12.dtsi
> @@ -179,7 +179,7 @@
>   ranges;
>   status = "disabled";
>  
> - pmu@1002 {
> + pmu: pmu@1002 {
>   reg = <0x1002 0x3000>;
>   };
>  
> -- 
> Website: https://fossencdi.org
> OpenPGP: 0F30 D1A0 2F73 F70A 6FEE  048E 5816 A24C 1075 7FC4
> Key download: https://wiedmeyer.de/keys/ww.asc
> 


Re: [PATCH] ARM: dts: exynos: Add reboot reason support for Trats2

2016-09-22 Thread Krzysztof Kozlowski
On Thu, Sep 22, 2016 at 08:59:03PM +0200, Wolfgang Wiedmeyer wrote:
> 
> Krzysztof Kozlowski writes:
> 
> > On Thu, Sep 22, 2016 at 06:48:35PM +0200, Wolfgang Wiedmeyer wrote:
> >> This allows to reboot the device into recovery mode and into the download
> >> mode of the bootloader.
> >
> > Which bootloader? Probably UBoot... or Samsung stock one? Could you put
> > that information here?
> 
> I'm only working with the stock one. I was under the impression that the
> stock bootloader cannot be replaced on a i9300 because there's a
> signature check. Is UBoot loaded after the stock one on Trats2 or how
> does this work? I didn't find information on that.

+CC Marek,

Trats2 is working with U-Boot. Just U-Boot. However I never converted S3
into Trats2 on my own. I always used targets prepared to be "Trats2"
type. 

Of course kernel is independent to bootloader but in that case you want
to use a specific interface between kernel and specific bootloader
type/version. In that case - this should be U-Boot, I think.

> 
> >> 
> >> Signed-off-by: Wolfgang Wiedmeyer 
> >> ---
> >>  arch/arm/boot/dts/exynos4412-trats2.dts | 14 ++
> >>  arch/arm/boot/dts/exynos4x12.dtsi   |  2 +-
> >>  2 files changed, 15 insertions(+), 1 deletion(-)
> >> 
> >> diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts 
> >> b/arch/arm/boot/dts/exynos4412-trats2.dts
> >> index 129e973..a38d1e3 100644
> >> --- a/arch/arm/boot/dts/exynos4412-trats2.dts
> >> +++ b/arch/arm/boot/dts/exynos4412-trats2.dts
> >> @@ -1294,3 +1294,17 @@
> >>vtmu-supply = <&ldo10_reg>;
> >>status = "okay";
> >>  };
> >> +
> >> +&pmu {
> >> +  compatible = "syscon", "simple-mfd";
> >> +
> >> +  reboot-mode {
> >> +  compatible = "syscon-reboot-mode";
> >> +  offset = <0x80c>;
> >> +
> >> +  mode-normal = <0x12345670>;
> >> +  mode-bootloader = <0x12345671>;
> >> +  mode-download   = <0x12345671>;
> >> +  mode-recovery   = <0x12345674>;
> >
> > Hmmm, how did you get these values? Are they already supported?
> 
> I only have the vendor source drop as documentation. The magic mode
> values [1] and the offset [2] can be found there.

It would be useful to mention that in commit msg (just the source)...
however as I wrote above, these values should be for U-Boot, not the
stock one.

Best regards,
Krzysztof

> 
> > It would be nice to document them:
> > 1. In Documentation/arm/Samsung/Bootloader-interface.txt
> > 2. In header. I hate such magic numbers... you could add new header next
> >to existing rockchip one:
> >include/dt-bindings/soc/samsung,boot-mode.h
> >(and update maintainers entry :) )
> 
> Thanks for the review! I will do the documentation and update the commit
> message.
> 
> Best regards,
> Wolfgang
> 
> [1] 
> https://code.fossencdi.org/kernel_samsung_smdk4412.git/tree/arch/arm/mach-exynos/sec-reboot.c#n65
> 
> [2] 
> https://code.fossencdi.org/kernel_samsung_smdk4412.git/tree/arch/arm/mach-exynos/include/mach/regs-pmu.h#n79
> 
> 
> -- 
> Website: https://fossencdi.org
> Jabber: wolfg...@wiedmeyer.de
> OpenPGP: 0F30 D1A0 2F73 F70A 6FEE  048E 5816 A24C 1075 7FC4
> Key download: https://wiedmeyer.de/keys/ww.asc




Re: [PATCH] ARM: dts: exynos: Add reboot reason support for Trats2

2016-09-25 Thread Krzysztof Kozlowski
On Sat, Sep 24, 2016 at 11:04:49PM +0200, Wolfgang Wiedmeyer wrote:
> 
> Krzysztof Kozlowski writes:
> 
> > On Thu, Sep 22, 2016 at 08:59:03PM +0200, Wolfgang Wiedmeyer wrote:
> >> 
> >> Krzysztof Kozlowski writes:
> >> 
> >> > On Thu, Sep 22, 2016 at 06:48:35PM +0200, Wolfgang Wiedmeyer wrote:
> >> >> This allows to reboot the device into recovery mode and into the 
> >> >> download
> >> >> mode of the bootloader.
> >> >
> >> > Which bootloader? Probably UBoot... or Samsung stock one? Could you put
> >> > that information here?
> >> 
> >> I'm only working with the stock one. I was under the impression that the
> >> stock bootloader cannot be replaced on a i9300 because there's a
> >> signature check. Is UBoot loaded after the stock one on Trats2 or how
> >> does this work? I didn't find information on that.
> >
> > +CC Marek,
> >
> > Trats2 is working with U-Boot. Just U-Boot. However I never converted S3
> > into Trats2 on my own. I always used targets prepared to be "Trats2"
> > type. 
> 
> It would be awesome to be able to run U-Boot on i9300. Is there a way to
> test this by not risking to brick the device, e.g. by booting from the
> SD card? Then I could send an updated version of the patch that is
> compatible with U-Boot :)

I don't think the stock bootloader supports chaining another bootloader
from SD card. There is a way of booting from SD card by shortening a
resistor but it is an emergency rescue procedure to overwrite existing
bootloader with data from SD card (to restore device). This thread might
be interesting:
http://forum.xda-developers.com/showpost.php?p=47234165&postcount=220
https://smyl.es/samsung-galaxy-iii-s3-gt-i9300-jtag-leaked-document-how-to-repair-soft-bricked-galaxy-s3/

On xda-developers you might find more data about this (including the
procedure for emergency restore from SD card). Somehow people flash and
unbrick their devices when playing with CyanogenMod...

Best regards,
Krzysztof


Re: [PATCH 2/2] power: supply: max17042_battery: add technology property support

2016-09-26 Thread Krzysztof Kozlowski
On Sun, Sep 25, 2016 at 11:10:11PM +0200, Wolfgang Wiedmeyer wrote:
> This patch reports the battery technology as Li-ion.
> 
> Signed-off-by: Wolfgang Wiedmeyer 
> ---
>  drivers/power/max17042_battery.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/power/max17042_battery.c 
> b/drivers/power/max17042_battery.c
> index 20cb1fd..43cb5df 100644
> --- a/drivers/power/max17042_battery.c
> +++ b/drivers/power/max17042_battery.c
> @@ -92,6 +92,7 @@ static enum power_supply_property max17042_battery_props[] 
> = {
>   POWER_SUPPLY_PROP_TEMP_MIN,
>   POWER_SUPPLY_PROP_TEMP_MAX,
>   POWER_SUPPLY_PROP_HEALTH,
> + POWER_SUPPLY_PROP_TECHNOLOGY,
>   POWER_SUPPLY_PROP_CURRENT_NOW,
>   POWER_SUPPLY_PROP_CURRENT_AVG,
>  };
> @@ -296,6 +297,9 @@ static int max17042_get_property(struct power_supply *psy,
>   if (ret < 0)
>   return ret;
>   break;
> + case POWER_SUPPLY_PROP_TECHNOLOGY:
> + val->intval = POWER_SUPPLY_TECHNOLOGY_LION;

How can you be sure it is always Li-Ion? For wearables and mobiles, rather yes, 
but
the driver is also used in other devices. Technically, specs are saying
it might be used also with Li-Poly applications.

Best regards,
Krzysztof



Re: [PATCH 1/2] power: supply: max17042_battery: use VF SOC register for capacity property

2016-09-26 Thread Krzysztof Kozlowski
On Sun, Sep 25, 2016 at 11:10:10PM +0200, Wolfgang Wiedmeyer wrote:
> The capacity property uses the RepSOC register to report the current state
> of charge. This register did not provide a reliable SOC value during my
> testing with the max17047 variant on a Galaxy S3 (Trats2/GT-I9300). The
> reported value did not change or even stayed zero in some cases.
> However, the VF SOC register provided an accurate SOC value at all times.
> It uses the voltage fuel gauge to determine the SOC.
> 
> Signed-off-by: Wolfgang Wiedmeyer 
> ---
>  drivers/power/max17042_battery.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/power/max17042_battery.c 
> b/drivers/power/max17042_battery.c
> index da7a75f..20cb1fd 100644
> --- a/drivers/power/max17042_battery.c
> +++ b/drivers/power/max17042_battery.c
> @@ -246,7 +246,7 @@ static int max17042_get_property(struct power_supply *psy,
>   val->intval = data * 625 / 8;
>   break;
>   case POWER_SUPPLY_PROP_CAPACITY:
> - ret = regmap_read(map, MAX17042_RepSOC, &data);
> + ret = regmap_read(map, MAX17042_VFSOC, &data);
>   if (ret < 0)
>   return ret;

The RepSOC is for ModelGauge m3 which requires current sense resistor. I
don't remember whether the resistor is present on Trats2. If not, then
m1 is used. However in both cases (m1 and m3) the battery
characteristics (cell information) should be loaded which in case of DT
driver is not supported.

Overall, I am not sure whether your change is correct. It might fix this
particular scenario because:
1. We are not providing the cell information,
2. We mre not providing the SNS resistor value so we are in m1 mode (if
there is no SNS resistor).  but it might break other applications where
SNS is present and cell configuration is provided. Unless you tested it
in such?

Probably this should be based on Device Tree property describing what is
configured (e.g. missing model data). Maybe existing maxim,rsns-microohm
could be used - in case of lack of it, fall back to reading VFSOC?

Best regards,
Krzysztof



Re: [PATCH 2/2] power: supply: max17042_battery: add technology property support

2016-09-26 Thread Krzysztof Kozlowski
On Mon, Sep 26, 2016 at 02:56:44PM +0200, Wolfgang Wiedmeyer wrote:
> 
> Krzysztof Kozlowski writes:
> 
> > On Sun, Sep 25, 2016 at 11:10:11PM +0200, Wolfgang Wiedmeyer wrote:
> >> This patch reports the battery technology as Li-ion.
> >> 
> >> Signed-off-by: Wolfgang Wiedmeyer 
> >> ---
> >>  drivers/power/max17042_battery.c | 4 
> >>  1 file changed, 4 insertions(+)
> >> 
> >> diff --git a/drivers/power/max17042_battery.c 
> >> b/drivers/power/max17042_battery.c
> >> index 20cb1fd..43cb5df 100644
> >> --- a/drivers/power/max17042_battery.c
> >> +++ b/drivers/power/max17042_battery.c
> >> @@ -92,6 +92,7 @@ static enum power_supply_property 
> >> max17042_battery_props[] = {
> >>POWER_SUPPLY_PROP_TEMP_MIN,
> >>POWER_SUPPLY_PROP_TEMP_MAX,
> >>POWER_SUPPLY_PROP_HEALTH,
> >> +  POWER_SUPPLY_PROP_TECHNOLOGY,
> >>POWER_SUPPLY_PROP_CURRENT_NOW,
> >>POWER_SUPPLY_PROP_CURRENT_AVG,
> >>  };
> >> @@ -296,6 +297,9 @@ static int max17042_get_property(struct power_supply 
> >> *psy,
> >>if (ret < 0)
> >>return ret;
> >>break;
> >> +  case POWER_SUPPLY_PROP_TECHNOLOGY:
> >> +  val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
> >
> > How can you be sure it is always Li-Ion? For wearables and mobiles, rather 
> > yes, but
> > the driver is also used in other devices. Technically, specs are saying
> > it might be used also with Li-Poly applications.
> 
> I suppose that there is no way to detect this. Would it be ok if I add
> an optional Device Tree property that allows to specify if it's Li-Ion
> or Li-Poly? If the property is not supplied, then "unknown" is returned.

I am not sure in such case what will be the benefit of exposing this to
user-space... but it won't harm neither and sounds like a valid usage of
DT properties. Fine with me.

Best regards,
Krzysztof


Re: [PATCH] ARM: dts: exynos: Add reboot reason support for Trats2

2016-09-26 Thread Krzysztof Kozlowski
On Sun, Sep 25, 2016 at 09:34:45AM +0200, Krzysztof Kozlowski wrote:
> On Sat, Sep 24, 2016 at 11:04:49PM +0200, Wolfgang Wiedmeyer wrote:
> > 
> > Krzysztof Kozlowski writes:
> > 
> > > On Thu, Sep 22, 2016 at 08:59:03PM +0200, Wolfgang Wiedmeyer wrote:
> > >> 
> > >> Krzysztof Kozlowski writes:
> > >> 
> > >> > On Thu, Sep 22, 2016 at 06:48:35PM +0200, Wolfgang Wiedmeyer wrote:
> > >> >> This allows to reboot the device into recovery mode and into the 
> > >> >> download
> > >> >> mode of the bootloader.
> > >> >
> > >> > Which bootloader? Probably UBoot... or Samsung stock one? Could you put
> > >> > that information here?
> > >> 
> > >> I'm only working with the stock one. I was under the impression that the
> > >> stock bootloader cannot be replaced on a i9300 because there's a
> > >> signature check. Is UBoot loaded after the stock one on Trats2 or how
> > >> does this work? I didn't find information on that.
> > >
> > > +CC Marek,
> > >
> > > Trats2 is working with U-Boot. Just U-Boot. However I never converted S3
> > > into Trats2 on my own. I always used targets prepared to be "Trats2"
> > > type. 
> > 
> > It would be awesome to be able to run U-Boot on i9300. Is there a way to
> > test this by not risking to brick the device, e.g. by booting from the
> > SD card? Then I could send an updated version of the patch that is
> > compatible with U-Boot :)
> 
> I don't think the stock bootloader supports chaining another bootloader
> from SD card. There is a way of booting from SD card by shortening a
> resistor but it is an emergency rescue procedure to overwrite existing
> bootloader with data from SD card (to restore device). This thread might
> be interesting:
> http://forum.xda-developers.com/showpost.php?p=47234165&postcount=220
> https://smyl.es/samsung-galaxy-iii-s3-gt-i9300-jtag-leaked-document-how-to-repair-soft-bricked-galaxy-s3/
> 
> On xda-developers you might find more data about this (including the
> procedure for emergency restore from SD card). Somehow people flash and
> unbrick their devices when playing with CyanogenMod...

Hi Wolfgang,

Few more info from my side. It is (rather) not possible to just flash
GT-I9300 with U-Boot. It still requires S-Boot as a primary bootloader
(probably different than the stock one). I think such binary S-Boot was
published along with Tizen images for Trats2 (called RD-PQ). These
images however started to disappear from download.tizen.org. You can
still find some, e.g.:
http://download.tizen.org/releases/system/Tizen_RD-PQ_System_20130716_1.tar

(better download it soon :) ) This 'tar' should be uploaded through
Lthor (also from tizen.org) however it might require appropriate
Partition Information Table (PIT).
On Tizen Wiki you might find some guides for flashing/upgrading-PIT on Trats2.

However, please be careful, as all of these steps (and linked binary) are
targeted to existing RD-PQ/Trats2 boards. They are not intended as a
way of converting GT-I9300 into Trats2. The conversion might work but...
it might not.

Before playing with it, I think it would be wise to have the emergency
recovery procedure (with SD card) ready.

Best regards,
Krzysztof


Re: [PATCH 2/3] regulator: max77693: Also manipulate the fast charge current

2016-09-27 Thread Krzysztof Kozlowski
On Tue, Sep 27, 2016 at 01:31:09AM +0200, Wolfgang Wiedmeyer wrote:
> For MAX77693, the fast charge current also needs to be manipulated for
> proper charging. The fast charge current is only set in the case of
> the MAX77693 type, as the MAX77843 properly manipulates the fast
> charge current.

Are you sure it has to be manipulated? Some time I didn't dig into this.
Now I looked at the datasheet and it says that usually there is no need
for changing the charge current during the operation. Maxim recommends
to setting it to a maximum safe value for the battery. The device will
manage charge current on its own.

However I agree that the charge current should be set... maybe once, to
a maximum value appropriate for battery. Probably this should be done
by max77693_charger in max77693_dt_init().

Best regards,
Krzysztof


> The fast charge current is set to the next possible value below the
> maximum input current.


> 
> Signed-off-by: Wolfgang Wiedmeyer 
> ---
>  drivers/regulator/max77693-regulator.c | 45 
> +++---
>  1 file changed, 42 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/regulator/max77693-regulator.c 
> b/drivers/regulator/max77693-regulator.c
> index cfbb951..e2f7584 100644
> --- a/drivers/regulator/max77693-regulator.c
> +++ b/drivers/regulator/max77693-regulator.c
> @@ -54,14 +54,19 @@ struct chg_reg_data {
>   unsigned int linear_mask;
>   unsigned int uA_step;
>   unsigned int min_sel;
> +
> + bool set_fast;
> + unsigned int fast_reg;
> + unsigned int fast_mask;
>  };
>  
>  /*
>   * MAX77693 CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA
>   * 0x00, 0x01, 0x2, 0x03 = 60 mA
>   * 0x04 ~ 0x7E   = (60 + (X - 3) * 20) mA
> - * Actually for MAX77693 the driver manipulates the maximum input current,
> - * not the fast charge current (output). This should be fixed.
> + * Actually for MAX77693 the driver manipulates the maximum input current
> + * and the fast charge current (output) because the fast charge current
> + * is not set.
>   *
>   * On MAX77843 the calculation formula is the same (except values).
>   * Fortunately it properly manipulates the fast charge current.
> @@ -100,6 +105,8 @@ static int max77693_chg_set_current_limit(struct 
> regulator_dev *rdev,
>   const struct chg_reg_data *reg_data = rdev_get_drvdata(rdev);
>   unsigned int chg_min_uA = rdev->constraints->min_uA;
>   int sel = 0;
> + unsigned int data;
> + int ret;
>  
>   while (chg_min_uA + reg_data->uA_step * sel < min_uA)
>   sel++;
> @@ -110,7 +117,35 @@ static int max77693_chg_set_current_limit(struct 
> regulator_dev *rdev,
>   /* the first four codes for charger current are all 60mA */
>   sel += reg_data->min_sel;
>  
> - return regmap_write(rdev->regmap, reg_data->linear_reg, sel);
> + ret = regmap_write(rdev->regmap, reg_data->linear_reg, sel);
> + if (ret < 0)
> + return ret;
> +
> + if (reg_data->set_fast) {
> + /* disable fast charge if minimum value */
> + if (sel == reg_data->min_sel)
> + data = 0;
> + else {
> + /*
> +  * set the fast charge current to the closest value
> +  * below the input current
> +  */
> + ret = regmap_read(rdev->regmap, reg_data->fast_reg,
> +   &data);
> + if (ret < 0)
> + return ret;
> +
> + sel *= reg_data->uA_step / 1000; /* convert to mA */
> + data &= ~reg_data->fast_mask;
> + data |= sel * 10 / 333; /* 0.1A/3 steps */
> + }
> +
> + ret = regmap_write(rdev->regmap, reg_data->fast_reg, data);
> + if (ret < 0)
> + return ret;
> + }
> +
> + return 0;
>  }
>  /* end of CHARGER regulator ops */
>  
> @@ -197,6 +232,9 @@ static const struct chg_reg_data max77693_chg_reg_data = {
>   .linear_mask= CHG_CNFG_09_CHGIN_ILIM_MASK,
>   .uA_step= 2,
>   .min_sel= 3,
> + .set_fast   = true,
> + .fast_reg   = MAX77693_CHG_REG_CHG_CNFG_02,
> + .fast_mask  = CHG_CNFG_02_CC_MASK,
>  };
>  
>  #define  max77843_regulator_desc_esafeout(num)   {   
> \
> @@ -237,6 +275,7 @@ static const struct chg_reg_data max77843_chg_reg_data = {
>   .linear_mask= MAX77843_CHG_FAST_CHG_CURRENT_MASK,
>   .uA_step= MAX77843_CHG_FAST_CHG_CURRENT_STEP,
>   .min_sel= 2,
> + .set_fast   = false,
>  };
>  
>  static int max77693_pmic_probe(struct platform_device *pdev)
> -- 
> 2.8.0.rc3
> 


Re: [PATCH 1/3] mfd: max77693: Add defines for charger current control

2016-09-27 Thread Krzysztof Kozlowski
On Tue, Sep 27, 2016 at 01:31:08AM +0200, Wolfgang Wiedmeyer wrote:
> This prepares for an updated regulator and charger driver. The defines
> are needed to set the maximum input current and the fast charge
> current.
> 
> Signed-off-by: Wolfgang Wiedmeyer 

This shouldn't be separate patch, because:
1. You are touching later power and regulator so this patch should be
applied to one and then pulled by other... a lot of unneeded work.
2. It is difficult to find which new code is needed for which driver.

Simpler approach might work - when changing the regulator or psy driver,
just change the header as needed. Unless there are conflicts and both of
them need the same?

Best regards,
Krzysztof

> ---
>  include/linux/mfd/max77693-private.h | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/include/linux/mfd/max77693-private.h 
> b/include/linux/mfd/max77693-private.h
> index 3c7a63b..ca18344 100644
> --- a/include/linux/mfd/max77693-private.h
> +++ b/include/linux/mfd/max77693-private.h
> @@ -222,6 +222,9 @@ enum max77693_charger_battery_state {
>  #define CHG_CNFG_00_CHG_MASK 0x1
>  #define CHG_CNFG_00_BUCK_MASK0x4
>  
> +/* MAX77693 CHG_CNFG_02 register */
> +#define CHG_CNFG_02_CC_MASK  0x3F
> +
>  /* MAX77693_CHG_REG_CHG_CNFG_01 register */
>  #define CHG_CNFG_01_FCHGTIME_SHIFT   0
>  #define CHG_CNFG_01_CHGRSTRT_SHIFT   4
> @@ -258,6 +261,10 @@ enum max77693_charger_battery_state {
>  
>  /* MAX77693 CHG_CNFG_09 Register */
>  #define CHG_CNFG_09_CHGIN_ILIM_MASK  0x7F
> +#define CHG_CNFG_09_CHGIN_ILIM_500_MAX   50
> +#define CHG_CNFG_09_CHGIN_ILIM_500_MIN   47
> +#define CHG_CNFG_09_CHGIN_ILIM_0_MAX 6
> +#define CHG_CNFG_09_CHGIN_ILIM_0_MIN 0
>  
>  /* MAX77693 CHG_CTRL Register */
>  #define SAFEOUT_CTRL_SAFEOUT1_MASK   0x3
> -- 
> 2.8.0.rc3
> 


Re: [PATCH 3/3] power_supply: max77693: Listen for cable events and enable charging

2016-09-27 Thread Krzysztof Kozlowski
On Tue, Sep 27, 2016 at 01:31:10AM +0200, Wolfgang Wiedmeyer wrote:
> This patch adds a listener for extcon cable events and enables
> charging if an USB cable is connected. It recognizes SDP and DCP cable
> types and treats them the same (same input current and fast charge
> current). The maximum input current is set before the charger is
> enabled and before the charger gets disabled, the maximum input
> current is set to zero. The listener is inspired by the listener
> implementation that was used for the AXP288 Charger driver.
> 
> The patch also adds support for the CURRENT_NOW property. It reads the
> fast charge current that gets set before the charger is enabled or
> disabled.
> 
> Signed-off-by: Wolfgang Wiedmeyer 

No. This power supply driver should not manage regulators. It is not a
regulator consumer. For that specific need, there is a charger-manager driver.

I agree that you might configure here the charger. You might even expose
some writeable properties through power supply class. However the
purpose of this driver is to expose the battery charger to user-space,
not to replace the user-space with its work.

So... NACK.

If you would like to play with charger-manager, here is my old DTS for
Trats2 (might need updates):

index 595ad4ba6977..b4361b4a9de7 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -856,6 +856,44 @@
};
};
 
+   charger-manager@0 {
+   compatible = "charger-manager";
+   status = "okay";
+   chg-reg-supply = <&charger_reg>;
+
+   cm-name = "battery";
+   /* Polling only for external power source */
+   cm-poll-mode = <2>;
+   cm-poll-interval = <3>;
+
+   cm-fullbatt-vchkdrop-ms = <3>;
+   cm-fullbatt-vchkdrop-volt = <15>;
+   cm-fullbatt-soc = <100>;
+
+   cm-battery-stat = <0>;
+   cm-fuel-gauge = "max170xx_battery";
+
+   /* Allow charging for 5hr */
+   cm-charging-max = <1800>;
+   /* Allow discharging for 2hr */
+   cm-discharging-max = <720>;
+
+   cm-num-chargers = <1>;
+   cm-chargers = "max77693-charger";
+
+   charger@0 {
+   cm-regulator-name = "chg-reg";
+   cable@0 {
+   cm-cable-name = "USB";
+   cm-cable-extcon = "max77693-muic";
+   };
+   cable@1 {
+   cm-cable-name = "TA";
+   cm-cable-extcon = "max77693-muic";
+   };
+   };
+   };
+
exynos-usbphy@125B {
status = "okay";
};

Signed-off-by: Krzysztof Kozlowski 

Best regards,
Krzysztof



Re: [PATCH v4] ARM: dts: exynos: Enable HDMI for Arndale Octa board

2016-08-31 Thread Krzysztof Kozlowski
On 08/31/2016 08:54 AM, Andrzej Hajda wrote:
> On 08/31/2016 08:08 AM, Milo Kim wrote:
>> * GPIO for HDMI hot plug detect
>>   GPX3_7 is used. The HPD awareness is done when the GPIO is active high.
>>
>> * Enable HDMI block in Exynos5420
>>   HDMI VDD and PLL consume 1.0V LDO6 (PVDD_ANAIP_1V0) and HDMI oscillator
>>   requires 1.8V LDO7 (PVDD_ANAIP_1V8).
>>
>> * Support HDMI display data channel
>>   I2C #2 is assigned for the HDMI DDC. It enables the EDID access.
>>
>> Cc: Kukjin Kim 
>> Cc: Krzysztof Kozlowski 
>> Cc: Rob Herring 
>> Cc: linux-arm-ker...@lists.infradead.org
>> Cc: linux-samsung-...@vger.kernel.org
>> Cc: linux-kernel@vger.kernel.org
>> Signed-off-by: Milo Kim 
> 
> Reviewed-by: Andrzej Hajda 

Thanks, applied with Andrzej's review.

Best regards,
Krzysztof



[PATCH 7/9] ARM: dts: exynos: Use macros for GPIO configuration on exynos5260

2016-08-31 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos5260-pinctrl.dtsi  | 184 ++---
 arch/arm/boot/dts/exynos5260-xyref5260.dts |   6 +-
 2 files changed, 95 insertions(+), 95 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5260-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
index efd01b816538..acce33d93a7a 100644
--- a/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
@@ -198,217 +198,217 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <2>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
uart0_fctl: uart0-fctl {
samsung,pins = "gpa0-2", "gpa0-3";
-   samsung,pin-function = <2>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
uart1_data: uart1-data {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <2>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
uart1_fctl: uart1-fctl {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <2>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
uart2_data: uart2-data {
samsung,pins = "gpa1-4", "gpa1-5";
-   samsung,pin-function = <2>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
spi0_bus: spi0-bus {
samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3";
-   samsung,pin-function = <2>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
spi1_bus: spi1-bus {
samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
-   samsung,pin-function = <2>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
usb3_vbus0_en: usb3-vbus0-en {
samsung,pins = "gpa2-4";
-   samsung,pin-function = <1>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
i2s1_bus: i2s1-bus {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
"gpb0-4";
-   samsung,pin-function = <2>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
pcm1_bus: pcm1-bus {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
"gpb0-4";
-   samsung,pin-function = <3>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
spdif1_bus: spdif1-bus {
samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2";
-   samsung,pin-function = <4>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
spi2_bus: spi2-bus {
samsung,pins = "gpb1-0", "gpb1-2", "gpb1-3";
-   samsung,pin-function = <2>;
+   samsung,pin-function = ;
samsung,pin-pud = ;
-   samsung,pin-drv = <0>;
+   samsung,pin-drv = ;
};
 
i2c0_hs_bus: i2c0-hs-bus {
samsung,pins = "gpb3-0", "gpb3-1";
-   samsung,pin-function = <2>;
+   samsung,pin-function = ;
  

[PATCH 5/9] ARM: dts: exynos: Use macros for GPIO configuration on exynos4x12

2016-08-31 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi |  14 +-
 arch/arm/boot/dts/exynos4412-odroidx.dts|   2 +-
 arch/arm/boot/dts/exynos4412-origen.dts |  12 +-
 arch/arm/boot/dts/exynos4412-smdk4412.dts   |  12 +-
 arch/arm/boot/dts/exynos4x12-pinctrl.dtsi   | 504 
 5 files changed, 272 insertions(+), 272 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi 
b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index be644fe6a0fd..5adbeb485a97 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -163,26 +163,26 @@
 
 /* RSTN signal for eMMC */
 &sd1_cd {
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
 };
 
 &pinctrl_1 {
gpio_power_key: power_key {
samsung,pins = "gpx1-3";
-   samsung,pin-pud = <0>;
+   samsung,pin-pud = ;
};
 
max77686_irq: max77686-irq {
samsung,pins = "gpx3-2";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
hdmi_hpd: hdmi-hpd {
samsung,pins = "gpx3-7";
-   samsung,pin-pud = <1>;
+   samsung,pin-pud = ;
};
 };
 
diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts 
b/arch/arm/boot/dts/exynos4412-odroidx.dts
index 2af235151301..647a3e97d942 100644
--- a/arch/arm/boot/dts/exynos4412-odroidx.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidx.dts
@@ -83,7 +83,7 @@
 &pinctrl_1 {
gpio_home_key: home_key {
samsung,pins = "gpx2-2";
-   samsung,pin-pud = <0>;
+   samsung,pin-pud = ;
};
 };
 
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts 
b/arch/arm/boot/dts/exynos4412-origen.dts
index 26a36fed9652..0a490e0e7eac 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -500,16 +500,16 @@
 &pinctrl_1 {
keypad_rows: keypad-rows {
samsung,pins = "gpx2-0", "gpx2-1", "gpx2-2";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
keypad_cols: keypad-cols {
samsung,pins = "gpx1-0", "gpx1-1";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 };
 
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts 
b/arch/arm/boot/dts/exynos4412-smdk4412.dts
index 231ffbdbf9d0..d9ce24416bed 100644
--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -115,17 +115,17 @@
 &pinctrl_1 {
keypad_rows: keypad-rows {
samsung,pins = "gpx2-0", "gpx2-1", "gpx2-2";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
keypad_cols: keypad-cols {
samsung,pins = "gpx1-0", "gpx1-1", "gpx1-2", "gpx1-3",
   "gpx1-4", "gpx1-5", "gpx1-6", "gpx1-7";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 };
 
diff --git a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
index ba5865208d3e..dc5e9a932357 100644
--- a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
@@ -149,245 +149,245 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <0x2>;
-   samsung,pin-pud = <0>;
-   samsu

[PATCH 6/9] ARM: dts: exynos: Use macros for GPIO configuration on exynos5250

2016-08-31 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 402 +-
 arch/arm/boot/dts/exynos5250-smdk5250.dts |   6 +-
 arch/arm/boot/dts/exynos5250-snow-common.dtsi |  76 ++---
 arch/arm/boot/dts/exynos5250-snow-rev5.dts|   6 +-
 arch/arm/boot/dts/exynos5250-snow.dts |   6 +-
 arch/arm/boot/dts/exynos5250-spring.dts   |  72 ++---
 6 files changed, 284 insertions(+), 284 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
index 5563dd80d4d0..688c6231caae 100644
--- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
@@ -217,392 +217,392 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart0_fctl: uart0-fctl {
samsung,pins = "gpa0-2", "gpa0-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_bus: i2c2-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_hs_bus: i2c2-hs-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <4>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_data: uart2-data {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_fctl: uart2-fctl {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c3_bus: i2c3-bus {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c3_hs_bus: i2c3-hs-bus {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <4>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart3_data: uart3-data {
samsung,pins = "gpa1-4", "gpa1-4";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
spi0_bus: spi0-bus {
samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c4_bus: i2c4-bus {
samsung,pins = "gpa2-0", "gpa2-1";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c5_bus: i2c5-bus

[PATCH 4/9] ARM: dts: exynos: Use macros for GPIO configuration on exynos4415

2016-08-31 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos4415-pinctrl.dtsi | 286 +++---
 1 file changed, 143 insertions(+), 143 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4415-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
index ae9d140a24d1..e61741fb9765 100644
--- a/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
@@ -111,180 +111,180 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <0x2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart0_fctl: uart0-fctl {
samsung,pins = "gpa0-2", "gpa0-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_data: uart1-data {
samsung,pins = "gpa0-4", "gpa0-5";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_fctl: uart1-fctl {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_data: uart2-data {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_fctl: uart2-fctl {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart3_data: uart3-data {
samsung,pins = "gpa1-4", "gpa1-5";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_bus: i2c2-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c3_bus: i2c3-bus {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
spi0_bus: spi0-bus {
samsung,pins = "gpb-0", "gpb-2", "gpb-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c4_bus: i2c4-bus {
samsung,pins = "gpb-0", "gpb-1";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
spi1_bus: spi1-bus {
samsung,pins = "gpb-4", "gpb-6", "gpb-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsun

[PATCH 8/9] ARM: dts: exynos: Use macros for GPIO configuration on exynos5410

2016-08-31 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos5410-odroidxu.dts |  30 ++---
 arch/arm/boot/dts/exynos5410-pinctrl.dtsi | 180 +++---
 arch/arm/boot/dts/exynos5410-smdk5410.dts |  10 +-
 3 files changed, 110 insertions(+), 110 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts 
b/arch/arm/boot/dts/exynos5410-odroidxu.dts
index a5ae76c1838f..6b36b9bfd1ec 100644
--- a/arch/arm/boot/dts/exynos5410-odroidxu.dts
+++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts
@@ -473,38 +473,38 @@
 &pinctrl_0 {
emmc_nrst_pin: emmc-nrst {
samsung,pins = "gpd1-0";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
pmic_dvs_3: pmic-dvs-3 {
samsung,pins = "gpx0-0";
-   samsung,pin-function = <1>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
pmic_dvs_2: pmic-dvs-2 {
samsung,pins = "gpx0-1";
-   samsung,pin-function = <1>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
pmic_dvs_1: pmic-dvs-1 {
samsung,pins = "gpx0-2";
-   samsung,pin-function = <1>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
samsung,pin-val = <1>;
};
 
max77802_irq: max77802-irq {
samsung,pins = "gpx0-4";
-   samsung,pin-function = <0xf>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 };
 
diff --git a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
index 10272fa54c37..acb21cbbb1e1 100644
--- a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
@@ -296,212 +296,212 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart0_fctl: uart0-fctl {
samsung,pins = "gpa0-2", "gpa0-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_data: uart1-data {
samsung,pins = "gpa0-4", "gpa0-5";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_fctl: uart1-fctl {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_bus: i2c2-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_data: uart2-data {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-d

[PATCH 9/9] ARM: dts: exynos: Use macros for GPIO configuration on exynos542x/exynos5800

2016-08-31 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  |   6 +-
 arch/arm/boot/dts/exynos5420-peach-pit.dts | 126 
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi  | 354 ++---
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |  18 +-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  18 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts  | 126 
 6 files changed, 324 insertions(+), 324 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts 
b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index 39a3b81478fd..7b9f67807308 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -378,9 +378,9 @@
 &pinctrl_0 {
s2mps11_irq: s2mps11-irq {
samsung,pins = "gpx3-2";
-   samsung,pin-function = <0xf>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 };
 
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts 
b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index f6f256fd9b5e..69c511f67d26 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -753,171 +753,171 @@
 
wifi_en: wifi-en {
samsung,pins = "gpx0-0";
-   samsung,pin-function = <1>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
max98090_irq: max98090-irq {
samsung,pins = "gpx0-2";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
/* We need GPX0_6 to be low at sleep time; just keep it low always */
mask_tpm_reset: mask-tpm-reset {
samsung,pins = "gpx0-6";
-   samsung,pin-function = <1>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
samsung,pin-val = <0>;
};
 
tpm_irq: tpm-irq {
samsung,pins = "gpx1-0";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
trackpad_irq: trackpad-irq {
samsung,pins = "gpx1-1";
-   samsung,pin-function = <0xf>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
power_key_irq: power-key-irq {
samsung,pins = "gpx1-2";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
ec_irq: ec-irq {
samsung,pins = "gpx1-5";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
tps65090_irq: tps65090-irq {
samsung,pins = "gpx2-5";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
dp_hpd_gpio: dp_hpd_gpio {
samsung,pins = "gpx2-6";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
max77802_irq: max77802-irq {
samsung,pins = "gpx3-1";
-   samsung,pin-function = <0>;
- 

[PATCH 3/9] ARM: dts: exynos: Use macros for GPIO configuration on exynos4210

2016-08-31 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi   | 454 
 arch/arm/boot/dts/exynos4210-smdkv310.dts   |  12 +-
 arch/arm/boot/dts/exynos4210-universal_c210.dts |   8 +-
 3 files changed, 237 insertions(+), 237 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
index 21129263e4e5..55d62cae4472 100644
--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -163,245 +163,245 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <0x2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart0_fctl: uart0-fctl {
samsung,pins = "gpa0-2", "gpa0-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_data: uart1-data {
samsung,pins = "gpa0-4", "gpa0-5";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_fctl: uart1-fctl {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_bus: i2c2-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_data: uart2-data {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_fctl: uart2-fctl {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart_audio_a: uart-audio-a {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <4>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c3_bus: i2c3-bus {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart3_data: uart3-data {
samsung,pins = "gpa1-4", "gpa1-5";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   

[PATCH 0/9] ARM: dts: exynos: Use macros for GPIO to make it more readable

2016-08-31 Thread Krzysztof Kozlowski
Hi,

Example:
-   samsung,pin-function = <0x2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
 
This should be just more readable. Especially for drive strenghts which
are unobvious and different between some SoCs.

Tested with dtx_diff:
for i in dts-old/exynos*dtb; do scripts/dtc/dtx_diff $i dts-new/$(basename $i); 
 done


Everything generated with sed:

sed -i -e 's/samsung,pin-pud = <0>;$/samsung,pin-pud = ;/' 
arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-pud = <1>;$/samsung,pin-pud = ;/' 
arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-pud = <3>;$/samsung,pin-pud = ;/' 
arch/arm/boot/dts/exynos*

sed -i -e 's/samsung,pin-drv = <0>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos[34]* arch/arm/boot/dts/exynos5250*
sed -i -e 's/samsung,pin-drv = <2>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos[34]* arch/arm/boot/dts/exynos5250*
sed -i -e 's/samsung,pin-drv = <1>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos[34]* arch/arm/boot/dts/exynos5250*
sed -i -e 's/samsung,pin-drv = <3>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos[34]* arch/arm/boot/dts/exynos5250*

sed -i -e 's/samsung,pin-drv = <0>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos5260*
sed -i -e 's/samsung,pin-drv = <1>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos5260*
sed -i -e 's/samsung,pin-drv = <2>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos5260*
sed -i -e 's/samsung,pin-drv = <3>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos5260*

sed -i -e 's/samsung,pin-drv = <0>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos5[48]*
sed -i -e 's/samsung,pin-drv = <1>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos5[48]*
sed -i -e 's/samsung,pin-drv = <2>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos5[48]*
sed -i -e 's/samsung,pin-drv = <3>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos5[48]*

sed -i -e 's/samsung,pin-function = <0>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <1>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*

sed -i -e 's/samsung,pin-function = <2>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <\(0x\)\?2>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <\(0x\)\?3>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <3>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <4>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <5>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <6>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <0xf>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*

Best regards,
Krzysztof

Krzysztof Kozlowski (9):
  ARM: dts: exynos: Add macros for GPIO configuration
  ARM: dts: exynos: Use macros for GPIO configuration on exynos3250
  ARM: dts: exynos: Use macros for GPIO configuration on exynos4210
  ARM: dts: exynos: Use macros for GPIO configuration on exynos4415
  ARM: dts: exynos: Use macros for GPIO configuration on exynos4x12
  ARM: dts: exynos: Use macros for GPIO configuration on exynos5250
  ARM: dts: exynos: Use macros for GPIO configuration on exynos5260
  ARM: dts: exynos: Use macros for GPIO configuration on exynos5410
  ARM: dts: exynos: Use macros for GPIO configuration on
exynos542x/exynos5800

 arch/arm/boot/dts/exynos3250-pinctrl.dtsi  | 275 +--
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi  | 471 ++-
 arch/arm/boot/dts/exynos4210-smdkv310.dts  |  12 +-
 arch/arm/boot/dts/exynos4210-universal_c210.dts|   8 +-
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi|  14 +-
 arch/arm/boot/dts/exynos4412-odroidx.dts   |   2 +-
 arch/arm/boot/dts/exynos4412-origen.dts|  12 +-
 arch/arm/boot/dts/exynos4412-smdk4412.dts  |  12 +-
 arch/arm/boot/dts/exynos4415-pinctrl.dtsi  | 303 ++--
 arch/arm/boot/dts/exynos4x12-pinctrl.dtsi  | 517 +++--
 arch/arm/boot/dts/exynos5250-pinctrl.dtsi  | 419 +
 arch/arm/boot/dts/exynos5250-smdk5250.dts  |   6 +-
 arch/arm/boot/dts/exynos5250-snow-common.dtsi  |  76 +--
 arch/arm/boot/dts/exynos5250-snow-rev5.dts |   6 +-
 arch/arm/boot/dts/exynos52

[PATCH 2/9] ARM: dts: exynos: Use macros for GPIO configuration on exynos3250

2016-08-31 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 270 +++---
 1 file changed, 135 insertions(+), 135 deletions(-)

diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
index 645bc3669554..2d0b39c206ad 100644
--- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -130,158 +130,158 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <0x2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart0_fctl: uart0-fctl {
samsung,pins = "gpa0-2", "gpa0-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_data: uart1-data {
samsung,pins = "gpa0-4", "gpa0-5";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_fctl: uart1-fctl {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_bus: i2c2-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_data: uart2-data {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c3_bus: i2c3-bus {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
spi0_bus: spi0-bus {
samsung,pins = "gpb-0", "gpb-2", "gpb-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c4_bus: i2c4-bus {
samsung,pins = "gpb-0", "gpb-1";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
spi1_bus: spi1-bus {
samsung,pins = "gpb-4", "gpb-6", "gpb-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c5_bus: i2c5-bus {
samsung,pins = "gpb-2", "gpb-3";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2s2_bus: i2s2-bus {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-

[PATCH 1/9] ARM: dts: exynos: Add macros for GPIO configuration

2016-08-31 Thread Krzysztof Kozlowski
Add macros for replacing hard-coded GPIO configuration: pull up/down,
drive strength and function.

Although PIN_FUNC_SPC_2 does not bring much information about the
function itself, it still is more descriptive then hard-coded
number <2>.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi |  5 +
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi | 17 +
 arch/arm/boot/dts/exynos4415-pinctrl.dtsi | 17 +
 arch/arm/boot/dts/exynos4x12-pinctrl.dtsi | 13 +
 arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 17 +
 arch/arm/boot/dts/exynos5260-pinctrl.dtsi | 17 ++---
 arch/arm/boot/dts/exynos5410-pinctrl.dtsi | 16 
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi | 17 +
 8 files changed, 116 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
index 40ea7de44933..645bc3669554 100644
--- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -26,6 +26,11 @@
 #define PIN_PDN_INPUT  2
 #define PIN_PDN_PREV   3
 
+#define PIN_FUNC_INPUT 0
+#define PIN_FUNC_SPC_2 2
+#define PIN_FUNC_SPC_3 3
+#define PIN_FUNC_SPC_4 4
+
 #define PIN_IN(_pin, _pull, _drv)  \
_pin {  \
samsung,pins = #_pin;   \
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
index 9331c6252eff..21129263e4e5 100644
--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -14,6 +14,23 @@
  * published by the Free Software Foundation.
 */
 
+#define PIN_PULL_NONE  0
+#define PIN_PULL_DOWN  1
+#define PIN_PULL_UP3
+
+#define PIN_DRV_LV10
+#define PIN_DRV_LV22
+#define PIN_DRV_LV31
+#define PIN_DRV_LV43
+
+#define PIN_FUNC_INPUT 0
+#define PIN_FUNC_OUTPUT1
+#define PIN_FUNC_SPC_2 2
+#define PIN_FUNC_SPC_3 3
+#define PIN_FUNC_SPC_4 4
+#define PIN_FUNC_SPC_5 5
+#define PIN_FUNC_SPC_F 0xf
+
 / {
pinctrl@1140 {
gpa0: gpa0 {
diff --git a/arch/arm/boot/dts/exynos4415-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
index 75af9c56123e..ae9d140a24d1 100644
--- a/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
@@ -11,6 +11,23 @@
  * published by the Free Software Foundation.
 */
 
+#define PIN_PULL_NONE  0
+#define PIN_PULL_DOWN  1
+#define PIN_PULL_UP3
+
+#define PIN_DRV_LV10
+#define PIN_DRV_LV22
+#define PIN_DRV_LV31
+#define PIN_DRV_LV43
+
+#define PIN_FUNC_INPUT 0
+#define PIN_FUNC_OUTPUT1
+#define PIN_FUNC_SPC_2 2
+#define PIN_FUNC_SPC_3 3
+#define PIN_FUNC_SPC_4 4
+#define PIN_FUNC_SPC_5 5
+#define PIN_FUNC_SPC_F 0xf
+
 &pinctrl_0 {
gpa0: gpa0 {
gpio-controller;
diff --git a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
index 856b29254374..ba5865208d3e 100644
--- a/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
@@ -16,11 +16,24 @@
 #define PIN_PULL_DOWN  1
 #define PIN_PULL_UP3
 
+#define PIN_DRV_LV10
+#define PIN_DRV_LV22
+#define PIN_DRV_LV31
+#define PIN_DRV_LV43
+
 #define PIN_PDN_OUT0   0
 #define PIN_PDN_OUT1   1
 #define PIN_PDN_INPUT  2
 #define PIN_PDN_PREV   3
 
+#define PIN_FUNC_INPUT 0
+#define PIN_FUNC_OUTPUT1
+#define PIN_FUNC_SPC_2 2
+#define PIN_FUNC_SPC_3 3
+#define PIN_FUNC_SPC_4 4
+#define PIN_FUNC_SPC_5 5
+#define PIN_FUNC_SPC_F 0xf
+
 #define PIN_SLP(_pin, _mode, _pull)\
_pin {  \
samsung,pins = #_pin;   \
diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
index 880917e508b2..5563dd80d4d0 100644
--- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
@@ -12,6 +12,23 @@
  * published by the Free Software Foundation.
 */
 
+#define PIN_PULL_NONE  0
+#define PIN_PULL_DOWN  1
+#define PIN_PULL_UP3
+
+#define PIN_DRV_LV10
+#define PIN_DRV_LV22
+#define PIN_DRV_LV31
+#define PIN_DRV_LV43
+
+#define PIN_FUNC_INPUT 0
+#define PIN_FUNC_OUTPUT1
+#define PIN_FUNC_SPC_2 2
+#define PIN_FUNC_SPC_3 3
+#define PIN_FUNC_SPC_4 

Re: [PATCH 1/9] ARM: dts: exynos: Add macros for GPIO configuration

2016-08-31 Thread Krzysztof Kozlowski
On 08/31/2016 02:42 PM, Arnd Bergmann wrote:
> On Wednesday, August 31, 2016 2:13:25 PM CEST Krzysztof Kozlowski wrote:
>>
>> +#define PIN_PULL_NONE  0
>> +#define PIN_PULL_DOWN  1
>> +#define PIN_PULL_UP3
>> +
>> +#define PIN_DRV_LV10
>> +#define PIN_DRV_LV22
>> +#define PIN_DRV_LV31
>> +#define PIN_DRV_LV43
>> +
>> +#define PIN_FUNC_INPUT 0
>> +#define PIN_FUNC_OUTPUT1
>> +#define PIN_FUNC_SPC_2 2
>> +#define PIN_FUNC_SPC_3 3
>> +#define PIN_FUNC_SPC_4 4
>> +#define PIN_FUNC_SPC_5 5
>> +#define PIN_FUNC_SPC_F 0xf
> 
> Any reason for having a copy in each of those files instead of one
> that is shared across all of them?

The drive strengths differ between some of them. There are three groups
of drive strengths:
1. Exynos3250, Exynos4 (all) and Exynos5250,
2. Exynos5260,
3. Exynos5410, 542x and 5800.

Rest (functions and pull up/down) is the same so sharing the defines is
possible but not that obvious. Solution would be for example adding a
SoC-family prefix for PIN_DRV_LVx. Not that good...

I could put it into three DTSI:
 - exynos3-pinctrl.dtsi (new file)
 - exynos5260-pinctrl.dtsi (like it is now)
 - exynos54xx-pinctrl.dtsi (new file)

which would reduce the duplication. Other ideas?

Best regards,
Krzysztof






Re: [PATCH 0/7] ARM: dts: exynos: Remove skeleton.dtsi usage and fix memory node DTC warnings

2016-08-31 Thread Krzysztof Kozlowski
On 08/31/2016 02:14 PM, Javier Martinez Canillas wrote:
> Hello Krzysztof,
> 
> This series removes the usage of the skeleton.dtsi in all the Exynos dts,
> which allows to get rid of the DTC warnings about a mismatch between the
> memory nodes' unit names and reg properties.
> 
> Patches are pretty trivial and shouldn't cause functional changes AFAIK,
> but only the Exynos5 changes have been tested. The others patches were
> just built tested.

I think this is a common problem, not only Exynos-specific, so I would
prefer to stick to common pattern. Either all DTS/DTSI include skeleton
or none of them.

Best regards,
Krzysztof



Re: [PATCH 1/9] ARM: dts: exynos: Add macros for GPIO configuration

2016-08-31 Thread Krzysztof Kozlowski
On 08/31/2016 02:58 PM, Arnd Bergmann wrote:
> On Wednesday, August 31, 2016 2:53:02 PM CEST Krzysztof Kozlowski wrote:
>> On 08/31/2016 02:42 PM, Arnd Bergmann wrote:
>>> On Wednesday, August 31, 2016 2:13:25 PM CEST Krzysztof Kozlowski wrote:
>>>>
>>>> +#define PIN_PULL_NONE  0
>>>> +#define PIN_PULL_DOWN  1
>>>> +#define PIN_PULL_UP3
>>>> +
>>>> +#define PIN_DRV_LV10
>>>> +#define PIN_DRV_LV22
>>>> +#define PIN_DRV_LV31
>>>> +#define PIN_DRV_LV43
>>>> +
>>>> +#define PIN_FUNC_INPUT 0
>>>> +#define PIN_FUNC_OUTPUT1
>>>> +#define PIN_FUNC_SPC_2 2
>>>> +#define PIN_FUNC_SPC_3 3
>>>> +#define PIN_FUNC_SPC_4 4
>>>> +#define PIN_FUNC_SPC_5 5
>>>> +#define PIN_FUNC_SPC_F 0xf
>>>
>>> Any reason for having a copy in each of those files instead of one
>>> that is shared across all of them?
>>
>> The drive strengths differ between some of them. There are three groups
>> of drive strengths:
>> 1. Exynos3250, Exynos4 (all) and Exynos5250,
>> 2. Exynos5260,
>> 3. Exynos5410, 542x and 5800.
> 
> I see. That sounds like an even stronger reason to not duplicate
> the definitions, as this is very confusing.

Okay.

> 
>> Rest (functions and pull up/down) is the same so sharing the defines is
>> possible but not that obvious. Solution would be for example adding a
>> SoC-family prefix for PIN_DRV_LVx. Not that good...
>>
>> I could put it into three DTSI:
>>  - exynos3-pinctrl.dtsi (new file)
>>  - exynos5260-pinctrl.dtsi (like it is now)
>>  - exynos54xx-pinctrl.dtsi (new file)
>>
>> which would reduce the duplication. Other ideas?
> 
> I think having the soc-family prefix is better, as it avoids
> defining the same symbol to a different value. Better make this
> as explicit as possible.

Ok, sounds reasonable. I want to convert also older platforms S3C (drive
strengths and pull up/down differ) and arm64 SoC: Exynos7. For the
latter the problem is there is no common place for sharing DTS, except
the headers. However this does not really belong to headers. I guess
some level of duplication might be still exist.


> I think overall, a better solution would have been to define the
> constants globally (shared with non-exynos) to start with,
> and have the driver translate generic numbers into vendor
> specific ones. Obviously it's too late for that now.

We could extend driver by adding new bindings accepting generic numbers
(and still backward compatible) but this looks like an overkill.

Best regards,
Krzysztof



Re: [PATCH 1/7] ARM: dts: exynos: Add missing memory node for Exynos5440 boards

2016-08-31 Thread Krzysztof Kozlowski
On Wed, Aug 31, 2016 at 02:14:33PM +0200, Javier Martinez Canillas wrote:
> The skeleton.dtsi file was removed in ARM64 for different reasons as
> explained in commit ("3ebee5a2e141 arm64: dts: kill skeleton.dtsi").
> 
> These also applies to ARM and it will also allow to get rid of the
> following DTC warnings in the future:
> 
> "Node /memory has a reg or ranges property, but no unit name"
> 
> But these boards don't have a memory node defined, so removing the
> skeleton.dtsi inclusion in exynos4.dtsi will cause a change in the
> compiled DTB. Add a dummy memory node so the compiled DTB doesn't
> change if the skeleton.dtsi is removed from exynos4.dtsi.

You mean extnos5440.dtsi?

> 
> Eventually the correct starting addresses and sizes should be used
> but I didn't find that information.
> 
> Signed-off-by: Javier Martinez Canillas 
> ---
> 
>  arch/arm/boot/dts/exynos5440-sd5v1.dts| 5 +
>  arch/arm/boot/dts/exynos5440-ssdk5440.dts | 5 +
>  2 files changed, 10 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/exynos5440-sd5v1.dts 
> b/arch/arm/boot/dts/exynos5440-sd5v1.dts
> index a98501bab6fc..333db4ff373a 100644
> --- a/arch/arm/boot/dts/exynos5440-sd5v1.dts
> +++ b/arch/arm/boot/dts/exynos5440-sd5v1.dts
> @@ -20,6 +20,11 @@
>   bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel 
> earlyprintk no_console_suspend mem=2048M@0x8000 mem=6144M@0x1 
> console=ttySAC0,115200";
>   };
>  
> + memory {
> + device_type = "memory";
> + reg = <0 0>;
> + };
> +
>   fixed-rate-clocks {
>   xtal {
>   compatible = "samsung,clock-xtal";
> diff --git a/arch/arm/boot/dts/exynos5440-ssdk5440.dts 
> b/arch/arm/boot/dts/exynos5440-ssdk5440.dts
> index 6a0d802e87c8..82fea6f94704 100644
> --- a/arch/arm/boot/dts/exynos5440-ssdk5440.dts
> +++ b/arch/arm/boot/dts/exynos5440-ssdk5440.dts
> @@ -21,6 +21,11 @@
>   bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel 
> earlyprintk no_console_suspend mem=2048M@0x8000 mem=6144M@0x1 
> console=ttySAC0,115200";
>   };
>  
> + memory {
> + device_type = "memory";
> + reg = <0 0>;
> + };

This looks okay, but the default size and address cells won't be
present. Won't that be a problem?

Best regards,
Krzysztof


Re: [PATCH 0/7] ARM: dts: exynos: Remove skeleton.dtsi usage and fix memory node DTC warnings

2016-08-31 Thread Krzysztof Kozlowski
On Wed, Aug 31, 2016 at 03:45:24PM +0200, Javier Martinez Canillas wrote:
> Hello Krzysztof,
> 
> On 08/31/2016 02:55 PM, Krzysztof Kozlowski wrote:
> > On 08/31/2016 02:14 PM, Javier Martinez Canillas wrote:
> >> Hello Krzysztof,
> >>
> >> This series removes the usage of the skeleton.dtsi in all the Exynos dts,
> >> which allows to get rid of the DTC warnings about a mismatch between the
> >> memory nodes' unit names and reg properties.
> >>
> >> Patches are pretty trivial and shouldn't cause functional changes AFAIK,
> >> but only the Exynos5 changes have been tested. The others patches were
> >> just built tested.
> > 
> > I think this is a common problem, not only Exynos-specific, so I would
> 
> That's correct.
> 
> > prefer to stick to common pattern. Either all DTS/DTSI include skeleton
> > or none of them.
> >
> 
> The idea is to get rid of skeleton.dtsi [0], but that will of course take
> time until the dtsi is removed from all the files. So this patch is a step
> in the right direction so at least Exynos is not a blocker to remove it.

Acknowledged, thanks for pointing it.

I will start review and apply.

BR,
Krzysztof


Re: [RESEND PATCH 1/3] ARM: dts: Add TOPEET itop core board SCP package version

2016-08-31 Thread Krzysztof Kozlowski
On Wed, Aug 31, 2016 at 08:58:27PM +0800, Randy Li wrote:
> The TOPEET itop is a samsung exnynos 4412 core board, which have
> two package versions. This patch add the support for SCP version.
> 
> Currently supported are USB3503A HSIC, USB OTG, eMMC, rtc and
> PMIC. The future features are in the based board. Also MFC and
> watchdog have been enabled.
> 
> Signed-off-by: Randy Li 
> ---
>  arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi | 490 
> 
>  1 file changed, 490 insertions(+)
>  create mode 100644 arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi

You are not making the review process easier... I asked for:
1. Not chaining the consecutive versions of patchset to the previous
ones. But now you removed chain replies totally (also from patches).
2. Versioning all patches but this is a resend of v1?

The changelog and cover letters disappeared...

Please, make it simple:
[PATCH v5 0/3] ARM: dts: exynos: some cover letter etc etc
  \---[PATCH v5 1/3] ARM: dts: exynos: Add TOPEET itop core board SCP
  \---[PATCH v5 2/3] ARM: dts: exynos: something more
  \---[PATCH v5 3/3] ARM: dts: exynos: something even more

git format-patch and git send-email do this by default. In every
sensible mail program this looks like that and is easy to read.

I don't have a clue what happened to these patches and what is current
status...

Best regards,
Krzysztof


[PATCH v2 02/10] ARM: dts: exynos: Use common macros for pinctrl configuration

2016-09-01 Thread Krzysztof Kozlowski
Replace duplicated macros in each DTSI file with a common macro coming
from header.  Include the header in each pinctrl DTSI so further changes
could use it.

Although PIN_FUNC_SPC_2 does not bring much information about the
function itself, it still is more descriptive then hard-coded
number <2>.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 76 +++-
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi |  2 +
 arch/arm/boot/dts/exynos4415-pinctrl.dtsi |  2 +
 arch/arm/boot/dts/exynos4x12-pinctrl.dtsi | 21 +++
 arch/arm/boot/dts/exynos5250-pinctrl.dtsi |  2 +
 arch/arm/boot/dts/exynos5260-pinctrl.dtsi | 96 +++
 arch/arm/boot/dts/exynos5410-pinctrl.dtsi |  2 +
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi |  2 +
 8 files changed, 96 insertions(+), 107 deletions(-)

diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
index 40ea7de44933..ed22d94f4fe5 100644
--- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -12,58 +12,46 @@
  * published by the Free Software Foundation.
 */
 
-#define PIN_PULL_NONE  0
-#define PIN_PULL_DOWN  1
-#define PIN_PULL_UP3
-
-#define PIN_DRV_LV10
-#define PIN_DRV_LV22
-#define PIN_DRV_LV31
-#define PIN_DRV_LV43
-
-#define PIN_PDN_OUT0   0
-#define PIN_PDN_OUT1   1
-#define PIN_PDN_INPUT  2
-#define PIN_PDN_PREV   3
-
-#define PIN_IN(_pin, _pull, _drv)  \
-   _pin {  \
-   samsung,pins = #_pin;   \
-   samsung,pin-function = <0>; \
-   samsung,pin-pud = ;  \
-   samsung,pin-drv = ;\
+#include 
+
+#define PIN_IN(_pin, _pull, _drv)  \
+   _pin {  \
+   samsung,pins = #_pin;   \
+   samsung,pin-function = ; \
+   samsung,pin-pud = ;   \
+   samsung,pin-drv = ;\
}
 
-#define PIN_OUT(_pin, _drv)\
-   _pin {  \
-   samsung,pins = #_pin;   \
-   samsung,pin-function = <1>; \
-   samsung,pin-pud = <0>;  \
-   samsung,pin-drv = ;\
+#define PIN_OUT(_pin, _drv)\
+   _pin {  \
+   samsung,pins = #_pin;   \
+   samsung,pin-function = ;\
+   samsung,pin-pud = ;   \
+   samsung,pin-drv = ;\
}
 
-#define PIN_OUT_SET(_pin, _val, _drv)  \
-   _pin {  \
-   samsung,pins = #_pin;   \
-   samsung,pin-function = <1>; \
-   samsung,pin-pud = <0>;  \
-   samsung,pin-drv = ;\
-   samsung,pin-val = <_val>;   \
+#define PIN_OUT_SET(_pin, _val, _drv)  \
+   _pin {  \
+   samsung,pins = #_pin;   \
+   samsung,pin-function = ;\
+   samsung,pin-pud = ;   \
+   samsung,pin-drv = ;\
+   samsung,pin-val = <_val>;   \
}
 
-#define PIN_CFG(_pin, _sel, _pull, _drv)   \
-   _pin {  \
-   samsung,pins = #_pin;   \
-   samsung,pin-function = <_sel>;  \
-   samsung,pin-pud = ;  \
-   samsung,pin-drv = ;\
+#define PIN_CFG(_pin, _sel, _pull, _drv)   \
+   _pin {  \
+   samsung,pins = #_pin;   \
+   samsung,pin-function = <_sel>;  \
+   samsung,pin-pud = ;   \
+   samsung,pin-drv = ;\
}
 
-#define PIN_SLP(_pin, _mode, _pull)\
-   _pin {  \
-   samsung,pins = #_pin;   \
-   samsung,pin-con-pdn = ;   \
-   samsung,pin-pud-pdn = ;  \
+#define PIN_SLP(_pin, _mode, _pull)\
+   _pin {   

[PATCH v2 00/10] pinctrl: exynos/samsung: Add header with values used for configuration

2016-09-01 Thread Krzysztof Kozlowski
Hi,

Merging
===
Patch #1 should probably go through pinctrl tree. In that case I would
appreciate a stable branch/tag so DTS could base on top of it.


Changes since v1

1. Follow Arnd's suggestion about moving the macros to common place.
2. Subjects: replace "GPIO" with "pinctrl".
3. There were some major changes here so I did not add Javier's
   reviewed-by and tested-by tags.


Goal

Increase readability:
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 

Everything generated with sed:
sed -i -e 's/samsung,pin-pud = <0>;$/samsung,pin-pud = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-pud = <1>;$/samsung,pin-pud = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-pud = <3>;$/samsung,pin-pud = ;/' 
arch/arm/boot/dts/exynos*

sed -i -e 's/samsung,pin-drv = <0>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos[34]* arch/arm/boot/dts/exynos5250*
sed -i -e 's/samsung,pin-drv = <2>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos[34]* arch/arm/boot/dts/exynos5250*
sed -i -e 's/samsung,pin-drv = <1>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos[34]* arch/arm/boot/dts/exynos5250*
sed -i -e 's/samsung,pin-drv = <3>;$/samsung,pin-drv = ;/' 
arch/arm/boot/dts/exynos[34]* arch/arm/boot/dts/exynos5250*

sed -i -e 's/samsung,pin-drv = <0>;$/samsung,pin-drv = 
;/' arch/arm/boot/dts/exynos5260*
sed -i -e 's/samsung,pin-drv = <1>;$/samsung,pin-drv = 
;/' arch/arm/boot/dts/exynos5260*
sed -i -e 's/samsung,pin-drv = <2>;$/samsung,pin-drv = 
;/' arch/arm/boot/dts/exynos5260*
sed -i -e 's/samsung,pin-drv = <3>;$/samsung,pin-drv = 
;/' arch/arm/boot/dts/exynos5260*

sed -i -e 's/samsung,pin-drv = <0>;$/samsung,pin-drv = 
;/' arch/arm/boot/dts/exynos5[48]*
sed -i -e 's/samsung,pin-drv = <1>;$/samsung,pin-drv = 
;/' arch/arm/boot/dts/exynos5[48]*
sed -i -e 's/samsung,pin-drv = <2>;$/samsung,pin-drv = 
;/' arch/arm/boot/dts/exynos5[48]*
sed -i -e 's/samsung,pin-drv = <3>;$/samsung,pin-drv = 
;/' arch/arm/boot/dts/exynos5[48]*

sed -i -e 's/samsung,pin-function = <0>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <1>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*

sed -i -e 's/samsung,pin-function = <2>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <\(0x\)\?2>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <\(0x\)\?3>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <3>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <4>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <5>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <6>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*
sed -i -e 's/samsung,pin-function = <0xf>;$/samsung,pin-function = 
;/' arch/arm/boot/dts/exynos*

rm -fr dts-old; cp -r out/arch/arm/boot/dts dts-old
rm -fr dts-new; cp -r out/arch/arm/boot/dts dts-new
for i in dts-old/exynos*dtb; do scripts/dtc/dtx_diff $i dts-new/$(basename $i); 
 done


Best regards,
Krzysztof


Krzysztof Kozlowski (10):
  pinctrl: dt-bindings: samsung: Add header with values used for
configuration
  ARM: dts: exynos: Use common macros for pinctrl configuration
  ARM: dts: exynos: Use macros for pinctrl configuration on exynos3250
  ARM: dts: exynos: Use macros for pinctrl configuration on exynos4210
  ARM: dts: exynos: Use macros for pinctrl configuration on exynos4x12
  ARM: dts: exynos: Use macros for pinctrl configuration on exynos4415
  ARM: dts: exynos: Use macros for pinctrl configuration on exynos5250
  ARM: dts: exynos: Use macros for pinctrl configuration on exynos5260
  ARM: dts: exynos: Use macros for pinctrl configuration on exynos5410
  ARM: dts: exynos: Use macros for pinctrl configuration on
exynos542x/exynos5800

 MAINTAINERS|   1 +
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi  | 346 +++---
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi  | 456 +-
 arch/arm/boot/dts/exynos4210-smdkv310.dts  |  12 +-
 arch/arm/boot/dts/exynos4210

[PATCH v2 03/10] ARM: dts: exynos: Use macros for pinctrl configuration on exynos3250

2016-09-01 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 270 +++---
 1 file changed, 135 insertions(+), 135 deletions(-)

diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
index ed22d94f4fe5..ec331169c3d9 100644
--- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -113,158 +113,158 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <0x2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart0_fctl: uart0-fctl {
samsung,pins = "gpa0-2", "gpa0-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_data: uart1-data {
samsung,pins = "gpa0-4", "gpa0-5";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_fctl: uart1-fctl {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_bus: i2c2-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_data: uart2-data {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c3_bus: i2c3-bus {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
spi0_bus: spi0-bus {
samsung,pins = "gpb-0", "gpb-2", "gpb-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c4_bus: i2c4-bus {
samsung,pins = "gpb-0", "gpb-1";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
spi1_bus: spi1-bus {
samsung,pins = "gpb-4", "gpb-6", "gpb-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c5_bus: i2c5-bus {
samsung,pins = "gpb-2", "gpb-3";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2s2_bus: i2s2-bus {
samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
"gpc1-4";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-

[PATCH v2 07/10] ARM: dts: exynos: Use macros for pinctrl configuration on exynos5250

2016-09-01 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 402 +-
 arch/arm/boot/dts/exynos5250-smdk5250.dts |   6 +-
 arch/arm/boot/dts/exynos5250-snow-common.dtsi |  76 ++---
 arch/arm/boot/dts/exynos5250-snow-rev5.dts|   6 +-
 arch/arm/boot/dts/exynos5250-snow.dts |   6 +-
 arch/arm/boot/dts/exynos5250-spring.dts   |  72 ++---
 6 files changed, 284 insertions(+), 284 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
index d1a4ea0fb838..2f6ab32b5954 100644
--- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
@@ -202,392 +202,392 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart0_fctl: uart0-fctl {
samsung,pins = "gpa0-2", "gpa0-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_bus: i2c2-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_hs_bus: i2c2-hs-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <4>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_data: uart2-data {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_fctl: uart2-fctl {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c3_bus: i2c3-bus {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c3_hs_bus: i2c3-hs-bus {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <4>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart3_data: uart3-data {
samsung,pins = "gpa1-4", "gpa1-4";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
spi0_bus: spi0-bus {
samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c4_bus: i2c4-bus {
samsung,pins = "gpa2-0", "gpa2-1";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c5_bus: i2c5-bus

[PATCH v2 09/10] ARM: dts: exynos: Use macros for pinctrl configuration on exynos5410

2016-09-01 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos5410-odroidxu.dts |  30 ++---
 arch/arm/boot/dts/exynos5410-pinctrl.dtsi | 180 +++---
 arch/arm/boot/dts/exynos5410-smdk5410.dts |  10 +-
 3 files changed, 110 insertions(+), 110 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts 
b/arch/arm/boot/dts/exynos5410-odroidxu.dts
index a5ae76c1838f..f263372bfb7b 100644
--- a/arch/arm/boot/dts/exynos5410-odroidxu.dts
+++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts
@@ -473,38 +473,38 @@
 &pinctrl_0 {
emmc_nrst_pin: emmc-nrst {
samsung,pins = "gpd1-0";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
pmic_dvs_3: pmic-dvs-3 {
samsung,pins = "gpx0-0";
-   samsung,pin-function = <1>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
pmic_dvs_2: pmic-dvs-2 {
samsung,pins = "gpx0-1";
-   samsung,pin-function = <1>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
pmic_dvs_1: pmic-dvs-1 {
samsung,pins = "gpx0-2";
-   samsung,pin-function = <1>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
samsung,pin-val = <1>;
};
 
max77802_irq: max77802-irq {
samsung,pins = "gpx0-4";
-   samsung,pin-function = <0xf>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 };
 
diff --git a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
index bf43792efe27..a083d23fdee3 100644
--- a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
@@ -282,212 +282,212 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart0_fctl: uart0-fctl {
samsung,pins = "gpa0-2", "gpa0-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_data: uart1-data {
samsung,pins = "gpa0-4", "gpa0-5";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_fctl: uart1-fctl {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_bus: i2c2-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_data: uart2-data {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-d

[PATCH v2 01/10] pinctrl: dt-bindings: samsung: Add header with values used for configuration

2016-09-01 Thread Krzysztof Kozlowski
Hard-coded pinctrl configuration values are scattered through DTS files.
The numbers are difficult to decode by human, especially without the
datasheet.  Additionally the drive strength differs between Exynos SoC
families increasing the confusion.

The header will help making this more readable and maintainable.

Signed-off-by: Krzysztof Kozlowski 
---
 MAINTAINERS   |  1 +
 include/dt-bindings/pinctrl/samsung.h | 57 +++
 2 files changed, 58 insertions(+)
 create mode 100644 include/dt-bindings/pinctrl/samsung.h

diff --git a/MAINTAINERS b/MAINTAINERS
index d8e81b1dde30..836bcd327ee4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9318,6 +9318,7 @@ L:linux-arm-ker...@lists.infradead.org (moderated 
for non-subscribers)
 L: linux-samsung-...@vger.kernel.org (moderated for non-subscribers)
 S: Maintained
 F: drivers/pinctrl/samsung/
+F: include/dt-bindings/pinctrl/samsung.h
 
 PIN CONTROLLER - SINGLE
 M: Tony Lindgren 
diff --git a/include/dt-bindings/pinctrl/samsung.h 
b/include/dt-bindings/pinctrl/samsung.h
new file mode 100644
index ..0f410ba5ec7e
--- /dev/null
+++ b/include/dt-bindings/pinctrl/samsung.h
@@ -0,0 +1,57 @@
+/*
+ * Samsung's Exynos pinctrl bindings
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ * Author: Krzysztof Kozlowski 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __DT_BINDINGS_PINCTRL_EXYNOS_H__
+#define __DT_BINDINGS_PINCTRL_EXYNOS_H__
+
+#define EXYNOS_PIN_PULL_NONE   0
+#define EXYNOS_PIN_PULL_DOWN   1
+#define EXYNOS_PIN_PULL_UP 3
+
+/* Pin function in power down mode */
+#define EXYNOS_PIN_PDN_OUT00
+#define EXYNOS_PIN_PDN_OUT11
+#define EXYNOS_PIN_PDN_INPUT   2
+#define EXYNOS_PIN_PDN_PREV3
+
+/* Drive strengths for Exynos3250, Exynos4 (all) and Exynos5250 */
+#define EXYNOS4_PIN_DRV_LV10
+#define EXYNOS4_PIN_DRV_LV22
+#define EXYNOS4_PIN_DRV_LV31
+#define EXYNOS4_PIN_DRV_LV43
+
+/* Drive strengths for Exynos5260 */
+#define EXYNOS5260_PIN_DRV_LV1 0
+#define EXYNOS5260_PIN_DRV_LV2 1
+#define EXYNOS5260_PIN_DRV_LV4 2
+#define EXYNOS5260_PIN_DRV_LV6 3
+
+/* Drive strengths for Exynos5410, Exynos542x and Exynos5800 */
+#define EXYNOS5420_PIN_DRV_LV1 0
+#define EXYNOS5420_PIN_DRV_LV2 1
+#define EXYNOS5420_PIN_DRV_LV3 2
+#define EXYNOS5420_PIN_DRV_LV4 3
+
+#define EXYONS_PIN_PDN_OUT00
+#define EXYNOS_PIN_PDN_OUT11
+#define EXYNOS_PIN_PDN_INPUT   2
+#define EXYNOS_PIN_PDN_PREV3
+
+#define EXYNOS_PIN_FUNC_INPUT  0
+#define EXYNOS_PIN_FUNC_OUTPUT 1
+#define EXYNOS_PIN_FUNC_2  2
+#define EXYNOS_PIN_FUNC_3  3
+#define EXYNOS_PIN_FUNC_4  4
+#define EXYNOS_PIN_FUNC_5  5
+#define EXYNOS_PIN_FUNC_F  0xf
+
+#endif /* __DT_BINDINGS_PINCTRL_EXYNOS_H__ */
-- 
1.9.1



[PATCH v2 06/10] ARM: dts: exynos: Use macros for pinctrl configuration on exynos4415

2016-09-01 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos4415-pinctrl.dtsi | 286 +++---
 1 file changed, 143 insertions(+), 143 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4415-pinctrl.dtsi 
b/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
index 63714445dddb..f54aee53b6ec 100644
--- a/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4415-pinctrl.dtsi
@@ -96,180 +96,180 @@
 
uart0_data: uart0-data {
samsung,pins = "gpa0-0", "gpa0-1";
-   samsung,pin-function = <0x2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart0_fctl: uart0-fctl {
samsung,pins = "gpa0-2", "gpa0-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_data: uart1-data {
samsung,pins = "gpa0-4", "gpa0-5";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart1_fctl: uart1-fctl {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_data: uart2-data {
samsung,pins = "gpa1-0", "gpa1-1";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart2_fctl: uart2-fctl {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
uart3_data: uart3-data {
samsung,pins = "gpa1-4", "gpa1-5";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c2_bus: i2c2-bus {
samsung,pins = "gpa0-6", "gpa0-7";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c3_bus: i2c3-bus {
samsung,pins = "gpa1-2", "gpa1-3";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
spi0_bus: spi0-bus {
samsung,pins = "gpb-0", "gpb-2", "gpb-3";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
i2c4_bus: i2c4-bus {
samsung,pins = "gpb-0", "gpb-1";
-   samsung,pin-function = <3>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
spi1_bus: spi1-bus {
samsung,pins = "gpb-4", "gpb-6", "gpb-7";
-   samsung,pin-function = <2>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsun

[PATCH v2 10/10] ARM: dts: exynos: Use macros for pinctrl configuration on exynos542x/exynos5800

2016-09-01 Thread Krzysztof Kozlowski
Usage of DTS macros instead of hard-coded numbers makes code easier to
read.  One does not have to remember which value means pull-up/down or
specific driver strength.

Signed-off-by: Krzysztof Kozlowski 
---
 arch/arm/boot/dts/exynos5420-arndale-octa.dts  |   6 +-
 arch/arm/boot/dts/exynos5420-peach-pit.dts | 126 
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi  | 354 ++---
 arch/arm/boot/dts/exynos5420-smdk5420.dts  |  18 +-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |  18 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts  | 126 
 6 files changed, 324 insertions(+), 324 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts 
b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index 39a3b81478fd..657ffbb096c1 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -378,9 +378,9 @@
 &pinctrl_0 {
s2mps11_irq: s2mps11-irq {
samsung,pins = "gpx3-2";
-   samsung,pin-function = <0xf>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 };
 
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts 
b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index f6f256fd9b5e..a51175ad4b9f 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -753,171 +753,171 @@
 
wifi_en: wifi-en {
samsung,pins = "gpx0-0";
-   samsung,pin-function = <1>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
max98090_irq: max98090-irq {
samsung,pins = "gpx0-2";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
/* We need GPX0_6 to be low at sleep time; just keep it low always */
mask_tpm_reset: mask-tpm-reset {
samsung,pins = "gpx0-6";
-   samsung,pin-function = <1>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
samsung,pin-val = <0>;
};
 
tpm_irq: tpm-irq {
samsung,pins = "gpx1-0";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
trackpad_irq: trackpad-irq {
samsung,pins = "gpx1-1";
-   samsung,pin-function = <0xf>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
power_key_irq: power-key-irq {
samsung,pins = "gpx1-2";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
ec_irq: ec-irq {
samsung,pins = "gpx1-5";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
tps65090_irq: tps65090-irq {
samsung,pins = "gpx2-5";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <0>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
dp_hpd_gpio: dp_hpd_gpio {
samsung,pins = "gpx2-6";
-   samsung,pin-function = <0>;
-   samsung,pin-pud = <3>;
-   samsung,pin-drv = <0>;
+   samsung,pin-function = ;
+   samsung,pin-pud = ;
+   samsung,pin-drv = ;
};
 
max77802_irq: max77802-irq {
samsung,pins = "gpx3-1";
-   samsung,pin-function = <0>;
- 

  1   2   3   4   5   6   7   8   9   10   >