Re: [kvm-unit-tests PATCH v2 04/13] treewide: lib/stack: Make base_address arch specific

2024-03-11 Thread Nicholas Piggin
On Wed Mar 6, 2024 at 3:09 AM AEST, Andrew Jones wrote:
> Calculating the offset of an address is image specific, which is
> architecture specific. Until now, all architectures and architecture
> configurations which select CONFIG_RELOC were able to subtract
> _etext, but the EFI configuration of riscv cannot (it must subtract
> ImageBase). Make this function weak, such that an architecture may
> override it when necessary, to accommodate the image layout. Then,
> immediately supply the riscv override.
>

Thanks for making these changes. Looks good. For the generic parts,

Reviewed-by: Nicholas Piggin 

Thanks,
Nick

> Signed-off-by: Andrew Jones 
> ---
>  lib/riscv/stack.c | 18 ++
>  lib/stack.c   |  8 
>  lib/stack.h   |  2 ++
>  3 files changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/lib/riscv/stack.c b/lib/riscv/stack.c
> index d865594b9671..2cd7f012738b 100644
> --- a/lib/riscv/stack.c
> +++ b/lib/riscv/stack.c
> @@ -2,6 +2,24 @@
>  #include 
>  #include 
>  
> +#ifdef CONFIG_RELOC
> +extern char ImageBase, _text, _etext;
> +
> +bool arch_base_address(const void *rebased_addr, unsigned long *addr)
> +{
> + unsigned long ra = (unsigned long)rebased_addr;
> + unsigned long base = (unsigned long)
> + unsigned long start = (unsigned long)&_text;
> + unsigned long end = (unsigned long)&_etext;
> +
> + if (ra < start || ra >= end)
> + return false;
> +
> + *addr = ra - base;
> + return true;
> +}
> +#endif
> +
>  int arch_backtrace_frame(const void *frame, const void **return_addrs,
>int max_depth, bool current_frame)
>  {
> diff --git a/lib/stack.c b/lib/stack.c
> index dd6bfa8dac6e..086fec544a81 100644
> --- a/lib/stack.c
> +++ b/lib/stack.c
> @@ -14,7 +14,7 @@
>  #ifdef CONFIG_RELOC
>  extern char _text, _etext;
>  
> -static bool base_address(const void *rebased_addr, unsigned long *addr)
> +bool __attribute__((weak)) arch_base_address(const void *rebased_addr, 
> unsigned long *addr)
>  {
>   unsigned long ra = (unsigned long)rebased_addr;
>   unsigned long start = (unsigned long)&_text;
> @@ -27,7 +27,7 @@ static bool base_address(const void *rebased_addr, unsigned 
> long *addr)
>   return true;
>  }
>  #else
> -static bool base_address(const void *rebased_addr, unsigned long *addr)
> +bool __attribute__((weak)) arch_base_address(const void *rebased_addr, 
> unsigned long *addr)
>  {
>   *addr = (unsigned long)rebased_addr;
>   return true;
> @@ -45,13 +45,13 @@ static void print_stack(const void **return_addrs, int 
> depth,
>   /* @addr indicates a non-return address, as expected by the stack
>* pretty printer script. */
>   if (depth > 0 && !top_is_return_address) {
> - if (base_address(return_addrs[0], ))
> + if (arch_base_address(return_addrs[0], ))
>   printf(" @%lx", addr);
>   i++;
>   }
>  
>   for (; i < depth; i++) {
> - if (base_address(return_addrs[i], ))
> + if (arch_base_address(return_addrs[i], ))
>   printf(" %lx", addr);
>   }
>   printf("\n");
> diff --git a/lib/stack.h b/lib/stack.h
> index 6edc84344b51..df076d94bf8f 100644
> --- a/lib/stack.h
> +++ b/lib/stack.h
> @@ -34,4 +34,6 @@ static inline int backtrace_frame(const void *frame, const 
> void **return_addrs,
>  }
>  #endif
>  
> +bool __attribute__((weak)) arch_base_address(const void *rebased_addr, 
> unsigned long *addr);
> +
>  #endif



Re: [PATCH v5 02/10] locking/mutex: introduce devm_mutex_init

2024-03-11 Thread Christophe Leroy


Le 12/03/2024 à 02:10, Waiman Long a écrit :
> On 3/11/24 19:47, George Stark wrote:
>> Hello Waiman, Marek
>>
>> Thanks for the review.
>>
>> I've never used lockdep for debug but it seems preferable to
>> keep that feature working. It could be look like this:
>>
>> diff --git a/include/linux/mutex.h b/include/linux/mutex.h
>> index f7611c092db7..574f6de6084d 100644
>> --- a/include/linux/mutex.h
>> +++ b/include/linux/mutex.h
>> @@ -22,6 +22,8 @@
>>  #include 
>>  #include 
>>
>> +struct device;
>> +
>>  #ifdef CONFIG_DEBUG_LOCK_ALLOC
>>  # define __DEP_MAP_MUTEX_INITIALIZER(lockname)    \
>>  , .dep_map = {    \
>> @@ -115,10 +117,31 @@ do {    \
>>
>>  #ifdef CONFIG_DEBUG_MUTEXES
>>
>> +int debug_devm_mutex_init(struct device *dev, struct mutex *lock);
>> +
>> +#define devm_mutex_init(dev, mutex)    \
>> +({    \
>> +    int ret;    \
>> +    mutex_init(mutex);    \
>> +    ret = debug_devm_mutex_init(dev, mutex);    \
>> +    ret;    \
>> +})
> 
> The int ret variable is not needed. The macro can just end with 
> debug_devm_mutex_init().
> 
> 
>> +
>>  void mutex_destroy(struct mutex *lock);
>>
>>  #else
>>
>> +/*
>> +* When CONFIG_DEBUG_MUTEXES is off mutex_destroy is just a nop so
>> +* there's no really need to register it in devm subsystem.
> "no really need"?
>> +*/
>> +#define devm_mutex_init(dev, mutex)    \
>> +({    \
>> +    typecheck(struct device *, dev);    \
>> +    mutex_init(mutex);    \
>> +    0;    \
>> +})
> 
> Do we need a typecheck() here? Compilation will fail with 
> CONFIG_DEBUG_MUTEXES if dev is not a device pointer.

I guess the idea is to have it fail _also_ when CONFIG_DEBUG_MUTEXES is 
not selected, in order to discover errors as soon as possible.

> 
> 
>> +
>>  static inline void mutex_destroy(struct mutex *lock) {}
>>
>>  #endif
>> diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c
>> index bc8abb8549d2..967a5367c79a 100644
>> --- a/kernel/locking/mutex-debug.c
>> +++ b/kernel/locking/mutex-debug.c
>> @@ -19,6 +19,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>
>>  #include "mutex.h"
>>
>> @@ -89,6 +90,16 @@ void debug_mutex_init(struct mutex *lock, const 
>> char *name,
>>  lock->magic = lock;
>>  }
>>
>> +static void devm_mutex_release(void *res)
>> +{
>> +    mutex_destroy(res);
>> +}
>> +
>> +int debug_devm_mutex_init(struct device *dev, struct mutex *lock)
>> +{
>> +    return devm_add_action_or_reset(dev, devm_mutex_release, lock);
>> +}
>> +
>>  /***
>>   * mutex_destroy - mark a mutex unusable
>>   * @lock: the mutex to be destroyed
> 


Re: [PATCH v5 02/10] locking/mutex: introduce devm_mutex_init

2024-03-11 Thread Christophe Leroy


Le 12/03/2024 à 01:01, George Stark a écrit :
> [Vous ne recevez pas souvent de courriers de gnst...@salutedevices.com. 
> Découvrez pourquoi ceci est important à 
> https://aka.ms/LearnAboutSenderIdentification ]
> 
> Hello Andy
> 
> On 3/7/24 13:34, Andy Shevchenko wrote:
>> On Thu, Mar 7, 2024 at 4:40 AM George Stark 
>>  wrote:
>>>
>>> Using of devm API leads to a certain order of releasing resources.
>>> So all dependent resources which are not devm-wrapped should be deleted
>>> with respect to devm-release order. Mutex is one of such objects that
>>> often is bound to other resources and has no own devm wrapping.
>>> Since mutex_destroy() actually does nothing in non-debug builds
>>> frequently calling mutex_destroy() is just ignored which is safe for now
>>> but wrong formally and can lead to a problem if mutex_destroy() will be
>>> extended so introduce devm_mutex_init()
>>>
>>> Signed-off-by: George Stark 
>>> Signed-off-by: Christophe Leroy 
>>
>>>   Hello Christophe. Hope you don't mind I put you SoB tag because you 
>>> helped alot
>>>   to make this patch happen.
>>
>> You also need to figure out who should be the author of the patch and
>> probably add a (missing) Co-developed-by. After all you should also
>> follow the correct order of SoBs.
>>
> 
> Thanks for the review.
> I explained in the other letter as I see it. So I'd leave myself
> as author and add appropriate tag with Christophe's name.
> BTW what do you mean by correct SoB order?
> Is it alphabetical order or order of importance?
> 

The correct order is to first have the Author's SoB.


Re: [PATCH v8 1/3] powerpc: make fadump resilient with memory add/remove events

2024-03-11 Thread Sourabh Jain

Hello Hari,

On 11/03/24 14:08, Hari Bathini wrote:



On 17/02/24 12:50 pm, Sourabh Jain wrote:

Due to changes in memory resources caused by either memory hotplug or
online/offline events, the elfcorehdr, which describes the CPUs and
memory of the crashed kernel to the kernel that collects the dump (known
as second/fadump kernel), becomes outdated. Consequently, attempting
dump collection with an outdated elfcorehdr can lead to failed or
inaccurate dump collection.

Memory hotplug or online/offline events is referred as memory add/remove
events in reset of the commit message.

The current solution to address the aforementioned issue is as follows:
Monitor memory add/remove events in userspace using udev rules, and
re-register fadump whenever there are changes in memory resources. This
leads to the creation of a new elfcorehdr with updated system memory
information.

There are several notable issues associated with re-registering fadump
for every memory add/remove events.

1. Bulk memory add/remove events with udev-based fadump re-registration
    can lead to race conditions and, more importantly, it creates a wide
    window during which fadump is inactive until all memory add/remove
    events are settled.
2. Re-registering fadump for every memory add/remove event is
    inefficient.
3. The memory for elfcorehdr is allocated based on the memblock regions
    available during early boot and remains fixed thereafter. 
However, if

    elfcorehdr is later recreated with additional memblock regions, its
    size will increase, potentially leading to memory corruption.

Address the aforementioned challenges by shifting the creation of
elfcorehdr from the first kernel (also referred as the crashed kernel),
where it was created and frequently recreated for every memory
add/remove event, to the fadump kernel. As a result, the elfcorehdr only
needs to be created once, thus eliminating the necessity to re-register
fadump during memory add/remove events.

At present, the first kernel is responsible for preparing the fadump
header and storing it in the fadump reserved area. The fadump header
includes the start address of the elfcorehdr, crashing CPU details, and
other relevant information. In the event of a crash in the first kernel,
the second/fadump boots and accesses the fadump header prepared by the
first kernel. It then performs the following steps in a
platform-specific function [rtas|opal]_fadump_process:

1. Sanity check for fadump header
2. Update CPU notes in elfcorehdr

Along with the above, update the setup_fadump()/fadump.c to create
elfcorehdr and set its address to the global variable elfcorehdr_addr
for the vmcore module to process it in the second/fadump kernel.

Section below outlines the information required to create the elfcorehdr
and the changes made to make it available to the fadump kernel if it's
not already.

To create elfcorehdr, the following crashed kernel information is
required: CPU notes, vmcoreinfo, and memory ranges.

At present, the CPU notes are already prepared in the fadump kernel, so
no changes are needed in that regard. The fadump kernel has access to
all crashed kernel memory regions, including boot memory regions that
are relocated by firmware to fadump reserved areas, so no changes for
that either. However, it is necessary to add new members to the fadump
header, i.e., the 'fadump_crash_info_header' structure, in order to pass
the crashed kernel's vmcoreinfo address and its size to fadump kernel.

In addition to the vmcoreinfo address and size, there are a few other
attributes also added to the fadump_crash_info_header structure.

1. version:
    It stores the fadump header version, which is currently set to 1.
    This provides flexibility to update the fadump crash info header in
    the future without changing the magic number. For each change in the
    fadump header, the version will be increased. This will help the
    updated kernel determine how to handle kernel dumps from older
    kernels. The magic number remains relevant for checking fadump 
header

    corruption.

2. pt_regs_sz/cpu_mask_sz:
    Store size of pt_regs and cpu_mask structure of first kernel. These
    attributes are used to prevent dump processing if the sizes of
    pt_regs or cpu_mask structure differ between the first and fadump
    kernels.

Note: if either first/crashed kernel or second/fadump kernel do not have
the changes introduced here then kernel fail to collect the dump and
prints relevant error message on the console.

Signed-off-by: Sourabh Jain 
Cc: Aditya Gupta 
Cc: Aneesh Kumar K.V 
Cc: Hari Bathini 
Cc: Mahesh Salgaonkar 
Cc: Michael Ellerman 
Cc: Naveen N Rao 
---
  arch/powerpc/include/asm/fadump-internal.h   |  31 +-
  arch/powerpc/kernel/fadump.c | 339 +++
  arch/powerpc/platforms/powernv/opal-fadump.c |  22 +-
  arch/powerpc/platforms/pseries/rtas-fadump.c |  30 +-
  4 files changed, 232 insertions(+), 190 deletions(-)

diff --git 

Re: [PATCH v5 02/10] locking/mutex: introduce devm_mutex_init

2024-03-11 Thread Waiman Long

On 3/11/24 19:47, George Stark wrote:

Hello Waiman, Marek

Thanks for the review.

I've never used lockdep for debug but it seems preferable to
keep that feature working. It could be look like this:

diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index f7611c092db7..574f6de6084d 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -22,6 +22,8 @@
 #include 
 #include 

+struct device;
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 # define __DEP_MAP_MUTEX_INITIALIZER(lockname)    \
 , .dep_map = {    \
@@ -115,10 +117,31 @@ do {    \

 #ifdef CONFIG_DEBUG_MUTEXES

+int debug_devm_mutex_init(struct device *dev, struct mutex *lock);
+
+#define devm_mutex_init(dev, mutex)    \
+({    \
+    int ret;    \
+    mutex_init(mutex);    \
+    ret = debug_devm_mutex_init(dev, mutex);    \
+    ret;    \
+})


The int ret variable is not needed. The macro can just end with 
debug_devm_mutex_init().




+
 void mutex_destroy(struct mutex *lock);

 #else

+/*
+* When CONFIG_DEBUG_MUTEXES is off mutex_destroy is just a nop so
+* there's no really need to register it in devm subsystem.

"no really need"?

+*/
+#define devm_mutex_init(dev, mutex)    \
+({    \
+    typecheck(struct device *, dev);    \
+    mutex_init(mutex);    \
+    0;    \
+})


Do we need a typecheck() here? Compilation will fail with 
CONFIG_DEBUG_MUTEXES if dev is not a device pointer.




+
 static inline void mutex_destroy(struct mutex *lock) {}

 #endif
diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c
index bc8abb8549d2..967a5367c79a 100644
--- a/kernel/locking/mutex-debug.c
+++ b/kernel/locking/mutex-debug.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "mutex.h"

@@ -89,6 +90,16 @@ void debug_mutex_init(struct mutex *lock, const 
char *name,

 lock->magic = lock;
 }

+static void devm_mutex_release(void *res)
+{
+    mutex_destroy(res);
+}
+
+int debug_devm_mutex_init(struct device *dev, struct mutex *lock)
+{
+    return devm_add_action_or_reset(dev, devm_mutex_release, lock);
+}
+
 /***
  * mutex_destroy - mark a mutex unusable
  * @lock: the mutex to be destroyed




Re: [PATCH v5 02/10] locking/mutex: introduce devm_mutex_init

2024-03-11 Thread George Stark

Hello Andy

On 3/7/24 13:34, Andy Shevchenko wrote:

On Thu, Mar 7, 2024 at 4:40 AM George Stark  wrote:


Using of devm API leads to a certain order of releasing resources.
So all dependent resources which are not devm-wrapped should be deleted
with respect to devm-release order. Mutex is one of such objects that
often is bound to other resources and has no own devm wrapping.
Since mutex_destroy() actually does nothing in non-debug builds
frequently calling mutex_destroy() is just ignored which is safe for now
but wrong formally and can lead to a problem if mutex_destroy() will be
extended so introduce devm_mutex_init()

Signed-off-by: George Stark 
Signed-off-by: Christophe Leroy 



  Hello Christophe. Hope you don't mind I put you SoB tag because you helped 
alot
  to make this patch happen.


You also need to figure out who should be the author of the patch and
probably add a (missing) Co-developed-by. After all you should also
follow the correct order of SoBs.



Thanks for the review.
I explained in the other letter as I see it. So I'd leave myself
as author and add appropriate tag with Christophe's name.
BTW what do you mean by correct SoB order?
Is it alphabetical order or order of importance?

--
Best regards
George


Re: [PATCH v5 02/10] locking/mutex: introduce devm_mutex_init

2024-03-11 Thread George Stark

Hello Waiman, Marek

Thanks for the review.

I've never used lockdep for debug but it seems preferable to
keep that feature working. It could be look like this:


diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index f7611c092db7..574f6de6084d 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -22,6 +22,8 @@
 #include 
 #include 

+struct device;
+
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 # define __DEP_MAP_MUTEX_INITIALIZER(lockname) \
, .dep_map = {  \
@@ -115,10 +117,31 @@ do {  
\

 #ifdef CONFIG_DEBUG_MUTEXES

+int debug_devm_mutex_init(struct device *dev, struct mutex *lock);
+
+#define devm_mutex_init(dev, mutex)\
+({ \
+   int ret;\
+   mutex_init(mutex);  \
+   ret = debug_devm_mutex_init(dev, mutex);\
+   ret;\
+})
+
 void mutex_destroy(struct mutex *lock);

 #else

+/*
+* When CONFIG_DEBUG_MUTEXES is off mutex_destroy is just a nop so
+* there's no really need to register it in devm subsystem.
+*/
+#define devm_mutex_init(dev, mutex)\
+({ \
+   typecheck(struct device *, dev);\
+   mutex_init(mutex);  \
+   0;  \
+})
+
 static inline void mutex_destroy(struct mutex *lock) {}

 #endif
diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c
index bc8abb8549d2..967a5367c79a 100644
--- a/kernel/locking/mutex-debug.c
+++ b/kernel/locking/mutex-debug.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "mutex.h"

@@ -89,6 +90,16 @@ void debug_mutex_init(struct mutex *lock, const char 
*name,

lock->magic = lock;
 }

+static void devm_mutex_release(void *res)
+{
+   mutex_destroy(res);
+}
+
+int debug_devm_mutex_init(struct device *dev, struct mutex *lock)
+{
+   return devm_add_action_or_reset(dev, devm_mutex_release, lock);
+}
+
 /***
  * mutex_destroy - mark a mutex unusable
  * @lock: the mutex to be destroyed
--
2.25.1



And now I would drop the the refactoring patch with moving down 
mutex_destroy. devm block is big enough to be declared standalone.



On 3/7/24 19:44, Marek Behún wrote:

On Thu, 7 Mar 2024 08:39:46 -0500
Waiman Long  wrote:


On 3/7/24 04:56, Marek Behún wrote:

On Thu, Mar 07, 2024 at 05:40:26AM +0300, George Stark wrote:

Using of devm API leads to a certain order of releasing resources.
So all dependent resources which are not devm-wrapped should be deleted
with respect to devm-release order. Mutex is one of such objects that
often is bound to other resources and has no own devm wrapping.
Since mutex_destroy() actually does nothing in non-debug builds
frequently calling mutex_destroy() is just ignored which is safe for now
but wrong formally and can lead to a problem if mutex_destroy() will be
extended so introduce devm_mutex_init()

Signed-off-by: George Stark 
Signed-off-by: Christophe Leroy 
---
   Hello Christophe. Hope you don't mind I put you SoB tag because you helped 
alot
   to make this patch happen.

   include/linux/mutex.h| 13 +
   kernel/locking/mutex-debug.c | 22 ++
   2 files changed, 35 insertions(+)

diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index f7611c092db7..9bcf72cb941a 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -22,6 +22,8 @@
   #include 
   #include 

+struct device;
+
   #ifdef CONFIG_DEBUG_LOCK_ALLOC
   # define __DEP_MAP_MUTEX_INITIALIZER(lockname)   \
, .dep_map = {  \
@@ -115,10 +117,21 @@ do {  
\

   #ifdef CONFIG_DEBUG_MUTEXES

+int devm_mutex_init(struct device *dev, struct mutex *lock);
   void mutex_destroy(struct mutex *lock);

   #else

+static inline int devm_mutex_init(struct device *dev, struct mutex *lock)
+{
+   /*
+* since mutex_destroy is nop actually there's no need to register it
+* in devm subsystem.
+*/
+   mutex_init(lock);
+   return 0;
+}
+
   static inline void mutex_destroy(struct mutex *lock) {}

   #endif
diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c
index bc8abb8549d2..c9efab1a8026 100644
--- a/kernel/locking/mutex-debug.c
+++ b/kernel/locking/mutex-debug.c
@@ -19,6 +19,7 @@
   #include 
   #include 
   #include 
+#include 

   #include "mutex.h"

@@ -104,3 +105,24 @@ void mutex_destroy(struct mutex *lock)
   }

   EXPORT_SYMBOL_GPL(mutex_destroy);
+
+static void devm_mutex_release(void *res)
+{
+   mutex_destroy(res);
+}
+
+/**
+ * devm_mutex_init - Resource-managed mutex initialization
+ * @dev:  

Re: [PATCH v5 02/10] locking/mutex: introduce devm_mutex_init

2024-03-11 Thread George Stark

Hello Christophe

On 3/7/24 16:50, Christophe Leroy wrote:



Le 07/03/2024 à 03:40, George Stark a écrit :

[Vous ne recevez pas souvent de courriers de gnst...@salutedevices.com. 
Découvrez pourquoi ceci est important à 
https://aka.ms/LearnAboutSenderIdentification ]

Using of devm API leads to a certain order of releasing resources.
So all dependent resources which are not devm-wrapped should be deleted
with respect to devm-release order. Mutex is one of such objects that
often is bound to other resources and has no own devm wrapping.
Since mutex_destroy() actually does nothing in non-debug builds
frequently calling mutex_destroy() is just ignored which is safe for now
but wrong formally and can lead to a problem if mutex_destroy() will be
extended so introduce devm_mutex_init()

Signed-off-by: George Stark 
Signed-off-by: Christophe Leroy 
---
   Hello Christophe. Hope you don't mind I put you SoB tag because you helped 
alot
   to make this patch happen.


Up to you, I sent a RFC patch based on yours with my ideas included
because an exemple is easier than a lot of words for understanding, and
my scripts automatically sets the Signed-off-by: but feel free to change
it to Suggested-by:


Although we had close ideas for the final patch in v4
you encouraged me to do it in the right (=effective) way and go back
from devm-helpers.h to mutex.h in the first place, reinforced the 
concept with appropriate examples from existing code, reviewed a lot. 
Thanks. Probably Suggested-by: is more suited here


--
Best regards
George


Re: [PATCH v9 07/10] PCI: dwc: ep: Remove "core_init_notifier" flag

2024-03-11 Thread Niklas Cassel
On Mon, Mar 11, 2024 at 08:15:59PM +0530, Manivannan Sadhasivam wrote:
> > 
> > I would say that it is the following change that breaks things:
> > 
> > > - if (!core_init_notifier) {
> > > - ret = pci_epf_test_core_init(epf);
> > > - if (ret)
> > > - return ret;
> > > - }
> > > -
> > 
> > Since without this code, pci_epf_test_core_init() will no longer be called,
> > as there is currently no one that calls epf->core_init() for a EPF driver
> > after it has been bound. (For drivers that call dw_pcie_ep_init_notify() in
> > .probe())
> > 
> 
> Thanks a lot for testing, Niklas!
> 
> > I guess one way to solve this would be for the EPC core to keep track of
> > the current EPC "core state" (up/down). If the core is "up" at EPF .bind()
> > time, notify the EPF driver directly after .bind()?
> > 
> 
> Yeah, that's a good solution. But I think it would be better if the EPC caches
> all events if the EPF drivers are not available and dispatch them once the 
> bind
> happens for each EPF driver. Even though INIT_COMPLETE is the only event that 
> is
> getting generated before bind() now, IMO it is better to add provision to 
> catch
> other events also.
> 
> Wdyt?

I'm not sure.
What if the EPF goes up/down/up, it seems a bit silly to send all those
events to the EPF driver that will alloc+free+alloc.

Do we know for sure that we will want to store + replay events other than
INIT_COMPLETE?

And how many events should we store?


Until we can think of a good reason which events other than UP/DOWN we
can to store, I think that just storing the state as an integer in
struct pci_epc seems simpler.


Or I guess we could continue with a flag in struct pci_epc_features,
like has_perst_notifier, which would then require the EPC driver to
call both epc_notify_core_up() and epc_notify_core_down() when receiving
the PERST deassert/assert.
For a driver without the flag set, the EPC core would call
.epc_notify_core_up() after bind. (And .epc_notify_core_down() would never
be called, or it could call it before unbind().)
That way an EPF driver itself would not need any different handling
(all callbacks would always come, either triggered by an EPC driver that
has PERST GPIO irq, or triggered by the EPC core for a driver that lacks
a PERST GPIO).


Kind regards,
Niklas


Re: [PATCH v7 0/5] Add support for QMC HDLC

2024-03-11 Thread Jakub Kicinski
On Thu,  7 Mar 2024 12:39:03 +0100 Herve Codina wrote:
> This series introduces the QMC HDLC support.
> 
> Patches were previously sent as part of a full feature series and were
> previously reviewed in that context:
> "Add support for QMC HDLC, framer infrastructure and PEF2256 framer" [1]
> 
> In order to ease the merge, the full feature series has been split and
> needed parts were merged in v6.8-rc1:
>  - "Prepare the PowerQUICC QMC and TSA for the HDLC QMC driver" [2]
>  - "Add support for framer infrastructure and PEF2256 framer" [3]
> 
> This series contains patches related to the QMC HDLC part (QMC HDLC
> driver):
>  - Introduce the QMC HDLC driver (patches 1 and 2)
>  - Add timeslots change support in QMC HDLC (patch 3)
>  - Add framer support as a framer consumer in QMC HDLC (patch 4)
> 
> Compare to the original full feature series, a modification was done on
> patch 3 in order to use a coherent prefix in the commit title.
> 
> I kept the patches unsquashed as they were previously sent and reviewed.
> Of course, I can squash them if needed.

Applied, thank you!


Re: [RFC PATCH v2 3/3] tpm: of: If available use linux,sml-log to get the log and its size

2024-03-11 Thread Stefan Berger




On 3/11/24 16:25, Jarkko Sakkinen wrote:

On Mon Mar 11, 2024 at 3:20 PM EET, Stefan Berger wrote:

If linux,sml-log is available use it to get the TPM log rather than the
pointer found in linux,sml-base. This resolves an issue on PowerVM and KVM
on Power where after a kexec the memory pointed to by linux,sml-base may
have become inaccessible or corrupted. Also, linux,sml-log has replaced
linux,sml-base and linux,sml-size on these two platforms.

Keep the handling of linux,sml-base/sml-size for powernv platforms that
provide the two properties via skiboot.

Fixes: c5df39262dd5 ("drivers/char/tpm: Add securityfs support for event log")
Signed-off-by: Stefan Berger 


I'm worried about not being up to date and instead using "cached" values
when verifying anything from a security chip. Does this guarantee that
TPM log is corrupted and will not get updated somehow?



What do you mean 'guarantee that TPM log is corrupted'?

The TPM was handed over from the firmware to Linux and the firmware then 
freed all memory associated with the log and will then not create a new 
log or touch the TPM or do anything that would require an update to the 
handed-over log. Linux also does not append to the firmware log. So 
whatever we now find in linux,sml-log would be the latest firmware log 
and the state of the 'firmware PCRs' computed from it should correspond 
to the current state of the 'firmware PCRs'.




BR, Jarkko



Re: [RFC PATCH v2 3/3] tpm: of: If available use linux,sml-log to get the log and its size

2024-03-11 Thread Jarkko Sakkinen
On Mon Mar 11, 2024 at 3:20 PM EET, Stefan Berger wrote:
> If linux,sml-log is available use it to get the TPM log rather than the
> pointer found in linux,sml-base. This resolves an issue on PowerVM and KVM
> on Power where after a kexec the memory pointed to by linux,sml-base may
> have become inaccessible or corrupted. Also, linux,sml-log has replaced
> linux,sml-base and linux,sml-size on these two platforms.
>
> Keep the handling of linux,sml-base/sml-size for powernv platforms that
> provide the two properties via skiboot.
>
> Fixes: c5df39262dd5 ("drivers/char/tpm: Add securityfs support for event log")
> Signed-off-by: Stefan Berger 

I'm worried about not being up to date and instead using "cached" values
when verifying anything from a security chip. Does this guarantee that
TPM log is corrupted and will not get updated somehow?

BR, Jarkko


Re: [RFC PATCH v2 1/3] powerpc/prom_init: Replace linux,sml-base/sml-size with linux,sml-log

2024-03-11 Thread Jarkko Sakkinen
On Mon Mar 11, 2024 at 3:20 PM EET, Stefan Berger wrote:
> linux,sml-base holds the address of a buffer with the TPM log. This
> buffer may become invalid after a kexec. To avoid accessing an invalid
> address or corrupted buffer, embed the whole TPM log in the device tree
> property linux,sml-log. This helps to protect the log since it is
> properly carried across a kexec soft reboot with both of the kexec
> syscalls.

- Describe the environment where TPM log gets corrupted.
- Describe why TPM log gets corrupted on kexec.

>
> Avoid having the firmware ingest the whole TPM log when calling
> prom_setprop but only create the linux,sml-log property as a place holder.
> Insert the actual TPM log during the tree flattening phase.

This commit message should shed some light about reasons of the
corruption in order to conclude that it should be fixed up like
this. I.e. why the "post-state" is a legit state where can be
continued despite a log being corrupted. Especially in security
features this is pretty essential information.

BR, Jarkko


Re: [PATCH 2/2] tpm: of: If available Use linux,sml-log to get the log and its size

2024-03-11 Thread Jarkko Sakkinen
On Fri Mar 8, 2024 at 2:17 PM EET, Stefan Berger wrote:
>
>
> On 3/7/24 15:00, Jarkko Sakkinen wrote:
> > On Thu Mar 7, 2024 at 9:57 PM EET, Jarkko Sakkinen wrote:
> >> in short summary: s/Use/use/
> >>
> >> On Wed Mar 6, 2024 at 5:55 PM EET, Stefan Berger wrote:
> >>> If linux,sml-log is available use it to get the TPM log rather than the
> >>> pointer found in linux,sml-base. This resolves an issue on PowerVM and KVM
> >>> on Power where after a kexec the memory pointed to by linux,sml-base may
> >>> have been corrupted. Also, linux,sml-log has replaced linux,sml-base and
> >>> linux,sml-size on these two platforms.
> >>>
> >>> Signed-off-by: Stefan Berger 
> >>
> >> So shouldn't this have a fixed tag, or not?
> > 
> > In English: do we want this to be backported to stable kernel releases or 
> > not?
>
> Ideally, yes. v3 will have 3 patches and all 3 of them will have to be 
> backported *together* and not applied otherwise if any one of them 
> fails. Can this be 'guaranteed'?

All of them will end up to stable if the following conditions hold:

- All have a fixes tag.
- All have "Cc: sta...@vger.kernel.org".
- We agree in the review process that they are all legit fixes.

BR, Jarkko


Re: [PATCH v6 3/6] KEYS: trusted: Introduce NXP DCP-backed trusted keys

2024-03-11 Thread Jarkko Sakkinen
On Fri Mar 8, 2024 at 9:17 AM EET, David Gstir wrote:
> Hi Jarkko,
>
> > On 07.03.2024, at 20:30, Jarkko Sakkinen  wrote:
>
> [...]
>
> >> +
> >> +static int trusted_dcp_init(void)
> >> +{
> >> + int ret;
> >> +
> >> + if (use_otp_key)
> >> + pr_info("Using DCP OTP key\n");
> >> +
> >> + ret = test_for_zero_key();
> >> + if (ret) {
> >> + pr_err("Test for zero'ed keys failed: %i\n", ret);
> > 
> > I'm not sure whether this should err or warn.
> > 
> > What sort of situations can cause the test the fail (e.g.
> > adversary/interposer, bad configuration etc.).
>
> This occurs when the hardware is not in "secure mode". I.e. it’s a bad 
> configuration issue.
> Once the board is properly configured, this will never trigger again.
> Do you think a warning is better for this then?

Bad configuration is not unexpected configuration so it cannot possibly
be an error situation as far as Linux is considered. So warning is 
appropriate here I'd figure.

BR, Jarkko


Re: [RFC PATCH v2 1/3] powerpc/prom_init: Replace linux,sml-base/sml-size with linux,sml-log

2024-03-11 Thread Stefan Berger




On 3/11/24 13:24, Christophe Leroy wrote:



Le 11/03/2024 à 14:20, Stefan Berger a écrit :

linux,sml-base holds the address of a buffer with the TPM log. This
buffer may become invalid after a kexec. To avoid accessing an invalid
address or corrupted buffer, embed the whole TPM log in the device tree
property linux,sml-log. This helps to protect the log since it is
properly carried across a kexec soft reboot with both of the kexec
syscalls.

Avoid having the firmware ingest the whole TPM log when calling
prom_setprop but only create the linux,sml-log property as a place holder.
Insert the actual TPM log during the tree flattening phase.

Fixes: 4a727429abec ("PPC64: Add support for instantiating SML from Open 
Firmware")
Suggested-by: Michael Ellerman 
Signed-off-by: Stefan Berger 
---



@@ -2645,6 +2645,17 @@ static void __init scan_dt_build_struct(phandle node, 
unsigned long *mem_start,
}
prev_name = sstart + soff;
   
+		if (!prom_strcmp("linux,sml-log", pname)) {

+   /* push property head */
+   dt_push_token(OF_DT_PROP, mem_start, mem_end);
+   dt_push_token(sml_size, mem_start, mem_end);
+   dt_push_token(soff, mem_start, mem_end);
+   /* push property content */
+   valp = make_room(mem_start, mem_end, sml_size, 1);
+   memcpy(valp, (void *)sml_base, sml_size);


You can't cast a u64 into a pointer. If sml_base is an address, it must
be declared as an unsigned long.

Build with pmac32_defconfig :

CC  arch/powerpc/kernel/prom_init.o
arch/powerpc/kernel/prom_init.c: In function 'scan_dt_build_struct':
arch/powerpc/kernel/prom_init.c:2663:38: error: cast to pointer from
integer of different size [-Werror=int-to-pointer-cast]
   2663 | memcpy(valp, (void *)sml_base, sml_size);
|  ^
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243:
arch/powerpc/kernel/prom_init.o] Error 1


Next round will have this block under #ifdef CONFIG_PPC64.

Thanks.


Re: [RFC PATCH v2 1/3] powerpc/prom_init: Replace linux,sml-base/sml-size with linux,sml-log

2024-03-11 Thread Jerry Snitselaar
On Mon, Mar 11, 2024 at 09:20:28AM -0400, Stefan Berger wrote:
> linux,sml-base holds the address of a buffer with the TPM log. This
> buffer may become invalid after a kexec. To avoid accessing an invalid
> address or corrupted buffer, embed the whole TPM log in the device tree
> property linux,sml-log. This helps to protect the log since it is
> properly carried across a kexec soft reboot with both of the kexec
> syscalls.
> 
> Avoid having the firmware ingest the whole TPM log when calling
> prom_setprop but only create the linux,sml-log property as a place holder.
> Insert the actual TPM log during the tree flattening phase.
> 
> Fixes: 4a727429abec ("PPC64: Add support for instantiating SML from Open 
> Firmware")
> Suggested-by: Michael Ellerman 
> Signed-off-by: Stefan Berger 
> ---
>  arch/powerpc/kernel/prom_init.c | 27 +++
>  1 file changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index e67effdba85c..6f7ca72013c2 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -211,6 +211,8 @@ static cell_t __prombss regbuf[1024];
>  
>  static bool  __prombss rtas_has_query_cpu_stopped;
>  
> +static u64 __prombss sml_base;
> +static u32 __prombss sml_size;

Should inside an #ifdef CONFIG_PPC64 since prom_instantiate_sml() is?

>  
>  /*
>   * Error results ... some OF calls will return "-1" on error, some
> @@ -1954,17 +1956,15 @@ static void __init prom_instantiate_sml(void)
>   }
>   prom_printf(" done\n");
>  
> - reserve_mem(base, size);
> -
> - prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-base",
> -  , sizeof(base));
> - prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-size",
> -  , sizeof(size));
> -
> - prom_debug("sml base = 0x%llx\n", base);
> + /* Add property now, defer adding log to tree flattening phase */
> + prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-log",
> +  NULL, 0);
>   prom_debug("sml size = 0x%x\n", size);
>  
>   prom_debug("prom_instantiate_sml: end...\n");
> +
> + sml_base = base;
> + sml_size = size;
>  }
>  
>  /*
> @@ -2645,6 +2645,17 @@ static void __init scan_dt_build_struct(phandle node, 
> unsigned long *mem_start,
>   }
>   prev_name = sstart + soff;
>  
> + if (!prom_strcmp("linux,sml-log", pname)) {
> + /* push property head */
> + dt_push_token(OF_DT_PROP, mem_start, mem_end);
> + dt_push_token(sml_size, mem_start, mem_end);
> + dt_push_token(soff, mem_start, mem_end);
> + /* push property content */
> + valp = make_room(mem_start, mem_end, sml_size, 1);
> + memcpy(valp, (void *)sml_base, sml_size);
> + *mem_start = ALIGN(*mem_start, 4);
> + continue;
> + }

