Re: [Bisected] PowerMac G5 fails booting kernel 6.6-rc3 (BUG: Unable to handle kernel data access at 0xfeffbb62ffec65fe)

2023-10-16 Thread Michael Ellerman
Erhard Furtner  writes:
> On Thu, 12 Oct 2023 22:41:56 +1100
> Michael Ellerman  wrote:
>
>> Can you checkout the exact commit that crash is from and do:
>> 
>>  $ make arch/powerpc/mm/book3s64/hash_utils.lst
>> 
>> And paste/attach the content of that file.
>> 
>> cheers
>
> Ok, attached the output from:
>
> git checkout 9fee28baa601f4dbf869b1373183b312d2d5ef3d
> make vmlinux -j16
> make arch/powerpc/mm/book3s64/hash_utils.lst
>
> Commit 9fee28baa601f4dbf869b1373183b312d2d5ef3d is the 1st bad commit of my 
> bisect.

Thanks.

I think I've reproduced the crash on my Quad G5 by using your config
with some things tweaked, but I don't get any output on the screen :/

Do you mind booting the commit above and taking a photo of the oops and
attach it here. The oops you transcribed didn't entirely make sense,
probably due to a typo here or there, so a photo would be best.

cheers


[PATCHv9 2/2] powerpc/setup: Loosen the mapping between cpu logical id and its seq in dt

2023-10-16 Thread Pingfan Liu
*** Idea ***
For kexec -p, the boot cpu can be not the cpu0, this causes the problem
of allocating memory for paca_ptrs[]. However, in theory, there is no
requirement to assign cpu's logical id as its present sequence in the
device tree. But there is something like cpu_first_thread_sibling(),
which makes assumption on the mapping inside a core. Hence partially
loosening the mapping, i.e. unbind the mapping of core while keep the
mapping inside a core.

*** Implement ***
At this early stage, there are plenty of memory to utilize. Hence, this
patch allocates interim memory to link the cpu info on a list, then
reorder cpus by changing the list head. As a result, there is a rotate
shift between the sequence number in dt and the cpu logical number.

*** Result ***
After this patch, a boot-cpu's logical id will always be mapped into the
range [0,threads_per_core).

Besides this, at this phase, all threads in the boot core are forced to
be onlined. This restriction will be lifted in a later patch with
extra effort.

Signed-off-by: Pingfan Liu 
Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Christophe Leroy 
Cc: Mahesh Salgaonkar 
Cc: Wen Xiong 
Cc: Baoquan He 
Cc: Ming Lei 
Cc: Sourabh Jain 
Cc: Hari Bathini 
Cc: ke...@lists.infradead.org
To: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/kernel/prom.c | 25 +
 arch/powerpc/kernel/setup-common.c | 84 +++---
 2 files changed, 82 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index ec82f5bda908..7ed9034912ca 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -76,7 +76,9 @@ u64 ppc64_rma_size;
 unsigned int boot_cpu_node_count __ro_after_init;
 #endif
 static phys_addr_t first_memblock_size;
+#ifdef CONFIG_SMP
 static int __initdata boot_cpu_count;
