LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] powerpc: config: Sync skiroot defconfig
From: Joel Stanley @ 2019-03-05  4:46 UTC (permalink / raw)
  To: linuxppc-dev

This updates the skiroot defconfig with the version from the OpenPower
firmwre build tree.

Important changes are the addition of QED and E1000E ethernet drivers.

Signed-off-by: Joel Stanley <joel@jms.id.au>
---
Generated on top of next-20190304

 arch/powerpc/configs/skiroot_defconfig | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/configs/skiroot_defconfig b/arch/powerpc/configs/skiroot_defconfig
index bf31334efbce..b3a9ea838244 100644
--- a/arch/powerpc/configs/skiroot_defconfig
+++ b/arch/powerpc/configs/skiroot_defconfig
@@ -52,10 +52,10 @@ CONFIG_MODULE_SIG=y
 CONFIG_MODULE_SIG_FORCE=y
 CONFIG_MODULE_SIG_SHA512=y
 CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_KYBER is not set
 # CONFIG_COMPACTION is not set
 # CONFIG_MIGRATION is not set
-# CONFIG_BOUNCE is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -136,9 +136,11 @@ CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_NET_VENDOR_AQUANTIA is not set
 # CONFIG_NET_VENDOR_ARC is not set
 # CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_VENDOR_AURORA is not set
 CONFIG_TIGON3=m
 CONFIG_BNX2X=m
 # CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
 # CONFIG_NET_VENDOR_CAVIUM is not set
 CONFIG_CHELSIO_T1=m
 # CONFIG_NET_VENDOR_CISCO is not set
@@ -150,6 +152,7 @@ CONFIG_BE2NET=m
 # CONFIG_NET_VENDOR_HP is not set
 # CONFIG_NET_VENDOR_HUAWEI is not set
 CONFIG_E1000=m
+CONFIG_E1000E=m
 CONFIG_IGB=m
 CONFIG_IXGB=m
 CONFIG_IXGBE=m
@@ -159,6 +162,7 @@ CONFIG_MLX4_EN=m
 # CONFIG_MLX4_CORE_GEN2 is not set
 CONFIG_MLX5_CORE=m
 # CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
 CONFIG_MYRI10GE=m
 # CONFIG_NET_VENDOR_NATSEMI is not set
 CONFIG_S2IO=m
@@ -166,8 +170,11 @@ CONFIG_S2IO=m
 # CONFIG_NET_VENDOR_NI is not set
 # CONFIG_NET_VENDOR_NVIDIA is not set
 # CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_VENDOR_PACKET_ENGINES is not set
 CONFIG_QLGE=m
 CONFIG_NETXEN_NIC=m
+CONFIG_QED=m
+CONFIG_QEDE=m
 # CONFIG_NET_VENDOR_QUALCOMM is not set
 # CONFIG_NET_VENDOR_RDC is not set
 # CONFIG_NET_VENDOR_REALTEK is not set
-- 
2.20.1


^ permalink raw reply related

* Re: [PATCH] Disable kcov for slb routines.
From: Andrew Donnellan @ 2019-03-05  3:31 UTC (permalink / raw)
  To: Mahesh J Salgaonkar, linuxppc-dev
  Cc: syzkaller, Paul Mackerras, Nicholas Piggin, Andrew Donnellan
In-Reply-To: <155168793242.4372.10864050702181452671.stgit@jupiter.in.ibm.com>

On 4/3/19 7:25 pm, Mahesh J Salgaonkar wrote:
> From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> 
> The kcov instrumentation inside SLB routines causes duplicate SLB entries
> to be added resulting into SLB multihit machine checks.
> Disable kcov instrumentation on slb.o
> 
> Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

Summary line needs a powerpc:

> ---
>   arch/powerpc/mm/Makefile |    1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
> index d4d32e229ace..f9cb40684746 100644
> --- a/arch/powerpc/mm/Makefile
> +++ b/arch/powerpc/mm/Makefile
> @@ -60,3 +60,4 @@ obj-$(CONFIG_PPC_MEM_KEYS)	+= pkeys.o
>   # This is necessary for booting with kcov enabled on book3e machines
>   KCOV_INSTRUMENT_tlb_nohash.o := n
>   KCOV_INSTRUMENT_fsl_booke_mmu.o := n
> +KCOV_INSTRUMENT_slb.o := n

The SLB stuff isn't related to the book3e issues, I'd appreciate a 
separate comment here.

Otherwise

Acked-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>



-- 
Andrew Donnellan              OzLabs, ADL Canberra
andrew.donnellan@au1.ibm.com  IBM Australia Limited


^ permalink raw reply

* Re: [PATCH 3/6] x86: clean up _TIF_SYSCALL_EMU handling using ptrace_syscall_enter hook
From: Haibo Xu (Arm Technology China) @ 2019-03-05  2:14 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Steve Capper, Catalin Marinas, jdike@addtoit.com, x86@kernel.org,
	Will Deacon, linux-kernel@vger.kernel.org, Oleg Nesterov,
	Richard Weinberger, Ingo Molnar, Paul Mackerras, Andy Lutomirski,
	Borislav Petkov, Thomas Gleixner, Bin Lu (Arm Technology China),
	linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190304101205.GA1504@e107155-lin>

On 2019/3/4 18:12, Sudeep Holla wrote:
> On Mon, Mar 04, 2019 at 08:25:28AM +0000, Haibo Xu (Arm Technology China) wrote:
>> On 2019/3/1 2:32, Sudeep Holla wrote:
>>> Now that we have a new hook ptrace_syscall_enter that can be called from
>>> syscall entry code and it handles PTRACE_SYSEMU in generic code, we
>>> can do some cleanup using the same in syscall_trace_enter.
>>>
>>> Further the extra logic to find single stepping PTRACE_SYSEMU_SINGLESTEP
>>> in syscall_slow_exit_work seems unnecessary. Let's remove the same.
>>
>> I think we should not change the logic here. Is so, it will double the report of syscall
>> when PTRACE_SYSEMU_SINGLESTEP is enabled.
>>
>
> I don't think that should happen, but I may be missing something.
> Can you explain how ?
>
> --
> Regards,
> Sudeep
>

When PTRACE_SYSEMU_SINGLESTEP is enabled, both the _TIF_SYSCALL_EMU and _TIF_SINGLESTEP
flags are set, but ptrace only need to report(send SIGTRAP) at the entry of a system call,
no need to report at the exit of a system call.

Regards,
Haibo
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

^ permalink raw reply

* Re: [PATCH RESEND v5 1/3] ASoC: fsl: Add Audio Mixer CPU DAI driver
From: kbuild test robot @ 2019-03-04 20:31 UTC (permalink / raw)
  To: Viorel Suman
  Cc: Mark Rutland, devicetree@vger.kernel.org,
	alsa-devel@alsa-project.org, linuxppc-dev@lists.ozlabs.org,
	Timur Tabi, Xiubo Li, linux-kernel@vger.kernel.org, S.j. Wang,
	Takashi Iwai, Liam Girdwood, Rob Herring, Jaroslav Kysela,
	Nicolin Chen, Cosmin Samoila, Mark Brown, kbuild-all,
	Viorel Suman, Viorel Suman, Fabio Estevam, Daniel Baluta,
	dl-linux-imx
In-Reply-To: <1551695748-21541-2-git-send-email-viorel.suman@nxp.com>

[-- Attachment #1: Type: text/plain, Size: 3681 bytes --]

Hi Viorel,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on asoc/for-next]
[also build test WARNING on v5.0 next-20190304]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Viorel-Suman/Add-NXP-AUDMIX-device-and-machine-drivers/20190305-023038
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
config: nds32-allyesconfig (attached as .config)
compiler: nds32le-linux-gcc (GCC) 6.4.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=6.4.0 make.cross ARCH=nds32 

All warnings (new ones prefixed by >>):

   In file included from include/linux/printk.h:331:0,
                    from include/linux/kernel.h:14,
                    from include/linux/clk.h:16,
                    from sound/soc/fsl/fsl_audmix.c:8:
   sound/soc/fsl/fsl_audmix.c: In function 'fsl_audmix_state_trans':
   include/linux/dynamic_debug.h:80:13: error: initializer element is not constant
      .format = (fmt),    \
                ^
   include/linux/dynamic_debug.h:111:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA_KEY'
     DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, 0, 0)
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:133:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA'
     DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);  \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/device.h:1473:2: note: in expansion of macro 'dynamic_dev_dbg'
     dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
     ^~~~~~~~~~~~~~~
>> sound/soc/fsl/fsl_audmix.c:93:3: note: in expansion of macro 'dev_dbg'
      dev_dbg(comp->dev, prm.msg);
      ^~~~~~~
   include/linux/dynamic_debug.h:80:13: note: (near initialization for 'descriptor.format')
      .format = (fmt),    \
                ^
   include/linux/dynamic_debug.h:111:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA_KEY'
     DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, 0, 0)
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:133:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA'
     DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);  \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/device.h:1473:2: note: in expansion of macro 'dynamic_dev_dbg'
     dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
     ^~~~~~~~~~~~~~~
>> sound/soc/fsl/fsl_audmix.c:93:3: note: in expansion of macro 'dev_dbg'
      dev_dbg(comp->dev, prm.msg);
      ^~~~~~~

vim +/dev_dbg +93 sound/soc/fsl/fsl_audmix.c

    85	
    86	static int fsl_audmix_state_trans(struct snd_soc_component *comp,
    87					  unsigned int *mask, unsigned int *ctr,
    88					  const struct fsl_audmix_state prm)
    89	{
    90		struct fsl_audmix *priv = snd_soc_component_get_drvdata(comp);
    91		/* Enforce all required TDMs are started */
    92		if ((priv->tdms & prm.tdms) != prm.tdms) {
  > 93			dev_dbg(comp->dev, prm.msg);
    94			return -EINVAL;
    95		}
    96	
    97		switch (prm.clk) {
    98		case 1:
    99		case 2:
   100			/* Set mix clock */
   101			(*mask) |= FSL_AUDMIX_CTR_MIXCLK_MASK;
   102			(*ctr)  |= FSL_AUDMIX_CTR_MIXCLK(prm.clk - 1);
   103			break;
   104		default:
   105			break;
   106		}
   107	
   108		return 0;
   109	}
   110	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 49979 bytes --]

^ permalink raw reply

* Re: [PATCH RESEND v5 1/3] ASoC: fsl: Add Audio Mixer CPU DAI driver
From: kbuild test robot @ 2019-03-04 20:23 UTC (permalink / raw)
  To: Viorel Suman
  Cc: Mark Rutland, devicetree@vger.kernel.org,
	alsa-devel@alsa-project.org, linuxppc-dev@lists.ozlabs.org,
	Timur Tabi, Xiubo Li, linux-kernel@vger.kernel.org, S.j. Wang,
	Takashi Iwai, Liam Girdwood, Rob Herring, Jaroslav Kysela,
	Nicolin Chen, Cosmin Samoila, Mark Brown, kbuild-all,
	Viorel Suman, Viorel Suman, Fabio Estevam, Daniel Baluta,
	dl-linux-imx
In-Reply-To: <1551695748-21541-2-git-send-email-viorel.suman@nxp.com>

[-- Attachment #1: Type: text/plain, Size: 6323 bytes --]

Hi Viorel,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on asoc/for-next]
[also build test ERROR on v5.0 next-20190304]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Viorel-Suman/Add-NXP-AUDMIX-device-and-machine-drivers/20190305-023038
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.2.0 make.cross ARCH=xtensa 

All errors (new ones prefixed by >>):

   In file included from include/linux/printk.h:331,
                    from include/linux/kernel.h:14,
                    from include/linux/clk.h:16,
                    from sound/soc/fsl/fsl_audmix.c:8:
   sound/soc/fsl/fsl_audmix.c: In function 'fsl_audmix_state_trans':
>> include/linux/dynamic_debug.h:80:13: error: initializer element is not constant
      .format = (fmt),    \
                ^
   include/linux/dynamic_debug.h:99:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA_KEY'
     DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:133:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA'
     DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);  \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/device.h:1473:2: note: in expansion of macro 'dynamic_dev_dbg'
     dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
     ^~~~~~~~~~~~~~~
   sound/soc/fsl/fsl_audmix.c:93:3: note: in expansion of macro 'dev_dbg'
      dev_dbg(comp->dev, prm.msg);
      ^~~~~~~
   include/linux/dynamic_debug.h:80:13: note: (near initialization for 'descriptor.format')
      .format = (fmt),    \
                ^
   include/linux/dynamic_debug.h:99:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA_KEY'
     DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:133:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA'
     DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);  \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/device.h:1473:2: note: in expansion of macro 'dynamic_dev_dbg'
     dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
     ^~~~~~~~~~~~~~~
   sound/soc/fsl/fsl_audmix.c:93:3: note: in expansion of macro 'dev_dbg'
      dev_dbg(comp->dev, prm.msg);
      ^~~~~~~
--
   In file included from include/linux/printk.h:331,
                    from include/linux/kernel.h:14,
                    from include/linux/clk.h:16,
                    from sound/soc//fsl/fsl_audmix.c:8:
   sound/soc//fsl/fsl_audmix.c: In function 'fsl_audmix_state_trans':
>> include/linux/dynamic_debug.h:80:13: error: initializer element is not constant
      .format = (fmt),    \
                ^
   include/linux/dynamic_debug.h:99:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA_KEY'
     DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:133:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA'
     DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);  \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/device.h:1473:2: note: in expansion of macro 'dynamic_dev_dbg'
     dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
     ^~~~~~~~~~~~~~~
   sound/soc//fsl/fsl_audmix.c:93:3: note: in expansion of macro 'dev_dbg'
      dev_dbg(comp->dev, prm.msg);
      ^~~~~~~
   include/linux/dynamic_debug.h:80:13: note: (near initialization for 'descriptor.format')
      .format = (fmt),    \
                ^
   include/linux/dynamic_debug.h:99:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA_KEY'
     DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, .key.dd_key_false, \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/dynamic_debug.h:133:2: note: in expansion of macro 'DEFINE_DYNAMIC_DEBUG_METADATA'
     DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);  \
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/device.h:1473:2: note: in expansion of macro 'dynamic_dev_dbg'
     dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
     ^~~~~~~~~~~~~~~
   sound/soc//fsl/fsl_audmix.c:93:3: note: in expansion of macro 'dev_dbg'
      dev_dbg(comp->dev, prm.msg);
      ^~~~~~~

vim +80 include/linux/dynamic_debug.h

ffa10cb4 Jason Baron 2011-08-11  68  
b9075fa9 Joe Perches 2011-10-31  69  extern __printf(3, 4)
906d2015 Joe Perches 2014-09-24  70  void __dynamic_netdev_dbg(struct _ddebug *descriptor,
ffa10cb4 Jason Baron 2011-08-11  71  			  const struct net_device *dev,
b9075fa9 Joe Perches 2011-10-31  72  			  const char *fmt, ...);
ffa10cb4 Jason Baron 2011-08-11  73  
9049fc74 Jason Baron 2016-08-03  74  #define DEFINE_DYNAMIC_DEBUG_METADATA_KEY(name, fmt, key, init)	\
c0d2af63 Joe Perches 2012-10-18  75  	static struct _ddebug  __aligned(8)			\
07613b0b Jason Baron 2011-10-04  76  	__attribute__((section("__verbose"))) name = {		\
07613b0b Jason Baron 2011-10-04  77  		.modname = KBUILD_MODNAME,			\
07613b0b Jason Baron 2011-10-04  78  		.function = __func__,				\
07613b0b Jason Baron 2011-10-04  79  		.filename = __FILE__,				\
07613b0b Jason Baron 2011-10-04 @80  		.format = (fmt),				\
07613b0b Jason Baron 2011-10-04  81  		.lineno = __LINE__,				\
07613b0b Jason Baron 2011-10-04  82  		.flags = _DPRINTK_FLAGS_DEFAULT,		\
9049fc74 Jason Baron 2016-08-03  83  		dd_key_init(key, init)				\
07613b0b Jason Baron 2011-10-04  84  	}
07613b0b Jason Baron 2011-10-04  85  

:::::: The code at line 80 was first introduced by commit
:::::: 07613b0b5ef8570033aa806d1731dce599862223 dynamic_debug: consolidate repetitive struct _ddebug descriptor definitions

:::::: TO: Jason Baron <jbaron@redhat.com>
:::::: CC: Greg Kroah-Hartman <gregkh@suse.de>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 56353 bytes --]

^ permalink raw reply

* [RFC v3] sched/topology: fix kernel crash when a CPU is hotplugged in a memoryless node
From: Laurent Vivier @ 2019-03-04 19:59 UTC (permalink / raw)
  To: linux-kernel
  Cc: Laurent Vivier, Srikar Dronamraju, Peter Zijlstra,
	Michael Bringmann, Ingo Molnar, Suravee Suthikulpanit,
	Nathan Fontenot, Borislav Petkov, linuxppc-dev, David Gibson

When we hotplug a CPU in a memoryless/cpuless node,
the kernel crashes when it rebuilds the sched_domains data.

