Re: [PATCH v9 10/15] media: uapi: Add V4L2_CTRL_TYPE_FIXED_POINT

2023-11-15 Thread Tomasz Figa
On Wed, Nov 15, 2023 at 8:49 PM Laurent Pinchart
 wrote:
>
> Hi Hans,
>
> On Wed, Nov 15, 2023 at 12:19:31PM +0100, Hans Verkuil wrote:
> > On 11/15/23 11:55, Laurent Pinchart wrote:
> > > On Wed, Nov 15, 2023 at 09:09:42AM +0100, Hans Verkuil wrote:
> > >> On 13/11/2023 13:44, Laurent Pinchart wrote:
> > >>> On Mon, Nov 13, 2023 at 01:05:12PM +0100, Hans Verkuil wrote:
> >  On 13/11/2023 12:43, Laurent Pinchart wrote:
> > > On Mon, Nov 13, 2023 at 11:28:51AM +, Sakari Ailus wrote:
> > >> On Mon, Nov 13, 2023 at 12:24:14PM +0100, Hans Verkuil wrote:
> > >>> On 13/11/2023 12:07, Laurent Pinchart wrote:
> >  On Mon, Nov 13, 2023 at 11:56:49AM +0100, Hans Verkuil wrote:
> > > On 13/11/2023 11:42, Laurent Pinchart wrote:
> > >> On Mon, Nov 13, 2023 at 11:29:09AM +0100, Hans Verkuil wrote:
> > >>> On 10/11/2023 06:48, Shengjiu Wang wrote:
> >  Fixed point controls are used by the user to configure
> >  a fixed point value in 64bits, which Q31.32 format.
> > 
> >  Signed-off-by: Shengjiu Wang 
> > >>>
> > >>> This patch adds a new control type. This is something that also 
> > >>> needs to be
> > >>> tested by v4l2-compliance, and for that we need to add support 
> > >>> for this to
> > >>> one of the media test-drivers. The best place for that is the 
> > >>> vivid driver,
> > >>> since that has already a bunch of test controls for other 
> > >>> control types.
> > >>>
> > >>> See e.g. VIVID_CID_INTEGER64 in vivid-ctrls.c.
> > >>>
> > >>> Can you add a patch adding a fixed point test control to vivid?
> > >>
> > >> I don't think V4L2_CTRL_TYPE_FIXED_POINT is a good idea. This 
> > >> seems to
> > >> relate more to units than control types. We have lots of 
> > >> fixed-point
> > >> values in controls already, using the 32-bit and 64-bit integer 
> > >> control
> > >> types. They use various locations for the decimal point, 
> > >> depending on
> > >> the control. If we want to make this more explicit to users, we 
> > >> should
> > >> work on adding unit support to the V4L2 controls.
> > >
> > > "Fixed Point" is not a unit, it's a type. 'Db', 'Hz' etc. are 
> > > units.
> > 
> >  It's not a unit, but I think it's related to units. My point is 
> >  that,
> >  without units support, I don't see why we need a formal definition 
> >  of
> >  fixed-point types, and why this series couldn't just use
> >  VIVID_CID_INTEGER64. Drivers already interpret VIVID_CID_INTEGER64
> >  values as they see fit.
> > >>>
> > >>> They do? That's new to me. A quick grep for V4L2_CTRL_TYPE_INTEGER64
> > >>> (I assume you meant that rather than VIVID_CID_INTEGER64) shows 
> > >>> that it
> > >
> > > Yes, I meant V4L2_CTRL_TYPE_INTEGER64. Too hasty copy & paste :-)
> > >
> > >>> is always interpreted as a 64 bit integer and nothing else. As it 
> > >>> should.
> > >
> > > The most common case for control handling in drivers is taking the
> > > integer value and converting it to a register value, using
> > > device-specific encoding of the register value. It can be a 
> > > fixed-point
> > > format or something else, depending on the device. My point is that
> > > drivers routinely convert a "plain" integer to something else, and 
> > > that
> > > has never been considered as a cause of concern. I don't see why it
> > > would be different in this series.
> > >
> > >>> And while we do not have support for units (other than the 
> > >>> documentation),
> > >>> we do have type support in the form of V4L2_CTRL_TYPE_*.
> > >>>
> > > A quick "git grep -i "fixed point" 
> > > Documentation/userspace-api/media/'
> > > only shows a single driver specific control (dw100.rst).
> > >
> > > I'm not aware of other controls in mainline that use fixed point.
> > 
> >  The analog gain control for sensors for instance.
> > >>>
> > >>> Not really. The documentation is super vague:
> > >>>
> > >>> V4L2_CID_ANALOGUE_GAIN (integer)
> > >>>
> > >>>   Analogue gain is gain affecting all colour components in the 
> > >>> pixel matrix. The
> > >>>   gain operation is performed in the analogue domain before A/D 
> > >>> conversion.
> > >>>
> > >>> And the integer is just a range. Internally it might map to some 
> > >>> fixed
> > >>> point value, but userspace won't see that, it's hidden in the 
> > >>> driver AFAICT.
> > >
> > > It's hidden so well that libcamera has a database of the sensor it
> > > supports, with formulas to map a real gain value to the
> 

[PATCH RFC 06/12] mm/gup: Drop folio_fast_pin_allowed() in hugepd processing

2023-11-15 Thread Peter Xu
Hugepd format is only used in PowerPC with hugetlbfs.  In commit
a6e79df92e4a ("mm/gup: disallow FOLL_LONGTERM GUP-fast writing to
file-backed mappings"), we added a check to fail gup-fast if there's
potential risk of violating GUP over writeback file systems.  That should
never apply to hugepd.

Drop that check, not only because it'll never be true for hugepd, but also
it paves way for reusing the function outside fast-gup.

Cc: Lorenzo Stoakes 
Cc: Michael Ellerman 
Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Peter Xu 
---
 mm/gup.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 0e00204761d2..424d45e1afb3 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -2816,11 +2816,6 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, 
unsigned long addr,
return 0;
}
 