+#endif
 
 static int __init early_parse_mem(char *p)
 {
@@ -331,8 +333,7 @@ static int __init early_init_dt_scan_cpus(unsigned long 
node,
const __be32 *intserv;
int i, nthreads;
int len;
-   int found = -1;
-   int found_thread = 0;
+   bool found = false;
 
/* We are scanning "cpu" nodes only */
if (type == NULL || strcmp(type, "cpu") != 0)
@@ -355,8 +356,15 @@ static int __init early_init_dt_scan_cpus(unsigned long 
node,
for (i = 0; i < nthreads; i++) {
if (be32_to_cpu(intserv[i]) ==
fdt_boot_cpuid_phys(initial_boot_params)) {
-   found = boot_cpu_count;
-   found_thread = i;
+   /*
+* always map the boot-cpu logical id into the
+* range of [0, thread_per_core)
+*/
+   boot_cpuid = i;
+   found = true;
+   /* This forces all threads in a core to be online */
+   if (nr_cpu_ids % nthreads != 0)
+   set_nr_cpu_ids(ALIGN(nr_cpu_ids, nthreads));
}
 #ifdef CONFIG_SMP
/* logical cpu id is always 0 on UP kernels */
@@ -365,14 +373,13 @@ static int __init early_init_dt_scan_cpus(unsigned long 
node,
}
 
/* Not the boot CPU */
-   if (found < 0)
+   if (!found)
return 0;
 
-   DBG("boot cpu: logical %d physical %d\n", found,
-   be32_to_cpu(intserv[found_thread]));
-   boot_cpuid = found;
+   DBG("boot cpu: logical %d physical %d\n", boot_cpuid,
+   be32_to_cpu(intserv[boot_cpuid]));
 
-   boot_cpu_hwid = be32_to_cpu(intserv[found_thread]);
+   boot_cpu_hwid = be32_to_cpu(intserv[boot_cpuid]);
 
/*
 * PAPR defines "logical" PVR values for cpus that
diff --git a/arch/powerpc/kernel/setup-common.c 
b/arch/powerpc/kernel/setup-common.c
index 707f0490639d..9802c7e5ee2f 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -425,6 +426,13 @@ static void __init cpu_init_thread_core_maps(int tpc)
 
 u32 *cpu_to_phys_id = NULL;
 
+struct interrupt_server_node {
+   struct list_head node;
+   boolavail;
+   int len;
+   __be32 intserv[];
+};
+
 /**
  * setup_cpu_maps - initialize the following cpu maps:
  *  cpu_possible_mask
@@ -446,11 +454,16 @@ u32 *cpu_to_phys_id = NULL;
 void __init smp_setup_cpu_maps(void)
 {
struct device_node *dn;
-   int cpu = 0;
-   int nthreads = 1;
+   int shift = 0, cpu = 0;
+   int j, nthreads = 1;
+   int len;
+   struct interrupt_server_node *intserv_node, *n;
+   struct list_head *bt_node, head;
+   bool avail, found_boot_cpu = false;
 
DBG("smp_setup_cpu_maps()\n");
 
+   INIT_LIST_HEAD();
cpu_to_phys_id = memblock_alloc(nr_cpu_ids * sizeof(u32),

[PATCHv9 1/2] powerpc/setup : Enable boot_cpu_hwid for PPC32

2023-10-16 Thread Pingfan Liu
In order to identify the boot cpu, its intserv[] should be recorded and
checked in smp_setup_cpu_maps().

smp_setup_cpu_maps() is shared between PPC64 and PPC32. Since PPC64 has
already used boot_cpu_hwid to carry that information, enabling this
variable on PPC32 so later it can also be used to carry that information
for PPC32 in the coming patch.

Signed-off-by: Pingfan Liu 
Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Christophe Leroy 
Cc: Mahesh Salgaonkar 
Cc: Wen Xiong 
Cc: Baoquan He 
Cc: Ming Lei 
Cc: Sourabh Jain 
Cc: Hari Bathini 
Cc: ke...@lists.infradead.org
To: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/include/asm/smp.h | 2 +-
 arch/powerpc/kernel/prom.c | 3 +--
 arch/powerpc/kernel/setup-common.c | 2 --
 3 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 576d0e15..5db9178cc800 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -26,7 +26,7 @@
 #include 
 
 extern int boot_cpuid;
-extern int boot_cpu_hwid; /* PPC64 only */
+extern int boot_cpu_hwid;
 extern int spinning_secondaries;
 extern u32 *cpu_to_phys_id;
 extern bool coregroup_enabled;
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 0b5878c3125b..ec82f5bda908 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -372,8 +372,7 @@ static int __init early_init_dt_scan_cpus(unsigned long 
node,
be32_to_cpu(intserv[found_thread]));
boot_cpuid = found;
 
-   if (IS_ENABLED(CONFIG_PPC64))
-   boot_cpu_hwid = be32_to_cpu(intserv[found_thread]);
+   boot_cpu_hwid = be32_to_cpu(intserv[found_thread]);
 
/*
 * PAPR defines "logical" PVR values for cpus that
diff --git a/arch/powerpc/kernel/setup-common.c 
b/arch/powerpc/kernel/setup-common.c
index 2f1026fba00d..707f0490639d 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -87,9 +87,7 @@ EXPORT_SYMBOL(machine_id);
 int boot_cpuid = -1;
 EXPORT_SYMBOL_GPL(boot_cpuid);
 
-#ifdef CONFIG_PPC64
 int boot_cpu_hwid = -1;
-#endif
 
 /*
  * These are used in binfmt_elf.c to put aux entries on the stack
-- 
2.31.1



[PATCHv9 0/2] enable nr_cpus for powerpc

2023-10-16 Thread Pingfan Liu
From: Pingfan Liu 


Since my last v4 [1], the code has undergone great changes. The paca[]
array has been reorganized and indexed by paca_ptrs[], which
dramatically decreases the memory consumption even if there are many
unpresent cpus in the middle.

However, reordering the logical cpu numbers can further decrease the
size of paca_ptrs[] in the kdump case. These two patches rotate-shifts
the cpu's sequence number in the device tree to obtain the logical cpu
id.


[1]: 
https://lore.kernel.org/linuxppc-dev/1520829790-14029-1-git-send-email-kernelf...@gmail.com/
---
v8 -> v9
  put aside [3-5/5] in v8 for the time being, which complicates the code.
  optimize out some unnecessary initialization according to Hari's
suggestion

Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Christophe Leroy 
Cc: Mahesh Salgaonkar 
Cc: Wen Xiong 
Cc: Baoquan He 
Cc: Ming Lei 
Cc: Sourabh Jain 
Cc: Hari Bathini 
Cc: ke...@lists.infradead.org
To: linuxppc-dev@lists.ozlabs.org

Pingfan Liu (2):
  powerpc/setup : Enable boot_cpu_hwid for PPC32
  powerpc/setup: Loosen the mapping between cpu logical id and its seq
in dt

 arch/powerpc/include/asm/smp.h |  2 +-
 arch/powerpc/kernel/prom.c | 26 +
 arch/powerpc/kernel/setup-common.c | 86 +++---
 3 files changed, 83 insertions(+), 31 deletions(-)

-- 
2.31.1



Re: [PATCHv8 1/5] powerpc/setup : Enable boot_cpu_hwid for PPC32

2023-10-16 Thread Pingfan Liu
On Mon, Oct 16, 2023 at 12:13:53PM +0530, Sourabh Jain wrote:
> Hello Pingfan,
> 
> > > > > > With this patch series applied, the kdump kernel fails to boot on
> > > > > > powerpc with nr_cpus=1.
> > > > > > 
> > > > > > Console logs:
> > > > > > ---
> > > > > > [root]# echo c > /proc/sysrq-trigger
> > > > > > [   74.783235] sysrq: Trigger a crash
> > > > > > [   74.783244] Kernel panic - not syncing: sysrq triggered crash
> > > > > > [   74.783252] CPU: 58 PID: 3838 Comm: bash Kdump: loaded Not 
> > > > > > tainted
> > > > > > 6.6.0-rc5pf-nr-cpus+ #3
> > > > > > [   74.783259] Hardware name: POWER10 (raw) phyp pSeries
> > > > > > [   74.783275] Call Trace:
> > > > > > [   74.783280] [c0020f4ebac0] [c0ed9f38]
> > > > > > dump_stack_lvl+0x6c/0x9c (unreliable)
> > > > > > [   74.783291] [c0020f4ebaf0] [c0150300] 
> > > > > > panic+0x178/0x438
> > > > > > [   74.783298] [c0020f4ebb90] [c0936d48]
> > > > > > sysrq_handle_crash+0x28/0x30
> > > > > > [   74.783304] [c0020f4ebbf0] [c093773c]
> > > > > > __handle_sysrq+0x10c/0x250
> > > > > > [   74.783309] [c0020f4ebc90] [c0937fa8]
> > > > > > write_sysrq_trigger+0xc8/0x168
> > > > > > [   74.783314] [c0020f4ebcd0] [c0665d8c]
> > > > > > proc_reg_write+0x10c/0x1b0
> > > > > > [   74.783321] [c0020f4ebd00] [c058da54]
> > > > > > vfs_write+0x104/0x4b0
> > > > > > [   74.783326] [c0020f4ebdc0] [c058dfdc]
> > > > > > ksys_write+0x7c/0x140
> > > > > > [   74.783331] [c0020f4ebe10] [c0033a64]
> > > > > > system_call_exception+0x144/0x3a0
> > > > > > [   74.783337] [c0020f4ebe50] [c000c554]
> > > > > > system_call_common+0xf4/0x258
> > > > > > [   74.783343] --- interrupt: c00 at 0x7fffa0721594
> > > > > > [   74.783352] NIP:  7fffa0721594 LR: 7fffa0697bf4 CTR:
> > > > > > 
> > > > > > [   74.783364] REGS: c0020f4ebe80 TRAP: 0c00   Not tainted
> > > > > > (6.6.0-rc5pf-nr-cpus+)
> > > > > > [   74.783376] MSR:  8280f033
> > > > > >   CR: 2802  XER: 
> > > > > > [   74.783394] IRQMASK: 0
> > > > > > [   74.783394] GPR00: 0004 7c4b6800 
> > > > > > 7fffa0807300
> > > > > > 0001
> > > > > > [   74.783394] GPR04: 00013549ea60 0002 
> > > > > > 0010
> > > > > > 
> > > > > > [   74.783394] GPR08:   
> > > > > > 
> > > > > > 
> > > > > > [   74.783394] GPR12:  7fffa0abaf70 
> > > > > > 4000
> > > > > > 00011a0f9798
> > > > > > [   74.783394] GPR16: 00011a0f9724 00011a097688 
> > > > > > 00011a02ff70
> > > > > > 00011a0fd568
> > > > > > [   74.783394] GPR20: 000135554bf0 0001 
> > > > > > 00011a0aa478
> > > > > > 7c4b6a24
> > > > > > [   74.783394] GPR24: 7c4b6a20 00011a0faf94 
> > > > > > 0002
> > > > > > 00013549ea60
> > > > > > [   74.783394] GPR28: 0002 7fffa08017a0 
> > > > > > 00013549ea60
> > > > > > 0002
> > > > > > [   74.783440] NIP [7fffa0721594] 0x7fffa0721594
> > > > > > [   74.783443] LR [7fffa0697bf4] 0x7fffa0697bf4
> > > > > > [   74.783447] --- interrupt: c00
> > > > > > I'm in purgatory
> > > > > > [0.00] radix-mmu: Page sizes from device-tree:
> > > > > > [0.00] radix-mmu: Page size shift = 12 AP=0x0
> > > > > > [0.00] radix-mmu: Page size shift = 16 AP=0x5
> > > > > > [0.00] radix-mmu: Page size shift = 21 AP=0x1
> > > > > > [0.00] radix-mmu: Page size shift = 30 AP=0x2
> > > > > > [0.00] Activating Kernel Userspace Access Prevention
> > > > > > [0.00] Activating Kernel Userspace Execution Prevention
> > > > > > [0.00] radix-mmu: Mapped 
> > > > > > 0x-0x0001
> > > > > > with 64.0 KiB pages (exec)
> > > > > > [0.00] radix-mmu: Mapped 
> > > > > > 0x0001-0x0020
> > > > > > with 64.0 KiB pages
> > > > > > [0.00] radix-mmu: Mapped 
> > > > > > 0x0020-0x2000
> > > > > > with 2.00 MiB pages
> > > > > > [0.00] radix-mmu: Mapped 
> > > > > > 0x2000-0x2260
> > > > > > with 2.00 MiB pages (exec)
> > > > > > [0.00] radix-mmu: Mapped 
> > > > > > 0x2260-0x4000
> > > > > > with 2.00 MiB pages
> > > > > > [0.00] radix-mmu: Mapped 
> > > > > > 0x4000-0x00018000
> > > > > > with 1.00 GiB pages
> > > > > > [0.00] radix-mmu: Mapped 
> > > > > > 0x00018000-0x0001a000
> > > > > > with 2.00 MiB pages
> > > > > > [0.00] lpar: Using radix MMU under hypervisor
> > > > > > [0.00] Linux version 6.6.0-rc5pf-nr-cpus+
> > > > > > (r...@ltcever7x0-lp1.aus.stglabs.ibm.com) (gcc (GCC) 8.5.0 20210514 
> > > > > > (Red
> > > > > > Hat 

Re: [PATCH] scsi: ibmvfc: Use 'unsigned int' for single-bit bitfields in 'struct ibmvfc_host'

2023-10-16 Thread Martin K. Petersen
On Tue, 10 Oct 2023 13:32:37 -0700, Nathan Chancellor wrote:

> Clang warns (or errors with CONFIG_WERROR=y) several times along the
> lines of:
> 
>   drivers/scsi/ibmvscsi/ibmvfc.c:650:17: warning: implicit truncation from 
> 'int' to a one-bit wide bit-field changes value from 1 to -1 
> [-Wsingle-bit-bitfield-constant-conversion]
> 650 | vhost->reinit = 1;
> |   ^ ~
> 
> [...]

Applied to 6.7/scsi-queue, thanks!

[1/1] scsi: ibmvfc: Use 'unsigned int' for single-bit bitfields in 'struct 
ibmvfc_host'
  https://git.kernel.org/mkp/scsi/c/78882c7657bb

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH V2 0/3] Fix for shellcheck issues with latest scripts in tests/shell

2023-10-16 Thread Namhyung Kim
Hello,

On Fri, Oct 13, 2023 at 12:31 AM Athira Rajeev
 wrote:
>
> shellcheck was run on perf tool shell scripts as a pre-requisite
> to include a build option for shellcheck discussed here:
> https://www.spinics.net/lists/linux-perf-users/msg25553.html
>
> And fixes were added for the coding/formatting issues in
> two patchsets:
> https://lore.kernel.org/linux-perf-users/20230613164145.50488-1-atraj...@linux.vnet.ibm.com/
> https://lore.kernel.org/linux-perf-users/20230709182800.53002-1-atraj...@linux.vnet.ibm.com/
>
> Three additional issues were observed and fixes are part of:
> git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git
>
> With recent commits in perf, other three issues are observed.
> shellcheck version: 0.6.0
> The changes are with recent commits ( which is mentioned in each patch)
> for lock_contention, record_sideband and stat_all_metricgroups test.
> Patch series fixes these testcases and patches are on top of:
> git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git
>
> The version 1 patchset had fix patch for test_arm_coresight.sh.
> Dropping that in V2 based on discussion here:
> https://lore.kernel.org/linux-perf-users/f265857d-0d37-4878-908c-d20732f21...@linux.vnet.ibm.com/T/#u
>
> Athira Rajeev (3):
>   tools/perf/tests Ignore the shellcheck SC2046 warning in
> lock_contention
>   tools/perf/tests: Fix shellcheck warning in record_sideband.sh test
>   tools/perf/tests/shell: Fix shellcheck warning SC2112 with
> stat_all_metricgroups

For the series,
Acked-by: Namhyung Kim 

Thanks,
Namhyung


Re: [PATCH] powerpc/pseries/vas: Migration suspend waits for no in-progress open windows

2023-10-16 Thread Haren Myneni




On 10/16/23 1:30 PM, Nathan Lynch wrote:

Nathan Lynch  writes:

Haren Myneni  writes:

Haren Myneni  writes:

The hypervisor returns migration failure if all VAS windows are not
closed. During pre-migration stage, vas_migration_handler() sets
migration_in_progress flag and closes all windows from the list.
The allocate VAS window routine checks the migration flag, setup
the window and then add it to the list. So there is possibility of
the migration handler missing the window that is still in the
process of setup.

t1: Allocate and open VAS   t2: Migration event
  window

lock vas_pseries_mutex
If migration_in_progress set
unlock vas_pseries_mutex
return
open window HCALL
unlock vas_pseries_mutex
Modify window HCALL lock vas_pseries_mutex
setup windowmigration_in_progress=true
Closes all windows from
the list
unlock vas_pseries_mutex
lock vas_pseries_mutex  return
if nr_closed_windows == 0
// No DLPAR CPU or migration
add to the list
unlock vas_pseries_mutex
return
unlock vas_pseries_mutex
Close VAS window
// due to DLPAR CPU or migration
return -EBUSY


Could the the path t1 takes simply hold the mutex for the duration of
its execution instead of dropping and reacquiring it in the middle?

Here's the relevant code from vas_allocate_window():

mutex_lock(_pseries_mutex);
if (migration_in_progress)
rc = -EBUSY;
else
rc = allocate_setup_window(txwin, (u64 *)[0],
   cop_feat_caps->win_type);
mutex_unlock(_pseries_mutex);
if (rc)
goto out;

rc = h_modify_vas_window(txwin);
if (!rc)
rc = get_vas_user_win_ref(>vas_win.task_ref);
if (rc)
goto out_free;

txwin->win_type = cop_feat_caps->win_type;
mutex_lock(_pseries_mutex);
if (!caps->nr_close_wins) {
list_add(>win_list, >list);
caps->nr_open_windows++;
mutex_unlock(_pseries_mutex);
vas_user_win_add_mm_context(>vas_win.task_ref);
return >vas_win;
}
mutex_unlock(_pseries_mutex);

Is there something about h_modify_vas_window() or get_vas_user_win_ref()
that requires temporarily dropping the lock?



Thanks Nathan for your comments.

vas_pseries_mutex protects window ID and IRQ allocation between alloc
and free window HCALLs, and window list. Generally try to not using
mutex in HCALLs, but we need this mutex with these HCALLs.

We can add h_modify_vas_window() or get_vas_user_win_ref() with in the
mutex context, but not needed.


Hmm. I contend that it would fix your bug in a simpler way that
eliminates the race instead of coping with it by adding more state and
complicating the locking model. With your change, readers of the
migration_in_progress flag check it under the mutex, but the writer
updates it outside of the mutex, which seems strange and unlikely to be
correct.


Expanding on this, with your change, migration_in_progress becomes a
boolean atomic_t flag accessed only with atomic_set() and
atomic_read(). These are non-RMW operations. Documentation/atomic_t.txt
says:

   Non-RMW ops:

   The non-RMW ops are (typically) regular LOADs and STOREs and are
   canonically implemented using READ_ONCE(), WRITE_ONCE(),
   smp_load_acquire() and smp_store_release() respectively. Therefore, if
   you find yourself only using the Non-RMW operations of atomic_t, you
   do not in fact need atomic_t at all and are doing it wrong.

So making migration_in_progress an atomic_t does not confer any
advantageous properties to it that it lacks as a plain boolean.

Considering also (from the same document):

  - non-RMW operations are unordered;

  - RMW operations that have no return value are unordered;

I am concerned that threads executing these segments of code will not
always observe each others' effects in the intended order:

// vas_allocate_window()

 mutex_lock(_pseries_mutex);
 if (!caps->nr_close_wins && !atomic_read(_in_progress)) {
 list_add(>win_list, >list);
 caps->nr_open_windows++;
 atomic_dec(>nr_open_wins_progress);
 mutex_unlock(_pseries_mutex);
 vas_user_win_add_mm_context(>vas_win.task_ref);
 return >vas_win;
 }
 mutex_unlock(_pseries_mutex);
 ...
 atomic_dec(>nr_open_wins_progress);
 wake_up(_win_progress_wq);

// vas_migration_handler()

 atomic_set(_in_progress, 1);
 ...
 mutex_lock(_pseries_mutex);
 rc = reconfig_close_windows(vcaps, 
vcaps->nr_open_windows,
 true);
 

Re: [PATCH] powerpc/pseries/vas: Migration suspend waits for no in-progress open windows

2023-10-16 Thread Nathan Lynch
Nathan Lynch  writes:
> Haren Myneni  writes:
>>> Haren Myneni  writes:
 The hypervisor returns migration failure if all VAS windows are not
 closed. During pre-migration stage, vas_migration_handler() sets
 migration_in_progress flag and closes all windows from the list.
 The allocate VAS window routine checks the migration flag, setup
 the window and then add it to the list. So there is possibility of
 the migration handler missing the window that is still in the
 process of setup.

 t1: Allocate and open VAS  t2: Migration event
  window

 lock vas_pseries_mutex
 If migration_in_progress set
unlock vas_pseries_mutex
return
 open window HCALL
 unlock vas_pseries_mutex
 Modify window HCALLlock vas_pseries_mutex
 setup window   migration_in_progress=true
Closes all windows from
the list
unlock vas_pseries_mutex
 lock vas_pseries_mutex return
 if nr_closed_windows == 0
// No DLPAR CPU or migration
add to the list
unlock vas_pseries_mutex
return
 unlock vas_pseries_mutex
 Close VAS window
 // due to DLPAR CPU or migration
 return -EBUSY
>>> 
>>> Could the the path t1 takes simply hold the mutex for the duration of
>>> its execution instead of dropping and reacquiring it in the middle?
>>> 
>>> Here's the relevant code from vas_allocate_window():
>>> 
>>> mutex_lock(_pseries_mutex);
>>> if (migration_in_progress)
>>> rc = -EBUSY;
>>> else
>>> rc = allocate_setup_window(txwin, (u64 *)[0],
>>>cop_feat_caps->win_type);
>>> mutex_unlock(_pseries_mutex);
>>> if (rc)
>>> goto out;
>>> 
>>> rc = h_modify_vas_window(txwin);
>>> if (!rc)
>>> rc = get_vas_user_win_ref(>vas_win.task_ref);
>>> if (rc)
>>> goto out_free;
>>> 
>>> txwin->win_type = cop_feat_caps->win_type;
>>> mutex_lock(_pseries_mutex);
>>> if (!caps->nr_close_wins) {
>>> list_add(>win_list, >list);
>>> caps->nr_open_windows++;
>>> mutex_unlock(_pseries_mutex);
>>> vas_user_win_add_mm_context(>vas_win.task_ref);
>>> return >vas_win;
>>> }
>>> mutex_unlock(_pseries_mutex);
>>> 
>>> Is there something about h_modify_vas_window() or get_vas_user_win_ref()
>>> that requires temporarily dropping the lock?
>>> 
>>
>> Thanks Nathan for your comments.
>>
>> vas_pseries_mutex protects window ID and IRQ allocation between alloc 
>> and free window HCALLs, and window list. Generally try to not using 
>> mutex in HCALLs, but we need this mutex with these HCALLs.
>>
>> We can add h_modify_vas_window() or get_vas_user_win_ref() with in the 
>> mutex context, but not needed.
>
> Hmm. I contend that it would fix your bug in a simpler way that
> eliminates the race instead of coping with it by adding more state and
> complicating the locking model. With your change, readers of the
> migration_in_progress flag check it under the mutex, but the writer
> updates it outside of the mutex, which seems strange and unlikely to be
> correct.

Expanding on this, with your change, migration_in_progress becomes a
boolean atomic_t flag accessed only with atomic_set() and
atomic_read(). These are non-RMW operations. Documentation/atomic_t.txt
says:

  Non-RMW ops:

  The non-RMW ops are (typically) regular LOADs and STOREs and are
  canonically implemented using READ_ONCE(), WRITE_ONCE(),
  smp_load_acquire() and smp_store_release() respectively. Therefore, if
  you find yourself only using the Non-RMW operations of atomic_t, you
  do not in fact need atomic_t at all and are doing it wrong.

So making migration_in_progress an atomic_t does not confer any
advantageous properties to it that it lacks as a plain boolean.

Considering also (from the same document):

 - non-RMW operations are unordered;

 - RMW operations that have no return value are unordered;

I am concerned that threads executing these segments of code will not
always observe each others' effects in the intended order:

// vas_allocate_window()

mutex_lock(_pseries_mutex);
if (!caps->nr_close_wins && !atomic_read(_in_progress)) {
list_add(>win_list, >list);
caps->nr_open_windows++;
atomic_dec(>nr_open_wins_progress);
mutex_unlock(_pseries_mutex);
vas_user_win_add_mm_context(>vas_win.task_ref);
return >vas_win;
}
mutex_unlock(_pseries_mutex);
...
atomic_dec(>nr_open_wins_progress);
wake_up(_win_progress_wq);

// vas_migration_handler()

atomic_set(_in_progress, 1);
...
mutex_lock(_pseries_mutex);
rc = 

Re: [PATCH 2/3] PCI: layerscape: add suspend/resume for ls1021a

2023-10-16 Thread Frank Li
On Mon, Oct 16, 2023 at 10:28:24PM +0530, Manivannan Sadhasivam wrote:
> On Fri, Sep 15, 2023 at 02:43:05PM -0400, Frank Li wrote:
> > ls1021a add suspend/resume support.
> > 
> 
> Please add what the driver is doing during suspend/resume.
> 
> > Signed-off-by: Frank Li 
> > ---
> >  drivers/pci/controller/dwc/pci-layerscape.c | 88 -
> >  1 file changed, 87 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/pci/controller/dwc/pci-layerscape.c 
> > b/drivers/pci/controller/dwc/pci-layerscape.c
> > index 20c48c06e2248..bc5a8ff1a26ce 100644
> > --- a/drivers/pci/controller/dwc/pci-layerscape.c
> > +++ b/drivers/pci/controller/dwc/pci-layerscape.c
> > @@ -35,6 +35,12 @@
> >  #define PF_MCR_PTOMR   BIT(0)
> >  #define PF_MCR_EXL2S   BIT(1)
> >  
> > +/* LS1021A PEXn PM Write Control Register */
> > +#define SCFG_PEXPMWRCR(idx)(0x5c + (idx) * 0x64)
> > +#define PMXMTTURNOFF   BIT(31)
> > +#define SCFG_PEXSFTRSTCR   0x190
> > +#define PEXSR(idx) BIT(idx)
> > +
> >  #define PCIE_IATU_NUM  6
> >  
> >  struct ls_pcie_drvdata {
> > @@ -48,6 +54,8 @@ struct ls_pcie {
> > struct dw_pcie *pci;
> > const struct ls_pcie_drvdata *drvdata;
> > void __iomem *pf_base;
> > +   struct regmap *scfg;
> > +   int index;
> > bool big_endian;
> >  };
> >  
> > @@ -170,13 +178,91 @@ static int ls_pcie_host_init(struct dw_pcie_rp *pp)
> > return 0;
> >  }
> >  
> > +static void ls1021a_pcie_send_turnoff_msg(struct dw_pcie_rp *pp)
> > +{
> > +   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > +   struct ls_pcie *pcie = to_ls_pcie(pci);
> > +   u32 val;
> > +
> > +   if (!pcie->scfg) {
> 
> Can this ever happen?
> 
> > +   dev_dbg(pcie->pci->dev, "SYSCFG is NULL\n");
> > +   return;
> > +   }
> > +
> > +   /* Send Turn_off message */
> 
> "Send PME_Turn_Off message"
> 
> > +   regmap_read(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), );
> > +   val |= PMXMTTURNOFF;
> > +   regmap_write(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), val);
> > +
> > +   /* There are not register to check ACK, so wait 
> > PCIE_PME_TO_L2_TIMEOUT_US */
> 
> "There is no specific register to check for PME_To_Ack from endpoint. So on 
> the
> safe side, wait for PCIE_PME_TO_L2_TIMEOUT_US."
> 
> > +   mdelay(PCIE_PME_TO_L2_TIMEOUT_US/1000);
> > +
> > +   /* Clear Turn_off message */
> 
> "PME_Turn_off". But I'm not sure if this is really required. Are you doing it
> because the layerspace hw implements the PME_Turn_Off bit as "level 
> triggered"?

I am not sure how hardware implement this. But reference manual said:
 
PMXMTTURNOFF:
Generate PM turnoff message for power management of PCI Express controllers.
This bit should be cleared by software.
0 Clear PM turnoff (default)
1 Trigger PM turnoff

Frank

> 
> > +   regmap_read(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), );
> > +   val &= ~PMXMTTURNOFF;
> > +   regmap_write(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), val);
> > +}
> > +
> > +static void ls1021a_pcie_exit_from_l2(struct dw_pcie_rp *pp)
> > +{
> > +   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > +   struct ls_pcie *pcie = to_ls_pcie(pci);
> > +   u32 val;
> > +
> 
> A comment here would be good.
> 
> > +   regmap_read(pcie->scfg, SCFG_PEXSFTRSTCR, );
> > +   val |= PEXSR(pcie->index);
> > +   regmap_write(pcie->scfg, SCFG_PEXSFTRSTCR, val);
> > +
> > +   regmap_read(pcie->scfg, SCFG_PEXSFTRSTCR, );
> > +   val &= ~PEXSR(pcie->index);
> > +   regmap_write(pcie->scfg, SCFG_PEXSFTRSTCR, val);
> > +}
> > +
> > +static int ls1021a_pcie_host_init(struct dw_pcie_rp *pp)
> > +{
> > +   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > +   struct ls_pcie *pcie = to_ls_pcie(pci);
> > +   struct device *dev = pcie->pci->dev;
> > +   u32 index[2];
> > +   int ret;
> > +
> > +   ret = ls_pcie_host_init(pp);
> > +   if (ret)
> > +   return ret;
> > +
> > +   pcie->scfg = syscon_regmap_lookup_by_phandle(dev->of_node, 
> > "fsl,pcie-scfg");
> > +   if (IS_ERR(pcie->scfg)) {
> > +   ret = PTR_ERR(pcie->scfg);
> > +   dev_err(dev, "No syscfg phandle specified\n");
> > +   pcie->scfg = NULL;
> > +   return ret;
> > +   }
> > +
> > +   ret = of_property_read_u32_array(dev->of_node, "fsl,pcie-scfg", index, 
> > 2);
> > +   if (ret) {
> > +   pcie->scfg = NULL;
> > +   return ret;
> > +   }
> > +
> > +   pcie->index = index[1];
> > +
> 
> The above syscon parsing could be done conditionally during probe itself. 
> There
> is no need to do it during host_init() time.
> 
> - Mani
> 
> > +   return ret;
> > +}
> > +
> >  static const struct dw_pcie_host_ops ls_pcie_host_ops = {
> > .host_init = ls_pcie_host_init,
> > .pme_turn_off = ls_pcie_send_turnoff_msg,
> >  };
> >  
> > +static const struct dw_pcie_host_ops ls1021a_pcie_host_ops = {
> > +   .host_init = ls1021a_pcie_host_init,
> > +   .pme_turn_off = ls1021a_pcie_send_turnoff_msg,
> > +};
> > +
> >  static const struct ls_pcie_drvdata 

Re: [PATCH 3/3] PCI: layerscape: add suspend/resume for ls1043a

2023-10-16 Thread Manivannan Sadhasivam
On Fri, Sep 15, 2023 at 02:43:06PM -0400, Frank Li wrote:
> ls1043a add suspend/resume support.
> 

Same comment as previous patch for patch description.

