Re: [PATCH 1/2] f2fs: add missing quota_initialize in f2fs_set_acl

2017-10-24 Thread Chao Yu
On 2017/10/25 13:44, Jaegeuk Kim wrote:
> On 10/24, Chao Yu wrote:
>> On 2017/10/24 6:14, Jaegeuk Kim wrote:
>>> This patch adds to call quota_intialize in f2fs_set_acl.
>>>
>>> Signed-off-by: Jaegeuk Kim 
>>> ---
>>>  fs/f2fs/acl.c | 4 
>>>  1 file changed, 4 insertions(+)
>>>
>>> diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
>>> index 436b3a1464d9..f6471f9d707e 100644
>>> --- a/fs/f2fs/acl.c
>>> +++ b/fs/f2fs/acl.c
>>> @@ -209,6 +209,10 @@ static int __f2fs_set_acl(struct inode *inode, int 
>>> type,
>>> int error;
>>> umode_t mode = inode->i_mode;
>>>  
>>> +   error = dquot_initialize(inode);
>>> +   if (error)
>>> +   return error;
>>
>> Could you move this to f2fs_setxattr, and also add missing dquot_initialize 
>> in
>> unlink and rename like ext4?
> 
> I've checked that f2fs_unlink and f2fs_rename are calling dquot_initialize().

ext4_unlink:

retval = dquot_initialize(dir);
if (retval)
return retval;
retval = dquot_initialize(d_inode(dentry));
if (retval)
return retval;

f2fs_unlink:

err = dquot_initialize(dir);
if (err)
return err;

ext4_rename

retval = dquot_initialize(old.dir);
if (retval)
return retval;
retval = dquot_initialize(new.dir);
if (retval)
return retval;

/* Initialize quotas before so that eventual writes go
 * in separate transaction */
if (new.inode) {
retval = dquot_initialize(new.inode);
if (retval)
return retval;
}

f2fs_rename

err = dquot_initialize(old_dir);
if (err)
goto out;

err = dquot_initialize(new_dir);
if (err)
goto out;

ext4 call one more dquot_initialize than f2fs, I didn't look into this in
detail, but it's better to check that. :)

Thanks,
> 
> Thanks,
> 
>>
>> Thanks,
>>
>>> +
>>> switch (type) {
>>> case ACL_TYPE_ACCESS:
>>> name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
>>>
> 
> .
> 



Re: [PATCH 1/2] f2fs: add missing quota_initialize in f2fs_set_acl

2017-10-24 Thread Chao Yu
On 2017/10/25 13:44, Jaegeuk Kim wrote:
> On 10/24, Chao Yu wrote:
>> On 2017/10/24 6:14, Jaegeuk Kim wrote:
>>> This patch adds to call quota_intialize in f2fs_set_acl.
>>>
>>> Signed-off-by: Jaegeuk Kim 
>>> ---
>>>  fs/f2fs/acl.c | 4 
>>>  1 file changed, 4 insertions(+)
>>>
>>> diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
>>> index 436b3a1464d9..f6471f9d707e 100644
>>> --- a/fs/f2fs/acl.c
>>> +++ b/fs/f2fs/acl.c
>>> @@ -209,6 +209,10 @@ static int __f2fs_set_acl(struct inode *inode, int 
>>> type,
>>> int error;
>>> umode_t mode = inode->i_mode;
>>>  
>>> +   error = dquot_initialize(inode);
>>> +   if (error)
>>> +   return error;
>>
>> Could you move this to f2fs_setxattr, and also add missing dquot_initialize 
>> in
>> unlink and rename like ext4?
> 
> I've checked that f2fs_unlink and f2fs_rename are calling dquot_initialize().

ext4_unlink:

retval = dquot_initialize(dir);
if (retval)
return retval;
retval = dquot_initialize(d_inode(dentry));
if (retval)
return retval;

f2fs_unlink:

err = dquot_initialize(dir);
if (err)
return err;

ext4_rename

retval = dquot_initialize(old.dir);
if (retval)
return retval;
retval = dquot_initialize(new.dir);
if (retval)
return retval;

/* Initialize quotas before so that eventual writes go
 * in separate transaction */
if (new.inode) {
retval = dquot_initialize(new.inode);
if (retval)
return retval;
}

f2fs_rename

err = dquot_initialize(old_dir);
if (err)
goto out;

err = dquot_initialize(new_dir);
if (err)
goto out;

ext4 call one more dquot_initialize than f2fs, I didn't look into this in
detail, but it's better to check that. :)

Thanks,
> 
> Thanks,
> 
>>
>> Thanks,
>>
>>> +
>>> switch (type) {
>>> case ACL_TYPE_ACCESS:
>>> name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
>>>
> 
> .
> 



Re: [PATCH v3 8/8] block: Assign a lock_class per gendisk used for wait_for_completion()

2017-10-24 Thread Ingo Molnar

* Byungchul Park  wrote:

> > Isn't lockdep_map a zero size structure that is always defined? If yes then 
> > there's no need for an #ifdef.
> 
> No, a zero size structure for lockdep_map is not provided yet.
> There are two options I can do:
> 
> 1. Add a zero size structure for lockdep_map and remove #ifdef
> 2. Replace CONFIG_LOCKDEP_COMPLETIONS with CONFIG_LOCKDEP here.
> 
> Or something else?
> 
> Which one do you prefer?

Ok, could we try #1 in a new patch and re-spin the simplified block layer patch 
on 
top of that?

The less ugly a debug facility's impact on unrelated kernel is, the better - 
especially when it comes to annotating false positives.

Thanks,

Ingo


Re: [PATCH v3 8/8] block: Assign a lock_class per gendisk used for wait_for_completion()

2017-10-24 Thread Ingo Molnar

* Byungchul Park  wrote:

> > Isn't lockdep_map a zero size structure that is always defined? If yes then 
> > there's no need for an #ifdef.
> 
> No, a zero size structure for lockdep_map is not provided yet.
> There are two options I can do:
> 
> 1. Add a zero size structure for lockdep_map and remove #ifdef
> 2. Replace CONFIG_LOCKDEP_COMPLETIONS with CONFIG_LOCKDEP here.
> 
> Or something else?
> 
> Which one do you prefer?

Ok, could we try #1 in a new patch and re-spin the simplified block layer patch 
on 
top of that?

The less ugly a debug facility's impact on unrelated kernel is, the better - 
especially when it comes to annotating false positives.

Thanks,

Ingo


Re: [PATCH v2 6/6] f2fs: give up CP_TRIMMED_FLAG if it drops discards

2017-10-24 Thread Chao Yu
On 2017/10/25 13:45, Jaegeuk Kim wrote:
> On 10/24, Chao Yu wrote:
>> On 2017/10/24 20:46, Jaegeuk Kim wrote:
>>> On 10/24, Chao Yu wrote:
 Hi Jaegeuk,

 On 2017/10/4 9:08, Chao Yu wrote:
> From: Chao Yu 
>
> In ->umount, once we drop remained discard entries, we should not
> set CP_TRIMMED_FLAG with another checkpoint.
>
> Signed-off-by: Chao Yu 
> ---
> v2:
> - rebase on last codes of Jaegeuk's dev-test branch.
>  fs/f2fs/f2fs.h|  2 +-
>  fs/f2fs/segment.c | 15 +++
>  fs/f2fs/super.c   |  5 +++--
>  3 files changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index f274805e231d..c85f49c41003 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -2565,7 +2565,7 @@ void init_discard_policy(struct discard_policy 
> *dpolicy, int discard_type,
>   unsigned int granularity);
>  void refresh_sit_entry(struct f2fs_sb_info *sbi, block_t old, block_t 
> new);
>  void stop_discard_thread(struct f2fs_sb_info *sbi);
> -void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
> +bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
>  void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control 
> *cpc);
>  void release_discard_addrs(struct f2fs_sb_info *sbi);
>  int npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 4a108321233d..bfbcff8339c5 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -1196,12 +1196,13 @@ static int __issue_discard_cmd(struct 
> f2fs_sb_info *sbi,
>   return issued;
>  }
>  
> -static void __drop_discard_cmd(struct f2fs_sb_info *sbi)
> +static bool __drop_discard_cmd(struct f2fs_sb_info *sbi)
>  {
>   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
>   struct list_head *pend_list;
>   struct discard_cmd *dc, *tmp;
>   int i;
> + bool dropped = false;
>  
>   mutex_lock(>cmd_lock);
>   for (i = MAX_PLIST_NUM - 1; i >= 0; i--) {
> @@ -1209,9 +1210,12 @@ static void __drop_discard_cmd(struct f2fs_sb_info 
> *sbi)
>   list_for_each_entry_safe(dc, tmp, pend_list, list) {
>   f2fs_bug_on(sbi, dc->state != D_PREP);
>   __remove_discard_cmd(sbi, dc);
> + dropped = true;
>   }
>   }
>   mutex_unlock(>cmd_lock);
> +
> + return dropped;
>  }
>  
>  static void __wait_one_discard_bio(struct f2fs_sb_info *sbi,
> @@ -1306,15 +1310,18 @@ void stop_discard_thread(struct f2fs_sb_info *sbi)
>  }
>  
>  /* This comes from f2fs_put_super */
> -void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
> +bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
>  {
>   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
>   struct discard_policy dpolicy;
> + bool dropped;
>  
>   init_discard_policy(, DPOLICY_UMOUNT, dcc->discard_granularity);
>   __issue_discard_cmd(sbi, );
> - __drop_discard_cmd(sbi);
> + dropped = __drop_discard_cmd(sbi);
>   __wait_all_discard_cmd(sbi, );
> +
> + return dropped;
>  }
>  
>  static int issue_discard_thread(void *data)
> @@ -1659,7 +1666,7 @@ void init_discard_policy(struct discard_policy 
> *dpolicy,
>   dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
>   dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
>   dpolicy->io_aware_gran = MAX_PLIST_NUM;
> - dpolicy->io_aware = false;
> + dpolicy->io_aware = true;

 I notice this change should not belong to this patch, could you please 
 help to
 move this into "f2fs: split discard policy" in your branch?
>>>
>>> Yup, done. Could you check it in dev-test?
>>
>> I didn't find it, did you forget to push to that branch?
> 
> Yup, I pushed it. :)

I've checked that, it's OK to me now. :)

Thanks,

> 
> Thanks,
> 
>>
>> Thanks,
>>
>>>
>>> Thanks,
>>>

 Thanks,

>   } else if (discard_type == DPOLICY_FSTRIM) {
>   dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
>   dpolicy->io_aware_gran = MAX_PLIST_NUM;
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index a13269d1a1f0..1d68c18a487b 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -807,6 +807,7 @@ static void f2fs_put_super(struct super_block *sb)
>  {
>   struct f2fs_sb_info *sbi = F2FS_SB(sb);
>   int i;
> + bool dropped;
>  
>   f2fs_quota_off_umount(sb);
>  
> @@ -827,9 +828,9 @@ static void f2fs_put_super(struct super_block *sb)
>   }
>  
>   /* be sure to wait for any on-going discard commands */
> - f2fs_wait_discard_bios(sbi, 

Re: [PATCH v2 6/6] f2fs: give up CP_TRIMMED_FLAG if it drops discards

2017-10-24 Thread Chao Yu
On 2017/10/25 13:45, Jaegeuk Kim wrote:
> On 10/24, Chao Yu wrote:
>> On 2017/10/24 20:46, Jaegeuk Kim wrote:
>>> On 10/24, Chao Yu wrote:
 Hi Jaegeuk,

 On 2017/10/4 9:08, Chao Yu wrote:
> From: Chao Yu 
>
> In ->umount, once we drop remained discard entries, we should not
> set CP_TRIMMED_FLAG with another checkpoint.
>
> Signed-off-by: Chao Yu 
> ---
> v2:
> - rebase on last codes of Jaegeuk's dev-test branch.
>  fs/f2fs/f2fs.h|  2 +-
>  fs/f2fs/segment.c | 15 +++
>  fs/f2fs/super.c   |  5 +++--
>  3 files changed, 15 insertions(+), 7 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index f274805e231d..c85f49c41003 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -2565,7 +2565,7 @@ void init_discard_policy(struct discard_policy 
> *dpolicy, int discard_type,
>   unsigned int granularity);
>  void refresh_sit_entry(struct f2fs_sb_info *sbi, block_t old, block_t 
> new);
>  void stop_discard_thread(struct f2fs_sb_info *sbi);
> -void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
> +bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
>  void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control 
> *cpc);
>  void release_discard_addrs(struct f2fs_sb_info *sbi);
>  int npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 4a108321233d..bfbcff8339c5 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -1196,12 +1196,13 @@ static int __issue_discard_cmd(struct 
> f2fs_sb_info *sbi,
>   return issued;
>  }
>  
> -static void __drop_discard_cmd(struct f2fs_sb_info *sbi)
> +static bool __drop_discard_cmd(struct f2fs_sb_info *sbi)
>  {
>   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
>   struct list_head *pend_list;
>   struct discard_cmd *dc, *tmp;
>   int i;
> + bool dropped = false;
>  
>   mutex_lock(>cmd_lock);
>   for (i = MAX_PLIST_NUM - 1; i >= 0; i--) {
> @@ -1209,9 +1210,12 @@ static void __drop_discard_cmd(struct f2fs_sb_info 
> *sbi)
>   list_for_each_entry_safe(dc, tmp, pend_list, list) {
>   f2fs_bug_on(sbi, dc->state != D_PREP);
>   __remove_discard_cmd(sbi, dc);
> + dropped = true;
>   }
>   }
>   mutex_unlock(>cmd_lock);
> +
> + return dropped;
>  }
>  
>  static void __wait_one_discard_bio(struct f2fs_sb_info *sbi,
> @@ -1306,15 +1310,18 @@ void stop_discard_thread(struct f2fs_sb_info *sbi)
>  }
>  
>  /* This comes from f2fs_put_super */
> -void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
> +bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
>  {
>   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
>   struct discard_policy dpolicy;
> + bool dropped;
>  
>   init_discard_policy(, DPOLICY_UMOUNT, dcc->discard_granularity);
>   __issue_discard_cmd(sbi, );
> - __drop_discard_cmd(sbi);
> + dropped = __drop_discard_cmd(sbi);
>   __wait_all_discard_cmd(sbi, );
> +
> + return dropped;
>  }
>  
>  static int issue_discard_thread(void *data)
> @@ -1659,7 +1666,7 @@ void init_discard_policy(struct discard_policy 
> *dpolicy,
>   dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
>   dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
>   dpolicy->io_aware_gran = MAX_PLIST_NUM;
> - dpolicy->io_aware = false;
> + dpolicy->io_aware = true;

 I notice this change should not belong to this patch, could you please 
 help to
 move this into "f2fs: split discard policy" in your branch?
>>>
>>> Yup, done. Could you check it in dev-test?
>>
>> I didn't find it, did you forget to push to that branch?
> 
> Yup, I pushed it. :)

I've checked that, it's OK to me now. :)

Thanks,

> 
> Thanks,
> 
>>
>> Thanks,
>>
>>>
>>> Thanks,
>>>

 Thanks,

>   } else if (discard_type == DPOLICY_FSTRIM) {
>   dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
>   dpolicy->io_aware_gran = MAX_PLIST_NUM;
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index a13269d1a1f0..1d68c18a487b 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -807,6 +807,7 @@ static void f2fs_put_super(struct super_block *sb)
>  {
>   struct f2fs_sb_info *sbi = F2FS_SB(sb);
>   int i;
> + bool dropped;
>  
>   f2fs_quota_off_umount(sb);
>  
> @@ -827,9 +828,9 @@ static void f2fs_put_super(struct super_block *sb)
>   }
>  
>   /* be sure to wait for any on-going discard commands */
> - f2fs_wait_discard_bios(sbi, true);
> + dropped = 

Re: 492b95e597 ("rcuperf: Set more user-friendly defaults"): WARNING: CPU: 0 PID: 1 at arch/x86/kernel/smp.c:128 native_smp_send_reschedule

2017-10-24 Thread Fengguang Wu

Hi Paul,

On Tue, Oct 24, 2017 at 06:25:13AM -0700, Paul E. McKenney wrote:

On Tue, Oct 24, 2017 at 04:49:52AM +0200, Fengguang Wu 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 492b95e59735998312f678d77a2d5fe20af6b0b9
Author: Paul E. McKenney 
AuthorDate: Fri Apr 21 16:09:15 2017 -0700
Commit: Paul E. McKenney 
CommitDate: Thu Jun 8 08:25:31 2017 -0700

 rcuperf: Set more user-friendly defaults

 Common-case use of rcuperf must set rcuperf.nreaders=0 and if not built
 as a module, rcuperf.shutdown.  This commit therefore sets the default
 for rcuperf.nreaders to zero and sets the default for rcuperf.shutdown
 to zero if rcuperf is built as a module and to one otherwise.

 Signed-off-by: Paul E. McKenney 


I don't believe that this commit has anything to do with this, however,
this failure is rare, so bisection is unlikely to find anything.  I do
have a pair of commits that fix this in -rcu:

a54daabfde1a ("sched: Stop resched_cpu() from sending IPIs to offline CPUs")
e600277461ed ("sched: Stop switched_to_rt() from sending IPIs to offline CPUs")

Do these two commits prevent the problem on your systems?


Yeah the problem does not show up in rcu/dev HEAD fe368e2596 ("rcu:
Add comment giving debug strategy for double call_rcu()"). However
there are some kernel hang/reboots in early boot stage:

early console in setup code
Probing EDD (edd=off to disable)... ok
early console in extract_kernel
input_data: 0x045f9276
input_len: 0x00a2a66d
output: 0x0100
output_len: 0x02362830
kernel_total_size: 0x04043000

Decompressing Linux... Parsing ELF... done.
Booting the kernel.

Elapsed time: 10
BUG: kernel reboot-without-warning in boot stage
Linux version 4.14.0-rc4-00054-gfe368e2 #1
Command line: root=/dev/ram0 hung_task_panic=1 debug apic=debug 
sysrq_always_enabled rcupdate.rcu_cpu_stall_timeout=100 net.ifnames=0 
printk.devkmsg=on panic=-1 softlockup_panic=1 nmi_watchdog=panic oops=panic 
load_ramdisk=2 prompt_ramdisk=0 drbd.minor_count=8 systemd.log_level=err 
ignore_loglevel console=tty0 earlyprintk=ttyS0,115200 console=ttyS0,115200 
vga=normal rw 
link=/kbuild-tests/run-queue/kvm/x86_64-randconfig-a0-10221140/rcu:rcu:dev:fe368e2596a235ca15af01ebf203fca0594e01ea/.vmlinuz-fe368e2596a235ca15af01ebf203fca0594e01ea-20171024225823-78:quantal-intel12-27
 branch=rcu/rcu/dev 
BOOT_IMAGE=/pkg/linux/x86_64-randconfig-a0-10221140/gcc-6/fe368e2596a235ca15af01ebf203fca0594e01ea/vmlinuz-4.14.0-rc4-00054-gfe368e2
 drbd.minor_count=8

I'll try bisecting that error.

Thanks,
Fengguang


3ddf20c953  srcu: Shrink Tiny SRCU a bit more
492b95e597  rcuperf: Set more user-friendly defaults
bb176f6709  Linux 4.14-rc6
36ef71cae3  Add linux-next specific files for 20171018
+--+++---+---+
|  | 3ddf20c953 | 
492b95e597 | v4.14-rc6 | next-20171018 |
+--+++---+---+
| boot_successes   | 910| 
21 | 199   | 60|
| boot_failures| 0  | 9 
 | 111   | 21|
| WARNING:at_arch/x86/kernel/smp.c:#native_smp_send_reschedule | 0  | 9 
 | 111   | 21|
+--+++---+---+

[   29.173654] augmented rbtree testing
[   32.263469]  -> 83223 cycles
[   32.540332] gpio_it87: no device
[   32.541422] sched: Unexpected reschedule of offline CPU#1!
[   32.542355] [ cut here ]
[   32.543057] WARNING: CPU: 0 PID: 1 at arch/x86/kernel/smp.c:128 
native_smp_send_reschedule+0x83/0xbb
[   32.544646] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
4.12.0-rc4-00028-g492b95e #1
[   32.545397] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
1.10.2-1 04/01/2014
[   32.546381] task: 88001e2e task.stack: 88001e2e8000
[   32.547031] RIP: 0010:native_smp_send_reschedule+0x83/0xbb
[   32.547642] RSP: :88001e2ebca0 EFLAGS: 00010086
[   32.548225] RAX: 002e RBX: 0003 RCX: 
[   32.548989] RDX: 002e0001 RSI:  RDI: 0096
[   32.550034] RBP: 88001e2ebcb8 R08: 0003 R09: 
[   32.551039] R10: 88001e2e0758 R11: 00021001 R12: 0001
[   32.551996] R13:  R14: 88001e38 R15: 88001e50
[   32.552727] FS:  () GS:88001e40() 

Re: 492b95e597 ("rcuperf: Set more user-friendly defaults"): WARNING: CPU: 0 PID: 1 at arch/x86/kernel/smp.c:128 native_smp_send_reschedule

2017-10-24 Thread Fengguang Wu

Hi Paul,

On Tue, Oct 24, 2017 at 06:25:13AM -0700, Paul E. McKenney wrote:

On Tue, Oct 24, 2017 at 04:49:52AM +0200, Fengguang Wu 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 492b95e59735998312f678d77a2d5fe20af6b0b9
Author: Paul E. McKenney 
AuthorDate: Fri Apr 21 16:09:15 2017 -0700
Commit: Paul E. McKenney 
CommitDate: Thu Jun 8 08:25:31 2017 -0700

 rcuperf: Set more user-friendly defaults

 Common-case use of rcuperf must set rcuperf.nreaders=0 and if not built
 as a module, rcuperf.shutdown.  This commit therefore sets the default
 for rcuperf.nreaders to zero and sets the default for rcuperf.shutdown
 to zero if rcuperf is built as a module and to one otherwise.

 Signed-off-by: Paul E. McKenney 


I don't believe that this commit has anything to do with this, however,
this failure is rare, so bisection is unlikely to find anything.  I do
have a pair of commits that fix this in -rcu:

a54daabfde1a ("sched: Stop resched_cpu() from sending IPIs to offline CPUs")
e600277461ed ("sched: Stop switched_to_rt() from sending IPIs to offline CPUs")

Do these two commits prevent the problem on your systems?


Yeah the problem does not show up in rcu/dev HEAD fe368e2596 ("rcu:
Add comment giving debug strategy for double call_rcu()"). However
there are some kernel hang/reboots in early boot stage:

early console in setup code
Probing EDD (edd=off to disable)... ok
early console in extract_kernel
input_data: 0x045f9276
input_len: 0x00a2a66d
output: 0x0100
output_len: 0x02362830
kernel_total_size: 0x04043000

Decompressing Linux... Parsing ELF... done.
Booting the kernel.

Elapsed time: 10
BUG: kernel reboot-without-warning in boot stage
Linux version 4.14.0-rc4-00054-gfe368e2 #1
Command line: root=/dev/ram0 hung_task_panic=1 debug apic=debug 
sysrq_always_enabled rcupdate.rcu_cpu_stall_timeout=100 net.ifnames=0 
printk.devkmsg=on panic=-1 softlockup_panic=1 nmi_watchdog=panic oops=panic 
load_ramdisk=2 prompt_ramdisk=0 drbd.minor_count=8 systemd.log_level=err 
ignore_loglevel console=tty0 earlyprintk=ttyS0,115200 console=ttyS0,115200 
vga=normal rw 
link=/kbuild-tests/run-queue/kvm/x86_64-randconfig-a0-10221140/rcu:rcu:dev:fe368e2596a235ca15af01ebf203fca0594e01ea/.vmlinuz-fe368e2596a235ca15af01ebf203fca0594e01ea-20171024225823-78:quantal-intel12-27
 branch=rcu/rcu/dev 
BOOT_IMAGE=/pkg/linux/x86_64-randconfig-a0-10221140/gcc-6/fe368e2596a235ca15af01ebf203fca0594e01ea/vmlinuz-4.14.0-rc4-00054-gfe368e2
 drbd.minor_count=8

I'll try bisecting that error.

Thanks,
Fengguang


3ddf20c953  srcu: Shrink Tiny SRCU a bit more
492b95e597  rcuperf: Set more user-friendly defaults
bb176f6709  Linux 4.14-rc6
36ef71cae3  Add linux-next specific files for 20171018
+--+++---+---+
|  | 3ddf20c953 | 
492b95e597 | v4.14-rc6 | next-20171018 |
+--+++---+---+
| boot_successes   | 910| 
21 | 199   | 60|
| boot_failures| 0  | 9 
 | 111   | 21|
| WARNING:at_arch/x86/kernel/smp.c:#native_smp_send_reschedule | 0  | 9 
 | 111   | 21|
+--+++---+---+

[   29.173654] augmented rbtree testing
[   32.263469]  -> 83223 cycles
[   32.540332] gpio_it87: no device
[   32.541422] sched: Unexpected reschedule of offline CPU#1!
[   32.542355] [ cut here ]
[   32.543057] WARNING: CPU: 0 PID: 1 at arch/x86/kernel/smp.c:128 
native_smp_send_reschedule+0x83/0xbb
[   32.544646] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
4.12.0-rc4-00028-g492b95e #1
[   32.545397] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 
1.10.2-1 04/01/2014
[   32.546381] task: 88001e2e task.stack: 88001e2e8000
[   32.547031] RIP: 0010:native_smp_send_reschedule+0x83/0xbb
[   32.547642] RSP: :88001e2ebca0 EFLAGS: 00010086
[   32.548225] RAX: 002e RBX: 0003 RCX: 
[   32.548989] RDX: 002e0001 RSI:  RDI: 0096
[   32.550034] RBP: 88001e2ebcb8 R08: 0003 R09: 
[   32.551039] R10: 88001e2e0758 R11: 00021001 R12: 0001
[   32.551996] R13:  R14: 88001e38 R15: 88001e50
[   32.552727] FS:  () GS:88001e40() 
knlGS:
[   32.553585] CS:  0010 DS:  ES:  CR0: 

Re: [PATCH v3 2/8] lockdep: Introduce CROSSRELEASE_STACK_TRACE and make it not unwind as default

2017-10-24 Thread Ingo Molnar

* Byungchul Park  wrote:

> On Tue, Oct 24, 2017 at 12:05:16PM +0200, Ingo Molnar wrote:
> > 
> > * Byungchul Park  wrote:
> > 
> > > Johan Hovold reported a performance regression by crossrelease like:
> > 
> > Pplease add Reported-by and Analyzed-by tags - you didn't even Cc: Johan!
> 
> Excuse me but, I am sure, whom is the issue analyzed by? Me?

Well, Johan tracked it all down for us, Thomas gave the right suggestion to fix 
the performance regression, so I meant something like:

  Reported-by: Johan Hovold 
  Bisected-by: Johan Hovold 
  Analyzed-by: Thomas Gleixner 

Thanks,

Ingo


Re: [PATCH v3 2/8] lockdep: Introduce CROSSRELEASE_STACK_TRACE and make it not unwind as default

2017-10-24 Thread Ingo Molnar

* Byungchul Park  wrote:

> On Tue, Oct 24, 2017 at 12:05:16PM +0200, Ingo Molnar wrote:
> > 
> > * Byungchul Park  wrote:
> > 
> > > Johan Hovold reported a performance regression by crossrelease like:
> > 
> > Pplease add Reported-by and Analyzed-by tags - you didn't even Cc: Johan!
> 
> Excuse me but, I am sure, whom is the issue analyzed by? Me?

Well, Johan tracked it all down for us, Thomas gave the right suggestion to fix 
the performance regression, so I meant something like:

  Reported-by: Johan Hovold 
  Bisected-by: Johan Hovold 
  Analyzed-by: Thomas Gleixner 

Thanks,

Ingo


Re: [RESEND PATCH] irq_work: Don't reinvent the wheel but use existing llist API

2017-10-24 Thread Byungchul Park
On Wed, May 31, 2017 at 04:04:17PM +0200, Frederic Weisbecker wrote:
> On Tue, May 30, 2017 at 02:29:20PM +0900, Byungchul Park wrote:
> > On Fri, May 12, 2017 at 09:45:35AM +0900, Byungchul Park wrote:
> > > Although llist provides proper APIs, they are not used. Make them used.
> > 
> > +to pet...@infradead.org
> > +to mi...@kernel.org
> > +to rost...@goodmis.org
> > 
> > I am not sure whom should I send this patch to..
> > Could you check this if you are right person?
> 
> I'll take it.

Hello Frederic,

Please let me know if there are some problems with this.

If so, I will request it to others.

Thanks.

> Thanks!


Re: [RESEND PATCH] irq_work: Don't reinvent the wheel but use existing llist API

2017-10-24 Thread Byungchul Park
On Wed, May 31, 2017 at 04:04:17PM +0200, Frederic Weisbecker wrote:
> On Tue, May 30, 2017 at 02:29:20PM +0900, Byungchul Park wrote:
> > On Fri, May 12, 2017 at 09:45:35AM +0900, Byungchul Park wrote:
> > > Although llist provides proper APIs, they are not used. Make them used.
> > 
> > +to pet...@infradead.org
> > +to mi...@kernel.org
> > +to rost...@goodmis.org
> > 
> > I am not sure whom should I send this patch to..
> > Could you check this if you are right person?
> 
> I'll take it.

Hello Frederic,

Please let me know if there are some problems with this.

If so, I will request it to others.

Thanks.

> Thanks!


Re: [PATCH v10] vfio: platform: reset: Add Broadcom FlexRM reset module

2017-10-24 Thread Anup Patel
On Tue, Oct 3, 2017 at 10:57 AM, Anup Patel  wrote:
> This patch adds Broadcom FlexRM low-level reset for
> VFIO platform.
>
> It will do the following:
> 1. Disable/Deactivate each FlexRM ring
> 2. Flush each FlexRM ring
>
> The cleanup sequence for FlexRM rings is adapted from
> Broadcom FlexRM mailbox driver.
>
> Signed-off-by: Anup Patel 
> Reviewed-by: Oza Oza 
> Reviewed-by: Scott Branden 
> Reviewed-by: Eric Auger 
> ---
>  drivers/vfio/platform/reset/Kconfig|   9 ++
>  drivers/vfio/platform/reset/Makefile   |   1 +
>  .../vfio/platform/reset/vfio_platform_bcmflexrm.c  | 113 
> +
>  3 files changed, 123 insertions(+)
>  create mode 100644 drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c
>
> diff --git a/drivers/vfio/platform/reset/Kconfig 
> b/drivers/vfio/platform/reset/Kconfig
> index 705..392e3c0 100644
> --- a/drivers/vfio/platform/reset/Kconfig
> +++ b/drivers/vfio/platform/reset/Kconfig
> @@ -13,3 +13,12 @@ config VFIO_PLATFORM_AMDXGBE_RESET
>   Enables the VFIO platform driver to handle reset for AMD XGBE
>
>   If you don't know what to do here, say N.
> +
> +config VFIO_PLATFORM_BCMFLEXRM_RESET
> +   tristate "VFIO support for Broadcom FlexRM reset"
> +   depends on VFIO_PLATFORM && (ARCH_BCM_IPROC || COMPILE_TEST)
> +   default ARCH_BCM_IPROC
> +   help
> + Enables the VFIO platform driver to handle reset for Broadcom FlexRM
> +
> + If you don't know what to do here, say N.
> diff --git a/drivers/vfio/platform/reset/Makefile 
> b/drivers/vfio/platform/reset/Makefile
> index 93f4e23..8d9874b 100644
> --- a/drivers/vfio/platform/reset/Makefile
> +++ b/drivers/vfio/platform/reset/Makefile
> @@ -5,3 +5,4 @@ ccflags-y += -Idrivers/vfio/platform
>
>  obj-$(CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET) += 
> vfio-platform-calxedaxgmac.o
>  obj-$(CONFIG_VFIO_PLATFORM_AMDXGBE_RESET) += vfio-platform-amdxgbe.o
> +obj-$(CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET) += vfio_platform_bcmflexrm.o
> diff --git a/drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c 
> b/drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c
> new file mode 100644
> index 000..d45c3be
> --- /dev/null
> +++ b/drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c
> @@ -0,0 +1,113 @@
> +/*
> + * Copyright (C) 2017 Broadcom
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +/*
> + * This driver provides reset support for Broadcom FlexRM ring manager
> + * to VFIO platform.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "vfio_platform_private.h"
> +
> +/* FlexRM configuration */
> +#define RING_REGS_SIZE 0x1
> +#define RING_VER_MAGIC 0x76303031
> +
> +/* Per-Ring register offsets */
> +#define RING_VER   0x000
> +#define RING_CONTROL   0x034
> +#define RING_FLUSH_DONE0x038
> +
> +/* Register RING_CONTROL fields */
> +#define CONTROL_FLUSH_SHIFT5
> +
> +/* Register RING_FLUSH_DONE fields */
> +#define FLUSH_DONE_MASK0x1
> +
> +static int vfio_platform_bcmflexrm_shutdown(void __iomem *ring)
> +{
> +   unsigned int timeout;
> +
> +   /* Disable/inactivate ring */
> +   writel_relaxed(0x0, ring + RING_CONTROL);
> +
> +   /* Set ring flush state */
> +   timeout = 1000; /* timeout of 1s */
> +   writel_relaxed(BIT(CONTROL_FLUSH_SHIFT), ring + RING_CONTROL);
> +   do {
> +   if (readl_relaxed(ring + RING_FLUSH_DONE) &
> +   FLUSH_DONE_MASK)
> +   break;
> +   mdelay(1);
> +   } while (--timeout);
> +   if (!timeout)
> +   return -ETIMEDOUT;
> +
> +   /* Clear ring flush state */
> +   timeout = 1000; /* timeout of 1s */
> +   writel_relaxed(0x0, ring + RING_CONTROL);
> +   do {
> +   if (!(readl_relaxed(ring + RING_FLUSH_DONE) &
> + FLUSH_DONE_MASK))
> +   break;
> +   mdelay(1);
> +   } while (--timeout);
> +   if (!timeout)
> +   return -ETIMEDOUT;
> +
> +   return 0;
> +}
> +
> +static int vfio_platform_bcmflexrm_reset(struct vfio_platform_device *vdev)
> +{
> +   void __iomem 

Re: [PATCH v10] vfio: platform: reset: Add Broadcom FlexRM reset module

2017-10-24 Thread Anup Patel
On Tue, Oct 3, 2017 at 10:57 AM, Anup Patel  wrote:
> This patch adds Broadcom FlexRM low-level reset for
> VFIO platform.
>
> It will do the following:
> 1. Disable/Deactivate each FlexRM ring
> 2. Flush each FlexRM ring
>
> The cleanup sequence for FlexRM rings is adapted from
> Broadcom FlexRM mailbox driver.
>
> Signed-off-by: Anup Patel 
> Reviewed-by: Oza Oza 
> Reviewed-by: Scott Branden 
> Reviewed-by: Eric Auger 
> ---
>  drivers/vfio/platform/reset/Kconfig|   9 ++
>  drivers/vfio/platform/reset/Makefile   |   1 +
>  .../vfio/platform/reset/vfio_platform_bcmflexrm.c  | 113 
> +
>  3 files changed, 123 insertions(+)
>  create mode 100644 drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c
>
> diff --git a/drivers/vfio/platform/reset/Kconfig 
> b/drivers/vfio/platform/reset/Kconfig
> index 705..392e3c0 100644
> --- a/drivers/vfio/platform/reset/Kconfig
> +++ b/drivers/vfio/platform/reset/Kconfig
> @@ -13,3 +13,12 @@ config VFIO_PLATFORM_AMDXGBE_RESET
>   Enables the VFIO platform driver to handle reset for AMD XGBE
>
>   If you don't know what to do here, say N.
> +
> +config VFIO_PLATFORM_BCMFLEXRM_RESET
> +   tristate "VFIO support for Broadcom FlexRM reset"
> +   depends on VFIO_PLATFORM && (ARCH_BCM_IPROC || COMPILE_TEST)
> +   default ARCH_BCM_IPROC
> +   help
> + Enables the VFIO platform driver to handle reset for Broadcom FlexRM
> +
> + If you don't know what to do here, say N.
> diff --git a/drivers/vfio/platform/reset/Makefile 
> b/drivers/vfio/platform/reset/Makefile
> index 93f4e23..8d9874b 100644
> --- a/drivers/vfio/platform/reset/Makefile
> +++ b/drivers/vfio/platform/reset/Makefile
> @@ -5,3 +5,4 @@ ccflags-y += -Idrivers/vfio/platform
>
>  obj-$(CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET) += 
> vfio-platform-calxedaxgmac.o
>  obj-$(CONFIG_VFIO_PLATFORM_AMDXGBE_RESET) += vfio-platform-amdxgbe.o
> +obj-$(CONFIG_VFIO_PLATFORM_BCMFLEXRM_RESET) += vfio_platform_bcmflexrm.o
> diff --git a/drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c 
> b/drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c
> new file mode 100644
> index 000..d45c3be
> --- /dev/null
> +++ b/drivers/vfio/platform/reset/vfio_platform_bcmflexrm.c
> @@ -0,0 +1,113 @@
> +/*
> + * Copyright (C) 2017 Broadcom
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +/*
> + * This driver provides reset support for Broadcom FlexRM ring manager
> + * to VFIO platform.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "vfio_platform_private.h"
> +
> +/* FlexRM configuration */
> +#define RING_REGS_SIZE 0x1
> +#define RING_VER_MAGIC 0x76303031
> +
> +/* Per-Ring register offsets */
> +#define RING_VER   0x000
> +#define RING_CONTROL   0x034
> +#define RING_FLUSH_DONE0x038
> +
> +/* Register RING_CONTROL fields */
> +#define CONTROL_FLUSH_SHIFT5
> +
> +/* Register RING_FLUSH_DONE fields */
> +#define FLUSH_DONE_MASK0x1
> +
> +static int vfio_platform_bcmflexrm_shutdown(void __iomem *ring)
> +{
> +   unsigned int timeout;
> +
> +   /* Disable/inactivate ring */
> +   writel_relaxed(0x0, ring + RING_CONTROL);
> +
> +   /* Set ring flush state */
> +   timeout = 1000; /* timeout of 1s */
> +   writel_relaxed(BIT(CONTROL_FLUSH_SHIFT), ring + RING_CONTROL);
> +   do {
> +   if (readl_relaxed(ring + RING_FLUSH_DONE) &
> +   FLUSH_DONE_MASK)
> +   break;
> +   mdelay(1);
> +   } while (--timeout);
> +   if (!timeout)
> +   return -ETIMEDOUT;
> +
> +   /* Clear ring flush state */
> +   timeout = 1000; /* timeout of 1s */
> +   writel_relaxed(0x0, ring + RING_CONTROL);
> +   do {
> +   if (!(readl_relaxed(ring + RING_FLUSH_DONE) &
> + FLUSH_DONE_MASK))
> +   break;
> +   mdelay(1);
> +   } while (--timeout);
> +   if (!timeout)
> +   return -ETIMEDOUT;
> +
> +   return 0;
> +}
> +
> +static int vfio_platform_bcmflexrm_reset(struct vfio_platform_device *vdev)
> +{
> +   void __iomem *ring;
> +   int rc = 0, ret = 0, ring_num = 0;
> +   struct vfio_platform_region *reg = >regions[0];
> +
> +   

Re: [PATCH v2 6/6] f2fs: give up CP_TRIMMED_FLAG if it drops discards

2017-10-24 Thread Jaegeuk Kim
On 10/24, Chao Yu wrote:
> On 2017/10/24 20:46, Jaegeuk Kim wrote:
> > On 10/24, Chao Yu wrote:
> >> Hi Jaegeuk,
> >>
> >> On 2017/10/4 9:08, Chao Yu wrote:
> >>> From: Chao Yu 
> >>>
> >>> In ->umount, once we drop remained discard entries, we should not
> >>> set CP_TRIMMED_FLAG with another checkpoint.
> >>>
> >>> Signed-off-by: Chao Yu 
> >>> ---
> >>> v2:
> >>> - rebase on last codes of Jaegeuk's dev-test branch.
> >>>  fs/f2fs/f2fs.h|  2 +-
> >>>  fs/f2fs/segment.c | 15 +++
> >>>  fs/f2fs/super.c   |  5 +++--
> >>>  3 files changed, 15 insertions(+), 7 deletions(-)
> >>>
> >>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> >>> index f274805e231d..c85f49c41003 100644
> >>> --- a/fs/f2fs/f2fs.h
> >>> +++ b/fs/f2fs/f2fs.h
> >>> @@ -2565,7 +2565,7 @@ void init_discard_policy(struct discard_policy 
> >>> *dpolicy, int discard_type,
> >>>   unsigned int granularity);
> >>>  void refresh_sit_entry(struct f2fs_sb_info *sbi, block_t old, block_t 
> >>> new);
> >>>  void stop_discard_thread(struct f2fs_sb_info *sbi);
> >>> -void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
> >>> +bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
> >>>  void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control 
> >>> *cpc);
> >>>  void release_discard_addrs(struct f2fs_sb_info *sbi);
> >>>  int npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
> >>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> >>> index 4a108321233d..bfbcff8339c5 100644
> >>> --- a/fs/f2fs/segment.c
> >>> +++ b/fs/f2fs/segment.c
> >>> @@ -1196,12 +1196,13 @@ static int __issue_discard_cmd(struct 
> >>> f2fs_sb_info *sbi,
> >>>   return issued;
> >>>  }
> >>>  
> >>> -static void __drop_discard_cmd(struct f2fs_sb_info *sbi)
> >>> +static bool __drop_discard_cmd(struct f2fs_sb_info *sbi)
> >>>  {
> >>>   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
> >>>   struct list_head *pend_list;
> >>>   struct discard_cmd *dc, *tmp;
> >>>   int i;
> >>> + bool dropped = false;
> >>>  
> >>>   mutex_lock(>cmd_lock);
> >>>   for (i = MAX_PLIST_NUM - 1; i >= 0; i--) {
> >>> @@ -1209,9 +1210,12 @@ static void __drop_discard_cmd(struct f2fs_sb_info 
> >>> *sbi)
> >>>   list_for_each_entry_safe(dc, tmp, pend_list, list) {
> >>>   f2fs_bug_on(sbi, dc->state != D_PREP);
> >>>   __remove_discard_cmd(sbi, dc);
> >>> + dropped = true;
> >>>   }
> >>>   }
> >>>   mutex_unlock(>cmd_lock);
> >>> +
> >>> + return dropped;
> >>>  }
> >>>  
> >>>  static void __wait_one_discard_bio(struct f2fs_sb_info *sbi,
> >>> @@ -1306,15 +1310,18 @@ void stop_discard_thread(struct f2fs_sb_info *sbi)
> >>>  }
> >>>  
> >>>  /* This comes from f2fs_put_super */
> >>> -void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
> >>> +bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
> >>>  {
> >>>   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
> >>>   struct discard_policy dpolicy;
> >>> + bool dropped;
> >>>  
> >>>   init_discard_policy(, DPOLICY_UMOUNT, dcc->discard_granularity);
> >>>   __issue_discard_cmd(sbi, );
> >>> - __drop_discard_cmd(sbi);
> >>> + dropped = __drop_discard_cmd(sbi);
> >>>   __wait_all_discard_cmd(sbi, );
> >>> +
> >>> + return dropped;
> >>>  }
> >>>  
> >>>  static int issue_discard_thread(void *data)
> >>> @@ -1659,7 +1666,7 @@ void init_discard_policy(struct discard_policy 
> >>> *dpolicy,
> >>>   dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
> >>>   dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
> >>>   dpolicy->io_aware_gran = MAX_PLIST_NUM;
> >>> - dpolicy->io_aware = false;
> >>> + dpolicy->io_aware = true;
> >>
> >> I notice this change should not belong to this patch, could you please 
> >> help to
> >> move this into "f2fs: split discard policy" in your branch?
> > 
> > Yup, done. Could you check it in dev-test?
> 
> I didn't find it, did you forget to push to that branch?

Yup, I pushed it. :)

Thanks,

> 
> Thanks,
> 
> > 
> > Thanks,
> > 
> >>
> >> Thanks,
> >>
> >>>   } else if (discard_type == DPOLICY_FSTRIM) {
> >>>   dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
> >>>   dpolicy->io_aware_gran = MAX_PLIST_NUM;
> >>> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> >>> index a13269d1a1f0..1d68c18a487b 100644
> >>> --- a/fs/f2fs/super.c
> >>> +++ b/fs/f2fs/super.c
> >>> @@ -807,6 +807,7 @@ static void f2fs_put_super(struct super_block *sb)
> >>>  {
> >>>   struct f2fs_sb_info *sbi = F2FS_SB(sb);
> >>>   int i;
> >>> + bool dropped;
> >>>  
> >>>   f2fs_quota_off_umount(sb);
> >>>  
> >>> @@ -827,9 +828,9 @@ static void f2fs_put_super(struct super_block *sb)
> >>>   }
> >>>  
> >>>   /* be sure to wait for any on-going discard commands */
> >>> - f2fs_wait_discard_bios(sbi, true);
> >>> + dropped = f2fs_wait_discard_bios(sbi);
> >>>  
> >>> - if (f2fs_discard_en(sbi) && 

Re: [PATCH v2 6/6] f2fs: give up CP_TRIMMED_FLAG if it drops discards

2017-10-24 Thread Jaegeuk Kim
On 10/24, Chao Yu wrote:
> On 2017/10/24 20:46, Jaegeuk Kim wrote:
> > On 10/24, Chao Yu wrote:
> >> Hi Jaegeuk,
> >>
> >> On 2017/10/4 9:08, Chao Yu wrote:
> >>> From: Chao Yu 
> >>>
> >>> In ->umount, once we drop remained discard entries, we should not
> >>> set CP_TRIMMED_FLAG with another checkpoint.
> >>>
> >>> Signed-off-by: Chao Yu 
> >>> ---
> >>> v2:
> >>> - rebase on last codes of Jaegeuk's dev-test branch.
> >>>  fs/f2fs/f2fs.h|  2 +-
> >>>  fs/f2fs/segment.c | 15 +++
> >>>  fs/f2fs/super.c   |  5 +++--
> >>>  3 files changed, 15 insertions(+), 7 deletions(-)
> >>>
> >>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> >>> index f274805e231d..c85f49c41003 100644
> >>> --- a/fs/f2fs/f2fs.h
> >>> +++ b/fs/f2fs/f2fs.h
> >>> @@ -2565,7 +2565,7 @@ void init_discard_policy(struct discard_policy 
> >>> *dpolicy, int discard_type,
> >>>   unsigned int granularity);
> >>>  void refresh_sit_entry(struct f2fs_sb_info *sbi, block_t old, block_t 
> >>> new);
> >>>  void stop_discard_thread(struct f2fs_sb_info *sbi);
> >>> -void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
> >>> +bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi);
> >>>  void clear_prefree_segments(struct f2fs_sb_info *sbi, struct cp_control 
> >>> *cpc);
> >>>  void release_discard_addrs(struct f2fs_sb_info *sbi);
> >>>  int npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
> >>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> >>> index 4a108321233d..bfbcff8339c5 100644
> >>> --- a/fs/f2fs/segment.c
> >>> +++ b/fs/f2fs/segment.c
> >>> @@ -1196,12 +1196,13 @@ static int __issue_discard_cmd(struct 
> >>> f2fs_sb_info *sbi,
> >>>   return issued;
> >>>  }
> >>>  
> >>> -static void __drop_discard_cmd(struct f2fs_sb_info *sbi)
> >>> +static bool __drop_discard_cmd(struct f2fs_sb_info *sbi)
> >>>  {
> >>>   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
> >>>   struct list_head *pend_list;
> >>>   struct discard_cmd *dc, *tmp;
> >>>   int i;
> >>> + bool dropped = false;
> >>>  
> >>>   mutex_lock(>cmd_lock);
> >>>   for (i = MAX_PLIST_NUM - 1; i >= 0; i--) {
> >>> @@ -1209,9 +1210,12 @@ static void __drop_discard_cmd(struct f2fs_sb_info 
> >>> *sbi)
> >>>   list_for_each_entry_safe(dc, tmp, pend_list, list) {
> >>>   f2fs_bug_on(sbi, dc->state != D_PREP);
> >>>   __remove_discard_cmd(sbi, dc);
> >>> + dropped = true;
> >>>   }
> >>>   }
> >>>   mutex_unlock(>cmd_lock);
> >>> +
> >>> + return dropped;
> >>>  }
> >>>  
> >>>  static void __wait_one_discard_bio(struct f2fs_sb_info *sbi,
> >>> @@ -1306,15 +1310,18 @@ void stop_discard_thread(struct f2fs_sb_info *sbi)
> >>>  }
> >>>  
> >>>  /* This comes from f2fs_put_super */
> >>> -void f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
> >>> +bool f2fs_wait_discard_bios(struct f2fs_sb_info *sbi)
> >>>  {
> >>>   struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
> >>>   struct discard_policy dpolicy;
> >>> + bool dropped;
> >>>  
> >>>   init_discard_policy(, DPOLICY_UMOUNT, dcc->discard_granularity);
> >>>   __issue_discard_cmd(sbi, );
> >>> - __drop_discard_cmd(sbi);
> >>> + dropped = __drop_discard_cmd(sbi);
> >>>   __wait_all_discard_cmd(sbi, );
> >>> +
> >>> + return dropped;
> >>>  }
> >>>  
> >>>  static int issue_discard_thread(void *data)
> >>> @@ -1659,7 +1666,7 @@ void init_discard_policy(struct discard_policy 
> >>> *dpolicy,
> >>>   dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME;
> >>>   dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
> >>>   dpolicy->io_aware_gran = MAX_PLIST_NUM;
> >>> - dpolicy->io_aware = false;
> >>> + dpolicy->io_aware = true;
> >>
> >> I notice this change should not belong to this patch, could you please 
> >> help to
> >> move this into "f2fs: split discard policy" in your branch?
> > 
> > Yup, done. Could you check it in dev-test?
> 
> I didn't find it, did you forget to push to that branch?

Yup, I pushed it. :)

Thanks,

> 
> Thanks,
> 
> > 
> > Thanks,
> > 
> >>
> >> Thanks,
> >>
> >>>   } else if (discard_type == DPOLICY_FSTRIM) {
> >>>   dpolicy->max_requests = DEF_MAX_DISCARD_REQUEST;
> >>>   dpolicy->io_aware_gran = MAX_PLIST_NUM;
> >>> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> >>> index a13269d1a1f0..1d68c18a487b 100644
> >>> --- a/fs/f2fs/super.c
> >>> +++ b/fs/f2fs/super.c
> >>> @@ -807,6 +807,7 @@ static void f2fs_put_super(struct super_block *sb)
> >>>  {
> >>>   struct f2fs_sb_info *sbi = F2FS_SB(sb);
> >>>   int i;
> >>> + bool dropped;
> >>>  
> >>>   f2fs_quota_off_umount(sb);
> >>>  
> >>> @@ -827,9 +828,9 @@ static void f2fs_put_super(struct super_block *sb)
> >>>   }
> >>>  
> >>>   /* be sure to wait for any on-going discard commands */
> >>> - f2fs_wait_discard_bios(sbi, true);
> >>> + dropped = f2fs_wait_discard_bios(sbi);
> >>>  
> >>> - if (f2fs_discard_en(sbi) && !sbi->discard_blks) {
> >>> + if 

Re: [PATCH 1/2] f2fs: add missing quota_initialize in f2fs_set_acl

2017-10-24 Thread Jaegeuk Kim
On 10/24, Chao Yu wrote:
> On 2017/10/24 6:14, Jaegeuk Kim wrote:
> > This patch adds to call quota_intialize in f2fs_set_acl.
> > 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> >  fs/f2fs/acl.c | 4 
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
> > index 436b3a1464d9..f6471f9d707e 100644
> > --- a/fs/f2fs/acl.c
> > +++ b/fs/f2fs/acl.c
> > @@ -209,6 +209,10 @@ static int __f2fs_set_acl(struct inode *inode, int 
> > type,
> > int error;
> > umode_t mode = inode->i_mode;
> >  
> > +   error = dquot_initialize(inode);
> > +   if (error)
> > +   return error;
> 
> Could you move this to f2fs_setxattr, and also add missing dquot_initialize in
> unlink and rename like ext4?

I've checked that f2fs_unlink and f2fs_rename are calling dquot_initialize().

Thanks,

> 
> Thanks,
> 
> > +
> > switch (type) {
> > case ACL_TYPE_ACCESS:
> > name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
> > 


Re: [PATCH 1/2] f2fs: add missing quota_initialize in f2fs_set_acl

2017-10-24 Thread Jaegeuk Kim
On 10/24, Chao Yu wrote:
> On 2017/10/24 6:14, Jaegeuk Kim wrote:
> > This patch adds to call quota_intialize in f2fs_set_acl.
> > 
> > Signed-off-by: Jaegeuk Kim 
> > ---
> >  fs/f2fs/acl.c | 4 
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
> > index 436b3a1464d9..f6471f9d707e 100644
> > --- a/fs/f2fs/acl.c
> > +++ b/fs/f2fs/acl.c
> > @@ -209,6 +209,10 @@ static int __f2fs_set_acl(struct inode *inode, int 
> > type,
> > int error;
> > umode_t mode = inode->i_mode;
> >  
> > +   error = dquot_initialize(inode);
> > +   if (error)
> > +   return error;
> 
> Could you move this to f2fs_setxattr, and also add missing dquot_initialize in
> unlink and rename like ext4?

I've checked that f2fs_unlink and f2fs_rename are calling dquot_initialize().

Thanks,

> 
> Thanks,
> 
> > +
> > switch (type) {
> > case ACL_TYPE_ACCESS:
> > name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
> > 


Re: [PATCH 1/2 v2] f2fs: add missing quota_initialize in f2fs_set_acl

2017-10-24 Thread Jaegeuk Kim
This patch adds to call quota_intialize in f2fs_set_acl.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/xattr.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 147b481c6902..8801db019892 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -686,6 +686,10 @@ int f2fs_setxattr(struct inode *inode, int index, const 
char *name,
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
int err;
 
+   err = dquot_initialize(inode);
+   if (err)
+   return err;
+
/* this case is only from init_inode_metadata */
if (ipage)
return __f2fs_setxattr(inode, index, name, value,
-- 
2.14.0.rc1.383.gd1ce394fe2-goog



Re: [PATCH 1/2 v2] f2fs: add missing quota_initialize in f2fs_set_acl

2017-10-24 Thread Jaegeuk Kim
This patch adds to call quota_intialize in f2fs_set_acl.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/xattr.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 147b481c6902..8801db019892 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -686,6 +686,10 @@ int f2fs_setxattr(struct inode *inode, int index, const 
char *name,
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
int err;
 
+   err = dquot_initialize(inode);
+   if (err)
+   return err;
+
/* this case is only from init_inode_metadata */
if (ipage)
return __f2fs_setxattr(inode, index, name, value,
-- 
2.14.0.rc1.383.gd1ce394fe2-goog



Re: [PATCH] kbuild: fix dependency of dtbs targets

2017-10-24 Thread Masahiro Yamada
Hi.


2017-10-10 0:05 GMT+09:00 Russell King - ARM Linux :
> On Wed, Oct 04, 2017 at 01:27:20PM +0900, Masahiro Yamada wrote:
>> The target "dtbs" should depend on "scripts" because it needs to
>> build dtc.  The "prepare" target is unneeded here.
>
> Looks fine for ARM, as the only thing the dtbs should depend on is
> the kernel configuration (to decide which to build) and DT tooling.
>
> Acked-by: Russell King 
>
> --


I found a potential issue on this
because the default DTB install path depends on $(KERNELRELEASE).


In top-level Makefile:
export INSTALL_DTBS_PATH ?= $(INSTALL_PATH)/dtbs/$(KERNELRELEASE)


The include/config/kernel.release is created by "prepare3" target.

If the dependency on "parepare" is removed,
it is possible to run "make dtbs" and "make dtbs_install"
without creating include/config/kernel.release.

So, the $(KERNELRELEASE) could be empty when installing DTB.


Maybe, drop this patch, or reduce the dependency to "parepare3"?







-- 
Best Regards
Masahiro Yamada


Re: [PATCH] kbuild: fix dependency of dtbs targets

2017-10-24 Thread Masahiro Yamada
Hi.


2017-10-10 0:05 GMT+09:00 Russell King - ARM Linux :
> On Wed, Oct 04, 2017 at 01:27:20PM +0900, Masahiro Yamada wrote:
>> The target "dtbs" should depend on "scripts" because it needs to
>> build dtc.  The "prepare" target is unneeded here.
>
> Looks fine for ARM, as the only thing the dtbs should depend on is
> the kernel configuration (to decide which to build) and DT tooling.
>
> Acked-by: Russell King 
>
> --


I found a potential issue on this
because the default DTB install path depends on $(KERNELRELEASE).


In top-level Makefile:
export INSTALL_DTBS_PATH ?= $(INSTALL_PATH)/dtbs/$(KERNELRELEASE)


The include/config/kernel.release is created by "prepare3" target.

If the dependency on "parepare" is removed,
it is possible to run "make dtbs" and "make dtbs_install"
without creating include/config/kernel.release.

So, the $(KERNELRELEASE) could be empty when installing DTB.


Maybe, drop this patch, or reduce the dependency to "parepare3"?







-- 
Best Regards
Masahiro Yamada


[PATCH 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer

2017-10-24 Thread rick
ATCPIT100 is often used on the Andes architecture,
This timer provide 4 PIT channels. Each PIT channel is a
multi-function timer, can be configured as 32,16,8 bit timers
or PWM as well.

For system timer it will set 32-bit timer0 as clock source
and count downwards until underflow and restart again.

It also set 32-bit timer1 as clock event and count downwards
until condition match. It will generate an interrupt for
handling periodically.

Signed-off-by: rick 
Signed-off-by: rick 
Signed-off-by: Greentime Hu 
---
 drivers/clocksource/timer-atcpit100.c |  199 +
 1 file changed, 199 insertions(+)
 create mode 100644 drivers/clocksource/timer-atcpit100.c

diff --git a/drivers/clocksource/timer-atcpit100.c 
b/drivers/clocksource/timer-atcpit100.c
new file mode 100644
index 000..6b224c4
--- /dev/null
+++ b/drivers/clocksource/timer-atcpit100.c
@@ -0,0 +1,199 @@
+/*
+ *  Andestech ATCPIT100 Timer Device Driver Implementation
+ *
+ *  Copyright (C) 2016 Andes Technology Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void __iomem *base;
+static u32 freq;
+
+/*
+ * Definition of register offsets
+ */
+
+/* ID and Revision Register */
+#define ID_REV 0x0
+
+/* Configuration Register */
+#define CFG0x10
+
+/* Interrupt Enable Register */
+#define INT_EN 0x14
+#define CH_INT_EN(c, i)((1<

[PATCH 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer

2017-10-24 Thread rick
ATCPIT100 is often used on the Andes architecture,
This timer provide 4 PIT channels. Each PIT channel is a
multi-function timer, can be configured as 32,16,8 bit timers
or PWM as well.

For system timer it will set 32-bit timer0 as clock source
and count downwards until underflow and restart again.

It also set 32-bit timer1 as clock event and count downwards
until condition match. It will generate an interrupt for
handling periodically.

Signed-off-by: rick 
Signed-off-by: rick 
Signed-off-by: Greentime Hu 
---
 drivers/clocksource/timer-atcpit100.c |  199 +
 1 file changed, 199 insertions(+)
 create mode 100644 drivers/clocksource/timer-atcpit100.c

diff --git a/drivers/clocksource/timer-atcpit100.c 
b/drivers/clocksource/timer-atcpit100.c
new file mode 100644
index 000..6b224c4
--- /dev/null
+++ b/drivers/clocksource/timer-atcpit100.c
@@ -0,0 +1,199 @@
+/*
+ *  Andestech ATCPIT100 Timer Device Driver Implementation
+ *
+ *  Copyright (C) 2016 Andes Technology Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+void __iomem *base;
+static u32 freq;
+
+/*
+ * Definition of register offsets
+ */
+
+/* ID and Revision Register */
+#define ID_REV 0x0
+
+/* Configuration Register */
+#define CFG0x10
+
+/* Interrupt Enable Register */
+#define INT_EN 0x14
+#define CH_INT_EN(c, i)((1mult = div_sc(freq, NSEC_PER_SEC, evt->shift);
+   evt->max_delta_ns = clockevent_delta2ns(0x, evt);
+   evt->min_delta_ns = clockevent_delta2ns(3, evt);
+   clockevents_register_device(evt);
+   setup_irq(irq, _irq);
+}
+
+static int __init atcpit100_init(struct device_node *dev)
+{
+   int irq;
+
+   base = of_iomap(dev, 0);
+   if (!base) {
+   pr_warn("Can't remap registers");
+   return -ENXIO;
+   }
+
+   if (of_property_read_u32(dev, "clock-frequency", )) {
+   pr_warn("Can't read clock-frequency");
+   return -EINVAL;
+   }
+   irq = irq_of_parse_and_map(dev, 0);
+
+   if (irq <= 0) {
+   pr_warn("Failed to map timer IRQ\n");
+   return -EINVAL;
+   }
+   pr_info("ATCPIT100 timer 1 installed on IRQ %d, with clock %d at %d HZ. 
in 0x%08x\r\n",
+   irq, freq, HZ, (u32)base);
+   writel(APB_CLK|TMR_32, base + CH_CTL(0));
+   writel(readl(base + INT_EN) | CH_INT_EN(0, 0), base + INT_EN);
+   writel(readl(base + CH_EN) | CH_TMR_EN(0, 0), base + CH_EN);
+   atcpit100_clocksource_init();
+   atcpit100_clockevent_init(irq);
+
+   return 0;
+}
+
+TIMER_OF_DECLARE(atcpit100, "andestech,atcpit100", atcpit100_init);
-- 
1.7.9.5



[PATCH 3/3] dt-bindings: timer: Add andestech atcpit100 timer binding doc

2017-10-24 Thread rick
Signed-off-by: rick 
Signed-off-by: rick 
Signed-off-by: Greentime Hu 
---
 .../bindings/timer/andestech,atcpit100-timer.txt   |   31 
 1 file changed, 31 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt

diff --git 
a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt 
b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt
new file mode 100644
index 000..a87278a
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt
@@ -0,0 +1,31 @@
+Andestech ATCPIT100 timer
+--
+ATCPIT100 is a generic IP block from Andes Technology, embedded in
+Andestech AE3XX platforms and other designs.
+
+This timer is a set of compact multi-function timers, which can be
+used as pulse width modulators (PWM) as well as simple timers.
+
+It supports up to 4 PIT channels. Each PIT channel is a
+multi-function timer and provide the following usage scenarios:
+One 32-bit timer
+Two 16-bit timers
+Four 8-bit timers
+One 16-bit PWM
+One 16-bit timer and one 8-bit PWM
+Two 8-bit timer and one 8-bit PWM
+
+Required properties:
+- compatible   : Should be "andestech,atcpit100"
+- reg  : Address and length of the register set
+- interrupts   : Reference to the timer interrupt
+- clock-frequency : The rate in HZ in input of the Andestech ATCPIT100 timer
+
+Examples:
+
+timer0: timer@f040 {
+   compatible = "andestech,atcpit100";
+   reg = <0xf040 0x1000>;
+   interrupts = <2 4>;
+   clock-frequency = <3000>;
+};
-- 
1.7.9.5



[PATCH 3/3] dt-bindings: timer: Add andestech atcpit100 timer binding doc

2017-10-24 Thread rick
Signed-off-by: rick 
Signed-off-by: rick 
Signed-off-by: Greentime Hu 
---
 .../bindings/timer/andestech,atcpit100-timer.txt   |   31 
 1 file changed, 31 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt

diff --git 
a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt 
b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt
new file mode 100644
index 000..a87278a
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt
@@ -0,0 +1,31 @@
+Andestech ATCPIT100 timer
+--
+ATCPIT100 is a generic IP block from Andes Technology, embedded in
+Andestech AE3XX platforms and other designs.
+
+This timer is a set of compact multi-function timers, which can be
+used as pulse width modulators (PWM) as well as simple timers.
+
+It supports up to 4 PIT channels. Each PIT channel is a
+multi-function timer and provide the following usage scenarios:
+One 32-bit timer
+Two 16-bit timers
+Four 8-bit timers
+One 16-bit PWM
+One 16-bit timer and one 8-bit PWM
+Two 8-bit timer and one 8-bit PWM
+
+Required properties:
+- compatible   : Should be "andestech,atcpit100"
+- reg  : Address and length of the register set
+- interrupts   : Reference to the timer interrupt
+- clock-frequency : The rate in HZ in input of the Andestech ATCPIT100 timer
+
+Examples:
+
+timer0: timer@f040 {
+   compatible = "andestech,atcpit100";
+   reg = <0xf040 0x1000>;
+   interrupts = <2 4>;
+   clock-frequency = <3000>;
+};
-- 
1.7.9.5



[PATCH 2/3] clocksource/drivers/Kconfig: Support andestech atcpit100

2017-10-24 Thread rick
Signed-off-by: rick 
Signed-off-by: rick 
Signed-off-by: Greentime Hu 
---
 drivers/clocksource/Kconfig  |6 ++
 drivers/clocksource/Makefile |1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cc60620..e950066 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -615,4 +615,10 @@ config CLKSRC_ST_LPC
  Enable this option to use the Low Power controller timer
  as clocksource.
 
+config CLKSRC_ATCPIT100
+   bool "Clocksource for AE3XX platform" if COMPILE_TEST
+  depends on GENERIC_CLOCKEVENTS && HAS_IOMEM
+   help
+ This option enables support for the Andestech AE3XX platform timers.
+
 endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index dbc1ad1..24d15bd 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -74,3 +74,4 @@ obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o
 obj-$(CONFIG_H8300_TPU)+= h8300_tpu.o
 obj-$(CONFIG_CLKSRC_ST_LPC)+= clksrc_st_lpc.o
 obj-$(CONFIG_X86_NUMACHIP) += numachip.o
+obj-$(CONFIG_CLKSRC_ATCPIT100) += timer-atcpit100.o
-- 
1.7.9.5



[PATCH 2/3] clocksource/drivers/Kconfig: Support andestech atcpit100

2017-10-24 Thread rick
Signed-off-by: rick 
Signed-off-by: rick 
Signed-off-by: Greentime Hu 
---
 drivers/clocksource/Kconfig  |6 ++
 drivers/clocksource/Makefile |1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cc60620..e950066 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -615,4 +615,10 @@ config CLKSRC_ST_LPC
  Enable this option to use the Low Power controller timer
  as clocksource.
 
+config CLKSRC_ATCPIT100
+   bool "Clocksource for AE3XX platform" if COMPILE_TEST
+  depends on GENERIC_CLOCKEVENTS && HAS_IOMEM
+   help
+ This option enables support for the Andestech AE3XX platform timers.
+
 endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index dbc1ad1..24d15bd 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -74,3 +74,4 @@ obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o
 obj-$(CONFIG_H8300_TPU)+= h8300_tpu.o
 obj-$(CONFIG_CLKSRC_ST_LPC)+= clksrc_st_lpc.o
 obj-$(CONFIG_X86_NUMACHIP) += numachip.o
+obj-$(CONFIG_CLKSRC_ATCPIT100) += timer-atcpit100.o
-- 
1.7.9.5



Re: [PATCH] drivers/wireless: iwlwifi/mvm: Convert timers to use timer_setup()

2017-10-24 Thread Luca Coelho
On Tue, 2017-10-24 at 02:29 -0700, Kees Cook wrote:
> In preparation for unconditionally passing the struct timer_list
> pointer to
> all timer callbacks, switch to using the new timer_setup() and
> from_timer()
> to pass the timer pointer explicitly.
> 
> The RCU lifetime on baid_data is unclear, so this adds a direct copy
> of the
> rcu_ptr passed to the original callback. It may be possible to
> improve this
> to just use baid_data->mvm->baid_map[baid_data->baid] instead.
> 
> Cc: Johannes Berg 
> Cc: Emmanuel Grumbach 
> Cc: Luca Coelho 
> Cc: Intel Linux Wireless 
> Cc: Kalle Valo 
> Cc: Sara Sharon 
> Cc: linux-wirel...@vger.kernel.org
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 
> ---

Thanks, Kees.  I'm taking this for review on our internal tree.  If all
our checks pass, I'll apply it and it will reach the mainline following
our usual upstreaming process.

--
Cheers,
Luca.


Re: [PATCH] drivers/wireless: iwlwifi/mvm: Convert timers to use timer_setup()

2017-10-24 Thread Luca Coelho
On Tue, 2017-10-24 at 02:29 -0700, Kees Cook wrote:
> In preparation for unconditionally passing the struct timer_list
> pointer to
> all timer callbacks, switch to using the new timer_setup() and
> from_timer()
> to pass the timer pointer explicitly.
> 
> The RCU lifetime on baid_data is unclear, so this adds a direct copy
> of the
> rcu_ptr passed to the original callback. It may be possible to
> improve this
> to just use baid_data->mvm->baid_map[baid_data->baid] instead.
> 
> Cc: Johannes Berg 
> Cc: Emmanuel Grumbach 
> Cc: Luca Coelho 
> Cc: Intel Linux Wireless 
> Cc: Kalle Valo 
> Cc: Sara Sharon 
> Cc: linux-wirel...@vger.kernel.org
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 
> ---

Thanks, Kees.  I'm taking this for review on our internal tree.  If all
our checks pass, I'll apply it and it will reach the mainline following
our usual upstreaming process.

--
Cheers,
Luca.


Re: [PATCH 1/3] driver: mailbox: add support for Hi3660

2017-10-24 Thread Leo Yan
Hi Jassi,

On Wed, Oct 25, 2017 at 09:47:34AM +0530, Jassi Brar wrote:
> On Mon, Aug 7, 2017 at 2:47 PM, Zhong Kaihua  wrote:
> > From: Kaihua Zhong 
> >
> > Add mailbox driver for Hi3660.
> >
> > Signed-off-by: Leo Yan 
> > Signed-off-by: Ruyi Wang 
> > Tested-by: Kaihua Zhong 
> >
> > ---
> >  drivers/mailbox/Kconfig  |   6 +
> >  drivers/mailbox/Makefile |   2 +
> >  drivers/mailbox/hi3660-mailbox.c | 688 
> > +++
> >  3 files changed, 696 insertions(+)
> >  create mode 100644 drivers/mailbox/hi3660-mailbox.c
> >
> > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> > index ee1a3d9..778ba85 100644
> > --- a/drivers/mailbox/Kconfig
> > +++ b/drivers/mailbox/Kconfig
> > @@ -116,6 +116,12 @@ config HI6220_MBOX
> >   between application processors and MCU. Say Y here if you want to
> >   build Hi6220 mailbox controller driver.
> >
> > +config HI3660_MBOX
> > +   tristate "Hi3660 Mailbox"
> > +   depends on ARCH_HISI
> > +   help
> > + Mailbox implementation for Hi3660.
> > +
> >  config MAILBOX_TEST
> > tristate "Mailbox Test Client"
> > depends on OF
> > diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> > index e2bcb03..f1c2fc4 100644
> > --- a/drivers/mailbox/Makefile
> > +++ b/drivers/mailbox/Makefile
> > @@ -28,6 +28,8 @@ obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += 
> > mailbox-xgene-slimpro.o
> >
> >  obj-$(CONFIG_HI6220_MBOX)  += hi6220-mailbox.o
> >
> > +obj-$(CONFIG_HI3660_MBOX)  += hi3660-mailbox.o
> > +
> >  obj-$(CONFIG_BCM_PDC_MBOX) += bcm-pdc-mailbox.o
> >
> >  obj-$(CONFIG_BCM_FLEXRM_MBOX)  += bcm-flexrm-mailbox.o
> > diff --git a/drivers/mailbox/hi3660-mailbox.c 
> > b/drivers/mailbox/hi3660-mailbox.c
> > new file mode 100644
> > index 000..14f469d
> > --- /dev/null
> > +++ b/drivers/mailbox/hi3660-mailbox.c
> > @@ -0,0 +1,688 @@
> > +/*
> > + * Hisilicon's Hi3660 mailbox driver
> > + *
> > + * Copyright (c) 2017 Hisilicon Limited.
> > + * Copyright (c) 2017 Linaro Limited.
> > + *
> > + * Author: Leo Yan 
> > + *
> > + * This program is free software: you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation, version 2 of the License.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> >
> no client.h please

Will remove.

> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "mailbox.h"
> > +
> > +#define MBOX_CHAN_MAX  32
> > +
> > +#define MBOX_TX0x1
> > +
> > +/* Mailbox message length: 2 words */
> > +#define MBOX_MSG_LEN   2
> > +
> > +#define MBOX_OFF(m)(0x40 * (m))
> > +#define MBOX_SRC_REG(m)MBOX_OFF(m)
> > +#define MBOX_DST_REG(m)(MBOX_OFF(m) + 0x04)
> > +#define MBOX_DCLR_REG(m)   (MBOX_OFF(m) + 0x08)
> > +#define MBOX_DSTAT_REG(m)  (MBOX_OFF(m) + 0x0C)
> > +#define MBOX_MODE_REG(m)   (MBOX_OFF(m) + 0x10)
> > +#define MBOX_IMASK_REG(m)  (MBOX_OFF(m) + 0x14)
> > +#define MBOX_ICLR_REG(m)   (MBOX_OFF(m) + 0x18)
> > +#define MBOX_SEND_REG(m)   (MBOX_OFF(m) + 0x1C)
> > +#define MBOX_DATA_REG(m, i)(MBOX_OFF(m) + 0x20 + ((i) << 2))
> > +
> > +#define MBOX_CPU_IMASK(cpu)(((cpu) << 3) + 0x800)
> > +#define MBOX_CPU_IRST(cpu) (((cpu) << 3) + 0x804)
> > +#define MBOX_IPC_LOCK  (0xA00)
> > +
> > +#define MBOX_IPC_UNLOCKED  0x
> > +#define AUTOMATIC_ACK_CONFIG   (1 << 0)
> > +#define NO_FUNC_CONFIG (0 << 0)
> > +
> > +#define MBOX_MANUAL_ACK0
> > +#define MBOX_AUTO_ACK  1
> > +
> > +#define MBOX_STATE_IDLE(1 << 4)
> > +#define MBOX_STATE_OUT (1 << 5)
> > +#define MBOX_STATE_IN  (1 << 6)
> > +#define MBOX_STATE_ACK (1 << 7)
> > +
> > +#define MBOX_DESTINATION_STATUS(1 << 6)
> > +
> BIT(x) please

Will fix.

> > +struct hi3660_mbox_chan {
> > +
> > +   /*
> > +* Description for channel's hardware info:
> > +*  - direction: tx or rx
> > +*  - dst irq: peer core's irq number
> > +*  - ack irq: local irq number
> > +*  - slot number
> > +*/
> > +   unsigned int dir, 

Re: [PATCH 1/3] driver: mailbox: add support for Hi3660

2017-10-24 Thread Leo Yan
Hi Jassi,

On Wed, Oct 25, 2017 at 09:47:34AM +0530, Jassi Brar wrote:
> On Mon, Aug 7, 2017 at 2:47 PM, Zhong Kaihua  wrote:
> > From: Kaihua Zhong 
> >
> > Add mailbox driver for Hi3660.
> >
> > Signed-off-by: Leo Yan 
> > Signed-off-by: Ruyi Wang 
> > Tested-by: Kaihua Zhong 
> >
> > ---
> >  drivers/mailbox/Kconfig  |   6 +
> >  drivers/mailbox/Makefile |   2 +
> >  drivers/mailbox/hi3660-mailbox.c | 688 
> > +++
> >  3 files changed, 696 insertions(+)
> >  create mode 100644 drivers/mailbox/hi3660-mailbox.c
> >
> > diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> > index ee1a3d9..778ba85 100644
> > --- a/drivers/mailbox/Kconfig
> > +++ b/drivers/mailbox/Kconfig
> > @@ -116,6 +116,12 @@ config HI6220_MBOX
> >   between application processors and MCU. Say Y here if you want to
> >   build Hi6220 mailbox controller driver.
> >
> > +config HI3660_MBOX
> > +   tristate "Hi3660 Mailbox"
> > +   depends on ARCH_HISI
> > +   help
> > + Mailbox implementation for Hi3660.
> > +
> >  config MAILBOX_TEST
> > tristate "Mailbox Test Client"
> > depends on OF
> > diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> > index e2bcb03..f1c2fc4 100644
> > --- a/drivers/mailbox/Makefile
> > +++ b/drivers/mailbox/Makefile
> > @@ -28,6 +28,8 @@ obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += 
> > mailbox-xgene-slimpro.o
> >
> >  obj-$(CONFIG_HI6220_MBOX)  += hi6220-mailbox.o
> >
> > +obj-$(CONFIG_HI3660_MBOX)  += hi3660-mailbox.o
> > +
> >  obj-$(CONFIG_BCM_PDC_MBOX) += bcm-pdc-mailbox.o
> >
> >  obj-$(CONFIG_BCM_FLEXRM_MBOX)  += bcm-flexrm-mailbox.o
> > diff --git a/drivers/mailbox/hi3660-mailbox.c 
> > b/drivers/mailbox/hi3660-mailbox.c
> > new file mode 100644
> > index 000..14f469d
> > --- /dev/null
> > +++ b/drivers/mailbox/hi3660-mailbox.c
> > @@ -0,0 +1,688 @@
> > +/*
> > + * Hisilicon's Hi3660 mailbox driver
> > + *
> > + * Copyright (c) 2017 Hisilicon Limited.
> > + * Copyright (c) 2017 Linaro Limited.
> > + *
> > + * Author: Leo Yan 
> > + *
> > + * This program is free software: you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation, version 2 of the License.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> >
> no client.h please

Will remove.

> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "mailbox.h"
> > +
> > +#define MBOX_CHAN_MAX  32
> > +
> > +#define MBOX_TX0x1
> > +
> > +/* Mailbox message length: 2 words */
> > +#define MBOX_MSG_LEN   2
> > +
> > +#define MBOX_OFF(m)(0x40 * (m))
> > +#define MBOX_SRC_REG(m)MBOX_OFF(m)
> > +#define MBOX_DST_REG(m)(MBOX_OFF(m) + 0x04)
> > +#define MBOX_DCLR_REG(m)   (MBOX_OFF(m) + 0x08)
> > +#define MBOX_DSTAT_REG(m)  (MBOX_OFF(m) + 0x0C)
> > +#define MBOX_MODE_REG(m)   (MBOX_OFF(m) + 0x10)
> > +#define MBOX_IMASK_REG(m)  (MBOX_OFF(m) + 0x14)
> > +#define MBOX_ICLR_REG(m)   (MBOX_OFF(m) + 0x18)
> > +#define MBOX_SEND_REG(m)   (MBOX_OFF(m) + 0x1C)
> > +#define MBOX_DATA_REG(m, i)(MBOX_OFF(m) + 0x20 + ((i) << 2))
> > +
> > +#define MBOX_CPU_IMASK(cpu)(((cpu) << 3) + 0x800)
> > +#define MBOX_CPU_IRST(cpu) (((cpu) << 3) + 0x804)
> > +#define MBOX_IPC_LOCK  (0xA00)
> > +
> > +#define MBOX_IPC_UNLOCKED  0x
> > +#define AUTOMATIC_ACK_CONFIG   (1 << 0)
> > +#define NO_FUNC_CONFIG (0 << 0)
> > +
> > +#define MBOX_MANUAL_ACK0
> > +#define MBOX_AUTO_ACK  1
> > +
> > +#define MBOX_STATE_IDLE(1 << 4)
> > +#define MBOX_STATE_OUT (1 << 5)
> > +#define MBOX_STATE_IN  (1 << 6)
> > +#define MBOX_STATE_ACK (1 << 7)
> > +
> > +#define MBOX_DESTINATION_STATUS(1 << 6)
> > +
> BIT(x) please

Will fix.

> > +struct hi3660_mbox_chan {
> > +
> > +   /*
> > +* Description for channel's hardware info:
> > +*  - direction: tx or rx
> > +*  - dst irq: peer core's irq number
> > +*  - ack irq: local irq number
> > +*  - slot number
> > +*/
> > +   unsigned int dir, dst_irq, ack_irq;
> > +   unsigned int slot;
> > +
> > +   unsigned int *buf;
> > +
> I think you mean   u32 *buf

We have polished 

[PATCH v4 5/7] completion: Add support for initializing completion with lockdep_map

2017-10-24 Thread Byungchul Park
Sometimes, we want to initialize completions with sparate lockdep maps
to assign lock classes as desired. For example, the workqueue code
needs to directly manage lockdep maps, since only the code is aware of
how to classify lockdep maps properly.

Provide additional macros initializing completions in that way.

Signed-off-by: Byungchul Park 
---
 include/linux/completion.h | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/completion.h b/include/linux/completion.h
index cae5400..02f8cde 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -49,6 +49,13 @@ static inline void complete_release_commit(struct completion 
*x)
lock_commit_crosslock((struct lockdep_map *)>map);
 }
 
+#define init_completion_map(x, m)  \
+do {   \
+   lockdep_init_map_crosslock((struct lockdep_map *)&(x)->map, \
+   (m)->name, (m)->key, 0);
\
+   __init_completion(x);   \
+} while (0)
+
 #define init_completion(x) \
 do {   \
static struct lock_class_key __key; \
@@ -58,6 +65,7 @@ static inline void complete_release_commit(struct completion 
*x)
__init_completion(x);   \
 } while (0)
 #else
+#define init_completion_map(x, m) __init_completion(x)
 #define init_completion(x) __init_completion(x)
 static inline void complete_acquire(struct completion *x) {}
 static inline void complete_release(struct completion *x) {}
@@ -73,6 +81,9 @@ static inline void complete_release_commit(struct completion 
*x) {}
{ 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
 #endif
 
+#define COMPLETION_INITIALIZER_ONSTACK_MAP(work, map) \
+   (*({ init_completion_map(&(work), &(map)); &(work); }))
+
 #define COMPLETION_INITIALIZER_ONSTACK(work) \
(*({ init_completion();  }))
 
@@ -102,8 +113,11 @@ static inline void complete_release_commit(struct 
completion *x) {}
 #ifdef CONFIG_LOCKDEP
 # define DECLARE_COMPLETION_ONSTACK(work) \
struct completion work = COMPLETION_INITIALIZER_ONSTACK(work)
+# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) \
+   struct completion work = COMPLETION_INITIALIZER_ONSTACK_MAP(work, map)
 #else
 # define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
+# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) DECLARE_COMPLETION(work)
 #endif
 
 /**
-- 
1.9.1



[PATCH v4 5/7] completion: Add support for initializing completion with lockdep_map

2017-10-24 Thread Byungchul Park
Sometimes, we want to initialize completions with sparate lockdep maps
to assign lock classes as desired. For example, the workqueue code
needs to directly manage lockdep maps, since only the code is aware of
how to classify lockdep maps properly.

Provide additional macros initializing completions in that way.

Signed-off-by: Byungchul Park 
---
 include/linux/completion.h | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/completion.h b/include/linux/completion.h
index cae5400..02f8cde 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -49,6 +49,13 @@ static inline void complete_release_commit(struct completion 
*x)
lock_commit_crosslock((struct lockdep_map *)>map);
 }
 
+#define init_completion_map(x, m)  \
+do {   \
+   lockdep_init_map_crosslock((struct lockdep_map *)&(x)->map, \
+   (m)->name, (m)->key, 0);
\
+   __init_completion(x);   \
+} while (0)
+
 #define init_completion(x) \
 do {   \
static struct lock_class_key __key; \
@@ -58,6 +65,7 @@ static inline void complete_release_commit(struct completion 
*x)
__init_completion(x);   \
 } while (0)
 #else
+#define init_completion_map(x, m) __init_completion(x)
 #define init_completion(x) __init_completion(x)
 static inline void complete_acquire(struct completion *x) {}
 static inline void complete_release(struct completion *x) {}
@@ -73,6 +81,9 @@ static inline void complete_release_commit(struct completion 
*x) {}
{ 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
 #endif
 
+#define COMPLETION_INITIALIZER_ONSTACK_MAP(work, map) \
+   (*({ init_completion_map(&(work), &(map)); &(work); }))
+
 #define COMPLETION_INITIALIZER_ONSTACK(work) \
(*({ init_completion();  }))
 
@@ -102,8 +113,11 @@ static inline void complete_release_commit(struct 
completion *x) {}
 #ifdef CONFIG_LOCKDEP
 # define DECLARE_COMPLETION_ONSTACK(work) \
struct completion work = COMPLETION_INITIALIZER_ONSTACK(work)
+# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) \
+   struct completion work = COMPLETION_INITIALIZER_ONSTACK_MAP(work, map)
 #else
 # define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
+# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) DECLARE_COMPLETION(work)
 #endif
 
 /**
-- 
1.9.1



[PATCH v4 1/7] block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait

2017-10-24 Thread Byungchul Park
From: Christoph Hellwig 

Simplify the code by getting rid of the submit_bio_ret structure.

Signed-off-by: Christoph Hellwig 
---
 block/bio.c | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 5f5472e..99d0ca5 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -917,17 +917,9 @@ int bio_iov_iter_get_pages(struct bio *bio, struct 
iov_iter *iter)
 }
 EXPORT_SYMBOL_GPL(bio_iov_iter_get_pages);
 
-struct submit_bio_ret {
-   struct completion event;
-   int error;
-};
-
 static void submit_bio_wait_endio(struct bio *bio)
 {
-   struct submit_bio_ret *ret = bio->bi_private;
-
-   ret->error = blk_status_to_errno(bio->bi_status);
-   complete(>event);
+   complete(bio->bi_private);
 }
 
 /**
@@ -943,16 +935,15 @@ static void submit_bio_wait_endio(struct bio *bio)
  */
 int submit_bio_wait(struct bio *bio)
 {
-   struct submit_bio_ret ret;
+   DECLARE_COMPLETION_ONSTACK(done);
 
-   init_completion();
-   bio->bi_private = 
+   bio->bi_private = 
bio->bi_end_io = submit_bio_wait_endio;
bio->bi_opf |= REQ_SYNC;
submit_bio(bio);
-   wait_for_completion_io();
+   wait_for_completion_io();
 
-   return ret.error;
+   return blk_status_to_errno(bio->bi_status);
 }
 EXPORT_SYMBOL(submit_bio_wait);
 
-- 
1.9.1



[PATCH v4 7/7] block: Assign a lock_class per gendisk used for wait_for_completion()

2017-10-24 Thread Byungchul Park
Darrick posted the following warning and Dave Chinner analyzed it:

> ==
> WARNING: possible circular locking dependency detected
> 4.14.0-rc1-fixes #1 Tainted: GW
> --
> loop0/31693 is trying to acquire lock:
>  (&(>i_mmaplock)->mr_lock){}, at: [] 
> xfs_ilock+0x23c/0x330 [xfs]
>
> but now in release context of a crosslock acquired at the following:
>  ((complete)){+.+.}, at: [] 
> submit_bio_wait+0x7f/0xb0
>
> which lock already depends on the new lock.
>
> the existing dependency chain (in reverse order) is:
>
> -> #2 ((complete)){+.+.}:
>lock_acquire+0xab/0x200
>wait_for_completion_io+0x4e/0x1a0
>submit_bio_wait+0x7f/0xb0
>blkdev_issue_zeroout+0x71/0xa0
>xfs_bmapi_convert_unwritten+0x11f/0x1d0 [xfs]
>xfs_bmapi_write+0x374/0x11f0 [xfs]
>xfs_iomap_write_direct+0x2ac/0x430 [xfs]
>xfs_file_iomap_begin+0x20d/0xd50 [xfs]
>iomap_apply+0x43/0xe0
>dax_iomap_rw+0x89/0xf0
>xfs_file_dax_write+0xcc/0x220 [xfs]
>xfs_file_write_iter+0xf0/0x130 [xfs]
>__vfs_write+0xd9/0x150
>vfs_write+0xc8/0x1c0
>SyS_write+0x45/0xa0
>entry_SYSCALL_64_fastpath+0x1f/0xbe
>
> -> #1 (_nondir_ilock_class){}:
>lock_acquire+0xab/0x200
>down_write_nested+0x4a/0xb0
>xfs_ilock+0x263/0x330 [xfs]
>xfs_setattr_size+0x152/0x370 [xfs]
>xfs_vn_setattr+0x6b/0x90 [xfs]
>notify_change+0x27d/0x3f0
>do_truncate+0x5b/0x90
>path_openat+0x237/0xa90
>do_filp_open+0x8a/0xf0
>do_sys_open+0x11c/0x1f0
>entry_SYSCALL_64_fastpath+0x1f/0xbe
>
> -> #0 (&(>i_mmaplock)->mr_lock){}:
>up_write+0x1c/0x40
>xfs_iunlock+0x1d0/0x310 [xfs]
>xfs_file_fallocate+0x8a/0x310 [xfs]
>loop_queue_work+0xb7/0x8d0
>kthread_worker_fn+0xb9/0x1f0
>
> Chain exists of:
>   &(>i_mmaplock)->mr_lock --> _nondir_ilock_class --> 
> (complete)
>
>  Possible unsafe locking scenario by crosslock:
>
>CPU0CPU1
>
>   lock(_nondir_ilock_class);
>   lock((complete));
>lock(&(>i_mmaplock)->mr_lock);
>unlock((complete));
>
>*** DEADLOCK ***

The warning is a false positive, caused by the fact that all
wait_for_completion()s in submit_bio_wait() are waiting with the same
lock class.

However, some bios have nothing to do with others, for example, the case
might happen while using loop devices, between bios of an upper device
and a lower device(=loop device).

The safest way to assign different lock classes to different devices is
to do it for each gendisk. In other words, this patch assigns a
lockdep_map per gendisk and uses it when initializing completion in
submit_bio_wait().

Of course, it might be too conservative. But, making it safest for now
and extended by block layer experts later is good, at the moment.

Reported-by: Darrick J. Wong 
Analyzed-by: Dave Chinner 
Signed-off-by: Byungchul Park 
---
 block/bio.c   |  2 +-
 block/genhd.c | 10 ++
 include/linux/genhd.h | 24 ++--
 3 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 99d0ca5..a3cb1d1 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -935,7 +935,7 @@ static void submit_bio_wait_endio(struct bio *bio)
  */
 int submit_bio_wait(struct bio *bio)
 {
-   DECLARE_COMPLETION_ONSTACK(done);
+   DECLARE_COMPLETION_ONSTACK_MAP(done, bio->bi_disk->lockdep_map);
 
bio->bi_private = 
bio->bi_end_io = submit_bio_wait_endio;
diff --git a/block/genhd.c b/block/genhd.c
index dd305c6..630c0da 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1354,13 +1354,7 @@ dev_t blk_lookup_devt(const char *name, int partno)
 }
 EXPORT_SYMBOL(blk_lookup_devt);
 
-struct gendisk *alloc_disk(int minors)
-{
-   return alloc_disk_node(minors, NUMA_NO_NODE);
-}
-EXPORT_SYMBOL(alloc_disk);
-
-struct gendisk *alloc_disk_node(int minors, int node_id)
+struct gendisk *__alloc_disk_node(int minors, int node_id)
 {
struct gendisk *disk;
struct disk_part_tbl *ptbl;
@@ -1411,7 +1405,7 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
}
return disk;
 }
-EXPORT_SYMBOL(alloc_disk_node);
+EXPORT_SYMBOL(__alloc_disk_node);
 
 struct kobject *get_disk(struct gendisk *disk)
 {
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 6d85a75..f6ec6a2 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -206,6 +206,9 @@ struct gendisk {
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
int node_id;
struct badblocks *bb;
+#ifdef CONFIG_LOCKDEP
+   struct lockdep_map lockdep_map;
+#endif
 };
 
 static inline struct gendisk 

[PATCH v4 1/7] block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait

2017-10-24 Thread Byungchul Park
From: Christoph Hellwig 

Simplify the code by getting rid of the submit_bio_ret structure.

Signed-off-by: Christoph Hellwig 
---
 block/bio.c | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 5f5472e..99d0ca5 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -917,17 +917,9 @@ int bio_iov_iter_get_pages(struct bio *bio, struct 
iov_iter *iter)
 }
 EXPORT_SYMBOL_GPL(bio_iov_iter_get_pages);
 
-struct submit_bio_ret {
-   struct completion event;
-   int error;
-};
-
 static void submit_bio_wait_endio(struct bio *bio)
 {
-   struct submit_bio_ret *ret = bio->bi_private;
-
-   ret->error = blk_status_to_errno(bio->bi_status);
-   complete(>event);
+   complete(bio->bi_private);
 }
 
 /**
@@ -943,16 +935,15 @@ static void submit_bio_wait_endio(struct bio *bio)
  */
 int submit_bio_wait(struct bio *bio)
 {
-   struct submit_bio_ret ret;
+   DECLARE_COMPLETION_ONSTACK(done);
 
-   init_completion();
-   bio->bi_private = 
+   bio->bi_private = 
bio->bi_end_io = submit_bio_wait_endio;
bio->bi_opf |= REQ_SYNC;
submit_bio(bio);
-   wait_for_completion_io();
+   wait_for_completion_io();
 
-   return ret.error;
+   return blk_status_to_errno(bio->bi_status);
 }
 EXPORT_SYMBOL(submit_bio_wait);
 
-- 
1.9.1



[PATCH v4 7/7] block: Assign a lock_class per gendisk used for wait_for_completion()

2017-10-24 Thread Byungchul Park
Darrick posted the following warning and Dave Chinner analyzed it:

> ==
> WARNING: possible circular locking dependency detected
> 4.14.0-rc1-fixes #1 Tainted: GW
> --
> loop0/31693 is trying to acquire lock:
>  (&(>i_mmaplock)->mr_lock){}, at: [] 
> xfs_ilock+0x23c/0x330 [xfs]
>
> but now in release context of a crosslock acquired at the following:
>  ((complete)){+.+.}, at: [] 
> submit_bio_wait+0x7f/0xb0
>
> which lock already depends on the new lock.
>
> the existing dependency chain (in reverse order) is:
>
> -> #2 ((complete)){+.+.}:
>lock_acquire+0xab/0x200
>wait_for_completion_io+0x4e/0x1a0
>submit_bio_wait+0x7f/0xb0
>blkdev_issue_zeroout+0x71/0xa0
>xfs_bmapi_convert_unwritten+0x11f/0x1d0 [xfs]
>xfs_bmapi_write+0x374/0x11f0 [xfs]
>xfs_iomap_write_direct+0x2ac/0x430 [xfs]
>xfs_file_iomap_begin+0x20d/0xd50 [xfs]
>iomap_apply+0x43/0xe0
>dax_iomap_rw+0x89/0xf0
>xfs_file_dax_write+0xcc/0x220 [xfs]
>xfs_file_write_iter+0xf0/0x130 [xfs]
>__vfs_write+0xd9/0x150
>vfs_write+0xc8/0x1c0
>SyS_write+0x45/0xa0
>entry_SYSCALL_64_fastpath+0x1f/0xbe
>
> -> #1 (_nondir_ilock_class){}:
>lock_acquire+0xab/0x200
>down_write_nested+0x4a/0xb0
>xfs_ilock+0x263/0x330 [xfs]
>xfs_setattr_size+0x152/0x370 [xfs]
>xfs_vn_setattr+0x6b/0x90 [xfs]
>notify_change+0x27d/0x3f0
>do_truncate+0x5b/0x90
>path_openat+0x237/0xa90
>do_filp_open+0x8a/0xf0
>do_sys_open+0x11c/0x1f0
>entry_SYSCALL_64_fastpath+0x1f/0xbe
>
> -> #0 (&(>i_mmaplock)->mr_lock){}:
>up_write+0x1c/0x40
>xfs_iunlock+0x1d0/0x310 [xfs]
>xfs_file_fallocate+0x8a/0x310 [xfs]
>loop_queue_work+0xb7/0x8d0
>kthread_worker_fn+0xb9/0x1f0
>
> Chain exists of:
>   &(>i_mmaplock)->mr_lock --> _nondir_ilock_class --> 
> (complete)
>
>  Possible unsafe locking scenario by crosslock:
>
>CPU0CPU1
>
>   lock(_nondir_ilock_class);
>   lock((complete));
>lock(&(>i_mmaplock)->mr_lock);
>unlock((complete));
>
>*** DEADLOCK ***

The warning is a false positive, caused by the fact that all
wait_for_completion()s in submit_bio_wait() are waiting with the same
lock class.

However, some bios have nothing to do with others, for example, the case
might happen while using loop devices, between bios of an upper device
and a lower device(=loop device).

The safest way to assign different lock classes to different devices is
to do it for each gendisk. In other words, this patch assigns a
lockdep_map per gendisk and uses it when initializing completion in
submit_bio_wait().

Of course, it might be too conservative. But, making it safest for now
and extended by block layer experts later is good, at the moment.

Reported-by: Darrick J. Wong 
Analyzed-by: Dave Chinner 
Signed-off-by: Byungchul Park 
---
 block/bio.c   |  2 +-
 block/genhd.c | 10 ++
 include/linux/genhd.h | 24 ++--
 3 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 99d0ca5..a3cb1d1 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -935,7 +935,7 @@ static void submit_bio_wait_endio(struct bio *bio)
  */
 int submit_bio_wait(struct bio *bio)
 {
-   DECLARE_COMPLETION_ONSTACK(done);
+   DECLARE_COMPLETION_ONSTACK_MAP(done, bio->bi_disk->lockdep_map);
 
bio->bi_private = 
bio->bi_end_io = submit_bio_wait_endio;
diff --git a/block/genhd.c b/block/genhd.c
index dd305c6..630c0da 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1354,13 +1354,7 @@ dev_t blk_lookup_devt(const char *name, int partno)
 }
 EXPORT_SYMBOL(blk_lookup_devt);
 
-struct gendisk *alloc_disk(int minors)
-{
-   return alloc_disk_node(minors, NUMA_NO_NODE);
-}
-EXPORT_SYMBOL(alloc_disk);
-
-struct gendisk *alloc_disk_node(int minors, int node_id)
+struct gendisk *__alloc_disk_node(int minors, int node_id)
 {
struct gendisk *disk;
struct disk_part_tbl *ptbl;
@@ -1411,7 +1405,7 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
}
return disk;
 }
-EXPORT_SYMBOL(alloc_disk_node);
+EXPORT_SYMBOL(__alloc_disk_node);
 
 struct kobject *get_disk(struct gendisk *disk)
 {
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 6d85a75..f6ec6a2 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -206,6 +206,9 @@ struct gendisk {
 #endif /* CONFIG_BLK_DEV_INTEGRITY */
int node_id;
struct badblocks *bb;
+#ifdef CONFIG_LOCKDEP
+   struct lockdep_map lockdep_map;
+#endif
 };
 
 static inline struct gendisk *part_to_disk(struct hd_struct *part)
@@ -590,8 +593,7 @@ extern struct 

[PATCH v4 2/7] locking/lockdep: Add a boot parameter allowing unwind in cross-release and disable it by default

2017-10-24 Thread Byungchul Park
Johan Hovold reported a heavy performance regression caused by lockdep
cross-release:

 > Boot time (from "Linux version" to login prompt) had in fact doubled
 > since 4.13 where it took 17 seconds (with my current config) compared to
 > the 35 seconds I now see with 4.14-rc4.
 >
 > I quick bisect pointed to lockdep and specifically the following commit:
 >
 >  28a903f63ec0 ("locking/lockdep: Handle non(or multi)-acquisition
 > of a crosslock")
 >
 > which I've verified is the commit which doubled the boot time (compared
 > to 28a903f63ec0^) (added by lockdep crossrelease series [1]).

Currently cross-release performs unwind on every acquisition, but that
is very expensive.

This patch makes unwind optional and disables it by default and only
records acquire_ip.

Full stack traces are sometimes required for full analysis, in which
case a boot paramter, crossrelease_fullstack, can be specified.

On my qemu Ubuntu machine (x86_64, 4 cores, 512M), the regression was
fixed. We measure boot times with 'perf stat --null --repeat 10 $QEMU',
where $QEMU launches a kernel with init=/bin/true:

1. No lockdep enabled:

 Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):

   2.756558155 seconds time elapsed( +-  0.09% )

2. Lockdep enabled:

 Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):

   2.968710420 seconds time elapsed( +-  0.12% )

3. Lockdep enabled + cross-release enabled:

 Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):

   3.153839636 seconds time elapsed( +-  0.31% )

4. Lockdep enabled + cross-release enabled + this patch applied:

 Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):

   2.963669551 seconds time elapsed( +-  0.11% )

I.e. lockdep cross-release performance is now indistinguishable from
vanilla lockdep.

Reported-by: Johan Hovold 
Suggested-by: Thomas Gleixner 
Signed-off-by: Byungchul Park 
---
 Documentation/admin-guide/kernel-parameters.txt |  3 +++
 kernel/locking/lockdep.c| 19 +--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index ead7f40..4107b01 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -709,6 +709,9 @@
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
 
+   crossrelease_fullstack
+   [KNL] Allow to record full stack trace in cross-release
+
cryptomgr.notests
 [KNL] Disable crypto self-tests
 
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e36e652..160b5d6 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -76,6 +76,15 @@
 #define lock_stat 0
 #endif
 
+static int crossrelease_fullstack;
+static int __init allow_crossrelease_fullstack(char *str)
+{
+   crossrelease_fullstack = 1;
+   return 0;
+}
+
+early_param("crossrelease_fullstack", allow_crossrelease_fullstack);
+
 /*
  * lockdep_lock: protects the lockdep graph, the hashes and the
  *   class/list/hash allocators.
@@ -4863,8 +4872,14 @@ static void add_xhlock(struct held_lock *hlock)
xhlock->trace.nr_entries = 0;
xhlock->trace.max_entries = MAX_XHLOCK_TRACE_ENTRIES;
xhlock->trace.entries = xhlock->trace_entries;
-   xhlock->trace.skip = 3;
-   save_stack_trace(>trace);
+
+   if (crossrelease_fullstack) {
+   xhlock->trace.skip = 3;
+   save_stack_trace(>trace);
+   } else {
+   xhlock->trace.nr_entries = 1;
+   xhlock->trace.entries[0] = hlock->acquire_ip;
+   }
 }
 
 static inline int same_context_xhlock(struct hist_lock *xhlock)
-- 
1.9.1



[PATCH v4 2/7] locking/lockdep: Add a boot parameter allowing unwind in cross-release and disable it by default

2017-10-24 Thread Byungchul Park
Johan Hovold reported a heavy performance regression caused by lockdep
cross-release:

 > Boot time (from "Linux version" to login prompt) had in fact doubled
 > since 4.13 where it took 17 seconds (with my current config) compared to
 > the 35 seconds I now see with 4.14-rc4.
 >
 > I quick bisect pointed to lockdep and specifically the following commit:
 >
 >  28a903f63ec0 ("locking/lockdep: Handle non(or multi)-acquisition
 > of a crosslock")
 >
 > which I've verified is the commit which doubled the boot time (compared
 > to 28a903f63ec0^) (added by lockdep crossrelease series [1]).

Currently cross-release performs unwind on every acquisition, but that
is very expensive.

This patch makes unwind optional and disables it by default and only
records acquire_ip.

Full stack traces are sometimes required for full analysis, in which
case a boot paramter, crossrelease_fullstack, can be specified.

On my qemu Ubuntu machine (x86_64, 4 cores, 512M), the regression was
fixed. We measure boot times with 'perf stat --null --repeat 10 $QEMU',
where $QEMU launches a kernel with init=/bin/true:

1. No lockdep enabled:

 Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):

   2.756558155 seconds time elapsed( +-  0.09% )

2. Lockdep enabled:

 Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):

   2.968710420 seconds time elapsed( +-  0.12% )

3. Lockdep enabled + cross-release enabled:

 Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):

   3.153839636 seconds time elapsed( +-  0.31% )

4. Lockdep enabled + cross-release enabled + this patch applied:

 Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):

   2.963669551 seconds time elapsed( +-  0.11% )

I.e. lockdep cross-release performance is now indistinguishable from
vanilla lockdep.

Reported-by: Johan Hovold 
Suggested-by: Thomas Gleixner 
Signed-off-by: Byungchul Park 
---
 Documentation/admin-guide/kernel-parameters.txt |  3 +++
 kernel/locking/lockdep.c| 19 +--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index ead7f40..4107b01 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -709,6 +709,9 @@
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
 
+   crossrelease_fullstack
+   [KNL] Allow to record full stack trace in cross-release
+
cryptomgr.notests
 [KNL] Disable crypto self-tests
 
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e36e652..160b5d6 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -76,6 +76,15 @@
 #define lock_stat 0
 #endif
 
+static int crossrelease_fullstack;
+static int __init allow_crossrelease_fullstack(char *str)
+{
+   crossrelease_fullstack = 1;
+   return 0;
+}
+
+early_param("crossrelease_fullstack", allow_crossrelease_fullstack);
+
 /*
  * lockdep_lock: protects the lockdep graph, the hashes and the
  *   class/list/hash allocators.
@@ -4863,8 +4872,14 @@ static void add_xhlock(struct held_lock *hlock)
xhlock->trace.nr_entries = 0;
xhlock->trace.max_entries = MAX_XHLOCK_TRACE_ENTRIES;
xhlock->trace.entries = xhlock->trace_entries;
-   xhlock->trace.skip = 3;
-   save_stack_trace(>trace);
+
+   if (crossrelease_fullstack) {
+   xhlock->trace.skip = 3;
+   save_stack_trace(>trace);
+   } else {
+   xhlock->trace.nr_entries = 1;
+   xhlock->trace.entries[0] = hlock->acquire_ip;
+   }
 }
 
 static inline int same_context_xhlock(struct hist_lock *xhlock)
-- 
1.9.1



[PATCH v4 6/7] workqueue: Remove unnecessary acquisitions wrt workqueue flush

2017-10-24 Thread Byungchul Park
The workqueue added manual acquisitions to catch deadlock cases.
Now crossrelease was introduced, some of those are redundant, since
wait_for_completion() already includes the acquisition for itself.
Removed it.

Signed-off-by: Byungchul Park 
---
 include/linux/workqueue.h |  4 ++--
 kernel/workqueue.c| 19 +++
 2 files changed, 5 insertions(+), 18 deletions(-)

diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index f3c47a0..1455b5e 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -218,7 +218,7 @@ static inline void destroy_delayed_work_on_stack(struct 
delayed_work *work) { }
\
__init_work((_work), _onstack); \
(_work)->data = (atomic_long_t) WORK_DATA_INIT();   \
-   lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0); \
+   lockdep_init_map(&(_work)->lockdep_map, "(complete)"#_work, 
&__key, 0); \
INIT_LIST_HEAD(&(_work)->entry);\
(_work)->func = (_func);\
} while (0)
@@ -399,7 +399,7 @@ enum {
static struct lock_class_key __key; \
const char *__lock_name;\
\
-   __lock_name = #fmt#args;\
+   __lock_name = "(complete)"#fmt#args;\
\
__alloc_workqueue_key((fmt), (flags), (max_active), \
  &__key, __lock_name, ##args); \
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index c77fdf6..ee05d19 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -2496,15 +2496,8 @@ static void insert_wq_barrier(struct pool_workqueue *pwq,
INIT_WORK_ONSTACK(>work, wq_barrier_func);
__set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(>work));
 
-   /*
-* Explicitly init the crosslock for wq_barrier::done, make its lock
-* key a subkey of the corresponding work. As a result we won't
-* build a dependency between wq_barrier::done and unrelated work.
-*/
-   lockdep_init_map_crosslock((struct lockdep_map *)>done.map,
-  "(complete)wq_barr::done",
-  target->lockdep_map.key, 1);
-   __init_completion(>done);
+   init_completion_map(>done, >lockdep_map);
+
barr->task = current;
 
/*
@@ -2610,16 +2603,13 @@ void flush_workqueue(struct workqueue_struct *wq)
struct wq_flusher this_flusher = {
.list = LIST_HEAD_INIT(this_flusher.list),
.flush_color = -1,
-   .done = COMPLETION_INITIALIZER_ONSTACK(this_flusher.done),
+   .done = COMPLETION_INITIALIZER_ONSTACK_MAP(this_flusher.done, 
wq->lockdep_map),
};
int next_color;
 
if (WARN_ON(!wq_online))
return;
 
-   lock_map_acquire(>lockdep_map);
-   lock_map_release(>lockdep_map);
-
mutex_lock(>mutex);
 
/*
@@ -2882,9 +2872,6 @@ bool flush_work(struct work_struct *work)
if (WARN_ON(!wq_online))
return false;
 
-   lock_map_acquire(>lockdep_map);
-   lock_map_release(>lockdep_map);
-
if (start_flush_work(work, )) {
wait_for_completion();
destroy_work_on_stack();
-- 
1.9.1



[PATCH v4 4/7] locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK

2017-10-24 Thread Byungchul Park
The boot parameter, crossrelease_fullstack, was introduced to control
whether to enable unwind in cross-release or not. Add a Kconfig doing
the same thing.

Suggested-by: Ingo Molnar 
Signed-off-by: Byungchul Park 
---
 kernel/locking/lockdep.c |  4 
 lib/Kconfig.debug| 15 +++
 2 files changed, 19 insertions(+)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 160b5d6..db933d0 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -76,7 +76,11 @@
 #define lock_stat 0
 #endif
 
+#ifdef CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
+static int crossrelease_fullstack = 1;
+#else
 static int crossrelease_fullstack;
+#endif
 static int __init allow_crossrelease_fullstack(char *str)
 {
crossrelease_fullstack = 1;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 4bef610..e4b54a5 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1225,6 +1225,21 @@ config LOCKDEP_COMPLETIONS
 A deadlock caused by wait_for_completion() and complete() can be
 detected by lockdep using crossrelease feature.
 
+config BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
+   bool "Enable the boot parameter, crossrelease_fullstack"
+   depends on LOCKDEP_CROSSRELEASE
+   default n
+   help
+The lockdep "cross-release" feature needs to record stack traces
+(of calling functions) for all acquisitions, for eventual later
+use during analysis. By default only a single caller is recorded,
+because the unwind operation can be very expensive with deeper
+stack chains.
+
+However a boot parameter, crossrelease_fullstack, was
+introduced since sometimes deeper traces are required for full
+analysis. This option turns on the boot parameter.
+
 config DEBUG_LOCKDEP
bool "Lock dependency engine debugging"
depends on DEBUG_KERNEL && LOCKDEP
-- 
1.9.1



[PATCH v4 6/7] workqueue: Remove unnecessary acquisitions wrt workqueue flush

2017-10-24 Thread Byungchul Park
The workqueue added manual acquisitions to catch deadlock cases.
Now crossrelease was introduced, some of those are redundant, since
wait_for_completion() already includes the acquisition for itself.
Removed it.

Signed-off-by: Byungchul Park 
---
 include/linux/workqueue.h |  4 ++--
 kernel/workqueue.c| 19 +++
 2 files changed, 5 insertions(+), 18 deletions(-)

diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index f3c47a0..1455b5e 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -218,7 +218,7 @@ static inline void destroy_delayed_work_on_stack(struct 
delayed_work *work) { }
\
__init_work((_work), _onstack); \
(_work)->data = (atomic_long_t) WORK_DATA_INIT();   \
-   lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0); \
+   lockdep_init_map(&(_work)->lockdep_map, "(complete)"#_work, 
&__key, 0); \
INIT_LIST_HEAD(&(_work)->entry);\
(_work)->func = (_func);\
} while (0)
@@ -399,7 +399,7 @@ enum {
static struct lock_class_key __key; \
const char *__lock_name;\
\
-   __lock_name = #fmt#args;\
+   __lock_name = "(complete)"#fmt#args;\
\
__alloc_workqueue_key((fmt), (flags), (max_active), \
  &__key, __lock_name, ##args); \
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index c77fdf6..ee05d19 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -2496,15 +2496,8 @@ static void insert_wq_barrier(struct pool_workqueue *pwq,
INIT_WORK_ONSTACK(>work, wq_barrier_func);
__set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(>work));
 
-   /*
-* Explicitly init the crosslock for wq_barrier::done, make its lock
-* key a subkey of the corresponding work. As a result we won't
-* build a dependency between wq_barrier::done and unrelated work.
-*/
-   lockdep_init_map_crosslock((struct lockdep_map *)>done.map,
-  "(complete)wq_barr::done",
-  target->lockdep_map.key, 1);
-   __init_completion(>done);
+   init_completion_map(>done, >lockdep_map);
+
barr->task = current;
 
/*
@@ -2610,16 +2603,13 @@ void flush_workqueue(struct workqueue_struct *wq)
struct wq_flusher this_flusher = {
.list = LIST_HEAD_INIT(this_flusher.list),
.flush_color = -1,
-   .done = COMPLETION_INITIALIZER_ONSTACK(this_flusher.done),
+   .done = COMPLETION_INITIALIZER_ONSTACK_MAP(this_flusher.done, 
wq->lockdep_map),
};
int next_color;
 
if (WARN_ON(!wq_online))
return;
 
-   lock_map_acquire(>lockdep_map);
-   lock_map_release(>lockdep_map);
-
mutex_lock(>mutex);
 
/*
@@ -2882,9 +2872,6 @@ bool flush_work(struct work_struct *work)
if (WARN_ON(!wq_online))
return false;
 
-   lock_map_acquire(>lockdep_map);
-   lock_map_release(>lockdep_map);
-
if (start_flush_work(work, )) {
wait_for_completion();
destroy_work_on_stack();
-- 
1.9.1



[PATCH v4 4/7] locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK

2017-10-24 Thread Byungchul Park
The boot parameter, crossrelease_fullstack, was introduced to control
whether to enable unwind in cross-release or not. Add a Kconfig doing
the same thing.

Suggested-by: Ingo Molnar 
Signed-off-by: Byungchul Park 
---
 kernel/locking/lockdep.c |  4 
 lib/Kconfig.debug| 15 +++
 2 files changed, 19 insertions(+)

diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 160b5d6..db933d0 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -76,7 +76,11 @@
 #define lock_stat 0
 #endif
 
+#ifdef CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
+static int crossrelease_fullstack = 1;
+#else
 static int crossrelease_fullstack;
+#endif
 static int __init allow_crossrelease_fullstack(char *str)
 {
crossrelease_fullstack = 1;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 4bef610..e4b54a5 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1225,6 +1225,21 @@ config LOCKDEP_COMPLETIONS
 A deadlock caused by wait_for_completion() and complete() can be
 detected by lockdep using crossrelease feature.
 
+config BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
+   bool "Enable the boot parameter, crossrelease_fullstack"
+   depends on LOCKDEP_CROSSRELEASE
+   default n
+   help
+The lockdep "cross-release" feature needs to record stack traces
+(of calling functions) for all acquisitions, for eventual later
+use during analysis. By default only a single caller is recorded,
+because the unwind operation can be very expensive with deeper
+stack chains.
+
+However a boot parameter, crossrelease_fullstack, was
+introduced since sometimes deeper traces are required for full
+analysis. This option turns on the boot parameter.
+
 config DEBUG_LOCKDEP
bool "Lock dependency engine debugging"
depends on DEBUG_KERNEL && LOCKDEP
-- 
1.9.1



[PATCH v4 0/7] cross-release: Enhence performance and fix false positives

2017-10-24 Thread Byungchul Park
There are two things I didn't apply as Ingo suggested, since I didn't
understand his intention exactly:

   1. Adding 'Analyzed-by' tag at the 2nd patch
   2. Using a inline function instead #define at the 7th patch

Let me know if the above should still be applied.

Changes from v3
- Exclude a patch removing white space
- Enhance commit messages as Ingo suggested
- Re-design patches adding a boot param and a Kconfig allowing unwind
- Simplify a patch assigning lock classes to genhds as Ingo suggested
- Add proper tags in commit messages e.g. reported-by and analyzed-by

Changes from v2
- Combine 2 serises, fixing false positives and enhance performance
- Add Christoph Hellwig's patch simplifying submit_bio_wait() code
- Add 2 more 'init with lockdep map' macros for completionm
- Rename init_completion_with_map() to init_completion_map()

Changes from v1
- Fix kconfig description as Ingo suggested
- Fix commit message writing out CONFIG_ variable
- Introduce a new kernel parameter, crossrelease_fullstack
- Replace the number with the output of *perf*
- Separate a patch removing white space

Byungchul Park (6):
  locking/lockdep: Add a boot parameter allowing unwind in cross-release
and disable it by default
  locking/lockdep: Remove the BROKEN flag from
CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS
  locking/lockdep: Introduce
CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
  completion: Add support for initializing completion with lockdep_map
  workqueue: Remove unnecessary acquisitions wrt workqueue flush
  block: Assign a lock_class per gendisk used for wait_for_completion()

Christoph Hellwig (1):
  block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait

 Documentation/admin-guide/kernel-parameters.txt |  3 +++
 block/bio.c | 19 +--
 block/genhd.c   | 10 ++
 include/linux/completion.h  | 14 ++
 include/linux/genhd.h   | 24 ++--
 include/linux/workqueue.h   |  4 ++--
 kernel/locking/lockdep.c| 23 +--
 kernel/workqueue.c  | 19 +++
 lib/Kconfig.debug   | 19 +--
 9 files changed, 89 insertions(+), 46 deletions(-)

-- 
1.9.1



[PATCH v4 0/7] cross-release: Enhence performance and fix false positives

2017-10-24 Thread Byungchul Park
There are two things I didn't apply as Ingo suggested, since I didn't
understand his intention exactly:

   1. Adding 'Analyzed-by' tag at the 2nd patch
   2. Using a inline function instead #define at the 7th patch

Let me know if the above should still be applied.

Changes from v3
- Exclude a patch removing white space
- Enhance commit messages as Ingo suggested
- Re-design patches adding a boot param and a Kconfig allowing unwind
- Simplify a patch assigning lock classes to genhds as Ingo suggested
- Add proper tags in commit messages e.g. reported-by and analyzed-by

Changes from v2
- Combine 2 serises, fixing false positives and enhance performance
- Add Christoph Hellwig's patch simplifying submit_bio_wait() code
- Add 2 more 'init with lockdep map' macros for completionm
- Rename init_completion_with_map() to init_completion_map()

Changes from v1
- Fix kconfig description as Ingo suggested
- Fix commit message writing out CONFIG_ variable
- Introduce a new kernel parameter, crossrelease_fullstack
- Replace the number with the output of *perf*
- Separate a patch removing white space

Byungchul Park (6):
  locking/lockdep: Add a boot parameter allowing unwind in cross-release
and disable it by default
  locking/lockdep: Remove the BROKEN flag from
CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS
  locking/lockdep: Introduce
CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
  completion: Add support for initializing completion with lockdep_map
  workqueue: Remove unnecessary acquisitions wrt workqueue flush
  block: Assign a lock_class per gendisk used for wait_for_completion()

Christoph Hellwig (1):
  block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait

 Documentation/admin-guide/kernel-parameters.txt |  3 +++
 block/bio.c | 19 +--
 block/genhd.c   | 10 ++
 include/linux/completion.h  | 14 ++
 include/linux/genhd.h   | 24 ++--
 include/linux/workqueue.h   |  4 ++--
 kernel/locking/lockdep.c| 23 +--
 kernel/workqueue.c  | 19 +++
 lib/Kconfig.debug   | 19 +--
 9 files changed, 89 insertions(+), 46 deletions(-)

-- 
1.9.1



[PATCH v4 3/7] locking/lockdep: Remove the BROKEN flag from CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS

2017-10-24 Thread Byungchul Park
Now that the performance regression is fixed, re-enable
CONFIG_LOCKDEP_CROSSRELEASE=y and CONFIG_LOCKDEP_COMPLETIONS=y.

Signed-off-by: Byungchul Park 
---
 lib/Kconfig.debug | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 3db9167..4bef610 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1138,8 +1138,8 @@ config PROVE_LOCKING
select DEBUG_MUTEXES
select DEBUG_RT_MUTEXES if RT_MUTEXES
select DEBUG_LOCK_ALLOC
-   select LOCKDEP_CROSSRELEASE if BROKEN
-   select LOCKDEP_COMPLETIONS if BROKEN
+   select LOCKDEP_CROSSRELEASE
+   select LOCKDEP_COMPLETIONS
select TRACE_IRQFLAGS
default n
help
-- 
1.9.1



[PATCH v4 3/7] locking/lockdep: Remove the BROKEN flag from CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS

2017-10-24 Thread Byungchul Park
Now that the performance regression is fixed, re-enable
CONFIG_LOCKDEP_CROSSRELEASE=y and CONFIG_LOCKDEP_COMPLETIONS=y.

Signed-off-by: Byungchul Park 
---
 lib/Kconfig.debug | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 3db9167..4bef610 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1138,8 +1138,8 @@ config PROVE_LOCKING
select DEBUG_MUTEXES
select DEBUG_RT_MUTEXES if RT_MUTEXES
select DEBUG_LOCK_ALLOC
-   select LOCKDEP_CROSSRELEASE if BROKEN
-   select LOCKDEP_COMPLETIONS if BROKEN
+   select LOCKDEP_CROSSRELEASE
+   select LOCKDEP_COMPLETIONS
select TRACE_IRQFLAGS
default n
help
-- 
1.9.1



[PATCH 1/2] gpio: gpiolib: Expand sleep tolerance to include controller reset

2017-10-24 Thread Andrew Jeffery
Reset tolerance is added to gpiolib with the introduction of a new
pinconf parameter propagating the request to hardware. The existing
persistence support for sleep is augmented to include reset tolerance
if the GPIO driver provides it. Persistence continues to be enabled by
default; in-kernel consumers can opt out, but userspace (currently) does
not have a choice.

The *_SLEEP_MAY_LOSE_VALUE and *_SLEEP_MAINTAIN_VALUE symbols are
renamed, dropping the SLEEP prefix to reflect that the concept is no
longer sleep-specific.  I feel that renaming to just *_MAY_LOSE_VALUE
could initially be misinterpreted, so I've further changed the symbols
to *_TRANSITORY and *_PERSISTENT to address this.

The sysfs interface is modified only to keep consistency with the
chardev interface in enforcing persistence for userspace exports.

Signed-off-by: Andrew Jeffery 
---
I'm not wedded to the names 'transitory' and 'persistent', so feel free to
paint the bikeshed some other colour.

 drivers/gpio/gpiolib-of.c   |  6 ++--
 drivers/gpio/gpiolib-sysfs.c| 14 +---
 drivers/gpio/gpiolib.c  | 58 ++---
 drivers/gpio/gpiolib.h  |  2 +-
 include/dt-bindings/gpio/gpio.h |  6 ++--
 include/linux/gpio/consumer.h   |  8 +
 include/linux/gpio/machine.h|  4 +--
 include/linux/of_gpio.h |  2 +-
 include/linux/pinctrl/pinconf-generic.h |  2 ++
 9 files changed, 84 insertions(+), 18 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index e0d59e61b52f..4a2b8d3397c7 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -153,8 +153,8 @@ struct gpio_desc *of_find_gpio(struct device *dev, const 
char *con_id,
*flags |= GPIO_OPEN_SOURCE;
}
 
-   if (of_flags & OF_GPIO_SLEEP_MAY_LOSE_VALUE)
-   *flags |= GPIO_SLEEP_MAY_LOSE_VALUE;
+   if (of_flags & OF_GPIO_TRANSITORY)
+   *flags |= GPIO_TRANSITORY;
 
return desc;
 }
@@ -214,6 +214,8 @@ static struct gpio_desc *of_parse_own_gpio(struct 
device_node *np,
 
if (xlate_flags & OF_GPIO_ACTIVE_LOW)
*lflags |= GPIO_ACTIVE_LOW;
+   if (xlate_flags & OF_GPIO_TRANSITORY)
+   *lflags |= GPIO_TRANSITORY;
 
if (of_property_read_bool(np, "input"))
*dflags |= GPIOD_IN;
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 3f454eaf2101..0bd472ffb072 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -474,11 +474,15 @@ static ssize_t export_store(struct class *class,
status = -ENODEV;
goto done;
}
-   status = gpiod_export(desc, true);
-   if (status < 0)
-   gpiod_free(desc);
-   else
-   set_bit(FLAG_SYSFS, >flags);
+
+   status = gpiod_set_transitory(desc, false);
+   if (!status) {
+   status = gpiod_export(desc, true);
+   if (status < 0)
+   gpiod_free(desc);
+   else
+   set_bit(FLAG_SYSFS, >flags);
+   }
 
 done:
if (status)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 3827f0767101..fb29c81225f3 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -503,6 +503,10 @@ static int linehandle_create(struct gpio_device *gdev, 
void __user *ip)
if (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)
set_bit(FLAG_OPEN_SOURCE, >flags);
 
+   ret = gpiod_set_transitory(desc, false);
+   if (ret < 0)
+   goto out_free_descs;
+
/*
 * Lines have to be requested explicitly for input
 * or output, else the line will be treated "as is".
@@ -2424,6 +2428,46 @@ int gpiod_set_debounce(struct gpio_desc *desc, unsigned 
debounce)
 EXPORT_SYMBOL_GPL(gpiod_set_debounce);
 
 /**
+ * gpiod_set_transitory - Lose or retain GPIO state on suspend or reset
+ * @desc: descriptor of the GPIO for which to configure persistence
+ * @transitory: True to lose state on suspend or reset, false for persistence
+ *
+ * Returns:
+ * 0 on success, otherwise a negative error code.
+ */
+int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
+{
+   struct gpio_chip *chip;
+   unsigned long packed;
+   int gpio;
+   int rc;
+
+   /* Handle FLAG_TRANSITORY first for suspend case */
+   if (transitory)
+   set_bit(FLAG_TRANSITORY, >flags);
+   else
+   clear_bit(FLAG_TRANSITORY, >flags);
+
+   /* Configure reset persistence if the controller supports it */
+   chip = desc->gdev->chip;
+   if (!chip->set_config)
+   return 0;
+
+   packed = pinconf_to_config_packed(PIN_CONFIG_RESET_TOLERANT,
+ !transitory);
+   

[PATCH 1/2] gpio: gpiolib: Expand sleep tolerance to include controller reset

2017-10-24 Thread Andrew Jeffery
Reset tolerance is added to gpiolib with the introduction of a new
pinconf parameter propagating the request to hardware. The existing
persistence support for sleep is augmented to include reset tolerance
if the GPIO driver provides it. Persistence continues to be enabled by
default; in-kernel consumers can opt out, but userspace (currently) does
not have a choice.

The *_SLEEP_MAY_LOSE_VALUE and *_SLEEP_MAINTAIN_VALUE symbols are
renamed, dropping the SLEEP prefix to reflect that the concept is no
longer sleep-specific.  I feel that renaming to just *_MAY_LOSE_VALUE
could initially be misinterpreted, so I've further changed the symbols
to *_TRANSITORY and *_PERSISTENT to address this.

The sysfs interface is modified only to keep consistency with the
chardev interface in enforcing persistence for userspace exports.

Signed-off-by: Andrew Jeffery 
---
I'm not wedded to the names 'transitory' and 'persistent', so feel free to
paint the bikeshed some other colour.

 drivers/gpio/gpiolib-of.c   |  6 ++--
 drivers/gpio/gpiolib-sysfs.c| 14 +---
 drivers/gpio/gpiolib.c  | 58 ++---
 drivers/gpio/gpiolib.h  |  2 +-
 include/dt-bindings/gpio/gpio.h |  6 ++--
 include/linux/gpio/consumer.h   |  8 +
 include/linux/gpio/machine.h|  4 +--
 include/linux/of_gpio.h |  2 +-
 include/linux/pinctrl/pinconf-generic.h |  2 ++
 9 files changed, 84 insertions(+), 18 deletions(-)

diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
index e0d59e61b52f..4a2b8d3397c7 100644
--- a/drivers/gpio/gpiolib-of.c
+++ b/drivers/gpio/gpiolib-of.c
@@ -153,8 +153,8 @@ struct gpio_desc *of_find_gpio(struct device *dev, const 
char *con_id,
*flags |= GPIO_OPEN_SOURCE;
}
 
-   if (of_flags & OF_GPIO_SLEEP_MAY_LOSE_VALUE)
-   *flags |= GPIO_SLEEP_MAY_LOSE_VALUE;
+   if (of_flags & OF_GPIO_TRANSITORY)
+   *flags |= GPIO_TRANSITORY;
 
return desc;
 }
@@ -214,6 +214,8 @@ static struct gpio_desc *of_parse_own_gpio(struct 
device_node *np,
 
if (xlate_flags & OF_GPIO_ACTIVE_LOW)
*lflags |= GPIO_ACTIVE_LOW;
+   if (xlate_flags & OF_GPIO_TRANSITORY)
+   *lflags |= GPIO_TRANSITORY;
 
if (of_property_read_bool(np, "input"))
*dflags |= GPIOD_IN;
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 3f454eaf2101..0bd472ffb072 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -474,11 +474,15 @@ static ssize_t export_store(struct class *class,
status = -ENODEV;
goto done;
}
-   status = gpiod_export(desc, true);
-   if (status < 0)
-   gpiod_free(desc);
-   else
-   set_bit(FLAG_SYSFS, >flags);
+
+   status = gpiod_set_transitory(desc, false);
+   if (!status) {
+   status = gpiod_export(desc, true);
+   if (status < 0)
+   gpiod_free(desc);
+   else
+   set_bit(FLAG_SYSFS, >flags);
+   }
 
 done:
if (status)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 3827f0767101..fb29c81225f3 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -503,6 +503,10 @@ static int linehandle_create(struct gpio_device *gdev, 
void __user *ip)
if (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)
set_bit(FLAG_OPEN_SOURCE, >flags);
 
+   ret = gpiod_set_transitory(desc, false);
+   if (ret < 0)
+   goto out_free_descs;
+
/*
 * Lines have to be requested explicitly for input
 * or output, else the line will be treated "as is".
@@ -2424,6 +2428,46 @@ int gpiod_set_debounce(struct gpio_desc *desc, unsigned 
debounce)
 EXPORT_SYMBOL_GPL(gpiod_set_debounce);
 
 /**
+ * gpiod_set_transitory - Lose or retain GPIO state on suspend or reset
+ * @desc: descriptor of the GPIO for which to configure persistence
+ * @transitory: True to lose state on suspend or reset, false for persistence
+ *
+ * Returns:
+ * 0 on success, otherwise a negative error code.
+ */
+int gpiod_set_transitory(struct gpio_desc *desc, bool transitory)
+{
+   struct gpio_chip *chip;
+   unsigned long packed;
+   int gpio;
+   int rc;
+
+   /* Handle FLAG_TRANSITORY first for suspend case */
+   if (transitory)
+   set_bit(FLAG_TRANSITORY, >flags);
+   else
+   clear_bit(FLAG_TRANSITORY, >flags);
+
+   /* Configure reset persistence if the controller supports it */
+   chip = desc->gdev->chip;
+   if (!chip->set_config)
+   return 0;
+
+   packed = pinconf_to_config_packed(PIN_CONFIG_RESET_TOLERANT,
+ !transitory);
+   gpio = 

[PATCH 2/2] gpio: aspeed: Add support for reset tolerance

2017-10-24 Thread Andrew Jeffery
Use the new pinconf parameter for reset tolerance to expose the
associated capability of the Aspeed GPIO controller.

Signed-off-by: Andrew Jeffery 
---
 drivers/gpio/gpio-aspeed.c | 39 +--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index 00dc1c020198..856498925538 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -60,6 +60,7 @@ struct aspeed_gpio_bank {
uint16_tval_regs;
uint16_tirq_regs;
uint16_tdebounce_regs;
+   uint16_ttolerance_regs;
const char  names[4][3];
 };
 
@@ -70,48 +71,56 @@ static const struct aspeed_gpio_bank aspeed_gpio_banks[] = {
.val_regs = 0x,
.irq_regs = 0x0008,
.debounce_regs = 0x0040,
+   .tolerance_regs = 0x001c,
.names = { "A", "B", "C", "D" },
},
{
.val_regs = 0x0020,
.irq_regs = 0x0028,
.debounce_regs = 0x0048,
+   .tolerance_regs = 0x003c,
.names = { "E", "F", "G", "H" },
},
{
.val_regs = 0x0070,
.irq_regs = 0x0098,
.debounce_regs = 0x00b0,
+   .tolerance_regs = 0x00ac,
.names = { "I", "J", "K", "L" },
},
{
.val_regs = 0x0078,
.irq_regs = 0x00e8,
.debounce_regs = 0x0100,
+   .tolerance_regs = 0x00fc,
.names = { "M", "N", "O", "P" },
},
{
.val_regs = 0x0080,
.irq_regs = 0x0118,
.debounce_regs = 0x0130,
+   .tolerance_regs = 0x012c,
.names = { "Q", "R", "S", "T" },
},
{
.val_regs = 0x0088,
.irq_regs = 0x0148,
.debounce_regs = 0x0160,
+   .tolerance_regs = 0x015c,
.names = { "U", "V", "W", "X" },
},
{
.val_regs = 0x01E0,
.irq_regs = 0x0178,
.debounce_regs = 0x0190,
+   .tolerance_regs = 0x018c,
.names = { "Y", "Z", "AA", "AB" },
},
{
-   .val_regs = 0x01E8,
-   .irq_regs = 0x01A8,
+   .val_regs = 0x01e8,
+   .irq_regs = 0x01a8,
.debounce_regs = 0x01c0,
+   .tolerance_regs = 0x01bc,
.names = { "AC", "", "", "" },
},
 };
@@ -534,6 +543,30 @@ static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
return 0;
 }
 
+static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
+   unsigned int offset, bool enable)
+{
+   struct aspeed_gpio *gpio = gpiochip_get_data(chip);
+   const struct aspeed_gpio_bank *bank;
+   unsigned long flags;
+   u32 val;
+
+   bank = to_bank(offset);
+
+   spin_lock_irqsave(>lock, flags);
+   val = readl(gpio->base + bank->tolerance_regs);
+
+   if (enable)
+   val |= GPIO_BIT(offset);
+   else
+   val &= ~GPIO_BIT(offset);
+
+   writel(val, gpio->base + bank->tolerance_regs);
+   spin_unlock_irqrestore(>lock, flags);
+
+   return 0;
+}
+
 static int aspeed_gpio_request(struct gpio_chip *chip, unsigned int offset)
 {
if (!have_gpio(gpiochip_get_data(chip), offset))
@@ -771,6 +804,8 @@ static int aspeed_gpio_set_config(struct gpio_chip *chip, 
unsigned int offset,
param == PIN_CONFIG_DRIVE_OPEN_SOURCE)
/* Return -ENOTSUPP to trigger emulation, as per datasheet */
return -ENOTSUPP;
+   else if (param == PIN_CONFIG_RESET_TOLERANT)
+   return aspeed_gpio_reset_tolerance(chip, offset, arg);
 
return -ENOTSUPP;
 }
-- 
2.11.0



[PATCH 0/2] gpio: Expose reset tolerance capability

2017-10-24 Thread Andrew Jeffery
Hello,

This short series enables GPIO state persistence across controller resets,
modifying gpiolib to expose control of the behaviour and providing an initial
implementation in the Aspeed GPIO controller.

This is a follow-up to the initial RFC series[1], which had some undesirable
features (and bugs).

>From the RFC, I've:

1. Dropped the idea of distinguishing between sleep and reset cases[2]
2. Changed the default behaviour from transitory to persistent (must explicitly
   request transitory behaviour for controllers supporting reset tolerance)[3]
3. Dropped the ability for userspace to configure whether or not the exported
   GPIO is persistent[4][5]

On point 2, whilst the patch modifying the sysfs interface ABI no-longer lives,
gpiolib-sysfs still requires modification to provide consistent behaviour with
the chardev interface in providing a default-persistent GPIO on export.

Regarding point 3, I figured this is something we can add later once there's
been some discussion on how much of a good idea it is.

As some of the capabilities in the RFC have been dropped, I've squashed the
gpiolib support into a single patch as it's not really that complex.

Hopefully that addresses the feedback on the RFC. Please review!

Andrew

[1] https://www.spinics.net/lists/devicetree/msg199559.html
[2] https://www.spinics.net/lists/devicetree/msg199566.html
[3] https://www.spinics.net/lists/devicetree/msg199574.html
[4] https://www.spinics.net/lists/devicetree/msg199568.html
[5] https://www.spinics.net/lists/devicetree/msg199569.html 

Andrew Jeffery (2):
  gpio: gpiolib: Expand sleep tolerance to include controller reset
  gpio: aspeed: Add support for reset tolerance

 drivers/gpio/gpio-aspeed.c  | 39 --
 drivers/gpio/gpiolib-of.c   |  6 ++--
 drivers/gpio/gpiolib-sysfs.c| 14 +---
 drivers/gpio/gpiolib.c  | 58 ++---
 drivers/gpio/gpiolib.h  |  2 +-
 include/dt-bindings/gpio/gpio.h |  6 ++--
 include/linux/gpio/consumer.h   |  8 +
 include/linux/gpio/machine.h|  4 +--
 include/linux/of_gpio.h |  2 +-
 include/linux/pinctrl/pinconf-generic.h |  2 ++
 10 files changed, 121 insertions(+), 20 deletions(-)

-- 
2.11.0



[PATCH 2/2] gpio: aspeed: Add support for reset tolerance

2017-10-24 Thread Andrew Jeffery
Use the new pinconf parameter for reset tolerance to expose the
associated capability of the Aspeed GPIO controller.

Signed-off-by: Andrew Jeffery 
---
 drivers/gpio/gpio-aspeed.c | 39 +--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index 00dc1c020198..856498925538 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -60,6 +60,7 @@ struct aspeed_gpio_bank {
uint16_tval_regs;
uint16_tirq_regs;
uint16_tdebounce_regs;
+   uint16_ttolerance_regs;
const char  names[4][3];
 };
 
@@ -70,48 +71,56 @@ static const struct aspeed_gpio_bank aspeed_gpio_banks[] = {
.val_regs = 0x,
.irq_regs = 0x0008,
.debounce_regs = 0x0040,
+   .tolerance_regs = 0x001c,
.names = { "A", "B", "C", "D" },
},
{
.val_regs = 0x0020,
.irq_regs = 0x0028,
.debounce_regs = 0x0048,
+   .tolerance_regs = 0x003c,
.names = { "E", "F", "G", "H" },
},
{
.val_regs = 0x0070,
.irq_regs = 0x0098,
.debounce_regs = 0x00b0,
+   .tolerance_regs = 0x00ac,
.names = { "I", "J", "K", "L" },
},
{
.val_regs = 0x0078,
.irq_regs = 0x00e8,
.debounce_regs = 0x0100,
+   .tolerance_regs = 0x00fc,
.names = { "M", "N", "O", "P" },
},
{
.val_regs = 0x0080,
.irq_regs = 0x0118,
.debounce_regs = 0x0130,
+   .tolerance_regs = 0x012c,
.names = { "Q", "R", "S", "T" },
},
{
.val_regs = 0x0088,
.irq_regs = 0x0148,
.debounce_regs = 0x0160,
+   .tolerance_regs = 0x015c,
.names = { "U", "V", "W", "X" },
},
{
.val_regs = 0x01E0,
.irq_regs = 0x0178,
.debounce_regs = 0x0190,
+   .tolerance_regs = 0x018c,
.names = { "Y", "Z", "AA", "AB" },
},
{
-   .val_regs = 0x01E8,
-   .irq_regs = 0x01A8,
+   .val_regs = 0x01e8,
+   .irq_regs = 0x01a8,
.debounce_regs = 0x01c0,
+   .tolerance_regs = 0x01bc,
.names = { "AC", "", "", "" },
},
 };
@@ -534,6 +543,30 @@ static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
return 0;
 }
 
+static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
+   unsigned int offset, bool enable)
+{
+   struct aspeed_gpio *gpio = gpiochip_get_data(chip);
+   const struct aspeed_gpio_bank *bank;
+   unsigned long flags;
+   u32 val;
+
+   bank = to_bank(offset);
+
+   spin_lock_irqsave(>lock, flags);
+   val = readl(gpio->base + bank->tolerance_regs);
+
+   if (enable)
+   val |= GPIO_BIT(offset);
+   else
+   val &= ~GPIO_BIT(offset);
+
+   writel(val, gpio->base + bank->tolerance_regs);
+   spin_unlock_irqrestore(>lock, flags);
+
+   return 0;
+}
+
 static int aspeed_gpio_request(struct gpio_chip *chip, unsigned int offset)
 {
if (!have_gpio(gpiochip_get_data(chip), offset))
@@ -771,6 +804,8 @@ static int aspeed_gpio_set_config(struct gpio_chip *chip, 
unsigned int offset,
param == PIN_CONFIG_DRIVE_OPEN_SOURCE)
/* Return -ENOTSUPP to trigger emulation, as per datasheet */
return -ENOTSUPP;
+   else if (param == PIN_CONFIG_RESET_TOLERANT)
+   return aspeed_gpio_reset_tolerance(chip, offset, arg);
 
return -ENOTSUPP;
 }
-- 
2.11.0



[PATCH 0/2] gpio: Expose reset tolerance capability

2017-10-24 Thread Andrew Jeffery
Hello,

This short series enables GPIO state persistence across controller resets,
modifying gpiolib to expose control of the behaviour and providing an initial
implementation in the Aspeed GPIO controller.

This is a follow-up to the initial RFC series[1], which had some undesirable
features (and bugs).

>From the RFC, I've:

1. Dropped the idea of distinguishing between sleep and reset cases[2]
2. Changed the default behaviour from transitory to persistent (must explicitly
   request transitory behaviour for controllers supporting reset tolerance)[3]
3. Dropped the ability for userspace to configure whether or not the exported
   GPIO is persistent[4][5]

On point 2, whilst the patch modifying the sysfs interface ABI no-longer lives,
gpiolib-sysfs still requires modification to provide consistent behaviour with
the chardev interface in providing a default-persistent GPIO on export.

Regarding point 3, I figured this is something we can add later once there's
been some discussion on how much of a good idea it is.

As some of the capabilities in the RFC have been dropped, I've squashed the
gpiolib support into a single patch as it's not really that complex.

Hopefully that addresses the feedback on the RFC. Please review!

Andrew

[1] https://www.spinics.net/lists/devicetree/msg199559.html
[2] https://www.spinics.net/lists/devicetree/msg199566.html
[3] https://www.spinics.net/lists/devicetree/msg199574.html
[4] https://www.spinics.net/lists/devicetree/msg199568.html
[5] https://www.spinics.net/lists/devicetree/msg199569.html 

Andrew Jeffery (2):
  gpio: gpiolib: Expand sleep tolerance to include controller reset
  gpio: aspeed: Add support for reset tolerance

 drivers/gpio/gpio-aspeed.c  | 39 --
 drivers/gpio/gpiolib-of.c   |  6 ++--
 drivers/gpio/gpiolib-sysfs.c| 14 +---
 drivers/gpio/gpiolib.c  | 58 ++---
 drivers/gpio/gpiolib.h  |  2 +-
 include/dt-bindings/gpio/gpio.h |  6 ++--
 include/linux/gpio/consumer.h   |  8 +
 include/linux/gpio/machine.h|  4 +--
 include/linux/of_gpio.h |  2 +-
 include/linux/pinctrl/pinconf-generic.h |  2 ++
 10 files changed, 121 insertions(+), 20 deletions(-)

-- 
2.11.0



Re: Kernel error messages: leds fujitsu::radio_led: Setting an LED's brightness failed

2017-10-24 Thread Michał Kępień
> >   - Investigating the E LED.  This requires taking a look at the DSDT
> > dump from your laptop and searching for clues as to how this LED is
> > handled.  I will be happy to do that, but again, no promises about
> > how much time it will take.  (And given the nature of this task, I
> > cannot promise I will find anything reasonable at all.  I also might
> > ask you to do some further experiments as I do not have an E751
> > myself.)

I feel stupid for only suggesting this now, but can this simply be the
eco LED?  The DSDT dump from your laptop suggests so, as well as the
description of the E LED in the manual.  Have you tried playing around
with /sys/class/leds/fujitsu::eco_led?

> Don't forget to take a look at the I LED...

I could not find anything in the DSDT dump from your laptop that would
suggest this LED can be controlled using ACPI.

-- 
Best regards,
Michał Kępień


Re: Kernel error messages: leds fujitsu::radio_led: Setting an LED's brightness failed

2017-10-24 Thread Michał Kępień
> >   - Investigating the E LED.  This requires taking a look at the DSDT
> > dump from your laptop and searching for clues as to how this LED is
> > handled.  I will be happy to do that, but again, no promises about
> > how much time it will take.  (And given the nature of this task, I
> > cannot promise I will find anything reasonable at all.  I also might
> > ask you to do some further experiments as I do not have an E751
> > myself.)

I feel stupid for only suggesting this now, but can this simply be the
eco LED?  The DSDT dump from your laptop suggests so, as well as the
description of the E LED in the manual.  Have you tried playing around
with /sys/class/leds/fujitsu::eco_led?

> Don't forget to take a look at the I LED...

I could not find anything in the DSDT dump from your laptop that would
suggest this LED can be controlled using ACPI.

-- 
Best regards,
Michał Kępień


Re: [PATCH v7 2/2] crypto: s5p-sss: Add HASH support for Exynos

2017-10-24 Thread Vladimir Zapolskiy
Hi Kamil,

I'll just answer to your question, all the comments from you are accepted,
please send a new version with the minor fixes, hopefully the change will
be included into v4.15-rc.

On 10/24/2017 02:27 PM, Kamil Konieczny wrote:
> Hi Vladimir,
> 
> Thank you for review, I will apply almost all of your remarks,
> see answers below.
> 
> On 22.10.2017 12:18, Vladimir Zapolskiy wrote:
>> Hi Kamil,
>>
>> thank you for updates, I have just a few more comments.
>>

[snip]

>>> +/**
>>> + * s5p_hash_import - import hash state
>>> + * @req:   AHASH request
>>> + * @in:buffer with state to be imported from
>>> + */
>>> +static int s5p_hash_import(struct ahash_request *req, const void *in)
>>> +{
>>> +   struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
>>> +   struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
>>> +   struct s5p_hash_ctx *tctx = crypto_ahash_ctx(tfm);
>>> +   const struct s5p_hash_reqctx *ctx_in = in;
>>> +
>>> +   memcpy(ctx, in, sizeof(*ctx) + BUFLEN);
>>> +   if (ctx_in->bufcnt < 0 || ctx_in->bufcnt > BUFLEN) {
>>
>> Now "ctx_in->bufcnt < 0" condition can be removed, moreover it
>> will eliminate a warning reproted by the compiler:
>>
>> drivers/crypto/s5p-sss.c:1748:21: warning: comparison of unsigned expression 
>> < 0 is always false [-Wtype-limits]
>>   if (ctx_in->bufcnt < 0 || ctx_in->bufcnt > BUFLEN) {
>>  ^
> 
> You are right, I will drop first condition. BTW what compiler options are you 
> using ?
> This one was not reported by my compilation process.
> 

Regularly I specify 'make C=1 W=1' options to build a kernel with changes,
some of the new reported warnings are false positives, but in general it
makes sense to check the output to catch potential issues like this one.

--
With best wishes,
Vladimir


Re: [PATCH v7 2/2] crypto: s5p-sss: Add HASH support for Exynos

2017-10-24 Thread Vladimir Zapolskiy
Hi Kamil,

I'll just answer to your question, all the comments from you are accepted,
please send a new version with the minor fixes, hopefully the change will
be included into v4.15-rc.

On 10/24/2017 02:27 PM, Kamil Konieczny wrote:
> Hi Vladimir,
> 
> Thank you for review, I will apply almost all of your remarks,
> see answers below.
> 
> On 22.10.2017 12:18, Vladimir Zapolskiy wrote:
>> Hi Kamil,
>>
>> thank you for updates, I have just a few more comments.
>>

[snip]

>>> +/**
>>> + * s5p_hash_import - import hash state
>>> + * @req:   AHASH request
>>> + * @in:buffer with state to be imported from
>>> + */
>>> +static int s5p_hash_import(struct ahash_request *req, const void *in)
>>> +{
>>> +   struct s5p_hash_reqctx *ctx = ahash_request_ctx(req);
>>> +   struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
>>> +   struct s5p_hash_ctx *tctx = crypto_ahash_ctx(tfm);
>>> +   const struct s5p_hash_reqctx *ctx_in = in;
>>> +
>>> +   memcpy(ctx, in, sizeof(*ctx) + BUFLEN);
>>> +   if (ctx_in->bufcnt < 0 || ctx_in->bufcnt > BUFLEN) {
>>
>> Now "ctx_in->bufcnt < 0" condition can be removed, moreover it
>> will eliminate a warning reproted by the compiler:
>>
>> drivers/crypto/s5p-sss.c:1748:21: warning: comparison of unsigned expression 
>> < 0 is always false [-Wtype-limits]
>>   if (ctx_in->bufcnt < 0 || ctx_in->bufcnt > BUFLEN) {
>>  ^
> 
> You are right, I will drop first condition. BTW what compiler options are you 
> using ?
> This one was not reported by my compilation process.
> 

Regularly I specify 'make C=1 W=1' options to build a kernel with changes,
some of the new reported warnings are false positives, but in general it
makes sense to check the output to catch potential issues like this one.

--
With best wishes,
Vladimir


[PATCH] platform/x86: fujitsu-laptop: Fix radio LED detection

2017-10-24 Thread Michał Kępień
Radio LED detection method implemented in commit 4f62568c1fcf
("fujitsu-laptop: Support radio LED") turned out to be incorrect as it
causes a radio LED to be erroneously detected on a Fujitsu Lifebook E751
which has a slide switch (and thus no radio LED).  Use bit 17 of
flags_supported (the value returned by method S000 of ACPI device
FUJ02E3) to determine whether a radio LED is present as it seems to be a
more reliable indicator, based on comparing DSDT tables of four Fujitsu
Lifebook models (E744, E751, S7110, S8420).

Reported-by: Heinrich Siebmanns 
Signed-off-by: Michał Kępień 
---
I do not have a Fujitsu laptop with a radio LED for testing, so I was
only able to check that this patch still does not cause a radio LED to
be detected on a Lifebook S7020.

Harvey, could you please try this patch on your Lifebook E751 and see
whether the log messages you reported disappear?  I will be happy to
assist you off-list in case you need help with it.

 drivers/platform/x86/fujitsu-laptop.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c 
b/drivers/platform/x86/fujitsu-laptop.c
index 56a8195096a2..2cfbd3fa5136 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -691,6 +691,7 @@ static enum led_brightness eco_led_get(struct led_classdev 
*cdev)
 
 static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
 {
+   struct fujitsu_laptop *priv = acpi_driver_data(device);
struct led_classdev *led;
int result;
 
@@ -724,12 +725,15 @@ static int acpi_fujitsu_laptop_leds_register(struct 
acpi_device *device)
}
 
/*
-* BTNI bit 24 seems to indicate the presence of a radio toggle
-* button in place of a slide switch, and all such machines appear
-* to also have an RF LED.  Therefore use bit 24 as an indicator
-* that an RF LED is present.
+* Some Fujitsu laptops have a radio toggle button in place of a slide
+* switch and all such machines appear to also have an RF LED.  Based on
+* comparing DSDT tables of four Fujitsu Lifebook models (E744, E751,
+* S7110, S8420; the first one has a radio toggle button, the other
+* three have slide switches), bit 17 of flags_supported (the value
+* returned by method S000 of ACPI device FUJ02E3) seems to indicate
+* whether given model has a radio toggle button.
 */
-   if (call_fext_func(device, FUNC_BUTTONS, 0x0, 0x0, 0x0) & BIT(24)) {
+   if (priv->flags_supported & BIT(17)) {
led = devm_kzalloc(>dev, sizeof(*led), GFP_KERNEL);
if (!led)
return -ENOMEM;
-- 
2.14.2



[PATCH] platform/x86: fujitsu-laptop: Fix radio LED detection

2017-10-24 Thread Michał Kępień
Radio LED detection method implemented in commit 4f62568c1fcf
("fujitsu-laptop: Support radio LED") turned out to be incorrect as it
causes a radio LED to be erroneously detected on a Fujitsu Lifebook E751
which has a slide switch (and thus no radio LED).  Use bit 17 of
flags_supported (the value returned by method S000 of ACPI device
FUJ02E3) to determine whether a radio LED is present as it seems to be a
more reliable indicator, based on comparing DSDT tables of four Fujitsu
Lifebook models (E744, E751, S7110, S8420).

Reported-by: Heinrich Siebmanns 
Signed-off-by: Michał Kępień 
---
I do not have a Fujitsu laptop with a radio LED for testing, so I was
only able to check that this patch still does not cause a radio LED to
be detected on a Lifebook S7020.

Harvey, could you please try this patch on your Lifebook E751 and see
whether the log messages you reported disappear?  I will be happy to
assist you off-list in case you need help with it.

 drivers/platform/x86/fujitsu-laptop.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/platform/x86/fujitsu-laptop.c 
b/drivers/platform/x86/fujitsu-laptop.c
index 56a8195096a2..2cfbd3fa5136 100644
--- a/drivers/platform/x86/fujitsu-laptop.c
+++ b/drivers/platform/x86/fujitsu-laptop.c
@@ -691,6 +691,7 @@ static enum led_brightness eco_led_get(struct led_classdev 
*cdev)
 
 static int acpi_fujitsu_laptop_leds_register(struct acpi_device *device)
 {
+   struct fujitsu_laptop *priv = acpi_driver_data(device);
struct led_classdev *led;
int result;
 
@@ -724,12 +725,15 @@ static int acpi_fujitsu_laptop_leds_register(struct 
acpi_device *device)
}
 
/*
-* BTNI bit 24 seems to indicate the presence of a radio toggle
-* button in place of a slide switch, and all such machines appear
-* to also have an RF LED.  Therefore use bit 24 as an indicator
-* that an RF LED is present.
+* Some Fujitsu laptops have a radio toggle button in place of a slide
+* switch and all such machines appear to also have an RF LED.  Based on
+* comparing DSDT tables of four Fujitsu Lifebook models (E744, E751,
+* S7110, S8420; the first one has a radio toggle button, the other
+* three have slide switches), bit 17 of flags_supported (the value
+* returned by method S000 of ACPI device FUJ02E3) seems to indicate
+* whether given model has a radio toggle button.
 */
-   if (call_fext_func(device, FUNC_BUTTONS, 0x0, 0x0, 0x0) & BIT(24)) {
+   if (priv->flags_supported & BIT(17)) {
led = devm_kzalloc(>dev, sizeof(*led), GFP_KERNEL);
if (!led)
return -ENOMEM;
-- 
2.14.2



Re: [PATCH] paravirt/locks: avoid modifying static key before jump_label_init()

2017-10-24 Thread Dou Liyang

Hi Juergen,

At 10/23/2017 09:49 PM, Juergen Gross wrote:

Don't try to set the static virt_spin_lock_key to a value before
jump_label_init() has been called, as this will result in a WARN().

Solve the problem by introducing a new lock_init() hook called after
jump_label_init() instead of doing the call inside of
smp_prepare_boot_cpu().

Signed-off-by: Juergen Gross 
---
Based on kernel/git/tip/tip.git locking/core


I also found that WARN() in tip tree.

IMO, adding a hook in start_kernel() is not elegant. It will
affect other arches and increase the complexity of the system.

I like your original method.
So, I try to fix it by moving the native_pv_lock_init() from
 native_smp_prepare_boot_cpu() to native_smp_prepare_cpus().

I hope it's useful to you.

Thanks,
dou.

==<
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index aed1460..6b1335a 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1323,6 +1323,8 @@ void __init native_smp_prepare_cpus(unsigned int 
max_cpus)

pr_info("CPU0: ");
print_cpu_info(_data(0));

+   native_pv_lock_init();
+
uv_system_init();

set_mtrr_aps_delayed_init();
@@ -1350,7 +1352,6 @@ void __init native_smp_prepare_boot_cpu(void)
/* already set me in cpu_online_mask in boot_cpu_init() */
cpumask_set_cpu(me, cpu_callout_mask);
cpu_set_state_online(me);
-   native_pv_lock_init();
 }

 void __init native_smp_cpus_done(unsigned int max_cpus)
diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c
index 5147140..570b2bc 100644
--- a/arch/x86/xen/smp_pv.c
+++ b/arch/x86/xen/smp_pv.c
@@ -236,6 +236,8 @@ static void __init xen_pv_smp_prepare_cpus(unsigned 
int max_cpus)

xen_raw_printk(m);
panic(m);
}
+   native_pv_lock_init();
+
xen_init_lock_cpu(0);

smp_store_boot_cpu_info();

---
 arch/x86/include/asm/qspinlock.h | 5 +
 arch/x86/kernel/smpboot.c| 1 -
 include/asm-generic/qspinlock.h  | 6 ++
 include/linux/spinlock.h | 4 
 include/linux/spinlock_up.h  | 4 
 init/main.c  | 2 ++
 kernel/locking/spinlock.c| 7 +++
 7 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h
index 308dfd0714c7..a53ef9ed0dc1 100644
--- a/arch/x86/include/asm/qspinlock.h
+++ b/arch/x86/include/asm/qspinlock.h
@@ -49,6 +49,7 @@ static inline void queued_spin_unlock(struct qspinlock *lock)
 #ifdef CONFIG_PARAVIRT
 DECLARE_STATIC_KEY_TRUE(virt_spin_lock_key);

+#define native_pv_lock_init native_pv_lock_init
 void native_pv_lock_init(void) __init;

 #define virt_spin_lock virt_spin_lock
@@ -70,10 +71,6 @@ static inline bool virt_spin_lock(struct qspinlock *lock)

return true;
 }
-#else
-static inline void native_pv_lock_init(void)
-{
-}
 #endif /* CONFIG_PARAVIRT */

 #include 
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 361f91674ce5..55a3121dd479 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1385,7 +1385,6 @@ void __init native_smp_prepare_boot_cpu(void)
/* already set me in cpu_online_mask in boot_cpu_init() */
cpumask_set_cpu(me, cpu_callout_mask);
cpu_set_state_online(me);
-   native_pv_lock_init();
 }

 void __init native_smp_cpus_done(unsigned int max_cpus)
diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h
index 66260777d644..42784a353401 100644
--- a/include/asm-generic/qspinlock.h
+++ b/include/asm-generic/qspinlock.h
@@ -111,6 +111,12 @@ static __always_inline bool virt_spin_lock(struct 
qspinlock *lock)
 }
 #endif

+#ifndef native_pv_lock_init
+static __always_inline void native_pv_lock_init(void)
+{
+}
+#endif
+
 /*
  * Remapping spinlock architecture specific functions to the corresponding
  * queued spinlock functions.
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 69e079c5ff98..6654ff285e5c 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -420,4 +420,8 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, 
spinlock_t *lock);
 #define atomic_dec_and_lock(atomic, lock) \
__cond_lock(lock, _atomic_dec_and_lock(atomic, lock))

+#ifdef CONFIG_SMP
+void lock_init(void) __init;
+#endif
+
 #endif /* __LINUX_SPINLOCK_H */
diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h
index 612fb530af41..bc4787900ad7 100644
--- a/include/linux/spinlock_up.h
+++ b/include/linux/spinlock_up.h
@@ -80,4 +80,8 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 #define arch_read_can_lock(lock)   (((void)(lock), 1))
 #define arch_write_can_lock(lock)  (((void)(lock), 1))

+static inline lock_init(void)
+{
+}
+
 #endif /* __LINUX_SPINLOCK_UP_H */
diff --git a/init/main.c b/init/main.c
index 0ee9c6866ada..e5c9f9bcd311 100644
--- a/init/main.c
+++ b/init/main.c

Re: [PATCH] paravirt/locks: avoid modifying static key before jump_label_init()

2017-10-24 Thread Dou Liyang

Hi Juergen,

At 10/23/2017 09:49 PM, Juergen Gross wrote:

Don't try to set the static virt_spin_lock_key to a value before
jump_label_init() has been called, as this will result in a WARN().

Solve the problem by introducing a new lock_init() hook called after
jump_label_init() instead of doing the call inside of
smp_prepare_boot_cpu().

Signed-off-by: Juergen Gross 
---
Based on kernel/git/tip/tip.git locking/core


I also found that WARN() in tip tree.

IMO, adding a hook in start_kernel() is not elegant. It will
affect other arches and increase the complexity of the system.

I like your original method.
So, I try to fix it by moving the native_pv_lock_init() from
 native_smp_prepare_boot_cpu() to native_smp_prepare_cpus().

I hope it's useful to you.

Thanks,
dou.

==<
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index aed1460..6b1335a 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1323,6 +1323,8 @@ void __init native_smp_prepare_cpus(unsigned int 
max_cpus)

pr_info("CPU0: ");
print_cpu_info(_data(0));

+   native_pv_lock_init();
+
uv_system_init();

set_mtrr_aps_delayed_init();
@@ -1350,7 +1352,6 @@ void __init native_smp_prepare_boot_cpu(void)
/* already set me in cpu_online_mask in boot_cpu_init() */
cpumask_set_cpu(me, cpu_callout_mask);
cpu_set_state_online(me);
-   native_pv_lock_init();
 }

 void __init native_smp_cpus_done(unsigned int max_cpus)
diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c
index 5147140..570b2bc 100644
--- a/arch/x86/xen/smp_pv.c
+++ b/arch/x86/xen/smp_pv.c
@@ -236,6 +236,8 @@ static void __init xen_pv_smp_prepare_cpus(unsigned 
int max_cpus)

xen_raw_printk(m);
panic(m);
}
+   native_pv_lock_init();
+
xen_init_lock_cpu(0);

smp_store_boot_cpu_info();

---
 arch/x86/include/asm/qspinlock.h | 5 +
 arch/x86/kernel/smpboot.c| 1 -
 include/asm-generic/qspinlock.h  | 6 ++
 include/linux/spinlock.h | 4 
 include/linux/spinlock_up.h  | 4 
 init/main.c  | 2 ++
 kernel/locking/spinlock.c| 7 +++
 7 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/qspinlock.h b/arch/x86/include/asm/qspinlock.h
index 308dfd0714c7..a53ef9ed0dc1 100644
--- a/arch/x86/include/asm/qspinlock.h
+++ b/arch/x86/include/asm/qspinlock.h
@@ -49,6 +49,7 @@ static inline void queued_spin_unlock(struct qspinlock *lock)
 #ifdef CONFIG_PARAVIRT
 DECLARE_STATIC_KEY_TRUE(virt_spin_lock_key);

+#define native_pv_lock_init native_pv_lock_init
 void native_pv_lock_init(void) __init;

 #define virt_spin_lock virt_spin_lock
@@ -70,10 +71,6 @@ static inline bool virt_spin_lock(struct qspinlock *lock)

return true;
 }
-#else
-static inline void native_pv_lock_init(void)
-{
-}
 #endif /* CONFIG_PARAVIRT */

 #include 
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 361f91674ce5..55a3121dd479 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1385,7 +1385,6 @@ void __init native_smp_prepare_boot_cpu(void)
/* already set me in cpu_online_mask in boot_cpu_init() */
cpumask_set_cpu(me, cpu_callout_mask);
cpu_set_state_online(me);
-   native_pv_lock_init();
 }

 void __init native_smp_cpus_done(unsigned int max_cpus)
diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h
index 66260777d644..42784a353401 100644
--- a/include/asm-generic/qspinlock.h
+++ b/include/asm-generic/qspinlock.h
@@ -111,6 +111,12 @@ static __always_inline bool virt_spin_lock(struct 
qspinlock *lock)
 }
 #endif

+#ifndef native_pv_lock_init
+static __always_inline void native_pv_lock_init(void)
+{
+}
+#endif
+
 /*
  * Remapping spinlock architecture specific functions to the corresponding
  * queued spinlock functions.
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 69e079c5ff98..6654ff285e5c 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -420,4 +420,8 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, 
spinlock_t *lock);
 #define atomic_dec_and_lock(atomic, lock) \
__cond_lock(lock, _atomic_dec_and_lock(atomic, lock))

+#ifdef CONFIG_SMP
+void lock_init(void) __init;
+#endif
+
 #endif /* __LINUX_SPINLOCK_H */
diff --git a/include/linux/spinlock_up.h b/include/linux/spinlock_up.h
index 612fb530af41..bc4787900ad7 100644
--- a/include/linux/spinlock_up.h
+++ b/include/linux/spinlock_up.h
@@ -80,4 +80,8 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 #define arch_read_can_lock(lock)   (((void)(lock), 1))
 #define arch_write_can_lock(lock)  (((void)(lock), 1))

+static inline lock_init(void)
+{
+}
+
 #endif /* __LINUX_SPINLOCK_UP_H */
diff --git a/init/main.c b/init/main.c
index 0ee9c6866ada..e5c9f9bcd311 100644
--- a/init/main.c
+++ b/init/main.c
@@ -88,6 +88,7 

Re: [PATCH] drivers/net: wan/sbni: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:47:00 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: David Howells 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH] drivers/net: wan/sbni: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:47:00 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: David Howells 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH v7 1/2] crypto: s5p-sss: change spaces into tabs in defines

2017-10-24 Thread Vladimir Zapolskiy
Hi Kamil,

On 10/24/2017 01:19 PM, Kamil Konieczny wrote:
> Hi Vladimir,
> 
> Thank you for review.
> 
> On 22.10.2017 12:18, Vladimir Zapolskiy wrote:
>> Hi Kamil,
>>
>> On 10/17/2017 02:28 PM, Kamil Konieczny wrote:
>>> change spaces into tabs in defines
>>
>> Here a grammatically correct sentence in English is welcome.
> 
> What about: "Change spaces to tabs" ?
> 

yes, it'll be fine, sorry if I was excessively pedantic.

--
With best wishes,
Vladimir


Re: [PATCH v7 1/2] crypto: s5p-sss: change spaces into tabs in defines

2017-10-24 Thread Vladimir Zapolskiy
Hi Kamil,

On 10/24/2017 01:19 PM, Kamil Konieczny wrote:
> Hi Vladimir,
> 
> Thank you for review.
> 
> On 22.10.2017 12:18, Vladimir Zapolskiy wrote:
>> Hi Kamil,
>>
>> On 10/17/2017 02:28 PM, Kamil Konieczny wrote:
>>> change spaces into tabs in defines
>>
>> Here a grammatically correct sentence in English is welcome.
> 
> What about: "Change spaces to tabs" ?
> 

yes, it'll be fine, sorry if I was excessively pedantic.

--
With best wishes,
Vladimir


Re: [PATCH] net: xfrm_user: use BUG_ON instead of if condition followed by BUG

2017-10-24 Thread David Miller
From: Herbert Xu 
Date: Wed, 25 Oct 2017 12:05:41 +0800

> On Tue, Oct 24, 2017 at 05:48:42PM +0900, David Miller wrote:
>> 
>> This discussion has happened before.
>> 
>> But I'll explain the conclusion here for your benefit.
>> 
>> BUG_ON() is a statement and everything inside of it will
>> always execute.
>> 
>> BUG_ON() is always preferred because it allows arch
>> specific code to pass the conditional result properly
>> into inline asm and builtins for optimal code generation.
> 
> This is a good point.  However, while a little bit more verbose you
> can still achieve the same assembly-level result by something like
> 
>   int err;
> 
>   err = ;
>   BUG_ON(err);
> 
> Having real code in BUG_ON may pose problems to people reading the
> code because some of us tend to ignore code in BUG_ON and similar
> macros such as BUILD_BUG_ON.

I agree that this makes the code easier to read and audit.


Re: [PATCH] net: xfrm_user: use BUG_ON instead of if condition followed by BUG

2017-10-24 Thread David Miller
From: Herbert Xu 
Date: Wed, 25 Oct 2017 12:05:41 +0800

> On Tue, Oct 24, 2017 at 05:48:42PM +0900, David Miller wrote:
>> 
>> This discussion has happened before.
>> 
>> But I'll explain the conclusion here for your benefit.
>> 
>> BUG_ON() is a statement and everything inside of it will
>> always execute.
>> 
>> BUG_ON() is always preferred because it allows arch
>> specific code to pass the conditional result properly
>> into inline asm and builtins for optimal code generation.
> 
> This is a good point.  However, while a little bit more verbose you
> can still achieve the same assembly-level result by something like
> 
>   int err;
> 
>   err = ;
>   BUG_ON(err);
> 
> Having real code in BUG_ON may pose problems to people reading the
> code because some of us tend to ignore code in BUG_ON and similar
> macros such as BUILD_BUG_ON.

I agree that this makes the code easier to read and audit.


Re: [PATCH] drivers/net: sis: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:46:52 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: Francois Romieu 
> Cc: Daniele Venzano 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH] drivers/net: sis: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:46:52 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: Francois Romieu 
> Cc: Daniele Venzano 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH 1/3] driver: mailbox: add support for Hi3660

2017-10-24 Thread Jassi Brar
On Mon, Aug 7, 2017 at 2:47 PM, Zhong Kaihua  wrote:
> From: Kaihua Zhong 
>
> Add mailbox driver for Hi3660.
>
> Signed-off-by: Leo Yan 
> Signed-off-by: Ruyi Wang 
> Tested-by: Kaihua Zhong 
>
> ---
>  drivers/mailbox/Kconfig  |   6 +
>  drivers/mailbox/Makefile |   2 +
>  drivers/mailbox/hi3660-mailbox.c | 688 
> +++
>  3 files changed, 696 insertions(+)
>  create mode 100644 drivers/mailbox/hi3660-mailbox.c
>
> diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> index ee1a3d9..778ba85 100644
> --- a/drivers/mailbox/Kconfig
> +++ b/drivers/mailbox/Kconfig
> @@ -116,6 +116,12 @@ config HI6220_MBOX
>   between application processors and MCU. Say Y here if you want to
>   build Hi6220 mailbox controller driver.
>
> +config HI3660_MBOX
> +   tristate "Hi3660 Mailbox"
> +   depends on ARCH_HISI
> +   help
> + Mailbox implementation for Hi3660.
> +
>  config MAILBOX_TEST
> tristate "Mailbox Test Client"
> depends on OF
> diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> index e2bcb03..f1c2fc4 100644
> --- a/drivers/mailbox/Makefile
> +++ b/drivers/mailbox/Makefile
> @@ -28,6 +28,8 @@ obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o
>
>  obj-$(CONFIG_HI6220_MBOX)  += hi6220-mailbox.o
>
> +obj-$(CONFIG_HI3660_MBOX)  += hi3660-mailbox.o
> +
>  obj-$(CONFIG_BCM_PDC_MBOX) += bcm-pdc-mailbox.o
>
>  obj-$(CONFIG_BCM_FLEXRM_MBOX)  += bcm-flexrm-mailbox.o
> diff --git a/drivers/mailbox/hi3660-mailbox.c 
> b/drivers/mailbox/hi3660-mailbox.c
> new file mode 100644
> index 000..14f469d
> --- /dev/null
> +++ b/drivers/mailbox/hi3660-mailbox.c
> @@ -0,0 +1,688 @@
> +/*
> + * Hisilicon's Hi3660 mailbox driver
> + *
> + * Copyright (c) 2017 Hisilicon Limited.
> + * Copyright (c) 2017 Linaro Limited.
> + *
> + * Author: Leo Yan 
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, version 2 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
>
no client.h please

> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "mailbox.h"
> +
> +#define MBOX_CHAN_MAX  32
> +
> +#define MBOX_TX0x1
> +
> +/* Mailbox message length: 2 words */
> +#define MBOX_MSG_LEN   2
> +
> +#define MBOX_OFF(m)(0x40 * (m))
> +#define MBOX_SRC_REG(m)MBOX_OFF(m)
> +#define MBOX_DST_REG(m)(MBOX_OFF(m) + 0x04)
> +#define MBOX_DCLR_REG(m)   (MBOX_OFF(m) + 0x08)
> +#define MBOX_DSTAT_REG(m)  (MBOX_OFF(m) + 0x0C)
> +#define MBOX_MODE_REG(m)   (MBOX_OFF(m) + 0x10)
> +#define MBOX_IMASK_REG(m)  (MBOX_OFF(m) + 0x14)
> +#define MBOX_ICLR_REG(m)   (MBOX_OFF(m) + 0x18)
> +#define MBOX_SEND_REG(m)   (MBOX_OFF(m) + 0x1C)
> +#define MBOX_DATA_REG(m, i)(MBOX_OFF(m) + 0x20 + ((i) << 2))
> +
> +#define MBOX_CPU_IMASK(cpu)(((cpu) << 3) + 0x800)
> +#define MBOX_CPU_IRST(cpu) (((cpu) << 3) + 0x804)
> +#define MBOX_IPC_LOCK  (0xA00)
> +
> +#define MBOX_IPC_UNLOCKED  0x
> +#define AUTOMATIC_ACK_CONFIG   (1 << 0)
> +#define NO_FUNC_CONFIG (0 << 0)
> +
> +#define MBOX_MANUAL_ACK0
> +#define MBOX_AUTO_ACK  1
> +
> +#define MBOX_STATE_IDLE(1 << 4)
> +#define MBOX_STATE_OUT (1 << 5)
> +#define MBOX_STATE_IN  (1 << 6)
> +#define MBOX_STATE_ACK (1 << 7)
> +
> +#define MBOX_DESTINATION_STATUS(1 << 6)
> +
BIT(x) please

> +struct hi3660_mbox_chan {
> +
> +   /*
> +* Description for channel's hardware info:
> +*  - direction: tx or rx
> +*  - dst irq: peer core's irq number
> +*  - ack irq: local irq number
> +*  - slot number
> +*/
> +   unsigned int dir, dst_irq, ack_irq;
> +   unsigned int slot;
> +
> +   unsigned int *buf;
> +
I think you mean   u32 *buf

> +   unsigned int irq_mode;
> +
> +   struct hi3660_mbox *parent;
>
You could get 'struct mbox_controller *' from 'struct mbox_chan' and
use container_of to get 'struct hi3660_mbox *'

> +};
> +
> +struct hi3660_mbox {
> +   struct device *dev;
> +
> +

Re: [PATCH 1/3] driver: mailbox: add support for Hi3660

2017-10-24 Thread Jassi Brar
On Mon, Aug 7, 2017 at 2:47 PM, Zhong Kaihua  wrote:
> From: Kaihua Zhong 
>
> Add mailbox driver for Hi3660.
>
> Signed-off-by: Leo Yan 
> Signed-off-by: Ruyi Wang 
> Tested-by: Kaihua Zhong 
>
> ---
>  drivers/mailbox/Kconfig  |   6 +
>  drivers/mailbox/Makefile |   2 +
>  drivers/mailbox/hi3660-mailbox.c | 688 
> +++
>  3 files changed, 696 insertions(+)
>  create mode 100644 drivers/mailbox/hi3660-mailbox.c
>
> diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
> index ee1a3d9..778ba85 100644
> --- a/drivers/mailbox/Kconfig
> +++ b/drivers/mailbox/Kconfig
> @@ -116,6 +116,12 @@ config HI6220_MBOX
>   between application processors and MCU. Say Y here if you want to
>   build Hi6220 mailbox controller driver.
>
> +config HI3660_MBOX
> +   tristate "Hi3660 Mailbox"
> +   depends on ARCH_HISI
> +   help
> + Mailbox implementation for Hi3660.
> +
>  config MAILBOX_TEST
> tristate "Mailbox Test Client"
> depends on OF
> diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
> index e2bcb03..f1c2fc4 100644
> --- a/drivers/mailbox/Makefile
> +++ b/drivers/mailbox/Makefile
> @@ -28,6 +28,8 @@ obj-$(CONFIG_XGENE_SLIMPRO_MBOX) += mailbox-xgene-slimpro.o
>
>  obj-$(CONFIG_HI6220_MBOX)  += hi6220-mailbox.o
>
> +obj-$(CONFIG_HI3660_MBOX)  += hi3660-mailbox.o
> +
>  obj-$(CONFIG_BCM_PDC_MBOX) += bcm-pdc-mailbox.o
>
>  obj-$(CONFIG_BCM_FLEXRM_MBOX)  += bcm-flexrm-mailbox.o
> diff --git a/drivers/mailbox/hi3660-mailbox.c 
> b/drivers/mailbox/hi3660-mailbox.c
> new file mode 100644
> index 000..14f469d
> --- /dev/null
> +++ b/drivers/mailbox/hi3660-mailbox.c
> @@ -0,0 +1,688 @@
> +/*
> + * Hisilicon's Hi3660 mailbox driver
> + *
> + * Copyright (c) 2017 Hisilicon Limited.
> + * Copyright (c) 2017 Linaro Limited.
> + *
> + * Author: Leo Yan 
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, version 2 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
>
no client.h please

> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "mailbox.h"
> +
> +#define MBOX_CHAN_MAX  32
> +
> +#define MBOX_TX0x1
> +
> +/* Mailbox message length: 2 words */
> +#define MBOX_MSG_LEN   2
> +
> +#define MBOX_OFF(m)(0x40 * (m))
> +#define MBOX_SRC_REG(m)MBOX_OFF(m)
> +#define MBOX_DST_REG(m)(MBOX_OFF(m) + 0x04)
> +#define MBOX_DCLR_REG(m)   (MBOX_OFF(m) + 0x08)
> +#define MBOX_DSTAT_REG(m)  (MBOX_OFF(m) + 0x0C)
> +#define MBOX_MODE_REG(m)   (MBOX_OFF(m) + 0x10)
> +#define MBOX_IMASK_REG(m)  (MBOX_OFF(m) + 0x14)
> +#define MBOX_ICLR_REG(m)   (MBOX_OFF(m) + 0x18)
> +#define MBOX_SEND_REG(m)   (MBOX_OFF(m) + 0x1C)
> +#define MBOX_DATA_REG(m, i)(MBOX_OFF(m) + 0x20 + ((i) << 2))
> +
> +#define MBOX_CPU_IMASK(cpu)(((cpu) << 3) + 0x800)
> +#define MBOX_CPU_IRST(cpu) (((cpu) << 3) + 0x804)
> +#define MBOX_IPC_LOCK  (0xA00)
> +
> +#define MBOX_IPC_UNLOCKED  0x
> +#define AUTOMATIC_ACK_CONFIG   (1 << 0)
> +#define NO_FUNC_CONFIG (0 << 0)
> +
> +#define MBOX_MANUAL_ACK0
> +#define MBOX_AUTO_ACK  1
> +
> +#define MBOX_STATE_IDLE(1 << 4)
> +#define MBOX_STATE_OUT (1 << 5)
> +#define MBOX_STATE_IN  (1 << 6)
> +#define MBOX_STATE_ACK (1 << 7)
> +
> +#define MBOX_DESTINATION_STATUS(1 << 6)
> +
BIT(x) please

> +struct hi3660_mbox_chan {
> +
> +   /*
> +* Description for channel's hardware info:
> +*  - direction: tx or rx
> +*  - dst irq: peer core's irq number
> +*  - ack irq: local irq number
> +*  - slot number
> +*/
> +   unsigned int dir, dst_irq, ack_irq;
> +   unsigned int slot;
> +
> +   unsigned int *buf;
> +
I think you mean   u32 *buf

> +   unsigned int irq_mode;
> +
> +   struct hi3660_mbox *parent;
>
You could get 'struct mbox_controller *' from 'struct mbox_chan' and
use container_of to get 'struct hi3660_mbox *'

> +};
> +
> +struct hi3660_mbox {
> +   struct device *dev;
> +
> +   int irq;
> +
> +   /* flag of enabling tx's irq mode */
> +   bool tx_irq_mode;
> +
> +   /* region for mailbox */
> 

Re: [PATCH] net: atm/mpc: Stop using open-coded timer .data field

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:46:45 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using an explicit static variable to hold
> additional expiration details.
> 
> Cc: "David S. Miller" 
> Cc: Bhumika Goyal 
> Cc: Andrew Morton 
> Cc: Alexey Dobriyan 
> Cc: "Reshetova, Elena" 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH] net: atm/mpc: Stop using open-coded timer .data field

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:46:45 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using an explicit static variable to hold
> additional expiration details.
> 
> Cc: "David S. Miller" 
> Cc: Bhumika Goyal 
> Cc: Andrew Morton 
> Cc: Alexey Dobriyan 
> Cc: "Reshetova, Elena" 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH] ipv6: esp6: use BUG_ON instead of if condition followed by BUG

2017-10-24 Thread Herbert Xu
On Tue, Oct 24, 2017 at 11:28:26AM -0500, Gustavo A. R. Silva wrote:
> Use BUG_ON instead of if condition followed by BUG in esp_remove_trailer.
> 
> This issue was detected with the help of Coccinelle.
> 
> Signed-off-by: Gustavo A. R. Silva 
> ---
>  net/ipv6/esp6.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
> index 89910e2..603ff06 100644
> --- a/net/ipv6/esp6.c
> +++ b/net/ipv6/esp6.c
> @@ -483,8 +483,7 @@ static inline int esp_remove_trailer(struct sk_buff *skb)
>   goto out;
>   }
>  
> - if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2))
> - BUG();
> + BUG_ON(skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2));