Same question as above.

Regards,
Jerry

>   /* get length */
>   l = call_prom("getproplen", 2, 1, node, pname);
>  
> -- 
> 2.43.0
> 



Re: [RFC PATCH v2 1/3] powerpc/prom_init: Replace linux,sml-base/sml-size with linux,sml-log

2024-03-11 Thread Christophe Leroy


Le 11/03/2024 à 14:20, Stefan Berger a écrit :
> linux,sml-base holds the address of a buffer with the TPM log. This
> buffer may become invalid after a kexec. To avoid accessing an invalid
> address or corrupted buffer, embed the whole TPM log in the device tree
> property linux,sml-log. This helps to protect the log since it is
> properly carried across a kexec soft reboot with both of the kexec
> syscalls.
> 
> Avoid having the firmware ingest the whole TPM log when calling
> prom_setprop but only create the linux,sml-log property as a place holder.
> Insert the actual TPM log during the tree flattening phase.
> 
> Fixes: 4a727429abec ("PPC64: Add support for instantiating SML from Open 
> Firmware")
> Suggested-by: Michael Ellerman 
> Signed-off-by: Stefan Berger 
> ---
>   arch/powerpc/kernel/prom_init.c | 27 +++
>   1 file changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index e67effdba85c..6f7ca72013c2 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -211,6 +211,8 @@ static cell_t __prombss regbuf[1024];
>   
>   static bool  __prombss rtas_has_query_cpu_stopped;
>   
> +static u64 __prombss sml_base;
> +static u32 __prombss sml_size;
>   
>   /*
>* Error results ... some OF calls will return "-1" on error, some
> @@ -1954,17 +1956,15 @@ static void __init prom_instantiate_sml(void)
>   }
>   prom_printf(" done\n");
>   
> - reserve_mem(base, size);
> -
> - prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-base",
> -  , sizeof(base));
> - prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-size",
> -  , sizeof(size));
> -
> - prom_debug("sml base = 0x%llx\n", base);
> + /* Add property now, defer adding log to tree flattening phase */
> + prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-log",
> +  NULL, 0);
>   prom_debug("sml size = 0x%x\n", size);
>   
>   prom_debug("prom_instantiate_sml: end...\n");
> +
> + sml_base = base;
> + sml_size = size;
>   }
>   
>   /*
> @@ -2645,6 +2645,17 @@ static void __init scan_dt_build_struct(phandle node, 
> unsigned long *mem_start,
>   }
>   prev_name = sstart + soff;
>   
> + if (!prom_strcmp("linux,sml-log", pname)) {
> + /* push property head */
> + dt_push_token(OF_DT_PROP, mem_start, mem_end);
> + dt_push_token(sml_size, mem_start, mem_end);
> + dt_push_token(soff, mem_start, mem_end);
> + /* push property content */
> + valp = make_room(mem_start, mem_end, sml_size, 1);
> + memcpy(valp, (void *)sml_base, sml_size);

You can't cast a u64 into a pointer. If sml_base is an address, it must 
be declared as an unsigned long.

Build with pmac32_defconfig :

   CC  arch/powerpc/kernel/prom_init.o
arch/powerpc/kernel/prom_init.c: In function 'scan_dt_build_struct':
arch/powerpc/kernel/prom_init.c:2663:38: error: cast to pointer from 
integer of different size [-Werror=int-to-pointer-cast]
  2663 | memcpy(valp, (void *)sml_base, sml_size);
   |  ^
cc1: all warnings being treated as errors
make[4]: *** [scripts/Makefile.build:243: 
arch/powerpc/kernel/prom_init.o] Error 1


> + *mem_start = ALIGN(*mem_start, 4);
> + continue;
> + }
>   /* get length */
>   l = call_prom("getproplen", 2, 1, node, pname);
>   


[PATCH net v5 1/2] soc: fsl: qbman: Always disable interrupts when taking cgr_lock

2024-03-11 Thread Sean Anderson
smp_call_function_single disables IRQs when executing the callback. To
prevent deadlocks, we must disable IRQs when taking cgr_lock elsewhere.
This is already done by qman_update_cgr and qman_delete_cgr; fix the
other lockers.

Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
CC: sta...@vger.kernel.org
Signed-off-by: Sean Anderson 
Reviewed-by: Camelia Groza 
Tested-by: Vladimir Oltean 
---
Resent from a non-mangling email.

(no changes since v3)

Changes in v3:
- Change blamed commit to something more appropriate

Changes in v2:
- Fix one additional call to spin_unlock

 drivers/soc/fsl/qbman/qman.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 739e4eee6b75..1bf1f1ea67f0 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -1456,11 +1456,11 @@ static void qm_congestion_task(struct work_struct *work)
union qm_mc_result *mcr;
struct qman_cgr *cgr;
 