-   if (!folio_fast_pin_allowed(folio, flags)) {
-   gup_put_folio(folio, refs, flags);
-   return 0;
-   }
-
if (!pte_write(pte) && gup_must_unshare(NULL, flags, >page)) {
gup_put_folio(folio, refs, flags);
return 0;
-- 
2.41.0



Re: [PATCH 2/7] kexec_file: print out debugging message if required

2023-11-15 Thread kernel test robot
Hi Baoquan,

kernel test robot noticed the following build errors:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on tip/x86/core powerpc/next powerpc/fixes linus/master 
v6.7-rc1 next-20231115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/kexec_file-add-kexec_file-flag-to-control-debug-printing/20231114-234003
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git 
for-next/core
patch link:
https://lore.kernel.org/r/20231114153253.241262-3-bhe%40redhat.com
patch subject: [PATCH 2/7] kexec_file: print out debugging message if required
config: x86_64-randconfig-002-20231115 
(https://download.01.org/0day-ci/archive/20231116/202311160502.jnu7b8kf-...@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231116/202311160502.jnu7b8kf-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202311160502.jnu7b8kf-...@intel.com/

All errors (new ones prefixed by >>):

   kernel/crash_core.c: In function 'crash_prepare_elf64_headers':
>> kernel/crash_core.c:412:17: error: implicit declaration of function 
>> 'kexec_dprintk'; did you mean '_dev_printk'? 
>> [-Werror=implicit-function-declaration]
 412 | kexec_dprintk("Crash PT_LOAD ELF header. phdr=%p 
vaddr=0x%llx, paddr=0x%llx, "
 | ^
 | _dev_printk
   cc1: some warnings being treated as errors


vim +412 kernel/crash_core.c

   323  
   324  int crash_prepare_elf64_headers(struct crash_mem *mem, int 
need_kernel_map,
   325void **addr, unsigned long *sz)
   326  {
   327  Elf64_Ehdr *ehdr;
   328  Elf64_Phdr *phdr;
   329  unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz;
   330  unsigned char *buf;
   331  unsigned int cpu, i;
   332  unsigned long long notes_addr;
   333  unsigned long mstart, mend;
   334  
   335  /* extra phdr for vmcoreinfo ELF note */
   336  nr_phdr = nr_cpus + 1;
   337  nr_phdr += mem->nr_ranges;
   338  
   339  /*
   340   * kexec-tools creates an extra PT_LOAD phdr for kernel text 
mapping
   341   * area (for example, 8000 - a000 on 
x86_64).
   342   * I think this is required by tools like gdb. So same physical
   343   * memory will be mapped in two ELF headers. One will contain 
kernel
   344   * text virtual addresses and other will have __va(physical) 
addresses.
   345   */
   346  
   347  nr_phdr++;
   348  elf_sz = sizeof(Elf64_Ehdr) + nr_phdr * sizeof(Elf64_Phdr);
   349  elf_sz = ALIGN(elf_sz, ELF_CORE_HEADER_ALIGN);
   350  
   351  buf = vzalloc(elf_sz);
   352  if (!buf)
   353  return -ENOMEM;
   354  
   355  ehdr = (Elf64_Ehdr *)buf;
   356  phdr = (Elf64_Phdr *)(ehdr + 1);
   357  memcpy(ehdr->e_ident, ELFMAG, SELFMAG);
   358  ehdr->e_ident[EI_CLASS] = ELFCLASS64;
   359  ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
   360  ehdr->e_ident[EI_VERSION] = EV_CURRENT;
   361  ehdr->e_ident[EI_OSABI] = ELF_OSABI;
   362  memset(ehdr->e_ident + EI_PAD, 0, EI_NIDENT - EI_PAD);
   363  ehdr->e_type = ET_CORE;
   364  ehdr->e_machine = ELF_ARCH;
   365  ehdr->e_version = EV_CURRENT;
   366  ehdr->e_phoff = sizeof(Elf64_Ehdr);
   367  ehdr->e_ehsize = sizeof(Elf64_Ehdr);
   368  ehdr->e_phentsize = sizeof(Elf64_Phdr);
   369  
   370  /* Prepare one phdr of type PT_NOTE for each possible CPU */
   371  for_each_possible_cpu(cpu) {
   372  phdr->p_type = PT_NOTE;
   373  notes_addr = 
per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpu));
   374  phdr->p_offset = phdr->p_paddr = notes_addr;
   375  phdr->p_filesz = phdr->p_memsz = sizeof(note_buf_t);
   376  (ehdr->e_phnum)++;
   377  phdr++;
   378  }
   379  
   380  /* Prepare one PT_NOTE header for vmcoreinfo */
   381  phdr->p_type = PT_NOTE;
   382  phdr->p_offset = phdr->p_paddr = paddr_vmcoreinfo_note();
   383  phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE;
   384  (ehdr->e_phnum)++;
   385  phdr++;
   386  
   387 

Re: [PATCH v2] powernv/opal-prd: Silence memcpy() run-time false positive warnings

2023-11-15 Thread matoro

On 2023-08-15 06:47, Michael Ellerman wrote:

Joel Stanley  writes:
On Fri, 7 Jul 2023 at 05:11, Mahesh Salgaonkar  
wrote:


opal_prd_msg_notifier extracts the opal prd message size from the message
header and uses it for allocating opal_prd_msg_queue_item that includes
the correct message size to be copied. However, while running under
CONFIG_FORTIFY_SOURCE=y, it triggers following run-time warning:

[ 6458.234352] memcpy: detected field-spanning write (size 32) of single 
field ">msg" at arch/powerpc/platforms/powernv/opal-prd.c:355 (size 
4)
[ 6458.234390] WARNING: CPU: 9 PID: 660 at 
arch/powerpc/platforms/powernv/opal-prd.c:355 
opal_prd_msg_notifier+0x174/0x188 [opal_prd]

[...]
[ 6458.234709] NIP [c0080e0c0e6c] opal_prd_msg_notifier+0x174/0x188 
[opal_prd]
[ 6458.234723] LR [c0080e0c0e68] opal_prd_msg_notifier+0x170/0x188 
[opal_prd]

[ 6458.234736] Call Trace:
[ 6458.234742] [c002acb23c10] [c0080e0c0e68] 
opal_prd_msg_notifier+0x170/0x188 [opal_prd] (unreliable)
[ 6458.234759] [c002acb23ca0] [c019ccc0] 
notifier_call_chain+0xc0/0x1b0
[ 6458.234774] [c002acb23d00] [c019ceac] 
atomic_notifier_call_chain+0x2c/0x40
[ 6458.234788] [c002acb23d20] [c00d69b4] 
opal_message_notify+0xf4/0x2c0

[...]

Split the copy to avoid false positive run-time warning.

Reported-by: Aneesh Kumar K.V 
Signed-off-by: Mahesh Salgaonkar 


I hit this on a box running the Ubuntu 6.2.0-27-generic kernel.

Do we plan on merging this fix?


I thought it was papering over the issue rather than fixing the root
cause.

I'll send a new version, as soon as I can work out how to trigger that
code path.

cheers


Hi, I see this was still not accepted.  I was able to trigger this simply by 
starting the opal-prd userspace daemon.

Restarting the service does not re-trigger the warning, however.

[Wed Nov 15 14:01:06 2023] i2c_dev: i2c /dev entries driver
[Wed Nov 15 14:01:07 2023] [ cut here ]
[Wed Nov 15 14:01:07 2023] memcpy: detected field-spanning write (size 32) of 
single field ">msg" at arch/powerpc/platforms/powernv/opal-prd.c:355 
(size 4)
[Wed Nov 15 14:01:07 2023] WARNING: CPU: 5 PID: 379 at 
arch/powerpc/platforms/powernv/opal-prd.c:355 0xc00800640b1c
[Wed Nov 15 14:01:07 2023] Modules linked in: i2c_dev loop vhost_net vhost 
vhost_iotlb tap kvm_hv kvm bridge rpcsec_gss_krb5 auth_rpcgss tun nfsv4 
dns_resolver nfs lockd grace sunrpc fscache netfs cfg80211 rfkill 8021q garp 
mrp stp llc nft_masq nft_chain_nat nft_reject_inet nf_reject_ipv4 
nf_reject_ipv6 nft_reject nft_ct binfmt_misc nbd wireguard 
libcurve25519_generic ip6_udp_tunnel udp_tunnel nft_nat nf_tables nfnetlink 
nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 at24 ast i2c_algo_bit 
drm_shmem_helper joydev ftdi_sio crct10dif_vpmsum onboard_usb_hub ofpart 
drm_kms_helper ipmi_powernv rtc_opal ipmi_devintf powernv_flash 
ipmi_msghandler mtd opal_prd i2c_opal vmx_crypto nvme crc32c_vpmsum tg3 
nvme_core ixgbe nvme_common mdio
[Wed Nov 15 14:01:07 2023] CPU: 5 PID: 379 Comm: kopald Not tainted 
6.5.9-gentoo-dist #1
[Wed Nov 15 14:01:07 2023] Hardware name: T2P9S01 REV 1.01 POWER9 0x4e1203 
opal:skiboot-9858186 PowerNV
[Wed Nov 15 14:01:07 2023] NIP:  c00800640b1c LR: c00800640b18 CTR: 

[Wed Nov 15 14:01:07 2023] REGS: ce2339b0 TRAP: 0700   Not tainted  
(6.5.9-gentoo-dist)
[Wed Nov 15 14:01:07 2023] MSR:  90021033   CR: 
4400  XER: 

[Wed Nov 15 14:01:07 2023] CFAR: c0152b10 IRQMASK: 1
   GPR00: c00800640b18 ce233c50 
c00800668100 0086
   GPR04: 7fff ce233a10 
ce233a08 001ef74d
   GPR08: 0027 c01ef9626d10 
0001 4400
   GPR12: 20646c6569662065 c01fff7fb400 
c01900e8 ce919540
   GPR16:   
 
   GPR20:   
 
   GPR24: ce959de0 0006 
 c00800660290
   GPR28: c7498410 0020 
ce959de8 c7498400

[Wed Nov 15 14:01:07 2023] NIP [c00800640b1c] 0xc00800640b1c
[Wed Nov 15 14:01:07 2023] LR [c00800640b18] 0xc00800640b18
[Wed Nov 15 14:01:07 2023] Call Trace:
[Wed Nov 15 14:01:07 2023] [ce233c50] [c00800640b18] 
0xc00800640b18 (unreliable)
[Wed Nov 15 14:01:07 2023] [ce233cd0] [c0192dd0] 
notifier_call_chain+0xc0/0x1b0
[Wed Nov 15 14:01:07 2023] [ce233d30] [c0192eec] 
atomic_notifier_call_chain+0x2c/0x40
[Wed Nov 15 14:01:07 2023] [ce233d50] [c00cec44] 
opal_message_notify+0xf4/0x2a0
[Wed Nov 15 14:01:07 2023] [ce233de0] [c0206d58] 

[PATCH 2/3] modpost: Extended modversion support

2023-11-15 Thread Matthew Maurer
Adds a new format for modversions which stores each field in a separate
elf section. This initially adds support for variable length names, but
could later be used to add additional fields to modversions in a
backwards compatible way if needed.

Adding support for variable length names makes it possible to enable
MODVERSIONS and RUST at the same time.

Signed-off-by: Matthew Maurer 
---
 arch/powerpc/kernel/module_64.c | 24 +-
 init/Kconfig|  1 -
 kernel/module/internal.h| 16 ++-
 kernel/module/main.c|  9 +++-
 kernel/module/version.c | 77 +
 scripts/mod/modpost.c   | 33 --
 6 files changed, 151 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 7112adc597a8..2582353a2048 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -355,6 +355,24 @@ static void dedotify_versions(struct modversion_info *vers,
}
 }
 
+static void dedotify_ext_version_names(char *str_seq, unsigned long size)
+{
+   unsigned long out = 0;
+   unsigned long in;
+   char last = '\0';
+
+   for (in = 0; in < size; in++) {
+   if (last == '\0')
+   /* Skip all leading dots */
+   if (str_seq[in] == '.')
+   continue;
+   last = str_seq[in];
+   str_seq[out++] = last;
+   }
+   /* Zero the trailing portion of the names table for robustness */
+   bzero(_seq[out], size - out);
+}
+
 /*
  * Undefined symbols which refer to .funcname, hack to funcname. Make .TOC.
  * seem to be defined (value set later).
@@ -424,10 +442,12 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
me->arch.toc_section = i;
if (sechdrs[i].sh_addralign < 8)
sechdrs[i].sh_addralign = 8;
-   }
-   else if (strcmp(secstrings+sechdrs[i].sh_name,"__versions")==0)
+   } else if (strcmp(secstrings + sechdrs[i].sh_name, 
"__versions") == 0)
dedotify_versions((void *)hdr + sechdrs[i].sh_offset,
  sechdrs[i].sh_size);
+   else if (strcmp(secstrings + sechdrs[i].sh_name, 
"__version_ext_names") == 0)
+   dedotify_ext_version_names((void *)hdr + 
sechdrs[i].sh_offset,
+  sechdrs[i].sh_size);
 
if (sechdrs[i].sh_type == SHT_SYMTAB)
dedotify((void *)hdr + sechdrs[i].sh_offset,
diff --git a/init/Kconfig b/init/Kconfig
index 9ffb103fc927..6cac5b4db8f6 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1885,7 +1885,6 @@ config RUST
bool "Rust support"
depends on HAVE_RUST
depends on RUST_IS_AVAILABLE
-   depends on !MODVERSIONS
depends on !GCC_PLUGINS
depends on !RANDSTRUCT
depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE
diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index c8b7b4dcf782..0c188c96a045 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -80,7 +80,7 @@ struct load_info {
unsigned int used_pages;
 #endif
struct {
-   unsigned int sym, str, mod, vers, info, pcpu;
+   unsigned int sym, str, mod, vers, info, pcpu, vers_ext_crc, 
vers_ext_name;
} index;
 };
 
@@ -384,6 +384,20 @@ void module_layout(struct module *mod, struct 
modversion_info *ver, struct kerne
   struct kernel_symbol *ks, struct tracepoint * const *tp);
 int check_modstruct_version(const struct load_info *info, struct module *mod);
 int same_magic(const char *amagic, const char *bmagic, bool has_crcs);
+struct modversion_info_ext_s32 {
+   const s32 *value;
+   const s32 *end;
+};
+struct modversion_info_ext_string {
+   const char *value;
+   const char *end;
+};
+struct modversion_info_ext {
+   struct modversion_info_ext_s32 crc;
+   struct modversion_info_ext_string name;
+};
+ssize_t modversion_ext_start(const struct load_info *info, struct 
modversion_info_ext *ver);
+int modversion_ext_advance(struct modversion_info_ext *ver);
 #else /* !CONFIG_MODVERSIONS */
 static inline int check_version(const struct load_info *info,
const char *symname,
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 98fedfdb8db5..e69b2ae46161 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -1886,10 +1886,15 @@ static int elf_validity_cache_copy(struct load_info 
*info, int flags)
if (!info->name)
info->name = info->mod->name;
 
-   if (flags & MODULE_INIT_IGNORE_MODVERSIONS)
+   if (flags & MODULE_INIT_IGNORE_MODVERSIONS) {
info->index.vers = 0; /* Pretend no __versions section! */
-   else
+

Re: [PATCH 2/7] kexec_file: print out debugging message if required

2023-11-15 Thread kernel test robot
Hi Baoquan,

kernel test robot noticed the following build errors:

[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on tip/x86/core powerpc/next powerpc/fixes linus/master 
v6.7-rc1 next-20231115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/kexec_file-add-kexec_file-flag-to-control-debug-printing/20231114-234003
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git 
for-next/core
patch link:
https://lore.kernel.org/r/20231114153253.241262-3-bhe%40redhat.com
patch subject: [PATCH 2/7] kexec_file: print out debugging message if required
config: hexagon-comet_defconfig 
(https://download.01.org/0day-ci/archive/20231116/202311160431.bxpc7no9-...@intel.com/config)
compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git 
ae42196bc493ffe877a7e3dff8be32035dea4d07)
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231116/202311160431.bxpc7no9-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202311160431.bxpc7no9-...@intel.com/

All errors (new ones prefixed by >>):

   In file included from kernel/crash_core.c:13:
   In file included from include/linux/kexec.h:19:
   In file included from arch/hexagon/include/asm/io.h:337:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   val = __raw_readb(PCI_IOBASE + addr);
 ~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
   ~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from 
macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
 ^
   In file included from kernel/crash_core.c:13:
   In file included from include/linux/kexec.h:19:
   In file included from arch/hexagon/include/asm/io.h:337:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
   ~~ ^
   include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from 
macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
 ^
   In file included from kernel/crash_core.c:13:
   In file included from include/linux/kexec.h:19:
   In file included from arch/hexagon/include/asm/io.h:337:
   include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   __raw_writeb(value, PCI_IOBASE + addr);
   ~~ ^
   include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
 ~~ ^
   include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
 ~~ ^
>> kernel/crash_core.c:412:3: error: call to undeclared function 
>> 'kexec_dprintk'; ISO C99 and later do not support implicit function 
>> declarations [-Wimplicit-function-declaration]
   kexec_dprintk("Crash PT_LOAD ELF header. phdr=%p 
vaddr=0x%llx, paddr=0x%llx, "
   ^
   6 warnings and 1 error generated.


vim +/kexec_dprintk +412 kernel/crash_core.c

   323  
   324  int crash_prepare_elf64_headers(struct crash_mem *mem, int 
need_kernel_map,
   325void **addr, unsigned long *sz)
   326  {
   327  Elf64_Ehdr *ehdr;
   328  Elf64_Phdr *phdr;
   329  unsigned long nr_cpus = num_possible_cpus(), nr_phdr, elf_sz;
   330  unsigned char *buf;
   331  unsigned int cpu, i;
   332  unsigned long long notes_addr;
   333  unsigned long mstart, mend;
   334  
   335  /* extra phdr

Re: [PATCH 2/3] powerpc/pseries/memhp: Remove unbalanced dlpar_release_drc() call

2023-11-15 Thread Nick Child

Hi Nathan,
Patches 1 and 3 LGTM

Regarding this patch, dlpar_memory_remove_by_count() calls 
dlpar_add_lmb() and does not free drc on add error.

dlpar_add_lmb() is called here in error recovery so probably
not a big deal.

This is all new code to me but it looks like if the requested
number of lmbs cannot be removed then it attempts to add back
the ones that were successfully removed. So if you cannot add
an lmb that WAS successfully removed, it seems sane to also
release the drc.


On 11/14/23 11:01, Nathan Lynch via B4 Relay wrote:

From: Nathan Lynch 

Callers of dlpar_add_lmb() are responsible for first acquiring the DRC
and releasing it if dlpar_add_lmb() fails.

However, dlpar_add_lmb() performs a dlpar_release_drc() in one error
branch.  There is no corresponding dlpar_acquire_drc() in the
function, nor is there any stated justification. None of the other
error paths in dlpar_add_lmb() release the DRC.

This is a potential source of redundant attempts to release DRCs,
which is likely benign, but is confusing and inconsistent. Remove it.

Signed-off-by: Nathan Lynch 
---
  arch/powerpc/platforms/pseries/hotplug-memory.c | 1 -
  1 file changed, 1 deletion(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 6f2eebae7bee..ba883c1b9f6d 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -575,7 +575,6 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
  
  	rc = update_lmb_associativity_index(lmb);

if (rc) {
-   dlpar_release_drc(lmb->drc_index);
return rc;
}
  



Re: [PATCH 4/7] kexec_file, arm64: print out debugging message if required

2023-11-15 Thread kernel test robot
Hi Baoquan,

kernel test robot noticed the following build warnings:

[auto build test WARNING on arm64/for-next/core]
[also build test WARNING on tip/x86/core powerpc/next powerpc/fixes 
linus/master v6.7-rc1 next-20231115]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/kexec_file-add-kexec_file-flag-to-control-debug-printing/20231114-234003
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git 
for-next/core
patch link:
https://lore.kernel.org/r/20231114153253.241262-5-bhe%40redhat.com
patch subject: [PATCH 4/7] kexec_file, arm64: print out debugging message if 
required
config: arm64-randconfig-001-20231115 
(https://download.01.org/0day-ci/archive/20231116/202311160022.qm6xjysy-...@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20231116/202311160022.qm6xjysy-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot 
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202311160022.qm6xjysy-...@intel.com/

All warnings (new ones prefixed by >>):

   arch/arm64/kernel/machine_kexec.c: In function '_kexec_image_info':
>> arch/arm64/kernel/machine_kexec.c:35:23: warning: unused variable 'i' 
>> [-Wunused-variable]
  35 | unsigned long i;
 |   ^


vim +/i +35 arch/arm64/kernel/machine_kexec.c

d28f6df1305a86 Geoff Levand 2016-06-23  27  
221f2c770e10d3 Geoff Levand 2016-06-23  28  /**
221f2c770e10d3 Geoff Levand 2016-06-23  29   * kexec_image_info - For debugging 
output.
221f2c770e10d3 Geoff Levand 2016-06-23  30   */
221f2c770e10d3 Geoff Levand 2016-06-23  31  #define kexec_image_info(_i) 
_kexec_image_info(__func__, __LINE__, _i)
221f2c770e10d3 Geoff Levand 2016-06-23  32  static void _kexec_image_info(const 
char *func, int line,
221f2c770e10d3 Geoff Levand 2016-06-23  33  const struct kimage *kimage)
221f2c770e10d3 Geoff Levand 2016-06-23  34  {
221f2c770e10d3 Geoff Levand 2016-06-23 @35  unsigned long i;
221f2c770e10d3 Geoff Levand 2016-06-23  36  
f24d07b8c8e272 Baoquan He   2023-11-14  37  kexec_dprintk("%s:%d:\n", func, 
line);
f24d07b8c8e272 Baoquan He   2023-11-14  38  kexec_dprintk("  kexec kimage 
info:\n");
f24d07b8c8e272 Baoquan He   2023-11-14  39  kexec_dprintk("type:
%d\n", kimage->type);
f24d07b8c8e272 Baoquan He   2023-11-14  40  kexec_dprintk("head:
%lx\n", kimage->head);
f24d07b8c8e272 Baoquan He   2023-11-14  41  kexec_dprintk("kern_reloc: 
%pa\n", >arch.kern_reloc);
f24d07b8c8e272 Baoquan He   2023-11-14  42  kexec_dprintk("el2_vectors: 
%pa\n", >arch.el2_vectors);
221f2c770e10d3 Geoff Levand 2016-06-23  43  }
221f2c770e10d3 Geoff Levand 2016-06-23  44  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


[PATCH v9 23/27] net: wan: framer: Add support for the Lantiq PEF2256 framer

2023-11-15 Thread Herve Codina
The Lantiq PEF2256 is a framer and line interface component designed to
fulfill all required interfacing between an analog E1/T1/J1 line and the
digital PCM system highway/H.100 bus.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
Reviewed-by: Linus Walleij 
Acked-by: Jakub Kicinski 
---
 drivers/net/wan/framer/Kconfig|  16 +
 drivers/net/wan/framer/Makefile   |   1 +
 drivers/net/wan/framer/pef2256/Makefile   |   8 +
 drivers/net/wan/framer/pef2256/pef2256-regs.h | 250 +
 drivers/net/wan/framer/pef2256/pef2256.c  | 880 ++
 include/linux/framer/pef2256.h|  31 +
 6 files changed, 1186 insertions(+)
 create mode 100644 drivers/net/wan/framer/pef2256/Makefile
 create mode 100644 drivers/net/wan/framer/pef2256/pef2256-regs.h
 create mode 100644 drivers/net/wan/framer/pef2256/pef2256.c
 create mode 100644 include/linux/framer/pef2256.h

diff --git a/drivers/net/wan/framer/Kconfig b/drivers/net/wan/framer/Kconfig
index 57fe7ba6aa37..d85a9d416b3b 100644
--- a/drivers/net/wan/framer/Kconfig
+++ b/drivers/net/wan/framer/Kconfig
@@ -22,4 +22,20 @@ if FRAMER
 config GENERIC_FRAMER
bool
 
+config FRAMER_PEF2256
+   tristate "Lantiq PEF2256"
+   depends on OF
+   select GENERIC_FRAMER
+   select MFD_CORE
+   select REGMAP_MMIO
+   help
+ Enable support for the Lantiq PEF2256 (FALC56) framer.
+ The PEF2256 is a framer and line interface between analog E1/T1/J1
+ line and a digital PCM bus.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called framer-pef2256.
+
 endif # FRAMER
diff --git a/drivers/net/wan/framer/Makefile b/drivers/net/wan/framer/Makefile
index 78dbd8e563d0..3403f2b14534 100644
--- a/drivers/net/wan/framer/Makefile
+++ b/drivers/net/wan/framer/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-$(CONFIG_GENERIC_FRAMER)   += framer-core.o
+obj-$(CONFIG_FRAMER_PEF2256)   += pef2256/
diff --git a/drivers/net/wan/framer/pef2256/Makefile 
b/drivers/net/wan/framer/pef2256/Makefile
new file mode 100644
index ..f4d1208dd8a4
--- /dev/null
+++ b/drivers/net/wan/framer/pef2256/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the pef2256 driver.
+#
+
+obj-$(CONFIG_FRAMER_PEF2256)   += framer-pef2256.o
+
+framer-pef2256-objs:= pef2256.o
diff --git a/drivers/net/wan/framer/pef2256/pef2256-regs.h 
b/drivers/net/wan/framer/pef2256/pef2256-regs.h
new file mode 100644
index ..5d3183c91714
--- /dev/null
+++ b/drivers/net/wan/framer/pef2256/pef2256-regs.h
@@ -0,0 +1,250 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * PEF2256 registers definition
+ *
+ * Copyright 2023 CS GROUP France
+ *
+ * Author: Herve Codina 
+ */
+#ifndef __PEF2256_REGS_H__
+#define __PEF2256_REGS_H__
+
+#include "linux/bitfield.h"
+
+/* Command Register */
+#define PEF2256_CMDR   0x02
+#define PEF2256_CMDR_RRES  BIT(6)
+#define PEF2256_CMDR_XRES  BIT(4)
+#define PEF2256_CMDR_SRES  BIT(0)
+
+/* Interrupt Mask Register 0..5 */
+#define PEF2256_IMR0   0x14
+#define PEF2256_IMR1   0x15
+#define PEF2256_IMR2   0x16
+#define PEF2256_IMR3   0x17
+#define PEF2256_IMR4   0x18
+#define PEF2256_IMR5   0x19
+
+/* Framer Mode Register 0 */
+#define PEF2256_FMR0   0x1C
+#define PEF2256_FMR0_XC_MASK   GENMASK(7, 6)
+#define PEF2256_FMR0_XC_NRZFIELD_PREP_CONST(PEF2256_FMR0_XC_MASK, 0x0)
+#define PEF2256_FMR0_XC_CMIFIELD_PREP_CONST(PEF2256_FMR0_XC_MASK, 0x1)
+#define PEF2256_FMR0_XC_AMIFIELD_PREP_CONST(PEF2256_FMR0_XC_MASK, 0x2)
+#define PEF2256_FMR0_XC_HDB3   FIELD_PREP_CONST(PEF2256_FMR0_XC_MASK, 0x3)
+#define PEF2256_FMR0_RC_MASK   GENMASK(5, 4)
+#define PEF2256_FMR0_RC_NRZFIELD_PREP_CONST(PEF2256_FMR0_RC_MASK, 0x0)
+#define PEF2256_FMR0_RC_CMIFIELD_PREP_CONST(PEF2256_FMR0_RC_MASK, 0x1)
+#define PEF2256_FMR0_RC_AMIFIELD_PREP_CONST(PEF2256_FMR0_RC_MASK, 0x2)
+#define PEF2256_FMR0_RC_HDB3   FIELD_PREP_CONST(PEF2256_FMR0_RC_MASK, 0x3)
+
+/* Framer Mode Register 1 */
+#define PEF2256_FMR1   0x1D
+#define PEF2256_FMR1_XFS   BIT(3)
+#define PEF2256_FMR1_ECM   BIT(2)
+/* SSD is defined on 2 bits. The other bit is on SIC1 register */
+#define PEF2256_FMR1_SSD_MASK  GENMASK(1, 1)
+#define PEF2256_FMR1_SSD_2048  FIELD_PREP_CONST(PEF2256_FMR1_SSD_MASK, 0x0)
+#define PEF2256_FMR1_SSD_4096  FIELD_PREP_CONST(PEF2256_FMR1_SSD_MASK, 0x1)
+#define PEF2256_FMR1_SSD_8192  FIELD_PREP_CONST(PEF2256_FMR1_SSD_MASK, 0x0)
+#define PEF2256_FMR1_SSD_16384 FIELD_PREP_CONST(PEF2256_FMR1_SSD_MASK, 0x1)
+
+/* Framer Mode Register 2 */
+#define PEF2256_FMR2 0x1E
+#define PEF2256_FMR2_RFS_MASKGENMASK(7, 6)
+#define PEF2256_FMR2_RFS_DOUBLEFRAME 
FIELD_PREP_CONST(PEF2256_FMR2_RFS_MASK, 0x0)
+#define PEF2256_FMR2_RFS_CRC4_MULTIFRAME  

[PATCH v9 21/27] net: wan: Add framer framework support

2023-11-15 Thread Herve Codina
A framer is a component in charge of an E1/T1 line interface.
Connected usually to a TDM bus, it converts TDM frames to/from E1/T1
frames. It also provides information related to the E1/T1 line.

The framer framework provides a set of APIs for the framer drivers
(framer provider) to create/destroy a framer and APIs for the framer
users (framer consumer) to obtain a reference to the framer, and
use the framer.

This basic implementation provides a framer abstraction for:
 - power on/off the framer
 - get the framer status (line state)
 - be notified on framer status changes
 - get/set the framer configuration

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
Acked-by: Jakub Kicinski 
---
 drivers/net/wan/Kconfig|   2 +
 drivers/net/wan/Makefile   |   2 +
 drivers/net/wan/framer/Kconfig |  25 +
 drivers/net/wan/framer/Makefile|   6 +
 drivers/net/wan/framer/framer-core.c   | 882 +
 include/linux/framer/framer-provider.h | 194 ++
 include/linux/framer/framer.h  | 205 ++
 7 files changed, 1316 insertions(+)
 create mode 100644 drivers/net/wan/framer/Kconfig
 create mode 100644 drivers/net/wan/framer/Makefile
 create mode 100644 drivers/net/wan/framer/framer-core.c
 create mode 100644 include/linux/framer/framer-provider.h
 create mode 100644 include/linux/framer/framer.h

diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 8de99f4b647b..31ab2136cdf1 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -95,6 +95,8 @@ config HDLC_X25
 comment "X.25/LAPB support is disabled"
depends on HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
 
+source "drivers/net/wan/framer/Kconfig"
+
 config PCI200SYN
tristate "Goramo PCI200SYN support"
depends on HDLC && PCI
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index f338f4830626..00e9b7ee1e01 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -14,6 +14,8 @@ obj-$(CONFIG_HDLC_FR) += hdlc_fr.o
 obj-$(CONFIG_HDLC_PPP) += hdlc_ppp.o
 obj-$(CONFIG_HDLC_X25) += hdlc_x25.o
 
+obj-y  += framer/
+
 obj-$(CONFIG_FARSYNC)  += farsync.o
 
 obj-$(CONFIG_LAPBETHER)+= lapbether.o
diff --git a/drivers/net/wan/framer/Kconfig b/drivers/net/wan/framer/Kconfig
new file mode 100644
index ..57fe7ba6aa37
--- /dev/null
+++ b/drivers/net/wan/framer/Kconfig
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# FRAMER
+#
+
+menuconfig FRAMER
+   tristate "Framer Subsystem"
+   help
+ A framer is a component in charge of an E1/T1 line interface.
+ Connected usually to a TDM bus, it converts TDM frames to/from E1/T1
+ frames. It also provides information related to the E1/T1 line.
+ Used with HDLC, the network can be reached through the E1/T1 line.
+
+ This framework is designed to provide a generic interface for framer
+ devices present in the kernel. This layer will have the generic
+ API by which framer drivers can create framer using the framer
+ framework and framer users can obtain reference to the framer.
+ All the users of this framework should select this config.
+
+if FRAMER
+
+config GENERIC_FRAMER
+   bool
+
+endif # FRAMER
diff --git a/drivers/net/wan/framer/Makefile b/drivers/net/wan/framer/Makefile
new file mode 100644
index ..78dbd8e563d0
--- /dev/null
+++ b/drivers/net/wan/framer/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the framer drivers.
+#
+
+obj-$(CONFIG_GENERIC_FRAMER)   += framer-core.o
diff --git a/drivers/net/wan/framer/framer-core.c 
b/drivers/net/wan/framer/framer-core.c
new file mode 100644
index ..c04dc88bda6c
--- /dev/null
+++ b/drivers/net/wan/framer/framer-core.c
@@ -0,0 +1,882 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Generic Framer framework.
+ *
+ * Copyright 2023 CS GROUP France
+ *
+ * Author: Herve Codina 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static struct class *framer_class;
+static DEFINE_MUTEX(framer_provider_mutex);
+static LIST_HEAD(framer_provider_list);
+static DEFINE_IDA(framer_ida);
+
+#define dev_to_framer(a)   (container_of((a), struct framer, dev))
+
+int framer_pm_runtime_get(struct framer *framer)
+{
+   int ret;
+
+   if (!pm_runtime_enabled(>dev))
+   return -EOPNOTSUPP;
+
+   ret = pm_runtime_get(>dev);
+   if (ret < 0 && ret != -EINPROGRESS)
+   pm_runtime_put_noidle(>dev);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(framer_pm_runtime_get);
+
+int framer_pm_runtime_get_sync(struct framer *framer)
+{
+   int ret;
+
+   if (!pm_runtime_enabled(>dev))
+   return -EOPNOTSUPP;
+
+   ret = pm_runtime_get_sync(>dev);
+   if (ret < 0)
+   

[PATCH v9 19/27] soc: fsl: cpm1: qmc: Introduce functions to change timeslots at runtime

2023-11-15 Thread Herve Codina
Introduce qmc_chan_{get,set}_ts_info() function to allow timeslots
modification at runtime.

The modification is provided using qmc_chan_set_ts_info() and will be
applied on next qmc_chan_start().
qmc_chan_set_ts_info() must be called with the channel rx and/or tx
stopped.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 51 
 include/soc/fsl/qe/qmc.h | 10 
 2 files changed, 61 insertions(+)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index 73903ce31695..79fe79b9464f 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -290,6 +290,57 @@ int qmc_chan_get_info(struct qmc_chan *chan, struct 
qmc_chan_info *info)
 }
 EXPORT_SYMBOL(qmc_chan_get_info);
 
+int qmc_chan_get_ts_info(struct qmc_chan *chan, struct qmc_chan_ts_info 
*ts_info)
+{
+   unsigned long flags;
+
+   spin_lock_irqsave(>ts_lock, flags);
+
+   ts_info->rx_ts_mask_avail = chan->rx_ts_mask_avail;
+   ts_info->tx_ts_mask_avail = chan->tx_ts_mask_avail;
+   ts_info->rx_ts_mask = chan->rx_ts_mask;
+   ts_info->tx_ts_mask = chan->tx_ts_mask;
+
+   spin_unlock_irqrestore(>ts_lock, flags);
+
+   return 0;
+}
+EXPORT_SYMBOL(qmc_chan_get_ts_info);
+
+int qmc_chan_set_ts_info(struct qmc_chan *chan, const struct qmc_chan_ts_info 
*ts_info)
+{
+   unsigned long flags;
+   int ret;
+
+   /* Only a subset of available timeslots is allowed */
+   if ((ts_info->rx_ts_mask & chan->rx_ts_mask_avail) != 
ts_info->rx_ts_mask)
+   return -EINVAL;
+   if ((ts_info->tx_ts_mask & chan->tx_ts_mask_avail) != 
ts_info->tx_ts_mask)
+   return -EINVAL;
+
+   /* In case of common rx/tx table, rx/tx masks must be identical */
+   if (chan->qmc->is_tsa_64rxtx) {
+   if (ts_info->rx_ts_mask != ts_info->tx_ts_mask)
+   return -EINVAL;
+   }
+
+   spin_lock_irqsave(>ts_lock, flags);
+
+   if ((chan->tx_ts_mask != ts_info->tx_ts_mask && !chan->is_tx_stopped) ||
+   (chan->rx_ts_mask != ts_info->rx_ts_mask && !chan->is_rx_stopped)) {
+   dev_err(chan->qmc->dev, "Channel rx and/or tx not stopped\n");
+   ret = -EBUSY;
+   } else {
+   chan->tx_ts_mask = ts_info->tx_ts_mask;
+   chan->rx_ts_mask = ts_info->rx_ts_mask;
+   ret = 0;
+   }
+   spin_unlock_irqrestore(>ts_lock, flags);
+
+   return ret;
+}
+EXPORT_SYMBOL(qmc_chan_set_ts_info);
+
 int qmc_chan_set_param(struct qmc_chan *chan, const struct qmc_chan_param 
*param)
 {
if (param->mode != chan->mode)
diff --git a/include/soc/fsl/qe/qmc.h b/include/soc/fsl/qe/qmc.h
index 166484bb4294..2a333fc1ea81 100644
--- a/include/soc/fsl/qe/qmc.h
+++ b/include/soc/fsl/qe/qmc.h
@@ -40,6 +40,16 @@ struct qmc_chan_info {
 
 int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info);
 
+struct qmc_chan_ts_info {
+   u64 rx_ts_mask_avail;
+   u64 tx_ts_mask_avail;
+   u64 rx_ts_mask;
+   u64 tx_ts_mask;
+};
+
+int qmc_chan_get_ts_info(struct qmc_chan *chan, struct qmc_chan_ts_info 
*ts_info);
+int qmc_chan_set_ts_info(struct qmc_chan *chan, const struct qmc_chan_ts_info 
*ts_info);
+
 struct qmc_chan_param {
enum qmc_mode mode;
union {
-- 
2.41.0



[PATCH v9 20/27] wan: qmc_hdlc: Add runtime timeslots changes support

2023-11-15 Thread Herve Codina
QMC channels support runtime timeslots changes but nothing is done at
the QMC HDLC driver to handle these changes.

Use existing IFACE ioctl in order to configure the timeslots to use.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
Acked-by: Jakub Kicinski 
---
 drivers/net/wan/fsl_qmc_hdlc.c | 169 -
 1 file changed, 168 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c
index 31b637ec8390..82019cd96365 100644
--- a/drivers/net/wan/fsl_qmc_hdlc.c
+++ b/drivers/net/wan/fsl_qmc_hdlc.c
@@ -32,6 +32,7 @@ struct qmc_hdlc {
struct qmc_hdlc_desc tx_descs[8];
unsigned int tx_out;
struct qmc_hdlc_desc rx_descs[4];
+   u32 slot_map;
 };
 
 static inline struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev)
@@ -202,6 +203,162 @@ static netdev_tx_t qmc_hdlc_xmit(struct sk_buff *skb, 
struct net_device *netdev)
return NETDEV_TX_OK;
 }
 
+static int qmc_hdlc_xlate_slot_map(struct qmc_hdlc *qmc_hdlc,
+  u32 slot_map, struct qmc_chan_ts_info 
*ts_info)
+{
+   u64 ts_mask_avail;
+   unsigned int bit;
+   unsigned int i;
+   u64 ts_mask;
+   u64 map;
+
+   /* Tx and Rx masks must be identical */
+   if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) {
+   dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch 
(0x%llx, 0x%llx)\n",
+   ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail);
+   return -EINVAL;
+   }
+
+   ts_mask_avail = ts_info->rx_ts_mask_avail;
+   ts_mask = 0;
+   map = slot_map;
+   bit = 0;
+   for (i = 0; i < 64; i++) {
+   if (ts_mask_avail & BIT_ULL(i)) {
+   if (map & BIT_ULL(bit))
+   ts_mask |= BIT_ULL(i);
+   bit++;
+   }
+   }
+
+   if (hweight64(ts_mask) != hweight64(map)) {
+   dev_err(qmc_hdlc->dev, "Cannot translate timeslots 0x%llx -> 
(0x%llx,0x%llx)\n",
+   map, ts_mask_avail, ts_mask);
+   return -EINVAL;
+   }
+
+   ts_info->tx_ts_mask = ts_mask;
+   ts_info->rx_ts_mask = ts_mask;
+   return 0;
+}
+
+static int qmc_hdlc_xlate_ts_info(struct qmc_hdlc *qmc_hdlc,
+ const struct qmc_chan_ts_info *ts_info, u32 
*slot_map)
+{
+   u64 ts_mask_avail;
+   unsigned int bit;
+   unsigned int i;
+   u64 ts_mask;
+   u64 map;
+
+   /* Tx and Rx masks must be identical */
+   if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) {
+   dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch 
(0x%llx, 0x%llx)\n",
+   ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail);
+   return -EINVAL;
+   }
+   if (ts_info->rx_ts_mask != ts_info->tx_ts_mask) {
+   dev_err(qmc_hdlc->dev, "tx and rx timeslots mismatch (0x%llx, 
0x%llx)\n",
+   ts_info->rx_ts_mask, ts_info->tx_ts_mask);
+   return -EINVAL;
+   }
+
+   ts_mask_avail = ts_info->rx_ts_mask_avail;
+   ts_mask = ts_info->rx_ts_mask;
+   map = 0;
+   bit = 0;
+   for (i = 0; i < 64; i++) {
+   if (ts_mask_avail & BIT_ULL(i)) {
+   if (ts_mask & BIT_ULL(i))
+   map |= BIT_ULL(bit);
+   bit++;
+   }
+   }
+
+   if (hweight64(ts_mask) != hweight64(map)) {
+   dev_err(qmc_hdlc->dev, "Cannot translate timeslots 
(0x%llx,0x%llx) -> 0x%llx\n",
+   ts_mask_avail, ts_mask, map);
+   return -EINVAL;
+   }
+
+   if (map >= BIT_ULL(32)) {
+   dev_err(qmc_hdlc->dev, "Slot map out of 32bit (0x%llx,0x%llx) 
-> 0x%llx\n",
+   ts_mask_avail, ts_mask, map);
+   return -EINVAL;
+   }
+
+   *slot_map = map;
+   return 0;
+}
+
+static int qmc_hdlc_set_iface(struct qmc_hdlc *qmc_hdlc, int if_iface, const 
te1_settings *te1)
+{
+   struct qmc_chan_ts_info ts_info;
+   int ret;
+
+   ret = qmc_chan_get_ts_info(qmc_hdlc->qmc_chan, _info);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "get QMC channel ts info failed %d\n", 
ret);
+   return ret;
+   }
+   ret = qmc_hdlc_xlate_slot_map(qmc_hdlc, te1->slot_map, _info);
+   if (ret)
+   return ret;
+
+   ret = qmc_chan_set_ts_info(qmc_hdlc->qmc_chan, _info);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "set QMC channel ts info failed %d\n", 
ret);
+   return ret;
+   }
+
+   qmc_hdlc->slot_map = te1->slot_map;
+
+   return 0;
+}
+
+static int qmc_hdlc_ioctl(struct net_device *netdev, struct if_settings *ifs)
+{
+   struct qmc_hdlc *qmc_hdlc = netdev_to_qmc_hdlc(netdev);
+   te1_settings 

[PATCH v9 27/27] net: wan: fsl_qmc_hdlc: Add framer support

2023-11-15 Thread Herve Codina
Add framer support in the fsl_qmc_hdlc driver in order to be able to
signal carrier changes to the network stack based on the framer status
Also use this framer to provide information related to the E1/T1 line
interface on IF_GET_IFACE and configure the line interface according to
IF_IFACE_{E1,T1} information.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/net/wan/fsl_qmc_hdlc.c | 239 -
 1 file changed, 235 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c
index 82019cd96365..9bfb506a90cd 100644
--- a/drivers/net/wan/fsl_qmc_hdlc.c
+++ b/drivers/net/wan/fsl_qmc_hdlc.c
@@ -8,6 +8,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -27,6 +28,9 @@ struct qmc_hdlc {
struct device *dev;
struct qmc_chan *qmc_chan;
struct net_device *netdev;
+   struct framer *framer;
+   spinlock_t carrier_lock; /* Protect carrier detection */
+   struct notifier_block nb;
bool is_crc32;
spinlock_t tx_lock; /* Protect tx descriptors */
struct qmc_hdlc_desc tx_descs[8];
@@ -40,6 +44,195 @@ static inline struct qmc_hdlc *netdev_to_qmc_hdlc(struct 
net_device *netdev)
return dev_to_hdlc(netdev)->priv;
 }
 
+static int qmc_hdlc_framer_set_carrier(struct qmc_hdlc *qmc_hdlc)
+{
+   struct framer_status framer_status;
+   unsigned long flags;
+   int ret;
+
+   if (!qmc_hdlc->framer)
+   return 0;
+
+   spin_lock_irqsave(_hdlc->carrier_lock, flags);
+
+   ret = framer_get_status(qmc_hdlc->framer, _status);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "get framer status failed (%d)\n", ret);
+   goto end;
+   }
+   if (framer_status.link_is_on)
+   netif_carrier_on(qmc_hdlc->netdev);
+   else
+   netif_carrier_off(qmc_hdlc->netdev);
+
+end:
+   spin_unlock_irqrestore(_hdlc->carrier_lock, flags);
+   return ret;
+}
+
+static int qmc_hdlc_framer_notifier(struct notifier_block *nb, unsigned long 
action,
+   void *data)
+{
+   struct qmc_hdlc *qmc_hdlc = container_of(nb, struct qmc_hdlc, nb);
+   int ret;
+
+   if (action != FRAMER_EVENT_STATUS)
+   return NOTIFY_DONE;
+
+   ret = qmc_hdlc_framer_set_carrier(qmc_hdlc);
+   return ret ? NOTIFY_DONE : NOTIFY_OK;
+}
+
+static int qmc_hdlc_framer_start(struct qmc_hdlc *qmc_hdlc)
+{
+   struct framer_status framer_status;
+   int ret;
+
+   if (!qmc_hdlc->framer)
+   return 0;
+
+   ret = framer_power_on(qmc_hdlc->framer);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "framer power-on failed (%d)\n", ret);
+   return ret;
+   }
+
+   /* Be sure that get_status is supported */
+   ret = framer_get_status(qmc_hdlc->framer, _status);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "get framer status failed (%d)\n", ret);
+   goto framer_power_off;
+   }
+
+   qmc_hdlc->nb.notifier_call = qmc_hdlc_framer_notifier;
+   ret = framer_notifier_register(qmc_hdlc->framer, _hdlc->nb);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "framer notifier register failed 
(%d)\n", ret);
+   goto framer_power_off;
+   }
+
+   return 0;
+
+framer_power_off:
+   framer_power_off(qmc_hdlc->framer);
+   return ret;
+}
+
+static void qmc_hdlc_framer_stop(struct qmc_hdlc *qmc_hdlc)
+{
+   if (!qmc_hdlc->framer)
+   return;
+
+   framer_notifier_unregister(qmc_hdlc->framer, _hdlc->nb);
+   framer_power_off(qmc_hdlc->framer);
+}
+
+static int qmc_hdlc_framer_set_iface(struct qmc_hdlc *qmc_hdlc, int if_iface,
+const te1_settings *te1)
+{
+   struct framer_config config;
+   int ret;
+
+   if (!qmc_hdlc->framer)
+   return 0;
+
+   ret = framer_get_config(qmc_hdlc->framer, );
+   if (ret)
+   return ret;
+
+   switch (if_iface) {
+   case IF_IFACE_E1:
+   config.iface = FRAMER_IFACE_E1;
+   break;
+   case IF_IFACE_T1:
+   config.iface = FRAMER_IFACE_T1;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   switch (te1->clock_type) {
+   case CLOCK_DEFAULT:
+   /* Keep current value */
+   break;
+   case CLOCK_EXT:
+   config.clock_type = FRAMER_CLOCK_EXT;
+   break;
+   case CLOCK_INT:
+   config.clock_type = FRAMER_CLOCK_INT;
+   break;
+   default:
+   return -EINVAL;
+   }
+   config.line_clock_rate = te1->clock_rate;
+
+   return framer_set_config(qmc_hdlc->framer, );
+}
+
+static int qmc_hdlc_framer_get_iface(struct qmc_hdlc *qmc_hdlc, int *if_iface, 
te1_settings *te1)
+{
+   struct framer_config config;
+   int 

[PATCH v9 25/27] MAINTAINERS: Add the Lantiq PEF2256 driver entry

2023-11-15 Thread Herve Codina
After contributing the driver, add myself as the maintainer for the
Lantiq PEF2256 driver.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 MAINTAINERS | 8 
 1 file changed, 8 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 82d9afa8c083..1d473ce403c4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12035,6 +12035,14 @@ S: Maintained
 F: arch/mips/lantiq
 F: drivers/soc/lantiq
 
+LANTIQ PEF2256 DRIVER
+M: Herve Codina 
+S: Maintained
+F: Documentation/devicetree/bindings/net/lantiq,pef2256.yaml
+F: drivers/net/wan/framer/pef2256/
+F: drivers/pinctrl/pinctrl-pef2256.c
+F: include/linux/framer/pef2256.h
+
 LASI 53c700 driver for PARISC
 M: "James E.J. Bottomley" 
 L: linux-s...@vger.kernel.org
-- 
2.41.0



[PATCH v9 22/27] dt-bindings: net: Add the Lantiq PEF2256 E1/T1/J1 framer

2023-11-15 Thread Herve Codina
The Lantiq PEF2256 is a framer and line interface component designed to
fulfill all required interfacing between an analog E1/T1/J1 line and the
digital PCM system highway/H.100 bus.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
Reviewed-by: Rob Herring 
---
 .../bindings/net/lantiq,pef2256.yaml  | 213 ++
 1 file changed, 213 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/lantiq,pef2256.yaml

diff --git a/Documentation/devicetree/bindings/net/lantiq,pef2256.yaml 
b/Documentation/devicetree/bindings/net/lantiq,pef2256.yaml
new file mode 100644
index ..7da8370e2468
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/lantiq,pef2256.yaml
@@ -0,0 +1,213 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/lantiq,pef2256.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Lantiq PEF2256
+
+maintainers:
+  - Herve Codina 
+
+description:
+  The Lantiq PEF2256, also known as Infineon PEF2256 or FALC56, is a framer and
+  line interface component designed to fulfill all required interfacing between
+  an analog E1/T1/J1 line and the digital PCM system highway/H.100 bus.
+
+properties:
+  compatible:
+items:
+  - const: lantiq,pef2256
+
+  reg:
+maxItems: 1
+
+  clocks:
+items:
+  - description: Master Clock
+  - description: System Clock Receive
+  - description: System Clock Transmit
+
+  clock-names:
+items:
+  - const: mclk
+  - const: sclkr
+  - const: sclkx
+
+  interrupts:
+maxItems: 1
+
+  reset-gpios:
+description:
+  GPIO used to reset the device.
+maxItems: 1
+
+  pinctrl:
+$ref: /schemas/pinctrl/pinctrl.yaml#
+additionalProperties: false
+
+patternProperties:
+  '-pins$':
+type: object
+$ref: /schemas/pinctrl/pinmux-node.yaml#
+additionalProperties: false
+
+properties:
+  pins:
+enum: [ RPA, RPB, RPC, RPD, XPA, XPB, XPC, XPD ]
+
+  function:
+enum: [ SYPR, RFM, RFMB, RSIGM, RSIG, DLR, FREEZE, RFSP, LOS,
+SYPX, XFMS, XSIG, TCLK, XMFB, XSIGM, DLX, XCLK, XLT,
+GPI, GPOH, GPOL ]
+
+required:
+  - pins
+  - function
+
+  lantiq,data-rate-bps:
+enum: [2048000, 4096000, 8192000, 16384000]
+default: 2048000
+description:
+  Data rate (bit per seconds) on the system highway.
+
+  lantiq,clock-falling-edge:
+$ref: /schemas/types.yaml#/definitions/flag
+description:
+  Data is sent on falling edge of the clock (and received on the rising
+  edge). If 'clock-falling-edge' is not present, data is sent on the
+  rising edge (and received on the falling edge).
+
+  lantiq,channel-phase:
+$ref: /schemas/types.yaml#/definitions/uint32
+enum: [0, 1, 2, 3, 4, 5, 6, 7]
+default: 0
+description: |
+  The pef2256 delivers a full frame (32 8-bit time-slots in E1 and 24 8-bit
+  time-slots 8 8-bit signaling in E1/J1) every 125us. This lead to a data
+  rate of 2048000 bit/s. When lantiq,data-rate-bps is more than 2048000
+  bit/s, the data (all 32 8-bit) present in the frame are interleave with
+  unused time-slots. The lantiq,channel-phase property allows to set the
+  correct alignment of the interleave mechanism.
+  For instance, suppose lantiq,data-rate-bps = 8192000 (ie 4*2048000), and
+  lantiq,channel-phase = 2, the interleave schema with unused time-slots
+  (nu) and used time-slots (XX) for TSi is
+nu nu XX nu nu nu XX nu nu nu XX nu
+<-- TSi --> <- TSi+1 -> <- TSi+2 ->
+  With lantiq,data-rate-bps = 8192000, and lantiq,channel-phase = 1, the
+  interleave schema is
+nu XX nu nu nu XX nu nu nu XX nu nu
+<-- TSi --> <- TSi+1 -> <- TSi+2 ->
+  With lantiq,data-rate-bps = 4096000 (ie 2*2048000), and
+  lantiq,channel-phase = 1, the interleave schema is
+nuXXnuXXnuXX
+<-- TSi --> <- TSi+1 -> <- TSi+2 ->
+
+patternProperties:
+  '^codec(-([0-9]|[1-2][0-9]|3[0-1]))?$':
+type: object
+$ref: /schemas/sound/dai-common.yaml
+unevaluatedProperties: false
+description:
+  Codec provided by the pef2256. This codec allows to use some of the PCM
+  system highway time-slots as audio channels to transport audio data over
+  the E1/T1/J1 lines.
+  The time-slots used by the codec must be set and so, the properties
+  'dai-tdm-slot-num', 'dai-tdm-slot-width', 'dai-tdm-slot-tx-mask' and
+  'dai-tdm-slot-rx-mask' must be present in the sound card node for
+  sub-nodes that involve the codec. The codec uses 8-bit time-slots.
+  'dai-tdm-tdm-slot-with' must be set to 8.
+  The tx and rx masks define the pef2256 time-slots assigned to the codec.
+
+properties:
+  compatible:
+const: lantiq,pef2256-codec
+
+  '#sound-dai-cells':

[PATCH v9 18/27] soc: fsl: cpm1: qmc: Remove timeslots handling from setup_chan()

2023-11-15 Thread Herve Codina
Timeslots setting is done at channel start() and stop().
There is no more need to do that during setup_chan().

Simply remove timeslot setting from setup_chan().

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 28 
 1 file changed, 28 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index e56aea5803bf..73903ce31695 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -723,30 +723,6 @@ static int qmc_chan_setup_tsa_rx(struct qmc_chan *chan, 
bool enable)
return qmc_chan_setup_tsa_32rx(chan, , enable);
 }
 
-static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable)
-{
-   struct tsa_serial_info info;
-   int ret;
-
-   /* Retrieve info from the TSA related serial */
-   ret = tsa_serial_get_info(chan->qmc->tsa_serial, );
-   if (ret)
-   return ret;
-
-   /*
-* Setup one common 64 entries table or two 32 entries (one for Tx
-* and one for Tx) according to assigned TS numbers.
-*/
-   if (chan->qmc->is_tsa_64rxtx)
-   return qmc_chan_setup_tsa_64rxtx(chan, , enable);
-
-   ret = qmc_chan_setup_tsa_32rx(chan, , enable);
-   if (ret)
-   return ret;
-
-   return qmc_chan_setup_tsa_32tx(chan, , enable);
-}
-
 static int qmc_chan_command(struct qmc_chan *chan, u8 qmc_opcode)
 {
return cpm_command(chan->id << 2, (qmc_opcode << 4) | 0x0E);
@@ -1323,10 +1299,6 @@ static int qmc_setup_chan(struct qmc *qmc, struct 
qmc_chan *chan)
 
chan->qmc = qmc;
 
-   ret = qmc_chan_setup_tsa(chan, true);
-   if (ret)
-   return ret;
-
/* Set channel specific parameter base address */
chan->s_param = qmc->dpram + (chan->id * 64);
/* 16 bd per channel (8 rx and 8 tx) */
-- 
2.41.0



[PATCH v9 24/27] pinctrl: Add support for the Lantic PEF2256 pinmux

2023-11-15 Thread Herve Codina
The Lantiq PEF2256 is a framer and line interface component designed to
fulfill all required interfacing between an analog E1/T1/J1 line and the
digital PCM system highway/H.100 bus.

This kind of component can be found in old telecommunication system.
It was used to digital transmission of many simultaneous telephone calls
by time-division multiplexing. Also using HDLC protocol, WAN networks
can be reached through the framer.

This pinmux support handles the pin muxing part (pins RP(A..D) and pins
XP(A..D)) of the PEF2256.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
Reviewed-by: Linus Walleij 
---
 drivers/pinctrl/Kconfig   |  15 ++
 drivers/pinctrl/Makefile  |   1 +
 drivers/pinctrl/pinctrl-pef2256.c | 358 ++
 3 files changed, 374 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-pef2256.c

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 1de4e1edede0..b11144bb448c 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -366,6 +366,21 @@ config PINCTRL_PALMAS
  open drain configuration for the Palmas series devices like
  TPS65913, TPS80036 etc.
 
+config PINCTRL_PEF2256
+   tristate "Lantiq PEF2256 (FALC56) pin controller driver"
+   depends on OF && FRAMER_PEF2256
+   select PINMUX
+   select PINCONF
+   select GENERIC_PINCONF
+   help
+ This option enables the pin controller support for the Lantiq PEF2256
+ framer, also known as FALC56.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called pinctrl-pef2256.
+
 config PINCTRL_PIC32
bool "Microchip PIC32 pin controller driver"
depends on OF
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 37575deb7a69..7ac5d59c83e7 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_PINCTRL_MICROCHIP_SGPIO) += 
pinctrl-microchip-sgpio.o
 obj-$(CONFIG_PINCTRL_MLXBF3)   += pinctrl-mlxbf3.o
 obj-$(CONFIG_PINCTRL_OCELOT)   += pinctrl-ocelot.o
 obj-$(CONFIG_PINCTRL_PALMAS)   += pinctrl-palmas.o
+obj-$(CONFIG_PINCTRL_PEF2256)  += pinctrl-pef2256.o
 obj-$(CONFIG_PINCTRL_PIC32)+= pinctrl-pic32.o
 obj-$(CONFIG_PINCTRL_PISTACHIO)+= pinctrl-pistachio.o
 obj-$(CONFIG_PINCTRL_RK805)+= pinctrl-rk805.o
diff --git a/drivers/pinctrl/pinctrl-pef2256.c 
b/drivers/pinctrl/pinctrl-pef2256.c
new file mode 100644
index ..868ea33bec3c
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-pef2256.c
@@ -0,0 +1,358 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PEF2256 also known as FALC56 driver
+ *
+ * Copyright 2023 CS GROUP France
+ *
+ * Author: Herve Codina 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Port Configuration 1..4 */
+#define PEF2256_PC1  0x80
+#define PEF2256_PC2  0x81
+#define PEF2256_PC3  0x82
+#define PEF2256_PC4  0x83
+#define PEF2256_12_PC_RPC_MASK   GENMASK(6, 4)
+#define PEF2256_12_PC_RPC_SYPR   FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x0)
+#define PEF2256_12_PC_RPC_RFMFIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x1)
+#define PEF2256_12_PC_RPC_RFMB   FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x2)
+#define PEF2256_12_PC_RPC_RSIGM  
FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x3)
+#define PEF2256_12_PC_RPC_RSIG   FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x4)
+#define PEF2256_12_PC_RPC_DLRFIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x5)
+#define PEF2256_12_PC_RPC_FREEZE  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x6)
+#define PEF2256_12_PC_RPC_RFSP   FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x7)
+#define PEF2256_12_PC_XPC_MASKGENMASK(4, 0)
+#define PEF2256_12_PC_XPC_SYPX   FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x0)
+#define PEF2256_12_PC_XPC_XFMS   FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x1)
+#define PEF2256_12_PC_XPC_XSIG   FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x2)
+#define PEF2256_12_PC_XPC_TCLK   FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x3)
+#define PEF2256_12_PC_XPC_XMFB   FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x4)
+#define PEF2256_12_PC_XPC_XSIGM  
FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x5)
+#define PEF2256_12_PC_XPC_DLXFIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x6)
+#define PEF2256_12_PC_XPC_XCLK   FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x7)
+#define PEF2256_12_PC_XPC_XLTFIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x8)
+#define PEF2256_2X_PC_RPC_MASK   GENMASK(7, 4)
+#define PEF2256_2X_PC_RPC_SYPR   FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x0)
+#define PEF2256_2X_PC_RPC_RFMFIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x1)
+#define PEF2256_2X_PC_RPC_RFMB   FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x2)
+#define PEF2256_2X_PC_RPC_RSIGM  
FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x3)
+#define PEF2256_2X_PC_RPC_RSIG   FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x4)

[PATCH v9 26/27] ASoC: codecs: Add support for the framer codec

2023-11-15 Thread Herve Codina
The framer codec interacts with a framer.
It allows to use some of the framer timeslots as audio channels to
transport audio data over the framer E1/T1/J1 lines.
It also reports line carrier detection events through the ALSA jack
detection feature.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 sound/soc/codecs/Kconfig|  15 ++
 sound/soc/codecs/Makefile   |   2 +
 sound/soc/codecs/framer-codec.c | 413 
 3 files changed, 430 insertions(+)
 create mode 100644 sound/soc/codecs/framer-codec.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 3429419ca694..f54dcaaebd10 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -114,6 +114,7 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_ES8328_I2C
imply SND_SOC_ES7134
imply SND_SOC_ES7241
+   imply SND_SOC_FRAMER
imply SND_SOC_GTM601
imply SND_SOC_HDAC_HDMI
imply SND_SOC_HDAC_HDA
@@ -1097,6 +1098,20 @@ config SND_SOC_ES8328_SPI
depends on SPI_MASTER
select SND_SOC_ES8328
 
+config SND_SOC_FRAMER
+   tristate "Framer codec"
+   depends on GENERIC_FRAMER
+   help
+ Enable support for the framer codec.
+ The framer codec uses the generic framer infrastructure to transport
+ some audio data over an analog E1/T1/J1 line.
+ This codec allows to use some of the time slots available on the TDM
+ bus on which the framer is connected to transport the audio data.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-soc-framer.
+
+
 config SND_SOC_GTM601
tristate 'GTM601 UMTS modem audio codec'
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 2078bb0d981e..0cbcbda7b5a4 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -121,6 +121,7 @@ snd-soc-es8326-objs := es8326.o
 snd-soc-es8328-objs := es8328.o
 snd-soc-es8328-i2c-objs := es8328-i2c.o
 snd-soc-es8328-spi-objs := es8328-spi.o
+snd-soc-framer-objs := framer-codec.o
 snd-soc-gtm601-objs := gtm601.o
 snd-soc-hdac-hdmi-objs := hdac_hdmi.o
 snd-soc-hdac-hda-objs := hdac_hda.o
@@ -510,6 +511,7 @@ obj-$(CONFIG_SND_SOC_ES8326)+= snd-soc-es8326.o
 obj-$(CONFIG_SND_SOC_ES8328)   += snd-soc-es8328.o
 obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
 obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o
+obj-$(CONFIG_SND_SOC_FRAMER)   += snd-soc-framer.o
 obj-$(CONFIG_SND_SOC_GTM601)+= snd-soc-gtm601.o
 obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o
 obj-$(CONFIG_SND_SOC_HDAC_HDA) += snd-soc-hdac-hda.o
diff --git a/sound/soc/codecs/framer-codec.c b/sound/soc/codecs/framer-codec.c
new file mode 100644
index ..e5fcde9ee308
--- /dev/null
+++ b/sound/soc/codecs/framer-codec.c
@@ -0,0 +1,413 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Framer ALSA SoC driver
+//
+// Copyright 2023 CS GROUP France
+//
+// Author: Herve Codina 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define FRAMER_NB_CHANNEL  32
+#define FRAMER_JACK_MASK (SND_JACK_LINEIN | SND_JACK_LINEOUT)
+
+struct framer_codec {
+   struct framer *framer;
+   struct device *dev;
+   struct snd_soc_jack jack;
+   struct notifier_block nb;
+   struct work_struct carrier_work;
+   int max_chan_playback;
+   int max_chan_capture;
+};
+
+static int framer_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int 
tx_mask,
+  unsigned int rx_mask, int slots, int width)
+{
+   struct framer_codec *framer = 
snd_soc_component_get_drvdata(dai->component);
+
+   switch (width) {
+   case 0:
+   /* Not set -> default 8 */
+   case 8:
+   break;
+   default:
+   dev_err(dai->dev, "tdm slot width %d not supported\n", width);
+   return -EINVAL;
+   }
+
+   framer->max_chan_playback = hweight32(tx_mask);
+   if (framer->max_chan_playback > FRAMER_NB_CHANNEL) {
+   dev_err(dai->dev, "too many tx slots defined (mask = 0x%x) 
supported max %d\n",
+   tx_mask, FRAMER_NB_CHANNEL);
+   return -EINVAL;
+   }
+
+   framer->max_chan_capture = hweight32(rx_mask);
+   if (framer->max_chan_capture > FRAMER_NB_CHANNEL) {
+   dev_err(dai->dev, "too many rx slots defined (mask = 0x%x) 
supported max %d\n",
+   rx_mask, FRAMER_NB_CHANNEL);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+/*
+ * The constraints for format/channel is to match with the number of 8bit
+ * time-slots available.
+ */
+static int framer_dai_hw_rule_channels_by_format(struct snd_soc_dai *dai,
+struct snd_pcm_hw_params 
*params,
+unsigned int nb_ts)
+{
+   struct 

[PATCH v9 17/27] soc: fsl: cpm1: qmc: Handle timeslot entries at channel start() and stop()

2023-11-15 Thread Herve Codina
In order to support runtime timeslot route changes, enable the
channel timeslot entries at channel start() and disable them at
channel stop().

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 175 ---
 1 file changed, 163 insertions(+), 12 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index e651b3bba1ca..e56aea5803bf 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -177,6 +177,7 @@ struct qmc_chan {
struct qmc *qmc;
void __iomem *s_param;
enum qmc_mode mode;
+   spinlock_t  ts_lock; /* Protect timeslots */
u64 tx_ts_mask_avail;
u64 tx_ts_mask;
u64 rx_ts_mask_avail;
@@ -265,6 +266,7 @@ static void qmc_setbits32(void __iomem *addr, u32 set)
 int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info)
 {
struct tsa_serial_info tsa_info;
+   unsigned long flags;
int ret;
 
/* Retrieve info from the TSA related serial */
@@ -272,6 +274,8 @@ int qmc_chan_get_info(struct qmc_chan *chan, struct 
qmc_chan_info *info)
if (ret)
return ret;
 
+   spin_lock_irqsave(>ts_lock, flags);
+
info->mode = chan->mode;
info->rx_fs_rate = tsa_info.rx_fs_rate;
info->rx_bit_rate = tsa_info.rx_bit_rate;
@@ -280,6 +284,8 @@ int qmc_chan_get_info(struct qmc_chan *chan, struct 
qmc_chan_info *info)
info->tx_bit_rate = tsa_info.tx_bit_rate;
info->nb_rx_ts = hweight64(chan->rx_ts_mask);
 
+   spin_unlock_irqrestore(>ts_lock, flags);
+
return 0;
 }
 EXPORT_SYMBOL(qmc_chan_get_info);
@@ -683,6 +689,40 @@ static int qmc_chan_setup_tsa_32tx(struct qmc_chan *chan, 
const struct tsa_seria
return 0;
 }
 
+static int qmc_chan_setup_tsa_tx(struct qmc_chan *chan, bool enable)
+{
+   struct tsa_serial_info info;
+   int ret;
+
+   /* Retrieve info from the TSA related serial */
+   ret = tsa_serial_get_info(chan->qmc->tsa_serial, );
+   if (ret)
+   return ret;
+
+   /* Setup entries */
+   if (chan->qmc->is_tsa_64rxtx)
+   return qmc_chan_setup_tsa_64rxtx(chan, , enable);
+
+   return qmc_chan_setup_tsa_32tx(chan, , enable);
+}
+
+static int qmc_chan_setup_tsa_rx(struct qmc_chan *chan, bool enable)
+{
+   struct tsa_serial_info info;
+   int ret;
+
+   /* Retrieve info from the TSA related serial */
+   ret = tsa_serial_get_info(chan->qmc->tsa_serial, );
+   if (ret)
+   return ret;
+
+   /* Setup entries */
+   if (chan->qmc->is_tsa_64rxtx)
+   return qmc_chan_setup_tsa_64rxtx(chan, , enable);
+
+   return qmc_chan_setup_tsa_32rx(chan, , enable);
+}
+
 static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable)
 {
struct tsa_serial_info info;
@@ -719,6 +759,12 @@ static int qmc_chan_stop_rx(struct qmc_chan *chan)
 
spin_lock_irqsave(>rx_lock, flags);
 
+   if (chan->is_rx_stopped) {
+   /* The channel is already stopped -> simply return ok */
+   ret = 0;
+   goto end;
+   }
+
/* Send STOP RECEIVE command */
ret = qmc_chan_command(chan, 0x0);
if (ret) {
@@ -729,6 +775,15 @@ static int qmc_chan_stop_rx(struct qmc_chan *chan)
 
chan->is_rx_stopped = true;
 
+   if (!chan->qmc->is_tsa_64rxtx || chan->is_tx_stopped) {
+   ret = qmc_chan_setup_tsa_rx(chan, false);
+   if (ret) {
+   dev_err(chan->qmc->dev, "chan %u: Disable tsa entries 
failed (%d)\n",
+   chan->id, ret);
+   goto end;
+   }
+   }
+
 end:
spin_unlock_irqrestore(>rx_lock, flags);
return ret;
@@ -741,6 +796,12 @@ static int qmc_chan_stop_tx(struct qmc_chan *chan)
 
spin_lock_irqsave(>tx_lock, flags);
 
+   if (chan->is_tx_stopped) {
+   /* The channel is already stopped -> simply return ok */
+   ret = 0;
+   goto end;
+   }
+
/* Send STOP TRANSMIT command */
ret = qmc_chan_command(chan, 0x1);
if (ret) {
@@ -751,37 +812,82 @@ static int qmc_chan_stop_tx(struct qmc_chan *chan)
 
chan->is_tx_stopped = true;
 
+   if (!chan->qmc->is_tsa_64rxtx || chan->is_rx_stopped) {
+   ret = qmc_chan_setup_tsa_tx(chan, false);
+   if (ret) {
+   dev_err(chan->qmc->dev, "chan %u: Disable tsa entries 
failed (%d)\n",
+   chan->id, ret);
+   goto end;
+   }
+   }
+
 end:
spin_unlock_irqrestore(>tx_lock, flags);
return ret;
 }
 
+static int qmc_chan_start_rx(struct qmc_chan *chan);
+
 int qmc_chan_stop(struct qmc_chan *chan, int direction)
 {
-   int ret;
+   bool is_rx_rollback_needed = false;
+   unsigned long flags;
+   

[PATCH v9 16/27] soc: fsl: cpm1: qmc: Introduce is_tsa_64rxtx flag

2023-11-15 Thread Herve Codina
In order to support runtime timeslot route changes, some operations will
be different according the routing table used (common Rx and Tx table or
one table for Rx and one for Tx).

The is_tsa_64rxtx flag is introduced to avoid extra computation to
determine the table format each time we need it.
It is set once at initialization.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index 5ca4120779f8..e651b3bba1ca 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -216,6 +216,7 @@ struct qmc {
u16 __iomem *int_curr;
dma_addr_t int_dma_addr;
size_t int_size;
+   bool is_tsa_64rxtx;
struct list_head chan_head;
struct qmc_chan *chans[64];
 };
@@ -696,7 +697,7 @@ static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool 
enable)
 * Setup one common 64 entries table or two 32 entries (one for Tx
 * and one for Tx) according to assigned TS numbers.
 */
-   if (info.nb_tx_ts > 32 || info.nb_rx_ts > 32)
+   if (chan->qmc->is_tsa_64rxtx)
return qmc_chan_setup_tsa_64rxtx(chan, , enable);
 
ret = qmc_chan_setup_tsa_32rx(chan, , enable);
@@ -1053,6 +1054,7 @@ static int qmc_init_tsa_64rxtx(struct qmc *qmc, const 
struct tsa_serial_info *in
 * Everything was previously checked, Tx and Rx related stuffs are
 * identical -> Used Rx related stuff to build the table
 */
+   qmc->is_tsa_64rxtx = true;
 
/* Invalidate all entries */
for (i = 0; i < 64; i++)
@@ -1081,6 +1083,7 @@ static int qmc_init_tsa_32rx_32tx(struct qmc *qmc, const 
struct tsa_serial_info
 * Use a Tx 32 entries table and a Rx 32 entries table.
 * Everything was previously checked.
 */
+   qmc->is_tsa_64rxtx = false;
 
/* Invalidate all entries */
for (i = 0; i < 32; i++) {
-- 
2.41.0



[PATCH v9 15/27] soc: fsl: cpm1: qmc: Split Tx and Rx TSA entries setup

2023-11-15 Thread Herve Codina
The Tx and Rx entries for a given channel are set in one function.

In order to modify Rx entries and Tx entries independently of one other,
split this function in one for the Rx part and one for the Tx part.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 49 
 1 file changed, 35 insertions(+), 14 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index c1318fad296b..5ca4120779f8 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -610,14 +610,14 @@ static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan 
*chan, const struct tsa_ser
return 0;
 }
 
-static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct 
tsa_serial_info *info,
-   bool enable)
+static int qmc_chan_setup_tsa_32rx(struct qmc_chan *chan, const struct 
tsa_serial_info *info,
+  bool enable)
 {
unsigned int i;
u16 curr;
u16 val;
 
-   /* Use a Tx 32 entries table and a Rx 32 entries table */
+   /* Use a Rx 32 entries table */
 
val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id);
 
@@ -633,6 +633,30 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan 
*chan, const struct tsa_
return -EBUSY;
}
}
+
+   /* Set entries based on Rx stuff */
+   for (i = 0; i < info->nb_rx_ts; i++) {
+   if (!(chan->rx_ts_mask & (((u64)1) << i)))
+   continue;
+
+   qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
+~QMC_TSA_WRAP, enable ? val : 0x);
+   }
+
+   return 0;
+}
+
+static int qmc_chan_setup_tsa_32tx(struct qmc_chan *chan, const struct 
tsa_serial_info *info,
+  bool enable)
+{
+   unsigned int i;
+   u16 curr;
+   u16 val;
+
+   /* Use a Tx 32 entries table */
+
+   val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id);
+
/* Check entries based on Tx stuff */
for (i = 0; i < info->nb_tx_ts; i++) {
if (!(chan->tx_ts_mask & (((u64)1) << i)))
@@ -646,14 +670,6 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan 
*chan, const struct tsa_
}
}
 
-   /* Set entries based on Rx stuff */
-   for (i = 0; i < info->nb_rx_ts; i++) {
-   if (!(chan->rx_ts_mask & (((u64)1) << i)))
-   continue;
-
-   qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
-~QMC_TSA_WRAP, enable ? val : 0x);
-   }
/* Set entries based on Tx stuff */
for (i = 0; i < info->nb_tx_ts; i++) {
if (!(chan->tx_ts_mask & (((u64)1) << i)))
@@ -680,9 +696,14 @@ static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool 
enable)
 * Setup one common 64 entries table or two 32 entries (one for Tx
 * and one for Tx) according to assigned TS numbers.
 */
-   return ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) ?
-   qmc_chan_setup_tsa_64rxtx(chan, , enable) :
-   qmc_chan_setup_tsa_32rx_32tx(chan, , enable);
+   if (info.nb_tx_ts > 32 || info.nb_rx_ts > 32)
+   return qmc_chan_setup_tsa_64rxtx(chan, , enable);
+
+   ret = qmc_chan_setup_tsa_32rx(chan, , enable);
+   if (ret)
+   return ret;
+
+   return qmc_chan_setup_tsa_32tx(chan, , enable);
 }
 
 static int qmc_chan_command(struct qmc_chan *chan, u8 qmc_opcode)
-- 
2.41.0



[PATCH v9 14/27] soc: fsl: cpm1: qmc: Add support for disabling channel TSA entries

2023-11-15 Thread Herve Codina
In order to allow runtime timeslot route changes, disabling channel TSA
entries needs to be supported.

Add support for this new feature.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index 8d71e63d0f21..c1318fad296b 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -567,7 +567,8 @@ static void qmc_chan_read_done(struct qmc_chan *chan)
spin_unlock_irqrestore(>rx_lock, flags);
 }
 
-static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct 
tsa_serial_info *info)
+static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct 
tsa_serial_info *info,
+bool enable)
 {
unsigned int i;
u16 curr;
@@ -603,13 +604,14 @@ static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan 
*chan, const struct tsa_ser
continue;
 
qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
-~QMC_TSA_WRAP, val);
+~QMC_TSA_WRAP, enable ? val : 0x);
}
 
return 0;
 }
 
-static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct 
tsa_serial_info *info)
+static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct 
tsa_serial_info *info,
+   bool enable)
 {
unsigned int i;
u16 curr;
@@ -650,7 +652,7 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan 
*chan, const struct tsa_
continue;
 
qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
-~QMC_TSA_WRAP, val);
+~QMC_TSA_WRAP, enable ? val : 0x);
}
/* Set entries based on Tx stuff */
for (i = 0; i < info->nb_tx_ts; i++) {
@@ -658,13 +660,13 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan 
*chan, const struct tsa_
continue;
 
qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 2),
-~QMC_TSA_WRAP, val);
+~QMC_TSA_WRAP, enable ? val : 0x);
}
 
return 0;
 }
 
-static int qmc_chan_setup_tsa(struct qmc_chan *chan)
+static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable)
 {
struct tsa_serial_info info;
int ret;
@@ -679,8 +681,8 @@ static int qmc_chan_setup_tsa(struct qmc_chan *chan)
 * and one for Tx) according to assigned TS numbers.
 */
return ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) ?
-   qmc_chan_setup_tsa_64rxtx(chan, ) :
-   qmc_chan_setup_tsa_32rx_32tx(chan, );
+   qmc_chan_setup_tsa_64rxtx(chan, , enable) :
+   qmc_chan_setup_tsa_32rx_32tx(chan, , enable);
 }
 
 static int qmc_chan_command(struct qmc_chan *chan, u8 qmc_opcode)
@@ -1146,7 +1148,7 @@ static int qmc_setup_chan(struct qmc *qmc, struct 
qmc_chan *chan)
 
chan->qmc = qmc;
 
-   ret = qmc_chan_setup_tsa(chan);
+   ret = qmc_chan_setup_tsa(chan, true);
if (ret)
return ret;
 
-- 
2.41.0



[PATCH v9 13/27] soc: fsl: cpm1: qmc: Check available timeslots in qmc_check_chans()

2023-11-15 Thread Herve Codina
The timeslots checked in qmc_check_chans() are the timeslots used.
With the introduction of the available timeslots, the used timeslots
are a subset of the available timeslots. The timeslots checked during
the qmc_check_chans() call should be the available ones.

Simply update and check the available timeslots instead of the used
timeslots in qmc_check_chans().

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index f2a71a140db7..8d71e63d0f21 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -914,13 +914,13 @@ static int qmc_check_chans(struct qmc *qmc)
rx_ts_assigned_mask = info.nb_rx_ts == 64 ? U64_MAX : (((u64)1) << 
info.nb_rx_ts) - 1;
 