How about

ret = skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2);
BUG_ON(ret);

Thanks,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] ipv6: esp6: use BUG_ON instead of if condition followed by BUG

2017-10-24 Thread Herbert Xu
On Tue, Oct 24, 2017 at 11:28:26AM -0500, Gustavo A. R. Silva wrote:
> Use BUG_ON instead of if condition followed by BUG in esp_remove_trailer.
> 
> This issue was detected with the help of Coccinelle.
> 
> Signed-off-by: Gustavo A. R. Silva 
> ---
>  net/ipv6/esp6.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
> index 89910e2..603ff06 100644
> --- a/net/ipv6/esp6.c
> +++ b/net/ipv6/esp6.c
> @@ -483,8 +483,7 @@ static inline int esp_remove_trailer(struct sk_buff *skb)
>   goto out;
>   }
>  
> - if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2))
> - BUG();
> + BUG_ON(skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2));

How about

ret = skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2);
BUG_ON(ret);

Thanks,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] net: xfrm_user: use BUG_ON instead of if condition followed by BUG

2017-10-24 Thread Herbert Xu
On Tue, Oct 24, 2017 at 05:48:42PM +0900, David Miller wrote:
> 
> This discussion has happened before.
> 
> But I'll explain the conclusion here for your benefit.
> 
> BUG_ON() is a statement and everything inside of it will
> always execute.
> 
> BUG_ON() is always preferred because it allows arch
> specific code to pass the conditional result properly
> into inline asm and builtins for optimal code generation.

This is a good point.  However, while a little bit more verbose you
can still achieve the same assembly-level result by something like

int err;

err = ;
BUG_ON(err);

Having real code in BUG_ON may pose problems to people reading the
code because some of us tend to ignore code in BUG_ON and similar
macros such as BUILD_BUG_ON.

Cheers,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] net: xfrm_user: use BUG_ON instead of if condition followed by BUG

2017-10-24 Thread Herbert Xu
On Tue, Oct 24, 2017 at 05:48:42PM +0900, David Miller wrote:
> 
> This discussion has happened before.
> 
> But I'll explain the conclusion here for your benefit.
> 
> BUG_ON() is a statement and everything inside of it will
> always execute.
> 
> BUG_ON() is always preferred because it allows arch
> specific code to pass the conditional result properly
> into inline asm and builtins for optimal code generation.

This is a good point.  However, while a little bit more verbose you
can still achieve the same assembly-level result by something like

int err;

err = ;
BUG_ON(err);

Having real code in BUG_ON may pose problems to people reading the
code because some of us tend to ignore code in BUG_ON and similar
macros such as BUILD_BUG_ON.

Cheers,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


Re: [PATCH] net: hsr: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:46:16 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: Arvid Brodin 
> Cc: "David S. Miller" 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH] net: af_packet: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:46:26 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: "David S. Miller" 
> Cc: Eric Dumazet 
> Cc: Willem de Bruijn 
> Cc: Mike Maloney 
> Cc: Jarno Rajahalme 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH] net: hsr: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:46:16 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: Arvid Brodin 
> Cc: "David S. Miller" 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH] net: af_packet: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:46:26 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: "David S. Miller" 
> Cc: Eric Dumazet 
> Cc: Willem de Bruijn 
> Cc: Mike Maloney 
> Cc: Jarno Rajahalme 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH v7] printk: hash addresses printed with %p

2017-10-24 Thread Jason A. Donenfeld
On Wed, Oct 25, 2017 at 5:49 AM, Tobin C. Harding  wrote:
> static_branch_disable(_ptr_secret) : Doesn't sleep, just atomic read
> and set and maybe a WARN_ONCE.

Are you sure about that? I just looked myself, and though there is a
!HAVE_JUMP_LABEL ifdef that does what you described, there's also a
HAVE_JUMP_LABEL that takes a mutex, which sleeps:

static_branch_disable
  static_key_disable
cpus_read_lock
  percpu_down_read
percpu_down_read_preempt_disable
  might_sleep

> Now for the 'executes from process context' stuff.

Er, sorry, I meant to write non-process context in my original
message, which is generally where you're worried about sleeping.

> If the callback mechanism is utilized (i.e print before randomness is
> ready) then the call back will be executed the next time the randomness
> pool gets added to

So it sounds to me like this might be called in non-process context.
Disaster. I realize the static_key thing was my idea in the original
email, so sorry for leading you astray. But moving to do this in
early_initcall wound up fixing other issues too, so all and all a net
good in going this direction.

Two options: you stick with static_branch, because it's cool and speed
is fun, and work around all of the above with a call to queue_work so
that static_branch_enable is called only from process context.

Or, you give up on static_key, because it's not actually super
necessary, and instead just use an atomic, and reason that using `if
(unlikely(!atomic_read()))` is probably good enough. In this
option, the code would be pretty much the same as v7, except you'd
s/static_branch/atomic_t/, and change the helpers, etc. This is
probably the more reasonable way.


Re: [PATCH v7] printk: hash addresses printed with %p

2017-10-24 Thread Jason A. Donenfeld
On Wed, Oct 25, 2017 at 5:49 AM, Tobin C. Harding  wrote:
> static_branch_disable(_ptr_secret) : Doesn't sleep, just atomic read
> and set and maybe a WARN_ONCE.

Are you sure about that? I just looked myself, and though there is a
!HAVE_JUMP_LABEL ifdef that does what you described, there's also a
HAVE_JUMP_LABEL that takes a mutex, which sleeps:

static_branch_disable
  static_key_disable
cpus_read_lock
  percpu_down_read
percpu_down_read_preempt_disable
  might_sleep

> Now for the 'executes from process context' stuff.

Er, sorry, I meant to write non-process context in my original
message, which is generally where you're worried about sleeping.

> If the callback mechanism is utilized (i.e print before randomness is
> ready) then the call back will be executed the next time the randomness
> pool gets added to

So it sounds to me like this might be called in non-process context.
Disaster. I realize the static_key thing was my idea in the original
email, so sorry for leading you astray. But moving to do this in
early_initcall wound up fixing other issues too, so all and all a net
good in going this direction.

Two options: you stick with static_branch, because it's cool and speed
is fun, and work around all of the above with a call to queue_work so
that static_branch_enable is called only from process context.

Or, you give up on static_key, because it's not actually super
necessary, and instead just use an atomic, and reason that using `if
(unlikely(!atomic_read()))` is probably good enough. In this
option, the code would be pretty much the same as v7, except you'd
s/static_branch/atomic_t/, and change the helpers, etc. This is
probably the more reasonable way.


Re: [PATCH] net: dccp: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:46:09 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly. Adds a pointer back to the sock.
> 
> Cc: Gerrit Renker 
> Cc: "David S. Miller" 
> Cc: Soheil Hassas Yeganeh 
> Cc: Hannes Frederic Sowa 
> Cc: Eric Dumazet 
> Cc: d...@vger.kernel.org
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH] net: dccp: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:46:09 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly. Adds a pointer back to the sock.
> 
> Cc: Gerrit Renker 
> Cc: "David S. Miller" 
> Cc: Soheil Hassas Yeganeh 
> Cc: Hannes Frederic Sowa 
> Cc: Eric Dumazet 
> Cc: d...@vger.kernel.org
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH] net: ethernet/sfc: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:45:59 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: Solarflare linux maintainers 
> Cc: Edward Cree 
> Cc: Bert Kenward 
> Cc: "David S. Miller" 
> Cc: Eric Dumazet 
> Cc: Jiri Pirko 
> Cc: Jamal Hadi Salim 
> Cc: Ingo Molnar 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