I reproduce this problem on POWER and with a pseries VM, with the following
QEMU parameters:

  -machine pseries -enable-kvm -m 8192 \
  -smp 2,maxcpus=8,sockets=4,cores=2,threads=1 \
  -numa node,nodeid=0,cpus=0-1,mem=0 \
  -numa node,nodeid=1,cpus=2-3,mem=8192 \
  -numa node,nodeid=2,cpus=4-5,mem=0 \
  -numa node,nodeid=3,cpus=6-7,mem=0

Then I can trigger the crash by hotplugging a CPU on node-id 3:

  (qemu) device_add host-spapr-cpu-core,core-id=7,node-id=3

    Built 2 zonelists, mobility grouping on.  Total pages: 130162
    Policy zone: Normal
    WARNING: workqueue cpumask: online intersect > possible intersect
    BUG: Kernel NULL pointer dereference at 0x00000400
    Faulting instruction address: 0xc000000000170edc
    Oops: Kernel access of bad area, sig: 11 [#1]
    LE SMP NR_CPUS=2048 NUMA pSeries
    Modules linked in: ip6t_rpfilter ipt_REJECT nf_reject_ipv4 ip6t_REJECT nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ip6table_nat nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw iptable_nat nf_nat_ipv4 nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_mangle iptable_security iptable_raw ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter xts vmx_crypto ip_tables xfs libcrc32c virtio_net net_failover failover virtio_blk virtio_pci virtio_ring virtio dm_mirror dm_region_hash dm_log dm_mod
    CPU: 2 PID: 5661 Comm: kworker/2:0 Not tainted 5.0.0-rc6+ #20
    Workqueue: events cpuset_hotplug_workfn
    NIP:  c000000000170edc LR: c000000000170f98 CTR: 0000000000000000
    REGS: c000000003e931a0 TRAP: 0380   Not tainted  (5.0.0-rc6+)
    MSR:  8000000000009033 <SF,EE,ME,IR,DR,RI,LE>  CR: 22284028  XER: 00000000
    CFAR: c000000000170f20 IRQMASK: 0
    GPR00: c000000000170f98 c000000003e93430 c0000000011ac500 c0000001efe22000
    GPR04: 0000000000000001 0000000000000000 0000000000000000 0000000000000010
    GPR08: 0000000000000001 0000000000000400 ffffffffffffffff 0000000000000000
    GPR12: 0000000000008800 c00000003fffd680 c0000001f14b0000 c0000000011e1bf0
    GPR16: c0000000011e61f4 c0000001efe22200 c0000001efe22020 c0000001fba80000
    GPR20: c0000001ff567a80 0000000000000001 c000000000e27a80 ffffffffffffe830
    GPR24: ffffffffffffec30 000000000000102f 000000000000102f c0000001efca1000
    GPR28: c0000001efca0400 c0000001efe22000 c0000001efe23bff c0000001efe22a00
    NIP [c000000000170edc] free_sched_groups+0x5c/0xf0
    LR [c000000000170f98] destroy_sched_domain+0x28/0x90
    Call Trace:
    [c000000003e93430] [000000000000102f] 0x102f (unreliable)
    [c000000003e93470] [c000000000170f98] destroy_sched_domain+0x28/0x90
    [c000000003e934a0] [c0000000001716e0] cpu_attach_domain+0x100/0x920
    [c000000003e93600] [c000000000173128] build_sched_domains+0x1228/0x1370
    [c000000003e93740] [c00000000017429c] partition_sched_domains+0x23c/0x400
    [c000000003e937e0] [c0000000001f5ec8] rebuild_sched_domains_locked+0x78/0xe0
    [c000000003e93820] [c0000000001f9ff0] rebuild_sched_domains+0x30/0x50
    [c000000003e93850] [c0000000001fa1c0] cpuset_hotplug_workfn+0x1b0/0xb70
    [c000000003e93c80] [c00000000012e5a0] process_one_work+0x1b0/0x480
    [c000000003e93d20] [c00000000012e8f8] worker_thread+0x88/0x540
    [c000000003e93db0] [c00000000013714c] kthread+0x15c/0x1a0
    [c000000003e93e20] [c00000000000b55c] ret_from_kernel_thread+0x5c/0x80
    Instruction dump:
    2e240000 f8010010 f821ffc1 409e0014 48000080 7fbdf040 7fdff378 419e0074
    ebdf0000 4192002c e93f0010 7c0004ac <7d404828> 314affff 7d40492d 40c2fff4
    ---[ end trace f992c4a7d47d602a ]---

    Kernel panic - not syncing: Fatal exception

This happens in free_sched_groups() because the linked list of the
sched_groups is corrupted. Here what happens when we hotplug the CPU:

 - build_sched_groups() builds a sched_groups linked list for
   sched_domain D1, with only one entry A, refcount=1

   D1: A(ref=1)

 - build_sched_groups() builds a sched_groups linked list for
   sched_domain D2, with the same entry A

   D2: A(ref=2)

 - build_sched_groups() builds a sched_groups linked list for
   sched_domain D3, with the same entry A and a new entry B:

   D3: A(ref=3) -> B(ref=1)

 - destroy_sched_domain() is called for D1:

   D1: A(ref=3) -> B(ref=1) and as ref is 1, memory of B is released,
                                             but A->next always points to B

 - destroy_sched_domain() is called for D3:

   D3: A(ref=2) -> B(ref=0)

kernel crashes when it tries to use data inside B, as the memory has been
corrupted as it has been freed, the linked list (next) is broken too.

This problem appears with commit 051f3ca02e46
("sched/topology: Introduce NUMA identity node sched domain").

If I compare function calls sequence before and after this commit I can see
in the working case build_overlap_sched_groups() is called instead of
build_sched_groups() and in this case the reference counters have all the
same value and the linked list can be correctly unallocated.
The involved commit has introduced the node domain, and in the case of
powerpc the node domain can overlap, whereas it should not happen.

This happens because initially powerpc code computes
sched_domains_numa_masks of offline nodes as if they were merged with
node 0 (because firmware doesn't provide the distance information for
memoryless/cpuless nodes):

  node   0   1   2   3
    0:  10  40  10  10
    1:  40  10  40  40
    2:  10  40  10  10
    3:  10  40  10  10

We should have:

  node   0   1   2   3
    0:  10  40  40  40
    1:  40  10  40  40
    2:  40  40  10  40
    3:  40  40  40  10

And once a new CPU is added, node is onlined, numa masks are updated
but initial set bits are not cleared. This explains why nodes can overlap.

This patch changes the initial code to not initialize the distance for
offline nodes. The distances will be updated when node will become online
(on CPU hotplug) as it is already done.

This patch has been tested on powerpc but not on the other architectures.
They are impacted because the modified part is in the common code.
All comments are welcome (how to move the change to powerpc specific code
or if the other architectures can work with this change).

Fixes: 051f3ca02e46 ("sched/topology: Introduce NUMA identity node sched domain")
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Gibson <david@gibson.dropbear.id.au>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Cc: Michael Bringmann <mwb@linux.vnet.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---

Notes:
    v3: fix the root cause of the problem (sched numa mask initialization)
    v2: add scheduler maintainers in the CC: list

 kernel/sched/topology.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 3f35ba1d8fde..24831b86533b 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -1622,8 +1622,10 @@ void sched_init_numa(void)
 				return;
 
 			sched_domains_numa_masks[i][j] = mask;
+			if (!node_state(j, N_ONLINE))
+				continue;
 
-			for_each_node(k) {
+			for_each_online_node(k) {
 				if (node_distance(j, k) > sched_domains_numa_distance[i])
 					continue;
 
-- 
2.20.1


^ permalink raw reply related

* [PATCH] powerpc/hmi: Fix kernel hang when TB is in error state.
From: Mahesh J Salgaonkar @ 2019-03-04 19:42 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Stewart Smith

From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>

On TOD/TB errors timebase register stops/freezes until HMI error recovery
gets TOD/TB back into running state. On successful recovery, TB starts
running again and udelay() that relies on TB value continues to function
properly. But in case when HMI fails to recover from TOD/TB errors, the
TB register stay freezed. With TB not running the __delay() function
keeps looping and never return. If __delay() is called while in panic
path then system hangs and never reboots after panic.

Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
---
This patch has been tested with below skiboot changes:
http://patchwork.ozlabs.org/project/skiboot/list/?series=95315
---
 arch/powerpc/include/asm/opal-api.h            |   10 ++++++++++
 arch/powerpc/include/asm/opal.h                |    2 ++
 arch/powerpc/include/asm/time.h                |    2 ++
 arch/powerpc/kernel/time.c                     |    9 +++++++++
 arch/powerpc/platforms/powernv/opal-wrappers.S |    1 +
 arch/powerpc/platforms/powernv/opal.c          |   21 +++++++++++++++++++++
 arch/powerpc/platforms/powernv/setup.c         |    5 ++++-
 7 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h
index 870fb7b239ea..727c74c1693f 100644
--- a/arch/powerpc/include/asm/opal-api.h
+++ b/arch/powerpc/include/asm/opal-api.h
@@ -209,6 +209,7 @@
 #define OPAL_SENSOR_GROUP_ENABLE		163
 #define OPAL_PCI_GET_PBCQ_TUNNEL_BAR		164
 #define OPAL_PCI_SET_PBCQ_TUNNEL_BAR		165
+#define OPAL_HANDLE_HMI2			166
 #define	OPAL_NX_COPROC_INIT			167
 #define OPAL_LAST				167
 
@@ -634,6 +635,15 @@ struct OpalHMIEvent {
 	} u;
 };
 
+/* OPAL_HANDLE_HMI2 out_flags */
+enum {
+	OPAL_HMI_FLAGS_TB_RESYNC	= (1ull << 0), /* Timebase has been resynced */
+	OPAL_HMI_FLAGS_DEC_LOST		= (1ull << 1), /* DEC lost, needs to be reprogrammed */
+	OPAL_HMI_FLAGS_HDEC_LOST	= (1ull << 2), /* HDEC lost, needs to be reprogrammed */
+	OPAL_HMI_FLAGS_TOD_TB_FAIL	= (1ull << 3), /* TOD/TB recovery failed. */
+	OPAL_HMI_FLAGS_NEW_EVENT	= (1ull << 63), /* An event has been created */
+};
+
 enum {
 	OPAL_P7IOC_DIAG_TYPE_NONE	= 0,
 	OPAL_P7IOC_DIAG_TYPE_RGC	= 1,
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index a55b01c90bb1..7b0bc104a89c 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -203,6 +203,7 @@ int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer,
 int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data);
 int64_t opal_sensor_read_u64(u32 sensor_hndl, int token, __be64 *sensor_data);
 int64_t opal_handle_hmi(void);
+int64_t opal_handle_hmi2(__be64 *out_flags);
 int64_t opal_register_dump_region(uint32_t id, uint64_t start, uint64_t end);
 int64_t opal_unregister_dump_region(uint32_t id);
 int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val);
@@ -352,6 +353,7 @@ int opal_power_control_init(void);
 extern int opal_machine_check(struct pt_regs *regs);
 extern bool opal_mce_check_early_recovery(struct pt_regs *regs);
 extern int opal_hmi_exception_early(struct pt_regs *regs);
+extern int opal_hmi_exception_early2(struct pt_regs *regs);
 extern int opal_handle_hmi_exception(struct pt_regs *regs);
 
 extern void opal_shutdown(void);
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index 54bf7e68a7e1..57e968413d1e 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -36,6 +36,8 @@ extern unsigned long ppc_proc_freq;
 extern unsigned long ppc_tb_freq;
 #define DEFAULT_TB_FREQ		125000000UL
 
+extern bool tb_invalid;
+
 struct div_result {
 	u64 result_high;
 	u64 result_low;
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 3646affae963..523a6b455d8e 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -152,6 +152,8 @@ EXPORT_SYMBOL_GPL(ppc_proc_freq);
 unsigned long ppc_tb_freq;
 EXPORT_SYMBOL_GPL(ppc_tb_freq);
 
+bool tb_invalid;
+
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
 /*
  * Factor for converting from cputime_t (timebase ticks) to
@@ -461,6 +463,13 @@ void __delay(unsigned long loops)
 				diff += 1000000000;
 			spin_cpu_relax();
 		} while (diff < loops);
+	} else if (tb_invalid) {
+		/*
+		 * TB is in error state and isn't ticking anymore.
+		 * HMI handler was unable to recover from TB error.
+		 * Return immediately, so that kernel won't get stuck here.
+		 */
+		spin_cpu_relax();
 	} else {
 		start = get_tbl();
 		while (get_tbl() - start < loops)
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index f4875fe3f8ff..8ec43594aa1c 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -267,6 +267,7 @@ OPAL_CALL(opal_sensor_read,			OPAL_SENSOR_READ);
 OPAL_CALL(opal_get_param,			OPAL_GET_PARAM);
 OPAL_CALL(opal_set_param,			OPAL_SET_PARAM);
 OPAL_CALL(opal_handle_hmi,			OPAL_HANDLE_HMI);
+OPAL_CALL(opal_handle_hmi2,			OPAL_HANDLE_HMI2);
 OPAL_CALL(opal_config_cpu_idle_state,		OPAL_CONFIG_CPU_IDLE_STATE);
 OPAL_CALL(opal_slw_set_reg,			OPAL_SLW_SET_REG);
 OPAL_CALL(opal_register_dump_region,		OPAL_REGISTER_DUMP_REGION);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 79586f127521..e4adbcf89cf4 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -613,6 +613,27 @@ int opal_hmi_exception_early(struct pt_regs *regs)
 	return 0;
 }
 
+int opal_hmi_exception_early2(struct pt_regs *regs)
+{
+	s64 rc;
+	__be64 out_flags;
+
+	/*
+	 * call opal hmi handler.
+	 * Check 64-bit flag mask to find out if an event was generated,
+	 * and whether TB is still valid or not etc.
+	 */
+	rc = opal_handle_hmi2(&out_flags);
+	if (rc != OPAL_SUCCESS)
+		return 0;
+
+	if (be64_to_cpu(out_flags) & OPAL_HMI_FLAGS_NEW_EVENT)
+		local_paca->hmi_event_available = 1;
+	if (be64_to_cpu(out_flags) & OPAL_HMI_FLAGS_TOD_TB_FAIL)
+		tb_invalid = true;
+	return 1;
+}
+
 /* HMI exception handler called in virtual mode during check_irq_replay. */
 int opal_handle_hmi_exception(struct pt_regs *regs)
 {
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index 14befee4b3f1..3cf40f689aac 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -401,7 +401,10 @@ static void __init pnv_setup_machdep_opal(void)
 	/* ppc_md.system_reset_exception gets filled in by pnv_smp_init() */
 	ppc_md.machine_check_exception = opal_machine_check;
 	ppc_md.mce_check_early_recovery = opal_mce_check_early_recovery;
-	ppc_md.hmi_exception_early = opal_hmi_exception_early;
+	if (opal_check_token(OPAL_HANDLE_HMI2))
+		ppc_md.hmi_exception_early = opal_hmi_exception_early2;
+	else
+		ppc_md.hmi_exception_early = opal_hmi_exception_early;
 	ppc_md.handle_hmi_exception = opal_handle_hmi_exception;
 }
 


^ permalink raw reply related

* Re: [PULL REQUEST] powerpc generic command line
From: Daniel Walker @ 2019-03-04 18:11 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: linuxppc-dev, Andrew Morton, Paul Mackerras, xe-linux-external
In-Reply-To: <b804556b-9a2d-96a3-3e16-8ffbbd6006d4@c-s.fr>

On Mon, Mar 04, 2019 at 06:29:12PM +0100, Christophe Leroy wrote:
> 
> 
> Le 04/03/2019 à 17:57, Daniel Walker a écrit :
> > On Mon, Mar 04, 2019 at 02:55:08PM +0100, Christophe Leroy wrote:
> > > 
> > > 
> > > Le 01/03/2019 à 20:44, Daniel Walker a écrit :
> > > > Here are the generic command line changes for powerpc.
> > > > 
> > > > These changes have been in linux-next for two cycles, with few problems reported.
> > > > It's also been used at Cisco Systems, Inc. in production products for many many
> > > > years with no problems.
> > > > 
> > > > Please pull these changes.
> > > > 
> > > > 
> > > > The following changes since commit ccda4af0f4b92f7b4c308d3acc262f4a7e3affad:
> > > > 
> > > >     Linux 4.20-rc2 (2018-11-11 17:12:31 -0600)
> > > > 
> > > > are available in the git repository at:
> > > > 
> > > >     https://github.com/daniel-walker/cisco-linux.git for-powerpc
> > > > 
> > > > for you to fetch changes up to 5d4514a9c291ecf19b0626695161673d35e5d549:
> > > > 
> > > >     powerpc: convert config files to generic cmdline (2018-11-16 07:32:26 -0800)
> > > > 
> > > > ----------------------------------------------------------------
> > > > Daniel Walker (3):
> > > >         add generic builtin command line
> > > >         powerpc: convert to generic builtin command line
> > > >         powerpc: convert config files to generic cmdline
> > > 
> > > Hello,
> > > 
> > > This series is in total contradiction with the work being done to add KASAN
> > > support to powerpc.
> > > 
> > > It also modifies the behaviour for powerpc.
> > > 
> > > Please do not apply this series as is, see my comments on the individual
> > > patchs for details.
> > > 
> > 
> > Not trying to offend you, but you comments seems overly alarmist. KASAN is a
> > debug feature, generally we don't write code around debug features (especially
> > ones which aren't merged yet). It would not be hard to correct our use of string
> > functions when your KASAN enablement is merged, I'm sure you could do it, but I would be happy
> > to do it also. The other comments you had I don't think rise to the level of
> > stopping a pull request. Our code is stabilized, so I'm not going to
> > re-design it at a late date like this.
> > 
> > I think the pull request is still valid.
> > 
> 
> Ok, lets the KASAN stuff aside. And I agree I misread the patch when I felt
> that it was changing the behaviour in prom_init.c
> 
> I don't want to criticise your work either, but your series seems overkill.
> Anyway, could you explain your approach and what is the benefit of your
> series compared to what is already existing ?

Current behavior varies across different architectures. Some platforms prepend
the command line with the boot loader arguments some platforms append it. Cisco
uses all these platforms. We desire a method to either append or prepend on a
number of architectures. It reduces code duplication across multiple
architectures. It allows a number of other command line related features to be
added in a single location instead of across all architectures. For example MIPS
has some additional features added related to the command line arguments, this
could be made generic and available to all architectures.

> 
> Can you also explain how your changes fit with the what is done is the
> function early_init_dt_scan_chosen_ppc() in drivers/of/fdt.c as your series
> doesn't modify it ? (extract below)
> 
> 
> 
> 	/*
> 	 * CONFIG_CMDLINE is meant to be a default in case nothing else
> 	 * managed to set the command line, unless CONFIG_CMDLINE_FORCE
> 	 * is set in which case we override whatever was found earlier.
> 	 */
> #ifdef CONFIG_CMDLINE
> #if defined(CONFIG_CMDLINE_EXTEND)
> 	strlcat(data, " ", COMMAND_LINE_SIZE);
> 	strlcat(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
> #elif defined(CONFIG_CMDLINE_FORCE)
> 	strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
> #else
> 	/* No arguments from boot loader, use kernel's  cmdl*/
> 	if (!((char *)data)[0])
> 		strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
> #endif
> #endif /* CONFIG_CMDLINE */
 
Our code supersedes this code, and you can see the code is doing similar things.
Eventually this block will be replaced with a call into generic functions. We've
submitted changes to this code in the past,

https://lore.kernel.org/patchwork/patch/604997/

However, this code doesn't lend itself to piecemeal conversion to a generic
system. It's a generic system itself, but only for architectures/platforms with specific
characteristics. This is why we're doing it one at a time with PowerPC first.

> 
> 
> 
> What I like in your series is that you make the CMDLINE config common to all
> arches. But my feeling is that the 40 or so lines of code in your cmdline.h
> is way complex compared to what it aims to do, ie replacing a few lines on
> code in two places. But I might not have the complete picture so feel free
> to tell all the details behind it. I see you already submitted part of your
> series to the ppc list in Novembre
> (https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=75078)
> unfortunatly the first patch of the series was not there, and it seems at
> that time your series has not generated any further discussion.

Our code has been out there for years. I don't recall our first submission but
it was prior to last year.

Daniel

^ permalink raw reply

* Re: [PULL REQUEST] powerpc generic command line
From: Christophe Leroy @ 2019-03-04 17:29 UTC (permalink / raw)
  To: Daniel Walker
  Cc: linuxppc-dev, Andrew Morton, Paul Mackerras, xe-linux-external
In-Reply-To: <20190304165758.suqyact3tiueslqx@zorba>



Le 04/03/2019 à 17:57, Daniel Walker a écrit :
> On Mon, Mar 04, 2019 at 02:55:08PM +0100, Christophe Leroy wrote:
>>
>>
>> Le 01/03/2019 à 20:44, Daniel Walker a écrit :
>>> Here are the generic command line changes for powerpc.
>>>
>>> These changes have been in linux-next for two cycles, with few problems reported.
>>> It's also been used at Cisco Systems, Inc. in production products for many many
>>> years with no problems.
>>>
>>> Please pull these changes.
>>>
>>>
>>> The following changes since commit ccda4af0f4b92f7b4c308d3acc262f4a7e3affad:
>>>
>>>     Linux 4.20-rc2 (2018-11-11 17:12:31 -0600)
>>>
>>> are available in the git repository at:
>>>
>>>     https://github.com/daniel-walker/cisco-linux.git for-powerpc
>>>
>>> for you to fetch changes up to 5d4514a9c291ecf19b0626695161673d35e5d549:
>>>
>>>     powerpc: convert config files to generic cmdline (2018-11-16 07:32:26 -0800)
>>>
>>> ----------------------------------------------------------------
>>> Daniel Walker (3):
>>>         add generic builtin command line
>>>         powerpc: convert to generic builtin command line
>>>         powerpc: convert config files to generic cmdline
>>
>> Hello,
>>
>> This series is in total contradiction with the work being done to add KASAN
>> support to powerpc.
>>
>> It also modifies the behaviour for powerpc.
>>
>> Please do not apply this series as is, see my comments on the individual
>> patchs for details.
>>
> 
> Not trying to offend you, but you comments seems overly alarmist. KASAN is a
> debug feature, generally we don't write code around debug features (especially
> ones which aren't merged yet). It would not be hard to correct our use of string
> functions when your KASAN enablement is merged, I'm sure you could do it, but I would be happy
> to do it also. The other comments you had I don't think rise to the level of
> stopping a pull request. Our code is stabilized, so I'm not going to
> re-design it at a late date like this.
> 
> I think the pull request is still valid.
> 

Ok, lets the KASAN stuff aside. And I agree I misread the patch when I 
felt that it was changing the behaviour in prom_init.c

I don't want to criticise your work either, but your series seems 
overkill. Anyway, could you explain your approach and what is the 
benefit of your series compared to what is already existing ?

Can you also explain how your changes fit with the what is done is the 
function early_init_dt_scan_chosen_ppc() in drivers/of/fdt.c as your 
series doesn't modify it ? (extract below)



	/*
	 * CONFIG_CMDLINE is meant to be a default in case nothing else
	 * managed to set the command line, unless CONFIG_CMDLINE_FORCE
	 * is set in which case we override whatever was found earlier.
	 */
#ifdef CONFIG_CMDLINE
#if defined(CONFIG_CMDLINE_EXTEND)
	strlcat(data, " ", COMMAND_LINE_SIZE);
	strlcat(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
#elif defined(CONFIG_CMDLINE_FORCE)
	strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
#else
	/* No arguments from boot loader, use kernel's  cmdl*/
	if (!((char *)data)[0])
		strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
#endif
#endif /* CONFIG_CMDLINE */




What I like in your series is that you make the CMDLINE config common to 
all arches. But my feeling is that the 40 or so lines of code in your 
cmdline.h is way complex compared to what it aims to do, ie replacing a 
few lines on code in two places. But I might not have the complete 
picture so feel free to tell all the details behind it. I see you 
already submitted part of your series to the ppc list in Novembre 
(https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=75078) 
unfortunatly the first patch of the series was not there, and it seems 
at that time your series has not generated any further discussion.

Thanks
Christophe

^ permalink raw reply

* Re: [PULL REQUEST] powerpc generic command line
From: Daniel Walker @ 2019-03-04 16:57 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: linuxppc-dev, Andrew Morton, Paul Mackerras, xe-linux-external
In-Reply-To: <e80b18e3-92fe-3726-a7d7-72f98cdd0b86@c-s.fr>

On Mon, Mar 04, 2019 at 02:55:08PM +0100, Christophe Leroy wrote:
> 
> 
> Le 01/03/2019 à 20:44, Daniel Walker a écrit :
> > Here are the generic command line changes for powerpc.
> > 
> > These changes have been in linux-next for two cycles, with few problems reported.
> > It's also been used at Cisco Systems, Inc. in production products for many many
> > years with no problems.
> > 
> > Please pull these changes.
> > 
> > 
> > The following changes since commit ccda4af0f4b92f7b4c308d3acc262f4a7e3affad:
> > 
> >    Linux 4.20-rc2 (2018-11-11 17:12:31 -0600)
> > 
> > are available in the git repository at:
> > 
> >    https://github.com/daniel-walker/cisco-linux.git for-powerpc
> > 
> > for you to fetch changes up to 5d4514a9c291ecf19b0626695161673d35e5d549:
> > 
> >    powerpc: convert config files to generic cmdline (2018-11-16 07:32:26 -0800)
> > 
> > ----------------------------------------------------------------
> > Daniel Walker (3):
> >        add generic builtin command line
> >        powerpc: convert to generic builtin command line
> >        powerpc: convert config files to generic cmdline
> 
> Hello,
> 
> This series is in total contradiction with the work being done to add KASAN
> support to powerpc.
> 
> It also modifies the behaviour for powerpc.
> 
> Please do not apply this series as is, see my comments on the individual
> patchs for details.
> 

Not trying to offend you, but you comments seems overly alarmist. KASAN is a
debug feature, generally we don't write code around debug features (especially
ones which aren't merged yet). It would not be hard to correct our use of string
functions when your KASAN enablement is merged, I'm sure you could do it, but I would be happy
to do it also. The other comments you had I don't think rise to the level of
stopping a pull request. Our code is stabilized, so I'm not going to
re-design it at a late date like this.

I think the pull request is still valid.

Daniel

^ permalink raw reply

* Re: [PATCH 2/3] powerpc: convert to generic builtin command line
From: Christophe Leroy @ 2019-03-04 15:04 UTC (permalink / raw)
  To: Daniel Walker, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman
  Cc: xe-linux-external, linux-kernel, Maksym Kokhan, Daniel Walker,
	Andrew Morton, linuxppc-dev
In-Reply-To: <e6dc6500-0e33-da0c-c975-0d9125e38c0e@c-s.fr>



Le 04/03/2019 à 15:26, Christophe Leroy a écrit :
> 
> 
> Le 01/03/2019 à 20:44, Daniel Walker a écrit :
>> This updates the powerpc code to use the CONFIG_GENERIC_CMDLINE
>> option.
> 
> Please explain more in details how each powerpc option is replaced by 
> one of the generic options.
> 
>>
>> [maksym.kokhan@globallogic.com: add strlcat to prom_init_check.sh
>> whitelist]
>> Cc: Daniel Walker <dwalker@fifo99.com>
>> Cc: Daniel Walker <danielwa@cisco.com>
>> Cc: xe-linux-external@cisco.com
>> Signed-off-by: Daniel Walker <danielwa@cisco.com>
>> Signed-off-by: Maksym Kokhan <maksym.kokhan@globallogic.com>
>> ---
>>   arch/powerpc/Kconfig                   | 23 +----------------------
>>   arch/powerpc/kernel/prom.c             |  4 ++++
>>   arch/powerpc/kernel/prom_init.c        |  8 ++++----
>>   arch/powerpc/kernel/prom_init_check.sh |  2 +-
>>   4 files changed, 10 insertions(+), 27 deletions(-)
>>
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index 8be31261aec8..6321b2a0b87b 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -172,6 +172,7 @@ config PPC
>>       select GENERIC_STRNCPY_FROM_USER
>>       select GENERIC_STRNLEN_USER
>>       select GENERIC_TIME_VSYSCALL
>> +    select GENERIC_CMDLINE
>>       select HAVE_ARCH_AUDITSYSCALL
>>       select HAVE_ARCH_JUMP_LABEL
>>       select HAVE_ARCH_KGDB
>> @@ -777,28 +778,6 @@ config PPC_DENORMALISATION
>>         Add support for handling denormalisation of single precision
>>         values.  Useful for bare metal only.  If unsure say Y here.
>> -config CMDLINE_BOOL
>> -    bool "Default bootloader kernel arguments"
>> -
>> -config CMDLINE
>> -    string "Initial kernel command string"
>> -    depends on CMDLINE_BOOL
>> -    default "console=ttyS0,9600 console=tty0 root=/dev/sda2"
>> -    help
>> -      On some platforms, there is currently no way for the boot 
>> loader to
>> -      pass arguments to the kernel. For these platforms, you can supply
>> -      some command-line options at build time by entering them here.  In
>> -      most cases you will need to specify the root device here.
>> -
>> -config CMDLINE_FORCE
>> -    bool "Always use the default kernel command string"
>> -    depends on CMDLINE_BOOL
>> -    help
>> -      Always use the default kernel command string, even if the boot
>> -      loader passes other arguments to the kernel.
>> -      This is useful if you cannot or don't want to change the
>> -      command-line options your boot loader passes to the kernel.
>> -
>>   config EXTRA_TARGETS
>>       string "Additional default image types"
>>       help
>> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
>> index fe758cedb93f..d78b1d6fe1c8 100644
>> --- a/arch/powerpc/kernel/prom.c
>> +++ b/arch/powerpc/kernel/prom.c
>> @@ -34,6 +34,7 @@
>>   #include <linux/of_fdt.h>
>>   #include <linux/libfdt.h>
>>   #include <linux/cpu.h>
>> +#include <linux/cmdline.h>
>>   #include <asm/prom.h>
>>   #include <asm/rtas.h>
>> @@ -716,6 +717,9 @@ void __init early_init_devtree(void *params)
>>        */
>>       of_scan_flat_dt(early_init_dt_scan_chosen_ppc, boot_command_line);
>> +    /* append and prepend any arguments built into the kernel. */
>> +    cmdline_add_builtin(boot_command_line, NULL, COMMAND_LINE_SIZE);
>> +
> 
> I don't think it is worth an implementation as complex as in the 
> previous patch just for the above line.
> Could easily define the temporary buffer in this file directely, then 
> just locally do:
> 
> strlcpy(temp_buff, CONFIG_CMDLINE_PREPEND, COMMAND_LINE_SIZE);
> strlcat(temp_buff, boot_command_line, COMMAND_LINE_SIZE);
> strlcat(temp_buff, CONFIG_CMDLINE_APPEND, COMMAND_LINE_SIZE);
> strlcpy(boot_command_line, temp_buff, COMMAND_LINE_SIZE);

And in fact, what should really be done is not the above but simply 
update early_init_dt_scan_chosen_ppc() in drivers/of/fdt.c as it is 
there that CONFIG_CMDLINE and CONFIG_CMDLINE_FORCE and 
CONFIG_CMDLINE_EXTEND are handled.

It looks to me that the current implementation is rather complete and 
eventually only missing the prepend. Why not just add prepend to the 
current implementation, and also move CONFIG_CMDLINE etc ... into 
arch/Kconfig instead of having it in each arch ?

Christophe

> 
> 
> 
>>       /* Scan memory nodes and rebuild MEMBLOCKs */
>>       of_scan_flat_dt(early_init_dt_scan_root, NULL);
>>       of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
>> diff --git a/arch/powerpc/kernel/prom_init.c 
>> b/arch/powerpc/kernel/prom_init.c
>> index f33ff4163a51..e8e9fca22470 100644
>> --- a/arch/powerpc/kernel/prom_init.c
>> +++ b/arch/powerpc/kernel/prom_init.c
>> @@ -30,6 +30,7 @@
>>   #include <linux/delay.h>
>>   #include <linux/initrd.h>
>>   #include <linux/bitops.h>
>> +#include <linux/cmdline.h>
>>   #include <asm/prom.h>
>>   #include <asm/rtas.h>
>>   #include <asm/page.h>
>> @@ -637,11 +638,10 @@ static void __init early_cmdline_parse(void)
>>       p = prom_cmd_line;
>>       if ((long)prom.chosen > 0)
>>           l = prom_getprop(prom.chosen, "bootargs", p, 
>> COMMAND_LINE_SIZE-1);
>> -#ifdef CONFIG_CMDLINE
>> +
>>       if (l <= 0 || p[0] == '\0') /* dbl check */
>> -        strlcpy(prom_cmd_line,
>> -            CONFIG_CMDLINE, sizeof(prom_cmd_line));
>> -#endif /* CONFIG_CMDLINE */
>> +        cmdline_add_builtin_section(prom_cmd_line, NULL, 
>> sizeof(prom_cmd_line), __prombss);
>> +
> 
> You don't need something as complex as what your generic code does for 
> that. It could be done with the following simple line:
> 
> strlcpy(prom_cmd_line, CONFIG_CMDLINE_PREPEND " " CONFIG_CMDLINE_APPEND, 
> sizeof(prom_cmd_line));
> 
>>       prom_printf("command line: %s\n", prom_cmd_line);
>>   #ifdef CONFIG_PPC64
>> diff --git a/arch/powerpc/kernel/prom_init_check.sh 
>> b/arch/powerpc/kernel/prom_init_check.sh
>> index 667df97d2595..ab2acc8d8b5a 100644
>> --- a/arch/powerpc/kernel/prom_init_check.sh
>> +++ b/arch/powerpc/kernel/prom_init_check.sh
>> @@ -18,7 +18,7 @@
>>   WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
>>   _end enter_prom memcpy memset reloc_offset __secondary_hold
>> -__secondary_hold_acknowledge __secondary_hold_spinloop __start
>> +__secondary_hold_acknowledge __secondary_hold_spinloop __start strlcat
> 
> The above is a big issue. In the scope of KASAN implementation, we are 
> getting rid of generic string functions from prom_init because they are 
> KASAN instrumented and that's far too early for prom_init. See series 
> https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=94949 and 
> especially patch [v9,03/11] powerpc/prom_init: don't use string 
> functions from lib/
> 
>>   strcmp strcpy strlcpy strlen strncmp strstr kstrtobool 
>> logo_linux_clut224
>>   reloc_got2 kernstart_addr memstart_addr linux_banner _stext
>>   __prom_init_toc_start __prom_init_toc_end btext_setup_display TOC."
>>
> 
> Thanks
> Christophe

^ permalink raw reply

* Re: [PATCH 2/3] powerpc: convert to generic builtin command line
From: Christophe Leroy @ 2019-03-04 14:26 UTC (permalink / raw)
  To: Daniel Walker, Benjamin Herrenschmidt, Paul Mackerras,
	Michael Ellerman
  Cc: xe-linux-external, linux-kernel, Maksym Kokhan, Daniel Walker,
	Andrew Morton, linuxppc-dev
In-Reply-To: <1551469472-53043-3-git-send-email-danielwa@cisco.com>



Le 01/03/2019 à 20:44, Daniel Walker a écrit :
> This updates the powerpc code to use the CONFIG_GENERIC_CMDLINE
> option.

Please explain more in details how each powerpc option is replaced by 
one of the generic options.

> 
> [maksym.kokhan@globallogic.com: add strlcat to prom_init_check.sh
> whitelist]
> Cc: Daniel Walker <dwalker@fifo99.com>
> Cc: Daniel Walker <danielwa@cisco.com>
> Cc: xe-linux-external@cisco.com
> Signed-off-by: Daniel Walker <danielwa@cisco.com>
> Signed-off-by: Maksym Kokhan <maksym.kokhan@globallogic.com>
> ---
>   arch/powerpc/Kconfig                   | 23 +----------------------
>   arch/powerpc/kernel/prom.c             |  4 ++++
>   arch/powerpc/kernel/prom_init.c        |  8 ++++----
>   arch/powerpc/kernel/prom_init_check.sh |  2 +-
>   4 files changed, 10 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 8be31261aec8..6321b2a0b87b 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -172,6 +172,7 @@ config PPC
>   	select GENERIC_STRNCPY_FROM_USER
>   	select GENERIC_STRNLEN_USER
>   	select GENERIC_TIME_VSYSCALL
> +	select GENERIC_CMDLINE
>   	select HAVE_ARCH_AUDITSYSCALL
>   	select HAVE_ARCH_JUMP_LABEL
>   	select HAVE_ARCH_KGDB
> @@ -777,28 +778,6 @@ config PPC_DENORMALISATION
>   	  Add support for handling denormalisation of single precision
>   	  values.  Useful for bare metal only.  If unsure say Y here.
>   
> -config CMDLINE_BOOL
> -	bool "Default bootloader kernel arguments"
> -
> -config CMDLINE
> -	string "Initial kernel command string"
> -	depends on CMDLINE_BOOL
> -	default "console=ttyS0,9600 console=tty0 root=/dev/sda2"
> -	help
> -	  On some platforms, there is currently no way for the boot loader to
> -	  pass arguments to the kernel. For these platforms, you can supply
> -	  some command-line options at build time by entering them here.  In
> -	  most cases you will need to specify the root device here.
> -
> -config CMDLINE_FORCE
> -	bool "Always use the default kernel command string"
> -	depends on CMDLINE_BOOL
> -	help
> -	  Always use the default kernel command string, even if the boot
> -	  loader passes other arguments to the kernel.
> -	  This is useful if you cannot or don't want to change the
> -	  command-line options your boot loader passes to the kernel.
> -
>   config EXTRA_TARGETS
>   	string "Additional default image types"
>   	help
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index fe758cedb93f..d78b1d6fe1c8 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -34,6 +34,7 @@
>   #include <linux/of_fdt.h>
>   #include <linux/libfdt.h>
>   #include <linux/cpu.h>
> +#include <linux/cmdline.h>
>   
>   #include <asm/prom.h>
>   #include <asm/rtas.h>
> @@ -716,6 +717,9 @@ void __init early_init_devtree(void *params)
>   	 */
>   	of_scan_flat_dt(early_init_dt_scan_chosen_ppc, boot_command_line);
>   
> +	/* append and prepend any arguments built into the kernel. */
> +	cmdline_add_builtin(boot_command_line, NULL, COMMAND_LINE_SIZE);
> +

I don't think it is worth an implementation as complex as in the 
previous patch just for the above line.
Could easily define the temporary buffer in this file directely, then 
just locally do:

strlcpy(temp_buff, CONFIG_CMDLINE_PREPEND, COMMAND_LINE_SIZE);
strlcat(temp_buff, boot_command_line, COMMAND_LINE_SIZE);
strlcat(temp_buff, CONFIG_CMDLINE_APPEND, COMMAND_LINE_SIZE);
strlcpy(boot_command_line, temp_buff, COMMAND_LINE_SIZE);



>   	/* Scan memory nodes and rebuild MEMBLOCKs */
>   	of_scan_flat_dt(early_init_dt_scan_root, NULL);
>   	of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index f33ff4163a51..e8e9fca22470 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -30,6 +30,7 @@
>   #include <linux/delay.h>
>   #include <linux/initrd.h>
>   #include <linux/bitops.h>
> +#include <linux/cmdline.h>
>   #include <asm/prom.h>
>   #include <asm/rtas.h>
>   #include <asm/page.h>
> @@ -637,11 +638,10 @@ static void __init early_cmdline_parse(void)
>   	p = prom_cmd_line;
>   	if ((long)prom.chosen > 0)
>   		l = prom_getprop(prom.chosen, "bootargs", p, COMMAND_LINE_SIZE-1);
> -#ifdef CONFIG_CMDLINE
> +
>   	if (l <= 0 || p[0] == '\0') /* dbl check */
> -		strlcpy(prom_cmd_line,
> -			CONFIG_CMDLINE, sizeof(prom_cmd_line));
> -#endif /* CONFIG_CMDLINE */
> +		cmdline_add_builtin_section(prom_cmd_line, NULL, sizeof(prom_cmd_line), __prombss);
> +

You don't need something as complex as what your generic code does for 
that. It could be done with the following simple line:

strlcpy(prom_cmd_line, CONFIG_CMDLINE_PREPEND " " CONFIG_CMDLINE_APPEND, 
sizeof(prom_cmd_line));

>   	prom_printf("command line: %s\n", prom_cmd_line);
>   
>   #ifdef CONFIG_PPC64
> diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
> index 667df97d2595..ab2acc8d8b5a 100644
> --- a/arch/powerpc/kernel/prom_init_check.sh
> +++ b/arch/powerpc/kernel/prom_init_check.sh
> @@ -18,7 +18,7 @@
>   
>   WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
>   _end enter_prom memcpy memset reloc_offset __secondary_hold
> -__secondary_hold_acknowledge __secondary_hold_spinloop __start
> +__secondary_hold_acknowledge __secondary_hold_spinloop __start strlcat

The above is a big issue. In the scope of KASAN implementation, we are 
getting rid of generic string functions from prom_init because they are 
KASAN instrumented and that's far too early for prom_init. See series 
https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=94949 and 
especially patch [v9,03/11] powerpc/prom_init: don't use string 
functions from lib/

>   strcmp strcpy strlcpy strlen strncmp strstr kstrtobool logo_linux_clut224
>   reloc_got2 kernstart_addr memstart_addr linux_banner _stext
>   __prom_init_toc_start __prom_init_toc_end btext_setup_display TOC."
> 

Thanks
Christophe

^ permalink raw reply

* Re: [PATCH 1/3] add generic builtin command line
From: Christophe Leroy @ 2019-03-04 14:05 UTC (permalink / raw)
  To: Daniel Walker, Andrew Morton
  Cc: Maksym Kokhan, linux-kernel, Paul Mackerras, xe-linux-external,
	Daniel Walker, linuxppc-dev
In-Reply-To: <1551469472-53043-2-git-send-email-danielwa@cisco.com>



Le 01/03/2019 à 20:44, Daniel Walker a écrit :
> This code allows architectures to use a generic builtin command line.
> The state of the builtin command line options across architecture is
> diverse. On x86 and mips they have pretty much the same code and the
> code prepends the builtin command line onto the boot loader provided
> one. On powerpc there is only a builtin override and nothing else.
> 
> The code in this commit unifies the mips and x86 code into a generic
> header file under the CONFIG_GENERIC_CMDLINE option. When this
> option is enabled the architecture can call the cmdline_add_builtin()
> to add the builtin command line.
> 
> [maksym.kokhan@globallogic.com: fix cmdline_add_builtin() macro]
> Cc: Daniel Walker <dwalker@fifo99.com>
> Cc: Daniel Walker <danielwa@cisco.com>
> Cc: xe-linux-external@cisco.com
> Signed-off-by: Daniel Walker <danielwa@cisco.com>
> Signed-off-by: Maksym Kokhan <maksym.kokhan@globallogic.com>
> ---
>   include/linux/cmdline.h | 72 +++++++++++++++++++++++++++++++++++++++++++++++++
>   init/Kconfig            | 69 +++++++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 141 insertions(+)
>   create mode 100644 include/linux/cmdline.h
> 
> diff --git a/include/linux/cmdline.h b/include/linux/cmdline.h
> new file mode 100644
> index 000000000000..126fa52f55d2
> --- /dev/null
> +++ b/include/linux/cmdline.h
> @@ -0,0 +1,72 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef _LINUX_CMDLINE_H
> +#define _LINUX_CMDLINE_H
> +
> +/*
> + *
> + * Copyright (C) 2015. Cisco Systems, Inc.
> + *
> + * Generic Append/Prepend cmdline support.
> + */
> +
> +#if defined(CONFIG_GENERIC_CMDLINE) && defined(CONFIG_CMDLINE_BOOL)
> +
> +#ifndef CONFIG_CMDLINE_OVERRIDE
> +/*
> + * This function will append or prepend a builtin command line to the command
> + * line provided by the bootloader. Kconfig options can be used to alter
> + * the behavior of this builtin command line.
> + * @dest: The destination of the final appended/prepended string
> + * @src: The starting string or NULL if there isn't one.
> + * @tmp: temporary space used for prepending
> + * @length: the maximum length of the strings above.
> + */
> +static inline void
> +_cmdline_add_builtin(char *dest, char *src, char *tmp, unsigned long length)
> +{
> +	if (src != dest && src != NULL) {
> +		strlcpy(dest, " ", length);

Why prepend a space here ?

> +		strlcat(dest, src, length);
> +	}
> +
> +	strlcat(dest, " ", length);

Why a space here ? When there is nothing to append, there is no need of 
a space here. The space could simply be concatenated below in from of 
CONFIG_CMDLINE_APPEND

> +
> +	if (sizeof(CONFIG_CMDLINE_APPEND) > 1)
> +		strlcat(dest, CONFIG_CMDLINE_APPEND, length);
> +
> +	if (sizeof(CONFIG_CMDLINE_PREPEND) > 1) {
> +		strlcpy(tmp, CONFIG_CMDLINE_PREPEND, length);
> +		strlcat(tmp, " ", length);

Why not concatenate the space to above, ie:
strlcpy(tmp, CONFIG_CMDLINE_PREPEND " ", length);

> +		strlcat(tmp, dest, length);
> +		strlcpy(dest, tmp, length);
> +	}
> +}
> +
> +#define cmdline_add_builtin_section(dest, src, length, section) 	    \
> +{									    \
> +	if (sizeof(CONFIG_CMDLINE_PREPEND) > 1) {			    \
> +		static char cmdline_tmp_space[length] section;	            \
> +		_cmdline_add_builtin(dest, src, cmdline_tmp_space, length); \
> +	} else {							    \
> +		_cmdline_add_builtin(dest, src, NULL, length);		    \
> +	}								    \
> +}
> +#else
> +#define cmdline_add_builtin_section(dest, src, length, section) 	   \
> +{									   \
> +	strlcpy(dest, CONFIG_CMDLINE_PREPEND " " CONFIG_CMDLINE_APPEND,    \
> +		length);						   \
> +}
> +#endif /* !CONFIG_CMDLINE_OVERRIDE */
> +
> +#else
> +#define cmdline_add_builtin_section(dest, src, length, section) {          \
> +	if (src != NULL)						   \
> +		strlcpy(dest, src, length);				   \
> +}
> +#endif /* CONFIG_GENERIC_CMDLINE */
> +
> +#define cmdline_add_builtin(dest, src, length) \
> +	cmdline_add_builtin_section(dest, src, length, __initdata)

All those ifdefs are uggly, I don't think it is worth making something 
so complex just for the fun of getting something generic. See my 
comments to following patch.

> +
> +#endif /* _LINUX_CMDLINE_H */
> diff --git a/init/Kconfig b/init/Kconfig
> index a4112e95724a..b59e856511e1 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1775,6 +1775,75 @@ config PROFILING
>   config TRACEPOINTS
>   	bool
>   
> +config GENERIC_CMDLINE
> +	bool
> +
> +if GENERIC_CMDLINE
> +
> +config CMDLINE_BOOL
> +	bool "Built-in kernel command line"
> +	help
> +	  Allow for specifying boot arguments to the kernel at
> +	  build time.  On some systems (e.g. embedded ones), it is
> +	  necessary or convenient to provide some or all of the
> +	  kernel boot arguments with the kernel itself (that is,
> +	  to not rely on the boot loader to provide them.)
> +
> +	  To compile command line arguments into the kernel,
> +	  set this option to 'Y', then fill in the
> +	  the boot arguments in CONFIG_CMDLINE.
> +
> +	  Systems with fully functional boot loaders (i.e. non-embedded)
> +	  should leave this option set to 'N'.
> +
> +config CMDLINE_APPEND
> +	string "Built-in kernel command string append"
> +	depends on CMDLINE_BOOL

Would be better to remove this 'depends' and put the condition on the 
previous line. That way we would always have CONFIG_CMDLINE_APPEND and 
we could do something more simple in the code.

> +	default ""
> +	help
> +	  Enter arguments here that should be compiled into the kernel
> +	  image and used at boot time.  If the boot loader provides a
> +	  command line at boot time, this string is appended to it to
> +	  form the full kernel command line, when the system boots.
> +
> +	  However, you can use the CONFIG_CMDLINE_OVERRIDE option to
> +	  change this behavior.
> +
> +	  In most cases, the command line (whether built-in or provided
> +	  by the boot loader) should specify the device for the root
> +	  file system.
> +
> +config CMDLINE_PREPEND
> +	string "Built-in kernel command string prepend"
> +	depends on CMDLINE_BOOL

Would be better to remove this 'depends' and put the condition on the 
previous line. That way we would always have CONFIG_CMDLINE_APPEND and 
we could do something more simple in the code.

> +	default ""
> +	help
> +	  Enter arguments here that should be compiled into the kernel
> +	  image and used at boot time.  If the boot loader provides a
> +	  command line at boot time, this string is prepended to it to
> +	  form the full kernel command line, when the system boots.
> +
> +	  However, you can use the CONFIG_CMDLINE_OVERRIDE option to
> +	  change this behavior.
> +
> +	  In most cases, the command line (whether built-in or provided
> +	  by the boot loader) should specify the device for the root
> +	  file system.
> +
> +config CMDLINE_OVERRIDE
> +	bool "Built-in command line overrides boot loader arguments"
> +	depends on CMDLINE_BOOL
> +	help
> +	  Set this option to 'Y' to have the kernel ignore the boot loader
> +	  command line, and use ONLY the built-in command line. In this case
> +	  append and prepend strings are concatenated to form the full
> +	  command line.
> +
> +	  This is used to work around broken boot loaders.  This should
> +	  be set to 'N' under normal conditions.
> +
> +endif
> +
>   endmenu		# General setup
>   
>   source "arch/Kconfig"
> 

Christophe

^ permalink raw reply

* Re: [PULL REQUEST] powerpc generic command line
From: Christophe Leroy @ 2019-03-04 13:55 UTC (permalink / raw)
  To: Daniel Walker, Andrew Morton; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1551469472-53043-1-git-send-email-danielwa@cisco.com>



Le 01/03/2019 à 20:44, Daniel Walker a écrit :
> Here are the generic command line changes for powerpc.
> 
> These changes have been in linux-next for two cycles, with few problems reported.
> It's also been used at Cisco Systems, Inc. in production products for many many
> years with no problems.
> 
> Please pull these changes.
> 
> 
> The following changes since commit ccda4af0f4b92f7b4c308d3acc262f4a7e3affad:
> 
>    Linux 4.20-rc2 (2018-11-11 17:12:31 -0600)
> 
> are available in the git repository at:
> 
>    https://github.com/daniel-walker/cisco-linux.git for-powerpc
> 
> for you to fetch changes up to 5d4514a9c291ecf19b0626695161673d35e5d549:
> 
>    powerpc: convert config files to generic cmdline (2018-11-16 07:32:26 -0800)
> 
> ----------------------------------------------------------------
> Daniel Walker (3):
>        add generic builtin command line
>        powerpc: convert to generic builtin command line
>        powerpc: convert config files to generic cmdline

Hello,

This series is in total contradiction with the work being done to add 
KASAN support to powerpc.

It also modifies the behaviour for powerpc.

Please do not apply this series as is, see my comments on the individual 
patchs for details.

Thanks
Christophe

> 
>   arch/powerpc/Kconfig                          | 23 +--------
>   arch/powerpc/configs/44x/fsp2_defconfig       | 29 ++++++-----
>   arch/powerpc/configs/44x/iss476-smp_defconfig | 24 ++++-----
>   arch/powerpc/configs/44x/warp_defconfig       | 12 ++---
>   arch/powerpc/configs/holly_defconfig          | 12 ++---
>   arch/powerpc/configs/mvme5100_defconfig       | 25 +++++-----
>   arch/powerpc/configs/skiroot_defconfig        | 48 +++++++++---------
>   arch/powerpc/configs/storcenter_defconfig     | 15 +++---
>   arch/powerpc/kernel/prom.c                    |  4 ++
>   arch/powerpc/kernel/prom_init.c               |  8 +--
>   arch/powerpc/kernel/prom_init_check.sh        |  2 +-
>   include/linux/cmdline.h                       | 72 +++++++++++++++++++++++++++
>   init/Kconfig                                  | 69 +++++++++++++++++++++++++
>   13 files changed, 231 insertions(+), 112 deletions(-)
>   create mode 100644 include/linux/cmdline.h
> 

^ permalink raw reply

* Re: [PATCH 5/8] iio/counter: add FlexTimer Module Quadrature decoder counter driver
From: Patrick Havelange @ 2019-03-04 12:36 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Mark Rutland, devicetree, Lars-Peter Clausen, linux-pwm,
	linux-iio, linux-kernel, Linus Walleij, Daniel Lezcano,
	William Breathitt Gray, Li Yang, linuxppc-dev, Rob Herring,
	Thierry Reding, linux-arm-kernel, Peter Meerwald-Stadler,
	Hartmut Knaack, Thomas Gleixner, Shawn Guo, Esben Haabendal
In-Reply-To: <20190220164154.00547a77@archlinux>

On Wed, Feb 20, 2019 at 5:42 PM Jonathan Cameron <jic23@kernel.org> wrote:
[skipped]
> > +
> > +struct ftm_quaddec {
> > +     struct platform_device *pdev;
> > +     void __iomem *ftm_base;
> > +     bool big_endian;
>
> I'm curious. What is the benefit of running in big endian mode?

It is based on the same behaviour as in drivers/clocksource/timer-fsl-ftm.c
The FlexTimer itself on the board I'm testing it with is working in
big endian mode, so this mode is required.

> > +static ssize_t ftm_write_reset(struct iio_dev *indio_dev,
> > +                             uintptr_t private,
> > +                             struct iio_chan_spec const *chan,
> > +                             const char *buf, size_t len)
> > +{
> > +     struct ftm_quaddec *ftm = iio_priv(indio_dev);
> > +
> > +     /* Only "counter reset" is supported for now */
> > +     if (!sysfs_streq(buf, "0")) {
> > +             dev_warn(&ftm->pdev->dev, "Reset only accepts '0'\n");
> > +             return -EINVAL;
>
> Why not just make the channel attribute itself writeable given we are
> setting it to 0?

Good idea, I'll see if this can be applied in the new subsystem.

[skipped]

All other comments are Acked.

^ permalink raw reply

* Re: [PATCH 2/6] ptrace: introduce ptrace_syscall_enter to consolidate PTRACE_SYSEMU handling
From: Sudeep Holla @ 2019-03-04 12:27 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Haibo Xu (Arm Technology China), Steve Capper, Catalin Marinas,
	jdike@addtoit.com, x86@kernel.org, Will Deacon,
	linux-kernel@vger.kernel.org, Oleg Nesterov, Ingo Molnar,
	Paul Mackerras, Richard Weinberger, Thomas Gleixner,
	Bin Lu (Arm Technology China), linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190304122331.GG3969@gate.crashing.org>

On Mon, Mar 04, 2019 at 06:23:32AM -0600, Segher Boessenkool wrote:
> On Mon, Mar 04, 2019 at 10:46:43AM +0000, Sudeep Holla wrote:
> > On Mon, Mar 04, 2019 at 08:03:47AM +0000, Haibo Xu (Arm Technology China) wrote:
> > > On 2019/3/1 2:32, Sudeep Holla wrote:
> > > > +long ptrace_syscall_enter(struct pt_regs *regs)
> > > > +{
> > > > +#ifdef TIF_SYSCALL_EMU
> > > > +	if (test_thread_flag(TIF_SYSCALL_EMU)) {
> > > > +		if (tracehook_report_syscall_entry(regs));
> > >
> > > Shall we remove the semi-colon at end of the above line?
> >
> > Added intentionally to keep GCC happy.
>
> GCC warns because the user explicitly asked for it, with __must_check.
> If you want to do things with an "if" like this, you should write e.g.
>
> 		if (tracehook_report_syscall_entry(regs))
> 			/*
> 			 * We can ignore the return code here, because of
> 			 * X and Y and Z.
> 			 */
> 			;
>
> Or it probably is nicer to use a block:
>
> 		if (tracehook_report_syscall_entry(regs)) {
> 			/*
> 			 * We can ignore the return code here, because of
> 			 * X and Y and Z.
> 			 */
> 		}
>
> The point is, you *always* should have a nice fat comment if you are
> ignoring the return code of a __must_check function.
>

Agreed, will add the comment.

--
Regards,
Sudeep

^ permalink raw reply

* Re: [PATCH 2/6] ptrace: introduce ptrace_syscall_enter to consolidate PTRACE_SYSEMU handling
From: Segher Boessenkool @ 2019-03-04 12:23 UTC (permalink / raw)
  To: Sudeep Holla
  Cc: Haibo Xu (Arm Technology China), Steve Capper, Catalin Marinas,
	jdike@addtoit.com, x86@kernel.org, Will Deacon,
	linux-kernel@vger.kernel.org, Oleg Nesterov, Ingo Molnar,
	Paul Mackerras, Richard Weinberger, Thomas Gleixner,
	Bin Lu (Arm Technology China), linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190304104643.GA28643@e107155-lin>

On Mon, Mar 04, 2019 at 10:46:43AM +0000, Sudeep Holla wrote:
> On Mon, Mar 04, 2019 at 08:03:47AM +0000, Haibo Xu (Arm Technology China) wrote:
> > On 2019/3/1 2:32, Sudeep Holla wrote:
> > > +long ptrace_syscall_enter(struct pt_regs *regs)
> > > +{
> > > +#ifdef TIF_SYSCALL_EMU
> > > +	if (test_thread_flag(TIF_SYSCALL_EMU)) {
> > > +		if (tracehook_report_syscall_entry(regs));
> > 
> > Shall we remove the semi-colon at end of the above line?
> 
> Added intentionally to keep GCC happy.

GCC warns because the user explicitly asked for it, with __must_check.
If you want to do things with an "if" like this, you should write e.g.

		if (tracehook_report_syscall_entry(regs))
			/*
			 * We can ignore the return code here, because of
			 * X and Y and Z.
			 */
			;

Or it probably is nicer to use a block:

		if (tracehook_report_syscall_entry(regs)) {
			/*
			 * We can ignore the return code here, because of
			 * X and Y and Z.
			 */
		}

The point is, you *always* should have a nice fat comment if you are
ignoring the return code of a __must_check function.


Segher

^ permalink raw reply

* Re: [PATCH RFC v4 0/9] powerpc/powernv/pci: Make hotplug self-sufficient, independent of FW and DT
From: Oliver @ 2019-03-04 11:38 UTC (permalink / raw)
  To: Sergey Miroshnichenko
  Cc: Stewart Smith, Alexey Kardashevskiy, linux, linuxppc-dev
In-Reply-To: <20190301160440.26262-1-s.miroshnichenko@yadro.com>

On Sat, Mar 2, 2019 at 3:04 AM Sergey Miroshnichenko
<s.miroshnichenko@yadro.com> wrote:
>
> This patchset allows switching from the pnv_php module to the standard
> pciehp driver for PCIe hotplug functionality, if the platform supports it:
> PowerNV working on on top of the skiboot with the "core/pci: Sync VFs and
> the changes of bdfns between the firmware and the OS" patch serie applied.
>
> The feature is activated by the "pci=realloc" command line argument.
>
> The goal is ability to hotplug bridges full of devices in the future. The
> "Movable BARs" [1] is a platform-independent part of our work in this. The
> final part will be movable bus numbers to support inserting a bridge in the
> middle of an existing PCIe tree.
>
> Tested on POWER8 PowerNV+PHB3 ppc64le (our Vesnin server) with:
>  - the pciehp driver active;
>  - the pnv_php driver disabled;

Cool :)

I've had a brief look at this and it the approach seems reasonable.
I'll have a more detailed look and see how it fares on a P9 system
tomorrow.

>  - The "pci=realloc" argument is passed;
>  - surprise hotplug of an NVME disk works;
>  - controlled hotplug of a network card with SR-IOV works;
>  - activating of SR-IOV on a network card works;
>  - [with extra patches] manually initiated (via sysfs) rescan has found
>    and turned on a hotplugged bridge;
>  - Without "pci=realloc" works just as before.
>
> Changes since v3 [2]:
>  - Subject changed;
>  - Don't disable EEH during rescan anymore - instead just unfreeze the
>    target buses deliberately;
>  - Add synchronization with the firmware when changing the PCIe topology;
>  - Fixed for VFs;
>  - Code cleanup.
>
> Changes since v2:
>  - Don't reassign bus numbers on PowerNV by default (to retain the default
>    behavior), but only when pci=realloc is passed;
>  - Less code affected;
>  - pci_add_device_node_info is refactored with add_one_dev_pci_data;
>  - Minor code cleanup.
>
> Changes since v1:
>  - Fixed build for ppc64le and ppc64be when CONFIG_PCI_IOV is disabled;
>  - Fixed build for ppc64e when CONFIG_EEH is disabled;
>  - Fixed code style warnings.
>
> [1] https://www.spinics.net/lists/linux-pci/msg79995.html
> [2] https://lists.ozlabs.org/pipermail/linuxppc-dev/2018-September/178053.html
>
> Sergey Miroshnichenko (9):
>   powerpc/pci: Access PCI config space directly w/o pci_dn
>   powerpc/powernv/pci: Suppress an EEH error when reading an empty slot
>   powerpc/pci: Create pci_dn on demand
>   powerpc/pci: Reduce code duplication in pci_add_device_node_info
>   powerpc/powernv/ioda: Fix using uninitialized IOMMU group
>   powerpc/pci/IOV: Add support for runtime enabling the VFs
>   powerpc/pci: Don't rely on DT is the PCI_REASSIGN_ALL_BUS is set
>   powerpc/powernv/pci: Hook up the writes to PCI_SECONDARY_BUS register
>   powerpc/powernv/pci: Enable reassigning the bus numbers
>
>  arch/powerpc/include/asm/pci-bridge.h        |   2 +-
>  arch/powerpc/include/asm/ppc-pci.h           |   1 +
>  arch/powerpc/kernel/pci_dn.c                 | 164 +++++++++++----
>  arch/powerpc/kernel/rtas_pci.c               |  97 ++++++---
>  arch/powerpc/platforms/powernv/eeh-powernv.c |   2 +-
>  arch/powerpc/platforms/powernv/pci-ioda.c    |   5 +-
>  arch/powerpc/platforms/powernv/pci.c         | 208 +++++++++++++++++--
>  arch/powerpc/platforms/pseries/pci.c         |   2 +-
>  8 files changed, 381 insertions(+), 100 deletions(-)
>
> --
> 2.20.1
>

^ permalink raw reply

* Re: [PATCH] tools: testing: selftests: Remove duplicate headers
From: Souptick Joarder @ 2019-03-04 10:49 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: linux-fsdevel, John Stultz, Andrew Morton, linux-gpio,
	Peter Zijlstra, boqun.feng, linuxppc-dev, linux-kernel,
	David S. Miller, sboyd, Sabyasachi Gupta, Bamvor Zhang,
	linux-kselftest, netdev, Mathieu Desnoyers, Paul Mackerras,
	Thomas Gleixner, Paul McKenney, shuah, Alexey Dobriyan
In-Reply-To: <CAFqt6zY0HV7E+_6_s5A3eG+jEj+4hgQnAgJQm-Pc1gyX4Vnbpg@mail.gmail.com>

On Tue, Feb 26, 2019 at 10:59 AM Souptick Joarder <jrdr.linux@gmail.com> wrote:
>
> On Tue, Feb 26, 2019 at 7:18 AM Michael Ellerman <mpe@ellerman.id.au> wrote:
> >
> > Souptick Joarder <jrdr.linux@gmail.com> writes:
> > > Remove duplicate headers which are included twice.
> > >
> > > Signed-off-by: Sabyasachi Gupta <sabyasachi.linux@gmail.com>
> > > Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
> > > ---
> > ...
> > >  tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c | 1 -
> >
> > I took this hunk via the powerpc tree.
>
> How about taking this entirely through a single tree ?
> or Shall I send these changes in different patches ?

If no comment, can we get this patch in queue for 5.1 ?

>
> >
> > > diff --git a/tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c b/tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c
> > > index 167135b..af1b802 100644
> > > --- a/tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c
> > > +++ b/tools/testing/selftests/powerpc/pmu/ebb/fork_cleanup_test.c
> > > @@ -11,7 +11,6 @@
> > >  #include <sys/wait.h>
> > >  #include <unistd.h>
> > >  #include <setjmp.h>
> > > -#include <signal.h>
> > >
> > >  #include "ebb.h"
> >
> >
> > cheers

^ permalink raw reply

* Re: [PATCH 2/6] ptrace: introduce ptrace_syscall_enter to consolidate PTRACE_SYSEMU handling
From: Sudeep Holla @ 2019-03-04 10:46 UTC (permalink / raw)
  To: Haibo Xu (Arm Technology China)
  Cc: Steve Capper, Catalin Marinas, jdike@addtoit.com, x86@kernel.org,
	Will Deacon, linux-kernel@vger.kernel.org, Oleg Nesterov,
	Richard Weinberger, Ingo Molnar, Paul Mackerras, Thomas Gleixner,
	Bin Lu (Arm Technology China), linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <f3441e63-c54d-3b9d-2919-8a3955cbee69@arm.com>

On Mon, Mar 04, 2019 at 08:03:47AM +0000, Haibo Xu (Arm Technology China) wrote:
> On 2019/3/1 2:32, Sudeep Holla wrote:
> > Currently each architecture handles PTRACE_SYSEMU in very similar way.
> > It's completely arch independent and can be handled in the code helping
> > to consolidate PTRACE_SYSEMU handling.
> > 
> > Let's introduce a hook 'ptrace_syscall_enter' that arch specific syscall
> > entry code can call.
> > 
> 
> The 'ptrace_syscall_enter' is dedicated for PTRACE_SYSEMU flag,
> So I suggest to rename the function to something like 'ptrace_syscall_emu_enter".
> 

I am fine to rename.

> > +/*
> > + * Hook to check and report for PTRACE_SYSEMU, can be called from arch
> > + * arch syscall entry code
> > + */
> > +long ptrace_syscall_enter(struct pt_regs *regs)
> > +{
> > +#ifdef TIF_SYSCALL_EMU
> > +	if (test_thread_flag(TIF_SYSCALL_EMU)) {
> > +		if (tracehook_report_syscall_entry(regs));
> 
> Shall we remove the semi-colon at end of the above line?
> 

Added intentionally to keep GCC happy.

--
Regards,
Sudeep

^ permalink raw reply

* Re: [PATCH 4/6] powerpc: use common ptrace_syscall_enter hook to handle _TIF_SYSCALL_EMU
From: Sudeep Holla @ 2019-03-04 10:42 UTC (permalink / raw)
  To: Haibo Xu (Arm Technology China)
  Cc: Sudeep Holla, Steve Capper, Catalin Marinas, jdike@addtoit.com,
	x86@kernel.org, Will Deacon, linux-kernel@vger.kernel.org,
	Oleg Nesterov, Richard Weinberger, Ingo Molnar, Paul Mackerras,
	Thomas Gleixner, Bin Lu (Arm Technology China),
	linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <247371ae-3360-95e2-bf1d-21eb9332c31c@arm.com>

On Mon, Mar 04, 2019 at 09:36:27AM +0000, Haibo Xu (Arm Technology China) wrote:
> On 2019/3/1 2:32, Sudeep Holla wrote:
> > Now that we have a new hook ptrace_syscall_enter that can be called from
> > syscall entry code and it handles PTRACE_SYSEMU in generic code, we
> > can do some cleanup using the same in do_syscall_trace_enter.
> >
> > Cc: Oleg Nesterov <oleg@redhat.com>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> > ---
> >  arch/powerpc/kernel/ptrace.c | 50 ++++++++++++++++--------------------
> >  1 file changed, 22 insertions(+), 28 deletions(-)
> >
> > diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> > index cb7e1439cafb..978cd2aac29e 100644
> > --- a/arch/powerpc/kernel/ptrace.c
> > +++ b/arch/powerpc/kernel/ptrace.c
> > @@ -3264,37 +3264,31 @@ long do_syscall_trace_enter(struct pt_regs *regs)
> >  {
> >  	u32 flags;
> >
> > -	user_exit();
>
> We'd better keep the user_exit() at here in case both context tracking and
> SYSCALL_EMU are enabled.
>

Ah right, spurious change will fix it.

--
Regards,
Sudeep

^ permalink raw reply

* [PATCH RESEND v5 3/3] ASoC: fsl: Add Audio Mixer machine driver
From: Viorel Suman @ 2019-03-04 10:36 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
	Jaroslav Kysela, Takashi Iwai, Timur Tabi, Nicolin Chen, Xiubo Li,
	Fabio Estevam, Viorel Suman, S.j. Wang, Daniel Baluta,
	Cosmin Samoila
  Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
	linux-kernel@vger.kernel.org, Viorel Suman, dl-linux-imx,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1551695748-21541-1-git-send-email-viorel.suman@nxp.com>

This patch implements Audio Mixer machine driver for NXP iMX8 SOCs.
It connects together Audio Mixer and related SAI instances.

Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
 sound/soc/fsl/Kconfig      |   9 ++
 sound/soc/fsl/Makefile     |   2 +
 sound/soc/fsl/imx-audmix.c | 327 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 338 insertions(+)
 create mode 100644 sound/soc/fsl/imx-audmix.c

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 0af2e056..d87c842 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -303,6 +303,15 @@ config SND_SOC_FSL_ASOC_CARD
 	 CS4271, CS4272 and SGTL5000.
 	 Say Y if you want to add support for Freescale Generic ASoC Sound Card.
 
+config SND_SOC_IMX_AUDMIX
+	tristate "SoC Audio support for i.MX boards with AUDMIX"
+	select SND_SOC_FSL_AUDMIX
+	select SND_SOC_FSL_SAI
+	help
+	  SoC Audio support for i.MX boards with Audio Mixer
+	  Say Y if you want to add support for SoC audio on an i.MX board with
+	  an Audio Mixer.
+
 endif # SND_IMX_SOC
 
 endmenu
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 4172d5a..c0dd044 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -62,6 +62,7 @@ snd-soc-imx-es8328-objs := imx-es8328.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
 snd-soc-imx-spdif-objs := imx-spdif.o
 snd-soc-imx-mc13783-objs := imx-mc13783.o
+snd-soc-imx-audmix-objs := imx-audmix.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
@@ -71,3 +72,4 @@ obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
 obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
+obj-$(CONFIG_SND_SOC_IMX_AUDMIX) += snd-soc-imx-audmix.o
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
new file mode 100644
index 0000000..72e37ca
--- /dev/null
+++ b/sound/soc/fsl/imx-audmix.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017 NXP
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/pm_runtime.h>
+#include "fsl_sai.h"
+#include "fsl_audmix.h"
+
+struct imx_audmix {
+	struct platform_device *pdev;
+	struct snd_soc_card card;
+	struct platform_device *audmix_pdev;
+	struct platform_device *out_pdev;
+	struct clk *cpu_mclk;
+	int num_dai;
+	struct snd_soc_dai_link *dai;
+	int num_dai_conf;
+	struct snd_soc_codec_conf *dai_conf;
+	int num_dapm_routes;
+	struct snd_soc_dapm_route *dapm_routes;
+};
+
+static const u32 imx_audmix_rates[] = {
+	8000, 12000, 16000, 24000, 32000, 48000, 64000, 96000,
+};
+
+static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = {
+	.count = ARRAY_SIZE(imx_audmix_rates),
+	.list = imx_audmix_rates,
+};
+
+static int imx_audmix_fe_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct imx_audmix *priv = snd_soc_card_get_drvdata(rtd->card);
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct device *dev = rtd->card->dev;
+	unsigned long clk_rate = clk_get_rate(priv->cpu_mclk);
+	int ret;
+
+	if (clk_rate % 24576000 == 0) {
+		ret = snd_pcm_hw_constraint_list(runtime, 0,
+						 SNDRV_PCM_HW_PARAM_RATE,
+						 &imx_audmix_rate_constraints);
+		if (ret < 0)
+			return ret;
+	} else {
+		dev_warn(dev, "mclk may be not supported %lu\n", clk_rate);
+	}
+
+	ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
+					   1, 8);
+	if (ret < 0)
+		return ret;
+
+	return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
+					    FSL_AUDMIX_FORMATS);
+}
+
+static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct device *dev = rtd->card->dev;
+	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+	u32 channels = params_channels(params);
+	int ret, dir;
+
+	/* For playback the AUDMIX is slave, and for record is master */
+	fmt |= tx ? SND_SOC_DAIFMT_CBS_CFS : SND_SOC_DAIFMT_CBM_CFM;
+	dir  = tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN;
+
+	/* set DAI configuration */
+	ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt);
+	if (ret) {
+		dev_err(dev, "failed to set cpu dai fmt: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, FSL_SAI_CLK_MAST1, 0, dir);
+	if (ret) {
+		dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * Per datasheet, AUDMIX expects 8 slots and 32 bits
+	 * for every slot in TDM mode.
+	 */
+	ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, BIT(channels) - 1,
+				       BIT(channels) - 1, 8, 32);
+	if (ret)
+		dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+
+	return ret;
+}
+
+static int imx_audmix_be_hw_params(struct snd_pcm_substream *substream,
+				   struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct device *dev = rtd->card->dev;
+	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+	int ret;
+
+	if (!tx)
+		return 0;
+
+	/* For playback the AUDMIX is slave */
+	fmt |= SND_SOC_DAIFMT_CBM_CFM;
+
+	/* set AUDMIX DAI configuration */
+	ret = snd_soc_dai_set_fmt(rtd->cpu_dai, fmt);
+	if (ret)
+		dev_err(dev, "failed to set AUDMIX DAI fmt: %d\n", ret);
+
+	return ret;
+}
+
+static struct snd_soc_ops imx_audmix_fe_ops = {
+	.startup = imx_audmix_fe_startup,
+	.hw_params = imx_audmix_fe_hw_params,
+};
+
+static struct snd_soc_ops imx_audmix_be_ops = {
+	.hw_params = imx_audmix_be_hw_params,
+};
+
+static int imx_audmix_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *audmix_np = NULL, *out_cpu_np = NULL;
+	struct platform_device *audmix_pdev = NULL;
+	struct platform_device *cpu_pdev;
+	struct of_phandle_args args;
+	struct imx_audmix *priv;
+	int i, num_dai, ret;
+	const char *fe_name_pref = "HiFi-AUDMIX-FE-";
+	char *be_name, *be_pb, *be_cp, *dai_name, *capture_dai_name;
+
+	if (pdev->dev.parent) {
+		audmix_np = pdev->dev.parent->of_node;
+	} else {
+		dev_err(&pdev->dev, "Missing parent device.\n");
+		return -EINVAL;
+	}
+
+	if (!audmix_np) {
+		dev_err(&pdev->dev, "Missign DT node for parent device.\n");
+		return -EINVAL;
+	}
+
+	audmix_pdev = of_find_device_by_node(audmix_np);
+	if (!audmix_pdev) {
+		dev_err(&pdev->dev, "Missing AUDMIX platform device for %s\n",
+			np->full_name);
+		return -EINVAL;
+	}
+
+	num_dai = of_count_phandle_with_args(audmix_np, "dais", NULL);
+	if (num_dai != FSL_AUDMIX_MAX_DAIS) {
+		dev_err(&pdev->dev, "Need 2 dais to be provided for %s\n",
+			audmix_np->full_name);
+		return -EINVAL;
+	}
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->num_dai = 2 * num_dai;
+	priv->dai = devm_kzalloc(&pdev->dev, priv->num_dai *
+				 sizeof(struct snd_soc_dai_link), GFP_KERNEL);
+	if (!priv->dai)
+		return -ENOMEM;
+
+	priv->num_dai_conf = num_dai;
+	priv->dai_conf = devm_kzalloc(&pdev->dev, priv->num_dai_conf *
+				      sizeof(struct snd_soc_codec_conf),
+				      GFP_KERNEL);
+	if (!priv->dai_conf)
+		return -ENOMEM;
+
+	priv->num_dapm_routes = 3 * num_dai;
+	priv->dapm_routes = devm_kzalloc(&pdev->dev, priv->num_dapm_routes *
+					 sizeof(struct snd_soc_dapm_route),
+					 GFP_KERNEL);
+	if (!priv->dapm_routes)
+		return -ENOMEM;
+
+	for (i = 0; i < num_dai; i++) {
+		ret = of_parse_phandle_with_args(audmix_np, "dais", NULL, i,
+						 &args);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "of_parse_phandle_with_args failed\n");
+			return ret;
+		}
+
+		cpu_pdev = of_find_device_by_node(args.np);
+		if (!cpu_pdev) {
+			dev_err(&pdev->dev, "failed to find SAI platform device\n");
+			return -EINVAL;
+		}
+
+		dai_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s%s",
+					  fe_name_pref, args.np->full_name + 1);
+
+		dev_info(pdev->dev.parent, "DAI FE name:%s\n", dai_name);
+
+		if (i == 0) {
+			out_cpu_np = args.np;
+			capture_dai_name =
+				devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
+					       dai_name, "CPU-Capture");
+		}
+
+		priv->dai[i].name = dai_name;
+		priv->dai[i].stream_name = "HiFi-AUDMIX-FE";
+		priv->dai[i].codec_dai_name = "snd-soc-dummy-dai";
+		priv->dai[i].codec_name = "snd-soc-dummy";
+		priv->dai[i].cpu_of_node = args.np;
+		priv->dai[i].cpu_dai_name = dev_name(&cpu_pdev->dev);
+		priv->dai[i].platform_of_node = args.np;
+		priv->dai[i].dynamic = 1;
+		priv->dai[i].dpcm_playback = 1;
+		priv->dai[i].dpcm_capture = (i == 0 ? 1 : 0);
+		priv->dai[i].ignore_pmdown_time = 1;
+		priv->dai[i].ops = &imx_audmix_fe_ops;
+
+		/* Add AUDMIX Backend */
+		be_name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+					 "audmix-%d", i);
+		be_pb = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+				       "AUDMIX-Playback-%d", i);
+		be_cp = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+				       "AUDMIX-Capture-%d", i);
+
+		priv->dai[num_dai + i].name = be_name;
+		priv->dai[num_dai + i].codec_dai_name = "snd-soc-dummy-dai";
+		priv->dai[num_dai + i].codec_name = "snd-soc-dummy";
+		priv->dai[num_dai + i].cpu_of_node = audmix_np;
+		priv->dai[num_dai + i].cpu_dai_name = be_name;
+		priv->dai[num_dai + i].platform_name = "snd-soc-dummy";
+		priv->dai[num_dai + i].no_pcm = 1;
+		priv->dai[num_dai + i].dpcm_playback = 1;
+		priv->dai[num_dai + i].dpcm_capture  = 1;
+		priv->dai[num_dai + i].ignore_pmdown_time = 1;
+		priv->dai[num_dai + i].ops = &imx_audmix_be_ops;
+
+		priv->dai_conf[i].of_node = args.np;
+		priv->dai_conf[i].name_prefix = dai_name;
+
+		priv->dapm_routes[i].source =
+			devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s %s",
+				       dai_name, "CPU-Playback");
+		priv->dapm_routes[i].sink = be_pb;
+		priv->dapm_routes[num_dai + i].source   = be_pb;
+		priv->dapm_routes[num_dai + i].sink     = be_cp;
+		priv->dapm_routes[2 * num_dai + i].source = be_cp;
+		priv->dapm_routes[2 * num_dai + i].sink   = capture_dai_name;
+	}
+
+	cpu_pdev = of_find_device_by_node(out_cpu_np);
+	if (!cpu_pdev) {
+		dev_err(&pdev->dev, "failed to find SAI platform device\n");
+		return -EINVAL;
+	}
+	priv->cpu_mclk = devm_clk_get(&cpu_pdev->dev, "mclk1");
+	if (IS_ERR(priv->cpu_mclk)) {
+		ret = PTR_ERR(priv->cpu_mclk);
+		dev_err(&cpu_pdev->dev, "failed to get DAI mclk1: %d\n", ret);
+		return -EINVAL;
+	}
+
+	priv->audmix_pdev = audmix_pdev;
+	priv->out_pdev  = cpu_pdev;
+
+	priv->card.dai_link = priv->dai;
+	priv->card.num_links = priv->num_dai;
+	priv->card.codec_conf = priv->dai_conf;
+	priv->card.num_configs = priv->num_dai_conf;
+	priv->card.dapm_routes = priv->dapm_routes;
+	priv->card.num_dapm_routes = priv->num_dapm_routes;
+	priv->card.dev = pdev->dev.parent;
+	priv->card.owner = THIS_MODULE;
+	priv->card.name = "imx-audmix";
+
+	platform_set_drvdata(pdev, &priv->card);
+	snd_soc_card_set_drvdata(&priv->card, priv);
+
+	ret = devm_snd_soc_register_card(pdev->dev.parent, &priv->card);
+	if (ret) {
+		dev_err(&pdev->dev, "snd_soc_register_card failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static struct platform_driver imx_audmix_driver = {
+	.probe = imx_audmix_probe,
+	.driver = {
+		.name = "imx-audmix",
+		.pm = &snd_soc_pm_ops,
+	},
+};
+module_platform_driver(imx_audmix_driver);
+
+MODULE_DESCRIPTION("NXP AUDMIX ASoC machine driver");
+MODULE_AUTHOR("Viorel Suman <viorel.suman@nxp.com>");
+MODULE_ALIAS("platform:imx-audmix");
+MODULE_LICENSE("GPL v2");
-- 
2.7.4


^ permalink raw reply related

* [PATCH RESEND v5 2/3] ASoC: add fsl_audmix DT binding documentation
From: Viorel Suman @ 2019-03-04 10:36 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
	Jaroslav Kysela, Takashi Iwai, Timur Tabi, Nicolin Chen, Xiubo Li,
	Fabio Estevam, Viorel Suman, S.j. Wang, Daniel Baluta,
	Cosmin Samoila
  Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
	linux-kernel@vger.kernel.org, Viorel Suman, dl-linux-imx,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1551695748-21541-1-git-send-email-viorel.suman@nxp.com>

Add the DT binding documentation for NXP Audio Mixer
CPU DAI driver.

Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/sound/fsl,audmix.txt       | 50 ++++++++++++++++++++++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt

diff --git a/Documentation/devicetree/bindings/sound/fsl,audmix.txt b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
new file mode 100644
index 0000000..840b7e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
@@ -0,0 +1,50 @@
+NXP Audio Mixer (AUDMIX).
+
+The Audio Mixer is a on-chip functional module that allows mixing of two
+audio streams into a single audio stream. Audio Mixer has two input serial
+audio interfaces. These are driven by two Synchronous Audio interface
+modules (SAI). Each input serial interface carries 8 audio channels in its
+frame in TDM manner. Mixer mixes audio samples of corresponding channels
+from two interfaces into a single sample. Before mixing, audio samples of
+two inputs can be attenuated based on configuration. The output of the
+Audio Mixer is also a serial audio interface. Like input interfaces it has
+the same TDM frame format. This output is used to drive the serial DAC TDM
+interface of audio codec and also sent to the external pins along with the
+receive path of normal audio SAI module for readback by the CPU.
+
+The output of Audio Mixer can be selected from any of the three streams
+ - serial audio input 1
+ - serial audio input 2
+ - mixed audio
+
+Mixing operation is independent of audio sample rate but the two audio
+input streams must have same audio sample rate with same number of channels
+in TDM frame to be eligible for mixing.
+
+Device driver required properties:
+=================================
+  - compatible		: Compatible list, contains "fsl,imx8qm-audmix"
+
+  - reg			: Offset and length of the register set for the device.
+
+  - clocks		: Must contain an entry for each entry in clock-names.
+
+  - clock-names		: Must include the "ipg" for register access.
+
+  - power-domains	: Must contain the phandle to AUDMIX power domain node
+
+  - dais		: Must contain a list of phandles to AUDMIX connected
+			  DAIs. The current implementation requires two phandles
+			  to SAI interfaces to be provided, the first SAI in the
+			  list being used to route the AUDMIX output.
+
+Device driver configuration example:
+======================================
+  audmix: audmix@59840000 {
+    compatible = "fsl,imx8qm-audmix";
+    reg = <0x0 0x59840000 0x0 0x10000>;
+    clocks = <&clk IMX8QXP_AUD_AUDMIX_IPG>;
+    clock-names = "ipg";
+    power-domains = <&pd_audmix>;
+    dais = <&sai4>, <&sai5>;
+  };
-- 
2.7.4


^ permalink raw reply related

* [PATCH RESEND v5 1/3] ASoC: fsl: Add Audio Mixer CPU DAI driver
From: Viorel Suman @ 2019-03-04 10:36 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
	Jaroslav Kysela, Takashi Iwai, Timur Tabi, Nicolin Chen, Xiubo Li,
	Fabio Estevam, Viorel Suman, S.j. Wang, Daniel Baluta,
	Cosmin Samoila
  Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
	linux-kernel@vger.kernel.org, Viorel Suman, dl-linux-imx,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <1551695748-21541-1-git-send-email-viorel.suman@nxp.com>

This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
The Audio Mixer is a on-chip functional module that allows mixing of
two audio streams into a single audio stream.

Audio Mixer datasheet is available here:
https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf

Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
 sound/soc/fsl/Kconfig      |   7 +
 sound/soc/fsl/Makefile     |   3 +
 sound/soc/fsl/fsl_audmix.c | 578 +++++++++++++++++++++++++++++++++++++++++++++
 sound/soc/fsl/fsl_audmix.h | 102 ++++++++
 4 files changed, 690 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 7b1d997..0af2e056 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,6 +24,13 @@ config SND_SOC_FSL_SAI
 	  This option is only useful for out-of-tree drivers since
 	  in-tree drivers select it automatically.
 
+config SND_SOC_FSL_AUDMIX
+	tristate "Audio Mixer (AUDMIX) module support"
+	select REGMAP_MMIO
+	help
+	  Say Y if you want to add Audio Mixer (AUDMIX)
+	  support for the NXP iMX CPUs.
+
 config SND_SOC_FSL_SSI
 	tristate "Synchronous Serial Interface module (SSI) support"
 	select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 3c0ff31..4172d5a 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -12,6 +12,7 @@ snd-soc-p1022-rdk-objs := p1022_rdk.o
 obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
 
 # Freescale SSI/DMA/SAI/SPDIF Support
+snd-soc-fsl-audmix-objs := fsl_audmix.o
 snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
 snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
 snd-soc-fsl-sai-objs := fsl_sai.o
@@ -22,6 +23,8 @@ snd-soc-fsl-esai-objs := fsl_esai.o
 snd-soc-fsl-micfil-objs := fsl_micfil.o
 snd-soc-fsl-utils-objs := fsl_utils.o
 snd-soc-fsl-dma-objs := fsl_dma.o
+
+obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o
 obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
 obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
 obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
new file mode 100644
index 0000000..07b72a3
--- /dev/null
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -0,0 +1,578 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP AUDMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+
+#include "fsl_audmix.h"
+
+#define SOC_ENUM_SINGLE_S(xreg, xshift, xtexts) \
+	SOC_ENUM_SINGLE(xreg, xshift, ARRAY_SIZE(xtexts), xtexts)
+
+static const char
+	*tdm_sel[] = { "TDM1", "TDM2", },
+	*mode_sel[] = { "Disabled", "TDM1", "TDM2", "Mixed", },
+	*width_sel[] = { "16b", "18b", "20b", "24b", "32b", },
+	*endis_sel[] = { "Disabled", "Enabled", },
+	*updn_sel[] = { "Downward", "Upward", },
+	*mask_sel[] = { "Unmask", "Mask", };
+
+static const struct soc_enum fsl_audmix_enum[] = {
+/* FSL_AUDMIX_CTR enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MIXCLK_SHIFT, tdm_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTSRC_SHIFT, mode_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTWIDTH_SHIFT, width_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKRTDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKCKDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCMODE_SHIFT, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCSRC_SHIFT, tdm_sel),
+/* FSL_AUDMIX_ATCR0 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 1, updn_sel),
+/* FSL_AUDMIX_ATCR1 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 1, updn_sel),
+};
+
+struct fsl_audmix_state {
+	u8 tdms;
+	u8 clk;
+	char msg[64];
+};
+
+static const struct fsl_audmix_state prms[4][4] = {{
+	/* DIS->DIS, do nothing */
+	{ .tdms = 0, .clk = 0, .msg = "" },
+	/* DIS->TDM1*/
+	{ .tdms = 1, .clk = 1, .msg = "DIS->TDM1: TDM1 not started!\n" },
+	/* DIS->TDM2*/
+	{ .tdms = 2, .clk = 2, .msg = "DIS->TDM2: TDM2 not started!\n" },
+	/* DIS->MIX */
+	{ .tdms = 3, .clk = 0, .msg = "DIS->MIX: Please start both TDMs!\n" }
+}, {	/* TDM1->DIS */
+	{ .tdms = 1, .clk = 0, .msg = "TDM1->DIS: TDM1 not started!\n" },
+	/* TDM1->TDM1, do nothing */
+	{ .tdms = 0, .clk = 0, .msg = "" },
+	/* TDM1->TDM2 */
+	{ .tdms = 3, .clk = 2, .msg = "TDM1->TDM2: Please start both TDMs!\n" },
+	/* TDM1->MIX */
+	{ .tdms = 3, .clk = 0, .msg = "TDM1->MIX: Please start both TDMs!\n" }
+}, {	/* TDM2->DIS */
+	{ .tdms = 2, .clk = 0, .msg = "TDM2->DIS: TDM2 not started!\n" },
+	/* TDM2->TDM1 */
+	{ .tdms = 3, .clk = 1, .msg = "TDM2->TDM1: Please start both TDMs!\n" },
+	/* TDM2->TDM2, do nothing */
+	{ .tdms = 0, .clk = 0, .msg = "" },
+	/* TDM2->MIX */
+	{ .tdms = 3, .clk = 0, .msg = "TDM2->MIX: Please start both TDMs!\n" }
+}, {	/* MIX->DIS */
+	{ .tdms = 3, .clk = 0, .msg = "MIX->DIS: Please start both TDMs!\n" },
+	/* MIX->TDM1 */
+	{ .tdms = 3, .clk = 1, .msg = "MIX->TDM1: Please start both TDMs!\n" },
+	/* MIX->TDM2 */
+	{ .tdms = 3, .clk = 2, .msg = "MIX->TDM2: Please start both TDMs!\n" },
+	/* MIX->MIX, do nothing */
+	{ .tdms = 0, .clk = 0, .msg = "" }
+}, };
+
+static int fsl_audmix_state_trans(struct snd_soc_component *comp,
+				  unsigned int *mask, unsigned int *ctr,
+				  const struct fsl_audmix_state prm)
+{
+	struct fsl_audmix *priv = snd_soc_component_get_drvdata(comp);
+	/* Enforce all required TDMs are started */
+	if ((priv->tdms & prm.tdms) != prm.tdms) {
+		dev_dbg(comp->dev, prm.msg);
+		return -EINVAL;
+	}
+
+	switch (prm.clk) {
+	case 1:
+	case 2:
+		/* Set mix clock */
+		(*mask) |= FSL_AUDMIX_CTR_MIXCLK_MASK;
+		(*ctr)  |= FSL_AUDMIX_CTR_MIXCLK(prm.clk - 1);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int fsl_audmix_put_mix_clk_src(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+	struct fsl_audmix *priv = snd_soc_component_get_drvdata(comp);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int *item = ucontrol->value.enumerated.item;
+	unsigned int reg_val, val, mix_clk;
+	int ret = 0;
+
+	/* Get current state */
+	ret = snd_soc_component_read(comp, FSL_AUDMIX_CTR, &reg_val);
+	if (ret)
+		return ret;
+
+	mix_clk = ((reg_val & FSL_AUDMIX_CTR_MIXCLK_MASK)
+			>> FSL_AUDMIX_CTR_MIXCLK_SHIFT);
+	val = snd_soc_enum_item_to_val(e, item[0]);
+
+	dev_dbg(comp->dev, "TDMs=x%08x, val=x%08x\n", priv->tdms, val);
+
+	/**
+	 * Ensure the current selected mixer clock is available
+	 * for configuration propagation
+	 */
+	if (!(priv->tdms & BIT(mix_clk))) {
+		dev_err(comp->dev,
+			"Started TDM%d needed for config propagation!\n",
+			mix_clk + 1);
+		return -EINVAL;
+	}
+
+	if (!(priv->tdms & BIT(val))) {
+		dev_err(comp->dev,
+			"The selected clock source has no TDM%d enabled!\n",
+			val + 1);
+		return -EINVAL;
+	}
+
+	return snd_soc_put_enum_double(kcontrol, ucontrol);
+}
+
+static int fsl_audmix_put_out_src(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+	struct fsl_audmix *priv = snd_soc_component_get_drvdata(comp);
+	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+	unsigned int *item = ucontrol->value.enumerated.item;
+	u32 out_src, mix_clk;
+	unsigned int reg_val, val, mask = 0, ctr = 0;
+	int ret = 0;
+
+	/* Get current state */
+	ret = snd_soc_component_read(comp, FSL_AUDMIX_CTR, &reg_val);
+	if (ret)
+		return ret;
+
+	/* "From" state */
+	out_src = ((reg_val & FSL_AUDMIX_CTR_OUTSRC_MASK)
+			>> FSL_AUDMIX_CTR_OUTSRC_SHIFT);
+	mix_clk = ((reg_val & FSL_AUDMIX_CTR_MIXCLK_MASK)
+			>> FSL_AUDMIX_CTR_MIXCLK_SHIFT);
+
+	/* "To" state */
+	val = snd_soc_enum_item_to_val(e, item[0]);
+
+	dev_dbg(comp->dev, "TDMs=x%08x, val=x%08x\n", priv->tdms, val);
+
+	/* Check if state is changing ... */
+	if (out_src == val)
+		return 0;
+	/**
+	 * Ensure the current selected mixer clock is available
+	 * for configuration propagation
+	 */
+	if (!(priv->tdms & BIT(mix_clk))) {
+		dev_err(comp->dev,
+			"Started TDM%d needed for config propagation!\n",
+			mix_clk + 1);
+		return -EINVAL;
+	}
+
+	/* Check state transition constraints */
+	ret = fsl_audmix_state_trans(comp, &mask, &ctr, prms[out_src][val]);
+	if (ret)
+		return ret;
+
+	/* Complete transition to new state */
+	mask |= FSL_AUDMIX_CTR_OUTSRC_MASK;
+	ctr  |= FSL_AUDMIX_CTR_OUTSRC(val);
+
+	return snd_soc_component_update_bits(comp, FSL_AUDMIX_CTR, mask, ctr);
+}
+
+static const struct snd_kcontrol_new fsl_audmix_snd_controls[] = {
+	/* FSL_AUDMIX_CTR controls */
+	SOC_ENUM_EXT("Mixing Clock Source", fsl_audmix_enum[0],
+		     snd_soc_get_enum_double, fsl_audmix_put_mix_clk_src),
+	SOC_ENUM_EXT("Output Source", fsl_audmix_enum[1],
+		     snd_soc_get_enum_double, fsl_audmix_put_out_src),
+	SOC_ENUM("Output Width", fsl_audmix_enum[2]),
+	SOC_ENUM("Frame Rate Diff Error", fsl_audmix_enum[3]),
+	SOC_ENUM("Clock Freq Diff Error", fsl_audmix_enum[4]),
+	SOC_ENUM("Sync Mode Config", fsl_audmix_enum[5]),
+	SOC_ENUM("Sync Mode Clk Source", fsl_audmix_enum[6]),
+	/* TDM1 Attenuation controls */
+	SOC_ENUM("TDM1 Attenuation", fsl_audmix_enum[7]),
+	SOC_ENUM("TDM1 Attenuation Direction", fsl_audmix_enum[8]),
+	SOC_SINGLE("TDM1 Attenuation Step Divider", FSL_AUDMIX_ATCR0,
+		   2, 0x00fff, 0),
+	SOC_SINGLE("TDM1 Attenuation Initial Value", FSL_AUDMIX_ATIVAL0,
+		   0, 0x3ffff, 0),
+	SOC_SINGLE("TDM1 Attenuation Step Up Factor", FSL_AUDMIX_ATSTPUP0,
+		   0, 0x3ffff, 0),
+	SOC_SINGLE("TDM1 Attenuation Step Down Factor", FSL_AUDMIX_ATSTPDN0,
+		   0, 0x3ffff, 0),
+	SOC_SINGLE("TDM1 Attenuation Step Target", FSL_AUDMIX_ATSTPTGT0,
+		   0, 0x3ffff, 0),
+	/* TDM2 Attenuation controls */
+	SOC_ENUM("TDM2 Attenuation", fsl_audmix_enum[9]),
+	SOC_ENUM("TDM2 Attenuation Direction", fsl_audmix_enum[10]),
+	SOC_SINGLE("TDM2 Attenuation Step Divider", FSL_AUDMIX_ATCR1,
+		   2, 0x00fff, 0),
+	SOC_SINGLE("TDM2 Attenuation Initial Value", FSL_AUDMIX_ATIVAL1,
+		   0, 0x3ffff, 0),
+	SOC_SINGLE("TDM2 Attenuation Step Up Factor", FSL_AUDMIX_ATSTPUP1,
+		   0, 0x3ffff, 0),
+	SOC_SINGLE("TDM2 Attenuation Step Down Factor", FSL_AUDMIX_ATSTPDN1,
+		   0, 0x3ffff, 0),
+	SOC_SINGLE("TDM2 Attenuation Step Target", FSL_AUDMIX_ATSTPTGT1,
+		   0, 0x3ffff, 0),
+};
+
+static int fsl_audmix_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct snd_soc_component *comp = dai->component;
+	u32 mask = 0, ctr = 0;
+
+	/* AUDMIX is working in DSP_A format only */
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_DSP_A:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* For playback the AUDMIX is slave, and for record is master */
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+	case SND_SOC_DAIFMT_CBS_CFS:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_IB_NF:
+		/* Output data will be written on positive edge of the clock */
+		ctr |= FSL_AUDMIX_CTR_OUTCKPOL(0);
+		break;
+	case SND_SOC_DAIFMT_NB_NF:
+		/* Output data will be written on negative edge of the clock */
+		ctr |= FSL_AUDMIX_CTR_OUTCKPOL(1);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	mask |= FSL_AUDMIX_CTR_OUTCKPOL_MASK;
+
+	return snd_soc_component_update_bits(comp, FSL_AUDMIX_CTR, mask, ctr);
+}
+
+static int fsl_audmix_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+				  struct snd_soc_dai *dai)
+{
+	struct fsl_audmix *priv = snd_soc_dai_get_drvdata(dai);
+
+	/* Capture stream shall not be handled */
+	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+		return 0;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_RESUME:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+		priv->tdms |= BIT(dai->driver->id);
+		break;
+	case SNDRV_PCM_TRIGGER_STOP:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		priv->tdms &= ~BIT(dai->driver->id);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops fsl_audmix_dai_ops = {
+	.set_fmt      = fsl_audmix_dai_set_fmt,
+	.trigger      = fsl_audmix_dai_trigger,
+};
+
+static struct snd_soc_dai_driver fsl_audmix_dai[] = {
+	{
+		.id   = 0,
+		.name = "audmix-0",
+		.playback = {
+			.stream_name = "AUDMIX-Playback-0",
+			.channels_min = 8,
+			.channels_max = 8,
+			.rate_min = 8000,
+			.rate_max = 96000,
+			.rates = SNDRV_PCM_RATE_8000_96000,
+			.formats = FSL_AUDMIX_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AUDMIX-Capture-0",
+			.channels_min = 8,
+			.channels_max = 8,
+			.rate_min = 8000,
+			.rate_max = 96000,
+			.rates = SNDRV_PCM_RATE_8000_96000,
+			.formats = FSL_AUDMIX_FORMATS,
+		},
+		.ops = &fsl_audmix_dai_ops,
+	},
+	{
+		.id   = 1,
+		.name = "audmix-1",
+		.playback = {
+			.stream_name = "AUDMIX-Playback-1",
+			.channels_min = 8,
+			.channels_max = 8,
+			.rate_min = 8000,
+			.rate_max = 96000,
+			.rates = SNDRV_PCM_RATE_8000_96000,
+			.formats = FSL_AUDMIX_FORMATS,
+		},
+		.capture = {
+			.stream_name = "AUDMIX-Capture-1",
+			.channels_min = 8,
+			.channels_max = 8,
+			.rate_min = 8000,
+			.rate_max = 96000,
+			.rates = SNDRV_PCM_RATE_8000_96000,
+			.formats = FSL_AUDMIX_FORMATS,
+		},
+		.ops = &fsl_audmix_dai_ops,
+	},
+};
+
+static const struct snd_soc_component_driver fsl_audmix_component = {
+	.name		  = "fsl-audmix-dai",
+	.controls	  = fsl_audmix_snd_controls,
+	.num_controls	  = ARRAY_SIZE(fsl_audmix_snd_controls),
+};
+
+static bool fsl_audmix_readable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case FSL_AUDMIX_CTR:
+	case FSL_AUDMIX_STR:
+	case FSL_AUDMIX_ATCR0:
+	case FSL_AUDMIX_ATIVAL0:
+	case FSL_AUDMIX_ATSTPUP0:
+	case FSL_AUDMIX_ATSTPDN0:
+	case FSL_AUDMIX_ATSTPTGT0:
+	case FSL_AUDMIX_ATTNVAL0:
+	case FSL_AUDMIX_ATSTP0:
+	case FSL_AUDMIX_ATCR1:
+	case FSL_AUDMIX_ATIVAL1:
+	case FSL_AUDMIX_ATSTPUP1:
+	case FSL_AUDMIX_ATSTPDN1:
+	case FSL_AUDMIX_ATSTPTGT1:
+	case FSL_AUDMIX_ATTNVAL1:
+	case FSL_AUDMIX_ATSTP1:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool fsl_audmix_writeable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case FSL_AUDMIX_CTR:
+	case FSL_AUDMIX_ATCR0:
+	case FSL_AUDMIX_ATIVAL0:
+	case FSL_AUDMIX_ATSTPUP0:
+	case FSL_AUDMIX_ATSTPDN0:
+	case FSL_AUDMIX_ATSTPTGT0:
+	case FSL_AUDMIX_ATCR1:
+	case FSL_AUDMIX_ATIVAL1:
+	case FSL_AUDMIX_ATSTPUP1:
+	case FSL_AUDMIX_ATSTPDN1:
+	case FSL_AUDMIX_ATSTPTGT1:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static const struct reg_default fsl_audmix_reg[] = {
+	{ FSL_AUDMIX_CTR,       0x00060 },
+	{ FSL_AUDMIX_STR,       0x00003 },
+	{ FSL_AUDMIX_ATCR0,     0x00000 },
+	{ FSL_AUDMIX_ATIVAL0,   0x3FFFF },
+	{ FSL_AUDMIX_ATSTPUP0,  0x2AAAA },
+	{ FSL_AUDMIX_ATSTPDN0,  0x30000 },
+	{ FSL_AUDMIX_ATSTPTGT0, 0x00010 },
+	{ FSL_AUDMIX_ATTNVAL0,  0x00000 },
+	{ FSL_AUDMIX_ATSTP0,    0x00000 },
+	{ FSL_AUDMIX_ATCR1,     0x00000 },
+	{ FSL_AUDMIX_ATIVAL1,   0x3FFFF },
+	{ FSL_AUDMIX_ATSTPUP1,  0x2AAAA },
+	{ FSL_AUDMIX_ATSTPDN1,  0x30000 },
+	{ FSL_AUDMIX_ATSTPTGT1, 0x00010 },
+	{ FSL_AUDMIX_ATTNVAL1,  0x00000 },
+	{ FSL_AUDMIX_ATSTP1,    0x00000 },
+};
+
+static const struct regmap_config fsl_audmix_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = FSL_AUDMIX_ATSTP1,
+	.reg_defaults = fsl_audmix_reg,
+	.num_reg_defaults = ARRAY_SIZE(fsl_audmix_reg),
+	.readable_reg = fsl_audmix_readable_reg,
+	.writeable_reg = fsl_audmix_writeable_reg,
+	.cache_type = REGCACHE_FLAT,
+};
+
+static const struct of_device_id fsl_audmix_ids[] = {
+	{
+		.compatible = "fsl,imx8qm-audmix",
+		.data = "imx-audmix",
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_audmix_ids);
+
+static int fsl_audmix_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct fsl_audmix *priv;
+	struct resource *res;
+	const char *mdrv;
+	const struct of_device_id *of_id;
+	void __iomem *regs;
+	int ret;
+
+	of_id = of_match_device(fsl_audmix_ids, dev);
+	if (!of_id || !of_id->data)
+		return -EINVAL;
+
+	mdrv = of_id->data;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	/* Get the addresses */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	priv->regmap = devm_regmap_init_mmio_clk(dev, "ipg", regs,
+						 &fsl_audmix_regmap_config);
+	if (IS_ERR(priv->regmap)) {
+		dev_err(dev, "failed to init regmap\n");
+		return PTR_ERR(priv->regmap);
+	}
+
+	priv->ipg_clk = devm_clk_get(dev, "ipg");
+	if (IS_ERR(priv->ipg_clk)) {
+		dev_err(dev, "failed to get ipg clock\n");
+		return PTR_ERR(priv->ipg_clk);
+	}
+
+	platform_set_drvdata(pdev, priv);
+	pm_runtime_enable(dev);
+
+	ret = devm_snd_soc_register_component(dev, &fsl_audmix_component,
+					      fsl_audmix_dai,
+					      ARRAY_SIZE(fsl_audmix_dai));
+	if (ret) {
+		dev_err(dev, "failed to register ASoC DAI\n");
+		return ret;
+	}
+
+	priv->pdev = platform_device_register_data(dev, mdrv, 0, NULL, 0);
+	if (IS_ERR(priv->pdev)) {
+		ret = PTR_ERR(priv->pdev);
+		dev_err(dev, "failed to register platform %s: %d\n", mdrv, ret);
+	}
+
+	return ret;
+}
+
+static int fsl_audmix_remove(struct platform_device *pdev)
+{
+	struct fsl_audmix *priv = dev_get_drvdata(&pdev->dev);
+
+	if (priv->pdev)
+		platform_device_unregister(priv->pdev);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int fsl_audmix_runtime_resume(struct device *dev)
+{
+	struct fsl_audmix *priv = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(priv->ipg_clk);
+	if (ret) {
+		dev_err(dev, "Failed to enable IPG clock: %d\n", ret);
+		return ret;
+	}
+
+	regcache_cache_only(priv->regmap, false);
+	regcache_mark_dirty(priv->regmap);
+
+	return regcache_sync(priv->regmap);
+}
+
+static int fsl_audmix_runtime_suspend(struct device *dev)
+{
+	struct fsl_audmix *priv = dev_get_drvdata(dev);
+
+	regcache_cache_only(priv->regmap, true);
+
+	clk_disable_unprepare(priv->ipg_clk);
+
+	return 0;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops fsl_audmix_pm = {
+	SET_RUNTIME_PM_OPS(fsl_audmix_runtime_suspend,
+			   fsl_audmix_runtime_resume,
+			   NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
+static struct platform_driver fsl_audmix_driver = {
+	.probe = fsl_audmix_probe,
+	.remove = fsl_audmix_remove,
+	.driver = {
+		.name = "fsl-audmix",
+		.of_match_table = fsl_audmix_ids,
+		.pm = &fsl_audmix_pm,
+	},
+};
+module_platform_driver(fsl_audmix_driver);
+
+MODULE_DESCRIPTION("NXP AUDMIX ASoC DAI driver");
+MODULE_AUTHOR("Viorel Suman <viorel.suman@nxp.com>");
+MODULE_ALIAS("platform:fsl-audmix");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/fsl/fsl_audmix.h b/sound/soc/fsl/fsl_audmix.h
new file mode 100644
index 0000000..7812ffe
--- /dev/null
+++ b/sound/soc/fsl/fsl_audmix.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * NXP AUDMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ */
+
+#ifndef __FSL_AUDMIX_H
+#define __FSL_AUDMIX_H
+
+#define FSL_AUDMIX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+			SNDRV_PCM_FMTBIT_S24_LE |\
+			SNDRV_PCM_FMTBIT_S32_LE)
+/* AUDMIX Registers */
+#define FSL_AUDMIX_CTR		0x200 /* Control */
+#define FSL_AUDMIX_STR		0x204 /* Status */
+
+#define FSL_AUDMIX_ATCR0	0x208 /* Attenuation Control */
+#define FSL_AUDMIX_ATIVAL0	0x20c /* Attenuation Initial Value */
+#define FSL_AUDMIX_ATSTPUP0	0x210 /* Attenuation step up factor */
+#define FSL_AUDMIX_ATSTPDN0	0x214 /* Attenuation step down factor */
+#define FSL_AUDMIX_ATSTPTGT0	0x218 /* Attenuation step target */
+#define FSL_AUDMIX_ATTNVAL0	0x21c /* Attenuation Value */
+#define FSL_AUDMIX_ATSTP0	0x220 /* Attenuation step number */
+
+#define FSL_AUDMIX_ATCR1	0x228 /* Attenuation Control */
+#define FSL_AUDMIX_ATIVAL1	0x22c /* Attenuation Initial Value */
+#define FSL_AUDMIX_ATSTPUP1	0x230 /* Attenuation step up factor */
+#define FSL_AUDMIX_ATSTPDN1	0x234 /* Attenuation step down factor */
+#define FSL_AUDMIX_ATSTPTGT1	0x238 /* Attenuation step target */
+#define FSL_AUDMIX_ATTNVAL1	0x23c /* Attenuation Value */
+#define FSL_AUDMIX_ATSTP1	0x240 /* Attenuation step number */
+
+/* AUDMIX Control Register */
+#define FSL_AUDMIX_CTR_MIXCLK_SHIFT	0
+#define FSL_AUDMIX_CTR_MIXCLK_MASK	BIT(FSL_AUDMIX_CTR_MIXCLK_SHIFT)
+#define FSL_AUDMIX_CTR_MIXCLK(i)	((i) << FSL_AUDMIX_CTR_MIXCLK_SHIFT)
+#define FSL_AUDMIX_CTR_OUTSRC_SHIFT	1
+#define FSL_AUDMIX_CTR_OUTSRC_MASK	(0x3 << FSL_AUDMIX_CTR_OUTSRC_SHIFT)
+#define FSL_AUDMIX_CTR_OUTSRC(i)	(((i) << FSL_AUDMIX_CTR_OUTSRC_SHIFT)\
+					      & FSL_AUDMIX_CTR_OUTSRC_MASK)
+#define FSL_AUDMIX_CTR_OUTWIDTH_SHIFT	3
+#define FSL_AUDMIX_CTR_OUTWIDTH_MASK	(0x7 << FSL_AUDMIX_CTR_OUTWIDTH_SHIFT)
+#define FSL_AUDMIX_CTR_OUTWIDTH(i)	(((i) << FSL_AUDMIX_CTR_OUTWIDTH_SHIFT)\
+					      & FSL_AUDMIX_CTR_OUTWIDTH_MASK)
+#define FSL_AUDMIX_CTR_OUTCKPOL_SHIFT	6
+#define FSL_AUDMIX_CTR_OUTCKPOL_MASK	BIT(FSL_AUDMIX_CTR_OUTCKPOL_SHIFT)
+#define FSL_AUDMIX_CTR_OUTCKPOL(i)	((i) << FSL_AUDMIX_CTR_OUTCKPOL_SHIFT)
+#define FSL_AUDMIX_CTR_MASKRTDF_SHIFT	7
+#define FSL_AUDMIX_CTR_MASKRTDF_MASK	BIT(FSL_AUDMIX_CTR_MASKRTDF_SHIFT)
+#define FSL_AUDMIX_CTR_MASKRTDF(i)	((i) << FSL_AUDMIX_CTR_MASKRTDF_SHIFT)
+#define FSL_AUDMIX_CTR_MASKCKDF_SHIFT	8
+#define FSL_AUDMIX_CTR_MASKCKDF_MASK	BIT(FSL_AUDMIX_CTR_MASKCKDF_SHIFT)
+#define FSL_AUDMIX_CTR_MASKCKDF(i)	((i) << FSL_AUDMIX_CTR_MASKCKDF_SHIFT)
+#define FSL_AUDMIX_CTR_SYNCMODE_SHIFT	9
+#define FSL_AUDMIX_CTR_SYNCMODE_MASK	BIT(FSL_AUDMIX_CTR_SYNCMODE_SHIFT)
+#define FSL_AUDMIX_CTR_SYNCMODE(i)	((i) << FSL_AUDMIX_CTR_SYNCMODE_SHIFT)
+#define FSL_AUDMIX_CTR_SYNCSRC_SHIFT	10
+#define FSL_AUDMIX_CTR_SYNCSRC_MASK	BIT(FSL_AUDMIX_CTR_SYNCSRC_SHIFT)
+#define FSL_AUDMIX_CTR_SYNCSRC(i)	((i) << FSL_AUDMIX_CTR_SYNCSRC_SHIFT)
+
+/* AUDMIX Status Register */
+#define FSL_AUDMIX_STR_RATEDIFF		BIT(0)
+#define FSL_AUDMIX_STR_CLKDIFF		BIT(1)
+#define FSL_AUDMIX_STR_MIXSTAT_SHIFT	2
+#define FSL_AUDMIX_STR_MIXSTAT_MASK	(0x3 << FSL_AUDMIX_STR_MIXSTAT_SHIFT)
+#define FSL_AUDMIX_STR_MIXSTAT(i)	(((i) & FSL_AUDMIX_STR_MIXSTAT_MASK) \
+					   >> FSL_AUDMIX_STR_MIXSTAT_SHIFT)
+/* AUDMIX Attenuation Control Register */
+#define FSL_AUDMIX_ATCR_AT_EN		BIT(0)
+#define FSL_AUDMIX_ATCR_AT_UPDN		BIT(1)
+#define FSL_AUDMIX_ATCR_ATSTPDIF_SHIFT	2
+#define FSL_AUDMIX_ATCR_ATSTPDFI_MASK	\
+				(0xfff << FSL_AUDMIX_ATCR_ATSTPDIF_SHIFT)
+
+/* AUDMIX Attenuation Initial Value Register */
+#define FSL_AUDMIX_ATIVAL_ATINVAL_MASK	0x3FFFF
+
+/* AUDMIX Attenuation Step Up Factor Register */
+#define FSL_AUDMIX_ATSTPUP_ATSTEPUP_MASK	0x3FFFF
+
+/* AUDMIX Attenuation Step Down Factor Register */
+#define FSL_AUDMIX_ATSTPDN_ATSTEPDN_MASK	0x3FFFF
+
+/* AUDMIX Attenuation Step Target Register */
+#define FSL_AUDMIX_ATSTPTGT_ATSTPTG_MASK	0x3FFFF
+
+/* AUDMIX Attenuation Value Register */
+#define FSL_AUDMIX_ATTNVAL_ATCURVAL_MASK	0x3FFFF
+
+/* AUDMIX Attenuation Step Number Register */
+#define FSL_AUDMIX_ATSTP_STPCTR_MASK	0x3FFFF
+
+#define FSL_AUDMIX_MAX_DAIS		2
+struct fsl_audmix {
+	struct platform_device *pdev;
+	struct regmap *regmap;
+	struct clk *ipg_clk;
+	u8 tdms;
+};
+
+#endif /* __FSL_AUDMIX_H */
-- 
2.7.4