> Signed-off-by: Frank Li 
> ---
>  drivers/pci/controller/dwc/pci-layerscape.c | 91 -
>  1 file changed, 90 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-layerscape.c 
> b/drivers/pci/controller/dwc/pci-layerscape.c
> index bc5a8ff1a26ce..debabb9bb41f4 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape.c
> @@ -41,10 +41,20 @@
>  #define SCFG_PEXSFTRSTCR 0x190
>  #define PEXSR(idx)   BIT(idx)
>  
> +/* LS1043A PEX PME control register */
> +#define SCFG_PEXPMECR0x144
> +#define PEXPME(idx)  BIT(31 - (idx) * 4)
> +
> +/* LS1043A PEX LUT debug register */
> +#define LS_PCIE_LDBG 0x7fc
> +#define LDBG_SR  BIT(30)
> +#define LDBG_WE  BIT(31)
> +
>  #define PCIE_IATU_NUM6
>  
>  struct ls_pcie_drvdata {
>   const u32 pf_off;
> + const u32 lut_off;
>   const struct dw_pcie_host_ops *ops;
>   void (*exit_from_l2)(struct dw_pcie_rp *pp);
>   bool pm_support;
> @@ -54,6 +64,7 @@ struct ls_pcie {
>   struct dw_pcie *pci;
>   const struct ls_pcie_drvdata *drvdata;
>   void __iomem *pf_base;
> + void __iomem *lut_base;
>   struct regmap *scfg;
>   int index;
>   bool big_endian;
> @@ -116,6 +127,23 @@ static void ls_pcie_pf_writel(struct ls_pcie *pcie, u32 
> off, u32 val)
>   iowrite32(val, pcie->pf_base + off);
>  }
>  
> +static u32 ls_pcie_lut_readl(struct ls_pcie *pcie, u32 off)
> +{

Looking at ls_pcie_pf_{readl/writel} you can use a common function that does the
read/write and pass the relevant base/offset. This will avoid code duplication.

> + if (pcie->big_endian)
> + return ioread32be(pcie->lut_base + off);
> +
> + return ioread32(pcie->lut_base + off);
> +}
> +
> +static void ls_pcie_lut_writel(struct ls_pcie *pcie, u32 off, u32 val)
> +{
> + if (pcie->big_endian)
> + iowrite32be(val, pcie->lut_base + off);
> + else
> + iowrite32(val, pcie->lut_base + off);
> +}
> +

Remove extra newline

> +
>  static void ls_pcie_send_turnoff_msg(struct dw_pcie_rp *pp)
>  {
>   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> @@ -249,6 +277,54 @@ static int ls1021a_pcie_host_init(struct dw_pcie_rp *pp)
>   return ret;
>  }
>  
> +static void ls1043a_pcie_send_turnoff_msg(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct ls_pcie *pcie = to_ls_pcie(pci);
> + u32 val;
> +
> + if (!pcie->scfg) {
> + dev_dbg(pcie->pci->dev, "SYSCFG is NULL\n");
> + return;
> + }
> +
> + /* Send Turn_off message */
> + regmap_read(pcie->scfg, SCFG_PEXPMECR, );

If the register offset is the only difference, then you could pass the register
offset via drvdata and use the same functions.

> + val |= PEXPME(pcie->index);
> + regmap_write(pcie->scfg, SCFG_PEXPMECR, val);
> +
> + /* There are not register to check ACK, so wait 
> PCIE_PME_TO_L2_TIMEOUT_US */
> + mdelay(PCIE_PME_TO_L2_TIMEOUT_US/1000);
> +
> + /* Clear Turn_off message */
> + regmap_read(pcie->scfg, SCFG_PEXPMECR, );
> + val &= ~PEXPME(pcie->index);
> + regmap_write(pcie->scfg, SCFG_PEXPMECR, val);
> +}
> +
> +static void ls1043a_pcie_exit_from_l2(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct ls_pcie *pcie = to_ls_pcie(pci);
> + u32 val;
> +

Again, a comment here would be useful.

- Mani

> + val = ls_pcie_lut_readl(pcie, LS_PCIE_LDBG);
> + val |= LDBG_WE;
> + ls_pcie_lut_writel(pcie, LS_PCIE_LDBG, val);
> +
> + val = ls_pcie_lut_readl(pcie, LS_PCIE_LDBG);
> + val |= LDBG_SR;
> + ls_pcie_lut_writel(pcie, LS_PCIE_LDBG, val);
> +
> + val = ls_pcie_lut_readl(pcie, LS_PCIE_LDBG);
> + val &= ~LDBG_SR;
> + ls_pcie_lut_writel(pcie, LS_PCIE_LDBG, val);
> +
> + val = ls_pcie_lut_readl(pcie, LS_PCIE_LDBG);
> + val &= ~LDBG_WE;
> + ls_pcie_lut_writel(pcie, LS_PCIE_LDBG, val);
> +}
> +
>  static const struct dw_pcie_host_ops ls_pcie_host_ops = {
>   .host_init = ls_pcie_host_init,
>   .pme_turn_off = ls_pcie_send_turnoff_msg,
> @@ -265,6 +341,18 @@ static const struct ls_pcie_drvdata ls1021a_drvdata = {
>   .exit_from_l2 = ls1021a_pcie_exit_from_l2,
>  };
>  
> +static const struct dw_pcie_host_ops ls1043a_pcie_host_ops = {
> + .host_init = ls1021a_pcie_host_init, /* the same as ls1021 */
> + .pme_turn_off = ls1043a_pcie_send_turnoff_msg,
> +};
> +
> +static const struct ls_pcie_drvdata ls1043a_drvdata = {
> + .lut_off = 0x1,
> + .pm_support = true,
> + .ops = _pcie_host_ops,
> + .exit_from_l2 = ls1043a_pcie_exit_from_l2,
> +};
> +
>  static const struct ls_pcie_drvdata 

Re: [PATCH 2/3] PCI: layerscape: add suspend/resume for ls1021a

2023-10-16 Thread Frank Li
On Mon, Oct 16, 2023 at 11:25:12AM -0500, Bjorn Helgaas wrote:
> On Mon, Oct 16, 2023 at 12:11:04PM -0400, Frank Li wrote:
> > On Mon, Oct 16, 2023 at 10:22:11AM -0500, Bjorn Helgaas wrote:
> 
> > > Obviously Lorenzo *could* edit all your subject lines on your behalf,
> > > but it makes everybody's life easier if people look at the existing
> > > code and follow the style when making changes.
> > 
> > Understand, but simple mark 'a' and 'A' to me. I will update patches and
> > take care for next time instead search whole docuemnt to guess which one
> > violated. I know I make some mistakes at here. But I am working on many
> > difference kernel subsystems, some require upper case, some require low
> > case, someone doesn't care.
> 
> Right, that's why I always suggest following the example of the
> surrounding code and history.  English is the only language I know,
> but I speculate that this typographical detail probably doesn't make
> sense in languages that don't have a similar upper/lowercase
> distinction.

If everyone thinks it is important. I suggest put it in checkpatch.pl
script. The only script check can prevent to human make mistakes.

I asked the same question at:
https://lore.kernel.org/imx/ZSV1sINV%2F2GrAYFr@lizhi-Precision-Tower-5810/T/#t

It lets teach kid mulitplication,  kid did 20 questions. only 1 failure.
The good teacher should tell which one is wrong and grade as 19/20 instead
of just grade 19/20 without any comments.

We are using email communication instead of face to face. The efficient of
communication is important. We have differece background, difference
native languadge, live on difference area in world and do the same jobs to
make linux kernel better.

The simple and straight forward's feedback can save both our time and
efforts.

Frank Li

> 
> Thanks for persevering; we'd be having a lot more trouble if I tried
> to send emails in your native language ;)
> 
> Bjorn


Re: [PATCH 2/3] PCI: layerscape: add suspend/resume for ls1021a

2023-10-16 Thread Manivannan Sadhasivam
On Fri, Sep 15, 2023 at 02:43:05PM -0400, Frank Li wrote:
> ls1021a add suspend/resume support.
> 

Please add what the driver is doing during suspend/resume.

> Signed-off-by: Frank Li 
> ---
>  drivers/pci/controller/dwc/pci-layerscape.c | 88 -
>  1 file changed, 87 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-layerscape.c 
> b/drivers/pci/controller/dwc/pci-layerscape.c
> index 20c48c06e2248..bc5a8ff1a26ce 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape.c
> @@ -35,6 +35,12 @@
>  #define PF_MCR_PTOMR BIT(0)
>  #define PF_MCR_EXL2S BIT(1)
>  
> +/* LS1021A PEXn PM Write Control Register */
> +#define SCFG_PEXPMWRCR(idx)  (0x5c + (idx) * 0x64)
> +#define PMXMTTURNOFF BIT(31)
> +#define SCFG_PEXSFTRSTCR 0x190
> +#define PEXSR(idx)   BIT(idx)
> +
>  #define PCIE_IATU_NUM6
>  
>  struct ls_pcie_drvdata {
> @@ -48,6 +54,8 @@ struct ls_pcie {
>   struct dw_pcie *pci;
>   const struct ls_pcie_drvdata *drvdata;
>   void __iomem *pf_base;
> + struct regmap *scfg;
> + int index;
>   bool big_endian;
>  };
>  
> @@ -170,13 +178,91 @@ static int ls_pcie_host_init(struct dw_pcie_rp *pp)
>   return 0;
>  }
>  
> +static void ls1021a_pcie_send_turnoff_msg(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct ls_pcie *pcie = to_ls_pcie(pci);
> + u32 val;
> +
> + if (!pcie->scfg) {

Can this ever happen?

> + dev_dbg(pcie->pci->dev, "SYSCFG is NULL\n");
> + return;
> + }
> +
> + /* Send Turn_off message */

"Send PME_Turn_Off message"

> + regmap_read(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), );
> + val |= PMXMTTURNOFF;
> + regmap_write(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), val);
> +
> + /* There are not register to check ACK, so wait 
> PCIE_PME_TO_L2_TIMEOUT_US */

"There is no specific register to check for PME_To_Ack from endpoint. So on the
safe side, wait for PCIE_PME_TO_L2_TIMEOUT_US."

> + mdelay(PCIE_PME_TO_L2_TIMEOUT_US/1000);
> +
> + /* Clear Turn_off message */

"PME_Turn_off". But I'm not sure if this is really required. Are you doing it
because the layerspace hw implements the PME_Turn_Off bit as "level triggered"?

> + regmap_read(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), );
> + val &= ~PMXMTTURNOFF;
> + regmap_write(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), val);
> +}
> +
> +static void ls1021a_pcie_exit_from_l2(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct ls_pcie *pcie = to_ls_pcie(pci);
> + u32 val;
> +

A comment here would be good.

> + regmap_read(pcie->scfg, SCFG_PEXSFTRSTCR, );
> + val |= PEXSR(pcie->index);
> + regmap_write(pcie->scfg, SCFG_PEXSFTRSTCR, val);
> +
> + regmap_read(pcie->scfg, SCFG_PEXSFTRSTCR, );
> + val &= ~PEXSR(pcie->index);
> + regmap_write(pcie->scfg, SCFG_PEXSFTRSTCR, val);
> +}
> +
> +static int ls1021a_pcie_host_init(struct dw_pcie_rp *pp)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> + struct ls_pcie *pcie = to_ls_pcie(pci);
> + struct device *dev = pcie->pci->dev;
> + u32 index[2];
> + int ret;
> +
> + ret = ls_pcie_host_init(pp);
> + if (ret)
> + return ret;
> +
> + pcie->scfg = syscon_regmap_lookup_by_phandle(dev->of_node, 
> "fsl,pcie-scfg");
> + if (IS_ERR(pcie->scfg)) {
> + ret = PTR_ERR(pcie->scfg);
> + dev_err(dev, "No syscfg phandle specified\n");
> + pcie->scfg = NULL;
> + return ret;
> + }
> +
> + ret = of_property_read_u32_array(dev->of_node, "fsl,pcie-scfg", index, 
> 2);
> + if (ret) {
> + pcie->scfg = NULL;
> + return ret;
> + }
> +
> + pcie->index = index[1];
> +

The above syscon parsing could be done conditionally during probe itself. There
is no need to do it during host_init() time.

- Mani

> + return ret;
> +}
> +
>  static const struct dw_pcie_host_ops ls_pcie_host_ops = {
>   .host_init = ls_pcie_host_init,
>   .pme_turn_off = ls_pcie_send_turnoff_msg,
>  };
>  
> +static const struct dw_pcie_host_ops ls1021a_pcie_host_ops = {
> + .host_init = ls1021a_pcie_host_init,
> + .pme_turn_off = ls1021a_pcie_send_turnoff_msg,
> +};
> +
>  static const struct ls_pcie_drvdata ls1021a_drvdata = {
> - .pm_support = false,
> + .pm_support = true,
> + .ops = _pcie_host_ops,
> + .exit_from_l2 = ls1021a_pcie_exit_from_l2,
>  };
>  
>  static const struct ls_pcie_drvdata layerscape_drvdata = {
> -- 
> 2.34.1
> 

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


Re: [PATCH 1/3] PCI: layerscape: add function pointer for exit_from_l2()

2023-10-16 Thread Manivannan Sadhasivam
On Fri, Sep 15, 2023 at 02:43:04PM -0400, Frank Li wrote:
> Difference layerscape chip have not difference exit_from_l2() method.
> Using function pointer for ls1028. It prepare for other layerscape
> suspend/resume support.
> 

How about:

Since difference SoCs require different sequence for exiting L2, let's add a
separate "exit_from_l2()" callback. This callback can be used to execute SoC
specific sequence.

> Signed-off-by: Frank Li 
> ---
>  drivers/pci/controller/dwc/pci-layerscape.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-layerscape.c 
> b/drivers/pci/controller/dwc/pci-layerscape.c
> index b931d597656f6..20c48c06e2248 100644
> --- a/drivers/pci/controller/dwc/pci-layerscape.c
> +++ b/drivers/pci/controller/dwc/pci-layerscape.c
> @@ -39,6 +39,8 @@
>  
>  struct ls_pcie_drvdata {
>   const u32 pf_off;
> + const struct dw_pcie_host_ops *ops;

Where is this ops used? If this is added as a preparatory for next patches, I'd
suggest you to move it to the respective one instead to avoid confusion.

> + void (*exit_from_l2)(struct dw_pcie_rp *pp);
>   bool pm_support;
>  };
>  
> @@ -180,6 +182,7 @@ static const struct ls_pcie_drvdata ls1021a_drvdata = {
>  static const struct ls_pcie_drvdata layerscape_drvdata = {
>   .pf_off = 0xc,
>   .pm_support = true,
> + .exit_from_l2 = ls_pcie_exit_from_l2,
>  };
>  
>  static const struct of_device_id ls_pcie_of_match[] = {
> @@ -213,7 +216,7 @@ static int ls_pcie_probe(struct platform_device *pdev)
>   pcie->drvdata = of_device_get_match_data(dev);
>  
>   pci->dev = dev;
> - pci->pp.ops = _pcie_host_ops;
> + pci->pp.ops = pcie->drvdata->ops ? pcie->drvdata->ops : 
> _pcie_host_ops;

This one also.

>  
>   pcie->pci = pci;
>  
> @@ -251,7 +254,7 @@ static int ls_pcie_resume_noirq(struct device *dev)
>   if (!pcie->drvdata->pm_support)
>   return 0;
>  
> - ls_pcie_exit_from_l2(>pci->pp);
> + pcie->drvdata->exit_from_l2(>pci->pp);

You should always check for the existence of the callback first before invoking
it.

- Mani

>  
>   return dw_pcie_resume_noirq(pcie->pci);
>  }
> -- 
> 2.34.1
> 

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


Re: [PATCH 2/3] PCI: layerscape: add suspend/resume for ls1021a

2023-10-16 Thread Lorenzo Pieralisi
On Mon, Oct 16, 2023 at 12:11:04PM -0400, Frank Li wrote:
> On Mon, Oct 16, 2023 at 10:22:11AM -0500, Bjorn Helgaas wrote:
> > On Mon, Oct 16, 2023 at 10:45:25AM -0400, Frank Li wrote:
> > > On Tue, Oct 10, 2023 at 06:02:36PM +0200, Lorenzo Pieralisi wrote:
> > > > On Tue, Oct 10, 2023 at 10:20:12AM -0400, Frank Li wrote:
> > 
> > > > > Ping
> > > > 
> > > > Read and follow please (and then ping us):
> > > > https://lore.kernel.org/linux-pci/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com
> > > 
> > > Could you please help point which specic one was not follow aboved guide?
> > > Then I can update my code. I think that's efficial communication method. I
> > > think I have read it serial times. But not sure which one violate the
> > > guide?
> > > 
> > > @Bjorn Helgaas. How do you think so? 
> > 
> > Since Lorenzo didn't point out anything specific in the patch itself,
> > I think he was probably referring to the subject line and this advice:
> > 
> >   - Follow the existing convention, i.e., run "git log --oneline
> > " and make yours match in format, capitalization, and
> > sentence structure.  For example, native host bridge driver patch
> > titles look like this:
> > 
> >   PCI: altera: Fix platform_get_irq() error handling
> >   PCI: vmd: Remove IRQ affinity so we can allocate more IRQs
> >   PCI: mediatek: Add MSI support for MT2712 and MT7622
> >   PCI: rockchip: Remove IRQ domain if probe fails
> > 
> > In this case, your subject line was:
> > 
> >   PCI: layerscape: add suspend/resume for ls1021a
> > 
> > The advice was to run this:
> > 
> >   $ git log --oneline drivers/pci/controller/dwc/pci-layerscape.c
> >   83c088148c8e PCI: Use PCI_HEADER_TYPE_* instead of literals
> >   9fda4d09905d PCI: layerscape: Add power management support for ls1028a
> >   277004d7a4a3 PCI: Remove unnecessary  includes
> >   60b3c27fb9b9 PCI: dwc: Rename struct pcie_port to dw_pcie_rp
> >   d23f0c11aca2 PCI: layerscape: Change to use the DWC common link-up check 
> > function
> >   7007b745a508 PCI: layerscape: Convert to builtin_platform_driver()
> >   60f5b73fa0f2 PCI: dwc: Remove unnecessary wrappers around 
> > dw_pcie_host_init()
> >   b9ac0f9dc8ea PCI: dwc: Move dw_pcie_setup_rc() to DWC common code
> >   f78f02638af5 PCI: dwc: Rework MSI initialization
> > 
> > Note that these summaries are all complete sentences that start with a
> > capital letter:
> > 
> >   Use PCI_HEADER_TYPE_* instead of literals
> >   Add power management support for ls1028a
> >   Remove unnecessary  includes
> >   ...
> > 
> > So yours could be this:
> > 
> >   PCI: layerscape: Add suspend/resume for ls1021a
> >^
> > 
> > This is trivial, obviously.  But the uppercase/lowercase distinction
> > carries information, and it's an unnecessary distraction to notice
> > that "oh, this is different from the rest; is the difference
> > important or should I ignore it?"
> 
> Thanks. Not everyone think it is trivial. Especially for the one, who
> English are not native language.
> 
> > 
> > Obviously Lorenzo *could* edit all your subject lines on your behalf,
> > but it makes everybody's life easier if people look at the existing
> > code and follow the style when making changes.
> 
> Understand, but simple mark 'a' and 'A' to me. I will update patches and
> take care for next time instead search whole docuemnt to guess which one
> violated. I know I make some mistakes at here. But I am working on many
> difference kernel subsystems, some require upper case, some require low
> case, someone doesn't care.
>  
> I respected all reviewer's and maintaner's time, but I hope respected
> the contributor's time also.

I do respect your time, please respect ours by following the guidelines I
provided you with multiple times already.

Thank you for resending the series.

Lorenzo


Re: [PATCH 2/3] PCI: layerscape: add suspend/resume for ls1021a

2023-10-16 Thread Bjorn Helgaas
On Mon, Oct 16, 2023 at 12:11:04PM -0400, Frank Li wrote:
> On Mon, Oct 16, 2023 at 10:22:11AM -0500, Bjorn Helgaas wrote:

> > Obviously Lorenzo *could* edit all your subject lines on your behalf,
> > but it makes everybody's life easier if people look at the existing
> > code and follow the style when making changes.
> 
> Understand, but simple mark 'a' and 'A' to me. I will update patches and
> take care for next time instead search whole docuemnt to guess which one
> violated. I know I make some mistakes at here. But I am working on many
> difference kernel subsystems, some require upper case, some require low
> case, someone doesn't care.

Right, that's why I always suggest following the example of the
surrounding code and history.  English is the only language I know,
but I speculate that this typographical detail probably doesn't make
sense in languages that don't have a similar upper/lowercase
distinction.

Thanks for persevering; we'd be having a lot more trouble if I tried
to send emails in your native language ;)

Bjorn


[PATCH v2 3/3] PCI: layerscape: Add suspend/resume for ls1043a

2023-10-16 Thread Frank Li
ls1043a add suspend/resume support.

Signed-off-by: Frank Li 
---

Notes:
Change from v1 to v2
- Change subject 'a' to 'A'

 drivers/pci/controller/dwc/pci-layerscape.c | 91 -
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pci-layerscape.c 
b/drivers/pci/controller/dwc/pci-layerscape.c
index bc5a8ff1a26c..debabb9bb41f 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -41,10 +41,20 @@
 #define SCFG_PEXSFTRSTCR   0x190
 #define PEXSR(idx) BIT(idx)
 
+/* LS1043A PEX PME control register */
+#define SCFG_PEXPMECR  0x144
+#define PEXPME(idx)BIT(31 - (idx) * 4)
+
+/* LS1043A PEX LUT debug register */
+#define LS_PCIE_LDBG   0x7fc
+#define LDBG_SRBIT(30)
+#define LDBG_WEBIT(31)
+
 #define PCIE_IATU_NUM  6
 
 struct ls_pcie_drvdata {
const u32 pf_off;
+   const u32 lut_off;
const struct dw_pcie_host_ops *ops;
void (*exit_from_l2)(struct dw_pcie_rp *pp);
bool pm_support;
@@ -54,6 +64,7 @@ struct ls_pcie {
struct dw_pcie *pci;
const struct ls_pcie_drvdata *drvdata;
void __iomem *pf_base;
+   void __iomem *lut_base;
struct regmap *scfg;
int index;
bool big_endian;
@@ -116,6 +127,23 @@ static void ls_pcie_pf_writel(struct ls_pcie *pcie, u32 
off, u32 val)
iowrite32(val, pcie->pf_base + off);
 }
 
+static u32 ls_pcie_lut_readl(struct ls_pcie *pcie, u32 off)
+{
+   if (pcie->big_endian)
+   return ioread32be(pcie->lut_base + off);
+
+   return ioread32(pcie->lut_base + off);
+}
+
+static void ls_pcie_lut_writel(struct ls_pcie *pcie, u32 off, u32 val)
+{
+   if (pcie->big_endian)
+   iowrite32be(val, pcie->lut_base + off);
+   else
+   iowrite32(val, pcie->lut_base + off);
+}
+
+
 static void ls_pcie_send_turnoff_msg(struct dw_pcie_rp *pp)
 {
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -249,6 +277,54 @@ static int ls1021a_pcie_host_init(struct dw_pcie_rp *pp)
return ret;
 }
 
+static void ls1043a_pcie_send_turnoff_msg(struct dw_pcie_rp *pp)
+{
+   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+   struct ls_pcie *pcie = to_ls_pcie(pci);
+   u32 val;
+
+   if (!pcie->scfg) {
+   dev_dbg(pcie->pci->dev, "SYSCFG is NULL\n");
+   return;
+   }
+
+   /* Send Turn_off message */
+   regmap_read(pcie->scfg, SCFG_PEXPMECR, );
+   val |= PEXPME(pcie->index);
+   regmap_write(pcie->scfg, SCFG_PEXPMECR, val);
+
+   /* There are not register to check ACK, so wait 
PCIE_PME_TO_L2_TIMEOUT_US */
+   mdelay(PCIE_PME_TO_L2_TIMEOUT_US/1000);
+
+   /* Clear Turn_off message */
+   regmap_read(pcie->scfg, SCFG_PEXPMECR, );
+   val &= ~PEXPME(pcie->index);
+   regmap_write(pcie->scfg, SCFG_PEXPMECR, val);
+}
+
+static void ls1043a_pcie_exit_from_l2(struct dw_pcie_rp *pp)
+{
+   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+   struct ls_pcie *pcie = to_ls_pcie(pci);
+   u32 val;
+
+   val = ls_pcie_lut_readl(pcie, LS_PCIE_LDBG);
+   val |= LDBG_WE;
+   ls_pcie_lut_writel(pcie, LS_PCIE_LDBG, val);
+
+   val = ls_pcie_lut_readl(pcie, LS_PCIE_LDBG);
+   val |= LDBG_SR;
+   ls_pcie_lut_writel(pcie, LS_PCIE_LDBG, val);
+
+   val = ls_pcie_lut_readl(pcie, LS_PCIE_LDBG);
+   val &= ~LDBG_SR;
+   ls_pcie_lut_writel(pcie, LS_PCIE_LDBG, val);
+
+   val = ls_pcie_lut_readl(pcie, LS_PCIE_LDBG);
+   val &= ~LDBG_WE;
+   ls_pcie_lut_writel(pcie, LS_PCIE_LDBG, val);
+}
+
 static const struct dw_pcie_host_ops ls_pcie_host_ops = {
.host_init = ls_pcie_host_init,
.pme_turn_off = ls_pcie_send_turnoff_msg,
@@ -265,6 +341,18 @@ static const struct ls_pcie_drvdata ls1021a_drvdata = {
.exit_from_l2 = ls1021a_pcie_exit_from_l2,
 };
 
+static const struct dw_pcie_host_ops ls1043a_pcie_host_ops = {
+   .host_init = ls1021a_pcie_host_init, /* the same as ls1021 */
+   .pme_turn_off = ls1043a_pcie_send_turnoff_msg,
+};
+
+static const struct ls_pcie_drvdata ls1043a_drvdata = {
+   .lut_off = 0x1,
+   .pm_support = true,
+   .ops = _pcie_host_ops,
+   .exit_from_l2 = ls1043a_pcie_exit_from_l2,
+};
+
 static const struct ls_pcie_drvdata layerscape_drvdata = {
.pf_off = 0xc,
.pm_support = true,
@@ -275,7 +363,7 @@ static const struct of_device_id ls_pcie_of_match[] = {
{ .compatible = "fsl,ls1012a-pcie", .data = _drvdata },
{ .compatible = "fsl,ls1021a-pcie", .data = _drvdata },
{ .compatible = "fsl,ls1028a-pcie", .data = _drvdata },
-   { .compatible = "fsl,ls1043a-pcie", .data = _drvdata },
+   { .compatible = "fsl,ls1043a-pcie", .data = _drvdata },
{ .compatible = "fsl,ls1046a-pcie", .data = _drvdata },
{ .compatible = 

[PATCH v2 2/3] PCI: layerscape: Add suspend/resume for ls1021a

2023-10-16 Thread Frank Li
ls1021a add suspend/resume support.

Signed-off-by: Frank Li 
---

Notes:
change from v1 to v2
- change subject 'a' to 'A'

 drivers/pci/controller/dwc/pci-layerscape.c | 88 -
 1 file changed, 87 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pci-layerscape.c 
b/drivers/pci/controller/dwc/pci-layerscape.c
index 20c48c06e224..bc5a8ff1a26c 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -35,6 +35,12 @@
 #define PF_MCR_PTOMR   BIT(0)
 #define PF_MCR_EXL2S   BIT(1)
 
+/* LS1021A PEXn PM Write Control Register */
+#define SCFG_PEXPMWRCR(idx)(0x5c + (idx) * 0x64)
+#define PMXMTTURNOFF   BIT(31)
+#define SCFG_PEXSFTRSTCR   0x190
+#define PEXSR(idx) BIT(idx)
+
 #define PCIE_IATU_NUM  6
 
 struct ls_pcie_drvdata {
@@ -48,6 +54,8 @@ struct ls_pcie {
struct dw_pcie *pci;
const struct ls_pcie_drvdata *drvdata;
void __iomem *pf_base;
+   struct regmap *scfg;
+   int index;
bool big_endian;
 };
 
@@ -170,13 +178,91 @@ static int ls_pcie_host_init(struct dw_pcie_rp *pp)
return 0;
 }
 
+static void ls1021a_pcie_send_turnoff_msg(struct dw_pcie_rp *pp)
+{
+   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+   struct ls_pcie *pcie = to_ls_pcie(pci);
+   u32 val;
+
+   if (!pcie->scfg) {
+   dev_dbg(pcie->pci->dev, "SYSCFG is NULL\n");
+   return;
+   }
+
+   /* Send Turn_off message */
+   regmap_read(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), );
+   val |= PMXMTTURNOFF;
+   regmap_write(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), val);
+
+   /* There are not register to check ACK, so wait 
PCIE_PME_TO_L2_TIMEOUT_US */
+   mdelay(PCIE_PME_TO_L2_TIMEOUT_US/1000);
+
+   /* Clear Turn_off message */
+   regmap_read(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), );
+   val &= ~PMXMTTURNOFF;
+   regmap_write(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), val);
+}
+
+static void ls1021a_pcie_exit_from_l2(struct dw_pcie_rp *pp)
+{
+   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+   struct ls_pcie *pcie = to_ls_pcie(pci);
+   u32 val;
+
+   regmap_read(pcie->scfg, SCFG_PEXSFTRSTCR, );
+   val |= PEXSR(pcie->index);
+   regmap_write(pcie->scfg, SCFG_PEXSFTRSTCR, val);
+
+   regmap_read(pcie->scfg, SCFG_PEXSFTRSTCR, );
+   val &= ~PEXSR(pcie->index);
+   regmap_write(pcie->scfg, SCFG_PEXSFTRSTCR, val);
+}
+
+static int ls1021a_pcie_host_init(struct dw_pcie_rp *pp)
+{
+   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+   struct ls_pcie *pcie = to_ls_pcie(pci);
+   struct device *dev = pcie->pci->dev;
+   u32 index[2];
+   int ret;
+
+   ret = ls_pcie_host_init(pp);
+   if (ret)
+   return ret;
+
+   pcie->scfg = syscon_regmap_lookup_by_phandle(dev->of_node, 
"fsl,pcie-scfg");
+   if (IS_ERR(pcie->scfg)) {
+   ret = PTR_ERR(pcie->scfg);
+   dev_err(dev, "No syscfg phandle specified\n");
+   pcie->scfg = NULL;
+   return ret;
+   }
+
+   ret = of_property_read_u32_array(dev->of_node, "fsl,pcie-scfg", index, 
2);
+   if (ret) {
+   pcie->scfg = NULL;
+   return ret;
+   }
+
+   pcie->index = index[1];
+
+   return ret;
+}
+
 static const struct dw_pcie_host_ops ls_pcie_host_ops = {
.host_init = ls_pcie_host_init,
.pme_turn_off = ls_pcie_send_turnoff_msg,
 };
 
+static const struct dw_pcie_host_ops ls1021a_pcie_host_ops = {
+   .host_init = ls1021a_pcie_host_init,
+   .pme_turn_off = ls1021a_pcie_send_turnoff_msg,
+};
+
 static const struct ls_pcie_drvdata ls1021a_drvdata = {
-   .pm_support = false,
+   .pm_support = true,
+   .ops = _pcie_host_ops,
+   .exit_from_l2 = ls1021a_pcie_exit_from_l2,
 };
 
 static const struct ls_pcie_drvdata layerscape_drvdata = {
-- 
2.34.1



[PATCH v2 1/3] PCI: layerscape: Add function pointer for exit_from_l2()

2023-10-16 Thread Frank Li
Difference layerscape chip have not difference exit_from_l2() method.
Using function pointer for ls1028. It prepare for other layerscape
suspend/resume support.

Signed-off-by: Frank Li 
---

Notes:
Change from v1 to v2
- change subject 'a' to 'A'

 drivers/pci/controller/dwc/pci-layerscape.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-layerscape.c 
b/drivers/pci/controller/dwc/pci-layerscape.c
index b931d597656f..20c48c06e224 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -39,6 +39,8 @@
 
 struct ls_pcie_drvdata {
const u32 pf_off;
+   const struct dw_pcie_host_ops *ops;
+   void (*exit_from_l2)(struct dw_pcie_rp *pp);
bool pm_support;
 };
 
@@ -180,6 +182,7 @@ static const struct ls_pcie_drvdata ls1021a_drvdata = {
 static const struct ls_pcie_drvdata layerscape_drvdata = {
.pf_off = 0xc,
.pm_support = true,
+   .exit_from_l2 = ls_pcie_exit_from_l2,
 };
 
 static const struct of_device_id ls_pcie_of_match[] = {
@@ -213,7 +216,7 @@ static int ls_pcie_probe(struct platform_device *pdev)
pcie->drvdata = of_device_get_match_data(dev);
 
pci->dev = dev;
-   pci->pp.ops = _pcie_host_ops;
+   pci->pp.ops = pcie->drvdata->ops ? pcie->drvdata->ops : 
_pcie_host_ops;
 
pcie->pci = pci;
 
@@ -251,7 +254,7 @@ static int ls_pcie_resume_noirq(struct device *dev)
if (!pcie->drvdata->pm_support)
return 0;
 
-   ls_pcie_exit_from_l2(>pci->pp);
+   pcie->drvdata->exit_from_l2(>pci->pp);
 
return dw_pcie_resume_noirq(pcie->pci);
 }
-- 
2.34.1



Re: [PATCH 2/3] PCI: layerscape: add suspend/resume for ls1021a

2023-10-16 Thread Lorenzo Pieralisi
On Mon, Oct 16, 2023 at 10:22:11AM -0500, Bjorn Helgaas wrote:
> On Mon, Oct 16, 2023 at 10:45:25AM -0400, Frank Li wrote:
> > On Tue, Oct 10, 2023 at 06:02:36PM +0200, Lorenzo Pieralisi wrote:
> > > On Tue, Oct 10, 2023 at 10:20:12AM -0400, Frank Li wrote:
> 
> > > > Ping
> > > 
> > > Read and follow please (and then ping us):
> > > https://lore.kernel.org/linux-pci/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com
> > 
> > Could you please help point which specic one was not follow aboved guide?
> > Then I can update my code. I think that's efficial communication method. I
> > think I have read it serial times. But not sure which one violate the
> > guide?
> > 
> > @Bjorn Helgaas. How do you think so? 
> 
> Since Lorenzo didn't point out anything specific in the patch itself,
> I think he was probably referring to the subject line and this advice:
> 
>   - Follow the existing convention, i.e., run "git log --oneline
> " and make yours match in format, capitalization, and
> sentence structure.  For example, native host bridge driver patch
> titles look like this:
> 
>   PCI: altera: Fix platform_get_irq() error handling
>   PCI: vmd: Remove IRQ affinity so we can allocate more IRQs
>   PCI: mediatek: Add MSI support for MT2712 and MT7622
>   PCI: rockchip: Remove IRQ domain if probe fails
> 
> In this case, your subject line was:
> 
>   PCI: layerscape: add suspend/resume for ls1021a
> 
> The advice was to run this:
> 
>   $ git log --oneline drivers/pci/controller/dwc/pci-layerscape.c
>   83c088148c8e PCI: Use PCI_HEADER_TYPE_* instead of literals
>   9fda4d09905d PCI: layerscape: Add power management support for ls1028a
>   277004d7a4a3 PCI: Remove unnecessary  includes
>   60b3c27fb9b9 PCI: dwc: Rename struct pcie_port to dw_pcie_rp
>   d23f0c11aca2 PCI: layerscape: Change to use the DWC common link-up check 
> function
>   7007b745a508 PCI: layerscape: Convert to builtin_platform_driver()
>   60f5b73fa0f2 PCI: dwc: Remove unnecessary wrappers around 
> dw_pcie_host_init()
>   b9ac0f9dc8ea PCI: dwc: Move dw_pcie_setup_rc() to DWC common code
>   f78f02638af5 PCI: dwc: Rework MSI initialization
> 
> Note that these summaries are all complete sentences that start with a
> capital letter:
> 
>   Use PCI_HEADER_TYPE_* instead of literals
>   Add power management support for ls1028a
>   Remove unnecessary  includes
>   ...
> 
> So yours could be this:
> 
>   PCI: layerscape: Add suspend/resume for ls1021a
>^
> 
> This is trivial, obviously.  But the uppercase/lowercase distinction
> carries information, and it's an unnecessary distraction to notice
> that "oh, this is different from the rest; is the difference
> important or should I ignore it?"
> 
> Obviously Lorenzo *could* edit all your subject lines on your behalf,
> but it makes everybody's life easier if people look at the existing
> code and follow the style when making changes.
> 
> E.g., write subject lines that are similar in style to previous ones,
> name local variables similarly to other functions, use line lengths
> consistent with the rest of the file, etc.  After applying a change,
> the file should look like a coherent whole; we should not be able to
> tell that this hunk was added later by somebody else.  This all helps
> make the code (and the git history) more readable and maintainable.

Thank you very much Bjorn. Frank, now please resend your patches and
make sure that you follow these guidelines, they must be clear by now.

Lorenzo


Re: [PATCH 2/3] PCI: layerscape: add suspend/resume for ls1021a

2023-10-16 Thread Frank Li
On Mon, Oct 16, 2023 at 10:22:11AM -0500, Bjorn Helgaas wrote:
> On Mon, Oct 16, 2023 at 10:45:25AM -0400, Frank Li wrote:
> > On Tue, Oct 10, 2023 at 06:02:36PM +0200, Lorenzo Pieralisi wrote:
> > > On Tue, Oct 10, 2023 at 10:20:12AM -0400, Frank Li wrote:
> 
> > > > Ping
> > > 
> > > Read and follow please (and then ping us):
> > > https://lore.kernel.org/linux-pci/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com
> > 
> > Could you please help point which specic one was not follow aboved guide?
> > Then I can update my code. I think that's efficial communication method. I
> > think I have read it serial times. But not sure which one violate the
> > guide?
> > 
> > @Bjorn Helgaas. How do you think so? 
> 
> Since Lorenzo didn't point out anything specific in the patch itself,
> I think he was probably referring to the subject line and this advice:
> 
>   - Follow the existing convention, i.e., run "git log --oneline
> " and make yours match in format, capitalization, and
> sentence structure.  For example, native host bridge driver patch
> titles look like this:
> 
>   PCI: altera: Fix platform_get_irq() error handling
>   PCI: vmd: Remove IRQ affinity so we can allocate more IRQs
>   PCI: mediatek: Add MSI support for MT2712 and MT7622
>   PCI: rockchip: Remove IRQ domain if probe fails
> 
> In this case, your subject line was:
> 
>   PCI: layerscape: add suspend/resume for ls1021a
> 
> The advice was to run this:
> 
>   $ git log --oneline drivers/pci/controller/dwc/pci-layerscape.c
>   83c088148c8e PCI: Use PCI_HEADER_TYPE_* instead of literals
>   9fda4d09905d PCI: layerscape: Add power management support for ls1028a
>   277004d7a4a3 PCI: Remove unnecessary  includes
>   60b3c27fb9b9 PCI: dwc: Rename struct pcie_port to dw_pcie_rp
>   d23f0c11aca2 PCI: layerscape: Change to use the DWC common link-up check 
> function
>   7007b745a508 PCI: layerscape: Convert to builtin_platform_driver()
>   60f5b73fa0f2 PCI: dwc: Remove unnecessary wrappers around 
> dw_pcie_host_init()
>   b9ac0f9dc8ea PCI: dwc: Move dw_pcie_setup_rc() to DWC common code
>   f78f02638af5 PCI: dwc: Rework MSI initialization
> 
> Note that these summaries are all complete sentences that start with a
> capital letter:
> 
>   Use PCI_HEADER_TYPE_* instead of literals
>   Add power management support for ls1028a
>   Remove unnecessary  includes
>   ...
> 
> So yours could be this:
> 
>   PCI: layerscape: Add suspend/resume for ls1021a
>^
> 
> This is trivial, obviously.  But the uppercase/lowercase distinction
> carries information, and it's an unnecessary distraction to notice
> that "oh, this is different from the rest; is the difference
> important or should I ignore it?"

Thanks. Not everyone think it is trivial. Especially for the one, who
English are not native language.

> 
> Obviously Lorenzo *could* edit all your subject lines on your behalf,
> but it makes everybody's life easier if people look at the existing
> code and follow the style when making changes.

Understand, but simple mark 'a' and 'A' to me. I will update patches and
take care for next time instead search whole docuemnt to guess which one
violated. I know I make some mistakes at here. But I am working on many
difference kernel subsystems, some require upper case, some require low
case, someone doesn't care.
 
I respected all reviewer's and maintaner's time, but I hope respected
the contributor's time also.

Just simple words like , 'a' to 'A' or
run git log --oneline to check subject. I will know what exact means. 

Do you think it will better than below words

"Read and follow please (and then ping us):   
https://lore.kernel.org/linux-pci/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com;

Frank

> 
> E.g., write subject lines that are similar in style to previous ones,
> name local variables similarly to other functions, use line lengths
> consistent with the rest of the file, etc.  After applying a change,
> the file should look like a coherent whole; we should not be able to
> tell that this hunk was added later by somebody else.  This all helps
> make the code (and the git history) more readable and maintainable.
> 
> Bjorn


Re: [PATCH 2/3] PCI: layerscape: add suspend/resume for ls1021a

2023-10-16 Thread Bjorn Helgaas
On Mon, Oct 16, 2023 at 10:45:25AM -0400, Frank Li wrote:
> On Tue, Oct 10, 2023 at 06:02:36PM +0200, Lorenzo Pieralisi wrote:
> > On Tue, Oct 10, 2023 at 10:20:12AM -0400, Frank Li wrote:

> > > Ping
> > 
> > Read and follow please (and then ping us):
> > https://lore.kernel.org/linux-pci/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com
> 
> Could you please help point which specic one was not follow aboved guide?
> Then I can update my code. I think that's efficial communication method. I
> think I have read it serial times. But not sure which one violate the
> guide?
> 
> @Bjorn Helgaas. How do you think so? 

Since Lorenzo didn't point out anything specific in the patch itself,
I think he was probably referring to the subject line and this advice:

  - Follow the existing convention, i.e., run "git log --oneline
" and make yours match in format, capitalization, and
sentence structure.  For example, native host bridge driver patch
titles look like this:

  PCI: altera: Fix platform_get_irq() error handling
  PCI: vmd: Remove IRQ affinity so we can allocate more IRQs
  PCI: mediatek: Add MSI support for MT2712 and MT7622
  PCI: rockchip: Remove IRQ domain if probe fails

In this case, your subject line was:

  PCI: layerscape: add suspend/resume for ls1021a

The advice was to run this:

  $ git log --oneline drivers/pci/controller/dwc/pci-layerscape.c
  83c088148c8e PCI: Use PCI_HEADER_TYPE_* instead of literals
  9fda4d09905d PCI: layerscape: Add power management support for ls1028a
  277004d7a4a3 PCI: Remove unnecessary  includes
  60b3c27fb9b9 PCI: dwc: Rename struct pcie_port to dw_pcie_rp
  d23f0c11aca2 PCI: layerscape: Change to use the DWC common link-up check 
function
  7007b745a508 PCI: layerscape: Convert to builtin_platform_driver()
  60f5b73fa0f2 PCI: dwc: Remove unnecessary wrappers around dw_pcie_host_init()
  b9ac0f9dc8ea PCI: dwc: Move dw_pcie_setup_rc() to DWC common code
  f78f02638af5 PCI: dwc: Rework MSI initialization

Note that these summaries are all complete sentences that start with a
capital letter:

  Use PCI_HEADER_TYPE_* instead of literals
  Add power management support for ls1028a
  Remove unnecessary  includes
  ...

So yours could be this:

  PCI: layerscape: Add suspend/resume for ls1021a
   ^

This is trivial, obviously.  But the uppercase/lowercase distinction
carries information, and it's an unnecessary distraction to notice
that "oh, this is different from the rest; is the difference
important or should I ignore it?"

Obviously Lorenzo *could* edit all your subject lines on your behalf,
but it makes everybody's life easier if people look at the existing
code and follow the style when making changes.

E.g., write subject lines that are similar in style to previous ones,
name local variables similarly to other functions, use line lengths
consistent with the rest of the file, etc.  After applying a change,
the file should look like a coherent whole; we should not be able to
tell that this hunk was added later by somebody else.  This all helps
make the code (and the git history) more readable and maintainable.

Bjorn


Re: [PATCH 2/3] PCI: layerscape: add suspend/resume for ls1021a

2023-10-16 Thread Frank Li
On Tue, Oct 10, 2023 at 06:02:36PM +0200, Lorenzo Pieralisi wrote:
> On Tue, Oct 10, 2023 at 10:20:12AM -0400, Frank Li wrote:
> > On Wed, Oct 04, 2023 at 10:23:51AM -0400, Frank Li wrote:
> > > On Fri, Sep 15, 2023 at 02:43:05PM -0400, Frank Li wrote:
> > > > ls1021a add suspend/resume support.
> > > > 
> > > > Signed-off-by: Frank Li 
> > > > ---
> > > 
> > > ping
> > > 
> > > Frank
> > 
> > Ping
> 
> Read and follow please (and then ping us):
> https://lore.kernel.org/linux-pci/20171026223701.ga25...@bhelgaas-glaptop.roam.corp.google.com

Could you please help point which specic one was not follow aboved guide?
Then I can update my code. I think that's efficial communication method. I
think I have read it serial times. But not sure which one violate the
guide?

@Bjorn Helgaas. How do you think so? 

best regards
Frank Li

> 
> > Frank
> > 
> > > 
> > > >  drivers/pci/controller/dwc/pci-layerscape.c | 88 -
> > > >  1 file changed, 87 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/pci/controller/dwc/pci-layerscape.c 
> > > > b/drivers/pci/controller/dwc/pci-layerscape.c
> > > > index 20c48c06e2248..bc5a8ff1a26ce 100644
> > > > --- a/drivers/pci/controller/dwc/pci-layerscape.c
> > > > +++ b/drivers/pci/controller/dwc/pci-layerscape.c
> > > > @@ -35,6 +35,12 @@
> > > >  #define PF_MCR_PTOMR   BIT(0)
> > > >  #define PF_MCR_EXL2S   BIT(1)
> > > >  
> > > > +/* LS1021A PEXn PM Write Control Register */
> > > > +#define SCFG_PEXPMWRCR(idx)(0x5c + (idx) * 0x64)
> > > > +#define PMXMTTURNOFF   BIT(31)
> > > > +#define SCFG_PEXSFTRSTCR   0x190
> > > > +#define PEXSR(idx) BIT(idx)
> > > > +
> > > >  #define PCIE_IATU_NUM  6
> > > >  
> > > >  struct ls_pcie_drvdata {
> > > > @@ -48,6 +54,8 @@ struct ls_pcie {
> > > > struct dw_pcie *pci;
> > > > const struct ls_pcie_drvdata *drvdata;
> > > > void __iomem *pf_base;
> > > > +   struct regmap *scfg;
> > > > +   int index;
> > > > bool big_endian;
> > > >  };
> > > >  
> > > > @@ -170,13 +178,91 @@ static int ls_pcie_host_init(struct dw_pcie_rp 
> > > > *pp)
> > > > return 0;
> > > >  }
> > > >  
> > > > +static void ls1021a_pcie_send_turnoff_msg(struct dw_pcie_rp *pp)
> > > > +{
> > > > +   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > > +   struct ls_pcie *pcie = to_ls_pcie(pci);
> > > > +   u32 val;
> > > > +
> > > > +   if (!pcie->scfg) {
> > > > +   dev_dbg(pcie->pci->dev, "SYSCFG is NULL\n");
> > > > +   return;
> > > > +   }
> > > > +
> > > > +   /* Send Turn_off message */
> > > > +   regmap_read(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), );
> > > > +   val |= PMXMTTURNOFF;
> > > > +   regmap_write(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), val);
> > > > +
> > > > +   /* There are not register to check ACK, so wait 
> > > > PCIE_PME_TO_L2_TIMEOUT_US */
> > > > +   mdelay(PCIE_PME_TO_L2_TIMEOUT_US/1000);
> > > > +
> > > > +   /* Clear Turn_off message */
> > > > +   regmap_read(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), );
> > > > +   val &= ~PMXMTTURNOFF;
> > > > +   regmap_write(pcie->scfg, SCFG_PEXPMWRCR(pcie->index), val);
> > > > +}
> > > > +
> > > > +static void ls1021a_pcie_exit_from_l2(struct dw_pcie_rp *pp)
> > > > +{
> > > > +   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > > +   struct ls_pcie *pcie = to_ls_pcie(pci);
> > > > +   u32 val;
> > > > +
> > > > +   regmap_read(pcie->scfg, SCFG_PEXSFTRSTCR, );
> > > > +   val |= PEXSR(pcie->index);
> > > > +   regmap_write(pcie->scfg, SCFG_PEXSFTRSTCR, val);
> > > > +
> > > > +   regmap_read(pcie->scfg, SCFG_PEXSFTRSTCR, );
> > > > +   val &= ~PEXSR(pcie->index);
> > > > +   regmap_write(pcie->scfg, SCFG_PEXSFTRSTCR, val);
> > > > +}
> > > > +
> > > > +static int ls1021a_pcie_host_init(struct dw_pcie_rp *pp)
> > > > +{
> > > > +   struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > > > +   struct ls_pcie *pcie = to_ls_pcie(pci);
> > > > +   struct device *dev = pcie->pci->dev;
> > > > +   u32 index[2];
> > > > +   int ret;
> > > > +
> > > > +   ret = ls_pcie_host_init(pp);
> > > > +   if (ret)
> > > > +   return ret;
> > > > +
> > > > +   pcie->scfg = syscon_regmap_lookup_by_phandle(dev->of_node, 
> > > > "fsl,pcie-scfg");
> > > > +   if (IS_ERR(pcie->scfg)) {
> > > > +   ret = PTR_ERR(pcie->scfg);
> > > > +   dev_err(dev, "No syscfg phandle specified\n");
> > > > +   pcie->scfg = NULL;
> > > > +   return ret;
> > > > +   }
> > > > +
> > > > +   ret = of_property_read_u32_array(dev->of_node, "fsl,pcie-scfg", 
> > > > index, 2);
> > > > +   if (ret) {
> > > > +   pcie->scfg = NULL;
> > > > +   return ret;
> > > > +   }
> > > > +
> > > > +   pcie->index = index[1];
> > > > +
> > > > +   return ret;
> > > > 

Re: [RFC PATCH v6 11/11] media: viaudm2m: add virtual driver for audio memory to memory

2023-10-16 Thread Hans Verkuil
On 13/10/2023 10:31, Shengjiu Wang wrote:
> 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|   9 +
>  drivers/media/test-drivers/Makefile   |   1 +
>  drivers/media/test-drivers/viaudm2m.c | 707 ++
>  3 files changed, 717 insertions(+)
>  create mode 100644 drivers/media/test-drivers/viaudm2m.c
> 
> diff --git a/drivers/media/test-drivers/Kconfig 
> b/drivers/media/test-drivers/Kconfig
> index 459b433e9fae..143d829e1b67 100644
> --- a/drivers/media/test-drivers/Kconfig
> +++ b/drivers/media/test-drivers/Kconfig
> @@ -17,6 +17,15 @@ config VIDEO_VIM2M
> This is a virtual test device for the memory-to-memory driver
> framework.
>  
> +config VIDEO_VIAUDM2M
> + tristate "Virtual Memory-to-Memory Driver For Audio"

I think this is better:

VIDEO_VIM2M_AUDIO

and name the source: vim2m_audio.c.

> + depends on VIDEO_DEV
> + select VIDEOBUF2_VMALLOC
> + select V4L2_MEM2MEM_DEV
> + 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..a39d27eb53fa 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_VIAUDM2M) += viaudm2m.o
>  obj-$(CONFIG_VIDEO_VIMC) += vimc/
>  obj-$(CONFIG_VIDEO_VIVID) += vivid/
>  obj-$(CONFIG_VIDEO_VISL) += visl/
> diff --git a/drivers/media/test-drivers/viaudm2m.c 
> b/drivers/media/test-drivers/viaudm2m.c
> new file mode 100644
> index ..5fefd616b6c8
> --- /dev/null
> +++ b/drivers/media/test-drivers/viaudm2m.c
> @@ -0,0 +1,707 @@
> +// 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");
> +MODULE_VERSION("0.1");

Drop this, rarely needed.

> +MODULE_ALIAS("audio_mem2mem_testdev");

Drop this as well. I'm not sure why it is in the original vim2m.c source.

> +
> +static unsigned int debug;
> +module_param(debug, uint, 0644);
> +MODULE_PARM_DESC(debug, "debug level");
> +
> +#define MEM2MEM_NAME "viaudm2m"

"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,
> +};
> +
> +struct audm2m_fmt {
> + u32 fourcc;
> + snd_pcm_format_tformat;

Same as for the previous driver: I think you can just drop this field and thus
the whole struct.

> +};
> +
> +static struct audm2m_fmt formats[] = {

And this is just a u32 array.

> + {
> + .fourcc = V4L2_AUDIO_FMT_S8,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_S16_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_U16_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_S24_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_S24_3LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_U24_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_U24_3LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_S32_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_U32_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_S20_3LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_U20_3LE,
> + },
> +};
> +
> +#define NUM_FORMATS ARRAY_SIZE(formats)
> +
> +/* Per-queue, driver-specific private data */
> +struct audm2m_q_data {
> + unsigned intrate;
> + unsigned intchannels;
> + unsigned intbuffersize;
> + struct audm2m_fmt   *fmt;
> +};
> +
> +enum {
> + V4L2_M2M_SRC = 0,
> + V4L2_M2M_DST = 1,
> +};
> +
> +static struct audm2m_fmt *find_format(u32 fourcc)
> +{
> + struct audm2m_fmt *fmt;
> + unsigned int k;
> +
> + for (k = 0; k < NUM_FORMATS; k++) {
> 

Re: [RFC PATCH v6 10/11] media: imx-asrc: Add memory to memory driver

2023-10-16 Thread Hans Verkuil
On 13/10/2023 10:31, Shengjiu Wang wrote:
> 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|   12 +
>  drivers/media/platform/nxp/Makefile   |1 +
>  drivers/media/platform/nxp/imx-asrc.c | 1248 +
>  3 files changed, 1261 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..8234644ee341 100644
> --- a/drivers/media/platform/nxp/Kconfig
> +++ b/drivers/media/platform/nxp/Kconfig
> @@ -67,3 +67,15 @@ 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
> + 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 ..373ca2b5ec90
> --- /dev/null
> +++ b/drivers/media/platform/nxp/imx-asrc.c
> @@ -0,0 +1,1248 @@
> +// 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"
> +
> +#define ASRC_M2M_BUFFER_SIZE (512 * 1024)
> +#define ASRC_M2M_PERIOD_SIZE (48 * 1024)
> +#define ASRC_M2M_SG_NUM (20)

Where do all these values come from? How do they relate?
Some comments would be welcome.

Esp. ASRC_M2M_SG_NUM is a bit odd.

> +
> +struct asrc_fmt {
> + u32 fourcc;
> + snd_pcm_format_t format;

Do you need this field? If not, then you can drop the whole
struct and just use u32 fourcc in the formats[] array.

> +};
> +
> +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];
> + struct v4l2_ctrl_fixed_point src_rate;
> + struct v4l2_ctrl_fixed_point dst_rate;
> +
> +};
> +
> +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;
> +};
> +
> +static struct asrc_fmt formats[] = {
> + {
> + .fourcc = V4L2_AUDIO_FMT_S8,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_S16_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_U16_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_S24_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_S24_3LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_U24_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_U24_3LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_S32_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_U32_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_S20_3LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_U20_3LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_FLOAT_LE,
> + },
> + {
> + .fourcc = V4L2_AUDIO_FMT_IEC958_SUBFRAME_LE,
> + },
> +};
> +
> +#define NUM_FORMATS ARRAY_SIZE(formats)
> +
> +static snd_pcm_format_t convert_fourcc(u32 fourcc) {
> +
> + return 

Re: Re: [PATCH v3 1/2] ASoC: dt-bindings: sound-card-common: List DAPM endpoints ignoring system suspend

2023-10-16 Thread Mark Brown
On Mon, Oct 16, 2023 at 12:08:56PM +, Chancel Liu wrote:

> Thanks Mark and Rob for your advice. In fact, it's common use case. We can see
> many drivers set widgets ignoring suspend. I will remove the linux specifics
> and focus on the key concept. How about the modification on the property name
> and description as following:
>   ignore-suspend-widgets:
> description: |
>   A list of audio sound widgets which are marked ignoring system suspend.
> Paths between these endpoints are still active over suspend of the 
> main
> application processor that the current operating system is running.

That's probably fine from my point of view.  There's likely a better way
of saying system suspend but I'm not immediately seeing it and it could
always be improved later.


signature.asc
Description: PGP signature


Re: [RFC PATCH v6 09/11] media: uapi: Add audio rate controls support

2023-10-16 Thread Hans Verkuil
Hi Shengjiu,

On 13/10/2023 10:31, Shengjiu Wang wrote:
> Fixed point controls are used by the user to configure
> the audio sample rate to driver.
> 
> Add V4L2_CID_ASRC_SOURCE_RATE and V4L2_CID_ASRC_DEST_RATE
> new IDs for ASRC rate control.
> 
> Signed-off-by: Shengjiu Wang 
> ---
>  .../userspace-api/media/v4l/common.rst|  1 +
>  .../media/v4l/ext-ctrls-fixed-point.rst   | 36 +++
>  .../media/v4l/vidioc-g-ext-ctrls.rst  |  4 +++
>  .../media/v4l/vidioc-queryctrl.rst|  7 
>  .../media/videodev2.h.rst.exceptions  |  1 +
>  drivers/media/v4l2-core/v4l2-ctrls-core.c |  5 +++
>  drivers/media/v4l2-core/v4l2-ctrls-defs.c |  4 +++
>  include/media/v4l2-ctrls.h|  2 ++
>  include/uapi/linux/v4l2-controls.h| 13 +++
>  include/uapi/linux/videodev2.h|  3 ++
>  10 files changed, 76 insertions(+)
>  create mode 100644 
> Documentation/userspace-api/media/v4l/ext-ctrls-fixed-point.rst
> 
> diff --git a/Documentation/userspace-api/media/v4l/common.rst 
> b/Documentation/userspace-api/media/v4l/common.rst
> index ea0435182e44..35707edffb13 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-fixed-point

Rename this to ext-ctrls-audio-m2m.

>  fourcc
>  format
>  planar-apis
> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-fixed-point.rst 
> b/Documentation/userspace-api/media/v4l/ext-ctrls-fixed-point.rst
> new file mode 100644
> index ..2ef6e250580c
> --- /dev/null
> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-fixed-point.rst
> @@ -0,0 +1,36 @@
> +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
> +
> +.. _fixed-point-controls:
> +
> +***
> +Fixed Point Control Reference

This is for audio controls. "Fixed Point" is just the type, and it doesn't make
sense to group fixed point controls. But it does make sense to group the audio
controls.

V4L2 controls can be grouped into classes. Basically it is a way to put controls
into categories, and for each category there is also a control that gives a
description of the class (see 2.15.15 in
https://linuxtv.org/downloads/v4l-dvb-apis-new/driver-api/v4l2-controls.html#introduction)

If you use e.g. 'v4l2-ctl -l' to list all the controls, then you will see that
they are grouped based on what class of control they are.

So I think it would be a good idea to create a new control class for M2M audio 
controls,
instead of just adding them to the catch-all 'User Controls' class.

Search e.g. for V4L2_CTRL_CLASS_COLORIMETRY and V4L2_CID_COLORIMETRY_CLASS to 
see how
it is done.

M2M_AUDIO would probably be a good name for the class.

> +***
> +
> +These controls are intended to support an asynchronous sample
> +rate converter.

Add ' (ASRC).' at the end to indicate the common abbreviation for
that.

> +
> +.. _v4l2-audio-asrc:
> +
> +``V4L2_CID_ASRC_SOURCE_RATE``
> +sets the resampler source rate.
> +
> +``V4L2_CID_ASRC_DEST_RATE``
> +sets the resampler destination rate.

Document the unit (Hz) for these two controls.

> +
> +.. c:type:: v4l2_ctrl_fixed_point
> +
> +.. cssclass:: longtable
> +
> +.. tabularcolumns:: |p{1.5cm}|p{5.8cm}|p{10.0cm}|
> +
> +.. flat-table:: struct v4l2_ctrl_fixed_point
> +:header-rows:  0
> +:stub-columns: 0
> +:widths:   1 1 2
> +
> +* - __u32

Hmm, shouldn't this be __s32?

> +  - ``integer``
> +  - integer part of fixed point value.
> +* - __s32

and this __u32?

You want to be able to use this generic type as a signed value.

> +  - ``fractional``
> +  - fractional part of fixed point value, which is Q31.
> 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 f9f73530a6be..1811dabf5c74 100644
> --- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
> +++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
> @@ -295,6 +295,10 @@ still cause this situation.
>- ``p_av1_film_grain``
>- A pointer to a struct :c:type:`v4l2_ctrl_av1_film_grain`. Valid if 
> this control is
>  of type ``V4L2_CTRL_TYPE_AV1_FILM_GRAIN``.
> +* - struct :c:type:`v4l2_ctrl_fixed_point` *
> +  - ``p_fixed_point``
> +  - A pointer to a struct :c:type:`v4l2_ctrl_fixed_point`. Valid if this 
> control is
> +of type ``V4L2_CTRL_TYPE_FIXED_POINT``.
>  * - void *
>- ``ptr``
>- A pointer to a compound type which can be an N-dimensional array
> diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst 
> b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> index 4d38acafe8e1..9285f4f39eed 100644
> --- 

Re: [PATCH v2 3/7] powerpc/rtas: serialize ibm,get-vpd service with papr-vpd sequences

2023-10-16 Thread Nathan Lynch


> Take the papr-vpd driver's internal mutex when sys_rtas performs
> ibm,get-vpd calls. This prevents sys_rtas(ibm,get-vpd) calls from
> interleaving with sequences performed by the driver, ensuring that
> such sequences are not disrupted.



> @@ -1861,6 +1862,28 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
>   goto copy_return;
>   }
>  
> + if (token == rtas_function_token(RTAS_FN_IBM_GET_VPD)) {
> + /*
> +  * ibm,get-vpd potentially needs to be invoked
> +  * multiple times to obtain complete results.
> +  * Interleaved ibm,get-vpd sequences disrupt each
> +  * other.
> +  *
> +  * /dev/papr-vpd doesn't have this problem and users
> +  * do not need to be aware of each other to use it
> +  * safely.
> +  *
> +  * We can prevent this call from disrupting a
> +  * /dev/papr-vpd-initiated sequence in progress by
> +  * reaching into the driver to take its internal
> +  * lock. Unfortunately there is no way to prevent
> +  * interference in the other direction without
> +  * resorting to even worse hacks.
> +  */
> + pr_notice_once("Calling ibm,get-vpd via sys_rtas is allowed but 
> deprecated. Use /dev/papr-vpd instead.\n");
> + papr_vpd_mutex_lock();
> + }
> +
>   buff_copy = get_errorlog_buffer();
>  
>   raw_spin_lock_irqsave(_lock, flags);
> @@ -1870,6 +1893,9 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
>   do_enter_rtas(_args);
>   args = rtas_args;
>  
> + if (token == rtas_function_token(RTAS_FN_IBM_GET_VPD))
> + papr_vpd_mutex_unlock();
> +

The mutex ought to nest entirely outside rtas_lock, this releases it
too early.

Anyway, I'm considering a different way to get the synchronization right
between drivers like papr-vpd and sys_rtas. Instead of having sys_rtas
acquire the driver's internal lock, rtas.c should provide a way for code
like papr-vpd to temporarily lock the syscall path.

Something like this:

// rtas.c

+ static DEFINE_MUTEX(rtas_syscall_lock);
+ void rtas_syscall_lock(void) { mutex_lock(_syscall_lock); }
+ void rtas_syscall_unlock(void) { mutex_unlock(_syscall_lock); }

  SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
  {
+rtas_syscall_lock();

 ...

 do_enter_rtas(_args);

 ...

+rtas_syscall_unlock();

 return 0;
  }

// papr-vpd.c

  static void vpd_sequence_begin(struct vpd_sequence *seq,
 const struct papr_location_code *loc_code)
  {
  static struct papr_location_code static_loc_code;
  papr_vpd_mutex_lock();
+ rtas_syscall_lock();
  static_loc_code = *loc_code;
  *seq = (struct vpd_sequence) {
  .params = {
  .work_area = rtas_work_area_alloc(SZ_4K),
  .loc_code = _loc_code,
  .sequence = 1,
  },
  };
  }

  /**
   * vpd_sequence_end() - Finalize a VPD retrieval sequence.
   * @seq: Sequence state.
   *
   * Releases resources obtained by vpd_sequence_begin().
   */
  static void vpd_sequence_end(struct vpd_sequence *seq)
  {
  rtas_work_area_free(seq->params.work_area);
+ rtas_syscall_unlock();
  papr_vpd_mutex_unlock();
  }


This is a sketch to communicate the idea. The locking in the real code
could be finer, perhaps a mutex per RTAS function.


Re: [PATCH] arch: powerpc: net: bpf_jit_comp32.c: Fixed 'instead' typo

2023-10-16 Thread Daniel Borkmann

On 10/13/23 7:31 AM, Muhammad Muzammil wrote:

Fixed 'instead' typo

Signed-off-by: Muhammad Muzammil 


Michael, I presume you'll pick it up?

Thanks,
Daniel


---
  arch/powerpc/net/bpf_jit_comp32.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/net/bpf_jit_comp32.c 
b/arch/powerpc/net/bpf_jit_comp32.c
index 7f91ea064c08..bc7f92ec7f2d 100644
--- a/arch/powerpc/net/bpf_jit_comp32.c
+++ b/arch/powerpc/net/bpf_jit_comp32.c
@@ -940,7 +940,7 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, 
struct codegen_context *
 * !fp->aux->verifier_zext. Emit NOP otherwise.
 *
 * Note that "li reg_h,0" is emitted for 
BPF_B/H/W case,
-* if necessary. So, jump there insted of 
emitting an
+* if necessary. So, jump there instead of 
emitting an
 * additional "li reg_h,0" instruction.
 */
if (size == BPF_DW && !fp->aux->verifier_zext)





[PATCH 6/6] powerpc/qspinlock: Rename yield_propagate_owner tunable

2023-10-16 Thread Nicholas Piggin
Rename yield_propagate_owner to yield_sleepy_owner, which better
describes what it does (what, not how).

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/lib/qspinlock.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c
index c68c2bd7b853..5de4dd549f6e 100644
--- a/arch/powerpc/lib/qspinlock.c
+++ b/arch/powerpc/lib/qspinlock.c
@@ -44,7 +44,7 @@ static bool pv_sleepy_lock_sticky __read_mostly = false;
 static u64 pv_sleepy_lock_interval_ns __read_mostly = 0;
 static int pv_sleepy_lock_factor __read_mostly = 256;
 static bool pv_yield_prev __read_mostly = true;
-static bool pv_yield_propagate_owner __read_mostly = true;
+static bool pv_yield_sleepy_owner __read_mostly = true;
 static bool pv_prod_head __read_mostly = false;
 
 static DEFINE_PER_CPU_ALIGNED(struct qnodes, qnodes);
@@ -357,7 +357,7 @@ static __always_inline void propagate_sleepy(struct qnode 
*node, u32 val, bool p
 
if (!paravirt)
return;
-   if (!pv_yield_propagate_owner)
+   if (!pv_yield_sleepy_owner)
return;
 
next = READ_ONCE(node->next);
@@ -381,7 +381,7 @@ static __always_inline bool yield_to_prev(struct qspinlock 
*lock, struct qnode *
if (!paravirt)
goto relax;
 
-   if (!pv_yield_propagate_owner)
+   if (!pv_yield_sleepy_owner)
goto yield_prev;
 
/*
@@ -934,21 +934,21 @@ static int pv_yield_prev_get(void *data, u64 *val)
 
 DEFINE_SIMPLE_ATTRIBUTE(fops_pv_yield_prev, pv_yield_prev_get, 
pv_yield_prev_set, "%llu\n");
 
-static int pv_yield_propagate_owner_set(void *data, u64 val)
+static int pv_yield_sleepy_owner_set(void *data, u64 val)
 {
-   pv_yield_propagate_owner = !!val;
+   pv_yield_sleepy_owner = !!val;
 
return 0;
 }
 
-static int pv_yield_propagate_owner_get(void *data, u64 *val)
+static int pv_yield_sleepy_owner_get(void *data, u64 *val)
 {
-   *val = pv_yield_propagate_owner;
+   *val = pv_yield_sleepy_owner;
 
return 0;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(fops_pv_yield_propagate_owner, 
pv_yield_propagate_owner_get, pv_yield_propagate_owner_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(fops_pv_yield_sleepy_owner, pv_yield_sleepy_owner_get, 
pv_yield_sleepy_owner_set, "%llu\n");
 
 static int pv_prod_head_set(void *data, u64 val)
 {
@@ -980,7 +980,7 @@ static __init int spinlock_debugfs_init(void)
debugfs_create_file("qspl_pv_sleepy_lock_interval_ns", 0600, 
arch_debugfs_dir, NULL, _pv_sleepy_lock_interval_ns);
debugfs_create_file("qspl_pv_sleepy_lock_factor", 0600, 
arch_debugfs_dir, NULL, _pv_sleepy_lock_factor);
debugfs_create_file("qspl_pv_yield_prev", 0600, 
arch_debugfs_dir, NULL, _pv_yield_prev);
-   debugfs_create_file("qspl_pv_yield_propagate_owner", 0600, 
arch_debugfs_dir, NULL, _pv_yield_propagate_owner);
+   debugfs_create_file("qspl_pv_yield_sleepy_owner", 0600, 
arch_debugfs_dir, NULL, _pv_yield_sleepy_owner);
debugfs_create_file("qspl_pv_prod_head", 0600, 
arch_debugfs_dir, NULL, _pv_prod_head);
}
 
-- 
2.42.0



[PATCH 5/6] powerpc/qspinlock: Propagate sleepy if previous waiter is preempted

2023-10-16 Thread Nicholas Piggin
The sleepy (aka lock-owner-is-preempted) condition is propagated down
the queue by each waiter. If a waiter becomes preempted, it can no
longer propagate sleepy. To allow subsequent waiters to yield to the
lock owner, also check the lock owner in this case.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/lib/qspinlock.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c
index 6bb627e90a32..c68c2bd7b853 100644
--- a/arch/powerpc/lib/qspinlock.c
+++ b/arch/powerpc/lib/qspinlock.c
@@ -384,7 +384,11 @@ static __always_inline bool yield_to_prev(struct qspinlock 
*lock, struct qnode *
if (!pv_yield_propagate_owner)
goto yield_prev;
 
-   if (node->sleepy) {
+   /*
+* If the previous waiter was preempted it might not be able to
+* propagate sleepy to us, so check the lock in that case too.
+*/
+   if (node->sleepy || vcpu_is_preempted(prev_cpu)) {
u32 val = READ_ONCE(lock->val);
 
if (val & _Q_LOCKED_VAL) {
-- 
2.42.0



[PATCH 4/6] powerpc/qspinlock: don't propagate the not-sleepy state

2023-10-16 Thread Nicholas Piggin
To simplify things, don't propagate the not-sleepy condition back down
the queue. Instead, have the waiters clear their own node->sleepy when
finding the lock owner is not preempted.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/lib/qspinlock.c | 26 --
 1 file changed, 8 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c
index 0932d24a6b07..6bb627e90a32 100644
--- a/arch/powerpc/lib/qspinlock.c
+++ b/arch/powerpc/lib/qspinlock.c
@@ -350,7 +350,7 @@ static __always_inline bool 
yield_head_to_locked_owner(struct qspinlock *lock, u
return __yield_to_locked_owner(lock, val, paravirt, mustq);
 }
 
-static __always_inline void propagate_sleepy(struct qnode *node, u32 val, bool 
*set_sleepy, bool paravirt)
+static __always_inline void propagate_sleepy(struct qnode *node, u32 val, bool 
paravirt)
 {
struct qnode *next;
int owner;
@@ -359,18 +359,17 @@ static __always_inline void propagate_sleepy(struct qnode 
*node, u32 val, bool *
return;
if (!pv_yield_propagate_owner)
return;
-   if (*set_sleepy)
-   return;
 
next = READ_ONCE(node->next);
if (!next)
return;
 
+   if (next->sleepy)
+   return;
+
owner = get_owner_cpu(val);
-   if (vcpu_is_preempted(owner)) {
+   if (vcpu_is_preempted(owner))
next->sleepy = 1;
-   *set_sleepy = true;
-   }
 }
 
 /* Called inside spin_begin() */
@@ -385,12 +384,7 @@ static __always_inline bool yield_to_prev(struct qspinlock 
*lock, struct qnode *
if (!pv_yield_propagate_owner)
goto yield_prev;
 
-   if (!READ_ONCE(node->sleepy)) {
-   /* Propagate back sleepy==false */
-   if (node->next && node->next->sleepy)
-   node->next->sleepy = 0;
-   goto yield_prev;
-   } else {
+   if (node->sleepy) {
u32 val = READ_ONCE(lock->val);
 
if (val & _Q_LOCKED_VAL) {
@@ -410,6 +404,7 @@ static __always_inline bool yield_to_prev(struct qspinlock 
*lock, struct qnode *
if (preempted)
return preempted;
}
+   node->sleepy = false;
}
 
 yield_prev:
@@ -533,7 +528,6 @@ static __always_inline void 
queued_spin_lock_mcs_queue(struct qspinlock *lock, b
bool sleepy = false;
bool mustq = false;
int idx;
-   bool set_sleepy = false;
int iters = 0;
 
BUILD_BUG_ON(CONFIG_NR_CPUS >= (1U << _Q_TAIL_CPU_BITS));
@@ -591,10 +585,6 @@ static __always_inline void 
queued_spin_lock_mcs_queue(struct qspinlock *lock, b
spec_barrier();
spin_end();
 
-   /* Clear out stale propagated sleepy */
-   if (paravirt && pv_yield_propagate_owner && node->sleepy)
-   node->sleepy = 0;
-
smp_rmb(); /* acquire barrier for the mcs lock */
 
/*
@@ -636,7 +626,7 @@ static __always_inline void 
queued_spin_lock_mcs_queue(struct qspinlock *lock, b
}
}
 
-   propagate_sleepy(node, val, _sleepy, paravirt);
+   propagate_sleepy(node, val, paravirt);
preempted = yield_head_to_locked_owner(lock, val, paravirt);
if (!maybe_stealers)
continue;
-- 
2.42.0



[PATCH 3/6] powerpc/qspinlock: propagate owner preemptedness rather than CPU number

2023-10-16 Thread Nicholas Piggin
Rather than propagating the CPU number of the preempted lock owner,
just propagate whether the owner was preempted. Waiters must read the
lock value when yielding to it to prevent races anyway, so might as
well always load the owner CPU from the lock.

To further simplify the code, also don't propagate the -1 (or
sleepy=false in the new scheme) down the queue. Instead, have the
waiters clear it themselves when finding the lock owner is not
preempted.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/lib/qspinlock.c | 80 
 1 file changed, 36 insertions(+), 44 deletions(-)

diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c
index 75608ced14c2..0932d24a6b07 100644
--- a/arch/powerpc/lib/qspinlock.c
+++ b/arch/powerpc/lib/qspinlock.c
@@ -16,7 +16,8 @@ struct qnode {
struct qnode*next;
struct qspinlock *lock;
int cpu;
-   int yield_cpu;
+   u8  sleepy; /* 1 if the previous vCPU was preempted or
+* if the previous node was sleepy */
u8  locked; /* 1 if lock acquired */
 };
 
@@ -349,7 +350,7 @@ static __always_inline bool 
yield_head_to_locked_owner(struct qspinlock *lock, u
return __yield_to_locked_owner(lock, val, paravirt, mustq);
 }
 
-static __always_inline void propagate_yield_cpu(struct qnode *node, u32 val, 
int *set_yield_cpu, bool paravirt)
+static __always_inline void propagate_sleepy(struct qnode *node, u32 val, bool 
*set_sleepy, bool paravirt)
 {
struct qnode *next;
int owner;
@@ -358,21 +359,17 @@ static __always_inline void propagate_yield_cpu(struct 
qnode *node, u32 val, int
return;
if (!pv_yield_propagate_owner)
return;
-
-   owner = get_owner_cpu(val);
-   if (*set_yield_cpu == owner)
+   if (*set_sleepy)
return;
 
next = READ_ONCE(node->next);
if (!next)
return;
 
+   owner = get_owner_cpu(val);
if (vcpu_is_preempted(owner)) {
-   next->yield_cpu = owner;
-   *set_yield_cpu = owner;
-   } else if (*set_yield_cpu != -1) {
-   next->yield_cpu = owner;
-   *set_yield_cpu = owner;
+   next->sleepy = 1;
+   *set_sleepy = true;
}
 }
 
@@ -380,7 +377,6 @@ static __always_inline void propagate_yield_cpu(struct 
qnode *node, u32 val, int
 static __always_inline bool yield_to_prev(struct qspinlock *lock, struct qnode 
*node, int prev_cpu, bool paravirt)
 {
u32 yield_count;
-   int yield_cpu;
bool preempted = false;
 
if (!paravirt)
@@ -389,36 +385,32 @@ static __always_inline bool yield_to_prev(struct 
qspinlock *lock, struct qnode *
if (!pv_yield_propagate_owner)
goto yield_prev;
 
-   yield_cpu = READ_ONCE(node->yield_cpu);
-   if (yield_cpu == -1) {
-   /* Propagate back the -1 CPU */
-   if (node->next && node->next->yield_cpu != -1)
-   node->next->yield_cpu = yield_cpu;
+   if (!READ_ONCE(node->sleepy)) {
+   /* Propagate back sleepy==false */
+   if (node->next && node->next->sleepy)
+   node->next->sleepy = 0;
goto yield_prev;
-   }
-
-   yield_count = yield_count_of(yield_cpu);
-   if ((yield_count & 1) == 0)
-   goto yield_prev; /* owner vcpu is running */
-
-   if (get_owner_cpu(READ_ONCE(lock->val)) != yield_cpu)
-   goto yield_prev; /* re-sample lock owner */
-
-   spin_end();
-
-   preempted = true;
-   seen_sleepy_node();
-
-   smp_rmb();
+   } else {
+   u32 val = READ_ONCE(lock->val);
+
+   if (val & _Q_LOCKED_VAL) {
+   if (node->next && !node->next->sleepy) {
+   /*
+* Propagate sleepy to next waiter. Only if
+* owner is preempted, which allows the queue
+* to become "non-sleepy" if vCPU preemption
+* ceases to occur, even if the lock remains
+* highly contended.
+*/
+   if (vcpu_is_preempted(get_owner_cpu(val)))
+   node->next->sleepy = 1;
+   }
 
-   if (yield_cpu == node->yield_cpu) {
-   if (node->next && node->next->yield_cpu != yield_cpu)
-   node->next->yield_cpu = yield_cpu;
-   yield_to_preempted(yield_cpu, yield_count);
-   spin_begin();
-   return preempted;
+   preempted = yield_to_locked_owner(lock, val, paravirt);
+   if (preempted)
+   return preempted;
+   

[PATCH 2/6] powerpc/qspinlock: stop queued waiters trying to set lock sleepy

2023-10-16 Thread Nicholas Piggin
If a queued waiter notices the lock owner or the previous waiter has
been preempted, it attempts to mark the lock sleepy, but it does this
as a try-set operation using the original lock value it got when
queueing, which will become stale as the queue progresses, and the
try-set will fail. Drop this and just set the sleepy seen clock.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/lib/qspinlock.c | 24 ++--
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c
index 6dd2f46bd3ef..75608ced14c2 100644
--- a/arch/powerpc/lib/qspinlock.c
+++ b/arch/powerpc/lib/qspinlock.c
@@ -247,22 +247,18 @@ static __always_inline void seen_sleepy_lock(void)
this_cpu_write(sleepy_lock_seen_clock, sched_clock());
 }
 
-static __always_inline void seen_sleepy_node(struct qspinlock *lock, u32 val)
+static __always_inline void seen_sleepy_node(void)
 {
if (pv_sleepy_lock) {
if (pv_sleepy_lock_interval_ns)
this_cpu_write(sleepy_lock_seen_clock, sched_clock());
-   if (val & _Q_LOCKED_VAL) {
-   if (!(val & _Q_SLEEPY_VAL))
-   try_set_sleepy(lock, val);
-   }
+   /* Don't set sleepy because we likely have a stale val */
}
 }
 
-static struct qnode *get_tail_qnode(struct qspinlock *lock, u32 val)
+static struct qnode *get_tail_qnode(struct qspinlock *lock, int prev_cpu)
 {
-   int cpu = decode_tail_cpu(val);
-   struct qnodes *qnodesp = per_cpu_ptr(, cpu);
+   struct qnodes *qnodesp = per_cpu_ptr(, prev_cpu);
int idx;
 
/*
@@ -381,9 +377,8 @@ static __always_inline void propagate_yield_cpu(struct 
qnode *node, u32 val, int
 }
 
 /* Called inside spin_begin() */
-static __always_inline bool yield_to_prev(struct qspinlock *lock, struct qnode 
*node, u32 val, bool paravirt)
+static __always_inline bool yield_to_prev(struct qspinlock *lock, struct qnode 
*node, int prev_cpu, bool paravirt)
 {
-   int prev_cpu = decode_tail_cpu(val);
u32 yield_count;
int yield_cpu;
bool preempted = false;
@@ -412,7 +407,7 @@ static __always_inline bool yield_to_prev(struct qspinlock 
*lock, struct qnode *
spin_end();
 
preempted = true;
-   seen_sleepy_node(lock, val);
+   seen_sleepy_node();
 
smp_rmb();
 
@@ -436,7 +431,7 @@ static __always_inline bool yield_to_prev(struct qspinlock 
*lock, struct qnode *
spin_end();
 
preempted = true;
-   seen_sleepy_node(lock, val);
+   seen_sleepy_node();
 
smp_rmb(); /* See __yield_to_locked_owner comment */
 
@@ -587,7 +582,8 @@ static __always_inline void 
queued_spin_lock_mcs_queue(struct qspinlock *lock, b
 * head of the waitqueue.
 */
if (old & _Q_TAIL_CPU_MASK) {
-   struct qnode *prev = get_tail_qnode(lock, old);
+   int prev_cpu = decode_tail_cpu(old);
+   struct qnode *prev = get_tail_qnode(lock, prev_cpu);
 
/* Link @node into the waitqueue. */
WRITE_ONCE(prev->next, node);
@@ -597,7 +593,7 @@ static __always_inline void 
queued_spin_lock_mcs_queue(struct qspinlock *lock, b
while (!READ_ONCE(node->locked)) {
spec_barrier();
 
-   if (yield_to_prev(lock, node, old, paravirt))
+   if (yield_to_prev(lock, node, prev_cpu, paravirt))
seen_preempted = true;
}
spec_barrier();
-- 
2.42.0



[PATCH 1/6] powerpc/qspinlock: Fix stale propagated yield_cpu

2023-10-16 Thread Nicholas Piggin
yield_cpu is a sample of a preempted lock holder that gets propagated
back through the queue. Queued waiters use this to yield to the
preempted lock holder without continually sampling the lock word (which
would defeat the purpose of MCS queueing by bouncing the cache line).

The problem is that yield_cpu can become stale. It can take some time to
be passed down the chain, and if any queued waiter gets preempted then
it will cease to propagate the yield_cpu to later waiters.

This can result in yielding to a CPU that no longer holds the lock,
which is bad, but particularly if it is currently in H_CEDE (idle),
then it appears to be preempted and some hypervisors (PowerVM) can
cause very long H_CONFER latencies waiting for H_CEDE wakeup. This
results in latency spikes and hard lockups on oversubscribed
partitions with lock contention.

This is a minimal fix. Before yielding to yield_cpu, sample the lock
word to confirm yield_cpu is still the owner, and bail out of it is not.

Thanks to a bunch of people who reported this and tracked down the
exact problem using tracepoints and dispatch trace logs.

Fixes: 28db61e207ea ("powerpc/qspinlock: allow propagation of yield CPU down 
the queue")
Reported-by: Srikar Dronamraju 
Reported-by: Laurent Dufour 
Reported-by: Shrikanth Hegde 
Debugged-by: Nysal Jan K.A 
Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/lib/qspinlock.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/lib/qspinlock.c b/arch/powerpc/lib/qspinlock.c
index 253620979d0c..6dd2f46bd3ef 100644
--- a/arch/powerpc/lib/qspinlock.c
+++ b/arch/powerpc/lib/qspinlock.c
@@ -406,6 +406,9 @@ static __always_inline bool yield_to_prev(struct qspinlock 
*lock, struct qnode *
if ((yield_count & 1) == 0)
goto yield_prev; /* owner vcpu is running */
 
+   if (get_owner_cpu(READ_ONCE(lock->val)) != yield_cpu)
+   goto yield_prev; /* re-sample lock owner */
+
spin_end();
 
preempted = true;
-- 
2.42.0



[PATCH 0/6] powerpc/qspinlock: Fix yield latency bug and other

2023-10-16 Thread Nicholas Piggin
This fixes a long-standing latency bug in the powerpc qspinlock
implementation that quite a few people have reported and helped
out with debugging.

The first patch is a minimal fix that avoids the problem. The
other patches are streamlining and improvements after the fix.

Thanks,
Nick

Nicholas Piggin (6):
  powerpc/qspinlock: Fix stale propagated yield_cpu
  powerpc/qspinlock: stop queued waiters trying to set lock sleepy
  powerpc/qspinlock: propagate owner preemptedness rather than CPU
number
  powerpc/qspinlock: don't propagate the not-sleepy state
  powerpc/qspinlock: Propagate sleepy if previous waiter is preempted
  powerpc/qspinlock: Rename yield_propagate_owner tunable

 arch/powerpc/lib/qspinlock.c | 119 +++
 1 file changed, 52 insertions(+), 67 deletions(-)

-- 
2.42.0



Re: [RFC PATCH v6 08/11] media: uapi: define audio sample format fourcc type

2023-10-16 Thread Hans Verkuil
On 13/10/2023 10:31, Shengjiu Wang wrote:
> 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  | 202 ++
>  .../userspace-api/media/v4l/pixfmt.rst|   1 +
>  drivers/media/v4l2-core/v4l2-ioctl.c  |  36 
>  include/uapi/linux/videodev2.h|  48 +
>  4 files changed, 287 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 ..ac89b2c4b594
> --- /dev/null
> +++ b/Documentation/userspace-api/media/v4l/pixfmt-audio.rst
> @@ -0,0 +1,202 @@
> +.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
> +
> +.. _pixfmt-audio:
> +
> +*
> +Audio Formats
> +*
> +
> +These formats are used for :ref:`audiomem2mem` interface only.
> +
> +.. 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-U8:
> +
> +  - ``V4L2_AUDIO_FMT_U8``
> +  - 'U8'
> +  - Corresponds to SNDRV_PCM_FORMAT_U8 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-S16-BE:
> +
> +  - ``V4L2_AUDIO_FMT_S16_BE``
> +  - 'S16_BE'
> +  - Corresponds to SNDRV_PCM_FORMAT_S16_BE 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-U16-BE:
> +
> +  - ``V4L2_AUDIO_FMT_U16_BE``
> +  - 'U16_BE'
> +  - Corresponds to SNDRV_PCM_FORMAT_U16_BE 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-S24-BE:
> +
> +  - ``V4L2_AUDIO_FMT_S24_BE``
> +  - 'S24_BE'
> +  - Corresponds to SNDRV_PCM_FORMAT_S24_BE 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-U24-BE:
> +
> +  - ``V4L2_AUDIO_FMT_U24_BE``
> +  - 'U24_BE'
> +  - Corresponds to SNDRV_PCM_FORMAT_U24_BE 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-S32-BE:
> +
> +  - ``V4L2_AUDIO_FMT_S32_BE``
> +  - 'S32_BE'
> +  - Corresponds to SNDRV_PCM_FORMAT_S32_BE 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-U32-BE:
> +
> +  - ``V4L2_AUDIO_FMT_U32_BE``
> +  - 'U32_BE'
> +  - Corresponds to SNDRV_PCM_FORMAT_U32_BE 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-FLOAT-BE:
> +
> +  - ``V4L2_AUDIO_FMT_FLOAT_BE``
> +  - 'FLOAT_BE'
> +  - Corresponds to SNDRV_PCM_FORMAT_FLOAT_BE in ALSA
> +* .. _V4L2-AUDIO-FMT-FLOAT64-LE:
> +
> +  - ``V4L2_AUDIO_FMT_FLOAT64_LE``
> +  - 'FLOAT64_LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_FLOAT64_LE in ALSA
> +* .. _V4L2-AUDIO-FMT-FLOAT64-BE:
> +
> +  - ``V4L2_AUDIO_FMT_FLOAT64_BE``
> +  - 'FLOAT64_BE'
> +  - Corresponds to SNDRV_PCM_FORMAT_FLOAT64_BE 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-IEC958-SUBFRAME-BE:
> +
> +  - ``V4L2_AUDIO_FMT_IEC958_SUBFRAME_BE``
> +  - 'IEC958_SUBFRAME_BE'
> +  - Corresponds to SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE in ALSA
> +* .. _V4L2-AUDIO-FMT-S20-LE:
> +
> +  - ``V4L2_AUDIO_FMT_S20_LE``
> +  - 'S20_LE'
> +  - Corresponds to SNDRV_PCM_FORMAT_S20_LE in ALSA
> +* .. _V4L2-AUDIO-FMT-S20-BE:
> +
> +  - ``V4L2_AUDIO_FMT_S20_BE``
> 

Re: [PATCH v6 0/5] powerpc/bpf: use BPF prog pack allocator

2023-10-16 Thread Daniel Borkmann

On 10/12/23 10:03 PM, Hari Bathini wrote:

Most BPF programs are small, but they consume a page each. For systems
with busy traffic and many BPF programs, this may also add significant
pressure on instruction TLB. High iTLB pressure usually slows down the
whole system causing visible performance degradation for production
workloads.

bpf_prog_pack, a customized allocator that packs multiple bpf programs
into preallocated memory chunks, was proposed [1] to address it. This
series extends this support on powerpc.

Both bpf_arch_text_copy() & bpf_arch_text_invalidate() functions,
needed for this support depend on instruction patching in text area.
Currently, patch_instruction() supports patching only one instruction
at a time. The first patch introduces patch_instructions() function
to enable patching more than one instruction at a time. This helps in
avoiding performance degradation while JITing bpf programs.

Patches 2 & 3 implement the above mentioned arch specific functions
using patch_instructions(). Patch 4 fixes a misnomer in bpf JITing
code. The last patch enables the use of BPF prog pack allocator on
powerpc and also, ensures cleanup is handled gracefully.

[1] https://lore.kernel.org/bpf/20220204185742.271030-1-s...@kernel.org/

Changes in v6:
* No changes in patches 2-5/5 except addition of Acked-by tags from Song.
* Skipped merging code path of patch_instruction() & patch_instructions()
   to avoid performance overhead observed on ppc32 with that.


I presume this will be routed via Michael?

Thanks,
Daniel


Re: [RFC PATCH v6 07/11] media: v4l2: Add audio capture and output support

2023-10-16 Thread Hans Verkuil
On 13/10/2023 10:31, Shengjiu Wang wrote:
> 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-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 +
>  12 files changed, 213 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 04dec3e570ed..80cf2cb20dfe 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 ..2ea493d0a73b
> --- /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
> +
> +
> +A audio memory-to-memory device can compress, decompress, transform, or

A -> An

> +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 codecs, audio preprocessing,

codecs -> audio codecs

Reason: within V4L2 'codec' refers to a video codec by default, so for audio
codecs it is better to be explicit and mention 'audio'.

> +audio postprocessing.
> +
> +A memory-to-memory audio node supports both output (sending frames from

I think it is better to write 'audio frames' instead of just 'frames', for
the same reason as why I prefer 'audio codec'. It makes it explicit that we
are dealing with audio.

> +memory to the hardware) and capture (receiving the processed frames

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:: 

RE: Re: [PATCH v3 1/2] ASoC: dt-bindings: sound-card-common: List DAPM endpoints ignoring system suspend

2023-10-16 Thread Chancel Liu
> >  I think the key thing
> > here is that these are endpoints that can be active over suspend of
> > the main application processor that the current operating system is
> > running (system DT stuff is an interesting corner case here...), and
> > the example is probably a bit specific.  Other bindings use "audio sound
> widgets"
> > rather than "DAPM widgets".
> >
> > We also shouldn't see that these endpoints "should not be disabled"
> > since that implies that they should be left on even if they aren't
> > active which isn't quite the case, instead it's that we can continue
> > playing an audio stream through them in suspend.
> 
> This seems like one of those things that everyone has/does, and everyone
> handles it a bit differently. I applaud trying to do something common, but it
> isn't really common until we have multiple users.
> 
> Rob

Thanks Mark and Rob for your advice. In fact, it's common use case. We can see
many drivers set widgets ignoring suspend. I will remove the linux specifics
and focus on the key concept. How about the modification on the property name
and description as following:
  ignore-suspend-widgets:
description: |
  A list of audio sound widgets which are marked ignoring system suspend.
  Paths between these endpoints are still active over suspend of the 
main
  application processor that the current operating system is running.

Regards, 
Chancel Liu


Re: [PATCH v2 9/9] iommu/dart: Remove the force_bypass variable

2023-10-16 Thread Janne Grunau
Hej,

On Thu, Sep 28, 2023, at 01:47, Jason Gunthorpe wrote:
> This flag just caches if the IO page size is larger than the CPU
> PAGE_SIZE. This only needs to be checked in two places so remove the
> confusingly named cache.
>
> dart would like to not support paging domains at all if the IO page size
> is larger than the CPU page size. In this case we should ideally fail
> domain_alloc_paging(), as there is no point in creating a domain that can
> never be attached. Move the test into apple_dart_finalize_domain().
>
> The check in apple_dart_mod_streams() will prevent the domain from being
> attached to the wrong dart
>
> There is no HW limitation that prevents BLOCKED domains from working,
> remove that test.
>
> The check in apple_dart_of_xlate() is redundant since immediately after
> the pgsize is checked. Remove it.
>
> Remove the variable.
>
> Suggested-by: Janne Grunau 
> Signed-off-by: Jason Gunthorpe 
> ---
>  drivers/iommu/apple-dart.c | 20 ++--
>  1 file changed, 6 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c
> index 126da0d89f0dd4..821b4a3465dfb9 100644
> --- a/drivers/iommu/apple-dart.c
> +++ b/drivers/iommu/apple-dart.c
> @@ -196,7 +196,6 @@ struct apple_dart_hw {
>   * @lock: lock for hardware operations involving this dart
>   * @pgsize: pagesize supported by this DART
>   * @supports_bypass: indicates if this DART supports bypass mode
> - * @force_bypass: force bypass mode due to pagesize mismatch?
>   * @sid2group: maps stream ids to iommu_groups
>   * @iommu: iommu core device
>   */
> @@ -217,7 +216,6 @@ struct apple_dart {
>   u32 pgsize;
>   u32 num_streams;
>   u32 supports_bypass : 1;
> - u32 force_bypass : 1;
> 
>   struct iommu_group *sid2group[DART_MAX_STREAMS];
>   struct iommu_device iommu;
> @@ -576,6 +574,9 @@ static int apple_dart_finalize_domain(struct 
> apple_dart_domain *dart_domain,
>   int ret = 0;
>   int i, j;
> 
> + if (dart->pgsize > PAGE_SIZE)
> + return -EINVAL;
> +
>   mutex_lock(_domain->init_lock);
> 
>   if (dart_domain->finalized)
> @@ -659,9 +660,6 @@ static int apple_dart_attach_dev_paging(struct 
> iommu_domain *domain,
>   struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
>   struct apple_dart_domain *dart_domain = to_dart_domain(domain);
> 
> - if (cfg->stream_maps[0].dart->force_bypass)
> - return -EINVAL;
> -
>   ret = apple_dart_finalize_domain(dart_domain, cfg);
>   if (ret)
>   return ret;
> @@ -706,9 +704,6 @@ static int apple_dart_attach_dev_blocked(struct 
> iommu_domain *domain,
>   struct apple_dart_stream_map *stream_map;
>   int i;
> 
> - if (cfg->stream_maps[0].dart->force_bypass)
> - return -EINVAL;
> -
>   for_each_stream_map(i, cfg, stream_map)
>   apple_dart_hw_disable_dma(stream_map);
>   return 0;
> @@ -803,8 +798,6 @@ static int apple_dart_of_xlate(struct device *dev, 
> struct of_phandle_args *args)
>   if (cfg_dart) {
>   if (cfg_dart->supports_bypass != dart->supports_bypass)
>   return -EINVAL;
> - if (cfg_dart->force_bypass != dart->force_bypass)
> - return -EINVAL;
>   if (cfg_dart->pgsize != dart->pgsize)
>   return -EINVAL;
>   }
> @@ -946,7 +939,7 @@ static int apple_dart_def_domain_type(struct device 
> *dev)
>  {
>   struct apple_dart_master_cfg *cfg = dev_iommu_priv_get(dev);
> 
> - if (cfg->stream_maps[0].dart->force_bypass)
> + if (cfg->stream_maps[0].dart->pgsize > PAGE_SIZE)
>   return IOMMU_DOMAIN_IDENTITY;
>   if (!cfg->stream_maps[0].dart->supports_bypass)
>   return IOMMU_DOMAIN_DMA;
> @@ -1146,8 +1139,6 @@ static int apple_dart_probe(struct platform_device 
> *pdev)
>   goto err_clk_disable;
>   }
> 
> - dart->force_bypass = dart->pgsize > PAGE_SIZE;
> -
>   ret = apple_dart_hw_reset(dart);
>   if (ret)
>   goto err_clk_disable;
> @@ -1171,7 +1162,8 @@ static int apple_dart_probe(struct 
> platform_device *pdev)
>   dev_info(
>   >dev,
>   "DART [pagesize %x, %d streams, bypass support: %d, bypass 
> forced: 
> %d] initialized\n",
> - dart->pgsize, dart->num_streams, dart->supports_bypass, 
> dart->force_bypass);
> + dart->pgsize, dart->num_streams, dart->supports_bypass,
> + dart->pgsize > PAGE_SIZE);
>   return 0;
> 
>  err_sysfs_remove:
> -- 

Reviewed-by: Janne Grunau 

thanks,
Janne


Re: [PATCH 06/20] mtd: powernv_flash: Convert to platform remove callback returning void

2023-10-16 Thread Miquel Raynal
On Sun, 2023-10-08 at 20:01:29 UTC, =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= wrote:
> The .remove() callback for a platform driver returns an int which makes
> many driver authors wrongly assume it's possible to do error handling by
> returning an error code. However the value returned is ignored (apart
> from emitting a warning) and this typically results in resource leaks.
> 
> To improve here there is a quest to make the remove callback return
> void. In the first step of this quest all drivers are converted to
> .remove_new(), which already returns void. Eventually after all drivers
> are converted, .remove_new() will be renamed to .remove().
> 
> Trivially convert this driver from always returning zero in the remove
> callback to the void returning variant.
> 
> Signed-off-by: Uwe Kleine-König 

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git 
mtd/next, thanks.

Miquel


Re: [PATCHv8 1/5] powerpc/setup : Enable boot_cpu_hwid for PPC32

2023-10-16 Thread Sourabh Jain

Hello Pingfan,


With this patch series applied, the kdump kernel fails to boot on
powerpc with nr_cpus=1.

Console logs:
---
[root]# echo c > /proc/sysrq-trigger
[   74.783235] sysrq: Trigger a crash
[   74.783244] Kernel panic - not syncing: sysrq triggered crash
[   74.783252] CPU: 58 PID: 3838 Comm: bash Kdump: loaded Not tainted
6.6.0-rc5pf-nr-cpus+ #3
[   74.783259] Hardware name: POWER10 (raw) phyp pSeries
[   74.783275] Call Trace:
[   74.783280] [c0020f4ebac0] [c0ed9f38]
dump_stack_lvl+0x6c/0x9c (unreliable)
[   74.783291] [c0020f4ebaf0] [c0150300] panic+0x178/0x438
[   74.783298] [c0020f4ebb90] [c0936d48]
sysrq_handle_crash+0x28/0x30
[   74.783304] [c0020f4ebbf0] [c093773c]
__handle_sysrq+0x10c/0x250
[   74.783309] [c0020f4ebc90] [c0937fa8]
write_sysrq_trigger+0xc8/0x168
[   74.783314] [c0020f4ebcd0] [c0665d8c]
proc_reg_write+0x10c/0x1b0
[   74.783321] [c0020f4ebd00] [c058da54]
vfs_write+0x104/0x4b0
[   74.783326] [c0020f4ebdc0] [c058dfdc]
ksys_write+0x7c/0x140
[   74.783331] [c0020f4ebe10] [c0033a64]
system_call_exception+0x144/0x3a0
[   74.783337] [c0020f4ebe50] [c000c554]
system_call_common+0xf4/0x258
[   74.783343] --- interrupt: c00 at 0x7fffa0721594
[   74.783352] NIP:  7fffa0721594 LR: 7fffa0697bf4 CTR:

[   74.783364] REGS: c0020f4ebe80 TRAP: 0c00   Not tainted
(6.6.0-rc5pf-nr-cpus+)
[   74.783376] MSR:  8280f033
  CR: 2802  XER: 
[   74.783394] IRQMASK: 0
[   74.783394] GPR00: 0004 7c4b6800 7fffa0807300
0001
[   74.783394] GPR04: 00013549ea60 0002 0010

[   74.783394] GPR08:   

[   74.783394] GPR12:  7fffa0abaf70 4000
00011a0f9798
[   74.783394] GPR16: 00011a0f9724 00011a097688 00011a02ff70
00011a0fd568
[   74.783394] GPR20: 000135554bf0 0001 00011a0aa478
7c4b6a24
[   74.783394] GPR24: 7c4b6a20 00011a0faf94 0002
00013549ea60
[   74.783394] GPR28: 0002 7fffa08017a0 00013549ea60
0002
[   74.783440] NIP [7fffa0721594] 0x7fffa0721594
[   74.783443] LR [7fffa0697bf4] 0x7fffa0697bf4
[   74.783447] --- interrupt: c00
I'm in purgatory
[0.00] radix-mmu: Page sizes from device-tree:
[0.00] radix-mmu: Page size shift = 12 AP=0x0
[0.00] radix-mmu: Page size shift = 16 AP=0x5
[0.00] radix-mmu: Page size shift = 21 AP=0x1
[0.00] radix-mmu: Page size shift = 30 AP=0x2
[0.00] Activating Kernel Userspace Access Prevention
[0.00] Activating Kernel Userspace Execution Prevention
[0.00] radix-mmu: Mapped 0x-0x0001
with 64.0 KiB pages (exec)
[0.00] radix-mmu: Mapped 0x0001-0x0020
with 64.0 KiB pages
[0.00] radix-mmu: Mapped 0x0020-0x2000
with 2.00 MiB pages
[0.00] radix-mmu: Mapped 0x2000-0x2260
with 2.00 MiB pages (exec)
[0.00] radix-mmu: Mapped 0x2260-0x4000
with 2.00 MiB pages
[0.00] radix-mmu: Mapped 0x4000-0x00018000
with 1.00 GiB pages
[0.00] radix-mmu: Mapped 0x00018000-0x0001a000
with 2.00 MiB pages
[0.00] lpar: Using radix MMU under hypervisor
[0.00] Linux version 6.6.0-rc5pf-nr-cpus+
(r...@ltcever7x0-lp1.aus.stglabs.ibm.com) (gcc (GCC) 8.5.0 20210514 (Red
Hat 8.5.0-20), GNU ld version 2.30-123.el8) #3 SMP Mon Oct  9 11:07:
41 CDT 2023
[0.00] Found initrd at 0xc00022e6:0xc000248f08d8
[0.00] Hardware name: IBM,9043-MRX POWER10 (raw) 0x800200
0xf06 of:IBM,FW1060.00 (NM1060_016) hv:phyp pSeries
[0.00] printk: bootconsole [udbg0] enabled
[0.00] the round shift between dt seq and the cpu logic number:
56
[0.00] BUG: Unable to handle kernel data access on write at
0xc001a000
[0.00] Faulting instruction address: 0xc00022009c64
[0.00] Oops: Kernel access of bad area, sig: 11 [#1]
[0.00] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries
[0.00] Modules linked in:
[0.00] CPU: 2 PID: 0 Comm: swapper Not tainted
6.6.0-rc5pf-nr-cpus+ #3
[0.00] Hardware name:  POWER10 (raw)  hv:phyp pSeries
[0.00] NIP:  c00022009c64 LR: c00022009c54 CTR:
c000201ff348
[0.00] REGS: c00022aebb00 TRAP: 0300   Not tainted
(6.6.0-rc5pf-nr-cpus+)
[0.00] MSR:  80001033  CR: 28222824
XER: 0001
[0.00] CFAR: c00020031574 DAR: c001a000 DSISR:
4200 IRQMASK: 1
[0.00] GPR00: c00022009ba0 c00022aebda0 c000213d1300
0004
[0.00] GPR04: 0001