-   spin_lock(>cgr_lock);
+   spin_lock_irq(>cgr_lock);
qm_mc_start(>p);
qm_mc_commit(>p, QM_MCC_VERB_QUERYCONGESTION);
if (!qm_mc_result_timeout(>p, )) {
-   spin_unlock(>cgr_lock);
+   spin_unlock_irq(>cgr_lock);
dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
qman_p_irqsource_add(p, QM_PIRQ_CSCI);
return;
@@ -1476,7 +1476,7 @@ static void qm_congestion_task(struct work_struct *work)
list_for_each_entry(cgr, >cgr_cbs, node)
if (cgr->cb && qman_cgrs_get(, cgr->cgrid))
cgr->cb(p, cgr, qman_cgrs_get(, cgr->cgrid));
-   spin_unlock(>cgr_lock);
+   spin_unlock_irq(>cgr_lock);
qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 }
 
@@ -2440,7 +2440,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
preempt_enable();
 
cgr->chan = p->config->channel;
-   spin_lock(>cgr_lock);
+   spin_lock_irq(>cgr_lock);
 
if (opts) {
struct qm_mcc_initcgr local_opts = *opts;
@@ -2477,7 +2477,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
qman_cgrs_get(>cgrs[1], cgr->cgrid))
cgr->cb(p, cgr, 1);
 out:
-   spin_unlock(>cgr_lock);
+   spin_unlock_irq(>cgr_lock);
put_affine_portal();
return ret;
 }
-- 
2.35.1.1320.gc452695387.dirty



[PATCH net v5 2/2] soc: fsl: qbman: Use raw spinlock for cgr_lock

2024-03-11 Thread Sean Anderson
smp_call_function always runs its callback in hard IRQ context, even on
PREEMPT_RT, where spinlocks can sleep. So we need to use a raw spinlock
for cgr_lock to ensure we aren't waiting on a sleeping task.

Although this bug has existed for a while, it was not apparent until
commit ef2a8d5478b9 ("net: dpaa: Adjust queue depth on rate change")
which invokes smp_call_function_single via qman_update_cgr_safe every
time a link goes up or down.

Fixes: 96f413f47677 ("soc/fsl/qbman: fix issue in qman_delete_cgr_safe()")
CC: sta...@vger.kernel.org
Reported-by: Vladimir Oltean 
Closes: https://lore.kernel.org/all/20230323153935.nofnjucqjqnz34ej@skbuf/
Reported-by: Steffen Trumtrar 
Closes: https://lore.kernel.org/linux-arm-kernel/87wmsyvclu@pengutronix.de/
Signed-off-by: Sean Anderson 
Reviewed-by: Camelia Groza 
Tested-by: Vladimir Oltean 

---

Changes in v5:
- Clarify commit message

Changes in v4:
- Add a note about how raw spinlocks aren't quite right

Changes in v3:
- Change blamed commit to something more appropriate

 drivers/soc/fsl/qbman/qman.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c
index 1bf1f1ea67f0..7e9074519ad2 100644
--- a/drivers/soc/fsl/qbman/qman.c
+++ b/drivers/soc/fsl/qbman/qman.c
@@ -991,7 +991,7 @@ struct qman_portal {
/* linked-list of CSCN handlers. */
struct list_head cgr_cbs;
/* list lock */
-   spinlock_t cgr_lock;
+   raw_spinlock_t cgr_lock;
struct work_struct congestion_work;
struct work_struct mr_work;
char irqname[MAX_IRQNAME];
@@ -1281,7 +1281,7 @@ static int qman_create_portal(struct qman_portal *portal,
/* if the given mask is NULL, assume all CGRs can be seen */
qman_cgrs_fill(>cgrs[0]);
INIT_LIST_HEAD(>cgr_cbs);
-   spin_lock_init(>cgr_lock);
+   raw_spin_lock_init(>cgr_lock);
INIT_WORK(>congestion_work, qm_congestion_task);
INIT_WORK(>mr_work, qm_mr_process_task);
portal->bits = 0;
@@ -1456,11 +1456,14 @@ static void qm_congestion_task(struct work_struct *work)
union qm_mc_result *mcr;
struct qman_cgr *cgr;
 
-   spin_lock_irq(>cgr_lock);
+   /*
+* FIXME: QM_MCR_TIMEOUT is 10ms, which is too long for a raw spinlock!
+*/
+   raw_spin_lock_irq(>cgr_lock);
qm_mc_start(>p);
qm_mc_commit(>p, QM_MCC_VERB_QUERYCONGESTION);
if (!qm_mc_result_timeout(>p, )) {
-   spin_unlock_irq(>cgr_lock);
+   raw_spin_unlock_irq(>cgr_lock);
dev_crit(p->config->dev, "QUERYCONGESTION timeout\n");
qman_p_irqsource_add(p, QM_PIRQ_CSCI);
return;
@@ -1476,7 +1479,7 @@ static void qm_congestion_task(struct work_struct *work)
list_for_each_entry(cgr, >cgr_cbs, node)
if (cgr->cb && qman_cgrs_get(, cgr->cgrid))
cgr->cb(p, cgr, qman_cgrs_get(, cgr->cgrid));
-   spin_unlock_irq(>cgr_lock);
+   raw_spin_unlock_irq(>cgr_lock);
qman_p_irqsource_add(p, QM_PIRQ_CSCI);
 }
 
@@ -2440,7 +2443,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
preempt_enable();
 
cgr->chan = p->config->channel;
-   spin_lock_irq(>cgr_lock);
+   raw_spin_lock_irq(>cgr_lock);
 
if (opts) {
struct qm_mcc_initcgr local_opts = *opts;
@@ -2477,7 +2480,7 @@ int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
qman_cgrs_get(>cgrs[1], cgr->cgrid))
cgr->cb(p, cgr, 1);
 out:
-   spin_unlock_irq(>cgr_lock);
+   raw_spin_unlock_irq(>cgr_lock);
put_affine_portal();
return ret;
 }
@@ -2512,7 +2515,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
return -EINVAL;
 
memset(_opts, 0, sizeof(struct qm_mcc_initcgr));
-   spin_lock_irqsave(>cgr_lock, irqflags);
+   raw_spin_lock_irqsave(>cgr_lock, irqflags);
list_del(>node);
/*
 * If there are no other CGR objects for this CGRID in the list,
@@ -2537,7 +2540,7 @@ int qman_delete_cgr(struct qman_cgr *cgr)
/* add back to the list */
list_add(>node, >cgr_cbs);
 release_lock:
-   spin_unlock_irqrestore(>cgr_lock, irqflags);
+   raw_spin_unlock_irqrestore(>cgr_lock, irqflags);
put_affine_portal();
return ret;
 }
@@ -2577,9 +2580,9 @@ static int qman_update_cgr(struct qman_cgr *cgr, struct 
qm_mcc_initcgr *opts)
if (!p)
return -EINVAL;
 
-   spin_lock_irqsave(>cgr_lock, irqflags);
+   raw_spin_lock_irqsave(>cgr_lock, irqflags);
ret = qm_modify_cgr(cgr, 0, opts);
-   spin_unlock_irqrestore(>cgr_lock, irqflags);
+   raw_spin_unlock_irqrestore(>cgr_lock, irqflags);
put_affine_portal();
return ret;
 }
-- 
2.35.1.1320.gc452695387.dirty



Re: [PATCH v9 07/10] PCI: dwc: ep: Remove "core_init_notifier" flag

2024-03-11 Thread Manivannan Sadhasivam
On Fri, Mar 08, 2024 at 02:24:35PM +0100, Niklas Cassel wrote:
> On Mon, Mar 04, 2024 at 02:52:19PM +0530, Manivannan Sadhasivam wrote:
> > "core_init_notifier" flag is set by the glue drivers requiring refclk from
> > the host to complete the DWC core initialization. Also, those drivers will
> > send a notification to the EPF drivers once the initialization is fully
> > completed using the pci_epc_init_notify() API. Only then, the EPF drivers
> > will start functioning.
> > 
> > For the rest of the drivers generating refclk locally, EPF drivers will
> > start functioning post binding with them. EPF drivers rely on the
> > 'core_init_notifier' flag to differentiate between the drivers.
> > Unfortunately, this creates two different flows for the EPF drivers.
> > 
> > So to avoid that, let's get rid of the "core_init_notifier" flag and follow
> > a single initialization flow for the EPF drivers. This is done by calling
> > the dw_pcie_ep_init_notify() from all glue drivers after the completion of
> > dw_pcie_ep_init_registers() API. This will allow all the glue drivers to
> > send the notification to the EPF drivers once the initialization is fully
> > completed.
> > 
> > Only difference here is that, the drivers requiring refclk from host will
> > send the notification once refclk is received, while others will send it
> > during probe time itself.
> > 
> > Reviewed-by: Frank Li 
> > Signed-off-by: Manivannan Sadhasivam 
> > ---
> > diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c 
> > b/drivers/pci/endpoint/functions/pci-epf-test.c
> > index 18c80002d3bd..fc0282b0d626 100644
> > --- a/drivers/pci/endpoint/functions/pci-epf-test.c
> > +++ b/drivers/pci/endpoint/functions/pci-epf-test.c
> > @@ -927,21 +928,12 @@ static int pci_epf_test_bind(struct pci_epf *epf)
> > if (ret)
> > return ret;
> >
> 
> Hello Mani,
> 
> Since you asked for testing, I gave your series a spin
> (with a driver without .core_init_notifier).
> 
> 
> There seems to be a problem that pci_epc_write_header() is never called.
> 
> Debugging this, it seems that .core_init in pci-epf-test is never called.
> 
> If I add debug prints in pci_epc_init_notify(), I see that it does not
> notify a single EPF driver.
> 
> It appears that the patch in $subject will call pci_epc_init_notify()
> at EPC driver .probe() time, and at that point in time, there are no
> EPF drivers registered.
> 
> They get registered later, when doing the configfs write.
> 
> 
> I would say that it is the following change that breaks things:
> 
> > -   if (!core_init_notifier) {
> > -   ret = pci_epf_test_core_init(epf);
> > -   if (ret)
> > -   return ret;
> > -   }
> > -
> 
> Since without this code, pci_epf_test_core_init() will no longer be called,
> as there is currently no one that calls epf->core_init() for a EPF driver
> after it has been bound. (For drivers that call dw_pcie_ep_init_notify() in
> .probe())
> 

Thanks a lot for testing, Niklas!

> I guess one way to solve this would be for the EPC core to keep track of
> the current EPC "core state" (up/down). If the core is "up" at EPF .bind()
> time, notify the EPF driver directly after .bind()?
> 

Yeah, that's a good solution. But I think it would be better if the EPC caches
all events if the EPF drivers are not available and dispatch them once the bind
happens for each EPF driver. Even though INIT_COMPLETE is the only event that is
getting generated before bind() now, IMO it is better to add provision to catch
other events also.

Wdyt?

- Mani

-- 
மணிவண்ணன் சதாசிவம்


[RFC PATCH v2 2/3] dt-bindings: tpm: Add linux,sml-log to ibm,vtpm.yaml

2024-03-11 Thread Stefan Berger
Add linux,sml-log, which carries the firmware TPM log in a uint8-array, to
the properties. Either this property is required or both linux,sml-base and
linux,sml-size are required. Add a test case for verification.

Fixes: 82003e0487fb ("Documentation: tpm: add the IBM Virtual TPM device tree 
binding documentation")
Cc: Lukas Wunner 
Cc: Nayna Jain 
Signed-off-by: Michael Ellerman 
Signed-off-by: Stefan Berger 
---
 .../devicetree/bindings/tpm/ibm,vtpm.yaml | 20 +--
 .../devicetree/bindings/tpm/tpm-common.yaml   | 14 -
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/tpm/ibm,vtpm.yaml 
b/Documentation/devicetree/bindings/tpm/ibm,vtpm.yaml
index 50a3fd31241c..8885ef3b7638 100644
--- a/Documentation/devicetree/bindings/tpm/ibm,vtpm.yaml
+++ b/Documentation/devicetree/bindings/tpm/ibm,vtpm.yaml
@@ -74,8 +74,6 @@ required:
   - ibm,my-dma-window
   - ibm,my-drc-index
   - ibm,loc-code
-  - linux,sml-base
-  - linux,sml-size
 
 allOf:
   - $ref: tpm-common.yaml#
@@ -102,3 +100,21 @@ examples:
 linux,sml-size = <0xbce10200>;
 };
 };
+  - |
+soc {
+#address-cells = <1>;
+#size-cells = <0>;
+
+tpm@3003 {
+compatible = "IBM,vtpm20";
+device_type = "IBM,vtpm";
+reg = <0x3003>;
+interrupts = <0xa0003 0x0>;
+ibm,#dma-address-cells = <0x2>;
+ibm,#dma-size-cells = <0x2>;
+ibm,my-dma-window = <0x1003 0x0 0x0 0x0 0x1000>;
+ibm,my-drc-index = <0x3003>;
+ibm,loc-code = "U9080.HEX.134CA08-V7-C3";
+linux,sml-log = <00 00 00 00 03 00 00>;
+};
+};
diff --git a/Documentation/devicetree/bindings/tpm/tpm-common.yaml 
b/Documentation/devicetree/bindings/tpm/tpm-common.yaml
index 3c1241b2a43f..f6f0b551268c 100644
--- a/Documentation/devicetree/bindings/tpm/tpm-common.yaml
+++ b/Documentation/devicetree/bindings/tpm/tpm-common.yaml
@@ -30,6 +30,11 @@ properties:
   size of reserved memory allocated for firmware event log
 $ref: /schemas/types.yaml#/definitions/uint32
 
+  linux,sml-log:
+description:
+  Content of firmware event log
+$ref: /schemas/types.yaml#/definitions/uint8-array
+
   memory-region:
 description: reserved memory allocated for firmware event log
 maxItems: 1
@@ -53,15 +58,22 @@ dependentRequired:
   linux,sml-base: ['linux,sml-size']
   linux,sml-size: ['linux,sml-base']
 
-# must only have either memory-region or linux,sml-base
+# must only have either memory-region or linux,sml-base/size or linux,sml-log
 # as well as either resets or reset-gpios
 dependentSchemas:
   memory-region:
 properties:
   linux,sml-base: false
+  linux,sml-log: false
   linux,sml-base:
 properties:
   memory-region: false
+  linux,sml-log: false
+  linux,sml-log:
+properties:
+  memory-region: false
+  linux,sml-base: false
+  linux,sml-size: false
   resets:
 properties:
   reset-gpios: false
-- 
2.43.0



[RFC PATCH v2 3/3] tpm: of: If available use linux,sml-log to get the log and its size

2024-03-11 Thread Stefan Berger
If linux,sml-log is available use it to get the TPM log rather than the
pointer found in linux,sml-base. This resolves an issue on PowerVM and KVM
on Power where after a kexec the memory pointed to by linux,sml-base may
have become inaccessible or corrupted. Also, linux,sml-log has replaced
linux,sml-base and linux,sml-size on these two platforms.

Keep the handling of linux,sml-base/sml-size for powernv platforms that
provide the two properties via skiboot.

Fixes: c5df39262dd5 ("drivers/char/tpm: Add securityfs support for event log")
Signed-off-by: Stefan Berger 
---
 drivers/char/tpm/eventlog/of.c | 36 +++---
 1 file changed, 11 insertions(+), 25 deletions(-)

diff --git a/drivers/char/tpm/eventlog/of.c b/drivers/char/tpm/eventlog/of.c
index 930fe43d5daf..dbd837d65264 100644
--- a/drivers/char/tpm/eventlog/of.c
+++ b/drivers/char/tpm/eventlog/of.c
@@ -54,8 +54,8 @@ int tpm_read_log_of(struct tpm_chip *chip)
const u32 *sizep;
const u64 *basep;
struct tpm_bios_log *log;
+   const void *logp;
u32 size;
-   u64 base;
 
log = >log;
if (chip->dev.parent && chip->dev.parent->of_node)
@@ -66,37 +66,23 @@ int tpm_read_log_of(struct tpm_chip *chip)
if (of_property_read_bool(np, "powered-while-suspended"))
chip->flags |= TPM_CHIP_FLAG_ALWAYS_POWERED;
 
-   sizep = of_get_property(np, "linux,sml-size", NULL);
-   basep = of_get_property(np, "linux,sml-base", NULL);
-   if (sizep == NULL && basep == NULL)
-   return tpm_read_log_memory_region(chip);
-   if (sizep == NULL || basep == NULL)
-   return -EIO;
-
-   /*
-* For both vtpm/tpm, firmware has log addr and log size in big
-* endian format. But in case of vtpm, there is a method called
-* sml-handover which is run during kernel init even before
-* device tree is setup. This sml-handover function takes care
-* of endianness and writes to sml-base and sml-size in little
-* endian format. For this reason, vtpm doesn't need conversion
-* but physical tpm needs the conversion.
-*/
-   if (of_property_match_string(np, "compatible", "IBM,vtpm") < 0 &&
-   of_property_match_string(np, "compatible", "IBM,vtpm20") < 0) {
+   logp = of_get_property(np, "linux,sml-log", );
+   if (logp == NULL) {
+   sizep = of_get_property(np, "linux,sml-size", NULL);
+   basep = of_get_property(np, "linux,sml-base", NULL);
+   if (sizep == NULL && basep == NULL)
+   return tpm_read_log_memory_region(chip);
+   if (sizep == NULL || basep == NULL)
+   return -EIO;
size = be32_to_cpup((__force __be32 *)sizep);
-   base = be64_to_cpup((__force __be64 *)basep);
-   } else {
-   size = *sizep;
-   base = *basep;
+   logp = __va(be64_to_cpup((__force __be64 *)basep));
}
-
if (size == 0) {
dev_warn(>dev, "%s: Event log area empty\n", __func__);
return -EIO;
}
 
-   log->bios_event_log = devm_kmemdup(>dev, __va(base), size, 
GFP_KERNEL);
+   log->bios_event_log = devm_kmemdup(>dev, logp, size, GFP_KERNEL);
if (!log->bios_event_log)
return -ENOMEM;
 
-- 
2.43.0



[RFC PATCH v2 1/3] powerpc/prom_init: Replace linux,sml-base/sml-size with linux,sml-log

2024-03-11 Thread Stefan Berger
linux,sml-base holds the address of a buffer with the TPM log. This
buffer may become invalid after a kexec. To avoid accessing an invalid
address or corrupted buffer, embed the whole TPM log in the device tree
property linux,sml-log. This helps to protect the log since it is
properly carried across a kexec soft reboot with both of the kexec
syscalls.

Avoid having the firmware ingest the whole TPM log when calling
prom_setprop but only create the linux,sml-log property as a place holder.
Insert the actual TPM log during the tree flattening phase.

Fixes: 4a727429abec ("PPC64: Add support for instantiating SML from Open 
Firmware")
Suggested-by: Michael Ellerman 
Signed-off-by: Stefan Berger 
---
 arch/powerpc/kernel/prom_init.c | 27 +++
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index e67effdba85c..6f7ca72013c2 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -211,6 +211,8 @@ static cell_t __prombss regbuf[1024];
 
 static bool  __prombss rtas_has_query_cpu_stopped;
 
+static u64 __prombss sml_base;
+static u32 __prombss sml_size;
 
 /*
  * Error results ... some OF calls will return "-1" on error, some
@@ -1954,17 +1956,15 @@ static void __init prom_instantiate_sml(void)
}
prom_printf(" done\n");
 
-   reserve_mem(base, size);
-
-   prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-base",
-, sizeof(base));
-   prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-size",
-, sizeof(size));
-
-   prom_debug("sml base = 0x%llx\n", base);
+   /* Add property now, defer adding log to tree flattening phase */
+   prom_setprop(ibmvtpm_node, "/vdevice/vtpm", "linux,sml-log",
+NULL, 0);
prom_debug("sml size = 0x%x\n", size);
 
prom_debug("prom_instantiate_sml: end...\n");
+
+   sml_base = base;
+   sml_size = size;
 }
 
 /*
@@ -2645,6 +2645,17 @@ static void __init scan_dt_build_struct(phandle node, 
unsigned long *mem_start,
}
prev_name = sstart + soff;
 
+   if (!prom_strcmp("linux,sml-log", pname)) {
+   /* push property head */
+   dt_push_token(OF_DT_PROP, mem_start, mem_end);
+   dt_push_token(sml_size, mem_start, mem_end);
+   dt_push_token(soff, mem_start, mem_end);
+   /* push property content */
+   valp = make_room(mem_start, mem_end, sml_size, 1);
+   memcpy(valp, (void *)sml_base, sml_size);
+   *mem_start = ALIGN(*mem_start, 4);
+   continue;
+   }
/* get length */
l = call_prom("getproplen", 2, 1, node, pname);
 
-- 
2.43.0



[RFC PATCH v2 0/3] Preserve TPM log across kexec

2024-03-11 Thread Stefan Berger
This series resolves an issue on PowerVM and KVM on Power where the memory
the TPM log was held in may become inaccessible or corrupted after a kexec
soft reboot. The solution on these two platforms is to store the whole log
in the device tree because the device tree is preserved across a kexec with
either of the two kexec syscalls.

Regards,
   Stefan

v2:
 - Added DT bindings patch (2/3)
 - Reformulated commit messages and addded Fixes tags
 - Follow Michael's suggestion on prom_init patch (1/3)

