Re: [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2

2017-10-09 Thread Byungchul Park
On Wed, Oct 04, 2017 at 10:34:30AM +0200, Peter Zijlstra wrote:
> Right, and print_circular_bug() uses @trace before it ever can be set,
> although I suspect the intention is that that only ever gets called from
> commit_xhlock() where we pass in an initialized @trace. A comment
> would've been good :/
> 
> So the whole point of that trace wankery here is to not do save_trace()
> when we'll not in fact use the stack trace.
> 
> It seems to me we can do that much saner by actually initializing our
> @trace buffer and testing if it contains an actual stacktrace.
> 
> Also killed that verbose thing, because dropping that graph_lock thing
> hurts my brain -- although I think it should work.
> 
> Does this make the corruption thing go away?

The commit ae813308f(locking/lockdep: Avoid creating redundant links)
seems to introduce the bug.

But as you may think, another commit ce07a9415(locking/lockdep: Make
check_prev_add() able to handle external stack_trace) is also fragile.

So I like your following patch which makes code robust.

Acked-by: byungchul.p...@lge.com

> ---
>  kernel/locking/lockdep.c | 48 
> 
>  1 file changed, 20 insertions(+), 28 deletions(-)
> 
> diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> index 44c8d0d17170..e36e652d996f 100644
> --- a/kernel/locking/lockdep.c
> +++ b/kernel/locking/lockdep.c
> @@ -1873,10 +1873,10 @@ check_prev_add(struct task_struct *curr, struct 
> held_lock *prev,
>  struct held_lock *next, int distance, struct stack_trace *trace,
>  int (*save)(struct stack_trace *trace))
>  {
> + struct lock_list *uninitialized_var(target_entry);
>   struct lock_list *entry;
> - int ret;
>   struct lock_list this;
> - struct lock_list *uninitialized_var(target_entry);
> + int ret;
>  
>   /*
>* Prove that the new  ->  dependency would not
> @@ -1890,8 +1890,17 @@ check_prev_add(struct task_struct *curr, struct 
> held_lock *prev,
>   this.class = hlock_class(next);
>   this.parent = NULL;
>   ret = check_noncircular(, hlock_class(prev), _entry);
> - if (unlikely(!ret))
> + if (unlikely(!ret)) {
> + if (!trace->entries) {
> + /*
> +  * If @save fails here, the printing might trigger
> +  * a WARN but because of the !nr_entries it should
> +  * not do bad things.
> +  */
> + save(trace);
> + }
>   return print_circular_bug(, target_entry, next, prev, 
> trace);
> + }
>   else if (unlikely(ret < 0))
>   return print_bfs_bug(ret);
>  
> @@ -1938,7 +1947,7 @@ check_prev_add(struct task_struct *curr, struct 
> held_lock *prev,
>   return print_bfs_bug(ret);
>  
>  
> - if (save && !save(trace))
> + if (!trace->entries && !save(trace))
>   return 0;
>  
>   /*
> @@ -1958,20 +1967,6 @@ check_prev_add(struct task_struct *curr, struct 
> held_lock *prev,
>   if (!ret)
>   return 0;
>  
> - /*
> -  * Debugging printouts:
> -  */
> - if (verbose(hlock_class(prev)) || verbose(hlock_class(next))) {
> - graph_unlock();
> - printk("\n new dependency: ");
> - print_lock_name(hlock_class(prev));
> - printk(KERN_CONT " => ");
> - print_lock_name(hlock_class(next));
> - printk(KERN_CONT "\n");
> - dump_stack();
> - if (!graph_lock())
> - return 0;
> - }
>   return 2;
>  }
>  
> @@ -1986,8 +1981,12 @@ check_prevs_add(struct task_struct *curr, struct 
> held_lock *next)
>  {
>   int depth = curr->lockdep_depth;
>   struct held_lock *hlock;
> - struct stack_trace trace;
> - int (*save)(struct stack_trace *trace) = save_trace;
> + struct stack_trace trace = {
> + .nr_entries = 0,
> + .max_entries = 0,
> + .entries = NULL,
> + .skip = 0,
> + };
>  
>   /*
>* Debugging checks.
> @@ -2018,17 +2017,10 @@ check_prevs_add(struct task_struct *curr, struct 
> held_lock *next)
>*/
>   if (hlock->read != 2 && hlock->check) {
>   int ret = check_prev_add(curr, hlock, next,
> -  distance, , 
> save);
> +  distance, , 
> save_trace);
>   if (!ret)
>   return 0;
>  
> - /*
> -  * Stop saving stack_trace if save_trace() was
> -  * called at least once:
> -  */
> - if (save && ret == 2)
> - save = NULL;
> -
> 

Re: [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2

2017-10-09 Thread Byungchul Park
On Wed, Oct 04, 2017 at 10:34:30AM +0200, Peter Zijlstra wrote:
> Right, and print_circular_bug() uses @trace before it ever can be set,
> although I suspect the intention is that that only ever gets called from
> commit_xhlock() where we pass in an initialized @trace. A comment
> would've been good :/
> 
> So the whole point of that trace wankery here is to not do save_trace()
> when we'll not in fact use the stack trace.
> 
> It seems to me we can do that much saner by actually initializing our
> @trace buffer and testing if it contains an actual stacktrace.
> 
> Also killed that verbose thing, because dropping that graph_lock thing
> hurts my brain -- although I think it should work.
> 
> Does this make the corruption thing go away?

The commit ae813308f(locking/lockdep: Avoid creating redundant links)
seems to introduce the bug.

But as you may think, another commit ce07a9415(locking/lockdep: Make
check_prev_add() able to handle external stack_trace) is also fragile.

So I like your following patch which makes code robust.

Acked-by: byungchul.p...@lge.com

> ---
>  kernel/locking/lockdep.c | 48 
> 
>  1 file changed, 20 insertions(+), 28 deletions(-)
> 
> diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
> index 44c8d0d17170..e36e652d996f 100644
> --- a/kernel/locking/lockdep.c
> +++ b/kernel/locking/lockdep.c
> @@ -1873,10 +1873,10 @@ check_prev_add(struct task_struct *curr, struct 
> held_lock *prev,
>  struct held_lock *next, int distance, struct stack_trace *trace,
>  int (*save)(struct stack_trace *trace))
>  {
> + struct lock_list *uninitialized_var(target_entry);
>   struct lock_list *entry;
> - int ret;
>   struct lock_list this;
> - struct lock_list *uninitialized_var(target_entry);
> + int ret;
>  
>   /*
>* Prove that the new  ->  dependency would not
> @@ -1890,8 +1890,17 @@ check_prev_add(struct task_struct *curr, struct 
> held_lock *prev,
>   this.class = hlock_class(next);
>   this.parent = NULL;
>   ret = check_noncircular(, hlock_class(prev), _entry);
> - if (unlikely(!ret))
> + if (unlikely(!ret)) {
> + if (!trace->entries) {
> + /*
> +  * If @save fails here, the printing might trigger
> +  * a WARN but because of the !nr_entries it should
> +  * not do bad things.
> +  */
> + save(trace);
> + }
>   return print_circular_bug(, target_entry, next, prev, 
> trace);
> + }
>   else if (unlikely(ret < 0))
>   return print_bfs_bug(ret);
>  
> @@ -1938,7 +1947,7 @@ check_prev_add(struct task_struct *curr, struct 
> held_lock *prev,
>   return print_bfs_bug(ret);
>  
>  
> - if (save && !save(trace))
> + if (!trace->entries && !save(trace))
>   return 0;
>  
>   /*
> @@ -1958,20 +1967,6 @@ check_prev_add(struct task_struct *curr, struct 
> held_lock *prev,
>   if (!ret)
>   return 0;
>  
> - /*
> -  * Debugging printouts:
> -  */
> - if (verbose(hlock_class(prev)) || verbose(hlock_class(next))) {
> - graph_unlock();
> - printk("\n new dependency: ");
> - print_lock_name(hlock_class(prev));
> - printk(KERN_CONT " => ");
> - print_lock_name(hlock_class(next));
> - printk(KERN_CONT "\n");
> - dump_stack();
> - if (!graph_lock())
> - return 0;
> - }
>   return 2;
>  }
>  
> @@ -1986,8 +1981,12 @@ check_prevs_add(struct task_struct *curr, struct 
> held_lock *next)
>  {
>   int depth = curr->lockdep_depth;
>   struct held_lock *hlock;
> - struct stack_trace trace;
> - int (*save)(struct stack_trace *trace) = save_trace;
> + struct stack_trace trace = {
> + .nr_entries = 0,
> + .max_entries = 0,
> + .entries = NULL,
> + .skip = 0,
> + };
>  
>   /*
>* Debugging checks.
> @@ -2018,17 +2017,10 @@ check_prevs_add(struct task_struct *curr, struct 
> held_lock *next)
>*/
>   if (hlock->read != 2 && hlock->check) {
>   int ret = check_prev_add(curr, hlock, next,
> -  distance, , 
> save);
> +  distance, , 
> save_trace);
>   if (!ret)
>   return 0;
>  
> - /*
> -  * Stop saving stack_trace if save_trace() was
> -  * called at least once:
> -  */
> - if (save && ret == 2)
> - save = NULL;
> -
> 

Re: [PATCH v3] mm, sysctl: make NUMA stats configurable

2017-10-09 Thread kemi


On 2017年10月10日 13:49, Michal Hocko wrote:
> On Mon 09-10-17 09:55:49, Michal Hocko wrote:
>> I haven't checked closely but what happens (or should happen) when you
>> do a partial read? Should you get an inconsistent results? Or is this
>> impossible?
> 
> Well, after thinking about it little bit more, partial reads are always
> inconsistent so this wouldn't add a new problem.
> 
> Anyway I still stand by my position that this sounds over-engineered and
> a simple 0/1 resp. on/off interface would be both simpler and safer. If
> anybody wants an auto mode it can be added later (as a value 2 resp.
> auto).
> 

It sounds good to me. If Andrew also tends to be a simple 0/1, I will submit
V4 patch for it. Thanks


Re: [PATCH v3] mm, sysctl: make NUMA stats configurable

2017-10-09 Thread kemi


On 2017年10月10日 13:49, Michal Hocko wrote:
> On Mon 09-10-17 09:55:49, Michal Hocko wrote:
>> I haven't checked closely but what happens (or should happen) when you
>> do a partial read? Should you get an inconsistent results? Or is this
>> impossible?
> 
> Well, after thinking about it little bit more, partial reads are always
> inconsistent so this wouldn't add a new problem.
> 
> Anyway I still stand by my position that this sounds over-engineered and
> a simple 0/1 resp. on/off interface would be both simpler and safer. If
> anybody wants an auto mode it can be added later (as a value 2 resp.
> auto).
> 

It sounds good to me. If Andrew also tends to be a simple 0/1, I will submit
V4 patch for it. Thanks


Re: [PATCH v2 15/18] powerpc: Emulate paste instruction

2017-10-09 Thread Michael Ellerman
Michael Neuling  writes:

> @ -1924,6 +1987,7 @@ struct ppc_emulated ppc_emulated = {
>>  WARN_EMULATED_SETUP(mfdscr),
>>  WARN_EMULATED_SETUP(mtdscr),
>>  WARN_EMULATED_SETUP(lq_stq),
>> +WARN_EMULATED_SETUP(paste),
>
> You'll need to rebase this on powerpc/next as this has changed upstream.

I can handle that, it should be a trivial conflict.

cheers


Re: [PATCH v2 15/18] powerpc: Emulate paste instruction

2017-10-09 Thread Michael Ellerman
Michael Neuling  writes:

> @ -1924,6 +1987,7 @@ struct ppc_emulated ppc_emulated = {
>>  WARN_EMULATED_SETUP(mfdscr),
>>  WARN_EMULATED_SETUP(mtdscr),
>>  WARN_EMULATED_SETUP(lq_stq),
>> +WARN_EMULATED_SETUP(paste),
>
> You'll need to rebase this on powerpc/next as this has changed upstream.

I can handle that, it should be a trivial conflict.

cheers


Re: [RFC] a question about mlockall() and mprotect()

2017-10-09 Thread Michal Hocko
On Tue 10-10-17 09:22:20, Xishi Qiu wrote:
> On 2017/10/10 2:26, Michal Hocko wrote:
> 
> > On Wed 27-09-17 13:51:09, Xishi Qiu wrote:
> >> On 2017/9/26 19:00, Michal Hocko wrote:
> >>
> >>> On Tue 26-09-17 11:45:16, Vlastimil Babka wrote:
>  On 09/26/2017 11:22 AM, Xishi Qiu wrote:
> > On 2017/9/26 17:13, Xishi Qiu wrote:
> >>> This is still very fuzzy. What are you actually trying to achieve?
> >>
> >> I don't expect page fault any more after mlock.
> >>
> >
> > Our apps is some thing like RT, and page-fault maybe cause a lot of 
> > time,
> > e.g. lock, mem reclaim ..., so I use mlock and don't want page fault
> > any more.
> 
>  Why does your app then have restricted mprotect when calling mlockall()
>  and only later adjusts the mprotect?
> >>>
> >>> Ahh, OK I see what is goging on. So you have PROT_NONE vma at the time
> >>> mlockall and then later mprotect it something else and want to fault all
> >>> that memory at the mprotect time?
> >>>
> >>> So basically to do
> >>> ---
> >>> diff --git a/mm/mprotect.c b/mm/mprotect.c
> >>> index 6d3e2f082290..b665b5d1c544 100644
> >>> --- a/mm/mprotect.c
> >>> +++ b/mm/mprotect.c
> >>> @@ -369,7 +369,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct 
> >>> vm_area_struct **pprev,
> >>>* Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
> >>>* fault on access.
> >>>*/
> >>> - if ((oldflags & (VM_WRITE | VM_SHARED | VM_LOCKED)) == VM_LOCKED &&
> >>> + if ((oldflags & (VM_WRITE | VM_LOCKED)) == VM_LOCKED &&
> >>>   (newflags & VM_WRITE)) {
> >>>   populate_vma_page_range(vma, start, end, NULL);
> >>>   }
> >>>
> >>
> >> Hi Michal,
> >>
> >> My kernel is v3.10, and I missed this code, thank you reminding me.
> > 
> > I guess I didn't get your answer. Does the above diff resolves your
> > problem?
> 
> Hi Michal,
> 
> This upstream patch 36f881883c57941bb32d25cea6524f9612ab5a2c has already
> resolve my problem, thank you for your attention.

OK, fair enough. But is does it make sense to extend this behavior to
shared mappings as well?
-- 
Michal Hocko
SUSE Labs


Re: [RFC] a question about mlockall() and mprotect()

2017-10-09 Thread Michal Hocko
On Tue 10-10-17 09:22:20, Xishi Qiu wrote:
> On 2017/10/10 2:26, Michal Hocko wrote:
> 
> > On Wed 27-09-17 13:51:09, Xishi Qiu wrote:
> >> On 2017/9/26 19:00, Michal Hocko wrote:
> >>
> >>> On Tue 26-09-17 11:45:16, Vlastimil Babka wrote:
>  On 09/26/2017 11:22 AM, Xishi Qiu wrote:
> > On 2017/9/26 17:13, Xishi Qiu wrote:
> >>> This is still very fuzzy. What are you actually trying to achieve?
> >>
> >> I don't expect page fault any more after mlock.
> >>
> >
> > Our apps is some thing like RT, and page-fault maybe cause a lot of 
> > time,
> > e.g. lock, mem reclaim ..., so I use mlock and don't want page fault
> > any more.
> 
>  Why does your app then have restricted mprotect when calling mlockall()
>  and only later adjusts the mprotect?
> >>>
> >>> Ahh, OK I see what is goging on. So you have PROT_NONE vma at the time
> >>> mlockall and then later mprotect it something else and want to fault all
> >>> that memory at the mprotect time?
> >>>
> >>> So basically to do
> >>> ---
> >>> diff --git a/mm/mprotect.c b/mm/mprotect.c
> >>> index 6d3e2f082290..b665b5d1c544 100644
> >>> --- a/mm/mprotect.c
> >>> +++ b/mm/mprotect.c
> >>> @@ -369,7 +369,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct 
> >>> vm_area_struct **pprev,
> >>>* Private VM_LOCKED VMA becoming writable: trigger COW to avoid major
> >>>* fault on access.
> >>>*/
> >>> - if ((oldflags & (VM_WRITE | VM_SHARED | VM_LOCKED)) == VM_LOCKED &&
> >>> + if ((oldflags & (VM_WRITE | VM_LOCKED)) == VM_LOCKED &&
> >>>   (newflags & VM_WRITE)) {
> >>>   populate_vma_page_range(vma, start, end, NULL);
> >>>   }
> >>>
> >>
> >> Hi Michal,
> >>
> >> My kernel is v3.10, and I missed this code, thank you reminding me.
> > 
> > I guess I didn't get your answer. Does the above diff resolves your
> > problem?
> 
> Hi Michal,
> 
> This upstream patch 36f881883c57941bb32d25cea6524f9612ab5a2c has already
> resolve my problem, thank you for your attention.

OK, fair enough. But is does it make sense to extend this behavior to
shared mappings as well?
-- 
Michal Hocko
SUSE Labs


Re: [PATCH v3] mm, sysctl: make NUMA stats configurable

2017-10-09 Thread Michal Hocko
On Mon 09-10-17 09:55:49, Michal Hocko wrote:
> I haven't checked closely but what happens (or should happen) when you
> do a partial read? Should you get an inconsistent results? Or is this
> impossible?

Well, after thinking about it little bit more, partial reads are always
inconsistent so this wouldn't add a new problem.

Anyway I still stand by my position that this sounds over-engineered and
a simple 0/1 resp. on/off interface would be both simpler and safer. If
anybody wants an auto mode it can be added later (as a value 2 resp.
auto).
-- 
Michal Hocko
SUSE Labs


Re: [PATCH v3] mm, sysctl: make NUMA stats configurable

2017-10-09 Thread Michal Hocko
On Mon 09-10-17 09:55:49, Michal Hocko wrote:
> I haven't checked closely but what happens (or should happen) when you
> do a partial read? Should you get an inconsistent results? Or is this
> impossible?

Well, after thinking about it little bit more, partial reads are always
inconsistent so this wouldn't add a new problem.

Anyway I still stand by my position that this sounds over-engineered and
a simple 0/1 resp. on/off interface would be both simpler and safer. If
anybody wants an auto mode it can be added later (as a value 2 resp.
auto).
-- 
Michal Hocko
SUSE Labs


[PATCH v2 2/2] ARM: cpuidle: Refactor rollback operations if init fails

2017-10-09 Thread Leo Yan
If init fails, we need execute two levels rollback operations: the first
level is for the failed CPU rollback operations, the second level is to
iterate all succeeded CPUs to cancel their registration; currently the
code uses one function to finish these two levels rollback operations.

This commit is to refactor rollback operations, so it adds a new
function arm_idle_init_cpu() to encapsulate one specified CPU driver
registration and rollback the first level operations; and use function
arm_idle_init() to iterate all CPUs and finish the second level's
rollback operations.

Suggested-by: Daniel Lezcano 
Signed-off-by: Leo Yan 
---
 drivers/cpuidle/cpuidle-arm.c | 145 --
 1 file changed, 82 insertions(+), 63 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index f47c545..ddee1b6 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -72,79 +72,74 @@ static const struct of_device_id arm_idle_state_match[] 
__initconst = {
 };
 
 /*
- * arm_idle_init
+ * arm_idle_init_cpu
  *
  * Registers the arm specific cpuidle driver with the cpuidle
  * framework. It relies on core code to parse the idle states
  * and initialize them using driver data structures accordingly.
  */
-static int __init arm_idle_init(void)
+static int __init arm_idle_init_cpu(int cpu)
 {
-   int cpu, ret;
+   int ret;
struct cpuidle_driver *drv;
struct cpuidle_device *dev;
 
-   for_each_possible_cpu(cpu) {
+   drv = kmemdup(_idle_driver, sizeof(*drv), GFP_KERNEL);
+   if (!drv)
+   return -ENOMEM;
 
-   drv = kmemdup(_idle_driver, sizeof(*drv), GFP_KERNEL);
-   if (!drv) {
-   ret = -ENOMEM;
-   goto out_fail;
-   }
-
-   drv->cpumask = (struct cpumask *)cpumask_of(cpu);
-
-   /*
-* Initialize idle states data, starting at index 1.  This
-* driver is DT only, if no DT idle states are detected (ret
-* == 0) let the driver initialization fail accordingly since
-* there is no reason to initialize the idle driver if only
-* wfi is supported.
-*/
-   ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
-   if (ret <= 0) {
-   ret = ret ? : -ENODEV;
-   goto out_kfree_drv;
-   }
-
-   ret = cpuidle_register_driver(drv);
-   if (ret) {
-   pr_err("Failed to register cpuidle driver\n");
-   goto out_kfree_drv;
-   }
-
-   /*
-* Call arch CPU operations in order to initialize
-* idle states suspend back-end specific data
-*/
-   ret = arm_cpuidle_init(cpu);
-
-   /*
-* Skip the cpuidle device initialization if the reported
-* failure is a HW misconfiguration/breakage (-ENXIO).
-*/
-   if (ret == -ENXIO)
-   continue;
-
-   if (ret) {
-   pr_err("CPU %d failed to init idle CPU ops\n", cpu);
-   goto out_unregister_drv;
-   }
-
-   dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-   if (!dev) {
-   pr_err("Failed to allocate cpuidle device\n");
-   ret = -ENOMEM;
-   goto out_unregister_drv;
-   }
-   dev->cpu = cpu;
-
-   ret = cpuidle_register_device(dev);
-   if (ret) {
-   pr_err("Failed to register cpuidle device for CPU %d\n",
-  cpu);
-   goto out_kfree_dev;
-   }
+   drv->cpumask = (struct cpumask *)cpumask_of(cpu);
+
+   /*
+* Initialize idle states data, starting at index 1.  This
+* driver is DT only, if no DT idle states are detected (ret
+* == 0) let the driver initialization fail accordingly since
+* there is no reason to initialize the idle driver if only
+* wfi is supported.
+*/
+   ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
+   if (ret <= 0) {
+   ret = ret ? : -ENODEV;
+   goto out_kfree_drv;
+   }
+
+   ret = cpuidle_register_driver(drv);
+   if (ret) {
+   pr_err("Failed to register cpuidle driver\n");
+   goto out_kfree_drv;
+   }
+
+   /*
+* Call arch CPU operations in order to initialize
+* idle states suspend back-end specific data
+*/
+   ret = arm_cpuidle_init(cpu);
+
+   /*
+* Skip the cpuidle device initialization if the reported
+* failure is a HW 

[PATCH v2 2/2] ARM: cpuidle: Refactor rollback operations if init fails

2017-10-09 Thread Leo Yan
If init fails, we need execute two levels rollback operations: the first
level is for the failed CPU rollback operations, the second level is to
iterate all succeeded CPUs to cancel their registration; currently the
code uses one function to finish these two levels rollback operations.

This commit is to refactor rollback operations, so it adds a new
function arm_idle_init_cpu() to encapsulate one specified CPU driver
registration and rollback the first level operations; and use function
arm_idle_init() to iterate all CPUs and finish the second level's
rollback operations.

Suggested-by: Daniel Lezcano 
Signed-off-by: Leo Yan 
---
 drivers/cpuidle/cpuidle-arm.c | 145 --
 1 file changed, 82 insertions(+), 63 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index f47c545..ddee1b6 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -72,79 +72,74 @@ static const struct of_device_id arm_idle_state_match[] 
__initconst = {
 };
 
 /*
- * arm_idle_init
+ * arm_idle_init_cpu
  *
  * Registers the arm specific cpuidle driver with the cpuidle
  * framework. It relies on core code to parse the idle states
  * and initialize them using driver data structures accordingly.
  */
-static int __init arm_idle_init(void)
+static int __init arm_idle_init_cpu(int cpu)
 {
-   int cpu, ret;
+   int ret;
struct cpuidle_driver *drv;
struct cpuidle_device *dev;
 
-   for_each_possible_cpu(cpu) {
+   drv = kmemdup(_idle_driver, sizeof(*drv), GFP_KERNEL);
+   if (!drv)
+   return -ENOMEM;
 
-   drv = kmemdup(_idle_driver, sizeof(*drv), GFP_KERNEL);
-   if (!drv) {
-   ret = -ENOMEM;
-   goto out_fail;
-   }
-
-   drv->cpumask = (struct cpumask *)cpumask_of(cpu);
-
-   /*
-* Initialize idle states data, starting at index 1.  This
-* driver is DT only, if no DT idle states are detected (ret
-* == 0) let the driver initialization fail accordingly since
-* there is no reason to initialize the idle driver if only
-* wfi is supported.
-*/
-   ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
-   if (ret <= 0) {
-   ret = ret ? : -ENODEV;
-   goto out_kfree_drv;
-   }
-
-   ret = cpuidle_register_driver(drv);
-   if (ret) {
-   pr_err("Failed to register cpuidle driver\n");
-   goto out_kfree_drv;
-   }
-
-   /*
-* Call arch CPU operations in order to initialize
-* idle states suspend back-end specific data
-*/
-   ret = arm_cpuidle_init(cpu);
-
-   /*
-* Skip the cpuidle device initialization if the reported
-* failure is a HW misconfiguration/breakage (-ENXIO).
-*/
-   if (ret == -ENXIO)
-   continue;
-
-   if (ret) {
-   pr_err("CPU %d failed to init idle CPU ops\n", cpu);
-   goto out_unregister_drv;
-   }
-
-   dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-   if (!dev) {
-   pr_err("Failed to allocate cpuidle device\n");
-   ret = -ENOMEM;
-   goto out_unregister_drv;
-   }
-   dev->cpu = cpu;
-
-   ret = cpuidle_register_device(dev);
-   if (ret) {
-   pr_err("Failed to register cpuidle device for CPU %d\n",
-  cpu);
-   goto out_kfree_dev;
-   }
+   drv->cpumask = (struct cpumask *)cpumask_of(cpu);
+
+   /*
+* Initialize idle states data, starting at index 1.  This
+* driver is DT only, if no DT idle states are detected (ret
+* == 0) let the driver initialization fail accordingly since
+* there is no reason to initialize the idle driver if only
+* wfi is supported.
+*/
+   ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
+   if (ret <= 0) {
+   ret = ret ? : -ENODEV;
+   goto out_kfree_drv;
+   }
+
+   ret = cpuidle_register_driver(drv);
+   if (ret) {
+   pr_err("Failed to register cpuidle driver\n");
+   goto out_kfree_drv;
+   }
+
+   /*
+* Call arch CPU operations in order to initialize
+* idle states suspend back-end specific data
+*/
+   ret = arm_cpuidle_init(cpu);
+
+   /*
+* Skip the cpuidle device initialization if the reported
+* failure is a HW misconfiguration/breakage (-ENXIO).
+*/
+   if (ret 

[PATCH v2 1/2] ARM: cpuidle: Correct driver unregistration if init fails

2017-10-09 Thread Leo Yan
If cpuidle init fails, the code misses to unregister the driver for
current CPU. Furthermore, we also need to rollback to cancel all
previous CPUs registration; but the code retrieves driver handler by
using function cpuidle_get_driver(), this function returns back
current CPU driver handler but not previous CPU's handler, which leads
to the failure handling code cannot unregister previous CPUs driver.

This commit fixes two mentioned issues, it adds error handling path
'goto out_unregister_drv' for current CPU driver unregistration; and
it is to replace cpuidle_get_driver() with cpuidle_get_cpu_driver(),
the later function can retrieve driver handler for previous CPUs
according to the CPU device handler so can unregister the driver
properly.

This patch also adds extra error handling paths 'goto out_kfree_dev'
and 'goto out_kfree_drv' and adjusts the freeing sentences for previous
CPUs; so make the code more readable for freeing 'dev' and 'drv'
structures.

Suggested-by: Daniel Lezcano 
Signed-off-by: Leo Yan 
Fixes: d50a7d8acd78 ("ARM: cpuidle: Support asymmetric idle definition")
---
 drivers/cpuidle/cpuidle-arm.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 52a7505..f47c545 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -104,13 +104,13 @@ static int __init arm_idle_init(void)
ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
if (ret <= 0) {
ret = ret ? : -ENODEV;
-   goto init_fail;
+   goto out_kfree_drv;
}
 
ret = cpuidle_register_driver(drv);
if (ret) {
pr_err("Failed to register cpuidle driver\n");
-   goto init_fail;
+   goto out_kfree_drv;
}
 
/*
@@ -128,14 +128,14 @@ static int __init arm_idle_init(void)
 
if (ret) {
pr_err("CPU %d failed to init idle CPU ops\n", cpu);
-   goto out_fail;
+   goto out_unregister_drv;
}
 
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
pr_err("Failed to allocate cpuidle device\n");
ret = -ENOMEM;
-   goto out_fail;
+   goto out_unregister_drv;
}
dev->cpu = cpu;
 
@@ -143,21 +143,25 @@ static int __init arm_idle_init(void)
if (ret) {
pr_err("Failed to register cpuidle device for CPU %d\n",
   cpu);
-   kfree(dev);
-   goto out_fail;
+   goto out_kfree_dev;
}
}
 
return 0;
-init_fail:
+
+out_kfree_dev:
+   kfree(dev);
+out_unregister_drv:
+   cpuidle_unregister_driver(drv);
+out_kfree_drv:
kfree(drv);
 out_fail:
while (--cpu >= 0) {
dev = per_cpu(cpuidle_devices, cpu);
+   drv = cpuidle_get_cpu_driver(dev);
cpuidle_unregister_device(dev);
-   kfree(dev);
-   drv = cpuidle_get_driver();
cpuidle_unregister_driver(drv);
+   kfree(dev);
kfree(drv);
}
 
-- 
2.7.4



[PATCH v2 1/2] ARM: cpuidle: Correct driver unregistration if init fails

2017-10-09 Thread Leo Yan
If cpuidle init fails, the code misses to unregister the driver for
current CPU. Furthermore, we also need to rollback to cancel all
previous CPUs registration; but the code retrieves driver handler by
using function cpuidle_get_driver(), this function returns back
current CPU driver handler but not previous CPU's handler, which leads
to the failure handling code cannot unregister previous CPUs driver.

This commit fixes two mentioned issues, it adds error handling path
'goto out_unregister_drv' for current CPU driver unregistration; and
it is to replace cpuidle_get_driver() with cpuidle_get_cpu_driver(),
the later function can retrieve driver handler for previous CPUs
according to the CPU device handler so can unregister the driver
properly.

This patch also adds extra error handling paths 'goto out_kfree_dev'
and 'goto out_kfree_drv' and adjusts the freeing sentences for previous
CPUs; so make the code more readable for freeing 'dev' and 'drv'
structures.

Suggested-by: Daniel Lezcano 
Signed-off-by: Leo Yan 
Fixes: d50a7d8acd78 ("ARM: cpuidle: Support asymmetric idle definition")
---
 drivers/cpuidle/cpuidle-arm.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
index 52a7505..f47c545 100644
--- a/drivers/cpuidle/cpuidle-arm.c
+++ b/drivers/cpuidle/cpuidle-arm.c
@@ -104,13 +104,13 @@ static int __init arm_idle_init(void)
ret = dt_init_idle_driver(drv, arm_idle_state_match, 1);
if (ret <= 0) {
ret = ret ? : -ENODEV;
-   goto init_fail;
+   goto out_kfree_drv;
}
 
ret = cpuidle_register_driver(drv);
if (ret) {
pr_err("Failed to register cpuidle driver\n");
-   goto init_fail;
+   goto out_kfree_drv;
}
 
/*
@@ -128,14 +128,14 @@ static int __init arm_idle_init(void)
 
if (ret) {
pr_err("CPU %d failed to init idle CPU ops\n", cpu);
-   goto out_fail;
+   goto out_unregister_drv;
}
 
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
pr_err("Failed to allocate cpuidle device\n");
ret = -ENOMEM;
-   goto out_fail;
+   goto out_unregister_drv;
}
dev->cpu = cpu;
 
@@ -143,21 +143,25 @@ static int __init arm_idle_init(void)
if (ret) {
pr_err("Failed to register cpuidle device for CPU %d\n",
   cpu);
-   kfree(dev);
-   goto out_fail;
+   goto out_kfree_dev;
}
}
 
return 0;
-init_fail:
+
+out_kfree_dev:
+   kfree(dev);
+out_unregister_drv:
+   cpuidle_unregister_driver(drv);
+out_kfree_drv:
kfree(drv);
 out_fail:
while (--cpu >= 0) {
dev = per_cpu(cpuidle_devices, cpu);
+   drv = cpuidle_get_cpu_driver(dev);
cpuidle_unregister_device(dev);
-   kfree(dev);
-   drv = cpuidle_get_driver();
cpuidle_unregister_driver(drv);
+   kfree(dev);
kfree(drv);
}
 
-- 
2.7.4



Re: [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2

2017-10-09 Thread Byungchul Park
On Tue, Oct 03, 2017 at 09:57:02AM -0700, Linus Torvalds wrote:
> On Tue, Oct 3, 2017 at 9:54 AM, Linus Torvalds
>  wrote:
> >
> > Can we consider just reverting the crossrelease thing?
> >
> > The apparent stack corruption really worries me [...]
> 
> Side note: I also think the thing is just broken.
> 
> Any actual cross-releaser should be way more annotated than just "set
> cross to 1" in the lockdep map.
> 
> The place where the release is done should simply be special.
> 
> Because we should *not* encourage the whole "acquire by one context,
> release by another" as being something normal and "just set the flag
> to let lockdep know".

Could you explain it more? Please let me apply what you point out. Now,
I don't understand your intention.

> So that commit is apparently buggy, but I think it might be more
> fundamentally the wrong model too.

It would be appriciated if you let me know what is buggy wrt
crossrelease and the model, then I will do my best to fix it.

But I believe the model crossrelease uses is what lockdep should have
adopted before.

Anyway, I might be wrong. It would be appriciated if you tell me why you
think so.

Thank you.


Re: [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2

2017-10-09 Thread Byungchul Park
On Tue, Oct 03, 2017 at 09:57:02AM -0700, Linus Torvalds wrote:
> On Tue, Oct 3, 2017 at 9:54 AM, Linus Torvalds
>  wrote:
> >
> > Can we consider just reverting the crossrelease thing?
> >
> > The apparent stack corruption really worries me [...]
> 
> Side note: I also think the thing is just broken.
> 
> Any actual cross-releaser should be way more annotated than just "set
> cross to 1" in the lockdep map.
> 
> The place where the release is done should simply be special.
> 
> Because we should *not* encourage the whole "acquire by one context,
> release by another" as being something normal and "just set the flag
> to let lockdep know".

Could you explain it more? Please let me apply what you point out. Now,
I don't understand your intention.

> So that commit is apparently buggy, but I think it might be more
> fundamentally the wrong model too.

It would be appriciated if you let me know what is buggy wrt
crossrelease and the model, then I will do my best to fix it.

But I believe the model crossrelease uses is what lockdep should have
adopted before.

Anyway, I might be wrong. It would be appriciated if you tell me why you
think so.

Thank you.


Re: Which came first, hard kernel lockup or SATA errors?

2017-10-09 Thread Ed Swierk
On Fri, Oct 6, 2017 at 6:25 PM, Ed Swierk  wrote:
> I'm trying to untangle a series of problems that suddenly occurred on
> a dual-socket Xeon server system that had been running a bunch of KVM
> workloads just fine for over 6 weeks (4.4.52-grsec kernel,
> Debian-derived userspace).

I think I've narrowed the hard lockup to a race between
task_numa_migrate() and idle_balance().

Here are the two lockup messages again, this time with approximate
code references.

[3851435.62] NMI watchdog: Watchdog detected hard LOCKUP on cpu 13
[3851435.784582] Modules linked in: vhost_net tun vhost macvtap 8021q garp mrp 
drbg ansi_cprng dm_crypt algif_skcipher af_alg ip_gre ip_tunnel gre macvlan 
ebtable_filter ebtables openvswitch nf_defrag_ipv6 libcrc32c nfsd auth_rpcgss 
nfs_acl nfs lockd grace fscache sunrpc ip6table_filter ip6_tables nf_log_ipv4 
nf_log_common xt_LOG xt_limit xt_tcpudp nf_conntrack_ipv4 nf_defrag_ipv4 
xt_conntrack nf_conntrack iptable_filter ip_tables x_tables iTCO_wdt 
iTCO_vendor_support x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel 
kvm irqbypass crct10dif_pclmul raid10 crc32_pclmul aesni_intel aes_x86_64 lrw 
gf128mul glue_helper ablk_helper cryptd sb_edac lpc_ich mfd_core mei_me mei 
i2c_i801 ioatdma ipmi_ssif ipmi_msghandler acpi_pad acpi_cpufreq squashfs 
lz4_decompress xhci_pci xhci_hcd ixgbe mdio vxlan ip6_udp_tunnel udp_tunnel ptp 
pps_core dca ehci_pci ehci_hcd usbcore ahci libahci usb_common tpm_tis
[3851435.874884] irq event stamp: 3828060294
[3851435.879398] hardirqs last  enabled at (3828060293): [] 
810db86c
[3851435.10] hardirqs last disabled at (3828060294): [] 
8170ff74
[3851435.898254] softirqs last  enabled at (3828060156): [] 
8107f31e
[3851435.907666] softirqs last disabled at (3828060139): [] 
8107f648
[3851435.917094] CPU: 13 PID: 2146 Comm: pocviexg Not tainted 4.4.52-grsec #1
[3851435.925252] Hardware name: Intel S2600WTTR, BIOS 
SE5C610.86B.01.01.0016.C1.033120161139 03/31/2016
[3851435.937473] task: 881c9ff35c00 ti: 881c9ff372b0 task.ti: 
881c9ff372b0
[3851435.946104] RIP: 0010:[]  [] 
try_to_wake_up+0xe4/0x500
[3851435.955614] RSP: :c90016beba40  EFLAGS: 0002
[3851435.961780] RAX:  RBX: 88102cc8e3d8 RCX: 
0001
[3851435.970016] RDX: 0001 RSI: 01e4 RDI: 

[3851435.978259] RBP: c90016beba80 R08:  R09: 
0001
[3851435.986493] R10: 00e0 R11: 881c9ff35c00 R12: 
0082
[3851435.994727] R13: 88102cc8dc00 R14: 001d3f00 R15: 
81f25060
[3851436.002962] FS:  6e79227fc700() GS:88203400() 
knlGS:
[3851436.012266] CS:  0010 DS:  ES:  CR0: 80050033
[3851436.018920] CR2: 6e79227fba38 CR3: 00201d2fe000 CR4: 
003626f0
[3851436.027155] DR0:  DR1:  DR2: 

[3851436.035391] DR3:  DR6: fffe0ff0 DR7: 
0400
[3851436.043626] Stack:
[3851436.046098]  8820341ce620 8820341ce608  
8820341ce600
[3851436.054695]  c90016bebb48 000d  
881033fce600
[3851436.063259]  c90016beba90 810adc80 c90016bebbe8 
8112c830
[3851436.071868] Call Trace:
[3851436.074862]  [] wake_up_process+0x10/0x20
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/sched/core.c#L1997
[3851436.081317]  [] stop_two_cpus+0x1b0/0x280
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/stop_machine.c#L235
[3851436.087778]  [] ? cpu_stop_park+0x40/0x40
[3851436.094237]  [] ? cpu_stop_park+0x40/0x40
[3851436.100715]  [] ? __migrate_swap_task.part.94+0x70/0x70
[3851436.108539]  [] migrate_swap+0xf1/0x1f0  
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/sched/core.c#L1408
[3851436.114800]  [] task_numa_migrate+0x345/0xb60
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/sched/fair.c#L1572
[3851436.121656]  [] ? futex_wait_queue_me+0xf3/0x160
[3851436.128801]  [] numa_migrate_preferred+0x73/0x80 
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/sched/fair.c#L1597
[3851436.135936]  [] task_numa_fault+0x7a4/0xee0  
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/sched/fair.c#L2137
[3851436.142604]  [] ? should_numa_migrate_memory+0x50/0x130
[3851436.150437]  [] handle_mm_fault+0xfd6/0x1e10 
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/mm/memory.c#L3503
[3851436.157189]  [] ? handle_mm_fault+0x48/0x1e10
[3851436.164051]  [] ? ___might_sleep+0x1ea/0x220
[3851436.170804]  [] __do_page_fault+0x1bf/0x460
[3851436.177475]  [] ? sys_futex+0x74/0x230
[3851436.183642]  [] do_page_fault+0x2c/0x40
[3851436.189909]  [] page_fault+0x28/0x30
[3851436.195892] Code: 0f 85 e0 02 00 00 

Re: Which came first, hard kernel lockup or SATA errors?

2017-10-09 Thread Ed Swierk
On Fri, Oct 6, 2017 at 6:25 PM, Ed Swierk  wrote:
> I'm trying to untangle a series of problems that suddenly occurred on
> a dual-socket Xeon server system that had been running a bunch of KVM
> workloads just fine for over 6 weeks (4.4.52-grsec kernel,
> Debian-derived userspace).

I think I've narrowed the hard lockup to a race between
task_numa_migrate() and idle_balance().

Here are the two lockup messages again, this time with approximate
code references.

[3851435.62] NMI watchdog: Watchdog detected hard LOCKUP on cpu 13
[3851435.784582] Modules linked in: vhost_net tun vhost macvtap 8021q garp mrp 
drbg ansi_cprng dm_crypt algif_skcipher af_alg ip_gre ip_tunnel gre macvlan 
ebtable_filter ebtables openvswitch nf_defrag_ipv6 libcrc32c nfsd auth_rpcgss 
nfs_acl nfs lockd grace fscache sunrpc ip6table_filter ip6_tables nf_log_ipv4 
nf_log_common xt_LOG xt_limit xt_tcpudp nf_conntrack_ipv4 nf_defrag_ipv4 
xt_conntrack nf_conntrack iptable_filter ip_tables x_tables iTCO_wdt 
iTCO_vendor_support x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel 
kvm irqbypass crct10dif_pclmul raid10 crc32_pclmul aesni_intel aes_x86_64 lrw 
gf128mul glue_helper ablk_helper cryptd sb_edac lpc_ich mfd_core mei_me mei 
i2c_i801 ioatdma ipmi_ssif ipmi_msghandler acpi_pad acpi_cpufreq squashfs 
lz4_decompress xhci_pci xhci_hcd ixgbe mdio vxlan ip6_udp_tunnel udp_tunnel ptp 
pps_core dca ehci_pci ehci_hcd usbcore ahci libahci usb_common tpm_tis
[3851435.874884] irq event stamp: 3828060294
[3851435.879398] hardirqs last  enabled at (3828060293): [] 
810db86c
[3851435.10] hardirqs last disabled at (3828060294): [] 
8170ff74
[3851435.898254] softirqs last  enabled at (3828060156): [] 
8107f31e
[3851435.907666] softirqs last disabled at (3828060139): [] 
8107f648
[3851435.917094] CPU: 13 PID: 2146 Comm: pocviexg Not tainted 4.4.52-grsec #1
[3851435.925252] Hardware name: Intel S2600WTTR, BIOS 
SE5C610.86B.01.01.0016.C1.033120161139 03/31/2016
[3851435.937473] task: 881c9ff35c00 ti: 881c9ff372b0 task.ti: 
881c9ff372b0
[3851435.946104] RIP: 0010:[]  [] 
try_to_wake_up+0xe4/0x500
[3851435.955614] RSP: :c90016beba40  EFLAGS: 0002
[3851435.961780] RAX:  RBX: 88102cc8e3d8 RCX: 
0001
[3851435.970016] RDX: 0001 RSI: 01e4 RDI: 

[3851435.978259] RBP: c90016beba80 R08:  R09: 
0001
[3851435.986493] R10: 00e0 R11: 881c9ff35c00 R12: 
0082
[3851435.994727] R13: 88102cc8dc00 R14: 001d3f00 R15: 
81f25060
[3851436.002962] FS:  6e79227fc700() GS:88203400() 
knlGS:
[3851436.012266] CS:  0010 DS:  ES:  CR0: 80050033
[3851436.018920] CR2: 6e79227fba38 CR3: 00201d2fe000 CR4: 
003626f0
[3851436.027155] DR0:  DR1:  DR2: 

[3851436.035391] DR3:  DR6: fffe0ff0 DR7: 
0400
[3851436.043626] Stack:
[3851436.046098]  8820341ce620 8820341ce608  
8820341ce600
[3851436.054695]  c90016bebb48 000d  
881033fce600
[3851436.063259]  c90016beba90 810adc80 c90016bebbe8 
8112c830
[3851436.071868] Call Trace:
[3851436.074862]  [] wake_up_process+0x10/0x20
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/sched/core.c#L1997
[3851436.081317]  [] stop_two_cpus+0x1b0/0x280
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/stop_machine.c#L235
[3851436.087778]  [] ? cpu_stop_park+0x40/0x40
[3851436.094237]  [] ? cpu_stop_park+0x40/0x40
[3851436.100715]  [] ? __migrate_swap_task.part.94+0x70/0x70
[3851436.108539]  [] migrate_swap+0xf1/0x1f0  
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/sched/core.c#L1408
[3851436.114800]  [] task_numa_migrate+0x345/0xb60
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/sched/fair.c#L1572
[3851436.121656]  [] ? futex_wait_queue_me+0xf3/0x160
[3851436.128801]  [] numa_migrate_preferred+0x73/0x80 
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/sched/fair.c#L1597
[3851436.135936]  [] task_numa_fault+0x7a4/0xee0  
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/kernel/sched/fair.c#L2137
[3851436.142604]  [] ? should_numa_migrate_memory+0x50/0x130
[3851436.150437]  [] handle_mm_fault+0xfd6/0x1e10 
https://github.com/skyportsystems/linux/blob/4.4.52-grsec/mm/memory.c#L3503
[3851436.157189]  [] ? handle_mm_fault+0x48/0x1e10
[3851436.164051]  [] ? ___might_sleep+0x1ea/0x220
[3851436.170804]  [] __do_page_fault+0x1bf/0x460
[3851436.177475]  [] ? sys_futex+0x74/0x230
[3851436.183642]  [] do_page_fault+0x2c/0x40
[3851436.189909]  [] page_fault+0x28/0x30
[3851436.195892] Code: 0f 85 e0 02 00 00 41 8b 85 b8 16 00 00 89 45 

Re: [PATCH v2] mm/page_alloc.c: inline __rmqueue()

2017-10-09 Thread Aaron Lu
On Mon, Oct 09, 2017 at 10:19:52PM -0700, Dave Hansen wrote:
> On 10/09/2017 07:56 PM, Aaron Lu wrote:
> > This patch adds inline to __rmqueue() and vmlinux' size doesn't have any
> > change after this patch according to size(1).
> > 
> > without this patch:
> >textdata bss dec hex filename
> > 9968576 5793372 17715200  33477148  1fed21c vmlinux
> > 
> > with this patch:
> >textdata bss dec hex filename
> > 9968576 5793372 17715200  33477148  1fed21c vmlinux
> 
> This is unexpected.  Could you double-check this, please?

mm/page_alloc.o has size changes:

Without this patch:
$ size mm/page_alloc.o
  textdata bss dec hex filename
 3669597928396   54883d663 mm/page_alloc.o

With this patch:
$ size mm/page_alloc.o
  textdata bss dec hex filename
 3751197928396   55699d993 mm/page_alloc.o

But vmlinux doesn't.

It's not clear to me what happened, do you want to me dig this out?


Re: [PATCH v2] mm/page_alloc.c: inline __rmqueue()

2017-10-09 Thread Aaron Lu
On Mon, Oct 09, 2017 at 10:19:52PM -0700, Dave Hansen wrote:
> On 10/09/2017 07:56 PM, Aaron Lu wrote:
> > This patch adds inline to __rmqueue() and vmlinux' size doesn't have any
> > change after this patch according to size(1).
> > 
> > without this patch:
> >textdata bss dec hex filename
> > 9968576 5793372 17715200  33477148  1fed21c vmlinux
> > 
> > with this patch:
> >textdata bss dec hex filename
> > 9968576 5793372 17715200  33477148  1fed21c vmlinux
> 
> This is unexpected.  Could you double-check this, please?

mm/page_alloc.o has size changes:

Without this patch:
$ size mm/page_alloc.o
  textdata bss dec hex filename
 3669597928396   54883d663 mm/page_alloc.o

With this patch:
$ size mm/page_alloc.o
  textdata bss dec hex filename
 3751197928396   55699d993 mm/page_alloc.o

But vmlinux doesn't.

It's not clear to me what happened, do you want to me dig this out?


[RFC][PATCH 2/3] of: overlay_mgr: Add ability to apply through sysfs entry

2017-10-09 Thread John Stultz
From: Dmitry Shmidt 

Allow pre-defined overlay_mgr DT fragments to be enabled on the
fly by writing to:
  /sys/devices/platform/overlay_mgr/current_overlay

Cc: Rob Herring 
Cc: Mark Rutland 
Cc: Frank Rowand 
Cc: Dmitry Shmidt 
Cc: devicet...@vger.kernel.org
Signed-off-by: Dmitry Shmidt 
[jstultz: Slightly reworded commit message]
Signed-off-by: John Stultz 
---
 drivers/of/overlay_mgr.c | 52 
 1 file changed, 52 insertions(+)

diff --git a/drivers/of/overlay_mgr.c b/drivers/of/overlay_mgr.c
index 1fdeb0a..5a082be 100644
--- a/drivers/of/overlay_mgr.c
+++ b/drivers/of/overlay_mgr.c
@@ -18,10 +18,14 @@
 #include 
 #include 
 #include 
+#include 
 
 static char *of_overlay_dt_entry;
 module_param_named(overlay_dt_entry, of_overlay_dt_entry, charp, 0644);
 
+static char *of_overlay_dt_apply;
+DEFINE_MUTEX(of_overlay_mgr_mutex);
+
 static int of_overlay_mgr_apply_overlay(struct device_node *onp)
 {
int ret;
@@ -61,8 +65,56 @@ static int of_overlay_mgr_apply_dt(struct device *dev, char 
*dt_entry)
return 0;
 }
 
+static ssize_t current_overlay_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   size_t len;
+
+   mutex_lock(_overlay_mgr_mutex);
+   if (!of_overlay_dt_apply) {
+   mutex_unlock(_overlay_mgr_mutex);
+   return 0;
+   }
+   len = strlen(of_overlay_dt_apply);
+   if (len >= PAGE_SIZE)
+   len = PAGE_SIZE - 1;
+   memcpy(buf, of_overlay_dt_apply, len + 1);
+   mutex_unlock(_overlay_mgr_mutex);
+   return len;
+}
+
+static ssize_t current_overlay_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t size)
+{
+   mutex_lock(_overlay_mgr_mutex);
+   kfree(of_overlay_dt_apply);
+   of_overlay_dt_apply = kmalloc(size, GFP_KERNEL);
+   if (!of_overlay_dt_apply) {
+   pr_err("overlay_mgr: fail to allocate memory\n");
+   mutex_unlock(_overlay_mgr_mutex);
+   return 0;
+   }
+   memcpy(of_overlay_dt_apply, buf, size);
+   of_overlay_dt_apply[size - 1] = '\0';
+
+   if (of_overlay_mgr_apply_dt(dev, of_overlay_dt_apply)) {
+   kfree(of_overlay_dt_apply);
+   of_overlay_dt_apply = NULL;
+   size = 0;
+   }
+   mutex_unlock(_overlay_mgr_mutex);
+   return size;
+}
+
+static DEVICE_ATTR(current_overlay, 0644, current_overlay_show,
+  current_overlay_store);
+
 static int of_overlay_mgr_probe(struct platform_device *pdev)
 {
+   if (device_create_file(>dev, _attr_current_overlay))
+   pr_err("overlay_mgr: fail to register apply entry\n");
+
if (!of_overlay_dt_entry)
return 0;
of_overlay_mgr_apply_dt(>dev, of_overlay_dt_entry);
-- 
2.7.4



[RFC][PATCH 2/3] of: overlay_mgr: Add ability to apply through sysfs entry

2017-10-09 Thread John Stultz
From: Dmitry Shmidt 

Allow pre-defined overlay_mgr DT fragments to be enabled on the
fly by writing to:
  /sys/devices/platform/overlay_mgr/current_overlay

Cc: Rob Herring 
Cc: Mark Rutland 
Cc: Frank Rowand 
Cc: Dmitry Shmidt 
Cc: devicet...@vger.kernel.org
Signed-off-by: Dmitry Shmidt 
[jstultz: Slightly reworded commit message]
Signed-off-by: John Stultz 
---
 drivers/of/overlay_mgr.c | 52 
 1 file changed, 52 insertions(+)

diff --git a/drivers/of/overlay_mgr.c b/drivers/of/overlay_mgr.c
index 1fdeb0a..5a082be 100644
--- a/drivers/of/overlay_mgr.c
+++ b/drivers/of/overlay_mgr.c
@@ -18,10 +18,14 @@
 #include 
 #include 
 #include 
+#include 
 
 static char *of_overlay_dt_entry;
 module_param_named(overlay_dt_entry, of_overlay_dt_entry, charp, 0644);
 
+static char *of_overlay_dt_apply;
+DEFINE_MUTEX(of_overlay_mgr_mutex);
+
 static int of_overlay_mgr_apply_overlay(struct device_node *onp)
 {
int ret;
@@ -61,8 +65,56 @@ static int of_overlay_mgr_apply_dt(struct device *dev, char 
*dt_entry)
return 0;
 }
 
+static ssize_t current_overlay_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   size_t len;
+
+   mutex_lock(_overlay_mgr_mutex);
+   if (!of_overlay_dt_apply) {
+   mutex_unlock(_overlay_mgr_mutex);
+   return 0;
+   }
+   len = strlen(of_overlay_dt_apply);
+   if (len >= PAGE_SIZE)
+   len = PAGE_SIZE - 1;
+   memcpy(buf, of_overlay_dt_apply, len + 1);
+   mutex_unlock(_overlay_mgr_mutex);
+   return len;
+}
+
+static ssize_t current_overlay_store(struct device *dev,
+struct device_attribute *attr,
+const char *buf, size_t size)
+{
+   mutex_lock(_overlay_mgr_mutex);
+   kfree(of_overlay_dt_apply);
+   of_overlay_dt_apply = kmalloc(size, GFP_KERNEL);
+   if (!of_overlay_dt_apply) {
+   pr_err("overlay_mgr: fail to allocate memory\n");
+   mutex_unlock(_overlay_mgr_mutex);
+   return 0;
+   }
+   memcpy(of_overlay_dt_apply, buf, size);
+   of_overlay_dt_apply[size - 1] = '\0';
+
+   if (of_overlay_mgr_apply_dt(dev, of_overlay_dt_apply)) {
+   kfree(of_overlay_dt_apply);
+   of_overlay_dt_apply = NULL;
+   size = 0;
+   }
+   mutex_unlock(_overlay_mgr_mutex);
+   return size;
+}
+
+static DEVICE_ATTR(current_overlay, 0644, current_overlay_show,
+  current_overlay_store);
+
 static int of_overlay_mgr_probe(struct platform_device *pdev)
 {
+   if (device_create_file(>dev, _attr_current_overlay))
+   pr_err("overlay_mgr: fail to register apply entry\n");
+
if (!of_overlay_dt_entry)
return 0;
of_overlay_mgr_apply_dt(>dev, of_overlay_dt_entry);
-- 
2.7.4



[RFC][PATCH 1/3] of: overlay_mgr: Add overlay manager driver

2017-10-09 Thread John Stultz
From: Dmitry Shmidt 

This patch adds a driver to manage applying pre-defined DT
overlay fragments at bootup.

The pre-defined DT fragments are specified via the main
overlay_mng entry which includes all the possible HW config setups.

Then kernel command line option is used to choose between them.

These entries are specified on kernel boot arguments as follows:
   overlay_mgr.overlay_dt_entry=hardware_cfg_0

Example DT entry:
overlay_mgr {
compatible = "linux,overlay_manager";
hardware_cfg_0 {
overlay@0 {
fragment@0 {
__overlay__ {
};
};
};
overlay@1 {
fragment@0 {
__overlay__ {
};
};
};
};
};

Cc: Rob Herring 
Cc: Mark Rutland 
Cc: Frank Rowand 
Cc: Dmitry Shmidt 
Cc: devicet...@vger.kernel.org
Signed-off-by: Dmitry Shmidt 
[jstultz: Reworded commit message]
Signed-off-by: John Stultz 
---
 .../devicetree/bindings/of/overlay_mgr.txt | 32 
 drivers/of/Kconfig | 10 +++
 drivers/of/Makefile|  1 +
 drivers/of/overlay_mgr.c   | 90 ++
 4 files changed, 133 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/of/overlay_mgr.txt
 create mode 100644 drivers/of/overlay_mgr.c

diff --git a/Documentation/devicetree/bindings/of/overlay_mgr.txt 
b/Documentation/devicetree/bindings/of/overlay_mgr.txt
new file mode 100644
index 000..5f3ce4c
--- /dev/null
+++ b/Documentation/devicetree/bindings/of/overlay_mgr.txt
@@ -0,0 +1,32 @@
+overlay_mgr
+
+Required properties:
+- compatible: "linux,overlay_manager";
+
+Optional properties:
+- starts from the word "hardware": hardware_cfg_0
+
+These properties can be chosen from kernel command line:
+overlay_mgr.overlay_dt_entry=hardware_cfg_0
+DT contains main overlay_mng entry with all possible
+HW config setups. And then kernel command line option
+will allow to choose between them.
+
+Example:
+overlay_mgr {
+compatible = "linux,overlay_manager";
+hardware_cfg_0 {
+overlay@0 {
+fragment@0 {
+__overlay__ {
+};
+};
+};
+overlay@1 {
+fragment@0 {
+__overlay__ {
+};
+};
+};
+};
+};
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index ba7b034..5132e41 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -112,4 +112,14 @@ config OF_OVERLAY
 config OF_NUMA
bool
 
+config OF_OVERLAY_MGR
+   bool "Enable Overlay manager"
+   default n
+   depends on OF_OVERLAY
+   help
+ Enables Overlay manager - it accepts DT entry from command line
+ overlay_mgr.overlay_dt_entry= and applies all overlays in
+ it to current DT. It is also possible to apply predefined DT
+ entry on the fly by writing it to 'current_overlay' sysfs entry.
+
 endif # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 97dc01c..e2b8afa 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -14,5 +14,6 @@ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
 obj-$(CONFIG_OF_RESOLVE)  += resolver.o
 obj-$(CONFIG_OF_OVERLAY) += overlay.o
 obj-$(CONFIG_OF_NUMA) += of_numa.o
+obj-$(CONFIG_OF_OVERLAY_MGR) += overlay_mgr.o
 
 obj-$(CONFIG_OF_UNITTEST) += unittest-data/
diff --git a/drivers/of/overlay_mgr.c b/drivers/of/overlay_mgr.c
new file mode 100644
index 000..1fdeb0a
--- /dev/null
+++ b/drivers/of/overlay_mgr.c
@@ -0,0 +1,90 @@
+/*
+ * Overlay manager that allows to apply list of overlays from DT entry
+ *
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static char *of_overlay_dt_entry;
+module_param_named(overlay_dt_entry, of_overlay_dt_entry, charp, 0644);
+
+static int of_overlay_mgr_apply_overlay(struct device_node *onp)
+{
+   int ret;
+
+   ret = of_overlay_create(onp);
+   if (ret < 0) {
+   pr_err("overlay_mgr: fail to create overlay: %d\n", ret);
+   

[RFC][PATCH 3/3] of: overlay_mgr: Add ability to apply several hardware configurations

2017-10-09 Thread John Stultz
From: Dmitry Shmidt 

This adds the ability to specify multiple DT overlay
configurations, which are predefined in the overlay_mgr entry,
at once via the boot arguments.

Example:
  overlay_mgr.overlay_dt_entry=hardware_cfg_0,hardware_cfg_1,...

Cc: Rob Herring 
Cc: Mark Rutland 
Cc: Frank Rowand 
Cc: Dmitry Shmidt 
Cc: devicet...@vger.kernel.org
Signed-off-by: Dmitry Shmidt 
[jstultz: reworded commit message]
Signed-off-by: John Stultz 
---
 drivers/of/overlay_mgr.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/of/overlay_mgr.c b/drivers/of/overlay_mgr.c
index 5a082be..6b15f7c 100644
--- a/drivers/of/overlay_mgr.c
+++ b/drivers/of/overlay_mgr.c
@@ -112,12 +112,22 @@ static DEVICE_ATTR(current_overlay, 0644, 
current_overlay_show,
 
 static int of_overlay_mgr_probe(struct platform_device *pdev)
 {
+   char *cur_entry;
+   char *next_entry;
+
if (device_create_file(>dev, _attr_current_overlay))
pr_err("overlay_mgr: fail to register apply entry\n");
 
if (!of_overlay_dt_entry)
return 0;
-   of_overlay_mgr_apply_dt(>dev, of_overlay_dt_entry);
+   next_entry = of_overlay_dt_entry;
+   do {
+   cur_entry = next_entry;
+   next_entry = strchr(cur_entry, ',');
+   if (next_entry)
+   *next_entry++ = '\0';
+   of_overlay_mgr_apply_dt(>dev, cur_entry);
+   } while (next_entry);
return 0;
 }
 
-- 
2.7.4



[RFC][PATCH 1/3] of: overlay_mgr: Add overlay manager driver

2017-10-09 Thread John Stultz
From: Dmitry Shmidt 

This patch adds a driver to manage applying pre-defined DT
overlay fragments at bootup.

The pre-defined DT fragments are specified via the main
overlay_mng entry which includes all the possible HW config setups.

Then kernel command line option is used to choose between them.

These entries are specified on kernel boot arguments as follows:
   overlay_mgr.overlay_dt_entry=hardware_cfg_0

Example DT entry:
overlay_mgr {
compatible = "linux,overlay_manager";
hardware_cfg_0 {
overlay@0 {
fragment@0 {
__overlay__ {
};
};
};
overlay@1 {
fragment@0 {
__overlay__ {
};
};
};
};
};

Cc: Rob Herring 
Cc: Mark Rutland 
Cc: Frank Rowand 
Cc: Dmitry Shmidt 
Cc: devicet...@vger.kernel.org
Signed-off-by: Dmitry Shmidt 
[jstultz: Reworded commit message]
Signed-off-by: John Stultz 
---
 .../devicetree/bindings/of/overlay_mgr.txt | 32 
 drivers/of/Kconfig | 10 +++
 drivers/of/Makefile|  1 +
 drivers/of/overlay_mgr.c   | 90 ++
 4 files changed, 133 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/of/overlay_mgr.txt
 create mode 100644 drivers/of/overlay_mgr.c

diff --git a/Documentation/devicetree/bindings/of/overlay_mgr.txt 
b/Documentation/devicetree/bindings/of/overlay_mgr.txt
new file mode 100644
index 000..5f3ce4c
--- /dev/null
+++ b/Documentation/devicetree/bindings/of/overlay_mgr.txt
@@ -0,0 +1,32 @@
+overlay_mgr
+
+Required properties:
+- compatible: "linux,overlay_manager";
+
+Optional properties:
+- starts from the word "hardware": hardware_cfg_0
+
+These properties can be chosen from kernel command line:
+overlay_mgr.overlay_dt_entry=hardware_cfg_0
+DT contains main overlay_mng entry with all possible
+HW config setups. And then kernel command line option
+will allow to choose between them.
+
+Example:
+overlay_mgr {
+compatible = "linux,overlay_manager";
+hardware_cfg_0 {
+overlay@0 {
+fragment@0 {
+__overlay__ {
+};
+};
+};
+overlay@1 {
+fragment@0 {
+__overlay__ {
+};
+};
+};
+};
+};
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index ba7b034..5132e41 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -112,4 +112,14 @@ config OF_OVERLAY
 config OF_NUMA
bool
 
+config OF_OVERLAY_MGR
+   bool "Enable Overlay manager"
+   default n
+   depends on OF_OVERLAY
+   help
+ Enables Overlay manager - it accepts DT entry from command line
+ overlay_mgr.overlay_dt_entry= and applies all overlays in
+ it to current DT. It is also possible to apply predefined DT
+ entry on the fly by writing it to 'current_overlay' sysfs entry.
+
 endif # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 97dc01c..e2b8afa 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -14,5 +14,6 @@ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
 obj-$(CONFIG_OF_RESOLVE)  += resolver.o
 obj-$(CONFIG_OF_OVERLAY) += overlay.o
 obj-$(CONFIG_OF_NUMA) += of_numa.o
+obj-$(CONFIG_OF_OVERLAY_MGR) += overlay_mgr.o
 
 obj-$(CONFIG_OF_UNITTEST) += unittest-data/
diff --git a/drivers/of/overlay_mgr.c b/drivers/of/overlay_mgr.c
new file mode 100644
index 000..1fdeb0a
--- /dev/null
+++ b/drivers/of/overlay_mgr.c
@@ -0,0 +1,90 @@
+/*
+ * Overlay manager that allows to apply list of overlays from DT entry
+ *
+ * Copyright (C) 2016 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static char *of_overlay_dt_entry;
+module_param_named(overlay_dt_entry, of_overlay_dt_entry, charp, 0644);
+
+static int of_overlay_mgr_apply_overlay(struct device_node *onp)
+{
+   int ret;
+
+   ret = of_overlay_create(onp);
+   if (ret < 0) {
+   pr_err("overlay_mgr: fail to create overlay: %d\n", ret);
+   of_node_put(onp);
+   return ret;
+   }
+   pr_info("overlay_mgr: %s overlay applied\n", onp->name);
+   return 0;
+}
+
+static int 

[RFC][PATCH 3/3] of: overlay_mgr: Add ability to apply several hardware configurations

2017-10-09 Thread John Stultz
From: Dmitry Shmidt 

This adds the ability to specify multiple DT overlay
configurations, which are predefined in the overlay_mgr entry,
at once via the boot arguments.

Example:
  overlay_mgr.overlay_dt_entry=hardware_cfg_0,hardware_cfg_1,...

Cc: Rob Herring 
Cc: Mark Rutland 
Cc: Frank Rowand 
Cc: Dmitry Shmidt 
Cc: devicet...@vger.kernel.org
Signed-off-by: Dmitry Shmidt 
[jstultz: reworded commit message]
Signed-off-by: John Stultz 
---
 drivers/of/overlay_mgr.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/of/overlay_mgr.c b/drivers/of/overlay_mgr.c
index 5a082be..6b15f7c 100644
--- a/drivers/of/overlay_mgr.c
+++ b/drivers/of/overlay_mgr.c
@@ -112,12 +112,22 @@ static DEVICE_ATTR(current_overlay, 0644, 
current_overlay_show,
 
 static int of_overlay_mgr_probe(struct platform_device *pdev)
 {
+   char *cur_entry;
+   char *next_entry;
+
if (device_create_file(>dev, _attr_current_overlay))
pr_err("overlay_mgr: fail to register apply entry\n");
 
if (!of_overlay_dt_entry)
return 0;
-   of_overlay_mgr_apply_dt(>dev, of_overlay_dt_entry);
+   next_entry = of_overlay_dt_entry;
+   do {
+   cur_entry = next_entry;
+   next_entry = strchr(cur_entry, ',');
+   if (next_entry)
+   *next_entry++ = '\0';
+   of_overlay_mgr_apply_dt(>dev, cur_entry);
+   } while (next_entry);
return 0;
 }
 
-- 
2.7.4



Re: [PATCH v7 1/6] lib/dlock-list: Distributed and lock-protected lists

2017-10-09 Thread Boqun Feng
On Thu, Oct 05, 2017 at 06:43:23PM +, Waiman Long wrote:
[...]
> +/*
> + * As all the locks in the dlock list are dynamically allocated, they need
> + * to belong to their own special lock class to avoid warning and stack
> + * trace in kernel log when lockdep is enabled. Statically allocated locks
> + * don't have this problem.
> + */
> +static struct lock_class_key dlock_list_key;
> +

So in this way, you make all dlock_lists share the same lock_class_key,
which means if there are two structures:

struct some_a {
...
struct dlock_list_heads dlists;
};

struct some_b {
...
struct dlock_list_heads dlists;
};

some_a::dlists and some_b::dlists are going to have the same lockdep
key, is this what you want? If not, you may want to do something like
init_srcu_struct() does.

> +/*
> + * Initialize cpu2idx mapping table
> + *
> + * It is possible that a dlock-list can be allocated before the cpu2idx is
> + * initialized. In this case, all the cpus are mapped to the first entry
> + * before initialization.
> + *
> + */
> +static int __init cpu2idx_init(void)
> +{
> + int idx, cpu;
> +
> + idx = 0;
> + for_each_possible_cpu(cpu)
> + per_cpu(cpu2idx, cpu) = idx++;
> + return 0;
> +}
> +postcore_initcall(cpu2idx_init);
> +
> +/**
> + * alloc_dlock_list_heads - Initialize and allocate the list of head entries
> + * @dlist: Pointer to the dlock_list_heads structure to be initialized
> + * Return: 0 if successful, -ENOMEM if memory allocation error
> + *
> + * This function does not allocate the dlock_list_heads structure itself. The
> + * callers will have to do their own memory allocation, if necessary. 
> However,
> + * this allows embedding the dlock_list_heads structure directly into other
> + * structures.
> + */
> +int alloc_dlock_list_heads(struct dlock_list_heads *dlist)
> +{
> + int idx;
> +
> + dlist->heads = kcalloc(nr_cpu_ids, sizeof(struct dlock_list_head),
> +GFP_KERNEL);
> +
> + if (!dlist->heads)
> + return -ENOMEM;
> +
> + for (idx = 0; idx < nr_cpu_ids; idx++) {
> + struct dlock_list_head *head = >heads[idx];
> +
> + INIT_LIST_HEAD(>list);
> + head->lock = __SPIN_LOCK_UNLOCKED(>lock);
> + lockdep_set_class(>lock, _list_key);
> + }
> + return 0;
> +}
> +
> +/**
> + * free_dlock_list_heads - Free all the heads entries of the dlock list
> + * @dlist: Pointer of the dlock_list_heads structure to be freed
> + *
> + * This function doesn't free the dlock_list_heads structure itself. So
> + * the caller will have to do it, if necessary.
> + */
> +void free_dlock_list_heads(struct dlock_list_heads *dlist)
> +{
> + kfree(dlist->heads);
> + dlist->heads = NULL;
> +}
> +
> +/**
> + * dlock_lists_empty - Check if all the dlock lists are empty
> + * @dlist: Pointer to the dlock_list_heads structure
> + * Return: true if list is empty, false otherwise.
> + *
> + * This can be a pretty expensive function call. If this function is required
> + * in a performance critical path, we may have to maintain a global count
> + * of the list entries in the global dlock_list_heads structure instead.
> + */
> +bool dlock_lists_empty(struct dlock_list_heads *dlist)
> +{
> + int idx;
> +
> + for (idx = 0; idx < nr_cpu_ids; idx++)
> + if (!list_empty(>heads[idx].list))
> + return false;
> + return true;
> +}
> +
> +/**
> + * dlock_lists_add - Adds a node to the given dlock list
> + * @node : The node to be added
> + * @dlist: The dlock list where the node is to be added
> + *
> + * List selection is based on the CPU being used when the dlock_list_add()
> + * function is called. However, deletion may be done by a different CPU.
> + */
> +void dlock_lists_add(struct dlock_list_node *node,
> +  struct dlock_list_heads *dlist)
> +{
> + struct dlock_list_head *head = >heads[this_cpu_read(cpu2idx)];
> +
> + /*
> +  * There is no need to disable preemption
> +  */
> + spin_lock(>lock);
> + node->head = head;
> + list_add(>list, >list);
> + spin_unlock(>lock);
> +}
> +
> +/**
> + * dlock_lists_del - Delete a node from a dlock list
> + * @node : The node to be deleted
> + *
> + * We need to check the lock pointer again after taking the lock to guard
> + * against concurrent deletion of the same node. If the lock pointer changes
> + * (becomes NULL or to a different one), we assume that the deletion was done
> + * elsewhere. A warning will be printed if this happens as it is likely to be
> + * a bug.
> + */
> +void dlock_lists_del(struct dlock_list_node *node)
> +{
> + struct dlock_list_head *head;
> + bool retry;
> +
> + do {
> + head = READ_ONCE(node->head);

Since we read node->head locklessly here, I think we should use
WRITE_ONCE() for all the stores of node->head, to avoid 

[RFC][PATCH 0/3] Overlay manager for predefined DT overlay fragments

2017-10-09 Thread John Stultz
In working with the HiKey and HiKey960 as targets for AOSP,
Dmitry developed the following overlay manager driver, which
allows a number of pre-determined DT overlay configurations to
be defined, and the configurations to be enabled at boot time
via a kernel boot argument.

This has been submitted before, but while the earlier discussion
didn't really resolve to any sort of actionable direction, this
issue cropped up again and was a major discussion topic at the
Linux Plumbers Conference Android Microconference, so I suspect
it is worth revisiting this solution again.

The overall use case is being able to configure devboards that
support a number of different mezzanine peripherals which
unfortunately cannot be probed. Some example mezzanines are
LCD panels or sensor hubs, as well as other options.

The new functionality this driver provides is a mechanism to
specify multiple pre-determined dt overlay fragments in a
dtb file, and providing a way to select which dt fragments
should be applied via the kernel boot argument.

The desire to use a kernel boot-argument as the selection
mechanism, comes from the Android Boot Image format not handling
dtbs independently. Usually with Android, the dtb is appended
to the kernel image, and modifying that is much more difficult
then changing the boot argugments. There is also a usability
argument that using a kernel command option to select
pre-defined entries is simpler for users to navigate.

Also, since the mezzanines are unable to be probed, we cannot
use other solutions, like having the bootloader specify
additional dtb overlays to the kernel.

Obviously the earlier objections to this approach likely still
apply, but we wanted to resubmit it for feedback in order to
restart the discussion to find an actionable direction as to
what sort of usable and more general approach could be found.

Cc: Rob Herring 
Cc: Mark Rutland 
Cc: Frank Rowand 
Cc: Dmitry Shmidt 
Cc: devicet...@vger.kernel.org

Dmitry Shmidt (3):
  of: overlay_mgr: Add overlay manager driver
  of: overlay_mgr: Add ability to apply through sysfs entry
  of: overlay_mgr: Add ability to apply several hardware configurations

 .../devicetree/bindings/of/overlay_mgr.txt |  32 +
 drivers/of/Kconfig |  10 ++
 drivers/of/Makefile|   1 +
 drivers/of/overlay_mgr.c   | 152 +
 4 files changed, 195 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/of/overlay_mgr.txt
 create mode 100644 drivers/of/overlay_mgr.c

-- 
2.7.4



Re: [PATCH v7 1/6] lib/dlock-list: Distributed and lock-protected lists

2017-10-09 Thread Boqun Feng
On Thu, Oct 05, 2017 at 06:43:23PM +, Waiman Long wrote:
[...]
> +/*
> + * As all the locks in the dlock list are dynamically allocated, they need
> + * to belong to their own special lock class to avoid warning and stack
> + * trace in kernel log when lockdep is enabled. Statically allocated locks
> + * don't have this problem.
> + */
> +static struct lock_class_key dlock_list_key;
> +

So in this way, you make all dlock_lists share the same lock_class_key,
which means if there are two structures:

struct some_a {
...
struct dlock_list_heads dlists;
};

struct some_b {
...
struct dlock_list_heads dlists;
};

some_a::dlists and some_b::dlists are going to have the same lockdep
key, is this what you want? If not, you may want to do something like
init_srcu_struct() does.

> +/*
> + * Initialize cpu2idx mapping table
> + *
> + * It is possible that a dlock-list can be allocated before the cpu2idx is
> + * initialized. In this case, all the cpus are mapped to the first entry
> + * before initialization.
> + *
> + */
> +static int __init cpu2idx_init(void)
> +{
> + int idx, cpu;
> +
> + idx = 0;
> + for_each_possible_cpu(cpu)
> + per_cpu(cpu2idx, cpu) = idx++;
> + return 0;
> +}
> +postcore_initcall(cpu2idx_init);
> +
> +/**
> + * alloc_dlock_list_heads - Initialize and allocate the list of head entries
> + * @dlist: Pointer to the dlock_list_heads structure to be initialized
> + * Return: 0 if successful, -ENOMEM if memory allocation error
> + *
> + * This function does not allocate the dlock_list_heads structure itself. The
> + * callers will have to do their own memory allocation, if necessary. 
> However,
> + * this allows embedding the dlock_list_heads structure directly into other
> + * structures.
> + */
> +int alloc_dlock_list_heads(struct dlock_list_heads *dlist)
> +{
> + int idx;
> +
> + dlist->heads = kcalloc(nr_cpu_ids, sizeof(struct dlock_list_head),
> +GFP_KERNEL);
> +
> + if (!dlist->heads)
> + return -ENOMEM;
> +
> + for (idx = 0; idx < nr_cpu_ids; idx++) {
> + struct dlock_list_head *head = >heads[idx];
> +
> + INIT_LIST_HEAD(>list);
> + head->lock = __SPIN_LOCK_UNLOCKED(>lock);
> + lockdep_set_class(>lock, _list_key);
> + }
> + return 0;
> +}
> +
> +/**
> + * free_dlock_list_heads - Free all the heads entries of the dlock list
> + * @dlist: Pointer of the dlock_list_heads structure to be freed
> + *
> + * This function doesn't free the dlock_list_heads structure itself. So
> + * the caller will have to do it, if necessary.
> + */
> +void free_dlock_list_heads(struct dlock_list_heads *dlist)
> +{
> + kfree(dlist->heads);
> + dlist->heads = NULL;
> +}
> +
> +/**
> + * dlock_lists_empty - Check if all the dlock lists are empty
> + * @dlist: Pointer to the dlock_list_heads structure
> + * Return: true if list is empty, false otherwise.
> + *
> + * This can be a pretty expensive function call. If this function is required
> + * in a performance critical path, we may have to maintain a global count
> + * of the list entries in the global dlock_list_heads structure instead.
> + */
> +bool dlock_lists_empty(struct dlock_list_heads *dlist)
> +{
> + int idx;
> +
> + for (idx = 0; idx < nr_cpu_ids; idx++)
> + if (!list_empty(>heads[idx].list))
> + return false;
> + return true;
> +}
> +
> +/**
> + * dlock_lists_add - Adds a node to the given dlock list
> + * @node : The node to be added
> + * @dlist: The dlock list where the node is to be added
> + *
> + * List selection is based on the CPU being used when the dlock_list_add()
> + * function is called. However, deletion may be done by a different CPU.
> + */
> +void dlock_lists_add(struct dlock_list_node *node,
> +  struct dlock_list_heads *dlist)
> +{
> + struct dlock_list_head *head = >heads[this_cpu_read(cpu2idx)];
> +
> + /*
> +  * There is no need to disable preemption
> +  */
> + spin_lock(>lock);
> + node->head = head;
> + list_add(>list, >list);
> + spin_unlock(>lock);
> +}
> +
> +/**
> + * dlock_lists_del - Delete a node from a dlock list
> + * @node : The node to be deleted
> + *
> + * We need to check the lock pointer again after taking the lock to guard
> + * against concurrent deletion of the same node. If the lock pointer changes
> + * (becomes NULL or to a different one), we assume that the deletion was done
> + * elsewhere. A warning will be printed if this happens as it is likely to be
> + * a bug.
> + */
> +void dlock_lists_del(struct dlock_list_node *node)
> +{
> + struct dlock_list_head *head;
> + bool retry;
> +
> + do {
> + head = READ_ONCE(node->head);

Since we read node->head locklessly here, I think we should use
WRITE_ONCE() for all the stores of node->head, to avoid 

[RFC][PATCH 0/3] Overlay manager for predefined DT overlay fragments

2017-10-09 Thread John Stultz
In working with the HiKey and HiKey960 as targets for AOSP,
Dmitry developed the following overlay manager driver, which
allows a number of pre-determined DT overlay configurations to
be defined, and the configurations to be enabled at boot time
via a kernel boot argument.

This has been submitted before, but while the earlier discussion
didn't really resolve to any sort of actionable direction, this
issue cropped up again and was a major discussion topic at the
Linux Plumbers Conference Android Microconference, so I suspect
it is worth revisiting this solution again.

The overall use case is being able to configure devboards that
support a number of different mezzanine peripherals which
unfortunately cannot be probed. Some example mezzanines are
LCD panels or sensor hubs, as well as other options.

The new functionality this driver provides is a mechanism to
specify multiple pre-determined dt overlay fragments in a
dtb file, and providing a way to select which dt fragments
should be applied via the kernel boot argument.

The desire to use a kernel boot-argument as the selection
mechanism, comes from the Android Boot Image format not handling
dtbs independently. Usually with Android, the dtb is appended
to the kernel image, and modifying that is much more difficult
then changing the boot argugments. There is also a usability
argument that using a kernel command option to select
pre-defined entries is simpler for users to navigate.

Also, since the mezzanines are unable to be probed, we cannot
use other solutions, like having the bootloader specify
additional dtb overlays to the kernel.

Obviously the earlier objections to this approach likely still
apply, but we wanted to resubmit it for feedback in order to
restart the discussion to find an actionable direction as to
what sort of usable and more general approach could be found.

Cc: Rob Herring 
Cc: Mark Rutland 
Cc: Frank Rowand 
Cc: Dmitry Shmidt 
Cc: devicet...@vger.kernel.org

Dmitry Shmidt (3):
  of: overlay_mgr: Add overlay manager driver
  of: overlay_mgr: Add ability to apply through sysfs entry
  of: overlay_mgr: Add ability to apply several hardware configurations

 .../devicetree/bindings/of/overlay_mgr.txt |  32 +
 drivers/of/Kconfig |  10 ++
 drivers/of/Makefile|   1 +
 drivers/of/overlay_mgr.c   | 152 +
 4 files changed, 195 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/of/overlay_mgr.txt
 create mode 100644 drivers/of/overlay_mgr.c

-- 
2.7.4



Re: [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2

2017-10-09 Thread Byungchul Park
On Tue, Oct 03, 2017 at 07:18:24PM +0200, Ingo Molnar wrote:
> 
> * Linus Torvalds  wrote:
> 
> > On Tue, Oct 3, 2017 at 7:06 AM, Fengguang Wu  wrote:
> > >
> > > This patch triggers a NULL-dereference bug at update_stack_state().
> > > Although its parent commit also has a NULL-dereference bug, however
> > > the call stack looks rather different. Both dmesg files are attached.
> > >
> > > It also triggers this warning, which is being discussed in another
> > > thread, so CC Josh. The full dmesg attached, too.
> > >
> > > Please press Enter to activate this console.
> > > [  138.605622] WARNING: kernel stack regs at be299c9a in 
> > > procd:340 has bad 'bp' value 01be
> > > [  138.605627] unwind stack type:0 next_sp:  (null) mask:0x2 
> > > graph_idx:0
> > > [  138.605631] be299c9a: 299ceb00 (0x299ceb00)
> > > [  138.605633] be299c9e: 2281f1be (0x2281f1be)
> > > [  138.605634] be299ca2: 299cebb6 (0x299cebb6)
> > >
> > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
> > >
> > > commit b09be676e0ff25bd6d2e7637e26d349f9109ad75
> > >  locking/lockdep: Implement the 'crossrelease' feature
> > 
> > Can we consider just reverting the crossrelease thing?
> 
> Yes, I'll do that tomorrow. I was always a bit unhappy about cross-release, 
> because it breaks the 'owner task owns the lock' model. Plus I don't think

Of course, I may have taken a mistake. It would be appriciated if you
let me know and fix it, if it actually exists.

But I believe that the design of crossrelease to detect deadlocks in
more general way is correct.

As you know, dependencies do not have to be created by the model, while
all waiters can create dependencies causing deadlocks. So the model
should be broken for such waiters to be in.



Re: [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2

2017-10-09 Thread Byungchul Park
On Tue, Oct 03, 2017 at 07:18:24PM +0200, Ingo Molnar wrote:
> 
> * Linus Torvalds  wrote:
> 
> > On Tue, Oct 3, 2017 at 7:06 AM, Fengguang Wu  wrote:
> > >
> > > This patch triggers a NULL-dereference bug at update_stack_state().
> > > Although its parent commit also has a NULL-dereference bug, however
> > > the call stack looks rather different. Both dmesg files are attached.
> > >
> > > It also triggers this warning, which is being discussed in another
> > > thread, so CC Josh. The full dmesg attached, too.
> > >
> > > Please press Enter to activate this console.
> > > [  138.605622] WARNING: kernel stack regs at be299c9a in 
> > > procd:340 has bad 'bp' value 01be
> > > [  138.605627] unwind stack type:0 next_sp:  (null) mask:0x2 
> > > graph_idx:0
> > > [  138.605631] be299c9a: 299ceb00 (0x299ceb00)
> > > [  138.605633] be299c9e: 2281f1be (0x2281f1be)
> > > [  138.605634] be299ca2: 299cebb6 (0x299cebb6)
> > >
> > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
> > >
> > > commit b09be676e0ff25bd6d2e7637e26d349f9109ad75
> > >  locking/lockdep: Implement the 'crossrelease' feature
> > 
> > Can we consider just reverting the crossrelease thing?
> 
> Yes, I'll do that tomorrow. I was always a bit unhappy about cross-release, 
> because it breaks the 'owner task owns the lock' model. Plus I don't think

Of course, I may have taken a mistake. It would be appriciated if you
let me know and fix it, if it actually exists.

But I believe that the design of crossrelease to detect deadlocks in
more general way is correct.

As you know, dependencies do not have to be created by the model, while
all waiters can create dependencies causing deadlocks. So the model
should be broken for such waiters to be in.



[PATCH v4 2/2] dma: sprd: Add Spreadtrum DMA driver

2017-10-09 Thread Baolin Wang
This patch adds the DMA controller driver for Spreadtrum SC9860 platform.

Signed-off-by: Baolin Wang 
---
Changes since v3:
 - Remove redundant local 'mask' and 'val' variables.
 - Simplify sprd_dma_get_req_type() function.
 - Change pm_runtime_put_sync() to pm_runtime_put() in probe function.
 - Simplify sizeof function.
 - Other coding style fixes.

Changes since v2:
 - Add COMPILE_TEST as dependency.
 - Renamed DMA macro definition properly.
 - Add sprd_dma_chn_update() helpers to save lots of code.
 - Change pm_runtime_put_sync() to pm_runtime_put() when free resources.
 - Re-implement the sprd_dma_tx_status() function.
 - Free irq and kill tasklet when remove driver.
 - Add some documentaion.
 - Change to module_init() level and add MODULE_ALIAS().
 - Other coding style fixes.

Changes since v1:
 - Use virt-dma to manage dma descriptors.
 - Remove link-list and channel-start-channel Spreadtrum special features.
 - Remove device_config implementation.
 - Other optimization.

Note: This patch just implemented the basic DMA_MEMCPY function, and in
future we will send new patches to introduce some Speadtrum special features,
that will be talk about how to handle these features easily instead of in one
big patch which is hard to review.
---
 drivers/dma/Kconfig|8 +
 drivers/dma/Makefile   |1 +
 drivers/dma/sprd-dma.c |  988 
 3 files changed, 997 insertions(+)
 create mode 100644 drivers/dma/sprd-dma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index fadc4d8..a2aa7fe 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -483,6 +483,14 @@ config STM32_DMA
  If you have a board based on such a MCU and wish to use DMA say Y
  here.
 
+config SPRD_DMA
+   tristate "Spreadtrum DMA support"
+   depends on ARCH_SPRD || COMPILE_TEST
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Enable support for the on-chip DMA controller on Spreadtrum platform.
+
 config S3C24XX_DMAC
bool "Samsung S3C24XX DMA support"
depends on ARCH_S3C24XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index f08f8de..9e7ec34 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_RENESAS_DMA) += sh/
 obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
 obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
 obj-$(CONFIG_STM32_DMA) += stm32-dma.o
+obj-$(CONFIG_SPRD_DMA) += sprd-dma.o
 obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
 obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
 obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
new file mode 100644
index 000..4d70f7c
--- /dev/null
+++ b/drivers/dma/sprd-dma.c
@@ -0,0 +1,988 @@
+/*
+ * Copyright (C) 2017 Spreadtrum Communications Inc.
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+#define SPRD_DMA_CHN_REG_OFFSET0x1000
+#define SPRD_DMA_CHN_REG_LENGTH0x40
+#define SPRD_DMA_MEMCPY_MIN_SIZE   64
+
+/* DMA global registers definition */
+#define SPRD_DMA_GLB_PAUSE 0x0
+#define SPRD_DMA_GLB_FRAG_WAIT 0x4
+#define SPRD_DMA_GLB_REQ_PEND0_EN  0x8
+#define SPRD_DMA_GLB_REQ_PEND1_EN  0xc
+#define SPRD_DMA_GLB_INT_RAW_STS   0x10
+#define SPRD_DMA_GLB_INT_MSK_STS   0x14
+#define SPRD_DMA_GLB_REQ_STS   0x18
+#define SPRD_DMA_GLB_CHN_EN_STS0x1c
+#define SPRD_DMA_GLB_DEBUG_STS 0x20
+#define SPRD_DMA_GLB_ARB_SEL_STS   0x24
+#define SPRD_DMA_GLB_REQ_UID(uid)  (0x4 * ((uid) - 1))
+#define SPRD_DMA_GLB_REQ_UID_OFFSET0x2000
+
+/* DMA channel registers definition */
+#define SPRD_DMA_CHN_PAUSE 0x0
+#define SPRD_DMA_CHN_REQ   0x4
+#define SPRD_DMA_CHN_CFG   0x8
+#define SPRD_DMA_CHN_INTC  0xc
+#define SPRD_DMA_CHN_SRC_ADDR  0x10
+#define SPRD_DMA_CHN_DES_ADDR  0x14
+#define SPRD_DMA_CHN_FRG_LEN   0x18
+#define SPRD_DMA_CHN_BLK_LEN   0x1c
+#define SPRD_DMA_CHN_TRSC_LEN  0x20
+#define SPRD_DMA_CHN_TRSF_STEP 0x24
+#define SPRD_DMA_CHN_WARP_PTR  0x28
+#define SPRD_DMA_CHN_WARP_TO   0x2c
+#define SPRD_DMA_CHN_LLIST_PTR 0x30
+#define SPRD_DMA_CHN_FRAG_STEP 0x34
+#define SPRD_DMA_CHN_SRC_BLK_STEP  0x38
+#define SPRD_DMA_CHN_DES_BLK_STEP  0x3c
+
+/* SPRD_DMA_CHN_INTC register definition */
+#define SPRD_DMA_INT_MASK  GENMASK(4, 0)
+#define SPRD_DMA_INT_CLR_OFFSET24
+#define SPRD_DMA_FRAG_INT_EN   BIT(0)
+#define SPRD_DMA_BLK_INT_ENBIT(1)
+#define SPRD_DMA_TRANS_INT_EN  BIT(2)
+#define SPRD_DMA_LIST_INT_EN   BIT(3)
+#define SPRD_DMA_CFG_ERR_INT_EN   

[PATCH v4 2/2] dma: sprd: Add Spreadtrum DMA driver

2017-10-09 Thread Baolin Wang
This patch adds the DMA controller driver for Spreadtrum SC9860 platform.

Signed-off-by: Baolin Wang 
---
Changes since v3:
 - Remove redundant local 'mask' and 'val' variables.
 - Simplify sprd_dma_get_req_type() function.
 - Change pm_runtime_put_sync() to pm_runtime_put() in probe function.
 - Simplify sizeof function.
 - Other coding style fixes.

Changes since v2:
 - Add COMPILE_TEST as dependency.
 - Renamed DMA macro definition properly.
 - Add sprd_dma_chn_update() helpers to save lots of code.
 - Change pm_runtime_put_sync() to pm_runtime_put() when free resources.
 - Re-implement the sprd_dma_tx_status() function.
 - Free irq and kill tasklet when remove driver.
 - Add some documentaion.
 - Change to module_init() level and add MODULE_ALIAS().
 - Other coding style fixes.

Changes since v1:
 - Use virt-dma to manage dma descriptors.
 - Remove link-list and channel-start-channel Spreadtrum special features.
 - Remove device_config implementation.
 - Other optimization.

Note: This patch just implemented the basic DMA_MEMCPY function, and in
future we will send new patches to introduce some Speadtrum special features,
that will be talk about how to handle these features easily instead of in one
big patch which is hard to review.
---
 drivers/dma/Kconfig|8 +
 drivers/dma/Makefile   |1 +
 drivers/dma/sprd-dma.c |  988 
 3 files changed, 997 insertions(+)
 create mode 100644 drivers/dma/sprd-dma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index fadc4d8..a2aa7fe 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -483,6 +483,14 @@ config STM32_DMA
  If you have a board based on such a MCU and wish to use DMA say Y
  here.
 
+config SPRD_DMA
+   tristate "Spreadtrum DMA support"
+   depends on ARCH_SPRD || COMPILE_TEST
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Enable support for the on-chip DMA controller on Spreadtrum platform.
+
 config S3C24XX_DMAC
bool "Samsung S3C24XX DMA support"
depends on ARCH_S3C24XX || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index f08f8de..9e7ec34 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_RENESAS_DMA) += sh/
 obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
 obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
 obj-$(CONFIG_STM32_DMA) += stm32-dma.o
+obj-$(CONFIG_SPRD_DMA) += sprd-dma.o
 obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o
 obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
 obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
new file mode 100644
index 000..4d70f7c
--- /dev/null
+++ b/drivers/dma/sprd-dma.c
@@ -0,0 +1,988 @@
+/*
+ * Copyright (C) 2017 Spreadtrum Communications Inc.
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+#define SPRD_DMA_CHN_REG_OFFSET0x1000
+#define SPRD_DMA_CHN_REG_LENGTH0x40
+#define SPRD_DMA_MEMCPY_MIN_SIZE   64
+
+/* DMA global registers definition */
+#define SPRD_DMA_GLB_PAUSE 0x0
+#define SPRD_DMA_GLB_FRAG_WAIT 0x4
+#define SPRD_DMA_GLB_REQ_PEND0_EN  0x8
+#define SPRD_DMA_GLB_REQ_PEND1_EN  0xc
+#define SPRD_DMA_GLB_INT_RAW_STS   0x10
+#define SPRD_DMA_GLB_INT_MSK_STS   0x14
+#define SPRD_DMA_GLB_REQ_STS   0x18
+#define SPRD_DMA_GLB_CHN_EN_STS0x1c
+#define SPRD_DMA_GLB_DEBUG_STS 0x20
+#define SPRD_DMA_GLB_ARB_SEL_STS   0x24
+#define SPRD_DMA_GLB_REQ_UID(uid)  (0x4 * ((uid) - 1))
+#define SPRD_DMA_GLB_REQ_UID_OFFSET0x2000
+
+/* DMA channel registers definition */
+#define SPRD_DMA_CHN_PAUSE 0x0
+#define SPRD_DMA_CHN_REQ   0x4
+#define SPRD_DMA_CHN_CFG   0x8
+#define SPRD_DMA_CHN_INTC  0xc
+#define SPRD_DMA_CHN_SRC_ADDR  0x10
+#define SPRD_DMA_CHN_DES_ADDR  0x14
+#define SPRD_DMA_CHN_FRG_LEN   0x18
+#define SPRD_DMA_CHN_BLK_LEN   0x1c
+#define SPRD_DMA_CHN_TRSC_LEN  0x20
+#define SPRD_DMA_CHN_TRSF_STEP 0x24
+#define SPRD_DMA_CHN_WARP_PTR  0x28
+#define SPRD_DMA_CHN_WARP_TO   0x2c
+#define SPRD_DMA_CHN_LLIST_PTR 0x30
+#define SPRD_DMA_CHN_FRAG_STEP 0x34
+#define SPRD_DMA_CHN_SRC_BLK_STEP  0x38
+#define SPRD_DMA_CHN_DES_BLK_STEP  0x3c
+
+/* SPRD_DMA_CHN_INTC register definition */
+#define SPRD_DMA_INT_MASK  GENMASK(4, 0)
+#define SPRD_DMA_INT_CLR_OFFSET24
+#define SPRD_DMA_FRAG_INT_EN   BIT(0)
+#define SPRD_DMA_BLK_INT_ENBIT(1)
+#define SPRD_DMA_TRANS_INT_EN  BIT(2)
+#define SPRD_DMA_LIST_INT_EN   BIT(3)
+#define SPRD_DMA_CFG_ERR_INT_ENBIT(4)
+
+/* 

[PATCH v4 1/2] dt-bindings: dma: Add Spreadtrum SC9860 DMA controller

2017-10-09 Thread Baolin Wang
This patch adds the binding documentation for Spreadtrum SC9860 DMA
controller device.

Signed-off-by: Baolin Wang 
Acked-by: Rob Herring 
---
Changes since v3:
 - No update.

Changes since v2:
 - No update.

Changes since v1:
 - Fix typos.
---
 Documentation/devicetree/bindings/dma/sprd-dma.txt |   41 
 1 file changed, 41 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/sprd-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/sprd-dma.txt 
b/Documentation/devicetree/bindings/dma/sprd-dma.txt
new file mode 100644
index 000..7a10fea
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/sprd-dma.txt
@@ -0,0 +1,41 @@
+* Spreadtrum DMA controller
+
+This binding follows the generic DMA bindings defined in dma.txt.
+
+Required properties:
+- compatible: Should be "sprd,sc9860-dma".
+- reg: Should contain DMA registers location and length.
+- interrupts: Should contain one interrupt shared by all channel.
+- #dma-cells: must be <1>. Used to represent the number of integer
+   cells in the dmas property of client device.
+- #dma-channels : Number of DMA channels supported. Should be 32.
+- clock-names: Should contain the clock of the DMA controller.
+- clocks: Should contain a clock specifier for each entry in clock-names.
+
+Example:
+
+Controller:
+apdma: dma-controller@2010 {
+   compatible = "sprd,sc9860-dma";
+   reg = <0x2010 0x4000>;
+   interrupts = ;
+   #dma-cells = <1>;
+   #dma-channels = <32>;
+   clock-names = "enable";
+   clocks = <_ap_ahb_gates 5>;
+};
+
+
+Client:
+DMA clients connected to the Spreadtrum DMA controller must use the format
+described in the dma.txt file, using a two-cell specifier for each channel.
+The two cells in order are:
+1. A phandle pointing to the DMA controller.
+2. The channel id.
+
+spi0: spi@70a0{
+   ...
+   dma-names = "rx_chn", "tx_chn";
+   dmas = < 11>, < 12>;
+   ...
+};
-- 
1.7.9.5



[PATCH v4 1/2] dt-bindings: dma: Add Spreadtrum SC9860 DMA controller

2017-10-09 Thread Baolin Wang
This patch adds the binding documentation for Spreadtrum SC9860 DMA
controller device.

Signed-off-by: Baolin Wang 
Acked-by: Rob Herring 
---
Changes since v3:
 - No update.

Changes since v2:
 - No update.

Changes since v1:
 - Fix typos.
---
 Documentation/devicetree/bindings/dma/sprd-dma.txt |   41 
 1 file changed, 41 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/sprd-dma.txt

diff --git a/Documentation/devicetree/bindings/dma/sprd-dma.txt 
b/Documentation/devicetree/bindings/dma/sprd-dma.txt
new file mode 100644
index 000..7a10fea
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/sprd-dma.txt
@@ -0,0 +1,41 @@
+* Spreadtrum DMA controller
+
+This binding follows the generic DMA bindings defined in dma.txt.
+
+Required properties:
+- compatible: Should be "sprd,sc9860-dma".
+- reg: Should contain DMA registers location and length.
+- interrupts: Should contain one interrupt shared by all channel.
+- #dma-cells: must be <1>. Used to represent the number of integer
+   cells in the dmas property of client device.
+- #dma-channels : Number of DMA channels supported. Should be 32.
+- clock-names: Should contain the clock of the DMA controller.
+- clocks: Should contain a clock specifier for each entry in clock-names.
+
+Example:
+
+Controller:
+apdma: dma-controller@2010 {
+   compatible = "sprd,sc9860-dma";
+   reg = <0x2010 0x4000>;
+   interrupts = ;
+   #dma-cells = <1>;
+   #dma-channels = <32>;
+   clock-names = "enable";
+   clocks = <_ap_ahb_gates 5>;
+};
+
+
+Client:
+DMA clients connected to the Spreadtrum DMA controller must use the format
+described in the dma.txt file, using a two-cell specifier for each channel.
+The two cells in order are:
+1. A phandle pointing to the DMA controller.
+2. The channel id.
+
+spi0: spi@70a0{
+   ...
+   dma-names = "rx_chn", "tx_chn";
+   dmas = < 11>, < 12>;
+   ...
+};
-- 
1.7.9.5



Re: [PATCH v2] mm/page_alloc.c: inline __rmqueue()

2017-10-09 Thread Dave Hansen
On 10/09/2017 07:56 PM, Aaron Lu wrote:
> This patch adds inline to __rmqueue() and vmlinux' size doesn't have any
> change after this patch according to size(1).
> 
> without this patch:
>textdata bss dec hex filename
> 9968576 5793372 17715200  33477148  1fed21c vmlinux
> 
> with this patch:
>textdata bss dec hex filename
> 9968576 5793372 17715200  33477148  1fed21c vmlinux

This is unexpected.  Could you double-check this, please?


Re: [PATCH v2] mm/page_alloc.c: inline __rmqueue()

2017-10-09 Thread Dave Hansen
On 10/09/2017 07:56 PM, Aaron Lu wrote:
> This patch adds inline to __rmqueue() and vmlinux' size doesn't have any
> change after this patch according to size(1).
> 
> without this patch:
>textdata bss dec hex filename
> 9968576 5793372 17715200  33477148  1fed21c vmlinux
> 
> with this patch:
>textdata bss dec hex filename
> 9968576 5793372 17715200  33477148  1fed21c vmlinux

This is unexpected.  Could you double-check this, please?


Re: [PATCH] net: ftgmac100: Request clock and set speed

2017-10-09 Thread Joel Stanley
On Tue, Oct 10, 2017 at 2:34 PM, Florian Fainelli  wrote:
>
>
> On 10/09/2017 09:49 PM, Joel Stanley wrote:
>> According to the ASPEED datasheet, gigabit speeds require a clock of
>> 100MHz or higher. Other speeds require 25MHz or higher.
>>
>> Signed-off-by: Joel Stanley 
>> ---
>
>> @@ -161,6 +170,9 @@ static int ftgmac100_reset_and_config_mac(struct 
>> ftgmac100 *priv)
>>   break;
>>   }
>>
>> + if (freq && priv->clk)
>> + clk_set_rate(priv->clk, freq);
>
> Checking for priv->clk should not be necessary all public clk APIs can
> deal with a NULL clock pointer.

The intention was to set ->clk to NULL to indicate that there was no
clk, and therefore there is no reason to attempt to set the rate or
call prepare/unprepare.

If the we prefer to call the clk apis unconditionally I will send a v2
with the checks removed.

Thanks for the review.

Cheers,

Joel


Re: [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2

2017-10-09 Thread Byungchul Park
On Tue, Oct 03, 2017 at 09:54:31AM -0700, Linus Torvalds wrote:
> On Tue, Oct 3, 2017 at 7:06 AM, Fengguang Wu  wrote:
> >
> > This patch triggers a NULL-dereference bug at update_stack_state().
> > Although its parent commit also has a NULL-dereference bug, however
> > the call stack looks rather different. Both dmesg files are attached.
> >
> > It also triggers this warning, which is being discussed in another
> > thread, so CC Josh. The full dmesg attached, too.
> >
> > Please press Enter to activate this console.
> > [  138.605622] WARNING: kernel stack regs at be299c9a in procd:340 
> > has bad 'bp' value 01be
> > [  138.605627] unwind stack type:0 next_sp:  (null) mask:0x2 
> > graph_idx:0
> > [  138.605631] be299c9a: 299ceb00 (0x299ceb00)
> > [  138.605633] be299c9e: 2281f1be (0x2281f1be)
> > [  138.605634] be299ca2: 299cebb6 (0x299cebb6)
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
> >
> > commit b09be676e0ff25bd6d2e7637e26d349f9109ad75
> >  locking/lockdep: Implement the 'crossrelease' feature

Hello,

I'm sorry for late. It was the biggest traditional holiday in Korea
until yesterday.

> Can we consider just reverting the crossrelease thing?
> 
> The apparent stack corruption really worries me, and what worries me
> most is that commit wasn't even supposed to change anything as far as
> I can tell - it only adds infrastructure, no actual users that *set*
> the cross-lock thing.

All users of wait_for_completion() and lock_page() are implicitly actual
users with CONFIG_LOCKDEP_CROSSRELEASE enabled, which sets the crosslock
thing internally on its initialization.



Re: [PATCH] net: ftgmac100: Request clock and set speed

2017-10-09 Thread Joel Stanley
On Tue, Oct 10, 2017 at 2:34 PM, Florian Fainelli  wrote:
>
>
> On 10/09/2017 09:49 PM, Joel Stanley wrote:
>> According to the ASPEED datasheet, gigabit speeds require a clock of
>> 100MHz or higher. Other speeds require 25MHz or higher.
>>
>> Signed-off-by: Joel Stanley 
>> ---
>
>> @@ -161,6 +170,9 @@ static int ftgmac100_reset_and_config_mac(struct 
>> ftgmac100 *priv)
>>   break;
>>   }
>>
>> + if (freq && priv->clk)
>> + clk_set_rate(priv->clk, freq);
>
> Checking for priv->clk should not be necessary all public clk APIs can
> deal with a NULL clock pointer.

The intention was to set ->clk to NULL to indicate that there was no
clk, and therefore there is no reason to attempt to set the rate or
call prepare/unprepare.

If the we prefer to call the clk apis unconditionally I will send a v2
with the checks removed.

Thanks for the review.

Cheers,

Joel


Re: [lockdep] b09be676e0 BUG: unable to handle kernel NULL pointer dereference at 000001f2

2017-10-09 Thread Byungchul Park
On Tue, Oct 03, 2017 at 09:54:31AM -0700, Linus Torvalds wrote:
> On Tue, Oct 3, 2017 at 7:06 AM, Fengguang Wu  wrote:
> >
> > This patch triggers a NULL-dereference bug at update_stack_state().
> > Although its parent commit also has a NULL-dereference bug, however
> > the call stack looks rather different. Both dmesg files are attached.
> >
> > It also triggers this warning, which is being discussed in another
> > thread, so CC Josh. The full dmesg attached, too.
> >
> > Please press Enter to activate this console.
> > [  138.605622] WARNING: kernel stack regs at be299c9a in procd:340 
> > has bad 'bp' value 01be
> > [  138.605627] unwind stack type:0 next_sp:  (null) mask:0x2 
> > graph_idx:0
> > [  138.605631] be299c9a: 299ceb00 (0x299ceb00)
> > [  138.605633] be299c9e: 2281f1be (0x2281f1be)
> > [  138.605634] be299ca2: 299cebb6 (0x299cebb6)
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
> >
> > commit b09be676e0ff25bd6d2e7637e26d349f9109ad75
> >  locking/lockdep: Implement the 'crossrelease' feature

Hello,

I'm sorry for late. It was the biggest traditional holiday in Korea
until yesterday.

> Can we consider just reverting the crossrelease thing?
> 
> The apparent stack corruption really worries me, and what worries me
> most is that commit wasn't even supposed to change anything as far as
> I can tell - it only adds infrastructure, no actual users that *set*
> the cross-lock thing.

All users of wait_for_completion() and lock_page() are implicitly actual
users with CONFIG_LOCKDEP_CROSSRELEASE enabled, which sets the crosslock
thing internally on its initialization.



Re: [PATCH] net: ftgmac100: Request clock and set speed

2017-10-09 Thread Florian Fainelli


On 10/09/2017 09:49 PM, Joel Stanley wrote:
> According to the ASPEED datasheet, gigabit speeds require a clock of
> 100MHz or higher. Other speeds require 25MHz or higher.
> 
> Signed-off-by: Joel Stanley 
> ---

> @@ -161,6 +170,9 @@ static int ftgmac100_reset_and_config_mac(struct 
> ftgmac100 *priv)
>   break;
>   }
>  
> + if (freq && priv->clk)
> + clk_set_rate(priv->clk, freq);

Checking for priv->clk should not be necessary all public clk APIs can
deal with a NULL clock pointer.

> +
>   /* (Re)initialize the queue pointers */
>   priv->rx_pointer = 0;
>   priv->tx_clean_pointer = 0;
> @@ -1775,6 +1787,13 @@ static int ftgmac100_probe(struct platform_device 
> *pdev)
>   priv->dev = >dev;
>   INIT_WORK(>reset_task, ftgmac100_reset_task);
>  
> + /* Enable clock if present */
> + priv->clk = devm_clk_get(>dev, NULL);
> + if (!IS_ERR(priv->clk))
> + clk_prepare_enable(priv->clk);
> + else
> + priv->clk = NULL;

Same here.

> +
>   /* map io memory */
>   priv->res = request_mem_region(res->start, resource_size(res),
>  dev_name(>dev));
> @@ -1883,6 +1902,9 @@ static int ftgmac100_remove(struct platform_device 
> *pdev)
>  
>   unregister_netdev(netdev);
>  
> + if (priv->clk)
> + clk_disable_unprepare(priv->clk);

And here.

> +
>   /* There's a small chance the reset task will have been re-queued,
>* during stop, make sure it's gone before we free the structure.
>*/
> 

-- 
Florian


Re: [PATCH] net: ftgmac100: Request clock and set speed

2017-10-09 Thread Florian Fainelli


On 10/09/2017 09:49 PM, Joel Stanley wrote:
> According to the ASPEED datasheet, gigabit speeds require a clock of
> 100MHz or higher. Other speeds require 25MHz or higher.
> 
> Signed-off-by: Joel Stanley 
> ---

> @@ -161,6 +170,9 @@ static int ftgmac100_reset_and_config_mac(struct 
> ftgmac100 *priv)
>   break;
>   }
>  
> + if (freq && priv->clk)
> + clk_set_rate(priv->clk, freq);

Checking for priv->clk should not be necessary all public clk APIs can
deal with a NULL clock pointer.

> +
>   /* (Re)initialize the queue pointers */
>   priv->rx_pointer = 0;
>   priv->tx_clean_pointer = 0;
> @@ -1775,6 +1787,13 @@ static int ftgmac100_probe(struct platform_device 
> *pdev)
>   priv->dev = >dev;
>   INIT_WORK(>reset_task, ftgmac100_reset_task);
>  
> + /* Enable clock if present */
> + priv->clk = devm_clk_get(>dev, NULL);
> + if (!IS_ERR(priv->clk))
> + clk_prepare_enable(priv->clk);
> + else
> + priv->clk = NULL;

Same here.

> +
>   /* map io memory */
>   priv->res = request_mem_region(res->start, resource_size(res),
>  dev_name(>dev));
> @@ -1883,6 +1902,9 @@ static int ftgmac100_remove(struct platform_device 
> *pdev)
>  
>   unregister_netdev(netdev);
>  
> + if (priv->clk)
> + clk_disable_unprepare(priv->clk);

And here.

> +
>   /* There's a small chance the reset task will have been re-queued,
>* during stop, make sure it's gone before we free the structure.
>*/
> 

-- 
Florian


Re: [PATCH v5 16/16] perf util: use correct IP mapping to find srcline for hist entry

2017-10-09 Thread Namhyung Kim
Hi Milian,

On Mon, Oct 09, 2017 at 10:33:10PM +0200, Milian Wolff wrote:
> When inline frame resolution is disabled, a bogus srcline is obtained
> for hist entries:
> 
> ~
> $ perf report -s sym,srcline --no-inline --stdio -g none
> 95.21% 0.00%  [.] __libc_start_main   
> 
> __libc_start_main+18446603358170398953
> 95.21% 0.00%  [.] _start  
> 
> _start+18446650082411225129
> 46.67% 0.00%  [.] main
> 
> main+18446650082411225208
> 38.75% 0.00%  [.] hypot   
> 
> hypot+18446603358164312084
> 23.75% 0.00%  [.] main
> 
> main+18446650082411225151
> 20.83%20.83%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.h:143
> 18.12% 0.00%  [.] main
> 
> main+18446650082411225165
> 13.12%13.12%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.tcc:3330
>  4.17% 4.17%  [.] __hypot_finite  
> 
> __hypot_finite+163
>  4.17% 4.17%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.tcc:
>  4.17% 0.00%  [.] __hypot_finite  
> 
> __hypot_finite+18446603358164312227
>  4.17% 0.00%  [.] std::generate_canonical std::linear_congruential_engine >  
> std::generate_canonical  2.92% 0.00%  [.] std::generate_canonical std::linear_congruential_engine >  
> std::generate_canonical  2.50% 2.50%  [.] __hypot_finite  
> 
> __hypot_finite+11
>  2.50% 2.50%  [.] __hypot_finite  
> 
> __hypot_finite+24
>  2.50% 0.00%  [.] __hypot_finite  
> 
> __hypot_finite+18446603358164312075
>  2.50% 0.00%  [.] __hypot_finite  
> 
> __hypot_finite+18446603358164312088
> ~
> 
> Note how we get very large offsets to main and cannot see any srcline
> from one of the complex or random headers, even though the instruction
> pointers actually lie in code inlined from there.
> 
> This patch fixes the mapping to use map__objdump_2mem instead of
> map__objdump_2mem in hist_entry__get_srcline. This fixes the srcline
> values for me when inline resolution is disabled:
> 
> ~
> $ perf report -s sym,srcline --no-inline --stdio -g none
> 95.21% 0.00%  [.] __libc_start_main   
> 
> __libc_start_main+233
> 95.21% 0.00%  [.] _start  
> _start+41
> 46.88% 0.00%  [.] main
> complex:589
> 43.96% 0.00%  [.] main
> random.h:185
> 38.75% 0.00%  [.] hypot   
> hypot+20
> 20.83% 0.00%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.h:143
> 13.12% 0.00%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.tcc:3330
>  4.17% 4.17%  [.] __hypot_finite  
> 
> __hypot_finite+140715545239715
>  4.17% 4.17%  [.] std::generate_canonical std::linear_congruential_engine >  
> std::generate_canonical  4.17% 0.00%  [.] __hypot_finite  
>

Re: [PATCH v5 16/16] perf util: use correct IP mapping to find srcline for hist entry

2017-10-09 Thread Namhyung Kim
Hi Milian,

On Mon, Oct 09, 2017 at 10:33:10PM +0200, Milian Wolff wrote:
> When inline frame resolution is disabled, a bogus srcline is obtained
> for hist entries:
> 
> ~
> $ perf report -s sym,srcline --no-inline --stdio -g none
> 95.21% 0.00%  [.] __libc_start_main   
> 
> __libc_start_main+18446603358170398953
> 95.21% 0.00%  [.] _start  
> 
> _start+18446650082411225129
> 46.67% 0.00%  [.] main
> 
> main+18446650082411225208
> 38.75% 0.00%  [.] hypot   
> 
> hypot+18446603358164312084
> 23.75% 0.00%  [.] main
> 
> main+18446650082411225151
> 20.83%20.83%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.h:143
> 18.12% 0.00%  [.] main
> 
> main+18446650082411225165
> 13.12%13.12%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.tcc:3330
>  4.17% 4.17%  [.] __hypot_finite  
> 
> __hypot_finite+163
>  4.17% 4.17%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.tcc:
>  4.17% 0.00%  [.] __hypot_finite  
> 
> __hypot_finite+18446603358164312227
>  4.17% 0.00%  [.] std::generate_canonical std::linear_congruential_engine >  
> std::generate_canonical  2.92% 0.00%  [.] std::generate_canonical std::linear_congruential_engine >  
> std::generate_canonical  2.50% 2.50%  [.] __hypot_finite  
> 
> __hypot_finite+11
>  2.50% 2.50%  [.] __hypot_finite  
> 
> __hypot_finite+24
>  2.50% 0.00%  [.] __hypot_finite  
> 
> __hypot_finite+18446603358164312075
>  2.50% 0.00%  [.] __hypot_finite  
> 
> __hypot_finite+18446603358164312088
> ~
> 
> Note how we get very large offsets to main and cannot see any srcline
> from one of the complex or random headers, even though the instruction
> pointers actually lie in code inlined from there.
> 
> This patch fixes the mapping to use map__objdump_2mem instead of
> map__objdump_2mem in hist_entry__get_srcline. This fixes the srcline
> values for me when inline resolution is disabled:
> 
> ~
> $ perf report -s sym,srcline --no-inline --stdio -g none
> 95.21% 0.00%  [.] __libc_start_main   
> 
> __libc_start_main+233
> 95.21% 0.00%  [.] _start  
> _start+41
> 46.88% 0.00%  [.] main
> complex:589
> 43.96% 0.00%  [.] main
> random.h:185
> 38.75% 0.00%  [.] hypot   
> hypot+20
> 20.83% 0.00%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.h:143
> 13.12% 0.00%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.tcc:3330
>  4.17% 4.17%  [.] __hypot_finite  
> 
> __hypot_finite+140715545239715
>  4.17% 4.17%  [.] std::generate_canonical std::linear_congruential_engine >  
> std::generate_canonical  4.17% 0.00%  [.] __hypot_finite  
> 
> __hypot_finite+163
>  4.17% 0.00%  [.] std::generate_canonical std::linear_congruential_engine >  
> random.tcc:
>  2.92% 2.92%  [.] 

[PATCH] net: ftgmac100: Request clock and set speed

2017-10-09 Thread Joel Stanley
According to the ASPEED datasheet, gigabit speeds require a clock of
100MHz or higher. Other speeds require 25MHz or higher.

Signed-off-by: Joel Stanley 
---
 drivers/net/ethernet/faraday/ftgmac100.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index 9ed8e4b81530..870ebd857978 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -21,6 +21,7 @@
 
 #define pr_fmt(fmt)KBUILD_MODNAME ": " fmt
 
+#include 
 #include 
 #include 
 #include 
@@ -59,6 +60,9 @@
 /* Min number of tx ring entries before stopping queue */
 #define TX_THRESHOLD   (MAX_SKB_FRAGS + 1)
 
+#define FTGMAC_100MHZ  1
+#define FTGMAC_25MHZ   2500
+
 struct ftgmac100 {
/* Registers */
struct resource *res;
@@ -96,6 +100,7 @@ struct ftgmac100 {
struct napi_struct napi;
struct work_struct reset_task;
struct mii_bus *mii_bus;
+   struct clk *clk;
 
/* Link management */
int cur_speed;
@@ -142,18 +147,22 @@ static int ftgmac100_reset_mac(struct ftgmac100 *priv, 
u32 maccr)
 static int ftgmac100_reset_and_config_mac(struct ftgmac100 *priv)
 {
u32 maccr = 0;
+   int freq = 0;
 
switch (priv->cur_speed) {
case SPEED_10:
case 0: /* no link */
+   freq = FTGMAC_25MHZ;
break;
 
case SPEED_100:
maccr |= FTGMAC100_MACCR_FAST_MODE;
+   freq = FTGMAC_25MHZ;
break;
 
case SPEED_1000:
maccr |= FTGMAC100_MACCR_GIGA_MODE;
+   freq = FTGMAC_100MHZ;
break;
default:
netdev_err(priv->netdev, "Unknown speed %d !\n",
@@ -161,6 +170,9 @@ static int ftgmac100_reset_and_config_mac(struct ftgmac100 
*priv)
break;
}
 
+   if (freq && priv->clk)
+   clk_set_rate(priv->clk, freq);
+
/* (Re)initialize the queue pointers */
priv->rx_pointer = 0;
priv->tx_clean_pointer = 0;
@@ -1775,6 +1787,13 @@ static int ftgmac100_probe(struct platform_device *pdev)
priv->dev = >dev;
INIT_WORK(>reset_task, ftgmac100_reset_task);
 
+   /* Enable clock if present */
+   priv->clk = devm_clk_get(>dev, NULL);
+   if (!IS_ERR(priv->clk))
+   clk_prepare_enable(priv->clk);
+   else
+   priv->clk = NULL;
+
/* map io memory */
priv->res = request_mem_region(res->start, resource_size(res),
   dev_name(>dev));
@@ -1883,6 +1902,9 @@ static int ftgmac100_remove(struct platform_device *pdev)
 
unregister_netdev(netdev);
 
+   if (priv->clk)
+   clk_disable_unprepare(priv->clk);
+
/* There's a small chance the reset task will have been re-queued,
 * during stop, make sure it's gone before we free the structure.
 */
-- 
2.14.1



[PATCH] net: ftgmac100: Request clock and set speed

2017-10-09 Thread Joel Stanley
According to the ASPEED datasheet, gigabit speeds require a clock of
100MHz or higher. Other speeds require 25MHz or higher.

Signed-off-by: Joel Stanley 
---
 drivers/net/ethernet/faraday/ftgmac100.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
index 9ed8e4b81530..870ebd857978 100644
--- a/drivers/net/ethernet/faraday/ftgmac100.c
+++ b/drivers/net/ethernet/faraday/ftgmac100.c
@@ -21,6 +21,7 @@
 
 #define pr_fmt(fmt)KBUILD_MODNAME ": " fmt
 
+#include 
 #include 
 #include 
 #include 
@@ -59,6 +60,9 @@
 /* Min number of tx ring entries before stopping queue */
 #define TX_THRESHOLD   (MAX_SKB_FRAGS + 1)
 
+#define FTGMAC_100MHZ  1
+#define FTGMAC_25MHZ   2500
+
 struct ftgmac100 {
/* Registers */
struct resource *res;
@@ -96,6 +100,7 @@ struct ftgmac100 {
struct napi_struct napi;
struct work_struct reset_task;
struct mii_bus *mii_bus;
+   struct clk *clk;
 
/* Link management */
int cur_speed;
@@ -142,18 +147,22 @@ static int ftgmac100_reset_mac(struct ftgmac100 *priv, 
u32 maccr)
 static int ftgmac100_reset_and_config_mac(struct ftgmac100 *priv)
 {
u32 maccr = 0;
+   int freq = 0;
 
switch (priv->cur_speed) {
case SPEED_10:
case 0: /* no link */
+   freq = FTGMAC_25MHZ;
break;
 
case SPEED_100:
maccr |= FTGMAC100_MACCR_FAST_MODE;
+   freq = FTGMAC_25MHZ;
break;
 
case SPEED_1000:
maccr |= FTGMAC100_MACCR_GIGA_MODE;
+   freq = FTGMAC_100MHZ;
break;
default:
netdev_err(priv->netdev, "Unknown speed %d !\n",
@@ -161,6 +170,9 @@ static int ftgmac100_reset_and_config_mac(struct ftgmac100 
*priv)
break;
}
 
+   if (freq && priv->clk)
+   clk_set_rate(priv->clk, freq);
+
/* (Re)initialize the queue pointers */
priv->rx_pointer = 0;
priv->tx_clean_pointer = 0;
@@ -1775,6 +1787,13 @@ static int ftgmac100_probe(struct platform_device *pdev)
priv->dev = >dev;
INIT_WORK(>reset_task, ftgmac100_reset_task);
 
+   /* Enable clock if present */
+   priv->clk = devm_clk_get(>dev, NULL);
+   if (!IS_ERR(priv->clk))
+   clk_prepare_enable(priv->clk);
+   else
+   priv->clk = NULL;
+
/* map io memory */
priv->res = request_mem_region(res->start, resource_size(res),
   dev_name(>dev));
@@ -1883,6 +1902,9 @@ static int ftgmac100_remove(struct platform_device *pdev)
 
unregister_netdev(netdev);
 
+   if (priv->clk)
+   clk_disable_unprepare(priv->clk);
+
/* There's a small chance the reset task will have been re-queued,
 * during stop, make sure it's gone before we free the structure.
 */
-- 
2.14.1



[PATCH] vmbus: hvsock: add proper sync for vmbus_hvsock_device_unregister()

2017-10-09 Thread Dexuan Cui

Without the patch, vmbus_hvsock_device_unregister() can destroy the device
prematurely when close() is called, and can cause NULl dereferencing or
potential data loss (the last portion of the data stream may be dropped
prematurely).

Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
---

The patch is rebased on today's char-misc tree's char-misc-linus branch.
Please consider it for v4.14.

 drivers/hv/channel_mgmt.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 018d2e0..379b0df 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -937,7 +937,10 @@ void vmbus_hvsock_device_unregister(struct vmbus_channel 
*channel)
 {
BUG_ON(!is_hvsock_channel(channel));
 
-   channel->rescind = true;
+   /* We always get a rescind msg when a connection is closed. */
+   while (!READ_ONCE(channel->probe_done) || !READ_ONCE(channel->rescind))
+   msleep(1);
+
vmbus_device_unregister(channel->device_obj);
 }
 EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
-- 
2.7.4



[PATCH] vmbus: hvsock: add proper sync for vmbus_hvsock_device_unregister()

2017-10-09 Thread Dexuan Cui

Without the patch, vmbus_hvsock_device_unregister() can destroy the device
prematurely when close() is called, and can cause NULl dereferencing or
potential data loss (the last portion of the data stream may be dropped
prematurely).

Signed-off-by: Dexuan Cui 
Cc: K. Y. Srinivasan 
Cc: Haiyang Zhang 
Cc: Stephen Hemminger 
---

The patch is rebased on today's char-misc tree's char-misc-linus branch.
Please consider it for v4.14.

 drivers/hv/channel_mgmt.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 018d2e0..379b0df 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -937,7 +937,10 @@ void vmbus_hvsock_device_unregister(struct vmbus_channel 
*channel)
 {
BUG_ON(!is_hvsock_channel(channel));
 
-   channel->rescind = true;
+   /* We always get a rescind msg when a connection is closed. */
+   while (!READ_ONCE(channel->probe_done) || !READ_ONCE(channel->rescind))
+   msleep(1);
+
vmbus_device_unregister(channel->device_obj);
 }
 EXPORT_SYMBOL_GPL(vmbus_hvsock_device_unregister);
-- 
2.7.4



[PATCH] i2c: aspeed: Deassert reset in probe

2017-10-09 Thread Joel Stanley
In order to use i2c from a cold boot, the i2c peripheral must be taken
out of reset. We request a shared reset controller each time a bus
driver is loaded, as the reset is shared between the 14 i2c buses.

On remove the reset is asserted, which only touches the hardware once
the last i2c bus is removed.

The request is optional, so if a device tree does not specify a reset
controller (or the driver is not built in), the driver continues to
probe.

Signed-off-by: Joel Stanley 
---
 drivers/i2c/busses/i2c-aspeed.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 284f8670dbeb..ad06f902f90f 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -28,6 +28,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /* I2C Register */
 #define ASPEED_I2C_FUN_CTRL_REG0x00
@@ -132,6 +134,7 @@ struct aspeed_i2c_bus {
struct i2c_adapter  adap;
struct device   *dev;
void __iomem*base;
+   struct reset_control*rst;
/* Synchronizes I/O mem access to base. */
spinlock_t  lock;
struct completion   cmd_complete;
@@ -847,6 +850,9 @@ static int aspeed_i2c_probe_bus(struct platform_device 
*pdev)
/* We just need the clock rate, we don't actually use the clk object. */
devm_clk_put(>dev, parent_clk);
 
+   bus->rst = devm_reset_control_get_optional_shared(>dev, NULL);
+   reset_control_deassert(bus->rst);
+
ret = of_property_read_u32(pdev->dev.of_node,
   "bus-frequency", >bus_frequency);
if (ret < 0) {
@@ -919,6 +925,8 @@ static int aspeed_i2c_remove_bus(struct platform_device 
*pdev)
 
i2c_del_adapter(>adap);
 
+   reset_control_assert(bus->rst);
+
return 0;
 }
 
-- 
2.14.1



[PATCH] i2c: aspeed: Deassert reset in probe

2017-10-09 Thread Joel Stanley
In order to use i2c from a cold boot, the i2c peripheral must be taken
out of reset. We request a shared reset controller each time a bus
driver is loaded, as the reset is shared between the 14 i2c buses.

On remove the reset is asserted, which only touches the hardware once
the last i2c bus is removed.

The request is optional, so if a device tree does not specify a reset
controller (or the driver is not built in), the driver continues to
probe.

Signed-off-by: Joel Stanley 
---
 drivers/i2c/busses/i2c-aspeed.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 284f8670dbeb..ad06f902f90f 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -28,6 +28,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /* I2C Register */
 #define ASPEED_I2C_FUN_CTRL_REG0x00
@@ -132,6 +134,7 @@ struct aspeed_i2c_bus {
struct i2c_adapter  adap;
struct device   *dev;
void __iomem*base;
+   struct reset_control*rst;
/* Synchronizes I/O mem access to base. */
spinlock_t  lock;
struct completion   cmd_complete;
@@ -847,6 +850,9 @@ static int aspeed_i2c_probe_bus(struct platform_device 
*pdev)
/* We just need the clock rate, we don't actually use the clk object. */
devm_clk_put(>dev, parent_clk);
 
+   bus->rst = devm_reset_control_get_optional_shared(>dev, NULL);
+   reset_control_deassert(bus->rst);
+
ret = of_property_read_u32(pdev->dev.of_node,
   "bus-frequency", >bus_frequency);
if (ret < 0) {
@@ -919,6 +925,8 @@ static int aspeed_i2c_remove_bus(struct platform_device 
*pdev)
 
i2c_del_adapter(>adap);
 
+   reset_control_assert(bus->rst);
+
return 0;
 }
 
-- 
2.14.1



Re: ce07a9415f ("locking/lockdep: Make check_prev_add() able to .."): BUG: unable to handle kernel NULL pointer dereference at 00000020

2017-10-09 Thread Byungchul Park
On Tue, Oct 03, 2017 at 11:32:37AM +0200, Ingo Molnar wrote:
> 
> Any progress with fixing this crash?
> 
> I'll have to revert this commit otherwise.

I am sorry for late. It was the biggest traditional holiday until
yesterday. I will reply it in another thread.

Thank you.

> Thanks,
> 
>   Ingo
> 
> * kernel test robot  wrote:
> 
> > Greetings,
> > 
> > 0day kernel testing robot got the below dmesg and the first bad commit is
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
> > 
> > commit ce07a9415f266e181a0a33033a5f7138760240a4
> > Author: Byungchul Park 
> > AuthorDate: Mon Aug 7 16:12:51 2017 +0900
> > Commit: Ingo Molnar 
> > CommitDate: Thu Aug 10 12:29:06 2017 +0200
> > 
> > locking/lockdep: Make check_prev_add() able to handle external 
> > stack_trace
> > 
> > Currently, a space for stack_trace is pinned in check_prev_add(), that
> > makes us not able to use external stack_trace. The simplest way to
> > achieve it is to pass an external stack_trace as an argument.
> > 
> > A more suitable solution is to pass a callback additionally along with
> > a stack_trace so that callers can decide the way to save or whether to
> > save. Actually crossrelease needs to do other than saving a stack_trace.
> > So pass a stack_trace and callback to handle it, to check_prev_add().
> > 
> > Signed-off-by: Byungchul Park 
> > Signed-off-by: Peter Zijlstra (Intel) 
> > Cc: Linus Torvalds 
> > Cc: Peter Zijlstra 
> > Cc: Thomas Gleixner 
> > Cc: a...@linux-foundation.org
> > Cc: boqun.f...@gmail.com
> > Cc: kernel-t...@lge.com
> > Cc: kir...@shutemov.name
> > Cc: npig...@gmail.com
> > Cc: wal...@google.com
> > Cc: wi...@infradead.org
> > Link: 
> > http://lkml.kernel.org/r/1502089981-21272-5-git-send-email-byungchul.p...@lge.com
> > Signed-off-by: Ingo Molnar 
> > 
> > 70911fdc95  locking/lockdep: Change the meaning of check_prev_add()'s 
> > return value
> > ce07a9415f  locking/lockdep: Make check_prev_add() able to handle external 
> > stack_trace
> > 74d83ec2b7  Merge tag 'platform-drivers-x86-v4.14-2' of 
> > git://git.infradead.org/linux-platform-drivers-x86
> > 1418b85217  Add linux-next specific files for 20170929
> > +---++++---+
> > |   | 70911fdc95 | 
> > ce07a9415f | 74d83ec2b7 | next-20170929 |
> > +---++++---+
> > | boot_successes| 516| 129  
> >   | 167| 479   |
> > | boot_failures | 0  | 6
> >   | 43 | 146   |
> > | BUG:unable_to_handle_kernel   | 0  | 6
> >   | 24 | 42|
> > | Oops:#[##]| 0  | 6
> >   | 24 | 42|
> > | EIP:iput  | 0  | 5
> >   ||   |
> > | Kernel_panic-not_syncing:Fatal_exception  | 0  | 6
> >   | 1  |   |
> > | EIP:do_raw_spin_trylock   | 0  | 1
> >   | 1  |   |
> > | WARNING:kernel_stack  | 0  | 0
> >   | 20 | 110   |
> > | EIP:update_stack_state| 0  | 0
> >   | 23 | 42|
> > | Kernel_panic-not_syncing:Fatal_exception_in_interrupt | 0  | 0
> >   | 23 | 42|
> > | invoked_oom-killer:gfp_mask=0x| 0  | 0
> >   | 0  | 16|
> > | Mem-Info  | 0  | 0
> >   | 0  | 16|
> > | EIP:clear_user| 0  | 0
> >   | 0  | 2 |
> > | EIP:copy_page_to_iter | 0  | 0
> >   | 0  | 1 |
> > +---++++---+
> > 
> > procd: Instance odhcpd::instance1 s in a crash loop 6 crashes, 0 seconds 
> > since last crash
> > procd: Instance uhttpd::instance1 s in a crash loop 6 crashes, 0 seconds 
> > since last crash
> > procd: Instance dnsmasq::instance1 s in a crash loop 6 crashes, 0 seconds 
> > since last crash
> > [  

Re: ce07a9415f ("locking/lockdep: Make check_prev_add() able to .."): BUG: unable to handle kernel NULL pointer dereference at 00000020

2017-10-09 Thread Byungchul Park
On Tue, Oct 03, 2017 at 11:32:37AM +0200, Ingo Molnar wrote:
> 
> Any progress with fixing this crash?
> 
> I'll have to revert this commit otherwise.

I am sorry for late. It was the biggest traditional holiday until
yesterday. I will reply it in another thread.

Thank you.

> Thanks,
> 
>   Ingo
> 
> * kernel test robot  wrote:
> 
> > Greetings,
> > 
> > 0day kernel testing robot got the below dmesg and the first bad commit is
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
> > 
> > commit ce07a9415f266e181a0a33033a5f7138760240a4
> > Author: Byungchul Park 
> > AuthorDate: Mon Aug 7 16:12:51 2017 +0900
> > Commit: Ingo Molnar 
> > CommitDate: Thu Aug 10 12:29:06 2017 +0200
> > 
> > locking/lockdep: Make check_prev_add() able to handle external 
> > stack_trace
> > 
> > Currently, a space for stack_trace is pinned in check_prev_add(), that
> > makes us not able to use external stack_trace. The simplest way to
> > achieve it is to pass an external stack_trace as an argument.
> > 
> > A more suitable solution is to pass a callback additionally along with
> > a stack_trace so that callers can decide the way to save or whether to
> > save. Actually crossrelease needs to do other than saving a stack_trace.
> > So pass a stack_trace and callback to handle it, to check_prev_add().
> > 
> > Signed-off-by: Byungchul Park 
> > Signed-off-by: Peter Zijlstra (Intel) 
> > Cc: Linus Torvalds 
> > Cc: Peter Zijlstra 
> > Cc: Thomas Gleixner 
> > Cc: a...@linux-foundation.org
> > Cc: boqun.f...@gmail.com
> > Cc: kernel-t...@lge.com
> > Cc: kir...@shutemov.name
> > Cc: npig...@gmail.com
> > Cc: wal...@google.com
> > Cc: wi...@infradead.org
> > Link: 
> > http://lkml.kernel.org/r/1502089981-21272-5-git-send-email-byungchul.p...@lge.com
> > Signed-off-by: Ingo Molnar 
> > 
> > 70911fdc95  locking/lockdep: Change the meaning of check_prev_add()'s 
> > return value
> > ce07a9415f  locking/lockdep: Make check_prev_add() able to handle external 
> > stack_trace
> > 74d83ec2b7  Merge tag 'platform-drivers-x86-v4.14-2' of 
> > git://git.infradead.org/linux-platform-drivers-x86
> > 1418b85217  Add linux-next specific files for 20170929
> > +---++++---+
> > |   | 70911fdc95 | 
> > ce07a9415f | 74d83ec2b7 | next-20170929 |
> > +---++++---+
> > | boot_successes| 516| 129  
> >   | 167| 479   |
> > | boot_failures | 0  | 6
> >   | 43 | 146   |
> > | BUG:unable_to_handle_kernel   | 0  | 6
> >   | 24 | 42|
> > | Oops:#[##]| 0  | 6
> >   | 24 | 42|
> > | EIP:iput  | 0  | 5
> >   ||   |
> > | Kernel_panic-not_syncing:Fatal_exception  | 0  | 6
> >   | 1  |   |
> > | EIP:do_raw_spin_trylock   | 0  | 1
> >   | 1  |   |
> > | WARNING:kernel_stack  | 0  | 0
> >   | 20 | 110   |
> > | EIP:update_stack_state| 0  | 0
> >   | 23 | 42|
> > | Kernel_panic-not_syncing:Fatal_exception_in_interrupt | 0  | 0
> >   | 23 | 42|
> > | invoked_oom-killer:gfp_mask=0x| 0  | 0
> >   | 0  | 16|
> > | Mem-Info  | 0  | 0
> >   | 0  | 16|
> > | EIP:clear_user| 0  | 0
> >   | 0  | 2 |
> > | EIP:copy_page_to_iter | 0  | 0
> >   | 0  | 1 |
> > +---++++---+
> > 
> > procd: Instance odhcpd::instance1 s in a crash loop 6 crashes, 0 seconds 
> > since last crash
> > procd: Instance uhttpd::instance1 s in a crash loop 6 crashes, 0 seconds 
> > since last crash
> > procd: Instance dnsmasq::instance1 s in a crash loop 6 crashes, 0 seconds 
> > since last crash
> > [  187.661000] Writes:  Total: 2  Max/Min: 0/0   Fail: 0 
> > procd: - shutdown -
> > [  220.353842] BUG: unable to handle kernel NULL pointer dereference at 
> > 0020
> > [  220.354946] IP: iput+0x544/0x650
> 

Re: [PATCH] thermal/intel_powerclamp: pr_err()/pr_info() strings should end with newlines

2017-10-09 Thread Joe Perches
On Mon, 2017-10-09 at 14:33 +0200, Daniel Lezcano wrote:
> On 09/10/2017 13:51, Arvind Yadav wrote:
> > pr_err()/pr_info() messages should end with a new-line to avoid
> > other messages being concatenated.
[]
> > diff --git a/drivers/thermal/intel_powerclamp.c 
> > b/drivers/thermal/intel_powerclamp.c
> > @@ -675,13 +675,13 @@ static int __init powerclamp_probe(void)
> >  {
> >  
> > if (!x86_match_cpu(intel_powerclamp_ids)) {
> > -   pr_err("CPU does not support MWAIT");
> > +   pr_err("CPU does not support MWAIT\n");

[etc...]

> Hi Arvind,
> 
> you are sending these fixes for all the drivers around. There is a way
> to fix this once and for all: use the coccinelle tools [1], add the
> script in the changelog with a big patchset and add the script in the
> coccinelle scripts directory [2].

That can't work as any printk without a newline termination
could be followed by a printk(KERN_CONT/pr_cont( in another
function.

All of these must be hand-verified.



Re: [PATCH] thermal/intel_powerclamp: pr_err()/pr_info() strings should end with newlines

2017-10-09 Thread Joe Perches
On Mon, 2017-10-09 at 14:33 +0200, Daniel Lezcano wrote:
> On 09/10/2017 13:51, Arvind Yadav wrote:
> > pr_err()/pr_info() messages should end with a new-line to avoid
> > other messages being concatenated.
[]
> > diff --git a/drivers/thermal/intel_powerclamp.c 
> > b/drivers/thermal/intel_powerclamp.c
> > @@ -675,13 +675,13 @@ static int __init powerclamp_probe(void)
> >  {
> >  
> > if (!x86_match_cpu(intel_powerclamp_ids)) {
> > -   pr_err("CPU does not support MWAIT");
> > +   pr_err("CPU does not support MWAIT\n");

[etc...]

> Hi Arvind,
> 
> you are sending these fixes for all the drivers around. There is a way
> to fix this once and for all: use the coccinelle tools [1], add the
> script in the changelog with a big patchset and add the script in the
> coccinelle scripts directory [2].

That can't work as any printk without a newline termination
could be followed by a printk(KERN_CONT/pr_cont( in another
function.

All of these must be hand-verified.



Re: [PATCH v2] Userfaultfd: Add description for UFFD_FEATURE_SIGBUS

2017-10-09 Thread Mike Rapoport
On Mon, Oct 09, 2017 at 03:45:51PM -0700, Prakash Sangappa wrote:
> Userfaultfd feature UFFD_FEATURE_SIGBUS was merged recently and should
> be available in Linux 4.14 release. This patch is for the manpage
> changes documenting this API.
> 
> Documents the following commit:
> 
> commit 2d6d6f5a09a96cc1fec7ed992b825e05f64cb50e
> Author: Prakash Sangappa 
> Date: Wed Sep 6 16:23:39 2017 -0700
> 
>  mm: userfaultfd: add feature to request for a signal delivery
> 
> Signed-off-by: Prakash Sangappa 

Reviewed-by: Mike Rapoport 

> ---
> v2: Incorporated review feedback changes.
> ---
>  man2/ioctl_userfaultfd.2 |  9 +
>  man2/userfaultfd.2   | 23 +++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/man2/ioctl_userfaultfd.2 b/man2/ioctl_userfaultfd.2
> index 60fd29b..32f0744 100644
> --- a/man2/ioctl_userfaultfd.2
> +++ b/man2/ioctl_userfaultfd.2
> @@ -196,6 +196,15 @@ with the
>  flag set,
>  .BR memfd_create (2),
>  and so on.
> +.TP
> +.B UFFD_FEATURE_SIGBUS
> +Since Linux 4.14, If this feature bit is set, no page-fault events
> +.B (UFFD_EVENT_PAGEFAULT)
> +will be delivered, instead a
> +.B SIGBUS
> +signal will be sent to the faulting process. Applications using this
> +feature will not require the use of a userfaultfd monitor for processing
> +memory accesses to the regions registered with userfaultfd.
>  .IP
>  The returned
>  .I ioctls
> diff --git a/man2/userfaultfd.2 b/man2/userfaultfd.2
> index 1741ee3..3c5b9c0 100644
> --- a/man2/userfaultfd.2
> +++ b/man2/userfaultfd.2
> @@ -172,6 +172,29 @@ or
>  .BR ioctl (2)
>  operations to resolve the page fault.
>  .PP
> +Starting from Linux 4.14, if application sets
> +.B UFFD_FEATURE_SIGBUS
> +feature bit using
> +.B UFFDIO_API
> +.BR ioctl (2),
> +no page fault notification will be forwarded to
> +the user-space, instead a
> +.B SIGBUS
> +signal is delivered to the faulting process. With this feature,
> +userfaultfd can be used for robustness purpose to simply catch
> +any access to areas within the registered address range that do not
> +have pages allocated, without having to listen to userfaultfd events.
> +No userfaultfd monitor will be required for dealing with such memory
> +accesses. For example, this feature can be useful for applications that
> +want to prevent the kernel from automatically allocating pages and filling
> +holes in sparse files when the hole is accessed thru mapped address.
> +.PP
> +The
> +.B UFFD_FEATURE_SIGBUS
> +feature is implicitly inherited through fork() if used in combination with
> +.BR UFFD_FEATURE_FORK .
> +
> +.PP
>  Details of the various
>  .BR ioctl (2)
>  operations can be found in
> -- 
> 2.7.4
> 

-- 
Sincerely yours,
Mike.



Re: [PATCH v2] Userfaultfd: Add description for UFFD_FEATURE_SIGBUS

2017-10-09 Thread Mike Rapoport
On Mon, Oct 09, 2017 at 03:45:51PM -0700, Prakash Sangappa wrote:
> Userfaultfd feature UFFD_FEATURE_SIGBUS was merged recently and should
> be available in Linux 4.14 release. This patch is for the manpage
> changes documenting this API.
> 
> Documents the following commit:
> 
> commit 2d6d6f5a09a96cc1fec7ed992b825e05f64cb50e
> Author: Prakash Sangappa 
> Date: Wed Sep 6 16:23:39 2017 -0700
> 
>  mm: userfaultfd: add feature to request for a signal delivery
> 
> Signed-off-by: Prakash Sangappa 

Reviewed-by: Mike Rapoport 

> ---
> v2: Incorporated review feedback changes.
> ---
>  man2/ioctl_userfaultfd.2 |  9 +
>  man2/userfaultfd.2   | 23 +++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/man2/ioctl_userfaultfd.2 b/man2/ioctl_userfaultfd.2
> index 60fd29b..32f0744 100644
> --- a/man2/ioctl_userfaultfd.2
> +++ b/man2/ioctl_userfaultfd.2
> @@ -196,6 +196,15 @@ with the
>  flag set,
>  .BR memfd_create (2),
>  and so on.
> +.TP
> +.B UFFD_FEATURE_SIGBUS
> +Since Linux 4.14, If this feature bit is set, no page-fault events
> +.B (UFFD_EVENT_PAGEFAULT)
> +will be delivered, instead a
> +.B SIGBUS
> +signal will be sent to the faulting process. Applications using this
> +feature will not require the use of a userfaultfd monitor for processing
> +memory accesses to the regions registered with userfaultfd.
>  .IP
>  The returned
>  .I ioctls
> diff --git a/man2/userfaultfd.2 b/man2/userfaultfd.2
> index 1741ee3..3c5b9c0 100644
> --- a/man2/userfaultfd.2
> +++ b/man2/userfaultfd.2
> @@ -172,6 +172,29 @@ or
>  .BR ioctl (2)
>  operations to resolve the page fault.
>  .PP
> +Starting from Linux 4.14, if application sets
> +.B UFFD_FEATURE_SIGBUS
> +feature bit using
> +.B UFFDIO_API
> +.BR ioctl (2),
> +no page fault notification will be forwarded to
> +the user-space, instead a
> +.B SIGBUS
> +signal is delivered to the faulting process. With this feature,
> +userfaultfd can be used for robustness purpose to simply catch
> +any access to areas within the registered address range that do not
> +have pages allocated, without having to listen to userfaultfd events.
> +No userfaultfd monitor will be required for dealing with such memory
> +accesses. For example, this feature can be useful for applications that
> +want to prevent the kernel from automatically allocating pages and filling
> +holes in sparse files when the hole is accessed thru mapped address.
> +.PP
> +The
> +.B UFFD_FEATURE_SIGBUS
> +feature is implicitly inherited through fork() if used in combination with
> +.BR UFFD_FEATURE_FORK .
> +
> +.PP
>  Details of the various
>  .BR ioctl (2)
>  operations can be found in
> -- 
> 2.7.4
> 

-- 
Sincerely yours,
Mike.



Re: [PATCH v3] HID: hid-multitouch: support fine-grain orientation reporting

2017-10-09 Thread Wei-Ning Huang
Hi Benjamin,

Thanks for the review. I've fixed according to your comments and sent
the v4 patch:
https://patchwork.kernel.org/patch/9995003/

Wei-Ning

On Fri, Oct 6, 2017 at 4:13 PM, Benjamin Tissoires
 wrote:
> Hi,
>
> On Oct 05 2017 or thereabouts, Jiri Kosina wrote:
>>
>> [ adding Benjamin to CC ]
>>
>> On Thu, 28 Sep 2017, Wei-Ning Huang wrote:
>>
>> > The current hid-multitouch driver only allow the report of two
>> > orientations, vertical and horizontal. We use the Azimuth orientation
>> > usage 0x3F under the Digitizer usage page to report orientation if the
>> > device supports it.
>> >
>> > Changelog:
>> >   v1 -> v2:
>> >- Fix commit message.
>> >- Remove resolution reporting for ABS_MT_ORIENTATION.
>> >   v2 -> v3:
>> >- Fix commit message.
>> >
>> > Signed-off-by: Wei-Ning Huang 
>> > Reviewed-by: Dmitry Torokhov 
>> > ---
>> >  drivers/hid/hid-multitouch.c | 35 +--
>> >  include/linux/hid.h  |  1 +
>> >  2 files changed, 34 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
>> > index 440b999304a5..f9801d1b1eae 100644
>> > --- a/drivers/hid/hid-multitouch.c
>> > +++ b/drivers/hid/hid-multitouch.c
>> > @@ -84,11 +84,12 @@ MODULE_LICENSE("GPL");
>> >  #define MT_IO_FLAGS_PENDING_SLOTS  2
>> >
>> >  struct mt_slot {
>> > -   __s32 x, y, cx, cy, p, w, h;
>> > +   __s32 x, y, cx, cy, p, w, h, a;
>> > __s32 contactid;/* the device ContactID assigned to this slot 
>> > */
>> > bool touch_state;   /* is the touch valid? */
>> > bool inrange_state; /* is the finger in proximity of the sensor? */
>> > bool confidence_state;  /* is the touch made by a finger? */
>> > +   bool has_azimuth;   /* the contact reports azimuth */
>> >  };
>> >
>> >  struct mt_class {
>> > @@ -591,6 +592,20 @@ static int mt_touch_input_mapping(struct hid_device 
>> > *hdev, struct hid_input *hi,
>> > td->cc_index = field->index;
>> > td->cc_value_index = usage->usage_index;
>> > return 1;
>> > +   case HID_DG_AZIMUTH:
>> > +   hid_map_usage(hi, usage, bit, max,
>> > +   EV_ABS, ABS_MT_ORIENTATION);
>> > +   /*
>> > +* Azimuth has the range of [0, MAX) representing a 
>> > full
>> > +* revolution. Set ABS_MT_ORIENTATION to a quarter of
>> > +* MAX according the definition of ABS_MT_ORIENTATION
>> > +*/
>> > +   input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
>> > +   0, field->logical_maximum / 4,
>
> Shouldn't this be "-field->logical_maximum / 4, field->logical_maximum / 4,"?
>
> Also, if HID_DG_HEIGHT is seen after HID_DG_AZIMUTH, it'll change the
> ABS_MT_ORIENTATION you just set here.
>
>> > +   cls->sn_move ?
>> > +   field->logical_maximum / cls->sn_move : 0, 0);
>> > +   mt_store_field(usage, td, hi);
>> > +   return 1;
>> > case HID_DG_CONTACTMAX:
>> > /* we don't set td->last_slot_field as contactcount and
>> >  * contact max are global to the report */
>> > @@ -683,6 +698,10 @@ static void mt_complete_slot(struct mt_device *td, 
>> > struct input_dev *input)
>> > int wide = (s->w > s->h);
>> > int major = max(s->w, s->h);
>> > int minor = min(s->w, s->h);
>> > +   int orientation = wide;
>> > +
>> > +   if (s->has_azimuth)
>> > +   orientation = s->a;
>> >
>> > /*
>> >  * divided by two to match visual scale of touch
>> > @@ -699,7 +718,8 @@ static void mt_complete_slot(struct mt_device *td, 
>> > struct input_dev *input)
>> > input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy);
>> > input_event(input, EV_ABS, ABS_MT_DISTANCE,
>> > !s->touch_state);
>> > -   input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
>> > +   input_event(input, EV_ABS, ABS_MT_ORIENTATION,
>> > +   orientation);
>> > input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
>> > input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
>> > input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
>> > @@ -789,6 +809,17 @@ static void mt_process_mt_event(struct hid_device 
>> > *hid, struct hid_field *field,
>> > break;
>> > case HID_DG_CONTACTCOUNT:
>> > break;
>> > +   case HID_DG_AZIMUTH:
>> > +   /*
>> > +* Azimuth is 

Re: [PATCH v3] HID: hid-multitouch: support fine-grain orientation reporting

2017-10-09 Thread Wei-Ning Huang
Hi Benjamin,

Thanks for the review. I've fixed according to your comments and sent
the v4 patch:
https://patchwork.kernel.org/patch/9995003/

Wei-Ning

On Fri, Oct 6, 2017 at 4:13 PM, Benjamin Tissoires
 wrote:
> Hi,
>
> On Oct 05 2017 or thereabouts, Jiri Kosina wrote:
>>
>> [ adding Benjamin to CC ]
>>
>> On Thu, 28 Sep 2017, Wei-Ning Huang wrote:
>>
>> > The current hid-multitouch driver only allow the report of two
>> > orientations, vertical and horizontal. We use the Azimuth orientation
>> > usage 0x3F under the Digitizer usage page to report orientation if the
>> > device supports it.
>> >
>> > Changelog:
>> >   v1 -> v2:
>> >- Fix commit message.
>> >- Remove resolution reporting for ABS_MT_ORIENTATION.
>> >   v2 -> v3:
>> >- Fix commit message.
>> >
>> > Signed-off-by: Wei-Ning Huang 
>> > Reviewed-by: Dmitry Torokhov 
>> > ---
>> >  drivers/hid/hid-multitouch.c | 35 +--
>> >  include/linux/hid.h  |  1 +
>> >  2 files changed, 34 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
>> > index 440b999304a5..f9801d1b1eae 100644
>> > --- a/drivers/hid/hid-multitouch.c
>> > +++ b/drivers/hid/hid-multitouch.c
>> > @@ -84,11 +84,12 @@ MODULE_LICENSE("GPL");
>> >  #define MT_IO_FLAGS_PENDING_SLOTS  2
>> >
>> >  struct mt_slot {
>> > -   __s32 x, y, cx, cy, p, w, h;
>> > +   __s32 x, y, cx, cy, p, w, h, a;
>> > __s32 contactid;/* the device ContactID assigned to this slot 
>> > */
>> > bool touch_state;   /* is the touch valid? */
>> > bool inrange_state; /* is the finger in proximity of the sensor? */
>> > bool confidence_state;  /* is the touch made by a finger? */
>> > +   bool has_azimuth;   /* the contact reports azimuth */
>> >  };
>> >
>> >  struct mt_class {
>> > @@ -591,6 +592,20 @@ static int mt_touch_input_mapping(struct hid_device 
>> > *hdev, struct hid_input *hi,
>> > td->cc_index = field->index;
>> > td->cc_value_index = usage->usage_index;
>> > return 1;
>> > +   case HID_DG_AZIMUTH:
>> > +   hid_map_usage(hi, usage, bit, max,
>> > +   EV_ABS, ABS_MT_ORIENTATION);
>> > +   /*
>> > +* Azimuth has the range of [0, MAX) representing a 
>> > full
>> > +* revolution. Set ABS_MT_ORIENTATION to a quarter of
>> > +* MAX according the definition of ABS_MT_ORIENTATION
>> > +*/
>> > +   input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
>> > +   0, field->logical_maximum / 4,
>
> Shouldn't this be "-field->logical_maximum / 4, field->logical_maximum / 4,"?
>
> Also, if HID_DG_HEIGHT is seen after HID_DG_AZIMUTH, it'll change the
> ABS_MT_ORIENTATION you just set here.
>
>> > +   cls->sn_move ?
>> > +   field->logical_maximum / cls->sn_move : 0, 0);
>> > +   mt_store_field(usage, td, hi);
>> > +   return 1;
>> > case HID_DG_CONTACTMAX:
>> > /* we don't set td->last_slot_field as contactcount and
>> >  * contact max are global to the report */
>> > @@ -683,6 +698,10 @@ static void mt_complete_slot(struct mt_device *td, 
>> > struct input_dev *input)
>> > int wide = (s->w > s->h);
>> > int major = max(s->w, s->h);
>> > int minor = min(s->w, s->h);
>> > +   int orientation = wide;
>> > +
>> > +   if (s->has_azimuth)
>> > +   orientation = s->a;
>> >
>> > /*
>> >  * divided by two to match visual scale of touch
>> > @@ -699,7 +718,8 @@ static void mt_complete_slot(struct mt_device *td, 
>> > struct input_dev *input)
>> > input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy);
>> > input_event(input, EV_ABS, ABS_MT_DISTANCE,
>> > !s->touch_state);
>> > -   input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
>> > +   input_event(input, EV_ABS, ABS_MT_ORIENTATION,
>> > +   orientation);
>> > input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
>> > input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
>> > input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
>> > @@ -789,6 +809,17 @@ static void mt_process_mt_event(struct hid_device 
>> > *hid, struct hid_field *field,
>> > break;
>> > case HID_DG_CONTACTCOUNT:
>> > break;
>> > +   case HID_DG_AZIMUTH:
>> > +   /*
>> > +* Azimuth is counter-clockwise and ranges from [0, 
>> > MAX)
>> > +* (a full 

Re: [PATCH 1/3] net/atm: Delete an error message for a failed memory allocation in five functions

2017-10-09 Thread Joe Perches
On Mon, 2017-10-09 at 22:49 +0200, SF Markus Elfring wrote:
> Omit extra messages for a memory allocation failure in these functions.
[]
> diff --git a/net/atm/mpc.c b/net/atm/mpc.c
> @@ -184,10 +184,8 @@ struct atm_mpoa_qos *atm_mpoa_add_qos(__be32 dst_ip, 
> struct atm_qos *qos)
>   }
>  
>   entry = kmalloc(sizeof(struct atm_mpoa_qos), GFP_KERNEL);
> - if (entry == NULL) {
> - pr_info("mpoa: out of memory\n");
> + if (!entry)

Unspecified change.  Make sure your changelog is comprehensive.

>   return entry;
> - }

 
>   entry->ipaddr = dst_ip;
>   entry->qos = *qos;
> @@ -473,10 +471,8 @@ static const uint8_t *copy_macs(struct mpoa_client *mpc,
>   kfree(mpc->mps_macs);
>   mpc->number_of_mps_macs = 0;
>   mpc->mps_macs = kmalloc(num_macs * ETH_ALEN, GFP_KERNEL);
> - if (mpc->mps_macs == NULL) {
> - pr_info("(%s) out of mem\n", mpc->dev->name);
> + if (!mpc->mps_macs)
>   return NULL;

etc...



Re: [PATCH 1/3] net/atm: Delete an error message for a failed memory allocation in five functions

2017-10-09 Thread Joe Perches
On Mon, 2017-10-09 at 22:49 +0200, SF Markus Elfring wrote:
> Omit extra messages for a memory allocation failure in these functions.
[]
> diff --git a/net/atm/mpc.c b/net/atm/mpc.c
> @@ -184,10 +184,8 @@ struct atm_mpoa_qos *atm_mpoa_add_qos(__be32 dst_ip, 
> struct atm_qos *qos)
>   }
>  
>   entry = kmalloc(sizeof(struct atm_mpoa_qos), GFP_KERNEL);
> - if (entry == NULL) {
> - pr_info("mpoa: out of memory\n");
> + if (!entry)

Unspecified change.  Make sure your changelog is comprehensive.

>   return entry;
> - }

 
>   entry->ipaddr = dst_ip;
>   entry->qos = *qos;
> @@ -473,10 +471,8 @@ static const uint8_t *copy_macs(struct mpoa_client *mpc,
>   kfree(mpc->mps_macs);
>   mpc->number_of_mps_macs = 0;
>   mpc->mps_macs = kmalloc(num_macs * ETH_ALEN, GFP_KERNEL);
> - if (mpc->mps_macs == NULL) {
> - pr_info("(%s) out of mem\n", mpc->dev->name);
> + if (!mpc->mps_macs)
>   return NULL;

etc...



[PATCH v4] HID: hid-multitouch: support fine-grain orientation reporting

2017-10-09 Thread Wei-Ning Huang
From: Wei-Ning Huang 

The current hid-multitouch driver only allow the report of two
orientations, vertical and horizontal. We use the Azimuth orientation
usage 0x3F under the Digitizer usage page to report orientation if the
device supports it.

Changelog:
  v1 -> v2:
   - Fix commit message.
   - Remove resolution reporting for ABS_MT_ORIENTATION.
  v2 -> v3:
   - Fix commit message.
  v3 -> v4:
   - Fix ABS_MT_ORIENTATION ABS param range.
   - Don't set ABS_MT_ORIENTATION in ABS_DG_HEIGHT when it is already
 set by ABS_DG_AZIMUTH.

Signed-off-by: Wei-Ning Huang 
Reviewed-by: Dmitry Torokhov 
---
 drivers/hid/hid-multitouch.c | 52 
 include/linux/hid.h  |  1 +
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 440b999304a5..3317dae64ef7 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -84,11 +84,12 @@ MODULE_LICENSE("GPL");
 #define MT_IO_FLAGS_PENDING_SLOTS  2
 
 struct mt_slot {
-   __s32 x, y, cx, cy, p, w, h;
+   __s32 x, y, cx, cy, p, w, h, a;
__s32 contactid;/* the device ContactID assigned to this slot */
bool touch_state;   /* is the touch valid? */
bool inrange_state; /* is the finger in proximity of the sensor? */
bool confidence_state;  /* is the touch made by a finger? */
+   bool has_azimuth;   /* the contact reports azimuth */
 };
 
 struct mt_class {
@@ -571,8 +572,15 @@ static int mt_touch_input_mapping(struct hid_device *hdev, 
struct hid_input *hi,
if (!(cls->quirks & MT_QUIRK_NO_AREA)) {
set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
cls->sn_height);
-   input_set_abs_params(hi->input,
-   ABS_MT_ORIENTATION, 0, 1, 0, 0);
+
+   /*
+* Only set ABS_MT_ORIENTATION if it is not
+* already set by the HID_DG_AZIMUTH usage.
+*/
+   if (!test_bit(ABS_MT_ORIENTATION,
+   hi->input->absbit))
+   input_set_abs_params(hi->input,
+   ABS_MT_ORIENTATION, 0, 1, 0, 0);
}
mt_store_field(usage, td, hi);
return 1;
@@ -591,6 +599,21 @@ static int mt_touch_input_mapping(struct hid_device *hdev, 
struct hid_input *hi,
td->cc_index = field->index;
td->cc_value_index = usage->usage_index;
return 1;
+   case HID_DG_AZIMUTH:
+   hid_map_usage(hi, usage, bit, max,
+   EV_ABS, ABS_MT_ORIENTATION);
+   /*
+* Azimuth has the range of [0, MAX) representing a full
+* revolution. Set ABS_MT_ORIENTATION to a quarter of
+* MAX according the definition of ABS_MT_ORIENTATION
+*/
+   input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
+   -field->logical_maximum / 4,
+   field->logical_maximum / 4,
+   cls->sn_move ?
+   field->logical_maximum / cls->sn_move : 0, 0);
+   mt_store_field(usage, td, hi);
+   return 1;
case HID_DG_CONTACTMAX:
/* we don't set td->last_slot_field as contactcount and
 * contact max are global to the report */
@@ -683,6 +706,10 @@ static void mt_complete_slot(struct mt_device *td, struct 
input_dev *input)
int wide = (s->w > s->h);
int major = max(s->w, s->h);
int minor = min(s->w, s->h);
+   int orientation = wide;
+
+   if (s->has_azimuth)
+   orientation = s->a;
 
/*
 * divided by two to match visual scale of touch
@@ -699,7 +726,8 @@ static void mt_complete_slot(struct mt_device *td, struct 
input_dev *input)
input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy);
input_event(input, EV_ABS, ABS_MT_DISTANCE,
!s->touch_state);
-   input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
+   input_event(input, EV_ABS, ABS_MT_ORIENTATION,
+   orientation);
input_event(input, EV_ABS, 

[PATCH v4] HID: hid-multitouch: support fine-grain orientation reporting

2017-10-09 Thread Wei-Ning Huang
From: Wei-Ning Huang 

The current hid-multitouch driver only allow the report of two
orientations, vertical and horizontal. We use the Azimuth orientation
usage 0x3F under the Digitizer usage page to report orientation if the
device supports it.

Changelog:
  v1 -> v2:
   - Fix commit message.
   - Remove resolution reporting for ABS_MT_ORIENTATION.
  v2 -> v3:
   - Fix commit message.
  v3 -> v4:
   - Fix ABS_MT_ORIENTATION ABS param range.
   - Don't set ABS_MT_ORIENTATION in ABS_DG_HEIGHT when it is already
 set by ABS_DG_AZIMUTH.

Signed-off-by: Wei-Ning Huang 
Reviewed-by: Dmitry Torokhov 
---
 drivers/hid/hid-multitouch.c | 52 
 include/linux/hid.h  |  1 +
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 440b999304a5..3317dae64ef7 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -84,11 +84,12 @@ MODULE_LICENSE("GPL");
 #define MT_IO_FLAGS_PENDING_SLOTS  2
 
 struct mt_slot {
-   __s32 x, y, cx, cy, p, w, h;
+   __s32 x, y, cx, cy, p, w, h, a;
__s32 contactid;/* the device ContactID assigned to this slot */
bool touch_state;   /* is the touch valid? */
bool inrange_state; /* is the finger in proximity of the sensor? */
bool confidence_state;  /* is the touch made by a finger? */
+   bool has_azimuth;   /* the contact reports azimuth */
 };
 
 struct mt_class {
@@ -571,8 +572,15 @@ static int mt_touch_input_mapping(struct hid_device *hdev, 
struct hid_input *hi,
if (!(cls->quirks & MT_QUIRK_NO_AREA)) {
set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
cls->sn_height);
-   input_set_abs_params(hi->input,
-   ABS_MT_ORIENTATION, 0, 1, 0, 0);
+
+   /*
+* Only set ABS_MT_ORIENTATION if it is not
+* already set by the HID_DG_AZIMUTH usage.
+*/
+   if (!test_bit(ABS_MT_ORIENTATION,
+   hi->input->absbit))
+   input_set_abs_params(hi->input,
+   ABS_MT_ORIENTATION, 0, 1, 0, 0);
}
mt_store_field(usage, td, hi);
return 1;
@@ -591,6 +599,21 @@ static int mt_touch_input_mapping(struct hid_device *hdev, 
struct hid_input *hi,
td->cc_index = field->index;
td->cc_value_index = usage->usage_index;
return 1;
+   case HID_DG_AZIMUTH:
+   hid_map_usage(hi, usage, bit, max,
+   EV_ABS, ABS_MT_ORIENTATION);
+   /*
+* Azimuth has the range of [0, MAX) representing a full
+* revolution. Set ABS_MT_ORIENTATION to a quarter of
+* MAX according the definition of ABS_MT_ORIENTATION
+*/
+   input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
+   -field->logical_maximum / 4,
+   field->logical_maximum / 4,
+   cls->sn_move ?
+   field->logical_maximum / cls->sn_move : 0, 0);
+   mt_store_field(usage, td, hi);
+   return 1;
case HID_DG_CONTACTMAX:
/* we don't set td->last_slot_field as contactcount and
 * contact max are global to the report */
@@ -683,6 +706,10 @@ static void mt_complete_slot(struct mt_device *td, struct 
input_dev *input)
int wide = (s->w > s->h);
int major = max(s->w, s->h);
int minor = min(s->w, s->h);
+   int orientation = wide;
+
+   if (s->has_azimuth)
+   orientation = s->a;
 
/*
 * divided by two to match visual scale of touch
@@ -699,7 +726,8 @@ static void mt_complete_slot(struct mt_device *td, struct 
input_dev *input)
input_event(input, EV_ABS, ABS_MT_TOOL_Y, s->cy);
input_event(input, EV_ABS, ABS_MT_DISTANCE,
!s->touch_state);
-   input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
+   input_event(input, EV_ABS, ABS_MT_ORIENTATION,
+   orientation);
input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
input_event(input, 

Re: [PATCH v6 3/3] eeprom: at24: enable runtime pm support

2017-10-09 Thread Tomasz Figa
On Tue, Oct 3, 2017 at 11:23 PM, sakari.ai...@iki.fi
 wrote:
> On Wed, Sep 20, 2017 at 11:45:20AM +0300, sakari.ai...@iki.fi wrote:
>> > >> @@ -743,11 +770,17 @@ static int at24_probe(struct i2c_client *client, 
>> > >> const
>> > >> struct i2c_device_id *id)
>> > >>
>> > >>   i2c_set_clientdata(client, at24);
>> > >>
>> > >> + /* enable runtime pm */
>> > >> + pm_runtime_get_noresume(>dev);
>> > >> + pm_runtime_set_active(>dev);
>> > >> + pm_runtime_enable(>dev);
>> >
>> > Do we need this get_noresume/set_active dance? I remember it was for
>> > some reason needed for PCI devices, but I don't see why for I2C
>> > anything else than just pm_runtime_enable() would be necessary.
>>
>> You specifically do not need (all) this for PCI devices, but AFAIU for I涎
>> devices you do. The runtime PM status of a device is disabled by default
>> and the use count is zero, but on ACPI based systems the device is still
>> powered on.
>>
>> >
>> > Also, we enable runtime PM, but we don't provide any callbacks. If
>> > there is no callback in any level of the hierarchy, NULL would be
>> > returned in [3], making [2] return -ENOSYS and [1] fail. The behavior
>> > depends on subsystem and whether the device is attached to a
>> > pm_domain. In our particular case I'd guess the device would be in an
>> > ACPI pm_domain and that would work, but the driver is generic and must
>> > work in any cases.
>>
>> Agreed.
>
> I looked at the code and what actually happens here is the runtime_suspend
> and runtime_resume callbacks aren't set is that the first pm_runtime_put()
> call itself succeeds because checking the the runtime_suspend callback will
> be done in the work queue function. This leaves the device in RPM_ACTIVE
> state, which I don't think is a problem since the driver did not have
> explicit functions to control the device power state.
>
> Further pm_runtime_put() and pm_runtime_get() calls will succeed because
> the device is in RPM_ACTIVE state.
>
> So I see no reason to set the callbacks if they would not actually control
> regulators, clocks or GPIOs required by the device.
>
> Cc linux-pm.

Sounds reasonable. I remember seeing some problems in the past, but
looks like they may be already fixed in current upstream. Thanks for
checking this thoroughly.

Best regards,
Tomasz


Re: [PATCH v6 3/3] eeprom: at24: enable runtime pm support

2017-10-09 Thread Tomasz Figa
On Mon, Oct 9, 2017 at 12:14 PM, Mohandass, Divagar
 wrote:
> Hi Tomasz,
>
>>-Original Message-
>>From: sakari.ai...@iki.fi [mailto:sakari.ai...@iki.fi]
>>Sent: Tuesday, October 03, 2017 7:21 PM
>>To: Tomasz Figa 
>>Cc: Mani, Rajmohan ; Mohandass, Divagar
>>; robh...@kernel.org;
>>mark.rutl...@arm.com; w...@the-dreams.de; devicet...@vger.kernel.org;
>>linux-...@vger.kernel.org; linux-kernel@vger.kernel.org;
>>mika.westerb...@linux.intel.com; linux...@vger.kernel.org
>>Subject: Re: [PATCH v6 3/3] eeprom: at24: enable runtime pm support
>>
>>Hi Tomasz,
>>
>>On Wed, Sep 20, 2017 at 12:32:22PM +0300, sakari.ai...@iki.fi wrote:
>>> > >> >> @@ -743,11 +770,17 @@ static int at24_probe(struct i2c_client
>>> > >> >> *client, const struct i2c_device_id *id)
>>> > >> >>
>>> > >> >>   i2c_set_clientdata(client, at24);
>>> > >> >>
>>> > >> >> + /* enable runtime pm */
>>> > >> >> + pm_runtime_get_noresume(>dev);
>>> > >> >> + pm_runtime_set_active(>dev);
>>> > >> >> + pm_runtime_enable(>dev);
>>> > >>
>>> > >> Do we need this get_noresume/set_active dance? I remember it was
>>> > >> for some reason needed for PCI devices, but I don't see why for
>>> > >> I2C anything else than just pm_runtime_enable() would be necessary.
>>> > >
>>> > > You specifically do not need (all) this for PCI devices, but AFAIU
>>> > > for I涎
>>> > > devices you do. The runtime PM status of a device is disabled by
>>> > > default and the use count is zero, but on ACPI based systems the
>>> > > device is still powered on.
>>> >
>>> > Okay, so _get_noresume() and _set_active() would do the thing for
>>> > ACPI indeed, but not sure about other platforms. Perhaps _enable(),
>>> > _get_sync() would be more general?
>>>
>>> What I ended up doing in e.g. the smiapp driver was to explicitly
>>> power the device on first and then enable runtime PM. (See
>>> drivers/media/i2c/smiapp/smiapp-core.c .) This approach works even if
>>> CONFIG_PM is disabled, both on DT and ACPI.
>>
>>pm_runtime_get_noresume() + pm_runtime_put() can be replaced by a single
>>pm_runtime_idle() call (where pm_runtime_put() was). pm_runtime_enable()
>>is required to enable runtime PM for a device.
>
> Verified the change suggested by Sakari.
> Let me know I can send a updated patch version with this change.

Okay, looks like Sakari confirmed that the driver should work fine
without callbacks, so please go ahead. Thanks for patience.

Best regards,
Tomasz


Re: [PATCH v6 3/3] eeprom: at24: enable runtime pm support

2017-10-09 Thread Tomasz Figa
On Tue, Oct 3, 2017 at 11:23 PM, sakari.ai...@iki.fi
 wrote:
> On Wed, Sep 20, 2017 at 11:45:20AM +0300, sakari.ai...@iki.fi wrote:
>> > >> @@ -743,11 +770,17 @@ static int at24_probe(struct i2c_client *client, 
>> > >> const
>> > >> struct i2c_device_id *id)
>> > >>
>> > >>   i2c_set_clientdata(client, at24);
>> > >>
>> > >> + /* enable runtime pm */
>> > >> + pm_runtime_get_noresume(>dev);
>> > >> + pm_runtime_set_active(>dev);
>> > >> + pm_runtime_enable(>dev);
>> >
>> > Do we need this get_noresume/set_active dance? I remember it was for
>> > some reason needed for PCI devices, but I don't see why for I2C
>> > anything else than just pm_runtime_enable() would be necessary.
>>
>> You specifically do not need (all) this for PCI devices, but AFAIU for I涎
>> devices you do. The runtime PM status of a device is disabled by default
>> and the use count is zero, but on ACPI based systems the device is still
>> powered on.
>>
>> >
>> > Also, we enable runtime PM, but we don't provide any callbacks. If
>> > there is no callback in any level of the hierarchy, NULL would be
>> > returned in [3], making [2] return -ENOSYS and [1] fail. The behavior
>> > depends on subsystem and whether the device is attached to a
>> > pm_domain. In our particular case I'd guess the device would be in an
>> > ACPI pm_domain and that would work, but the driver is generic and must
>> > work in any cases.
>>
>> Agreed.
>
> I looked at the code and what actually happens here is the runtime_suspend
> and runtime_resume callbacks aren't set is that the first pm_runtime_put()
> call itself succeeds because checking the the runtime_suspend callback will
> be done in the work queue function. This leaves the device in RPM_ACTIVE
> state, which I don't think is a problem since the driver did not have
> explicit functions to control the device power state.
>
> Further pm_runtime_put() and pm_runtime_get() calls will succeed because
> the device is in RPM_ACTIVE state.
>
> So I see no reason to set the callbacks if they would not actually control
> regulators, clocks or GPIOs required by the device.
>
> Cc linux-pm.

Sounds reasonable. I remember seeing some problems in the past, but
looks like they may be already fixed in current upstream. Thanks for
checking this thoroughly.

Best regards,
Tomasz


Re: [PATCH v6 3/3] eeprom: at24: enable runtime pm support

2017-10-09 Thread Tomasz Figa
On Mon, Oct 9, 2017 at 12:14 PM, Mohandass, Divagar
 wrote:
> Hi Tomasz,
>
>>-Original Message-
>>From: sakari.ai...@iki.fi [mailto:sakari.ai...@iki.fi]
>>Sent: Tuesday, October 03, 2017 7:21 PM
>>To: Tomasz Figa 
>>Cc: Mani, Rajmohan ; Mohandass, Divagar
>>; robh...@kernel.org;
>>mark.rutl...@arm.com; w...@the-dreams.de; devicet...@vger.kernel.org;
>>linux-...@vger.kernel.org; linux-kernel@vger.kernel.org;
>>mika.westerb...@linux.intel.com; linux...@vger.kernel.org
>>Subject: Re: [PATCH v6 3/3] eeprom: at24: enable runtime pm support
>>
>>Hi Tomasz,
>>
>>On Wed, Sep 20, 2017 at 12:32:22PM +0300, sakari.ai...@iki.fi wrote:
>>> > >> >> @@ -743,11 +770,17 @@ static int at24_probe(struct i2c_client
>>> > >> >> *client, const struct i2c_device_id *id)
>>> > >> >>
>>> > >> >>   i2c_set_clientdata(client, at24);
>>> > >> >>
>>> > >> >> + /* enable runtime pm */
>>> > >> >> + pm_runtime_get_noresume(>dev);
>>> > >> >> + pm_runtime_set_active(>dev);
>>> > >> >> + pm_runtime_enable(>dev);
>>> > >>
>>> > >> Do we need this get_noresume/set_active dance? I remember it was
>>> > >> for some reason needed for PCI devices, but I don't see why for
>>> > >> I2C anything else than just pm_runtime_enable() would be necessary.
>>> > >
>>> > > You specifically do not need (all) this for PCI devices, but AFAIU
>>> > > for I涎
>>> > > devices you do. The runtime PM status of a device is disabled by
>>> > > default and the use count is zero, but on ACPI based systems the
>>> > > device is still powered on.
>>> >
>>> > Okay, so _get_noresume() and _set_active() would do the thing for
>>> > ACPI indeed, but not sure about other platforms. Perhaps _enable(),
>>> > _get_sync() would be more general?
>>>
>>> What I ended up doing in e.g. the smiapp driver was to explicitly
>>> power the device on first and then enable runtime PM. (See
>>> drivers/media/i2c/smiapp/smiapp-core.c .) This approach works even if
>>> CONFIG_PM is disabled, both on DT and ACPI.
>>
>>pm_runtime_get_noresume() + pm_runtime_put() can be replaced by a single
>>pm_runtime_idle() call (where pm_runtime_put() was). pm_runtime_enable()
>>is required to enable runtime PM for a device.
>
> Verified the change suggested by Sakari.
> Let me know I can send a updated patch version with this change.

Okay, looks like Sakari confirmed that the driver should work fine
without callbacks, so please go ahead. Thanks for patience.

Best regards,
Tomasz


Re: [PATCH] Input: synaptics - Disable kernel tracking on SMBus devices

2017-10-09 Thread Dmitry Torokhov
On Fri, Sep 29, 2017 at 10:08:44AM +0200, Benjamin Tissoires wrote:
> On Sep 28 2017 or thereabouts, Andrew Duggan wrote:
> > In certain situations kernel tracking seems to be getting confused
> > and incorrectly reporting the slot of a contact. On example is when
> > the user does a three finger click or tap and then places two fingers
> > on the touchpad in the same area. The kernel tracking code seems to
> > continue to think that there are three contacts on the touchpad and
> > incorrectly alternates the slot of one of the contacts. The result that
> > is the input subsystem reports a stream of button press and release
> > events as the reported slot changes.
> > 
> > Kernel tracking was originally enabled to prevent cursor jumps, but it
> > is unclear how much of an issue kernel jumps actually are. This patch
> > simply disabled kernel tracking for now.
> > 
> > Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1482640
> > 
> > Signed-off-by: Andrew Duggan 
> > Tested-by: Kamil Páral 
> 
> Acked-by: Benjamin Tissoires 
> 
> Thanks Andrew for the patch!

Applied, thank you.

> 
> Cheers,
> Benjamin
> 
> > ---
> >  drivers/input/mouse/synaptics.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> > 
> > diff --git a/drivers/input/mouse/synaptics.c 
> > b/drivers/input/mouse/synaptics.c
> > index 5af0b7d..ee5466a 100644
> > --- a/drivers/input/mouse/synaptics.c
> > +++ b/drivers/input/mouse/synaptics.c
> > @@ -1709,8 +1709,7 @@ static int synaptics_create_intertouch(struct psmouse 
> > *psmouse,
> > .sensor_pdata = {
> > .sensor_type = rmi_sensor_touchpad,
> > .axis_align.flip_y = true,
> > -   /* to prevent cursors jumps: */
> > -   .kernel_tracking = true,
> > +   .kernel_tracking = false,
> > .topbuttonpad = topbuttonpad,
> > },
> > .f30_data = {
> > -- 
> > 2.7.4
> > 

-- 
Dmitry


Re: [PATCH] Input: synaptics - Disable kernel tracking on SMBus devices

2017-10-09 Thread Dmitry Torokhov
On Fri, Sep 29, 2017 at 10:08:44AM +0200, Benjamin Tissoires wrote:
> On Sep 28 2017 or thereabouts, Andrew Duggan wrote:
> > In certain situations kernel tracking seems to be getting confused
> > and incorrectly reporting the slot of a contact. On example is when
> > the user does a three finger click or tap and then places two fingers
> > on the touchpad in the same area. The kernel tracking code seems to
> > continue to think that there are three contacts on the touchpad and
> > incorrectly alternates the slot of one of the contacts. The result that
> > is the input subsystem reports a stream of button press and release
> > events as the reported slot changes.
> > 
> > Kernel tracking was originally enabled to prevent cursor jumps, but it
> > is unclear how much of an issue kernel jumps actually are. This patch
> > simply disabled kernel tracking for now.
> > 
> > Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1482640
> > 
> > Signed-off-by: Andrew Duggan 
> > Tested-by: Kamil Páral 
> 
> Acked-by: Benjamin Tissoires 
> 
> Thanks Andrew for the patch!

Applied, thank you.

> 
> Cheers,
> Benjamin
> 
> > ---
> >  drivers/input/mouse/synaptics.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> > 
> > diff --git a/drivers/input/mouse/synaptics.c 
> > b/drivers/input/mouse/synaptics.c
> > index 5af0b7d..ee5466a 100644
> > --- a/drivers/input/mouse/synaptics.c
> > +++ b/drivers/input/mouse/synaptics.c
> > @@ -1709,8 +1709,7 @@ static int synaptics_create_intertouch(struct psmouse 
> > *psmouse,
> > .sensor_pdata = {
> > .sensor_type = rmi_sensor_touchpad,
> > .axis_align.flip_y = true,
> > -   /* to prevent cursors jumps: */
> > -   .kernel_tracking = true,
> > +   .kernel_tracking = false,
> > .topbuttonpad = topbuttonpad,
> > },
> > .f30_data = {
> > -- 
> > 2.7.4
> > 

-- 
Dmitry


Re: [PATCH v2 0/5] Simplify panel bridge cleanup

2017-10-09 Thread Archit Taneja



On 10/02/2017 03:02 PM, Benjamin Gaignard wrote:

The goal of this series is to simplify driver code when they need to clean up
a previously allocated panel bridge.
Few drivers have "is_panel_bridge" flag to be able to distinguish a
drm_panel_bridge from "simple" drm_bridge.
To remove this flag I propose to
- let drm_panel_bridge_remove() check if the bridge provided in parameter is
   really a drm_panel_bridge.
- add drm_of_panel_bridge_remove() to remove a bridge given DT port and
   endpoint
Finally that allow to remove drm_bridge structure and "is_panel_bridge" flag
from stm driver internal structure.

version 2:
- does the same for vc4 and dw-mipi-dsi

For the series:

Reviewed-by: Archit Taneja 

Feel free to queue to drm-misc-next.

Thanks,
Archit



Benjamin Gaignard (5):
   drm/bridge: make drm_panel_bridge_remove more robust
   drm/drm_of: add drm_of_panel_bridge_remove function
   drm/stm: ltdc: remove bridge from driver internal structure
   drm/vc4: remove bridge from driver internal structure
   drm/bridge/synopsys: dsi :remove is_panel_bridge

  drivers/gpu/drm/bridge/panel.c| 10 +++-
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c |  5 +---
  drivers/gpu/drm/drm_of.c  | 33 +++
  drivers/gpu/drm/stm/ltdc.c| 16 -
  drivers/gpu/drm/stm/ltdc.h|  2 --
  drivers/gpu/drm/vc4/vc4_dpi.c | 17 +-
  include/drm/drm_of.h  |  8 +++
  7 files changed, 62 insertions(+), 29 deletions(-)



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [PATCH v2 0/5] Simplify panel bridge cleanup

2017-10-09 Thread Archit Taneja



On 10/02/2017 03:02 PM, Benjamin Gaignard wrote:

The goal of this series is to simplify driver code when they need to clean up
a previously allocated panel bridge.
Few drivers have "is_panel_bridge" flag to be able to distinguish a
drm_panel_bridge from "simple" drm_bridge.
To remove this flag I propose to
- let drm_panel_bridge_remove() check if the bridge provided in parameter is
   really a drm_panel_bridge.
- add drm_of_panel_bridge_remove() to remove a bridge given DT port and
   endpoint
Finally that allow to remove drm_bridge structure and "is_panel_bridge" flag
from stm driver internal structure.

version 2:
- does the same for vc4 and dw-mipi-dsi

For the series:

Reviewed-by: Archit Taneja 

Feel free to queue to drm-misc-next.

Thanks,
Archit



Benjamin Gaignard (5):
   drm/bridge: make drm_panel_bridge_remove more robust
   drm/drm_of: add drm_of_panel_bridge_remove function
   drm/stm: ltdc: remove bridge from driver internal structure
   drm/vc4: remove bridge from driver internal structure
   drm/bridge/synopsys: dsi :remove is_panel_bridge

  drivers/gpu/drm/bridge/panel.c| 10 +++-
  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c |  5 +---
  drivers/gpu/drm/drm_of.c  | 33 +++
  drivers/gpu/drm/stm/ltdc.c| 16 -
  drivers/gpu/drm/stm/ltdc.h|  2 --
  drivers/gpu/drm/vc4/vc4_dpi.c | 17 +-
  include/drm/drm_of.h  |  8 +++
  7 files changed, 62 insertions(+), 29 deletions(-)



--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


Re: [musl] Re: [PATCHv3] uapi libc compat: add fallback for unsupported libcs

2017-10-09 Thread Florian Fainelli
Le 10/01/17 à 03:37, Hauke Mehrtens a écrit :
> On 07/29/2017 04:02 PM, Felix Janda wrote:
>> libc-compat.h aims to prevent symbol collisions between uapi and libc
>> headers for each supported libc. This requires continuous coordination
>> between them.
>>
>> The goal of this commit is to improve the situation for libcs (such as
>> musl) which are not yet supported and/or do not wish to be explicitly
>> supported, while not affecting supported libcs. More precisely, with
>> this commit, unsupported libcs can request the suppression of any
>> specific uapi definition by defining the correspondings _UAPI_DEF_*
>> macro as 0. This can fix symbol collisions for them, as long as the
>> libc headers are included before the uapi headers. Inclusion in the
>> other order is outside the scope of this commit.
>>
>> All infrastructure in order to enable this fallback for unsupported
>> libcs is already in place, except that libc-compat.h unconditionally
>> defines all _UAPI_DEF_* macros to 1 for all unsupported libcs so that
>> any previous definitions are ignored. In order to fix this, this commit
>> merely makes these definitions conditional.
>>
>> This commit together with the musl libc commit
>>
>> http://git.musl-libc.org/cgit/musl/commit/?id=04983f2272382af92eb8f8838964ff944fbb8258
>>
>> fixes for example the following compiler errors when  is
>> included after musl's :
>>
>> ./linux/in6.h:32:8: error: redefinition of 'struct in6_addr'
>> ./linux/in6.h:49:8: error: redefinition of 'struct sockaddr_in6'
>> ./linux/in6.h:59:8: error: redefinition of 'struct ipv6_mreq'
>>
>> Signed-off-by: Felix Janda 
>> ---
>> v3: Fix typos, add a comment to the file and use #ifndef.
>> v2: The only change to the previous version is the commit title and
>> message.
> 
> Was this send to the wrong mailing lists? I would like to see this in
> the mainline kernel and I am wondering why it neither gets any comments
> nor shows up in linux-next.

Same here. Without such changes we cannot essentially build upstream
kernels in OpenWrt/LEDE using musl-libc without patching kernel headers,
which is really not great...
-- 
Florian


Re: [musl] Re: [PATCHv3] uapi libc compat: add fallback for unsupported libcs

2017-10-09 Thread Florian Fainelli
Le 10/01/17 à 03:37, Hauke Mehrtens a écrit :
> On 07/29/2017 04:02 PM, Felix Janda wrote:
>> libc-compat.h aims to prevent symbol collisions between uapi and libc
>> headers for each supported libc. This requires continuous coordination
>> between them.
>>
>> The goal of this commit is to improve the situation for libcs (such as
>> musl) which are not yet supported and/or do not wish to be explicitly
>> supported, while not affecting supported libcs. More precisely, with
>> this commit, unsupported libcs can request the suppression of any
>> specific uapi definition by defining the correspondings _UAPI_DEF_*
>> macro as 0. This can fix symbol collisions for them, as long as the
>> libc headers are included before the uapi headers. Inclusion in the
>> other order is outside the scope of this commit.
>>
>> All infrastructure in order to enable this fallback for unsupported
>> libcs is already in place, except that libc-compat.h unconditionally
>> defines all _UAPI_DEF_* macros to 1 for all unsupported libcs so that
>> any previous definitions are ignored. In order to fix this, this commit
>> merely makes these definitions conditional.
>>
>> This commit together with the musl libc commit
>>
>> http://git.musl-libc.org/cgit/musl/commit/?id=04983f2272382af92eb8f8838964ff944fbb8258
>>
>> fixes for example the following compiler errors when  is
>> included after musl's :
>>
>> ./linux/in6.h:32:8: error: redefinition of 'struct in6_addr'
>> ./linux/in6.h:49:8: error: redefinition of 'struct sockaddr_in6'
>> ./linux/in6.h:59:8: error: redefinition of 'struct ipv6_mreq'
>>
>> Signed-off-by: Felix Janda 
>> ---
>> v3: Fix typos, add a comment to the file and use #ifndef.
>> v2: The only change to the previous version is the commit title and
>> message.
> 
> Was this send to the wrong mailing lists? I would like to see this in
> the mainline kernel and I am wondering why it neither gets any comments
> nor shows up in linux-next.

Same here. Without such changes we cannot essentially build upstream
kernels in OpenWrt/LEDE using musl-libc without patching kernel headers,
which is really not great...
-- 
Florian


Re: [PATCH net-next] once: switch to new jump label API

2017-10-09 Thread David Miller
From: Eric Biggers 
Date: Mon,  9 Oct 2017 14:30:52 -0700

> From: Eric Biggers 
> 
> Switch the DO_ONCE() macro from the deprecated jump label API to the new
> one.  The new one is more readable, and for DO_ONCE() it also makes the
> generated code more icache-friendly: now the one-time initialization
> code is placed out-of-line at the jump target, rather than at the inline
> fallthrough case.
> 
> Acked-by: Hannes Frederic Sowa 
> Signed-off-by: Eric Biggers 

Applied, thank you.


Re: [PATCH net-next] once: switch to new jump label API

2017-10-09 Thread David Miller
From: Eric Biggers 
Date: Mon,  9 Oct 2017 14:30:52 -0700

> From: Eric Biggers 
> 
> Switch the DO_ONCE() macro from the deprecated jump label API to the new
> one.  The new one is more readable, and for DO_ONCE() it also makes the
> generated code more icache-friendly: now the one-time initialization
> code is placed out-of-line at the jump target, rather than at the inline
> fallthrough case.
> 
> Acked-by: Hannes Frederic Sowa 
> Signed-off-by: Eric Biggers 

Applied, thank you.


Re: [PATCH] cpufreq: dt-platdev: drop socionext,uniphier-ld6b from whitelist

2017-10-09 Thread Viresh Kumar
On 14-09-17, 14:26, Viresh Kumar wrote:
> On 30-08-17, 00:37, Masahiro Yamada wrote:
> > As you see arch/arm/boot/dts/uniphier-ld6b.dtsi, it includes
> > uniphier-pxs2.dtsi, which uses "operating-points-v2" property
> > and whose cpufreq device is automatically created.
> > 
> > Signed-off-by: Masahiro Yamada 
> > ---
> > 
> >  drivers/cpufreq/cpufreq-dt-platdev.c | 2 --
> >  1 file changed, 2 deletions(-)
> > 
> > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c 
> > b/drivers/cpufreq/cpufreq-dt-platdev.c
> > index a020da7940d6..c344fc1c4eb8 100644
> > --- a/drivers/cpufreq/cpufreq-dt-platdev.c
> > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c
> > @@ -83,8 +83,6 @@ static const struct of_device_id whitelist[] __initconst 
> > = {
> > { .compatible = "rockchip,rk3368", },
> > { .compatible = "rockchip,rk3399", },
> >  
> > -   { .compatible = "socionext,uniphier-ld6b", },
> > -
> > { .compatible = "st-ericsson,u8500", },
> > { .compatible = "st-ericsson,u8540", },
> > { .compatible = "st-ericsson,u9500", },
> 
> Acked-by: Viresh Kumar 

@Rafael: You missed my Ack while applying this patch ?

-- 
viresh


Re: [PATCH] cpufreq: dt-platdev: drop socionext,uniphier-ld6b from whitelist

2017-10-09 Thread Viresh Kumar
On 14-09-17, 14:26, Viresh Kumar wrote:
> On 30-08-17, 00:37, Masahiro Yamada wrote:
> > As you see arch/arm/boot/dts/uniphier-ld6b.dtsi, it includes
> > uniphier-pxs2.dtsi, which uses "operating-points-v2" property
> > and whose cpufreq device is automatically created.
> > 
> > Signed-off-by: Masahiro Yamada 
> > ---
> > 
> >  drivers/cpufreq/cpufreq-dt-platdev.c | 2 --
> >  1 file changed, 2 deletions(-)
> > 
> > diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c 
> > b/drivers/cpufreq/cpufreq-dt-platdev.c
> > index a020da7940d6..c344fc1c4eb8 100644
> > --- a/drivers/cpufreq/cpufreq-dt-platdev.c
> > +++ b/drivers/cpufreq/cpufreq-dt-platdev.c
> > @@ -83,8 +83,6 @@ static const struct of_device_id whitelist[] __initconst 
> > = {
> > { .compatible = "rockchip,rk3368", },
> > { .compatible = "rockchip,rk3399", },
> >  
> > -   { .compatible = "socionext,uniphier-ld6b", },
> > -
> > { .compatible = "st-ericsson,u8500", },
> > { .compatible = "st-ericsson,u8540", },
> > { .compatible = "st-ericsson,u9500", },
> 
> Acked-by: Viresh Kumar 

@Rafael: You missed my Ack while applying this patch ?

-- 
viresh


Re: [PATCH v2] usb: musb: sunxi: Explicitly release USB PHY on exit

2017-10-09 Thread Bin Liu
On Tue, Oct 10, 2017 at 01:45:25PM +1100, Jonathan Liu wrote:
> This fixes a kernel oops when unloading the driver due to usb_put_phy
> being called after usb_phy_generic_unregister when the device is
> detached. Calling usb_phy_generic_unregister causes x->dev->driver to
> be NULL in usb_put_phy and results in a NULL pointer dereference.
> 
> Cc: sta...@vger.kernel.org # v4.3+
> Signed-off-by: Jonathan Liu 
> ---
> Changes for v2:
>  - Use devm_usb_put_phy instead of usb_put_phy
> 
>  drivers/usb/musb/sunxi.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
> index c9a09b5bb6e5..dc353e24d53c 100644
> --- a/drivers/usb/musb/sunxi.c
> +++ b/drivers/usb/musb/sunxi.c
> @@ -297,6 +297,8 @@ static int sunxi_musb_exit(struct musb *musb)
>   if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, >flags))
>   sunxi_sram_release(musb->controller->parent);
>  
> + devm_usb_put_phy(glue->dev, glue->xceiv);
> +
>   return 0;
>  }


Applied. Thanks.
-Bin.


Re: [PATCH v2] usb: musb: sunxi: Explicitly release USB PHY on exit

2017-10-09 Thread Bin Liu
On Tue, Oct 10, 2017 at 01:45:25PM +1100, Jonathan Liu wrote:
> This fixes a kernel oops when unloading the driver due to usb_put_phy
> being called after usb_phy_generic_unregister when the device is
> detached. Calling usb_phy_generic_unregister causes x->dev->driver to
> be NULL in usb_put_phy and results in a NULL pointer dereference.
> 
> Cc: sta...@vger.kernel.org # v4.3+
> Signed-off-by: Jonathan Liu 
> ---
> Changes for v2:
>  - Use devm_usb_put_phy instead of usb_put_phy
> 
>  drivers/usb/musb/sunxi.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/usb/musb/sunxi.c b/drivers/usb/musb/sunxi.c
> index c9a09b5bb6e5..dc353e24d53c 100644
> --- a/drivers/usb/musb/sunxi.c
> +++ b/drivers/usb/musb/sunxi.c
> @@ -297,6 +297,8 @@ static int sunxi_musb_exit(struct musb *musb)
>   if (test_bit(SUNXI_MUSB_FL_HAS_SRAM, >flags))
>   sunxi_sram_release(musb->controller->parent);
>  
> + devm_usb_put_phy(glue->dev, glue->xceiv);
> +
>   return 0;
>  }


Applied. Thanks.
-Bin.


[PATCH v4 00/11] drm/sun4i: hdmi: Support HDMI controller on A31

2017-10-09 Thread Chen-Yu Tsai
Hi everyone,

This is v4 of my A31 HDMI support series. The DTS patches depend on
the patch "clk: sunxi-ng: sun6i: Export video PLLs" alreay merged.
The DRM patches depend on "regmap: add iopoll-like polling macro for
regmap_field" already merged on a topic branch in the regmap repository.

Changes since v3:

- Renamed sun4i_get_first_tcon() to sun4i_get_tcon0()

- Made sun4i_get_tcon0() return NULL when it fails, and
  sun6i_tcon_set_mux() will error out if that happens.

- Removed has_unknown_mux field in tcon_quirks structure,
  as its function is replaced by the per-soc muxing function
  pointer.

- Dropped clk and regmap patches that were merged.

Changes since v2:

- TCON muxing moved into functions for each platform, with pointers
  to them in the TCON quirks structure.

- CCU "hdmi-ddc" clock renamed to "ddc".

- Added Maxime's acks.

Changes since v1:

- Core changes to sun4i-drm to support two display pipelines
  have been merged into drm-misc and thus dropped from this
  version

- Reworked DDC variant support onto new exposed I2C interface bits.

- Reworked DDC variant support to use regmap_fields.

- Patches to add variant support to various (TMDS, DDC, HDMI
  controller) sub-blocks have been merged into one patch.

This series adds support for the HDMI controller found on Allwinner
A31/A31s SoCs. It builds upon Maxime's work that added support for
the HDMI controller on the Allwinner A10s SoC.

The HDMI controllers in the older generation Allwinner SoCs is very
similar. The A10/A10s/A20 all have the same hardware block, with the
A10 having slightly different initial configuration values. The A31's
variant splits out the DDC parent clock, has different formulas for
the DDC and TMDS clocks, and a different register layout for the DDC
block. Also, it does not expose the CEC pins outside of the SoC, which
is unfortunate.

Patch 1 moves the existing TCON muxing code for the A13 into a separate
function, pointed to by by function pointer in the quirks structure.
The existing sun4i_tcon_set_mux() function calls the function pointer
if it is set.

Patch 2 adds support for the TCON demuxing feature on the A31. This is
needed if the user wants to output through HDMI from the second display
pipeline.

Patch 3 adds proper error path cleanup to the HDMI driver.

Patch 4 adds a regmap for the HDMI driver, to be used in a subsequent
patch.

Patch 5 allows the HDMI TMDS clock to use the second PLL as its parent,
in case the first PLL is driving an incompatible dot clock.

Patch 6 adds the A31 HDMI controller variant to the device tree binding.

Patch 7 adds support for different variants of the HDMI controller
hardware, with the differences mentioned in the beginning of this
letter.

Patch 8 adds defines for the A31 specific DDC register offsets.

Patch 9 adds support for the A31's HDMI controller variant.

Patch 10 adds a device node for the HDMI controller on the A31.

Patch 11 enable HDMI video output on three boards that I have.


I also had simultaneous output on both display pipelines on the SinA31s,
one with an LCD panel and the other using HDMI. After boot, both screens
showed a proper console. The HDMI screen had higher resolution, so the
console was limited to the upper left corner.

Note that this series does not deal with conflicting pixel clocks.

As I still don't have a freedesktop.org account [1] to access drm-misc,
Maxime will have to apply the patches for me.


Regards
ChenYu


[1] https://bugs.freedesktop.org/show_bug.cgi?id=102920

Chen-Yu Tsai (11):
  drm/sun4i: tcon: Add variant callback for TCON output muxing
  drm/sun4i: tcon: Add support for demuxing TCON output on A31
  drm/sun4i: hdmi: Disable clks in bind function error path and unbind
function
  drm/sun4i: hdmi: create a regmap for later use
  drm/sun4i: hdmi: Allow using second PLL as TMDS clk parent
  dt-bindings: display: sun4i: Add binding for A31 HDMI controller
  drm/sun4i: hdmi: Add support for controller hardware variants
  drm/sun4i: hdmi: Add A31 specific DDC register definitions
  drm/sun4i: hdmi: Add support for A31's HDMI controller
  ARM: dts: sun6i: Add device node for HDMI controller
  ARM: dts: sun6i: Enable HDMI support on some A31/A31s devices

 .../bindings/display/sunxi/sun4i-drm.txt   |   3 +
 arch/arm/boot/dts/sun6i-a31-hummingbird.dts|  21 ++
 arch/arm/boot/dts/sun6i-a31.dtsi   |  55 +
 arch/arm/boot/dts/sun6i-a31s-primo81.dts   |  25 +++
 arch/arm/boot/dts/sun6i-a31s-sina31s.dts   |  25 +++
 drivers/gpu/drm/sun4i/sun4i_hdmi.h | 107 ++
 drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c |  38 +++-
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 204 +++---
 drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c | 227 +++--
 drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c|  68 +++---
 drivers/gpu/drm/sun4i/sun4i_tcon.c

[PATCH v4 00/11] drm/sun4i: hdmi: Support HDMI controller on A31

2017-10-09 Thread Chen-Yu Tsai
Hi everyone,

This is v4 of my A31 HDMI support series. The DTS patches depend on
the patch "clk: sunxi-ng: sun6i: Export video PLLs" alreay merged.
The DRM patches depend on "regmap: add iopoll-like polling macro for
regmap_field" already merged on a topic branch in the regmap repository.

Changes since v3:

- Renamed sun4i_get_first_tcon() to sun4i_get_tcon0()

- Made sun4i_get_tcon0() return NULL when it fails, and
  sun6i_tcon_set_mux() will error out if that happens.

- Removed has_unknown_mux field in tcon_quirks structure,
  as its function is replaced by the per-soc muxing function
  pointer.

- Dropped clk and regmap patches that were merged.

Changes since v2:

- TCON muxing moved into functions for each platform, with pointers
  to them in the TCON quirks structure.

- CCU "hdmi-ddc" clock renamed to "ddc".

- Added Maxime's acks.

Changes since v1:

- Core changes to sun4i-drm to support two display pipelines
  have been merged into drm-misc and thus dropped from this
  version

- Reworked DDC variant support onto new exposed I2C interface bits.

- Reworked DDC variant support to use regmap_fields.

- Patches to add variant support to various (TMDS, DDC, HDMI
  controller) sub-blocks have been merged into one patch.

This series adds support for the HDMI controller found on Allwinner
A31/A31s SoCs. It builds upon Maxime's work that added support for
the HDMI controller on the Allwinner A10s SoC.

The HDMI controllers in the older generation Allwinner SoCs is very
similar. The A10/A10s/A20 all have the same hardware block, with the
A10 having slightly different initial configuration values. The A31's
variant splits out the DDC parent clock, has different formulas for
the DDC and TMDS clocks, and a different register layout for the DDC
block. Also, it does not expose the CEC pins outside of the SoC, which
is unfortunate.

Patch 1 moves the existing TCON muxing code for the A13 into a separate
function, pointed to by by function pointer in the quirks structure.
The existing sun4i_tcon_set_mux() function calls the function pointer
if it is set.

Patch 2 adds support for the TCON demuxing feature on the A31. This is
needed if the user wants to output through HDMI from the second display
pipeline.

Patch 3 adds proper error path cleanup to the HDMI driver.

Patch 4 adds a regmap for the HDMI driver, to be used in a subsequent
patch.

Patch 5 allows the HDMI TMDS clock to use the second PLL as its parent,
in case the first PLL is driving an incompatible dot clock.

Patch 6 adds the A31 HDMI controller variant to the device tree binding.

Patch 7 adds support for different variants of the HDMI controller
hardware, with the differences mentioned in the beginning of this
letter.

Patch 8 adds defines for the A31 specific DDC register offsets.

Patch 9 adds support for the A31's HDMI controller variant.

Patch 10 adds a device node for the HDMI controller on the A31.

Patch 11 enable HDMI video output on three boards that I have.


I also had simultaneous output on both display pipelines on the SinA31s,
one with an LCD panel and the other using HDMI. After boot, both screens
showed a proper console. The HDMI screen had higher resolution, so the
console was limited to the upper left corner.

Note that this series does not deal with conflicting pixel clocks.

As I still don't have a freedesktop.org account [1] to access drm-misc,
Maxime will have to apply the patches for me.


Regards
ChenYu


[1] https://bugs.freedesktop.org/show_bug.cgi?id=102920

Chen-Yu Tsai (11):
  drm/sun4i: tcon: Add variant callback for TCON output muxing
  drm/sun4i: tcon: Add support for demuxing TCON output on A31
  drm/sun4i: hdmi: Disable clks in bind function error path and unbind
function
  drm/sun4i: hdmi: create a regmap for later use
  drm/sun4i: hdmi: Allow using second PLL as TMDS clk parent
  dt-bindings: display: sun4i: Add binding for A31 HDMI controller
  drm/sun4i: hdmi: Add support for controller hardware variants
  drm/sun4i: hdmi: Add A31 specific DDC register definitions
  drm/sun4i: hdmi: Add support for A31's HDMI controller
  ARM: dts: sun6i: Add device node for HDMI controller
  ARM: dts: sun6i: Enable HDMI support on some A31/A31s devices

 .../bindings/display/sunxi/sun4i-drm.txt   |   3 +
 arch/arm/boot/dts/sun6i-a31-hummingbird.dts|  21 ++
 arch/arm/boot/dts/sun6i-a31.dtsi   |  55 +
 arch/arm/boot/dts/sun6i-a31s-primo81.dts   |  25 +++
 arch/arm/boot/dts/sun6i-a31s-sina31s.dts   |  25 +++
 drivers/gpu/drm/sun4i/sun4i_hdmi.h | 107 ++
 drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c |  38 +++-
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 204 +++---
 drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c | 227 +++--
 drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c|  68 +++---
 drivers/gpu/drm/sun4i/sun4i_tcon.c

[PATCH v4 01/11] drm/sun4i: tcon: Add variant callback for TCON output muxing

2017-10-09 Thread Chen-Yu Tsai
Different SoCs have different muxing options and values for the TCON
outputs. Instead of stuffing every possibility in sun4i_tcon_set_mux(),
add a callback pointer to sun4i_tcon_quirks that each TCON variant
can use to provide muxing support.

The current muxing options in sun4i_tcon_set_mux() for sun5i-a13 are
moved to a new sun5i-specific callback function.

Since the new callback replaces what the .has_unknown_mux field in
tcon quirks did in the past, the field is removed.

Signed-off-by: Chen-Yu Tsai 
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 44 +++---
 drivers/gpu/drm/sun4i/sun4i_tcon.h |  6 +-
 2 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index e853dfe51389..75124043d655 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -14,9 +14,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
+#include 
+
 #include 
 #include 
 #include 
@@ -112,23 +115,13 @@ EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
 void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
struct drm_encoder *encoder)
 {
-   u32 val;
-
-   if (!tcon->quirks->has_unknown_mux)
-   return;
+   int ret = -ENOTSUPP;
 
-   if (channel != 1)
-   return;
-
-   if (encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
-   val = 1;
-   else
-   val = 0;
+   if (tcon->quirks->set_mux)
+   ret = tcon->quirks->set_mux(tcon, encoder);
 
-   /*
-* FIXME: Undocumented bits
-*/
-   regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val);
+   DRM_DEBUG_DRIVER("Muxing encoder %s to CRTC %s: %d\n",
+encoder->name, encoder->crtc->name, ret);
 }
 EXPORT_SYMBOL(sun4i_tcon_set_mux);
 
@@ -767,9 +760,26 @@ static int sun4i_tcon_remove(struct platform_device *pdev)
return 0;
 }
 
+/* platform specific TCON muxing callbacks */
+static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon,
+ struct drm_encoder *encoder)
+{
+   u32 val;
+
+   if (encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
+   val = 1;
+   else
+   val = 0;
+
+   /*
+* FIXME: Undocumented bits
+*/
+   return regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val);
+}
+
 static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
-   .has_unknown_mux = true,
-   .has_channel_1  = true,
+   .has_channel_1  = true,
+   .set_mux= sun5i_a13_tcon_set_mux,
 };
 
 static const struct sun4i_tcon_quirks sun6i_a31_quirks = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h 
b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index 5a219d1ccc26..d9e1357cc8ae 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -145,10 +145,14 @@
 
 #define SUN4I_TCON_MAX_CHANNELS2
 
+struct sun4i_tcon;
+
 struct sun4i_tcon_quirks {
-   boolhas_unknown_mux; /* sun5i has undocumented mux */
boolhas_channel_1;  /* a33 does not have channel 1 */
boolneeds_de_be_mux; /* sun6i needs mux to select backend */
+
+   /* callback to handle tcon muxing options */
+   int (*set_mux)(struct sun4i_tcon *, struct drm_encoder *);
 };
 
 struct sun4i_tcon {
-- 
2.14.2



[PATCH v4 03/11] drm/sun4i: hdmi: Disable clks in bind function error path and unbind function

2017-10-09 Thread Chen-Yu Tsai
The HDMI driver enables the bus and mod clocks in the bind function, but
does not disable them if it then bails our due to any errors. Neither
does it disable the clocks in the unbind function.

Fix this by adding a proper error path to the bind function, and
clk_disable_unprepare calls to the unbind function.

Also rename the err_cleanup_connector label to err_cleanup_encoder,
since it is the encoder that gets cleaned up.

Fixes: 9c5681011a0c ("drm/sun4i: Add HDMI support")
Signed-off-by: Chen-Yu Tsai 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 9ea6cd5a1370..3cf1a6932fac 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -302,26 +302,29 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
hdmi->mod_clk = devm_clk_get(dev, "mod");
if (IS_ERR(hdmi->mod_clk)) {
dev_err(dev, "Couldn't get the HDMI mod clock\n");
-   return PTR_ERR(hdmi->mod_clk);
+   ret = PTR_ERR(hdmi->mod_clk);
+   goto err_disable_bus_clk;
}
clk_prepare_enable(hdmi->mod_clk);
 
hdmi->pll0_clk = devm_clk_get(dev, "pll-0");
if (IS_ERR(hdmi->pll0_clk)) {
dev_err(dev, "Couldn't get the HDMI PLL 0 clock\n");
-   return PTR_ERR(hdmi->pll0_clk);
+   ret = PTR_ERR(hdmi->pll0_clk);
+   goto err_disable_mod_clk;
}
 
hdmi->pll1_clk = devm_clk_get(dev, "pll-1");
if (IS_ERR(hdmi->pll1_clk)) {
dev_err(dev, "Couldn't get the HDMI PLL 1 clock\n");
-   return PTR_ERR(hdmi->pll1_clk);
+   ret = PTR_ERR(hdmi->pll1_clk);
+   goto err_disable_mod_clk;
}
 
ret = sun4i_tmds_create(hdmi);
if (ret) {
dev_err(dev, "Couldn't create the TMDS clock\n");
-   return ret;
+   goto err_disable_mod_clk;
}
 
writel(SUN4I_HDMI_CTRL_ENABLE, hdmi->base + SUN4I_HDMI_CTRL_REG);
@@ -362,7 +365,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
ret = sun4i_hdmi_i2c_create(dev, hdmi);
if (ret) {
dev_err(dev, "Couldn't create the HDMI I2C adapter\n");
-   return ret;
+   goto err_disable_mod_clk;
}
 
drm_encoder_helper_add(>encoder,
@@ -422,6 +425,10 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
drm_encoder_cleanup(>encoder);
 err_del_i2c_adapter:
i2c_del_adapter(hdmi->i2c);
+err_disable_mod_clk:
+   clk_disable_unprepare(hdmi->mod_clk);
+err_disable_bus_clk:
+   clk_disable_unprepare(hdmi->bus_clk);
return ret;
 }
 
@@ -434,6 +441,8 @@ static void sun4i_hdmi_unbind(struct device *dev, struct 
device *master,
drm_connector_cleanup(>connector);
drm_encoder_cleanup(>encoder);
i2c_del_adapter(hdmi->i2c);
+   clk_disable_unprepare(hdmi->mod_clk);
+   clk_disable_unprepare(hdmi->bus_clk);
 }
 
 static const struct component_ops sun4i_hdmi_ops = {
-- 
2.14.2



[PATCH v4 01/11] drm/sun4i: tcon: Add variant callback for TCON output muxing

2017-10-09 Thread Chen-Yu Tsai
Different SoCs have different muxing options and values for the TCON
outputs. Instead of stuffing every possibility in sun4i_tcon_set_mux(),
add a callback pointer to sun4i_tcon_quirks that each TCON variant
can use to provide muxing support.

The current muxing options in sun4i_tcon_set_mux() for sun5i-a13 are
moved to a new sun5i-specific callback function.

Since the new callback replaces what the .has_unknown_mux field in
tcon quirks did in the past, the field is removed.

Signed-off-by: Chen-Yu Tsai 
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 44 +++---
 drivers/gpu/drm/sun4i/sun4i_tcon.h |  6 +-
 2 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index e853dfe51389..75124043d655 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -14,9 +14,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
+#include 
+
 #include 
 #include 
 #include 
@@ -112,23 +115,13 @@ EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
 void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
struct drm_encoder *encoder)
 {
-   u32 val;
-
-   if (!tcon->quirks->has_unknown_mux)
-   return;
+   int ret = -ENOTSUPP;
 
-   if (channel != 1)
-   return;
-
-   if (encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
-   val = 1;
-   else
-   val = 0;
+   if (tcon->quirks->set_mux)
+   ret = tcon->quirks->set_mux(tcon, encoder);
 
-   /*
-* FIXME: Undocumented bits
-*/
-   regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val);
+   DRM_DEBUG_DRIVER("Muxing encoder %s to CRTC %s: %d\n",
+encoder->name, encoder->crtc->name, ret);
 }
 EXPORT_SYMBOL(sun4i_tcon_set_mux);
 
@@ -767,9 +760,26 @@ static int sun4i_tcon_remove(struct platform_device *pdev)
return 0;
 }
 
+/* platform specific TCON muxing callbacks */
+static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon,
+ struct drm_encoder *encoder)
+{
+   u32 val;
+
+   if (encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)
+   val = 1;
+   else
+   val = 0;
+
+   /*
+* FIXME: Undocumented bits
+*/
+   return regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val);
+}
+
 static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
-   .has_unknown_mux = true,
-   .has_channel_1  = true,
+   .has_channel_1  = true,
+   .set_mux= sun5i_a13_tcon_set_mux,
 };
 
 static const struct sun4i_tcon_quirks sun6i_a31_quirks = {
diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h 
b/drivers/gpu/drm/sun4i/sun4i_tcon.h
index 5a219d1ccc26..d9e1357cc8ae 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h
@@ -145,10 +145,14 @@
 
 #define SUN4I_TCON_MAX_CHANNELS2
 
+struct sun4i_tcon;
+
 struct sun4i_tcon_quirks {
-   boolhas_unknown_mux; /* sun5i has undocumented mux */
boolhas_channel_1;  /* a33 does not have channel 1 */
boolneeds_de_be_mux; /* sun6i needs mux to select backend */
+
+   /* callback to handle tcon muxing options */
+   int (*set_mux)(struct sun4i_tcon *, struct drm_encoder *);
 };
 
 struct sun4i_tcon {
-- 
2.14.2



[PATCH v4 03/11] drm/sun4i: hdmi: Disable clks in bind function error path and unbind function

2017-10-09 Thread Chen-Yu Tsai
The HDMI driver enables the bus and mod clocks in the bind function, but
does not disable them if it then bails our due to any errors. Neither
does it disable the clocks in the unbind function.

Fix this by adding a proper error path to the bind function, and
clk_disable_unprepare calls to the unbind function.

Also rename the err_cleanup_connector label to err_cleanup_encoder,
since it is the encoder that gets cleaned up.

Fixes: 9c5681011a0c ("drm/sun4i: Add HDMI support")
Signed-off-by: Chen-Yu Tsai 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 19 ++-
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 9ea6cd5a1370..3cf1a6932fac 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -302,26 +302,29 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
hdmi->mod_clk = devm_clk_get(dev, "mod");
if (IS_ERR(hdmi->mod_clk)) {
dev_err(dev, "Couldn't get the HDMI mod clock\n");
-   return PTR_ERR(hdmi->mod_clk);
+   ret = PTR_ERR(hdmi->mod_clk);
+   goto err_disable_bus_clk;
}
clk_prepare_enable(hdmi->mod_clk);
 
hdmi->pll0_clk = devm_clk_get(dev, "pll-0");
if (IS_ERR(hdmi->pll0_clk)) {
dev_err(dev, "Couldn't get the HDMI PLL 0 clock\n");
-   return PTR_ERR(hdmi->pll0_clk);
+   ret = PTR_ERR(hdmi->pll0_clk);
+   goto err_disable_mod_clk;
}
 
hdmi->pll1_clk = devm_clk_get(dev, "pll-1");
if (IS_ERR(hdmi->pll1_clk)) {
dev_err(dev, "Couldn't get the HDMI PLL 1 clock\n");
-   return PTR_ERR(hdmi->pll1_clk);
+   ret = PTR_ERR(hdmi->pll1_clk);
+   goto err_disable_mod_clk;
}
 
ret = sun4i_tmds_create(hdmi);
if (ret) {
dev_err(dev, "Couldn't create the TMDS clock\n");
-   return ret;
+   goto err_disable_mod_clk;
}
 
writel(SUN4I_HDMI_CTRL_ENABLE, hdmi->base + SUN4I_HDMI_CTRL_REG);
@@ -362,7 +365,7 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
ret = sun4i_hdmi_i2c_create(dev, hdmi);
if (ret) {
dev_err(dev, "Couldn't create the HDMI I2C adapter\n");
-   return ret;
+   goto err_disable_mod_clk;
}
 
drm_encoder_helper_add(>encoder,
@@ -422,6 +425,10 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
drm_encoder_cleanup(>encoder);
 err_del_i2c_adapter:
i2c_del_adapter(hdmi->i2c);
+err_disable_mod_clk:
+   clk_disable_unprepare(hdmi->mod_clk);
+err_disable_bus_clk:
+   clk_disable_unprepare(hdmi->bus_clk);
return ret;
 }
 
@@ -434,6 +441,8 @@ static void sun4i_hdmi_unbind(struct device *dev, struct 
device *master,
drm_connector_cleanup(>connector);
drm_encoder_cleanup(>encoder);
i2c_del_adapter(hdmi->i2c);
+   clk_disable_unprepare(hdmi->mod_clk);
+   clk_disable_unprepare(hdmi->bus_clk);
 }
 
 static const struct component_ops sun4i_hdmi_ops = {
-- 
2.14.2



[PATCH v4 06/11] dt-bindings: display: sun4i: Add binding for A31 HDMI controller

2017-10-09 Thread Chen-Yu Tsai
The HDMI controller in the A31 SoC is slightly different from the
earlier version. In addition to the TMDS clock and DDC controls,
this version now takes a second DDC clock input.

Add a compatible string for it, and add the DDC clock input to the
list of clocks required.

Signed-off-by: Chen-Yu Tsai 
Acked-by: Rob Herring 
---
 Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt 
b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 92441086caba..46df3b78ae9e 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -41,14 +41,17 @@ CEC. It is one end of the pipeline.
 Required properties:
   - compatible: value must be one of:
 * allwinner,sun5i-a10s-hdmi
+* allwinner,sun6i-a31-hdmi
   - reg: base address and size of memory-mapped region
   - interrupts: interrupt associated to this IP
   - clocks: phandles to the clocks feeding the HDMI encoder
 * ahb: the HDMI interface clock
 * mod: the HDMI module clock
+* ddc: the HDMI ddc clock (A31 only)
 * pll-0: the first video PLL
 * pll-1: the second video PLL
   - clock-names: the clock names mentioned above
+  - resets: phandle to the reset control for the HDMI encoder (A31 only)
   - dmas: phandles to the DMA channels used by the HDMI encoder
 * ddc-tx: The channel for DDC transmission
 * ddc-rx: The channel for DDC reception
-- 
2.14.2



[PATCH v4 06/11] dt-bindings: display: sun4i: Add binding for A31 HDMI controller

2017-10-09 Thread Chen-Yu Tsai
The HDMI controller in the A31 SoC is slightly different from the
earlier version. In addition to the TMDS clock and DDC controls,
this version now takes a second DDC clock input.

Add a compatible string for it, and add the DDC clock input to the
list of clocks required.

Signed-off-by: Chen-Yu Tsai 
Acked-by: Rob Herring 
---
 Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt 
b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
index 92441086caba..46df3b78ae9e 100644
--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
+++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt
@@ -41,14 +41,17 @@ CEC. It is one end of the pipeline.
 Required properties:
   - compatible: value must be one of:
 * allwinner,sun5i-a10s-hdmi
+* allwinner,sun6i-a31-hdmi
   - reg: base address and size of memory-mapped region
   - interrupts: interrupt associated to this IP
   - clocks: phandles to the clocks feeding the HDMI encoder
 * ahb: the HDMI interface clock
 * mod: the HDMI module clock
+* ddc: the HDMI ddc clock (A31 only)
 * pll-0: the first video PLL
 * pll-1: the second video PLL
   - clock-names: the clock names mentioned above
+  - resets: phandle to the reset control for the HDMI encoder (A31 only)
   - dmas: phandles to the DMA channels used by the HDMI encoder
 * ddc-tx: The channel for DDC transmission
 * ddc-rx: The channel for DDC reception
-- 
2.14.2



[PATCH v4 10/11] ARM: dts: sun6i: Add device node for HDMI controller

2017-10-09 Thread Chen-Yu Tsai
Now that we support the HDMI controller on the A31 SoC, we can add it
to the device tree.

This adds a device node for the HDMI controller, and the of_graph nodes
connecting it to the 2 TCONs.

Signed-off-by: Chen-Yu Tsai 
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 55 
 1 file changed, 55 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 93209cda28db..48b2382a18a9 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -289,6 +289,12 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
+
+   tcon0_out_hdmi: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = 
<_in_tcon0>;
+   allwinner,tcon-channel = <1>;
+   };
};
};
};
@@ -331,6 +337,12 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
+
+   tcon1_out_hdmi: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = 
<_in_tcon1>;
+   allwinner,tcon-channel = <1>;
+   };
};
};
};
@@ -411,6 +423,49 @@
#size-cells = <0>;
};
 
+   hdmi: hdmi@01c16000 {
+   compatible = "allwinner,sun6i-a31-hdmi";
+   reg = <0x01c16000 0x1000>;
+   interrupts = ;
+   clocks = < CLK_AHB1_HDMI>, < CLK_HDMI>,
+< CLK_HDMI_DDC>,
+< CLK_PLL_VIDEO0_2X>,
+< CLK_PLL_VIDEO1_2X>;
+   clock-names = "ahb", "mod", "ddc", "pll-0", "pll-1";
+   resets = < RST_AHB1_HDMI>;
+   reset-names = "ahb";
+   dma-names = "ddc-tx", "ddc-rx", "audio-tx";
+   dmas = < 13>, < 13>, < 14>;
+   status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   hdmi_in: port@0 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reg = <0>;
+
+   hdmi_in_tcon0: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = 
<_out_hdmi>;
+   };
+
+   hdmi_in_tcon1: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = 
<_out_hdmi>;
+   };
+   };
+
+   hdmi_out: port@1 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reg = <1>;
+   };
+   };
+   };
+
usb_otg: usb@01c19000 {
compatible = "allwinner,sun6i-a31-musb";
reg = <0x01c19000 0x0400>;
-- 
2.14.2



[PATCH v4 05/11] drm/sun4i: hdmi: Allow using second PLL as TMDS clk parent

2017-10-09 Thread Chen-Yu Tsai
On SoCs with two display pipelines, it is possible that the two
pipelines are active at the same time, with potentially incompatible
dot clocks.

Let the HDMI encoder's TMDS clock go through all of its parents when
calculating possible clock rates. This allows usage of the second video
PLL as its parent.

Signed-off-by: Chen-Yu Tsai 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 53 -
 1 file changed, 29 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c 
b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
index 5cf2527bffc8..e8d4c311b80d 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
@@ -67,11 +67,11 @@ static unsigned long sun4i_tmds_calc_divider(unsigned long 
rate,
 static int sun4i_tmds_determine_rate(struct clk_hw *hw,
 struct clk_rate_request *req)
 {
-   struct clk_hw *parent;
+   struct clk_hw *parent = NULL;
unsigned long best_parent = 0;
unsigned long rate = req->rate;
int best_div = 1, best_half = 1;
-   int i, j;
+   int i, j, p;
 
/*
 * We only consider PLL3, since the TCON is very likely to be
@@ -79,32 +79,37 @@ static int sun4i_tmds_determine_rate(struct clk_hw *hw,
 * clock, so we should not need to do anything.
 */
 
-   parent = clk_hw_get_parent_by_index(hw, 0);
-   if (!parent)
-   return -EINVAL;
-
-   for (i = 1; i < 3; i++) {
-   for (j = 1; j < 16; j++) {
-   unsigned long ideal = rate * i * j;
-   unsigned long rounded;
-
-   rounded = clk_hw_round_rate(parent, ideal);
-
-   if (rounded == ideal) {
-   best_parent = rounded;
-   best_half = i;
-   best_div = j;
-   goto out;
-   }
-
-   if (abs(rate - rounded / i) <
-   abs(rate - best_parent / best_div)) {
-   best_parent = rounded;
-   best_div = i;
+   for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
+   parent = clk_hw_get_parent_by_index(hw, p);
+   if (!parent)
+   continue;
+
+   for (i = 1; i < 3; i++) {
+   for (j = 1; j < 16; j++) {
+   unsigned long ideal = rate * i * j;
+   unsigned long rounded;
+
+   rounded = clk_hw_round_rate(parent, ideal);
+
+   if (rounded == ideal) {
+   best_parent = rounded;
+   best_half = i;
+   best_div = j;
+   goto out;
+   }
+
+   if (abs(rate - rounded / i) <
+   abs(rate - best_parent / best_div)) {
+   best_parent = rounded;
+   best_div = i;
+   }
}
}
}
 
+   if (!parent)
+   return -EINVAL;
+
 out:
req->rate = best_parent / best_half / best_div;
req->best_parent_rate = best_parent;
-- 
2.14.2



[PATCH v4 10/11] ARM: dts: sun6i: Add device node for HDMI controller

2017-10-09 Thread Chen-Yu Tsai
Now that we support the HDMI controller on the A31 SoC, we can add it
to the device tree.

This adds a device node for the HDMI controller, and the of_graph nodes
connecting it to the 2 TCONs.

Signed-off-by: Chen-Yu Tsai 
---
 arch/arm/boot/dts/sun6i-a31.dtsi | 55 
 1 file changed, 55 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 93209cda28db..48b2382a18a9 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -289,6 +289,12 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
+
+   tcon0_out_hdmi: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = 
<_in_tcon0>;
+   allwinner,tcon-channel = <1>;
+   };
};
};
};
@@ -331,6 +337,12 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
+
+   tcon1_out_hdmi: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = 
<_in_tcon1>;
+   allwinner,tcon-channel = <1>;
+   };
};
};
};
@@ -411,6 +423,49 @@
#size-cells = <0>;
};
 
+   hdmi: hdmi@01c16000 {
+   compatible = "allwinner,sun6i-a31-hdmi";
+   reg = <0x01c16000 0x1000>;
+   interrupts = ;
+   clocks = < CLK_AHB1_HDMI>, < CLK_HDMI>,
+< CLK_HDMI_DDC>,
+< CLK_PLL_VIDEO0_2X>,
+< CLK_PLL_VIDEO1_2X>;
+   clock-names = "ahb", "mod", "ddc", "pll-0", "pll-1";
+   resets = < RST_AHB1_HDMI>;
+   reset-names = "ahb";
+   dma-names = "ddc-tx", "ddc-rx", "audio-tx";
+   dmas = < 13>, < 13>, < 14>;
+   status = "disabled";
+
+   ports {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   hdmi_in: port@0 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reg = <0>;
+
+   hdmi_in_tcon0: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = 
<_out_hdmi>;
+   };
+
+   hdmi_in_tcon1: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = 
<_out_hdmi>;
+   };
+   };
+
+   hdmi_out: port@1 {
+   #address-cells = <1>;
+   #size-cells = <0>;
+   reg = <1>;
+   };
+   };
+   };
+
usb_otg: usb@01c19000 {
compatible = "allwinner,sun6i-a31-musb";
reg = <0x01c19000 0x0400>;
-- 
2.14.2



[PATCH v4 05/11] drm/sun4i: hdmi: Allow using second PLL as TMDS clk parent

2017-10-09 Thread Chen-Yu Tsai
On SoCs with two display pipelines, it is possible that the two
pipelines are active at the same time, with potentially incompatible
dot clocks.

Let the HDMI encoder's TMDS clock go through all of its parents when
calculating possible clock rates. This allows usage of the second video
PLL as its parent.

Signed-off-by: Chen-Yu Tsai 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c | 53 -
 1 file changed, 29 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c 
b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
index 5cf2527bffc8..e8d4c311b80d 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c
@@ -67,11 +67,11 @@ static unsigned long sun4i_tmds_calc_divider(unsigned long 
rate,
 static int sun4i_tmds_determine_rate(struct clk_hw *hw,
 struct clk_rate_request *req)
 {
-   struct clk_hw *parent;
+   struct clk_hw *parent = NULL;
unsigned long best_parent = 0;
unsigned long rate = req->rate;
int best_div = 1, best_half = 1;
-   int i, j;
+   int i, j, p;
 
/*
 * We only consider PLL3, since the TCON is very likely to be
@@ -79,32 +79,37 @@ static int sun4i_tmds_determine_rate(struct clk_hw *hw,
 * clock, so we should not need to do anything.
 */
 
-   parent = clk_hw_get_parent_by_index(hw, 0);
-   if (!parent)
-   return -EINVAL;
-
-   for (i = 1; i < 3; i++) {
-   for (j = 1; j < 16; j++) {
-   unsigned long ideal = rate * i * j;
-   unsigned long rounded;
-
-   rounded = clk_hw_round_rate(parent, ideal);
-
-   if (rounded == ideal) {
-   best_parent = rounded;
-   best_half = i;
-   best_div = j;
-   goto out;
-   }
-
-   if (abs(rate - rounded / i) <
-   abs(rate - best_parent / best_div)) {
-   best_parent = rounded;
-   best_div = i;
+   for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
+   parent = clk_hw_get_parent_by_index(hw, p);
+   if (!parent)
+   continue;
+
+   for (i = 1; i < 3; i++) {
+   for (j = 1; j < 16; j++) {
+   unsigned long ideal = rate * i * j;
+   unsigned long rounded;
+
+   rounded = clk_hw_round_rate(parent, ideal);
+
+   if (rounded == ideal) {
+   best_parent = rounded;
+   best_half = i;
+   best_div = j;
+   goto out;
+   }
+
+   if (abs(rate - rounded / i) <
+   abs(rate - best_parent / best_div)) {
+   best_parent = rounded;
+   best_div = i;
+   }
}
}
}
 
+   if (!parent)
+   return -EINVAL;
+
 out:
req->rate = best_parent / best_half / best_div;
req->best_parent_rate = best_parent;
-- 
2.14.2



[PATCH v4 11/11] ARM: dts: sun6i: Enable HDMI support on some A31/A31s devices

2017-10-09 Thread Chen-Yu Tsai
All the A31/A31s devices I own have some kind of HDMI connector wired
to the dedicated HDMI pins on the SoC:

  - A31 Hummingbird (standard HDMI connector, display already enabled)
  - Sinlinx SinA31s (standard HDMI connector)
  - MSI Primo81 tablet (micro HDMI connector)

Enable the display pipeline (if needed) and HDMI output for them.

Signed-off-by: Chen-Yu Tsai 
---
 arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 21 +
 arch/arm/boot/dts/sun6i-a31s-primo81.dts| 25 +
 arch/arm/boot/dts/sun6i-a31s-sina31s.dts| 25 +
 3 files changed, 71 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts 
b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
index 9ecb5f0b3f83..19e382a11297 100644
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -62,6 +62,17 @@
stdout-path = "serial0:115200n8";
};
 
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
vga-connector {
compatible = "vga-connector";
 
@@ -162,6 +173,16 @@
};
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts 
b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
index 4c10123509c4..0cdb38ab3377 100644
--- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
@@ -52,17 +52,42 @@
 / {
model = "MSI Primo81 tablet";
compatible = "msi,primo81", "allwinner,sun6i-a31s";
+
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "c";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
 };
 
  {
cpu-supply = <_dcdc3>;
 };
 
+ {
+   status = "okay";
+};
+
  {
/* rtl8188etv wifi is connected here */
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
/* pull-ups and device VDDIO use AXP221 DLDO3 */
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts 
b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
index b3d98222bd81..298476485bb4 100644
--- a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
@@ -53,6 +53,17 @@
stdout-path = "serial0:115200n8";
};
 
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -90,6 +101,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
/* USB 2.0 4 port hub IC */
status = "okay";
@@ -112,6 +127,16 @@
};
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
-- 
2.14.2



[PATCH v4 11/11] ARM: dts: sun6i: Enable HDMI support on some A31/A31s devices

2017-10-09 Thread Chen-Yu Tsai
All the A31/A31s devices I own have some kind of HDMI connector wired
to the dedicated HDMI pins on the SoC:

  - A31 Hummingbird (standard HDMI connector, display already enabled)
  - Sinlinx SinA31s (standard HDMI connector)
  - MSI Primo81 tablet (micro HDMI connector)

Enable the display pipeline (if needed) and HDMI output for them.

Signed-off-by: Chen-Yu Tsai 
---
 arch/arm/boot/dts/sun6i-a31-hummingbird.dts | 21 +
 arch/arm/boot/dts/sun6i-a31s-primo81.dts| 25 +
 arch/arm/boot/dts/sun6i-a31s-sina31s.dts| 25 +
 3 files changed, 71 insertions(+)

diff --git a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts 
b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
index 9ecb5f0b3f83..19e382a11297 100644
--- a/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
+++ b/arch/arm/boot/dts/sun6i-a31-hummingbird.dts
@@ -62,6 +62,17 @@
stdout-path = "serial0:115200n8";
};
 
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
vga-connector {
compatible = "vga-connector";
 
@@ -162,6 +173,16 @@
};
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts 
b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
index 4c10123509c4..0cdb38ab3377 100644
--- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
@@ -52,17 +52,42 @@
 / {
model = "MSI Primo81 tablet";
compatible = "msi,primo81", "allwinner,sun6i-a31s";
+
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "c";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
 };
 
  {
cpu-supply = <_dcdc3>;
 };
 
+ {
+   status = "okay";
+};
+
  {
/* rtl8188etv wifi is connected here */
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
/* pull-ups and device VDDIO use AXP221 DLDO3 */
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts 
b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
index b3d98222bd81..298476485bb4 100644
--- a/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
+++ b/arch/arm/boot/dts/sun6i-a31s-sina31s.dts
@@ -53,6 +53,17 @@
stdout-path = "serial0:115200n8";
};
 
+   hdmi-connector {
+   compatible = "hdmi-connector";
+   type = "a";
+
+   port {
+   hdmi_con_in: endpoint {
+   remote-endpoint = <_out_con>;
+   };
+   };
+   };
+
leds {
compatible = "gpio-leds";
pinctrl-names = "default";
@@ -90,6 +101,10 @@
status = "okay";
 };
 
+ {
+   status = "okay";
+};
+
  {
/* USB 2.0 4 port hub IC */
status = "okay";
@@ -112,6 +127,16 @@
};
 };
 
+ {
+   status = "okay";
+};
+
+_out {
+   hdmi_out_con: endpoint {
+   remote-endpoint = <_con_in>;
+   };
+};
+
  {
pinctrl-names = "default";
pinctrl-0 = <_pins_a>;
-- 
2.14.2



[PATCH v4 08/11] drm/sun4i: hdmi: Add A31 specific DDC register definitions

2017-10-09 Thread Chen-Yu Tsai
The DDC block for the HDMI controller is different on the A31.

This patch adds the register definitions.

Signed-off-by: Chen-Yu Tsai 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi.h | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h 
b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index 3057e31219f6..ee42ae7e5a21 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -153,6 +153,37 @@
 
 #define SUN4I_HDMI_DDC_FIFO_SIZE   16
 
+/* A31 specific */
+#define SUN6I_HDMI_DDC_CTRL_REG0x500
+#define SUN6I_HDMI_DDC_CTRL_RESET  BIT(31)
+#define SUN6I_HDMI_DDC_CTRL_START_CMD  BIT(27)
+#define SUN6I_HDMI_DDC_CTRL_SDA_ENABLE BIT(6)
+#define SUN6I_HDMI_DDC_CTRL_SCL_ENABLE BIT(4)
+#define SUN6I_HDMI_DDC_CTRL_ENABLE BIT(0)
+
+#define SUN6I_HDMI_DDC_CMD_REG 0x508
+#define SUN6I_HDMI_DDC_CMD_BYTE_COUNT(count)   ((count) << 16)
+/* command types in lower 3 bits are the same as sun4i */
+
+#define SUN6I_HDMI_DDC_ADDR_REG0x50c
+#define SUN6I_HDMI_DDC_ADDR_SEGMENT(seg)   (((seg) & 0xff) << 24)
+#define SUN6I_HDMI_DDC_ADDR_EDDC(addr) (((addr) & 0xff) << 16)
+#define SUN6I_HDMI_DDC_ADDR_OFFSET(off)(((off) & 0xff) << 8)
+#define SUN6I_HDMI_DDC_ADDR_SLAVE(addr)(((addr) & 0xff) << 1)
+
+#define SUN6I_HDMI_DDC_INT_STATUS_REG  0x514
+#define SUN6I_HDMI_DDC_INT_STATUS_TIMEOUT  BIT(8)
+/* lower 8 bits are the same as sun4i */
+
+#define SUN6I_HDMI_DDC_FIFO_CTRL_REG   0x518
+#define SUN6I_HDMI_DDC_FIFO_CTRL_CLEAR BIT(15)
+/* lower 9 bits are the same as sun4i */
+
+#define SUN6I_HDMI_DDC_CLK_REG 0x520
+/* DDC CLK bit fields are the same, but the formula is not */
+
+#define SUN6I_HDMI_DDC_FIFO_DATA_REG   0x580
+
 enum sun4i_hdmi_pkt_type {
SUN4I_HDMI_PKT_AVI = 2,
SUN4I_HDMI_PKT_END = 15,
-- 
2.14.2



[PATCH v4 08/11] drm/sun4i: hdmi: Add A31 specific DDC register definitions

2017-10-09 Thread Chen-Yu Tsai
The DDC block for the HDMI controller is different on the A31.

This patch adds the register definitions.

Signed-off-by: Chen-Yu Tsai 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi.h | 31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h 
b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index 3057e31219f6..ee42ae7e5a21 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -153,6 +153,37 @@
 
 #define SUN4I_HDMI_DDC_FIFO_SIZE   16
 
+/* A31 specific */
+#define SUN6I_HDMI_DDC_CTRL_REG0x500
+#define SUN6I_HDMI_DDC_CTRL_RESET  BIT(31)
+#define SUN6I_HDMI_DDC_CTRL_START_CMD  BIT(27)
+#define SUN6I_HDMI_DDC_CTRL_SDA_ENABLE BIT(6)
+#define SUN6I_HDMI_DDC_CTRL_SCL_ENABLE BIT(4)
+#define SUN6I_HDMI_DDC_CTRL_ENABLE BIT(0)
+
+#define SUN6I_HDMI_DDC_CMD_REG 0x508
+#define SUN6I_HDMI_DDC_CMD_BYTE_COUNT(count)   ((count) << 16)
+/* command types in lower 3 bits are the same as sun4i */
+
+#define SUN6I_HDMI_DDC_ADDR_REG0x50c
+#define SUN6I_HDMI_DDC_ADDR_SEGMENT(seg)   (((seg) & 0xff) << 24)
+#define SUN6I_HDMI_DDC_ADDR_EDDC(addr) (((addr) & 0xff) << 16)
+#define SUN6I_HDMI_DDC_ADDR_OFFSET(off)(((off) & 0xff) << 8)
+#define SUN6I_HDMI_DDC_ADDR_SLAVE(addr)(((addr) & 0xff) << 1)
+
+#define SUN6I_HDMI_DDC_INT_STATUS_REG  0x514
+#define SUN6I_HDMI_DDC_INT_STATUS_TIMEOUT  BIT(8)
+/* lower 8 bits are the same as sun4i */
+
+#define SUN6I_HDMI_DDC_FIFO_CTRL_REG   0x518
+#define SUN6I_HDMI_DDC_FIFO_CTRL_CLEAR BIT(15)
+/* lower 9 bits are the same as sun4i */
+
+#define SUN6I_HDMI_DDC_CLK_REG 0x520
+/* DDC CLK bit fields are the same, but the formula is not */
+
+#define SUN6I_HDMI_DDC_FIFO_DATA_REG   0x580
+
 enum sun4i_hdmi_pkt_type {
SUN4I_HDMI_PKT_AVI = 2,
SUN4I_HDMI_PKT_END = 15,
-- 
2.14.2



[PATCH v4 04/11] drm/sun4i: hdmi: create a regmap for later use

2017-10-09 Thread Chen-Yu Tsai
The HDMI driver is written with readl/writel I/O to the registers.
However, to support the A31 variant, which has a different layout
for the DDC registers, it was recommended to use regfields to have
a cleaner implementation. To use regfields, we need to create an
underlying regmap.

This patch only adds the regmap. It does not convert the existing
driver accesses to use regmap.

Signed-off-by: Chen-Yu Tsai 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi.h |  1 +
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 15 +++
 2 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h 
b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index a1f8cba251a2..aef157d3b659 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -163,6 +163,7 @@ struct sun4i_hdmi {
struct device   *dev;
 
void __iomem*base;
+   struct regmap   *regmap;
 
/* Parent clocks */
struct clk  *bus_clk;
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 3cf1a6932fac..5ab811cda00e 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sun4i_backend.h"
 #include "sun4i_crtc.h"
@@ -267,6 +268,13 @@ static const struct cec_pin_ops sun4i_hdmi_cec_pin_ops = {
 };
 #endif
 
+static const struct regmap_config sun4i_hdmi_regmap_config = {
+   .reg_bits   = 32,
+   .val_bits   = 32,
+   .reg_stride = 4,
+   .max_register   = 0x580,
+};
+
 static int sun4i_hdmi_bind(struct device *dev, struct device *master,
   void *data)
 {
@@ -321,6 +329,13 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
goto err_disable_mod_clk;
}
 
+   hdmi->regmap = devm_regmap_init_mmio(dev, hdmi->base,
+_hdmi_regmap_config);
+   if (IS_ERR(hdmi->regmap)) {
+   dev_err(dev, "Couldn't create HDMI encoder regmap\n");
+   return PTR_ERR(hdmi->regmap);
+   }
+
ret = sun4i_tmds_create(hdmi);
if (ret) {
dev_err(dev, "Couldn't create the TMDS clock\n");
-- 
2.14.2



[PATCH v4 04/11] drm/sun4i: hdmi: create a regmap for later use

2017-10-09 Thread Chen-Yu Tsai
The HDMI driver is written with readl/writel I/O to the registers.
However, to support the A31 variant, which has a different layout
for the DDC registers, it was recommended to use regfields to have
a cleaner implementation. To use regfields, we need to create an
underlying regmap.

This patch only adds the regmap. It does not convert the existing
driver accesses to use regmap.

Signed-off-by: Chen-Yu Tsai 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi.h |  1 +
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 15 +++
 2 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h 
b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index a1f8cba251a2..aef157d3b659 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -163,6 +163,7 @@ struct sun4i_hdmi {
struct device   *dev;
 
void __iomem*base;
+   struct regmap   *regmap;
 
/* Parent clocks */
struct clk  *bus_clk;
diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c 
b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 3cf1a6932fac..5ab811cda00e 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "sun4i_backend.h"
 #include "sun4i_crtc.h"
@@ -267,6 +268,13 @@ static const struct cec_pin_ops sun4i_hdmi_cec_pin_ops = {
 };
 #endif
 
+static const struct regmap_config sun4i_hdmi_regmap_config = {
+   .reg_bits   = 32,
+   .val_bits   = 32,
+   .reg_stride = 4,
+   .max_register   = 0x580,
+};
+
 static int sun4i_hdmi_bind(struct device *dev, struct device *master,
   void *data)
 {
@@ -321,6 +329,13 @@ static int sun4i_hdmi_bind(struct device *dev, struct 
device *master,
goto err_disable_mod_clk;
}
 
+   hdmi->regmap = devm_regmap_init_mmio(dev, hdmi->base,
+_hdmi_regmap_config);
+   if (IS_ERR(hdmi->regmap)) {
+   dev_err(dev, "Couldn't create HDMI encoder regmap\n");
+   return PTR_ERR(hdmi->regmap);
+   }
+
ret = sun4i_tmds_create(hdmi);
if (ret) {
dev_err(dev, "Couldn't create the TMDS clock\n");
-- 
2.14.2



[PATCH v4 07/11] drm/sun4i: hdmi: Add support for controller hardware variants

2017-10-09 Thread Chen-Yu Tsai
The HDMI controller found in earlier Allwinner SoCs have slight
differences between the A10, A10s, and the A31:

  - Need different initial values for the PLL related registers

  - Different behavior of the DDC and TMDS clocks

  - Different register layout for the DDC portion

  - Separate DDC parent clock on the A31

  - Explicit reset control

For the A31, the HDMI TMDS clock has a different value offset for
the divider. The HDMI DDC block is different from the one in the
other SoCs. As far as the DDC clock goes, it has no pre-divider,
as it is clocked from a slower parent clock, not the TMDS clock.
The divider offset from the register value is different. And the
clock control register is at a different offset.

A new variant data structure is created to store pointers to the
above functions, structures, and the different initial values.
Another flag notates whether there is a separate DDC parent clock.
If not, the TMDS clock is passed to the DDC clock create function,
as before.

Regmap fields are used to deal with the different register layout
of the DDC block.

Signed-off-by: Chen-Yu Tsai 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/sun4i/sun4i_hdmi.h  |  72 +
 drivers/gpu/drm/sun4i/sun4i_hdmi_ddc_clk.c  |  38 +++--
 drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c  | 112 +++---
 drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c  | 227 
 drivers/gpu/drm/sun4i/sun4i_hdmi_tmds_clk.c |  17 ++-
 5 files changed, 369 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h 
b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
index aef157d3b659..3057e31219f6 100644
--- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h
@@ -14,6 +14,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -157,6 +158,55 @@ enum sun4i_hdmi_pkt_type {
SUN4I_HDMI_PKT_END = 15,
 };
 
+struct sun4i_hdmi_variant {
+   bool has_ddc_parent_clk;
+   bool has_reset_control;
+
+   u32 pad_ctrl0_init_val;
+   u32 pad_ctrl1_init_val;
+   u32 pll_ctrl_init_val;
+
+   struct reg_field ddc_clk_reg;
+   u8 ddc_clk_pre_divider;
+   u8 ddc_clk_m_offset;
+
+   u8 tmds_clk_div_offset;
+
+   /* Register fields for I2C adapter */
+   struct reg_fieldfield_ddc_en;
+   struct reg_fieldfield_ddc_start;
+   struct reg_fieldfield_ddc_reset;
+   struct reg_fieldfield_ddc_addr_reg;
+   struct reg_fieldfield_ddc_slave_addr;
+   struct reg_fieldfield_ddc_int_mask;
+   struct reg_fieldfield_ddc_int_status;
+   struct reg_fieldfield_ddc_fifo_clear;
+   struct reg_fieldfield_ddc_fifo_rx_thres;
+   struct reg_fieldfield_ddc_fifo_tx_thres;
+   struct reg_fieldfield_ddc_byte_count;
+   struct reg_fieldfield_ddc_cmd;
+   struct reg_fieldfield_ddc_sda_en;
+   struct reg_fieldfield_ddc_sck_en;
+
+   /* DDC FIFO register offset */
+   u32 ddc_fifo_reg;
+
+   /*
+* DDC FIFO threshold boundary conditions
+*
+* This is used to cope with the threshold boundary condition
+* being slightly different on sun5i and sun6i.
+*
+* On sun5i the threshold is exclusive, i.e. does not include,
+* the value of the threshold. ( > for RX; < for TX )
+* On sun6i the threshold is inclusive, i.e. includes, the
+* value of the threshold. ( >= for RX; <= for TX )
+*/
+   boolddc_fifo_thres_incl;
+
+   boolddc_fifo_has_dir;
+};
+
 struct sun4i_hdmi {
struct drm_connectorconnector;
struct drm_encoder  encoder;
@@ -165,9 +215,13 @@ struct sun4i_hdmi {
void __iomem*base;
struct regmap   *regmap;
 
+   /* Reset control */
+   struct reset_control*reset;
+
/* Parent clocks */
struct clk  *bus_clk;
struct clk  *mod_clk;
+   struct clk  *ddc_parent_clk;
struct clk  *pll0_clk;
struct clk  *pll1_clk;
 
@@ -177,10 +231,28 @@ struct sun4i_hdmi {
 
struct i2c_adapter  *i2c;
 
+   /* Regmap fields for I2C adapter */
+   struct regmap_field *field_ddc_en;
+   struct regmap_field *field_ddc_start;
+   struct regmap_field *field_ddc_reset;
+   struct regmap_field *field_ddc_addr_reg;
+   struct regmap_field *field_ddc_slave_addr;
+   struct regmap_field *field_ddc_int_mask;
+   struct regmap_field *field_ddc_int_status;
+   struct regmap_field *field_ddc_fifo_clear;
+   struct regmap_field *field_ddc_fifo_rx_thres;
+   struct regmap_field *field_ddc_fifo_tx_thres;
+   struct regmap_field *field_ddc_byte_count;
+   struct 

[PATCH v4 02/11] drm/sun4i: tcon: Add support for demuxing TCON output on A31

2017-10-09 Thread Chen-Yu Tsai
On systems with 2 TCONs such as the A31, it is possible to demux the
output of the TCONs to one encoder.

Add support for this for the A31.

Signed-off-by: Chen-Yu Tsai 
---
 drivers/gpu/drm/sun4i/sun4i_tcon.c | 47 ++
 1 file changed, 47 insertions(+)

diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c 
b/drivers/gpu/drm/sun4i/sun4i_tcon.c
index 75124043d655..68751b999877 100644
--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
+++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
@@ -112,6 +112,27 @@ void sun4i_tcon_enable_vblank(struct sun4i_tcon *tcon, 
bool enable)
 }
 EXPORT_SYMBOL(sun4i_tcon_enable_vblank);
 
+/*
+ * This function is a helper for TCON output muxing. The TCON output
+ * muxing control register in earlier SoCs (without the TCON TOP block)
+ * are located in TCON0. This helper returns a pointer to TCON0's
+ * sun4i_tcon structure, or NULL if not found.
+ */
+static struct sun4i_tcon *sun4i_get_tcon0(struct drm_device *drm)
+{
+   struct sun4i_drv *drv = drm->dev_private;
+   struct sun4i_tcon *tcon;
+
+   list_for_each_entry(tcon, >tcon_list, list)
+   if (tcon->id == 0)
+   return tcon;
+
+   dev_warn(drm->dev,
+"TCON0 not found, display output muxing may not work\n");
+
+   return NULL;
+}
+
 void sun4i_tcon_set_mux(struct sun4i_tcon *tcon, int channel,
struct drm_encoder *encoder)
 {
@@ -777,6 +798,31 @@ static int sun5i_a13_tcon_set_mux(struct sun4i_tcon *tcon,
return regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, val);
 }
 
+static int sun6i_tcon_set_mux(struct sun4i_tcon *tcon,
+ struct drm_encoder *encoder)
+{
+   struct sun4i_tcon *tcon0 = sun4i_get_tcon0(encoder->dev);
+   u32 shift;
+
+   if (!tcon0)
+   return -EINVAL;
+
+   switch (encoder->encoder_type) {
+   case DRM_MODE_ENCODER_TMDS:
+   /* HDMI */
+   shift = 8;
+   break;
+   default:
+   /* TODO A31 has MIPI DSI but A31s does not */
+   return -EINVAL;
+   }
+
+   regmap_update_bits(tcon0->regs, SUN4I_TCON_MUX_CTRL_REG,
+  0x3 << shift, tcon->id << shift);
+
+   return 0;
+}
+
 static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
.has_channel_1  = true,
.set_mux= sun5i_a13_tcon_set_mux,
@@ -785,6 +831,7 @@ static const struct sun4i_tcon_quirks sun5i_a13_quirks = {
 static const struct sun4i_tcon_quirks sun6i_a31_quirks = {
.has_channel_1  = true,
.needs_de_be_mux= true,
+   .set_mux= sun6i_tcon_set_mux,
 };
 
 static const struct sun4i_tcon_quirks sun6i_a31s_quirks = {
-- 
2.14.2



  1   2   3   4   5   6   7   8   9   10   >