LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [powerpc:next-test 42/193] arch/powerpc/platforms/44x/ppc476.c:241:34: sparse: sparse: incorrect type in argument 1 (different address spaces)
From: kernel test robot @ 2020-12-07  6:38 UTC (permalink / raw)
  To: Christophe Leroy; +Cc: linuxppc-dev, kbuild-all

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

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next-test
head:   8817aabb1bdd5811130f94ff6442bb19c9158a3a
commit: 894fa235eb4ca0bfa692dbe4932c2f940cdc8c1e [42/193] powerpc: inline iomap accessors
config: powerpc64-randconfig-s032-20201207 (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.3-179-ga00755aa-dirty
        # https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id=894fa235eb4ca0bfa692dbe4932c2f940cdc8c1e
        git remote add powerpc https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git
        git fetch --no-tags powerpc next-test
        git checkout 894fa235eb4ca0bfa692dbe4932c2f940cdc8c1e
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=powerpc64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


"sparse warnings: (new ones prefixed by >>)"
   arch/powerpc/platforms/44x/ppc476.c:236:17: sparse: sparse: cast removes address space '__iomem' of expression
>> arch/powerpc/platforms/44x/ppc476.c:241:34: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void const volatile [noderef] __iomem *addr @@     got unsigned char [usertype] * @@
   arch/powerpc/platforms/44x/ppc476.c:241:34: sparse:     expected void const volatile [noderef] __iomem *addr
   arch/powerpc/platforms/44x/ppc476.c:241:34: sparse:     got unsigned char [usertype] *
   arch/powerpc/platforms/44x/ppc476.c:243:17: sparse: sparse: incorrect type in argument 1 (different address spaces) @@     expected void volatile [noderef] __iomem *addr @@     got unsigned char [usertype] *[assigned] fpga @@
   arch/powerpc/platforms/44x/ppc476.c:243:17: sparse:     expected void volatile [noderef] __iomem *addr
   arch/powerpc/platforms/44x/ppc476.c:243:17: sparse:     got unsigned char [usertype] *[assigned] fpga

vim +241 arch/powerpc/platforms/44x/ppc476.c

228d55053397e6d arch/powerpc/platforms/44x/currituck.c Tony Breeds     2011-11-30  217  
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  218  static int board_rev = -1;
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  219  static int __init ppc47x_get_board_rev(void)
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  220  {
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06  221  	int reg;
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06  222  	u8 *fpga;
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06  223  	struct device_node *np = NULL;
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  224  
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06  225  	if (of_machine_is_compatible("ibm,currituck")) {
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  226  		np = of_find_compatible_node(NULL, NULL, "ibm,currituck-fpga");
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06  227  		reg = 0;
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06  228  	} else if (of_machine_is_compatible("ibm,akebono")) {
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06  229  		np = of_find_compatible_node(NULL, NULL, "ibm,akebono-fpga");
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06  230  		reg = 2;
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06  231  	}
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06  232  
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  233  	if (!np)
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  234  		goto fail;
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  235  
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06 @236  	fpga = (u8 *) of_iomap(np, 0);
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  237  	of_node_put(np);
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  238  	if (!fpga)
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  239  		goto fail;
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  240  
2a2c74b2efcb1a0 arch/powerpc/platforms/44x/ppc476.c    Alistair Popple 2014-03-06 @241  	board_rev = ioread8(fpga + reg) & 0x03;
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  242  	pr_info("%s: Found board revision %d\n", __func__, board_rev);
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  243  	iounmap(fpga);
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  244  	return 0;
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  245  
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  246  fail:
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  247  	pr_info("%s: Unable to find board revision\n", __func__);
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  248  	return 0;
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  249  }
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  250  machine_arch_initcall(ppc47x, ppc47x_get_board_rev);
ab9a4183fddf232 arch/powerpc/platforms/44x/currituck.c Alistair Popple 2013-05-09  251  

:::::: The code at line 241 was first introduced by commit
:::::: 2a2c74b2efcb1a0ca3fdcb5fbb96ad8de6a29177 IBM Akebono: Add the Akebono platform

:::::: TO: Alistair Popple <alistair@popple.id.au>
:::::: CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

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

^ permalink raw reply

* [PATCH] EDAC/mv64x60: Remove orphan mv64x60 driver
From: Michael Ellerman @ 2020-12-07  4:02 UTC (permalink / raw)
  To: bp
  Cc: tony.luck, rric, linux-kernel, linuxppc-dev, james.morse, mchehab,
	linux-edac

The mv64x60 EDAC driver depends on CONFIG_MV64X60. But that symbol is
not user-selectable, and the last code that selected it was removed
with the C2K board support in 2018, see:

  92c8c16f3457 ("powerpc/embedded6xx: Remove C2K board support")

That means the driver is now dead code, so remove it.

Suggested-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 drivers/edac/Kconfig        |   7 -
 drivers/edac/Makefile       |   1 -
 drivers/edac/mv64x60_edac.c | 883 ------------------------------------
 drivers/edac/mv64x60_edac.h | 114 -----
 4 files changed, 1005 deletions(-)
 delete mode 100644 drivers/edac/mv64x60_edac.c
 delete mode 100644 drivers/edac/mv64x60_edac.h

diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index fa0c3b5797e4..f3816f1131ed 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -292,13 +292,6 @@ config EDAC_LAYERSCAPE
 	  Support for error detection and correction on Freescale memory
 	  controllers on Layerscape SoCs.
 
-config EDAC_MV64X60
-	tristate "Marvell MV64x60"
-	depends on MV64X60
-	help
-	  Support for error detection and correction on the Marvell
-	  MV64360 and MV64460 chipsets.
-
 config EDAC_PASEMI
 	tristate "PA Semi PWRficient"
 	depends on PPC_PASEMI && PCI
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index 3cd1aeb0a916..464d3d8d850a 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -65,7 +65,6 @@ obj-$(CONFIG_EDAC_SKX)			+= skx_edac.o
 i10nm_edac-y				:= skx_common.o i10nm_base.o
 obj-$(CONFIG_EDAC_I10NM)		+= i10nm_edac.o
 
-obj-$(CONFIG_EDAC_MV64X60)		+= mv64x60_edac.o
 obj-$(CONFIG_EDAC_CELL)			+= cell_edac.o
 obj-$(CONFIG_EDAC_PPC4XX)		+= ppc4xx_edac.o
 obj-$(CONFIG_EDAC_AMD8111)		+= amd8111_edac.o
diff --git a/drivers/edac/mv64x60_edac.c b/drivers/edac/mv64x60_edac.c
deleted file mode 100644
index 3c68bb525d5d..000000000000
--- a/drivers/edac/mv64x60_edac.c
+++ /dev/null
@@ -1,883 +0,0 @@
-/*
- * Marvell MV64x60 Memory Controller kernel module for PPC platforms
- *
- * Author: Dave Jiang <djiang@mvista.com>
- *
- * 2006-2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/edac.h>
-#include <linux/gfp.h>
-
-#include "edac_module.h"
-#include "mv64x60_edac.h"
-
-static const char *mv64x60_ctl_name = "MV64x60";
-static int edac_dev_idx;
-static int edac_pci_idx;
-static int edac_mc_idx;
-
-/*********************** PCI err device **********************************/
-#ifdef CONFIG_PCI
-static void mv64x60_pci_check(struct edac_pci_ctl_info *pci)
-{
-	struct mv64x60_pci_pdata *pdata = pci->pvt_info;
-	u32 cause;
-
-	cause = readl(pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
-	if (!cause)
-		return;
-
-	printk(KERN_ERR "Error in PCI %d Interface\n", pdata->pci_hose);
-	printk(KERN_ERR "Cause register: 0x%08x\n", cause);
-	printk(KERN_ERR "Address Low: 0x%08x\n",
-	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_ADDR_LO));
-	printk(KERN_ERR "Address High: 0x%08x\n",
-	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_ADDR_HI));
-	printk(KERN_ERR "Attribute: 0x%08x\n",
-	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_ATTR));
-	printk(KERN_ERR "Command: 0x%08x\n",
-	       readl(pdata->pci_vbase + MV64X60_PCI_ERROR_CMD));
-	writel(~cause, pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
-
-	if (cause & MV64X60_PCI_PE_MASK)
-		edac_pci_handle_pe(pci, pci->ctl_name);
-
-	if (!(cause & MV64X60_PCI_PE_MASK))
-		edac_pci_handle_npe(pci, pci->ctl_name);
-}
-
-static irqreturn_t mv64x60_pci_isr(int irq, void *dev_id)
-{
-	struct edac_pci_ctl_info *pci = dev_id;
-	struct mv64x60_pci_pdata *pdata = pci->pvt_info;
-	u32 val;
-
-	val = readl(pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
-	if (!val)
-		return IRQ_NONE;
-
-	mv64x60_pci_check(pci);
-
-	return IRQ_HANDLED;
-}
-
-/*
- * Bit 0 of MV64x60_PCIx_ERR_MASK does not exist on the 64360 and because of
- * errata FEr-#11 and FEr-##16 for the 64460, it should be 0 on that chip as
- * well.  IOW, don't set bit 0.
- */
-
-/* Erratum FEr PCI-#16: clear bit 0 of PCI SERRn Mask reg. */
-static int __init mv64x60_pci_fixup(struct platform_device *pdev)
-{
-	struct resource *r;
-	void __iomem *pci_serr;
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (!r) {
-		printk(KERN_ERR "%s: Unable to get resource for "
-		       "PCI err regs\n", __func__);
-		return -ENOENT;
-	}
-
-	pci_serr = ioremap(r->start, resource_size(r));
-	if (!pci_serr)
-		return -ENOMEM;
-
-	writel(readl(pci_serr) & ~0x1, pci_serr);
-	iounmap(pci_serr);
-
-	return 0;
-}
-
-static int mv64x60_pci_err_probe(struct platform_device *pdev)
-{
-	struct edac_pci_ctl_info *pci;
-	struct mv64x60_pci_pdata *pdata;
-	struct resource *r;
-	int res = 0;
-
-	if (!devres_open_group(&pdev->dev, mv64x60_pci_err_probe, GFP_KERNEL))
-		return -ENOMEM;
-
-	pci = edac_pci_alloc_ctl_info(sizeof(*pdata), "mv64x60_pci_err");
-	if (!pci)
-		return -ENOMEM;
-
-	pdata = pci->pvt_info;
-
-	pdata->pci_hose = pdev->id;
-	pdata->name = "mv64x60_pci_err";
-	platform_set_drvdata(pdev, pci);
-	pci->dev = &pdev->dev;
-	pci->dev_name = dev_name(&pdev->dev);
-	pci->mod_name = EDAC_MOD_STR;
-	pci->ctl_name = pdata->name;
-
-	if (edac_op_state == EDAC_OPSTATE_POLL)
-		pci->edac_check = mv64x60_pci_check;
-
-	pdata->edac_idx = edac_pci_idx++;
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r) {
-		printk(KERN_ERR "%s: Unable to get resource for "
-		       "PCI err regs\n", __func__);
-		res = -ENOENT;
-		goto err;
-	}
-
-	if (!devm_request_mem_region(&pdev->dev,
-				     r->start,
-				     resource_size(r),
-				     pdata->name)) {
-		printk(KERN_ERR "%s: Error while requesting mem region\n",
-		       __func__);
-		res = -EBUSY;
-		goto err;
-	}
-
-	pdata->pci_vbase = devm_ioremap(&pdev->dev,
-					r->start,
-					resource_size(r));
-	if (!pdata->pci_vbase) {
-		printk(KERN_ERR "%s: Unable to setup PCI err regs\n", __func__);
-		res = -ENOMEM;
-		goto err;
-	}
-
-	res = mv64x60_pci_fixup(pdev);
-	if (res < 0) {
-		printk(KERN_ERR "%s: PCI fixup failed\n", __func__);
-		goto err;
-	}
-
-	writel(0, pdata->pci_vbase + MV64X60_PCI_ERROR_CAUSE);
-	writel(0, pdata->pci_vbase + MV64X60_PCI_ERROR_MASK);
-	writel(MV64X60_PCIx_ERR_MASK_VAL,
-		  pdata->pci_vbase + MV64X60_PCI_ERROR_MASK);
-
-	if (edac_pci_add_device(pci, pdata->edac_idx) > 0) {
-		edac_dbg(3, "failed edac_pci_add_device()\n");
-		goto err;
-	}
-
-	if (edac_op_state == EDAC_OPSTATE_INT) {
-		pdata->irq = platform_get_irq(pdev, 0);
-		res = devm_request_irq(&pdev->dev,
-				       pdata->irq,
-				       mv64x60_pci_isr,
-				       0,
-				       "[EDAC] PCI err",
-				       pci);
-		if (res < 0) {
-			printk(KERN_ERR "%s: Unable to request irq %d for "
-			       "MV64x60 PCI ERR\n", __func__, pdata->irq);
-			res = -ENODEV;
-			goto err2;
-		}
-		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for PCI Err\n",
-		       pdata->irq);
-	}
-
-	devres_remove_group(&pdev->dev, mv64x60_pci_err_probe);
-
-	/* get this far and it's successful */
-	edac_dbg(3, "success\n");
-
-	return 0;
-
-err2:
-	edac_pci_del_device(&pdev->dev);
-err:
-	edac_pci_free_ctl_info(pci);
-	devres_release_group(&pdev->dev, mv64x60_pci_err_probe);
-	return res;
-}
-
-static int mv64x60_pci_err_remove(struct platform_device *pdev)
-{
-	struct edac_pci_ctl_info *pci = platform_get_drvdata(pdev);
-
-	edac_dbg(0, "\n");
-
-	edac_pci_del_device(&pdev->dev);
-
-	edac_pci_free_ctl_info(pci);
-
-	return 0;
-}
-
-static struct platform_driver mv64x60_pci_err_driver = {
-	.probe = mv64x60_pci_err_probe,
-	.remove = mv64x60_pci_err_remove,
-	.driver = {
-		   .name = "mv64x60_pci_err",
-	}
-};
-
-#endif /* CONFIG_PCI */
-
-/*********************** SRAM err device **********************************/
-static void mv64x60_sram_check(struct edac_device_ctl_info *edac_dev)
-{
-	struct mv64x60_sram_pdata *pdata = edac_dev->pvt_info;
-	u32 cause;
-
-	cause = readl(pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE);
-	if (!cause)
-		return;
-
-	printk(KERN_ERR "Error in internal SRAM\n");
-	printk(KERN_ERR "Cause register: 0x%08x\n", cause);
-	printk(KERN_ERR "Address Low: 0x%08x\n",
-	       readl(pdata->sram_vbase + MV64X60_SRAM_ERR_ADDR_LO));
-	printk(KERN_ERR "Address High: 0x%08x\n",
-	       readl(pdata->sram_vbase + MV64X60_SRAM_ERR_ADDR_HI));
-	printk(KERN_ERR "Data Low: 0x%08x\n",
-	       readl(pdata->sram_vbase + MV64X60_SRAM_ERR_DATA_LO));
-	printk(KERN_ERR "Data High: 0x%08x\n",
-	       readl(pdata->sram_vbase + MV64X60_SRAM_ERR_DATA_HI));
-	printk(KERN_ERR "Parity: 0x%08x\n",
-	       readl(pdata->sram_vbase + MV64X60_SRAM_ERR_PARITY));
-	writel(0, pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE);
-
-	edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
-}
-
-static irqreturn_t mv64x60_sram_isr(int irq, void *dev_id)
-{
-	struct edac_device_ctl_info *edac_dev = dev_id;
-	struct mv64x60_sram_pdata *pdata = edac_dev->pvt_info;
-	u32 cause;
-
-	cause = readl(pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE);
-	if (!cause)
-		return IRQ_NONE;
-
-	mv64x60_sram_check(edac_dev);
-
-	return IRQ_HANDLED;
-}
-
-static int mv64x60_sram_err_probe(struct platform_device *pdev)
-{
-	struct edac_device_ctl_info *edac_dev;
-	struct mv64x60_sram_pdata *pdata;
-	struct resource *r;
-	int res = 0;
-
-	if (!devres_open_group(&pdev->dev, mv64x60_sram_err_probe, GFP_KERNEL))
-		return -ENOMEM;
-
-	edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
-					      "sram", 1, NULL, 0, 0, NULL, 0,
-					      edac_dev_idx);
-	if (!edac_dev) {
-		devres_release_group(&pdev->dev, mv64x60_sram_err_probe);
-		return -ENOMEM;
-	}
-
-	pdata = edac_dev->pvt_info;
-	pdata->name = "mv64x60_sram_err";
-	edac_dev->dev = &pdev->dev;
-	platform_set_drvdata(pdev, edac_dev);
-	edac_dev->dev_name = dev_name(&pdev->dev);
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r) {
-		printk(KERN_ERR "%s: Unable to get resource for "
-		       "SRAM err regs\n", __func__);
-		res = -ENOENT;
-		goto err;
-	}
-
-	if (!devm_request_mem_region(&pdev->dev,
-				     r->start,
-				     resource_size(r),
-				     pdata->name)) {
-		printk(KERN_ERR "%s: Error while request mem region\n",
-		       __func__);
-		res = -EBUSY;
-		goto err;
-	}
-
-	pdata->sram_vbase = devm_ioremap(&pdev->dev,
-					 r->start,
-					 resource_size(r));
-	if (!pdata->sram_vbase) {
-		printk(KERN_ERR "%s: Unable to setup SRAM err regs\n",
-		       __func__);
-		res = -ENOMEM;
-		goto err;
-	}
-
-	/* setup SRAM err registers */
-	writel(0, pdata->sram_vbase + MV64X60_SRAM_ERR_CAUSE);
-
-	edac_dev->mod_name = EDAC_MOD_STR;
-	edac_dev->ctl_name = pdata->name;
-
-	if (edac_op_state == EDAC_OPSTATE_POLL)
-		edac_dev->edac_check = mv64x60_sram_check;
-
-	pdata->edac_idx = edac_dev_idx++;
-
-	if (edac_device_add_device(edac_dev) > 0) {
-		edac_dbg(3, "failed edac_device_add_device()\n");
-		goto err;
-	}
-
-	if (edac_op_state == EDAC_OPSTATE_INT) {
-		pdata->irq = platform_get_irq(pdev, 0);
-		res = devm_request_irq(&pdev->dev,
-				       pdata->irq,
-				       mv64x60_sram_isr,
-				       0,
-				       "[EDAC] SRAM err",
-				       edac_dev);
-		if (res < 0) {
-			printk(KERN_ERR
-			       "%s: Unable to request irq %d for "
-			       "MV64x60 SRAM ERR\n", __func__, pdata->irq);
-			res = -ENODEV;
-			goto err2;
-		}
-
-		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for SRAM Err\n",
-		       pdata->irq);
-	}
-
-	devres_remove_group(&pdev->dev, mv64x60_sram_err_probe);
-
-	/* get this far and it's successful */
-	edac_dbg(3, "success\n");
-
-	return 0;
-
-err2:
-	edac_device_del_device(&pdev->dev);
-err:
-	devres_release_group(&pdev->dev, mv64x60_sram_err_probe);
-	edac_device_free_ctl_info(edac_dev);
-	return res;
-}
-
-static int mv64x60_sram_err_remove(struct platform_device *pdev)
-{
-	struct edac_device_ctl_info *edac_dev = platform_get_drvdata(pdev);
-
-	edac_dbg(0, "\n");
-
-	edac_device_del_device(&pdev->dev);
-	edac_device_free_ctl_info(edac_dev);
-
-	return 0;
-}
-
-static struct platform_driver mv64x60_sram_err_driver = {
-	.probe = mv64x60_sram_err_probe,
-	.remove = mv64x60_sram_err_remove,
-	.driver = {
-		   .name = "mv64x60_sram_err",
-	}
-};
-
-/*********************** CPU err device **********************************/
-static void mv64x60_cpu_check(struct edac_device_ctl_info *edac_dev)
-{
-	struct mv64x60_cpu_pdata *pdata = edac_dev->pvt_info;
-	u32 cause;
-
-	cause = readl(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE) &
-	    MV64x60_CPU_CAUSE_MASK;
-	if (!cause)
-		return;
-
-	printk(KERN_ERR "Error on CPU interface\n");
-	printk(KERN_ERR "Cause register: 0x%08x\n", cause);
-	printk(KERN_ERR "Address Low: 0x%08x\n",
-	       readl(pdata->cpu_vbase[0] + MV64x60_CPU_ERR_ADDR_LO));
-	printk(KERN_ERR "Address High: 0x%08x\n",
-	       readl(pdata->cpu_vbase[0] + MV64x60_CPU_ERR_ADDR_HI));
-	printk(KERN_ERR "Data Low: 0x%08x\n",
-	       readl(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_DATA_LO));
-	printk(KERN_ERR "Data High: 0x%08x\n",
-	       readl(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_DATA_HI));
-	printk(KERN_ERR "Parity: 0x%08x\n",
-	       readl(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_PARITY));
-	writel(0, pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE);
-
-	edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
-}
-
-static irqreturn_t mv64x60_cpu_isr(int irq, void *dev_id)
-{
-	struct edac_device_ctl_info *edac_dev = dev_id;
-	struct mv64x60_cpu_pdata *pdata = edac_dev->pvt_info;
-	u32 cause;
-
-	cause = readl(pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE) &
-	    MV64x60_CPU_CAUSE_MASK;
-	if (!cause)
-		return IRQ_NONE;
-
-	mv64x60_cpu_check(edac_dev);
-
-	return IRQ_HANDLED;
-}
-
-static int mv64x60_cpu_err_probe(struct platform_device *pdev)
-{
-	struct edac_device_ctl_info *edac_dev;
-	struct resource *r;
-	struct mv64x60_cpu_pdata *pdata;
-	int res = 0;
-
-	if (!devres_open_group(&pdev->dev, mv64x60_cpu_err_probe, GFP_KERNEL))
-		return -ENOMEM;
-
-	edac_dev = edac_device_alloc_ctl_info(sizeof(*pdata),
-					      "cpu", 1, NULL, 0, 0, NULL, 0,
-					      edac_dev_idx);
-	if (!edac_dev) {
-		devres_release_group(&pdev->dev, mv64x60_cpu_err_probe);
-		return -ENOMEM;
-	}
-
-	pdata = edac_dev->pvt_info;
-	pdata->name = "mv64x60_cpu_err";
-	edac_dev->dev = &pdev->dev;
-	platform_set_drvdata(pdev, edac_dev);
-	edac_dev->dev_name = dev_name(&pdev->dev);
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r) {
-		printk(KERN_ERR "%s: Unable to get resource for "
-		       "CPU err regs\n", __func__);
-		res = -ENOENT;
-		goto err;
-	}
-
-	if (!devm_request_mem_region(&pdev->dev,
-				     r->start,
-				     resource_size(r),
-				     pdata->name)) {
-		printk(KERN_ERR "%s: Error while requesting mem region\n",
-		       __func__);
-		res = -EBUSY;
-		goto err;
-	}
-
-	pdata->cpu_vbase[0] = devm_ioremap(&pdev->dev,
-					   r->start,
-					   resource_size(r));
-	if (!pdata->cpu_vbase[0]) {
-		printk(KERN_ERR "%s: Unable to setup CPU err regs\n", __func__);
-		res = -ENOMEM;
-		goto err;
-	}
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (!r) {
-		printk(KERN_ERR "%s: Unable to get resource for "
-		       "CPU err regs\n", __func__);
-		res = -ENOENT;
-		goto err;
-	}
-
-	if (!devm_request_mem_region(&pdev->dev,
-				     r->start,
-				     resource_size(r),
-				     pdata->name)) {
-		printk(KERN_ERR "%s: Error while requesting mem region\n",
-		       __func__);
-		res = -EBUSY;
-		goto err;
-	}
-
-	pdata->cpu_vbase[1] = devm_ioremap(&pdev->dev,
-					   r->start,
-					   resource_size(r));
-	if (!pdata->cpu_vbase[1]) {
-		printk(KERN_ERR "%s: Unable to setup CPU err regs\n", __func__);
-		res = -ENOMEM;
-		goto err;
-	}
-
-	/* setup CPU err registers */
-	writel(0, pdata->cpu_vbase[1] + MV64x60_CPU_ERR_CAUSE);
-	writel(0, pdata->cpu_vbase[1] + MV64x60_CPU_ERR_MASK);
-	writel(0x000000ff, pdata->cpu_vbase[1] + MV64x60_CPU_ERR_MASK);
-
-	edac_dev->mod_name = EDAC_MOD_STR;
-	edac_dev->ctl_name = pdata->name;
-	if (edac_op_state == EDAC_OPSTATE_POLL)
-		edac_dev->edac_check = mv64x60_cpu_check;
-
-	pdata->edac_idx = edac_dev_idx++;
-
-	if (edac_device_add_device(edac_dev) > 0) {
-		edac_dbg(3, "failed edac_device_add_device()\n");
-		goto err;
-	}
-
-	if (edac_op_state == EDAC_OPSTATE_INT) {
-		pdata->irq = platform_get_irq(pdev, 0);
-		res = devm_request_irq(&pdev->dev,
-				       pdata->irq,
-				       mv64x60_cpu_isr,
-				       0,
-				       "[EDAC] CPU err",
-				       edac_dev);
-		if (res < 0) {
-			printk(KERN_ERR
-			       "%s: Unable to request irq %d for MV64x60 "
-			       "CPU ERR\n", __func__, pdata->irq);
-			res = -ENODEV;
-			goto err2;
-		}
-
-		printk(KERN_INFO EDAC_MOD_STR
-		       " acquired irq %d for CPU Err\n", pdata->irq);
-	}
-
-	devres_remove_group(&pdev->dev, mv64x60_cpu_err_probe);
-
-	/* get this far and it's successful */
-	edac_dbg(3, "success\n");
-
-	return 0;
-
-err2:
-	edac_device_del_device(&pdev->dev);
-err:
-	devres_release_group(&pdev->dev, mv64x60_cpu_err_probe);
-	edac_device_free_ctl_info(edac_dev);
-	return res;
-}
-
-static int mv64x60_cpu_err_remove(struct platform_device *pdev)
-{
-	struct edac_device_ctl_info *edac_dev = platform_get_drvdata(pdev);
-
-	edac_dbg(0, "\n");
-
-	edac_device_del_device(&pdev->dev);
-	edac_device_free_ctl_info(edac_dev);
-	return 0;
-}
-
-static struct platform_driver mv64x60_cpu_err_driver = {
-	.probe = mv64x60_cpu_err_probe,
-	.remove = mv64x60_cpu_err_remove,
-	.driver = {
-		   .name = "mv64x60_cpu_err",
-	}
-};
-
-/*********************** DRAM err device **********************************/
-
-static void mv64x60_mc_check(struct mem_ctl_info *mci)
-{
-	struct mv64x60_mc_pdata *pdata = mci->pvt_info;
-	u32 reg;
-	u32 err_addr;
-	u32 sdram_ecc;
-	u32 comp_ecc;
-	u32 syndrome;
-
-	reg = readl(pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR);
-	if (!reg)
-		return;
-
-	err_addr = reg & ~0x3;
-	sdram_ecc = readl(pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_RCVD);
-	comp_ecc = readl(pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_CALC);
-	syndrome = sdram_ecc ^ comp_ecc;
-
-	/* first bit clear in ECC Err Reg, 1 bit error, correctable by HW */
-	if (!(reg & 0x1))
-		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, 1,
-				     err_addr >> PAGE_SHIFT,
-				     err_addr & PAGE_MASK, syndrome,
-				     0, 0, -1,
-				     mci->ctl_name, "");
-	else	/* 2 bit error, UE */
-		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, 1,
-				     err_addr >> PAGE_SHIFT,
-				     err_addr & PAGE_MASK, 0,
-				     0, 0, -1,
-				     mci->ctl_name, "");
-
-	/* clear the error */
-	writel(0, pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR);
-}
-
-static irqreturn_t mv64x60_mc_isr(int irq, void *dev_id)
-{
-	struct mem_ctl_info *mci = dev_id;
-	struct mv64x60_mc_pdata *pdata = mci->pvt_info;
-	u32 reg;
-
-	reg = readl(pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR);
-	if (!reg)
-		return IRQ_NONE;
-
-	/* writing 0's to the ECC err addr in check function clears irq */
-	mv64x60_mc_check(mci);
-
-	return IRQ_HANDLED;
-}
-
-static void get_total_mem(struct mv64x60_mc_pdata *pdata)
-{
-	struct device_node *np = NULL;
-	const unsigned int *reg;
-
-	np = of_find_node_by_type(NULL, "memory");
-	if (!np)
-		return;
-
-	reg = of_get_property(np, "reg", NULL);
-
-	pdata->total_mem = reg[1];
-}
-
-static void mv64x60_init_csrows(struct mem_ctl_info *mci,
-				struct mv64x60_mc_pdata *pdata)
-{
-	struct csrow_info *csrow;
-	struct dimm_info *dimm;
-
-	u32 devtype;
-	u32 ctl;
-
-	get_total_mem(pdata);
-
-	ctl = readl(pdata->mc_vbase + MV64X60_SDRAM_CONFIG);
-
-	csrow = mci->csrows[0];
-	dimm = csrow->channels[0]->dimm;
-
-	dimm->nr_pages = pdata->total_mem >> PAGE_SHIFT;
-	dimm->grain = 8;
-
-	dimm->mtype = (ctl & MV64X60_SDRAM_REGISTERED) ? MEM_RDDR : MEM_DDR;
-
-	devtype = (ctl >> 20) & 0x3;
-	switch (devtype) {
-	case 0x0:
-		dimm->dtype = DEV_X32;
-		break;
-	case 0x2:		/* could be X8 too, but no way to tell */
-		dimm->dtype = DEV_X16;
-		break;
-	case 0x3:
-		dimm->dtype = DEV_X4;
-		break;
-	default:
-		dimm->dtype = DEV_UNKNOWN;
-		break;
-	}
-
-	dimm->edac_mode = EDAC_SECDED;
-}
-
-static int mv64x60_mc_err_probe(struct platform_device *pdev)
-{
-	struct mem_ctl_info *mci;
-	struct edac_mc_layer layers[2];
-	struct mv64x60_mc_pdata *pdata;
-	struct resource *r;
-	u32 ctl;
-	int res = 0;
-
-	if (!devres_open_group(&pdev->dev, mv64x60_mc_err_probe, GFP_KERNEL))
-		return -ENOMEM;
-
-	layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
-	layers[0].size = 1;
-	layers[0].is_virt_csrow = true;
-	layers[1].type = EDAC_MC_LAYER_CHANNEL;
-	layers[1].size = 1;
-	layers[1].is_virt_csrow = false;
-	mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers,
-			    sizeof(struct mv64x60_mc_pdata));
-	if (!mci) {
-		printk(KERN_ERR "%s: No memory for CPU err\n", __func__);
-		devres_release_group(&pdev->dev, mv64x60_mc_err_probe);
-		return -ENOMEM;
-	}
-
-	pdata = mci->pvt_info;
-	mci->pdev = &pdev->dev;
-	platform_set_drvdata(pdev, mci);
-	pdata->name = "mv64x60_mc_err";
-	mci->dev_name = dev_name(&pdev->dev);
-	pdata->edac_idx = edac_mc_idx++;
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!r) {
-		printk(KERN_ERR "%s: Unable to get resource for "
-		       "MC err regs\n", __func__);
-		res = -ENOENT;
-		goto err;
-	}
-
-	if (!devm_request_mem_region(&pdev->dev,
-				     r->start,
-				     resource_size(r),
-				     pdata->name)) {
-		printk(KERN_ERR "%s: Error while requesting mem region\n",
-		       __func__);
-		res = -EBUSY;
-		goto err;
-	}
-
-	pdata->mc_vbase = devm_ioremap(&pdev->dev,
-				       r->start,
-				       resource_size(r));
-	if (!pdata->mc_vbase) {
-		printk(KERN_ERR "%s: Unable to setup MC err regs\n", __func__);
-		res = -ENOMEM;
-		goto err;
-	}
-
-	ctl = readl(pdata->mc_vbase + MV64X60_SDRAM_CONFIG);
-	if (!(ctl & MV64X60_SDRAM_ECC)) {
-		/* Non-ECC RAM? */
-		printk(KERN_WARNING "%s: No ECC DIMMs discovered\n", __func__);
-		res = -ENODEV;
-		goto err;
-	}
-
-	edac_dbg(3, "init mci\n");
-	mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR;
-	mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED;
-	mci->edac_cap = EDAC_FLAG_SECDED;
-	mci->mod_name = EDAC_MOD_STR;
-	mci->ctl_name = mv64x60_ctl_name;
-
-	if (edac_op_state == EDAC_OPSTATE_POLL)
-		mci->edac_check = mv64x60_mc_check;
-
-	mci->ctl_page_to_phys = NULL;
-
-	mci->scrub_mode = SCRUB_SW_SRC;
-
-	mv64x60_init_csrows(mci, pdata);
-
-	/* setup MC registers */
-	writel(0, pdata->mc_vbase + MV64X60_SDRAM_ERR_ADDR);
-	ctl = readl(pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_CNTL);
-	ctl = (ctl & 0xff00ffff) | 0x10000;
-	writel(ctl, pdata->mc_vbase + MV64X60_SDRAM_ERR_ECC_CNTL);
-
-	res = edac_mc_add_mc(mci);
-	if (res) {
-		edac_dbg(3, "failed edac_mc_add_mc()\n");
-		goto err;
-	}
-
-	if (edac_op_state == EDAC_OPSTATE_INT) {
-		/* acquire interrupt that reports errors */
-		pdata->irq = platform_get_irq(pdev, 0);
-		res = devm_request_irq(&pdev->dev,
-				       pdata->irq,
-				       mv64x60_mc_isr,
-				       0,
-				       "[EDAC] MC err",
-				       mci);
-		if (res < 0) {
-			printk(KERN_ERR "%s: Unable to request irq %d for "
-			       "MV64x60 DRAM ERR\n", __func__, pdata->irq);
-			res = -ENODEV;
-			goto err2;
-		}
-
-		printk(KERN_INFO EDAC_MOD_STR " acquired irq %d for MC Err\n",
-		       pdata->irq);
-	}
-
-	/* get this far and it's successful */
-	edac_dbg(3, "success\n");
-
-	return 0;
-
-err2:
-	edac_mc_del_mc(&pdev->dev);
-err:
-	devres_release_group(&pdev->dev, mv64x60_mc_err_probe);
-	edac_mc_free(mci);
-	return res;
-}
-
-static int mv64x60_mc_err_remove(struct platform_device *pdev)
-{
-	struct mem_ctl_info *mci = platform_get_drvdata(pdev);
-
-	edac_dbg(0, "\n");
-
-	edac_mc_del_mc(&pdev->dev);
-	edac_mc_free(mci);
-	return 0;
-}
-
-static struct platform_driver mv64x60_mc_err_driver = {
-	.probe = mv64x60_mc_err_probe,
-	.remove = mv64x60_mc_err_remove,
-	.driver = {
-		   .name = "mv64x60_mc_err",
-	}
-};
-
-static struct platform_driver * const drivers[] = {
-	&mv64x60_mc_err_driver,
-	&mv64x60_cpu_err_driver,
-	&mv64x60_sram_err_driver,
-#ifdef CONFIG_PCI
-	&mv64x60_pci_err_driver,
-#endif
-};
-
-static int __init mv64x60_edac_init(void)
-{
-
-	printk(KERN_INFO "Marvell MV64x60 EDAC driver " MV64x60_REVISION "\n");
-	printk(KERN_INFO "\t(C) 2006-2007 MontaVista Software\n");
-
-	/* make sure error reporting method is sane */
-	switch (edac_op_state) {
-	case EDAC_OPSTATE_POLL:
-	case EDAC_OPSTATE_INT:
-		break;
-	default:
-		edac_op_state = EDAC_OPSTATE_INT;
-		break;
-	}
-
-	return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
-}
-module_init(mv64x60_edac_init);
-
-static void __exit mv64x60_edac_exit(void)
-{
-	platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
-}
-module_exit(mv64x60_edac_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Montavista Software, Inc.");
-module_param(edac_op_state, int, 0444);
-MODULE_PARM_DESC(edac_op_state,
-		 "EDAC Error Reporting state: 0=Poll, 2=Interrupt");
diff --git a/drivers/edac/mv64x60_edac.h b/drivers/edac/mv64x60_edac.h
deleted file mode 100644
index c7f209c92a1a..000000000000
--- a/drivers/edac/mv64x60_edac.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * EDAC defs for Marvell MV64x60 bridge chip
- *
- * Author: Dave Jiang <djiang@mvista.com>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- *
- */
-#ifndef _MV64X60_EDAC_H_
-#define _MV64X60_EDAC_H_
-
-#define MV64x60_REVISION " Ver: 2.0.0"
-#define EDAC_MOD_STR	"MV64x60_edac"
-
-#define mv64x60_printk(level, fmt, arg...) \
-	edac_printk(level, "MV64x60", fmt, ##arg)
-
-#define mv64x60_mc_printk(mci, level, fmt, arg...) \
-	edac_mc_chipset_printk(mci, level, "MV64x60", fmt, ##arg)
-
-/* CPU Error Report Registers */
-#define MV64x60_CPU_ERR_ADDR_LO		0x00	/* 0x0070 */
-#define MV64x60_CPU_ERR_ADDR_HI		0x08	/* 0x0078 */
-#define MV64x60_CPU_ERR_DATA_LO		0x00	/* 0x0128 */
-#define MV64x60_CPU_ERR_DATA_HI		0x08	/* 0x0130 */
-#define MV64x60_CPU_ERR_PARITY		0x10	/* 0x0138 */
-#define MV64x60_CPU_ERR_CAUSE		0x18	/* 0x0140 */
-#define MV64x60_CPU_ERR_MASK		0x20	/* 0x0148 */
-
-#define MV64x60_CPU_CAUSE_MASK		0x07ffffff
-
-/* SRAM Error Report Registers */
-#define MV64X60_SRAM_ERR_CAUSE		0x08	/* 0x0388 */
-#define MV64X60_SRAM_ERR_ADDR_LO	0x10	/* 0x0390 */
-#define MV64X60_SRAM_ERR_ADDR_HI	0x78	/* 0x03f8 */
-#define MV64X60_SRAM_ERR_DATA_LO	0x18	/* 0x0398 */
-#define MV64X60_SRAM_ERR_DATA_HI	0x20	/* 0x03a0 */
-#define MV64X60_SRAM_ERR_PARITY		0x28	/* 0x03a8 */
-
-/* SDRAM Controller Registers */
-#define MV64X60_SDRAM_CONFIG		0x00	/* 0x1400 */
-#define MV64X60_SDRAM_ERR_DATA_HI	0x40	/* 0x1440 */
-#define MV64X60_SDRAM_ERR_DATA_LO	0x44	/* 0x1444 */
-#define MV64X60_SDRAM_ERR_ECC_RCVD	0x48	/* 0x1448 */
-#define MV64X60_SDRAM_ERR_ECC_CALC	0x4c	/* 0x144c */
-#define MV64X60_SDRAM_ERR_ADDR		0x50	/* 0x1450 */
-#define MV64X60_SDRAM_ERR_ECC_CNTL	0x54	/* 0x1454 */
-#define MV64X60_SDRAM_ERR_ECC_ERR_CNT	0x58	/* 0x1458 */
-
-#define MV64X60_SDRAM_REGISTERED	0x20000
-#define MV64X60_SDRAM_ECC		0x40000
-
-#ifdef CONFIG_PCI
-/*
- * Bit 0 of MV64x60_PCIx_ERR_MASK does not exist on the 64360 and because of
- * errata FEr-#11 and FEr-##16 for the 64460, it should be 0 on that chip as
- * well.  IOW, don't set bit 0.
- */
-#define MV64X60_PCIx_ERR_MASK_VAL	0x00a50c24
-
-/* Register offsets from PCIx error address low register */
-#define MV64X60_PCI_ERROR_ADDR_LO	0x00
-#define MV64X60_PCI_ERROR_ADDR_HI	0x04
-#define MV64X60_PCI_ERROR_ATTR		0x08
-#define MV64X60_PCI_ERROR_CMD		0x10
-#define MV64X60_PCI_ERROR_CAUSE		0x18
-#define MV64X60_PCI_ERROR_MASK		0x1c
-
-#define MV64X60_PCI_ERR_SWrPerr		0x0002
-#define MV64X60_PCI_ERR_SRdPerr		0x0004
-#define	MV64X60_PCI_ERR_MWrPerr		0x0020
-#define MV64X60_PCI_ERR_MRdPerr		0x0040
-
-#define MV64X60_PCI_PE_MASK	(MV64X60_PCI_ERR_SWrPerr | \
-				MV64X60_PCI_ERR_SRdPerr | \
-				MV64X60_PCI_ERR_MWrPerr | \
-				MV64X60_PCI_ERR_MRdPerr)
-
-struct mv64x60_pci_pdata {
-	int pci_hose;
-	void __iomem *pci_vbase;
-	char *name;
-	int irq;
-	int edac_idx;
-};
-
-#endif				/* CONFIG_PCI */
-
-struct mv64x60_mc_pdata {
-	void __iomem *mc_vbase;
-	int total_mem;
-	char *name;
-	int irq;
-	int edac_idx;
-};
-
-struct mv64x60_cpu_pdata {
-	void __iomem *cpu_vbase[2];
-	char *name;
-	int irq;
-	int edac_idx;
-};
-
-struct mv64x60_sram_pdata {
-	void __iomem *sram_vbase;
-	char *name;
-	int irq;
-	int edac_idx;
-};
-
-#endif
-- 
2.25.1


^ permalink raw reply related

* Re: [PATCH v6 1/5] PCI: Unify ECAM constants in native PCI Express drivers
From: Florian Fainelli @ 2020-12-07  3:25 UTC (permalink / raw)
  To: Krzysztof Wilczyński, Bjorn Helgaas, Jim Quinlan
  Cc: Heiko Stuebner, Shawn Lin, Paul Mackerras, Thomas Petazzoni,
	Jonathan Chocron, Toan Le, Will Deacon, Rob Herring,
	Lorenzo Pieralisi, Michal Simek, linux-rockchip,
	bcm-kernel-feedback-list, Jonathan Derrick, linux-pci, Ray Jui,
	linux-rpi-kernel, Jonathan Cameron, linux-arm-kernel,
	Scott Branden, Zhou Wang, Robert Richter, linuxppc-dev,
	Nicolas Saenz Julienne
In-Reply-To: <X808JJGeIREwqIjb@rocinante>

+JimQ,

On 12/6/2020 12:16 PM, Krzysztof Wilczyński wrote:
> Hello Nicolas, Florian and Florian,
> 
> [...]
>> -/* Configuration space read/write support */
>> -static inline int brcm_pcie_cfg_index(int busnr, int devfn, int reg)
>> -{
>> -	return ((PCI_SLOT(devfn) & 0x1f) << PCIE_EXT_SLOT_SHIFT)
>> -		| ((PCI_FUNC(devfn) & 0x07) << PCIE_EXT_FUNC_SHIFT)
>> -		| (busnr << PCIE_EXT_BUSNUM_SHIFT)
>> -		| (reg & ~3);
>> -}
>> -
>>  static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,
>>  					int where)
>>  {
>> @@ -716,7 +704,7 @@ static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,
>>  		return PCI_SLOT(devfn) ? NULL : base + where;
>>  
>>  	/* For devices, write to the config space index register */
>> -	idx = brcm_pcie_cfg_index(bus->number, devfn, 0);
>> +	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
>>  	writel(idx, pcie->base + PCIE_EXT_CFG_INDEX);
>>  	return base + PCIE_EXT_CFG_DATA + where;
>>  }
> [...]
> 
> Passing the hard-coded 0 as the "reg" argument here never actually did
> anything, thus the 32 bit alignment was never correctly enforced.
> 
> My question would be: should this be 32 bit aligned?  It seems like the
> intention was to perhaps make the alignment?  I am sadly not intimately
> familiar with his hardware, so I am not sure if there is something to
> fix here or not.
> 
> Also, I wonder whether it would be safe to pass the offset (the "where"
> variable) rather than hard-coded 0?
> 
> Thank you for help in advance!
> 
> Bjorn also asked the same question:
>   https://lore.kernel.org/linux-pci/20201120203428.GA272511@bjorn-Precision-5520/
> 
> Krzysztof
> 

-- 
Florian

^ permalink raw reply

* [PATCH 2/2] powerpc/powernv/idle: Restore CIABR after idle for Power9
From: Jordan Niethe @ 2020-12-07  1:05 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jordan Niethe
In-Reply-To: <20201207010519.15597-1-jniethe5@gmail.com>

On Power9, CIABR is lost after idle. This means that instruction
breakpoints set by xmon which use CIABR do not work. Fix this by
restoring CIABR after idle.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/platforms/powernv/idle.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
index 1ed7c5286487..e6f461812856 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -589,6 +589,7 @@ struct p9_sprs {
 	u64 spurr;
 	u64 dscr;
 	u64 wort;
+	u64 ciabr;
 
 	u64 mmcra;
 	u32 mmcr0;
@@ -668,6 +669,7 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
 		sprs.spurr	= mfspr(SPRN_SPURR);
 		sprs.dscr	= mfspr(SPRN_DSCR);
 		sprs.wort	= mfspr(SPRN_WORT);
+		sprs.ciabr	= mfspr(SPRN_CIABR);
 
 		sprs.mmcra	= mfspr(SPRN_MMCRA);
 		sprs.mmcr0	= mfspr(SPRN_MMCR0);
@@ -785,6 +787,7 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on)
 	mtspr(SPRN_SPURR,	sprs.spurr);
 	mtspr(SPRN_DSCR,	sprs.dscr);
 	mtspr(SPRN_WORT,	sprs.wort);
+	mtspr(SPRN_CIABR,	sprs.ciabr);
 
 	mtspr(SPRN_MMCRA,	sprs.mmcra);
 	mtspr(SPRN_MMCR0,	sprs.mmcr0);
-- 
2.17.1


^ permalink raw reply related

* [PATCH 1/2] powerpc/book3s64/kexec: Clear CIABR on kexec
From: Jordan Niethe @ 2020-12-07  1:05 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jordan Niethe

The value in CIABR persists across kexec which can lead to unintended
results when the new kernel hits the old kernel's breakpoint. For
example:

0:mon> bi $loadavg_proc_show
0:mon> b
   type            address
1 inst   c000000000519060  loadavg_proc_show+0x0/0x130
0:mon> x

$ kexec -l /mnt/vmlinux --initrd=/mnt/rootfs.cpio.gz --append='xmon=off'
$ kexec -e

$ cat /proc/loadavg
Trace/breakpoint trap

Make sure CIABR is cleared so this does not happen.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
---
 arch/powerpc/include/asm/book3s/64/kexec.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/powerpc/include/asm/book3s/64/kexec.h b/arch/powerpc/include/asm/book3s/64/kexec.h
index 6b5c3a248ba2..d4b9d476ecba 100644
--- a/arch/powerpc/include/asm/book3s/64/kexec.h
+++ b/arch/powerpc/include/asm/book3s/64/kexec.h
@@ -3,6 +3,7 @@
 #ifndef _ASM_POWERPC_BOOK3S_64_KEXEC_H_
 #define _ASM_POWERPC_BOOK3S_64_KEXEC_H_
 
+#include <asm/plpar_wrappers.h>
 
 #define reset_sprs reset_sprs
 static inline void reset_sprs(void)
@@ -14,6 +15,10 @@ static inline void reset_sprs(void)
 
 	if (cpu_has_feature(CPU_FTR_ARCH_207S)) {
 		mtspr(SPRN_IAMR, 0);
+		if (cpu_has_feature(CPU_FTR_HVMODE))
+			mtspr(SPRN_CIABR, 0);
+		else
+			plpar_set_ciabr(0);
 	}
 
 	/*  Do we need isync()? We are going via a kexec reset */
-- 
2.17.1


^ permalink raw reply related

* Re: [PATCH] powerpc/mm: Fix KUAP warning by providing copy_from_kernel_nofault_allowed()
From: Michael Ellerman @ 2020-12-07  0:24 UTC (permalink / raw)
  To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras, hch,
	viro, akpm
  Cc: linux-mm, linuxppc-dev, linux-kernel
In-Reply-To: <e559e60c43f679195bfe4c7b0a301431c6f02c7a.1607157766.git.christophe.leroy@csgroup.eu>

Christophe Leroy <christophe.leroy@csgroup.eu> writes:
> Since commit c33165253492 ("powerpc: use non-set_fs based maccess
> routines"), userspace access is not granted anymore when using
> copy_from_kernel_nofault()
>
> However, kthread_probe_data() uses copy_from_kernel_nofault()
> to check validity of pointers. When the pointer is NULL,
> it points to userspace, leading to a KUAP fault and triggering
> the following big hammer warning many times when you request
> a sysrq "show task":
>
> [ 1117.202054] ------------[ cut here ]------------
> [ 1117.202102] Bug: fault blocked by AP register !
> [ 1117.202261] WARNING: CPU: 0 PID: 377 at arch/powerpc/include/asm/nohash/32/kup-8xx.h:66 do_page_fault+0x4a8/0x5ec
> [ 1117.202310] Modules linked in:
> [ 1117.202428] CPU: 0 PID: 377 Comm: sh Tainted: G        W         5.10.0-rc5-01340-g83f53be2de31-dirty #4175
> [ 1117.202499] NIP:  c0012048 LR: c0012048 CTR: 00000000
> [ 1117.202573] REGS: cacdbb88 TRAP: 0700   Tainted: G        W          (5.10.0-rc5-01340-g83f53be2de31-dirty)
> [ 1117.202625] MSR:  00021032 <ME,IR,DR,RI>  CR: 24082222  XER: 20000000
> [ 1117.202899]
> [ 1117.202899] GPR00: c0012048 cacdbc40 c2929290 00000023 c092e554 00000001 c09865e8 c092e640
> [ 1117.202899] GPR08: 00001032 00000000 00000000 00014efc 28082224 100d166a 100a0920 00000000
> [ 1117.202899] GPR16: 100cac0c 100b0000 1080c3fc 1080d685 100d0000 100d0000 00000000 100a0900
> [ 1117.202899] GPR24: 100d0000 c07892ec 00000000 c0921510 c21f4440 0000005c c0000000 cacdbc80
> [ 1117.204362] NIP [c0012048] do_page_fault+0x4a8/0x5ec
> [ 1117.204461] LR [c0012048] do_page_fault+0x4a8/0x5ec
> [ 1117.204509] Call Trace:
> [ 1117.204609] [cacdbc40] [c0012048] do_page_fault+0x4a8/0x5ec (unreliable)
> [ 1117.204771] [cacdbc70] [c00112f0] handle_page_fault+0x8/0x34
> [ 1117.204911] --- interrupt: 301 at copy_from_kernel_nofault+0x70/0x1c0
> [ 1117.204979] NIP:  c010dbec LR: c010dbac CTR: 00000001
> [ 1117.205053] REGS: cacdbc80 TRAP: 0301   Tainted: G        W          (5.10.0-rc5-01340-g83f53be2de31-dirty)
> [ 1117.205104] MSR:  00009032 <EE,ME,IR,DR,RI>  CR: 28082224  XER: 00000000
> [ 1117.205416] DAR: 0000005c DSISR: c0000000
> [ 1117.205416] GPR00: c0045948 cacdbd38 c2929290 00000001 00000017 00000017 00000027 0000000f
> [ 1117.205416] GPR08: c09926ec 00000000 00000000 3ffff000 24082224
> [ 1117.206106] NIP [c010dbec] copy_from_kernel_nofault+0x70/0x1c0
> [ 1117.206202] LR [c010dbac] copy_from_kernel_nofault+0x30/0x1c0
> [ 1117.206258] --- interrupt: 301
> [ 1117.206372] [cacdbd38] [c004bbb0] kthread_probe_data+0x44/0x70 (unreliable)
> [ 1117.206561] [cacdbd58] [c0045948] print_worker_info+0xe0/0x194
> [ 1117.206717] [cacdbdb8] [c00548ac] sched_show_task+0x134/0x168
> [ 1117.206851] [cacdbdd8] [c005a268] show_state_filter+0x70/0x100
> [ 1117.206989] [cacdbe08] [c039baa0] sysrq_handle_showstate+0x14/0x24
> [ 1117.207122] [cacdbe18] [c039bf18] __handle_sysrq+0xac/0x1d0
> [ 1117.207257] [cacdbe48] [c039c0c0] write_sysrq_trigger+0x4c/0x74
> [ 1117.207407] [cacdbe68] [c01fba48] proc_reg_write+0xb4/0x114
> [ 1117.207550] [cacdbe88] [c0179968] vfs_write+0x12c/0x478
> [ 1117.207686] [cacdbf08] [c0179e60] ksys_write+0x78/0x128
> [ 1117.207826] [cacdbf38] [c00110d0] ret_from_syscall+0x0/0x34
> [ 1117.207938] --- interrupt: c01 at 0xfd4e784
> [ 1117.208008] NIP:  0fd4e784 LR: 0fe0f244 CTR: 10048d38
> [ 1117.208083] REGS: cacdbf48 TRAP: 0c01   Tainted: G        W          (5.10.0-rc5-01340-g83f53be2de31-dirty)
> [ 1117.208134] MSR:  0000d032 <EE,PR,ME,IR,DR,RI>  CR: 44002222  XER: 00000000
> [ 1117.208470]
> [ 1117.208470] GPR00: 00000004 7fc34090 77bfb4e0 00000001 1080fa40 00000002 7400000f fefefeff
> [ 1117.208470] GPR08: 7f7f7f7f 10048d38 1080c414 7fc343c0 00000000
> [ 1117.209104] NIP [0fd4e784] 0xfd4e784
> [ 1117.209180] LR [0fe0f244] 0xfe0f244
> [ 1117.209236] --- interrupt: c01
> [ 1117.209274] Instruction dump:
> [ 1117.209353] 714a4000 418200f0 73ca0001 40820084 73ca0032 408200f8 73c90040 4082ff60
> [ 1117.209727] 0fe00000 3c60c082 386399f4 48013b65 <0fe00000> 80010034 3860000b 7c0803a6
> [ 1117.210102] ---[ end trace 1927c0323393af3e ]---
>
> To avoid that, copy_from_kernel_nofault_allowed() is used to check
> whether the address is a valid kernel address. But the default
> version of it returns true for any address.
>
> Provide a powerpc version of copy_from_kernel_nofault_allowed()
> that returns false when the address is below TASK_USER_MAX,
> so that copy_from_kernel_nofault() will return -ERANGE.
>
> Reported-by: Qian Cai <qcai@redhat.com>
> Fixes: c33165253492 ("powerpc: use non-set_fs based maccess routines")
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Al Viro <viro@zeniv.linux.org.uk>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
> This issue was introduced in 5.10. I didn't mark it for stable, hopping it will go into 5.10-rc7
> ---
>  arch/powerpc/mm/Makefile  | 2 +-
>  arch/powerpc/mm/maccess.c | 9 +++++++++
>  2 files changed, 10 insertions(+), 1 deletion(-)
>  create mode 100644 arch/powerpc/mm/maccess.c
>
> diff --git a/arch/powerpc/mm/maccess.c b/arch/powerpc/mm/maccess.c
> new file mode 100644
> index 000000000000..56e97c0fb233
> --- /dev/null
> +++ b/arch/powerpc/mm/maccess.c
> @@ -0,0 +1,9 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include <linux/uaccess.h>
> +#include <linux/kernel.h>
> +
> +bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
> +{
> +	return (unsigned long)unsafe_src >= TASK_SIZE_MAX;
> +}

Is there a reason we're using TASK_SIZE_MAX?

It's copy from *kernel* (nofault) allowed, so shouldn't we be checking
that the address plausibly points at kernel memory? Not at no-man's land
above TASK_SIZE_MAX but below the start of kernel memory?

We have is_kernel_addr() which already encapsulates some platform quirks
around that logic, it seems like it would be a better fit?

ie:

bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
{
	return is_kernel_addr((unsigned long)unsafe_src);
}

cheers

^ permalink raw reply

* Re: [PATCH] powerpc/book3s_hv_uvmem: Check for failed page migration
From: Alistair Popple @ 2020-12-07  0:13 UTC (permalink / raw)
  To: Ram Pai; +Cc: linuxppc-dev, Bharata B Rao
In-Reply-To: <20201204165244.GA3390@ram-ibm-com.ibm.com>

On Saturday, 5 December 2020 3:52:44 AM AEDT Ram Pai wrote:
> On Fri, Dec 04, 2020 at 03:48:41PM +0530, Bharata B Rao wrote:
> > On Thu, Dec 03, 2020 at 04:08:12PM +1100, Alistair Popple wrote:

> This patch certainly looks like the problem, that has been hurting
> us for a while.  Let me run this patch through my SVM tests.  Looks very
> promising.
> 
> BTW: The code does a similar thing while paging out.  It pages out from the
> UV, and then does the migration. Is there a bug there aswell?

As specified the migrate_pages_vma() API can fail to migrate device private 
pages. However the fix was less obvious to me, and in practice I don't think it 
will ever fail for device private pages as you don't have the same races to 
establish the page and device private pages can't be pinned.

It might be worth adding some kind of warning though in case this ever 
changes.

 - Alistair
 
> RP
> 





^ permalink raw reply

* Re: [PATCH] powerpc/book3s_hv_uvmem: Check for failed page migration
From: Alistair Popple @ 2020-12-06 23:55 UTC (permalink / raw)
  To: bharata; +Cc: linuxppc-dev, Ram Pai
In-Reply-To: <20201204101841.GA621541@in.ibm.com>

On Friday, 4 December 2020 9:18:41 PM AEDT Bharata B Rao wrote:
> 
> Reviewed-by: Bharata B Rao <bharata@linux.ibm.com>
> 
> Did you actually hit this scenario with secure VMs where a UV-paged-in
> page was later found to be not migratable?

No, this was found by inspection. I have no way of testing this but we had a 
similar issue in Nouveau and I think you would have a similar issue here 
although it might be hard to hit.

migrate_vma_pages() will fail a page migration if a CPU thread has raced and 
established a non-zero page PTE for the address. See migrate_vma_insert_page() 
for the implementation. It will also fail if something else has taken a 
reference on the page after calling migrate_vma_setup(), but that is less 
likely as any existing pages will have been isolated.

 - Alistair

> Regards,
> Bharata.
> 





^ permalink raw reply

* RE: [PATCH v5 09/19] dt-bindings: usb: renesas-xhci: Refer to the usb-xhci.yaml file
From: Prabhakar Mahadev Lad @ 2020-12-06 22:09 UTC (permalink / raw)
  To: Serge Semin, Mathias Nyman, Felipe Balbi, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Rob Herring, Chunfeng Yun, Yoshihiro Shimoda
  Cc: devicetree@vger.kernel.org, Ahmad Zainie,
	linux-kernel@vger.kernel.org, linux-snps-arc@lists.infradead.org,
	Neil Armstrong, Martin Blumenstingl, Kevin Hilman,
	linux-usb@vger.kernel.org, linux-mips@vger.kernel.org,
	Serge Semin, Bjorn Andersson, Manu Gautam, Andy Gross,
	Pavel Parkhomenko, Alexey Malahov, linuxppc-dev@lists.ozlabs.org,
	Rob Herring, linux-arm-kernel@lists.infradead.org, Roger Quadros
In-Reply-To: <20201205152427.29537-10-Sergey.Semin@baikalelectronics.ru>

Hi Serge,

Thank you for the patch.

> -----Original Message-----
> From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Sent: 05 December 2020 15:24
> To: Mathias Nyman <mathias.nyman@intel.com>; Felipe Balbi <balbi@kernel.org>; Krzysztof Kozlowski
> <krzk@kernel.org>; Greg Kroah-Hartman <gregkh@linuxfoundation.org>; Rob Herring <robh+dt@kernel.org>;
> Chunfeng Yun <chunfeng.yun@mediatek.com>; Prabhakar Mahadev Lad <prabhakar.mahadev-
> lad.rj@bp.renesas.com>; Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> Cc: Serge Semin <Sergey.Semin@baikalelectronics.ru>; Serge Semin <fancer.lancer@gmail.com>; Alexey
> Malahov <Alexey.Malahov@baikalelectronics.ru>; Pavel Parkhomenko
> <Pavel.Parkhomenko@baikalelectronics.ru>; Andy Gross <agross@kernel.org>; Bjorn Andersson
> <bjorn.andersson@linaro.org>; Manu Gautam <mgautam@codeaurora.org>; Roger Quadros <rogerq@ti.com>;
> Neil Armstrong <narmstrong@baylibre.com>; Kevin Hilman <khilman@baylibre.com>; Martin Blumenstingl
> <martin.blumenstingl@googlemail.com>; Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>; linux-
> arm-kernel@lists.infradead.org; linux-snps-arc@lists.infradead.org; linux-mips@vger.kernel.org;
> linuxppc-dev@lists.ozlabs.org; linux-usb@vger.kernel.org; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org; Rob Herring <robh@kernel.org>
> Subject: [PATCH v5 09/19] dt-bindings: usb: renesas-xhci: Refer to the usb-xhci.yaml file
> 
> With minor peculiarities (like uploading some vendor-specific firmware)
> these are just Generic xHCI controllers fully compatible with its
> properties. Make sure the Renesas USB xHCI DT nodes are also validated
> against the Generic xHCI DT schema.
> 
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Reviewed-by: Rob Herring <robh@kernel.org>
> Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> ---
>  Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>

Cheers,
Prabhakar

> diff --git a/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml
> b/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml
> index 0f078bd0a3e5..7e5ed196b52c 100644
> --- a/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml
> +++ b/Documentation/devicetree/bindings/usb/renesas,usb-xhci.yaml
> @@ -11,7 +11,7 @@ maintainers:
>    - Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
> 
>  allOf:
> -  - $ref: "usb-hcd.yaml"
> +  - $ref: "usb-xhci.yaml"
> 
>  properties:
>    compatible:
> @@ -69,7 +69,7 @@ required:
>    - power-domains
>    - resets
> 
> -additionalProperties: false
> +unevaluatedProperties: false
> 
>  examples:
>    - |
> --
> 2.29.2


^ permalink raw reply

* Re: [PATCH v6 1/5] PCI: Unify ECAM constants in native PCI Express drivers
From: Krzysztof Wilczyński @ 2020-12-06 20:16 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Heiko Stuebner, Shawn Lin, Paul Mackerras, Thomas Petazzoni,
	Jonathan Chocron, Toan Le, Will Deacon, Rob Herring,
	Lorenzo Pieralisi, Michal Simek, linux-rockchip,
	bcm-kernel-feedback-list, Jonathan Derrick, linux-pci, Ray Jui,
	Florian Fainelli, linux-rpi-kernel, Jonathan Cameron,
	linux-arm-kernel, Scott Branden, Zhou Wang, Robert Richter,
	linuxppc-dev, Nicolas Saenz Julienne
In-Reply-To: <20201129230743.3006978-2-kw@linux.com>

Hello Nicolas, Florian and Florian,

[...]
> -/* Configuration space read/write support */
> -static inline int brcm_pcie_cfg_index(int busnr, int devfn, int reg)
> -{
> -	return ((PCI_SLOT(devfn) & 0x1f) << PCIE_EXT_SLOT_SHIFT)
> -		| ((PCI_FUNC(devfn) & 0x07) << PCIE_EXT_FUNC_SHIFT)
> -		| (busnr << PCIE_EXT_BUSNUM_SHIFT)
> -		| (reg & ~3);
> -}
> -
>  static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,
>  					int where)
>  {
> @@ -716,7 +704,7 @@ static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,
>  		return PCI_SLOT(devfn) ? NULL : base + where;
>  
>  	/* For devices, write to the config space index register */
> -	idx = brcm_pcie_cfg_index(bus->number, devfn, 0);
> +	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
>  	writel(idx, pcie->base + PCIE_EXT_CFG_INDEX);
>  	return base + PCIE_EXT_CFG_DATA + where;
>  }
[...]

Passing the hard-coded 0 as the "reg" argument here never actually did
anything, thus the 32 bit alignment was never correctly enforced.

My question would be: should this be 32 bit aligned?  It seems like the
intention was to perhaps make the alignment?  I am sadly not intimately
familiar with his hardware, so I am not sure if there is something to
fix here or not.

Also, I wonder whether it would be safe to pass the offset (the "where"
variable) rather than hard-coded 0?

Thank you for help in advance!

Bjorn also asked the same question:
  https://lore.kernel.org/linux-pci/20201120203428.GA272511@bjorn-Precision-5520/

Krzysztof

^ permalink raw reply

* RE: [PATCH v5 19/19] dt-bindings: usb: intel,keembay-dwc3: Validate DWC3 sub-node
From: Wan Mohamad, Wan Ahmad Zainie @ 2020-12-06  9:56 UTC (permalink / raw)
  To: Serge Semin, Nyman, Mathias, Felipe Balbi, Krzysztof Kozlowski,
	Greg Kroah-Hartman, Rob Herring, Chunfeng Yun
  Cc: devicetree@vger.kernel.org, linux-snps-arc@lists.infradead.org,
	linux-mips@vger.kernel.org, narmstrong, Martin Blumenstingl,
	Kevin Hilman, Yoshihiro Shimoda, linux-usb@vger.kernel.org,
	linux-kernel@vger.kernel.org, Lad Prabhakar, Serge Semin,
	Bjorn Andersson, Manu Gautam, Andy Gross, Pavel Parkhomenko,
	Alexey Malahov, linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org, Roger Quadros
In-Reply-To: <20201205152427.29537-20-Sergey.Semin@baikalelectronics.ru>

Hi Serge.

> -----Original Message-----
> From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> Sent: Saturday, December 5, 2020 11:24 PM
> To: Nyman, Mathias <mathias.nyman@intel.com>; Felipe Balbi
> <balbi@kernel.org>; Krzysztof Kozlowski <krzk@kernel.org>; Greg Kroah-
> Hartman <gregkh@linuxfoundation.org>; Rob Herring
> <robh+dt@kernel.org>; Chunfeng Yun <chunfeng.yun@mediatek.com>;
> Wan Mohamad, Wan Ahmad Zainie
> <wan.ahmad.zainie.wan.mohamad@intel.com>
> Cc: Serge Semin <Sergey.Semin@baikalelectronics.ru>; Serge Semin
> <fancer.lancer@gmail.com>; Alexey Malahov
> <Alexey.Malahov@baikalelectronics.ru>; Pavel Parkhomenko
> <Pavel.Parkhomenko@baikalelectronics.ru>; Andy Gross
> <agross@kernel.org>; Bjorn Andersson <bjorn.andersson@linaro.org>;
> Manu Gautam <mgautam@codeaurora.org>; Roger Quadros
> <rogerq@ti.com>; Lad Prabhakar <prabhakar.mahadev-
> lad.rj@bp.renesas.com>; Yoshihiro Shimoda
> <yoshihiro.shimoda.uh@renesas.com>; narmstrong
> <narmstrong@baylibre.com>; Kevin Hilman <khilman@baylibre.com>;
> Martin Blumenstingl <martin.blumenstingl@googlemail.com>; linux-arm-
> kernel@lists.infradead.org; linux-snps-arc@lists.infradead.org; linux-
> mips@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; linux-
> usb@vger.kernel.org; devicetree@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Subject: [PATCH v5 19/19] dt-bindings: usb: intel,keembay-dwc3: Validate
> DWC3 sub-node
> 
> Intel Keem Bay DWC3 compatible DT nodes are supposed to have a DWC
> USB3 compatible sub-node to describe a fully functioning USB interface. Let's
> use the available DWC USB3 DT schema to validate the Qualcomm DWC3 sub-
> nodes.
> 
> Note since the generic DWC USB3 DT node is supposed to be named as
> generic USB HCD ("^usb(@.*)?") one we have to accordingly fix the sub-
> nodes name regexp and fix the DT node example.
> 
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>

LGTM. With minor change to fix the typo above, Qualcomm to Intel
Keem Bay,
Acked-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>

> 
> ---
> 
> Changelog v5:
> - This is a new patch created for the new Intel Keem Bay bindings file,
>   which has been added just recently.
> ---
>  .../devicetree/bindings/usb/intel,keembay-dwc3.yaml      | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/usb/intel,keembay-
> dwc3.yaml b/Documentation/devicetree/bindings/usb/intel,keembay-
> dwc3.yaml
> index dd32c10ce6c7..43b91ab62004 100644
> --- a/Documentation/devicetree/bindings/usb/intel,keembay-dwc3.yaml
> +++ b/Documentation/devicetree/bindings/usb/intel,keembay-dwc3.yaml
> @@ -34,11 +34,8 @@ properties:
>  # Required child node:
> 
>  patternProperties:
> -  "^dwc3@[0-9a-f]+$":
> -    type: object
> -    description:
> -      A child node must exist to represent the core DWC3 IP block.
> -      The content of the node is defined in dwc3.txt.
> +  "^usb@[0-9a-f]+$":
> +    $ref: snps,dwc3.yaml#
> 
>  required:
>    - compatible
> @@ -68,7 +65,7 @@ examples:
>            #address-cells = <1>;
>            #size-cells = <1>;
> 
> -          dwc3@34000000 {
> +          usb@34000000 {
>                  compatible = "snps,dwc3";
>                  reg = <0x34000000 0x10000>;
>                  interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
> --
> 2.29.2

Best regards,
Zainie

^ permalink raw reply

* Re: [PATCH v5 19/19] dt-bindings: usb: intel,keembay-dwc3: Validate DWC3 sub-node
From: Serge Semin @ 2020-12-06 10:05 UTC (permalink / raw)
  To: Wan Mohamad, Wan Ahmad Zainie
  Cc: narmstrong, Bjorn Andersson, Pavel Parkhomenko, Kevin Hilman,
	Krzysztof Kozlowski, Andy Gross, Chunfeng Yun,
	linux-snps-arc@lists.infradead.org, devicetree@vger.kernel.org,
	Nyman, Mathias, Martin Blumenstingl, Lad Prabhakar,
	Alexey Malahov, Rob Herring, linux-arm-kernel@lists.infradead.org,
	Roger Quadros, Felipe Balbi, Greg Kroah-Hartman,
	Yoshihiro Shimoda, linux-usb@vger.kernel.org,
	linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org,
	Serge Semin, Manu Gautam, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <DM6PR11MB3721E8FEB4E755328D7A517EDDCF0@DM6PR11MB3721.namprd11.prod.outlook.com>

Hi Wan,

On Sun, Dec 06, 2020 at 09:56:47AM +0000, Wan Mohamad, Wan Ahmad Zainie wrote:
> Hi Serge.
> 
> > -----Original Message-----
> > From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> > Sent: Saturday, December 5, 2020 11:24 PM
> > To: Nyman, Mathias <mathias.nyman@intel.com>; Felipe Balbi
> > <balbi@kernel.org>; Krzysztof Kozlowski <krzk@kernel.org>; Greg Kroah-
> > Hartman <gregkh@linuxfoundation.org>; Rob Herring
> > <robh+dt@kernel.org>; Chunfeng Yun <chunfeng.yun@mediatek.com>;
> > Wan Mohamad, Wan Ahmad Zainie
> > <wan.ahmad.zainie.wan.mohamad@intel.com>
> > Cc: Serge Semin <Sergey.Semin@baikalelectronics.ru>; Serge Semin
> > <fancer.lancer@gmail.com>; Alexey Malahov
> > <Alexey.Malahov@baikalelectronics.ru>; Pavel Parkhomenko
> > <Pavel.Parkhomenko@baikalelectronics.ru>; Andy Gross
> > <agross@kernel.org>; Bjorn Andersson <bjorn.andersson@linaro.org>;
> > Manu Gautam <mgautam@codeaurora.org>; Roger Quadros
> > <rogerq@ti.com>; Lad Prabhakar <prabhakar.mahadev-
> > lad.rj@bp.renesas.com>; Yoshihiro Shimoda
> > <yoshihiro.shimoda.uh@renesas.com>; narmstrong
> > <narmstrong@baylibre.com>; Kevin Hilman <khilman@baylibre.com>;
> > Martin Blumenstingl <martin.blumenstingl@googlemail.com>; linux-arm-
> > kernel@lists.infradead.org; linux-snps-arc@lists.infradead.org; linux-
> > mips@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; linux-
> > usb@vger.kernel.org; devicetree@vger.kernel.org; linux-
> > kernel@vger.kernel.org
> > Subject: [PATCH v5 19/19] dt-bindings: usb: intel,keembay-dwc3: Validate
> > DWC3 sub-node
> > 
> > Intel Keem Bay DWC3 compatible DT nodes are supposed to have a DWC
> > USB3 compatible sub-node to describe a fully functioning USB interface. Let's
> > use the available DWC USB3 DT schema to validate the Qualcomm DWC3 sub-
> > nodes.
> > 
> > Note since the generic DWC USB3 DT node is supposed to be named as
> > generic USB HCD ("^usb(@.*)?") one we have to accordingly fix the sub-
> > nodes name regexp and fix the DT node example.
> > 
> > Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
> 

> LGTM. With minor change to fix the typo above, Qualcomm to Intel
> Keem Bay,
> Acked-by: Wan Ahmad Zainie <wan.ahmad.zainie.wan.mohamad@intel.com>

Ah, right. Thanks for noticing that. A probability of copy-paste mistakes
increases proportionally to the number sleepless hours.)

-Sergey

> 
> > 
> > ---
> > 
> > Changelog v5:
> > - This is a new patch created for the new Intel Keem Bay bindings file,
> >   which has been added just recently.
> > ---
> >  .../devicetree/bindings/usb/intel,keembay-dwc3.yaml      | 9 +++------
> >  1 file changed, 3 insertions(+), 6 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/usb/intel,keembay-
> > dwc3.yaml b/Documentation/devicetree/bindings/usb/intel,keembay-
> > dwc3.yaml
> > index dd32c10ce6c7..43b91ab62004 100644
> > --- a/Documentation/devicetree/bindings/usb/intel,keembay-dwc3.yaml
> > +++ b/Documentation/devicetree/bindings/usb/intel,keembay-dwc3.yaml
> > @@ -34,11 +34,8 @@ properties:
> >  # Required child node:
> > 
> >  patternProperties:
> > -  "^dwc3@[0-9a-f]+$":
> > -    type: object
> > -    description:
> > -      A child node must exist to represent the core DWC3 IP block.
> > -      The content of the node is defined in dwc3.txt.
> > +  "^usb@[0-9a-f]+$":
> > +    $ref: snps,dwc3.yaml#
> > 
> >  required:
> >    - compatible
> > @@ -68,7 +65,7 @@ examples:
> >            #address-cells = <1>;
> >            #size-cells = <1>;
> > 
> > -          dwc3@34000000 {
> > +          usb@34000000 {
> >                  compatible = "snps,dwc3";
> >                  reg = <0x34000000 0x10000>;
> >                  interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
> > --
> > 2.29.2
> 
> Best regards,
> Zainie

^ permalink raw reply

* [PATCH v2 2/2] ASoC: fsl: Add imx-hdmi machine driver
From: Shengjiu Wang @ 2020-12-06 10:41 UTC (permalink / raw)
  To: timur, nicoleotsuka, Xiubo.Lee, festevam, lgirdwood, broonie,
	perex, tiwai, alsa-devel, linuxppc-dev, linux-kernel, robh+dt,
	devicetree
In-Reply-To: <1607251319-5821-1-git-send-email-shengjiu.wang@nxp.com>

The driver is initially designed for sound card using HDMI
interface on i.MX platform. There is internal HDMI IP or
external HDMI modules connect with SAI or AUD2HTX interface.
It supports both transmitter and receiver devices.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
changes in v2
- update according to Nicolin's comments.

 sound/soc/fsl/Kconfig    |  12 ++
 sound/soc/fsl/Makefile   |   2 +
 sound/soc/fsl/imx-hdmi.c | 236 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 250 insertions(+)
 create mode 100644 sound/soc/fsl/imx-hdmi.c

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 24710decd38a..84db0b7b9d59 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -305,6 +305,18 @@ config SND_SOC_IMX_AUDMIX
 	  Say Y if you want to add support for SoC audio on an i.MX board with
 	  an Audio Mixer.
 
+config SND_SOC_IMX_HDMI
+	tristate "SoC Audio support for i.MX boards with HDMI port"
+	select SND_SOC_FSL_SAI
+	select SND_SOC_FSL_AUD2HTX
+	select SND_SOC_HDMI_CODEC
+	help
+	  ALSA SoC Audio support with HDMI feature for Freescale SoCs that have
+	  SAI/AUD2HTX and connect with internal HDMI IP or external module
+	  SII902X.
+	  Say Y if you want to add support for SoC audio on an i.MX board with
+	  IMX HDMI.
+
 endif # SND_IMX_SOC
 
 endmenu
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 0b20e038b65b..8c5fa8a859c0 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -65,9 +65,11 @@ 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-audmix-objs := imx-audmix.o
+snd-soc-imx-hdmi-objs := imx-hdmi.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 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_AUDMIX) += snd-soc-imx-audmix.o
+obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o
diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c
new file mode 100644
index 000000000000..2c2a76a71940
--- /dev/null
+++ b/sound/soc/fsl/imx-hdmi.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2017-2020 NXP
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <sound/jack.h>
+#include <sound/pcm_params.h>
+#include <sound/hdmi-codec.h>
+#include "fsl_sai.h"
+
+/**
+ * struct cpu_priv - CPU private data
+ * @sysclk_freq: SYSCLK rates for set_sysclk()
+ * @sysclk_dir: SYSCLK directions for set_sysclk()
+ * @sysclk_id: SYSCLK ids for set_sysclk()
+ * @slot_width: Slot width of each frame
+ *
+ * Note: [1] for tx and [0] for rx
+ */
+struct cpu_priv {
+	unsigned long sysclk_freq[2];
+	u32 sysclk_dir[2];
+	u32 sysclk_id[2];
+	u32 slot_width;
+};
+
+struct imx_hdmi_data {
+	struct snd_soc_dai_link dai;
+	struct snd_soc_card card;
+	struct snd_soc_jack hdmi_jack;
+	struct snd_soc_jack_pin hdmi_jack_pin;
+	struct cpu_priv cpu_priv;
+	u32 dai_fmt;
+};
+
+static int imx_hdmi_hw_params(struct snd_pcm_substream *substream,
+			      struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct imx_hdmi_data *data = snd_soc_card_get_drvdata(rtd->card);
+	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+	struct snd_soc_card *card = rtd->card;
+	struct device *dev = card->dev;
+	u32 slot_width = data->cpu_priv.slot_width;
+	int ret;
+
+	/* MCLK always is (256 or 192) * rate. */
+	ret = snd_soc_dai_set_sysclk(cpu_dai, data->cpu_priv.sysclk_id[tx],
+				     8 * slot_width * params_rate(params),
+				     tx ? SND_SOC_CLOCK_OUT : SND_SOC_CLOCK_IN);
+	if (ret && ret != -ENOTSUPP) {
+		dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0, 2, slot_width);
+	if (ret && ret != -ENOTSUPP) {
+		dev_err(dev, "failed to set cpu dai tdm slot: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct snd_soc_ops imx_hdmi_ops = {
+	.hw_params = imx_hdmi_hw_params,
+};
+
+static const struct snd_soc_dapm_widget imx_hdmi_widgets[] = {
+	SND_SOC_DAPM_LINE("HDMI Jack", NULL),
+};
+
+static int imx_hdmi_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_card *card = rtd->card;
+	struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
+	struct snd_soc_component *component = codec_dai->component;
+	struct imx_hdmi_data *data = snd_soc_card_get_drvdata(card);
+	int ret;
+
+	data->hdmi_jack_pin.pin = "HDMI Jack";
+	data->hdmi_jack_pin.mask = SND_JACK_LINEOUT;
+	/* enable jack detection */
+	ret = snd_soc_card_jack_new(card, "HDMI Jack", SND_JACK_LINEOUT,
+				    &data->hdmi_jack, &data->hdmi_jack_pin, 1);
+	if (ret) {
+		dev_err(card->dev, "Can't new HDMI Jack %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_component_set_jack(component, &data->hdmi_jack, NULL);
+	if (ret && ret != -EOPNOTSUPP) {
+		dev_err(card->dev, "Can't set HDMI Jack %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+};
+
+static int imx_hdmi_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	bool hdmi_out = of_property_read_bool(np, "hdmi-out");
+	bool hdmi_in = of_property_read_bool(np, "hdmi-in");
+	struct snd_soc_dai_link_component *dlc;
+	struct platform_device *cpu_pdev;
+	struct device_node *cpu_np;
+	struct imx_hdmi_data *data;
+	int ret;
+
+	dlc = devm_kzalloc(&pdev->dev, 3 * sizeof(*dlc), GFP_KERNEL);
+	if (!dlc)
+		return -ENOMEM;
+
+	cpu_np = of_parse_phandle(np, "audio-cpu", 0);
+	if (!cpu_np) {
+		dev_err(&pdev->dev, "cpu dai phandle missing or invalid\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	cpu_pdev = of_find_device_by_node(cpu_np);
+	if (!cpu_pdev) {
+		dev_err(&pdev->dev, "failed to find SAI platform device\n");
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	data->dai.cpus = &dlc[0];
+	data->dai.num_cpus = 1;
+	data->dai.platforms = &dlc[1];
+	data->dai.num_platforms = 1;
+	data->dai.codecs = &dlc[2];
+	data->dai.num_codecs = 1;
+
+	data->dai.name = "i.MX HDMI";
+	data->dai.stream_name = "i.MX HDMI";
+	data->dai.cpus->dai_name = dev_name(&cpu_pdev->dev);
+	data->dai.platforms->of_node = cpu_np;
+	data->dai.ops = &imx_hdmi_ops;
+	data->dai.playback_only = true;
+	data->dai.capture_only = false;
+	data->dai.init = imx_hdmi_init;
+
+	if (of_node_name_eq(cpu_np, "sai")) {
+		data->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1;
+		data->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
+	}
+
+	if (of_device_is_compatible(np, "fsl,imx-audio-sii902x")) {
+		data->dai_fmt = SND_SOC_DAIFMT_LEFT_J;
+		data->cpu_priv.slot_width = 24;
+	} else {
+		data->dai_fmt = SND_SOC_DAIFMT_I2S;
+		data->cpu_priv.slot_width = 32;
+	}
+
+	if ((hdmi_out && hdmi_in) || (!hdmi_out && !hdmi_in)) {
+		dev_err(&pdev->dev, "Invalid HDMI DAI link\n");
+		goto fail;
+	}
+
+	if (hdmi_out) {
+		data->dai.playback_only = true;
+		data->dai.capture_only = false;
+		data->dai.codecs->dai_name = "i2s-hifi";
+		data->dai.codecs->name = "hdmi-audio-codec.1";
+		data->dai.dai_fmt = data->dai_fmt |
+				    SND_SOC_DAIFMT_NB_NF |
+				    SND_SOC_DAIFMT_CBS_CFS;
+	}
+
+	if (hdmi_in) {
+		data->dai.playback_only = false;
+		data->dai.capture_only = true;
+		data->dai.codecs->dai_name = "i2s-hifi";
+		data->dai.codecs->name = "hdmi-audio-codec.2";
+		data->dai.dai_fmt = data->dai_fmt |
+				    SND_SOC_DAIFMT_NB_NF |
+				    SND_SOC_DAIFMT_CBM_CFM;
+	}
+
+	data->card.dapm_widgets = imx_hdmi_widgets;
+	data->card.num_dapm_widgets = ARRAY_SIZE(imx_hdmi_widgets);
+	data->card.dev = &pdev->dev;
+	data->card.owner = THIS_MODULE;
+	ret = snd_soc_of_parse_card_name(&data->card, "model");
+	if (ret)
+		goto fail;
+
+	data->card.num_links = 1;
+	data->card.dai_link = &data->dai;
+
+	snd_soc_card_set_drvdata(&data->card, data);
+	ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
+	if (ret) {
+		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
+		goto fail;
+	}
+
+fail:
+	if (cpu_np)
+		of_node_put(cpu_np);
+
+	return ret;
+}
+
+static const struct of_device_id imx_hdmi_dt_ids[] = {
+	{ .compatible = "fsl,imx-audio-hdmi", },
+	{ .compatible = "fsl,imx-audio-sii902x", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
+
+static struct platform_driver imx_hdmi_driver = {
+	.driver = {
+		.name = "imx-hdmi",
+		.owner = THIS_MODULE,
+		.pm = &snd_soc_pm_ops,
+		.of_match_table = imx_hdmi_dt_ids,
+	},
+	.probe = imx_hdmi_probe,
+};
+module_platform_driver(imx_hdmi_driver);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Freescale i.MX hdmi audio ASoC machine driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:imx-hdmi");
-- 
2.27.0


^ permalink raw reply related

* [PATCH v2 1/2] ASoC: dt-bindings: imx-hdmi: Add binding doc for hdmi machine driver
From: Shengjiu Wang @ 2020-12-06 10:41 UTC (permalink / raw)
  To: timur, nicoleotsuka, Xiubo.Lee, festevam, lgirdwood, broonie,
	perex, tiwai, alsa-devel, linuxppc-dev, linux-kernel, robh+dt,
	devicetree

Imx-hdmi is a new added machine driver for supporting hdmi devices
on i.MX platforms. There is HDMI IP or external HDMI modules connect
with SAI or AUD2HTX interface.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
changes in v2:
- none

 .../bindings/sound/imx-audio-hdmi.yaml        | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/imx-audio-hdmi.yaml

diff --git a/Documentation/devicetree/bindings/sound/imx-audio-hdmi.yaml b/Documentation/devicetree/bindings/sound/imx-audio-hdmi.yaml
new file mode 100644
index 000000000000..d5474f83ac2c
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audio-hdmi.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/imx-audio-hdmi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX audio complex with HDMI
+
+maintainers:
+  - Shengjiu Wang <shengjiu.wang@nxp.com>
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx-audio-hdmi
+      - fsl,imx-audio-sii902x
+
+  model:
+    $ref: /schemas/types.yaml#/definitions/string
+    description: User specified audio sound card name
+
+  audio-cpu:
+    description: The phandle of an CPU DAI controller
+
+  hdmi-out:
+    description: |
+      This is a boolean property. If present, the transmitting function
+      of HDMI will be enabled, indicating there's a physical HDMI out
+      connector or jack on the board or it's connecting to some other IP
+      block, such as an HDMI encoder or display-controller.
+
+  hdmi-in:
+    description: |
+      This is a boolean property. If present, the receiving function of
+      HDMI will be enabled, indicating there is a physical HDMI in
+      connector/jack on the board.
+
+required:
+  - compatible
+  - model
+  - audio-cpu
+
+additionalProperties: false
+
+examples:
+  - |
+    sound-hdmi {
+        compatible = "fsl,imx-audio-hdmi";
+        model = "audio-hdmi";
+        audio-cpu = <&aud2htx>;
+        hdmi-out;
+    };
-- 
2.27.0


^ permalink raw reply related

* Patch "powerpc: Stop exporting __clear_user which is now inlined." has been added to the 4.4-stable tree
From: gregkh @ 2020-12-06 10:19 UTC (permalink / raw)
  To: benh, linuxppc-dev, mpe, msuchanek, paulus; +Cc: stable-commits
In-Reply-To: <20201204232807.31887-1-msuchanek@suse.de>


This is a note to let you know that I've just added the patch titled

    powerpc: Stop exporting __clear_user which is now inlined.

to the 4.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     powerpc-stop-exporting-__clear_user-which-is-now-inlined.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.


From msuchanek@suse.de  Sun Dec  6 10:49:43 2020
From: Michal Suchanek <msuchanek@suse.de>
Date: Sat,  5 Dec 2020 00:28:07 +0100
Subject: powerpc: Stop exporting __clear_user which is now inlined.
To: stable@vger.kernel.org
Cc: Michal Suchanek <msuchanek@suse.de>, Benjamin Herrenschmidt <benh@kernel.crashing.org>, Paul Mackerras <paulus@samba.org>, Michael Ellerman <mpe@ellerman.id.au>, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org
Message-ID: <20201204232807.31887-1-msuchanek@suse.de>

From: Michal Suchanek <msuchanek@suse.de>

Stable commit 452e2a83ea23 ("powerpc: Fix __clear_user() with KUAP
enabled") redefines __clear_user as inline function but does not remove
the export.

Fixes: 452e2a83ea23 ("powerpc: Fix __clear_user() with KUAP enabled")

Signed-off-by: Michal Suchanek <msuchanek@suse.de>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/lib/ppc_ksyms.c |    1 -
 1 file changed, 1 deletion(-)

--- a/arch/powerpc/lib/ppc_ksyms.c
+++ b/arch/powerpc/lib/ppc_ksyms.c
@@ -24,7 +24,6 @@ EXPORT_SYMBOL(csum_tcpudp_magic);
 #endif
 
 EXPORT_SYMBOL(__copy_tofrom_user);
-EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(copy_page);
 
 #ifdef CONFIG_PPC64


Patches currently in stable-queue which might be from msuchanek@suse.de are

queue-4.4/powerpc-stop-exporting-__clear_user-which-is-now-inlined.patch

^ permalink raw reply

* Re: [PATCH] powerpc: Stop exporting __clear_user which is now inlined.
From: Greg KH @ 2020-12-06  9:50 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: linux-kernel, stable, Paul Mackerras, Michal Suchanek,
	linuxppc-dev
In-Reply-To: <87y2ictt80.fsf@mpe.ellerman.id.au>

On Sat, Dec 05, 2020 at 09:58:23PM +1100, Michael Ellerman wrote:
> Michal Suchanek <msuchanek@suse.de> writes:
> > Stable commit 452e2a83ea23 ("powerpc: Fix __clear_user() with KUAP
> > enabled") redefines __clear_user as inline function but does not remove
> > the export.
> >
> > Fixes: 452e2a83ea23 ("powerpc: Fix __clear_user() with KUAP enabled")
> >
> > Signed-off-by: Michal Suchanek <msuchanek@suse.de>
> > ---
> >  arch/powerpc/lib/ppc_ksyms.c | 1 -
> >  1 file changed, 1 deletion(-)
> 
> Acked-by: Michael Ellerman <mpe@ellerman.id.au>

Now applied, thanks.

greg k-h

^ permalink raw reply

* Re: [PATCH 2/8] x86: use exit_lazy_tlb rather than membarrier_mm_sync_core_before_usermode
From: Nicholas Piggin @ 2020-12-06  3:59 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: linux-arch, Arnd Bergmann, Peter Zijlstra, X86 ML, LKML, Linux-MM,
	Mathieu Desnoyers, linuxppc-dev
In-Reply-To: <CALCETrWFjOXAd5=ctX3tzgUbyfwM+bT-f8WY_QWOeuDdFxhWbg@mail.gmail.com>

Excerpts from Andy Lutomirski's message of December 6, 2020 10:36 am:
> On Sat, Dec 5, 2020 at 3:15 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>>
>> Excerpts from Andy Lutomirski's message of December 6, 2020 2:11 am:
>> >
> 
>> If an mm was lazy tlb for a kernel thread and then it becomes unlazy,
>> and if switch_mm is serialising but return to user is not, then you
>> need a serialising instruction somewhere before return to user. unlazy
>> is the logical place to add that, because the lazy tlb mm (i.e.,
>> switching to a kernel thread and back without switching mm) is what
>> opens the hole.
> 
> The issue here is that unlazying on x86 sometimes serializes and
> sometimes doesn't.

That's additional state that x86 keeps around though, which is
fine. It can optimise that case if it knows it's already
serialised.

> It's straightforward to add logic to the x86 code
> to serialize specifically in the case where membarrier core sync is
> registered and unlazying would otherwise not serialize, but trying to
> define sensible semantics for this in a call to core code seems
> complicated.

It's not though, it's a call from core code (to arch code).

> (Specifically, the x86 code only sometimes sends IPIs to
> lazy CPUs for TLB flushes.  If an IPI is skipped, then unlazying will
> flush the TLB, and that operation is serializing.
> 
> The whole lazy thing is IMO a red herring for membarrier().  The
> membarrier() logic requires that switching *logical* mms
> (rq->curr->mm) serializes before user mode if the new mm is registered
> for core sync.

It's not a red herring, the reason the IPI gets skipped is because
we go to a kernel thread -- that's all core code and core lazy tlb
handling.

That x86 might do some additional ops serialise during un-lazy in
some cases doesn't make that a red herring, it just means that you
can take advantage of it and avoid doing an extra serialising op.

> AFAICT the only architecture on which this isn't
> automatic is x86, and somehow the logic turned into "actually changing
> rq->curr->mm serializes, but unlazying only sometimes serializes, so
> we need to do an extra serialization step on unlazying operations"
> instead of "tell x86 to make sure it always serializes when it
> switches logical mms".  The latter is easy to specify and easy to
> implement.
> 
>>
>> How do you mean? exit_lazy_tlb is the opposite, core scheduler notifying
>> arch code about when an mm becomes not-lazy, and nothing to do with
>> membarrier at all even. It's a convenient hook to do your un-lazying.
>> I guess you can do it also checking things in switch_mm and keeping state
>> in arch code, I don't think that's necessarily the best place to put it.
> 
> I'm confused.  I just re-read your patches, and it looks like you have
> arch code calling exit_lazy_tlb().

More for code-comment / consistency than anything else. They are
entirely arch hooks.

> On x86, if we do a TLB shootdown
> IPI to a lazy CPU, the IPI handler will unlazy that CPU (by switching
> to init_mm for real), and we have no way to notify the core scheduler
> about this, so we don't.  The result is that the core scheduler state
> and the x86 state gets out of sync.  If the core scheduler
> subsequently switches us back to the mm that it thinks we were still
> using lazily them, from the x86 code's perspective, we're not
> unlazying -- we're just doing a regular switch from init_mm to some
> other mm.  This is why x86's switch_mm_irqs_off() totally ignores its
> 'prev' argument.

You actually do now have such a way to do that now that we've
(hopefully) closed races, and I think should use it, which might make 
things simpler for you. See patch 6 do_shoot_lazy_tlb().

> I'm honestly a bit surprised that other architectures don't do the
> same thing.  I suppose that some architectures don't use shootdown
> IPIs at all, in which case there doesn't seem to be any good reason to
> aggressively unlazy.

powerpc/radix does (in some cases) since a few years ago. It just 
doesn't fully exploit that for the final TLB shootdown to always clean 
them all up and avoid the subsequent shoot-lazies IPI, but it could be 
more aggressive there.

The powerpc virtualised hash architecture is the traditional one and 
isn't conducive to this (translation management is done via hcalls, and
the hypervisor maintains the TLB) so I suspect that's why it wasn't
done earlier there. That will continue to rely on shoot-lazies.

> (Oddly, despite the fact that, since Ivy Bridge, x86 has a "just flush
> the TLB" instruction, that instruction is considerably slower than the
> old "switch mm and flush" operation.  So the operation "switch to
> init_mm" is only ever any slower than "flush and stay lazy" if we get
> lucky and unlazy to the same mm before we get a second TLB shootdown
> *and* if unlazying to the same mm would not have needed to flush.  I
> spend quite a bit of time tuning this stuff and being quite surprised
> at the bizarre performance properties of Intel's TLB management
> instructions.)

Well, you also casue an extra mm switch in case you returned to the
same mm. Which probably isn't uncommon (app<->idle).

>>
>> So membarrier code is unchanged (it cares that the serialise is done at
>> un-lazy time), core code is simpler (no knowledge of this membarrier
>> quirk and it already knows about lazy-tlb so the calls actually improve
>> the documentation), and x86 code I would argue becomes nicer (or no real
>> difference at worst) because you can move some exit lazy tlb handling to
>> that specific call rather than decipher it from switch_mm.
> 
> As above, I can't move the exit-lazy handling because the scheduler
> doesn't know when I'm unlazying.

As above, you can actually tell it. But even if you don't do that, in
the current scheme it's still telling you a superset of what you need, 
so you'd just put move your extra checks there.

> 
>>
>> >
>> > I’m currently trying to document how membarrier actually works, and
>> > hopefully this will result in untangling membarrier from mmdrop() and
>> > such.
>>
>> That would be nice.
> 
> It's still a work in progress.  I haven't actually convinced myself
> that the non-IPI case in membarrier() is correct, nor have I convinced
> myself that it's incorrect.
> 
> Anyway, I think that my patch is a bit incorrect and I either need a
> barrier somewhere (which may already exist) or a store-release to
> lazy_mm to make sure that all accesses to the lazy mm are done before
> lazy_mm is freed.  On x86, even aside from the fact that all stores
> are releases, this isn't needed -- stopping using an mm is itself a
> full barrier.  Will this be a performance issue on power?

store-release is lwsync on power. Not so bad as a full barrier, but
probably not wonderful. The fast path would be worse than shoot-lazies
of course, but may not be prohibitive.

I'm still going to persue shoot-lazies for the merge window. As you
see it's about a dozen lines and a if (IS_ENABLED(... in core code.
Your change is common code, but a significant complexity (which
affects all archs) so needs a lot more review and testing at this
point.

If x86 is already shooting lazies in its final TLB flush, I don't
know why you're putting so much effort in though, surely it's more
complexity and (even slightly) more cost there too.

> 
>>
>> >
>> > A silly part of this is that x86 already has a high quality
>> > implementation of most of membarrier(): flush_tlb_mm().  If you flush
>> > an mm’s TLB, we carefully propagate the flush to all threads, with
>> > attention to memory ordering.  We can’t use this directly as an
>> > arch-specific implementation of membarrier because it has the annoying
>> > side affect of flushing the TLB and because upcoming hardware might be
>> > able to flush without guaranteeing a core sync.  (Upcoming means Zen
>> > 3, but the Zen 3 implementation is sadly not usable by Linux.)
>> >
>>
>> A hardware broadcast TLB flush, you mean? What makes it unusable by
>> Linux out of curiosity?
> 
> The new instruction is INVLPGB.  Unfortunately, x86's ASID field is
> very narrow, and there's no way we can give each mm the same ASID
> across all CPUs, which means we can't accurately target the flush at
> the correct set of TLB entries.  I've asked engineers at both Intel
> and AMD to widen the ASID field, but that will end up being
> complicated -- x86 has run out of bits in its absurdly overloaded CR3
> encoding, and widening the ASID to any reasonable size would require
> adding a new way to switch mms.  There are lots of reasons that x86
> should do that anyway [0], but it would be a big project and I'm not
> sure that either company is interested in big projects like that.

Interesting, thanks. powerpc has a PID register for guest ASIDs that
implements about 20 bits.

The IPI is very flexible though, it allows more complex/fine grained
flushes and also software state to be updated, so we've started using
it a bit. I haven't seen much software where performance of IPIs is
prohibitive these days. Maybe improvements to threaded malloc, JVMs
databases etc reduce the amount of flushes.


> [0] On x86, you can't switch between (64-bit execution, 48-bit virtual
> address space) and (64-bit execution, 57-bit address space) without
> exiting 64-bit mode in the middle.  This is because the way that the
> addressing mode is split among multiple registers prevents a single
> instruction from switching between the two states.  This is absolutely
> delightful for anyone trying to boot an OS on a system with a very,
> very large amount of memory.
> 

powerpc has some issues like that with context switching guest / host
state there are several MMU registers involved that can't be switched 
with a single instruction. It doesn't require such a big hammer, but
a careful sequence to switch things.

Thanks,
Nick

^ permalink raw reply

* [powerpc:next-test] BUILD SUCCESS 8817aabb1bdd5811130f94ff6442bb19c9158a3a
From: kernel test robot @ 2020-12-06  2:16 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git  next-test
branch HEAD: 8817aabb1bdd5811130f94ff6442bb19c9158a3a  powerpc: Remove ucache_bsize

elapsed time: 864m

configs tested: 137
configs skipped: 10

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                             alldefconfig
powerpc                 mpc8272_ads_defconfig
powerpc                          g5_defconfig
powerpc                     sequoia_defconfig
powerpc                    gamecube_defconfig
nios2                            alldefconfig
arc                        vdk_hs38_defconfig
powerpc                      cm5200_defconfig
arm                          tango4_defconfig
mips                 decstation_r4k_defconfig
powerpc                     tqm8555_defconfig
sh                           se7721_defconfig
c6x                        evmc6457_defconfig
mips                     loongson1c_defconfig
powerpc                         wii_defconfig
mips                  decstation_64_defconfig
xtensa                  cadence_csp_defconfig
arm                        shmobile_defconfig
um                           x86_64_defconfig
ia64                          tiger_defconfig
arm                         mv78xx0_defconfig
ia64                            zx1_defconfig
sh                 kfr2r09-romimage_defconfig
mips                       capcella_defconfig
x86_64                              defconfig
mips                       rbtx49xx_defconfig
arm                          ixp4xx_defconfig
mips                        bcm63xx_defconfig
powerpc                   motionpro_defconfig
mips                           jazz_defconfig
powerpc                        cell_defconfig
ia64                             alldefconfig
powerpc                     tqm5200_defconfig
arc                         haps_hs_defconfig
arm                           spitz_defconfig
arm                          exynos_defconfig
mips                         tb0219_defconfig
arm                          prima2_defconfig
sh                            titan_defconfig
powerpc                       eiger_defconfig
arm                        trizeps4_defconfig
sh                          lboxre2_defconfig
powerpc                    amigaone_defconfig
powerpc               mpc834x_itxgp_defconfig
sparc                               defconfig
arm                        spear3xx_defconfig
arm                         at91_dt_defconfig
powerpc                       ebony_defconfig
mips                         tb0226_defconfig
sh                             espt_defconfig
arm                         vf610m4_defconfig
arm                        multi_v5_defconfig
arm                         nhk8815_defconfig
arm                           sama5_defconfig
powerpc                 mpc8560_ads_defconfig
ia64                        generic_defconfig
arm                           omap1_defconfig
arm                        mini2440_defconfig
s390                                defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
c6x                              allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
i386                               tinyconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a005-20201205
i386                 randconfig-a004-20201205
i386                 randconfig-a001-20201205
i386                 randconfig-a002-20201205
i386                 randconfig-a006-20201205
i386                 randconfig-a003-20201205
i386                 randconfig-a005-20201204
i386                 randconfig-a004-20201204
i386                 randconfig-a001-20201204
i386                 randconfig-a002-20201204
i386                 randconfig-a006-20201204
i386                 randconfig-a003-20201204
x86_64               randconfig-a016-20201205
x86_64               randconfig-a012-20201205
x86_64               randconfig-a014-20201205
x86_64               randconfig-a013-20201205
x86_64               randconfig-a015-20201205
x86_64               randconfig-a011-20201205
i386                 randconfig-a014-20201205
i386                 randconfig-a013-20201205
i386                 randconfig-a011-20201205
i386                 randconfig-a015-20201205
i386                 randconfig-a012-20201205
i386                 randconfig-a016-20201205
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                                   rhel
x86_64                           allyesconfig
x86_64                    rhel-7.6-kselftests
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-a004-20201205
x86_64               randconfig-a006-20201205
x86_64               randconfig-a002-20201205
x86_64               randconfig-a001-20201205
x86_64               randconfig-a005-20201205
x86_64               randconfig-a003-20201205

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply

* [powerpc:merge] BUILD SUCCESS 9acd775e4579bde0a6d937d72f9669e418aa87ad
From: kernel test robot @ 2020-12-06  2:16 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git  merge
branch HEAD: 9acd775e4579bde0a6d937d72f9669e418aa87ad  Automatic merge of 'master' into merge (2020-12-05 22:54)

elapsed time: 848m

configs tested: 119
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                             alldefconfig
powerpc                 mpc8272_ads_defconfig
powerpc                          g5_defconfig
powerpc                     sequoia_defconfig
powerpc                    gamecube_defconfig
powerpc                     tqm8555_defconfig
sh                           se7721_defconfig
mips                         tb0219_defconfig
sh                          rsk7269_defconfig
parisc                              defconfig
sh                        sh7785lcr_defconfig
arm                        shmobile_defconfig
um                           x86_64_defconfig
ia64                          tiger_defconfig
arm                         mv78xx0_defconfig
ia64                            zx1_defconfig
sh                 kfr2r09-romimage_defconfig
mips                       capcella_defconfig
x86_64                              defconfig
mips                       rbtx49xx_defconfig
arm                          ixp4xx_defconfig
mips                        bcm63xx_defconfig
powerpc                     tqm5200_defconfig
arc                         haps_hs_defconfig
arm                           spitz_defconfig
arm                          exynos_defconfig
arm                          prima2_defconfig
sh                            titan_defconfig
powerpc                       eiger_defconfig
arm                        trizeps4_defconfig
sh                          lboxre2_defconfig
sh                             espt_defconfig
arm                         vf610m4_defconfig
arm                        multi_v5_defconfig
arm                         nhk8815_defconfig
arm                           sama5_defconfig
powerpc                 mpc8560_ads_defconfig
ia64                        generic_defconfig
arm                           omap1_defconfig
arm                        mini2440_defconfig
s390                                defconfig
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
c6x                              allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
s390                             allyesconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                               tinyconfig
i386                                defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
i386                 randconfig-a005-20201205
i386                 randconfig-a004-20201205
i386                 randconfig-a001-20201205
i386                 randconfig-a002-20201205
i386                 randconfig-a006-20201205
i386                 randconfig-a003-20201205
i386                 randconfig-a005-20201204
i386                 randconfig-a004-20201204
i386                 randconfig-a001-20201204
i386                 randconfig-a002-20201204
i386                 randconfig-a006-20201204
i386                 randconfig-a003-20201204
x86_64               randconfig-a016-20201205
x86_64               randconfig-a012-20201205
x86_64               randconfig-a014-20201205
x86_64               randconfig-a013-20201205
x86_64               randconfig-a015-20201205
x86_64               randconfig-a011-20201205
i386                 randconfig-a014-20201205
i386                 randconfig-a013-20201205
i386                 randconfig-a011-20201205
i386                 randconfig-a015-20201205
i386                 randconfig-a012-20201205
i386                 randconfig-a016-20201205
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                                   rhel
x86_64                           allyesconfig
x86_64                    rhel-7.6-kselftests
x86_64                               rhel-8.3
x86_64                                  kexec

clang tested configs:
x86_64               randconfig-a004-20201205
x86_64               randconfig-a006-20201205
x86_64               randconfig-a002-20201205
x86_64               randconfig-a001-20201205
x86_64               randconfig-a005-20201205
x86_64               randconfig-a003-20201205

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

^ permalink raw reply

* Re: [PATCH 2/8] x86: use exit_lazy_tlb rather than membarrier_mm_sync_core_before_usermode
From: Andy Lutomirski @ 2020-12-06  0:36 UTC (permalink / raw)
  To: Nicholas Piggin
  Cc: linux-arch, Arnd Bergmann, Peter Zijlstra, X86 ML, LKML, Linux-MM,
	Mathieu Desnoyers, Andy Lutomirski, linuxppc-dev
In-Reply-To: <1607209402.fogfsh8ov4.astroid@bobo.none>

On Sat, Dec 5, 2020 at 3:15 PM Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Excerpts from Andy Lutomirski's message of December 6, 2020 2:11 am:
> >

> If an mm was lazy tlb for a kernel thread and then it becomes unlazy,
> and if switch_mm is serialising but return to user is not, then you
> need a serialising instruction somewhere before return to user. unlazy
> is the logical place to add that, because the lazy tlb mm (i.e.,
> switching to a kernel thread and back without switching mm) is what
> opens the hole.

The issue here is that unlazying on x86 sometimes serializes and
sometimes doesn't.  It's straightforward to add logic to the x86 code
to serialize specifically in the case where membarrier core sync is
registered and unlazying would otherwise not serialize, but trying to
define sensible semantics for this in a call to core code seems
complicated.  (Specifically, the x86 code only sometimes sends IPIs to
lazy CPUs for TLB flushes.  If an IPI is skipped, then unlazying will
flush the TLB, and that operation is serializing.

The whole lazy thing is IMO a red herring for membarrier().  The
membarrier() logic requires that switching *logical* mms
(rq->curr->mm) serializes before user mode if the new mm is registered
for core sync.  AFAICT the only architecture on which this isn't
automatic is x86, and somehow the logic turned into "actually changing
rq->curr->mm serializes, but unlazying only sometimes serializes, so
we need to do an extra serialization step on unlazying operations"
instead of "tell x86 to make sure it always serializes when it
switches logical mms".  The latter is easy to specify and easy to
implement.

>
> How do you mean? exit_lazy_tlb is the opposite, core scheduler notifying
> arch code about when an mm becomes not-lazy, and nothing to do with
> membarrier at all even. It's a convenient hook to do your un-lazying.
> I guess you can do it also checking things in switch_mm and keeping state
> in arch code, I don't think that's necessarily the best place to put it.

I'm confused.  I just re-read your patches, and it looks like you have
arch code calling exit_lazy_tlb().  On x86, if we do a TLB shootdown
IPI to a lazy CPU, the IPI handler will unlazy that CPU (by switching
to init_mm for real), and we have no way to notify the core scheduler
about this, so we don't.  The result is that the core scheduler state
and the x86 state gets out of sync.  If the core scheduler
subsequently switches us back to the mm that it thinks we were still
using lazily them, from the x86 code's perspective, we're not
unlazying -- we're just doing a regular switch from init_mm to some
other mm.  This is why x86's switch_mm_irqs_off() totally ignores its
'prev' argument.

I'm honestly a bit surprised that other architectures don't do the
same thing.  I suppose that some architectures don't use shootdown
IPIs at all, in which case there doesn't seem to be any good reason to
aggressively unlazy.

(Oddly, despite the fact that, since Ivy Bridge, x86 has a "just flush
the TLB" instruction, that instruction is considerably slower than the
old "switch mm and flush" operation.  So the operation "switch to
init_mm" is only ever any slower than "flush and stay lazy" if we get
lucky and unlazy to the same mm before we get a second TLB shootdown
*and* if unlazying to the same mm would not have needed to flush.  I
spend quite a bit of time tuning this stuff and being quite surprised
at the bizarre performance properties of Intel's TLB management
instructions.)

>
> So membarrier code is unchanged (it cares that the serialise is done at
> un-lazy time), core code is simpler (no knowledge of this membarrier
> quirk and it already knows about lazy-tlb so the calls actually improve
> the documentation), and x86 code I would argue becomes nicer (or no real
> difference at worst) because you can move some exit lazy tlb handling to
> that specific call rather than decipher it from switch_mm.

As above, I can't move the exit-lazy handling because the scheduler
doesn't know when I'm unlazying.

>
> >
> > I’m currently trying to document how membarrier actually works, and
> > hopefully this will result in untangling membarrier from mmdrop() and
> > such.
>
> That would be nice.

It's still a work in progress.  I haven't actually convinced myself
that the non-IPI case in membarrier() is correct, nor have I convinced
myself that it's incorrect.

Anyway, I think that my patch is a bit incorrect and I either need a
barrier somewhere (which may already exist) or a store-release to
lazy_mm to make sure that all accesses to the lazy mm are done before
lazy_mm is freed.  On x86, even aside from the fact that all stores
are releases, this isn't needed -- stopping using an mm is itself a
full barrier.  Will this be a performance issue on power?

>
> >
> > A silly part of this is that x86 already has a high quality
> > implementation of most of membarrier(): flush_tlb_mm().  If you flush
> > an mm’s TLB, we carefully propagate the flush to all threads, with
> > attention to memory ordering.  We can’t use this directly as an
> > arch-specific implementation of membarrier because it has the annoying
> > side affect of flushing the TLB and because upcoming hardware might be
> > able to flush without guaranteeing a core sync.  (Upcoming means Zen
> > 3, but the Zen 3 implementation is sadly not usable by Linux.)
> >
>
> A hardware broadcast TLB flush, you mean? What makes it unusable by
> Linux out of curiosity?

The new instruction is INVLPGB.  Unfortunately, x86's ASID field is
very narrow, and there's no way we can give each mm the same ASID
across all CPUs, which means we can't accurately target the flush at
the correct set of TLB entries.  I've asked engineers at both Intel
and AMD to widen the ASID field, but that will end up being
complicated -- x86 has run out of bits in its absurdly overloaded CR3
encoding, and widening the ASID to any reasonable size would require
adding a new way to switch mms.  There are lots of reasons that x86
should do that anyway [0], but it would be a big project and I'm not
sure that either company is interested in big projects like that.

[0] On x86, you can't switch between (64-bit execution, 48-bit virtual
address space) and (64-bit execution, 57-bit address space) without
exiting 64-bit mode in the middle.  This is because the way that the
addressing mode is split among multiple registers prevents a single
instruction from switching between the two states.  This is absolutely
delightful for anyone trying to boot an OS on a system with a very,
very large amount of memory.

^ permalink raw reply

* Re: [PATCH 2/8] x86: use exit_lazy_tlb rather than membarrier_mm_sync_core_before_usermode
From: Nicholas Piggin @ 2020-12-05 23:14 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: linux-arch, Arnd Bergmann, Peter Zijlstra, X86 ML, LKML, Linux-MM,
	Mathieu Desnoyers, Andy Lutomirski, linuxppc-dev
In-Reply-To: <116A6B40-C77B-4B6A-897B-18342CD62CEC@amacapital.net>

Excerpts from Andy Lutomirski's message of December 6, 2020 2:11 am:
> 
>> On Dec 5, 2020, at 12:00 AM, Nicholas Piggin <npiggin@gmail.com> wrote:
>> 
>> 
>> I disagree. Until now nobody following it noticed that the mm gets
>> un-lazied in other cases, because that was not too clear from the
>> code (only indirectly using non-standard terminology in the arch
>> support document).
> 
>> In other words, membarrier needs a special sync to deal with the case 
>> when a kthread takes the mm.
> 
> I don’t think this is actually true. Somehow the x86 oddities about 
> CR3 writes leaked too much into the membarrier core code and comments. 
> (I doubt this is x86 specific.  The actual x86 specific part seems to 
> be that we can return to user mode without syncing the instruction 
> stream.)
> 
> As far as I can tell, membarrier doesn’t care at all about laziness. 
> Membarrier cares about rq->curr->mm.  The fact that a cpu can switch 
> its actual loaded mm without scheduling at all (on x86 at least) is 
> entirely beside the point except insofar as it has an effect on 
> whether a subsequent switch_mm() call serializes.

Core membarrier itself doesn't care about laziness, which is why the
membarrier flush should go in exit_lazy_tlb() or other x86 specific
code (at least until more architectures did the same thing and we moved
it into generic code). I just meant this non-serialising return as 
documented in the membarrier arch enablement doc specifies the lazy tlb
requirement.

If an mm was lazy tlb for a kernel thread and then it becomes unlazy,
and if switch_mm is serialising but return to user is not, then you
need a serialising instruction somewhere before return to user. unlazy
is the logical place to add that, because the lazy tlb mm (i.e., 
switching to a kernel thread and back without switching mm) is what 
opens the hole.

> If we notify 
> membarrier about x86’s asynchronous CR3 writes, then membarrier needs 
> to understand what to do with them, which results in an unmaintainable 
> mess in membarrier *and* in the x86 code.

How do you mean? exit_lazy_tlb is the opposite, core scheduler notifying
arch code about when an mm becomes not-lazy, and nothing to do with
membarrier at all even. It's a convenient hook to do your un-lazying.
I guess you can do it also checking things in switch_mm and keeping state
in arch code, I don't think that's necessarily the best place to put it.

So membarrier code is unchanged (it cares that the serialise is done at
un-lazy time), core code is simpler (no knowledge of this membarrier 
quirk and it already knows about lazy-tlb so the calls actually improve 
the documentation), and x86 code I would argue becomes nicer (or no real
difference at worst) because you can move some exit lazy tlb handling to
that specific call rather than decipher it from switch_mm.

> 
> I’m currently trying to document how membarrier actually works, and 
> hopefully this will result in untangling membarrier from mmdrop() and 
> such.

That would be nice.

> 
> A silly part of this is that x86 already has a high quality 
> implementation of most of membarrier(): flush_tlb_mm().  If you flush 
> an mm’s TLB, we carefully propagate the flush to all threads, with 
> attention to memory ordering.  We can’t use this directly as an 
> arch-specific implementation of membarrier because it has the annoying 
> side affect of flushing the TLB and because upcoming hardware might be 
> able to flush without guaranteeing a core sync.  (Upcoming means Zen 
> 3, but the Zen 3 implementation is sadly not usable by Linux.)
> 

A hardware broadcast TLB flush, you mean? What makes it unusable by 
Linux out of curiosity?

^ permalink raw reply

* Re: [PATCH 11/20] ethernet: ucc_geth: fix use-after-free in ucc_geth_remove()
From: Rasmus Villemoes @ 2020-12-05 21:50 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Vladimir Oltean, linux-kernel, Li Yang, netdev, linuxppc-dev,
	David S. Miller, Zhao Qiang
In-Reply-To: <4d35ef11-b1eb-c450-2937-94e20fa9a213@prevas.dk>


> I only noticed because I needed to add a free of the ug_info in a later
> patch.

Where, ironically, I add a use-after-free bug by freeing ug_info before
the ucc_geth_memclean() call.

:facepalm:


^ permalink raw reply

* Re: [PATCH 00/20] ethernet: ucc_geth: assorted fixes and simplifications
From: Rasmus Villemoes @ 2020-12-05 21:36 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: netdev, linux-kernel, Li Yang, Vladimir Oltean, linuxppc-dev,
	David S. Miller, linux-arm-kernel, Qiang Zhao
In-Reply-To: <20201205132716.4c68e35d@kicinski-fedora-pc1c0hjn.DHCP.thefacebook.com>

On 05/12/2020 22.27, Jakub Kicinski wrote:
> On Sat, 5 Dec 2020 22:11:39 +0100 Rasmus Villemoes wrote:
>>> rebase (retest) and post them against the net tree:
>>>
>>> https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/  
>>
>> So I thought this would go through Li Yang's tree. That's where my
>> previous QE related patches have gone through, and at least some need
>> some input from NXP folks - and what MAINTAINERS suggests. So not
>> marking the patches with net or net-next was deliberate. But I'm happy
>> to rearrange and send to net/net-next as appropriate if that's what you
>> and Li Yang can agree to.
> 
> Ah, now I noticed you didn't CC all of the patches to netdev.
> Please don't do that, build bots won't be able to validate partially
> posted patches.

Hm, I mostly rely on scripts/get_maintainer.pl, invoked via a script I
give to --to-cmd/--cc-cmd. They are all sent to LKML, so buildbots
should be OK. But regardless of whether Li Yang will be handling it or
not, I'll try to remember to cc the whole series to netdev when resending.

Rasmus

^ permalink raw reply

* Re: [PATCH 11/20] ethernet: ucc_geth: fix use-after-free in ucc_geth_remove()
From: Rasmus Villemoes @ 2020-12-05 21:35 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Vladimir Oltean, linux-kernel, Li Yang, netdev, linuxppc-dev,
	David S. Miller, Zhao Qiang
In-Reply-To: <20201205131928.7d5c8e59@kicinski-fedora-pc1c0hjn.DHCP.thefacebook.com>

On 05/12/2020 22.19, Jakub Kicinski wrote:
> On Sat, 5 Dec 2020 22:04:28 +0100 Rasmus Villemoes wrote:
>> On 05/12/2020 21.48, Jakub Kicinski wrote:
>>> On Sat,  5 Dec 2020 20:17:34 +0100 Rasmus Villemoes wrote:  
>>>> -	unregister_netdev(dev);
>>>> -	free_netdev(dev);
>>>>  	ucc_geth_memclean(ugeth);
>>>>  	if (of_phy_is_fixed_link(np))
>>>>  		of_phy_deregister_fixed_link(np);
>>>>  	of_node_put(ugeth->ug_info->tbi_node);
>>>>  	of_node_put(ugeth->ug_info->phy_node);
>>>> +	unregister_netdev(dev);
>>>> +	free_netdev(dev);  
>>>
>>> Are you sure you want to move the unregister_netdev() as well as the
>>> free?
>>
>> Hm, dunno, I don't think it's needed per se, but it also shouldn't hurt
>> from what I can tell. It seems more natural that they go together, but
>> if you prefer a minimal patch that's of course also possible.
> 
> I was concerned about the fact that we free things and release
> references while the device may still be up (given that it's
> unregister_netdev() that will take it down).

I guess you're right. I'll fix it locally (and pull the patch earlier)
and wait a few days with sending an updated version to give Li Yang some
time to say if he wants to handle the series or not.

Thanks,
Rasmus

^ permalink raw reply

* Re: [PATCH 00/20] ethernet: ucc_geth: assorted fixes and simplifications
From: Jakub Kicinski @ 2020-12-05 21:27 UTC (permalink / raw)
  To: Rasmus Villemoes
  Cc: netdev, linux-kernel, Li Yang, Vladimir Oltean, linuxppc-dev,
	David S. Miller, linux-arm-kernel, Qiang Zhao
In-Reply-To: <7e78df84-0035-6935-acb0-adbd0c648128@prevas.dk>

On Sat, 5 Dec 2020 22:11:39 +0100 Rasmus Villemoes wrote:
> > Looks like a nice clean up on a quick look.
> > 
> > Please separate patches 1 and 11 (which are the two bug fixes I see)  
> 
> I think patch 2 is a bug fix as well, but I'd like someone from NXP to
> comment.

Sure, makes sense.

> > rebase (retest) and post them against the net tree:
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/  
> 
> So I thought this would go through Li Yang's tree. That's where my
> previous QE related patches have gone through, and at least some need
> some input from NXP folks - and what MAINTAINERS suggests. So not
> marking the patches with net or net-next was deliberate. But I'm happy
> to rearrange and send to net/net-next as appropriate if that's what you
> and Li Yang can agree to.

Ah, now I noticed you didn't CC all of the patches to netdev.
Please don't do that, build bots won't be able to validate partially
posted patches.

^ 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