Stefan Berger (3):
  powerpc/prom_init: Replace linux,sml-base/sml-size with linux,sml-log
  dt-bindings: tpm: Add linux,sml-log to ibm,vtpm.yaml
  tpm: of: If available use linux,sml-log to get the log and its size

 .../devicetree/bindings/tpm/ibm,vtpm.yaml | 20 +--
 .../devicetree/bindings/tpm/tpm-common.yaml   | 14 +++-
 arch/powerpc/kernel/prom_init.c   | 27 +-
 drivers/char/tpm/eventlog/of.c| 36 ++-
 4 files changed, 61 insertions(+), 36 deletions(-)

-- 
2.43.0



Re: [PATCH 0/4] PCI: Consolidate TLP Log reading and printing

2024-03-11 Thread Ilpo Järvinen
On Fri, 8 Mar 2024, Bjorn Helgaas wrote:

> On Tue, Feb 06, 2024 at 03:57:13PM +0200, Ilpo Järvinen wrote:
> > This series consolidates AER & DPC TLP Log handling code. Helpers are
> > added for reading and printing the TLP Log and the format is made to
> > include E-E Prefixes in both cases (previously only one DPC RP PIO
> > displayed the E-E Prefixes).
> > 
> > I'd appreciate if people familiar with ixgbe could check the error
> > handling conversion within the driver is correct.
> > 
> > Ilpo Järvinen (4):
> >   PCI/AER: Cleanup register variable
> >   PCI: Generalize TLP Header Log reading
> 
> I applied these first two to pci/aer for v6.9, thanks, these are all
> nice improvements!
> 
> I postponed the ixgbe part for now because I think we should get an
> ack from those maintainers or just send it to them since it subtly
> changes the error and device removal checking there.

Okay, I'll make sure they're separated properly for the remaining patches 
(I was already planning on doing that separation and posting v2 to avoid 
their input blocking the changed but you beat me to it).

> >   PCI: Add TLP Prefix reading into pcie_read_tlp_log()
> >   PCI: Create helper to print TLP Header and Prefix Log
> 
> I'll respond to these with some minor comments.

Did you forget to send those comments?


-- 
 i.


[PATCH v3 5/5] ASoC: fsl: imx-rpmsg: Update to correct DT node

2024-03-11 Thread Chancel Liu
In order to support register and unregister rpmsg sound card through
remoteproc platform device for card to probe is registered in
imx-audio-rpmsg. ASoC machine driver no longer can get DT node of ASoC
CPU DAI device through parent device.

ASoC machine driver can get DT node of ASoC CPU DAI device with rpmsg
channel name acquired from platform specific data.

Signed-off-by: Chancel Liu 
---
 sound/soc/fsl/imx-rpmsg.c | 28 +++-
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/sound/soc/fsl/imx-rpmsg.c b/sound/soc/fsl/imx-rpmsg.c
index e5bd63dab10c..0f1ad7ad7d27 100644
--- a/sound/soc/fsl/imx-rpmsg.c
+++ b/sound/soc/fsl/imx-rpmsg.c
@@ -108,10 +108,8 @@ static int imx_rpmsg_late_probe(struct snd_soc_card *card)
 static int imx_rpmsg_probe(struct platform_device *pdev)
 {
struct snd_soc_dai_link_component *dlc;
-   struct device *dev = pdev->dev.parent;
-   /* rpmsg_pdev is the platform device for the rpmsg node that probed us 
*/
-   struct platform_device *rpmsg_pdev = to_platform_device(dev);
-   struct device_node *np = rpmsg_pdev->dev.of_node;
+   struct snd_soc_dai *cpu_dai;
+   struct device_node *np = NULL;
struct of_phandle_args args;
const char *platform_name;
struct imx_rpmsg *data;
@@ -127,10 +125,6 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
goto fail;
}
 
-   ret = of_reserved_mem_device_init_by_idx(>dev, np, 0);
-   if (ret)
-   dev_warn(>dev, "no reserved DMA memory\n");
-
data->dai.cpus = [0];
data->dai.num_cpus = 1;
data->dai.platforms = [1];
@@ -152,6 +146,23 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
 */
data->dai.ignore_pmdown_time = 1;
 
+   data->dai.cpus->dai_name = pdev->dev.platform_data;
+   cpu_dai = snd_soc_find_dai(data->dai.cpus);
+   if (!cpu_dai) {
+   ret = -EPROBE_DEFER;
+   goto fail;
+   }
+   np = cpu_dai->dev->of_node;
+   if (!np) {
+   dev_err(>dev, "failed to parse CPU DAI device node\n");
+   ret = -ENODEV;
+   goto fail;
+   }
+
+   ret = of_reserved_mem_device_init_by_idx(>dev, np, 0);
+   if (ret)
+   dev_warn(>dev, "no reserved DMA memory\n");
+
/* Optional codec node */
ret = of_parse_phandle_with_fixed_args(np, "audio-codec", 0, 0, );
if (ret) {
@@ -170,7 +181,6 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
data->sysclk = clk_get_rate(clk);
}
 
-   data->dai.cpus->dai_name = dev_name(_pdev->dev);
if (!of_property_read_string(np, "fsl,rpmsg-channel-name", 
_name))
data->dai.platforms->name = platform_name;
else
-- 
2.43.0



[PATCH v3 4/5] ASoC: fsl: fsl_rpmsg: Register CPU DAI with name of rpmsg channel

2024-03-11 Thread Chancel Liu
Each rpmsg sound card sits on one rpmsg channel. Register CPU DAI with
name of rpmsg channel so that ASoC machine driver can easily link CPU
DAI with rpmsg channel name.

Signed-off-by: Chancel Liu 
---
 sound/soc/fsl/fsl_rpmsg.c | 32 ++--
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/sound/soc/fsl/fsl_rpmsg.c b/sound/soc/fsl/fsl_rpmsg.c
index 53bd517e59d6..bc41a0666856 100644
--- a/sound/soc/fsl/fsl_rpmsg.c
+++ b/sound/soc/fsl/fsl_rpmsg.c
@@ -135,7 +135,6 @@ static struct snd_soc_dai_driver fsl_rpmsg_dai = {
 
 static const struct snd_soc_component_driver fsl_component = {
.name   = "fsl-rpmsg",
-   .legacy_dai_naming  = 1,
 };
 
 static const struct fsl_rpmsg_soc_data imx7ulp_data = {
@@ -190,19 +189,40 @@ MODULE_DEVICE_TABLE(of, fsl_rpmsg_ids);
 static int fsl_rpmsg_probe(struct platform_device *pdev)
 {
struct device_node *np = pdev->dev.of_node;
+   struct snd_soc_dai_driver *dai_drv;
+   const char *dai_name;
struct fsl_rpmsg *rpmsg;
int ret;
 
+   dai_drv = devm_kzalloc(>dev, sizeof(struct snd_soc_dai_driver), 
GFP_KERNEL);
+   if (!dai_drv)
+   return -ENOMEM;
+   memcpy(dai_drv, _rpmsg_dai, sizeof(fsl_rpmsg_dai));
+
rpmsg = devm_kzalloc(>dev, sizeof(struct fsl_rpmsg), GFP_KERNEL);
if (!rpmsg)
return -ENOMEM;
 
rpmsg->soc_data = of_device_get_match_data(>dev);
 
-   fsl_rpmsg_dai.playback.rates = rpmsg->soc_data->rates;
-   fsl_rpmsg_dai.capture.rates = rpmsg->soc_data->rates;
-   fsl_rpmsg_dai.playback.formats = rpmsg->soc_data->formats;
-   fsl_rpmsg_dai.capture.formats = rpmsg->soc_data->formats;
+   if (rpmsg->soc_data) {
+   dai_drv->playback.rates = rpmsg->soc_data->rates;
+   dai_drv->capture.rates = rpmsg->soc_data->rates;
+   dai_drv->playback.formats = rpmsg->soc_data->formats;
+   dai_drv->capture.formats = rpmsg->soc_data->formats;
+   }
+
+   /* Use rpmsg channel name as cpu dai name */
+   ret = of_property_read_string(np, "fsl,rpmsg-channel-name", _name);
+   if (ret) {
+   if (ret == -EINVAL) {
+   dai_name = "rpmsg-audio-channel";
+   } else {
+   dev_err(>dev, "Failed to get rpmsg channel name: 
%d!\n", ret);
+   return ret;
+   }
+   }
+   dai_drv->name = dai_name;
 
if (of_property_read_bool(np, "fsl,enable-lpa")) {
rpmsg->enable_lpa = 1;
@@ -236,7 +256,7 @@ static int fsl_rpmsg_probe(struct platform_device *pdev)
pm_runtime_enable(>dev);
 
ret = devm_snd_soc_register_component(>dev, _component,
- _rpmsg_dai, 1);
+ dai_drv, 1);
if (ret)
goto err_pm_disable;
 
-- 
2.43.0



[PATCH v3 3/5] ASoC: fsl: Let imx-audio-rpmsg register platform device for card

2024-03-11 Thread Chancel Liu
Let imx-audio-rpmsg register platform device for card. So that card
register and unregister can be controlled by rpmsg driver's register
and unregister.

Signed-off-by: Chancel Liu 
---
 sound/soc/fsl/fsl_rpmsg.c   | 11 ---
 sound/soc/fsl/imx-audio-rpmsg.c | 17 -
 2 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/sound/soc/fsl/fsl_rpmsg.c b/sound/soc/fsl/fsl_rpmsg.c
index 00852f174a69..53bd517e59d6 100644
--- a/sound/soc/fsl/fsl_rpmsg.c
+++ b/sound/soc/fsl/fsl_rpmsg.c
@@ -240,17 +240,6 @@ static int fsl_rpmsg_probe(struct platform_device *pdev)
if (ret)
goto err_pm_disable;
 
-   rpmsg->card_pdev = platform_device_register_data(>dev,
-"imx-audio-rpmsg",
-PLATFORM_DEVID_AUTO,
-NULL,
-0);
-   if (IS_ERR(rpmsg->card_pdev)) {
-   dev_err(>dev, "failed to register rpmsg card\n");
-   ret = PTR_ERR(rpmsg->card_pdev);
-   goto err_pm_disable;
-   }
-
return 0;
 
 err_pm_disable:
diff --git a/sound/soc/fsl/imx-audio-rpmsg.c b/sound/soc/fsl/imx-audio-rpmsg.c
index 40820d5ad92d..38aafb8954c7 100644
--- a/sound/soc/fsl/imx-audio-rpmsg.c
+++ b/sound/soc/fsl/imx-audio-rpmsg.c
@@ -12,6 +12,7 @@
  */
 struct imx_audio_rpmsg {
struct platform_device *rpmsg_pdev;
+   struct platform_device *card_pdev;
 };
 
 static int imx_audio_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
@@ -95,6 +96,16 @@ static int imx_audio_rpmsg_probe(struct rpmsg_device *rpdev)
ret = PTR_ERR(data->rpmsg_pdev);
}
 
+   data->card_pdev = platform_device_register_data(>dev,
+   "imx-audio-rpmsg",
+   PLATFORM_DEVID_AUTO,
+   rpdev->id.name,
+   strlen(rpdev->id.name) 
+ 1);
+   if (IS_ERR(data->card_pdev)) {
+   dev_err(>dev, "failed to register rpmsg card.\n");
+   ret = PTR_ERR(data->card_pdev);
+   }
+
return ret;
 }
 
@@ -105,6 +116,9 @@ static void imx_audio_rpmsg_remove(struct rpmsg_device 
*rpdev)
if (data->rpmsg_pdev)
platform_device_unregister(data->rpmsg_pdev);
 
+   if (data->card_pdev)
+   platform_device_unregister(data->card_pdev);
+
dev_info(>dev, "audio rpmsg driver is removed\n");
 }
 
@@ -113,6 +127,7 @@ static struct rpmsg_device_id imx_audio_rpmsg_id_table[] = {
{ .name = "rpmsg-micfil-channel" },
{ },
 };
+MODULE_DEVICE_TABLE(rpmsg, imx_audio_rpmsg_id_table);
 
 static struct rpmsg_driver imx_audio_rpmsg_driver = {
.drv.name   = "imx_audio_rpmsg",
@@ -126,5 +141,5 @@ module_rpmsg_driver(imx_audio_rpmsg_driver);
 
 MODULE_DESCRIPTION("Freescale SoC Audio RPMSG interface");
 MODULE_AUTHOR("Shengjiu Wang ");
-MODULE_ALIAS("platform:imx_audio_rpmsg");
+MODULE_ALIAS("rpmsg:imx_audio_rpmsg");
 MODULE_LICENSE("GPL v2");
-- 
2.43.0



[PATCH v3 2/5] ASoC: fsl: imx-audio-rpmsg: Register device with rpmsg channel name

2024-03-11 Thread Chancel Liu
This rpmsg driver registers device for ASoC platform driver. To align
with platform driver use rpmsg channel name to create device.

Signed-off-by: Chancel Liu 
---
 sound/soc/fsl/imx-audio-rpmsg.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/imx-audio-rpmsg.c b/sound/soc/fsl/imx-audio-rpmsg.c
index 289e47c03d40..40820d5ad92d 100644
--- a/sound/soc/fsl/imx-audio-rpmsg.c
+++ b/sound/soc/fsl/imx-audio-rpmsg.c
@@ -87,8 +87,8 @@ static int imx_audio_rpmsg_probe(struct rpmsg_device *rpdev)
 
/* Register platform driver for rpmsg routine */
data->rpmsg_pdev = platform_device_register_data(>dev,
-IMX_PCM_DRV_NAME,
-PLATFORM_DEVID_AUTO,
+rpdev->id.name,
+PLATFORM_DEVID_NONE,
 NULL, 0);
if (IS_ERR(data->rpmsg_pdev)) {
dev_err(>dev, "failed to register rpmsg platform.\n");
-- 
2.43.0



[PATCH v3 1/5] ASoC: fsl: imx-pcm-rpmsg: Register component with rpmsg channel name

2024-03-11 Thread Chancel Liu
Machine driver uses rpmsg channel name to link this platform component.
However if the component is re-registerd card will not find this new
created component in snd_soc_try_rebind_card().

Explicitly register this component with rpmsg channel name so that
card can always find this component.

Signed-off-by: Chancel Liu 
---
 sound/soc/fsl/imx-pcm-rpmsg.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/sound/soc/fsl/imx-pcm-rpmsg.c b/sound/soc/fsl/imx-pcm-rpmsg.c
index fb9244c1e9c5..b84d1dfddba2 100644
--- a/sound/soc/fsl/imx-pcm-rpmsg.c
+++ b/sound/soc/fsl/imx-pcm-rpmsg.c
@@ -732,9 +732,6 @@ static int imx_rpmsg_pcm_probe(struct platform_device *pdev)
goto fail;
}
 
-   /* platform component name is used by machine driver to link with */
-   component->name = info->rpdev->id.name;
-
 #ifdef CONFIG_DEBUG_FS
component->debugfs_prefix = "rpmsg";
 #endif
@@ -822,9 +819,17 @@ static const struct dev_pm_ops imx_rpmsg_pcm_pm_ops = {
imx_rpmsg_pcm_resume)
 };
 
+static const struct platform_device_id imx_rpmsg_pcm_id_table[] = {
+   { .name = "rpmsg-audio-channel" },
+   { .name = "rpmsg-micfil-channel" },
+   { },
+};
+MODULE_DEVICE_TABLE(platform, imx_rpmsg_pcm_id_table);
+
 static struct platform_driver imx_pcm_rpmsg_driver = {
.probe  = imx_rpmsg_pcm_probe,
.remove_new = imx_rpmsg_pcm_remove,
+   .id_table = imx_rpmsg_pcm_id_table,
.driver = {
.name = IMX_PCM_DRV_NAME,
.pm = _rpmsg_pcm_pm_ops,
-- 
2.43.0



[PATCH v3 0/5] ASoC: fsl: Support register and unregister rpmsg sound card through remoteproc

2024-03-11 Thread Chancel Liu
echo /lib/firmware/fw.elf > /sys/class/remoteproc/remoteproc0/firmware
(A) echo start > /sys/class/remoteproc/remoteproc0/state
(B) echo stop > /sys/class/remoteproc/remoteproc0/state

The rpmsg sound card is registered in (A) and unregistered in (B).
After "start", imx-audio-rpmsg registers devices for ASoC platform driver
and machine driver. Then sound card is registered. After "stop",
imx-audio-rpmsg unregisters devices for ASoC platform driver and machine
driver. Then sound card is unregistered.

changes in v2
- Fix build errors reported by kernel test robot

changes in v3
- Add a new patch for fsl_rpmsg to register CPU DAI with rpmsg channel
  name
- Update imx-rpmsg.c to get DT node of ASoC CPU DAI device with rpmsg
  channel name instead of using undocumented bindings

Chancel Liu (5):
  ASoC: fsl: imx-pcm-rpmsg: Register component with rpmsg channel name
  ASoC: fsl: imx-audio-rpmsg: Register device with rpmsg channel name
  ASoC: fsl: Let imx-audio-rpmsg register platform device for card
  ASoC: fsl: fsl_rpmsg: Register CPU DAI with name of rpmsg channel
  ASoC: fsl: imx-rpmsg: Update to correct DT node

 sound/soc/fsl/fsl_rpmsg.c   | 43 -
 sound/soc/fsl/imx-audio-rpmsg.c | 21 +---
 sound/soc/fsl/imx-pcm-rpmsg.c   | 11 ++---
 sound/soc/fsl/imx-rpmsg.c   | 28 ++---
 4 files changed, 71 insertions(+), 32 deletions(-)

--
2.43.0



[PATCH v14 16/16] media: vim2m-audio: add virtual driver for audio memory to memory

2024-03-11 Thread Shengjiu Wang
Audio memory to memory virtual driver use video memory to memory
virtual driver vim2m.c as example. The main difference is
device type is VFL_TYPE_AUDIO and device cap type is V4L2_CAP_AUDIO_M2M.

The device_run function is a dummy function, which is simply
copy the data from input buffer to output buffer.

Signed-off-by: Shengjiu Wang 
---
 drivers/media/test-drivers/Kconfig   |  10 +
 drivers/media/test-drivers/Makefile  |   1 +
 drivers/media/test-drivers/vim2m-audio.c | 793 +++
 3 files changed, 804 insertions(+)
 create mode 100644 drivers/media/test-drivers/vim2m-audio.c

diff --git a/drivers/media/test-drivers/Kconfig 
b/drivers/media/test-drivers/Kconfig
index 5a5379524bde..b6b52a7ca042 100644
--- a/drivers/media/test-drivers/Kconfig
+++ b/drivers/media/test-drivers/Kconfig
@@ -16,6 +16,16 @@ config VIDEO_VIM2M
  This is a virtual test device for the memory-to-memory driver
  framework.
 
+config VIDEO_VIM2M_AUDIO
+   tristate "Virtual Memory-to-Memory Driver For Audio"
+   depends on VIDEO_DEV
+   select VIDEOBUF2_VMALLOC
+   select V4L2_MEM2MEM_DEV
+   select MEDIA_CONTROLLER
+   help
+ This is a virtual audio test device for the memory-to-memory driver
+ framework.
+
 source "drivers/media/test-drivers/vicodec/Kconfig"
 source "drivers/media/test-drivers/vimc/Kconfig"
 source "drivers/media/test-drivers/vivid/Kconfig"
diff --git a/drivers/media/test-drivers/Makefile 
b/drivers/media/test-drivers/Makefile
index 740714a4584d..0c61c9ada3e1 100644
--- a/drivers/media/test-drivers/Makefile
+++ b/drivers/media/test-drivers/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_DVB_VIDTV) += vidtv/
 
 obj-$(CONFIG_VIDEO_VICODEC) += vicodec/
 obj-$(CONFIG_VIDEO_VIM2M) += vim2m.o
+obj-$(CONFIG_VIDEO_VIM2M_AUDIO) += vim2m-audio.o
 obj-$(CONFIG_VIDEO_VIMC) += vimc/
 obj-$(CONFIG_VIDEO_VIVID) += vivid/
 obj-$(CONFIG_VIDEO_VISL) += visl/
diff --git a/drivers/media/test-drivers/vim2m-audio.c 
b/drivers/media/test-drivers/vim2m-audio.c
new file mode 100644
index ..6361df6320b3
--- /dev/null
+++ b/drivers/media/test-drivers/vim2m-audio.c
@@ -0,0 +1,793 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * A virtual v4l2-mem2mem example for audio device.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+MODULE_DESCRIPTION("Virtual device for audio mem2mem testing");
+MODULE_LICENSE("GPL");
+
+static unsigned int debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "debug level");
+
+#define MEM2MEM_NAME "vim2m-audio"
+
+#define dprintk(dev, lvl, fmt, arg...) \
+   v4l2_dbg(lvl, debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
+
+#define SAMPLE_NUM 4096
+
+static void audm2m_dev_release(struct device *dev)
+{}
+
+static struct platform_device audm2m_pdev = {
+   .name   = MEM2MEM_NAME,
+   .dev.release= audm2m_dev_release,
+};
+
+static u32 formats[] = {
+   V4L2_AUDIO_FMT_S16_LE,
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+/* Per-queue, driver-specific private data */
+struct audm2m_q_data {
+   unsigned intrate;
+   unsigned intchannels;
+   unsigned intbuffersize;
+   unsigned intsequence;
+   u32 fourcc;
+};
+
+enum {
+   V4L2_M2M_SRC = 0,
+   V4L2_M2M_DST = 1,
+};
+
+static snd_pcm_format_t find_format(u32 fourcc)
+{
+   snd_pcm_format_t fmt;
+   unsigned int k;
+
+   for (k = 0; k < NUM_FORMATS; k++) {
+   if (formats[k] == fourcc)
+   break;
+   }
+
+   if (k == NUM_FORMATS)
+   return 0;
+
+   fmt = v4l2_fourcc_to_audfmt(formats[k]);
+
+   return fmt;
+}
+
+struct audm2m_dev {
+   struct v4l2_device  v4l2_dev;
+   struct video_device vfd;
+
+   struct mutexdev_mutex;
+
+   struct v4l2_m2m_dev *m2m_dev;
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct media_device mdev;
+#endif
+};
+
+struct audm2m_ctx {
+   struct v4l2_fh  fh;
+   struct v4l2_ctrl_handlerctrl_handler;
+   struct audm2m_dev   *dev;
+
+   struct mutexvb_mutex;
+
+   /* Source and destination queue data */
+   struct audm2m_q_data   q_data[2];
+};
+
+static inline struct audm2m_ctx *file2ctx(struct file *file)
+{
+   return container_of(file->private_data, struct audm2m_ctx, fh);
+}
+
+static struct audm2m_q_data *get_q_data(struct audm2m_ctx *ctx,
+   enum v4l2_buf_type type)
+{
+   if (type == V4L2_BUF_TYPE_AUDIO_OUTPUT)
+   return >q_data[V4L2_M2M_SRC];
+   return >q_data[V4L2_M2M_DST];
+}
+
+static const char *type_name(enum v4l2_buf_type type)
+{
+   if (type == V4L2_BUF_TYPE_AUDIO_OUTPUT)
+   return "Output";
+   return "Capture";
+}
+
+/*
+ * mem2mem callbacks
+ */

[PATCH v14 15/16] media: imx-asrc: Add memory to memory driver

2024-03-11 Thread Shengjiu Wang
Implement the ASRC memory to memory function using
the v4l2 framework, user can use this function with
v4l2 ioctl interface.

User send the output and capture buffer to driver and
driver store the converted data to the capture buffer.

This feature can be shared by ASRC and EASRC drivers

Signed-off-by: Shengjiu Wang 
---
 drivers/media/platform/nxp/Kconfig|   13 +
 drivers/media/platform/nxp/Makefile   |1 +
 drivers/media/platform/nxp/imx-asrc.c | 1256 +
 3 files changed, 1270 insertions(+)
 create mode 100644 drivers/media/platform/nxp/imx-asrc.c

diff --git a/drivers/media/platform/nxp/Kconfig 
b/drivers/media/platform/nxp/Kconfig
index 40e3436669e2..8d0ca335601f 100644
--- a/drivers/media/platform/nxp/Kconfig
+++ b/drivers/media/platform/nxp/Kconfig
@@ -67,3 +67,16 @@ config VIDEO_MX2_EMMAPRP
 
 source "drivers/media/platform/nxp/dw100/Kconfig"
 source "drivers/media/platform/nxp/imx-jpeg/Kconfig"
+
+config VIDEO_IMX_ASRC
+   tristate "NXP i.MX ASRC M2M support"
+   depends on V4L_MEM2MEM_DRIVERS
+   depends on MEDIA_SUPPORT
+   select VIDEOBUF2_DMA_CONTIG
+   select V4L2_MEM2MEM_DEV
+   select MEDIA_CONTROLLER
+   help
+   Say Y if you want to add ASRC M2M support for NXP CPUs.
+   It is a complement for ASRC M2P and ASRC P2M features.
+   This option is only useful for out-of-tree drivers since
+   in-tree drivers select it automatically.
diff --git a/drivers/media/platform/nxp/Makefile 
b/drivers/media/platform/nxp/Makefile
index 4d90eb713652..1325675e34f5 100644
--- a/drivers/media/platform/nxp/Makefile
+++ b/drivers/media/platform/nxp/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) += imx8mq-mipi-csi2.o
 obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) += imx-mipi-csis.o
 obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o
 obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
+obj-$(CONFIG_VIDEO_IMX_ASRC) += imx-asrc.o
diff --git a/drivers/media/platform/nxp/imx-asrc.c 
b/drivers/media/platform/nxp/imx-asrc.c
new file mode 100644
index ..0c25a36199b1
--- /dev/null
+++ b/drivers/media/platform/nxp/imx-asrc.c
@@ -0,0 +1,1256 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (C) 2014-2016 Freescale Semiconductor, Inc.
+// Copyright (C) 2019-2023 NXP
+//
+// Freescale ASRC Memory to Memory (M2M) driver
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define V4L_CAP OUT
+#define V4L_OUT IN
+
+#define ASRC_xPUT_DMA_CALLBACK(dir) \
+   (((dir) == V4L_OUT) ? asrc_input_dma_callback \
+   : asrc_output_dma_callback)
+
+#define DIR_STR(dir) (dir) == V4L_OUT ? "out" : "cap"
+
+/* Maximum output and capture buffer size */
+#define ASRC_M2M_BUFFER_SIZE (512 * 1024)
+
+/* Maximum output and capture period size */
+#define ASRC_M2M_PERIOD_SIZE (48 * 1024)
+
+struct asrc_pair_m2m {
+   struct fsl_asrc_pair *pair;
+   struct asrc_m2m *m2m;
+   struct v4l2_fh fh;
+   struct v4l2_ctrl_handler ctrl_handler;
+   int channels[2];
+   unsigned int sequence[2];
+   s64 src_rate_off_prev;  /* Q31.32 */
+   s64 dst_rate_off_prev;  /* Q31.32 */
+   s64 src_rate_off_cur;   /* Q31.32 */
+   s64 dst_rate_off_cur;   /* Q31.32 */
+};
+
+struct asrc_m2m {
+   struct fsl_asrc_m2m_pdata pdata;
+   struct v4l2_device v4l2_dev;
+   struct v4l2_m2m_dev *m2m_dev;
+   struct video_device *dec_vdev;
+   struct mutex mlock; /* v4l2 ioctls serialization */
+   struct platform_device *pdev;
+#ifdef CONFIG_MEDIA_CONTROLLER
+   struct media_device mdev;
+#endif
+};
+
+static u32 formats[] = {
+   V4L2_AUDIO_FMT_S8,
+   V4L2_AUDIO_FMT_S16_LE,
+   V4L2_AUDIO_FMT_U16_LE,
+   V4L2_AUDIO_FMT_S24_LE,
+   V4L2_AUDIO_FMT_S24_3LE,
+   V4L2_AUDIO_FMT_U24_LE,
+   V4L2_AUDIO_FMT_U24_3LE,
+   V4L2_AUDIO_FMT_S32_LE,
+   V4L2_AUDIO_FMT_U32_LE,
+   V4L2_AUDIO_FMT_S20_3LE,
+   V4L2_AUDIO_FMT_U20_3LE,
+   V4L2_AUDIO_FMT_FLOAT_LE,
+   V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE,
+};
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+static const s64 asrc_v1_m2m_rates[] = {
+   5512, 8000, 11025, 12000, 16000,
+   22050, 24000, 32000, 44100,
+   48000, 64000, 88200, 96000,
+   128000, 176400, 192000,
+};
+
+static const s64 asrc_v2_m2m_rates[] = {
+   8000, 11025, 12000, 16000,
+   22050, 24000, 32000, 44100,
+   48000, 64000, 88200, 96000,
+   128000, 176400, 192000, 256000,
+   352800, 384000, 705600, 768000,
+};
+
+static u32 find_fourcc(snd_pcm_format_t format)
+{
+   snd_pcm_format_t fmt;
+   unsigned int k;
+
+   for (k = 0; k < NUM_FORMATS; k++) {
+   fmt = v4l2_fourcc_to_audfmt(formats[k]);
+   if (fmt == format)
+   return formats[k];
+   }
+
+   return 0;
+}
+
+static snd_pcm_format_t find_format(u32 fourcc)
+{
+   unsigned int k;
+

[PATCH v14 14/16] media: vivid: add fixed point test controls

2024-03-11 Thread Shengjiu Wang
Add fixed point test controls, one is for Q4.16 format
another one is for Q63 format.

Signed-off-by: Shengjiu Wang 
---
 drivers/media/test-drivers/vivid/vivid-core.h |  2 ++
 .../media/test-drivers/vivid/vivid-ctrls.c| 26 +++
 include/media/v4l2-ctrls.h|  6 +
 3 files changed, 34 insertions(+)

diff --git a/drivers/media/test-drivers/vivid/vivid-core.h 
b/drivers/media/test-drivers/vivid/vivid-core.h
index cfb8e66083f6..f65465191bc9 100644
--- a/drivers/media/test-drivers/vivid/vivid-core.h
+++ b/drivers/media/test-drivers/vivid/vivid-core.h
@@ -222,6 +222,8 @@ struct vivid_dev {
struct v4l2_ctrl*boolean;
struct v4l2_ctrl*int32;
struct v4l2_ctrl*int64;
+   struct v4l2_ctrl*int32_q16;
+   struct v4l2_ctrl*int64_q63;
struct v4l2_ctrl*menu;
struct v4l2_ctrl*string;
struct v4l2_ctrl*bitmask;
diff --git a/drivers/media/test-drivers/vivid/vivid-ctrls.c 
b/drivers/media/test-drivers/vivid/vivid-ctrls.c
index f2b20e25a7a4..2444ea95b285 100644
--- a/drivers/media/test-drivers/vivid/vivid-ctrls.c
+++ b/drivers/media/test-drivers/vivid/vivid-ctrls.c
@@ -38,6 +38,8 @@
 #define VIVID_CID_U8_PIXEL_ARRAY   (VIVID_CID_CUSTOM_BASE + 14)
 #define VIVID_CID_S32_ARRAY(VIVID_CID_CUSTOM_BASE + 15)
 #define VIVID_CID_S64_ARRAY(VIVID_CID_CUSTOM_BASE + 16)
+#define VIVID_CID_INT_Q4_16(VIVID_CID_CUSTOM_BASE + 17)
+#define VIVID_CID_INT64_Q63(VIVID_CID_CUSTOM_BASE + 18)
 
 #define VIVID_CID_VIVID_BASE   (0x00f0 | 0xf000)
 #define VIVID_CID_VIVID_CLASS  (0x00f0 | 1)
@@ -182,6 +184,28 @@ static const struct v4l2_ctrl_config vivid_ctrl_int64 = {
.step = 1,
 };
 
+static const struct v4l2_ctrl_config vivid_ctrl_int32_q16 = {
+   .ops = _user_gen_ctrl_ops,
+   .id = VIVID_CID_INT_Q4_16,
+   .name = "Integer 32 Bits Q4.16",
+   .type = V4L2_CTRL_TYPE_INTEGER,
+   .min = v4l2_ctrl_fp_compose(-16, 0, 16),
+   .max = v4l2_ctrl_fp_compose(15, 0x, 16),
+   .step = 1,
+   .fraction_bits = 16,
+};
+
+static const struct v4l2_ctrl_config vivid_ctrl_int64_q63 = {
+   .ops = _user_gen_ctrl_ops,
+   .id = VIVID_CID_INT64_Q63,
+   .name = "Integer 64 Bits Q63",
+   .type = V4L2_CTRL_TYPE_INTEGER64,
+   .min = v4l2_ctrl_fp_compose(-1, 0, 63),
+   .max = v4l2_ctrl_fp_compose(0, LLONG_MAX, 63),
+   .step = 1,
+   .fraction_bits = 63,
+};
+
 static const struct v4l2_ctrl_config vivid_ctrl_u32_array = {
.ops = _user_gen_ctrl_ops,
.id = VIVID_CID_U32_ARRAY,
@@ -1670,6 +1694,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool 
show_ccs_cap,
dev->button = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_button, 
NULL);
dev->int32 = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_int32, 
NULL);
dev->int64 = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_int64, 
NULL);
+   dev->int32_q16 = v4l2_ctrl_new_custom(hdl_user_gen, 
_ctrl_int32_q16, NULL);
+   dev->int64_q63 = v4l2_ctrl_new_custom(hdl_user_gen, 
_ctrl_int64_q63, NULL);
dev->boolean = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_boolean, 
NULL);
dev->menu = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_menu, NULL);
dev->string = v4l2_ctrl_new_custom(hdl_user_gen, _ctrl_string, 
NULL);
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index c35514c5bf88..197d8b67ac13 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -1593,4 +1593,10 @@ void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl);
  */
 int v4l2_ctrl_type_op_validate(const struct v4l2_ctrl *ctrl, union 
v4l2_ctrl_ptr ptr);
 