^ permalink raw reply related

* [PATCH RESEND v5 0/3] Add NXP AUDMIX device and machine drivers
From: Viorel Suman @ 2019-03-04 10:36 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
	Jaroslav Kysela, Takashi Iwai, Timur Tabi, Nicolin Chen, Xiubo Li,
	Fabio Estevam, Viorel Suman, S.j. Wang, Daniel Baluta,
	Cosmin Samoila
  Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
	linux-kernel@vger.kernel.org, Viorel Suman, dl-linux-imx,
	linuxppc-dev@lists.ozlabs.org

The patchset adds NXP Audio Mixer (AUDMIX) device and machine
drivers and related DT bindings documentation.

Changes since V4:
1. Removed "model" attribute from device driver DT bindings documentation
   as suggested by Nicolin.

Changes since V3:
1. Removed machine driver DT bindings documentation.
2. Trigger machine driver probe from device driver as suggested by Nicolin.

Changes since V2:
1. Moved "dais" node from machine driver DTS node to device driver DTS node
  as suggested by Rob.

Changes since V1:
1. Original patch split into distinct patches for the device driver and
  DT binding documentation.
2. Replaced AMIX with AUDMIX in both code and file names as it looks more
  RM-compliant.
3. Removed polarity control from CPU DAI driver as suggested by Nicolin.
4. Added machine driver and related DT binding documentation.

Viorel Suman (3):
  ASoC: fsl: Add Audio Mixer CPU DAI driver
  ASoC: add fsl_audmix DT binding documentation
  ASoC: fsl: Add Audio Mixer machine driver

 .../devicetree/bindings/sound/fsl,audmix.txt       |  50 ++
 sound/soc/fsl/Kconfig                              |  16 +
 sound/soc/fsl/Makefile                             |   5 +
 sound/soc/fsl/fsl_audmix.c                         | 578 +++++++++++++++++++++
 sound/soc/fsl/fsl_audmix.h                         | 102 ++++
 sound/soc/fsl/imx-audmix.c                         | 327 ++++++++++++
 6 files changed, 1078 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h
 create mode 100644 sound/soc/fsl/imx-audmix.c

-- 
2.7.4


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox