RE: MEETING IN DUBAI
Dear i only need your help to meet with Mr kelly adams who is right now in Dubai,you will play a roll of the beneficiary of the funds which i have agreed to give you 40% of the total sum,this money will be used for investment in uae,please the box is right now in London security company,once you cooperate with my representative and have meeting together,we can now proceed to instruct the company to ship down the consignment to Dubai through diplomatic shipment,the duty of my representative is to stay with you until you receive the cash,then once you have every thing in your control,you will give him one million dollars cash from the box to bring down for me,as you know my government over here has confiscated all my bank account,i only have that said funds secret for now,please keep this transaction private to your self,then invest the rest of the funds in good business of your choice in ant country in the world,just book your ticket to Dubai,three days we can finish ok,not every thing we talk on the phone or email,must things will be discus face to face thanks for your understanding fill free to call me at your convenient time please cooperate with Mr kelly adams, attached is my identity i send you a proposals thanks for your understanding we will put all money in real estate REPLY BACK HERE : nikolai.nikolai...@gmail.com Best Regards MOHAMED ABDUL
RE: MEETING IN DUBAI
Dear i only need your help to meet with Mr kelly adams who is right now in Dubai,you will play a roll of the beneficiary of the funds which i have agreed to give you 40% of the total sum,this money will be used for investment in uae,please the box is right now in London security company,once you cooperate with my representative and have meeting together,we can now proceed to instruct the company to ship down the consignment to Dubai through diplomatic shipment,the duty of my representative is to stay with you until you receive the cash,then once you have every thing in your control,you will give him one million dollars cash from the box to bring down for me,as you know my government over here has confiscated all my bank account,i only have that said funds secret for now,please keep this transaction private to your self,then invest the rest of the funds in good business of your choice in ant country in the world,just book your ticket to Dubai,three days we can finish ok,not every thing we talk on the phone or email,must things will be discus face to face thanks for your understanding fill free to call me at your convenient time please cooperate with Mr kelly adams, attached is my identity i send you a proposals thanks for your understanding we will put all money in real estate REPLY BACK HERE : nikolai.nikolai...@gmail.com Best Regards MOHAMED ABDUL
[PATCH RESEND v3] arm64: clean the additional checks before calling ghes_notify_sea()
In order to remove the additional check before calling the ghes_notify_sea(), make stub definition when !CONFIG_ACPI_APEI_SEA. After this cleanup, we can simply call the ghes_notify_sea() to let APEI driver handle the SEA notification. CC: Tyler Baicar CC: James Morse Signed-off-by: Dongjiu Geng Acked-by: Will Deacon Reviewed-by: Tyler Baicar --- This cleanup is ever mentioned by Mark Rutland in [1] [1]: https://lkml.org/lkml/2018/5/31/289 change since v2: 1. Add 'Reviewed-by' of Tyler change since v1: 1. Update the commit messages 2. CC Tyler and James 3. Add 'Acked-by' of Will --- arch/arm64/mm/fault.c | 7 +-- include/acpi/ghes.h | 4 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index b8eecc7..9ffe01d 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -727,12 +727,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) int handle_guest_sea(phys_addr_t addr, unsigned int esr) { - int ret = -ENOENT; - - if (IS_ENABLED(CONFIG_ACPI_APEI_SEA)) - ret = ghes_notify_sea(); - - return ret; + return ghes_notify_sea(); } asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h index 1624e2b..82cb4eb 100644 --- a/include/acpi/ghes.h +++ b/include/acpi/ghes.h @@ -118,6 +118,10 @@ static inline void *acpi_hest_get_next(struct acpi_hest_generic_data *gdata) (void *)section - (void *)(estatus + 1) < estatus->data_length; \ section = acpi_hest_get_next(section)) +#ifdef CONFIG_ACPI_APEI_SEA int ghes_notify_sea(void); +#else +static inline int ghes_notify_sea(void) { return -ENOENT; } +#endif #endif /* GHES_H */ -- 1.9.1
[PATCH RESEND v3] arm64: clean the additional checks before calling ghes_notify_sea()
In order to remove the additional check before calling the ghes_notify_sea(), make stub definition when !CONFIG_ACPI_APEI_SEA. After this cleanup, we can simply call the ghes_notify_sea() to let APEI driver handle the SEA notification. CC: Tyler Baicar CC: James Morse Signed-off-by: Dongjiu Geng Acked-by: Will Deacon Reviewed-by: Tyler Baicar --- This cleanup is ever mentioned by Mark Rutland in [1] [1]: https://lkml.org/lkml/2018/5/31/289 change since v2: 1. Add 'Reviewed-by' of Tyler change since v1: 1. Update the commit messages 2. CC Tyler and James 3. Add 'Acked-by' of Will --- arch/arm64/mm/fault.c | 7 +-- include/acpi/ghes.h | 4 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index b8eecc7..9ffe01d 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -727,12 +727,7 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) int handle_guest_sea(phys_addr_t addr, unsigned int esr) { - int ret = -ENOENT; - - if (IS_ENABLED(CONFIG_ACPI_APEI_SEA)) - ret = ghes_notify_sea(); - - return ret; + return ghes_notify_sea(); } asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, diff --git a/include/acpi/ghes.h b/include/acpi/ghes.h index 1624e2b..82cb4eb 100644 --- a/include/acpi/ghes.h +++ b/include/acpi/ghes.h @@ -118,6 +118,10 @@ static inline void *acpi_hest_get_next(struct acpi_hest_generic_data *gdata) (void *)section - (void *)(estatus + 1) < estatus->data_length; \ section = acpi_hest_get_next(section)) +#ifdef CONFIG_ACPI_APEI_SEA int ghes_notify_sea(void); +#else +static inline int ghes_notify_sea(void) { return -ENOENT; } +#endif #endif /* GHES_H */ -- 1.9.1
linux-next: Signed-off-by missing for commit in the v4l-dvb tree
Hi Mauro, Commit da2048b7348a ("Revert "media: vivid: shut up warnings due to a non-trivial logic"") is missing a Signed-off-by from its author and committer. Reverts are commits, too. -- Cheers, Stephen Rothwell pgpd8X7yEeTU1.pgp Description: OpenPGP digital signature
linux-next: Signed-off-by missing for commit in the v4l-dvb tree
Hi Mauro, Commit da2048b7348a ("Revert "media: vivid: shut up warnings due to a non-trivial logic"") is missing a Signed-off-by from its author and committer. Reverts are commits, too. -- Cheers, Stephen Rothwell pgpd8X7yEeTU1.pgp Description: OpenPGP digital signature
[PATCH V2] kernel: locking: rtmutex: Fix a possible sleep-in-atomic-context bug in rt_mutex_handle_deadlock()
The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.16 are: [FUNC] schedule kernel/locking/rtmutex.c, 1223: schedule in rt_mutex_handle_deadlock kernel/locking/rtmutex.c, 1273: rt_mutex_handle_deadlock in rt_mutex_slowlock kernel/locking/rtmutex.c, 1249: _raw_spin_lock_irqsave in rt_mutex_slowlock To fix the bug, the spinlock is released before the loop of schedule() This is found by my static analysis tool (DSAC). Signed-off-by: Jia-Ju Bai --- v2: * Release the spinlock before the loop, instead of v1 that releases the spinlock before schedule() and then acquires the spinlock again. Thank Steven for good advice. --- kernel/locking/rtmutex.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 2823d4163a37..8f25a289abe8 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1205,7 +1205,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, } static void rt_mutex_handle_deadlock(int res, int detect_deadlock, -struct rt_mutex_waiter *w) +struct rt_mutex_waiter *w, struct rt_mutex *lock) { /* * If the result is not -EDEADLOCK or the caller requested @@ -1218,6 +1218,8 @@ static void rt_mutex_handle_deadlock(int res, int detect_deadlock, * Yell lowdly and stop the task right here. */ rt_mutex_print_deadlock(w); + /* We're not going anywhere, release the wait_lock */ + raw_spin_unlock_irq(>wait_lock); while (1) { set_current_state(TASK_INTERRUPTIBLE); schedule(); @@ -1269,7 +1271,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, if (unlikely(ret)) { __set_current_state(TASK_RUNNING); remove_waiter(lock, ); - rt_mutex_handle_deadlock(ret, chwalk, ); + rt_mutex_handle_deadlock(ret, chwalk, , lock); } /* -- 2.17.0
[PATCH V2] kernel: locking: rtmutex: Fix a possible sleep-in-atomic-context bug in rt_mutex_handle_deadlock()
The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.16 are: [FUNC] schedule kernel/locking/rtmutex.c, 1223: schedule in rt_mutex_handle_deadlock kernel/locking/rtmutex.c, 1273: rt_mutex_handle_deadlock in rt_mutex_slowlock kernel/locking/rtmutex.c, 1249: _raw_spin_lock_irqsave in rt_mutex_slowlock To fix the bug, the spinlock is released before the loop of schedule() This is found by my static analysis tool (DSAC). Signed-off-by: Jia-Ju Bai --- v2: * Release the spinlock before the loop, instead of v1 that releases the spinlock before schedule() and then acquires the spinlock again. Thank Steven for good advice. --- kernel/locking/rtmutex.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 2823d4163a37..8f25a289abe8 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1205,7 +1205,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, } static void rt_mutex_handle_deadlock(int res, int detect_deadlock, -struct rt_mutex_waiter *w) +struct rt_mutex_waiter *w, struct rt_mutex *lock) { /* * If the result is not -EDEADLOCK or the caller requested @@ -1218,6 +1218,8 @@ static void rt_mutex_handle_deadlock(int res, int detect_deadlock, * Yell lowdly and stop the task right here. */ rt_mutex_print_deadlock(w); + /* We're not going anywhere, release the wait_lock */ + raw_spin_unlock_irq(>wait_lock); while (1) { set_current_state(TASK_INTERRUPTIBLE); schedule(); @@ -1269,7 +1271,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, if (unlikely(ret)) { __set_current_state(TASK_RUNNING); remove_waiter(lock, ); - rt_mutex_handle_deadlock(ret, chwalk, ); + rt_mutex_handle_deadlock(ret, chwalk, , lock); } /* -- 2.17.0
Re: [PATCH] kernel: locking: rtmutex: Fix a possible sleep-in-atomic-context bug in rt_mutex_handle_deadlock()
On 2018/8/11 10:44, Steven Rostedt wrote: On Sat, Aug 11, 2018 at 10:35:24AM +0800, Jia-Ju Bai wrote: The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.16 are: [FUNC] schedule kernel/locking/rtmutex.c, 1223: schedule in rt_mutex_handle_deadlock kernel/locking/rtmutex.c, 1273: rt_mutex_handle_deadlock in rt_mutex_slowlock kernel/locking/rtmutex.c, 1249: _raw_spin_lock_irqsave in rt_mutex_slowlock To fix the bug, the spinlock is released before schedule() and then acquired again. This is found by my static analysis tool (DSAC). Signed-off-by: Jia-Ju Bai --- kernel/locking/rtmutex.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 2823d4163a37..af03e162f812 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1205,7 +1205,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, } static void rt_mutex_handle_deadlock(int res, int detect_deadlock, -struct rt_mutex_waiter *w) +struct rt_mutex_waiter *w, struct rt_mutex *lock) { /* * If the result is not -EDEADLOCK or the caller requested @@ -1219,8 +1219,10 @@ static void rt_mutex_handle_deadlock(int res, int detect_deadlock, */ rt_mutex_print_deadlock(w); while (1) { + raw_spin_unlock_irq(>wait_lock); set_current_state(TASK_INTERRUPTIBLE); schedule(); + raw_spin_lock_irq(>wait_lock); } If you look at the code you will notice that it stops the task and never lets it continue. Ever. If we hit this path, it means we are in a deadlock scenario and will not make any forward progress. If anything, it should simply be: rt_mutex_print_deadlock(w); + /* We're not going anywhere, release the wait_lock */ + raw_spin_unlock_irq(>wait_lock); while (1) { set_current_state(TASK_INTERRUPTIBLE); schedule(); } Thanks for your reply :) Okay, I will send a V2 patch. Best wishes, Jia-Ju Bai
Re: [PATCH] kernel: locking: rtmutex: Fix a possible sleep-in-atomic-context bug in rt_mutex_handle_deadlock()
On 2018/8/11 10:44, Steven Rostedt wrote: On Sat, Aug 11, 2018 at 10:35:24AM +0800, Jia-Ju Bai wrote: The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.16 are: [FUNC] schedule kernel/locking/rtmutex.c, 1223: schedule in rt_mutex_handle_deadlock kernel/locking/rtmutex.c, 1273: rt_mutex_handle_deadlock in rt_mutex_slowlock kernel/locking/rtmutex.c, 1249: _raw_spin_lock_irqsave in rt_mutex_slowlock To fix the bug, the spinlock is released before schedule() and then acquired again. This is found by my static analysis tool (DSAC). Signed-off-by: Jia-Ju Bai --- kernel/locking/rtmutex.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 2823d4163a37..af03e162f812 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1205,7 +1205,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, } static void rt_mutex_handle_deadlock(int res, int detect_deadlock, -struct rt_mutex_waiter *w) +struct rt_mutex_waiter *w, struct rt_mutex *lock) { /* * If the result is not -EDEADLOCK or the caller requested @@ -1219,8 +1219,10 @@ static void rt_mutex_handle_deadlock(int res, int detect_deadlock, */ rt_mutex_print_deadlock(w); while (1) { + raw_spin_unlock_irq(>wait_lock); set_current_state(TASK_INTERRUPTIBLE); schedule(); + raw_spin_lock_irq(>wait_lock); } If you look at the code you will notice that it stops the task and never lets it continue. Ever. If we hit this path, it means we are in a deadlock scenario and will not make any forward progress. If anything, it should simply be: rt_mutex_print_deadlock(w); + /* We're not going anywhere, release the wait_lock */ + raw_spin_unlock_irq(>wait_lock); while (1) { set_current_state(TASK_INTERRUPTIBLE); schedule(); } Thanks for your reply :) Okay, I will send a V2 patch. Best wishes, Jia-Ju Bai
drivers/mtd/chips/cfi_util.o: warning: objtool: cfi_qry_present() falls through to next function cfi_merge_status()
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: f313b43be461f157755a57c1156f86abe10588de commit: ed7d40bc67b8353c677b38c6cdddcdc310c0f452 tracing: Fix SKIP_STACK_VALIDATION=1 build due to bad merge with -mrecord-mcount date: 7 weeks ago config: x86_64-randconfig-g0-08111005 (attached as .config) compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4 reproduce: git checkout ed7d40bc67b8353c677b38c6cdddcdc310c0f452 # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): >> drivers/mtd/chips/cfi_util.o: warning: objtool: cfi_qry_present() falls >> through to next function cfi_merge_status() -- >> drivers/mtd/chips/cfi_cmdset_0002.o: warning: objtool: chip_good() falls >> through to next function fixup_use_fwh_lock() --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
drivers/mtd/chips/cfi_util.o: warning: objtool: cfi_qry_present() falls through to next function cfi_merge_status()
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: f313b43be461f157755a57c1156f86abe10588de commit: ed7d40bc67b8353c677b38c6cdddcdc310c0f452 tracing: Fix SKIP_STACK_VALIDATION=1 build due to bad merge with -mrecord-mcount date: 7 weeks ago config: x86_64-randconfig-g0-08111005 (attached as .config) compiler: gcc-4.9 (Debian 4.9.4-2) 4.9.4 reproduce: git checkout ed7d40bc67b8353c677b38c6cdddcdc310c0f452 # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): >> drivers/mtd/chips/cfi_util.o: warning: objtool: cfi_qry_present() falls >> through to next function cfi_merge_status() -- >> drivers/mtd/chips/cfi_cmdset_0002.o: warning: objtool: chip_good() falls >> through to next function fixup_use_fwh_lock() --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] kernel: locking: rtmutex: Fix a possible sleep-in-atomic-context bug in rt_mutex_handle_deadlock()
On Sat, Aug 11, 2018 at 10:35:24AM +0800, Jia-Ju Bai wrote: > The driver may sleep with holding a spinlock. > > The function call paths (from bottom to top) in Linux-4.16 are: > > [FUNC] schedule > kernel/locking/rtmutex.c, 1223: > schedule in rt_mutex_handle_deadlock > kernel/locking/rtmutex.c, 1273: > rt_mutex_handle_deadlock in rt_mutex_slowlock > kernel/locking/rtmutex.c, 1249: > _raw_spin_lock_irqsave in rt_mutex_slowlock > > To fix the bug, the spinlock is released before schedule() and then acquired > again. > This is found by my static analysis tool (DSAC). > > Signed-off-by: Jia-Ju Bai > --- > kernel/locking/rtmutex.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c > index 2823d4163a37..af03e162f812 100644 > --- a/kernel/locking/rtmutex.c > +++ b/kernel/locking/rtmutex.c > @@ -1205,7 +1205,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, > } > > static void rt_mutex_handle_deadlock(int res, int detect_deadlock, > - struct rt_mutex_waiter *w) > + struct rt_mutex_waiter *w, struct rt_mutex > *lock) > { > /* >* If the result is not -EDEADLOCK or the caller requested > @@ -1219,8 +1219,10 @@ static void rt_mutex_handle_deadlock(int res, int > detect_deadlock, >*/ > rt_mutex_print_deadlock(w); > while (1) { > + raw_spin_unlock_irq(>wait_lock); > set_current_state(TASK_INTERRUPTIBLE); > schedule(); > + raw_spin_lock_irq(>wait_lock); > } If you look at the code you will notice that it stops the task and never lets it continue. Ever. If we hit this path, it means we are in a deadlock scenario and will not make any forward progress. If anything, it should simply be: rt_mutex_print_deadlock(w); + /* We're not going anywhere, release the wait_lock */ + raw_spin_unlock_irq(>wait_lock); while (1) { set_current_state(TASK_INTERRUPTIBLE); schedule(); } -- Steve > } > > @@ -1269,7 +1271,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, > if (unlikely(ret)) { > __set_current_state(TASK_RUNNING); > remove_waiter(lock, ); > - rt_mutex_handle_deadlock(ret, chwalk, ); > + rt_mutex_handle_deadlock(ret, chwalk, , lock); > } > > /* > -- > 2.17.0
Re: [PATCH] kernel: locking: rtmutex: Fix a possible sleep-in-atomic-context bug in rt_mutex_handle_deadlock()
On Sat, Aug 11, 2018 at 10:35:24AM +0800, Jia-Ju Bai wrote: > The driver may sleep with holding a spinlock. > > The function call paths (from bottom to top) in Linux-4.16 are: > > [FUNC] schedule > kernel/locking/rtmutex.c, 1223: > schedule in rt_mutex_handle_deadlock > kernel/locking/rtmutex.c, 1273: > rt_mutex_handle_deadlock in rt_mutex_slowlock > kernel/locking/rtmutex.c, 1249: > _raw_spin_lock_irqsave in rt_mutex_slowlock > > To fix the bug, the spinlock is released before schedule() and then acquired > again. > This is found by my static analysis tool (DSAC). > > Signed-off-by: Jia-Ju Bai > --- > kernel/locking/rtmutex.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c > index 2823d4163a37..af03e162f812 100644 > --- a/kernel/locking/rtmutex.c > +++ b/kernel/locking/rtmutex.c > @@ -1205,7 +1205,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, > } > > static void rt_mutex_handle_deadlock(int res, int detect_deadlock, > - struct rt_mutex_waiter *w) > + struct rt_mutex_waiter *w, struct rt_mutex > *lock) > { > /* >* If the result is not -EDEADLOCK or the caller requested > @@ -1219,8 +1219,10 @@ static void rt_mutex_handle_deadlock(int res, int > detect_deadlock, >*/ > rt_mutex_print_deadlock(w); > while (1) { > + raw_spin_unlock_irq(>wait_lock); > set_current_state(TASK_INTERRUPTIBLE); > schedule(); > + raw_spin_lock_irq(>wait_lock); > } If you look at the code you will notice that it stops the task and never lets it continue. Ever. If we hit this path, it means we are in a deadlock scenario and will not make any forward progress. If anything, it should simply be: rt_mutex_print_deadlock(w); + /* We're not going anywhere, release the wait_lock */ + raw_spin_unlock_irq(>wait_lock); while (1) { set_current_state(TASK_INTERRUPTIBLE); schedule(); } -- Steve > } > > @@ -1269,7 +1271,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, > if (unlikely(ret)) { > __set_current_state(TASK_RUNNING); > remove_waiter(lock, ); > - rt_mutex_handle_deadlock(ret, chwalk, ); > + rt_mutex_handle_deadlock(ret, chwalk, , lock); > } > > /* > -- > 2.17.0
[PATCH] kernel: locking: rtmutex: Fix a possible sleep-in-atomic-context bug in rt_mutex_handle_deadlock()
The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.16 are: [FUNC] schedule kernel/locking/rtmutex.c, 1223: schedule in rt_mutex_handle_deadlock kernel/locking/rtmutex.c, 1273: rt_mutex_handle_deadlock in rt_mutex_slowlock kernel/locking/rtmutex.c, 1249: _raw_spin_lock_irqsave in rt_mutex_slowlock To fix the bug, the spinlock is released before schedule() and then acquired again. This is found by my static analysis tool (DSAC). Signed-off-by: Jia-Ju Bai --- kernel/locking/rtmutex.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 2823d4163a37..af03e162f812 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1205,7 +1205,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, } static void rt_mutex_handle_deadlock(int res, int detect_deadlock, -struct rt_mutex_waiter *w) +struct rt_mutex_waiter *w, struct rt_mutex *lock) { /* * If the result is not -EDEADLOCK or the caller requested @@ -1219,8 +1219,10 @@ static void rt_mutex_handle_deadlock(int res, int detect_deadlock, */ rt_mutex_print_deadlock(w); while (1) { + raw_spin_unlock_irq(>wait_lock); set_current_state(TASK_INTERRUPTIBLE); schedule(); + raw_spin_lock_irq(>wait_lock); } } @@ -1269,7 +1271,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, if (unlikely(ret)) { __set_current_state(TASK_RUNNING); remove_waiter(lock, ); - rt_mutex_handle_deadlock(ret, chwalk, ); + rt_mutex_handle_deadlock(ret, chwalk, , lock); } /* -- 2.17.0
[PATCH] kernel: locking: rtmutex: Fix a possible sleep-in-atomic-context bug in rt_mutex_handle_deadlock()
The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.16 are: [FUNC] schedule kernel/locking/rtmutex.c, 1223: schedule in rt_mutex_handle_deadlock kernel/locking/rtmutex.c, 1273: rt_mutex_handle_deadlock in rt_mutex_slowlock kernel/locking/rtmutex.c, 1249: _raw_spin_lock_irqsave in rt_mutex_slowlock To fix the bug, the spinlock is released before schedule() and then acquired again. This is found by my static analysis tool (DSAC). Signed-off-by: Jia-Ju Bai --- kernel/locking/rtmutex.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 2823d4163a37..af03e162f812 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -1205,7 +1205,7 @@ __rt_mutex_slowlock(struct rt_mutex *lock, int state, } static void rt_mutex_handle_deadlock(int res, int detect_deadlock, -struct rt_mutex_waiter *w) +struct rt_mutex_waiter *w, struct rt_mutex *lock) { /* * If the result is not -EDEADLOCK or the caller requested @@ -1219,8 +1219,10 @@ static void rt_mutex_handle_deadlock(int res, int detect_deadlock, */ rt_mutex_print_deadlock(w); while (1) { + raw_spin_unlock_irq(>wait_lock); set_current_state(TASK_INTERRUPTIBLE); schedule(); + raw_spin_lock_irq(>wait_lock); } } @@ -1269,7 +1271,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, int state, if (unlikely(ret)) { __set_current_state(TASK_RUNNING); remove_waiter(lock, ); - rt_mutex_handle_deadlock(ret, chwalk, ); + rt_mutex_handle_deadlock(ret, chwalk, , lock); } /* -- 2.17.0
Re: [PATCH v4 0/4] seccomp trap to userspace
On Tue, Aug 07, 2018 at 09:11:50PM -0700, Dinesh Subhraveti wrote: > On Mon, Aug 6, 2018 at 7:44 PM, Tycho Andersen wrote: > > Hi all, > > > > Dinesh Subhraveti has claimed that some part of this series might be > > patented. While he has not furnished me with anything to confirm this > > claim, I'll put this series on hold. > > For the sake of everyone's clarity, there is no patent or intellectual > property issue here and we'd like to see this feature in the kernel. I did > indicate that there is a patent related to the mechanism underlying this > patch set but that is completely incidental to the issue here. We have > filed that patent only for the purpose of defense and have no interest or > resources to go after infringements. As such, I spoke about the approach, > it's value for networking and a few possible ways of implementing it in the > kernel at Linux Plumbers Conference 2017. > > As a contractor and a member of our team at AppSwitch (FKA Fermat), Tycho > Andersen helped implement a fully user space version of system call trap > mechanism based on seccomp / fd-passing and participated in our team > discussions about upstreaming a kernel version of the feature. Given that > context, we were taken aback that he posted the v1 patch set without > letting us know and without any mention of AppSwitch in the post even > though he was still under contract at that time. It seems we disagree on the series of events, but agree that this patchset should move forward. I'll work on preparing a v5. Thanks! Tycho
Re: [PATCH v4 0/4] seccomp trap to userspace
On Tue, Aug 07, 2018 at 09:11:50PM -0700, Dinesh Subhraveti wrote: > On Mon, Aug 6, 2018 at 7:44 PM, Tycho Andersen wrote: > > Hi all, > > > > Dinesh Subhraveti has claimed that some part of this series might be > > patented. While he has not furnished me with anything to confirm this > > claim, I'll put this series on hold. > > For the sake of everyone's clarity, there is no patent or intellectual > property issue here and we'd like to see this feature in the kernel. I did > indicate that there is a patent related to the mechanism underlying this > patch set but that is completely incidental to the issue here. We have > filed that patent only for the purpose of defense and have no interest or > resources to go after infringements. As such, I spoke about the approach, > it's value for networking and a few possible ways of implementing it in the > kernel at Linux Plumbers Conference 2017. > > As a contractor and a member of our team at AppSwitch (FKA Fermat), Tycho > Andersen helped implement a fully user space version of system call trap > mechanism based on seccomp / fd-passing and participated in our team > discussions about upstreaming a kernel version of the feature. Given that > context, we were taken aback that he posted the v1 patch set without > letting us know and without any mention of AppSwitch in the post even > though he was still under contract at that time. It seems we disagree on the series of events, but agree that this patchset should move forward. I'll work on preparing a v5. Thanks! Tycho
KASAN errors from unwind_frame
Hi All, I have observed following KASAN error with 4.14.56 kernel. Can you please copy change-[1](kasan: add no_sanitize attribute for clang builds) into stable kernels? [1] - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/include/linux/compiler-clang.h?h=v4.18-rc8=12c8f25a016dff69ee284aa3338bebfd2cfcba33 == BUG: KASAN: out-of-bounds in __read_once_size_nocheck include/linux/compiler.h:196 [inline] BUG: KASAN: out-of-bounds in unwind_frame+0xc4/0x324 arch/arm64/kernel/stacktrace.c:56 Read of size 8 at addr ffe3123ff4b0 by task poc/15233 CPU: 7 PID: 15233 Comm: poc Tainted: G S W O4.14.56+ #3 Hardware name: Qualcomm Technologies, Inc. Call trace: dump_backtrace+0x0/0x388 show_stack+0x24/0x30 __dump_stack+0x24/0x2c dump_stack+0x8c/0xd0 print_address_description+0x74/0x234 kasan_report+0x240/0x264 __asan_report_load8_noabort+0x2c/0x38 unwind_frame+0xc4/0x324 walk_stackframe+0x44/0x6c __save_stack_trace+0x250/0x444 save_stack_trace_tsk+0x2c/0x38 proc_pid_stack+0x134/0x268 proc_single_show+0xdc/0x130 traverse+0x244/0x5b0 seq_lseek+0x10c/0x27c vfs_llseek+0xb4/0xe4 SyS_lseek+0x54/0xa0 el0_svc_naked+0x34/0x38 The buggy address belongs to the page: page:ffbf8c48ffc0 count:0 mapcount:0 mapping: (null) index:0x0 flags: 0x0() raw: raw: dead0200 page dumped because: kasan: bad access detected page_owner info is not active (free page?) Memory state around the buggy address: ffe3123ff380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffe3123ff400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffe3123ff480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ ffe3123ff500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffe3123ff580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 == -Thanks, Prasad -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, Linux Foundation Collaborative Project
KASAN errors from unwind_frame
Hi All, I have observed following KASAN error with 4.14.56 kernel. Can you please copy change-[1](kasan: add no_sanitize attribute for clang builds) into stable kernels? [1] - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/include/linux/compiler-clang.h?h=v4.18-rc8=12c8f25a016dff69ee284aa3338bebfd2cfcba33 == BUG: KASAN: out-of-bounds in __read_once_size_nocheck include/linux/compiler.h:196 [inline] BUG: KASAN: out-of-bounds in unwind_frame+0xc4/0x324 arch/arm64/kernel/stacktrace.c:56 Read of size 8 at addr ffe3123ff4b0 by task poc/15233 CPU: 7 PID: 15233 Comm: poc Tainted: G S W O4.14.56+ #3 Hardware name: Qualcomm Technologies, Inc. Call trace: dump_backtrace+0x0/0x388 show_stack+0x24/0x30 __dump_stack+0x24/0x2c dump_stack+0x8c/0xd0 print_address_description+0x74/0x234 kasan_report+0x240/0x264 __asan_report_load8_noabort+0x2c/0x38 unwind_frame+0xc4/0x324 walk_stackframe+0x44/0x6c __save_stack_trace+0x250/0x444 save_stack_trace_tsk+0x2c/0x38 proc_pid_stack+0x134/0x268 proc_single_show+0xdc/0x130 traverse+0x244/0x5b0 seq_lseek+0x10c/0x27c vfs_llseek+0xb4/0xe4 SyS_lseek+0x54/0xa0 el0_svc_naked+0x34/0x38 The buggy address belongs to the page: page:ffbf8c48ffc0 count:0 mapcount:0 mapping: (null) index:0x0 flags: 0x0() raw: raw: dead0200 page dumped because: kasan: bad access detected page_owner info is not active (free page?) Memory state around the buggy address: ffe3123ff380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffe3123ff400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffe3123ff480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ ffe3123ff500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffe3123ff580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 == -Thanks, Prasad -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, Linux Foundation Collaborative Project
Re: [PATCH v5 1/2] leds: core: Introduce LED pattern trigger
Hi Jacek, On 11 August 2018 at 02:10, Jacek Anaszewski wrote: > Hi Baolin, > > On 08/10/2018 05:26 PM, Baolin Wang wrote: >> Hi Jacek, >> >> On 9 August 2018 at 21:21, Jacek Anaszewski >> wrote: >>> Hi Baolin, >>> >>> On 08/09/2018 07:48 AM, Baolin Wang wrote: >>> [...] +static int pattern_trig_start_pattern(struct pattern_trig_data *data, + struct led_classdev *led_cdev) +{ + if (!data->npatterns) + return 0; + + if (led_cdev->pattern_set) { + return led_cdev->pattern_set(led_cdev, data->patterns, + data->npatterns, data->repeat); >>> >>> I think that it would be more flexible if software pattern fallback >>> was applied in case of pattern_set failure. Otherwise, it would >>> lead to the situation where LED class devices that support hardware >>> blinking couldn't be applied the same set of patterns as LED class >>> devices that don't implement pattern_set. The latter will always have to >>> resort to using software pattern engine which will accept far greater >>> amount of pattern combinations. >> >> Hmmm, I am not sure this is useful for hardware pattern, since the LED >> hardware can be diverse which is hard to be compatible with software >> pattern. >> >> For example, for our SC27XX LED, it only supports 4 hardware patterns >> setting (low time, rising time, high time and falling time) to make it >> work at breathing mode. If user provides 3 or 5 patterns values, it >> will failed to issue pattern_set(). But at this time, we don't want to >> use software pattern instead since it will be not the breathing mode >> expected by user. I don't know if there are other special LED >> hardware. > > Good point. So this is the issue we should dwell on, since the > requested pattern effect should look similar on all devices. > Of course in case of software pattern it will be often impossible > to achieve the same fluency. Similarly as in case of rendering graphics > with and without acceleration. > > In case of your device, I'd say that we'd need more complex description > of breathing mode pattern. More complex than just four intervals. > It should reflect all the intervals the hardware engine needs to perform > to achieve the breathing effect. Can this information be inferred from > the docs? >From our docs, it only provides registers to set the low time, rising time, high time and falling time (value unit is 0.125s and max value is 63 = 7.875s) to enable breathing mode. So each interval value can be 1 ~ 63. But that is still hard for software pattern to simulate the breathing mode performed by hardware pattern. >>> >>> Software fallback is not expected to show similar performance to the >>> hardware engine on the whole span of the supported time range. >>> >>> Having min rise time value at 125ms, and given that max_brightness >>> is 255, then we'd have 255 / 125 = 2.04 of brightness level rise per >>> 1ms. So, the pattern for rising edge could look like (assuming we >>> stop at 254): >>> >>> 0 1 2 1 4 1 6 1 8 1 10 1 ... 254 1 >> >> Right, maybe this can work, maybe not. Since we can met different >> cases when failed to issue pattern_set(). Maybe the LED hardware >> occurs some errors, in this case we should shutdown the LED, not >> enable the software pattern instead, which still can not work. > > This is arguable. Timer trigger always resorts to using software > fallback if blink_set() fails. Timer trigger is simple which only need delay_on and delay_off, that means software can be easy to show the same performance. But hardware pattern can be diverse, we need to convert hardware patterns to software patterns. >> Maybe >> driver can set NULL for pattern_set/clear interfaces to disable >> hardware pattern, then next time user will perform the patterns with >> software pattern mode. > > Resetting any ops after LED class driver is probed should be > deemed forbidden, since LED core can make some decisions basing on > whether given ops are initialized or not. OK. > >> For our SC27XX LED, like I said if user provides only 3 pattern values >> which will failed to issue pattern_set(). But I still do not need use >> software patterns to show similar performance, instead it will still >> keep the last hardware pattern performance ( It did not overlap the >> previous hardware pattern setting). Maybe different drivers have >> different error handling, that's why I think we can leave driver to >> choose the proper way to handle. > > ABI semantics is generic, i.e. common for all drivers. Driver can > always log any problems occurred while setting pattern, but it shouldn't > necessarily need to prevent pattern trigger from using software > fallback. Fine. >>
Re: [PATCH v5 1/2] leds: core: Introduce LED pattern trigger
Hi Jacek, On 11 August 2018 at 02:10, Jacek Anaszewski wrote: > Hi Baolin, > > On 08/10/2018 05:26 PM, Baolin Wang wrote: >> Hi Jacek, >> >> On 9 August 2018 at 21:21, Jacek Anaszewski >> wrote: >>> Hi Baolin, >>> >>> On 08/09/2018 07:48 AM, Baolin Wang wrote: >>> [...] +static int pattern_trig_start_pattern(struct pattern_trig_data *data, + struct led_classdev *led_cdev) +{ + if (!data->npatterns) + return 0; + + if (led_cdev->pattern_set) { + return led_cdev->pattern_set(led_cdev, data->patterns, + data->npatterns, data->repeat); >>> >>> I think that it would be more flexible if software pattern fallback >>> was applied in case of pattern_set failure. Otherwise, it would >>> lead to the situation where LED class devices that support hardware >>> blinking couldn't be applied the same set of patterns as LED class >>> devices that don't implement pattern_set. The latter will always have to >>> resort to using software pattern engine which will accept far greater >>> amount of pattern combinations. >> >> Hmmm, I am not sure this is useful for hardware pattern, since the LED >> hardware can be diverse which is hard to be compatible with software >> pattern. >> >> For example, for our SC27XX LED, it only supports 4 hardware patterns >> setting (low time, rising time, high time and falling time) to make it >> work at breathing mode. If user provides 3 or 5 patterns values, it >> will failed to issue pattern_set(). But at this time, we don't want to >> use software pattern instead since it will be not the breathing mode >> expected by user. I don't know if there are other special LED >> hardware. > > Good point. So this is the issue we should dwell on, since the > requested pattern effect should look similar on all devices. > Of course in case of software pattern it will be often impossible > to achieve the same fluency. Similarly as in case of rendering graphics > with and without acceleration. > > In case of your device, I'd say that we'd need more complex description > of breathing mode pattern. More complex than just four intervals. > It should reflect all the intervals the hardware engine needs to perform > to achieve the breathing effect. Can this information be inferred from > the docs? >From our docs, it only provides registers to set the low time, rising time, high time and falling time (value unit is 0.125s and max value is 63 = 7.875s) to enable breathing mode. So each interval value can be 1 ~ 63. But that is still hard for software pattern to simulate the breathing mode performed by hardware pattern. >>> >>> Software fallback is not expected to show similar performance to the >>> hardware engine on the whole span of the supported time range. >>> >>> Having min rise time value at 125ms, and given that max_brightness >>> is 255, then we'd have 255 / 125 = 2.04 of brightness level rise per >>> 1ms. So, the pattern for rising edge could look like (assuming we >>> stop at 254): >>> >>> 0 1 2 1 4 1 6 1 8 1 10 1 ... 254 1 >> >> Right, maybe this can work, maybe not. Since we can met different >> cases when failed to issue pattern_set(). Maybe the LED hardware >> occurs some errors, in this case we should shutdown the LED, not >> enable the software pattern instead, which still can not work. > > This is arguable. Timer trigger always resorts to using software > fallback if blink_set() fails. Timer trigger is simple which only need delay_on and delay_off, that means software can be easy to show the same performance. But hardware pattern can be diverse, we need to convert hardware patterns to software patterns. >> Maybe >> driver can set NULL for pattern_set/clear interfaces to disable >> hardware pattern, then next time user will perform the patterns with >> software pattern mode. > > Resetting any ops after LED class driver is probed should be > deemed forbidden, since LED core can make some decisions basing on > whether given ops are initialized or not. OK. > >> For our SC27XX LED, like I said if user provides only 3 pattern values >> which will failed to issue pattern_set(). But I still do not need use >> software patterns to show similar performance, instead it will still >> keep the last hardware pattern performance ( It did not overlap the >> previous hardware pattern setting). Maybe different drivers have >> different error handling, that's why I think we can leave driver to >> choose the proper way to handle. > > ABI semantics is generic, i.e. common for all drivers. Driver can > always log any problems occurred while setting pattern, but it shouldn't > necessarily need to prevent pattern trigger from using software > fallback. Fine. >>
[PATCH v2] pinctrl: uniphier: drop meaningless pin from SD1 pin-mux of Pro4
The pin 327 was supposed to be used as a voltage control line for the SD card regulator, but the SD card port1 does not support UHS-I. It only supports 3.3V signaling, hence this pin is pointless. Just a note about the background. At first, hardware engineers tried to implement the UHS for this port. Then, they needed to shrink the silicon die size, and gave up the UHS, but forgot to remove the pin assignment. Signed-off-by: Masahiro Yamada --- Changes in v2: - rebase onto linux-pinctrl/devel branch drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c index 89148f8..6fca8d5 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c @@ -1047,9 +1047,8 @@ static const unsigned nand_cs1_pins[] = {131, 132}; static const int nand_cs1_muxvals[] = {1, 1}; static const unsigned sd_pins[] = {150, 151, 152, 153, 154, 155, 156, 157, 158}; static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; -static const unsigned sd1_pins[] = {319, 320, 321, 322, 323, 324, 325, 326, - 327}; -static const int sd1_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned int sd1_pins[] = {319, 320, 321, 322, 323, 324, 325, 326}; +static const int sd1_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned spi0_pins[] = {199, 200, 201, 202}; static const int spi0_muxvals[] = {11, 11, 11, 11}; static const unsigned spi1_pins[] = {195, 196, 197, 198, 235, 238, 239}; -- 2.7.4
[PATCH v2] pinctrl: uniphier: drop meaningless pin from SD1 pin-mux of Pro4
The pin 327 was supposed to be used as a voltage control line for the SD card regulator, but the SD card port1 does not support UHS-I. It only supports 3.3V signaling, hence this pin is pointless. Just a note about the background. At first, hardware engineers tried to implement the UHS for this port. Then, they needed to shrink the silicon die size, and gave up the UHS, but forgot to remove the pin assignment. Signed-off-by: Masahiro Yamada --- Changes in v2: - rebase onto linux-pinctrl/devel branch drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c index 89148f8..6fca8d5 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c @@ -1047,9 +1047,8 @@ static const unsigned nand_cs1_pins[] = {131, 132}; static const int nand_cs1_muxvals[] = {1, 1}; static const unsigned sd_pins[] = {150, 151, 152, 153, 154, 155, 156, 157, 158}; static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; -static const unsigned sd1_pins[] = {319, 320, 321, 322, 323, 324, 325, 326, - 327}; -static const int sd1_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned int sd1_pins[] = {319, 320, 321, 322, 323, 324, 325, 326}; +static const int sd1_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned spi0_pins[] = {199, 200, 201, 202}; static const int spi0_muxvals[] = {11, 11, 11, 11}; static const unsigned spi1_pins[] = {195, 196, 197, 198, 235, 238, 239}; -- 2.7.4
[BUG] gpio: gpio-adp5588: A possible sleep-in-atomic-context bug in adp5588_gpio_write()
The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.16 are: [FUNC] schedule_timeout drivers/media/platform/marvell-ccic/cafe-driver.c, 206: schedule_timeout in cafe_smbus_write_data drivers/media/platform/marvell-ccic/cafe-driver.c, 307: cafe_smbus_write_data in cafe_smbus_xfer drivers/i2c/i2c-core-smbus.c, 541: [FUNC_PTR]cafe_smbus_xfer in i2c_smbus_xfer drivers/i2c/i2c-core-smbus.c, 156: i2c_smbus_xfer in i2c_smbus_write_byte_data drivers/gpio/gpio-adp5588.c, 58: i2c_smbus_write_byte_data in adp5588_gpio_write drivers/gpio/gpio-adp5588.c, 115: adp5588_gpio_write in adp5588_gpio_direction_input drivers/gpio/gpio-adp5588.c, 224: adp5588_gpio_direction_input in adp5588_irq_set_type kernel/irq/manage.c, 686: [FUNC_PTR]adp5588_irq_set_type in __irq_set_trigger kernel/irq/manage.c, 1350: __irq_set_trigger in __setup_irq kernel/irq/manage.c, 1238: _raw_spin_lock_irqsave in __setup_irq [FUNC] mutex_lock_nested drivers/i2c/busses/i2c-cht-wc.c, 138: mutex_lock_nested in cht_wc_i2c_adap_smbus_xfer drivers/i2c/i2c-core-smbus.c, 541: [FUNC_PTR]cht_wc_i2c_adap_smbus_xfer in i2c_smbus_xfer drivers/i2c/i2c-core-smbus.c, 156: i2c_smbus_xfer in i2c_smbus_write_byte_data drivers/gpio/gpio-adp5588.c, 58: i2c_smbus_write_byte_data in adp5588_gpio_write drivers/gpio/gpio-adp5588.c, 115: adp5588_gpio_write in adp5588_gpio_direction_input drivers/gpio/gpio-adp5588.c, 224: adp5588_gpio_direction_input in adp5588_irq_set_type kernel/irq/manage.c, 686: [FUNC_PTR]adp5588_irq_set_type in __irq_set_trigger kernel/irq/manage.c, 1350: __irq_set_trigger in __setup_irq kernel/irq/manage.c, 1238: _raw_spin_lock_irqsave in __setup_irq [FUNC] mutex_lock_nested drivers/i2c/busses/i2c-i801.c, 828: mutex_lock_nested in i801_access drivers/i2c/i2c-core-smbus.c, 541: [FUNC_PTR]i801_access in i2c_smbus_xfer drivers/i2c/i2c-core-smbus.c, 156: i2c_smbus_xfer in i2c_smbus_write_byte_data drivers/gpio/gpio-adp5588.c, 58: i2c_smbus_write_byte_data in adp5588_gpio_write drivers/gpio/gpio-adp5588.c, 115: adp5588_gpio_write in adp5588_gpio_direction_input drivers/gpio/gpio-adp5588.c, 224: adp5588_gpio_direction_input in adp5588_irq_set_type kernel/irq/manage.c, 686: [FUNC_PTR]adp5588_irq_set_type in __irq_set_trigger kernel/irq/manage.c, 1350: __irq_set_trigger in __setup_irq kernel/irq/manage.c, 1238: _raw_spin_lock_irqsave in __setup_irq Note that [FUNC_PTR] means a function pointer call is used. I do not find a good way to fix, so I only report. Maybe adp5588_gpio_direction_input() and adp5588_gpio_write() should not be called in adp5588_irq_set_type(). This is found by my static analysis tool (DSAC). Best wishes, Jia-Ju Bai
[BUG] gpio: gpio-adp5588: A possible sleep-in-atomic-context bug in adp5588_gpio_write()
The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.16 are: [FUNC] schedule_timeout drivers/media/platform/marvell-ccic/cafe-driver.c, 206: schedule_timeout in cafe_smbus_write_data drivers/media/platform/marvell-ccic/cafe-driver.c, 307: cafe_smbus_write_data in cafe_smbus_xfer drivers/i2c/i2c-core-smbus.c, 541: [FUNC_PTR]cafe_smbus_xfer in i2c_smbus_xfer drivers/i2c/i2c-core-smbus.c, 156: i2c_smbus_xfer in i2c_smbus_write_byte_data drivers/gpio/gpio-adp5588.c, 58: i2c_smbus_write_byte_data in adp5588_gpio_write drivers/gpio/gpio-adp5588.c, 115: adp5588_gpio_write in adp5588_gpio_direction_input drivers/gpio/gpio-adp5588.c, 224: adp5588_gpio_direction_input in adp5588_irq_set_type kernel/irq/manage.c, 686: [FUNC_PTR]adp5588_irq_set_type in __irq_set_trigger kernel/irq/manage.c, 1350: __irq_set_trigger in __setup_irq kernel/irq/manage.c, 1238: _raw_spin_lock_irqsave in __setup_irq [FUNC] mutex_lock_nested drivers/i2c/busses/i2c-cht-wc.c, 138: mutex_lock_nested in cht_wc_i2c_adap_smbus_xfer drivers/i2c/i2c-core-smbus.c, 541: [FUNC_PTR]cht_wc_i2c_adap_smbus_xfer in i2c_smbus_xfer drivers/i2c/i2c-core-smbus.c, 156: i2c_smbus_xfer in i2c_smbus_write_byte_data drivers/gpio/gpio-adp5588.c, 58: i2c_smbus_write_byte_data in adp5588_gpio_write drivers/gpio/gpio-adp5588.c, 115: adp5588_gpio_write in adp5588_gpio_direction_input drivers/gpio/gpio-adp5588.c, 224: adp5588_gpio_direction_input in adp5588_irq_set_type kernel/irq/manage.c, 686: [FUNC_PTR]adp5588_irq_set_type in __irq_set_trigger kernel/irq/manage.c, 1350: __irq_set_trigger in __setup_irq kernel/irq/manage.c, 1238: _raw_spin_lock_irqsave in __setup_irq [FUNC] mutex_lock_nested drivers/i2c/busses/i2c-i801.c, 828: mutex_lock_nested in i801_access drivers/i2c/i2c-core-smbus.c, 541: [FUNC_PTR]i801_access in i2c_smbus_xfer drivers/i2c/i2c-core-smbus.c, 156: i2c_smbus_xfer in i2c_smbus_write_byte_data drivers/gpio/gpio-adp5588.c, 58: i2c_smbus_write_byte_data in adp5588_gpio_write drivers/gpio/gpio-adp5588.c, 115: adp5588_gpio_write in adp5588_gpio_direction_input drivers/gpio/gpio-adp5588.c, 224: adp5588_gpio_direction_input in adp5588_irq_set_type kernel/irq/manage.c, 686: [FUNC_PTR]adp5588_irq_set_type in __irq_set_trigger kernel/irq/manage.c, 1350: __irq_set_trigger in __setup_irq kernel/irq/manage.c, 1238: _raw_spin_lock_irqsave in __setup_irq Note that [FUNC_PTR] means a function pointer call is used. I do not find a good way to fix, so I only report. Maybe adp5588_gpio_direction_input() and adp5588_gpio_write() should not be called in adp5588_irq_set_type(). This is found by my static analysis tool (DSAC). Best wishes, Jia-Ju Bai
[BUG] gpio: gpio-adp5588: A possible sleep-in-atomic-context bug in adp5588_gpio_direction_input()
The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.16 are: [FUNC] mutex_lock_nested drivers/gpio/gpio-adp5588.c, 113: mutex_lock_nested in adp5588_gpio_direction_input drivers/gpio/gpio-adp5588.c, 224: adp5588_gpio_direction_input in adp5588_irq_set_type kernel/irq/manage.c, 686: [FUNC_PTR]adp5588_irq_set_type in __irq_set_trigger kernel/irq/manage.c, 1350: __irq_set_trigger in __setup_irq kernel/irq/manage.c, 1238: _raw_spin_lock_irqsave in __setup_irq Note that [FUNC_PTR] means a function pointer call is used. I do not find a good way to fix, so I only report. This is found by my static analysis tool (DSAC). Best wishes, Jia-Ju Bai
[BUG] gpio: gpio-adp5588: A possible sleep-in-atomic-context bug in adp5588_gpio_direction_input()
The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.16 are: [FUNC] mutex_lock_nested drivers/gpio/gpio-adp5588.c, 113: mutex_lock_nested in adp5588_gpio_direction_input drivers/gpio/gpio-adp5588.c, 224: adp5588_gpio_direction_input in adp5588_irq_set_type kernel/irq/manage.c, 686: [FUNC_PTR]adp5588_irq_set_type in __irq_set_trigger kernel/irq/manage.c, 1350: __irq_set_trigger in __setup_irq kernel/irq/manage.c, 1238: _raw_spin_lock_irqsave in __setup_irq Note that [FUNC_PTR] means a function pointer call is used. I do not find a good way to fix, so I only report. This is found by my static analysis tool (DSAC). Best wishes, Jia-Ju Bai
[PATCH v4 2/2] clk: qcom: gcc: Register QUPv3 RCGs for DFS on SDM845
QUPv3 clocks support DFS and thus register the RCGs which require support for the same. Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sdm845.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index fa1a196..fef6732 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -3458,9 +3458,29 @@ enum { }; MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table); +static struct clk_rcg2 *gcc_dfs_clocks[] = { + _qupv3_wrap0_s0_clk_src, + _qupv3_wrap0_s1_clk_src, + _qupv3_wrap0_s2_clk_src, + _qupv3_wrap0_s3_clk_src, + _qupv3_wrap0_s4_clk_src, + _qupv3_wrap0_s5_clk_src, + _qupv3_wrap0_s6_clk_src, + _qupv3_wrap0_s7_clk_src, + _qupv3_wrap1_s0_clk_src, + _qupv3_wrap1_s1_clk_src, + _qupv3_wrap1_s2_clk_src, + _qupv3_wrap1_s3_clk_src, + _qupv3_wrap1_s4_clk_src, + _qupv3_wrap1_s5_clk_src, + _qupv3_wrap1_s6_clk_src, + _qupv3_wrap1_s7_clk_src, +}; + static int gcc_sdm845_probe(struct platform_device *pdev) { struct regmap *regmap; + int ret; regmap = qcom_cc_map(pdev, _sdm845_desc); if (IS_ERR(regmap)) @@ -3470,6 +3490,11 @@ static int gcc_sdm845_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); regmap_update_bits(regmap, 0x71028, 0x3, 0x3); + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, + ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) + return ret; + return qcom_cc_really_probe(pdev, _sdm845_desc, regmap); } -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v4 1/2] clk: qcom: Add support for RCG to register for DFS
Dynamic Frequency switch is a feature of clock controller by which request from peripherals allows automatic switching frequency of input clock without SW intervention. There are various performance levels associated with a root clock. When the input performance state changes, the source clocks and division ratios of the new performance state are loaded on to RCG via HW and the RCG switches to new clock frequency when the RCG is in DFS HW enabled mode. Register the root clock generators(RCG) to switch to use the dfs clock ops in the cases where DFS is enabled. The clk_round_rate() called by the clock consumer would invoke the dfs determine clock ops and would read the DFS performance level registers to identify all the frequencies supported and update the frequency table. The DFS clock consumers would maintain these frequency mapping and request the desired performance levels. Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-rcg.h | 2 + drivers/clk/qcom/clk-rcg2.c | 224 2 files changed, 226 insertions(+) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index dbd5a9e..e6300e0 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -163,4 +163,6 @@ struct clk_rcg2 { extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +extern int qcom_cc_register_rcg_dfs(struct regmap *regmap, +struct clk_rcg2 **rcgs, int num_clks); #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 52208d4..55a5b58 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -40,6 +41,14 @@ #define N_REG 0xc #define D_REG 0x10 +/* Dynamic Frequency Scaling */ +#define MAX_PERF_LEVEL 8 +#define SE_CMD_DFSR_OFFSET 0x14 +#define SE_CMD_DFS_EN BIT(0) +#define SE_PERF_DFSR(level)(0x1c + 0x4 * (level)) +#define SE_PERF_M_DFSR(level) (0x5c + 0x4 * (level)) +#define SE_PERF_N_DFSR(level) (0x9c + 0x4 * (level)) + enum freq_policy { FLOOR, CEIL, @@ -929,3 +938,218 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw) .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + +/* Common APIs to be used for DFS based RCGR */ +static unsigned long clk_rcg2_calculate_freq(struct clk_hw *hw, + int level, struct freq_tbl *f) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + struct clk_hw *p; + unsigned long prate = 0; + u32 val, mask, cfg, m_off, n_off, offset, mode; + int i, ret, num_parents; + + offset = SE_PERF_DFSR(level); + ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + offset, ); + if (ret) + return ret; + + mask = BIT(rcg->hid_width) - 1; + f->pre_div = cfg & mask ? (cfg & mask) : 1; + + mode = cfg & CFG_MODE_MASK; + mode >>= CFG_MODE_SHIFT; + + cfg &= CFG_SRC_SEL_MASK; + cfg >>= CFG_SRC_SEL_SHIFT; + + num_parents = clk_hw_get_num_parents(hw); + for (i = 0; i < num_parents; i++) { + if (cfg == rcg->parent_map[i].cfg) { + f->src = rcg->parent_map[i].src; + p = clk_hw_get_parent_by_index(>clkr.hw, i); + prate = clk_hw_get_rate(p); + } + } + + if (mode) { + /* Calculate M & N values */ + m_off = SE_PERF_M_DFSR(level); + n_off = SE_PERF_N_DFSR(level); + + mask = BIT(rcg->mnd_width) - 1; + ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + m_off, + ); + if (ret) { + pr_err("Failed to read M offset register\n"); + return ret; + } + val &= mask; + f->m = val; + + ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + n_off, + ); + if (ret) { + pr_err("Failed to read N offset register\n"); + return ret; + } + /* val ~(N-M) */ + val = ~val; + val &= mask; + val += f->m; + f->n = val; + } + + return calc_rate(prate, f->m, f->n, mode, f->pre_div); +} + +static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg) +{ + struct freq_tbl *freq_tbl; + unsigned long calc_freq; + int i; + + freq_tbl = kcalloc(MAX_PERF_LEVEL, sizeof(*freq_tbl), + GFP_KERNEL); + if (!freq_tbl) + return -ENOMEM; + + for (i = 0; i < MAX_PERF_LEVEL; i++) { + calc_freq = clk_rcg2_calculate_freq(>clkr.hw, +
[PATCH v4 0/2] clk: qcom: Add support for RCG to register for DFS
[v4] * Add recalc_clk_ops to calculate the clock frequency reading the current perf state, also add CLK_GET_RATE_NOCACHE flag. * Cleanup 'goto' during mode check in 'clk_rcg2_calculate_freq'. * cleanup return from function 'com_cc_register_rcg_dfs'. [v3] * Rename clk_rcg2_calculate_m_and_n with clk_rcg2_calculate_freq, as this function would now calculate the frequency. * Rename dfs_freq_tbl to freq_tbl. * Remove the logic to remove duplicate frequencies. * Remove recalc_rate & set_rate clock ops. * clk_rcg2_dfs_ops clock ops is static. * Override the clock ops only if DFS mode is enabled. * qcom_cc_register_rcg_dfs uses regmap instead of device. * Few cleanups : Remove DFS probing after registering clocks. sizeof(*init), sizeof(*freq_tbl). [v2] * Move the dfs register function 'qcom_cc_register_rcg_dfs' to clk-rcg2.c instead of common.c * At boot read the DFS enable register and override the clk_ops to be used for dfs or non-dfs RCGs. * Remove flag 'dfs_enabled'. * Remove functions 'clk_rcg2_dfs_determine_rate_lazy' * Remove 'struct dfs_table *dfs_entry' * Remove '_freq_tbl_determine_dfs_rate' * Combine the function 'clk_index_pre_div_and_mode' and 'calculate_m_and_n' to a single function and named it 'clk_rcg2_calculate_m_and_n'. * Remove taking M/N/PERF offsets as function arguments. * Add clocks in gcc-sdm845.c the DFS clock array to register. [v1] * Update SPDX for files. * Add new clk_ops for DFS mode which would be used if dfs is enabled, else fall back to the clk_rcg2_shared_ops. * Use kcalloc in place kzalloc. * Fixed the return type for 'clk_parent_index_pre_div_and_mode' which is now renamed to 'clk_index_pre_div_and_mode'. * Removed return of -EPERM from 'clk_rcg2_set_rate' and new dfs clk_ops is introduced. * Pass frequency table entry structure to function calculate_m_and_n. * Remove desc from qcom_cc_register_rcg_dfs and instead pass array of clk_rcg2. * Add a dfs_enable flag to identify if dfs mode is enabled. In the cases where a RCG requires a Dynamic Frequency switch support requires to register which would at runtime read the clock perf level registers to identify the frequencies supported and update the frequency table accordingly. Taniya Das (2): clk: qcom: Add support for RCG to register for DFS clk: qcom: gcc: Register QUPv3 RCGs for DFS on SDM845 drivers/clk/qcom/clk-rcg.h| 2 + drivers/clk/qcom/clk-rcg2.c | 224 ++ drivers/clk/qcom/gcc-sdm845.c | 25 + 3 files changed, 251 insertions(+) -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v4 2/2] clk: qcom: gcc: Register QUPv3 RCGs for DFS on SDM845
QUPv3 clocks support DFS and thus register the RCGs which require support for the same. Signed-off-by: Taniya Das --- drivers/clk/qcom/gcc-sdm845.c | 25 + 1 file changed, 25 insertions(+) diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c index fa1a196..fef6732 100644 --- a/drivers/clk/qcom/gcc-sdm845.c +++ b/drivers/clk/qcom/gcc-sdm845.c @@ -3458,9 +3458,29 @@ enum { }; MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table); +static struct clk_rcg2 *gcc_dfs_clocks[] = { + _qupv3_wrap0_s0_clk_src, + _qupv3_wrap0_s1_clk_src, + _qupv3_wrap0_s2_clk_src, + _qupv3_wrap0_s3_clk_src, + _qupv3_wrap0_s4_clk_src, + _qupv3_wrap0_s5_clk_src, + _qupv3_wrap0_s6_clk_src, + _qupv3_wrap0_s7_clk_src, + _qupv3_wrap1_s0_clk_src, + _qupv3_wrap1_s1_clk_src, + _qupv3_wrap1_s2_clk_src, + _qupv3_wrap1_s3_clk_src, + _qupv3_wrap1_s4_clk_src, + _qupv3_wrap1_s5_clk_src, + _qupv3_wrap1_s6_clk_src, + _qupv3_wrap1_s7_clk_src, +}; + static int gcc_sdm845_probe(struct platform_device *pdev) { struct regmap *regmap; + int ret; regmap = qcom_cc_map(pdev, _sdm845_desc); if (IS_ERR(regmap)) @@ -3470,6 +3490,11 @@ static int gcc_sdm845_probe(struct platform_device *pdev) regmap_update_bits(regmap, 0x09ffc, 0x3, 0x3); regmap_update_bits(regmap, 0x71028, 0x3, 0x3); + ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, + ARRAY_SIZE(gcc_dfs_clocks)); + if (ret) + return ret; + return qcom_cc_really_probe(pdev, _sdm845_desc, regmap); } -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH v4 1/2] clk: qcom: Add support for RCG to register for DFS
Dynamic Frequency switch is a feature of clock controller by which request from peripherals allows automatic switching frequency of input clock without SW intervention. There are various performance levels associated with a root clock. When the input performance state changes, the source clocks and division ratios of the new performance state are loaded on to RCG via HW and the RCG switches to new clock frequency when the RCG is in DFS HW enabled mode. Register the root clock generators(RCG) to switch to use the dfs clock ops in the cases where DFS is enabled. The clk_round_rate() called by the clock consumer would invoke the dfs determine clock ops and would read the DFS performance level registers to identify all the frequencies supported and update the frequency table. The DFS clock consumers would maintain these frequency mapping and request the desired performance levels. Signed-off-by: Taniya Das --- drivers/clk/qcom/clk-rcg.h | 2 + drivers/clk/qcom/clk-rcg2.c | 224 2 files changed, 226 insertions(+) diff --git a/drivers/clk/qcom/clk-rcg.h b/drivers/clk/qcom/clk-rcg.h index dbd5a9e..e6300e0 100644 --- a/drivers/clk/qcom/clk-rcg.h +++ b/drivers/clk/qcom/clk-rcg.h @@ -163,4 +163,6 @@ struct clk_rcg2 { extern const struct clk_ops clk_gfx3d_ops; extern const struct clk_ops clk_rcg2_shared_ops; +extern int qcom_cc_register_rcg_dfs(struct regmap *regmap, +struct clk_rcg2 **rcgs, int num_clks); #endif diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index 52208d4..55a5b58 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -40,6 +41,14 @@ #define N_REG 0xc #define D_REG 0x10 +/* Dynamic Frequency Scaling */ +#define MAX_PERF_LEVEL 8 +#define SE_CMD_DFSR_OFFSET 0x14 +#define SE_CMD_DFS_EN BIT(0) +#define SE_PERF_DFSR(level)(0x1c + 0x4 * (level)) +#define SE_PERF_M_DFSR(level) (0x5c + 0x4 * (level)) +#define SE_PERF_N_DFSR(level) (0x9c + 0x4 * (level)) + enum freq_policy { FLOOR, CEIL, @@ -929,3 +938,218 @@ static void clk_rcg2_shared_disable(struct clk_hw *hw) .set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent, }; EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops); + +/* Common APIs to be used for DFS based RCGR */ +static unsigned long clk_rcg2_calculate_freq(struct clk_hw *hw, + int level, struct freq_tbl *f) +{ + struct clk_rcg2 *rcg = to_clk_rcg2(hw); + struct clk_hw *p; + unsigned long prate = 0; + u32 val, mask, cfg, m_off, n_off, offset, mode; + int i, ret, num_parents; + + offset = SE_PERF_DFSR(level); + ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + offset, ); + if (ret) + return ret; + + mask = BIT(rcg->hid_width) - 1; + f->pre_div = cfg & mask ? (cfg & mask) : 1; + + mode = cfg & CFG_MODE_MASK; + mode >>= CFG_MODE_SHIFT; + + cfg &= CFG_SRC_SEL_MASK; + cfg >>= CFG_SRC_SEL_SHIFT; + + num_parents = clk_hw_get_num_parents(hw); + for (i = 0; i < num_parents; i++) { + if (cfg == rcg->parent_map[i].cfg) { + f->src = rcg->parent_map[i].src; + p = clk_hw_get_parent_by_index(>clkr.hw, i); + prate = clk_hw_get_rate(p); + } + } + + if (mode) { + /* Calculate M & N values */ + m_off = SE_PERF_M_DFSR(level); + n_off = SE_PERF_N_DFSR(level); + + mask = BIT(rcg->mnd_width) - 1; + ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + m_off, + ); + if (ret) { + pr_err("Failed to read M offset register\n"); + return ret; + } + val &= mask; + f->m = val; + + ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + n_off, + ); + if (ret) { + pr_err("Failed to read N offset register\n"); + return ret; + } + /* val ~(N-M) */ + val = ~val; + val &= mask; + val += f->m; + f->n = val; + } + + return calc_rate(prate, f->m, f->n, mode, f->pre_div); +} + +static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg) +{ + struct freq_tbl *freq_tbl; + unsigned long calc_freq; + int i; + + freq_tbl = kcalloc(MAX_PERF_LEVEL, sizeof(*freq_tbl), + GFP_KERNEL); + if (!freq_tbl) + return -ENOMEM; + + for (i = 0; i < MAX_PERF_LEVEL; i++) { + calc_freq = clk_rcg2_calculate_freq(>clkr.hw, +
[PATCH v4 0/2] clk: qcom: Add support for RCG to register for DFS
[v4] * Add recalc_clk_ops to calculate the clock frequency reading the current perf state, also add CLK_GET_RATE_NOCACHE flag. * Cleanup 'goto' during mode check in 'clk_rcg2_calculate_freq'. * cleanup return from function 'com_cc_register_rcg_dfs'. [v3] * Rename clk_rcg2_calculate_m_and_n with clk_rcg2_calculate_freq, as this function would now calculate the frequency. * Rename dfs_freq_tbl to freq_tbl. * Remove the logic to remove duplicate frequencies. * Remove recalc_rate & set_rate clock ops. * clk_rcg2_dfs_ops clock ops is static. * Override the clock ops only if DFS mode is enabled. * qcom_cc_register_rcg_dfs uses regmap instead of device. * Few cleanups : Remove DFS probing after registering clocks. sizeof(*init), sizeof(*freq_tbl). [v2] * Move the dfs register function 'qcom_cc_register_rcg_dfs' to clk-rcg2.c instead of common.c * At boot read the DFS enable register and override the clk_ops to be used for dfs or non-dfs RCGs. * Remove flag 'dfs_enabled'. * Remove functions 'clk_rcg2_dfs_determine_rate_lazy' * Remove 'struct dfs_table *dfs_entry' * Remove '_freq_tbl_determine_dfs_rate' * Combine the function 'clk_index_pre_div_and_mode' and 'calculate_m_and_n' to a single function and named it 'clk_rcg2_calculate_m_and_n'. * Remove taking M/N/PERF offsets as function arguments. * Add clocks in gcc-sdm845.c the DFS clock array to register. [v1] * Update SPDX for files. * Add new clk_ops for DFS mode which would be used if dfs is enabled, else fall back to the clk_rcg2_shared_ops. * Use kcalloc in place kzalloc. * Fixed the return type for 'clk_parent_index_pre_div_and_mode' which is now renamed to 'clk_index_pre_div_and_mode'. * Removed return of -EPERM from 'clk_rcg2_set_rate' and new dfs clk_ops is introduced. * Pass frequency table entry structure to function calculate_m_and_n. * Remove desc from qcom_cc_register_rcg_dfs and instead pass array of clk_rcg2. * Add a dfs_enable flag to identify if dfs mode is enabled. In the cases where a RCG requires a Dynamic Frequency switch support requires to register which would at runtime read the clock perf level registers to identify the frequencies supported and update the frequency table accordingly. Taniya Das (2): clk: qcom: Add support for RCG to register for DFS clk: qcom: gcc: Register QUPv3 RCGs for DFS on SDM845 drivers/clk/qcom/clk-rcg.h| 2 + drivers/clk/qcom/clk-rcg2.c | 224 ++ drivers/clk/qcom/gcc-sdm845.c | 25 + 3 files changed, 251 insertions(+) -- Qualcomm INDIA, on behalf of Qualcomm Innovation Center, Inc.is a member of the Code Aurora Forum, hosted by the Linux Foundation.
[PATCH 3/5] serial: sprd: Remove unnecessary resource validation
The devm_ioremap_resource() will valid the resources, thus remove the unnecessary resource validation in the driver. Signed-off-by: Baolin Wang --- drivers/tty/serial/sprd_serial.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index e18d8af..03b0cd4 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -710,15 +710,12 @@ static int sprd_probe(struct platform_device *pdev) up->uartclk = clk_get_rate(clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(>dev, "not provide mem resource\n"); - return -ENODEV; - } - up->mapbase = res->start; up->membase = devm_ioremap_resource(>dev, res); if (IS_ERR(up->membase)) return PTR_ERR(up->membase); + up->mapbase = res->start; + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(>dev, "not provide irq resource: %d\n", irq); -- 1.9.1
[PATCH 2/5] serial: sprd: Use readable macros instead of magic number
Define readable macros instead of magic number to make code more readable. Signed-off-by: Baolin Wang --- drivers/tty/serial/sprd_serial.c | 25 + 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 1b0e3fb..e18d8af 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -45,6 +45,8 @@ /* data number in TX and RX fifo */ #define SPRD_STS1 0x000C +#define SPRD_RX_FIFO_CNT_MASK GENMASK(7, 0) +#define SPRD_TX_FIFO_CNT_MASK GENMASK(15, 8) /* interrupt enable register and its BITs */ #define SPRD_IEN 0x0010 @@ -82,11 +84,15 @@ /* fifo threshold register */ #define SPRD_CTL2 0x0020 #define THLD_TX_EMPTY 0x40 +#define THLD_TX_EMPTY_SHIFT8 #define THLD_RX_FULL 0x40 /* config baud rate register */ #define SPRD_CLKD0 0x0024 +#define SPRD_CLKD0_MASKGENMASK(15, 0) #define SPRD_CLKD1 0x0028 +#define SPRD_CLKD1_MASKGENMASK(20, 16) +#define SPRD_CLKD1_SHIFT 16 /* interrupt mask status register */ #define SPRD_IMSR 0x002C @@ -115,7 +121,7 @@ static inline void serial_out(struct uart_port *port, int offset, int value) static unsigned int sprd_tx_empty(struct uart_port *port) { - if (serial_in(port, SPRD_STS1) & 0xff00) + if (serial_in(port, SPRD_STS1) & SPRD_TX_FIFO_CNT_MASK) return 0; else return TIOCSER_TEMT; @@ -213,7 +219,8 @@ static inline void sprd_rx(struct uart_port *port) struct tty_port *tty = >state->port; unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT; - while ((serial_in(port, SPRD_STS1) & 0x00ff) && max_count--) { + while ((serial_in(port, SPRD_STS1) & SPRD_RX_FIFO_CNT_MASK) && + max_count--) { lsr = serial_in(port, SPRD_LSR); ch = serial_in(port, SPRD_RXD); flag = TTY_NORMAL; @@ -303,16 +310,17 @@ static int sprd_startup(struct uart_port *port) struct sprd_uart_port *sp; unsigned long flags; - serial_out(port, SPRD_CTL2, ((THLD_TX_EMPTY << 8) | THLD_RX_FULL)); + serial_out(port, SPRD_CTL2, + THLD_TX_EMPTY << THLD_TX_EMPTY_SHIFT | THLD_RX_FULL); /* clear rx fifo */ timeout = SPRD_TIMEOUT; - while (timeout-- && serial_in(port, SPRD_STS1) & 0x00ff) + while (timeout-- && serial_in(port, SPRD_STS1) & SPRD_RX_FIFO_CNT_MASK) serial_in(port, SPRD_RXD); /* clear tx fifo */ timeout = SPRD_TIMEOUT; - while (timeout-- && serial_in(port, SPRD_STS1) & 0xff00) + while (timeout-- && serial_in(port, SPRD_STS1) & SPRD_TX_FIFO_CNT_MASK) cpu_relax(); /* clear interrupt */ @@ -433,10 +441,11 @@ static void sprd_set_termios(struct uart_port *port, } /* clock divider bit0~bit15 */ - serial_out(port, SPRD_CLKD0, quot & 0x); + serial_out(port, SPRD_CLKD0, quot & SPRD_CLKD0_MASK); /* clock divider bit16~bit20 */ - serial_out(port, SPRD_CLKD1, (quot & 0x1f) >> 16); + serial_out(port, SPRD_CLKD1, + (quot & SPRD_CLKD1_MASK) >> SPRD_CLKD1_SHIFT); serial_out(port, SPRD_LCR, lcr); fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF; serial_out(port, SPRD_CTL1, fc); @@ -510,7 +519,7 @@ static void wait_for_xmitr(struct uart_port *port) if (--tmout == 0) break; udelay(1); - } while (status & 0xff00); + } while (status & SPRD_TX_FIFO_CNT_MASK); } static void sprd_console_putchar(struct uart_port *port, int ch) -- 1.9.1
[PATCH 3/5] serial: sprd: Remove unnecessary resource validation
The devm_ioremap_resource() will valid the resources, thus remove the unnecessary resource validation in the driver. Signed-off-by: Baolin Wang --- drivers/tty/serial/sprd_serial.c | 7 ++- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index e18d8af..03b0cd4 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -710,15 +710,12 @@ static int sprd_probe(struct platform_device *pdev) up->uartclk = clk_get_rate(clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(>dev, "not provide mem resource\n"); - return -ENODEV; - } - up->mapbase = res->start; up->membase = devm_ioremap_resource(>dev, res); if (IS_ERR(up->membase)) return PTR_ERR(up->membase); + up->mapbase = res->start; + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(>dev, "not provide irq resource: %d\n", irq); -- 1.9.1
[PATCH 2/5] serial: sprd: Use readable macros instead of magic number
Define readable macros instead of magic number to make code more readable. Signed-off-by: Baolin Wang --- drivers/tty/serial/sprd_serial.c | 25 + 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 1b0e3fb..e18d8af 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -45,6 +45,8 @@ /* data number in TX and RX fifo */ #define SPRD_STS1 0x000C +#define SPRD_RX_FIFO_CNT_MASK GENMASK(7, 0) +#define SPRD_TX_FIFO_CNT_MASK GENMASK(15, 8) /* interrupt enable register and its BITs */ #define SPRD_IEN 0x0010 @@ -82,11 +84,15 @@ /* fifo threshold register */ #define SPRD_CTL2 0x0020 #define THLD_TX_EMPTY 0x40 +#define THLD_TX_EMPTY_SHIFT8 #define THLD_RX_FULL 0x40 /* config baud rate register */ #define SPRD_CLKD0 0x0024 +#define SPRD_CLKD0_MASKGENMASK(15, 0) #define SPRD_CLKD1 0x0028 +#define SPRD_CLKD1_MASKGENMASK(20, 16) +#define SPRD_CLKD1_SHIFT 16 /* interrupt mask status register */ #define SPRD_IMSR 0x002C @@ -115,7 +121,7 @@ static inline void serial_out(struct uart_port *port, int offset, int value) static unsigned int sprd_tx_empty(struct uart_port *port) { - if (serial_in(port, SPRD_STS1) & 0xff00) + if (serial_in(port, SPRD_STS1) & SPRD_TX_FIFO_CNT_MASK) return 0; else return TIOCSER_TEMT; @@ -213,7 +219,8 @@ static inline void sprd_rx(struct uart_port *port) struct tty_port *tty = >state->port; unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT; - while ((serial_in(port, SPRD_STS1) & 0x00ff) && max_count--) { + while ((serial_in(port, SPRD_STS1) & SPRD_RX_FIFO_CNT_MASK) && + max_count--) { lsr = serial_in(port, SPRD_LSR); ch = serial_in(port, SPRD_RXD); flag = TTY_NORMAL; @@ -303,16 +310,17 @@ static int sprd_startup(struct uart_port *port) struct sprd_uart_port *sp; unsigned long flags; - serial_out(port, SPRD_CTL2, ((THLD_TX_EMPTY << 8) | THLD_RX_FULL)); + serial_out(port, SPRD_CTL2, + THLD_TX_EMPTY << THLD_TX_EMPTY_SHIFT | THLD_RX_FULL); /* clear rx fifo */ timeout = SPRD_TIMEOUT; - while (timeout-- && serial_in(port, SPRD_STS1) & 0x00ff) + while (timeout-- && serial_in(port, SPRD_STS1) & SPRD_RX_FIFO_CNT_MASK) serial_in(port, SPRD_RXD); /* clear tx fifo */ timeout = SPRD_TIMEOUT; - while (timeout-- && serial_in(port, SPRD_STS1) & 0xff00) + while (timeout-- && serial_in(port, SPRD_STS1) & SPRD_TX_FIFO_CNT_MASK) cpu_relax(); /* clear interrupt */ @@ -433,10 +441,11 @@ static void sprd_set_termios(struct uart_port *port, } /* clock divider bit0~bit15 */ - serial_out(port, SPRD_CLKD0, quot & 0x); + serial_out(port, SPRD_CLKD0, quot & SPRD_CLKD0_MASK); /* clock divider bit16~bit20 */ - serial_out(port, SPRD_CLKD1, (quot & 0x1f) >> 16); + serial_out(port, SPRD_CLKD1, + (quot & SPRD_CLKD1_MASK) >> SPRD_CLKD1_SHIFT); serial_out(port, SPRD_LCR, lcr); fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF; serial_out(port, SPRD_CTL1, fc); @@ -510,7 +519,7 @@ static void wait_for_xmitr(struct uart_port *port) if (--tmout == 0) break; udelay(1); - } while (status & 0xff00); + } while (status & SPRD_TX_FIFO_CNT_MASK); } static void sprd_console_putchar(struct uart_port *port, int ch) -- 1.9.1
[PATCH 5/5] serial: sprd: Fix the indentation issue
Make the macros' definition and code have the same correct indentation. Signed-off-by: Baolin Wang --- drivers/tty/serial/sprd_serial.c | 46 +++- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 8d5c9cd..4287ca3 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -68,24 +68,24 @@ #define SPRD_LCR_DATA_LEN6 0x4 #define SPRD_LCR_DATA_LEN7 0x8 #define SPRD_LCR_DATA_LEN8 0xc -#define SPRD_LCR_PARITY(BIT(0) | BIT(1)) +#define SPRD_LCR_PARITY(BIT(0) | BIT(1)) #define SPRD_LCR_PARITY_EN 0x2 #define SPRD_LCR_EVEN_PAR 0x0 #define SPRD_LCR_ODD_PAR 0x1 /* control register 1 */ -#define SPRD_CTL1 0x001C +#define SPRD_CTL1 0x001C #define RX_HW_FLOW_CTL_THLDBIT(6) #define RX_HW_FLOW_CTL_EN BIT(7) #define TX_HW_FLOW_CTL_EN BIT(8) #define RX_TOUT_THLD_DEF 0x3E00 -#define RX_HFC_THLD_DEF0x40 +#define RX_HFC_THLD_DEF0x40 /* fifo threshold register */ #define SPRD_CTL2 0x0020 -#define THLD_TX_EMPTY 0x40 +#define THLD_TX_EMPTY 0x40 #define THLD_TX_EMPTY_SHIFT8 -#define THLD_RX_FULL 0x40 +#define THLD_RX_FULL 0x40 /* config baud rate register */ #define SPRD_CLKD0 0x0024 @@ -95,11 +95,11 @@ #define SPRD_CLKD1_SHIFT 16 /* interrupt mask status register */ -#define SPRD_IMSR 0x002C -#define SPRD_IMSR_RX_FIFO_FULL BIT(0) +#define SPRD_IMSR 0x002C +#define SPRD_IMSR_RX_FIFO_FULL BIT(0) #define SPRD_IMSR_TX_FIFO_EMPTYBIT(1) -#define SPRD_IMSR_BREAK_DETECT BIT(7) -#define SPRD_IMSR_TIMEOUT BIT(13) +#define SPRD_IMSR_BREAK_DETECT BIT(7) +#define SPRD_IMSR_TIMEOUT BIT(13) struct sprd_uart_port { struct uart_port port; @@ -229,7 +229,7 @@ static inline void sprd_rx(struct uart_port *port) port->icount.rx++; if (lsr & (SPRD_LSR_BI | SPRD_LSR_PE | - SPRD_LSR_FE | SPRD_LSR_OE)) + SPRD_LSR_FE | SPRD_LSR_OE)) if (handle_lsr_errors(port, , )) continue; if (uart_handle_sysrq_char(port, ch)) @@ -292,8 +292,8 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) if (ims & SPRD_IMSR_TIMEOUT) serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT); - if (ims & (SPRD_IMSR_RX_FIFO_FULL | - SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) + if (ims & (SPRD_IMSR_RX_FIFO_FULL | SPRD_IMSR_BREAK_DETECT | + SPRD_IMSR_TIMEOUT)) sprd_rx(port); if (ims & SPRD_IMSR_TX_FIFO_EMPTY) @@ -333,7 +333,7 @@ static int sprd_startup(struct uart_port *port) sp = container_of(port, struct sprd_uart_port, port); snprintf(sp->name, sizeof(sp->name), "sprd_serial%d", port->line); ret = devm_request_irq(port->dev, port->irq, sprd_handle_irq, - IRQF_SHARED, sp->name, port); + IRQF_SHARED, sp->name, port); if (ret) { dev_err(port->dev, "fail to request serial irq %d, ret=%d\n", port->irq, ret); @@ -361,8 +361,8 @@ static void sprd_shutdown(struct uart_port *port) } static void sprd_set_termios(struct uart_port *port, - struct ktermios *termios, - struct ktermios *old) +struct ktermios *termios, +struct ktermios *old) { unsigned int baud, quot; unsigned int lcr = 0, fc; @@ -480,8 +480,7 @@ static void sprd_config_port(struct uart_port *port, int flags) port->type = PORT_SPRD; } -static int sprd_verify_port(struct uart_port *port, - struct serial_struct *ser) +static int sprd_verify_port(struct uart_port *port, struct serial_struct *ser) { if (ser->type != PORT_SPRD) return -EINVAL; @@ -531,7 +530,7 @@ static void sprd_console_putchar(struct uart_port *port, int ch) } static void sprd_console_write(struct console *co, const char *s, - unsigned int count) + unsigned int count) { struct uart_port *port = _port[co->index]->port; int locked = 1; @@ -594,7 +593,7 @@ static void sprd_putc(struct uart_port *port, int c) unsigned int timeout = SPRD_TIMEOUT; while (timeout-- && - !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER)) + !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER)) cpu_relax(); writeb(c, port->membase + SPRD_TXD); @@ -607,9 +606,8 @@ static void
[PATCH 1/5] serial: sprd: Remove unused structure
Remove the unused reg_backup structure. Signed-off-by: Baolin Wang --- drivers/tty/serial/sprd_serial.c | 11 --- 1 file changed, 11 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 828f114..1b0e3fb 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -95,19 +95,8 @@ #define SPRD_IMSR_BREAK_DETECT BIT(7) #define SPRD_IMSR_TIMEOUT BIT(13) -struct reg_backup { - u32 ien; - u32 ctrl0; - u32 ctrl1; - u32 ctrl2; - u32 clkd0; - u32 clkd1; - u32 dspwait; -}; - struct sprd_uart_port { struct uart_port port; - struct reg_backup reg_bak; char name[16]; }; -- 1.9.1
[PATCH 4/5] serial: sprd: Change 'int' to 'unsigned int'
The register offset value should be 'unsigned int' type. Moreover, prefer 'unsigned int' to bare use of 'unsigned'. Signed-off-by: Baolin Wang --- drivers/tty/serial/sprd_serial.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 03b0cd4..8d5c9cd 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -109,12 +109,14 @@ struct sprd_uart_port { static struct sprd_uart_port *sprd_port[UART_NR_MAX]; static int sprd_ports_num; -static inline unsigned int serial_in(struct uart_port *port, int offset) +static inline unsigned int serial_in(struct uart_port *port, +unsigned int offset) { return readl_relaxed(port->membase + offset); } -static inline void serial_out(struct uart_port *port, int offset, int value) +static inline void serial_out(struct uart_port *port, unsigned int offset, + int value) { writel_relaxed(value, port->membase + offset); } @@ -598,8 +600,7 @@ static void sprd_putc(struct uart_port *port, int c) writeb(c, port->membase + SPRD_TXD); } -static void sprd_early_write(struct console *con, const char *s, - unsigned n) +static void sprd_early_write(struct console *con, const char *s, unsigned int n) { struct earlycon_device *dev = con->data; -- 1.9.1
[PATCH 5/5] serial: sprd: Fix the indentation issue
Make the macros' definition and code have the same correct indentation. Signed-off-by: Baolin Wang --- drivers/tty/serial/sprd_serial.c | 46 +++- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 8d5c9cd..4287ca3 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -68,24 +68,24 @@ #define SPRD_LCR_DATA_LEN6 0x4 #define SPRD_LCR_DATA_LEN7 0x8 #define SPRD_LCR_DATA_LEN8 0xc -#define SPRD_LCR_PARITY(BIT(0) | BIT(1)) +#define SPRD_LCR_PARITY(BIT(0) | BIT(1)) #define SPRD_LCR_PARITY_EN 0x2 #define SPRD_LCR_EVEN_PAR 0x0 #define SPRD_LCR_ODD_PAR 0x1 /* control register 1 */ -#define SPRD_CTL1 0x001C +#define SPRD_CTL1 0x001C #define RX_HW_FLOW_CTL_THLDBIT(6) #define RX_HW_FLOW_CTL_EN BIT(7) #define TX_HW_FLOW_CTL_EN BIT(8) #define RX_TOUT_THLD_DEF 0x3E00 -#define RX_HFC_THLD_DEF0x40 +#define RX_HFC_THLD_DEF0x40 /* fifo threshold register */ #define SPRD_CTL2 0x0020 -#define THLD_TX_EMPTY 0x40 +#define THLD_TX_EMPTY 0x40 #define THLD_TX_EMPTY_SHIFT8 -#define THLD_RX_FULL 0x40 +#define THLD_RX_FULL 0x40 /* config baud rate register */ #define SPRD_CLKD0 0x0024 @@ -95,11 +95,11 @@ #define SPRD_CLKD1_SHIFT 16 /* interrupt mask status register */ -#define SPRD_IMSR 0x002C -#define SPRD_IMSR_RX_FIFO_FULL BIT(0) +#define SPRD_IMSR 0x002C +#define SPRD_IMSR_RX_FIFO_FULL BIT(0) #define SPRD_IMSR_TX_FIFO_EMPTYBIT(1) -#define SPRD_IMSR_BREAK_DETECT BIT(7) -#define SPRD_IMSR_TIMEOUT BIT(13) +#define SPRD_IMSR_BREAK_DETECT BIT(7) +#define SPRD_IMSR_TIMEOUT BIT(13) struct sprd_uart_port { struct uart_port port; @@ -229,7 +229,7 @@ static inline void sprd_rx(struct uart_port *port) port->icount.rx++; if (lsr & (SPRD_LSR_BI | SPRD_LSR_PE | - SPRD_LSR_FE | SPRD_LSR_OE)) + SPRD_LSR_FE | SPRD_LSR_OE)) if (handle_lsr_errors(port, , )) continue; if (uart_handle_sysrq_char(port, ch)) @@ -292,8 +292,8 @@ static irqreturn_t sprd_handle_irq(int irq, void *dev_id) if (ims & SPRD_IMSR_TIMEOUT) serial_out(port, SPRD_ICLR, SPRD_ICLR_TIMEOUT); - if (ims & (SPRD_IMSR_RX_FIFO_FULL | - SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT)) + if (ims & (SPRD_IMSR_RX_FIFO_FULL | SPRD_IMSR_BREAK_DETECT | + SPRD_IMSR_TIMEOUT)) sprd_rx(port); if (ims & SPRD_IMSR_TX_FIFO_EMPTY) @@ -333,7 +333,7 @@ static int sprd_startup(struct uart_port *port) sp = container_of(port, struct sprd_uart_port, port); snprintf(sp->name, sizeof(sp->name), "sprd_serial%d", port->line); ret = devm_request_irq(port->dev, port->irq, sprd_handle_irq, - IRQF_SHARED, sp->name, port); + IRQF_SHARED, sp->name, port); if (ret) { dev_err(port->dev, "fail to request serial irq %d, ret=%d\n", port->irq, ret); @@ -361,8 +361,8 @@ static void sprd_shutdown(struct uart_port *port) } static void sprd_set_termios(struct uart_port *port, - struct ktermios *termios, - struct ktermios *old) +struct ktermios *termios, +struct ktermios *old) { unsigned int baud, quot; unsigned int lcr = 0, fc; @@ -480,8 +480,7 @@ static void sprd_config_port(struct uart_port *port, int flags) port->type = PORT_SPRD; } -static int sprd_verify_port(struct uart_port *port, - struct serial_struct *ser) +static int sprd_verify_port(struct uart_port *port, struct serial_struct *ser) { if (ser->type != PORT_SPRD) return -EINVAL; @@ -531,7 +530,7 @@ static void sprd_console_putchar(struct uart_port *port, int ch) } static void sprd_console_write(struct console *co, const char *s, - unsigned int count) + unsigned int count) { struct uart_port *port = _port[co->index]->port; int locked = 1; @@ -594,7 +593,7 @@ static void sprd_putc(struct uart_port *port, int c) unsigned int timeout = SPRD_TIMEOUT; while (timeout-- && - !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER)) + !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER)) cpu_relax(); writeb(c, port->membase + SPRD_TXD); @@ -607,9 +606,8 @@ static void
[PATCH 1/5] serial: sprd: Remove unused structure
Remove the unused reg_backup structure. Signed-off-by: Baolin Wang --- drivers/tty/serial/sprd_serial.c | 11 --- 1 file changed, 11 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 828f114..1b0e3fb 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -95,19 +95,8 @@ #define SPRD_IMSR_BREAK_DETECT BIT(7) #define SPRD_IMSR_TIMEOUT BIT(13) -struct reg_backup { - u32 ien; - u32 ctrl0; - u32 ctrl1; - u32 ctrl2; - u32 clkd0; - u32 clkd1; - u32 dspwait; -}; - struct sprd_uart_port { struct uart_port port; - struct reg_backup reg_bak; char name[16]; }; -- 1.9.1
[PATCH 4/5] serial: sprd: Change 'int' to 'unsigned int'
The register offset value should be 'unsigned int' type. Moreover, prefer 'unsigned int' to bare use of 'unsigned'. Signed-off-by: Baolin Wang --- drivers/tty/serial/sprd_serial.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c index 03b0cd4..8d5c9cd 100644 --- a/drivers/tty/serial/sprd_serial.c +++ b/drivers/tty/serial/sprd_serial.c @@ -109,12 +109,14 @@ struct sprd_uart_port { static struct sprd_uart_port *sprd_port[UART_NR_MAX]; static int sprd_ports_num; -static inline unsigned int serial_in(struct uart_port *port, int offset) +static inline unsigned int serial_in(struct uart_port *port, +unsigned int offset) { return readl_relaxed(port->membase + offset); } -static inline void serial_out(struct uart_port *port, int offset, int value) +static inline void serial_out(struct uart_port *port, unsigned int offset, + int value) { writel_relaxed(value, port->membase + offset); } @@ -598,8 +600,7 @@ static void sprd_putc(struct uart_port *port, int c) writeb(c, port->membase + SPRD_TXD); } -static void sprd_early_write(struct console *con, const char *s, - unsigned n) +static void sprd_early_write(struct console *con, const char *s, unsigned int n) { struct earlycon_device *dev = con->data; -- 1.9.1
tools/include/asm-generic/bitsperlong.h:14:2: error: #error Inconsistent word size. Check asm/bitsperlong.h
Hi Alexei, FYI, the error/warning still remains. tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: f313b43be461f157755a57c1156f86abe10588de commit: 819dd92b9c0bc7bce9097d8c1f14240f471bb386 bpfilter: switch to CC from HOSTCC date: 9 weeks ago config: alpha-allyesconfig (attached as .config) compiler: alpha-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout 819dd92b9c0bc7bce9097d8c1f14240f471bb386 # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=alpha All errors (new ones prefixed by >>): In file included from tools/include/uapi/asm/bitsperlong.h:17:0, from /usr/alpha-linux-gnu/include/asm-generic/int-l64.h:11, from /usr/alpha-linux-gnu/include/asm/types.h:12, from tools/include/linux/types.h:10, from ./include/uapi/linux/bpf.h:11, from net/bpfilter/main.c:9: >> tools/include/asm-generic/bitsperlong.h:14:2: error: #error Inconsistent >> word size. Check asm/bitsperlong.h #error Inconsistent word size. Check asm/bitsperlong.h ^ vim +14 tools/include/asm-generic/bitsperlong.h bb970707 Arnaldo Carvalho de Melo 2016-07-12 12 2a00f026 Arnaldo Carvalho de Melo 2016-07-13 13 #if BITS_PER_LONG != __BITS_PER_LONG bb970707 Arnaldo Carvalho de Melo 2016-07-12 @14 #error Inconsistent word size. Check asm/bitsperlong.h bb970707 Arnaldo Carvalho de Melo 2016-07-12 15 #endif bb970707 Arnaldo Carvalho de Melo 2016-07-12 16 :: The code at line 14 was first introduced by commit :: bb9707077b4ee5f77bc9939b057ff8a0d410296f tools: Copy the bitsperlong.h files from the kernel :: TO: Arnaldo Carvalho de Melo :: CC: Arnaldo Carvalho de Melo --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
tools/include/asm-generic/bitsperlong.h:14:2: error: #error Inconsistent word size. Check asm/bitsperlong.h
Hi Alexei, FYI, the error/warning still remains. tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master head: f313b43be461f157755a57c1156f86abe10588de commit: 819dd92b9c0bc7bce9097d8c1f14240f471bb386 bpfilter: switch to CC from HOSTCC date: 9 weeks ago config: alpha-allyesconfig (attached as .config) compiler: alpha-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git checkout 819dd92b9c0bc7bce9097d8c1f14240f471bb386 # save the attached .config to linux build tree GCC_VERSION=7.2.0 make.cross ARCH=alpha All errors (new ones prefixed by >>): In file included from tools/include/uapi/asm/bitsperlong.h:17:0, from /usr/alpha-linux-gnu/include/asm-generic/int-l64.h:11, from /usr/alpha-linux-gnu/include/asm/types.h:12, from tools/include/linux/types.h:10, from ./include/uapi/linux/bpf.h:11, from net/bpfilter/main.c:9: >> tools/include/asm-generic/bitsperlong.h:14:2: error: #error Inconsistent >> word size. Check asm/bitsperlong.h #error Inconsistent word size. Check asm/bitsperlong.h ^ vim +14 tools/include/asm-generic/bitsperlong.h bb970707 Arnaldo Carvalho de Melo 2016-07-12 12 2a00f026 Arnaldo Carvalho de Melo 2016-07-13 13 #if BITS_PER_LONG != __BITS_PER_LONG bb970707 Arnaldo Carvalho de Melo 2016-07-12 @14 #error Inconsistent word size. Check asm/bitsperlong.h bb970707 Arnaldo Carvalho de Melo 2016-07-12 15 #endif bb970707 Arnaldo Carvalho de Melo 2016-07-12 16 :: The code at line 14 was first introduced by commit :: bb9707077b4ee5f77bc9939b057ff8a0d410296f tools: Copy the bitsperlong.h files from the kernel :: TO: Arnaldo Carvalho de Melo :: CC: Arnaldo Carvalho de Melo --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v1 3/4] drivers: edac: Add EDAC driver support for QCOM SoCs
On Fri, Aug 10, 2018 at 4:13 PM wrote: > > On 2018-08-10 10:23, Evan Green wrote: > > On Wed, Aug 1, 2018 at 1:34 PM Venkata Narendra Kumar Gutta > > wrote: > >> > >> From: Channagoud Kadabi > >> > >> Add error reporting driver for SBEs and DBEs. As of now, this driver > >> supports erp for Last Level Cache Controller (LLCC). This driver takes > >> care of dumping registers and adding config options to enable and > >> disable panic when the errors happen in cache. > >> > >> Co-developed-by: Venkata Narendra Kumar Gutta > >> > >> Signed-off-by: Venkata Narendra Kumar Gutta > >> Signed-off-by: Channagoud Kadabi > >> --- > >> MAINTAINERS | 7 + > >> drivers/edac/Kconfig | 28 +++ > >> drivers/edac/Makefile| 1 + > >> drivers/edac/qcom_edac.c | 507 > >> +++ > >> 4 files changed, 543 insertions(+) > >> create mode 100644 drivers/edac/qcom_edac.c > >> > > ... > >> diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c > >> new file mode 100644 > >> index 000..cf3e2b0 > >> --- /dev/null > >> +++ b/drivers/edac/qcom_edac.c > >> @@ -0,0 +1,507 @@ > >> +// SPDX-License-Identifier: GPL-2.0 > >> +/* > >> + * Copyright (c) 2018, The Linux Foundation. All rights reserved. > >> + */ > >> + > >> +#include > >> +#include > >> +#include > >> +#include > >> +#include > >> +#include > >> +#include > >> +#include > > > > Please alphabetize these includes, and remove any unneeded ones. > Ok, I'll update it in the next version. I didn't know that it's > mandatory to have in alphabetic order. > Is it recommended or a strict rule that we have includes in alphabetize > order? You know, I'm not actually sure if it's a strict rule. I'm still learning many of the conventions here myself. But it seems to get commented on consistently by reviewers, so it's in my bag of "things I look out for".
Re: [PATCH v1 3/4] drivers: edac: Add EDAC driver support for QCOM SoCs
On Fri, Aug 10, 2018 at 4:13 PM wrote: > > On 2018-08-10 10:23, Evan Green wrote: > > On Wed, Aug 1, 2018 at 1:34 PM Venkata Narendra Kumar Gutta > > wrote: > >> > >> From: Channagoud Kadabi > >> > >> Add error reporting driver for SBEs and DBEs. As of now, this driver > >> supports erp for Last Level Cache Controller (LLCC). This driver takes > >> care of dumping registers and adding config options to enable and > >> disable panic when the errors happen in cache. > >> > >> Co-developed-by: Venkata Narendra Kumar Gutta > >> > >> Signed-off-by: Venkata Narendra Kumar Gutta > >> Signed-off-by: Channagoud Kadabi > >> --- > >> MAINTAINERS | 7 + > >> drivers/edac/Kconfig | 28 +++ > >> drivers/edac/Makefile| 1 + > >> drivers/edac/qcom_edac.c | 507 > >> +++ > >> 4 files changed, 543 insertions(+) > >> create mode 100644 drivers/edac/qcom_edac.c > >> > > ... > >> diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c > >> new file mode 100644 > >> index 000..cf3e2b0 > >> --- /dev/null > >> +++ b/drivers/edac/qcom_edac.c > >> @@ -0,0 +1,507 @@ > >> +// SPDX-License-Identifier: GPL-2.0 > >> +/* > >> + * Copyright (c) 2018, The Linux Foundation. All rights reserved. > >> + */ > >> + > >> +#include > >> +#include > >> +#include > >> +#include > >> +#include > >> +#include > >> +#include > >> +#include > > > > Please alphabetize these includes, and remove any unneeded ones. > Ok, I'll update it in the next version. I didn't know that it's > mandatory to have in alphabetic order. > Is it recommended or a strict rule that we have includes in alphabetize > order? You know, I'm not actually sure if it's a strict rule. I'm still learning many of the conventions here myself. But it seems to get commented on consistently by reviewers, so it's in my bag of "things I look out for".
Re: [PATCH 3/3] arm64: dts: qcom: pm8998: Add die temperature channel node to the ADC
Hi, On Wed, Aug 8, 2018 at 12:13 PM, Matthias Kaehlcke wrote: > Add a channel node for the die temperature to the ADC. > > Signed-off-by: Matthias Kaehlcke > --- > arch/arm64/boot/dts/qcom/pm8998.dtsi | 5 + > 1 file changed, 5 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi > b/arch/arm64/boot/dts/qcom/pm8998.dtsi > index f70f6101bceb..499bae0afb7f 100644 > --- a/arch/arm64/boot/dts/qcom/pm8998.dtsi > +++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi > @@ -20,6 +20,11 @@ > #size-cells = <0>; > #io-channel-cells = <1>; > io-channel-ranges; > + > + die-temp { > + reg = ; > + label = "die_temp"; > + }; Seems to match the binding. I'm no expert, but FWIW: Reviewed-by: Douglas Anderson
Re: [PATCH 3/3] arm64: dts: qcom: pm8998: Add die temperature channel node to the ADC
Hi, On Wed, Aug 8, 2018 at 12:13 PM, Matthias Kaehlcke wrote: > Add a channel node for the die temperature to the ADC. > > Signed-off-by: Matthias Kaehlcke > --- > arch/arm64/boot/dts/qcom/pm8998.dtsi | 5 + > 1 file changed, 5 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi > b/arch/arm64/boot/dts/qcom/pm8998.dtsi > index f70f6101bceb..499bae0afb7f 100644 > --- a/arch/arm64/boot/dts/qcom/pm8998.dtsi > +++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi > @@ -20,6 +20,11 @@ > #size-cells = <0>; > #io-channel-cells = <1>; > io-channel-ranges; > + > + die-temp { > + reg = ; > + label = "die_temp"; > + }; Seems to match the binding. I'm no expert, but FWIW: Reviewed-by: Douglas Anderson
Re: [PATCH 2/3] arm64: dts: qcom: pm8998: Add adc node
Hi, On Wed, Aug 8, 2018 at 12:13 PM, Matthias Kaehlcke wrote: > This adds the adc node to pm8998 based on the examples in the > bindings. It also fixes the order of the included headers. > > Signed-off-by: Matthias Kaehlcke > --- > arch/arm64/boot/dts/qcom/pm8998.dtsi | 13 - > 1 file changed, 12 insertions(+), 1 deletion(-) > > diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi > b/arch/arm64/boot/dts/qcom/pm8998.dtsi > index 92bed1e7d4bb..f70f6101bceb 100644 > --- a/arch/arm64/boot/dts/qcom/pm8998.dtsi > +++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi > @@ -1,8 +1,9 @@ > // SPDX-License-Identifier: (GPL-2.0+ OR MIT) > /* Copyright 2018 Google LLC. */ > > -#include > +#include > #include > +#include > > _bus { > pm8998_lsid0: pmic@0 { > @@ -11,6 +12,16 @@ > #address-cells = <1>; > #size-cells = <0>; > > + pm8998_adc: adc@3100 { > + compatible = "qcom,spmi-adc-rev2"; > + reg = <0x3100>; > + interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; > + #address-cells = <1>; > + #size-cells = <0>; > + #io-channel-cells = <1>; > + io-channel-ranges; > + }; I'm a little confused about what the "io-channel-ranges" does here. The documentation isn't clear at all to me for it. If I'm reading it right it's also supposed to be for iio-consumers, but you're using it in a provider. I see you copied this from the example. Maybe the example is wrong? ...or I'm just confused... Other than that question, this looks fine to me. -Doug
Re: [PATCH 2/3] arm64: dts: qcom: pm8998: Add adc node
Hi, On Wed, Aug 8, 2018 at 12:13 PM, Matthias Kaehlcke wrote: > This adds the adc node to pm8998 based on the examples in the > bindings. It also fixes the order of the included headers. > > Signed-off-by: Matthias Kaehlcke > --- > arch/arm64/boot/dts/qcom/pm8998.dtsi | 13 - > 1 file changed, 12 insertions(+), 1 deletion(-) > > diff --git a/arch/arm64/boot/dts/qcom/pm8998.dtsi > b/arch/arm64/boot/dts/qcom/pm8998.dtsi > index 92bed1e7d4bb..f70f6101bceb 100644 > --- a/arch/arm64/boot/dts/qcom/pm8998.dtsi > +++ b/arch/arm64/boot/dts/qcom/pm8998.dtsi > @@ -1,8 +1,9 @@ > // SPDX-License-Identifier: (GPL-2.0+ OR MIT) > /* Copyright 2018 Google LLC. */ > > -#include > +#include > #include > +#include > > _bus { > pm8998_lsid0: pmic@0 { > @@ -11,6 +12,16 @@ > #address-cells = <1>; > #size-cells = <0>; > > + pm8998_adc: adc@3100 { > + compatible = "qcom,spmi-adc-rev2"; > + reg = <0x3100>; > + interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; > + #address-cells = <1>; > + #size-cells = <0>; > + #io-channel-cells = <1>; > + io-channel-ranges; > + }; I'm a little confused about what the "io-channel-ranges" does here. The documentation isn't clear at all to me for it. If I'm reading it right it's also supposed to be for iio-consumers, but you're using it in a provider. I see you copied this from the example. Maybe the example is wrong? ...or I'm just confused... Other than that question, this looks fine to me. -Doug
Re: [PATCH v3 7/7] firmware: coreboot: Request table region for exclusive access
Quoting Stephen Boyd (2018-08-09 19:54:27) > What's with the top posting? ;-) > > Quoting Julius Werner (2018-08-09 16:44:43) > > Actually, looking at what IO_STRICT_DEVMEM really does, would it > > really prevent userspace accesses to these areas? Because it seems > > that it only prevents accesses to areas marked as IORESOURCE_BUSY, and > > while I can't fully follow how the kernel assigns that, comments > > suggest that this is only set when "Driver has marked this resource > > busy". > > Requesting the memory region as is done in this patch marks it as busy. > > > > > So after you make the change to the other patch where we immediately > > unmap the coreboot table again at the end of the probe() function, > > shouldn't it become available to userspace again even with > > IO_STRICT_DEVMEM set? > > Yes, if we unmap the region immediately after devices are populated then > this whole point is moot with the assumption that this code isn't > running at the same time as the cbmem utility. I've done this already > and it is working on arm. I still need to build/boot/test on an x86 > platform which I should be able to do tomorrow. > I tried my latest version of the patches (unplubished so far) and those work on x86 with cbmem. So things look good and we don't need to keep the mapping around.
Re: [PATCH v3 7/7] firmware: coreboot: Request table region for exclusive access
Quoting Stephen Boyd (2018-08-09 19:54:27) > What's with the top posting? ;-) > > Quoting Julius Werner (2018-08-09 16:44:43) > > Actually, looking at what IO_STRICT_DEVMEM really does, would it > > really prevent userspace accesses to these areas? Because it seems > > that it only prevents accesses to areas marked as IORESOURCE_BUSY, and > > while I can't fully follow how the kernel assigns that, comments > > suggest that this is only set when "Driver has marked this resource > > busy". > > Requesting the memory region as is done in this patch marks it as busy. > > > > > So after you make the change to the other patch where we immediately > > unmap the coreboot table again at the end of the probe() function, > > shouldn't it become available to userspace again even with > > IO_STRICT_DEVMEM set? > > Yes, if we unmap the region immediately after devices are populated then > this whole point is moot with the assumption that this code isn't > running at the same time as the cbmem utility. I've done this already > and it is working on arm. I still need to build/boot/test on an x86 > platform which I should be able to do tomorrow. > I tried my latest version of the patches (unplubished so far) and those work on x86 with cbmem. So things look good and we don't need to keep the mapping around.
Re: [PATCH v3] checkpatch: DT bindings should be a separate patch
On Fri, 2018-08-10 at 16:50 -0600, Rob Herring wrote: > Devicetree bindings should be their own patch as documented in > Documentation/devicetree/bindings/submitting-patches.txt section I.1. > This is because bindings are logically independent from a driver > implementation, they have a different maintainer (even though they often > are applied via the same tree), and it makes for a cleaner history in > the DT only tree created with git-filter-branch. Thanks Rob. Acked-by: Joe Perches
Re: [PATCH v3] checkpatch: DT bindings should be a separate patch
On Fri, 2018-08-10 at 16:50 -0600, Rob Herring wrote: > Devicetree bindings should be their own patch as documented in > Documentation/devicetree/bindings/submitting-patches.txt section I.1. > This is because bindings are logically independent from a driver > implementation, they have a different maintainer (even though they often > are applied via the same tree), and it makes for a cleaner history in > the DT only tree created with git-filter-branch. Thanks Rob. Acked-by: Joe Perches
Re: [PATCH v1 3/4] drivers: edac: Add EDAC driver support for QCOM SoCs
On 2018-08-10 10:23, Evan Green wrote: On Wed, Aug 1, 2018 at 1:34 PM Venkata Narendra Kumar Gutta wrote: From: Channagoud Kadabi Add error reporting driver for SBEs and DBEs. As of now, this driver supports erp for Last Level Cache Controller (LLCC). This driver takes care of dumping registers and adding config options to enable and disable panic when the errors happen in cache. Co-developed-by: Venkata Narendra Kumar Gutta Signed-off-by: Venkata Narendra Kumar Gutta Signed-off-by: Channagoud Kadabi --- MAINTAINERS | 7 + drivers/edac/Kconfig | 28 +++ drivers/edac/Makefile| 1 + drivers/edac/qcom_edac.c | 507 +++ 4 files changed, 543 insertions(+) create mode 100644 drivers/edac/qcom_edac.c ... diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c new file mode 100644 index 000..cf3e2b0 --- /dev/null +++ b/drivers/edac/qcom_edac.c @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include Please alphabetize these includes, and remove any unneeded ones. Ok, I'll update it in the next version. I didn't know that it's mandatory to have in alphabetic order. Is it recommended or a strict rule that we have includes in alphabetize order? +#include "edac_mc.h" +#include "edac_device.h" + +#ifdef CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE +#define LLCC_ERP_PANIC_ON_UE1 +#else +#define LLCC_ERP_PANIC_ON_UE0 +#endif + +#define EDAC_LLCC "qcom_llcc" + +#define TRP_SYN_REG_CNT 6 + +#define DRP_SYN_REG_CNT 8 + +#define LLCC_COMMON_STATUS0 0x0003000C +#define LLCC_LB_CNT_MASKGENMASK(31, 28) +#define LLCC_LB_CNT_SHIFT 28 + +/* single & Double Bit syndrome register offsets */ +#define TRP_ECC_SB_ERR_SYN0 0x0002304C +#define TRP_ECC_DB_ERR_SYN0 0x00020370 +#define DRP_ECC_SB_ERR_SYN0 0x0004204C +#define DRP_ECC_DB_ERR_SYN0 0x00042070 + +/* Error register offsets */ +#define TRP_ECC_ERROR_STATUS1 0x00020348 +#define TRP_ECC_ERROR_STATUS0 0x00020344 +#define DRP_ECC_ERROR_STATUS1 0x00042048 +#define DRP_ECC_ERROR_STATUS0 0x00042044 + +/* TRP, DRP interrupt register offsets */ +#define DRP_INTERRUPT_STATUS0x00041000 +#define TRP_INTERRUPT_0_STATUS 0x00020480 +#define DRP_INTERRUPT_CLEAR 0x00041008 +#define DRP_ECC_ERROR_CNTR_CLEAR0x00040004 +#define TRP_INTERRUPT_0_CLEAR 0x00020484 +#define TRP_ECC_ERROR_CNTR_CLEAR0x00020440 + +/* Mask and shift macros */ +#define ECC_DB_ERR_COUNT_MASK GENMASK(4, 0) +#define ECC_DB_ERR_WAYS_MASKGENMASK(31, 16) +#define ECC_DB_ERR_WAYS_SHIFT BIT(4) + +#define ECC_SB_ERR_COUNT_MASK GENMASK(23, 16) +#define ECC_SB_ERR_COUNT_SHIFT BIT(4) +#define ECC_SB_ERR_WAYS_MASKGENMASK(15, 0) + +#define SB_ECC_ERRORBIT(0) +#define DB_ECC_ERRORBIT(1) + +#define DRP_TRP_INT_CLEAR GENMASK(1, 0) +#define DRP_TRP_CNT_CLEAR GENMASK(1, 0) + +/* Config registers offsets*/ +#define DRP_ECC_ERROR_CFG 0x0004 + +/* TRP, DRP interrupt register offsets */ +#define CMN_INTERRUPT_0_ENABLE 0x0003001C +#define CMN_INTERRUPT_2_ENABLE 0x0003003C +#define TRP_INTERRUPT_0_ENABLE 0x00020488 +#define DRP_INTERRUPT_ENABLE0x0004100C + +#define SB_ERROR_THRESHOLD 0x1 +#define SB_ERROR_THRESHOLD_SHIFT24 +#define SB_DB_TRP_INTERRUPT_ENABLE 0x3 +#define TRP0_INTERRUPT_ENABLE 0x1 +#define DRP0_INTERRUPT_ENABLE BIT(6) +#define SB_DB_DRP_INTERRUPT_ENABLE 0x3 + + +enum { + LLCC_DRAM_CE = 0, + LLCC_DRAM_UE, + LLCC_TRAM_CE, + LLCC_TRAM_UE, +}; + +struct errors_edac { + const char *msg; + void (*func)(struct edac_device_ctl_info *edev_ctl, + int inst_nr, int block_nr, const char *msg); +}; + +static const struct errors_edac errors[] = { + {"LLCC Data RAM correctable Error", edac_device_handle_ce}, + {"LLCC Data RAM uncorrectable Error", edac_device_handle_ue}, + {"LLCC Tag RAM correctable Error", edac_device_handle_ce}, + {"LLCC Tag RAM uncorrectable Error", edac_device_handle_ue}, +}; + +static int qcom_llcc_core_setup(struct regmap *llcc_bcast_regmap) +{ + u32 sb_err_threshold; + int ret; + + /* Enable TRP in instance 2 of common interrupt enable register */ + ret = regmap_update_bits(llcc_bcast_regmap, CMN_INTERRUPT_2_ENABLE, +TRP0_INTERRUPT_ENABLE, +TRP0_INTERRUPT_ENABLE); + if (ret) +
Re: [PATCH v1 3/4] drivers: edac: Add EDAC driver support for QCOM SoCs
On 2018-08-10 10:23, Evan Green wrote: On Wed, Aug 1, 2018 at 1:34 PM Venkata Narendra Kumar Gutta wrote: From: Channagoud Kadabi Add error reporting driver for SBEs and DBEs. As of now, this driver supports erp for Last Level Cache Controller (LLCC). This driver takes care of dumping registers and adding config options to enable and disable panic when the errors happen in cache. Co-developed-by: Venkata Narendra Kumar Gutta Signed-off-by: Venkata Narendra Kumar Gutta Signed-off-by: Channagoud Kadabi --- MAINTAINERS | 7 + drivers/edac/Kconfig | 28 +++ drivers/edac/Makefile| 1 + drivers/edac/qcom_edac.c | 507 +++ 4 files changed, 543 insertions(+) create mode 100644 drivers/edac/qcom_edac.c ... diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c new file mode 100644 index 000..cf3e2b0 --- /dev/null +++ b/drivers/edac/qcom_edac.c @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include Please alphabetize these includes, and remove any unneeded ones. Ok, I'll update it in the next version. I didn't know that it's mandatory to have in alphabetic order. Is it recommended or a strict rule that we have includes in alphabetize order? +#include "edac_mc.h" +#include "edac_device.h" + +#ifdef CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE +#define LLCC_ERP_PANIC_ON_UE1 +#else +#define LLCC_ERP_PANIC_ON_UE0 +#endif + +#define EDAC_LLCC "qcom_llcc" + +#define TRP_SYN_REG_CNT 6 + +#define DRP_SYN_REG_CNT 8 + +#define LLCC_COMMON_STATUS0 0x0003000C +#define LLCC_LB_CNT_MASKGENMASK(31, 28) +#define LLCC_LB_CNT_SHIFT 28 + +/* single & Double Bit syndrome register offsets */ +#define TRP_ECC_SB_ERR_SYN0 0x0002304C +#define TRP_ECC_DB_ERR_SYN0 0x00020370 +#define DRP_ECC_SB_ERR_SYN0 0x0004204C +#define DRP_ECC_DB_ERR_SYN0 0x00042070 + +/* Error register offsets */ +#define TRP_ECC_ERROR_STATUS1 0x00020348 +#define TRP_ECC_ERROR_STATUS0 0x00020344 +#define DRP_ECC_ERROR_STATUS1 0x00042048 +#define DRP_ECC_ERROR_STATUS0 0x00042044 + +/* TRP, DRP interrupt register offsets */ +#define DRP_INTERRUPT_STATUS0x00041000 +#define TRP_INTERRUPT_0_STATUS 0x00020480 +#define DRP_INTERRUPT_CLEAR 0x00041008 +#define DRP_ECC_ERROR_CNTR_CLEAR0x00040004 +#define TRP_INTERRUPT_0_CLEAR 0x00020484 +#define TRP_ECC_ERROR_CNTR_CLEAR0x00020440 + +/* Mask and shift macros */ +#define ECC_DB_ERR_COUNT_MASK GENMASK(4, 0) +#define ECC_DB_ERR_WAYS_MASKGENMASK(31, 16) +#define ECC_DB_ERR_WAYS_SHIFT BIT(4) + +#define ECC_SB_ERR_COUNT_MASK GENMASK(23, 16) +#define ECC_SB_ERR_COUNT_SHIFT BIT(4) +#define ECC_SB_ERR_WAYS_MASKGENMASK(15, 0) + +#define SB_ECC_ERRORBIT(0) +#define DB_ECC_ERRORBIT(1) + +#define DRP_TRP_INT_CLEAR GENMASK(1, 0) +#define DRP_TRP_CNT_CLEAR GENMASK(1, 0) + +/* Config registers offsets*/ +#define DRP_ECC_ERROR_CFG 0x0004 + +/* TRP, DRP interrupt register offsets */ +#define CMN_INTERRUPT_0_ENABLE 0x0003001C +#define CMN_INTERRUPT_2_ENABLE 0x0003003C +#define TRP_INTERRUPT_0_ENABLE 0x00020488 +#define DRP_INTERRUPT_ENABLE0x0004100C + +#define SB_ERROR_THRESHOLD 0x1 +#define SB_ERROR_THRESHOLD_SHIFT24 +#define SB_DB_TRP_INTERRUPT_ENABLE 0x3 +#define TRP0_INTERRUPT_ENABLE 0x1 +#define DRP0_INTERRUPT_ENABLE BIT(6) +#define SB_DB_DRP_INTERRUPT_ENABLE 0x3 + + +enum { + LLCC_DRAM_CE = 0, + LLCC_DRAM_UE, + LLCC_TRAM_CE, + LLCC_TRAM_UE, +}; + +struct errors_edac { + const char *msg; + void (*func)(struct edac_device_ctl_info *edev_ctl, + int inst_nr, int block_nr, const char *msg); +}; + +static const struct errors_edac errors[] = { + {"LLCC Data RAM correctable Error", edac_device_handle_ce}, + {"LLCC Data RAM uncorrectable Error", edac_device_handle_ue}, + {"LLCC Tag RAM correctable Error", edac_device_handle_ce}, + {"LLCC Tag RAM uncorrectable Error", edac_device_handle_ue}, +}; + +static int qcom_llcc_core_setup(struct regmap *llcc_bcast_regmap) +{ + u32 sb_err_threshold; + int ret; + + /* Enable TRP in instance 2 of common interrupt enable register */ + ret = regmap_update_bits(llcc_bcast_regmap, CMN_INTERRUPT_2_ENABLE, +TRP0_INTERRUPT_ENABLE, +TRP0_INTERRUPT_ENABLE); + if (ret) +
[PATCH 2/5] vmbus: add driver_override support
From: Stephen Hemminger Add support for overriding the default driver for a VMBus device in the same way that it can be done for PCI devices. This patch adds the /sys/bus/vmbus/devices/.../driver_override file and the logic for matching. This is used by driverctl tool to do driver override. https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.com%2Fdriverctl%2Fdriverctldata=02%7C01%7Ckys%40microsoft.com%7C42e803feb2c544ef6ea908d5fd538878%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636693457619960040sdata=kEyYHRIjNZCk%2B37moCSqbrZL426YccNQrsWpENcrZdw%3Dreserved=0 Signed-off-by: Stephen Hemminger Signed-off-by: K. Y. Srinivasan --- Documentation/ABI/testing/sysfs-bus-vmbus | 21 drivers/hv/vmbus_drv.c| 115 ++ include/linux/hyperv.h| 1 + 3 files changed, 118 insertions(+), 19 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-vmbus diff --git a/Documentation/ABI/testing/sysfs-bus-vmbus b/Documentation/ABI/testing/sysfs-bus-vmbus new file mode 100644 index ..91e6c065973c --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-vmbus @@ -0,0 +1,21 @@ +What: /sys/bus/vmbus/devices/.../driver_override +Date: August 2019 +Contact: Stephen Hemminger +Description: + This file allows the driver for a device to be specified which + will override standard static and dynamic ID matching. When + specified, only a driver with a name matching the value written + to driver_override will have an opportunity to bind to the + device. The override is specified by writing a string to the + driver_override file (echo uio_hv_generic > driver_override) and + may be cleared with an empty string (echo > driver_override). + This returns the device to standard matching rules binding. + Writing to driver_override does not automatically unbind the + device from its current driver or make any attempt to + automatically load the specified driver. If no driver with a + matching name is currently loaded in the kernel, the device + will not bind to any driver. This also allows devices to + opt-out of driver binding using a driver_override name such as + "none". Only a single driver may be specified in the override, + there is no support for parsing delimiters. + diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index b1b548a21f91..e6d8fdac6d8b 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -498,6 +498,54 @@ static ssize_t device_show(struct device *dev, } static DEVICE_ATTR_RO(device); +static ssize_t driver_override_store(struct device *dev, +struct device_attribute *attr, +const char *buf, size_t count) +{ + struct hv_device *hv_dev = device_to_hv_device(dev); + char *driver_override, *old, *cp; + + /* We need to keep extra room for a newline */ + if (count >= (PAGE_SIZE - 1)) + return -EINVAL; + + driver_override = kstrndup(buf, count, GFP_KERNEL); + if (!driver_override) + return -ENOMEM; + + cp = strchr(driver_override, '\n'); + if (cp) + *cp = '\0'; + + device_lock(dev); + old = hv_dev->driver_override; + if (strlen(driver_override)) { + hv_dev->driver_override = driver_override; + } else { + kfree(driver_override); + hv_dev->driver_override = NULL; + } + device_unlock(dev); + + kfree(old); + + return count; +} + +static ssize_t driver_override_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hv_device *hv_dev = device_to_hv_device(dev); + ssize_t len; + + device_lock(dev); + len = snprintf(buf, PAGE_SIZE, "%s\n", hv_dev->driver_override); + device_unlock(dev); + + return len; +} +static DEVICE_ATTR_RW(driver_override); + /* Set up per device attributes in /sys/bus/vmbus/devices/ */ static struct attribute *vmbus_dev_attrs[] = { _attr_id.attr, @@ -528,6 +576,7 @@ static struct attribute *vmbus_dev_attrs[] = { _attr_channel_vp_mapping.attr, _attr_vendor.attr, _attr_device.attr, + _attr_driver_override.attr, NULL, }; ATTRIBUTE_GROUPS(vmbus_dev); @@ -563,17 +612,26 @@ static inline bool is_null_guid(const uuid_le *guid) return true; } -/* - * Return a matching hv_vmbus_device_id pointer. - * If there is no match, return NULL. - */ -static const struct hv_vmbus_device_id *hv_vmbus_get_id(struct hv_driver *drv, - const uuid_le *guid) +static const struct hv_vmbus_device_id *
[PATCH 2/5] vmbus: add driver_override support
From: Stephen Hemminger Add support for overriding the default driver for a VMBus device in the same way that it can be done for PCI devices. This patch adds the /sys/bus/vmbus/devices/.../driver_override file and the logic for matching. This is used by driverctl tool to do driver override. https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.com%2Fdriverctl%2Fdriverctldata=02%7C01%7Ckys%40microsoft.com%7C42e803feb2c544ef6ea908d5fd538878%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636693457619960040sdata=kEyYHRIjNZCk%2B37moCSqbrZL426YccNQrsWpENcrZdw%3Dreserved=0 Signed-off-by: Stephen Hemminger Signed-off-by: K. Y. Srinivasan --- Documentation/ABI/testing/sysfs-bus-vmbus | 21 drivers/hv/vmbus_drv.c| 115 ++ include/linux/hyperv.h| 1 + 3 files changed, 118 insertions(+), 19 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-vmbus diff --git a/Documentation/ABI/testing/sysfs-bus-vmbus b/Documentation/ABI/testing/sysfs-bus-vmbus new file mode 100644 index ..91e6c065973c --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-vmbus @@ -0,0 +1,21 @@ +What: /sys/bus/vmbus/devices/.../driver_override +Date: August 2019 +Contact: Stephen Hemminger +Description: + This file allows the driver for a device to be specified which + will override standard static and dynamic ID matching. When + specified, only a driver with a name matching the value written + to driver_override will have an opportunity to bind to the + device. The override is specified by writing a string to the + driver_override file (echo uio_hv_generic > driver_override) and + may be cleared with an empty string (echo > driver_override). + This returns the device to standard matching rules binding. + Writing to driver_override does not automatically unbind the + device from its current driver or make any attempt to + automatically load the specified driver. If no driver with a + matching name is currently loaded in the kernel, the device + will not bind to any driver. This also allows devices to + opt-out of driver binding using a driver_override name such as + "none". Only a single driver may be specified in the override, + there is no support for parsing delimiters. + diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index b1b548a21f91..e6d8fdac6d8b 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -498,6 +498,54 @@ static ssize_t device_show(struct device *dev, } static DEVICE_ATTR_RO(device); +static ssize_t driver_override_store(struct device *dev, +struct device_attribute *attr, +const char *buf, size_t count) +{ + struct hv_device *hv_dev = device_to_hv_device(dev); + char *driver_override, *old, *cp; + + /* We need to keep extra room for a newline */ + if (count >= (PAGE_SIZE - 1)) + return -EINVAL; + + driver_override = kstrndup(buf, count, GFP_KERNEL); + if (!driver_override) + return -ENOMEM; + + cp = strchr(driver_override, '\n'); + if (cp) + *cp = '\0'; + + device_lock(dev); + old = hv_dev->driver_override; + if (strlen(driver_override)) { + hv_dev->driver_override = driver_override; + } else { + kfree(driver_override); + hv_dev->driver_override = NULL; + } + device_unlock(dev); + + kfree(old); + + return count; +} + +static ssize_t driver_override_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hv_device *hv_dev = device_to_hv_device(dev); + ssize_t len; + + device_lock(dev); + len = snprintf(buf, PAGE_SIZE, "%s\n", hv_dev->driver_override); + device_unlock(dev); + + return len; +} +static DEVICE_ATTR_RW(driver_override); + /* Set up per device attributes in /sys/bus/vmbus/devices/ */ static struct attribute *vmbus_dev_attrs[] = { _attr_id.attr, @@ -528,6 +576,7 @@ static struct attribute *vmbus_dev_attrs[] = { _attr_channel_vp_mapping.attr, _attr_vendor.attr, _attr_device.attr, + _attr_driver_override.attr, NULL, }; ATTRIBUTE_GROUPS(vmbus_dev); @@ -563,17 +612,26 @@ static inline bool is_null_guid(const uuid_le *guid) return true; } -/* - * Return a matching hv_vmbus_device_id pointer. - * If there is no match, return NULL. - */ -static const struct hv_vmbus_device_id *hv_vmbus_get_id(struct hv_driver *drv, - const uuid_le *guid) +static const struct hv_vmbus_device_id *
[PATCH 1/5] Tools: hv: Fix a bug in the key delete code
From: "K. Y. Srinivasan" Fix a bug in the key delete code - the num_records range from 0 to num_records-1. Signed-off-by: K. Y. Srinivasan Reported-by: David Binderman Cc: --- tools/hv/hv_kvp_daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index dbf6e8bd98ba..bbb2a8ef367c 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -286,7 +286,7 @@ static int kvp_key_delete(int pool, const __u8 *key, int key_size) * Found a match; just move the remaining * entries up. */ - if (i == num_records) { + if (i == (num_records - 1)) { kvp_file_info[pool].num_records--; kvp_update_file(pool); return 0; -- 2.18.0
[PATCH 4/5] uio_hv_generic: drop #ifdef DEBUG
From: Stephen Hemminger DEBUG is leftover from the development phase, remove it. Signed-off-by: Stephen Hemminger Signed-off-by: K. Y. Srinivasan --- drivers/uio/uio_hv_generic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index 35678d08d9d8..ab0c0e7e8a44 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -19,7 +19,6 @@ * # echo -n "ed963694-e847-4b2a-85af-bc9cfc11d6f3" \ *> /sys/bus/vmbus/drivers/uio_hv_generic/bind */ -#define DEBUG 1 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -- 2.18.0
[PATCH 3/5] uio_hv_generic: increase size of receive and send buffers
From: Stephen Hemminger When using DPDK there is significant performance boost by using the largest possible send and receive buffer area. Unfortunately, with UIO model there is not a good way to configure this at run time. But it is okay to have a bigger buffer available even if application only decides to use a smaller piece of it. Signed-off-by: Stephen Hemminger Signed-off-by: K. Y. Srinivasan --- drivers/uio/uio_hv_generic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index c690d100adcd..35678d08d9d8 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -35,13 +35,13 @@ #include "../hv/hyperv_vmbus.h" -#define DRIVER_VERSION "0.02.0" +#define DRIVER_VERSION "0.02.1" #define DRIVER_AUTHOR "Stephen Hemminger " #define DRIVER_DESC"Generic UIO driver for VMBus devices" #define HV_RING_SIZE512/* pages */ -#define SEND_BUFFER_SIZE (15 * 1024 * 1024) -#define RECV_BUFFER_SIZE (15 * 1024 * 1024) +#define SEND_BUFFER_SIZE (16 * 1024 * 1024) +#define RECV_BUFFER_SIZE (31 * 1024 * 1024) /* * List of resources to be mapped to user space -- 2.18.0
[PATCH 1/5] Tools: hv: Fix a bug in the key delete code
From: "K. Y. Srinivasan" Fix a bug in the key delete code - the num_records range from 0 to num_records-1. Signed-off-by: K. Y. Srinivasan Reported-by: David Binderman Cc: --- tools/hv/hv_kvp_daemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index dbf6e8bd98ba..bbb2a8ef367c 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -286,7 +286,7 @@ static int kvp_key_delete(int pool, const __u8 *key, int key_size) * Found a match; just move the remaining * entries up. */ - if (i == num_records) { + if (i == (num_records - 1)) { kvp_file_info[pool].num_records--; kvp_update_file(pool); return 0; -- 2.18.0
[PATCH 4/5] uio_hv_generic: drop #ifdef DEBUG
From: Stephen Hemminger DEBUG is leftover from the development phase, remove it. Signed-off-by: Stephen Hemminger Signed-off-by: K. Y. Srinivasan --- drivers/uio/uio_hv_generic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index 35678d08d9d8..ab0c0e7e8a44 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -19,7 +19,6 @@ * # echo -n "ed963694-e847-4b2a-85af-bc9cfc11d6f3" \ *> /sys/bus/vmbus/drivers/uio_hv_generic/bind */ -#define DEBUG 1 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -- 2.18.0
[PATCH 3/5] uio_hv_generic: increase size of receive and send buffers
From: Stephen Hemminger When using DPDK there is significant performance boost by using the largest possible send and receive buffer area. Unfortunately, with UIO model there is not a good way to configure this at run time. But it is okay to have a bigger buffer available even if application only decides to use a smaller piece of it. Signed-off-by: Stephen Hemminger Signed-off-by: K. Y. Srinivasan --- drivers/uio/uio_hv_generic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index c690d100adcd..35678d08d9d8 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -35,13 +35,13 @@ #include "../hv/hyperv_vmbus.h" -#define DRIVER_VERSION "0.02.0" +#define DRIVER_VERSION "0.02.1" #define DRIVER_AUTHOR "Stephen Hemminger " #define DRIVER_DESC"Generic UIO driver for VMBus devices" #define HV_RING_SIZE512/* pages */ -#define SEND_BUFFER_SIZE (15 * 1024 * 1024) -#define RECV_BUFFER_SIZE (15 * 1024 * 1024) +#define SEND_BUFFER_SIZE (16 * 1024 * 1024) +#define RECV_BUFFER_SIZE (31 * 1024 * 1024) /* * List of resources to be mapped to user space -- 2.18.0
[PATCH 5/5] Drivers: hv: vmbus: Fix synic per-cpu context initialization
From: Michael Kelley If hv_synic_alloc() errors out, the state of the per-cpu context for some CPUs is unknown since the zero'ing is done as each CPU is iterated over. In such case, hv_synic_cleanup() may try to free memory based on uninitialized values. Fix this by zero'ing the per-cpu context for all CPUs before doing any memory allocations that might fail. Signed-off-by: Michael Kelley Reported-by: Dan Carpenter Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 748a1c4172a6..332d7c34be5c 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -189,6 +189,17 @@ static void hv_init_clockevent_device(struct clock_event_device *dev, int cpu) int hv_synic_alloc(void) { int cpu; + struct hv_per_cpu_context *hv_cpu; + + /* +* First, zero all per-cpu memory areas so hv_synic_free() can +* detect what memory has been allocated and cleanup properly +* after any failures. +*/ + for_each_present_cpu(cpu) { + hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); + memset(hv_cpu, 0, sizeof(*hv_cpu)); + } hv_context.hv_numa_map = kcalloc(nr_node_ids, sizeof(struct cpumask), GFP_KERNEL); @@ -198,10 +209,8 @@ int hv_synic_alloc(void) } for_each_present_cpu(cpu) { - struct hv_per_cpu_context *hv_cpu - = per_cpu_ptr(hv_context.cpu_context, cpu); + hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); - memset(hv_cpu, 0, sizeof(*hv_cpu)); tasklet_init(_cpu->msg_dpc, vmbus_on_msg_dpc, (unsigned long) hv_cpu); -- 2.18.0
[PATCH 5/5] Drivers: hv: vmbus: Fix synic per-cpu context initialization
From: Michael Kelley If hv_synic_alloc() errors out, the state of the per-cpu context for some CPUs is unknown since the zero'ing is done as each CPU is iterated over. In such case, hv_synic_cleanup() may try to free memory based on uninitialized values. Fix this by zero'ing the per-cpu context for all CPUs before doing any memory allocations that might fail. Signed-off-by: Michael Kelley Reported-by: Dan Carpenter Signed-off-by: K. Y. Srinivasan --- drivers/hv/hv.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index 748a1c4172a6..332d7c34be5c 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -189,6 +189,17 @@ static void hv_init_clockevent_device(struct clock_event_device *dev, int cpu) int hv_synic_alloc(void) { int cpu; + struct hv_per_cpu_context *hv_cpu; + + /* +* First, zero all per-cpu memory areas so hv_synic_free() can +* detect what memory has been allocated and cleanup properly +* after any failures. +*/ + for_each_present_cpu(cpu) { + hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); + memset(hv_cpu, 0, sizeof(*hv_cpu)); + } hv_context.hv_numa_map = kcalloc(nr_node_ids, sizeof(struct cpumask), GFP_KERNEL); @@ -198,10 +209,8 @@ int hv_synic_alloc(void) } for_each_present_cpu(cpu) { - struct hv_per_cpu_context *hv_cpu - = per_cpu_ptr(hv_context.cpu_context, cpu); + hv_cpu = per_cpu_ptr(hv_context.cpu_context, cpu); - memset(hv_cpu, 0, sizeof(*hv_cpu)); tasklet_init(_cpu->msg_dpc, vmbus_on_msg_dpc, (unsigned long) hv_cpu); -- 2.18.0
[PATCH 0/5] Miscellaneous fixes/enhancements
From: "K. Y. Srinivasan" Miscellaneous fixes/enhancements. K. Y. Srinivasan (1): Tools: hv: Fix a bug in the key delete code Michael Kelley (1): Drivers: hv: vmbus: Fix synic per-cpu context initialization Stephen Hemminger (3): vmbus: add driver_override support uio_hv_generic: increase size of receive and send buffers uio_hv_generic: drop #ifdef DEBUG Documentation/ABI/testing/sysfs-bus-vmbus | 21 drivers/hv/hv.c | 15 ++- drivers/hv/vmbus_drv.c| 115 ++ drivers/uio/uio_hv_generic.c | 7 +- include/linux/hyperv.h| 1 + tools/hv/hv_kvp_daemon.c | 2 +- 6 files changed, 134 insertions(+), 27 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-vmbus -- 2.18.0
[PATCH 0/5] Miscellaneous fixes/enhancements
From: "K. Y. Srinivasan" Miscellaneous fixes/enhancements. K. Y. Srinivasan (1): Tools: hv: Fix a bug in the key delete code Michael Kelley (1): Drivers: hv: vmbus: Fix synic per-cpu context initialization Stephen Hemminger (3): vmbus: add driver_override support uio_hv_generic: increase size of receive and send buffers uio_hv_generic: drop #ifdef DEBUG Documentation/ABI/testing/sysfs-bus-vmbus | 21 drivers/hv/hv.c | 15 ++- drivers/hv/vmbus_drv.c| 115 ++ drivers/uio/uio_hv_generic.c | 7 +- include/linux/hyperv.h| 1 + tools/hv/hv_kvp_daemon.c | 2 +- 6 files changed, 134 insertions(+), 27 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-vmbus -- 2.18.0
Re: [PATCH v1 2/4] drivers: soc: Add support to register LLCC EDAC driver
On 2018-08-10 10:21, Evan Green wrote: On Wed, Aug 1, 2018 at 1:33 PM Venkata Narendra Kumar Gutta wrote: Cache error reporting controller is to detect and report single and double bit errors on Last Level Cache Controller (LLCC) cache. Add required support to register LLCC EDAC driver as platform driver, from LLCC driver. Signed-off-by: Venkata Narendra Kumar Gutta --- drivers/soc/qcom/llcc-slice.c | 18 -- include/linux/soc/qcom/llcc-qcom.h | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/llcc-slice.c b/drivers/soc/qcom/llcc-slice.c index a63640d..09c8bb0 100644 --- a/drivers/soc/qcom/llcc-slice.c +++ b/drivers/soc/qcom/llcc-slice.c @@ -224,7 +224,7 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev) u32 attr0_val; u32 max_cap_cacheline; u32 sz; - int ret; + int ret = 0; const struct llcc_slice_config *llcc_table; struct llcc_slice_desc desc; @@ -282,6 +282,7 @@ int qcom_llcc_probe(struct platform_device *pdev, struct resource *llcc_banks_res, *llcc_bcast_res; void __iomem *llcc_banks_base, *llcc_bcast_base; int ret, i; + struct platform_device *llcc_edac; drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); if (!drv_data) @@ -341,6 +342,19 @@ int qcom_llcc_probe(struct platform_device *pdev, mutex_init(_data->lock); platform_set_drvdata(pdev, drv_data); - return qcom_llcc_cfg_program(pdev); + ret = qcom_llcc_cfg_program(pdev); + if (ret) + return ret; + + drv_data->ecc_irq = platform_get_irq(pdev, 0); + if (drv_data->ecc_irq >= 0) { This condition will always be true for u32. See below... That's true. I missed that. + llcc_edac = platform_device_register_data(>dev, + "qcom_llcc_edac", -1, drv_data, + sizeof(*drv_data)); + if (IS_ERR(llcc_edac)) + dev_err(dev, "Failed to register llcc edac driver\n"); + } + + return ret; } EXPORT_SYMBOL_GPL(qcom_llcc_probe); diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index c681e79..1a3bc25 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -78,6 +78,7 @@ struct llcc_slice_config { * @num_banks: Number of llcc banks * @bitmap: Bit map to track the active slice ids * @offsets: Pointer to the bank offsets array + * @ecc_irq: interrupt for llcc cache error detection and reporting */ struct llcc_drv_data { struct regmap *regmap; @@ -89,6 +90,7 @@ struct llcc_drv_data { u32 num_banks; unsigned long *bitmap; u32 *offsets; + u32 ecc_irq; The return type for platform_get_irq is int, so this should probably be int, or "unsigned", but then you'd need to fix your logic above. I think we should keep that as int. I'll check on which one I'm supposed to use here and update in the next version. }; #if IS_ENABLED(CONFIG_QCOM_LLCC) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v1 2/4] drivers: soc: Add support to register LLCC EDAC driver
On 2018-08-10 10:21, Evan Green wrote: On Wed, Aug 1, 2018 at 1:33 PM Venkata Narendra Kumar Gutta wrote: Cache error reporting controller is to detect and report single and double bit errors on Last Level Cache Controller (LLCC) cache. Add required support to register LLCC EDAC driver as platform driver, from LLCC driver. Signed-off-by: Venkata Narendra Kumar Gutta --- drivers/soc/qcom/llcc-slice.c | 18 -- include/linux/soc/qcom/llcc-qcom.h | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/llcc-slice.c b/drivers/soc/qcom/llcc-slice.c index a63640d..09c8bb0 100644 --- a/drivers/soc/qcom/llcc-slice.c +++ b/drivers/soc/qcom/llcc-slice.c @@ -224,7 +224,7 @@ static int qcom_llcc_cfg_program(struct platform_device *pdev) u32 attr0_val; u32 max_cap_cacheline; u32 sz; - int ret; + int ret = 0; const struct llcc_slice_config *llcc_table; struct llcc_slice_desc desc; @@ -282,6 +282,7 @@ int qcom_llcc_probe(struct platform_device *pdev, struct resource *llcc_banks_res, *llcc_bcast_res; void __iomem *llcc_banks_base, *llcc_bcast_base; int ret, i; + struct platform_device *llcc_edac; drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); if (!drv_data) @@ -341,6 +342,19 @@ int qcom_llcc_probe(struct platform_device *pdev, mutex_init(_data->lock); platform_set_drvdata(pdev, drv_data); - return qcom_llcc_cfg_program(pdev); + ret = qcom_llcc_cfg_program(pdev); + if (ret) + return ret; + + drv_data->ecc_irq = platform_get_irq(pdev, 0); + if (drv_data->ecc_irq >= 0) { This condition will always be true for u32. See below... That's true. I missed that. + llcc_edac = platform_device_register_data(>dev, + "qcom_llcc_edac", -1, drv_data, + sizeof(*drv_data)); + if (IS_ERR(llcc_edac)) + dev_err(dev, "Failed to register llcc edac driver\n"); + } + + return ret; } EXPORT_SYMBOL_GPL(qcom_llcc_probe); diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index c681e79..1a3bc25 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -78,6 +78,7 @@ struct llcc_slice_config { * @num_banks: Number of llcc banks * @bitmap: Bit map to track the active slice ids * @offsets: Pointer to the bank offsets array + * @ecc_irq: interrupt for llcc cache error detection and reporting */ struct llcc_drv_data { struct regmap *regmap; @@ -89,6 +90,7 @@ struct llcc_drv_data { u32 num_banks; unsigned long *bitmap; u32 *offsets; + u32 ecc_irq; The return type for platform_get_irq is int, so this should probably be int, or "unsigned", but then you'd need to fix your logic above. I think we should keep that as int. I'll check on which one I'm supposed to use here and update in the next version. }; #if IS_ENABLED(CONFIG_QCOM_LLCC) -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH v1 3/4] drivers: edac: Add EDAC driver support for QCOM SoCs
On 2018-08-09 20:59, Borislav Petkov wrote: On Wed, Aug 01, 2018 at 01:33:34PM -0700, Venkata Narendra Kumar Gutta wrote: From: Channagoud Kadabi Add error reporting driver for SBEs and DBEs. As of now, this driver Please write out those abbreviations. Done, I just followed the other commits which has the same and thought they are understood in the community, I'll update it in the next patch set. supports erp for Last Level Cache Controller (LLCC). This driver takes care of dumping registers and adding config options to enable and disable panic when the errors happen in cache. Co-developed-by: Venkata Narendra Kumar Gutta Signed-off-by: Venkata Narendra Kumar Gutta Signed-off-by: Channagoud Kadabi The proper order is: SOB: Author SOB: Sender/handler/... So: Signed-off-by: Channagoud Kadabi Signed-off-by: Venkata Narendra Kumar Gutta Ok, I'll update accordingly. --- MAINTAINERS | 7 + drivers/edac/Kconfig | 28 +++ drivers/edac/Makefile| 1 + drivers/edac/qcom_edac.c | 507 +++ 4 files changed, 543 insertions(+) create mode 100644 drivers/edac/qcom_edac.c diff --git a/MAINTAINERS b/MAINTAINERS index f6a9b08..68b3484 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5227,6 +5227,13 @@ L: linux-e...@vger.kernel.org S: Maintained F: drivers/edac/ti_edac.c +EDAC-QUALCOMM +M: Channagoud Kadabi +M: Venkata Narendra Kumar Gutta Space between name and email address. +L: linux-arm-...@vger.kernel.org Also L: linux-e...@vger.kernel.org so that the EDAC ML gets CCed too. Ok, Done +S: Maintained +F: drivers/edac/qcom_edac.c + EDIROL UA-101/UA-1000 DRIVER M: Clemens Ladisch L: alsa-de...@alsa-project.org (moderated for non-subscribers) diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 57304b2..c654b0e 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -460,4 +460,32 @@ config EDAC_TI Support for error detection and correction on the TI SoCs. +config EDAC_QCOM + depends on EDAC=y Why on EDAC=y? Did you blindly copy it or is there a reason why edac_core should be only built-in or can it be a module too? I took it from EDAC_ALTERA example. I want to put it like EDAC_QCOM should be dependent on EDAC. Doesn't it make any sense or we don't need this at all? or do you think it's redundant? + tristate "QCOM EDAC Controller" + help + Support for error detection and correction on the + QCOM SoCs. + +config EDAC_QCOM_LLCC + depends on EDAC_QCOM=y && QCOM_LLCC + tristate "QCOM EDAC Controller for LLCC Cache" + help + Support for error detection and correction on the + QCOM LLCC cache. Report errors caught by LLCC ECC + mechanism. + + For debugging issues having to do with stability and overall system + health, you should probably say 'Y' here. + +config EDAC_QCOM_LLCC_PANIC_ON_UE + depends on EDAC_QCOM_LLCC + bool "Panic on uncorrectable errors - qcom llcc" + help + Forcibly cause a kernel panic if an uncorrectable error (UE) is + detected. This can reduce debugging times on hardware which may be + operating at voltages or frequencies outside normal specification. + + For production builds, you should probably say 'N' here. + endif # EDAC diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 02b43a7..716096d 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -77,3 +77,4 @@ obj-$(CONFIG_EDAC_ALTERA) += altera_edac.o obj-$(CONFIG_EDAC_SYNOPSYS)+= synopsys_edac.o obj-$(CONFIG_EDAC_XGENE) += xgene_edac.o obj-$(CONFIG_EDAC_TI) += ti_edac.o +obj-$(CONFIG_EDAC_QCOM)+= qcom_edac.o diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c new file mode 100644 index 000..cf3e2b0 --- /dev/null +++ b/drivers/edac/qcom_edac.c @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "edac_mc.h" +#include "edac_device.h" + +#ifdef CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE +#define LLCC_ERP_PANIC_ON_UE1 +#else +#define LLCC_ERP_PANIC_ON_UE0 +#endif + +#define EDAC_LLCC "qcom_llcc" + +#define TRP_SYN_REG_CNT 6 + +#define DRP_SYN_REG_CNT 8 + +#define LLCC_COMMON_STATUS0 0x0003000C +#define LLCC_LB_CNT_MASKGENMASK(31, 28) +#define LLCC_LB_CNT_SHIFT 28 + +/* single & Double Bit syndrome register offsets */ +#define TRP_ECC_SB_ERR_SYN0 0x0002304C +#define TRP_ECC_DB_ERR_SYN0 0x00020370 +#define
Re: [PATCH v1 3/4] drivers: edac: Add EDAC driver support for QCOM SoCs
On 2018-08-09 20:59, Borislav Petkov wrote: On Wed, Aug 01, 2018 at 01:33:34PM -0700, Venkata Narendra Kumar Gutta wrote: From: Channagoud Kadabi Add error reporting driver for SBEs and DBEs. As of now, this driver Please write out those abbreviations. Done, I just followed the other commits which has the same and thought they are understood in the community, I'll update it in the next patch set. supports erp for Last Level Cache Controller (LLCC). This driver takes care of dumping registers and adding config options to enable and disable panic when the errors happen in cache. Co-developed-by: Venkata Narendra Kumar Gutta Signed-off-by: Venkata Narendra Kumar Gutta Signed-off-by: Channagoud Kadabi The proper order is: SOB: Author SOB: Sender/handler/... So: Signed-off-by: Channagoud Kadabi Signed-off-by: Venkata Narendra Kumar Gutta Ok, I'll update accordingly. --- MAINTAINERS | 7 + drivers/edac/Kconfig | 28 +++ drivers/edac/Makefile| 1 + drivers/edac/qcom_edac.c | 507 +++ 4 files changed, 543 insertions(+) create mode 100644 drivers/edac/qcom_edac.c diff --git a/MAINTAINERS b/MAINTAINERS index f6a9b08..68b3484 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5227,6 +5227,13 @@ L: linux-e...@vger.kernel.org S: Maintained F: drivers/edac/ti_edac.c +EDAC-QUALCOMM +M: Channagoud Kadabi +M: Venkata Narendra Kumar Gutta Space between name and email address. +L: linux-arm-...@vger.kernel.org Also L: linux-e...@vger.kernel.org so that the EDAC ML gets CCed too. Ok, Done +S: Maintained +F: drivers/edac/qcom_edac.c + EDIROL UA-101/UA-1000 DRIVER M: Clemens Ladisch L: alsa-de...@alsa-project.org (moderated for non-subscribers) diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 57304b2..c654b0e 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -460,4 +460,32 @@ config EDAC_TI Support for error detection and correction on the TI SoCs. +config EDAC_QCOM + depends on EDAC=y Why on EDAC=y? Did you blindly copy it or is there a reason why edac_core should be only built-in or can it be a module too? I took it from EDAC_ALTERA example. I want to put it like EDAC_QCOM should be dependent on EDAC. Doesn't it make any sense or we don't need this at all? or do you think it's redundant? + tristate "QCOM EDAC Controller" + help + Support for error detection and correction on the + QCOM SoCs. + +config EDAC_QCOM_LLCC + depends on EDAC_QCOM=y && QCOM_LLCC + tristate "QCOM EDAC Controller for LLCC Cache" + help + Support for error detection and correction on the + QCOM LLCC cache. Report errors caught by LLCC ECC + mechanism. + + For debugging issues having to do with stability and overall system + health, you should probably say 'Y' here. + +config EDAC_QCOM_LLCC_PANIC_ON_UE + depends on EDAC_QCOM_LLCC + bool "Panic on uncorrectable errors - qcom llcc" + help + Forcibly cause a kernel panic if an uncorrectable error (UE) is + detected. This can reduce debugging times on hardware which may be + operating at voltages or frequencies outside normal specification. + + For production builds, you should probably say 'N' here. + endif # EDAC diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 02b43a7..716096d 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -77,3 +77,4 @@ obj-$(CONFIG_EDAC_ALTERA) += altera_edac.o obj-$(CONFIG_EDAC_SYNOPSYS)+= synopsys_edac.o obj-$(CONFIG_EDAC_XGENE) += xgene_edac.o obj-$(CONFIG_EDAC_TI) += ti_edac.o +obj-$(CONFIG_EDAC_QCOM)+= qcom_edac.o diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c new file mode 100644 index 000..cf3e2b0 --- /dev/null +++ b/drivers/edac/qcom_edac.c @@ -0,0 +1,507 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "edac_mc.h" +#include "edac_device.h" + +#ifdef CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE +#define LLCC_ERP_PANIC_ON_UE1 +#else +#define LLCC_ERP_PANIC_ON_UE0 +#endif + +#define EDAC_LLCC "qcom_llcc" + +#define TRP_SYN_REG_CNT 6 + +#define DRP_SYN_REG_CNT 8 + +#define LLCC_COMMON_STATUS0 0x0003000C +#define LLCC_LB_CNT_MASKGENMASK(31, 28) +#define LLCC_LB_CNT_SHIFT 28 + +/* single & Double Bit syndrome register offsets */ +#define TRP_ECC_SB_ERR_SYN0 0x0002304C +#define TRP_ECC_DB_ERR_SYN0 0x00020370 +#define
[PATCH v3] checkpatch: DT bindings should be a separate patch
Devicetree bindings should be their own patch as documented in Documentation/devicetree/bindings/submitting-patches.txt section I.1. This is because bindings are logically independent from a driver implementation, they have a different maintainer (even though they often are applied via the same tree), and it makes for a cleaner history in the DT only tree created with git-filter-branch. Cc: Andy Whitcroft Cc: Joe Perches Signed-off-by: Rob Herring --- scripts/checkpatch.pl | 14 ++ 1 file changed, 14 insertions(+) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index a9c05506e325..fa9b50d6f3d4 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2236,6 +2236,7 @@ sub process { our $clean = 1; my $signoff = 0; my $is_patch = 0; + my $is_binding_patch = -1; my $in_header_lines = $file ? 0 : 1; my $in_commit_log = 0; #Scanning lines before patch my $has_commit_log = 0; #Encountered lines before patch @@ -2485,6 +2486,19 @@ sub process { $check = $check_orig; } $checklicenseline = 1; + + if ($realfile !~ /^MAINTAINERS/) { + my $last_binding_patch = $is_binding_patch; + + $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; + + if (($last_binding_patch != -1) && + ($last_binding_patch ^ $is_binding_patch)) { + WARN("DT_SPLIT_BINDING_PATCH", +"DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n"); + } + } + next; } -- 2.17.1
[PATCH v3] checkpatch: DT bindings should be a separate patch
Devicetree bindings should be their own patch as documented in Documentation/devicetree/bindings/submitting-patches.txt section I.1. This is because bindings are logically independent from a driver implementation, they have a different maintainer (even though they often are applied via the same tree), and it makes for a cleaner history in the DT only tree created with git-filter-branch. Cc: Andy Whitcroft Cc: Joe Perches Signed-off-by: Rob Herring --- scripts/checkpatch.pl | 14 ++ 1 file changed, 14 insertions(+) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index a9c05506e325..fa9b50d6f3d4 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2236,6 +2236,7 @@ sub process { our $clean = 1; my $signoff = 0; my $is_patch = 0; + my $is_binding_patch = -1; my $in_header_lines = $file ? 0 : 1; my $in_commit_log = 0; #Scanning lines before patch my $has_commit_log = 0; #Encountered lines before patch @@ -2485,6 +2486,19 @@ sub process { $check = $check_orig; } $checklicenseline = 1; + + if ($realfile !~ /^MAINTAINERS/) { + my $last_binding_patch = $is_binding_patch; + + $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; + + if (($last_binding_patch != -1) && + ($last_binding_patch ^ $is_binding_patch)) { + WARN("DT_SPLIT_BINDING_PATCH", +"DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n"); + } + } + next; } -- 2.17.1
Warning splat on x86_32 during perf stress
I sometimes trigger this splat in my tests (which cause them to fail), but it's not always hit. Note, this is on x86_32 arch. [ cut here ] IRQs not enabled as expected WARNING: CPU: 0 PID: 0 at /work/build/trace/nobackup/linux-test.git/kernel/time/tick-sched.c:982 tick_nohz_idle_enter+0x44/0x8c Modules linked in: ip6t_REJECT nf_reject_ipv6 nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter ip6_tables ipv6 crc_ccitt r8169 ppdev parport_pc parport CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.18.0-rc6-test+ #3 Hardware name: MSI MS-7823/CSM-H87M-G43 (MS-7823), BIOS V1.6 02/22/2014 EIP: tick_nohz_idle_enter+0x44/0x8c Code: e8 05 00 00 00 75 26 83 b8 bc 05 00 00 00 75 1d 80 3d 81 f7 3c c1 00 75 14 68 d6 82 11 c1 c6 05 81 f7 3c c1 01 e8 63 fb f8 ff <0f> 0b 58 fa bb 60 76 65 c1 e8 0d 04 04 00 64 03 1d 28 c1 50 c1 8b EAX: 001c EBX: c14803a0 ECX: 0006 EDX: 0007 perf: interrupt took too long (12533 > 12527), lowering kernel.perf_event_max_sample_rate to 15000 ESI: c12b8d00 EDI: 0147 EBP: c12a5f30 ESP: c12a5f28 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010292 CR0: 80050033 CR2: 080a45b0 CR3: 3075b600 CR4: 001406f0 Call Trace: do_idle+0x33/0x1f9 cpu_startup_entry+0x61/0x63 rest_init+0xb2/0xb4 start_kernel+0x3fa/0x410 i386_start_kernel+0x9a/0x9e startup_32_smp+0x164/0x168 irq event stamp: 8712154 hardirqs last enabled at (8712153): [] trace_hardirqs_on_thunk+0xc/0x10 hardirqs last disabled at (8712154): [] trace_hardirqs_off_thunk+0xc/0x10 softirqs last enabled at (8712148): [] __do_softirq+0x258/0x2b8 softirqs last disabled at (8712107): [] call_on_stack+0x45/0x4b ---[ end trace 7bebbaceab0fedbc ]--- This is where I think my patch: http://lkml.kernel.org/r/20180806214107.11062...@gandalf.local.home would help. As I don't know if IRQs were really enabled, or if lockdep was broken. -- Steve
Warning splat on x86_32 during perf stress
I sometimes trigger this splat in my tests (which cause them to fail), but it's not always hit. Note, this is on x86_32 arch. [ cut here ] IRQs not enabled as expected WARNING: CPU: 0 PID: 0 at /work/build/trace/nobackup/linux-test.git/kernel/time/tick-sched.c:982 tick_nohz_idle_enter+0x44/0x8c Modules linked in: ip6t_REJECT nf_reject_ipv6 nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter ip6_tables ipv6 crc_ccitt r8169 ppdev parport_pc parport CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.18.0-rc6-test+ #3 Hardware name: MSI MS-7823/CSM-H87M-G43 (MS-7823), BIOS V1.6 02/22/2014 EIP: tick_nohz_idle_enter+0x44/0x8c Code: e8 05 00 00 00 75 26 83 b8 bc 05 00 00 00 75 1d 80 3d 81 f7 3c c1 00 75 14 68 d6 82 11 c1 c6 05 81 f7 3c c1 01 e8 63 fb f8 ff <0f> 0b 58 fa bb 60 76 65 c1 e8 0d 04 04 00 64 03 1d 28 c1 50 c1 8b EAX: 001c EBX: c14803a0 ECX: 0006 EDX: 0007 perf: interrupt took too long (12533 > 12527), lowering kernel.perf_event_max_sample_rate to 15000 ESI: c12b8d00 EDI: 0147 EBP: c12a5f30 ESP: c12a5f28 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 EFLAGS: 00010292 CR0: 80050033 CR2: 080a45b0 CR3: 3075b600 CR4: 001406f0 Call Trace: do_idle+0x33/0x1f9 cpu_startup_entry+0x61/0x63 rest_init+0xb2/0xb4 start_kernel+0x3fa/0x410 i386_start_kernel+0x9a/0x9e startup_32_smp+0x164/0x168 irq event stamp: 8712154 hardirqs last enabled at (8712153): [] trace_hardirqs_on_thunk+0xc/0x10 hardirqs last disabled at (8712154): [] trace_hardirqs_off_thunk+0xc/0x10 softirqs last enabled at (8712148): [] __do_softirq+0x258/0x2b8 softirqs last disabled at (8712107): [] call_on_stack+0x45/0x4b ---[ end trace 7bebbaceab0fedbc ]--- This is where I think my patch: http://lkml.kernel.org/r/20180806214107.11062...@gandalf.local.home would help. As I don't know if IRQs were really enabled, or if lockdep was broken. -- Steve
[PATCH] perf tools: arm-spe: Fix uninitialized record error variable
The auxtrace init variable 'err' was not being initialized, leading perf to abort early in an SPE record command when there was no explicit error, rather only based whatever memory contents were on the stack. Initialize it explicitly on getting an SPE successfully, the same way cs-etm does. Signed-off-by: Kim Phillips --- Hi Arnaldo, please apply to perf/urgent / stable series if at all possible. Thank you. tools/perf/arch/arm64/util/arm-spe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index 1120e39c1b00..5ccfce87e693 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -194,6 +194,7 @@ struct auxtrace_record *arm_spe_recording_init(int *err, sper->itr.read_finish = arm_spe_read_finish; sper->itr.alignment = 0; + *err = 0; return >itr; } -- 2.17.1
[PATCH] perf tools: arm-spe: Fix uninitialized record error variable
The auxtrace init variable 'err' was not being initialized, leading perf to abort early in an SPE record command when there was no explicit error, rather only based whatever memory contents were on the stack. Initialize it explicitly on getting an SPE successfully, the same way cs-etm does. Signed-off-by: Kim Phillips --- Hi Arnaldo, please apply to perf/urgent / stable series if at all possible. Thank you. tools/perf/arch/arm64/util/arm-spe.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index 1120e39c1b00..5ccfce87e693 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -194,6 +194,7 @@ struct auxtrace_record *arm_spe_recording_init(int *err, sper->itr.read_finish = arm_spe_read_finish; sper->itr.alignment = 0; + *err = 0; return >itr; } -- 2.17.1
Re: [PATCH 3/3] mm/memory_hotplug: Cleanup unregister_mem_sect_under_nodes
On Fri, 10 Aug 2018 17:29:31 +0200 osalva...@techadventures.net wrote: > From: Oscar Salvador > > With the assumption that the relationship between > memory_block <-> node is 1:1, we can refactor this function a bit. > > This assumption is being taken from register_mem_sect_under_node() > code. > > register_mem_sect_under_node() takes the mem_blk's nid, and compares it > to the pfn's nid we are checking. > If they match, we go ahead and link both objects. > Once done, we just return. > > So, the relationship between memory_block <-> node seems to stand. > > Currently, unregister_mem_sect_under_nodes() defines a nodemask_t > which is being checked in the loop to see if we have already unliked certain > node. "unlinked a certain node" > But since a memory_block can only belong to a node, we can drop the nodemask "to a single node"? > and the check within the loop. > > If we find a match between the mem_block->nid and the nid of the > pfn we are checking, we unlink the objects and return, as unlink the objects "unlinking" > once is enough. > > --- a/drivers/base/node.c > +++ b/drivers/base/node.c > @@ -448,35 +448,27 @@ int register_mem_sect_under_node(struct memory_block > *mem_blk, void *arg) > return 0; > } > > -/* unregister memory section under all nodes that it spans */ > +/* unregister memory section from the node it belongs to */ > int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, > unsigned long phys_index) > { > - NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL); > unsigned long pfn, sect_start_pfn, sect_end_pfn; > - > - if (!unlinked_nodes) > - return -ENOMEM; > - nodes_clear(*unlinked_nodes); > + int nid = mem_blk->nid; > > sect_start_pfn = section_nr_to_pfn(phys_index); > sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; > for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { > - int nid; > + int page_nid = get_nid_for_pfn(pfn); > > - nid = get_nid_for_pfn(pfn); > - if (nid < 0) > - continue; > - if (!node_online(nid)) > - continue; > - if (node_test_and_set(nid, *unlinked_nodes)) > - continue; > - sysfs_remove_link(_devices[nid]->dev.kobj, > - kobject_name(_blk->dev.kobj)); > - sysfs_remove_link(_blk->dev.kobj, > - kobject_name(_devices[nid]->dev.kobj)); > + if (page_nid >= 0 && page_nid == nid) { > + sysfs_remove_link(_devices[nid]->dev.kobj, > + kobject_name(_blk->dev.kobj)); > + sysfs_remove_link(_blk->dev.kobj, > + kobject_name(_devices[nid]->dev.kobj)); > + break; > + } > } > - NODEMASK_FREE(unlinked_nodes); > + > return 0; > } I guess so. But the node_online() check was silently removed?
Re: [PATCH 3/3] mm/memory_hotplug: Cleanup unregister_mem_sect_under_nodes
On Fri, 10 Aug 2018 17:29:31 +0200 osalva...@techadventures.net wrote: > From: Oscar Salvador > > With the assumption that the relationship between > memory_block <-> node is 1:1, we can refactor this function a bit. > > This assumption is being taken from register_mem_sect_under_node() > code. > > register_mem_sect_under_node() takes the mem_blk's nid, and compares it > to the pfn's nid we are checking. > If they match, we go ahead and link both objects. > Once done, we just return. > > So, the relationship between memory_block <-> node seems to stand. > > Currently, unregister_mem_sect_under_nodes() defines a nodemask_t > which is being checked in the loop to see if we have already unliked certain > node. "unlinked a certain node" > But since a memory_block can only belong to a node, we can drop the nodemask "to a single node"? > and the check within the loop. > > If we find a match between the mem_block->nid and the nid of the > pfn we are checking, we unlink the objects and return, as unlink the objects "unlinking" > once is enough. > > --- a/drivers/base/node.c > +++ b/drivers/base/node.c > @@ -448,35 +448,27 @@ int register_mem_sect_under_node(struct memory_block > *mem_blk, void *arg) > return 0; > } > > -/* unregister memory section under all nodes that it spans */ > +/* unregister memory section from the node it belongs to */ > int unregister_mem_sect_under_nodes(struct memory_block *mem_blk, > unsigned long phys_index) > { > - NODEMASK_ALLOC(nodemask_t, unlinked_nodes, GFP_KERNEL); > unsigned long pfn, sect_start_pfn, sect_end_pfn; > - > - if (!unlinked_nodes) > - return -ENOMEM; > - nodes_clear(*unlinked_nodes); > + int nid = mem_blk->nid; > > sect_start_pfn = section_nr_to_pfn(phys_index); > sect_end_pfn = sect_start_pfn + PAGES_PER_SECTION - 1; > for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) { > - int nid; > + int page_nid = get_nid_for_pfn(pfn); > > - nid = get_nid_for_pfn(pfn); > - if (nid < 0) > - continue; > - if (!node_online(nid)) > - continue; > - if (node_test_and_set(nid, *unlinked_nodes)) > - continue; > - sysfs_remove_link(_devices[nid]->dev.kobj, > - kobject_name(_blk->dev.kobj)); > - sysfs_remove_link(_blk->dev.kobj, > - kobject_name(_devices[nid]->dev.kobj)); > + if (page_nid >= 0 && page_nid == nid) { > + sysfs_remove_link(_devices[nid]->dev.kobj, > + kobject_name(_blk->dev.kobj)); > + sysfs_remove_link(_blk->dev.kobj, > + kobject_name(_devices[nid]->dev.kobj)); > + break; > + } > } > - NODEMASK_FREE(unlinked_nodes); > + > return 0; > } I guess so. But the node_online() check was silently removed?
Re: [PATCH] regulator: qcom-rpmh: Add stylistic breaks in the default cases
On 08/10/2018 01:05 PM, Douglas Anderson wrote: > No functional change here but it can make the code more readable to > have breaks in the "default" case even though it's the last case. > Let's add them. > > Signed-off-by: Douglas Anderson > --- > > drivers/regulator/qcom-rpmh-regulator.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/regulator/qcom-rpmh-regulator.c > b/drivers/regulator/qcom-rpmh-regulator.c > index 9f27daebd8c8..b8434e521d72 100644 > --- a/drivers/regulator/qcom-rpmh-regulator.c > +++ b/drivers/regulator/qcom-rpmh-regulator.c > @@ -504,6 +504,7 @@ static unsigned int > rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode) > break; > default: > mode = REGULATOR_MODE_INVALID; > + break; > } > > return mode; > @@ -537,6 +538,7 @@ rpmh_regulator_pmic4_smps_of_map_mode(unsigned int > rpmh_mode) > break; > default: > mode = REGULATOR_MODE_INVALID; > + break; > } > > return mode; > @@ -566,6 +568,7 @@ static unsigned int > rpmh_regulator_pmic4_bob_of_map_mode(unsigned int rpmh_mode) > break; > default: > mode = REGULATOR_MODE_INVALID; > + break; > } > > return mode; Reviewed-by: David Collins -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH] regulator: qcom-rpmh: Add stylistic breaks in the default cases
On 08/10/2018 01:05 PM, Douglas Anderson wrote: > No functional change here but it can make the code more readable to > have breaks in the "default" case even though it's the last case. > Let's add them. > > Signed-off-by: Douglas Anderson > --- > > drivers/regulator/qcom-rpmh-regulator.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/regulator/qcom-rpmh-regulator.c > b/drivers/regulator/qcom-rpmh-regulator.c > index 9f27daebd8c8..b8434e521d72 100644 > --- a/drivers/regulator/qcom-rpmh-regulator.c > +++ b/drivers/regulator/qcom-rpmh-regulator.c > @@ -504,6 +504,7 @@ static unsigned int > rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode) > break; > default: > mode = REGULATOR_MODE_INVALID; > + break; > } > > return mode; > @@ -537,6 +538,7 @@ rpmh_regulator_pmic4_smps_of_map_mode(unsigned int > rpmh_mode) > break; > default: > mode = REGULATOR_MODE_INVALID; > + break; > } > > return mode; > @@ -566,6 +568,7 @@ static unsigned int > rpmh_regulator_pmic4_bob_of_map_mode(unsigned int rpmh_mode) > break; > default: > mode = REGULATOR_MODE_INVALID; > + break; > } > > return mode; Reviewed-by: David Collins -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH 2/3] arm64: dts: qcom: sdm845-mtp: Add RPMh VRM/XOB regulators
Add regulator devices for PMIC regulators managed via VRM and XOB RPMh accelerators. A few notes here: - Regulators are added directly to the board file. While it's true that this will mean a bunch of copy/pasting for other boards that are very similar to MTP, this is probably the right call since boards could make changes to the way these regulators are hooked up and trying to find a way to avoid duplication will result in some confusing node overrides. - Regulators are always given labels based on the schematic. If there is more than one logical name on the schematic for the same rail the all of these secondary names are also listed and should be referred to as appropriate. - Regulators all default to HPM mode with the assumption that if a rail is being provided to a driver that doesn't specify the needed current that we'll at least be correct. NOTE: This patch is loosely based on one originally shared to me by David Collins. Signed-off-by: Douglas Anderson --- Changes in v2: - LDO14 initial mode is LPM and shouldn't be always on (Vivek G) - LDO25 should have min voltage of 3.3V arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 445 1 file changed, 445 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts index 13b50dff440f..839ef9125bf4 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts @@ -7,6 +7,7 @@ /dts-v1/; +#include #include "sdm845.dtsi" / { @@ -20,6 +21,450 @@ chosen { stdout-path = "serial0:115200n8"; }; + + vph_pwr: vph-pwr-regulator { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <370>; + regulator-max-microvolt = <370>; + }; + + /* +* Apparently RPMh does not provide support for PM8998 S4 because it +* is always-on; model it as a fixed regulator. +*/ + vreg_s4a_1p8: pm8998-smps4 { + compatible = "regulator-fixed"; + regulator-name = "vreg_s4a_1p8"; + + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + + regulator-always-on; + regulator-boot-on; + }; +}; + +_rsc { + pm8998-rpmh-regulators { + compatible = "qcom,pm8998-rpmh-regulators"; + qcom,pmic-id = "a"; + + vdd-s1-supply = <_pwr>; + vdd-s2-supply = <_pwr>; + vdd-s3-supply = <_pwr>; + vdd-s4-supply = <_pwr>; + vdd-s5-supply = <_pwr>; + vdd-s6-supply = <_pwr>; + vdd-s7-supply = <_pwr>; + vdd-s8-supply = <_pwr>; + vdd-s9-supply = <_pwr>; + vdd-s10-supply = <_pwr>; + vdd-s11-supply = <_pwr>; + vdd-s12-supply = <_pwr>; + vdd-s13-supply = <_pwr>; + vdd-l1-l27-supply = <_s7a_1p025>; + vdd-l2-l8-l17-supply = <_s3a_1p35>; + vdd-l3-l11-supply = <_s7a_1p025>; + vdd-l4-l5-supply = <_s7a_1p025>; + vdd-l6-supply = <_pwr>; + vdd-l7-l12-l14-l15-supply = <_s5a_2p04>; + vdd-l9-supply = <_bob>; + vdd-l10-l23-l25-supply = <_bob>; + vdd-l13-l19-l21-supply = <_bob>; + vdd-l16-l28-supply = <_bob>; + vdd-l18-l22-supply = <_bob>; + vdd-l20-l24-supply = <_bob>; + vdd-l26-supply = <_s3a_1p35>; + vin-lvs-1-2-supply = <_s4a_1p8>; + + vreg_s2a_1p125: smps2 { + regulator-min-microvolt = <110>; + regulator-max-microvolt = <110>; + }; + + vreg_s3a_1p35: smps3 { + regulator-min-microvolt = <1352000>; + regulator-max-microvolt = <1352000>; + }; + + vreg_s5a_2p04: smps5 { + regulator-min-microvolt = <1904000>; + regulator-max-microvolt = <204>; + }; + + vreg_s7a_1p025: smps7 { + regulator-min-microvolt = <90>; + regulator-max-microvolt = <1028000>; + }; + + vdd_qusb_hs0: + vdda_hp_pcie_core: + vdda_mipi_csi0_0p9: + vdda_mipi_csi1_0p9: + vdda_mipi_csi2_0p9: + vdda_mipi_dsi0_pll: + vdda_mipi_dsi1_pll: + vdda_qlink_lv: + vdda_qlink_lv_ck: + vdda_qrefs_0p875: + vdda_pcie_core: + vdda_pll_cc_ebi01: + vdda_pll_cc_ebi23: + vdda_sp_sensor: + vdda_ufs1_core: + vdda_ufs2_core: +
[PATCH 2/3] arm64: dts: qcom: sdm845-mtp: Add RPMh VRM/XOB regulators
Add regulator devices for PMIC regulators managed via VRM and XOB RPMh accelerators. A few notes here: - Regulators are added directly to the board file. While it's true that this will mean a bunch of copy/pasting for other boards that are very similar to MTP, this is probably the right call since boards could make changes to the way these regulators are hooked up and trying to find a way to avoid duplication will result in some confusing node overrides. - Regulators are always given labels based on the schematic. If there is more than one logical name on the schematic for the same rail the all of these secondary names are also listed and should be referred to as appropriate. - Regulators all default to HPM mode with the assumption that if a rail is being provided to a driver that doesn't specify the needed current that we'll at least be correct. NOTE: This patch is loosely based on one originally shared to me by David Collins. Signed-off-by: Douglas Anderson --- Changes in v2: - LDO14 initial mode is LPM and shouldn't be always on (Vivek G) - LDO25 should have min voltage of 3.3V arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 445 1 file changed, 445 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts index 13b50dff440f..839ef9125bf4 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts @@ -7,6 +7,7 @@ /dts-v1/; +#include #include "sdm845.dtsi" / { @@ -20,6 +21,450 @@ chosen { stdout-path = "serial0:115200n8"; }; + + vph_pwr: vph-pwr-regulator { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <370>; + regulator-max-microvolt = <370>; + }; + + /* +* Apparently RPMh does not provide support for PM8998 S4 because it +* is always-on; model it as a fixed regulator. +*/ + vreg_s4a_1p8: pm8998-smps4 { + compatible = "regulator-fixed"; + regulator-name = "vreg_s4a_1p8"; + + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + + regulator-always-on; + regulator-boot-on; + }; +}; + +_rsc { + pm8998-rpmh-regulators { + compatible = "qcom,pm8998-rpmh-regulators"; + qcom,pmic-id = "a"; + + vdd-s1-supply = <_pwr>; + vdd-s2-supply = <_pwr>; + vdd-s3-supply = <_pwr>; + vdd-s4-supply = <_pwr>; + vdd-s5-supply = <_pwr>; + vdd-s6-supply = <_pwr>; + vdd-s7-supply = <_pwr>; + vdd-s8-supply = <_pwr>; + vdd-s9-supply = <_pwr>; + vdd-s10-supply = <_pwr>; + vdd-s11-supply = <_pwr>; + vdd-s12-supply = <_pwr>; + vdd-s13-supply = <_pwr>; + vdd-l1-l27-supply = <_s7a_1p025>; + vdd-l2-l8-l17-supply = <_s3a_1p35>; + vdd-l3-l11-supply = <_s7a_1p025>; + vdd-l4-l5-supply = <_s7a_1p025>; + vdd-l6-supply = <_pwr>; + vdd-l7-l12-l14-l15-supply = <_s5a_2p04>; + vdd-l9-supply = <_bob>; + vdd-l10-l23-l25-supply = <_bob>; + vdd-l13-l19-l21-supply = <_bob>; + vdd-l16-l28-supply = <_bob>; + vdd-l18-l22-supply = <_bob>; + vdd-l20-l24-supply = <_bob>; + vdd-l26-supply = <_s3a_1p35>; + vin-lvs-1-2-supply = <_s4a_1p8>; + + vreg_s2a_1p125: smps2 { + regulator-min-microvolt = <110>; + regulator-max-microvolt = <110>; + }; + + vreg_s3a_1p35: smps3 { + regulator-min-microvolt = <1352000>; + regulator-max-microvolt = <1352000>; + }; + + vreg_s5a_2p04: smps5 { + regulator-min-microvolt = <1904000>; + regulator-max-microvolt = <204>; + }; + + vreg_s7a_1p025: smps7 { + regulator-min-microvolt = <90>; + regulator-max-microvolt = <1028000>; + }; + + vdd_qusb_hs0: + vdda_hp_pcie_core: + vdda_mipi_csi0_0p9: + vdda_mipi_csi1_0p9: + vdda_mipi_csi2_0p9: + vdda_mipi_dsi0_pll: + vdda_mipi_dsi1_pll: + vdda_qlink_lv: + vdda_qlink_lv_ck: + vdda_qrefs_0p875: + vdda_pcie_core: + vdda_pll_cc_ebi01: + vdda_pll_cc_ebi23: + vdda_sp_sensor: + vdda_ufs1_core: + vdda_ufs2_core: +
[PATCH 1/3] arm64: dts: qcom: sdm845: Add USB-related nodes
From: Manu Gautam This adds nodes for USB and related PHYs. Signed-off-by: Manu Gautam [dianders: reworked quite a bit] Signed-off-by: Douglas Anderson --- Changes in v2: - Use "0x784000" for qfprom rather than "0x78" as per docs. - Add calibration for 2nd USB port too arch/arm64/boot/dts/qcom/sdm845.dtsi | 196 +++ 1 file changed, 196 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index ae57c065780c..f13d8c2fb4a5 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include / { @@ -249,6 +250,23 @@ #power-domain-cells = <1>; }; + qfprom@784000 { + compatible = "qcom,qfprom"; + reg = <0x78 0x8ff>; + #address-cells = <1>; + #size-cells = <1>; + + qusb2p_hstx_trim: hstx-trim-primary@1eb { + reg = <0x1eb 0x1>; + bits = <1 4>; + }; + + qusb2s_hstx_trim: hstx-trim-secondary@1eb { + reg = <0x1eb 0x2>; + bits = <6 4>; + }; + }; + qupv3_id_0: geniqup@8c { compatible = "qcom,geni-se-qup"; reg = <0x8c 0x6000>; @@ -962,6 +980,184 @@ }; }; + usb_1_hsphy: phy@88e2000 { + compatible = "qcom,sdm845-qusb2-phy"; + reg = <0x88e2000 0x400>; + status = "disabled"; + #phy-cells = <0>; + + clocks = < GCC_USB_PHY_CFG_AHB2PHY_CLK>, +< RPMH_CXO_CLK>; + clock-names = "cfg_ahb", "ref"; + + resets = < GCC_QUSB2PHY_PRIM_BCR>; + + nvmem-cells = <_hstx_trim>; + }; + + usb_2_hsphy: phy@88e3000 { + compatible = "qcom,sdm845-qusb2-phy"; + reg = <0x88e3000 0x400>; + status = "disabled"; + #phy-cells = <0>; + + clocks = < GCC_USB_PHY_CFG_AHB2PHY_CLK>, +< RPMH_CXO_CLK>; + clock-names = "cfg_ahb", "ref"; + + resets = < GCC_QUSB2PHY_SEC_BCR>; + + nvmem-cells = <_hstx_trim>; + }; + + usb_1_qmpphy: phy@88e9000 { + compatible = "qcom,sdm845-qmp-usb3-phy"; + reg = <0x88e9000 0x18c>, + <0x88e8000 0x10>; + reg-names = "reg-base", "dp_com"; + status = "disabled"; + #clock-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = < GCC_USB3_PRIM_PHY_AUX_CLK>, +< GCC_USB_PHY_CFG_AHB2PHY_CLK>, +< GCC_USB3_PRIM_CLKREF_CLK>, +< GCC_USB3_PRIM_PHY_COM_AUX_CLK>; + clock-names = "aux", "cfg_ahb", "ref", "com_aux"; + + resets = < GCC_USB3_DP_PHY_PRIM_BCR>, +< GCC_USB3_PHY_PRIM_BCR>; + reset-names = "phy", "common"; + + usb_1_ssphy: lane@88e9200 { + reg = <0x88e9200 0x128>, + <0x88e9400 0x200>, + <0x88e9c00 0x218>, + <0x88e9a00 0x100>; + #phy-cells = <0>; + clocks = < GCC_USB3_PRIM_PHY_PIPE_CLK>; + clock-names = "pipe0"; + clock-output-names = "usb3_phy_pipe_clk_src"; + }; + }; + + usb_2_qmpphy: phy@88eb000 { + compatible = "qcom,sdm845-qmp-usb3-uni-phy"; + reg = <0x88eb000 0x18c>; + status = "disabled"; + #clock-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = < GCC_USB3_SEC_PHY_AUX_CLK>, +< GCC_USB_PHY_CFG_AHB2PHY_CLK>, +< GCC_USB3_SEC_CLKREF_CLK>, +< GCC_USB3_SEC_PHY_COM_AUX_CLK>; + clock-names = "aux", "cfg_ahb", "ref", "com_aux"; +
[PATCH 1/3] arm64: dts: qcom: sdm845: Add USB-related nodes
From: Manu Gautam This adds nodes for USB and related PHYs. Signed-off-by: Manu Gautam [dianders: reworked quite a bit] Signed-off-by: Douglas Anderson --- Changes in v2: - Use "0x784000" for qfprom rather than "0x78" as per docs. - Add calibration for 2nd USB port too arch/arm64/boot/dts/qcom/sdm845.dtsi | 196 +++ 1 file changed, 196 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index ae57c065780c..f13d8c2fb4a5 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include / { @@ -249,6 +250,23 @@ #power-domain-cells = <1>; }; + qfprom@784000 { + compatible = "qcom,qfprom"; + reg = <0x78 0x8ff>; + #address-cells = <1>; + #size-cells = <1>; + + qusb2p_hstx_trim: hstx-trim-primary@1eb { + reg = <0x1eb 0x1>; + bits = <1 4>; + }; + + qusb2s_hstx_trim: hstx-trim-secondary@1eb { + reg = <0x1eb 0x2>; + bits = <6 4>; + }; + }; + qupv3_id_0: geniqup@8c { compatible = "qcom,geni-se-qup"; reg = <0x8c 0x6000>; @@ -962,6 +980,184 @@ }; }; + usb_1_hsphy: phy@88e2000 { + compatible = "qcom,sdm845-qusb2-phy"; + reg = <0x88e2000 0x400>; + status = "disabled"; + #phy-cells = <0>; + + clocks = < GCC_USB_PHY_CFG_AHB2PHY_CLK>, +< RPMH_CXO_CLK>; + clock-names = "cfg_ahb", "ref"; + + resets = < GCC_QUSB2PHY_PRIM_BCR>; + + nvmem-cells = <_hstx_trim>; + }; + + usb_2_hsphy: phy@88e3000 { + compatible = "qcom,sdm845-qusb2-phy"; + reg = <0x88e3000 0x400>; + status = "disabled"; + #phy-cells = <0>; + + clocks = < GCC_USB_PHY_CFG_AHB2PHY_CLK>, +< RPMH_CXO_CLK>; + clock-names = "cfg_ahb", "ref"; + + resets = < GCC_QUSB2PHY_SEC_BCR>; + + nvmem-cells = <_hstx_trim>; + }; + + usb_1_qmpphy: phy@88e9000 { + compatible = "qcom,sdm845-qmp-usb3-phy"; + reg = <0x88e9000 0x18c>, + <0x88e8000 0x10>; + reg-names = "reg-base", "dp_com"; + status = "disabled"; + #clock-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = < GCC_USB3_PRIM_PHY_AUX_CLK>, +< GCC_USB_PHY_CFG_AHB2PHY_CLK>, +< GCC_USB3_PRIM_CLKREF_CLK>, +< GCC_USB3_PRIM_PHY_COM_AUX_CLK>; + clock-names = "aux", "cfg_ahb", "ref", "com_aux"; + + resets = < GCC_USB3_DP_PHY_PRIM_BCR>, +< GCC_USB3_PHY_PRIM_BCR>; + reset-names = "phy", "common"; + + usb_1_ssphy: lane@88e9200 { + reg = <0x88e9200 0x128>, + <0x88e9400 0x200>, + <0x88e9c00 0x218>, + <0x88e9a00 0x100>; + #phy-cells = <0>; + clocks = < GCC_USB3_PRIM_PHY_PIPE_CLK>; + clock-names = "pipe0"; + clock-output-names = "usb3_phy_pipe_clk_src"; + }; + }; + + usb_2_qmpphy: phy@88eb000 { + compatible = "qcom,sdm845-qmp-usb3-uni-phy"; + reg = <0x88eb000 0x18c>; + status = "disabled"; + #clock-cells = <1>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + clocks = < GCC_USB3_SEC_PHY_AUX_CLK>, +< GCC_USB_PHY_CFG_AHB2PHY_CLK>, +< GCC_USB3_SEC_CLKREF_CLK>, +< GCC_USB3_SEC_PHY_COM_AUX_CLK>; + clock-names = "aux", "cfg_ahb", "ref", "com_aux"; +
[PATCH v1] dd: Invoke one probe retry cycle after some initcall levels
Drivers that are registered at an initcall level may have to wait until late_init before the probe deferral mechanism can retry their probe functions. It is possible that their dependencies were resolved much earlier, in some cases even before the next initcall level. Invoke one probe retry cycle at every _sync initcall level after subsys initcall, allowing these drivers to be probed earlier. Signed-off-by: Vikram Mulukutla Signed-off-by: Rishabh Bhatnagar --- To give an example many Qualcomm drivers are dependent on the regulator and bus driver. Both the regulator and bus driver are probed in the subsys_initcall level. Now the probe of bus driver requires regulator to be working. If the probe of bus driver happens before regulator, then bus driver's probe will be deferred and all other device's probes which depend on bus driver will also be deferred. The impact of this problem is reduced if we have this patch. Changes since v0: * Remove arch_initcall_sync(deferred_probe_initcall) from patch. This is not really needed as none of the devices are re-probed in arch_initcall_sync level. drivers/base/dd.c | 32 ++-- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 1435d72..9aa41aa 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -224,23 +224,43 @@ void device_unblock_probing(void) driver_deferred_probe_trigger(); } +static void enable_trigger_defer_cycle(void) +{ + driver_deferred_probe_enable = true; + driver_deferred_probe_trigger(); + /* +* Sort as many dependencies as possible before the next initcall +* level +*/ + flush_work(_probe_work); +} + /** * deferred_probe_initcall() - Enable probing of deferred devices * * We don't want to get in the way when the bulk of drivers are getting probed. * Instead, this initcall makes sure that deferred probing is delayed until - * late_initcall time. + * all the registered initcall functions at a particular level are completed. + * This function is invoked at every *_initcall_sync level. */ static int deferred_probe_initcall(void) { - driver_deferred_probe_enable = true; - driver_deferred_probe_trigger(); - /* Sort as many dependencies as possible before exiting initcalls */ - flush_work(_probe_work); + enable_trigger_defer_cycle(); + driver_deferred_probe_enable = false; + return 0; +} +subsys_initcall_sync(deferred_probe_initcall); +fs_initcall_sync(deferred_probe_initcall); +device_initcall_sync(deferred_probe_initcall); + +static int deferred_probe_enable_fn(void) +{ + /* Enable deferred probing for all time */ + enable_trigger_defer_cycle(); initcalls_done = true; return 0; } -late_initcall(deferred_probe_initcall); +late_initcall(deferred_probe_enable_fn); /** * device_is_bound() - Check if device is bound to a driver -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH 3/3] arm64: dts: qcom: sdm845-mtp: Add nodes for USB
Set the various nodes to "okay" and hook up the regulators. NOTE: For now the main USB port (the one that goes out the Type C connector) is forced to host. Eventually someone will need to get the Type C detection hooked up and get this all integrated with the PMI8998 PMIC. The reason for forcing to "host" in the meantime is that this will leave us with one "host" and one "peripheral" port. In order for host mode this to work, we assume that the bootloader left things configured enough for us. Apparently the magic for that is is to do these writes on pmi8998: - pm_comm_write_byte(2, 0x1153, 0x2C, 0); - pm_comm_write_byte(2, 0x1152, 0x07, 0); - pm_comm_write_byte(2, 0x1140, 0x00, 0); - pm_comm_write_byte(2, 0x1140, 0x01, 0); Signed-off-by: Douglas Anderson --- Changes in v2: None arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 61 + 1 file changed, 61 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts index 839ef9125bf4..eb9400bf2cbf 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts @@ -480,6 +480,67 @@ status = "okay"; }; +_1 { + status = "okay"; +}; + +_1_dwc3 { + /* Until we have Type C hooked up we'll force this as host. */ + dr_mode = "host"; +}; + +_1_hsphy { + status = "okay"; + + vdd-supply = <_usb1_ss_core>; + vdda-pll-supply = <_qusb_hs0_1p8>; + vdda-phy-dpdm-supply = <_qusb_hs0_3p1>; + + qcom,imp-res-offset-value = <8>; + qcom,hstx-trim-value = ; + qcom,preemphasis-level = ; + qcom,preemphasis-width = ; +}; + +_1_qmpphy { + status = "okay"; + + vdda-phy-supply = <_usb1_ss_1p2>; + vdda-pll-supply = <_usb1_ss_core>; +}; + +_2 { + status = "okay"; +}; + +_2_dwc3 { + /* +* Though the USB block on SDM845 can support host, there's no vbus +* signal for this port on MTP. Thus (unless you have a non-compliant +* hub that works without vbus) the only sensible thing is to force +* peripheral mode. +*/ + dr_mode = "peripheral"; +}; + +_2_hsphy { + status = "okay"; + + vdd-supply = <_usb2_ss_core>; + vdda-pll-supply = <_qusb_hs0_1p8>; + vdda-phy-dpdm-supply = <_qusb_hs0_3p1>; + + qcom,imp-res-offset-value = <8>; + qcom,hstx-trim-value = ; +}; + +_2_qmpphy { + status = "okay"; + + vdda-phy-supply = <_usb2_ss_1p2>; + vdda-pll-supply = <_usb2_ss_core>; +}; + /* PINCTRL - additions to nodes defined in sdm845.dtsi */ _i2c10_default { -- 2.18.0.597.ga71716f1ad-goog
[PATCH v1] dd: Invoke one probe retry cycle after some initcall levels
Drivers that are registered at an initcall level may have to wait until late_init before the probe deferral mechanism can retry their probe functions. It is possible that their dependencies were resolved much earlier, in some cases even before the next initcall level. Invoke one probe retry cycle at every _sync initcall level after subsys initcall, allowing these drivers to be probed earlier. Signed-off-by: Vikram Mulukutla Signed-off-by: Rishabh Bhatnagar --- To give an example many Qualcomm drivers are dependent on the regulator and bus driver. Both the regulator and bus driver are probed in the subsys_initcall level. Now the probe of bus driver requires regulator to be working. If the probe of bus driver happens before regulator, then bus driver's probe will be deferred and all other device's probes which depend on bus driver will also be deferred. The impact of this problem is reduced if we have this patch. Changes since v0: * Remove arch_initcall_sync(deferred_probe_initcall) from patch. This is not really needed as none of the devices are re-probed in arch_initcall_sync level. drivers/base/dd.c | 32 ++-- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 1435d72..9aa41aa 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -224,23 +224,43 @@ void device_unblock_probing(void) driver_deferred_probe_trigger(); } +static void enable_trigger_defer_cycle(void) +{ + driver_deferred_probe_enable = true; + driver_deferred_probe_trigger(); + /* +* Sort as many dependencies as possible before the next initcall +* level +*/ + flush_work(_probe_work); +} + /** * deferred_probe_initcall() - Enable probing of deferred devices * * We don't want to get in the way when the bulk of drivers are getting probed. * Instead, this initcall makes sure that deferred probing is delayed until - * late_initcall time. + * all the registered initcall functions at a particular level are completed. + * This function is invoked at every *_initcall_sync level. */ static int deferred_probe_initcall(void) { - driver_deferred_probe_enable = true; - driver_deferred_probe_trigger(); - /* Sort as many dependencies as possible before exiting initcalls */ - flush_work(_probe_work); + enable_trigger_defer_cycle(); + driver_deferred_probe_enable = false; + return 0; +} +subsys_initcall_sync(deferred_probe_initcall); +fs_initcall_sync(deferred_probe_initcall); +device_initcall_sync(deferred_probe_initcall); + +static int deferred_probe_enable_fn(void) +{ + /* Enable deferred probing for all time */ + enable_trigger_defer_cycle(); initcalls_done = true; return 0; } -late_initcall(deferred_probe_initcall); +late_initcall(deferred_probe_enable_fn); /** * device_is_bound() - Check if device is bound to a driver -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH 3/3] arm64: dts: qcom: sdm845-mtp: Add nodes for USB
Set the various nodes to "okay" and hook up the regulators. NOTE: For now the main USB port (the one that goes out the Type C connector) is forced to host. Eventually someone will need to get the Type C detection hooked up and get this all integrated with the PMI8998 PMIC. The reason for forcing to "host" in the meantime is that this will leave us with one "host" and one "peripheral" port. In order for host mode this to work, we assume that the bootloader left things configured enough for us. Apparently the magic for that is is to do these writes on pmi8998: - pm_comm_write_byte(2, 0x1153, 0x2C, 0); - pm_comm_write_byte(2, 0x1152, 0x07, 0); - pm_comm_write_byte(2, 0x1140, 0x00, 0); - pm_comm_write_byte(2, 0x1140, 0x01, 0); Signed-off-by: Douglas Anderson --- Changes in v2: None arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 61 + 1 file changed, 61 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts index 839ef9125bf4..eb9400bf2cbf 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts @@ -480,6 +480,67 @@ status = "okay"; }; +_1 { + status = "okay"; +}; + +_1_dwc3 { + /* Until we have Type C hooked up we'll force this as host. */ + dr_mode = "host"; +}; + +_1_hsphy { + status = "okay"; + + vdd-supply = <_usb1_ss_core>; + vdda-pll-supply = <_qusb_hs0_1p8>; + vdda-phy-dpdm-supply = <_qusb_hs0_3p1>; + + qcom,imp-res-offset-value = <8>; + qcom,hstx-trim-value = ; + qcom,preemphasis-level = ; + qcom,preemphasis-width = ; +}; + +_1_qmpphy { + status = "okay"; + + vdda-phy-supply = <_usb1_ss_1p2>; + vdda-pll-supply = <_usb1_ss_core>; +}; + +_2 { + status = "okay"; +}; + +_2_dwc3 { + /* +* Though the USB block on SDM845 can support host, there's no vbus +* signal for this port on MTP. Thus (unless you have a non-compliant +* hub that works without vbus) the only sensible thing is to force +* peripheral mode. +*/ + dr_mode = "peripheral"; +}; + +_2_hsphy { + status = "okay"; + + vdd-supply = <_usb2_ss_core>; + vdda-pll-supply = <_qusb_hs0_1p8>; + vdda-phy-dpdm-supply = <_qusb_hs0_3p1>; + + qcom,imp-res-offset-value = <8>; + qcom,hstx-trim-value = ; +}; + +_2_qmpphy { + status = "okay"; + + vdda-phy-supply = <_usb2_ss_1p2>; + vdda-pll-supply = <_usb2_ss_core>; +}; + /* PINCTRL - additions to nodes defined in sdm845.dtsi */ _i2c10_default { -- 2.18.0.597.ga71716f1ad-goog
[PATCH 0/3] arm64: dts: sdm845: Add RPMh-regulators and usb
This series adds device tree nodes for the RPMh regulators and USB. These patches are based on patches in various downstream kernels from Manu Gautam, David Collins, and Vivek Gautam. This series was tested on SDM845-MTP (with no-AC firmware) atop Andy Gross's current "for-next" branch at commit 76b9e7f947f1 ("Merge tag 'qcom-defconfig-for-4.19' into all-for-4.19") with some extra patches: >From mainline: - 87ed1405ef09 ("nvmem: Don't let a NULL cell_id for nvmem_cell_get() crash us") >From clk-next: - 9c7e47025a6b ("clk: qcom: clk-rpmh: Add QCOM RPMh clock driver") >From regulator/for-next: - 46fc033eba42 ("regulator: add QCOM RPMh regulator driver") - 0db021f7a273 ("regulator: dt-bindings: add QCOM RPMh regulator bindings") >From Will Deacon's tree (for-joerg/arm-smmu/updates): - d1e20222d537 ("iommu/arm-smmu: Error out only if not enough context interrupts") >From the mailing list (needs to be spun but works OK): - dts: arm64/sdm845: Add node for arm,mmu-500 https://lore.kernel.org/patchwork/patch/964814/ As you can see from the above all the dependencies except the addition of the MMU node have landed so this series should be about ready to land too. If anyone would like to see the tree I used for test, it can be found at: https://chromium.googlesource.com/chromiumos/third_party/kernel/+log/refs/sandbox/dianders/180810-agross-usbv2 Changes in v2: - Use "0x784000" for qfprom rather than "0x78" as per docs. - Add calibration for 2nd USB port too - LDO14 initial mode is LPM and shouldn't be always on (Vivek G) - LDO25 should have min voltage of 3.3V Douglas Anderson (2): arm64: dts: qcom: sdm845-mtp: Add RPMh VRM/XOB regulators arm64: dts: qcom: sdm845-mtp: Add nodes for USB Manu Gautam (1): arm64: dts: qcom: sdm845: Add USB-related nodes arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 506 arch/arm64/boot/dts/qcom/sdm845.dtsi| 196 + 2 files changed, 702 insertions(+) -- 2.18.0.597.ga71716f1ad-goog
[PATCH 0/3] arm64: dts: sdm845: Add RPMh-regulators and usb
This series adds device tree nodes for the RPMh regulators and USB. These patches are based on patches in various downstream kernels from Manu Gautam, David Collins, and Vivek Gautam. This series was tested on SDM845-MTP (with no-AC firmware) atop Andy Gross's current "for-next" branch at commit 76b9e7f947f1 ("Merge tag 'qcom-defconfig-for-4.19' into all-for-4.19") with some extra patches: >From mainline: - 87ed1405ef09 ("nvmem: Don't let a NULL cell_id for nvmem_cell_get() crash us") >From clk-next: - 9c7e47025a6b ("clk: qcom: clk-rpmh: Add QCOM RPMh clock driver") >From regulator/for-next: - 46fc033eba42 ("regulator: add QCOM RPMh regulator driver") - 0db021f7a273 ("regulator: dt-bindings: add QCOM RPMh regulator bindings") >From Will Deacon's tree (for-joerg/arm-smmu/updates): - d1e20222d537 ("iommu/arm-smmu: Error out only if not enough context interrupts") >From the mailing list (needs to be spun but works OK): - dts: arm64/sdm845: Add node for arm,mmu-500 https://lore.kernel.org/patchwork/patch/964814/ As you can see from the above all the dependencies except the addition of the MMU node have landed so this series should be about ready to land too. If anyone would like to see the tree I used for test, it can be found at: https://chromium.googlesource.com/chromiumos/third_party/kernel/+log/refs/sandbox/dianders/180810-agross-usbv2 Changes in v2: - Use "0x784000" for qfprom rather than "0x78" as per docs. - Add calibration for 2nd USB port too - LDO14 initial mode is LPM and shouldn't be always on (Vivek G) - LDO25 should have min voltage of 3.3V Douglas Anderson (2): arm64: dts: qcom: sdm845-mtp: Add RPMh VRM/XOB regulators arm64: dts: qcom: sdm845-mtp: Add nodes for USB Manu Gautam (1): arm64: dts: qcom: sdm845: Add USB-related nodes arch/arm64/boot/dts/qcom/sdm845-mtp.dts | 506 arch/arm64/boot/dts/qcom/sdm845.dtsi| 196 + 2 files changed, 702 insertions(+) -- 2.18.0.597.ga71716f1ad-goog
Re: Fwd: PROBLEM: tpm_cpg can't request region with AMD/Dell fTPM
On Fri, Aug 10, 2018 at 07:57:35PM +0300, Jarkko Sakkinen wrote: > On Tue, Aug 07, 2018 at 02:43:10PM -0400, Harlan Lieberman-Berg wrote: > > (Resending as it seems to have been spamfiltered out from the ml; > > sorry Peter, Jarkko for the duplicate) > > I came on Monday from four week leave and have been basically been > catching up with my emails :-) I'll look into this next week with > time. The error message is saying that someone else has reserved the resource (-EBUSY). This looks odd: e78bf000-e7bbefff : ACPI Non-volatile Storage e7bb6000-e7bb9fff : MSFT0101:00 e7bba000-e7bbdfff : MSFT0101:00 Why would be TPM registers mapped inside ACPI NV? I would *guess* that what is happening is that perhaps drivers/acpi/nvs.c maps the address space. This looks like a firmware bug, and such that we cannot do anything about it. I'm having a weird issue with the ACPI tables: $ acpixtract acpidump.txt Intel ACPI Component Architecture ACPI Binary Table Extraction Utility version 20180105 Copyright (c) 2000 - 2018 Intel Corporation DSDT - 31048 bytes written (0x7948) - dsdt.dat SSDT - 349 bytes written (0x015D) - ssdt1.dat SSDT - 18086 bytes written (0x46A6) - ssdt2.dat SSDT -5225 bytes written (0x1469) - ssdt3.dat SSDT -1082 bytes written (0x043A) - ssdt4.dat SSDT -1017 bytes written (0x03F9) - ssdt5.dat SSDT -5369 bytes written (0x14F9) - ssdt6.dat $ iasl -d *.dat Intel ACPI Component Architecture ASL+ Optimizing Compiler/Disassembler version 20180105 Copyright (c) 2000 - 2018 Intel Corporation Input file dsdt.dat, Length 0x7948 (31048) bytes Table [DSDT] is too long for file - needs: 0x815D, remaining in file: 0x7948 Could not get ACPI tables from dsdt.dat, AE_BAD_HEADER This has not happened to me before. /Jarkko
Re: Fwd: PROBLEM: tpm_cpg can't request region with AMD/Dell fTPM
On Fri, Aug 10, 2018 at 07:57:35PM +0300, Jarkko Sakkinen wrote: > On Tue, Aug 07, 2018 at 02:43:10PM -0400, Harlan Lieberman-Berg wrote: > > (Resending as it seems to have been spamfiltered out from the ml; > > sorry Peter, Jarkko for the duplicate) > > I came on Monday from four week leave and have been basically been > catching up with my emails :-) I'll look into this next week with > time. The error message is saying that someone else has reserved the resource (-EBUSY). This looks odd: e78bf000-e7bbefff : ACPI Non-volatile Storage e7bb6000-e7bb9fff : MSFT0101:00 e7bba000-e7bbdfff : MSFT0101:00 Why would be TPM registers mapped inside ACPI NV? I would *guess* that what is happening is that perhaps drivers/acpi/nvs.c maps the address space. This looks like a firmware bug, and such that we cannot do anything about it. I'm having a weird issue with the ACPI tables: $ acpixtract acpidump.txt Intel ACPI Component Architecture ACPI Binary Table Extraction Utility version 20180105 Copyright (c) 2000 - 2018 Intel Corporation DSDT - 31048 bytes written (0x7948) - dsdt.dat SSDT - 349 bytes written (0x015D) - ssdt1.dat SSDT - 18086 bytes written (0x46A6) - ssdt2.dat SSDT -5225 bytes written (0x1469) - ssdt3.dat SSDT -1082 bytes written (0x043A) - ssdt4.dat SSDT -1017 bytes written (0x03F9) - ssdt5.dat SSDT -5369 bytes written (0x14F9) - ssdt6.dat $ iasl -d *.dat Intel ACPI Component Architecture ASL+ Optimizing Compiler/Disassembler version 20180105 Copyright (c) 2000 - 2018 Intel Corporation Input file dsdt.dat, Length 0x7948 (31048) bytes Table [DSDT] is too long for file - needs: 0x815D, remaining in file: 0x7948 Could not get ACPI tables from dsdt.dat, AE_BAD_HEADER This has not happened to me before. /Jarkko
Re: [PATCH] gpio: it87: Add support for IT8613
On Thu, Aug 9, 2018 at 12:27 AM Leonid Bloch wrote: > This was tested on actual hardware and found to work fine, but currently > the official specifications of this chip could not be obtained to > confirm the numbers. > > Signed-off-by: Leonid Bloch Patch applied. Yours, Linus Walleij
Re: [PATCH] gpio: it87: Add support for IT8613
On Thu, Aug 9, 2018 at 12:27 AM Leonid Bloch wrote: > This was tested on actual hardware and found to work fine, but currently > the official specifications of this chip could not be obtained to > confirm the numbers. > > Signed-off-by: Leonid Bloch Patch applied. Yours, Linus Walleij
Re: [PATCH] pinctrl: axp209: Fix NULL pointer dereference after allocation
On Mon, Aug 6, 2018 at 6:07 PM Anton Vasilyev wrote: > There is no check that allocation in axp20x_funcs_groups_from_mask > is successful. > The patch adds corresponding check and return values. > > Found by Linux Driver Verification project (linuxtesting.org). > > Signed-off-by: Anton Vasilyev Patch applied with Chen-Yu's ACK. Yours, Linus Walleij
Re: [PATCH] pinctrl: axp209: Fix NULL pointer dereference after allocation
On Mon, Aug 6, 2018 at 6:07 PM Anton Vasilyev wrote: > There is no check that allocation in axp20x_funcs_groups_from_mask > is successful. > The patch adds corresponding check and return values. > > Found by Linux Driver Verification project (linuxtesting.org). > > Signed-off-by: Anton Vasilyev Patch applied with Chen-Yu's ACK. Yours, Linus Walleij