+/*
+ * Fixed point compose helper define. This helper maps to the value
+ * i + f / (1 << fraction_bits).
+ */
+#define v4l2_ctrl_fp_compose(i, f, fraction_bits) (((s64)(i) << fraction_bits) 
+ (f))
+
 #endif
-- 
2.34.1



[PATCH v14 13/16] media: uapi: Add an entity type for audio resampler

2024-03-11 Thread Shengjiu Wang
Add and document a media entity type for an audio resampler.
It is MEDIA_ENT_F_PROC_AUDIO_RESAMPLER.

Signed-off-by: Shengjiu Wang 
---
 Documentation/userspace-api/media/mediactl/media-types.rst | 6 ++
 include/uapi/linux/media.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/Documentation/userspace-api/media/mediactl/media-types.rst 
b/Documentation/userspace-api/media/mediactl/media-types.rst
index adfb37430f8e..d353f17c3344 100644
--- a/Documentation/userspace-api/media/mediactl/media-types.rst
+++ b/Documentation/userspace-api/media/mediactl/media-types.rst
@@ -40,6 +40,7 @@ Types and flags used to represent the media graph elements
 .. _MEDIA-ENT-F-PROC-VIDEO-ENCODER:
 .. _MEDIA-ENT-F-PROC-VIDEO-DECODER:
 .. _MEDIA-ENT-F-PROC-VIDEO-ISP:
+.. _MEDIA-ENT-F-PROC-AUDIO-RESAMPLER:
 .. _MEDIA-ENT-F-VID-MUX:
 .. _MEDIA-ENT-F-VID-IF-BRIDGE:
 .. _MEDIA-ENT-F-DV-DECODER:
@@ -208,6 +209,11 @@ Types and flags used to represent the media graph elements
  combination of custom V4L2 controls and IOCTLs, and parameters
  supplied in a metadata buffer.
 
+*  -  ``MEDIA_ENT_F_PROC_AUDIO_RESAMPLER``
+   -  An Audio Resampler device. An entity capable of
+ resampling an audio stream from one sample rate to another sample
+ rate. Must have one sink pad and at least one source pad.
+
 *  -  ``MEDIA_ENT_F_VID_MUX``
- Video multiplexer. An entity capable of multiplexing must have at
  least two sink pads and one source pad, and must pass the video
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index 9ff6dec7393a..a8266eaa8042 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -125,6 +125,7 @@ struct media_device_info {
 #define MEDIA_ENT_F_PROC_VIDEO_ENCODER (MEDIA_ENT_F_BASE + 0x4007)
 #define MEDIA_ENT_F_PROC_VIDEO_DECODER (MEDIA_ENT_F_BASE + 0x4008)
 #define MEDIA_ENT_F_PROC_VIDEO_ISP (MEDIA_ENT_F_BASE + 0x4009)
+#define MEDIA_ENT_F_PROC_AUDIO_RESAMPLER   (MEDIA_ENT_F_BASE + 0x400a)
 
 /*
  * Switch and bridge entity functions
-- 
2.34.1



[PATCH v14 12/16] media: uapi: Declare interface types for Audio

2024-03-11 Thread Shengjiu Wang
Declare the interface types that will be used by Audio.
The type is MEDIA_INTF_T_V4L_AUDIO.

Signed-off-by: Shengjiu Wang 
---
 .../userspace-api/media/mediactl/media-types.rst|  5 +
 drivers/media/v4l2-core/v4l2-dev.c  |  4 
 drivers/media/v4l2-core/v4l2-mem2mem.c  | 13 +
 include/uapi/linux/media.h  |  1 +
 4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/Documentation/userspace-api/media/mediactl/media-types.rst 
b/Documentation/userspace-api/media/mediactl/media-types.rst
index 6332e8395263..adfb37430f8e 100644
--- a/Documentation/userspace-api/media/mediactl/media-types.rst
+++ b/Documentation/userspace-api/media/mediactl/media-types.rst
@@ -265,6 +265,7 @@ Types and flags used to represent the media graph elements
 .. _MEDIA-INTF-T-V4L-SUBDEV:
 .. _MEDIA-INTF-T-V4L-SWRADIO:
 .. _MEDIA-INTF-T-V4L-TOUCH:
+.. _MEDIA-INTF-T-V4L-AUDIO:
 .. _MEDIA-INTF-T-ALSA-PCM-CAPTURE:
 .. _MEDIA-INTF-T-ALSA-PCM-PLAYBACK:
 .. _MEDIA-INTF-T-ALSA-CONTROL:
@@ -322,6 +323,10 @@ Types and flags used to represent the media graph elements
-  Device node interface for Touch device (V4L)
-  typically, /dev/v4l-touch?
 
+*  -  ``MEDIA_INTF_T_V4L_AUDIO``
+   -  Device node interface for Audio device (V4L)
+   -  typically, /dev/v4l-audio?
+
 *  -  ``MEDIA_INTF_T_ALSA_PCM_CAPTURE``
-  Device node interface for ALSA PCM Capture
-  typically, /dev/snd/pcmC?D?c
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index bac008fcedc6..ca8462a61e1f 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -844,6 +844,10 @@ static int video_register_media_controller(struct 
video_device *vdev)
intf_type = MEDIA_INTF_T_V4L_SUBDEV;
/* Entity will be created via v4l2_device_register_subdev() */
break;
+   case VFL_TYPE_AUDIO:
+   intf_type = MEDIA_INTF_T_V4L_AUDIO;
+   /* Entity will be created via v4l2_device_register_subdev() */
+   break;
default:
return 0;
}
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 75517134a5e9..cda5e255305f 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -1143,10 +1143,15 @@ int v4l2_m2m_register_media_controller(struct 
v4l2_m2m_dev *m2m_dev,
if (ret)
goto err_rm_links0;
 
-   /* Create video interface */
-   m2m_dev->intf_devnode = media_devnode_create(mdev,
-   MEDIA_INTF_T_V4L_VIDEO, 0,
-   VIDEO_MAJOR, vdev->minor);
+   if (vdev->vfl_type == VFL_TYPE_AUDIO)
+   m2m_dev->intf_devnode = media_devnode_create(mdev,
+   MEDIA_INTF_T_V4L_AUDIO, 0,
+   VIDEO_MAJOR, vdev->minor);
+   else
+   /* Create video interface */
+   m2m_dev->intf_devnode = media_devnode_create(mdev,
+   MEDIA_INTF_T_V4L_VIDEO, 0,
+   VIDEO_MAJOR, vdev->minor);
if (!m2m_dev->intf_devnode) {
ret = -ENOMEM;
goto err_rm_links1;
diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h
index 1c80b1d6bbaf..9ff6dec7393a 100644
--- a/include/uapi/linux/media.h
+++ b/include/uapi/linux/media.h
@@ -260,6 +260,7 @@ struct media_links_enum {
 #define MEDIA_INTF_T_V4L_SUBDEV(MEDIA_INTF_T_V4L_BASE 
+ 3)
 #define MEDIA_INTF_T_V4L_SWRADIO   (MEDIA_INTF_T_V4L_BASE + 4)
 #define MEDIA_INTF_T_V4L_TOUCH (MEDIA_INTF_T_V4L_BASE + 5)
+#define MEDIA_INTF_T_V4L_AUDIO (MEDIA_INTF_T_V4L_BASE + 6)
 
 #define MEDIA_INTF_T_ALSA_BASE 0x0300
 #define MEDIA_INTF_T_ALSA_PCM_CAPTURE  (MEDIA_INTF_T_ALSA_BASE)
-- 
2.34.1



[PATCH v14 11/16] media: uapi: Add audio rate controls support

2024-03-11 Thread Shengjiu Wang
Add V4L2_CID_M2M_AUDIO_SOURCE_RATE and V4L2_CID_M2M_AUDIO_DEST_RATE
new IDs for rate control.

Add V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET and
V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET for clock drift.

Signed-off-by: Shengjiu Wang 
---
 .../media/v4l/ext-ctrls-audio-m2m.rst | 38 +++
 drivers/media/v4l2-core/v4l2-ctrls-defs.c |  6 +++
 include/uapi/linux/v4l2-controls.h|  5 +++
 3 files changed, 49 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst 
b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst
index 82d2ecedbfee..b137b7c442e6 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst
@@ -19,3 +19,41 @@ Audio M2M Control IDs
 The Audio M2M class descriptor. Calling
 :ref:`VIDIOC_QUERYCTRL` for this control will
 return a description of this control class.
+
+.. _v4l2-audio-asrc:
+
+``V4L2_CID_M2M_AUDIO_SOURCE_RATE (integer menu)``
+This control specifies the audio source sample rate, unit is Hz
+
+``V4L2_CID_M2M_AUDIO_DEST_RATE (integer menu)``
+This control specifies the audio destination sample rate, unit is Hz
+
+``V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET (fixed point)``
+This control specifies the offset from the audio source sample rate,
+unit is Hz.
+
+The offset compensates for any clock drift. The actual source audio
+sample rate is the ideal source audio sample rate from
+``V4L2_CID_M2M_AUDIO_SOURCE_RATE`` plus this fixed point offset.
+
+The audio source clock may have some drift. Reducing or increasing the
+audio sample rate dynamically to ensure that Sample Rate Converter is
+working on the real sample rate, this feature is for the Asynchronous
+Sample Rate Converter module.
+So, userspace would be expected to be monitoring such drift
+and increasing/decreasing the sample frequency as needed by this control.
+
+``V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET (fixed point)``
+This control specifies the offset from the audio destination sample rate,
+unit is Hz.
+
+The offset compensates for any clock drift. The actual destination audio
+sample rate is the ideal source audio sample rate from
+``V4L2_CID_M2M_AUDIO_DEST_RATE`` plus this fixed point offset.
+
+The audio destination clock may have some drift. Reducing or increasing
+the audio sample rate dynamically to ensure that sample rate converter
+is working on the real sample rate, this feature is for the Asynchronous
+Sample Rate Converter module.
+So, userspace would be expected to be monitoring such drift
+and increasing/decreasing the sample frequency as needed by this control.
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c 
b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
index 2a85ea3dc92f..91e1f5348c23 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
@@ -1245,6 +1245,8 @@ const char *v4l2_ctrl_get_name(u32 id)
 
/* Audio M2M controls */
case V4L2_CID_M2M_AUDIO_CLASS:  return "Audio M2M Controls";
+   case V4L2_CID_M2M_AUDIO_SOURCE_RATE:return "Audio Source Sample 
Rate";
+   case V4L2_CID_M2M_AUDIO_DEST_RATE:  return "Audio Destination 
Sample Rate";
default:
return NULL;
}
@@ -1606,6 +1608,10 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum 
v4l2_ctrl_type *type,
case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY:
*type = V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY;
break;
+   case V4L2_CID_M2M_AUDIO_SOURCE_RATE:
+   case V4L2_CID_M2M_AUDIO_DEST_RATE:
+   *type = V4L2_CTRL_TYPE_INTEGER_MENU;
+   break;
default:
*type = V4L2_CTRL_TYPE_INTEGER;
break;
diff --git a/include/uapi/linux/v4l2-controls.h 
b/include/uapi/linux/v4l2-controls.h
index a8b4b830c757..30129ccdc282 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -3495,6 +3495,11 @@ struct v4l2_ctrl_av1_film_grain {
 #define V4L2_CID_M2M_AUDIO_CLASS_BASE  (V4L2_CTRL_CLASS_M2M_AUDIO | 0x900)
 #define V4L2_CID_M2M_AUDIO_CLASS   (V4L2_CTRL_CLASS_M2M_AUDIO | 1)
 
+#define V4L2_CID_M2M_AUDIO_SOURCE_RATE (V4L2_CID_M2M_AUDIO_CLASS_BASE + 0)
+#define V4L2_CID_M2M_AUDIO_DEST_RATE   (V4L2_CID_M2M_AUDIO_CLASS_BASE + 1)
+#define V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET  (V4L2_CID_M2M_AUDIO_CLASS_BASE 
+ 2)
+#define V4L2_CID_M2M_AUDIO_DEST_RATE_OFFSET(V4L2_CID_M2M_AUDIO_CLASS_BASE 
+ 3)
+
 /* MPEG-compression definitions kept for backwards compatibility */
 #ifndef __KERNEL__
 #define V4L2_CTRL_CLASS_MPEGV4L2_CTRL_CLASS_CODEC
-- 
2.34.1



[PATCH v14 10/16] media: uapi: Add V4L2_CTRL_CLASS_M2M_AUDIO

2024-03-11 Thread Shengjiu Wang
The Audio M2M class includes controls for audio memory-to-memory
use cases. The controls can be used for audio codecs, audio
preprocessing, audio postprocessing.

Signed-off-by: Shengjiu Wang 
---
 .../userspace-api/media/v4l/common.rst|  1 +
 .../media/v4l/ext-ctrls-audio-m2m.rst | 21 +++
 .../media/v4l/vidioc-g-ext-ctrls.rst  |  4 
 drivers/media/v4l2-core/v4l2-ctrls-defs.c |  4 
 include/uapi/linux/v4l2-controls.h|  4 
 5 files changed, 34 insertions(+)
 create mode 100644 
Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst

diff --git a/Documentation/userspace-api/media/v4l/common.rst 
b/Documentation/userspace-api/media/v4l/common.rst
index ea0435182e44..d5366e96a596 100644
--- a/Documentation/userspace-api/media/v4l/common.rst
+++ b/Documentation/userspace-api/media/v4l/common.rst
@@ -52,6 +52,7 @@ applicable to all devices.
 ext-ctrls-fm-rx
 ext-ctrls-detect
 ext-ctrls-colorimetry
+ext-ctrls-audio-m2m
 fourcc
 format
 planar-apis
diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst 
b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst
new file mode 100644
index ..82d2ecedbfee
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-audio-m2m.rst
@@ -0,0 +1,21 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+
+.. _audiom2m-controls:
+
+***
+Audio M2M Control Reference
+***
+
+The Audio M2M class includes controls for audio memory-to-memory
+use cases. The controls can be used for audio codecs, audio
+preprocessing, audio postprocessing.
+
+Audio M2M Control IDs
+---
+
+.. _audiom2m-control-id:
+
+``V4L2_CID_M2M_AUDIO_CLASS (class)``
+The Audio M2M class descriptor. Calling
+:ref:`VIDIOC_QUERYCTRL` for this control will
+return a description of this control class.
diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst 
b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
index 4d56c0528ad7..aeb1ad8e7d29 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
@@ -488,6 +488,10 @@ still cause this situation.
   - 0xa5
   - The class containing colorimetry controls. These controls are
described in :ref:`colorimetry-controls`.
+* - ``V4L2_CTRL_CLASS_M2M_AUDIO``
+  - 0xa6
+  - The class containing audio m2m controls. These controls are
+   described in :ref:`audiom2m-controls`.
 
 Return Value
 
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c 
b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
index 8696eb1cdd61..2a85ea3dc92f 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
@@ -1242,6 +1242,9 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_COLORIMETRY_CLASS:return "Colorimetry Controls";
case V4L2_CID_COLORIMETRY_HDR10_CLL_INFO:   return "HDR10 
Content Light Info";
case V4L2_CID_COLORIMETRY_HDR10_MASTERING_DISPLAY:  return "HDR10 
Mastering Display";
+
+   /* Audio M2M controls */
+   case V4L2_CID_M2M_AUDIO_CLASS:  return "Audio M2M Controls";
default:
return NULL;
}
@@ -1451,6 +1454,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum 
v4l2_ctrl_type *type,
case V4L2_CID_DETECT_CLASS:
case V4L2_CID_CODEC_STATELESS_CLASS:
case V4L2_CID_COLORIMETRY_CLASS:
+   case V4L2_CID_M2M_AUDIO_CLASS:
*type = V4L2_CTRL_TYPE_CTRL_CLASS;
/* You can neither read nor write these */
*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
diff --git a/include/uapi/linux/v4l2-controls.h 
b/include/uapi/linux/v4l2-controls.h
index 99c3f5e99da7..a8b4b830c757 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -30,6 +30,7 @@
 #define V4L2_CTRL_CLASS_DETECT 0x00a3  /* Detection controls */
 #define V4L2_CTRL_CLASS_CODEC_STATELESS 0x00a4 /* Stateless codecs 
controls */
 #define V4L2_CTRL_CLASS_COLORIMETRY0x00a5  /* Colorimetry controls 
*/
+#define V4L2_CTRL_CLASS_M2M_AUDIO  0x00a6  /* Audio M2M controls */
 
 /* User-class control IDs */
 
@@ -3491,6 +3492,9 @@ struct v4l2_ctrl_av1_film_grain {
__u8 reserved[4];
 };
 
+#define V4L2_CID_M2M_AUDIO_CLASS_BASE  (V4L2_CTRL_CLASS_M2M_AUDIO | 0x900)
+#define V4L2_CID_M2M_AUDIO_CLASS   (V4L2_CTRL_CLASS_M2M_AUDIO | 1)
+
 /* MPEG-compression definitions kept for backwards compatibility */
 #ifndef __KERNEL__
 #define V4L2_CTRL_CLASS_MPEGV4L2_CTRL_CLASS_CODEC
-- 
2.34.1



[PATCH v14 09/16] media: uapi: Define audio sample format fourcc type

2024-03-11 Thread Shengjiu Wang
The audio sample format definition is from alsa,
the header file is include/uapi/sound/asound.h, but
don't include this header file directly, because in
user space, there is another copy in alsa-lib.
There will be conflict in userspace for include
videodev2.h & asound.h and asoundlib.h

Here still use the fourcc format.

Signed-off-by: Shengjiu Wang 
---
 .../userspace-api/media/v4l/pixfmt-audio.rst  | 100 ++
 .../userspace-api/media/v4l/pixfmt.rst|   1 +
 drivers/media/v4l2-core/v4l2-ioctl.c  |  13 +++
 include/uapi/linux/videodev2.h|  29 +
 4 files changed, 143 insertions(+)
 create mode 100644 Documentation/userspace-api/media/v4l/pixfmt-audio.rst

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-audio.rst 
b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
new file mode 100644
index ..a66db9a19936
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
@@ -0,0 +1,100 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+
+.. _pixfmt-audio:
+
+*
+Audio Formats
+*
+
+These formats are used for :ref:`audiomem2mem` interface only.
+
+All FourCCs starting with 'AU' are reserved for mappings
+of the snd_pcm_format_t type.
+
+The v4l2_audfmt_to_fourcc() is defined to convert the snd_pcm_format_t
+type to a FourCC. The first character is 'A', the second character
+is 'U', and the remaining two characters is the snd_pcm_format_t
+value in ASCII. Example: SNDRV_PCM_FORMAT_S16_LE (with value 2)
+maps to 'AU02' and SNDRV_PCM_FORMAT_S24_3LE (with value 32) maps
+to 'AU32'."
+
+The v4l2_fourcc_to_audfmt() is defined to convert these FourCCs to
+snd_pcm_format_t type.
+
+.. tabularcolumns:: |p{5.8cm}|p{1.2cm}|p{10.3cm}|
+
+.. cssclass:: longtable
+
+.. flat-table:: Audio Format
+:header-rows:  1
+:stub-columns: 0
+:widths:   3 1 4
+
+* - Identifier
+  - Code
+  - Details
+* .. _V4L2-AUDIO-FMT-S8:
+
+  - ``V4L2_AUDIO_FMT_S8``
+  - 'S8'
+  - Corresponds to SNDRV_PCM_FORMAT_S8 in ALSA
+* .. _V4L2-AUDIO-FMT-S16-LE:
+
+  - ``V4L2_AUDIO_FMT_S16_LE``
+  - 'S16_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_S16_LE in ALSA
+* .. _V4L2-AUDIO-FMT-U16-LE:
+
+  - ``V4L2_AUDIO_FMT_U16_LE``
+  - 'U16_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_U16_LE in ALSA
+* .. _V4L2-AUDIO-FMT-S24-LE:
+
+  - ``V4L2_AUDIO_FMT_S24_LE``
+  - 'S24_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_S24_LE in ALSA
+* .. _V4L2-AUDIO-FMT-U24-LE:
+
+  - ``V4L2_AUDIO_FMT_U24_LE``
+  - 'U24_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_U24_LE in ALSA
+* .. _V4L2-AUDIO-FMT-S32-LE:
+
+  - ``V4L2_AUDIO_FMT_S32_LE``
+  - 'S32_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_S32_LE in ALSA
+* .. _V4L2-AUDIO-FMT-U32-LE:
+
+  - ``V4L2_AUDIO_FMT_U32_LE``
+  - 'U32_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_U32_LE in ALSA
+* .. _V4L2-AUDIO-FMT-FLOAT-LE:
+
+  - ``V4L2_AUDIO_FMT_FLOAT_LE``
+  - 'FLOAT_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_FLOAT_LE in ALSA
+* .. _V4L2-AUDIO-FMT-IEC958-SUBFRAME-LE:
+
+  - ``V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE``
+  - 'IEC958_SUBFRAME_LE'
+  - Corresponds to SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE in ALSA
+* .. _V4L2-AUDIO-FMT-S24-3LE:
+
+  - ``V4L2_AUDIO_FMT_S24_3LE``
+  - 'S24_3LE'
+  - Corresponds to SNDRV_PCM_FORMAT_S24_3LE in ALSA
+* .. _V4L2-AUDIO-FMT-U24-3LE:
+
+  - ``V4L2_AUDIO_FMT_U24_3LE``
+  - 'U24_3LE'
+  - Corresponds to SNDRV_PCM_FORMAT_U24_3LE in ALSA
+* .. _V4L2-AUDIO-FMT-S20-3LE:
+
+  - ``V4L2_AUDIO_FMT_S20_3LE``
+  - 'S20_3LE'
+  - Corresponds to SNDRV_PCM_FORMAT_S24_3LE in ALSA
+* .. _V4L2-AUDIO-FMT-U20-3LE:
+
+  - ``V4L2_AUDIO_FMT_U20_3LE``
+  - 'U20_3LE'
+  - Corresponds to SNDRV_PCM_FORMAT_U20_3LE in ALSA
diff --git a/Documentation/userspace-api/media/v4l/pixfmt.rst 
b/Documentation/userspace-api/media/v4l/pixfmt.rst
index 11dab4a90630..2eb6fdd3b43d 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt.rst
@@ -36,3 +36,4 @@ see also :ref:`VIDIOC_G_FBUF `.)
 colorspaces
 colorspaces-defs
 colorspaces-details
+pixfmt-audio
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 961abcdf7290..be229c69e991 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1471,6 +1471,19 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_Y210: descr = "10-bit YUYV Packed"; break;
case V4L2_PIX_FMT_Y212: descr = "12-bit YUYV Packed"; break;
case V4L2_PIX_FMT_Y216: descr = "16-bit YUYV Packed"; break;
+   case V4L2_AUDIO_FMT_S8: descr = "8-bit Signed"; break;
+   case V4L2_AUDIO_FMT_S16_LE: descr = "16-bit Signed LE"; break;
+   case V4L2_AUDIO_FMT_U16_LE:   

[PATCH v14 08/16] media: v4l2: Add audio capture and output support

2024-03-11 Thread Shengjiu Wang
Audio signal processing has the requirement for memory to
memory similar as Video.

This patch is to add this support in v4l2 framework, defined
new buffer type V4L2_BUF_TYPE_AUDIO_CAPTURE and
V4L2_BUF_TYPE_AUDIO_OUTPUT, defined new format v4l2_audio_format
for audio case usage.

The created audio device is named "/dev/v4l-audioX".

Signed-off-by: Shengjiu Wang 
---
 .../userspace-api/media/v4l/buffer.rst|  6 ++
 .../media/v4l/dev-audio-mem2mem.rst   | 71 +++
 .../userspace-api/media/v4l/devices.rst   |  1 +
 .../media/v4l/vidioc-enum-fmt.rst |  2 +
 .../userspace-api/media/v4l/vidioc-g-fmt.rst  |  4 ++
 .../media/videodev2.h.rst.exceptions  |  2 +
 .../media/common/videobuf2/videobuf2-v4l2.c   |  4 ++
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |  9 +++
 drivers/media/v4l2-core/v4l2-dev.c| 17 +
 drivers/media/v4l2-core/v4l2-ioctl.c  | 53 ++
 include/media/v4l2-dev.h  |  2 +
 include/media/v4l2-ioctl.h| 34 +
 include/uapi/linux/videodev2.h| 17 +
 13 files changed, 222 insertions(+)
 create mode 100644 Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst

diff --git a/Documentation/userspace-api/media/v4l/buffer.rst 
b/Documentation/userspace-api/media/v4l/buffer.rst
index 52bbee81c080..a3754ca6f0d6 100644
--- a/Documentation/userspace-api/media/v4l/buffer.rst
+++ b/Documentation/userspace-api/media/v4l/buffer.rst
@@ -438,6 +438,12 @@ enum v4l2_buf_type
 * - ``V4L2_BUF_TYPE_META_OUTPUT``
   - 14
   - Buffer for metadata output, see :ref:`metadata`.
+* - ``V4L2_BUF_TYPE_AUDIO_CAPTURE``
+  - 15
+  - Buffer for audio capture, see :ref:`audio`.
+* - ``V4L2_BUF_TYPE_AUDIO_OUTPUT``
+  - 16
+  - Buffer for audio output, see :ref:`audio`.
 
 
 .. _buffer-flags:
diff --git a/Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst 
b/Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst
new file mode 100644
index ..54cc2abb6c04
--- /dev/null
+++ b/Documentation/userspace-api/media/v4l/dev-audio-mem2mem.rst
@@ -0,0 +1,71 @@
+.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
+
+.. _audiomem2mem:
+
+
+Audio Memory-To-Memory Interface
+
+
+An audio memory-to-memory device can compress, decompress, transform, or
+otherwise convert audio data from one format into another format, in memory.
+Such memory-to-memory devices set the ``V4L2_CAP_AUDIO_M2M`` capability.
+Examples of memory-to-memory devices are audio codecs, audio preprocessing,
+audio postprocessing.
+
+A memory-to-memory audio node supports both output (sending audio frames from
+memory to the hardware) and capture (receiving the processed audio frames
+from the hardware into memory) stream I/O. An application will have to
+setup the stream I/O for both sides and finally call
+:ref:`VIDIOC_STREAMON ` for both capture and output to
+start the hardware.
+
+Memory-to-memory devices function as a shared resource: you can
+open the audio node multiple times, each application setting up their
+own properties that are local to the file handle, and each can use
+it independently from the others. The driver will arbitrate access to
+the hardware and reprogram it whenever another file handler gets access.
+
+Audio memory-to-memory devices are accessed through character device
+special files named ``/dev/v4l-audio``
+
+Querying Capabilities
+=
+
+Device nodes supporting the audio memory-to-memory interface set the
+``V4L2_CAP_AUDIO_M2M`` flag in the ``device_caps`` field of the
+:c:type:`v4l2_capability` structure returned by the :c:func:`VIDIOC_QUERYCAP`
+ioctl.
+
+Data Format Negotiation
+===
+
+The audio device uses the :ref:`format` ioctls to select the capture format.
+The audio buffer content format is bound to that selected format. In addition
+to the basic :ref:`format` ioctls, the :c:func:`VIDIOC_ENUM_FMT` ioctl must be
+supported as well.
+
+To use the :ref:`format` ioctls applications set the ``type`` field of the
+:c:type:`v4l2_format` structure to ``V4L2_BUF_TYPE_AUDIO_CAPTURE`` or to
+``V4L2_BUF_TYPE_AUDIO_OUTPUT``. Both drivers and applications must set the
+remainder of the :c:type:`v4l2_format` structure to 0.
+
+.. c:type:: v4l2_audio_format
+
+.. tabularcolumns:: |p{1.4cm}|p{2.4cm}|p{13.5cm}|
+
+.. flat-table:: struct v4l2_audio_format
+:header-rows:  0
+:stub-columns: 0
+:widths:   1 1 2
+
+* - __u32
+  - ``audioformat``
+  - The sample format, set by the application. see :ref:`pixfmt-audio`
+* - __u32
+  - ``channels``
+  - The channel number, set by the application. channel number range is
+[1, 32].
+* - __u32
+  - ``buffersize``
+  - Maximum buffer size in bytes required for data. The value is set by the
+driver.
diff --git 

[PATCH v14 07/16] media: uapi: Add V4L2_CAP_AUDIO_M2M capability flag

2024-03-11 Thread Shengjiu Wang
V4L2_CAP_AUDIO_M2M is similar to V4L2_CAP_VIDEO_M2M flag.

It is used for audio memory to memory case.

Signed-off-by: Shengjiu Wang 
---
 Documentation/userspace-api/media/v4l/vidioc-querycap.rst| 3 +++
 Documentation/userspace-api/media/videodev2.h.rst.exceptions | 1 +
 include/uapi/linux/videodev2.h   | 1 +
 3 files changed, 5 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/vidioc-querycap.rst 
b/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
index 6c57b8428356..1c0d97bf192a 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-querycap.rst
@@ -173,6 +173,9 @@ specification the ioctl returns an ``EINVAL`` error code.
interface. A video overlay device typically stores captured images
directly in the video memory of a graphics card, with hardware
clipping and scaling.
+* - ``V4L2_CAP_AUDIO_M2M``
+  - 0x0008
+  - The device supports the audio Memory-To-Memory interface.
 * - ``V4L2_CAP_VBI_CAPTURE``
   - 0x0010
   - The device supports the :ref:`Raw VBI Capture `
diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions 
b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
index 3e58aac4ef0b..da6d0b8e4c2c 100644
--- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
+++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
@@ -197,6 +197,7 @@ replace define V4L2_CAP_META_OUTPUT device-capabilities
 replace define V4L2_CAP_DEVICE_CAPS device-capabilities
 replace define V4L2_CAP_TOUCH device-capabilities
 replace define V4L2_CAP_IO_MC device-capabilities
+replace define V4L2_CAP_AUDIO_M2M device-capabilities
 
 # V4L2 pix flags
 replace define V4L2_PIX_FMT_PRIV_MAGIC :c:type:`v4l2_pix_format`
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index b8573e9ccde6..5cc2a978fd9c 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -473,6 +473,7 @@ struct v4l2_capability {
 #define V4L2_CAP_VIDEO_CAPTURE 0x0001  /* Is a video capture 
device */
 #define V4L2_CAP_VIDEO_OUTPUT  0x0002  /* Is a video output device 
*/
 #define V4L2_CAP_VIDEO_OVERLAY 0x0004  /* Can do video overlay */
+#define V4L2_CAP_AUDIO_M2M 0x0008  /* audio memory to memory */
 #define V4L2_CAP_VBI_CAPTURE   0x0010  /* Is a raw VBI capture 
device */
 #define V4L2_CAP_VBI_OUTPUT0x0020  /* Is a raw VBI output 
device */
 #define V4L2_CAP_SLICED_VBI_CAPTURE0x0040  /* Is a sliced VBI capture 
device */
-- 
2.34.1



[PATCH v14 06/16] ASoC: fsl_easrc: register m2m platform device

2024-03-11 Thread Shengjiu Wang
Register m2m platform device,that user can
use M2M feature.

Signed-off-by: Shengjiu Wang 
Acked-by: Mark Brown 
---
 sound/soc/fsl/fsl_easrc.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index cf7ad30a323b..ccbf45c7abf4 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -2075,6 +2075,7 @@ MODULE_DEVICE_TABLE(of, fsl_easrc_dt_ids);
 static int fsl_easrc_probe(struct platform_device *pdev)
 {
struct fsl_easrc_priv *easrc_priv;
+   struct fsl_asrc_m2m_pdata m2m_pdata;
struct device *dev = >dev;
struct fsl_asrc *easrc;
struct resource *res;
@@ -2190,6 +2191,19 @@ static int fsl_easrc_probe(struct platform_device *pdev)
goto err_pm_disable;
}
 
+   m2m_pdata.asrc = easrc;
+   m2m_pdata.fmt_in = FSL_EASRC_FORMATS;
+   m2m_pdata.fmt_out = FSL_EASRC_FORMATS | 
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
+   m2m_pdata.rate_min = 8000;
+   m2m_pdata.rate_max = 768000;
+   m2m_pdata.chan_min = 1;
+   m2m_pdata.chan_max = 32;
+   easrc->m2m_pdev = platform_device_register_data(>dev,
+   M2M_DRV_NAME,
+   PLATFORM_DEVID_AUTO,
+   _pdata,
+   sizeof(m2m_pdata));
+
return 0;
 
 err_pm_disable:
@@ -2199,6 +2213,11 @@ static int fsl_easrc_probe(struct platform_device *pdev)
 
 static void fsl_easrc_remove(struct platform_device *pdev)
 {
+   struct fsl_asrc *easrc = dev_get_drvdata(>dev);
+
+   if (easrc->m2m_pdev && !IS_ERR(easrc->m2m_pdev))
+   platform_device_unregister(easrc->m2m_pdev);
+
pm_runtime_disable(>dev);
 }
 
-- 
2.34.1



[PATCH v14 05/16] ASoC: fsl_asrc: register m2m platform device

2024-03-11 Thread Shengjiu Wang
Register m2m platform device, that user can
use M2M feature.

Defined platform data structure and platform
driver name.

Signed-off-by: Shengjiu Wang 
Acked-by: Mark Brown 
---
 include/sound/fsl_asrc_common.h | 23 +++
 sound/soc/fsl/fsl_asrc.c| 18 ++
 2 files changed, 41 insertions(+)

diff --git a/include/sound/fsl_asrc_common.h b/include/sound/fsl_asrc_common.h
index 3b53d366182f..c709b8906929 100644
--- a/include/sound/fsl_asrc_common.h
+++ b/include/sound/fsl_asrc_common.h
@@ -71,6 +71,7 @@ struct fsl_asrc_pair {
  * @dma_params_rx: DMA parameters for receive channel
  * @dma_params_tx: DMA parameters for transmit channel
  * @pdev: platform device pointer
+ * @m2m_pdev: m2m platform device pointer
  * @regmap: regmap handler
  * @paddr: physical address to the base address of registers
  * @mem_clk: clock source to access register
@@ -103,6 +104,7 @@ struct fsl_asrc {
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct platform_device *pdev;
+   struct platform_device *m2m_pdev;
struct regmap *regmap;
unsigned long paddr;
struct clk *mem_clk;
@@ -139,6 +141,27 @@ struct fsl_asrc {
void *private;
 };
 
+/**
+ * struct fsl_asrc_m2m_pdata - platform data
+ * @asrc: pointer to struct fsl_asrc
+ * @fmt_in: input sample format
+ * @fmt_out: output sample format
+ * @chan_min: minimum channel number
+ * @chan_max: maximum channel number
+ * @rate_min: minimum rate
+ * @rate_max: maximum rete
+ */
+struct fsl_asrc_m2m_pdata {
+   struct fsl_asrc *asrc;
+   u64 fmt_in;
+   u64 fmt_out;
+   int chan_min;
+   int chan_max;
+   int rate_min;
+   int rate_max;
+};
+
+#define M2M_DRV_NAME "fsl_asrc_m2m"
 #define DRV_NAME "fsl-asrc-dai"
 extern struct snd_soc_component_driver fsl_asrc_component;
 
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 7d8643ee0ba0..5ecb5d869607 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1187,6 +1187,7 @@ static int fsl_asrc_runtime_suspend(struct device *dev);
 static int fsl_asrc_probe(struct platform_device *pdev)
 {
struct device_node *np = pdev->dev.of_node;
+   struct fsl_asrc_m2m_pdata m2m_pdata;
struct fsl_asrc_priv *asrc_priv;
struct fsl_asrc *asrc;
struct resource *res;
@@ -1368,6 +1369,18 @@ static int fsl_asrc_probe(struct platform_device *pdev)
goto err_pm_get_sync;
}
 
+   m2m_pdata.asrc = asrc;
+   m2m_pdata.fmt_in = FSL_ASRC_FORMATS;
+   m2m_pdata.fmt_out = FSL_ASRC_FORMATS | SNDRV_PCM_FMTBIT_S8;
+   m2m_pdata.rate_min = 5512;
+   m2m_pdata.rate_max = 192000;
+   m2m_pdata.chan_min = 1;
+   m2m_pdata.chan_max = 10;
+   asrc->m2m_pdev = platform_device_register_data(>dev,
+  M2M_DRV_NAME,
+  PLATFORM_DEVID_AUTO,
+  _pdata,
+  sizeof(m2m_pdata));
return 0;
 
 err_pm_get_sync:
@@ -1380,6 +1393,11 @@ static int fsl_asrc_probe(struct platform_device *pdev)
 
 static void fsl_asrc_remove(struct platform_device *pdev)
 {
+   struct fsl_asrc *asrc = dev_get_drvdata(>dev);
+
+   if (asrc->m2m_pdev && !IS_ERR(asrc->m2m_pdev))
+   platform_device_unregister(asrc->m2m_pdev);
+
pm_runtime_disable(>dev);
if (!pm_runtime_status_suspended(>dev))
fsl_asrc_runtime_suspend(>dev);
-- 
2.34.1



[PATCH v14 04/16] ASoC: fsl_asrc: move fsl_asrc_common.h to include/sound

2024-03-11 Thread Shengjiu Wang
Move fsl_asrc_common.h to include/sound that it can be
included from other drivers.

Signed-off-by: Shengjiu Wang 
Acked-by: Mark Brown 
---
 {sound/soc/fsl => include/sound}/fsl_asrc_common.h | 0
 sound/soc/fsl/fsl_asrc.h   | 2 +-
 sound/soc/fsl/fsl_asrc_dma.c   | 2 +-
 sound/soc/fsl/fsl_easrc.h  | 2 +-
 4 files changed, 3 insertions(+), 3 deletions(-)
 rename {sound/soc/fsl => include/sound}/fsl_asrc_common.h (100%)

diff --git a/sound/soc/fsl/fsl_asrc_common.h b/include/sound/fsl_asrc_common.h
similarity index 100%
rename from sound/soc/fsl/fsl_asrc_common.h
rename to include/sound/fsl_asrc_common.h
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h
index 1c492eb237f5..66544624de7b 100644
--- a/sound/soc/fsl/fsl_asrc.h
+++ b/sound/soc/fsl/fsl_asrc.h
@@ -10,7 +10,7 @@
 #ifndef _FSL_ASRC_H
 #define _FSL_ASRC_H
 
-#include  "fsl_asrc_common.h"
+#include  
 
 #define ASRC_M2M_INPUTFIFO_WML 0x4
 #define ASRC_M2M_OUTPUTFIFO_WML0x2
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index f501f47242fb..f067bf1ecea7 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -12,7 +12,7 @@
 #include 
 #include 
 
-#include "fsl_asrc_common.h"
+#include 
 
 #define FSL_ASRC_DMABUF_SIZE   (256 * 1024)
 
diff --git a/sound/soc/fsl/fsl_easrc.h b/sound/soc/fsl/fsl_easrc.h
index c9f770862662..a24e540876a4 100644
--- a/sound/soc/fsl/fsl_easrc.h
+++ b/sound/soc/fsl/fsl_easrc.h
@@ -9,7 +9,7 @@
 #include 
 #include 
 
-#include "fsl_asrc_common.h"
+#include 
 
 /* EASRC Register Map */
 
-- 
2.34.1



[PATCH v14 03/16] ASoC: fsl_easrc: define functions for memory to memory usage

2024-03-11 Thread Shengjiu Wang
ASRC can be used on memory to memory case, define several
functions for m2m usage and export them as function pointer.

Signed-off-by: Shengjiu Wang 
Acked-by: Mark Brown 
---
 sound/soc/fsl/fsl_easrc.c | 214 ++
 sound/soc/fsl/fsl_easrc.h |   4 +
 2 files changed, 218 insertions(+)

diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index ec53bda46a46..cf7ad30a323b 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -1861,6 +1861,211 @@ static int fsl_easrc_get_fifo_addr(u8 dir, enum 
asrc_pair_index index)
return REG_EASRC_FIFO(dir, index);
 }
 
+/* Get sample numbers in FIFO */
+static unsigned int fsl_easrc_get_output_fifo_size(struct fsl_asrc_pair *pair)
+{
+   struct fsl_asrc *asrc = pair->asrc;
+   enum asrc_pair_index index = pair->index;
+   u32 val;
+
+   regmap_read(asrc->regmap, REG_EASRC_SFS(index), );
+   val &= EASRC_SFS_NSGO_MASK;
+
+   return val >> EASRC_SFS_NSGO_SHIFT;
+}
+
+static int fsl_easrc_m2m_prepare(struct fsl_asrc_pair *pair)
+{
+   struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
+   struct fsl_asrc *asrc = pair->asrc;
+   struct device *dev = >pdev->dev;
+   int ret;
+
+   ctx_priv->in_params.sample_rate = pair->rate[IN];
+   ctx_priv->in_params.sample_format = pair->sample_format[IN];
+   ctx_priv->out_params.sample_rate = pair->rate[OUT];
+   ctx_priv->out_params.sample_format = pair->sample_format[OUT];
+
+   ctx_priv->in_params.fifo_wtmk = FSL_EASRC_INPUTFIFO_WML;
+   ctx_priv->out_params.fifo_wtmk = FSL_EASRC_OUTPUTFIFO_WML;
+   /* Fill the right half of the re-sampler with zeros */
+   ctx_priv->rs_init_mode = 0x2;
+   /* Zero fill the right half of the prefilter */
+   ctx_priv->pf_init_mode = 0x2;
+
+   ret = fsl_easrc_set_ctx_format(pair,
+  _priv->in_params.sample_format,
+  _priv->out_params.sample_format);
+   if (ret) {
+   dev_err(dev, "failed to set context format: %d\n", ret);
+   return ret;
+   }
+
+   ret = fsl_easrc_config_context(asrc, pair->index);
+   if (ret) {
+   dev_err(dev, "failed to config context %d\n", ret);
+   return ret;
+   }
+
+   ctx_priv->in_params.iterations = 1;
+   ctx_priv->in_params.group_len = pair->channels;
+   ctx_priv->in_params.access_len = pair->channels;
+   ctx_priv->out_params.iterations = 1;
+   ctx_priv->out_params.group_len = pair->channels;
+   ctx_priv->out_params.access_len = pair->channels;
+
+   ret = fsl_easrc_set_ctx_organziation(pair);
+   if (ret) {
+   dev_err(dev, "failed to set fifo organization\n");
+   return ret;
+   }
+
+   /* The context start flag */
+   pair->first_convert = 1;
+   return 0;
+}
+
+static int fsl_easrc_m2m_start(struct fsl_asrc_pair *pair)
+{
+   /* start context once */
+   if (pair->first_convert) {
+   fsl_easrc_start_context(pair);
+   pair->first_convert = 0;
+   }
+
+   return 0;
+}
+
+static int fsl_easrc_m2m_stop(struct fsl_asrc_pair *pair)
+{
+   /* Stop pair/context */
+   if (!pair->first_convert) {
+   fsl_easrc_stop_context(pair);
+   pair->first_convert = 1;
+   }
+
+   return 0;
+}
+
+/* calculate capture data length according to output data length and sample 
rate */
+static int fsl_easrc_m2m_calc_out_len(struct fsl_asrc_pair *pair, int 
input_buffer_length)
+{
+   struct fsl_asrc *easrc = pair->asrc;
+   struct fsl_easrc_priv *easrc_priv = easrc->private;
+   struct fsl_easrc_ctx_priv *ctx_priv = pair->private;
+   unsigned int in_rate = ctx_priv->in_params.norm_rate;
+   unsigned int out_rate = ctx_priv->out_params.norm_rate;
+   unsigned int channels = pair->channels;
+   unsigned int in_samples, out_samples;
+   unsigned int in_width, out_width;
+   unsigned int out_length;
+   unsigned int frac_bits;
+   u64 val1, val2;
+
+   switch (easrc_priv->rs_num_taps) {
+   case EASRC_RS_32_TAPS:
+   /* integer bits = 5; */
+   frac_bits = 39;
+   break;
+   case EASRC_RS_64_TAPS:
+   /* integer bits = 6; */
+   frac_bits = 38;
+   break;
+   case EASRC_RS_128_TAPS:
+   /* integer bits = 7; */
+   frac_bits = 37;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   val1 = (u64)in_rate << frac_bits;
+   do_div(val1, out_rate);
+   val1 += (s64)ctx_priv->ratio_mod << (frac_bits - 31);
+
+   in_width = 
snd_pcm_format_physical_width(ctx_priv->in_params.sample_format) / 8;
+   out_width = 
snd_pcm_format_physical_width(ctx_priv->out_params.sample_format) / 8;
+
+   ctx_priv->in_filled_len += input_buffer_length;
+   

[PATCH v14 02/16] ASoC: fsl_asrc: define functions for memory to memory usage

2024-03-11 Thread Shengjiu Wang
ASRC can be used on memory to memory case, define several
functions for m2m usage.

m2m_prepare: prepare for the start step
m2m_start: the start step
m2m_unprepare: unprepare for stop step, optional
m2m_stop: stop step
m2m_check_format: check format is supported or not
m2m_calc_out_len: calculate output length according to input length
m2m_get_maxburst: burst size for dma
m2m_pair_suspend: suspend function of pair, optional.
m2m_pair_resume: resume function of pair
get_output_fifo_size: get remaining data size in FIFO

Signed-off-by: Shengjiu Wang 
Acked-by: Mark Brown 
---
 sound/soc/fsl/fsl_asrc.c| 126 
 sound/soc/fsl/fsl_asrc.h|   2 +
 sound/soc/fsl/fsl_asrc_common.h |  37 ++
 3 files changed, 165 insertions(+)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index b793263291dc..7d8643ee0ba0 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1063,6 +1063,124 @@ static int fsl_asrc_get_fifo_addr(u8 dir, enum 
asrc_pair_index index)
return REG_ASRDx(dir, index);
 }
 
+/* Get sample numbers in FIFO */
+static unsigned int fsl_asrc_get_output_fifo_size(struct fsl_asrc_pair *pair)
+{
+   struct fsl_asrc *asrc = pair->asrc;
+   enum asrc_pair_index index = pair->index;
+   u32 val;
+
+   regmap_read(asrc->regmap, REG_ASRFST(index), );
+
+   val &= ASRFSTi_OUTPUT_FIFO_MASK;
+
+   return val >> ASRFSTi_OUTPUT_FIFO_SHIFT;
+}
+
+static int fsl_asrc_m2m_prepare(struct fsl_asrc_pair *pair)
+{
+   struct fsl_asrc_pair_priv *pair_priv = pair->private;
+   struct fsl_asrc *asrc = pair->asrc;
+   struct device *dev = >pdev->dev;
+   struct asrc_config config;
+   int ret;
+
+   /* fill config */
+   config.pair = pair->index;
+   config.channel_num = pair->channels;
+   config.input_sample_rate = pair->rate[IN];
+   config.output_sample_rate = pair->rate[OUT];
+   config.input_format = pair->sample_format[IN];
+   config.output_format = pair->sample_format[OUT];
+   config.inclk = INCLK_NONE;
+   config.outclk = OUTCLK_ASRCK1_CLK;
+
+   pair_priv->config = 
+   ret = fsl_asrc_config_pair(pair, true);
+   if (ret) {
+   dev_err(dev, "failed to config pair: %d\n", ret);
+   return ret;
+   }
+
+   pair->first_convert = 1;
+
+   return 0;
+}
+
+static int fsl_asrc_m2m_start(struct fsl_asrc_pair *pair)
+{
+   if (pair->first_convert) {
+   fsl_asrc_start_pair(pair);
+   pair->first_convert = 0;
+   }
+   /*
+* Clear DMA request during the stall state of ASRC:
+* During STALL state, the remaining in input fifo would never be
+* smaller than the input threshold while the output fifo would not
+* be bigger than output one. Thus the DMA request would be cleared.
+*/
+   fsl_asrc_set_watermarks(pair, ASRC_FIFO_THRESHOLD_MIN,
+   ASRC_FIFO_THRESHOLD_MAX);
+
+   /* Update the real input threshold to raise DMA request */
+   fsl_asrc_set_watermarks(pair, ASRC_M2M_INPUTFIFO_WML,
+   ASRC_M2M_OUTPUTFIFO_WML);
+
+   return 0;
+}
+
+static int fsl_asrc_m2m_stop(struct fsl_asrc_pair *pair)
+{
+   if (!pair->first_convert) {
+   fsl_asrc_stop_pair(pair);
+   pair->first_convert = 1;
+   }
+
+   return 0;
+}
+
+/* calculate capture data length according to output data length and sample 
rate */
+static int fsl_asrc_m2m_calc_out_len(struct fsl_asrc_pair *pair, int 
input_buffer_length)
+{
+   unsigned int in_width, out_width;
+   unsigned int channels = pair->channels;
+   unsigned int in_samples, out_samples;
+   unsigned int out_length;
+
+   in_width = snd_pcm_format_physical_width(pair->sample_format[IN]) / 8;
+   out_width = snd_pcm_format_physical_width(pair->sample_format[OUT]) / 8;
+
+   in_samples = input_buffer_length / in_width / channels;
+   out_samples = pair->rate[OUT] * in_samples / pair->rate[IN];
+   out_length = (out_samples - ASRC_OUTPUT_LAST_SAMPLE) * out_width * 
channels;
+
+   return out_length;
+}
+
+static int fsl_asrc_m2m_get_maxburst(u8 dir, struct fsl_asrc_pair *pair)
+{
+   struct fsl_asrc *asrc = pair->asrc;
+   struct fsl_asrc_priv *asrc_priv = asrc->private;
+   int wml = (dir == IN) ? ASRC_M2M_INPUTFIFO_WML : 
ASRC_M2M_OUTPUTFIFO_WML;
+
+   if (!asrc_priv->soc->use_edma)
+   return wml * pair->channels;
+   else
+   return 1;
+}
+
+static int fsl_asrc_m2m_pair_resume(struct fsl_asrc_pair *pair)
+{
+   struct fsl_asrc *asrc = pair->asrc;
+   int i;
+
+   for (i = 0; i < pair->channels * 4; i++)
+   regmap_write(asrc->regmap, REG_ASRDI(pair->index), 0);
+
+   pair->first_convert = 1;
+   return 0;
+}
+
 static int fsl_asrc_runtime_resume(struct device *dev);
 static int 

[PATCH v14 00/16] Add audio support in v4l2 framework

2024-03-11 Thread Shengjiu Wang
Audio signal processing also has the requirement for memory to
memory similar as Video.

This asrc memory to memory (memory ->asrc->memory) case is a non
real time use case.

User fills the input buffer to the asrc module, after conversion, then asrc
sends back the output buffer to user. So it is not a traditional ALSA playback
and capture case.

It is a specific use case,  there is no reference in current kernel.
v4l2 memory to memory is the closed implementation,  v4l2 current
support video, image, radio, tuner, touch devices, so it is not
complicated to add support for this specific audio case.

Because we had implemented the "memory -> asrc ->i2s device-> codec"
use case in ALSA.  Now the "memory->asrc->memory" needs
to reuse the code in asrc driver, so the first 3 patches is for refining
the code to make it can be shared by the "memory->asrc->memory"
driver.

The main change is in the v4l2 side, A /dev/vl4-audioX will be created,
user applications only use the ioctl of v4l2 framework.

Other change is to add memory to memory support for two kinds of i.MX ASRC
module.

changes in v14:
- document the reservation of 'AUXX' fourcc format.
- add v4l2_audfmt_to_fourcc() definition.

changes in v13
- change 'pixelformat' to 'audioformat' in dev-audio-mem2mem.rst
- add more description for clock drift in ext-ctrls-audio-m2m.rst
- Add "media: v4l2-ctrls: add support for fraction_bits" from Hans
  to avoid build issue for kernel test robot

changes in v12
- minor changes according to comments
- drop min_buffers_needed = 1 and V4L2_CTRL_FLAG_UPDATE flag
- drop bus_info

changes in v11
- add add-fixed-point-test-controls in vivid.
- add v4l2_ctrl_fp_compose() helper function for min and max

changes in v10
- remove FIXED_POINT type
- change code base on media: v4l2-ctrls: add support for fraction_bits
- fix issue reported by kernel test robot
- remove module_alias

changes in v9:
- add MEDIA_ENT_F_PROC_AUDIO_RESAMPLER.
- add MEDIA_INTF_T_V4L_AUDIO
- add media controller support
- refine the vim2m-audio to support 8k<->16k conversion.

changes in v8:
- refine V4L2_CAP_AUDIO_M2M to be 0x0008
- update doc for FIXED_POINT
- address comments for imx-asrc

changes in v7:
- add acked-by from Mark
- separate commit for fixed point, m2m audio class, audio rate controls
- use INTEGER_MENU for rate,  FIXED_POINT for rate offset
- remove used fmts
- address other comments for Hans

changes in v6:
- use m2m_prepare/m2m_unprepare/m2m_start/m2m_stop to replace
  m2m_start_part_one/m2m_stop_part_one, m2m_start_part_two/m2m_stop_part_two.
- change V4L2_CTRL_TYPE_ASRC_RATE to V4L2_CTRL_TYPE_FIXED_POINT
- fix warning by kernel test rebot
- remove some unused format V4L2_AUDIO_FMT_XX
- Get SNDRV_PCM_FORMAT from V4L2_AUDIO_FMT in driver.
- rename audm2m to viaudm2m.

changes in v5:
- remove V4L2_AUDIO_FMT_LPCM
- define audio pixel format like V4L2_AUDIO_FMT_S8...
- remove rate and format in struct v4l2_audio_format.
- Add V4L2_CID_ASRC_SOURCE_RATE and V4L2_CID_ASRC_DEST_RATE controls
- updata document accordingly.

changes in v4:
- update document style
- separate V4L2_AUDIO_FMT_LPCM and V4L2_CAP_AUDIO_M2M in separate commit

changes in v3:
- Modify documents for adding audio m2m support
- Add audio virtual m2m driver
- Defined V4L2_AUDIO_FMT_LPCM format type for audio.
- Defined V4L2_CAP_AUDIO_M2M capability type for audio m2m case.
- with modification in v4l-utils, pass v4l2-compliance test.

changes in v2:
- decouple the implementation in v4l2 and ALSA
- implement the memory to memory driver as a platfrom driver
  and move it to driver/media
- move fsl_asrc_common.h to include/sound folder

Hans Verkuil (1):
  media: v4l2-ctrls: add support for fraction_bits

Shengjiu Wang (15):
  ASoC: fsl_asrc: define functions for memory to memory usage
  ASoC: fsl_easrc: define functions for memory to memory usage
  ASoC: fsl_asrc: move fsl_asrc_common.h to include/sound
  ASoC: fsl_asrc: register m2m platform device
  ASoC: fsl_easrc: register m2m platform device
  media: uapi: Add V4L2_CAP_AUDIO_M2M capability flag
  media: v4l2: Add audio capture and output support
  media: uapi: Define audio sample format fourcc type
  media: uapi: Add V4L2_CTRL_CLASS_M2M_AUDIO
  media: uapi: Add audio rate controls support
  media: uapi: Declare interface types for Audio
  media: uapi: Add an entity type for audio resampler
  media: vivid: add fixed point test controls
  media: imx-asrc: Add memory to memory driver
  media: vim2m-audio: add virtual driver for audio memory to memory

 .../media/mediactl/media-types.rst|   11 +
 .../userspace-api/media/v4l/buffer.rst|6 +
 .../userspace-api/media/v4l/common.rst|1 +
 .../media/v4l/dev-audio-mem2mem.rst   |   71 +
 .../userspace-api/media/v4l/devices.rst   |1 +
 .../media/v4l/ext-ctrls-audio-m2m.rst |   59 +
 .../userspace-api/media/v4l/pixfmt-audio.rst  |  100 ++
 .../userspace-api/media/v4l/pixfmt.rst|1 +
 

[PATCH v14 01/16] media: v4l2-ctrls: add support for fraction_bits

2024-03-11 Thread Shengjiu Wang
From: Hans Verkuil 

This adds support for the fraction_bits field, used with integer controls.
This allows fixed point formats to be described.

The fraction_bits field is only exposed through VIDIOC_QUERY_EXT_CTRL.

For a given signed two's complement Qf fixed point value 'f' equals
fraction_bits.

Signed-off-by: Hans Verkuil 
---
 .../media/v4l/vidioc-queryctrl.rst| 11 ++-
 drivers/media/v4l2-core/v4l2-ctrls-api.c  |  1 +
 drivers/media/v4l2-core/v4l2-ctrls-core.c | 93 +++
 include/media/v4l2-ctrls.h|  7 +-
 include/uapi/linux/videodev2.h|  3 +-
 5 files changed, 95 insertions(+), 20 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst 
b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
index 4d38acafe8e1..e65c7e5d78ec 100644
--- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
+++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
@@ -267,7 +267,16 @@ See also the examples in :ref:`control`.
   - The size of each dimension. The first ``nr_of_dims`` elements of
this array must be non-zero, all remaining elements must be zero.
 * - __u32
-  - ``reserved``\ [32]
+  - ``fraction_bits``
+  - The number of least significant bits of the control value that
+form the fraction of the fixed point value. This is 0 if the value
+   is a regular integer. This can be used with all integer control types
+   (``INTEGER``, ``INTEGER64``, ``U8``, ``U16`` and ``U32``).
+   For the signed types the signed two's complement representation is used.
+   This field applies to the control value as well as the ``minimum``,
+   ``maximum``, ``step`` and ``default_value`` fields.
+* - __u32
+  - ``reserved``\ [31]
   - Reserved for future extensions. Applications and drivers must set
the array to zero.
 
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c 
b/drivers/media/v4l2-core/v4l2-ctrls-api.c
index d9a422017bd9..ef16b00421ec 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-api.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c
@@ -1101,6 +1101,7 @@ int v4l2_query_ext_ctrl(struct v4l2_ctrl_handler *hdl, 
struct v4l2_query_ext_ctr
qc->elems = ctrl->elems;
qc->nr_of_dims = ctrl->nr_of_dims;
memcpy(qc->dims, ctrl->dims, qc->nr_of_dims * sizeof(qc->dims[0]));
+   qc->fraction_bits = ctrl->fraction_bits;
qc->minimum = ctrl->minimum;
qc->maximum = ctrl->maximum;
qc->default_value = ctrl->default_value;
diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c 
b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index c4d995f32191..d83a37198bb5 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -252,12 +252,61 @@ void v4l2_ctrl_type_op_init(const struct v4l2_ctrl *ctrl, 
u32 from_idx,
 }
 EXPORT_SYMBOL(v4l2_ctrl_type_op_init);
 
+static void v4l2_ctrl_log_fp(s64 v, unsigned int fraction_bits)
+{
+   s64 i, f, mask;
+
+   if (!fraction_bits) {
+   pr_cont("%lld", v);
+   return;
+   }
+
+   mask = (1ULL << fraction_bits) - 1;
+
+   /*
+* Note: this function does not support fixed point u64 with
+* fraction_bits set to 64. At the moment there is no U64
+* control type, but if that is added, then this code will have
+* to add support for it.
+*/
+   if (fraction_bits >= 63)
+   i = v < 0 ? -1 : 0;
+   else
+   i = div64_s64(v, 1LL << fraction_bits);
+
+   f = v < 0 ? -((-v) & mask) : (v & mask);
+
+   if (!f) {
+   pr_cont("%lld", i);
+   } else if (fraction_bits < 20) {
+   u64 div = 1ULL << fraction_bits;
+
+   if (!i && f < 0)
+   pr_cont("-%lld/%llu", -f, div);
+   else if (!i)
+   pr_cont("%lld/%llu", f, div);
+   else if (i < 0 || f < 0)
+   pr_cont("-%lld-%llu/%llu", -i, -f, div);
+   else
+   pr_cont("%lld+%llu/%llu", i, f, div);
+   } else {
+   if (!i && f < 0)
+   pr_cont("-%lld/(2^%u)", -f, fraction_bits);
+   else if (!i)
+   pr_cont("%lld/(2^%u)", f, fraction_bits);
+   else if (i < 0 || f < 0)
+   pr_cont("-%lld-%llu/(2^%u)", -i, -f, fraction_bits);
+   else
+   pr_cont("%lld+%llu/(2^%u)", i, f, fraction_bits);
+   }
+}
+
 void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl)
 {
union v4l2_ctrl_ptr ptr = ctrl->p_cur;
 
if (ctrl->is_array) {
-   unsigned i;
+   unsigned int i;
 
for (i = 0; i < ctrl->nr_of_dims; i++)
pr_cont("[%u]", ctrl->dims[i]);
@@ -266,7 +315,7 @@ void v4l2_ctrl_type_op_log(const struct v4l2_ctrl *ctrl)
 
 

Re: [PATCH RFC 00/13] mm/treewide: Remove pXd_huge() API

2024-03-11 Thread Christophe Leroy


Le 06/03/2024 à 11:41, pet...@redhat.com a écrit :
> From: Peter Xu 
> 
> [based on akpm/mm-unstable latest commit a7f399ae964e]
> 
> In previous work [1], we removed the pXd_large() API, which is arch
> specific.  This patchset further removes the hugetlb pXd_huge() API.
> 
> Hugetlb was never special on creating huge mappings when compared with
> other huge mappings.  Having a standalone API just to detect such pgtable
> entries is more or less redundant, especially after the pXd_leaf() API set
> is introduced with/without CONFIG_HUGETLB_PAGE.
> 
> When looking at this problem, a few issues are also exposed that we don't
> have a clear definition of the *_huge() variance API.  This patchset
> started by cleaning these issues first, then replace all *_huge() users to
> use *_leaf(), then drop all *_huge() code.
> 
> On x86/sparc, swap entries will be reported "true" in pXd_huge(), while for
> all the rest archs they're reported "false" instead.  This part is done in
> patch 1-5, in which I suspect patch 1 can be seen as a bug fix, but I'll
> leave that to hmm experts to decide.
> 
> Besides, there are three archs (arm, arm64, powerpc) that have slightly
> different definitions between the *_huge() v.s. *_leaf() variances.  I
> tackled them separately so that it'll be easier for arch experts to chim in
> when necessary.  This part is done in patch 6-9.
> 
> The final patches 10-13 do the rest on the final removal, since *_leaf()
> will be the ultimate API in the future, and we seem to have quite some
> confusions on how *_huge() APIs can be defined, provide a rich comment for
> *_leaf() API set to define them properly to avoid future misuse, and
> hopefully that'll also help new archs to start support huge mappings and
> avoid traps (like either swap entries, or PROT_NONE entry checks).
> 
> The whole series is only lightly tested on x86, while as usual I don't have
> the capability to test all archs that it touches.
> 
> Marking this series RFC as of now.
> 
> [1] https://lore.kernel.org/r/20240305043750.93762-1-pet...@redhat.com
> 

Hi Peter, and nice job you are doing in cleaning up things around _huge 
stuff.

One thing that might be worth looking at also at some point is the mess 
around pmd_clear_huge() and pud_clear_huge().

I tried to clean things up with commit c742199a014d ("mm/pgtable: add 
stubs for {pmd/pub}_{set/clear}_huge") but it was reverted because of 
arm64 by commit d8a719059b9d ("Revert "mm/pgtable: add stubs for 
{pmd/pub}_{set/clear}_huge"")

So now powerpc/8xx has to implement pmd_clear_huge() and 
pud_clear_huge() allthough 8xx page hierarchy only has 2 levels.

Christophe


Re: [PATCH v8 1/3] powerpc: make fadump resilient with memory add/remove events

2024-03-11 Thread Hari Bathini




On 17/02/24 12:50 pm, Sourabh Jain wrote:

Due to changes in memory resources caused by either memory hotplug or
online/offline events, the elfcorehdr, which describes the CPUs and
memory of the crashed kernel to the kernel that collects the dump (known
as second/fadump kernel), becomes outdated. Consequently, attempting
dump collection with an outdated elfcorehdr can lead to failed or
inaccurate dump collection.

Memory hotplug or online/offline events is referred as memory add/remove
events in reset of the commit message.

The current solution to address the aforementioned issue is as follows:
Monitor memory add/remove events in userspace using udev rules, and
re-register fadump whenever there are changes in memory resources. This
leads to the creation of a new elfcorehdr with updated system memory
information.

There are several notable issues associated with re-registering fadump
for every memory add/remove events.

1. Bulk memory add/remove events with udev-based fadump re-registration
can lead to race conditions and, more importantly, it creates a wide
window during which fadump is inactive until all memory add/remove
events are settled.
2. Re-registering fadump for every memory add/remove event is
inefficient.
3. The memory for elfcorehdr is allocated based on the memblock regions
available during early boot and remains fixed thereafter. However, if
elfcorehdr is later recreated with additional memblock regions, its
size will increase, potentially leading to memory corruption.

Address the aforementioned challenges by shifting the creation of
elfcorehdr from the first kernel (also referred as the crashed kernel),
where it was created and frequently recreated for every memory
add/remove event, to the fadump kernel. As a result, the elfcorehdr only
needs to be created once, thus eliminating the necessity to re-register
fadump during memory add/remove events.

At present, the first kernel is responsible for preparing the fadump
header and storing it in the fadump reserved area. The fadump header
includes the start address of the elfcorehdr, crashing CPU details, and
other relevant information. In the event of a crash in the first kernel,
the second/fadump boots and accesses the fadump header prepared by the
first kernel. It then performs the following steps in a
platform-specific function [rtas|opal]_fadump_process:

1. Sanity check for fadump header
2. Update CPU notes in elfcorehdr

Along with the above, update the setup_fadump()/fadump.c to create
elfcorehdr and set its address to the global variable elfcorehdr_addr
for the vmcore module to process it in the second/fadump kernel.

Section below outlines the information required to create the elfcorehdr
and the changes made to make it available to the fadump kernel if it's
not already.

To create elfcorehdr, the following crashed kernel information is
required: CPU notes, vmcoreinfo, and memory ranges.

At present, the CPU notes are already prepared in the fadump kernel, so
no changes are needed in that regard. The fadump kernel has access to
all crashed kernel memory regions, including boot memory regions that
are relocated by firmware to fadump reserved areas, so no changes for
that either. However, it is necessary to add new members to the fadump
header, i.e., the 'fadump_crash_info_header' structure, in order to pass
the crashed kernel's vmcoreinfo address and its size to fadump kernel.

In addition to the vmcoreinfo address and size, there are a few other
attributes also added to the fadump_crash_info_header structure.

1. version:
It stores the fadump header version, which is currently set to 1.
This provides flexibility to update the fadump crash info header in
the future without changing the magic number. For each change in the
fadump header, the version will be increased. This will help the
updated kernel determine how to handle kernel dumps from older
kernels. The magic number remains relevant for checking fadump header
corruption.

2. pt_regs_sz/cpu_mask_sz:
Store size of pt_regs and cpu_mask structure of first kernel. These
attributes are used to prevent dump processing if the sizes of
pt_regs or cpu_mask structure differ between the first and fadump
kernels.

Note: if either first/crashed kernel or second/fadump kernel do not have
the changes introduced here then kernel fail to collect the dump and
prints relevant error message on the console.

Signed-off-by: Sourabh Jain 
Cc: Aditya Gupta 
Cc: Aneesh Kumar K.V 
Cc: Hari Bathini 
Cc: Mahesh Salgaonkar 
Cc: Michael Ellerman 
Cc: Naveen N Rao 
---
  arch/powerpc/include/asm/fadump-internal.h   |  31 +-
  arch/powerpc/kernel/fadump.c | 339 +++
  arch/powerpc/platforms/powernv/opal-fadump.c |  22 +-
  arch/powerpc/platforms/pseries/rtas-fadump.c |  30 +-
  4 files changed, 232 insertions(+), 190 deletions(-)

diff --git a/arch/powerpc/include/asm/fadump-internal.h 

RE: Re: [PATCH v2 4/4] ASoC: fsl: imx-rpmsg: Update to correct DT node

2024-03-11 Thread Chancel Liu
> On 11/03/2024 08:33, Chancel Liu wrote:
> >>> @@ -127,6 +126,22 @@ static int imx_rpmsg_probe(struct
> platform_device
> >> *pdev)
> >>>   goto fail;
> >>>   }
> >>>
> >>> + if (!strcmp(pdev->dev.platform_data, "rpmsg-micfil-channel"))
> >>> + np = of_find_node_by_name(NULL, "rpmsg_micfil");
> >>> + else
> >>> + np = of_find_node_by_name(NULL, "rpmsg_audio");
> >>
> >> Why do you create ABI on node names? Where is it documented? Why
> can't
> >> you use phandles?
> >>
> >> Best regards,
> >> Krzysztof
> >
> > Thanks for your reminder. Truly I shouldn't use undocumented bindings. I
> will
> > use “fsl,rpmsg-channel-name” to refine patch set. Please help review next
> > version.
> 
> Instead of hard-coding node names in the driver you want to put it in
> "fsl,rpmsg-channel-name" property? I don't follow. I recommended instead
> using phandles, care to address that?

imx-rpmsg is ASoC machine driver and fsl_rpmsg is ASoC CPU DAI driver. In
imx-rpmsg, driver needs to get CPU DAI DT node for hardware configuration. So
imx-rpmsg needs some "information" to find the correct DT node. As you
recommended, it's not wise to use hard-coding node name. Also the device of
imx-rpmsg is created by imx-audio-rpmsg so it can't directly get phandle of CPU
DAI node.

Sorry for unclear statement. "fsl,rpmsg-channel-name" is the property of rpmsg
channel name. Each rpmsg sound card sits on one rpmsg channel. So I decide to
use rpmsg channel name to connect all parts of this sound card. If the CPU DAI
is registerd with rpmsg channel name then imx-rpmsg can easily get the DT node
by this name.

Regards, 
Chancel Liu


Re: [PATCH v2 4/4] ASoC: fsl: imx-rpmsg: Update to correct DT node

2024-03-11 Thread Krzysztof Kozlowski
On 11/03/2024 08:33, Chancel Liu wrote:
>>> @@ -127,6 +126,22 @@ static int imx_rpmsg_probe(struct platform_device
>> *pdev)
>>>   goto fail;
>>>   }
>>>
>>> + if (!strcmp(pdev->dev.platform_data, "rpmsg-micfil-channel"))
>>> + np = of_find_node_by_name(NULL, "rpmsg_micfil");
>>> + else
>>> + np = of_find_node_by_name(NULL, "rpmsg_audio");
>>
>> Why do you create ABI on node names? Where is it documented? Why can't
>> you use phandles?
>>
>> Best regards,
>> Krzysztof
> 
> Thanks for your reminder. Truly I shouldn't use undocumented bindings. I will
> use “fsl,rpmsg-channel-name” to refine patch set. Please help review next
> version.

Instead of hard-coding node names in the driver you want to put it in
"fsl,rpmsg-channel-name" property? I don't follow. I recommended instead
using phandles, care to address that?

Best regards,
Krzysztof



RE: Re: [PATCH v2 4/4] ASoC: fsl: imx-rpmsg: Update to correct DT node

2024-03-11 Thread Chancel Liu
> On 07/03/2024 08:44, Chancel Liu wrote:
> > Platform device for card to probe is registered in imx-audio-rpmsg.
> > According to this change DT node of ASoC CPU DAI device is updated.
> >
> > Signed-off-by: Chancel Liu 
> > ---
> >  sound/soc/fsl/imx-rpmsg.c | 21 ++---
> >  1 file changed, 18 insertions(+), 3 deletions(-)
> >
> > diff --git a/sound/soc/fsl/imx-rpmsg.c b/sound/soc/fsl/imx-rpmsg.c
> > index e5bd63dab10c..2686125b3043 100644
> > --- a/sound/soc/fsl/imx-rpmsg.c
> > +++ b/sound/soc/fsl/imx-rpmsg.c
> > @@ -108,10 +108,9 @@ static int imx_rpmsg_late_probe(struct
> snd_soc_card *card)
> >  static int imx_rpmsg_probe(struct platform_device *pdev)
> >  {
> >   struct snd_soc_dai_link_component *dlc;
> > - struct device *dev = pdev->dev.parent;
> >   /* rpmsg_pdev is the platform device for the rpmsg node that probed
> us */
> > - struct platform_device *rpmsg_pdev = to_platform_device(dev);
> > - struct device_node *np = rpmsg_pdev->dev.of_node;
> > + struct platform_device *rpmsg_pdev = NULL;
> > + struct device_node *np = NULL;
> >   struct of_phandle_args args;
> >   const char *platform_name;
> >   struct imx_rpmsg *data;
> > @@ -127,6 +126,22 @@ static int imx_rpmsg_probe(struct platform_device
> *pdev)
> >   goto fail;
> >   }
> >
> > + if (!strcmp(pdev->dev.platform_data, "rpmsg-micfil-channel"))
> > + np = of_find_node_by_name(NULL, "rpmsg_micfil");
> > + else
> > + np = of_find_node_by_name(NULL, "rpmsg_audio");
> 
> Why do you create ABI on node names? Where is it documented? Why can't
> you use phandles?
> 
> Best regards,
> Krzysztof

Thanks for your reminder. Truly I shouldn't use undocumented bindings. I will
use “fsl,rpmsg-channel-name” to refine patch set. Please help review next
version.

Regards, 
Chancel Liu