list_for_each_entry(chan, >chan_head, list) {
-   if (chan->tx_ts_mask > tx_ts_assigned_mask) {
-   dev_err(qmc->dev, "chan %u uses TSA unassigned Tx 
TS\n", chan->id);
+   if (chan->tx_ts_mask_avail > tx_ts_assigned_mask) {
+   dev_err(qmc->dev, "chan %u can use TSA unassigned Tx 
TS\n", chan->id);
return -EINVAL;
}
 
-   if (chan->rx_ts_mask > rx_ts_assigned_mask) {
-   dev_err(qmc->dev, "chan %u uses TSA unassigned Rx 
TS\n", chan->id);
+   if (chan->rx_ts_mask_avail > rx_ts_assigned_mask) {
+   dev_err(qmc->dev, "chan %u can use TSA unassigned Rx 
TS\n", chan->id);
return -EINVAL;
}
}
-- 
2.41.0



[PATCH v9 12/27] soc: fsl: cpm1: qmc: Remove no more needed checks from qmc_check_chans()

2023-11-15 Thread Herve Codina
The newly introduced qmc_chan_setup_tsa* functions check that the
channel entries are not already used.
These checks are also performed by qmc_check_chans() and are no more
needed.

Remove them from qmc_check_chans().

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 20 
 1 file changed, 20 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index 5d7e2ecdd933..f2a71a140db7 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -884,10 +884,7 @@ EXPORT_SYMBOL(qmc_chan_reset);
 static int qmc_check_chans(struct qmc *qmc)
 {
struct tsa_serial_info info;
-   bool is_one_table = false;
struct qmc_chan *chan;
-   u64 tx_ts_mask = 0;
-   u64 rx_ts_mask = 0;
u64 tx_ts_assigned_mask;
u64 rx_ts_assigned_mask;
int ret;
@@ -911,7 +908,6 @@ static int qmc_check_chans(struct qmc *qmc)
dev_err(qmc->dev, "Number of TSA Tx/Rx TS assigned are 
not equal\n");
return -EINVAL;
}
-   is_one_table = true;
}
 
tx_ts_assigned_mask = info.nb_tx_ts == 64 ? U64_MAX : (((u64)1) << 
info.nb_tx_ts) - 1;
@@ -922,27 +918,11 @@ static int qmc_check_chans(struct qmc *qmc)
dev_err(qmc->dev, "chan %u uses TSA unassigned Tx 
TS\n", chan->id);
return -EINVAL;
}
-   if (tx_ts_mask & chan->tx_ts_mask) {
-   dev_err(qmc->dev, "chan %u uses an already used Tx 
TS\n", chan->id);
-   return -EINVAL;
-   }
 
if (chan->rx_ts_mask > rx_ts_assigned_mask) {
dev_err(qmc->dev, "chan %u uses TSA unassigned Rx 
TS\n", chan->id);
return -EINVAL;
}
-   if (rx_ts_mask & chan->rx_ts_mask) {
-   dev_err(qmc->dev, "chan %u uses an already used Rx 
TS\n", chan->id);
-   return -EINVAL;
-   }
-
-   if (is_one_table && (chan->tx_ts_mask != chan->rx_ts_mask)) {
-   dev_err(qmc->dev, "chan %u uses different Rx and Tx 
TS\n", chan->id);
-   return -EINVAL;
-   }
-
-   tx_ts_mask |= chan->tx_ts_mask;
-   rx_ts_mask |= chan->rx_ts_mask;
}
 
return 0;
-- 
2.41.0



[PATCH v9 11/27] soc: fsl: cpm1: qmc: Introduce qmc_chan_setup_tsa*

2023-11-15 Thread Herve Codina
Introduce the qmc_chan_setup_tsa* functions to setup entries related
to the given channel.
Use them during QMC channels setup.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 161 ++-
 1 file changed, 125 insertions(+), 36 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index e3f2afb8fa4d..5d7e2ecdd933 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -240,6 +240,11 @@ static void qmc_clrbits16(void __iomem *addr, u16 clr)
qmc_write16(addr, qmc_read16(addr) & ~clr);
 }
 
+static void qmc_clrsetbits16(void __iomem *addr, u16 clr, u16 set)
+{
+   qmc_write16(addr, (qmc_read16(addr) & ~clr) | set);
+}
+
 static void qmc_write32(void __iomem *addr, u32 val)
 {
iowrite32be(val, addr);
@@ -562,6 +567,122 @@ static void qmc_chan_read_done(struct qmc_chan *chan)
spin_unlock_irqrestore(>rx_lock, flags);
 }
 
+static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct 
tsa_serial_info *info)
+{
+   unsigned int i;
+   u16 curr;
+   u16 val;
+
+   /*
+* Use a common Tx/Rx 64 entries table.
+* Tx and Rx related stuffs must be identical
+*/
+   if (chan->tx_ts_mask != chan->rx_ts_mask) {
+   dev_err(chan->qmc->dev, "chan %u uses different Rx and Tx 
TS\n", chan->id);
+   return -EINVAL;
+   }
+
+   val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id);
+
+   /* Check entries based on Rx stuff*/
+   for (i = 0; i < info->nb_rx_ts; i++) {
+   if (!(chan->rx_ts_mask & (((u64)1) << i)))
+   continue;
+
+   curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 
2));
+   if (curr & QMC_TSA_VALID && (curr & ~QMC_TSA_WRAP) != val) {
+   dev_err(chan->qmc->dev, "chan %u TxRx entry %d already 
used\n",
+   chan->id, i);
+   return -EBUSY;
+   }
+   }
+
+   /* Set entries based on Rx stuff*/
+   for (i = 0; i < info->nb_rx_ts; i++) {
+   if (!(chan->rx_ts_mask & (((u64)1) << i)))
+   continue;
+
+   qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
+~QMC_TSA_WRAP, val);
+   }
+
+   return 0;
+}
+
+static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct 
tsa_serial_info *info)
+{
+   unsigned int i;
+   u16 curr;
+   u16 val;
+
+   /* Use a Tx 32 entries table and a Rx 32 entries table */
+
+   val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id);
+
+   /* Check entries based on Rx stuff */
+   for (i = 0; i < info->nb_rx_ts; i++) {
+   if (!(chan->rx_ts_mask & (((u64)1) << i)))
+   continue;
+
+   curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 
2));
+   if (curr & QMC_TSA_VALID && (curr & ~QMC_TSA_WRAP) != val) {
+   dev_err(chan->qmc->dev, "chan %u Rx entry %d already 
used\n",
+   chan->id, i);
+   return -EBUSY;
+   }
+   }
+   /* Check entries based on Tx stuff */
+   for (i = 0; i < info->nb_tx_ts; i++) {
+   if (!(chan->tx_ts_mask & (((u64)1) << i)))
+   continue;
+
+   curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 
2));
+   if (curr & QMC_TSA_VALID && (curr & ~QMC_TSA_WRAP) != val) {
+   dev_err(chan->qmc->dev, "chan %u Tx entry %d already 
used\n",
+   chan->id, i);
+   return -EBUSY;
+   }
+   }
+
+   /* Set entries based on Rx stuff */
+   for (i = 0; i < info->nb_rx_ts; i++) {
+   if (!(chan->rx_ts_mask & (((u64)1) << i)))
+   continue;
+
+   qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
+~QMC_TSA_WRAP, val);
+   }
+   /* Set entries based on Tx stuff */
+   for (i = 0; i < info->nb_tx_ts; i++) {
+   if (!(chan->tx_ts_mask & (((u64)1) << i)))
+   continue;
+
+   qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 2),
+~QMC_TSA_WRAP, val);
+   }
+
+   return 0;
+}
+
+static int qmc_chan_setup_tsa(struct qmc_chan *chan)
+{
+   struct tsa_serial_info info;
+   int ret;
+
+   /* Retrieve info from the TSA related serial */
+   ret = tsa_serial_get_info(chan->qmc->tsa_serial, );
+   if (ret)
+   return ret;
+
+   /*
+* Setup one common 64 entries table or two 32 entries (one for Tx
+* and one for Tx) according to assigned TS numbers.
+*/
+   return ((info.nb_tx_ts > 32) || 

[PATCH v9 10/27] soc: fsl: cpm1: qmc: Rename qmc_setup_tsa* to qmc_init_tsa*

2023-11-15 Thread Herve Codina
qmc_setup_tsa* are called once at initialisation.
They initialize the QMC TSA table.
In order to introduce setup function later on for dynamic timeslots
management, rename the function to avoid later confusion.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index 0413e25d4c67..e3f2afb8fa4d 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -919,7 +919,7 @@ static int qmc_of_parse_chans(struct qmc *qmc, struct 
device_node *np)
return qmc_check_chans(qmc);
 }
 
-static int qmc_setup_tsa_64rxtx(struct qmc *qmc, const struct tsa_serial_info 
*info)
+static int qmc_init_tsa_64rxtx(struct qmc *qmc, const struct tsa_serial_info 
*info)
 {
struct qmc_chan *chan;
unsigned int i;
@@ -961,7 +961,7 @@ static int qmc_setup_tsa_64rxtx(struct qmc *qmc, const 
struct tsa_serial_info *i
return 0;
 }
 
-static int qmc_setup_tsa_32rx_32tx(struct qmc *qmc, const struct 
tsa_serial_info *info)
+static int qmc_init_tsa_32rx_32tx(struct qmc *qmc, const struct 
tsa_serial_info *info)
 {
struct qmc_chan *chan;
unsigned int i;
@@ -1019,7 +1019,7 @@ static int qmc_setup_tsa_32rx_32tx(struct qmc *qmc, const 
struct tsa_serial_info
return 0;
 }
 
-static int qmc_setup_tsa(struct qmc *qmc)
+static int qmc_init_tsa(struct qmc *qmc)
 {
struct tsa_serial_info info;
int ret;
@@ -1030,12 +1030,12 @@ static int qmc_setup_tsa(struct qmc *qmc)
return ret;
 
/*
-* Setup one common 64 entries table or two 32 entries (one for Tx and
-* one for Tx) according to assigned TS numbers.
+* Initialize one common 64 entries table or two 32 entries (one for Tx
+* and one for Tx) according to assigned TS numbers.
 */
return ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) ?
-   qmc_setup_tsa_64rxtx(qmc, ) :
-   qmc_setup_tsa_32rx_32tx(qmc, );
+   qmc_init_tsa_64rxtx(qmc, ) :
+   qmc_init_tsa_32rx_32tx(qmc, );
 }
 
 static int qmc_setup_chan_trnsync(struct qmc *qmc, struct qmc_chan *chan)
@@ -1391,7 +1391,7 @@ static int qmc_probe(struct platform_device *pdev)
qmc_write32(qmc->scc_pram + QMC_GBL_C_MASK32, 0xDEBB20E3);
qmc_write16(qmc->scc_pram + QMC_GBL_C_MASK16, 0xF0B8);
 
-   ret = qmc_setup_tsa(qmc);
+   ret = qmc_init_tsa(qmc);
if (ret)
goto err_tsa_serial_disconnect;
 
-- 
2.41.0



[PATCH v9 09/27] soc: fsl: cpm1: qmc: Introduce available timeslots masks

2023-11-15 Thread Herve Codina
Available timeslots masks define timeslots available for the related
channel. These timeslots are defined by the QMC binding.

Timeslots used are initialized to available timeslots but can be a
subset of available timeslots.
This prepares the dynamic timeslots management (ie. changing timeslots
at runtime).

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index e716f13669a0..0413e25d4c67 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -177,7 +177,9 @@ struct qmc_chan {
struct qmc *qmc;
void __iomem *s_param;
enum qmc_mode mode;
+   u64 tx_ts_mask_avail;
u64 tx_ts_mask;
+   u64 rx_ts_mask_avail;
u64 rx_ts_mask;
bool is_reverse_data;
 
@@ -875,7 +877,8 @@ static int qmc_of_parse_chans(struct qmc *qmc, struct 
device_node *np)
of_node_put(chan_np);
return ret;
}
-   chan->tx_ts_mask = ts_mask;
+   chan->tx_ts_mask_avail = ts_mask;
+   chan->tx_ts_mask = chan->tx_ts_mask_avail;
 
ret = of_property_read_u64(chan_np, "fsl,rx-ts-mask", _mask);
if (ret) {
@@ -884,7 +887,8 @@ static int qmc_of_parse_chans(struct qmc *qmc, struct 
device_node *np)
of_node_put(chan_np);
return ret;
}
-   chan->rx_ts_mask = ts_mask;
+   chan->rx_ts_mask_avail = ts_mask;
+   chan->rx_ts_mask = chan->rx_ts_mask_avail;
 
mode = "transparent";
ret = of_property_read_string(chan_np, "fsl,operational-mode", 
);
-- 
2.41.0



[PATCH v9 08/27] MAINTAINERS: Add the Freescale QMC HDLC driver entry

2023-11-15 Thread Herve Codina
After contributing the driver, add myself as the maintainer for the
Freescale QMC HDLC driver.

Signed-off-by: Herve Codina 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 97f51d5ec1cf..82d9afa8c083 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8524,6 +8524,13 @@ F:   
Documentation/devicetree/bindings/soc/fsl/cpm_qe/fsl,cpm1-scc-qmc.yaml
 F: drivers/soc/fsl/qe/qmc.c
 F: include/soc/fsl/qe/qmc.h
 
+FREESCALE QUICC ENGINE QMC HDLC DRIVER
+M: Herve Codina 
+L: net...@vger.kernel.org
+L: linuxppc-dev@lists.ozlabs.org
+S: Maintained
+F: drivers/net/wan/fsl_qmc_hdlc.c
+
 FREESCALE QUICC ENGINE TSA DRIVER
 M: Herve Codina 
 L: linuxppc-dev@lists.ozlabs.org
-- 
2.41.0



[PATCH v9 07/27] net: wan: Add support for QMC HDLC

2023-11-15 Thread Herve Codina
The QMC HDLC driver provides support for HDLC using the QMC (QUICC
Multichannel Controller) to transfer the HDLC data.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
Acked-by: Jakub Kicinski 
---
 drivers/net/wan/Kconfig|  12 +
 drivers/net/wan/Makefile   |   1 +
 drivers/net/wan/fsl_qmc_hdlc.c | 422 +
 3 files changed, 435 insertions(+)
 create mode 100644 drivers/net/wan/fsl_qmc_hdlc.c

diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index dcb069dde66b..8de99f4b647b 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -195,6 +195,18 @@ config FARSYNC
  To compile this driver as a module, choose M here: the
  module will be called farsync.
 
+config FSL_QMC_HDLC
+   tristate "Freescale QMC HDLC support"
+   depends on HDLC
+   depends on CPM_QMC
+   help
+ HDLC support using the Freescale QUICC Multichannel Controller (QMC).
+
+ To compile this driver as a module, choose M here: the
+ module will be called fsl_qmc_hdlc.
+
+ If unsure, say N.
+
 config FSL_UCC_HDLC
tristate "Freescale QUICC Engine HDLC support"
depends on HDLC
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index 5bec8fae47f8..f338f4830626 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_WANXL)   += wanxl.o
 obj-$(CONFIG_PCI200SYN)+= pci200syn.o
 obj-$(CONFIG_PC300TOO) += pc300too.o
 obj-$(CONFIG_IXP4XX_HSS)   += ixp4xx_hss.o
+obj-$(CONFIG_FSL_QMC_HDLC) += fsl_qmc_hdlc.o
 obj-$(CONFIG_FSL_UCC_HDLC) += fsl_ucc_hdlc.o
 obj-$(CONFIG_SLIC_DS26522) += slic_ds26522.o
 
diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c
new file mode 100644
index ..31b637ec8390
--- /dev/null
+++ b/drivers/net/wan/fsl_qmc_hdlc.c
@@ -0,0 +1,422 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Freescale QMC HDLC Device Driver
+ *
+ * Copyright 2023 CS GROUP France
+ *
+ * Author: Herve Codina 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct qmc_hdlc_desc {
+   struct net_device *netdev;
+   struct sk_buff *skb; /* NULL if the descriptor is not in use */
+   dma_addr_t dma_addr;
+   size_t dma_size;
+};
+
+struct qmc_hdlc {
+   struct device *dev;
+   struct qmc_chan *qmc_chan;
+   struct net_device *netdev;
+   bool is_crc32;
+   spinlock_t tx_lock; /* Protect tx descriptors */
+   struct qmc_hdlc_desc tx_descs[8];
+   unsigned int tx_out;
+   struct qmc_hdlc_desc rx_descs[4];
+};
+
+static inline struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev)
+{
+   return dev_to_hdlc(netdev)->priv;
+}
+
+static int qmc_hdlc_recv_queue(struct qmc_hdlc *qmc_hdlc, struct qmc_hdlc_desc 
*desc, size_t size);
+
+#define QMC_HDLC_RX_ERROR_FLAGS (QMC_RX_FLAG_HDLC_OVF | \
+QMC_RX_FLAG_HDLC_UNA | \
+QMC_RX_FLAG_HDLC_ABORT | \
+QMC_RX_FLAG_HDLC_CRC)
+
+static void qmc_hcld_recv_complete(void *context, size_t length, unsigned int 
flags)
+{
+   struct qmc_hdlc_desc *desc = context;
+   struct net_device *netdev = desc->netdev;
+   struct qmc_hdlc *qmc_hdlc = netdev_to_qmc_hdlc(desc->netdev);
+   int ret;
+
+   dma_unmap_single(qmc_hdlc->dev, desc->dma_addr, desc->dma_size, 
DMA_FROM_DEVICE);
+
+   if (flags & QMC_HDLC_RX_ERROR_FLAGS) {
+   netdev->stats.rx_errors++;
+   if (flags & QMC_RX_FLAG_HDLC_OVF) /* Data overflow */
+   netdev->stats.rx_over_errors++;
+   if (flags & QMC_RX_FLAG_HDLC_UNA) /* bits received not multiple 
of 8 */
+   netdev->stats.rx_frame_errors++;
+   if (flags & QMC_RX_FLAG_HDLC_ABORT) /* Received an abort 
sequence */
+   netdev->stats.rx_frame_errors++;
+   if (flags & QMC_RX_FLAG_HDLC_CRC) /* CRC error */
+   netdev->stats.rx_crc_errors++;
+   kfree_skb(desc->skb);
+   } else {
+   netdev->stats.rx_packets++;
+   netdev->stats.rx_bytes += length;
+
+   skb_put(desc->skb, length);
+   desc->skb->protocol = hdlc_type_trans(desc->skb, netdev);
+   netif_rx(desc->skb);
+   }
+
+   /* Re-queue a transfer using the same descriptor */
+   ret = qmc_hdlc_recv_queue(qmc_hdlc, desc, desc->dma_size);
+   if (ret) {
+   dev_err(qmc_hdlc->dev, "queue recv desc failed (%d)\n", ret);
+   netdev->stats.rx_errors++;
+   }
+}
+
+static int qmc_hdlc_recv_queue(struct qmc_hdlc *qmc_hdlc, struct qmc_hdlc_desc 
*desc, size_t size)
+{
+   int ret;
+
+   desc->skb = dev_alloc_skb(size);
+   if (!desc->skb)
+   return -ENOMEM;
+
+   

[PATCH v9 06/27] soc: fsl: cpm1: qmc: Add support for child devices

2023-11-15 Thread Herve Codina
QMC child devices support is needed to avoid orphan DT nodes that use a
simple DT phandle to reference a QMC channel.

Allow to instantiate child devices and also extend the API to get the
qmc_chan using a child device.

Signed-off-by: Herve Codina 
---
 drivers/soc/fsl/qe/qmc.c | 91 +++-
 include/soc/fsl/qe/qmc.h |  2 +
 2 files changed, 73 insertions(+), 20 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index 27f2f16deac9..e716f13669a0 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -1425,8 +1425,16 @@ static int qmc_probe(struct platform_device *pdev)
 
platform_set_drvdata(pdev, qmc);
 
+   /* Populate channel related devices */
+   ret = devm_of_platform_populate(qmc->dev);
+   if (ret)
+   goto err_disable_txrx;
+
return 0;
 
+err_disable_txrx:
+   qmc_setbits32(qmc->scc_regs + SCC_GSMRL, 0);
+
 err_disable_intr:
qmc_write16(qmc->scc_regs + SCC_SCCM, 0);
 
@@ -1465,26 +1473,16 @@ static struct platform_driver qmc_driver = {
 };
 module_platform_driver(qmc_driver);
 
-struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char 
*phandle_name)
+static struct qmc_chan *qmc_chan_get_from_qmc(struct device_node *qmc_np, 
unsigned int chan_index)
 {
-   struct of_phandle_args out_args;
struct platform_device *pdev;
struct qmc_chan *qmc_chan;
struct qmc *qmc;
-   int ret;
 
-   ret = of_parse_phandle_with_fixed_args(np, phandle_name, 1, 0,
-  _args);
-   if (ret < 0)
-   return ERR_PTR(ret);
-
-   if (!of_match_node(qmc_driver.driver.of_match_table, out_args.np)) {
-   of_node_put(out_args.np);
+   if (!of_match_node(qmc_driver.driver.of_match_table, qmc_np))
return ERR_PTR(-EINVAL);
-   }
 
-   pdev = of_find_device_by_node(out_args.np);
-   of_node_put(out_args.np);
+   pdev = of_find_device_by_node(qmc_np);
if (!pdev)
return ERR_PTR(-ENODEV);
 
@@ -1494,17 +1492,12 @@ struct qmc_chan *qmc_chan_get_byphandle(struct 
device_node *np, const char *phan
return ERR_PTR(-EPROBE_DEFER);
}
 
-   if (out_args.args_count != 1) {
+   if (chan_index >= ARRAY_SIZE(qmc->chans)) {
platform_device_put(pdev);
return ERR_PTR(-EINVAL);
}
 
-   if (out_args.args[0] >= ARRAY_SIZE(qmc->chans)) {
-   platform_device_put(pdev);
-   return ERR_PTR(-EINVAL);
-   }
-
-   qmc_chan = qmc->chans[out_args.args[0]];
+   qmc_chan = qmc->chans[chan_index];
if (!qmc_chan) {
platform_device_put(pdev);
return ERR_PTR(-ENOENT);
@@ -1512,8 +1505,44 @@ struct qmc_chan *qmc_chan_get_byphandle(struct 
device_node *np, const char *phan
 
return qmc_chan;
 }
+
+struct qmc_chan *qmc_chan_get_byphandle(struct device_node *np, const char 
*phandle_name)
+{
+   struct of_phandle_args out_args;
+   struct qmc_chan *qmc_chan;
+   int ret;
+
+   ret = of_parse_phandle_with_fixed_args(np, phandle_name, 1, 0,
+  _args);
+   if (ret < 0)
+   return ERR_PTR(ret);
+
+   if (out_args.args_count != 1) {
+   of_node_put(out_args.np);
+   return ERR_PTR(-EINVAL);
+   }
+
+   qmc_chan = qmc_chan_get_from_qmc(out_args.np, out_args.args[0]);
+   of_node_put(out_args.np);
+   return qmc_chan;
+}
 EXPORT_SYMBOL(qmc_chan_get_byphandle);
 
+struct qmc_chan *qmc_chan_get_bychild(struct device_node *np)
+{
+   struct device_node *qmc_np;
+   u32 chan_index;
+   int ret;
+
+   qmc_np = np->parent;
+   ret = of_property_read_u32(np, "reg", _index);
+   if (ret)
+   return ERR_PTR(-EINVAL);
+
+   return qmc_chan_get_from_qmc(qmc_np, chan_index);
+}
+EXPORT_SYMBOL(qmc_chan_get_bychild);
+
 void qmc_chan_put(struct qmc_chan *chan)
 {
put_device(chan->qmc->dev);
@@ -1550,6 +1579,28 @@ struct qmc_chan *devm_qmc_chan_get_byphandle(struct 
device *dev,
 }
 EXPORT_SYMBOL(devm_qmc_chan_get_byphandle);
 
+struct qmc_chan *devm_qmc_chan_get_bychild(struct device *dev,
+  struct device_node *np)
+{
+   struct qmc_chan *qmc_chan;
+   struct qmc_chan **dr;
+
+   dr = devres_alloc(devm_qmc_chan_release, sizeof(*dr), GFP_KERNEL);
+   if (!dr)
+   return ERR_PTR(-ENOMEM);
+
+   qmc_chan = qmc_chan_get_bychild(np);
+   if (!IS_ERR(qmc_chan)) {
+   *dr = qmc_chan;
+   devres_add(dev, dr);
+   } else {
+   devres_free(dr);
+   }
+
+   return qmc_chan;
+}
+EXPORT_SYMBOL(devm_qmc_chan_get_bychild);
+
 MODULE_AUTHOR("Herve Codina ");
 MODULE_DESCRIPTION("CPM QMC driver");
 MODULE_LICENSE("GPL");
diff --git 

[PATCH v9 01/27] soc: fsl: cpm1: tsa: Fix __iomem addresses declaration

2023-11-15 Thread Herve Codina
Running sparse (make C=1) on tsa.c raises a lot of warning such as:
  --- 8< ---
  warning: incorrect type in assignment (different address spaces)
 expected void *[noderef] si_regs
 got void [noderef] __iomem *
  --- 8< ---

Indeed, some variable were declared 'type *__iomem var' instead of
'type __iomem *var'.

Use the correct declaration to remove these warnings.

Fixes: 1d4ba0b81c1c ("soc: fsl: cpm1: Add support for TSA")
Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/tsa.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/soc/fsl/qe/tsa.c b/drivers/soc/fsl/qe/tsa.c
index 3f9981335590..6c5741cf5e9d 100644
--- a/drivers/soc/fsl/qe/tsa.c
+++ b/drivers/soc/fsl/qe/tsa.c
@@ -98,9 +98,9 @@
 #define TSA_SIRP   0x10
 
 struct tsa_entries_area {
-   void *__iomem entries_start;
-   void *__iomem entries_next;
-   void *__iomem last_entry;
+   void __iomem *entries_start;
+   void __iomem *entries_next;
+   void __iomem *last_entry;
 };
 
 struct tsa_tdm {
@@ -117,8 +117,8 @@ struct tsa_tdm {
 
 struct tsa {
struct device *dev;
-   void *__iomem si_regs;
-   void *__iomem si_ram;
+   void __iomem *si_regs;
+   void __iomem *si_ram;
resource_size_t si_ram_sz;
spinlock_t  lock;
int tdms; /* TSA_TDMx ORed */
@@ -135,27 +135,27 @@ static inline struct tsa *tsa_serial_get_tsa(struct 
tsa_serial *tsa_serial)
return container_of(tsa_serial, struct tsa, serials[tsa_serial->id]);
 }
 
-static inline void tsa_write32(void *__iomem addr, u32 val)
+static inline void tsa_write32(void __iomem *addr, u32 val)
 {
iowrite32be(val, addr);
 }
 
-static inline void tsa_write8(void *__iomem addr, u32 val)
+static inline void tsa_write8(void __iomem *addr, u32 val)
 {
iowrite8(val, addr);
 }
 
-static inline u32 tsa_read32(void *__iomem addr)
+static inline u32 tsa_read32(void __iomem *addr)
 {
return ioread32be(addr);
 }
 
-static inline void tsa_clrbits32(void *__iomem addr, u32 clr)
+static inline void tsa_clrbits32(void __iomem *addr, u32 clr)
 {
tsa_write32(addr, tsa_read32(addr) & ~clr);
 }
 
-static inline void tsa_clrsetbits32(void *__iomem addr, u32 clr, u32 set)
+static inline void tsa_clrsetbits32(void __iomem *addr, u32 clr, u32 set)
 {
tsa_write32(addr, (tsa_read32(addr) & ~clr) | set);
 }
@@ -313,7 +313,7 @@ static u32 tsa_serial_id2csel(struct tsa *tsa, u32 
serial_id)
 static int tsa_add_entry(struct tsa *tsa, struct tsa_entries_area *area,
 u32 count, u32 serial_id)
 {
-   void *__iomem addr;
+   void __iomem *addr;
u32 left;
u32 val;
u32 cnt;
-- 
2.41.0



[PATCH v9 05/27] soc: fsl: cpm1: qmc: Remove inline function specifiers

2023-11-15 Thread Herve Codina
The inline function specifier is present on some functions but it is
better to let the compiler decide inlining or not these functions.

Remove inline specifiers.

Fixes: 3178d58e0b97 ("soc: fsl: cpm1: Add support for QMC")
Signed-off-by: Herve Codina 
Suggested-by: Andrew Lunn 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index 4b4832d93c9b..27f2f16deac9 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -218,37 +218,37 @@ struct qmc {
struct qmc_chan *chans[64];
 };
 
-static inline void qmc_write16(void __iomem *addr, u16 val)
+static void qmc_write16(void __iomem *addr, u16 val)
 {
iowrite16be(val, addr);
 }
 
-static inline u16 qmc_read16(void __iomem *addr)
+static u16 qmc_read16(void __iomem *addr)
 {
return ioread16be(addr);
 }
 
-static inline void qmc_setbits16(void __iomem *addr, u16 set)
+static void qmc_setbits16(void __iomem *addr, u16 set)
 {
qmc_write16(addr, qmc_read16(addr) | set);
 }
 
-static inline void qmc_clrbits16(void __iomem *addr, u16 clr)
+static void qmc_clrbits16(void __iomem *addr, u16 clr)
 {
qmc_write16(addr, qmc_read16(addr) & ~clr);
 }
 
-static inline void qmc_write32(void __iomem *addr, u32 val)
+static void qmc_write32(void __iomem *addr, u32 val)
 {
iowrite32be(val, addr);
 }
 
-static inline u32 qmc_read32(void __iomem *addr)
+static u32 qmc_read32(void __iomem *addr)
 {
return ioread32be(addr);
 }
 
-static inline void qmc_setbits32(void __iomem *addr, u32 set)
+static void qmc_setbits32(void __iomem *addr, u32 set)
 {
qmc_write32(addr, qmc_read32(addr) | set);
 }
-- 
2.41.0



[PATCH v9 00/27] Add support for QMC HDLC, framer infrastructure and PEF2256 framer

2023-11-15 Thread Herve Codina
Hi,

I have a system where I need to handle an HDLC interface and some audio
data.

The HDLC data are transferred using a TDM bus on which a PEF2256
(E1/T1 framer) is present. The PEF2256 transfers data from/to the TDM
bus to/from the E1 line. This PEF2256 is connected to a PowerQUICC SoC
for the control path and the TDM is connected to the SoC (QMC component)
for the data path.

>From the QMC HDLC driver, I need to handle HDLC data using the QMC,
carrier detection using the PEF2256 (E1 line carrier) and set/get some
PEF2256 configuration.

The QMC HDLC driver considers the PEF2256 as a generic framer.
It performs operations that involve the PEF2256 through the generic
framer API.

The audio data are exchanged with the PEF2256 using a CPU DAI connected
to the TDM bus through the QMC and the PEF2256 needs to be seen as a
codec in order to be linked to the CPU DAI.
The codec handles the carrier detection using the PEF2256 and reports
the carrier state to the ALSA subsystem using the ASoC jack detection.

The codec, even if instantiated by the PEF2256 driver, considers the
PEF2256 as a generic framer.

The generic framer has:
 - 2 consumers (QMC HDLC drv and codec)
 - 1 provider (PEF2256)

So, the design is the following:
+--+   +-+
| QMC  | <- TDM -> | PEF2256 | <-> E1
 +-+|  +-+ |   | |
 | CPU DAI | <-data--> | QMC channel | |   | |
 +-+|  +-+ |   | |
+--+|  +-+ |   | |
| QMC HDLC drv | <-data--> | QMC channel | |   | |
+--+|  +-+ |   | |
 ^  +--+   | |
 |   ++ +-+| |
 +-> | framer | <-> | PEF2256 drv | <- local bus ->| |
 || | |+-+
 +-> || | |
 |   ++ |  +---+  |
 +---> | codec |  |
|  +---+  |
+-+

Further more, the TDM timeslots used by the QMC HDLC driver need to be
configured at runtime (QMC dynamic timeslots).

Several weeks ago, I sent two series related to this topic:
 - Add the Lantiq PEF2256 audio support [1]
 - RFC Add support for QMC HDLC and PHY [2]
This current series is a rework of these two series taking into account
feedbacks previously received.

In order to implement all of this, I do the following:
 1) Perform some fixes (patches 1, 2, 3, 4, 5 )
 2) Introduce the QMC HDLC driver (patches 6, 7, 8)
 3) Add QMC dynamic timeslot support (patches 9 - 19)
 4) Add timeslots change support in QMC HDLC (patch 20)
 5) Introduce framer infrastructure (patch 21)
 6) Add PEF2256 framer provider (patches 22, 23, 24, 25)
 7) Add framer codec as a framer consumer (patch 26)
 8) Add framer support as a framer consumer in QMC HDLC (patch 27)

The series contains the full story and detailed modifications.
If needed, the series can be split and/or commits can be squashed.
Let me know.

Compare to the previous iteration
  
https://lore.kernel.org/linux-kernel/20231011061437.64213-1-herve.cod...@bootlin.com/
This v9 series:
 - Removes some patches already applied
 - Adds some 'Acked-by' tags

Best regards,
Hervé

[1]: 
https://lore.kernel.org/all/20230417171601.74656-1-herve.cod...@bootlin.com/
[2]: 
https://lore.kernel.org/all/20230323103154.264546-1-herve.cod...@bootlin.com/

Changes v8 -> v9

   - Removed Patches 6, 7 and 8 (patches applied)

   - Patches 7, 20, 21, 23 (patches 10, 23, 24, 26 in v8)
 Add 'Acked-by: Jakub Kicinski '

Changes v7 -> v8

  - Patch 10
Fix a race condition when stopping the queue in qmc_hdlc_close()

  - Patch 24
Move to menuconfig and hide CONFIG_GENERIC_FRAMER
Remove unneeded check (defensive programming)
Remove unneeded variable assignment

  - Patch 25
Add 'Reviewed-by: Rob Herring '

  - Patch 26
Use array notation for 'audio_devs'

Changes v6 -> v7

  - Patch 8
Move the 'compatible' property to the first property.
Add device/SoC specific compatible strings.
Add 'Reviewed-by: Rob Herring '

  - Patch 25
Remove '$ref' from the lantiq,data-rate-bps property. '-bps' is now
a standard suffix.

Changes v5 -> v6

  - All patches
Remove 'Signed-off-by: Christophe Leroy '
These Sob were added by Christophe when he sent the v4 while I was
on vacation.

https://lore.kernel.org/linux-kernel/992a2b31-e21f-eee3-8bfc-a65b69fe5...@csgroup.eu/

  - Patch 6, 7
Add 'Acked-by: Conor Dooley '
Add 'Acked-by: Rob Herring '

  - Patch 8
Add a constraint on fsl,framer.

  - Patch 25
Fix clocks description (inconsistent capitalisation)
Use '8-bit' instead of '8bit'
Add 'Reviewed-by: Christophe Leroy 

[PATCH v9 04/27] soc: fsl: cpm1: qmc: Extend the API to provide Rx status

2023-11-15 Thread Herve Codina
In HDLC mode, some status flags related to the data read transfer can be
set by the hardware and need to be known by a QMC consumer for further
analysis.

Extend the API in order to provide these transfer status flags at the
read complete() call.

In TRANSPARENT mode, these flags have no meaning. Keep only one read
complete() API and update the consumers working in transparent mode.
In this case, the newly introduced flags parameter is simply unused.

Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c  | 29 +
 include/soc/fsl/qe/qmc.h  | 15 ++-
 sound/soc/fsl/fsl_qmc_audio.c |  2 +-
 3 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index 2312152a44b3..4b4832d93c9b 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -166,7 +166,7 @@
 struct qmc_xfer_desc {
union {
void (*tx_complete)(void *context);
-   void (*rx_complete)(void *context, size_t length);
+   void (*rx_complete)(void *context, size_t length, unsigned int 
flags);
};
void *context;
 };
@@ -421,7 +421,8 @@ static void qmc_chan_write_done(struct qmc_chan *chan)
 }
 
 int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t length,
-void (*complete)(void *context, size_t length), void 
*context)
+void (*complete)(void *context, size_t length, 
unsigned int flags),
+void *context)
 {
struct qmc_xfer_desc *xfer_desc;
unsigned long flags;
@@ -454,6 +455,10 @@ int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t 
addr, size_t length,
xfer_desc->rx_complete = complete;
xfer_desc->context = context;
 
+   /* Clear previous status flags */
+   ctrl &= ~(QMC_BD_RX_L | QMC_BD_RX_F | QMC_BD_RX_LG | QMC_BD_RX_NO |
+ QMC_BD_RX_AB | QMC_BD_RX_CR);
+
/* Activate the descriptor */
ctrl |= (QMC_BD_RX_E | QMC_BD_RX_UB);
wmb(); /* Be sure to flush data before descriptor activation */
@@ -485,7 +490,7 @@ EXPORT_SYMBOL(qmc_chan_read_submit);
 
 static void qmc_chan_read_done(struct qmc_chan *chan)
 {
-   void (*complete)(void *context, size_t size);
+   void (*complete)(void *context, size_t size, unsigned int flags);
struct qmc_xfer_desc *xfer_desc;
unsigned long flags;
cbd_t __iomem *bd;
@@ -527,7 +532,23 @@ static void qmc_chan_read_done(struct qmc_chan *chan)
 
if (complete) {
spin_unlock_irqrestore(>rx_lock, flags);
-   complete(context, datalen);
+
+   /*
+* Avoid conversion between internal hardware flags and
+* the software API flags.
+* -> Be sure that the software API flags are consistent
+*with the hardware flags
+*/
+   BUILD_BUG_ON(QMC_RX_FLAG_HDLC_LAST  != QMC_BD_RX_L);
+   BUILD_BUG_ON(QMC_RX_FLAG_HDLC_FIRST != QMC_BD_RX_F);
+   BUILD_BUG_ON(QMC_RX_FLAG_HDLC_OVF   != QMC_BD_RX_LG);
+   BUILD_BUG_ON(QMC_RX_FLAG_HDLC_UNA   != QMC_BD_RX_NO);
+   BUILD_BUG_ON(QMC_RX_FLAG_HDLC_ABORT != QMC_BD_RX_AB);
+   BUILD_BUG_ON(QMC_RX_FLAG_HDLC_CRC   != QMC_BD_RX_CR);
+
+   complete(context, datalen,
+ctrl & (QMC_BD_RX_L | QMC_BD_RX_F | 
QMC_BD_RX_LG |
+QMC_BD_RX_NO | QMC_BD_RX_AB | 
QMC_BD_RX_CR));
spin_lock_irqsave(>rx_lock, flags);
}
 
diff --git a/include/soc/fsl/qe/qmc.h b/include/soc/fsl/qe/qmc.h
index 3c61a50d2ae2..6f1d6cebc9fe 100644
--- a/include/soc/fsl/qe/qmc.h
+++ b/include/soc/fsl/qe/qmc.h
@@ -9,6 +9,7 @@
 #ifndef __SOC_FSL_QMC_H__
 #define __SOC_FSL_QMC_H__
 
+#include 
 #include 
 
 struct device_node;
@@ -56,8 +57,20 @@ int qmc_chan_set_param(struct qmc_chan *chan, const struct 
qmc_chan_param *param
 int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t 
length,
  void (*complete)(void *context), void *context);
 
+/* Flags available (ORed) for read complete() flags parameter in HDLC mode.
+ * No flags are available in transparent mode and the read complete() flags
+ * parameter has no meaning in transparent mode.
+ */
+#define QMC_RX_FLAG_HDLC_LAST  BIT(11) /* Last in frame */
+#define QMC_RX_FLAG_HDLC_FIRST BIT(10) /* First in frame */
+#define QMC_RX_FLAG_HDLC_OVF   BIT(5)  /* Data overflow */
+#define QMC_RX_FLAG_HDLC_UNA   BIT(4)  /* Unaligned (ie. bits received not 
multiple of 8) */
+#define QMC_RX_FLAG_HDLC_ABORT BIT(3)  /* Received an abort sequence (seven 
consecutive ones) */
+#define QMC_RX_FLAG_HDLC_CRC   BIT(2)  

[PATCH v9 03/27] soc: fsl: cpm1: qmc: Fix rx channel reset

2023-11-15 Thread Herve Codina
The qmc_chan_reset_rx() set the is_rx_stopped flag. This leads to an
inconsistent state in the following sequence.
qmc_chan_stop()
qmc_chan_reset()
Indeed, after the qmc_chan_reset() call, the channel must still be
stopped. Only a qmc_chan_start() call can move the channel from stopped
state to started state.

Fix the issue removing the is_rx_stopped flag setting from
qmc_chan_reset()

Fixes: 3178d58e0b97 ("soc: fsl: cpm1: Add support for QMC")
Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index 3f3de1351c96..2312152a44b3 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -685,7 +685,6 @@ static void qmc_chan_reset_rx(struct qmc_chan *chan)
qmc_read16(chan->s_param + QMC_SPE_RBASE));
 
chan->rx_pending = 0;
-   chan->is_rx_stopped = false;
 
spin_unlock_irqrestore(>rx_lock, flags);
 }
-- 
2.41.0



[PATCH v9 02/27] soc: fsl: cpm1: qmc: Fix __iomem addresses declaration

2023-11-15 Thread Herve Codina
Running sparse (make C=1) on qmc.c raises a lot of warning such as:
  ...
  warning: incorrect type in assignment (different address spaces)
 expected struct cpm_buf_desc [usertype] *[noderef] __iomem bd
 got struct cpm_buf_desc [noderef] [usertype] __iomem *txbd_free
  ...

Indeed, some variable were declared 'type *__iomem var' instead of
'type __iomem *var'.

Use the correct declaration to remove these warnings.

Fixes: 3178d58e0b97 ("soc: fsl: cpm1: Add support for QMC")
Signed-off-by: Herve Codina 
Reviewed-by: Christophe Leroy 
---
 drivers/soc/fsl/qe/qmc.c | 34 +-
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
index 92ec76c03965..3f3de1351c96 100644
--- a/drivers/soc/fsl/qe/qmc.c
+++ b/drivers/soc/fsl/qe/qmc.c
@@ -175,7 +175,7 @@ struct qmc_chan {
struct list_head list;
unsigned int id;
struct qmc *qmc;
-   void *__iomem s_param;
+   void __iomem *s_param;
enum qmc_mode mode;
u64 tx_ts_mask;
u64 rx_ts_mask;
@@ -203,9 +203,9 @@ struct qmc_chan {
 struct qmc {
struct device *dev;
struct tsa_serial *tsa_serial;
-   void *__iomem scc_regs;
-   void *__iomem scc_pram;
-   void *__iomem dpram;
+   void __iomem *scc_regs;
+   void __iomem *scc_pram;
+   void __iomem *dpram;
u16 scc_pram_offset;
cbd_t __iomem *bd_table;
dma_addr_t bd_dma_addr;
@@ -218,37 +218,37 @@ struct qmc {
struct qmc_chan *chans[64];
 };
 
-static inline void qmc_write16(void *__iomem addr, u16 val)
+static inline void qmc_write16(void __iomem *addr, u16 val)
 {
iowrite16be(val, addr);
 }
 
-static inline u16 qmc_read16(void *__iomem addr)
+static inline u16 qmc_read16(void __iomem *addr)
 {
return ioread16be(addr);
 }
 
-static inline void qmc_setbits16(void *__iomem addr, u16 set)
+static inline void qmc_setbits16(void __iomem *addr, u16 set)
 {
qmc_write16(addr, qmc_read16(addr) | set);
 }
 
-static inline void qmc_clrbits16(void *__iomem addr, u16 clr)
+static inline void qmc_clrbits16(void __iomem *addr, u16 clr)
 {
qmc_write16(addr, qmc_read16(addr) & ~clr);
 }
 
-static inline void qmc_write32(void *__iomem addr, u32 val)
+static inline void qmc_write32(void __iomem *addr, u32 val)
 {
iowrite32be(val, addr);
 }
 
-static inline u32 qmc_read32(void *__iomem addr)
+static inline u32 qmc_read32(void __iomem *addr)
 {
return ioread32be(addr);
 }
 
-static inline void qmc_setbits32(void *__iomem addr, u32 set)
+static inline void qmc_setbits32(void __iomem *addr, u32 set)
 {
qmc_write32(addr, qmc_read32(addr) | set);
 }
@@ -318,7 +318,7 @@ int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t 
addr, size_t length,
 {
struct qmc_xfer_desc *xfer_desc;
unsigned long flags;
-   cbd_t *__iomem bd;
+   cbd_t __iomem *bd;
u16 ctrl;
int ret;
 
@@ -374,7 +374,7 @@ static void qmc_chan_write_done(struct qmc_chan *chan)
void (*complete)(void *context);
unsigned long flags;
void *context;
-   cbd_t *__iomem bd;
+   cbd_t __iomem *bd;
u16 ctrl;
 
/*
@@ -425,7 +425,7 @@ int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t 
addr, size_t length,
 {
struct qmc_xfer_desc *xfer_desc;
unsigned long flags;
-   cbd_t *__iomem bd;
+   cbd_t __iomem *bd;
u16 ctrl;
int ret;
 
@@ -488,7 +488,7 @@ static void qmc_chan_read_done(struct qmc_chan *chan)
void (*complete)(void *context, size_t size);
struct qmc_xfer_desc *xfer_desc;
unsigned long flags;
-   cbd_t *__iomem bd;
+   cbd_t __iomem *bd;
void *context;
u16 datalen;
u16 ctrl;
@@ -663,7 +663,7 @@ static void qmc_chan_reset_rx(struct qmc_chan *chan)
 {
struct qmc_xfer_desc *xfer_desc;
unsigned long flags;
-   cbd_t *__iomem bd;
+   cbd_t __iomem *bd;
u16 ctrl;
 
spin_lock_irqsave(>rx_lock, flags);
@@ -694,7 +694,7 @@ static void qmc_chan_reset_tx(struct qmc_chan *chan)
 {
struct qmc_xfer_desc *xfer_desc;
unsigned long flags;
-   cbd_t *__iomem bd;
+   cbd_t __iomem *bd;
u16 ctrl;
 
spin_lock_irqsave(>tx_lock, flags);
-- 
2.41.0



[PATCH v2 1/2] resource: add walk_system_ram_res_rev()

2023-11-15 Thread Baoquan He
This function, being a variant of walk_system_ram_res() introduced in
commit 8c86e70acead ("resource: provide new functions to walk through
resources"), walks through a list of all the resources of System RAM
in reversed order, i.e., from higher to lower.

It will be used in kexec_file code to load kernel, initrd etc when
preparing kexec reboot.

Signed-off-by: AKASHI Takahiro 
Signed-off-by: Baoquan He 
---
v1->v2:
- Use kvrealloc() to reallocate memory instead of kvcalloc(), this
  simplifies code. Suggested by Andrew.

 include/linux/ioport.h |  3 +++
 kernel/resource.c  | 57 ++
 2 files changed, 60 insertions(+)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 14f5cfabbbc8..db7fe25f3370 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -331,6 +331,9 @@ extern int
 walk_system_ram_res(u64 start, u64 end, void *arg,
int (*func)(struct resource *, void *));
 extern int
+walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+   int (*func)(struct resource *, void *));
+extern int
 walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 
end,
void *arg, int (*func)(struct resource *, void *));
 
diff --git a/kernel/resource.c b/kernel/resource.c
index 866ef3663a0b..e8a244300e5b 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -27,6 +27,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 
 
@@ -429,6 +431,61 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
 func);
 }
 
+/*
+ * This function, being a variant of walk_system_ram_res(), calls the @func
+ * callback against all memory ranges of type System RAM which are marked as
+ * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from
+ * higher to lower.
+ */
+int walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+   int (*func)(struct resource *, void *))
+{
+   struct resource res, *rams;
+   int rams_size = 16, i;
+   unsigned long flags;
+   int ret = -1;
+
+   /* create a list */
+   rams = kvcalloc(rams_size, sizeof(struct resource), GFP_KERNEL);
+   if (!rams)
+   return ret;
+
+   flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+   i = 0;
+   while ((start < end) &&
+   (!find_next_iomem_res(start, end, flags, IORES_DESC_NONE, 
))) {
+   if (i >= rams_size) {
+   /* re-alloc */
+   struct resource *rams_new;
+
+   rams_new = kvrealloc(rams, rams_size * sizeof(struct 
resource),
+(rams_size + 16) * sizeof(struct 
resource),
+GFP_KERNEL);
+   if (!rams_new)
+   goto out;
+
+   rams = rams_new;
+   rams_size += 16;
+   }
+
+   rams[i].start = res.start;
+   rams[i++].end = res.end;
+
+   start = res.end + 1;
+   }
+
+   /* go reverse */
+   for (i--; i >= 0; i--) {
+   ret = (*func)([i], arg);
+   if (ret)
+   break;
+   }
+
+out:
+   kvfree(rams);
+   return ret;
+}
+
 /*
  * This function calls the @func callback against all memory ranges, which
  * are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
-- 
2.41.0



Re: [PATCH v2 1/7] kexec_file: add kexec_file flag to control debug printing

2023-11-15 Thread Baoquan He
When specifying 'kexec -c -d', kexec_load interface will print loading
information, e.g the regions where kernel/initrd/purgatory/cmdline
are put, the memmap passed to 2nd kernel taken as system RAM ranges,
and printing all contents of struct kexec_segment, etc. These are
very helpful for analyzing or positioning what's happening when
kexec/kdump itself failed. The debugging printing for kexec_load
interface is made in user space utility kexec-tools.

Whereas, with kexec_file_load interface, 'kexec -s -d' print nothing.
Because kexec_file code is mostly implemented in kernel space, and the
debugging printing functionality is missed. It's not convenient when
debugging kexec/kdump loading and jumping with kexec_file_load
interface.

Now add KEXEC_FILE_DEBUG to kexec_file flag to control the debugging
message printing. And add global variable kexec_file_dbg_print and
macro kexec_dprintk() to facilitate the printing.

This is a preparation, later kexec_dprintk() will be used to replace the
existing pr_debug(). Once 'kexec -s -d' is specified, it will print out
kexec/kdump loading information at KERN_INFO level. If '-d' is not
specified, it regresses to print message at KERN_DEBUG level.

Signed-off-by: Baoquan He 
---
v1->v2:
- Rewrite the kexec_dprintk() macro as Joe suggested to reduce kernel
  text size.

 include/linux/kexec.h  | 10 +-
 include/uapi/linux/kexec.h |  1 +
 kernel/kexec_file.c|  5 +
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 8227455192b7..66997efe36f1 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -264,6 +264,14 @@ arch_kexec_apply_relocations(struct purgatory_info *pi, 
Elf_Shdr *section,
return -ENOEXEC;
 }
 #endif
+
+extern bool kexec_file_dbg_print;
+
+#define kexec_dprintk(fmt, ...)\
+   printk("%s" fmt,\
+  kexec_file_dbg_print ? KERN_INFO : KERN_DEBUG,   \
+  ##__VA_ARGS__)
+
 #endif /* CONFIG_KEXEC_FILE */
 
 #ifdef CONFIG_KEXEC_ELF
@@ -403,7 +411,7 @@ bool kexec_load_permitted(int kexec_image_type);
 
 /* List of defined/legal kexec file flags */
 #define KEXEC_FILE_FLAGS   (KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \
-KEXEC_FILE_NO_INITRAMFS)
+KEXEC_FILE_NO_INITRAMFS | KEXEC_FILE_DEBUG)
 
 /* flag to track if kexec reboot is in progress */
 extern bool kexec_in_progress;
diff --git a/include/uapi/linux/kexec.h b/include/uapi/linux/kexec.h
index 01766dd839b0..c17bb096ea68 100644
--- a/include/uapi/linux/kexec.h
+++ b/include/uapi/linux/kexec.h
@@ -25,6 +25,7 @@
 #define KEXEC_FILE_UNLOAD  0x0001
 #define KEXEC_FILE_ON_CRASH0x0002
 #define KEXEC_FILE_NO_INITRAMFS0x0004
+#define KEXEC_FILE_DEBUG   0x0008
 
 /* These values match the ELF architecture values.
  * Unless there is a good reason that should continue to be the case.
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index f9a419cd22d4..4c35500ae40a 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -38,6 +38,8 @@ void set_kexec_sig_enforced(void)
 }
 #endif
 
+bool kexec_file_dbg_print;
+
 static int kexec_calculate_store_digests(struct kimage *image);
 
 /* Maximum size in bytes for kernel/initrd files. */
@@ -123,6 +125,8 @@ void kimage_file_post_load_cleanup(struct kimage *image)
 */
kfree(image->image_loader_data);
image->image_loader_data = NULL;
+
+   kexec_file_dbg_print = false;
 }
 
 #ifdef CONFIG_KEXEC_SIG
@@ -278,6 +282,7 @@ kimage_file_alloc_init(struct kimage **rimage, int 
kernel_fd,
if (!image)
return -ENOMEM;
 
+   kexec_file_dbg_print = !!(flags & KEXEC_FILE_DEBUG);
image->file_mode = 1;
 
if (kexec_on_panic) {
-- 
2.41.0



Re: [PATCH] powerpc: Restrict ARCH_HIBERNATION_POSSIBLE to supported configurations

2023-11-15 Thread Aneesh Kumar K V
On 11/15/23 5:23 PM, Vishal Chourasia wrote:
> 
> On 15/11/23 1:39 pm, Aneesh Kumar K.V wrote:
>> Vishal Chourasia  writes:
>>
>>> This patch modifies the ARCH_HIBERNATION_POSSIBLE option to ensure that it
>>> correctly depends on these PowerPC configurations being enabled. As a 
>>> result,
>>> it prevents the HOTPLUG_CPU from being selected when the required 
>>> dependencies
>>> are not satisfied.
>>>
>>> This change aligns the dependency tree with the expected hardware support 
>>> for
>>> CPU hot-plugging under PowerPC architectures, ensuring that the kernel
>>> configuration steps do not lead to inconsistent states.
>>>
>>> Signed-off-by: Vishal Chourasia 
>>> ---
>>> During the configuration process with 'make randconfig' followed by
>>> 'make olddefconfig', we observed a warning indicating an unmet direct
>>> dependency for the HOTPLUG_CPU option. The dependency in question relates to
>>> various PowerPC configurations (PPC_PSERIES, PPC_PMAC, PPC_POWERNV,
>>> FSL_SOC_BOOKE) which were not enabled, yet the HOTPLUG_CPU was being
>>> erroneously selected due to an implicit assumption by the PM_SLEEP_SMP 
>>> option.
>>> This misalignment in dependencies could potentially lead to inconsistent 
>>> kernel
>>> configuration states, especially when considering the necessary hardware
>>> support for CPU hot-plugging on PowerPC platforms. The patch aims to correct
>>> this by ensuring that ARCH_HIBERNATION_POSSIBLE is contingent upon the
>>> appropriate PowerPC configurations being active.
>>>
>>> steps to reproduce (before applying the patch):
>>>
>>> Run 'make pseries_le_defconfig'
>>> Run 'make menuconfig'
>>> Enable hibernation [ Kernel options -> Hibernation (aka 'suspend to disk') 
>>> ] 
>>> Disable [ Platform support -> IBM PowerNV (Non-Virtualized) platform 
>>> support ]
>>> Disable [ Platform support -> IBM pSeries & new (POWER5-based) iSeries ]
>>> Enable SMP [ Processor support -> Symmetric multi-processing support ]
>>> Save the config
>>> Run 'make olddefconfig'
>>>
>>>  arch/powerpc/Kconfig | 5 +++--
>>>  1 file changed, 3 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>>> index 6f105ee4f3cf..bf99ff9869f6 100644
>>> --- a/arch/powerpc/Kconfig
>>> +++ b/arch/powerpc/Kconfig
>>> @@ -380,8 +380,9 @@ config DEFAULT_UIMAGE
>>>   Used to allow a board to specify it wants a uImage built by default
>>>  
>>>  config ARCH_HIBERNATION_POSSIBLE
>>> -   bool
>>> -   default y
>>> +   def_bool y
>>> +   depends on PPC_PSERIES || \
>>> +   PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE
>>>  
>>>  config ARCH_SUSPEND_POSSIBLE
>>> def_bool y
>>>
>> I am wondering whether it should be switched to using select from
>> config PPC? 
> 
> selecting ARCH_HIBERNATION_POSSIBLE based on value of config PPC
> will not guarantee config PPC_PSERIES being set
> 
> PPC_PSERIES can be set to N, even when config PPC is set.
> 
> grep -A 5 -i "config ppc_pseries" arch/powerpc/platforms/pseries/Kconfig
> config PPC_PSERIES
>     depends on PPC64 && PPC_BOOK3S
>     bool "IBM pSeries & new (POWER5-based) iSeries"
>     select HAVE_PCSPKR_PLATFORM
>     select MPIC
>     select OF_DYNAMIC
> 

modified   arch/powerpc/Kconfig
@@ -156,6 +156,7 @@ config PPC
select ARCH_HAS_UACCESS_FLUSHCACHE
select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARCH_HAVE_NMI_SAFE_CMPXCHG
+   select ARCH_HIBERNATION_POSSIBLEif (PPC_PSERIES || PPC_PMAC || 
PPC_POWERNV || FSL_SOC_BOOKE)
select ARCH_KEEP_MEMBLOCK
select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if PPC_RADIX_MMU
select ARCH_MIGHT_HAVE_PC_PARPORT


-aneesh


Re: [PATCH] powerpc: Restrict ARCH_HIBERNATION_POSSIBLE to supported configurations

2023-11-15 Thread Vishal Chourasia


On 15/11/23 1:39 pm, Aneesh Kumar K.V wrote:
> Vishal Chourasia  writes:
>
>> This patch modifies the ARCH_HIBERNATION_POSSIBLE option to ensure that it
>> correctly depends on these PowerPC configurations being enabled. As a result,
>> it prevents the HOTPLUG_CPU from being selected when the required 
>> dependencies
>> are not satisfied.
>>
>> This change aligns the dependency tree with the expected hardware support for
>> CPU hot-plugging under PowerPC architectures, ensuring that the kernel
>> configuration steps do not lead to inconsistent states.
>>
>> Signed-off-by: Vishal Chourasia 
>> ---
>> During the configuration process with 'make randconfig' followed by
>> 'make olddefconfig', we observed a warning indicating an unmet direct
>> dependency for the HOTPLUG_CPU option. The dependency in question relates to
>> various PowerPC configurations (PPC_PSERIES, PPC_PMAC, PPC_POWERNV,
>> FSL_SOC_BOOKE) which were not enabled, yet the HOTPLUG_CPU was being
>> erroneously selected due to an implicit assumption by the PM_SLEEP_SMP 
>> option.
>> This misalignment in dependencies could potentially lead to inconsistent 
>> kernel
>> configuration states, especially when considering the necessary hardware
>> support for CPU hot-plugging on PowerPC platforms. The patch aims to correct
>> this by ensuring that ARCH_HIBERNATION_POSSIBLE is contingent upon the
>> appropriate PowerPC configurations being active.
>>
>> steps to reproduce (before applying the patch):
>>
>> Run 'make pseries_le_defconfig'
>> Run 'make menuconfig'
>> Enable hibernation [ Kernel options -> Hibernation (aka 'suspend to disk') ] 
>> Disable [ Platform support -> IBM PowerNV (Non-Virtualized) platform support 
>> ]
>> Disable [ Platform support -> IBM pSeries & new (POWER5-based) iSeries ]
>> Enable SMP [ Processor support -> Symmetric multi-processing support ]
>> Save the config
>> Run 'make olddefconfig'
>>
>>  arch/powerpc/Kconfig | 5 +++--
>>  1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index 6f105ee4f3cf..bf99ff9869f6 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -380,8 +380,9 @@ config DEFAULT_UIMAGE
>>Used to allow a board to specify it wants a uImage built by default
>>  
>>  config ARCH_HIBERNATION_POSSIBLE
>> -bool
>> -default y
>> +def_bool y
>> +depends on PPC_PSERIES || \
>> +PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE
>>  
>>  config ARCH_SUSPEND_POSSIBLE
>>  def_bool y
>>
> I am wondering whether it should be switched to using select from
> config PPC? 

selecting ARCH_HIBERNATION_POSSIBLE based on value of config PPC
will not guarantee config PPC_PSERIES being set

PPC_PSERIES can be set to N, even when config PPC is set.

grep -A 5 -i "config ppc_pseries" arch/powerpc/platforms/pseries/Kconfig
config PPC_PSERIES
    depends on PPC64 && PPC_BOOK3S
    bool "IBM pSeries & new (POWER5-based) iSeries"
    select HAVE_PCSPKR_PLATFORM
    select MPIC
    select OF_DYNAMIC

>
> -aneesh


Re: [PATCH v9 10/15] media: uapi: Add V4L2_CTRL_TYPE_FIXED_POINT

2023-11-15 Thread Laurent Pinchart
Hi Hans,

On Wed, Nov 15, 2023 at 12:19:31PM +0100, Hans Verkuil wrote:
> On 11/15/23 11:55, Laurent Pinchart wrote:
> > On Wed, Nov 15, 2023 at 09:09:42AM +0100, Hans Verkuil wrote:
> >> On 13/11/2023 13:44, Laurent Pinchart wrote:
> >>> On Mon, Nov 13, 2023 at 01:05:12PM +0100, Hans Verkuil wrote:
>  On 13/11/2023 12:43, Laurent Pinchart wrote:
> > On Mon, Nov 13, 2023 at 11:28:51AM +, Sakari Ailus wrote:
> >> On Mon, Nov 13, 2023 at 12:24:14PM +0100, Hans Verkuil wrote:
> >>> On 13/11/2023 12:07, Laurent Pinchart wrote:
>  On Mon, Nov 13, 2023 at 11:56:49AM +0100, Hans Verkuil wrote:
> > On 13/11/2023 11:42, Laurent Pinchart wrote:
> >> On Mon, Nov 13, 2023 at 11:29:09AM +0100, Hans Verkuil wrote:
> >>> On 10/11/2023 06:48, Shengjiu Wang wrote:
>  Fixed point controls are used by the user to configure
>  a fixed point value in 64bits, which Q31.32 format.
> 
>  Signed-off-by: Shengjiu Wang 
> >>>
> >>> This patch adds a new control type. This is something that also 
> >>> needs to be
> >>> tested by v4l2-compliance, and for that we need to add support 
> >>> for this to
> >>> one of the media test-drivers. The best place for that is the 
> >>> vivid driver,
> >>> since that has already a bunch of test controls for other control 
> >>> types.
> >>>
> >>> See e.g. VIVID_CID_INTEGER64 in vivid-ctrls.c.
> >>>
> >>> Can you add a patch adding a fixed point test control to vivid?
> >>
> >> I don't think V4L2_CTRL_TYPE_FIXED_POINT is a good idea. This 
> >> seems to
> >> relate more to units than control types. We have lots of 
> >> fixed-point
> >> values in controls already, using the 32-bit and 64-bit integer 
> >> control
> >> types. They use various locations for the decimal point, depending 
> >> on
> >> the control. If we want to make this more explicit to users, we 
> >> should
> >> work on adding unit support to the V4L2 controls.
> >
> > "Fixed Point" is not a unit, it's a type. 'Db', 'Hz' etc. are units.
> 
>  It's not a unit, but I think it's related to units. My point is that,
>  without units support, I don't see why we need a formal definition of
>  fixed-point types, and why this series couldn't just use
>  VIVID_CID_INTEGER64. Drivers already interpret VIVID_CID_INTEGER64
>  values as they see fit.
> >>>
> >>> They do? That's new to me. A quick grep for V4L2_CTRL_TYPE_INTEGER64
> >>> (I assume you meant that rather than VIVID_CID_INTEGER64) shows that 
> >>> it
> >
> > Yes, I meant V4L2_CTRL_TYPE_INTEGER64. Too hasty copy & paste :-)
> >
> >>> is always interpreted as a 64 bit integer and nothing else. As it 
> >>> should.
> >
> > The most common case for control handling in drivers is taking the
> > integer value and converting it to a register value, using
> > device-specific encoding of the register value. It can be a fixed-point
> > format or something else, depending on the device. My point is that
> > drivers routinely convert a "plain" integer to something else, and that
> > has never been considered as a cause of concern. I don't see why it
> > would be different in this series.
> >
> >>> And while we do not have support for units (other than the 
> >>> documentation),
> >>> we do have type support in the form of V4L2_CTRL_TYPE_*.
> >>>
> > A quick "git grep -i "fixed point" 
> > Documentation/userspace-api/media/'
> > only shows a single driver specific control (dw100.rst).
> >
> > I'm not aware of other controls in mainline that use fixed point.
> 
>  The analog gain control for sensors for instance.
> >>>
> >>> Not really. The documentation is super vague:
> >>>
> >>> V4L2_CID_ANALOGUE_GAIN (integer)
> >>>
> >>>   Analogue gain is gain affecting all colour components in the 
> >>> pixel matrix. The
> >>>   gain operation is performed in the analogue domain before A/D 
> >>> conversion.
> >>>
> >>> And the integer is just a range. Internally it might map to some fixed
> >>> point value, but userspace won't see that, it's hidden in the driver 
> >>> AFAICT.
> >
> > It's hidden so well that libcamera has a database of the sensor it
> > supports, with formulas to map a real gain value to the
> > V4L2_CID_ANALOGUE_GAIN control. The encoding of the integer value does
> > matter, and the kernel doesn't expose it. We may or may not consider
> > that as a shortcoming of the V4L2 control API, but in any case it's the
> > situation we have today.
> >
> >> I wonder if Laurent meant digital gain.
> 

Re: [PATCH v4 1/5] powerpc/smp: Enable Asym packing for cores on shared processor

2023-11-15 Thread Srikar Dronamraju
* Aneesh Kumar K.V  [2023-11-15 12:05:22]:

> Srikar Dronamraju  writes:
> 
> >
> >  arch/powerpc/kernel/smp.c | 37 +
> >  1 file changed, 29 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> > index ab691c89d787..69a3262024f1 100644
> > --- a/arch/powerpc/kernel/smp.c
> > +++ b/arch/powerpc/kernel/smp.c
> > @@ -993,16 +993,20 @@ static bool shared_caches;
> >  /* cpumask of CPUs with asymmetric SMT dependency */
> >  static int powerpc_smt_flags(void)
> >  {
> > -   int flags = SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES;
> > +   if (!cpu_has_feature(CPU_FTR_ASYM_SMT))
> > +   return SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES;
> >  
> > -   if (cpu_has_feature(CPU_FTR_ASYM_SMT)) {
> > -   printk_once(KERN_INFO "Enabling Asymmetric SMT scheduling\n");
> > -   flags |= SD_ASYM_PACKING;
> > -   }
> > -   return flags;
> > +   return SD_SHARE_CPUCAPACITY | SD_SHARE_PKG_RESOURCES | SD_ASYM_PACKING;
> >  }
> >  #endif
> >
> 
> Only relevant change there is dropping printk_once(). Rest of the
> changes are not needed?
> 
> -aneesh

If you are looking at just this hunk, then yes its moving the printk_once to
another function.

-- 
Thanks and Regards
Srikar Dronamraju


Re: [PATCH v9 10/15] media: uapi: Add V4L2_CTRL_TYPE_FIXED_POINT

2023-11-15 Thread Hans Verkuil
On 11/15/23 11:55, Laurent Pinchart wrote:
> Hi Hans,
> 
> On Wed, Nov 15, 2023 at 09:09:42AM +0100, Hans Verkuil wrote:
>> On 13/11/2023 13:44, Laurent Pinchart wrote:
>>> On Mon, Nov 13, 2023 at 01:05:12PM +0100, Hans Verkuil wrote:
 On 13/11/2023 12:43, Laurent Pinchart wrote:
> On Mon, Nov 13, 2023 at 11:28:51AM +, Sakari Ailus wrote:
>> On Mon, Nov 13, 2023 at 12:24:14PM +0100, Hans Verkuil wrote:
>>> On 13/11/2023 12:07, Laurent Pinchart wrote:
 On Mon, Nov 13, 2023 at 11:56:49AM +0100, Hans Verkuil wrote:
> On 13/11/2023 11:42, Laurent Pinchart wrote:
>> On Mon, Nov 13, 2023 at 11:29:09AM +0100, Hans Verkuil wrote:
>>> On 10/11/2023 06:48, Shengjiu Wang wrote:
 Fixed point controls are used by the user to configure
 a fixed point value in 64bits, which Q31.32 format.

 Signed-off-by: Shengjiu Wang 
>>>
>>> This patch adds a new control type. This is something that also 
>>> needs to be
>>> tested by v4l2-compliance, and for that we need to add support for 
>>> this to
>>> one of the media test-drivers. The best place for that is the vivid 
>>> driver,
>>> since that has already a bunch of test controls for other control 
>>> types.
>>>
>>> See e.g. VIVID_CID_INTEGER64 in vivid-ctrls.c.
>>>
>>> Can you add a patch adding a fixed point test control to vivid?
>>
>> I don't think V4L2_CTRL_TYPE_FIXED_POINT is a good idea. This seems 
>> to
>> relate more to units than control types. We have lots of fixed-point
>> values in controls already, using the 32-bit and 64-bit integer 
>> control
>> types. They use various locations for the decimal point, depending on
>> the control. If we want to make this more explicit to users, we 
>> should
>> work on adding unit support to the V4L2 controls.
>
> "Fixed Point" is not a unit, it's a type. 'Db', 'Hz' etc. are units.

 It's not a unit, but I think it's related to units. My point is that,
 without units support, I don't see why we need a formal definition of
 fixed-point types, and why this series couldn't just use
 VIVID_CID_INTEGER64. Drivers already interpret VIVID_CID_INTEGER64
 values as they see fit.
>>>
>>> They do? That's new to me. A quick grep for V4L2_CTRL_TYPE_INTEGER64
>>> (I assume you meant that rather than VIVID_CID_INTEGER64) shows that it
>
> Yes, I meant V4L2_CTRL_TYPE_INTEGER64. Too hasty copy & paste :-)
>
>>> is always interpreted as a 64 bit integer and nothing else. As it 
>>> should.
>
> The most common case for control handling in drivers is taking the
> integer value and converting it to a register value, using
> device-specific encoding of the register value. It can be a fixed-point
> format or something else, depending on the device. My point is that
> drivers routinely convert a "plain" integer to something else, and that
> has never been considered as a cause of concern. I don't see why it
> would be different in this series.
>
>>> And while we do not have support for units (other than the 
>>> documentation),
>>> we do have type support in the form of V4L2_CTRL_TYPE_*.
>>>
> A quick "git grep -i "fixed point" Documentation/userspace-api/media/'
> only shows a single driver specific control (dw100.rst).
>
> I'm not aware of other controls in mainline that use fixed point.

 The analog gain control for sensors for instance.
>>>
>>> Not really. The documentation is super vague:
>>>
>>> V4L2_CID_ANALOGUE_GAIN (integer)
>>>
>>> Analogue gain is gain affecting all colour components in the 
>>> pixel matrix. The
>>> gain operation is performed in the analogue domain before A/D 
>>> conversion.
>>>
>>> And the integer is just a range. Internally it might map to some fixed
>>> point value, but userspace won't see that, it's hidden in the driver 
>>> AFAICT.
>
> It's hidden so well that libcamera has a database of the sensor it
> supports, with formulas to map a real gain value to the
> V4L2_CID_ANALOGUE_GAIN control. The encoding of the integer value does
> matter, and the kernel doesn't expose it. We may or may not consider
> that as a shortcoming of the V4L2 control API, but in any case it's the
> situation we have today.
>
>> I wonder if Laurent meant digital gain.
>
> No, I meant analog. It applies to digital gain too though.
>
>> Those are often Q numbers. The practice there has been that the default
>> value yields gain of 1.
>>
>> There are probably many other examples in controls where something being
>> controlled isn't 

Re: [PATCH v9 10/15] media: uapi: Add V4L2_CTRL_TYPE_FIXED_POINT

2023-11-15 Thread Laurent Pinchart
Hi Hans,

On Wed, Nov 15, 2023 at 09:09:42AM +0100, Hans Verkuil wrote:
> On 13/11/2023 13:44, Laurent Pinchart wrote:
> > On Mon, Nov 13, 2023 at 01:05:12PM +0100, Hans Verkuil wrote:
> >> On 13/11/2023 12:43, Laurent Pinchart wrote:
> >>> On Mon, Nov 13, 2023 at 11:28:51AM +, Sakari Ailus wrote:
>  On Mon, Nov 13, 2023 at 12:24:14PM +0100, Hans Verkuil wrote:
> > On 13/11/2023 12:07, Laurent Pinchart wrote:
> >> On Mon, Nov 13, 2023 at 11:56:49AM +0100, Hans Verkuil wrote:
> >>> On 13/11/2023 11:42, Laurent Pinchart wrote:
>  On Mon, Nov 13, 2023 at 11:29:09AM +0100, Hans Verkuil wrote:
> > On 10/11/2023 06:48, Shengjiu Wang wrote:
> >> Fixed point controls are used by the user to configure
> >> a fixed point value in 64bits, which Q31.32 format.
> >>
> >> Signed-off-by: Shengjiu Wang 
> >
> > This patch adds a new control type. This is something that also 
> > needs to be
> > tested by v4l2-compliance, and for that we need to add support for 
> > this to
> > one of the media test-drivers. The best place for that is the vivid 
> > driver,
> > since that has already a bunch of test controls for other control 
> > types.
> >
> > See e.g. VIVID_CID_INTEGER64 in vivid-ctrls.c.
> >
> > Can you add a patch adding a fixed point test control to vivid?
> 
>  I don't think V4L2_CTRL_TYPE_FIXED_POINT is a good idea. This seems 
>  to
>  relate more to units than control types. We have lots of fixed-point
>  values in controls already, using the 32-bit and 64-bit integer 
>  control
>  types. They use various locations for the decimal point, depending on
>  the control. If we want to make this more explicit to users, we 
>  should
>  work on adding unit support to the V4L2 controls.
> >>>
> >>> "Fixed Point" is not a unit, it's a type. 'Db', 'Hz' etc. are units.
> >>
> >> It's not a unit, but I think it's related to units. My point is that,
> >> without units support, I don't see why we need a formal definition of
> >> fixed-point types, and why this series couldn't just use
> >> VIVID_CID_INTEGER64. Drivers already interpret VIVID_CID_INTEGER64
> >> values as they see fit.
> >
> > They do? That's new to me. A quick grep for V4L2_CTRL_TYPE_INTEGER64
> > (I assume you meant that rather than VIVID_CID_INTEGER64) shows that it
> >>>
> >>> Yes, I meant V4L2_CTRL_TYPE_INTEGER64. Too hasty copy & paste :-)
> >>>
> > is always interpreted as a 64 bit integer and nothing else. As it 
> > should.
> >>>
> >>> The most common case for control handling in drivers is taking the
> >>> integer value and converting it to a register value, using
> >>> device-specific encoding of the register value. It can be a fixed-point
> >>> format or something else, depending on the device. My point is that
> >>> drivers routinely convert a "plain" integer to something else, and that
> >>> has never been considered as a cause of concern. I don't see why it
> >>> would be different in this series.
> >>>
> > And while we do not have support for units (other than the 
> > documentation),
> > we do have type support in the form of V4L2_CTRL_TYPE_*.
> >
> >>> A quick "git grep -i "fixed point" Documentation/userspace-api/media/'
> >>> only shows a single driver specific control (dw100.rst).
> >>>
> >>> I'm not aware of other controls in mainline that use fixed point.
> >>
> >> The analog gain control for sensors for instance.
> >
> > Not really. The documentation is super vague:
> >
> > V4L2_CID_ANALOGUE_GAIN (integer)
> >
> > Analogue gain is gain affecting all colour components in the 
> > pixel matrix. The
> > gain operation is performed in the analogue domain before A/D 
> > conversion.
> >
> > And the integer is just a range. Internally it might map to some fixed
> > point value, but userspace won't see that, it's hidden in the driver 
> > AFAICT.
> >>>
> >>> It's hidden so well that libcamera has a database of the sensor it
> >>> supports, with formulas to map a real gain value to the
> >>> V4L2_CID_ANALOGUE_GAIN control. The encoding of the integer value does
> >>> matter, and the kernel doesn't expose it. We may or may not consider
> >>> that as a shortcoming of the V4L2 control API, but in any case it's the
> >>> situation we have today.
> >>>
>  I wonder if Laurent meant digital gain.
> >>>
> >>> No, I meant analog. It applies to digital gain too though.
> >>>
>  Those are often Q numbers. The practice there has been that the default
>  value yields gain of 1.
> 
>  There are probably many other examples in controls where something being
>  controlled isn't actually an integer while integer controls are still 
> 

[PATCH 18/32] fbdev/ps3fb: Set FBINFO_VIRTFB flag

2023-11-15 Thread Thomas Zimmermann
The ps3fb driver operates on system memory. Mark the framebuffer
accordingly. Helpers operating on the framebuffer memory will test
for the presence of this flag.

Signed-off-by: Thomas Zimmermann 
Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Christophe Leroy 
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/video/fbdev/ps3fb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/ps3fb.c b/drivers/video/fbdev/ps3fb.c
index 64d291d6b1532..de81ad3a5d1ed 100644
--- a/drivers/video/fbdev/ps3fb.c
+++ b/drivers/video/fbdev/ps3fb.c
@@ -1145,7 +1145,7 @@ static int ps3fb_probe(struct ps3_system_bus_device *dev)
info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START;
 
info->pseudo_palette = par->pseudo_palette;
-   info->flags = FBINFO_READS_FAST |
+   info->flags = FBINFO_VIRTFB | FBINFO_READS_FAST |
  FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
 
retval = fb_alloc_cmap(>cmap, 256, 0);
-- 
2.42.0



[PATCH 19/32] fbdev/ps3fb: Initialize fb_ops with fbdev macros

2023-11-15 Thread Thomas Zimmermann
Initialize the instance of struct fb_ops with fbdev initializer
macros for framebuffers in virtual address space. Set the read/write,
draw and mmap callbacks to the correct implementation and avoid
implicit defaults. Also select the necessary helpers in Kconfig.

Fbdev drivers sometimes rely on the callbacks being NULL for a
default I/O-memory-based implementation to be invoked; hence
requiring the I/O helpers to be built in any case. Setting all
callbacks in all drivers explicitly will allow to make the I/O
helpers optional. This benefits systems that do not use these
functions.

Signed-off-by: Thomas Zimmermann 
Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Christophe Leroy 
Cc: linuxppc-dev@lists.ozlabs.org
---
 drivers/video/fbdev/Kconfig | 5 +
 drivers/video/fbdev/ps3fb.c | 7 ++-
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 2445cbca85579..812b3a9a49507 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1715,10 +1715,7 @@ config FB_IBM_GXT4500
 config FB_PS3
tristate "PS3 GPU framebuffer driver"
depends on FB && PS3_PS3AV
-   select FB_SYS_FILLRECT
-   select FB_SYS_COPYAREA
-   select FB_SYS_IMAGEBLIT
-   select FB_SYS_FOPS
+   select FB_SYSMEM_HELPERS
help
  Include support for the virtual frame buffer in the PS3 platform.
 
diff --git a/drivers/video/fbdev/ps3fb.c b/drivers/video/fbdev/ps3fb.c
index de81ad3a5d1ed..de8d78bf070a0 100644
--- a/drivers/video/fbdev/ps3fb.c
+++ b/drivers/video/fbdev/ps3fb.c
@@ -939,15 +939,12 @@ static const struct fb_ops ps3fb_ops = {
.owner  = THIS_MODULE,
.fb_open= ps3fb_open,
.fb_release = ps3fb_release,
-   .fb_read= fb_sys_read,
-   .fb_write   = fb_sys_write,
+   __FB_DEFAULT_SYSMEM_OPS_RDWR,
.fb_check_var   = ps3fb_check_var,
.fb_set_par = ps3fb_set_par,
.fb_setcolreg   = ps3fb_setcolreg,
.fb_pan_display = ps3fb_pan_display,
-   .fb_fillrect= sys_fillrect,
-   .fb_copyarea= sys_copyarea,
-   .fb_imageblit   = sys_imageblit,
+   __FB_DEFAULT_SYSMEM_OPS_DRAW,
.fb_mmap= ps3fb_mmap,
.fb_blank   = ps3fb_blank,
.fb_ioctl   = ps3fb_ioctl,
-- 
2.42.0



Re: Fbdev issue after the drm updates 'drm-next-2023-10-31-1'

2023-11-15 Thread Gerd Hoffmann
On Wed, Nov 15, 2023 at 09:33:28AM +0100, Geert Uytterhoeven wrote:
> Hi Christian,
> 
> CC virtgpu
> 
> On Tue, Nov 14, 2023 at 10:45 AM Christian Zigotzky
>  wrote:
> > On 13 November 2023 at 01:48 pm, Geert Uytterhoeven wrote:
> > > I can confirm there is no graphics output with m68k/virt, and
> 
> Before the error message you reported:
> 
> virtio-mmio virtio-mmio.125: [drm] *ERROR* fbdev: Failed to setup
> generic emulation (ret=-2)
> 
> it also prints:
> 
> virtio-mmio virtio-mmio.125: [drm] bpp/depth value of 32/24 not supported
> virtio-mmio virtio-mmio.125: [drm] No compatible format found
> 
> Upon closer look, it turns out virtgpu is special in that its main
> plane supports only a single format: DRM_FORMAT_HOST_XRGB, which
> is XR24 on little-endian, and BX24 on big-endian.  I.e. on big-endian,
> virtgpu does not support XR24.

Driver and device support both XR24 and BX24 on both little endian and
big endian just fine.

Problem is both fbdev interfaces and the ADDFB ioctl specify the format
using bpp instead of fourcc, and advertising only one framebuffer format
-- in native byte order -- used to worked best, especially on bigendian
machines.

That was years ago though, IIRC predating the generic fbdev emulation,
so maybe it's time to revisit that.  Changing it should be as simple as
updating the format arrays:

--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -30,11 +30,13 @@
 #include "virtgpu_drv.h"
 
 static const uint32_t virtio_gpu_formats[] = {
-   DRM_FORMAT_HOST_XRGB,
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_BGRX,
 };
 
 static const uint32_t virtio_gpu_cursor_formats[] = {
-   DRM_FORMAT_HOST_ARGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_BGRA,
 };
 
 uint32_t virtio_gpu_translate_format(uint32_t drm_fourcc)

HTH,
  Gerd



Re: [PATCH v9 10/15] media: uapi: Add V4L2_CTRL_TYPE_FIXED_POINT

2023-11-15 Thread Hans Verkuil
On 15/11/2023 09:45, Tomasz Figa wrote:
> On Wed, Nov 15, 2023 at 5:09 PM Hans Verkuil  wrote:
>>
>> Hi Laurent,
>>
>> On 13/11/2023 13:44, Laurent Pinchart wrote:
>>> Hi Hans,
>>>
>>> On Mon, Nov 13, 2023 at 01:05:12PM +0100, Hans Verkuil wrote:
 On 13/11/2023 12:43, Laurent Pinchart wrote:
> On Mon, Nov 13, 2023 at 11:28:51AM +, Sakari Ailus wrote:
>> On Mon, Nov 13, 2023 at 12:24:14PM +0100, Hans Verkuil wrote:
>>> On 13/11/2023 12:07, Laurent Pinchart wrote:
 On Mon, Nov 13, 2023 at 11:56:49AM +0100, Hans Verkuil wrote:
> On 13/11/2023 11:42, Laurent Pinchart wrote:
>> On Mon, Nov 13, 2023 at 11:29:09AM +0100, Hans Verkuil wrote:
>>> On 10/11/2023 06:48, Shengjiu Wang wrote:
 Fixed point controls are used by the user to configure
 a fixed point value in 64bits, which Q31.32 format.

 Signed-off-by: Shengjiu Wang 
>>>
>>> This patch adds a new control type. This is something that also 
>>> needs to be
>>> tested by v4l2-compliance, and for that we need to add support for 
>>> this to
>>> one of the media test-drivers. The best place for that is the vivid 
>>> driver,
>>> since that has already a bunch of test controls for other control 
>>> types.
>>>
>>> See e.g. VIVID_CID_INTEGER64 in vivid-ctrls.c.
>>>
>>> Can you add a patch adding a fixed point test control to vivid?
>>
>> I don't think V4L2_CTRL_TYPE_FIXED_POINT is a good idea. This seems 
>> to
>> relate more to units than control types. We have lots of fixed-point
>> values in controls already, using the 32-bit and 64-bit integer 
>> control
>> types. They use various locations for the decimal point, depending on
>> the control. If we want to make this more explicit to users, we 
>> should
>> work on adding unit support to the V4L2 controls.
>
> "Fixed Point" is not a unit, it's a type. 'Db', 'Hz' etc. are units.

 It's not a unit, but I think it's related to units. My point is that,
 without units support, I don't see why we need a formal definition of
 fixed-point types, and why this series couldn't just use
 VIVID_CID_INTEGER64. Drivers already interpret VIVID_CID_INTEGER64
 values as they see fit.
>>>
>>> They do? That's new to me. A quick grep for V4L2_CTRL_TYPE_INTEGER64
>>> (I assume you meant that rather than VIVID_CID_INTEGER64) shows that it
>
> Yes, I meant V4L2_CTRL_TYPE_INTEGER64. Too hasty copy & paste :-)
>
>>> is always interpreted as a 64 bit integer and nothing else. As it 
>>> should.
>
> The most common case for control handling in drivers is taking the
> integer value and converting it to a register value, using
> device-specific encoding of the register value. It can be a fixed-point
> format or something else, depending on the device. My point is that
> drivers routinely convert a "plain" integer to something else, and that
> has never been considered as a cause of concern. I don't see why it
> would be different in this series.
>
>>> And while we do not have support for units (other than the 
>>> documentation),
>>> we do have type support in the form of V4L2_CTRL_TYPE_*.
>>>
> A quick "git grep -i "fixed point" Documentation/userspace-api/media/'
> only shows a single driver specific control (dw100.rst).
>
> I'm not aware of other controls in mainline that use fixed point.

 The analog gain control for sensors for instance.
>>>
>>> Not really. The documentation is super vague:
>>>
>>> V4L2_CID_ANALOGUE_GAIN (integer)
>>>
>>>   Analogue gain is gain affecting all colour components in the pixel 
>>> matrix. The
>>>   gain operation is performed in the analogue domain before A/D 
>>> conversion.
>>>
>>> And the integer is just a range. Internally it might map to some fixed
>>> point value, but userspace won't see that, it's hidden in the driver 
>>> AFAICT.
>
> It's hidden so well that libcamera has a database of the sensor it
> supports, with formulas to map a real gain value to the
> V4L2_CID_ANALOGUE_GAIN control. The encoding of the integer value does
> matter, and the kernel doesn't expose it. We may or may not consider
> that as a shortcoming of the V4L2 control API, but in any case it's the
> situation we have today.
>
>> I wonder if Laurent meant digital gain.
>
> No, I meant analog. It applies to digital gain too though.
>
>> Those are often Q numbers. The practice there has been that the default
>> value yields gain of 1.
>>
>> There are probably many other examples in controls where something being
>> controlled isn't 

Re: [PATCH v9 10/15] media: uapi: Add V4L2_CTRL_TYPE_FIXED_POINT

2023-11-15 Thread Tomasz Figa
On Wed, Nov 15, 2023 at 5:09 PM Hans Verkuil  wrote:
>
> Hi Laurent,
>
> On 13/11/2023 13:44, Laurent Pinchart wrote:
> > Hi Hans,
> >
> > On Mon, Nov 13, 2023 at 01:05:12PM +0100, Hans Verkuil wrote:
> >> On 13/11/2023 12:43, Laurent Pinchart wrote:
> >>> On Mon, Nov 13, 2023 at 11:28:51AM +, Sakari Ailus wrote:
>  On Mon, Nov 13, 2023 at 12:24:14PM +0100, Hans Verkuil wrote:
> > On 13/11/2023 12:07, Laurent Pinchart wrote:
> >> On Mon, Nov 13, 2023 at 11:56:49AM +0100, Hans Verkuil wrote:
> >>> On 13/11/2023 11:42, Laurent Pinchart wrote:
>  On Mon, Nov 13, 2023 at 11:29:09AM +0100, Hans Verkuil wrote:
> > On 10/11/2023 06:48, Shengjiu Wang wrote:
> >> Fixed point controls are used by the user to configure
> >> a fixed point value in 64bits, which Q31.32 format.
> >>
> >> Signed-off-by: Shengjiu Wang 
> >
> > This patch adds a new control type. This is something that also 
> > needs to be
> > tested by v4l2-compliance, and for that we need to add support for 
> > this to
> > one of the media test-drivers. The best place for that is the vivid 
> > driver,
> > since that has already a bunch of test controls for other control 
> > types.
> >
> > See e.g. VIVID_CID_INTEGER64 in vivid-ctrls.c.
> >
> > Can you add a patch adding a fixed point test control to vivid?
> 
>  I don't think V4L2_CTRL_TYPE_FIXED_POINT is a good idea. This seems 
>  to
>  relate more to units than control types. We have lots of fixed-point
>  values in controls already, using the 32-bit and 64-bit integer 
>  control
>  types. They use various locations for the decimal point, depending on
>  the control. If we want to make this more explicit to users, we 
>  should
>  work on adding unit support to the V4L2 controls.
> >>>
> >>> "Fixed Point" is not a unit, it's a type. 'Db', 'Hz' etc. are units.
> >>
> >> It's not a unit, but I think it's related to units. My point is that,
> >> without units support, I don't see why we need a formal definition of
> >> fixed-point types, and why this series couldn't just use
> >> VIVID_CID_INTEGER64. Drivers already interpret VIVID_CID_INTEGER64
> >> values as they see fit.
> >
> > They do? That's new to me. A quick grep for V4L2_CTRL_TYPE_INTEGER64
> > (I assume you meant that rather than VIVID_CID_INTEGER64) shows that it
> >>>
> >>> Yes, I meant V4L2_CTRL_TYPE_INTEGER64. Too hasty copy & paste :-)
> >>>
> > is always interpreted as a 64 bit integer and nothing else. As it 
> > should.
> >>>
> >>> The most common case for control handling in drivers is taking the
> >>> integer value and converting it to a register value, using
> >>> device-specific encoding of the register value. It can be a fixed-point
> >>> format or something else, depending on the device. My point is that
> >>> drivers routinely convert a "plain" integer to something else, and that
> >>> has never been considered as a cause of concern. I don't see why it
> >>> would be different in this series.
> >>>
> > And while we do not have support for units (other than the 
> > documentation),
> > we do have type support in the form of V4L2_CTRL_TYPE_*.
> >
> >>> A quick "git grep -i "fixed point" Documentation/userspace-api/media/'
> >>> only shows a single driver specific control (dw100.rst).
> >>>
> >>> I'm not aware of other controls in mainline that use fixed point.
> >>
> >> The analog gain control for sensors for instance.
> >
> > Not really. The documentation is super vague:
> >
> > V4L2_CID_ANALOGUE_GAIN (integer)
> >
> >   Analogue gain is gain affecting all colour components in the pixel 
> > matrix. The
> >   gain operation is performed in the analogue domain before A/D 
> > conversion.
> >
> > And the integer is just a range. Internally it might map to some fixed
> > point value, but userspace won't see that, it's hidden in the driver 
> > AFAICT.
> >>>
> >>> It's hidden so well that libcamera has a database of the sensor it
> >>> supports, with formulas to map a real gain value to the
> >>> V4L2_CID_ANALOGUE_GAIN control. The encoding of the integer value does
> >>> matter, and the kernel doesn't expose it. We may or may not consider
> >>> that as a shortcoming of the V4L2 control API, but in any case it's the
> >>> situation we have today.
> >>>
>  I wonder if Laurent meant digital gain.
> >>>
> >>> No, I meant analog. It applies to digital gain too though.
> >>>
>  Those are often Q numbers. The practice there has been that the default
>  value yields gain of 1.
> 
>  There are probably many other examples in controls where something being
>  controlled isn't actually an integer while integer controls are 

Re: Fbdev issue after the drm updates 'drm-next-2023-10-31-1'

2023-11-15 Thread Geert Uytterhoeven
Hi Christian,

CC virtgpu

On Tue, Nov 14, 2023 at 10:45 AM Christian Zigotzky
 wrote:
> On 13 November 2023 at 01:48 pm, Geert Uytterhoeven wrote:
> > I can confirm there is no graphics output with m68k/virt, and

Before the error message you reported:

virtio-mmio virtio-mmio.125: [drm] *ERROR* fbdev: Failed to setup
generic emulation (ret=-2)

it also prints:

virtio-mmio virtio-mmio.125: [drm] bpp/depth value of 32/24 not supported
virtio-mmio virtio-mmio.125: [drm] No compatible format found

Upon closer look, it turns out virtgpu is special in that its main
plane supports only a single format: DRM_FORMAT_HOST_XRGB, which
is XR24 on little-endian, and BX24 on big-endian.  I.e. on big-endian,
virtgpu does not support XR24.  Isn't this a violation of the DRM
rule that every driver must implement support for XR24?

> > bisected this to my own commit 6ae2ff23aa43a0c4 ("drm/client: Convert
> > drm_client_buffer_addfb() to drm_mode_addfb2()"), ouch...
> >
> > It turns out the old call to drm_mode_addfb() caused a translation
> > from a fourcc to a bpp/depth pair to a _different_ fourcc, due to the
> > quirk processing in drm_driver_legacy_fb_format().
> > I.e. on m68k/virt, the original requested format was XR24, which was
> > translated to BX24. The former doesn't work, the latter works.
> >
> > The following (gmail-whitespace-damaged) patch fixed the issue for me:
> >
> > --- a/drivers/gpu/drm/drm_client.c
> > +++ b/drivers/gpu/drm/drm_client.c
> > @@ -400,6 +400,16 @@ static int drm_client_buffer_addfb(struct
> > drm_client_buffer *buffer,
> >
> > fb_req.width = width;
> > fb_req.height = height;
> > +   if (client->dev->mode_config.quirk_addfb_prefer_host_byte_order) {
> > +   if (format == DRM_FORMAT_XRGB)
> > +   format = DRM_FORMAT_HOST_XRGB;
> > +   if (format == DRM_FORMAT_ARGB)
> > +   format = DRM_FORMAT_HOST_ARGB;
> > +   if (format == DRM_FORMAT_RGB565)
> > +   format = DRM_FORMAT_HOST_RGB565;
> > +   if (format == DRM_FORMAT_XRGB1555)
> > +   format = DRM_FORMAT_HOST_XRGB1555;
> > +   }
> > fb_req.pixel_format = format;
> > fb_req.handles[0] = handle;
> > fb_req.pitches[0] = buffer->pitch;
> >
> > However, I don't think we want to sprinkle more of these
> > translations around... So perhaps we should (re)add a call to
> > drm_driver_legacy_fb_format() to drm_client_buffer_addfb()?
> >
> > Second, as I doubt you are using a big-endian system, you are probably
> > running into a slightly different issue.
> >
> > Oh wait, you did CC linuxppc-dev, so perhaps you are running on a
> > big-endian machine?
>
> Your patch works! :-) Thanks a lot!
>
> I tested it with the virtio-vga and with the virtio-gpu-pci device in a 
> virtual ppce500 QEMU/KVM HV machine with an e5500 CPU today.
>
> Tested-by: Christian Zigotzky 

Thanks for testing!

Gr{oetje,eeting}s,

Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


Re: [PATCH v9 10/15] media: uapi: Add V4L2_CTRL_TYPE_FIXED_POINT

2023-11-15 Thread Hans Verkuil
On 10/11/2023 06:48, Shengjiu Wang wrote:
> Fixed point controls are used by the user to configure
> a fixed point value in 64bits, which Q31.32 format.
> 
> Signed-off-by: Shengjiu Wang 
> ---
>  .../userspace-api/media/v4l/vidioc-g-ext-ctrls.rst  | 13 +++--
>  .../userspace-api/media/v4l/vidioc-queryctrl.rst|  9 -
>  .../userspace-api/media/videodev2.h.rst.exceptions  |  1 +
>  drivers/media/v4l2-core/v4l2-ctrls-api.c|  5 -
>  drivers/media/v4l2-core/v4l2-ctrls-core.c   |  2 ++
>  include/uapi/linux/videodev2.h  |  1 +
>  6 files changed, 23 insertions(+), 8 deletions(-)
> 
> 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 e8475f9fd2cf..e7e5d78dc11e 100644
> --- a/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
> +++ b/Documentation/userspace-api/media/v4l/vidioc-g-ext-ctrls.rst
> @@ -162,13 +162,13 @@ still cause this situation.
>  * - __s32
>- ``value``
>- New value or current value. Valid if this control is not of type
> - ``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is
> - not set.
> + ``V4L2_CTRL_TYPE_INTEGER64``, ``V4L2_CTRL_TYPE_FIXED_POINT`` and
> + ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is not set.
>  * - __s64
>- ``value64``
>- New value or current value. Valid if this control is of type
> - ``V4L2_CTRL_TYPE_INTEGER64`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is
> - not set.
> + ``V4L2_CTRL_TYPE_INTEGER64``, ``V4L2_CTRL_TYPE_FIXED_POINT`` and
> + ``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is not set.
>  * - char *
>- ``string``
>- A pointer to a string. Valid if this control is of type
> @@ -193,8 +193,9 @@ still cause this situation.
>  * - __s64 *
>- ``p_s64``
>- A pointer to a matrix control of signed 64-bit values. Valid if
> -this control is of type ``V4L2_CTRL_TYPE_INTEGER64`` and
> -``V4L2_CTRL_FLAG_HAS_PAYLOAD`` is set.
> +this control is of type ``V4L2_CTRL_TYPE_INTEGER64``,
> +``V4L2_CTRL_TYPE_FIXED_POINT`` and ``V4L2_CTRL_FLAG_HAS_PAYLOAD``
> +is set.
>  * - struct :c:type:`v4l2_area` *
>- ``p_area``
>- A pointer to a struct :c:type:`v4l2_area`. Valid if this control is
> diff --git a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst 
> b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> index 4d38acafe8e1..f3995ec57044 100644
> --- a/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> +++ b/Documentation/userspace-api/media/v4l/vidioc-queryctrl.rst
> @@ -235,7 +235,8 @@ See also the examples in :ref:`control`.
>- ``default_value``
>- The default value of a ``V4L2_CTRL_TYPE_INTEGER``, ``_INTEGER64``,
>   ``_BOOLEAN``, ``_BITMASK``, ``_MENU``, ``_INTEGER_MENU``, ``_U8``
> - or ``_U16`` control. Not valid for other types of controls.
> + ``_FIXED_POINT`` or ``_U16`` control. Not valid for other types of
> + controls.
>  
>   .. note::
>  
> @@ -549,6 +550,12 @@ See also the examples in :ref:`control`.
>- n/a
>- A struct :c:type:`v4l2_ctrl_av1_film_grain`, containing AV1 Film 
> Grain
>  parameters for stateless video decoders.
> +* - ``V4L2_CTRL_TYPE_FIXED_POINT``
> +  - any
> +  - any
> +  - any
> +  - A 64-bit integer valued control, containing parameter which is
> +Q31.32 format.
>  
>  .. raw:: latex
>  
> diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions 
> b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
> index e61152bb80d1..2faa5a2015eb 100644
> --- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions
> +++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions
> @@ -167,6 +167,7 @@ replace symbol V4L2_CTRL_TYPE_AV1_SEQUENCE 
> :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_AV1_TILE_GROUP_ENTRY :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_AV1_FRAME :c:type:`v4l2_ctrl_type`
>  replace symbol V4L2_CTRL_TYPE_AV1_FILM_GRAIN :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_FIXED_POINT :c:type:`v4l2_ctrl_type`
>  
>  # V4L2 capability defines
>  replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c 
> b/drivers/media/v4l2-core/v4l2-ctrls-api.c
> index 002ea6588edf..e6a0fb8d6791 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls-api.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c
> @@ -57,6 +57,7 @@ static int ptr_to_user(struct v4l2_ext_control *c,
>   return copy_to_user(c->string, ptr.p_char, len + 1) ?
>  -EFAULT : 0;
>   case V4L2_CTRL_TYPE_INTEGER64:
> + case V4L2_CTRL_TYPE_FIXED_POINT:n
>   c->value64 = *ptr.p_s64;
>   break;
>   default:
> @@ -132,6 +133,7 @@ static int user_to_new(struct v4l2_ext_control *c, 

Re: [PATCH] powerpc: Restrict ARCH_HIBERNATION_POSSIBLE to supported configurations

2023-11-15 Thread Aneesh Kumar K.V
Vishal Chourasia  writes:

> This patch modifies the ARCH_HIBERNATION_POSSIBLE option to ensure that it
> correctly depends on these PowerPC configurations being enabled. As a result,
> it prevents the HOTPLUG_CPU from being selected when the required dependencies
> are not satisfied.
>
> This change aligns the dependency tree with the expected hardware support for
> CPU hot-plugging under PowerPC architectures, ensuring that the kernel
> configuration steps do not lead to inconsistent states.
>
> Signed-off-by: Vishal Chourasia 
> ---
> During the configuration process with 'make randconfig' followed by
> 'make olddefconfig', we observed a warning indicating an unmet direct
> dependency for the HOTPLUG_CPU option. The dependency in question relates to
> various PowerPC configurations (PPC_PSERIES, PPC_PMAC, PPC_POWERNV,
> FSL_SOC_BOOKE) which were not enabled, yet the HOTPLUG_CPU was being
> erroneously selected due to an implicit assumption by the PM_SLEEP_SMP option.
> This misalignment in dependencies could potentially lead to inconsistent 
> kernel
> configuration states, especially when considering the necessary hardware
> support for CPU hot-plugging on PowerPC platforms. The patch aims to correct
> this by ensuring that ARCH_HIBERNATION_POSSIBLE is contingent upon the
> appropriate PowerPC configurations being active.
>
> steps to reproduce (before applying the patch):
>
> Run 'make pseries_le_defconfig'
> Run 'make menuconfig'
> Enable hibernation [ Kernel options -> Hibernation (aka 'suspend to disk') ] 
> Disable [ Platform support -> IBM PowerNV (Non-Virtualized) platform support ]
> Disable [ Platform support -> IBM pSeries & new (POWER5-based) iSeries ]
> Enable SMP [ Processor support -> Symmetric multi-processing support ]
> Save the config
> Run 'make olddefconfig'
>
>  arch/powerpc/Kconfig | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 6f105ee4f3cf..bf99ff9869f6 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -380,8 +380,9 @@ config DEFAULT_UIMAGE
> Used to allow a board to specify it wants a uImage built by default
>  
>  config ARCH_HIBERNATION_POSSIBLE
> - bool
> - default y
> + def_bool y
> + depends on PPC_PSERIES || \
> + PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE
>  
>  config ARCH_SUSPEND_POSSIBLE
>   def_bool y
>

I am wondering whether it should be switched to using select from
config PPC? 

-aneesh


Re: [PATCH v9 10/15] media: uapi: Add V4L2_CTRL_TYPE_FIXED_POINT

2023-11-15 Thread Hans Verkuil
Hi Laurent,

On 13/11/2023 13:44, Laurent Pinchart wrote:
> Hi Hans,
> 
> On Mon, Nov 13, 2023 at 01:05:12PM +0100, Hans Verkuil wrote:
>> On 13/11/2023 12:43, Laurent Pinchart wrote:
>>> On Mon, Nov 13, 2023 at 11:28:51AM +, Sakari Ailus wrote:
 On Mon, Nov 13, 2023 at 12:24:14PM +0100, Hans Verkuil wrote:
> On 13/11/2023 12:07, Laurent Pinchart wrote:
>> On Mon, Nov 13, 2023 at 11:56:49AM +0100, Hans Verkuil wrote:
>>> On 13/11/2023 11:42, Laurent Pinchart wrote:
 On Mon, Nov 13, 2023 at 11:29:09AM +0100, Hans Verkuil wrote:
> On 10/11/2023 06:48, Shengjiu Wang wrote:
>> Fixed point controls are used by the user to configure
>> a fixed point value in 64bits, which Q31.32 format.
>>
>> Signed-off-by: Shengjiu Wang 
>
> This patch adds a new control type. This is something that also needs 
> to be
> tested by v4l2-compliance, and for that we need to add support for 
> this to
> one of the media test-drivers. The best place for that is the vivid 
> driver,
> since that has already a bunch of test controls for other control 
> types.
>
> See e.g. VIVID_CID_INTEGER64 in vivid-ctrls.c.
>
> Can you add a patch adding a fixed point test control to vivid?

 I don't think V4L2_CTRL_TYPE_FIXED_POINT is a good idea. This seems to
 relate more to units than control types. We have lots of fixed-point
 values in controls already, using the 32-bit and 64-bit integer control
 types. They use various locations for the decimal point, depending on
 the control. If we want to make this more explicit to users, we should
 work on adding unit support to the V4L2 controls.
>>>
>>> "Fixed Point" is not a unit, it's a type. 'Db', 'Hz' etc. are units.
>>
>> It's not a unit, but I think it's related to units. My point is that,
>> without units support, I don't see why we need a formal definition of
>> fixed-point types, and why this series couldn't just use
>> VIVID_CID_INTEGER64. Drivers already interpret VIVID_CID_INTEGER64
>> values as they see fit.
>
> They do? That's new to me. A quick grep for V4L2_CTRL_TYPE_INTEGER64
> (I assume you meant that rather than VIVID_CID_INTEGER64) shows that it
>>>
>>> Yes, I meant V4L2_CTRL_TYPE_INTEGER64. Too hasty copy & paste :-)
>>>
> is always interpreted as a 64 bit integer and nothing else. As it should.
>>>
>>> The most common case for control handling in drivers is taking the
>>> integer value and converting it to a register value, using
>>> device-specific encoding of the register value. It can be a fixed-point
>>> format or something else, depending on the device. My point is that
>>> drivers routinely convert a "plain" integer to something else, and that
>>> has never been considered as a cause of concern. I don't see why it
>>> would be different in this series.
>>>
> And while we do not have support for units (other than the documentation),
> we do have type support in the form of V4L2_CTRL_TYPE_*.
>
>>> A quick "git grep -i "fixed point" Documentation/userspace-api/media/'
>>> only shows a single driver specific control (dw100.rst).
>>>
>>> I'm not aware of other controls in mainline that use fixed point.
>>
>> The analog gain control for sensors for instance.
>
> Not really. The documentation is super vague:
>
> V4L2_CID_ANALOGUE_GAIN (integer)
>
>   Analogue gain is gain affecting all colour components in the pixel 
> matrix. The
>   gain operation is performed in the analogue domain before A/D 
> conversion.
>
> And the integer is just a range. Internally it might map to some fixed
> point value, but userspace won't see that, it's hidden in the driver 
> AFAICT.
>>>
>>> It's hidden so well that libcamera has a database of the sensor it
>>> supports, with formulas to map a real gain value to the
>>> V4L2_CID_ANALOGUE_GAIN control. The encoding of the integer value does
>>> matter, and the kernel doesn't expose it. We may or may not consider
>>> that as a shortcoming of the V4L2 control API, but in any case it's the
>>> situation we have today.
>>>
 I wonder if Laurent meant digital gain.
>>>
>>> No, I meant analog. It applies to digital gain too though.
>>>
 Those are often Q numbers. The practice there has been that the default
 value yields gain of 1.

 There are probably many other examples in controls where something being
 controlled isn't actually an integer while integer controls are still being
 used for the purpose.
>>>
>>> A good summary of my opinion :-)
>>
>> And that works fine as long as userspace doesn't need to know what the value
>> actually means.
>>
>> That's not the case here. The control is really a fractional Hz value:
>>
>> +``V4L2_CID_M2M_AUDIO_SOURCE_RATE_OFFSET (fixed