Re: [PATCH] net: ethernet/sfc: Convert timers to use timer_setup()

2017-10-24 Thread David Miller
From: Kees Cook 
Date: Tue, 24 Oct 2017 01:45:59 -0700

> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
> 
> Cc: Solarflare linux maintainers 
> Cc: Edward Cree 
> Cc: Bert Kenward 
> Cc: "David S. Miller" 
> Cc: Eric Dumazet 
> Cc: Jiri Pirko 
> Cc: Jamal Hadi Salim 
> Cc: Ingo Molnar 
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook 

Applied.


[PATCH v3 5/6] dt-bindings: add the rockchip,dual-channel for dw-mipi-dsi

2017-10-24 Thread Nickey Yang
Configure dsi slave channel when driving a panel
which needs 2 DSI links.

Signed-off-by: Nickey Yang 
---
 .../devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt   | 2 ++
 1 file changed, 2 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
index 6bb59ab..a2bea22 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
+++ 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
@@ -19,6 +19,8 @@ Optional properties:
 - power-domains: a phandle to mipi dsi power domain node.
 - resets: list of phandle + reset specifier pairs, as described in [3].
 - reset-names: string reset name, must be "apb".
+- rockchip,dual-channel: phandle to a 2nd DSI channel, useful as a slave
+channel when driving a panel which needs 2 DSI links.
 
 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
 [2] Documentation/devicetree/bindings/media/video-interfaces.txt
-- 
1.9.1



[PATCH v3 5/6] dt-bindings: add the rockchip,dual-channel for dw-mipi-dsi

2017-10-24 Thread Nickey Yang
Configure dsi slave channel when driving a panel
which needs 2 DSI links.

Signed-off-by: Nickey Yang 
---
 .../devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt   | 2 ++
 1 file changed, 2 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
index 6bb59ab..a2bea22 100644
--- 
a/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
+++ 
b/Documentation/devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt
@@ -19,6 +19,8 @@ Optional properties:
 - power-domains: a phandle to mipi dsi power domain node.
 - resets: list of phandle + reset specifier pairs, as described in [3].
 - reset-names: string reset name, must be "apb".
+- rockchip,dual-channel: phandle to a 2nd DSI channel, useful as a slave
+channel when driving a panel which needs 2 DSI links.
 
 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
 [2] Documentation/devicetree/bindings/media/video-interfaces.txt
-- 
1.9.1



[PATCH v3 3/6] drm/rockchip/dsi: correct Feedback divider setting

2017-10-24 Thread Nickey Yang
This patch correct Feedback divider setting:
1、Set Feedback divider [8:5] when HIGH_PROGRAM_EN
2、Due to the use of a "by 2 pre-scaler," the range of the
feedback multiplication Feedback divider is limited to even
division numbers, and Feedback divider must be greater than
12, less than 1000.
3、Make the previously configured Feedback divider(LSB)
factors effective

Signed-off-by: Nickey Yang 
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 93 ++
 1 file changed, 62 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 09e7bfe..589b420 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -239,7 +239,7 @@
 #define LOW_PROGRAM_EN 0
 #define HIGH_PROGRAM_ENBIT(7)
 #define LOOP_DIV_LOW_SEL(val)  (((val) - 1) & 0x1f)
-#define LOOP_DIV_HIGH_SEL(val) val) - 1) >> 5) & 0x1f)
+#define LOOP_DIV_HIGH_SEL(val) val) - 1) >> 5) & 0xf)
 #define PLL_LOOP_DIV_ENBIT(5)
 #define PLL_INPUT_DIV_EN   BIT(4)
 
@@ -531,6 +531,14 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
dw_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
  LOOP_DIV_LOW_SEL(dsi->feedback_div) |
  LOW_PROGRAM_EN);
+   /*
+* we need set PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL immediately
+* to make the configrued LSB effective according to IP simulation
+* and lab test results.
+* Only in this way can we get correct mipi phy pll frequency.
+*/
+   dw_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,
+ PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
dw_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
  LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
  HIGH_PROGRAM_EN);
@@ -604,11 +612,16 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
 static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi,
struct drm_display_mode *mode)
 {
-   unsigned int i, pre;
-   unsigned long mpclk, pllref, tmp;
-   unsigned int m = 1, n = 1, target_mbps = 1000;
+   unsigned long mpclk, tmp;
+   unsigned int target_mbps = 1000;
unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
int bpp;
+   unsigned long best_freq = 0;
+   unsigned long fvco_min, fvco_max, fin, fout;
+   unsigned int min_prediv, max_prediv;
+   unsigned int _prediv, uninitialized_var(best_prediv);
+   unsigned long _fbdiv, uninitialized_var(best_fbdiv);
+   unsigned long min_delta = ULONG_MAX;
 
bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
if (bpp < 0) {
@@ -629,35 +642,53 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi 
*dsi,
  "DPHY clock frequency is out of range\n");
}
 
-   pllref = DIV_ROUND_UP(clk_get_rate(dsi->pllref_clk), USEC_PER_SEC);
-   tmp = pllref;
-
-   /*
-* The limits on the PLL divisor are:
-*
-*  5MHz <= (pllref / n) <= 40MHz
-*
-* we walk over these values in descreasing order so that if we hit
-* an exact match for target_mbps it is more likely that "m" will be
-* even.
-*
-* TODO: ensure that "m" is even after this loop.
-*/
-   for (i = pllref / 5; i > (pllref / 40); i--) {
-   pre = pllref / i;
-   if ((tmp > (target_mbps % pre)) && (target_mbps / pre < 512)) {
-   tmp = target_mbps % pre;
-   n = i;
-   m = target_mbps / pre;
+   fin = clk_get_rate(dsi->pllref_clk);
+   fout = target_mbps * USEC_PER_SEC;
+
+   /* constraint: 5Mhz <= Fref / N <= 40MHz */
+   min_prediv = DIV_ROUND_UP(fin, 40 * USEC_PER_SEC);
+   max_prediv = fin / (5 * USEC_PER_SEC);
+
+   /* constraint: 80MHz <= Fvco <= 1500Mhz */
+   fvco_min = 80 * USEC_PER_SEC;
+   fvco_max = 1500 * USEC_PER_SEC;
+
+   for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
+   u64 tmp;
+   u32 delta;
+   /* Fvco = Fref * M / N */
+   tmp = (u64)fout * _prediv;
+   do_div(tmp, fin);
+   _fbdiv = tmp;
+   /*
+* Due to the use of a "by 2 pre-scaler," the range of the
+* feedback multiplication value M is limited to even division
+* numbers, and m must be greater than 12, less than 1000.
+*/
+   if (_fbdiv <= 12 || _fbdiv >= 1000)
+   continue;
+
+   _fbdiv += _fbdiv % 2;
+
+   tmp = (u64)_fbdiv * fin;
+   do_div(tmp, _prediv);
+   if (tmp < fvco_min || tmp > 

[PATCH v3 3/6] drm/rockchip/dsi: correct Feedback divider setting

2017-10-24 Thread Nickey Yang
This patch correct Feedback divider setting:
1、Set Feedback divider [8:5] when HIGH_PROGRAM_EN
2、Due to the use of a "by 2 pre-scaler," the range of the
feedback multiplication Feedback divider is limited to even
division numbers, and Feedback divider must be greater than
12, less than 1000.
3、Make the previously configured Feedback divider(LSB)
factors effective

Signed-off-by: Nickey Yang 
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 93 ++
 1 file changed, 62 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 09e7bfe..589b420 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -239,7 +239,7 @@
 #define LOW_PROGRAM_EN 0
 #define HIGH_PROGRAM_ENBIT(7)
 #define LOOP_DIV_LOW_SEL(val)  (((val) - 1) & 0x1f)
-#define LOOP_DIV_HIGH_SEL(val) val) - 1) >> 5) & 0x1f)
+#define LOOP_DIV_HIGH_SEL(val) val) - 1) >> 5) & 0xf)
 #define PLL_LOOP_DIV_ENBIT(5)
 #define PLL_INPUT_DIV_EN   BIT(4)
 
@@ -531,6 +531,14 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
dw_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
  LOOP_DIV_LOW_SEL(dsi->feedback_div) |
  LOW_PROGRAM_EN);
+   /*
+* we need set PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL immediately
+* to make the configrued LSB effective according to IP simulation
+* and lab test results.
+* Only in this way can we get correct mipi phy pll frequency.
+*/
+   dw_mipi_dsi_phy_write(dsi, PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL,
+ PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
dw_mipi_dsi_phy_write(dsi, PLL_LOOP_DIVIDER_RATIO,
  LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
  HIGH_PROGRAM_EN);
@@ -604,11 +612,16 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
 static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi,
struct drm_display_mode *mode)
 {
-   unsigned int i, pre;
-   unsigned long mpclk, pllref, tmp;
-   unsigned int m = 1, n = 1, target_mbps = 1000;
+   unsigned long mpclk, tmp;
+   unsigned int target_mbps = 1000;
unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
int bpp;
+   unsigned long best_freq = 0;
+   unsigned long fvco_min, fvco_max, fin, fout;
+   unsigned int min_prediv, max_prediv;
+   unsigned int _prediv, uninitialized_var(best_prediv);
+   unsigned long _fbdiv, uninitialized_var(best_fbdiv);
+   unsigned long min_delta = ULONG_MAX;
 
bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
if (bpp < 0) {
@@ -629,35 +642,53 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi 
*dsi,
  "DPHY clock frequency is out of range\n");
}
 
-   pllref = DIV_ROUND_UP(clk_get_rate(dsi->pllref_clk), USEC_PER_SEC);
-   tmp = pllref;
-
-   /*
-* The limits on the PLL divisor are:
-*
-*  5MHz <= (pllref / n) <= 40MHz
-*
-* we walk over these values in descreasing order so that if we hit
-* an exact match for target_mbps it is more likely that "m" will be
-* even.
-*
-* TODO: ensure that "m" is even after this loop.
-*/
-   for (i = pllref / 5; i > (pllref / 40); i--) {
-   pre = pllref / i;
-   if ((tmp > (target_mbps % pre)) && (target_mbps / pre < 512)) {
-   tmp = target_mbps % pre;
-   n = i;
-   m = target_mbps / pre;
+   fin = clk_get_rate(dsi->pllref_clk);
+   fout = target_mbps * USEC_PER_SEC;
+
+   /* constraint: 5Mhz <= Fref / N <= 40MHz */
+   min_prediv = DIV_ROUND_UP(fin, 40 * USEC_PER_SEC);
+   max_prediv = fin / (5 * USEC_PER_SEC);
+
+   /* constraint: 80MHz <= Fvco <= 1500Mhz */
+   fvco_min = 80 * USEC_PER_SEC;
+   fvco_max = 1500 * USEC_PER_SEC;
+
+   for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) {
+   u64 tmp;
+   u32 delta;
+   /* Fvco = Fref * M / N */
+   tmp = (u64)fout * _prediv;
+   do_div(tmp, fin);
+   _fbdiv = tmp;
+   /*
+* Due to the use of a "by 2 pre-scaler," the range of the
+* feedback multiplication value M is limited to even division
+* numbers, and m must be greater than 12, less than 1000.
+*/
+   if (_fbdiv <= 12 || _fbdiv >= 1000)
+   continue;
+
+   _fbdiv += _fbdiv % 2;
+
+   tmp = (u64)_fbdiv * fin;
+   do_div(tmp, _prediv);
+   if (tmp < fvco_min || tmp > fvco_max)
+  

[PATCH v3 4/6] drm/rockchip/dsi: add dual mipi channel support

2017-10-24 Thread Nickey Yang
This patch add dual mipi channel support:
1.add definition of dsi1 register and grf operation.
2.dsi0 and dsi1 will work in master and slave mode
when driving dual mipi panel.

Signed-off-by: Nickey Yang 
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c  | 377 
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   1 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   2 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |   3 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |   1 +
 5 files changed, 279 insertions(+), 105 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 589b420..25e7b77 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -39,8 +39,42 @@
 #define RK3399_DSI1_SEL_VOP_LITBIT(4)
 
 /* disable turnrequest, turndisable, forcetxstopmode, forcerxmode */
-#define RK3399_GRF_SOC_CON22   0x6258
-#define RK3399_GRF_DSI_MODE0x
+#define RK3399_GRF_SOC_CON22   0x6258
+#define DPHY_TX0_TURNREQUEST_ENABLE(0xf << 12)
+#define DPHY_TX0_TURNREQUEST_SET   (DPHY_TX0_TURNREQUEST_ENABLE << 
16)
+#define DPHY_TX0_TURNDISABLE_ENABLE(0xf << 8)
+#define DPHY_TX0_TURNDISABLE_SET   (DPHY_TX0_TURNDISABLE_ENABLE << 
16)
+#define DPHY_TX0_FORCETXSTOPMODE_ENABLE(0xf << 4)
+#define DPHY_TX0_FORCETXSTOPMODE_SET   
(DPHY_TX0_FORCETXSTOPMODE_ENABLE << 16)
+#define DPHY_TX0_FORCETRXMODE_ENABLE   0xf
+#define DPHY_TX0_FORCETRXMODE_SET  (DPHY_TX0_FORCETRXMODE_ENABLE 
<< 16)
+#define RK3399_GRF_DSI_MODE(DPHY_TX0_TURNREQUEST_SET | \
+DPHY_TX0_TURNDISABLE_SET | \
+DPHY_TX0_FORCETXSTOPMODE_SET | 
\
+DPHY_TX0_FORCETRXMODE_SET)
+
+
+/* disable turndisable, forcetxstopmode, forcerxmode, enable */
+#define RK3399_GRF_SOC_CON23   0x625c
+#define DPHY_TX1RX1_TURNDISABLE_ENABLE (0xf << 12)
+#define DPHY_TX1RX1_TURNDISABLE_SET(DPHY_TX1RX1_TURNDISABLE_ENABLE 
<< 16)
+#define DPHY_TX1RX1_FORCETXSTOPMODE_ENABLE (0xf << 8)
+#define DPHY_TX1RX1_FORCETXSTOPMODE_SET
(DPHY_TX1RX1_FORCETXSTOPMODE_ENABLE << 16)
+#define DPHY_TX1RX1_FORCERXMODE_ENABLE (0xf << 4)
+#define DPHY_TX1RX1_FORCERXMODE_SET(DPHY_TX1RX1_FORCERXMODE_ENABLE 
<< 16)
+#define DPHY_TX1RX1_ENABLE_ENABLE  0xf
+#define DPHY_TX1RX1_ENABLE_SET (DPHY_TX1RX1_ENABLE_ENABLE << 
16)
+#define RK3399_GRF_DSI1_MODE   (DPHY_TX1RX1_TURNDISABLE_SET | \
+
DPHY_TX1RX1_FORCETXSTOPMODE_SET | \
+DPHY_TX1RX1_FORCERXMODE_SET | \
+DPHY_TX1RX1_ENABLE_SET)
+#define RK3399_GRF_DSI1_ENABLE ((DPHY_TX1RX1_ENABLE_SET | \
+ DPHY_TX1RX1_ENABLE_ENABLE))
+
+#define RK3399_GRF_SOC_CON24   0x6260
+#define RK3399_TXRX_MASTERSLAVEZ   BIT(7)
+#define RK3399_TXRX_ENABLECLK  BIT(6)
+#define RK3399_TXRX_BASEDIRBIT(5)
 
 #define DSI_VERSION0x00
 #define DSI_PWR_UP 0x04
@@ -315,6 +349,13 @@ struct dw_mipi_dsi_plat_data {
u32 grf_switch_reg;
u32 grf_dsi0_mode;
u32 grf_dsi0_mode_reg;
+   u32 grf_dsi1_mode;
+   u32 grf_dsi1_enable;
+   u32 grf_dsi1_mode_reg1;
+   u32 dsi1_basedir;
+   u32 dsi1_masterslavez;
+   u32 dsi1_enableclk;
+   u32 grf_dsi1_mode_reg2;
unsigned int flags;
unsigned int max_data_lanes;
 };
@@ -333,6 +374,10 @@ struct dw_mipi_dsi {
struct clk *pclk;
struct clk *phy_cfg_clk;
 
+   /* dual-channel */
+   struct dw_mipi_dsi *master;
+   struct dw_mipi_dsi *slave;
+
int dpms_mode;
unsigned int lane_mbps; /* per lane */
u32 channel;
@@ -617,6 +662,7 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi,
unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
int bpp;
unsigned long best_freq = 0;
+   int lanes = dsi->lanes;
unsigned long fvco_min, fvco_max, fin, fout;
unsigned int min_prediv, max_prediv;
unsigned int _prediv, uninitialized_var(best_prediv);
@@ -631,10 +677,13 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi 
*dsi,
return bpp;
}
 
+   if (dsi->slave || dsi->master)
+   lanes = dsi->lanes * 2;
+
mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
if (mpclk) {
/* take 1 / 0.8, since mbps must big than bandwidth of RGB */
-   tmp = mpclk * (bpp / dsi->lanes) * 10 / 8;
+  

[PATCH v3 6/6] arm64: dts: rockchip: add mipi_dsi1 support for rk3399

2017-10-24 Thread Nickey Yang
This patch adds the mipi_dsi1 related needed information.
e.g.: interrupts, grf, clocks, ports and so on.

Signed-off-by: Nickey Yang 
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 39 
 1 file changed, 39 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index a65f7f7..48e2695 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1515,6 +1515,11 @@
reg = <2>;
remote-endpoint = <_in_vopl>;
};
+
+   vopl_out_mipi1: endpoint@3 {
+   reg = <3>;
+   remote-endpoint = <_in_vopl>;
+   };
};
};
 
@@ -1562,6 +1567,11 @@
reg = <2>;
remote-endpoint = <_in_vopb>;
};
+
+   vopb_out_mipi1: endpoint@3 {
+   reg = <3>;
+   remote-endpoint = <_in_vopb>;
+   };
};
};
 
@@ -1657,6 +1667,35 @@
};
};
 
+   mipi_dsi1: mipi@ff968000 {
+   compatible = "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi";
+   reg = <0x0 0xff968000 0x0 0x8000>;
+   interrupts = ;
+   clocks = < SCLK_DPHY_PLL>, < PCLK_MIPI_DSI1>,
+< SCLK_DPHY_TX1RX1_CFG>, < PCLK_VIO_GRF>;
+   clock-names = "ref", "pclk", "phy_cfg", "grf";
+   power-domains = < RK3399_PD_VIO>;
+   rockchip,grf = <>;
+   status = "disabled";
+
+   ports {
+   mipi1_in: port {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   mipi1_in_vopb: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <_out_mipi1>;
+   };
+
+   mipi1_in_vopl: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = <_out_mipi1>;
+   };
+   };
+   };
+   };
+
edp: edp@ff97 {
compatible = "rockchip,rk3399-edp";
reg = <0x0 0xff97 0x0 0x8000>;
-- 
1.9.1



[PATCH v3 4/6] drm/rockchip/dsi: add dual mipi channel support

2017-10-24 Thread Nickey Yang
This patch add dual mipi channel support:
1.add definition of dsi1 register and grf operation.
2.dsi0 and dsi1 will work in master and slave mode
when driving dual mipi panel.

Signed-off-by: Nickey Yang 
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c  | 377 
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h |   1 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c |   2 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |   3 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c |   1 +
 5 files changed, 279 insertions(+), 105 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 589b420..25e7b77 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -39,8 +39,42 @@
 #define RK3399_DSI1_SEL_VOP_LITBIT(4)
 
 /* disable turnrequest, turndisable, forcetxstopmode, forcerxmode */
-#define RK3399_GRF_SOC_CON22   0x6258
-#define RK3399_GRF_DSI_MODE0x
+#define RK3399_GRF_SOC_CON22   0x6258
+#define DPHY_TX0_TURNREQUEST_ENABLE(0xf << 12)
+#define DPHY_TX0_TURNREQUEST_SET   (DPHY_TX0_TURNREQUEST_ENABLE << 
16)
+#define DPHY_TX0_TURNDISABLE_ENABLE(0xf << 8)
+#define DPHY_TX0_TURNDISABLE_SET   (DPHY_TX0_TURNDISABLE_ENABLE << 
16)
+#define DPHY_TX0_FORCETXSTOPMODE_ENABLE(0xf << 4)
+#define DPHY_TX0_FORCETXSTOPMODE_SET   
(DPHY_TX0_FORCETXSTOPMODE_ENABLE << 16)
+#define DPHY_TX0_FORCETRXMODE_ENABLE   0xf
+#define DPHY_TX0_FORCETRXMODE_SET  (DPHY_TX0_FORCETRXMODE_ENABLE 
<< 16)
+#define RK3399_GRF_DSI_MODE(DPHY_TX0_TURNREQUEST_SET | \
+DPHY_TX0_TURNDISABLE_SET | \
+DPHY_TX0_FORCETXSTOPMODE_SET | 
\
+DPHY_TX0_FORCETRXMODE_SET)
+
+
+/* disable turndisable, forcetxstopmode, forcerxmode, enable */
+#define RK3399_GRF_SOC_CON23   0x625c
+#define DPHY_TX1RX1_TURNDISABLE_ENABLE (0xf << 12)
+#define DPHY_TX1RX1_TURNDISABLE_SET(DPHY_TX1RX1_TURNDISABLE_ENABLE 
<< 16)
+#define DPHY_TX1RX1_FORCETXSTOPMODE_ENABLE (0xf << 8)
+#define DPHY_TX1RX1_FORCETXSTOPMODE_SET
(DPHY_TX1RX1_FORCETXSTOPMODE_ENABLE << 16)
+#define DPHY_TX1RX1_FORCERXMODE_ENABLE (0xf << 4)
+#define DPHY_TX1RX1_FORCERXMODE_SET(DPHY_TX1RX1_FORCERXMODE_ENABLE 
<< 16)
+#define DPHY_TX1RX1_ENABLE_ENABLE  0xf
+#define DPHY_TX1RX1_ENABLE_SET (DPHY_TX1RX1_ENABLE_ENABLE << 
16)
+#define RK3399_GRF_DSI1_MODE   (DPHY_TX1RX1_TURNDISABLE_SET | \
+
DPHY_TX1RX1_FORCETXSTOPMODE_SET | \
+DPHY_TX1RX1_FORCERXMODE_SET | \
+DPHY_TX1RX1_ENABLE_SET)
+#define RK3399_GRF_DSI1_ENABLE ((DPHY_TX1RX1_ENABLE_SET | \
+ DPHY_TX1RX1_ENABLE_ENABLE))
+
+#define RK3399_GRF_SOC_CON24   0x6260
+#define RK3399_TXRX_MASTERSLAVEZ   BIT(7)
+#define RK3399_TXRX_ENABLECLK  BIT(6)
+#define RK3399_TXRX_BASEDIRBIT(5)
 
 #define DSI_VERSION0x00
 #define DSI_PWR_UP 0x04
@@ -315,6 +349,13 @@ struct dw_mipi_dsi_plat_data {
u32 grf_switch_reg;
u32 grf_dsi0_mode;
u32 grf_dsi0_mode_reg;
+   u32 grf_dsi1_mode;
+   u32 grf_dsi1_enable;
+   u32 grf_dsi1_mode_reg1;
+   u32 dsi1_basedir;
+   u32 dsi1_masterslavez;
+   u32 dsi1_enableclk;
+   u32 grf_dsi1_mode_reg2;
unsigned int flags;
unsigned int max_data_lanes;
 };
@@ -333,6 +374,10 @@ struct dw_mipi_dsi {
struct clk *pclk;
struct clk *phy_cfg_clk;
 
+   /* dual-channel */
+   struct dw_mipi_dsi *master;
+   struct dw_mipi_dsi *slave;
+
int dpms_mode;
unsigned int lane_mbps; /* per lane */
u32 channel;
@@ -617,6 +662,7 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi,
unsigned int max_mbps = dppa_map[ARRAY_SIZE(dppa_map) - 1].max_mbps;
int bpp;
unsigned long best_freq = 0;
+   int lanes = dsi->lanes;
unsigned long fvco_min, fvco_max, fin, fout;
unsigned int min_prediv, max_prediv;
unsigned int _prediv, uninitialized_var(best_prediv);
@@ -631,10 +677,13 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi 
*dsi,
return bpp;
}
 
+   if (dsi->slave || dsi->master)
+   lanes = dsi->lanes * 2;
+
mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
if (mpclk) {
/* take 1 / 0.8, since mbps must big than bandwidth of RGB */
-   tmp = mpclk * (bpp / dsi->lanes) * 10 / 8;
+   tmp = mpclk * 

[PATCH v3 6/6] arm64: dts: rockchip: add mipi_dsi1 support for rk3399

2017-10-24 Thread Nickey Yang
This patch adds the mipi_dsi1 related needed information.
e.g.: interrupts, grf, clocks, ports and so on.

Signed-off-by: Nickey Yang 
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 39 
 1 file changed, 39 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index a65f7f7..48e2695 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1515,6 +1515,11 @@
reg = <2>;
remote-endpoint = <_in_vopl>;
};
+
+   vopl_out_mipi1: endpoint@3 {
+   reg = <3>;
+   remote-endpoint = <_in_vopl>;
+   };
};
};
 
@@ -1562,6 +1567,11 @@
reg = <2>;
remote-endpoint = <_in_vopb>;
};
+
+   vopb_out_mipi1: endpoint@3 {
+   reg = <3>;
+   remote-endpoint = <_in_vopb>;
+   };
};
};
 
@@ -1657,6 +1667,35 @@
};
};
 
+   mipi_dsi1: mipi@ff968000 {
+   compatible = "rockchip,rk3399-mipi-dsi", "snps,dw-mipi-dsi";
+   reg = <0x0 0xff968000 0x0 0x8000>;
+   interrupts = ;
+   clocks = < SCLK_DPHY_PLL>, < PCLK_MIPI_DSI1>,
+< SCLK_DPHY_TX1RX1_CFG>, < PCLK_VIO_GRF>;
+   clock-names = "ref", "pclk", "phy_cfg", "grf";
+   power-domains = < RK3399_PD_VIO>;
+   rockchip,grf = <>;
+   status = "disabled";
+
+   ports {
+   mipi1_in: port {
+   #address-cells = <1>;
+   #size-cells = <0>;
+
+   mipi1_in_vopb: endpoint@0 {
+   reg = <0>;
+   remote-endpoint = <_out_mipi1>;
+   };
+
+   mipi1_in_vopl: endpoint@1 {
+   reg = <1>;
+   remote-endpoint = <_out_mipi1>;
+   };
+   };
+   };
+   };
+
edp: edp@ff97 {
compatible = "rockchip,rk3399-edp";
reg = <0x0 0xff97 0x0 0x8000>;
-- 
1.9.1



[PATCH v3 2/6] drm/rockchip/dsi: correct phy parameter setting

2017-10-24 Thread Nickey Yang
As MIPI PHY document show, icpctrl<3..0> and lpfctrl<5..0>
should depend on frequency,so fix it.

Reviewed-by: Sean Paul 
Reviewed-by: Matthias Kaehlcke 
Signed-off-by: Nickey Yang 
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 98 --
 1 file changed, 70 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 95ce253..09e7bfe 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -217,10 +217,21 @@
 #define VCO_IN_CAP_CON_HIGH(0x2 << 1)
 #define REF_BIAS_CUR_SEL   BIT(0)
 
-#define CP_CURRENT_3MA BIT(3)
+#define CP_CURRENT_1_5UA   0x1
+#define CP_CURRENT_4_5UA   0x2
+#define CP_CURRENT_7_5UA   0x6
+#define CP_CURRENT_6UA 0x9
+#define CP_CURRENT_12UA0xb
+#define CP_CURRENT_SEL(val)((val) & 0xf)
 #define CP_PROGRAM_EN  BIT(7)
+
+#define LPF_RESISTORS_15_5KOHM 0x1
+#define LPF_RESISTORS_13KOHM   0x2
+#define LPF_RESISTORS_11_5KOHM 0x4
+#define LPF_RESISTORS_10_5KOHM 0x8
+#define LPF_RESISTORS_8KOHM0x10
 #define LPF_PROGRAM_EN BIT(6)
-#define LPF_RESISTORS_20_KOHM  0
+#define LPF_RESISTORS_SEL(val) ((val) & 0x3f)
 
 #define HSFREQRANGE_SEL(val)   (((val) & 0x3f) << 1)
 
@@ -339,32 +350,63 @@ enum dw_mipi_dsi_mode {
DW_MIPI_DSI_VID_MODE,
 };
 
-struct dphy_pll_testdin_map {
+struct dphy_pll_parameter_map {
unsigned int max_mbps;
-   u8 testdin;
+   u8 hsfreqrange;
+   u8 icpctrl;
+   u8 lpfctrl;
 };
 
 /* The table is based on 27MHz DPHY pll reference clock. */
-static const struct dphy_pll_testdin_map dptdin_map[] = {
-   {  90, 0x00}, { 100, 0x10}, { 110, 0x20}, { 130, 0x01},
-   { 140, 0x11}, { 150, 0x21}, { 170, 0x02}, { 180, 0x12},
-   { 200, 0x22}, { 220, 0x03}, { 240, 0x13}, { 250, 0x23},
-   { 270, 0x04}, { 300, 0x14}, { 330, 0x05}, { 360, 0x15},
-   { 400, 0x25}, { 450, 0x06}, { 500, 0x16}, { 550, 0x07},
-   { 600, 0x17}, { 650, 0x08}, { 700, 0x18}, { 750, 0x09},
-   { 800, 0x19}, { 850, 0x29}, { 900, 0x39}, { 950, 0x0a},
-   {1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
-   {1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
-   {1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
+static const struct dphy_pll_parameter_map dppa_map[] = {
+   {  89, 0x00, CP_CURRENT_1_5UA, LPF_RESISTORS_13KOHM},
+   {  99, 0x10, CP_CURRENT_1_5UA, LPF_RESISTORS_13KOHM},
+   { 109, 0x20, CP_CURRENT_1_5UA, LPF_RESISTORS_13KOHM},
+   { 129, 0x01, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 139, 0x11, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 149, 0x21, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 169, 0x02, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
+   { 179, 0x12, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
+   { 199, 0x22, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
+   { 219, 0x03, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
+   { 239, 0x13, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
+   { 249, 0x23, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
+   { 269, 0x04, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM},
+   { 299, 0x14, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM},
+   { 329, 0x05, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 359, 0x15, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 399, 0x25, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 449, 0x06, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 499, 0x16, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 549, 0x07, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM},
+   { 599, 0x17, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM},
+   { 649, 0x08, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 699, 0x18, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 749, 0x09, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 799, 0x19, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 849, 0x29, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 899, 0x39, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 949, 0x0a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
+   { 999, 0x1a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
+   {1049, 0x2a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
+   {1099, 0x3a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
+   {1149, 0x0b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1199, 0x1b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1249, 0x2b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1299, 0x3b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1349, 0x0c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1399, 0x1c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1449, 0x2c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1500, 0x3c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM}
 };
 
-static int max_mbps_to_testdin(unsigned int max_mbps)
+static int max_mbps_to_parameter(unsigned int max_mbps)
 

[PATCH v3 1/6] drm/rockchip/dsi: Define and use macros for PHY register addresses

2017-10-24 Thread Nickey Yang
Replace the hardcoded register address numerical values with macros to
clarify the code.

Signed-off-by: Nickey Yang 
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 129 ++---
 1 file changed, 85 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index b15755b..95ce253 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -254,6 +254,28 @@
 #define DW_MIPI_NEEDS_PHY_CFG_CLK  BIT(0)
 #define DW_MIPI_NEEDS_GRF_CLK  BIT(1)
 
+#define PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL   0x10
+#define PLL_CP_CONTROL_PLL_LOCK_BYPASS 0x11
+#define PLL_LPF_AND_CP_CONTROL 0x12
+#define PLL_INPUT_DIVIDER_RATIO0x17
+#define PLL_LOOP_DIVIDER_RATIO 0x18
+#define PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL  0x19
+#define BANDGAP_AND_BIAS_CONTROL   0x20
+#define TERMINATION_RESISTER_CONTROL   0x21
+#define AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY0x22
+#define HS_RX_CONTROL_OF_LANE_00x44
+#define HS_TX_CLOCK_LANE_REQUEST_STATE_TIME_CONTROL0x60
+#define HS_TX_CLOCK_LANE_PREPARE_STATE_TIME_CONTROL0x61
+#define HS_TX_CLOCK_LANE_HS_ZERO_STATE_TIME_CONTROL0x62
+#define HS_TX_CLOCK_LANE_TRAIL_STATE_TIME_CONTROL  0x63
+#define HS_TX_CLOCK_LANE_EXIT_STATE_TIME_CONTROL   0x64
+#define HS_TX_CLOCK_LANE_POST_TIME_CONTROL 0x65
+#define HS_TX_DATA_LANE_REQUEST_STATE_TIME_CONTROL 0x70
+#define HS_TX_DATA_LANE_PREPARE_STATE_TIME_CONTROL 0x71
+#define HS_TX_DATA_LANE_HS_ZERO_STATE_TIME_CONTROL 0x72
+#define HS_TX_DATA_LANE_TRAIL_STATE_TIME_CONTROL   0x73
+#define HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL0x74
+
 enum {
BANDGAP_97_07,
BANDGAP_98_05,
@@ -447,53 +469,72 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
return ret;
}
 
-   dw_mipi_dsi_phy_write(dsi, 0x10, BYPASS_VCO_RANGE |
-VCO_RANGE_CON_SEL(vco) |
-VCO_IN_CAP_CON_LOW |
-REF_BIAS_CUR_SEL);
-
-   dw_mipi_dsi_phy_write(dsi, 0x11, CP_CURRENT_3MA);
-   dw_mipi_dsi_phy_write(dsi, 0x12, CP_PROGRAM_EN | LPF_PROGRAM_EN |
-LPF_RESISTORS_20_KOHM);
-
-   dw_mipi_dsi_phy_write(dsi, 0x44, HSFREQRANGE_SEL(testdin));
-
-   dw_mipi_dsi_phy_write(dsi, 0x17, INPUT_DIVIDER(dsi->input_div));
-   dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_LOW_SEL(dsi->feedback_div) |
-LOW_PROGRAM_EN);
-   dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
-HIGH_PROGRAM_EN);
-   dw_mipi_dsi_phy_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
-
-   dw_mipi_dsi_phy_write(dsi, 0x22, LOW_PROGRAM_EN |
-BIASEXTR_SEL(BIASEXTR_127_7));
-   dw_mipi_dsi_phy_write(dsi, 0x22, HIGH_PROGRAM_EN |
-BANDGAP_SEL(BANDGAP_96_10));
-
-   dw_mipi_dsi_phy_write(dsi, 0x20, POWER_CONTROL | INTERNAL_REG_CURRENT |
-BIAS_BLOCK_ON | BANDGAP_ON);
-
-   dw_mipi_dsi_phy_write(dsi, 0x21, TER_RESISTOR_LOW | TER_CAL_DONE |
-SETRD_MAX | TER_RESISTORS_ON);
-   dw_mipi_dsi_phy_write(dsi, 0x21, TER_RESISTOR_HIGH | LEVEL_SHIFTERS_ON |
-SETRD_MAX | POWER_MANAGE |
-TER_RESISTORS_ON);
-
-   dw_mipi_dsi_phy_write(dsi, 0x60, TLP_PROGRAM_EN | ns2bc(dsi, 500));
-   dw_mipi_dsi_phy_write(dsi, 0x61, THS_PRE_PROGRAM_EN | ns2ui(dsi, 40));
-   dw_mipi_dsi_phy_write(dsi, 0x62, THS_ZERO_PROGRAM_EN | ns2bc(dsi, 300));
-   dw_mipi_dsi_phy_write(dsi, 0x63, THS_PRE_PROGRAM_EN | ns2ui(dsi, 100));
-   dw_mipi_dsi_phy_write(dsi, 0x64, BIT(5) | ns2bc(dsi, 100));
-   dw_mipi_dsi_phy_write(dsi, 0x65, BIT(5) | (ns2bc(dsi, 60) + 7));
-
-   dw_mipi_dsi_phy_write(dsi, 0x70, TLP_PROGRAM_EN | ns2bc(dsi, 500));
-   dw_mipi_dsi_phy_write(dsi, 0x71,
+   dw_mipi_dsi_phy_write(dsi, PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL,
+ BYPASS_VCO_RANGE |
+ VCO_RANGE_CON_SEL(vco) |
+ VCO_IN_CAP_CON_LOW |
+ REF_BIAS_CUR_SEL);
+
+   dw_mipi_dsi_phy_write(dsi, PLL_CP_CONTROL_PLL_LOCK_BYPASS,
+ CP_CURRENT_3MA);
+   dw_mipi_dsi_phy_write(dsi, PLL_LPF_AND_CP_CONTROL,
+ CP_PROGRAM_EN | LPF_PROGRAM_EN |
+ LPF_RESISTORS_20_KOHM);
+
+   dw_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_0,
+ HSFREQRANGE_SEL(testdin));
+
+   dw_mipi_dsi_phy_write(dsi, PLL_INPUT_DIVIDER_RATIO,
+ 

[PATCH v3 2/6] drm/rockchip/dsi: correct phy parameter setting

2017-10-24 Thread Nickey Yang
As MIPI PHY document show, icpctrl<3..0> and lpfctrl<5..0>
should depend on frequency,so fix it.

Reviewed-by: Sean Paul 
Reviewed-by: Matthias Kaehlcke 
Signed-off-by: Nickey Yang 
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 98 --
 1 file changed, 70 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 95ce253..09e7bfe 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -217,10 +217,21 @@
 #define VCO_IN_CAP_CON_HIGH(0x2 << 1)
 #define REF_BIAS_CUR_SEL   BIT(0)
 
-#define CP_CURRENT_3MA BIT(3)
+#define CP_CURRENT_1_5UA   0x1
+#define CP_CURRENT_4_5UA   0x2
+#define CP_CURRENT_7_5UA   0x6
+#define CP_CURRENT_6UA 0x9
+#define CP_CURRENT_12UA0xb
+#define CP_CURRENT_SEL(val)((val) & 0xf)
 #define CP_PROGRAM_EN  BIT(7)
+
+#define LPF_RESISTORS_15_5KOHM 0x1
+#define LPF_RESISTORS_13KOHM   0x2
+#define LPF_RESISTORS_11_5KOHM 0x4
+#define LPF_RESISTORS_10_5KOHM 0x8
+#define LPF_RESISTORS_8KOHM0x10
 #define LPF_PROGRAM_EN BIT(6)
-#define LPF_RESISTORS_20_KOHM  0
+#define LPF_RESISTORS_SEL(val) ((val) & 0x3f)
 
 #define HSFREQRANGE_SEL(val)   (((val) & 0x3f) << 1)
 
@@ -339,32 +350,63 @@ enum dw_mipi_dsi_mode {
DW_MIPI_DSI_VID_MODE,
 };
 
-struct dphy_pll_testdin_map {
+struct dphy_pll_parameter_map {
unsigned int max_mbps;
-   u8 testdin;
+   u8 hsfreqrange;
+   u8 icpctrl;
+   u8 lpfctrl;
 };
 
 /* The table is based on 27MHz DPHY pll reference clock. */
-static const struct dphy_pll_testdin_map dptdin_map[] = {
-   {  90, 0x00}, { 100, 0x10}, { 110, 0x20}, { 130, 0x01},
-   { 140, 0x11}, { 150, 0x21}, { 170, 0x02}, { 180, 0x12},
-   { 200, 0x22}, { 220, 0x03}, { 240, 0x13}, { 250, 0x23},
-   { 270, 0x04}, { 300, 0x14}, { 330, 0x05}, { 360, 0x15},
-   { 400, 0x25}, { 450, 0x06}, { 500, 0x16}, { 550, 0x07},
-   { 600, 0x17}, { 650, 0x08}, { 700, 0x18}, { 750, 0x09},
-   { 800, 0x19}, { 850, 0x29}, { 900, 0x39}, { 950, 0x0a},
-   {1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
-   {1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
-   {1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c}
+static const struct dphy_pll_parameter_map dppa_map[] = {
+   {  89, 0x00, CP_CURRENT_1_5UA, LPF_RESISTORS_13KOHM},
+   {  99, 0x10, CP_CURRENT_1_5UA, LPF_RESISTORS_13KOHM},
+   { 109, 0x20, CP_CURRENT_1_5UA, LPF_RESISTORS_13KOHM},
+   { 129, 0x01, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 139, 0x11, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 149, 0x21, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 169, 0x02, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
+   { 179, 0x12, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
+   { 199, 0x22, CP_CURRENT_6UA, LPF_RESISTORS_13KOHM},
+   { 219, 0x03, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
+   { 239, 0x13, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
+   { 249, 0x23, CP_CURRENT_4_5UA, LPF_RESISTORS_13KOHM},
+   { 269, 0x04, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM},
+   { 299, 0x14, CP_CURRENT_6UA, LPF_RESISTORS_11_5KOHM},
+   { 329, 0x05, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 359, 0x15, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 399, 0x25, CP_CURRENT_1_5UA, LPF_RESISTORS_15_5KOHM},
+   { 449, 0x06, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 499, 0x16, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 549, 0x07, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM},
+   { 599, 0x17, CP_CURRENT_7_5UA, LPF_RESISTORS_10_5KOHM},
+   { 649, 0x08, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 699, 0x18, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 749, 0x09, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 799, 0x19, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 849, 0x29, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 899, 0x39, CP_CURRENT_7_5UA, LPF_RESISTORS_11_5KOHM},
+   { 949, 0x0a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
+   { 999, 0x1a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
+   {1049, 0x2a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
+   {1099, 0x3a, CP_CURRENT_12UA, LPF_RESISTORS_8KOHM},
+   {1149, 0x0b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1199, 0x1b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1249, 0x2b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1299, 0x3b, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1349, 0x0c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1399, 0x1c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1449, 0x2c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM},
+   {1500, 0x3c, CP_CURRENT_12UA, LPF_RESISTORS_10_5KOHM}
 };
 
-static int max_mbps_to_testdin(unsigned int max_mbps)
+static int max_mbps_to_parameter(unsigned int max_mbps)
 {
int i;
 
-   for (i = 0; i < ARRAY_SIZE(dptdin_map); 

[PATCH v3 1/6] drm/rockchip/dsi: Define and use macros for PHY register addresses

2017-10-24 Thread Nickey Yang
Replace the hardcoded register address numerical values with macros to
clarify the code.

Signed-off-by: Nickey Yang 
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 129 ++---
 1 file changed, 85 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c 
b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index b15755b..95ce253 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -254,6 +254,28 @@
 #define DW_MIPI_NEEDS_PHY_CFG_CLK  BIT(0)
 #define DW_MIPI_NEEDS_GRF_CLK  BIT(1)
 
+#define PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL   0x10
+#define PLL_CP_CONTROL_PLL_LOCK_BYPASS 0x11
+#define PLL_LPF_AND_CP_CONTROL 0x12
+#define PLL_INPUT_DIVIDER_RATIO0x17
+#define PLL_LOOP_DIVIDER_RATIO 0x18
+#define PLL_INPUT_AND_LOOP_DIVIDER_RATIOS_CONTROL  0x19
+#define BANDGAP_AND_BIAS_CONTROL   0x20
+#define TERMINATION_RESISTER_CONTROL   0x21
+#define AFE_BIAS_BANDGAP_ANALOG_PROGRAMMABILITY0x22
+#define HS_RX_CONTROL_OF_LANE_00x44
+#define HS_TX_CLOCK_LANE_REQUEST_STATE_TIME_CONTROL0x60
+#define HS_TX_CLOCK_LANE_PREPARE_STATE_TIME_CONTROL0x61
+#define HS_TX_CLOCK_LANE_HS_ZERO_STATE_TIME_CONTROL0x62
+#define HS_TX_CLOCK_LANE_TRAIL_STATE_TIME_CONTROL  0x63
+#define HS_TX_CLOCK_LANE_EXIT_STATE_TIME_CONTROL   0x64
+#define HS_TX_CLOCK_LANE_POST_TIME_CONTROL 0x65
+#define HS_TX_DATA_LANE_REQUEST_STATE_TIME_CONTROL 0x70
+#define HS_TX_DATA_LANE_PREPARE_STATE_TIME_CONTROL 0x71
+#define HS_TX_DATA_LANE_HS_ZERO_STATE_TIME_CONTROL 0x72
+#define HS_TX_DATA_LANE_TRAIL_STATE_TIME_CONTROL   0x73
+#define HS_TX_DATA_LANE_EXIT_STATE_TIME_CONTROL0x74
+
 enum {
BANDGAP_97_07,
BANDGAP_98_05,
@@ -447,53 +469,72 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
return ret;
}
 
-   dw_mipi_dsi_phy_write(dsi, 0x10, BYPASS_VCO_RANGE |
-VCO_RANGE_CON_SEL(vco) |
-VCO_IN_CAP_CON_LOW |
-REF_BIAS_CUR_SEL);
-
-   dw_mipi_dsi_phy_write(dsi, 0x11, CP_CURRENT_3MA);
-   dw_mipi_dsi_phy_write(dsi, 0x12, CP_PROGRAM_EN | LPF_PROGRAM_EN |
-LPF_RESISTORS_20_KOHM);
-
-   dw_mipi_dsi_phy_write(dsi, 0x44, HSFREQRANGE_SEL(testdin));
-
-   dw_mipi_dsi_phy_write(dsi, 0x17, INPUT_DIVIDER(dsi->input_div));
-   dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_LOW_SEL(dsi->feedback_div) |
-LOW_PROGRAM_EN);
-   dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
-HIGH_PROGRAM_EN);
-   dw_mipi_dsi_phy_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
-
-   dw_mipi_dsi_phy_write(dsi, 0x22, LOW_PROGRAM_EN |
-BIASEXTR_SEL(BIASEXTR_127_7));
-   dw_mipi_dsi_phy_write(dsi, 0x22, HIGH_PROGRAM_EN |
-BANDGAP_SEL(BANDGAP_96_10));
-
-   dw_mipi_dsi_phy_write(dsi, 0x20, POWER_CONTROL | INTERNAL_REG_CURRENT |
-BIAS_BLOCK_ON | BANDGAP_ON);
-
-   dw_mipi_dsi_phy_write(dsi, 0x21, TER_RESISTOR_LOW | TER_CAL_DONE |
-SETRD_MAX | TER_RESISTORS_ON);
-   dw_mipi_dsi_phy_write(dsi, 0x21, TER_RESISTOR_HIGH | LEVEL_SHIFTERS_ON |
-SETRD_MAX | POWER_MANAGE |
-TER_RESISTORS_ON);
-
-   dw_mipi_dsi_phy_write(dsi, 0x60, TLP_PROGRAM_EN | ns2bc(dsi, 500));
-   dw_mipi_dsi_phy_write(dsi, 0x61, THS_PRE_PROGRAM_EN | ns2ui(dsi, 40));
-   dw_mipi_dsi_phy_write(dsi, 0x62, THS_ZERO_PROGRAM_EN | ns2bc(dsi, 300));
-   dw_mipi_dsi_phy_write(dsi, 0x63, THS_PRE_PROGRAM_EN | ns2ui(dsi, 100));
-   dw_mipi_dsi_phy_write(dsi, 0x64, BIT(5) | ns2bc(dsi, 100));
-   dw_mipi_dsi_phy_write(dsi, 0x65, BIT(5) | (ns2bc(dsi, 60) + 7));
-
-   dw_mipi_dsi_phy_write(dsi, 0x70, TLP_PROGRAM_EN | ns2bc(dsi, 500));
-   dw_mipi_dsi_phy_write(dsi, 0x71,
+   dw_mipi_dsi_phy_write(dsi, PLL_BIAS_CUR_SEL_CAP_VCO_CONTROL,
+ BYPASS_VCO_RANGE |
+ VCO_RANGE_CON_SEL(vco) |
+ VCO_IN_CAP_CON_LOW |
+ REF_BIAS_CUR_SEL);
+
+   dw_mipi_dsi_phy_write(dsi, PLL_CP_CONTROL_PLL_LOCK_BYPASS,
+ CP_CURRENT_3MA);
+   dw_mipi_dsi_phy_write(dsi, PLL_LPF_AND_CP_CONTROL,
+ CP_PROGRAM_EN | LPF_PROGRAM_EN |
+ LPF_RESISTORS_20_KOHM);
+
+   dw_mipi_dsi_phy_write(dsi, HS_RX_CONTROL_OF_LANE_0,
+ HSFREQRANGE_SEL(testdin));
+
+   dw_mipi_dsi_phy_write(dsi, PLL_INPUT_DIVIDER_RATIO,
+ 

  1   2   3   4   5   6   7   8   9   10   >