From caihuoqing at baidu.com  Wed Sep  1 00:40:30 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:40:30 +0800
Subject: [PATCH] mtd: rawnand: atmel: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074031.8883-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/atmel/pmecc.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c
index cbb023bf00f7..498e41ccabbd 100644
--- a/drivers/mtd/nand/raw/atmel/pmecc.c
+++ b/drivers/mtd/nand/raw/atmel/pmecc.c
@@ -834,7 +834,6 @@ static struct atmel_pmecc *atmel_pmecc_create(struct platform_device *pdev,
 {
 	struct device *dev = &pdev->dev;
 	struct atmel_pmecc *pmecc;
-	struct resource *res;
 
 	pmecc = devm_kzalloc(dev, sizeof(*pmecc), GFP_KERNEL);
 	if (!pmecc)
@@ -844,13 +843,11 @@ static struct atmel_pmecc *atmel_pmecc_create(struct platform_device *pdev,
 	pmecc->dev = dev;
 	mutex_init(&pmecc->lock);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, pmecc_res_idx);
-	pmecc->regs.base = devm_ioremap_resource(dev, res);
+	pmecc->regs.base = devm_platform_ioremap_resource(pdev, pmecc_res_idx);
 	if (IS_ERR(pmecc->regs.base))
 		return ERR_CAST(pmecc->regs.base);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, errloc_res_idx);
-	pmecc->regs.errloc = devm_ioremap_resource(dev, res);
+	pmecc->regs.errloc = devm_platform_ioremap_resource(pdev, errloc_res_idx);
 	if (IS_ERR(pmecc->regs.errloc))
 		return ERR_CAST(pmecc->regs.errloc);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:40:38 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:40:38 +0800
Subject: [PATCH] mtd: rawnand: bcm6368: Make use of the helper function
 devm_platform_ioremap_resource_byname()
Message-ID: <20210901074108.8933-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource_byname() helper instead of
calling platform_get_resource_byname() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c b/drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c
index 7c17ec4ce8b6..a06cd87f839a 100644
--- a/drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c
+++ b/drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c
@@ -88,16 +88,13 @@ static int bcm6368_nand_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct bcm6368_nand_soc *priv;
 	struct brcmnand_soc *soc;
-	struct resource *res;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 	soc = &priv->soc;
 
-	res = platform_get_resource_byname(pdev,
-		IORESOURCE_MEM, "nand-int-base");
-	priv->base = devm_ioremap_resource(dev, res);
+	priv->base = devm_platform_ioremap_resource_byname(pdev, "nand-int-base");
 	if (IS_ERR(priv->base))
 		return PTR_ERR(priv->base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:41:15 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:41:15 +0800
Subject: [PATCH] mtd: rawnand: denali: Make use of the helper function
 devm_platform_ioremap_resource_byname()
Message-ID: <20210901074116.8983-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource_byname() helper instead of
calling platform_get_resource_byname() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/denali_dt.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c
index f08740ae282b..8513bb9fcfcc 100644
--- a/drivers/mtd/nand/raw/denali_dt.c
+++ b/drivers/mtd/nand/raw/denali_dt.c
@@ -113,7 +113,6 @@ static int denali_dt_chip_init(struct denali_controller *denali,
 static int denali_dt_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct resource *res;
 	struct denali_dt *dt;
 	const struct denali_dt_data *data;
 	struct denali_controller *denali;
@@ -139,13 +138,11 @@ static int denali_dt_probe(struct platform_device *pdev)
 	if (denali->irq < 0)
 		return denali->irq;
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "denali_reg");
-	denali->reg = devm_ioremap_resource(dev, res);
+	denali->reg = devm_platform_ioremap_resource_byname(pdev, "denali_reg");
 	if (IS_ERR(denali->reg))
 		return PTR_ERR(denali->reg);
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
-	denali->host = devm_ioremap_resource(dev, res);
+	denali->host = devm_platform_ioremap_resource_byname(pdev, "nand_data");
 	if (IS_ERR(denali->host))
 		return PTR_ERR(denali->host);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:41:22 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:41:22 +0800
Subject: [PATCH] mtd: rawnand: gpio: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074123.9033-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/gpio.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/gpio.c b/drivers/mtd/nand/raw/gpio.c
index fb7a086de35e..8901c4aa0c21 100644
--- a/drivers/mtd/nand/raw/gpio.c
+++ b/drivers/mtd/nand/raw/gpio.c
@@ -303,8 +303,7 @@ static int gpio_nand_probe(struct platform_device *pdev)
 
 	chip = &gpiomtd->nand_chip;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	gpiomtd->io = devm_ioremap_resource(dev, res);
+	gpiomtd->io = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(gpiomtd->io))
 		return PTR_ERR(gpiomtd->io);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:41:30 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:41:30 +0800
Subject: [PATCH] mtd: rawnand: gpmi: Make use of the helper function
 devm_platform_ioremap_resource_byname()
Message-ID: <20210901074130.9083-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource_byname() helper instead of
calling platform_get_resource_byname() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 4d08e4ab5c1b..10cc71829dcb 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -951,11 +951,9 @@ static int acquire_register_block(struct gpmi_nand_data *this,
 {
 	struct platform_device *pdev = this->pdev;
 	struct resources *res = &this->resources;
-	struct resource *r;
 	void __iomem *p;
 
-	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
-	p = devm_ioremap_resource(&pdev->dev, r);
+	p = devm_platform_ioremap_resource_byname(pdev, res_name);
 	if (IS_ERR(p))
 		return PTR_ERR(p);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:41:37 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:41:37 +0800
Subject: [PATCH] mtd: rawnand: hisi504: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074138.9133-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/hisi504_nand.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/raw/hisi504_nand.c b/drivers/mtd/nand/raw/hisi504_nand.c
index 78c4e05434e2..c74f6b2192fc 100644
--- a/drivers/mtd/nand/raw/hisi504_nand.c
+++ b/drivers/mtd/nand/raw/hisi504_nand.c
@@ -738,7 +738,6 @@ static int hisi_nfc_probe(struct platform_device *pdev)
 	struct hinfc_host *host;
 	struct nand_chip  *chip;
 	struct mtd_info   *mtd;
-	struct resource	  *res;
 	struct device_node *np = dev->of_node;
 
 	host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
@@ -754,13 +753,11 @@ static int hisi_nfc_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENXIO;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	host->iobase = devm_ioremap_resource(dev, res);
+	host->iobase = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(host->iobase))
 		return PTR_ERR(host->iobase);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	host->mmio = devm_ioremap_resource(dev, res);
+	host->mmio = devm_platform_ioremap_resource(pdev, 1);
 	if (IS_ERR(host->mmio))
 		return PTR_ERR(host->mmio);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:41:44 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:41:44 +0800
Subject: [PATCH] mtd: rawnand: mtk: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074145.9183-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/mtk_nand.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
index 5c5c92132287..66f04c693c87 100644
--- a/drivers/mtd/nand/raw/mtk_nand.c
+++ b/drivers/mtd/nand/raw/mtk_nand.c
@@ -1520,7 +1520,6 @@ static int mtk_nfc_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct mtk_nfc *nfc;
-	struct resource *res;
 	int ret, irq;
 
 	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
@@ -1541,8 +1540,7 @@ static int mtk_nfc_probe(struct platform_device *pdev)
 	nfc->caps = of_device_get_match_data(dev);
 	nfc->dev = dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	nfc->regs = devm_ioremap_resource(dev, res);
+	nfc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(nfc->regs)) {
 		ret = PTR_ERR(nfc->regs);
 		goto release_ecc;
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:41:52 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:41:52 +0800
Subject: [PATCH] mtd: rawnand: mtk_ecc: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074153.9233-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/mtk_ecc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/mtk_ecc.c b/drivers/mtd/nand/raw/mtk_ecc.c
index c437d97debb8..1b47964cb6da 100644
--- a/drivers/mtd/nand/raw/mtk_ecc.c
+++ b/drivers/mtd/nand/raw/mtk_ecc.c
@@ -495,7 +495,6 @@ static int mtk_ecc_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_ecc *ecc;
-	struct resource *res;
 	u32 max_eccdata_size;
 	int irq, ret;
 
@@ -513,8 +512,7 @@ static int mtk_ecc_probe(struct platform_device *pdev)
 	if (!ecc->eccdata)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ecc->regs = devm_ioremap_resource(dev, res);
+	ecc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ecc->regs))
 		return PTR_ERR(ecc->regs);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:41:59 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:41:59 +0800
Subject: [PATCH] mtd: rawnand: omap_elm: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074200.9283-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/omap_elm.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c
index 2b21ce04b3ec..8bab753211e9 100644
--- a/drivers/mtd/nand/raw/omap_elm.c
+++ b/drivers/mtd/nand/raw/omap_elm.c
@@ -384,7 +384,7 @@ static irqreturn_t elm_isr(int this_irq, void *dev_id)
 static int elm_probe(struct platform_device *pdev)
 {
 	int ret = 0;
-	struct resource *res, *irq;
+	struct resource *irq;
 	struct elm_info *info;
 
 	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
@@ -399,8 +399,7 @@ static int elm_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	info->elm_base = devm_ioremap_resource(&pdev->dev, res);
+	info->elm_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(info->elm_base))
 		return PTR_ERR(info->elm_base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:42:07 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:42:07 +0800
Subject: [PATCH] mtd: rawnand: oxnas: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074207.9333-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/oxnas_nand.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/oxnas_nand.c b/drivers/mtd/nand/raw/oxnas_nand.c
index f44947043e5a..cd112d45e0b5 100644
--- a/drivers/mtd/nand/raw/oxnas_nand.c
+++ b/drivers/mtd/nand/raw/oxnas_nand.c
@@ -79,7 +79,6 @@ static int oxnas_nand_probe(struct platform_device *pdev)
 	struct oxnas_nand_ctrl *oxnas;
 	struct nand_chip *chip;
 	struct mtd_info *mtd;
-	struct resource *res;
 	int count = 0;
 	int err = 0;
 	int i;
@@ -92,8 +91,7 @@ static int oxnas_nand_probe(struct platform_device *pdev)
 
 	nand_controller_init(&oxnas->base);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	oxnas->io_base = devm_ioremap_resource(&pdev->dev, res);
+	oxnas->io_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(oxnas->io_base))
 		return PTR_ERR(oxnas->io_base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:42:14 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:42:14 +0800
Subject: [PATCH] mtd: rawnand: plat_nand: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074215.9383-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/plat_nand.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/plat_nand.c b/drivers/mtd/nand/raw/plat_nand.c
index 7711e1020c21..c1b2072cb507 100644
--- a/drivers/mtd/nand/raw/plat_nand.c
+++ b/drivers/mtd/nand/raw/plat_nand.c
@@ -41,7 +41,6 @@ static int plat_nand_probe(struct platform_device *pdev)
 	struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev);
 	struct plat_nand_data *data;
 	struct mtd_info *mtd;
-	struct resource *res;
 	const char **part_types;
 	int err = 0;
 
@@ -65,8 +64,7 @@ static int plat_nand_probe(struct platform_device *pdev)
 	nand_controller_init(&data->controller);
 	data->chip.controller = &data->controller;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	data->io_base = devm_ioremap_resource(&pdev->dev, res);
+	data->io_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->io_base))
 		return PTR_ERR(data->io_base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:42:22 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:42:22 +0800
Subject: [PATCH] mtd: rawnand: stm32_fmc2: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074222.9433-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/stm32_fmc2_nand.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
index 1c277fbb91f2..97b4e02e43e4 100644
--- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
+++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
@@ -1899,15 +1899,11 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
 
 		nfc->data_phys_addr[chip_cs] = res->start;
 
-		res = platform_get_resource(pdev, IORESOURCE_MEM,
-					    mem_region + 1);
-		nfc->cmd_base[chip_cs] = devm_ioremap_resource(dev, res);
+		nfc->cmd_base[chip_cs] = devm_platform_ioremap_resource(pdev, mem_region + 1);
 		if (IS_ERR(nfc->cmd_base[chip_cs]))
 			return PTR_ERR(nfc->cmd_base[chip_cs]);
 
-		res = platform_get_resource(pdev, IORESOURCE_MEM,
-					    mem_region + 2);
-		nfc->addr_base[chip_cs] = devm_ioremap_resource(dev, res);
+		nfc->addr_base[chip_cs] = devm_platform_ioremap_resource(pdev, mem_region + 2);
 		if (IS_ERR(nfc->addr_base[chip_cs]))
 			return PTR_ERR(nfc->addr_base[chip_cs]);
 	}
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:42:29 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:42:29 +0800
Subject: [PATCH] mtd: rawnand: tegra: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074230.9483-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/tegra_nand.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c
index fbf67722a049..32431bbe69b8 100644
--- a/drivers/mtd/nand/raw/tegra_nand.c
+++ b/drivers/mtd/nand/raw/tegra_nand.c
@@ -1144,7 +1144,6 @@ static int tegra_nand_probe(struct platform_device *pdev)
 {
 	struct reset_control *rst;
 	struct tegra_nand_controller *ctrl;
-	struct resource *res;
 	int err = 0;
 
 	ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
@@ -1155,8 +1154,7 @@ static int tegra_nand_probe(struct platform_device *pdev)
 	nand_controller_init(&ctrl->controller);
 	ctrl->controller.ops = &tegra_nand_controller_ops;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ctrl->regs = devm_ioremap_resource(&pdev->dev, res);
+	ctrl->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(ctrl->regs))
 		return PTR_ERR(ctrl->regs);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:42:37 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:42:37 +0800
Subject: [PATCH] mtd: rawnand: txx9ndfm: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074237.9533-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/txx9ndfmc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/txx9ndfmc.c b/drivers/mtd/nand/raw/txx9ndfmc.c
index b8894ac27073..b42d61b30c0b 100644
--- a/drivers/mtd/nand/raw/txx9ndfmc.c
+++ b/drivers/mtd/nand/raw/txx9ndfmc.c
@@ -284,13 +284,11 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
 	int i;
 	struct txx9ndfmc_drvdata *drvdata;
 	unsigned long gbusclk = plat->gbus_clock;
-	struct resource *res;
 
 	drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);
 	if (!drvdata)
 		return -ENOMEM;
-	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	drvdata->base = devm_ioremap_resource(&dev->dev, res);
+	drvdata->base = devm_platform_ioremap_resource(dev, 0);
 	if (IS_ERR(drvdata->base))
 		return PTR_ERR(drvdata->base);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:42:44 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:42:44 +0800
Subject: [PATCH] mtd: rawnand: vf610: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074245.9583-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/vf610_nfc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c
index 40d70f991d89..a2b89b75073f 100644
--- a/drivers/mtd/nand/raw/vf610_nfc.c
+++ b/drivers/mtd/nand/raw/vf610_nfc.c
@@ -807,7 +807,6 @@ static const struct nand_controller_ops vf610_nfc_controller_ops = {
 static int vf610_nfc_probe(struct platform_device *pdev)
 {
 	struct vf610_nfc *nfc;
-	struct resource *res;
 	struct mtd_info *mtd;
 	struct nand_chip *chip;
 	struct device_node *child;
@@ -831,8 +830,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
 	if (irq <= 0)
 		return -EINVAL;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	nfc->regs = devm_ioremap_resource(nfc->dev, res);
+	nfc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(nfc->regs))
 		return PTR_ERR(nfc->regs);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:42:51 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:42:51 +0800
Subject: [PATCH] mtd: rawnand: xway: Make use of the helper function
 devm_platform_ioremap_resource()
Message-ID: <20210901074252.9633-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource() helper instead of
calling platform_get_resource() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/nand/raw/xway_nand.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/xway_nand.c b/drivers/mtd/nand/raw/xway_nand.c
index 26751976e502..92067bd55384 100644
--- a/drivers/mtd/nand/raw/xway_nand.c
+++ b/drivers/mtd/nand/raw/xway_nand.c
@@ -167,7 +167,6 @@ static int xway_nand_probe(struct platform_device *pdev)
 {
 	struct xway_nand_data *data;
 	struct mtd_info *mtd;
-	struct resource *res;
 	int err;
 	u32 cs;
 	u32 cs_flag = 0;
@@ -178,8 +177,7 @@ static int xway_nand_probe(struct platform_device *pdev)
 	if (!data)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	data->nandaddr = devm_ioremap_resource(&pdev->dev, res);
+	data->nandaddr = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->nandaddr))
 		return PTR_ERR(data->nandaddr);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:42:59 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:42:59 +0800
Subject: [PATCH] mtd: spi-nor: hisi-sfc: Make use of the helper function
 devm_platform_ioremap_resource_byname()
Message-ID: <20210901074259.9683-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource_byname() helper instead of
calling platform_get_resource_byname() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/spi-nor/controllers/hisi-sfc.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/controllers/hisi-sfc.c b/drivers/mtd/spi-nor/controllers/hisi-sfc.c
index 47fbf1d1e557..5b6d1d994641 100644
--- a/drivers/mtd/spi-nor/controllers/hisi-sfc.c
+++ b/drivers/mtd/spi-nor/controllers/hisi-sfc.c
@@ -421,7 +421,6 @@ static int hisi_spi_nor_register_all(struct hifmc_host *host)
 static int hisi_spi_nor_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct resource *res;
 	struct hifmc_host *host;
 	int ret;
 
@@ -432,13 +431,11 @@ static int hisi_spi_nor_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, host);
 	host->dev = dev;
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control");
-	host->regbase = devm_ioremap_resource(dev, res);
+	host->regbase = devm_platform_ioremap_resource_byname(pdev, "control");
 	if (IS_ERR(host->regbase))
 		return PTR_ERR(host->regbase);
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
-	host->iobase = devm_ioremap_resource(dev, res);
+	host->iobase = devm_platform_ioremap_resource_byname(pdev, "memory");
 	if (IS_ERR(host->iobase))
 		return PTR_ERR(host->iobase);
 
-- 
2.25.1



From caihuoqing at baidu.com  Wed Sep  1 00:43:06 2021
From: caihuoqing at baidu.com (Cai Huoqing)
Date: Wed, 1 Sep 2021 15:43:06 +0800
Subject: [PATCH] mtd: spi-nor: nxp-spifi: Make use of the helper function
 devm_platform_ioremap_resource_byname()
Message-ID: <20210901074307.9733-1-caihuoqing@baidu.com>

Use the devm_platform_ioremap_resource_byname() helper instead of
calling platform_get_resource_byname() and devm_ioremap_resource()
separately

Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
---
 drivers/mtd/spi-nor/controllers/nxp-spifi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/spi-nor/controllers/nxp-spifi.c b/drivers/mtd/spi-nor/controllers/nxp-spifi.c
index 2635c80231bb..9032b9ab2eaf 100644
--- a/drivers/mtd/spi-nor/controllers/nxp-spifi.c
+++ b/drivers/mtd/spi-nor/controllers/nxp-spifi.c
@@ -381,20 +381,17 @@ static int nxp_spifi_probe(struct platform_device *pdev)
 {
 	struct device_node *flash_np;
 	struct nxp_spifi *spifi;
-	struct resource *res;
 	int ret;
 
 	spifi = devm_kzalloc(&pdev->dev, sizeof(*spifi), GFP_KERNEL);
 	if (!spifi)
 		return -ENOMEM;
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "spifi");
-	spifi->io_base = devm_ioremap_resource(&pdev->dev, res);
+	spifi->io_base = devm_platform_ioremap_resource_byname(pdev, "spifi");
 	if (IS_ERR(spifi->io_base))
 		return PTR_ERR(spifi->io_base);
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash");
-	spifi->flash_base = devm_ioremap_resource(&pdev->dev, res);
+	spifi->flash_base = devm_platform_ioremap_resource_byname(pdev, "flash");
 	if (IS_ERR(spifi->flash_base))
 		return PTR_ERR(spifi->flash_base);
 
-- 
2.25.1



From douzhaolei at huawei.com  Wed Sep  1 00:52:09 2021
From: douzhaolei at huawei.com (Zhaolei Dou)
Date: Wed, 1 Sep 2021 15:52:09 +0800
Subject: No subject
Message-ID: <20210901075210.1657-1-douzhaolei@huawei.com>


When the value of rp_size is greater than mtd->size, jffs2 can be remounted normally.
It can be easily reproduced with the steps listed below.
1.mount -t jffs2 -o rw,relatime  /dev/mtdblockx /mnt
2.mount -o remount -o rp_size=xxx /mnt



From douzhaolei at huawei.com  Wed Sep  1 00:52:10 2021
From: douzhaolei at huawei.com (Zhaolei Dou)
Date: Wed, 1 Sep 2021 15:52:10 +0800
Subject: [PATCH] jffs2:fix no error report when rp_size larger than mtd_size
 during remounting
In-Reply-To: <20210901075210.1657-1-douzhaolei@huawei.com>
References: <20210901075210.1657-1-douzhaolei@huawei.com>
Message-ID: <20210901075210.1657-2-douzhaolei@huawei.com>

From: douzhaolei <douzhaolei at huawei.com>

When the value of rp_size is greater than mtd->size,
jffs2 can be remounted normally.
It can be easily reproduced with the steps listed below.
1.mount -t jffs2 -o rw,relatime  /dev/mtdblockx /mnt
2.mount -o remount -o rp_size=xxx /mnt

Signed-off-by: douzhaolei <douzhaolei at huawei.com>
---
 fs/jffs2/super.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 81ca58c10b72..727693540a2d 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -212,7 +212,7 @@ static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
 	return 0;
 }
 
-static inline void jffs2_update_mount_opts(struct fs_context *fc)
+static int jffs2_update_mount_opts(struct fs_context *fc)
 {
 	struct jffs2_sb_info *new_c = fc->s_fs_info;
 	struct jffs2_sb_info *c = JFFS2_SB_INFO(fc->root->d_sb);
@@ -223,18 +223,29 @@ static inline void jffs2_update_mount_opts(struct fs_context *fc)
 		c->mount_opts.compr = new_c->mount_opts.compr;
 	}
 	if (new_c->mount_opts.set_rp_size) {
+		/* During remounting, compare the values of rp_szie and mtd->size. */
+		if (new_c->mount_opts.rp_size > c->mtd->size) {
+			mutex_unlock(&c->alloc_sem);
+			return invalf(fc, "jffs2: Too large reserve pool specified, max is %llu KB",
+					c->mtd->size / 1024);
+		}
 		c->mount_opts.set_rp_size = new_c->mount_opts.set_rp_size;
 		c->mount_opts.rp_size = new_c->mount_opts.rp_size;
 	}
 	mutex_unlock(&c->alloc_sem);
+
+	return 0;
 }
 
 static int jffs2_reconfigure(struct fs_context *fc)
 {
 	struct super_block *sb = fc->root->d_sb;
+	int ret;
 
 	sync_filesystem(sb);
-	jffs2_update_mount_opts(fc);
+	ret = jffs2_update_mount_opts(fc);
+	if (ret)
+		return -EINVAL;
 
 	return jffs2_do_remount_fs(sb, fc);
 }
-- 
2.12.3



From douzhaolei at huawei.com  Wed Sep  1 00:56:53 2021
From: douzhaolei at huawei.com (douzhaolei)
Date: Wed, 1 Sep 2021 07:56:53 +0000
Subject: =?gb2312?B?s7e72Dog?=
Message-ID: <ad3ab2d5e4974d819a6af19f6a1cdf0a@huawei.com>

douzhaolei ????????

From douzhaolei at huawei.com  Wed Sep  1 00:57:31 2021
From: douzhaolei at huawei.com (douzhaolei)
Date: Wed, 1 Sep 2021 07:57:31 +0000
Subject: =?gb2312?B?s7e72Dog?=
Message-ID: <a714246a6dd44dc6baddaed323e76960@huawei.com>

douzhaolei ????????

From narmstrong at baylibre.com  Wed Sep  1 01:14:28 2021
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 1 Sep 2021 10:14:28 +0200
Subject: [PATCH] mtd: rawnand: oxnas: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074207.9333-1-caihuoqing@baidu.com>
References: <20210901074207.9333-1-caihuoqing@baidu.com>
Message-ID: <61ab65d3-bf52-5701-95d2-476b8c2d719c@baylibre.com>

On 01/09/2021 09:42, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> ---
>  drivers/mtd/nand/raw/oxnas_nand.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/oxnas_nand.c b/drivers/mtd/nand/raw/oxnas_nand.c
> index f44947043e5a..cd112d45e0b5 100644
> --- a/drivers/mtd/nand/raw/oxnas_nand.c
> +++ b/drivers/mtd/nand/raw/oxnas_nand.c
> @@ -79,7 +79,6 @@ static int oxnas_nand_probe(struct platform_device *pdev)
>  	struct oxnas_nand_ctrl *oxnas;
>  	struct nand_chip *chip;
>  	struct mtd_info *mtd;
> -	struct resource *res;
>  	int count = 0;
>  	int err = 0;
>  	int i;
> @@ -92,8 +91,7 @@ static int oxnas_nand_probe(struct platform_device *pdev)
>  
>  	nand_controller_init(&oxnas->base);
>  
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	oxnas->io_base = devm_ioremap_resource(&pdev->dev, res);
> +	oxnas->io_base = devm_platform_ioremap_resource(pdev, 0);
>  	if (IS_ERR(oxnas->io_base))
>  		return PTR_ERR(oxnas->io_base);
>  
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From gregkh at linuxfoundation.org  Wed Sep  1 01:17:59 2021
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 1 Sep 2021 10:17:59 +0200
Subject: [PATCH v2 5.10.x] mtd: spinand: Fix incorrect parameters for
 on-die ECC
In-Reply-To: <20210830130211.445728-1-frieder@fris.de>
References: <20210830130211.445728-1-frieder@fris.de>
Message-ID: <YS83NzasS7jExTya@kroah.com>

On Mon, Aug 30, 2021 at 03:02:10PM +0200, Frieder Schrempf wrote:
> From: Frieder Schrempf <frieder.schrempf at kontron.de>
> 
> The new generic NAND ECC framework stores the configuration and
> requirements in separate places since commit 93ef92f6f422 ("mtd: nand: Use
> the new generic ECC object"). In 5.10.x The SPI NAND layer still uses only
> the requirements to track the ECC properties. This mismatch leads to
> values of zero being used for ECC strength and step_size in the SPI NAND
> layer wherever nanddev_get_ecc_conf() is used and therefore breaks the SPI
> NAND on-die ECC support in 5.10.x.
> 
> By using nanddev_get_ecc_requirements() instead of nanddev_get_ecc_conf()
> for SPI NAND, we make sure that the correct parameters for the detected
> chip are used. In later versions (5.11.x) this is fixed anyway with the
> implementation of the SPI NAND on-die ECC engine.
> 
> Cc: stable at vger.kernel.org # 5.10.x
> Reported-by: voice INTER connect GmbH <developer at voiceinterconnect.de>
> Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
> Acked-by: Miquel Raynal <miquel.raynal at bootlin.com>
> ---
> Changes in v2:
>   * Fix checkpatch error/warnings for commit message style
>   * Add Miquel's A-b tag

Now queued up, thanks.

greg k-h


From gregkh at linuxfoundation.org  Wed Sep  1 01:24:56 2021
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Wed, 01 Sep 2021 10:24:56 +0200
Subject: Patch "mtd: spinand: Fix incorrect parameters for on-die ECC" has
 been added to the 5.10-stable tree
In-Reply-To: <20210830130211.445728-1-frieder@fris.de>
Message-ID: <16304846968142@kroah.com>


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

    mtd: spinand: Fix incorrect parameters for on-die ECC

to the 5.10-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:
     mtd-spinand-fix-incorrect-parameters-for-on-die-ecc.patch
and it can be found in the queue-5.10 subdirectory.

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


>From frieder at fris.de  Wed Sep  1 10:16:58 2021
From: Frieder Schrempf <frieder at fris.de>
Date: Mon, 30 Aug 2021 15:02:10 +0200
Subject: mtd: spinand: Fix incorrect parameters for on-die ECC
To: Miquel Raynal <miquel.raynal at bootlin.com>
Cc: Frieder Schrempf <frieder.schrempf at kontron.de>, stable at vger.kernel.org, voice INTER connect GmbH <developer at voiceinterconnect.de>, Alexander Lobakin <alobakin at pm.me>, Felix Fietkau <nbd at nbd.name>, Greg Kroah-Hartman <gregkh at linuxfoundation.org>, linux-kernel at vger.kernel.org, linux-mtd at lists.infradead.org, Richard Weinberger <richard at nod.at>, YouChing Lin <ycllin at mxic.com.tw>
Message-ID: <20210830130211.445728-1-frieder at fris.de>


From: Frieder Schrempf <frieder.schrempf at kontron.de>

The new generic NAND ECC framework stores the configuration and
requirements in separate places since commit 93ef92f6f422 ("mtd: nand: Use
the new generic ECC object"). In 5.10.x The SPI NAND layer still uses only
the requirements to track the ECC properties. This mismatch leads to
values of zero being used for ECC strength and step_size in the SPI NAND
layer wherever nanddev_get_ecc_conf() is used and therefore breaks the SPI
NAND on-die ECC support in 5.10.x.

By using nanddev_get_ecc_requirements() instead of nanddev_get_ecc_conf()
for SPI NAND, we make sure that the correct parameters for the detected
chip are used. In later versions (5.11.x) this is fixed anyway with the
implementation of the SPI NAND on-die ECC engine.

Cc: stable at vger.kernel.org # 5.10.x
Reported-by: voice INTER connect GmbH <developer at voiceinterconnect.de>
Signed-off-by: Frieder Schrempf <frieder.schrempf at kontron.de>
Acked-by: Miquel Raynal <miquel.raynal at bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>

---
 drivers/mtd/nand/spi/core.c     |    6 +++---
 drivers/mtd/nand/spi/macronix.c |    6 +++---
 drivers/mtd/nand/spi/toshiba.c  |    6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -419,7 +419,7 @@ static int spinand_check_ecc_status(stru
 		 * fixed, so let's return the maximum possible value so that
 		 * wear-leveling layers move the data immediately.
 		 */
-		return nanddev_get_ecc_conf(nand)->strength;
+		return nanddev_get_ecc_requirements(nand)->strength;
 
 	case STATUS_ECC_UNCOR_ERROR:
 		return -EBADMSG;
@@ -1090,8 +1090,8 @@ static int spinand_init(struct spinand_d
 	mtd->oobavail = ret;
 
 	/* Propagate ECC information to mtd_info */
-	mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength;
-	mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size;
+	mtd->ecc_strength = nanddev_get_ecc_requirements(nand)->strength;
+	mtd->ecc_step_size = nanddev_get_ecc_requirements(nand)->step_size;
 
 	return 0;
 
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
@@ -84,11 +84,11 @@ static int mx35lf1ge4ab_ecc_get_status(s
 		 * data around if it's not necessary.
 		 */
 		if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr))
-			return nanddev_get_ecc_conf(nand)->strength;
+			return nanddev_get_ecc_requirements(nand)->strength;
 
-		if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength ||
+		if (WARN_ON(eccsr > nanddev_get_ecc_requirements(nand)->strength ||
 			    !eccsr))
-			return nanddev_get_ecc_conf(nand)->strength;
+			return nanddev_get_ecc_requirements(nand)->strength;
 
 		return eccsr;
 
--- a/drivers/mtd/nand/spi/toshiba.c
+++ b/drivers/mtd/nand/spi/toshiba.c
@@ -90,12 +90,12 @@ static int tx58cxgxsxraix_ecc_get_status
 		 * data around if it's not necessary.
 		 */
 		if (spi_mem_exec_op(spinand->spimem, &op))
-			return nanddev_get_ecc_conf(nand)->strength;
+			return nanddev_get_ecc_requirements(nand)->strength;
 
 		mbf >>= 4;
 
-		if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf))
-			return nanddev_get_ecc_conf(nand)->strength;
+		if (WARN_ON(mbf > nanddev_get_ecc_requirements(nand)->strength || !mbf))
+			return nanddev_get_ecc_requirements(nand)->strength;
 
 		return mbf;
 


Patches currently in stable-queue which might be from frieder at fris.de are

queue-5.10/mtd-spinand-fix-incorrect-parameters-for-on-die-ecc.patch


From sean at geanix.com  Wed Sep  1 01:34:42 2021
From: sean at geanix.com (Sean Nyekjaer)
Date: Wed,  1 Sep 2021 10:34:42 +0200
Subject: [PATCH] PM / suspend: move userspace freeze before disk sync
Message-ID: <20210901083442.210230-1-sean@geanix.com>

This fixes an issue where data remains unwritten before suspend.
UBI tried to write data, before the mtd device had been unsuspended.

Seen on an iMX6ULL board fitted with rawnand flash.

Before:
PM: suspend entry (deep)
Filesystems sync: 0.088 seconds
Freezing user space processes ... (elapsed 0.000 seconds) done.
OOM killer disabled.
Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
printk: Suspending console(s) (use no_console_suspend to debug)
PM: suspend devices took 0.030 seconds
Disabling non-boot CPUs ...
ubi0 error: ubi_io_write: error -16 while writing 4096 bytes to PEB 1762:94208, written 0 bytes

After:
PM: suspend entry (deep)
Freezing user space processes ... (elapsed 0.001 seconds) done.
OOM killer disabled.
Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
Filesystems sync: 0.060 seconds
printk: Suspending console(s) (use no_console_suspend to debug)
PM: suspend devices took 0.040 seconds
Disabling non-boot CPUs ...
PM: resume devices took 0.100 seconds

Signed-off-by: Sean Nyekjaer <sean at geanix.com>
---

Some explanation/discussion here:
http://lists.infradead.org/pipermail/linux-mtd/2021-July/087390.html

 kernel/power/suspend.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index 87331565e505..4ee3fcbb0e7a 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -562,6 +562,12 @@ static int enter_state(suspend_state_t state)
 	if (state == PM_SUSPEND_TO_IDLE)
 		s2idle_begin();
 
+	pm_pr_dbg("Preparing system for sleep (%s)\n", mem_sleep_labels[state]);
+	pm_suspend_clear_flags();
+	error = suspend_prepare(state);
+	if (error)
+		goto Unlock;
+
 #ifndef CONFIG_SUSPEND_SKIP_SYNC
 	trace_suspend_resume(TPS("sync_filesystems"), 0, true);
 	pr_info("Syncing filesystems ... ");
@@ -570,12 +576,6 @@ static int enter_state(suspend_state_t state)
 	trace_suspend_resume(TPS("sync_filesystems"), 0, false);
 #endif
 
-	pm_pr_dbg("Preparing system for sleep (%s)\n", mem_sleep_labels[state]);
-	pm_suspend_clear_flags();
-	error = suspend_prepare(state);
-	if (error)
-		goto Unlock;
-
 	if (suspend_test(TEST_FREEZER))
 		goto Finish;
 
-- 
2.33.0



From sean at geanix.com  Wed Sep  1 01:56:37 2021
From: sean at geanix.com (Sean Nyekjaer)
Date: Wed,  1 Sep 2021 10:56:37 +0200
Subject: [PATCH] mtd: ubi: io: add retries mtd_write
Message-ID: <20210901085637.210572-1-sean@geanix.com>

Fix "Device or resource busy" when resuming from suspend. Sometimes ubi
tries to call mtd_write before the rawnand is resumed.

So add 3 retries to the mtd_write call:
PM: suspend devices took 0.030 seconds
ubi0 warning: ubi_io_write: error -16 while writing 4096 bytes to PEB 1762:94208, written 0 bytes
Disabling non-boot CPUs ...
ubi0 warning: ubi_io_write: error -16 while writing 4096 bytes to PEB 1762:94208, written 0 bytes
ubi0 warning: ubi_io_write: error -16 while writing 4096 bytes to PEB 1762:94208, written 0 bytes
PM: resume devices took 0.110 seconds
OOM killer enabled.
Restarting tasks ... done.
PM: suspend exit

Signed-off-by: Sean Nyekjaer <sean at geanix.com>
---

Some explanation/discussion here:
http://lists.infradead.org/pipermail/linux-mtd/2021-July/087390.html

 drivers/mtd/ubi/io.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 0e3a76a9e2f8..fc01ee429358 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -89,6 +89,7 @@
 #include <linux/crc32.h>
 #include <linux/err.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 #include "ubi.h"
 
 static int self_check_not_bad(const struct ubi_device *ubi, int pnum);
@@ -235,7 +236,7 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
 int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
 		 int len)
 {
-	int err;
+	int err, retries = 0;
 	size_t written;
 	loff_t addr;
 
@@ -281,8 +282,16 @@ int ubi_io_write(struct ubi_device *ubi, const void *buf, int pnum, int offset,
 	}
 
 	addr = (loff_t)pnum * ubi->peb_size + offset;
+retry:
 	err = mtd_write(ubi->mtd, addr, len, &written, buf);
 	if (err) {
+		if (retries++ < UBI_IO_RETRIES) {
+			ubi_warn(ubi, "error %d while writing %d bytes to PEB %d:%d, written %zd bytes",
+				 err, len, pnum, offset, written);
+			mdelay(10); yield();
+			goto retry;
+		}
+
 		ubi_err(ubi, "error %d while writing %d bytes to PEB %d:%d, written %zd bytes",
 			err, len, pnum, offset, written);
 		dump_stack();
-- 
2.33.0



From nicolas.ferre at microchip.com  Wed Sep  1 02:51:46 2021
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Wed, 1 Sep 2021 11:51:46 +0200
Subject: [PATCH] mtd: rawnand: atmel: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074031.8883-1-caihuoqing@baidu.com>
References: <20210901074031.8883-1-caihuoqing@baidu.com>
Message-ID: <3ac919ad-be84-f050-a7d1-c15c8c06217e@microchip.com>

On 01/09/2021 at 09:40, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

Reviewed-by: Nicolas Ferre <nicolas.ferre at microchip.com>

> ---
>   drivers/mtd/nand/raw/atmel/pmecc.c | 7 ++-----
>   1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c
> index cbb023bf00f7..498e41ccabbd 100644
> --- a/drivers/mtd/nand/raw/atmel/pmecc.c
> +++ b/drivers/mtd/nand/raw/atmel/pmecc.c
> @@ -834,7 +834,6 @@ static struct atmel_pmecc *atmel_pmecc_create(struct platform_device *pdev,
>   {
>          struct device *dev = &pdev->dev;
>          struct atmel_pmecc *pmecc;
> -       struct resource *res;
> 
>          pmecc = devm_kzalloc(dev, sizeof(*pmecc), GFP_KERNEL);
>          if (!pmecc)
> @@ -844,13 +843,11 @@ static struct atmel_pmecc *atmel_pmecc_create(struct platform_device *pdev,
>          pmecc->dev = dev;
>          mutex_init(&pmecc->lock);
> 
> -       res = platform_get_resource(pdev, IORESOURCE_MEM, pmecc_res_idx);
> -       pmecc->regs.base = devm_ioremap_resource(dev, res);
> +       pmecc->regs.base = devm_platform_ioremap_resource(pdev, pmecc_res_idx);
>          if (IS_ERR(pmecc->regs.base))
>                  return ERR_CAST(pmecc->regs.base);
> 
> -       res = platform_get_resource(pdev, IORESOURCE_MEM, errloc_res_idx);
> -       pmecc->regs.errloc = devm_ioremap_resource(dev, res);
> +       pmecc->regs.errloc = devm_platform_ioremap_resource(pdev, errloc_res_idx);
>          if (IS_ERR(pmecc->regs.errloc))
>                  return ERR_CAST(pmecc->regs.errloc);
> 
> --
> 2.25.1
> 


-- 
Nicolas Ferre


From mdalam at codeaurora.org  Wed Sep  1 03:53:33 2021
From: mdalam at codeaurora.org (Md Sadre Alam)
Date: Wed,  1 Sep 2021 16:23:33 +0530
Subject: [PATCH V3] mtd: rawnand: qcom: Update code word value for raw read
Message-ID: <1630493613-8158-1-git-send-email-mdalam@codeaurora.org>

Fixes: 503ee5aa ("mtd: rawnand: qcom: update last code word register")
Cc: stable at kernel.org
Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
---
[V3]
 * Added Fixes tag
 * Removed change log from commit message.

    From QPIC V2 onwards there is a separate register to read
    last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".

    qcom_nandc_read_cw_raw() is used to read only one code word
    at a time. If we will configure number of code words to 1 in
    in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
    its reading the last code word, since from QPIC V2 onwards
    we are having separate register to read the last code word,
    we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
    register to fetch data from controller buffer to system
    memory.
 
 drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index ef0bade..04e6f7b 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
 	int data_size1, data_size2, oob_size1, oob_size2;
 	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
+	int raw_cw = cw;
 
 	nand_read_page_op(chip, page, 0, NULL, 0);
 	host->use_ecc = false;
 
+	if (nandc->props->qpic_v2)
+		raw_cw = ecc->steps - 1;
+
 	clear_bam_transaction(nandc);
 	set_address(host, host->cw_size * cw, page);
-	update_rw_regs(host, 1, true, cw);
+	update_rw_regs(host, 1, true, raw_cw);
 	config_nand_page_read(chip);
 
 	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
@@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
 		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
 	}
 
-	config_nand_cw_read(chip, false, cw);
+	config_nand_cw_read(chip, false, raw_cw);
 
 	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
 	reg_off += data_size1;
-- 
2.7.4



From mdalam at codeaurora.org  Wed Sep  1 03:55:15 2021
From: mdalam at codeaurora.org (mdalam at codeaurora.org)
Date: Wed, 01 Sep 2021 16:25:15 +0530
Subject: [PATCH V2] mtd: rawnand: qcom: Update code word value for raw read
In-Reply-To: <20210831134231.14413a4f@xps13>
References: <1630400200-2522-1-git-send-email-mdalam@codeaurora.org>
 <20210831134231.14413a4f@xps13>
Message-ID: <114bc85cdd51cb6c885b00d4d2819df9@codeaurora.org>

On 2021-08-31 17:12, Miquel Raynal wrote:
> Hi Md,
> 
> Md Sadre Alam <mdalam at codeaurora.org> wrote on Tue, 31 Aug 2021
> 14:26:40 +0530:
> 
>> From QPIC V2 onwards there is a separate register to read
>> last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".
>> 
>> qcom_nandc_read_cw_raw() is used to read only one code word
>> at a time. If we will configure number of code words to 1 in
>> in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
>> its reading the last code word, since from QPIC V2 onwards
>> we are having separate register to read the last code word,
>> we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
>> register to fetch data from controller buffer to system
>> memory.
>> 
>> Cc: stable at kernel.org
> 
> You miss the Fixes tag which is certainly the most important.

   Updated in V3 patch.
> 
>> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
>> 
>> [V2]
>>  * Added stable tags
> 
> The changelog should not be part of the commit message.
> You should put it...
> 
   Updated in V3 patch.

>> ---
> 
> ...here.
> 
>>  drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c 
>> b/drivers/mtd/nand/raw/qcom_nandc.c
>> index ef0bade..04e6f7b 100644
>> --- a/drivers/mtd/nand/raw/qcom_nandc.c
>> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
>> @@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>> struct nand_chip *chip,
>>  	struct nand_ecc_ctrl *ecc = &chip->ecc;
>>  	int data_size1, data_size2, oob_size1, oob_size2;
>>  	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
>> +	int raw_cw = cw;
>> 
>>  	nand_read_page_op(chip, page, 0, NULL, 0);
>>  	host->use_ecc = false;
>> 
>> +	if (nandc->props->qpic_v2)
>> +		raw_cw = ecc->steps - 1;
>> +
>>  	clear_bam_transaction(nandc);
>>  	set_address(host, host->cw_size * cw, page);
>> -	update_rw_regs(host, 1, true, cw);
>> +	update_rw_regs(host, 1, true, raw_cw);
>>  	config_nand_page_read(chip);
>> 
>>  	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
>> @@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>> struct nand_chip *chip,
>>  		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
>>  	}
>> 
>> -	config_nand_cw_read(chip, false, cw);
>> +	config_nand_cw_read(chip, false, raw_cw);
>> 
>>  	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
>>  	reg_off += data_size1;
> 
> Thanks,
> Miqu?l


From andreazanottifo at gmail.com  Wed Sep  1 04:20:25 2021
From: andreazanottifo at gmail.com (Andrea Zanotti)
Date: Wed, 1 Sep 2021 13:20:25 +0200
Subject: [PATCH] mtd: spi-nor: micron-st: added support for np8p128ax60
In-Reply-To: <4bf9396505975e3fee2cc6396a6eeff7@walle.cc>
References: <20210831081329.27420-1-andrea.zanotti@tyvak.eu>
 <3462300528bbe71207ef2164411e34d2@walle.cc>
 <CAGiusB1JvHkX7GSvD2JsqKWwC5xBePX_ruWk9nU9gugoroLnKA@mail.gmail.com>
 <CAGiusB0B5dN_K+bW1xudmT6UNmVOL=voBOuSVJeiYo3v6ywO8w@mail.gmail.com>
 <4bf9396505975e3fee2cc6396a6eeff7@walle.cc>
Message-ID: <CAGiusB29O+sNn9j2U9-VG0QV=9npUuWV=d5_sLyqD54SRgq9qA@mail.gmail.com>

Hi Michael,

I performed the test with drivers/misc/eeprom/at25.c.

I configured the DTS as such:
spi_pcm at 0 {
compatible = "atmel,at25";
reg = <0>;
spi-max-frequency = <50000000>;
size = <16777216>;
pagesize = <64>;
address-width = <24>;
label = "micron_pcm";
};
and activated the driver itself in the kernel configuration.

I think the system is recognizing it:
# ls -l /sys/bus/spi/devices/spi0.0/eeprom
-rw-------    1 root     root      16777216 Jan  1 00:01
/sys/bus/spi/devices/spi0.0/eeprom

However, if I am not wrong (again, please correct me if I am wrong)
this driver does not
work with the MTD layer (I am booting with the following cmdline bootargs:
mtdparts=micron_pcm:128k(bootstrap),128k(fdt),10M(kernel/rootfs),-(spare)
and I expected to have the same partitions as before, but of course
they are missing.)

I am checking the Company ID on the document "JEP106BC", revisioned on
June 2020,
downloaded from here https://www.jedec.org/system/files/docs/JEP106BC.pdf.

STMicroelectronics should be 20
Micron should be 2C
Intel is advertised as 89, in Table 1 "Manufacturer's Identification Code".

How do you suggest to proceed?

Andrea

Il giorno mar 31 ago 2021 alle ore 17:05 Michael Walle
<michael at walle.cc> ha scritto:
>
> Hi Andrea,
>
> Am 2021-08-31 12:11, schrieb Andrea Zanotti:
> > Il giorno mar 31 ago 2021 alle ore 11:09 Andrea Zanotti
> > <andreazanottifo at gmail.com> ha scritto:
> >>
> >> Hi Michael,
> >>
> >> Il giorno mar 31 ago 2021 alle ore 10:39 Michael Walle
> >> <michael at walle.cc> ha scritto:
> >>>
> >>> Hi Andrea,
> >>>
> >>> Am 2021-08-31 10:13, schrieb Andrea Zanotti:
> >>> > From: Andrea Zanotti <andreazanottifo at gmail.com>
> >>> >
> >>> > Added support for P8P Parallel Phase Change Memory.
> >>>
> >>> Please use present tense, eg "add support..."
> >>>
> >>> Is there a public datasheet? If so, please include it above
> >>> your SoB like so:
> >>> Datasheet: https://...
> >>>
> >>
> >> I will format the header as per your suggestions. I used the same
> >> datasheet
> >> linked by you at the end of the email
> >>
> >>>
> >>> > Added memory information (page size and sector size) as per data-
> >>> > sheet information, after typos corrections.
> >>>
> >>> After typos corrections?
> >>>
> >>
> >> The one specified in the following paragraph. I'll better write this.
> >> (What I meant
> >> is that there are some typos in the datasheet itself)
> >>
> >>>
> >>> > At page 37, paragraph 'SPI Memory Organization', it is written
> >>> > down that the memory is organized as:
> >>> >  * 16.772.216 bytes (typo here, there 16.777.216 bytes)
> >>> >  * 128 sectors of 128 Kbytes each (correct)
> >>> >  * 131.072 pages of 64 bytes each (typo here, as the total would be
> >>> >    64Mbit, but the total memory is actually 128Mbit, correct value
> >>> >    is 262.144 pages)
> >>> >
> >>> > Patch tested against the aforementioned PCM memory.
> >>>
> >>> What SPI host controller was used?
> >>>
> >>
> >> I used an AT91SAM9G20 processor, SPI controller "atmel,at91rm9200-spi"
> >> (spi-atmel.c)
> >>
> >>>
> >>> > No known regressions inserted, as the patch only adds the possibility
> >>> > to recognize said PCM memory inside the common spi-nor driver.
> >>>
> >>> Please drop this. If there were any regressions, the patch wouldn't
> >>> be picked up anyway.
> >>>
> >>
> >> It will be dropped.
> >>
> >>> >
> >>> > Signed-off-by: Andrea Zanotti <andreazanottifo at gmail.com>
> >>> > ---
> >>> >  drivers/mtd/spi-nor/micron-st.c | 1 +
> >>> >  1 file changed, 1 insertion(+)
> >>> >
> >>> > diff --git a/drivers/mtd/spi-nor/micron-st.c
> >>> > b/drivers/mtd/spi-nor/micron-st.c
> >>> > index c224e59820a1..c78331451082 100644
> >>> > --- a/drivers/mtd/spi-nor/micron-st.c
> >>> > +++ b/drivers/mtd/spi-nor/micron-st.c
> >>> > @@ -128,6 +128,7 @@ static const struct flash_info micron_parts[] = {
> >>> >       { "mt35xu02g", INFO(0x2c5b1c, 0, 128 * 1024, 2048,
> >>> >                           SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
> >>> >                           SPI_NOR_4B_OPCODES) },
> >>> > +     { "np8p128ax60", {0x89, 0xda, 0x18}, 3, 128 * 1024, 128, 64, 0, 0 },
> >>>
> >>> Eh? Please use INFO(). And why isn't this 0x20 for micron.
> >>>
> >>
> >> With INFO() macro I am locked in with .page_size = 256 (I would need
> >> 64), or am I missing something?
>
> Ok I see. Mh, then maybe there should be a new macro where you can
> set the page_size?
>
> >>>
> >>> I found this datasheet:
> >>> https://media.digikey.com/pdf/Data%20Sheets/Micron%20Technology%20Inc%20PDFs/NP8P128Ax60E_Rev_K.pdf
> >>>
> >>> According to that datasheet, the manuf id is 0x20. And the device id
> >>> should be either 0x88e1 or 0x8821.
> >>>
> >>
> >> You are right, checking it right now.
> >>
> >
> > - As per datasheet, table 10 on page 18, Manufacturer code is 0x89
> > (column "data" for parameter "Manufacturer Code").
>
> That is for the command 90h (which is for the parallel interface?). We
> issue 9Fh and according to the "READ IDENTIFICATION (RDID)" chapter:
>
>    The manufacturer identification is assigned by JEDEC and has the
>    value 20h for Micron.
>
> And in fact it is assigned by JEDEC, see below.
>
> > - On the datasheet, I agree with you that the device code is
> > advertised as either 0x88e1 or 0x8821. I changed the byte array
> > to something wrong in order to have the debug warning on the JEDEC id
> > bytes, and this is the log:
> >
> > spi-nor spi0.0: unrecognized JEDEC id bytes: 89 da 18 00 00 00
> >
> > Second and third byte are "0xda" and "0x18". I am not an expert in the
> > spi-nor driver, but from my understanding
> > (if it's wrong, please correct me) the spi-nor driver tries to match
> > the the read bytes from the memory with the ones
> > in the tables. I don't know if the datasheet is wrong also in that
> > cell of the table, or if I am interpreting the data wrongly.
>
> Looks like the datasheet is wrong or something is broken here. Yes
> you are correct in assuming that these are in fact the ID bytes.
>
> We'd need to check what vendor 0x89 is to avoid collisions with other
> vendors/flashes.
>
> Btw this "flash" has no need for an erase, just like the MRAM or an
> SPI EEPROM. Could you have a look at drivers/misc/eeprom/at25.c if
> that will work for you?
>
> -michael


From p.yadav at ti.com  Wed Sep  1 04:40:53 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Wed, 1 Sep 2021 17:10:53 +0530
Subject: [PATCH] mtd: spi-nor: hisi-sfc: Make use of the helper function
 devm_platform_ioremap_resource_byname()
In-Reply-To: <20210901074259.9683-1-caihuoqing@baidu.com>
References: <20210901074259.9683-1-caihuoqing@baidu.com>
Message-ID: <20210901114051.5cokevyl5hpgwrju@ti.com>

On 01/09/21 03:42PM, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource_byname() helper instead of
> calling platform_get_resource_byname() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

Acked-by: Pratyush Yadav <p.yadav at ti.com>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Wed Sep  1 04:41:43 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Wed, 1 Sep 2021 17:11:43 +0530
Subject: [PATCH] mtd: spi-nor: nxp-spifi: Make use of the helper function
 devm_platform_ioremap_resource_byname()
In-Reply-To: <20210901074307.9733-1-caihuoqing@baidu.com>
References: <20210901074307.9733-1-caihuoqing@baidu.com>
Message-ID: <20210901114140.caxl4qicjvtp2b3i@ti.com>

On 01/09/21 03:43PM, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource_byname() helper instead of
> calling platform_get_resource_byname() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

Acked-by: Pratyush Yadav <p.yadav at ti.com>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From miquel.raynal at bootlin.com  Wed Sep  1 07:36:15 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 1 Sep 2021 16:36:15 +0200
Subject: [PATCH V3] mtd: rawnand: qcom: Update code word value for raw read
In-Reply-To: <1630493613-8158-1-git-send-email-mdalam@codeaurora.org>
References: <1630493613-8158-1-git-send-email-mdalam@codeaurora.org>
Message-ID: <20210901163615.090c6f24@xps13>


Md Sadre Alam <mdalam at codeaurora.org> wrote on Wed,  1 Sep 2021
16:23:33 +0530:

> Fixes: 503ee5aa ("mtd: rawnand: qcom: update last code word register")
> Cc: stable at kernel.org
> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> ---
> [V3]
>  * Added Fixes tag
>  * Removed change log from commit message.
> 
>     From QPIC V2 onwards there is a separate register to read
>     last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".
> 
>     qcom_nandc_read_cw_raw() is used to read only one code word
>     at a time. If we will configure number of code words to 1 in
>     in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
>     its reading the last code word, since from QPIC V2 onwards
>     we are having separate register to read the last code word,
>     we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
>     register to fetch data from controller buffer to system
>     memory.

Really?

It's not your first contribution, you know what a changelog is and what
a commit message is, right? So please, keep the commit message
("why" your change is needed) where it was and only put
the changelog (the differences between two versions) below the three
dashes '---'.

>  
>  drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
> index ef0bade..04e6f7b 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
>  	struct nand_ecc_ctrl *ecc = &chip->ecc;
>  	int data_size1, data_size2, oob_size1, oob_size2;
>  	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
> +	int raw_cw = cw;
>  
>  	nand_read_page_op(chip, page, 0, NULL, 0);
>  	host->use_ecc = false;
>  
> +	if (nandc->props->qpic_v2)
> +		raw_cw = ecc->steps - 1;
> +
>  	clear_bam_transaction(nandc);
>  	set_address(host, host->cw_size * cw, page);
> -	update_rw_regs(host, 1, true, cw);
> +	update_rw_regs(host, 1, true, raw_cw);
>  	config_nand_page_read(chip);
>  
>  	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
> @@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
>  		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
>  	}
>  
> -	config_nand_cw_read(chip, false, cw);
> +	config_nand_cw_read(chip, false, raw_cw);
>  
>  	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
>  	reg_off += data_size1;



From christophe.kerello at foss.st.com  Wed Sep  1 08:58:36 2021
From: christophe.kerello at foss.st.com (Christophe Kerello)
Date: Wed, 1 Sep 2021 17:58:36 +0200
Subject: [Linux-stm32] [PATCH] mtd: rawnand: stm32_fmc2: Make use of the
 helper function devm_platform_ioremap_resource()
In-Reply-To: <20210901074222.9433-1-caihuoqing@baidu.com>
References: <20210901074222.9433-1-caihuoqing@baidu.com>
Message-ID: <a69d1484-fb7a-6da5-3d46-48c49b612d2a@foss.st.com>



On 9/1/21 9:42 AM, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> ---
>   drivers/mtd/nand/raw/stm32_fmc2_nand.c | 8 ++------
>   1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> index 1c277fbb91f2..97b4e02e43e4 100644
> --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c
> @@ -1899,15 +1899,11 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev)
>   
>   		nfc->data_phys_addr[chip_cs] = res->start;
>   
> -		res = platform_get_resource(pdev, IORESOURCE_MEM,
> -					    mem_region + 1);
> -		nfc->cmd_base[chip_cs] = devm_ioremap_resource(dev, res);
> +		nfc->cmd_base[chip_cs] = devm_platform_ioremap_resource(pdev, mem_region + 1);
>   		if (IS_ERR(nfc->cmd_base[chip_cs]))
>   			return PTR_ERR(nfc->cmd_base[chip_cs]);
>   
> -		res = platform_get_resource(pdev, IORESOURCE_MEM,
> -					    mem_region + 2);
> -		nfc->addr_base[chip_cs] = devm_ioremap_resource(dev, res);
> +		nfc->addr_base[chip_cs] = devm_platform_ioremap_resource(pdev, mem_region + 2);
>   		if (IS_ERR(nfc->addr_base[chip_cs]))
>   			return PTR_ERR(nfc->addr_base[chip_cs]);
>   	}
> 

Reviewed-by: Christophe Kerello <christophe.kerello at foss.st.com>


From ebiggers at kernel.org  Wed Sep  1 09:40:37 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed,  1 Sep 2021 09:40:37 -0700
Subject: [PATCH 5.4 0/4] backport fscrypt symlink fixes to 5.4
Message-ID: <20210901164041.176238-1-ebiggers@kernel.org>

This series backports some patches that failed to apply to 5.4-stable
due to the prototype of inode_operations::getattr having changed in
v5.12, as well several other conflicts.  Please apply to 5.4-stable.

Eric Biggers (4):
  fscrypt: add fscrypt_symlink_getattr() for computing st_size
  ext4: report correct st_size for encrypted symlinks
  f2fs: report correct st_size for encrypted symlinks
  ubifs: report correct st_size for encrypted symlinks

 fs/crypto/hooks.c       | 44 +++++++++++++++++++++++++++++++++++++++++
 fs/ext4/symlink.c       | 11 ++++++++++-
 fs/f2fs/namei.c         | 11 ++++++++++-
 fs/ubifs/file.c         | 12 ++++++++++-
 include/linux/fscrypt.h |  7 +++++++
 5 files changed, 82 insertions(+), 3 deletions(-)

-- 
2.33.0



From ebiggers at kernel.org  Wed Sep  1 09:40:39 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed,  1 Sep 2021 09:40:39 -0700
Subject: [PATCH 5.4 2/4] ext4: report correct st_size for encrypted symlinks
In-Reply-To: <20210901164041.176238-1-ebiggers@kernel.org>
References: <20210901164041.176238-1-ebiggers@kernel.org>
Message-ID: <20210901164041.176238-3-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 8c4bca10ceafc43b1ca0a9fab5fa27e13cbce99e upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after ext4_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: f348c252320b ("ext4 crypto: add symlink encryption")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-3-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/ext4/symlink.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
index dd05af983092d..a9457fed351ed 100644
--- a/fs/ext4/symlink.c
+++ b/fs/ext4/symlink.c
@@ -52,10 +52,19 @@ static const char *ext4_encrypted_get_link(struct dentry *dentry,
 	return paddr;
 }
 
+static int ext4_encrypted_symlink_getattr(const struct path *path,
+					  struct kstat *stat, u32 request_mask,
+					  unsigned int query_flags)
+{
+	ext4_getattr(path, stat, request_mask, query_flags);
+
+	return fscrypt_symlink_getattr(path, stat);
+}
+
 const struct inode_operations ext4_encrypted_symlink_inode_operations = {
 	.get_link	= ext4_encrypted_get_link,
 	.setattr	= ext4_setattr,
-	.getattr	= ext4_getattr,
+	.getattr	= ext4_encrypted_symlink_getattr,
 	.listxattr	= ext4_listxattr,
 };
 
-- 
2.33.0



From ebiggers at kernel.org  Wed Sep  1 09:40:41 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed,  1 Sep 2021 09:40:41 -0700
Subject: [PATCH 5.4 4/4] ubifs: report correct st_size for encrypted symlinks
In-Reply-To: <20210901164041.176238-1-ebiggers@kernel.org>
References: <20210901164041.176238-1-ebiggers@kernel.org>
Message-ID: <20210901164041.176238-5-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 064c734986011390b4d111f1a99372b7f26c3850 upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after ubifs_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: ca7f85be8d6c ("ubifs: Add support for encrypted symlinks")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-5-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/ubifs/file.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 8dada89bbe4da..6069c63d833ae 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1629,6 +1629,16 @@ static const char *ubifs_get_link(struct dentry *dentry,
 	return fscrypt_get_symlink(inode, ui->data, ui->data_len, done);
 }
 
+static int ubifs_symlink_getattr(const struct path *path, struct kstat *stat,
+				 u32 request_mask, unsigned int query_flags)
+{
+	ubifs_getattr(path, stat, request_mask, query_flags);
+
+	if (IS_ENCRYPTED(d_inode(path->dentry)))
+		return fscrypt_symlink_getattr(path, stat);
+	return 0;
+}
+
 const struct address_space_operations ubifs_file_address_operations = {
 	.readpage       = ubifs_readpage,
 	.writepage      = ubifs_writepage,
@@ -1654,7 +1664,7 @@ const struct inode_operations ubifs_file_inode_operations = {
 const struct inode_operations ubifs_symlink_inode_operations = {
 	.get_link    = ubifs_get_link,
 	.setattr     = ubifs_setattr,
-	.getattr     = ubifs_getattr,
+	.getattr     = ubifs_symlink_getattr,
 #ifdef CONFIG_UBIFS_FS_XATTR
 	.listxattr   = ubifs_listxattr,
 #endif
-- 
2.33.0



From ebiggers at kernel.org  Wed Sep  1 09:40:40 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed,  1 Sep 2021 09:40:40 -0700
Subject: [PATCH 5.4 3/4] f2fs: report correct st_size for encrypted symlinks
In-Reply-To: <20210901164041.176238-1-ebiggers@kernel.org>
References: <20210901164041.176238-1-ebiggers@kernel.org>
Message-ID: <20210901164041.176238-4-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 461b43a8f92e68e96c4424b31e15f2b35f1bbfa9 upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after f2fs_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: cbaf042a3cc6 ("f2fs crypto: add symlink encryption")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-4-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/f2fs/namei.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 3a97ac56821ba..81a18ba18e301 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -1256,9 +1256,18 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry,
 	return target;
 }
 
+static int f2fs_encrypted_symlink_getattr(const struct path *path,
+					  struct kstat *stat, u32 request_mask,
+					  unsigned int query_flags)
+{
+	f2fs_getattr(path, stat, request_mask, query_flags);
+
+	return fscrypt_symlink_getattr(path, stat);
+}
+
 const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
 	.get_link       = f2fs_encrypted_get_link,
-	.getattr	= f2fs_getattr,
+	.getattr	= f2fs_encrypted_symlink_getattr,
 	.setattr	= f2fs_setattr,
 #ifdef CONFIG_F2FS_FS_XATTR
 	.listxattr	= f2fs_listxattr,
-- 
2.33.0



From ebiggers at kernel.org  Wed Sep  1 09:40:38 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed,  1 Sep 2021 09:40:38 -0700
Subject: [PATCH 5.4 1/4] fscrypt: add fscrypt_symlink_getattr() for computing
 st_size
In-Reply-To: <20210901164041.176238-1-ebiggers@kernel.org>
References: <20210901164041.176238-1-ebiggers@kernel.org>
Message-ID: <20210901164041.176238-2-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit d18760560593e5af921f51a8c9b64b6109d634c2 upstream.

Add a helper function fscrypt_symlink_getattr() which will be called
from the various filesystems' ->getattr() methods to read and decrypt
the target of encrypted symlinks in order to report the correct st_size.

Detailed explanation:

As required by POSIX and as documented in various man pages, st_size for
a symlink is supposed to be the length of the symlink target.
Unfortunately, st_size has always been wrong for encrypted symlinks
because st_size is populated from i_size from disk, which intentionally
contains the length of the encrypted symlink target.  That's slightly
greater than the length of the decrypted symlink target (which is the
symlink target that userspace usually sees), and usually won't match the
length of the no-key encoded symlink target either.

This hadn't been fixed yet because reporting the correct st_size would
require reading the symlink target from disk and decrypting or encoding
it, which historically has been considered too heavyweight to do in
->getattr().  Also historically, the wrong st_size had only broken a
test (LTP lstat03) and there were no known complaints from real users.
(This is probably because the st_size of symlinks isn't used too often,
and when it is, typically it's for a hint for what buffer size to pass
to readlink() -- which a slightly-too-large size still works for.)

However, a couple things have changed now.  First, there have recently
been complaints about the current behavior from real users:

- Breakage in rpmbuild:
  https://github.com/rpm-software-management/rpm/issues/1682
  https://github.com/google/fscrypt/issues/305

- Breakage in toybox cpio:
  https://www.mail-archive.com/toybox at lists.landley.net/msg07193.html

- Breakage in libgit2: https://issuetracker.google.com/issues/189629152
  (on Android public issue tracker, requires login)

Second, we now cache decrypted symlink targets in ->i_link.  Therefore,
taking the performance hit of reading and decrypting the symlink target
in ->getattr() wouldn't be as big a deal as it used to be, since usually
it will just save having to do the same thing later.

Also note that eCryptfs ended up having to read and decrypt symlink
targets in ->getattr() as well, to fix this same issue; see
commit 3a60a1686f0d ("eCryptfs: Decrypt symlink target for stat size").

So, let's just bite the bullet, and read and decrypt the symlink target
in ->getattr() in order to report the correct st_size.  Add a function
fscrypt_symlink_getattr() which the filesystems will call to do this.

(Alternatively, we could store the decrypted size of symlinks on-disk.
But there isn't a great place to do so, and encryption is meant to hide
the original size to some extent; that property would be lost.)

Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-2-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/crypto/hooks.c       | 44 +++++++++++++++++++++++++++++++++++++++++
 include/linux/fscrypt.h |  7 +++++++
 2 files changed, 51 insertions(+)

diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index a5a40a76b8ed7..82575cfbb04db 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -305,3 +305,47 @@ const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
 	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(fscrypt_get_symlink);
+
+/**
+ * fscrypt_symlink_getattr() - set the correct st_size for encrypted symlinks
+ * @path: the path for the encrypted symlink being queried
+ * @stat: the struct being filled with the symlink's attributes
+ *
+ * Override st_size of encrypted symlinks to be the length of the decrypted
+ * symlink target (or the no-key encoded symlink target, if the key is
+ * unavailable) rather than the length of the encrypted symlink target.  This is
+ * necessary for st_size to match the symlink target that userspace actually
+ * sees.  POSIX requires this, and some userspace programs depend on it.
+ *
+ * This requires reading the symlink target from disk if needed, setting up the
+ * inode's encryption key if possible, and then decrypting or encoding the
+ * symlink target.  This makes lstat() more heavyweight than is normally the
+ * case.  However, decrypted symlink targets will be cached in ->i_link, so
+ * usually the symlink won't have to be read and decrypted again later if/when
+ * it is actually followed, readlink() is called, or lstat() is called again.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat)
+{
+	struct dentry *dentry = path->dentry;
+	struct inode *inode = d_inode(dentry);
+	const char *link;
+	DEFINE_DELAYED_CALL(done);
+
+	/*
+	 * To get the symlink target that userspace will see (whether it's the
+	 * decrypted target or the no-key encoded target), we can just get it in
+	 * the same way the VFS does during path resolution and readlink().
+	 */
+	link = READ_ONCE(inode->i_link);
+	if (!link) {
+		link = inode->i_op->get_link(dentry, inode, &done);
+		if (IS_ERR(link))
+			return PTR_ERR(link);
+	}
+	stat->size = strlen(link);
+	do_delayed_call(&done);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fscrypt_symlink_getattr);
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 032e5bcf97012..0d1a53d6c52dc 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -298,6 +298,7 @@ extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
 extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
 				       unsigned int max_size,
 				       struct delayed_call *done);
+int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat);
 static inline void fscrypt_set_ops(struct super_block *sb,
 				   const struct fscrypt_operations *s_cop)
 {
@@ -585,6 +586,12 @@ static inline const char *fscrypt_get_symlink(struct inode *inode,
 	return ERR_PTR(-EOPNOTSUPP);
 }
 
+static inline int fscrypt_symlink_getattr(const struct path *path,
+					  struct kstat *stat)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline void fscrypt_set_ops(struct super_block *sb,
 				   const struct fscrypt_operations *s_cop)
 {
-- 
2.33.0



From renaud.barbier at abaco.com  Wed Sep  1 09:51:23 2021
From: renaud.barbier at abaco.com (Barbier, Renaud)
Date: Wed, 1 Sep 2021 16:51:23 +0000
Subject: S25FL512 vs S25FS512
Message-ID: <MN2PR16MB313511219F7BFB2692C4C8B191CD9@MN2PR16MB3135.namprd16.prod.outlook.com>

Hello,
I bought a NXP ls1046ard evaluation board and saw some issues erasing the SPI NOR from my boot loader or ICE.
The boot loader reported the flash as being a S25FL512 which is a uniform (256KiB) sector SPI NOR as per manufacturing ID 1 and device id 2

The eval board has in fact a S25FS512 SPI NOR which is by default a bottom boot flash. This can be disabled through a configuration register in the SPI NOR.

I also see that Linux describes both the S25FL512 and S25FS512 as uniform sector flash:
{ "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
			      SPI_NOR_HAS_LOCK | USE_CLSR) },

{ "s25fs512s",  INFO6(0x010220, 0x4d0081, 256 * 1024, 256,
			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR)



According to Cypress PDF https://www.cypress.com/file/177971/download, this SPI NOR S25FL512 is indeed a uniform sector flash but with a device ID of 0x19.
While the Spansion documentation I found (https://datasheetspdf.com/pdf-file/831993/SPANSION/S25FL512S/1 ) described it with a Device ID of 0x2.

The S25FS512S has Device ID 0x2 according to Cypress documentation https://www.cypress.com/file/216376/download  and is a bottom boot flash.

Is the SPI support for S25FS512 in Linux 5.14 disabling the bottom boot feature? I have not found it in the code. Only something related to page size.

Cheers,
Renaud




From mcgrof at kernel.org  Wed Sep  1 14:00:19 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:19 -0700
Subject: [PATCH 01/10] mtip32xx: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-1-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
Message-ID: <20210901210028.1750956-2-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

The read_capacity_error error label already does what we need,
so just re-use that.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/mtip32xx/mtip32xx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 901855717cb5..d0b40309f47e 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -3633,7 +3633,9 @@ static int mtip_block_initialize(struct driver_data *dd)
 	set_capacity(dd->disk, capacity);
 
 	/* Enable the block device and add it to /dev */
-	device_add_disk(&dd->pdev->dev, dd->disk, mtip_disk_attr_groups);
+	rv = device_add_disk(&dd->pdev->dev, dd->disk, mtip_disk_attr_groups);
+	if (rv)
+		goto read_capacity_error;
 
 	if (dd->mtip_svc_handler) {
 		set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
-- 
2.30.2



From mcgrof at kernel.org  Wed Sep  1 14:00:25 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:25 -0700
Subject: [PATCH 07/10] block/sunvdc: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-1-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
Message-ID: <20210901210028.1750956-8-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

We re-use the same free tag call, so we also add a label for
that as well.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/sunvdc.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 4d4bb810c2ae..6f45a53f7cbf 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -826,8 +826,8 @@ static int probe_disk(struct vdc_port *port)
 	if (IS_ERR(g)) {
 		printk(KERN_ERR PFX "%s: Could not allocate gendisk.\n",
 		       port->vio.name);
-		blk_mq_free_tag_set(&port->tag_set);
-		return PTR_ERR(g);
+		err = PTR_ERR(g);
+		goto out_free_tag;
 	}
 
 	port->disk = g;
@@ -879,9 +879,17 @@ static int probe_disk(struct vdc_port *port)
 	       port->vdisk_size, (port->vdisk_size >> (20 - 9)),
 	       port->vio.ver.major, port->vio.ver.minor);
 
-	device_add_disk(&port->vio.vdev->dev, g, NULL);
+	err = device_add_disk(&port->vio.vdev->dev, g, NULL);
+	if (err)
+		goto out_cleanup_disk;
 
 	return 0;
+
+out_cleanup_disk:
+	blk_cleanup_disk(g);
+out_free_tag:
+	blk_mq_free_tag_set(&port->tag_set);
+	return err;
 }
 
 static struct ldc_channel_config vdc_ldc_cfg = {
-- 
2.30.2



From mcgrof at kernel.org  Wed Sep  1 14:00:26 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:26 -0700
Subject: [PATCH 08/10] block/sx8: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-1-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
Message-ID: <20210901210028.1750956-9-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

A completion is used to notify the initial probe what is
happening and so we must defer error handling on completion.
Do this by remembering the error and using the shared cleanup
function.

The tags are shared and so are hanlded later for the
driver already.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/sx8.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 420cd952ddc4..1c79248c4826 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -297,6 +297,7 @@ struct carm_host {
 
 	struct work_struct		fsm_task;
 
+	int probe_err;
 	struct completion		probe_comp;
 };
 
@@ -1181,8 +1182,11 @@ static void carm_fsm_task (struct work_struct *work)
 				struct gendisk *disk = port->disk;
 
 				set_capacity(disk, port->capacity);
-				add_disk(disk);
-				activated++;
+				host->probe_err = add_disk(disk);
+				if (!host->probe_err)
+					activated++;
+				else
+					break;
 			}
 
 		printk(KERN_INFO DRV_NAME "(%s): %d ports activated\n",
@@ -1192,11 +1196,9 @@ static void carm_fsm_task (struct work_struct *work)
 		reschedule = 1;
 		break;
 	}
-
 	case HST_PROBE_FINISHED:
 		complete(&host->probe_comp);
 		break;
-
 	case HST_ERROR:
 		/* FIXME: TODO */
 		break;
@@ -1507,7 +1509,10 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_out_free_irq;
 
 	DPRINTK("waiting for probe_comp\n");
+	host->probe_err = -ENODEV;
 	wait_for_completion(&host->probe_comp);
+	if (host->probe_err)
+		goto err_out_free_irq;
 
 	printk(KERN_INFO "%s: pci %s, ports %d, io %llx, irq %u, major %d\n",
 	       host->name, pci_name(pdev), (int) CARM_MAX_PORTS,
-- 
2.30.2



From mcgrof at kernel.org  Wed Sep  1 14:00:22 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:22 -0700
Subject: [PATCH 04/10] ps3vram: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-1-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
Message-ID: <20210901210028.1750956-5-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/ps3vram.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index c7b19e128b03..af2a0d09c598 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -755,9 +755,14 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev)
 	dev_info(&dev->core, "%s: Using %llu MiB of GPU memory\n",
 		 gendisk->disk_name, get_capacity(gendisk) >> 11);
 
-	device_add_disk(&dev->core, gendisk, NULL);
+	error = device_add_disk(&dev->core, gendisk, NULL);
+	if (error)
+		goto out_cleanup_disk;
+
 	return 0;
 
+out_cleanup_disk:
+	blk_cleanup_disk(gendisk);
 out_cache_cleanup:
 	remove_proc_entry(DEVICE_NAME, NULL);
 	ps3vram_cache_cleanup(dev);
-- 
2.30.2



From mcgrof at kernel.org  Wed Sep  1 14:00:24 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:24 -0700
Subject: [PATCH 06/10] block/rsxx: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-1-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
Message-ID: <20210901210028.1750956-7-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/rsxx/core.c |  4 +++-
 drivers/block/rsxx/dev.c  | 12 +++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c
index 83636714b8d7..8d9d69f5dfbc 100644
--- a/drivers/block/rsxx/core.c
+++ b/drivers/block/rsxx/core.c
@@ -935,7 +935,9 @@ static int rsxx_pci_probe(struct pci_dev *dev,
 			card->size8 = 0;
 	}
 
-	rsxx_attach_dev(card);
+	st = rsxx_attach_dev(card);
+	if (st)
+		goto failed_create_dev;
 
 	/************* Setup Debugfs *************/
 	rsxx_debugfs_dev_new(card);
diff --git a/drivers/block/rsxx/dev.c b/drivers/block/rsxx/dev.c
index 1cc40b0ea761..b2d3ac3efce2 100644
--- a/drivers/block/rsxx/dev.c
+++ b/drivers/block/rsxx/dev.c
@@ -192,6 +192,8 @@ static bool rsxx_discard_supported(struct rsxx_cardinfo *card)
 
 int rsxx_attach_dev(struct rsxx_cardinfo *card)
 {
+	int err = 0;
+
 	mutex_lock(&card->dev_lock);
 
 	/* The block device requires the stripe size from the config. */
@@ -200,13 +202,17 @@ int rsxx_attach_dev(struct rsxx_cardinfo *card)
 			set_capacity(card->gendisk, card->size8 >> 9);
 		else
 			set_capacity(card->gendisk, 0);
-		device_add_disk(CARD_TO_DEV(card), card->gendisk, NULL);
-		card->bdev_attached = 1;
+		err = device_add_disk(CARD_TO_DEV(card), card->gendisk, NULL);
+		if (err == 0)
+			card->bdev_attached = 1;
 	}
 
 	mutex_unlock(&card->dev_lock);
 
-	return 0;
+	if (err)
+		blk_cleanup_disk(card->gendisk);
+
+	return err;
 }
 
 void rsxx_detach_dev(struct rsxx_cardinfo *card)
-- 
2.30.2



From mcgrof at kernel.org  Wed Sep  1 14:00:21 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:21 -0700
Subject: [PATCH 03/10] ps3disk: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-1-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
Message-ID: <20210901210028.1750956-4-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/ps3disk.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 8d51efbe045d..3054adf77460 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -467,9 +467,13 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev)
 		 gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
 		 get_capacity(gendisk) >> 11);
 
-	device_add_disk(&dev->sbd.core, gendisk, NULL);
-	return 0;
+	error = device_add_disk(&dev->sbd.core, gendisk, NULL);
+	if (error)
+		goto fail_cleanup_disk;
 
+	return 0;
+fail_cleanup_disk:
+	blk_cleanup_disk(gendisk);
 fail_free_tag_set:
 	blk_mq_free_tag_set(&priv->tag_set);
 fail_teardown:
-- 
2.30.2



From mcgrof at kernel.org  Wed Sep  1 14:00:27 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:27 -0700
Subject: [PATCH 09/10] pf: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-1-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
Message-ID: <20210901210028.1750956-10-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/paride/pf.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index f471d48a87bc..380d80e507c7 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -962,7 +962,9 @@ static int __init pf_init_unit(struct pf_unit *pf, bool autoprobe, int port,
 	if (pf_probe(pf))
 		goto out_pi_release;
 
-	add_disk(disk);
+	ret = add_disk(disk);
+	if (ret)
+		goto out_pi_release;
 	pf->present = 1;
 	return 0;
 
-- 
2.30.2



From mcgrof at kernel.org  Wed Sep  1 14:00:18 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:18 -0700
Subject: [PATCH 00/10] block: fourth batch of add_disk() error handling
 conversions 
Message-ID: <20210901210028.1750956-1-mcgrof@kernel.org>

The full set of changes can be found on my branch titled
20210901-for-axboe-add-disk-error-handling [0] which is
now based on axboe/master.

[0] https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/log/?h=20210901-for-axboe-add-disk-error-handling

Luis Chamberlain (10):
  mtip32xx: add error handling support for add_disk()
  pktcdvd: add error handling support for add_disk()
  ps3disk: add error handling support for add_disk()
  ps3vram: add error handling support for add_disk()
  rnbd: add error handling support for add_disk()
  block/rsxx: add error handling support for add_disk()
  block/sunvdc: add error handling support for add_disk()
  block/sx8: add error handling support for add_disk()
  pf: add error handling support for add_disk()
  mtd/ubi/block: add error handling support for add_disk()

 drivers/block/mtip32xx/mtip32xx.c |  4 +++-
 drivers/block/paride/pf.c         |  4 +++-
 drivers/block/pktcdvd.c           |  4 +++-
 drivers/block/ps3disk.c           |  8 ++++++--
 drivers/block/ps3vram.c           |  7 ++++++-
 drivers/block/rnbd/rnbd-clt.c     | 13 +++++++++----
 drivers/block/rsxx/core.c         |  4 +++-
 drivers/block/rsxx/dev.c          | 12 +++++++++---
 drivers/block/sunvdc.c            | 14 +++++++++++---
 drivers/block/sx8.c               | 13 +++++++++----
 drivers/mtd/ubi/block.c           |  8 +++++++-
 11 files changed, 69 insertions(+), 22 deletions(-)

-- 
2.30.2



From mcgrof at kernel.org  Wed Sep  1 14:00:23 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:23 -0700
Subject: [PATCH 05/10] rnbd: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-1-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
Message-ID: <20210901210028.1750956-6-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/rnbd/rnbd-clt.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c
index bd4a41afbbfc..1ba1c868535a 100644
--- a/drivers/block/rnbd/rnbd-clt.c
+++ b/drivers/block/rnbd/rnbd-clt.c
@@ -1384,8 +1384,10 @@ static void setup_request_queue(struct rnbd_clt_dev *dev)
 	blk_queue_write_cache(dev->queue, dev->wc, dev->fua);
 }
 
-static void rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx)
+static int rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx)
 {
+	int err;
+
 	dev->gd->major		= rnbd_client_major;
 	dev->gd->first_minor	= idx << RNBD_PART_BITS;
 	dev->gd->minors		= 1 << RNBD_PART_BITS;
@@ -1410,7 +1412,11 @@ static void rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx)
 
 	if (!dev->rotational)
 		blk_queue_flag_set(QUEUE_FLAG_NONROT, dev->queue);
-	add_disk(dev->gd);
+	err = add_disk(dev->gd);
+	if (err)
+		blk_cleanup_disk(dev->gd);
+
+	return err;
 }
 
 static int rnbd_client_setup_device(struct rnbd_clt_dev *dev)
@@ -1426,8 +1432,7 @@ static int rnbd_client_setup_device(struct rnbd_clt_dev *dev)
 	rnbd_init_mq_hw_queues(dev);
 
 	setup_request_queue(dev);
-	rnbd_clt_setup_gen_disk(dev, idx);
-	return 0;
+	return rnbd_clt_setup_gen_disk(dev, idx);
 }
 
 static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess,
-- 
2.30.2



From mcgrof at kernel.org  Wed Sep  1 14:00:20 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:20 -0700
Subject: [PATCH 02/10] pktcdvd: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-1-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
Message-ID: <20210901210028.1750956-3-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

The out_mem2 error label already does what we need so
re-use that.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/pktcdvd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 0f26b2510a75..415248962e67 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2729,7 +2729,9 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
 	/* inherit events of the host device */
 	disk->events = pd->bdev->bd_disk->events;
 
-	add_disk(disk);
+	ret = add_disk(disk);
+	if (ret)
+		goto out_mem2;
 
 	pkt_sysfs_dev_new(pd);
 	pkt_debugfs_dev_new(pd);
-- 
2.30.2



From mcgrof at kernel.org  Wed Sep  1 14:00:28 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Wed,  1 Sep 2021 14:00:28 -0700
Subject: [PATCH 10/10] mtd/ubi/block: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-1-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
Message-ID: <20210901210028.1750956-11-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/mtd/ubi/block.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index e003b4b44ffa..062e6c2c45f5 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -447,12 +447,18 @@ int ubiblock_create(struct ubi_volume_info *vi)
 	list_add_tail(&dev->list, &ubiblock_devices);
 
 	/* Must be the last step: anyone can call file ops from now on */
-	add_disk(dev->gd);
+	ret = add_disk(dev->gd);
+	if (ret)
+		goto out_destroy_wq;
+
 	dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
 		 dev->ubi_num, dev->vol_id, vi->name);
 	mutex_unlock(&devices_mutex);
 	return 0;
 
+out_destroy_wq:
+	list_del(&dev->list);
+	destroy_workqueue(dev->wq);
 out_remove_minor:
 	idr_remove(&ubiblock_minor_idr, gd->first_minor);
 out_cleanup_disk:
-- 
2.30.2



From jinpu.wang at ionos.com  Wed Sep  1 22:32:44 2021
From: jinpu.wang at ionos.com (Jinpu Wang)
Date: Thu, 2 Sep 2021 07:32:44 +0200
Subject: [PATCH 05/10] rnbd: add error handling support for add_disk()
In-Reply-To: <20210901210028.1750956-6-mcgrof@kernel.org>
References: <20210901210028.1750956-1-mcgrof@kernel.org>
 <20210901210028.1750956-6-mcgrof@kernel.org>
Message-ID: <CAMGffE=+jnKpO-ZGqW5JQnUbdH+NjQHgq7_f4XoEem2itHhe9Q@mail.gmail.com>

On Wed, Sep 1, 2021 at 11:01 PM Luis Chamberlain <mcgrof at kernel.org> wrote:
>
> We never checked for errors on add_disk() as this function
> returned void. Now that this is fixed, use the shiny new
> error handling.
>
> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
looks good to me.
Acked-by: Jack Wang <jinpu.wang at ionos.com>
> ---
>  drivers/block/rnbd/rnbd-clt.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c
> index bd4a41afbbfc..1ba1c868535a 100644
> --- a/drivers/block/rnbd/rnbd-clt.c
> +++ b/drivers/block/rnbd/rnbd-clt.c
> @@ -1384,8 +1384,10 @@ static void setup_request_queue(struct rnbd_clt_dev *dev)
>         blk_queue_write_cache(dev->queue, dev->wc, dev->fua);
>  }
>
> -static void rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx)
> +static int rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx)
>  {
> +       int err;
> +
>         dev->gd->major          = rnbd_client_major;
>         dev->gd->first_minor    = idx << RNBD_PART_BITS;
>         dev->gd->minors         = 1 << RNBD_PART_BITS;
> @@ -1410,7 +1412,11 @@ static void rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx)
>
>         if (!dev->rotational)
>                 blk_queue_flag_set(QUEUE_FLAG_NONROT, dev->queue);
> -       add_disk(dev->gd);
> +       err = add_disk(dev->gd);
> +       if (err)
> +               blk_cleanup_disk(dev->gd);
> +
> +       return err;
>  }
>
>  static int rnbd_client_setup_device(struct rnbd_clt_dev *dev)
> @@ -1426,8 +1432,7 @@ static int rnbd_client_setup_device(struct rnbd_clt_dev *dev)
>         rnbd_init_mq_hw_queues(dev);
>
>         setup_request_queue(dev);
> -       rnbd_clt_setup_gen_disk(dev, idx);
> -       return 0;
> +       return rnbd_clt_setup_gen_disk(dev, idx);
>  }
>
>  static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess,
> --
> 2.30.2
>


From mdalam at codeaurora.org  Wed Sep  1 22:49:23 2021
From: mdalam at codeaurora.org (Md Sadre Alam)
Date: Thu,  2 Sep 2021 11:19:23 +0530
Subject: [PATCH V4] mtd: rawnand: qcom: Update code word value for raw read
Message-ID: <1630561763-18486-1-git-send-email-mdalam@codeaurora.org>

>From QPIC V2 onwards there is a separate register to read
last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".

qcom_nandc_read_cw_raw() is used to read only one code word
at a time. If we will configure number of code words to 1 in
in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
its reading the last code word, since from QPIC V2 onwards
we are having separate register to read the last code word,
we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
register to fetch data from controller buffer to system
memory.

Fixes: 503ee5aa ("mtd: rawnand: qcom: update last code word register")
Cc: stable at kernel.org
Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
---
[V4]
 * Added commit message
 * Added changelog

 In commit 503ee5aa added QPIC V2 support. Since QPIC V2 onwards there
 is separate register to get last CW data. If total number of CW configred is 1 
 then , QPIC controller treat this as last CW and software shhould copy data to memory
 via QPIC_NAND_READ_LOCATION_LAST_CW_n register instead of QPIC_NAND_READ_LOCATION_n.
 Since in raw read we are configuring total number of CW 1, this change fixes
 this if total number of CW 1 then make this as last CW.  raw_cw = ecc->steps - 1;
 since ecc->steps holds total number of CWs.

 drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index ef0bade..04e6f7b 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
 	int data_size1, data_size2, oob_size1, oob_size2;
 	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
+	int raw_cw = cw;
 
 	nand_read_page_op(chip, page, 0, NULL, 0);
 	host->use_ecc = false;
 
+	if (nandc->props->qpic_v2)
+		raw_cw = ecc->steps - 1;
+
 	clear_bam_transaction(nandc);
 	set_address(host, host->cw_size * cw, page);
-	update_rw_regs(host, 1, true, cw);
+	update_rw_regs(host, 1, true, raw_cw);
 	config_nand_page_read(chip);
 
 	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
@@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
 		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
 	}
 
-	config_nand_cw_read(chip, false, cw);
+	config_nand_cw_read(chip, false, raw_cw);
 
 	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
 	reg_off += data_size1;
-- 
2.7.4



From mdalam at codeaurora.org  Wed Sep  1 22:53:43 2021
From: mdalam at codeaurora.org (mdalam at codeaurora.org)
Date: Thu, 02 Sep 2021 11:23:43 +0530
Subject: [PATCH V3] mtd: rawnand: qcom: Update code word value for raw read
In-Reply-To: <20210901163615.090c6f24@xps13>
References: <1630493613-8158-1-git-send-email-mdalam@codeaurora.org>
 <20210901163615.090c6f24@xps13>
Message-ID: <b6473b7de57aa10682a5ca1651f6e620@codeaurora.org>

On 2021-09-01 20:06, Miquel Raynal wrote:
> Md Sadre Alam <mdalam at codeaurora.org> wrote on Wed,  1 Sep 2021
> 16:23:33 +0530:
> 
>> Fixes: 503ee5aa ("mtd: rawnand: qcom: update last code word register")
>> Cc: stable at kernel.org
>> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
>> ---
>> [V3]
>>  * Added Fixes tag
>>  * Removed change log from commit message.
>> 
>>     From QPIC V2 onwards there is a separate register to read
>>     last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".
>> 
>>     qcom_nandc_read_cw_raw() is used to read only one code word
>>     at a time. If we will configure number of code words to 1 in
>>     in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
>>     its reading the last code word, since from QPIC V2 onwards
>>     we are having separate register to read the last code word,
>>     we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
>>     register to fetch data from controller buffer to system
>>     memory.
> 
> Really?
> 
> It's not your first contribution, you know what a changelog is and what
> a commit message is, right? So please, keep the commit message
> ("why" your change is needed) where it was and only put
> the changelog (the differences between two versions) below the three
> dashes '---'.
> 
   Sorry for misinterpreting your comments.

   I have addressed your comment in patch V4

>> 
>>  drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c 
>> b/drivers/mtd/nand/raw/qcom_nandc.c
>> index ef0bade..04e6f7b 100644
>> --- a/drivers/mtd/nand/raw/qcom_nandc.c
>> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
>> @@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>> struct nand_chip *chip,
>>  	struct nand_ecc_ctrl *ecc = &chip->ecc;
>>  	int data_size1, data_size2, oob_size1, oob_size2;
>>  	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
>> +	int raw_cw = cw;
>> 
>>  	nand_read_page_op(chip, page, 0, NULL, 0);
>>  	host->use_ecc = false;
>> 
>> +	if (nandc->props->qpic_v2)
>> +		raw_cw = ecc->steps - 1;
>> +
>>  	clear_bam_transaction(nandc);
>>  	set_address(host, host->cw_size * cw, page);
>> -	update_rw_regs(host, 1, true, cw);
>> +	update_rw_regs(host, 1, true, raw_cw);
>>  	config_nand_page_read(chip);
>> 
>>  	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
>> @@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>> struct nand_chip *chip,
>>  		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
>>  	}
>> 
>> -	config_nand_cw_read(chip, false, cw);
>> +	config_nand_cw_read(chip, false, raw_cw);
>> 
>>  	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
>>  	reg_off += data_size1;


From mani at kernel.org  Thu Sep  2 02:17:30 2021
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Thu, 2 Sep 2021 14:47:30 +0530
Subject: [PATCH V4] mtd: rawnand: qcom: Update code word value for raw read
In-Reply-To: <1630561763-18486-1-git-send-email-mdalam@codeaurora.org>
References: <1630561763-18486-1-git-send-email-mdalam@codeaurora.org>
Message-ID: <20210902091730.GA10844@workstation>

On Thu, Sep 02, 2021 at 11:19:23AM +0530, Md Sadre Alam wrote:
> From QPIC V2 onwards there is a separate register to read
> last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".
> 
> qcom_nandc_read_cw_raw() is used to read only one code word
> at a time. If we will configure number of code words to 1 in
> in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
> its reading the last code word, since from QPIC V2 onwards
> we are having separate register to read the last code word,
> we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
> register to fetch data from controller buffer to system
> memory.
> 
> Fixes: 503ee5aa ("mtd: rawnand: qcom: update last code word register")

Commit hash should be of 12 digits.

> Cc: stable at kernel.org
> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> ---
> [V4]
>  * Added commit message
>  * Added changelog
> 
>  In commit 503ee5aa added QPIC V2 support. Since QPIC V2 onwards there
>  is separate register to get last CW data. If total number of CW configred is 1 
>  then , QPIC controller treat this as last CW and software shhould copy data to memory
>  via QPIC_NAND_READ_LOCATION_LAST_CW_n register instead of QPIC_NAND_READ_LOCATION_n.
>  Since in raw read we are configuring total number of CW 1, this change fixes
>  this if total number of CW 1 then make this as last CW.  raw_cw = ecc->steps - 1;
>  since ecc->steps holds total number of CWs.
> 

This is not a changelog. Changelog should mention what has been changed
between versions from v1 to v4. For example:

Changes in v4:

* Incorporated AAA comments from X
* Changed a local variable

Changes in v3:

* Incorporated BBB comments from X

Changes in v2:

* Incorporated CCC comments from X

>  drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
> index ef0bade..04e6f7b 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
>  	struct nand_ecc_ctrl *ecc = &chip->ecc;
>  	int data_size1, data_size2, oob_size1, oob_size2;
>  	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
> +	int raw_cw = cw;
>  
>  	nand_read_page_op(chip, page, 0, NULL, 0);
>  	host->use_ecc = false;
>  
> +	if (nandc->props->qpic_v2)
> +		raw_cw = ecc->steps - 1;
> +

Sorry, I don't understand how it can work. For reading a codeword like
0, you are reading the last codeword here if the controller is v2. And
you'll continue to read the last codeword only for any codeword
requested :/

Thanks,
Mani

>  	clear_bam_transaction(nandc);
>  	set_address(host, host->cw_size * cw, page);
> -	update_rw_regs(host, 1, true, cw);
> +	update_rw_regs(host, 1, true, raw_cw);
>  	config_nand_page_read(chip);
>  
>  	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
> @@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
>  		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
>  	}
>  
> -	config_nand_cw_read(chip, false, cw);
> +	config_nand_cw_read(chip, false, raw_cw);
>  
>  	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
>  	reg_off += data_size1;
> -- 
> 2.7.4
> 


From rogerq at kernel.org  Thu Sep  2 02:56:03 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  2 Sep 2021 12:56:03 +0300
Subject: [PATCH v2 0/6] dt-bindings: memory-controllers: ti,
 gpmc: Convert to yaml
Message-ID: <20210902095609.16583-1-rogerq@kernel.org>

Hi,

This series converts ti,gpmc memory controller and ti,gpmc-nand and
ti,gpmc-onenand MTD controller bindings to yaml.

cheers,
-roger

Changelog:
v2:
- Fix all errors in dtbs_check and dt_bindings_check
- remove references to gpmc-omap.txt
- Convert ti,gpmc-nand and ti,gpmc-onenand bindings to yaml as well

Roger Quadros (6):
  ARM: dts: omap: Fixup GPMC child nodes
  dt-bindings: memory-controllers: ti,gpmc: Convert to yaml
  dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
  dt-bindings: mtd: ti,gpmc-onenand: Convert to yaml
  dt-bindings: mtd: Remove gpmc-nor.txt
  dt-bindings: net: Remove gpmc-eth.txt

 .../bindings/memory-controllers/omap-gpmc.txt | 157 --------
 .../bindings/memory-controllers/ti,gpmc.yaml  | 364 ++++++++++++++++++
 .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 -------
 .../devicetree/bindings/mtd/gpmc-nor.txt      |  98 -----
 .../devicetree/bindings/mtd/gpmc-onenand.txt  |  48 ---
 .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 109 ++++++
 .../bindings/mtd/ti,gpmc-onenand.yaml         |  71 ++++
 .../devicetree/bindings/net/gpmc-eth.txt      |  97 -----
 .../boot/dts/logicpd-som-lv-baseboard.dtsi    |   2 +-
 .../boot/dts/logicpd-torpedo-37xx-devkit.dts  |   2 +-
 .../boot/dts/logicpd-torpedo-baseboard.dtsi   |   2 +-
 arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi     |  62 ++-
 arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi     |  59 ++-
 arch/arm/boot/dts/omap-zoom-common.dtsi       |  16 +-
 arch/arm/boot/dts/omap2430-sdp.dts            |   6 +-
 arch/arm/boot/dts/omap3-cm-t3x30.dtsi         |   6 +-
 .../arm/boot/dts/omap3-devkit8000-common.dtsi |   4 +-
 arch/arm/boot/dts/omap3-evm-37xx.dts          |   1 +
 arch/arm/boot/dts/omap3-evm-common.dtsi       |   9 -
 .../boot/dts/omap3-evm-processor-common.dtsi  |   5 +-
 arch/arm/boot/dts/omap3-evm.dts               |   1 +
 arch/arm/boot/dts/omap3-igep0020-common.dtsi  |   5 +-
 arch/arm/boot/dts/omap3-ldp.dts               |   5 +-
 arch/arm/boot/dts/omap3-n900.dts              |   2 +-
 .../dts/omap3-overo-chestnut43-common.dtsi    |   6 +-
 .../arm/boot/dts/omap3-overo-tobi-common.dtsi |   6 +-
 .../boot/dts/omap3-overo-tobiduo-common.dtsi  |   8 +-
 arch/arm/boot/dts/omap3-sb-t35.dtsi           |   4 +-
 arch/arm/boot/dts/omap4-duovero-parlor.dts    |   6 +-
 29 files changed, 649 insertions(+), 659 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
 delete mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt

-- 
2.17.1



From rogerq at kernel.org  Thu Sep  2 02:56:04 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  2 Sep 2021 12:56:04 +0300
Subject: [PATCH v2 1/6] ARM: dts: omap: Fixup GPMC child nodes
In-Reply-To: <20210902095609.16583-1-rogerq@kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
Message-ID: <20210902095609.16583-2-rogerq@kernel.org>

Fixes up the GPMC child nodes to prevent dtbs_check errors
after device tree binding conversion to yaml.

- Use reg address as node name
- gpmc,cycle2cycle-samecsen and gpmc,cycle2cycle-diffcsen are
  boolean properties.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../boot/dts/logicpd-som-lv-baseboard.dtsi    |  2 +-
 .../boot/dts/logicpd-torpedo-37xx-devkit.dts  |  2 +-
 .../boot/dts/logicpd-torpedo-baseboard.dtsi   |  2 +-
 arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi     | 62 +++++++++----------
 arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi     | 59 +++++++++---------
 arch/arm/boot/dts/omap-zoom-common.dtsi       | 16 ++---
 arch/arm/boot/dts/omap2430-sdp.dts            |  6 +-
 arch/arm/boot/dts/omap3-cm-t3x30.dtsi         |  6 +-
 .../arm/boot/dts/omap3-devkit8000-common.dtsi |  4 +-
 arch/arm/boot/dts/omap3-evm-37xx.dts          |  1 +
 arch/arm/boot/dts/omap3-evm-common.dtsi       |  9 ---
 .../boot/dts/omap3-evm-processor-common.dtsi  |  5 +-
 arch/arm/boot/dts/omap3-evm.dts               |  1 +
 arch/arm/boot/dts/omap3-igep0020-common.dtsi  |  5 +-
 arch/arm/boot/dts/omap3-ldp.dts               |  5 +-
 arch/arm/boot/dts/omap3-n900.dts              |  2 +-
 .../dts/omap3-overo-chestnut43-common.dtsi    |  6 +-
 .../arm/boot/dts/omap3-overo-tobi-common.dtsi |  6 +-
 .../boot/dts/omap3-overo-tobiduo-common.dtsi  |  8 +--
 arch/arm/boot/dts/omap3-sb-t35.dtsi           |  4 +-
 arch/arm/boot/dts/omap4-duovero-parlor.dts    |  6 +-
 21 files changed, 105 insertions(+), 112 deletions(-)

diff --git a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
index 7d0468a23781..f2364cb114c5 100644
--- a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
+++ b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
@@ -65,7 +65,7 @@
 		  1 0 0x2c000000 0x1000000	/* CS1: 16MB for LAN9221 */
 		  2 0 0x10000000 0x2000000>;    /* CS2: 32MB for NOR */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 1,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&lan9221_pins>;
 		interrupt-parent = <&gpio5>;
diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
index 5532db04046c..6357915d207b 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
+++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
@@ -4,8 +4,8 @@
 
 #include "omap36xx.dtsi"
 #include "logicpd-torpedo-som.dtsi"
-#include "omap-gpmc-smsc9221.dtsi"
 #include "logicpd-torpedo-baseboard.dtsi"
+#include "omap-gpmc-smsc9221.dtsi"
 
 / {
 	model = "LogicPD Zoom DM3730 Torpedo + Wireless Development Kit";
diff --git a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
index 533a47bc4a53..05049a34b6f1 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
+++ b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
@@ -95,7 +95,7 @@
 	ranges = <0 0 0x30000000 0x1000000	/* CS0: 16MB for NAND */
 		  1 0 0x2c000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 1,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&lan9221_pins>;
 		interrupt-parent = <&gpio5>;
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
index ded7e8fec9eb..2a462cb65a7d 100644
--- a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
+++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
@@ -20,36 +20,34 @@
 	};
 };
 
-&gpmc {
-	ethernet at gpmc {
-		compatible = "smsc,lan9221", "smsc,lan9115";
-		bank-width = <2>;
-		gpmc,device-width = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
-		gpmc,cs-on-ns = <5>;
-		gpmc,cs-rd-off-ns = <150>;
-		gpmc,cs-wr-off-ns = <150>;
-		gpmc,adv-on-ns = <0>;
-		gpmc,adv-rd-off-ns = <15>;
-		gpmc,adv-wr-off-ns = <40>;
-		gpmc,oe-on-ns = <45>;
-		gpmc,oe-off-ns = <140>;
-		gpmc,we-on-ns = <45>;
-		gpmc,we-off-ns = <140>;
-		gpmc,rd-cycle-ns = <155>;
-		gpmc,wr-cycle-ns = <155>;
-		gpmc,access-ns = <120>;
-		gpmc,page-burst-access-ns = <20>;
-		gpmc,bus-turnaround-ns = <75>;
-		gpmc,cycle2cycle-delay-ns = <75>;
-		gpmc,wait-monitoring-ns = <0>;
-		gpmc,clk-activation-ns = <0>;
-		gpmc,wr-data-mux-bus-ns = <0>;
-		gpmc,wr-access-ns = <0>;
-		vddvario-supply = <&vddvario>;
-		vdd33a-supply = <&vdd33a>;
-		reg-io-width = <4>;
-		smsc,save-mac-address;
-	};
+&gpmc_ethernet {
+	compatible = "smsc,lan9221", "smsc,lan9115";
+	bank-width = <2>;
+	gpmc,device-width = <1>;
+	gpmc,cycle2cycle-samecsen;
+	gpmc,cycle2cycle-diffcsen;
+	gpmc,cs-on-ns = <5>;
+	gpmc,cs-rd-off-ns = <150>;
+	gpmc,cs-wr-off-ns = <150>;
+	gpmc,adv-on-ns = <0>;
+	gpmc,adv-rd-off-ns = <15>;
+	gpmc,adv-wr-off-ns = <40>;
+	gpmc,oe-on-ns = <45>;
+	gpmc,oe-off-ns = <140>;
+	gpmc,we-on-ns = <45>;
+	gpmc,we-off-ns = <140>;
+	gpmc,rd-cycle-ns = <155>;
+	gpmc,wr-cycle-ns = <155>;
+	gpmc,access-ns = <120>;
+	gpmc,page-burst-access-ns = <20>;
+	gpmc,bus-turnaround-ns = <75>;
+	gpmc,cycle2cycle-delay-ns = <75>;
+	gpmc,wait-monitoring-ns = <0>;
+	gpmc,clk-activation-ns = <0>;
+	gpmc,wr-data-mux-bus-ns = <0>;
+	gpmc,wr-access-ns = <0>;
+	vddvario-supply = <&vddvario>;
+	vdd33a-supply = <&vdd33a>;
+	reg-io-width = <4>;
+	smsc,save-mac-address;
 };
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
index 7f6aefd13451..c1e78f929d2b 100644
--- a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
+++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
@@ -24,36 +24,33 @@
 	};
 };
 
-&gpmc {
-	ethernet at gpmc {
-		compatible = "smsc,lan9221","smsc,lan9115";
-		bank-width = <2>;
+&gpmc_ethernet {
+	compatible = "smsc,lan9221","smsc,lan9115";
+	bank-width = <2>;
+	gpmc,mux-add-data = <0>;
+	gpmc,cs-on-ns = <0>;
+	gpmc,cs-rd-off-ns = <42>;
+	gpmc,cs-wr-off-ns = <36>;
+	gpmc,adv-on-ns = <6>;
+	gpmc,adv-rd-off-ns = <12>;
+	gpmc,adv-wr-off-ns = <12>;
+	gpmc,oe-on-ns = <0>;
+	gpmc,oe-off-ns = <42>;
+	gpmc,we-on-ns = <0>;
+	gpmc,we-off-ns = <36>;
+	gpmc,rd-cycle-ns = <60>;
+	gpmc,wr-cycle-ns = <54>;
+	gpmc,access-ns = <36>;
+	gpmc,page-burst-access-ns = <0>;
+	gpmc,bus-turnaround-ns = <0>;
+	gpmc,cycle2cycle-delay-ns = <0>;
+	gpmc,wr-data-mux-bus-ns = <18>;
+	gpmc,wr-access-ns = <42>;
+	gpmc,cycle2cycle-samecsen;
+	gpmc,cycle2cycle-diffcsen;
 
-		gpmc,mux-add-data;
-		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <42>;
-		gpmc,cs-wr-off-ns = <36>;
-		gpmc,adv-on-ns = <6>;
-		gpmc,adv-rd-off-ns = <12>;
-		gpmc,adv-wr-off-ns = <12>;
-		gpmc,oe-on-ns = <0>;
-		gpmc,oe-off-ns = <42>;
-		gpmc,we-on-ns = <0>;
-		gpmc,we-off-ns = <36>;
-		gpmc,rd-cycle-ns = <60>;
-		gpmc,wr-cycle-ns = <54>;
-		gpmc,access-ns = <36>;
-		gpmc,page-burst-access-ns = <0>;
-		gpmc,bus-turnaround-ns = <0>;
-		gpmc,cycle2cycle-delay-ns = <0>;
-		gpmc,wr-data-mux-bus-ns = <18>;
-		gpmc,wr-access-ns = <42>;
-		gpmc,cycle2cycle-samecsen;
-		gpmc,cycle2cycle-diffcsen;
-
-		vddvario-supply = <&vddvario>;
-		vdd33a-supply = <&vdd33a>;
-		reg-io-width = <4>;
-		smsc,save-mac-address;
-	};
+	vddvario-supply = <&vddvario>;
+	vdd33a-supply = <&vdd33a>;
+	reg-io-width = <4>;
+	smsc,save-mac-address;
 };
diff --git a/arch/arm/boot/dts/omap-zoom-common.dtsi b/arch/arm/boot/dts/omap-zoom-common.dtsi
index d4ad9e58b199..47192c617cd1 100644
--- a/arch/arm/boot/dts/omap-zoom-common.dtsi
+++ b/arch/arm/boot/dts/omap-zoom-common.dtsi
@@ -3,8 +3,6 @@
  * Common features on the Zoom debug board
  */
 
-#include "omap-gpmc-smsc911x.dtsi"
-
 &gpmc {
 	ranges = <3 0 0x10000000 0x1000000>,	/* CS3: 16MB for UART */
 		 <7 0 0x2c000000 0x01000000>;
@@ -27,8 +25,8 @@
 		gpmc,mux-add-data = <0>;
 		gpmc,device-width = <1>;
 		gpmc,wait-pin = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 		gpmc,cs-on-ns = <5>;
 		gpmc,cs-rd-off-ns = <155>;
 		gpmc,cs-wr-off-ns = <155>;
@@ -50,7 +48,7 @@
 		gpmc,wr-data-mux-bus-ns = <45>;
 		gpmc,wr-access-ns = <145>;
 	};
-	uart at 3,1 {
+	uart at 3,100 {
 		compatible = "ns16550a";
 		reg = <3 0x100 8>;	/* CS3, offset 0x100, IO size 8 */
 		bank-width = <2>;
@@ -61,7 +59,7 @@
 		clock-frequency = <1843200>;
 		current-speed = <115200>;
 	};
-	uart at 3,2 {
+	uart at 3,200 {
 		compatible = "ns16550a";
 		reg = <3 0x200 8>;	/* CS3, offset 0x200, IO size 8 */
 		bank-width = <2>;
@@ -72,7 +70,7 @@
 		clock-frequency = <1843200>;
 		current-speed = <115200>;
 	};
-	uart at 3,3 {
+	uart at 3,300 {
 		compatible = "ns16550a";
 		reg = <3 0x300 8>;	/* CS3, offset 0x300, IO size 8 */
 		bank-width = <2>;
@@ -84,9 +82,11 @@
 		current-speed = <115200>;
 	};
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 7,0 {
 		reg = <7 0 0xff>;
 		interrupt-parent = <&gpio5>;
 		interrupts = <30 IRQ_TYPE_LEVEL_LOW>;	/* gpio158 */
 	};
 };
+
+#include "omap-gpmc-smsc911x.dtsi"
diff --git a/arch/arm/boot/dts/omap2430-sdp.dts b/arch/arm/boot/dts/omap2430-sdp.dts
index 7d27e907533f..f74906e4721b 100644
--- a/arch/arm/boot/dts/omap2430-sdp.dts
+++ b/arch/arm/boot/dts/omap2430-sdp.dts
@@ -34,7 +34,7 @@
 
 &gpmc {
 	ranges = <5 0 0x08000000 0x01000000>;
-	ethernet at gpmc {
+	ethernet at 5,300 {
 		compatible = "smsc,lan91c94";
 		interrupt-parent = <&gpio5>;
 		interrupts = <21 IRQ_TYPE_LEVEL_LOW>;	/* gpio149 */
@@ -43,8 +43,8 @@
 		gpmc,sync-clk-ps = <0>;
 		gpmc,mux-add-data = <2>;
 		gpmc,device-width = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 		gpmc,cs-on-ns = <6>;
 		gpmc,cs-rd-off-ns = <187>;
 		gpmc,cs-wr-off-ns = <187>;
diff --git a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
index 5e8943539fcc..2059463de9d6 100644
--- a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
+++ b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
@@ -47,13 +47,11 @@
 	};
 };
 
-#include "omap-gpmc-smsc911x.dtsi"
-
 &gpmc {
 	ranges = <5 0 0x2c000000 0x01000000>, /* CM-T3x30 SMSC9x Eth */
 		 <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
 
-	smsc1: ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		compatible = "smsc,lan9221", "smsc,lan9115";
 		pinctrl-names = "default";
 		pinctrl-0 = <&smsc1_pins>;
@@ -63,6 +61,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc911x.dtsi"
+
 &i2c1 {
 	twl: twl at 48 {
 		reg = <0x48>;
diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
index 2c19d6e255bd..5e55198e4576 100644
--- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
@@ -267,8 +267,8 @@
 		gpmc,mux-add-data = <0>;
 		gpmc,device-width = <1>;
 		gpmc,wait-pin = <0>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 
 		gpmc,cs-on-ns = <6>;
 		gpmc,cs-rd-off-ns = <180>;
diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts
index c9332195d096..077b1a19f171 100644
--- a/arch/arm/boot/dts/omap3-evm-37xx.dts
+++ b/arch/arm/boot/dts/omap3-evm-37xx.dts
@@ -7,6 +7,7 @@
 #include "omap36xx.dtsi"
 #include "omap3-evm-common.dtsi"
 #include "omap3-evm-processor-common.dtsi"
+#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	model = "TI OMAP37XX EVM (TMDSEVM3730)";
diff --git a/arch/arm/boot/dts/omap3-evm-common.dtsi b/arch/arm/boot/dts/omap3-evm-common.dtsi
index 17c89df6ce6b..2f7bdb248a51 100644
--- a/arch/arm/boot/dts/omap3-evm-common.dtsi
+++ b/arch/arm/boot/dts/omap3-evm-common.dtsi
@@ -4,7 +4,6 @@
  */
 
 #include <dt-bindings/input/input.h>
-#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	cpus {
@@ -182,14 +181,6 @@
 	power = <50>;
 };
 
-&gpmc {
-	ethernet at gpmc {
-		interrupt-parent = <&gpio6>;
-		interrupts = <16 8>;
-		reg = <5 0 0xff>;
-	};
-};
-
 &vaux2 {
 	regulator-name = "usb_1v8";
 	regulator-min-microvolt = <1800000>;
diff --git a/arch/arm/boot/dts/omap3-evm-processor-common.dtsi b/arch/arm/boot/dts/omap3-evm-processor-common.dtsi
index e6ba30a21166..3adb967b96c4 100644
--- a/arch/arm/boot/dts/omap3-evm-processor-common.dtsi
+++ b/arch/arm/boot/dts/omap3-evm-processor-common.dtsi
@@ -217,8 +217,11 @@
 	ranges = <0 0 0x30000000 0x1000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;	/* CS5: 16MB for LAN9220 */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&smsc911x_pins>;
+		interrupt-parent = <&gpio6>;
+		interrupts = <16 8>;
+		reg = <5 0 0xff>;
 	};
 };
diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts
index 5cc0cf7cd16c..805856d47cda 100644
--- a/arch/arm/boot/dts/omap3-evm.dts
+++ b/arch/arm/boot/dts/omap3-evm.dts
@@ -7,6 +7,7 @@
 #include "omap34xx.dtsi"
 #include "omap3-evm-common.dtsi"
 #include "omap3-evm-processor-common.dtsi"
+#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	model = "TI OMAP35XX EVM (TMDSEVM3530)";
diff --git a/arch/arm/boot/dts/omap3-igep0020-common.dtsi b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
index 73d8f471b9ec..104df84ea720 100644
--- a/arch/arm/boot/dts/omap3-igep0020-common.dtsi
+++ b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
@@ -7,7 +7,6 @@
  */
 
 #include "omap3-igep.dtsi"
-#include "omap-gpmc-smsc9221.dtsi"
 
 / {
 
@@ -217,7 +216,7 @@
 	ranges = <0 0 0x30000000 0x01000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;	/* CS5: 16MB for ethernet */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&smsc9221_pins>;
 		reg = <5 0 0xff>;
@@ -226,6 +225,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &uart2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart2_pins>;
diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts
index 9c6a92724590..a299f04217fd 100644
--- a/arch/arm/boot/dts/omap3-ldp.dts
+++ b/arch/arm/boot/dts/omap3-ldp.dts
@@ -6,7 +6,6 @@
 
 #include <dt-bindings/input/input.h>
 #include "omap34xx.dtsi"
-#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	model = "TI OMAP3430 LDP (Zoom1 Labrador)";
@@ -148,13 +147,15 @@
 		};
 	};
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 1,0 {
 		interrupt-parent = <&gpio5>;
 		interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
 		reg = <1 0 0xff>;
 	};
 };
 
+#include "omap-gpmc-smsc911x.dtsi"
+
 &i2c1 {
 	clock-frequency = <2600000>;
 
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 32335d4ce478..35602d7876aa 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -936,7 +936,7 @@
 	};
 
 	/* Ethernet is on some early development boards and qemu */
-	ethernet at gpmc {
+	ethernet at 1,0 {
 		compatible = "smsc,lan91c94";
 		interrupt-parent = <&gpio2>;
 		interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;	/* gpio54 */
diff --git a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
index 2d2c61d7aa86..34b805851dd2 100644
--- a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
@@ -49,16 +49,16 @@
 	};
 };
 
-#include "omap-gpmc-smsc9221.dtsi"
-
 &gpmc {
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;	/* GPIO 176 */
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &lis33de {
 	status = "disabled";
 };
diff --git a/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
index 9bf4b88a4b50..895803654e3c 100644
--- a/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
@@ -21,16 +21,16 @@
 	};
 };
 
-#include "omap-gpmc-smsc9221.dtsi"
-
 &gpmc {
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;	/* GPIO 176 */
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &lis33de {
 	status = "disabled";
 };
diff --git a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
index e5da3bc6f105..c212d72dcfe9 100644
--- a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
@@ -9,10 +9,8 @@
 
 #include "omap3-overo-common-peripherals.dtsi"
 
-#include "omap-gpmc-smsc9221.dtsi"
-
 &gpmc {
-	smsc1: ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;	/* GPIO 176 */
@@ -22,7 +20,7 @@
 		compatible = "smsc,lan9221","smsc,lan9115";
 		bank-width = <2>;
 
-		gpmc,mux-add-data;
+		gpmc,mux-add-data = <0>;
 		gpmc,cs-on-ns = <0>;
 		gpmc,cs-rd-off-ns = <42>;
 		gpmc,cs-wr-off-ns = <36>;
@@ -54,6 +52,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &lis33de {
 	status = "disabled";
 };
diff --git a/arch/arm/boot/dts/omap3-sb-t35.dtsi b/arch/arm/boot/dts/omap3-sb-t35.dtsi
index fb9842fa922c..5ec0893415e0 100644
--- a/arch/arm/boot/dts/omap3-sb-t35.dtsi
+++ b/arch/arm/boot/dts/omap3-sb-t35.dtsi
@@ -108,8 +108,8 @@
 		reg = <4 0 0xff>;
 		bank-width = <2>;
 		gpmc,device-width = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 		gpmc,cs-on-ns = <5>;
 		gpmc,cs-rd-off-ns = <150>;
 		gpmc,cs-wr-off-ns = <150>;
diff --git a/arch/arm/boot/dts/omap4-duovero-parlor.dts b/arch/arm/boot/dts/omap4-duovero-parlor.dts
index b294c22177cb..dfc50764c405 100644
--- a/arch/arm/boot/dts/omap4-duovero-parlor.dts
+++ b/arch/arm/boot/dts/omap4-duovero-parlor.dts
@@ -131,12 +131,10 @@
 	status = "disabled";
 };
 
-#include "omap-gpmc-smsc911x.dtsi"
-
 &gpmc {
 	ranges = <5 0 0x2c000000 0x1000000>;			/* CS5 */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio2>;
 		interrupts = <12 IRQ_TYPE_LEVEL_LOW>;		/* gpio_44 */
@@ -170,6 +168,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc911x.dtsi"
+
 &dss {
 	status = "okay";
 };
-- 
2.17.1



From rogerq at kernel.org  Thu Sep  2 02:56:05 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  2 Sep 2021 12:56:05 +0300
Subject: [PATCH v2 2/6] dt-bindings: memory-controllers: ti,
 gpmc: Convert to yaml
In-Reply-To: <20210902095609.16583-1-rogerq@kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
Message-ID: <20210902095609.16583-3-rogerq@kernel.org>

Convert omap-gpmc.txt to ti,gpmc.yaml.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../bindings/memory-controllers/omap-gpmc.txt | 157 --------
 .../bindings/memory-controllers/ti,gpmc.yaml  | 364 ++++++++++++++++++
 .../devicetree/bindings/mtd/gpmc-nand.txt     |   2 +-
 .../devicetree/bindings/mtd/gpmc-nor.txt      |   4 +-
 .../devicetree/bindings/mtd/gpmc-onenand.txt  |   2 +-
 .../devicetree/bindings/net/gpmc-eth.txt      |   4 +-
 6 files changed, 370 insertions(+), 163 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt b/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
deleted file mode 100644
index c1359f4d48d7..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
+++ /dev/null
@@ -1,157 +0,0 @@
-Device tree bindings for OMAP general purpose memory controllers (GPMC)
-
-The actual devices are instantiated from the child nodes of a GPMC node.
-
-Required properties:
-
- - compatible:		Should be set to one of the following:
-
-			ti,omap2420-gpmc (omap2420)
-			ti,omap2430-gpmc (omap2430)
-			ti,omap3430-gpmc (omap3430 & omap3630)
-			ti,omap4430-gpmc (omap4430 & omap4460 & omap543x)
-			ti,am3352-gpmc   (am335x devices)
-
- - reg:			A resource specifier for the register space
-			(see the example below)
- - ti,hwmods:		Should be set to "ti,gpmc" until the DT transition is
-			completed.
- - #address-cells:	Must be set to 2 to allow memory address translation
- - #size-cells:		Must be set to 1 to allow CS address passing
- - gpmc,num-cs:		The maximum number of chip-select lines that controller
-			can support.
- - gpmc,num-waitpins:	The maximum number of wait pins that controller can
-			support.
- - ranges:		Must be set up to reflect the memory layout with four
-			integer values for each chip-select line in use:
-
-			   <cs-number> 0 <physical address of mapping> <size>
-
-			Currently, calculated values derived from the contents
-			of the per-CS register GPMC_CONFIG7 (as set up by the
-			bootloader) are used for the physical address decoding.
-			As this will change in the future, filling correct
-			values here is a requirement.
- - interrupt-controller: The GPMC driver implements and interrupt controller for
-			the NAND events "fifoevent" and "termcount" plus the
-			rising/falling edges on the GPMC_WAIT pins.
-			The interrupt number mapping is as follows
-			0 - NAND_fifoevent
-			1 - NAND_termcount
-			2 - GPMC_WAIT0 pin edge
-			3 - GPMC_WAIT1 pin edge, and so on.
- - interrupt-cells:	Must be set to 2
- - gpio-controller:	The GPMC driver implements a GPIO controller for the
-			GPMC WAIT pins that can be used as general purpose inputs.
-			0 maps to GPMC_WAIT0 pin.
- - gpio-cells:		Must be set to 2
-
-Required properties when using NAND prefetch dma:
- - dmas			GPMC NAND prefetch dma channel
- - dma-names		Must be set to "rxtx"
-
-Timing properties for child nodes. All are optional and default to 0.
-
- - gpmc,sync-clk-ps:	Minimum clock period for synchronous mode, in picoseconds
-
- Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2:
- - gpmc,cs-on-ns:	Assertion time
- - gpmc,cs-rd-off-ns:	Read deassertion time
- - gpmc,cs-wr-off-ns:	Write deassertion time
-
- ADV signal timings (in nanoseconds) corresponding to GPMC_CONFIG3:
- - gpmc,adv-on-ns:	Assertion time
- - gpmc,adv-rd-off-ns:	Read deassertion time
- - gpmc,adv-wr-off-ns:	Write deassertion time
- - gpmc,adv-aad-mux-on-ns:	Assertion time for AAD
- - gpmc,adv-aad-mux-rd-off-ns:	Read deassertion time for AAD
- - gpmc,adv-aad-mux-wr-off-ns:	Write deassertion time for AAD
-
- WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
- - gpmc,we-on-ns	Assertion time
- - gpmc,we-off-ns:	Deassertion time
-
- OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
- - gpmc,oe-on-ns:	Assertion time
- - gpmc,oe-off-ns:	Deassertion time
- - gpmc,oe-aad-mux-on-ns:	Assertion time for AAD
- - gpmc,oe-aad-mux-off-ns:	Deassertion time for AAD
-
- Access time and cycle time timings (in nanoseconds) corresponding to
- GPMC_CONFIG5:
- - gpmc,page-burst-access-ns: 	Multiple access word delay
- - gpmc,access-ns:		Start-cycle to first data valid delay
- - gpmc,rd-cycle-ns:		Total read cycle time
- - gpmc,wr-cycle-ns:		Total write cycle time
- - gpmc,bus-turnaround-ns:	Turn-around time between successive accesses
- - gpmc,cycle2cycle-delay-ns:	Delay between chip-select pulses
- - gpmc,clk-activation-ns: 	GPMC clock activation time
- - gpmc,wait-monitoring-ns:	Start of wait monitoring with regard to valid
-				data
-
-Boolean timing parameters. If property is present parameter enabled and
-disabled if omitted:
- - gpmc,adv-extra-delay:	ADV signal is delayed by half GPMC clock
- - gpmc,cs-extra-delay:		CS signal is delayed by half GPMC clock
- - gpmc,cycle2cycle-diffcsen:	Add "cycle2cycle-delay" between successive
-				accesses to a different CS
- - gpmc,cycle2cycle-samecsen:	Add "cycle2cycle-delay" between successive
-				accesses to the same CS
- - gpmc,oe-extra-delay:		OE signal is delayed by half GPMC clock
- - gpmc,we-extra-delay:		WE signal is delayed by half GPMC clock
- - gpmc,time-para-granularity:	Multiply all access times by 2
-
-The following are only applicable to OMAP3+ and AM335x:
- - gpmc,wr-access-ns:		In synchronous write mode, for single or
-				burst accesses, defines the number of
-				GPMC_FCLK cycles from start access time
-				to the GPMC_CLK rising edge used by the
-				memory device for the first data capture.
- - gpmc,wr-data-mux-bus-ns:	In address-data multiplex mode, specifies
-				the time when the first data is driven on
-				the address-data bus.
-
-GPMC chip-select settings properties for child nodes. All are optional.
-
-- gpmc,burst-length	Page/burst length. Must be 4, 8 or 16.
-- gpmc,burst-wrap	Enables wrap bursting
-- gpmc,burst-read	Enables read page/burst mode
-- gpmc,burst-write	Enables write page/burst mode
-- gpmc,device-width	Total width of device(s) connected to a GPMC
-			chip-select in bytes. The GPMC supports 8-bit
-			and 16-bit devices and so this property must be
-			1 or 2.
-- gpmc,mux-add-data	Address and data multiplexing configuration.
-			Valid values are 1 for address-address-data
-			multiplexing mode and 2 for address-data
-			multiplexing mode.
-- gpmc,sync-read	Enables synchronous read. Defaults to asynchronous
-			is this is not set.
-- gpmc,sync-write	Enables synchronous writes. Defaults to asynchronous
-			is this is not set.
-- gpmc,wait-pin		Wait-pin used by client. Must be less than
-			"gpmc,num-waitpins".
-- gpmc,wait-on-read	Enables wait monitoring on reads.
-- gpmc,wait-on-write	Enables wait monitoring on writes.
-
-Example for an AM33xx board:
-
-	gpmc: gpmc at 50000000 {
-		compatible = "ti,am3352-gpmc";
-		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x2000>;
-		interrupts = <100>;
-		dmas = <&edma 52 0>;
-		dma-names = "rxtx";
-		gpmc,num-cs = <8>;
-		gpmc,num-waitpins = <2>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		gpio-controller;
-		#gpio-cells = <2>;
-
-		/* child nodes go here */
-	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
new file mode 100644
index 000000000000..b7d43370a95d
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
@@ -0,0 +1,364 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/ti,gpmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments GPMC Memory Controller device-tree bindings
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+  The GPMC is a unified memory controller dedicated for interfacing
+  with external memory devices like
+  - Asynchronous SRAM-like memories and ASICs
+  - Asynchronous, synchronous, and page mode burst NOR flash
+  - NAND flash
+  - Pseudo-SRAM devices
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - ti,omap2420-gpmc
+          - ti,omap2430-gpmc
+          - ti,omap3430-gpmc
+          - ti,omap4430-gpmc
+          - ti,am3352-gpmc
+
+  reg:
+    items:
+      - description:
+          Configuration registers for the controller.
+
+  interrupts: true
+
+  clocks:
+    maxItems: 1
+    description: |
+      Functional clock. Used for bus timing calculations and
+      GPMC configuration.
+
+  clock-names:
+    items:
+      - const: fck
+
+  dmas:
+    items:
+      - description: DMA channel for GPMC NAND prefetch
+
+  dma-names:
+    items:
+      - const: rxtx
+
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 1
+
+  gpmc,num-cs:
+    description: maximum number of supported chip-select lines.
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  gpmc,num-waitpins:
+    description: maximum number of supported wait pins.
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  ranges:
+    minItems: 1
+    description: |
+      Must be set up to reflect the memory layout with four
+      integer values for each chip-select line in use,
+      <cs-number> 0 <physical address of mapping> <size>
+
+    items:
+      - description: NAND bank 0
+      - description: NOR/SRAM bank 0
+      - description: NOR/SRAM bank 1
+
+  '#interrupt-cells':
+    const: 2
+
+  interrupt-controller:
+    description: |
+      The GPMC driver implements and interrupt controller for
+      the NAND events "fifoevent" and "termcount" plus the
+      rising/falling edges on the GPMC_WAIT pins.
+      The interrupt number mapping is as follows
+      0 - NAND_fifoevent
+      1 - NAND_termcount
+      2 - GPMC_WAIT0 pin edge
+      3 - GPMC_WAIT1 pin edge, and so on.
+
+  '#gpio-cells':
+     const: 2
+
+  gpio-controller:
+    description: |
+      The GPMC driver implements a GPIO controller for the
+      GPMC WAIT pins that can be used as general purpose inputs.
+      0 maps to GPMC_WAIT0 pin.
+
+  ti,hwmods:
+    description:
+      Name of the HWMOD associated with GPMC. This is for legacy
+      omap2/3 platforms only.
+    $ref: /schemas/types.yaml#/definitions/string
+    deprecated: true
+
+  ti,no-idle-on-init:
+    description:
+      Prevent idling the module at init. This is for legacy omap2/3
+      platforms only.
+    type: boolean
+    deprecated: true
+
+patternProperties:
+#  "@[0-3],[a-f0-9]+$":
+  "^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-fA-F]+(,[0-9a-fA-F]+)*$":
+    type: object
+    description: |
+      The child device node represents the device connected to the GPMC
+      bus. The device can be a NAND controller, SRAM device, NOR device
+      or an ASIC.
+
+    properties:
+      compatible:
+        description:
+          Compatible of attached device.
+
+      reg:
+        items:
+        - description: Register access space for the device
+
+# GPMC Timing properties for child nodes. All are optional and default to 0.
+
+      gpmc,sync-clk-ps:
+        description: Minimum clock period for synchronous mode, in picoseconds
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+# Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2:
+      gpmc,cs-on-ns:
+        description: Assertion time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,cs-rd-off-ns:
+        description: Read deassertion time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,cs-wr-off-ns:
+        description: Write deassertion time
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+# ADV signal timings (in nanoseconds) corresponding to GPMC_CONFIG3:
+      gpmc,adv-on-ns:
+        description: Assertion time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,adv-rd-off-ns:
+        description: Read deassertion time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,adv-wr-off-ns:
+        description: Write deassertion time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,adv-aad-mux-on-ns:
+        description: Assertion time for AAD
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,adv-aad-mux-rd-off-ns:
+        description: Read deassertion time for AAD
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,adv-aad-mux-wr-off-ns:
+        description: Write deassertion time for AAD
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+# WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
+      gpmc,we-on-ns:
+        description: Assertion time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,we-off-ns:
+        description: Deassertion time
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+# OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
+      gpmc,oe-on-ns:
+        description: Assertion time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,oe-off-ns:
+        description: Deassertion time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,oe-aad-mux-on-ns:
+        description:       Assertion time for AAD
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,oe-aad-mux-off-ns:
+        description:      Deassertion time for AAD
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+# Access time and cycle time timings (in nanoseconds) corresponding to
+# GPMC_CONFIG5:
+      gpmc,page-burst-access-ns:
+        description:   Multiple access word delay
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,access-ns:
+        description:              Start-cycle to first data valid delay
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,rd-cycle-ns:
+        description:            Total read cycle time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,wr-cycle-ns:
+        description:            Total write cycle time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,bus-turnaround-ns:
+        description:      Turn-around time between successive accesses
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,cycle2cycle-delay-ns:
+        description:   Delay between chip-select pulses
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,clk-activation-ns:
+        description:      GPMC clock activation time
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,wait-monitoring-ns:
+        description:     Start of wait monitoring with regard to valid data
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+# Boolean timing parameters. If property is present, parameter is enabled
+# otherwise disabled.
+      gpmc,adv-extra-delay:
+        description:        ADV signal is delayed by half GPMC clock
+        type: boolean
+      gpmc,cs-extra-delay:
+        description:         CS signal is delayed by half GPMC clock
+        type: boolean
+      gpmc,cycle2cycle-diffcsen:
+        description: |
+          Add "cycle2cycle-delay" between successive accesses
+          to a different CS
+        type: boolean
+      gpmc,cycle2cycle-samecsen:
+        description: |
+          Add "cycle2cycle-delay" between successive accesses
+          to the same CS
+        type: boolean
+      gpmc,oe-extra-delay:
+        description:         OE signal is delayed by half GPMC clock
+        type: boolean
+      gpmc,we-extra-delay:
+        description:         WE signal is delayed by half GPMC clock
+        type: boolean
+      gpmc,time-para-granularity:
+        description:  Multiply all access times by 2
+        type: boolean
+
+# The following two properties are applicable only to OMAP3+ and AM335x:
+      gpmc,wr-access-ns:
+        description: |
+          In synchronous write mode, for single or
+          burst accesses, defines the number of
+          GPMC_FCLK cycles from start access time
+          to the GPMC_CLK rising edge used by the
+          memory device for the first data capture.
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,wr-data-mux-bus-ns:
+        description: |
+          In address-data multiplex mode, specifies
+          the time when the first data is driven on
+          the address-data bus.
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+# GPMC chip-select settings properties for child nodes. All are optional.
+
+      gpmc,burst-length:
+        description:     Page/burst length. Must be 4, 8 or 16.
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [4, 8, 16]
+      gpmc,burst-wrap:
+        description:       Enables wrap bursting
+        type: boolean
+      gpmc,burst-read:
+        description:       Enables read page/burst mode
+        type: boolean
+      gpmc,burst-write:
+        description:      Enables write page/burst mode
+        type: boolean
+      gpmc,device-width:
+        description: |
+          Total width of device(s) connected to a GPMC
+          chip-select in bytes. The GPMC supports 8-bit
+          and 16-bit devices and so this property must be
+          1 or 2.
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [1, 2]
+      gpmc,mux-add-data:
+        description: |
+          Address and data multiplexing configuration.
+          Valid values are:
+          0 for Non multiplexed mode
+          1 for address-address-data multiplexing mode and
+          2 for address-data multiplexing mode.
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [0, 1, 2]
+      gpmc,sync-read:
+        description: |
+          Enables synchronous read. Defaults to asynchronous
+          is this is not set.
+        type: boolean
+      gpmc,sync-write:
+        description: |
+          Enables synchronous writes. Defaults to asynchronous
+          is this is not set.
+        type: boolean
+      gpmc,wait-pin:
+        description: |
+          Wait-pin used by client. Must be less than "gpmc,num-waitpins".
+        $ref: /schemas/types.yaml#/definitions/uint32
+      gpmc,wait-on-read:
+        description:     Enables wait monitoring on reads.
+        type: boolean
+      gpmc,wait-on-write:
+        description:    Enables wait monitoring on writes.
+        type: boolean
+
+    required:
+      - reg
+
+required:
+  - compatible
+  - reg
+  - gpmc,num-cs
+  - gpmc,num-waitpins
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    gpmc: memory-controller at 50000000 {
+      compatible = "ti,am3352-gpmc";
+      reg = <0x50000000 0x2000>;
+      interrupts = <100>;
+      clocks = <&l3s_clkctrl>;
+      clock-names = "fck";
+      dmas = <&edma 52 0>;
+      dma-names = "rxtx";
+      gpmc,num-cs = <8>;
+      gpmc,num-waitpins = <2>;
+      #address-cells = <2>;
+      #size-cells = <1>;
+      ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      gpio-controller;
+      #gpio-cells = <2>;
+
+      nand at 0,0 {
+        compatible = "ti,omap2-nand";
+        reg = <0 0 4>;
+        interrupt-parent = <&gpmc>;
+        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+                     <1 IRQ_TYPE_NONE>; /* termcount */
+        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */
+      };
+    };
diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index 44919d48d241..e439949d49e6 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -5,7 +5,7 @@ the GPMC controller with a name of "nand".
 
 All timing relevant properties as well as generic gpmc child properties are
 explained in a separate documents - please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
+Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
 
 For NAND specific properties such as ECC modes or bus width, please refer to
 Documentation/devicetree/bindings/mtd/nand-controller.yaml
diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
index c8567b40fe13..c9bea106ea65 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
@@ -5,7 +5,7 @@ child nodes of the GPMC controller with a name of "nor".
 
 All timing relevant properties as well as generic GPMC child properties are
 explained in a separate documents. Please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
+Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
 
 Required properties:
 - bank-width: 		Width of NOR flash in bytes. GPMC supports 8-bit and
@@ -28,7 +28,7 @@ Required properties:
 
 Optional properties:
 - gpmc,XXX		Additional GPMC timings and settings parameters. See
-			Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
+			Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
 
 Optional properties for partition table parsing:
 - #address-cells: should be set to 1
diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
index e9f01a963a0a..0da78cc4ccca 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
@@ -5,7 +5,7 @@ the GPMC controller with a name of "onenand".
 
 All timing relevant properties as well as generic gpmc child properties are
 explained in a separate documents - please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
+Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
 
 Required properties:
 
diff --git a/Documentation/devicetree/bindings/net/gpmc-eth.txt b/Documentation/devicetree/bindings/net/gpmc-eth.txt
index 32821066a85b..5e2f610455fa 100644
--- a/Documentation/devicetree/bindings/net/gpmc-eth.txt
+++ b/Documentation/devicetree/bindings/net/gpmc-eth.txt
@@ -9,7 +9,7 @@ the GPMC controller with an "ethernet" name.
 
 All timing relevant properties as well as generic GPMC child properties are
 explained in a separate documents. Please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
+Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
 
 For the properties relevant to the ethernet controller connected to the GPMC
 refer to the binding documentation of the device. For example, the documentation
@@ -43,7 +43,7 @@ Required properties:
 
 Optional properties:
 - gpmc,XXX		Additional GPMC timings and settings parameters. See
-			Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
+			Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
 
 Example:
 
-- 
2.17.1



From rogerq at kernel.org  Thu Sep  2 02:56:06 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  2 Sep 2021 12:56:06 +0300
Subject: [PATCH v2 3/6] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <20210902095609.16583-1-rogerq@kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
Message-ID: <20210902095609.16583-4-rogerq@kernel.org>

Convert gpmc-nand.txt to ti,gpmc-nand.yaml.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 ------------------
 .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 109 +++++++++++++
 2 files changed, 109 insertions(+), 147 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
deleted file mode 100644
index e439949d49e6..000000000000
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-Device tree bindings for GPMC connected NANDs
-
-GPMC connected NAND (found on OMAP boards) are represented as child nodes of
-the GPMC controller with a name of "nand".
-
-All timing relevant properties as well as generic gpmc child properties are
-explained in a separate documents - please refer to
-Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
-
-For NAND specific properties such as ECC modes or bus width, please refer to
-Documentation/devicetree/bindings/mtd/nand-controller.yaml
-
-
-Required properties:
-
- - compatible:	"ti,omap2-nand"
- - reg:		range id (CS number), base offset and length of the
-		NAND I/O space
- - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
-
-Optional properties:
-
- - nand-bus-width: 		Set this numeric value to 16 if the hardware
-				is wired that way. If not specified, a bus
-				width of 8 is assumed.
-
- - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
-		"sw"		1-bit Hamming ecc code via software
-		"hw"		<deprecated> use "ham1" instead
-		"hw-romcode"	<deprecated> use "ham1" instead
-		"ham1"		1-bit Hamming ecc code
-		"bch4"		4-bit BCH ecc code
-		"bch8"		8-bit BCH ecc code
-		"bch16"		16-bit BCH ECC code
-		Refer below "How to select correct ECC scheme for your device ?"
-
- - ti,nand-xfer-type:		A string setting the data transfer type. One of:
-
-		"prefetch-polled"	Prefetch polled mode (default)
-		"polled"		Polled mode, without prefetch
-		"prefetch-dma"		Prefetch enabled DMA mode
-		"prefetch-irq"		Prefetch enabled irq mode
-
- - elm_id:	<deprecated> use "ti,elm-id" instead
- - ti,elm-id:	Specifies phandle of the ELM devicetree node.
-		ELM is an on-chip hardware engine on TI SoC which is used for
-		locating ECC errors for BCHx algorithms. SoC devices which have
-		ELM hardware engines should specify this device node in .dtsi
-		Using ELM for ECC error correction frees some CPU cycles.
- - rb-gpios:	GPIO specifier for the ready/busy# pin.
-
-For inline partition table parsing (optional):
-
- - #address-cells: should be set to 1
- - #size-cells: should be set to 1
-
-Example for an AM33xx board:
-
-	gpmc: gpmc at 50000000 {
-		compatible = "ti,am3352-gpmc";
-		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x36c>;
-		interrupts = <100>;
-		gpmc,num-cs = <8>;
-		gpmc,num-waitpins = <2>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
-		elm_id = <&elm>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-
-		nand at 0,0 {
-			compatible = "ti,omap2-nand";
-			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
-			interrupt-parent = <&gpmc>;
-			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
-			nand-bus-width = <16>;
-			ti,nand-ecc-opt = "bch8";
-			ti,nand-xfer-type = "polled";
-			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
-
-			gpmc,sync-clk-ps = <0>;
-			gpmc,cs-on-ns = <0>;
-			gpmc,cs-rd-off-ns = <44>;
-			gpmc,cs-wr-off-ns = <44>;
-			gpmc,adv-on-ns = <6>;
-			gpmc,adv-rd-off-ns = <34>;
-			gpmc,adv-wr-off-ns = <44>;
-			gpmc,we-off-ns = <40>;
-			gpmc,oe-off-ns = <54>;
-			gpmc,access-ns = <64>;
-			gpmc,rd-cycle-ns = <82>;
-			gpmc,wr-cycle-ns = <82>;
-			gpmc,wr-access-ns = <40>;
-			gpmc,wr-data-mux-bus-ns = <0>;
-
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			/* partitions go here */
-		};
-	};
-
-How to select correct ECC scheme for your device ?
---------------------------------------------------
-Higher ECC scheme usually means better protection against bit-flips and
-increased system lifetime. However, selection of ECC scheme is dependent
-on various other factors also like;
-
-(1) support of built in hardware engines.
-	Some legacy OMAP SoC do not have ELM harware engine, so those SoC cannot
-	support ecc-schemes with hardware error-correction (BCHx_HW). However
-	such SoC can use ecc-schemes with software library for error-correction
-	(BCHx_HW_DETECTION_SW). The error correction capability with software
-	library remains equivalent to their hardware counter-part, but there is
-	slight CPU penalty when too many bit-flips are detected during reads.
-
-(2) Device parameters like OOBSIZE.
-	Other factor which governs the selection of ecc-scheme is oob-size.
-	Higher ECC schemes require more OOB/Spare area to store ECC syndrome,
-	so the device should have enough free bytes available its OOB/Spare
-	area to accommodate ECC for entire page. In general following expression
-	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
-	where
-		OOBSIZE		number of bytes in OOB/spare area
-		PAGESIZE	number of bytes in main-area of device page
-		ECC_BYTES	number of ECC bytes generated to protect
-		                512 bytes of data, which is:
-				'3' for HAM1_xx ecc schemes
-				'7' for BCH4_xx ecc schemes
-				'14' for BCH8_xx ecc schemes
-				'26' for BCH16_xx ecc schemes
-
-	Example(a): For a device with PAGESIZE = 2048 and OOBSIZE = 64 and
-		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
-		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
-		which is greater than capacity of NAND device (OOBSIZE=64)
-		Hence, BCH16 cannot be supported on given device. But it can
-		probably use lower ecc-schemes like BCH8.
-
-	Example(b): For a device with PAGESIZE = 2048 and OOBSIZE = 128 and
-		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
-		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
-		which can be accommodated in the OOB/Spare area of this device
-		(OOBSIZE=128). So this device can use BCH16 ecc-scheme.
diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
new file mode 100644
index 000000000000..31a0c673b0e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/ti,gpmc-nand.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments GPMC NAND Flash controller.
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+  GPMC NAND controller/Flash is represented as a child of the
+  GPMC controller node.
+
+  All GPMC timing relevant properties and generic GPMC child properties
+  are explained in
+  Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
+
+  For NAND specific properties such as ECC modes, bus width, RB GPIO, etc,
+  please refer to
+  Documentation/devicetree/bindings/mtd/nand-controller.yaml
+
+properties:
+  compatible:
+    const: ti,omap2-nand
+
+  reg:
+    items:
+      - description:
+          Chip Select number, register offset and size of
+          NAND register window.
+
+  interrupts:
+    items:
+      - description: Interrupt for fifoevent
+      - description: Interrupt for termcount
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ti,nand-ecc-opt:
+    description: Desired ECC algorithm
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [sw, ham1, bch4, bch8, bch16]
+
+  ti,nand-xfer-type:
+    description: Data transfer method between controller and chip.
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [prefetch-polled, polled, prefetch-dma, prefetch-irq]
+
+  ti,elm-id:
+    description:
+      phandle to the ELM (Error Location Module).
+    $ref: /schemas/types.yaml#/definitions/phandle
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: true
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    gpmc: memory-controller at 50000000 {
+      compatible = "ti,am3352-gpmc";
+      dmas = <&edma 52 0>;
+      dma-names = "rxtx";
+      clocks = <&l3s_gclk>;
+      clock-names = "fck";
+      reg = <0x50000000 0x2000>;
+      interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+      gpmc,num-cs = <7>;
+      gpmc,num-waitpins = <2>;
+      #address-cells = <2>;
+      #size-cells = <1>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      gpio-controller;
+      #gpio-cells = <2>;
+
+      ranges = <0 0 0x08000000 0x01000000>;   /* CS0 space. Min partition = 16MB */
+      nand at 0,0 {
+        compatible = "ti,omap2-nand";
+        reg = <0 0 4>;          /* device IO registers */
+        interrupt-parent = <&gpmc>;
+        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+                     <1 IRQ_TYPE_NONE>; /* termcount */
+        ti,nand-xfer-type = "prefetch-dma";
+        ti,nand-ecc-opt = "bch16";
+        ti,elm-id = <&elm>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        /* NAND generic properties */
+        nand-bus-width = <8>;
+        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>;  /* gpmc_wait0 */
+
+        /* GPMC properties*/
+        gpmc,device-width = <1>;
+      };
+    };
-- 
2.17.1



From rogerq at kernel.org  Thu Sep  2 02:56:07 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  2 Sep 2021 12:56:07 +0300
Subject: [PATCH v2 4/6] dt-bindings: mtd: ti,gpmc-onenand: Convert to yaml
In-Reply-To: <20210902095609.16583-1-rogerq@kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
Message-ID: <20210902095609.16583-5-rogerq@kernel.org>

Convert gpmc-onenand.txt to ti,gpmc-onenand.yaml.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/mtd/gpmc-onenand.txt  | 48 -------------
 .../bindings/mtd/ti,gpmc-onenand.yaml         | 71 +++++++++++++++++++
 2 files changed, 71 insertions(+), 48 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
deleted file mode 100644
index 0da78cc4ccca..000000000000
--- a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-Device tree bindings for GPMC connected OneNANDs
-
-GPMC connected OneNAND (found on OMAP boards) are represented as child nodes of
-the GPMC controller with a name of "onenand".
-
-All timing relevant properties as well as generic gpmc child properties are
-explained in a separate documents - please refer to
-Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
-
-Required properties:
-
- - compatible:		"ti,omap2-onenand"
- - reg:			The CS line the peripheral is connected to
- - gpmc,device-width:	Width of the ONENAND device connected to the GPMC
-			in bytes. Must be 1 or 2.
-
-Optional properties:
-
- - int-gpios:		GPIO specifier for the INT pin.
-
-For inline partition table parsing (optional):
-
- - #address-cells: should be set to 1
- - #size-cells: should be set to 1
-
-Example for an OMAP3430 board:
-
-	gpmc: gpmc at 6e000000 {
-		compatible = "ti,omap3430-gpmc";
-		ti,hwmods = "gpmc";
-		reg = <0x6e000000 0x1000000>;
-		interrupts = <20>;
-		gpmc,num-cs = <8>;
-		gpmc,num-waitpins = <4>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-
-		onenand at 0 {
-			compatible = "ti,omap2-onenand";
-			reg = <0 0 0>; /* CS0, offset 0 */
-			gpmc,device-width = <2>;
-
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			/* partitions go here */
-		};
-	};
diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
new file mode 100644
index 000000000000..5b0d2b549919
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/ti,gpmc-onenand.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: OneNAND over Texas Instruments GPMC bus.
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+
+  GPMC connected OneNAND (found on OMAP boards) are represented
+  as child nodes of the GPMC controller.
+
+  All timing relevant properties as well as generic gpmc child properties are
+  explained in
+  Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
+
+properties:
+  compatible:
+    const: ti,omap2-onenand
+
+  reg:
+    items:
+      - description: |
+          Chip Select number, register offset and size of
+          OneNAND register window.
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  int-gpios:
+    description: GPIO specifier for the INT pin.
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties: true
+
+examples:
+  - |
+    gpmc: memory-controller at 6e000000 {
+      compatible = "ti,omap3430-gpmc";
+      reg = <0x6e000000 0x02d0>;
+      interrupts = <20>;
+      gpmc,num-cs = <8>;
+      gpmc,num-waitpins = <4>;
+      clocks = <&l3s_clkctrl>;
+      clock-names = "fck";
+      #address-cells = <2>;
+      #size-cells = <1>;
+
+      ranges = <0 0 0x01000000 0x01000000>,   /* 16 MB for OneNAND */
+               <1 0 0x02000000 0x01000000>;   /* 16 MB for smc91c96 */
+
+      onenand at 0,0 {
+        compatible = "ti,omap2-onenand";
+        reg = <0 0 0x20000>;    /* CS0, offset 0, IO size 128K */
+        #address-cells = <1>;
+        #size-cells = <1>;
+      };
+    };
-- 
2.17.1



From rogerq at kernel.org  Thu Sep  2 02:56:08 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  2 Sep 2021 12:56:08 +0300
Subject: [PATCH v2 5/6] dt-bindings: mtd: Remove gpmc-nor.txt
In-Reply-To: <20210902095609.16583-1-rogerq@kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
Message-ID: <20210902095609.16583-6-rogerq@kernel.org>

There is no GPMC NOR compatible or device driver. GPMC is just
a bus interface over which standard (CFI/JEDC) NOR Flash chips
can be attached.

For NOR chip bindings, please refer to
Documentation/devicetree/bindings/mtd/mtd-physmap.yaml

For GPMC bus timing configuration, please refer to
Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/mtd/gpmc-nor.txt      | 98 -------------------
 1 file changed, 98 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
deleted file mode 100644
index c9bea106ea65..000000000000
--- a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-Device tree bindings for NOR flash connect to TI GPMC
-
-NOR flash connected to the TI GPMC (found on OMAP boards) are represented as
-child nodes of the GPMC controller with a name of "nor".
-
-All timing relevant properties as well as generic GPMC child properties are
-explained in a separate documents. Please refer to
-Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
-
-Required properties:
-- bank-width: 		Width of NOR flash in bytes. GPMC supports 8-bit and
-			16-bit devices and so must be either 1 or 2 bytes.
-- compatible:		Documentation/devicetree/bindings/mtd/mtd-physmap.txt
-- gpmc,cs-on-ns:		Chip-select assertion time
-- gpmc,cs-rd-off-ns:	Chip-select de-assertion time for reads
-- gpmc,cs-wr-off-ns:	Chip-select de-assertion time for writes
-- gpmc,oe-on-ns:	Output-enable assertion time
-- gpmc,oe-off-ns:	Output-enable de-assertion time
-- gpmc,we-on-ns		Write-enable assertion time
-- gpmc,we-off-ns:	Write-enable de-assertion time
-- gpmc,access-ns:	Start cycle to first data capture (read access)
-- gpmc,rd-cycle-ns:	Total read cycle time
-- gpmc,wr-cycle-ns:	Total write cycle time
-- linux,mtd-name:	Documentation/devicetree/bindings/mtd/mtd-physmap.txt
-- reg:			Chip-select, base address (relative to chip-select)
-			and size of NOR flash. Note that base address will be
-			typically 0 as this is the start of the chip-select.
-
-Optional properties:
-- gpmc,XXX		Additional GPMC timings and settings parameters. See
-			Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
-
-Optional properties for partition table parsing:
-- #address-cells: should be set to 1
-- #size-cells: should be set to 1
-
-Example:
-
-gpmc: gpmc at 6e000000 {
-	compatible = "ti,omap3430-gpmc", "simple-bus";
-	ti,hwmods = "gpmc";
-	reg = <0x6e000000 0x1000>;
-	interrupts = <20>;
-	gpmc,num-cs = <8>;
-	gpmc,num-waitpins = <4>;
-	#address-cells = <2>;
-	#size-cells = <1>;
-
-	ranges = <0 0 0x10000000 0x08000000>;
-
-	nor at 0,0 {
-		compatible = "cfi-flash";
-		linux,mtd-name= "intel,pf48f6000m0y1be";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		reg = <0 0 0x08000000>;
-		bank-width = <2>;
-
-		gpmc,mux-add-data;
-		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <186>;
-		gpmc,cs-wr-off-ns = <186>;
-		gpmc,adv-on-ns = <12>;
-		gpmc,adv-rd-off-ns = <48>;
-		gpmc,adv-wr-off-ns = <48>;
-		gpmc,oe-on-ns = <54>;
-		gpmc,oe-off-ns = <168>;
-		gpmc,we-on-ns = <54>;
-		gpmc,we-off-ns = <168>;
-		gpmc,rd-cycle-ns = <186>;
-		gpmc,wr-cycle-ns = <186>;
-		gpmc,access-ns = <114>;
-		gpmc,page-burst-access-ns = <6>;
-		gpmc,bus-turnaround-ns = <12>;
-		gpmc,cycle2cycle-delay-ns = <18>;
-		gpmc,wr-data-mux-bus-ns = <90>;
-		gpmc,wr-access-ns = <186>;
-		gpmc,cycle2cycle-samecsen;
-		gpmc,cycle2cycle-diffcsen;
-
-		partition at 0 {
-			label = "bootloader-nor";
-			reg = <0 0x40000>;
-		};
-		partition at 40000 {
-			label = "params-nor";
-			reg = <0x40000 0x40000>;
-		};
-		partition at 80000 {
-			label = "kernel-nor";
-			reg = <0x80000 0x200000>;
-		};
-		partition at 280000 {
-			label = "filesystem-nor";
-			reg = <0x240000 0x7d80000>;
-		};
-	};
-};
-- 
2.17.1



From rogerq at kernel.org  Thu Sep  2 02:56:09 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Thu,  2 Sep 2021 12:56:09 +0300
Subject: [PATCH v2 6/6] dt-bindings: net: Remove gpmc-eth.txt
In-Reply-To: <20210902095609.16583-1-rogerq@kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
Message-ID: <20210902095609.16583-7-rogerq@kernel.org>

There is no GPMC Ethernet compatible or device driver. GPMC is
just a bus interface over which devices like Ethernet controller
can be to.

For SMSC 911x Ethernet chip bindings, please refer to
Documentation/devicetree/bindings/net/smsc,lan9115.yaml

For GPMC bus timing configuration, please refer to
Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/net/gpmc-eth.txt      | 97 -------------------
 1 file changed, 97 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt

diff --git a/Documentation/devicetree/bindings/net/gpmc-eth.txt b/Documentation/devicetree/bindings/net/gpmc-eth.txt
deleted file mode 100644
index 5e2f610455fa..000000000000
--- a/Documentation/devicetree/bindings/net/gpmc-eth.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-Device tree bindings for Ethernet chip connected to TI GPMC
-
-Besides being used to interface with external memory devices, the
-General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices
-such as ethernet controllers to processors using the TI GPMC as a data bus.
-
-Ethernet controllers connected to TI GPMC are represented as child nodes of
-the GPMC controller with an "ethernet" name.
-
-All timing relevant properties as well as generic GPMC child properties are
-explained in a separate documents. Please refer to
-Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
-
-For the properties relevant to the ethernet controller connected to the GPMC
-refer to the binding documentation of the device. For example, the documentation
-for the SMSC 911x is Documentation/devicetree/bindings/net/smsc,lan9115.yaml
-
-Child nodes need to specify the GPMC bus address width using the "bank-width"
-property but is possible that an ethernet controller also has a property to
-specify the I/O registers address width. Even when the GPMC has a maximum 16-bit
-address width, it supports devices with 32-bit word registers.
-For example with an SMSC LAN911x/912x controller connected to the TI GPMC on an
-OMAP2+ board, "bank-width = <2>;" and "reg-io-width = <4>;".
-
-Required properties:
-- bank-width: 		Address width of the device in bytes. GPMC supports 8-bit
-			and 16-bit devices and so must be either 1 or 2 bytes.
-- compatible:		Compatible string property for the ethernet child device.
-- gpmc,cs-on-ns:	Chip-select assertion time
-- gpmc,cs-rd-off-ns:	Chip-select de-assertion time for reads
-- gpmc,cs-wr-off-ns:	Chip-select de-assertion time for writes
-- gpmc,oe-on-ns:	Output-enable assertion time
-- gpmc,oe-off-ns:	Output-enable de-assertion time
-- gpmc,we-on-ns:	Write-enable assertion time
-- gpmc,we-off-ns:	Write-enable de-assertion time
-- gpmc,access-ns:	Start cycle to first data capture (read access)
-- gpmc,rd-cycle-ns:	Total read cycle time
-- gpmc,wr-cycle-ns:	Total write cycle time
-- reg:			Chip-select, base address (relative to chip-select)
-			and size of the memory mapped for the device.
-			Note that base address will be typically 0 as this
-			is the start of the chip-select.
-
-Optional properties:
-- gpmc,XXX		Additional GPMC timings and settings parameters. See
-			Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
-
-Example:
-
-gpmc: gpmc at 6e000000 {
-	compatible = "ti,omap3430-gpmc";
-	ti,hwmods = "gpmc";
-	reg = <0x6e000000 0x1000>;
-	interrupts = <20>;
-	gpmc,num-cs = <8>;
-	gpmc,num-waitpins = <4>;
-	#address-cells = <2>;
-	#size-cells = <1>;
-
-	ranges = <5 0 0x2c000000 0x1000000>;
-
-	ethernet at 5,0 {
-		compatible = "smsc,lan9221", "smsc,lan9115";
-		reg = <5 0 0xff>;
-		bank-width = <2>;
-
-		gpmc,mux-add-data;
-		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <186>;
-		gpmc,cs-wr-off-ns = <186>;
-		gpmc,adv-on-ns = <12>;
-		gpmc,adv-rd-off-ns = <48>;
-		gpmc,adv-wr-off-ns = <48>;
-		gpmc,oe-on-ns = <54>;
-		gpmc,oe-off-ns = <168>;
-		gpmc,we-on-ns = <54>;
-		gpmc,we-off-ns = <168>;
-		gpmc,rd-cycle-ns = <186>;
-		gpmc,wr-cycle-ns = <186>;
-		gpmc,access-ns = <114>;
-		gpmc,page-burst-access-ns = <6>;
-		gpmc,bus-turnaround-ns = <12>;
-		gpmc,cycle2cycle-delay-ns = <18>;
-		gpmc,wr-data-mux-bus-ns = <90>;
-		gpmc,wr-access-ns = <186>;
-		gpmc,cycle2cycle-samecsen;
-		gpmc,cycle2cycle-diffcsen;
-
-		interrupt-parent = <&gpio6>;
-		interrupts = <16>;
-		vmmc-supply = <&vddvario>;
-		vmmc_aux-supply = <&vdd33a>;
-		reg-io-width = <4>;
-
-		smsc,save-mac-address;
-	};
-};
-- 
2.17.1



From robh at kernel.org  Thu Sep  2 05:03:59 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 02 Sep 2021 07:03:59 -0500
Subject: [PATCH v2 2/6] dt-bindings: memory-controllers: ti,
 gpmc: Convert to yaml
In-Reply-To: <20210902095609.16583-3-rogerq@kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
 <20210902095609.16583-3-rogerq@kernel.org>
Message-ID: <1630584239.117607.685604.nullmailer@robh.at.kernel.org>

On Thu, 02 Sep 2021 12:56:05 +0300, Roger Quadros wrote:
> Convert omap-gpmc.txt to ti,gpmc.yaml.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../bindings/memory-controllers/omap-gpmc.txt | 157 --------
>  .../bindings/memory-controllers/ti,gpmc.yaml  | 364 ++++++++++++++++++
>  .../devicetree/bindings/mtd/gpmc-nand.txt     |   2 +-
>  .../devicetree/bindings/mtd/gpmc-nor.txt      |   4 +-
>  .../devicetree/bindings/mtd/gpmc-onenand.txt  |   2 +-
>  .../devicetree/bindings/net/gpmc-eth.txt      |   4 +-
>  6 files changed, 370 insertions(+), 163 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/memory-controllers/ti,gpmc.example.dt.yaml:0:0: /example-0/memory-controller at 50000000/nand at 0,0: failed to match any schema with compatible: ['ti,omap2-nand']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1523568

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From rogerq at kernel.org  Thu Sep  2 07:21:41 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Thu, 2 Sep 2021 17:21:41 +0300
Subject: [PATCH v2 2/6] dt-bindings: memory-controllers: ti, gpmc: Convert
 to yaml
In-Reply-To: <1630584239.117607.685604.nullmailer@robh.at.kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
 <20210902095609.16583-3-rogerq@kernel.org>
 <1630584239.117607.685604.nullmailer@robh.at.kernel.org>
Message-ID: <d6b5a2b3-6a29-0c5d-cbe5-eda9b07b2c65@kernel.org>

Hi Rob,

On 02/09/2021 15:03, Rob Herring wrote:
> On Thu, 02 Sep 2021 12:56:05 +0300, Roger Quadros wrote:
>> Convert omap-gpmc.txt to ti,gpmc.yaml.
>>
>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>> ---
>>  .../bindings/memory-controllers/omap-gpmc.txt | 157 --------
>>  .../bindings/memory-controllers/ti,gpmc.yaml  | 364 ++++++++++++++++++
>>  .../devicetree/bindings/mtd/gpmc-nand.txt     |   2 +-
>>  .../devicetree/bindings/mtd/gpmc-nor.txt      |   4 +-
>>  .../devicetree/bindings/mtd/gpmc-onenand.txt  |   2 +-
>>  .../devicetree/bindings/net/gpmc-eth.txt      |   4 +-
>>  6 files changed, 370 insertions(+), 163 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>>
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/memory-controllers/ti,gpmc.example.dt.yaml:0:0: /example-0/memory-controller at 50000000/nand at 0,0: failed to match any schema with compatible: ['ti,omap2-nand']

'ti,omap2-nand' compatible is being added in patch 3 of this series.
So the error will go away there.

cheers,
-roger

> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.ozlabs.org/patch/1523568
> 
> This check can fail if there are any dependencies. The base for a patch
> series is generally the most recent rc1.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.
> 


From rafael at kernel.org  Thu Sep  2 09:28:14 2021
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 2 Sep 2021 18:28:14 +0200
Subject: [PATCH] PM / suspend: move userspace freeze before disk sync
In-Reply-To: <20210901083442.210230-1-sean@geanix.com>
References: <20210901083442.210230-1-sean@geanix.com>
Message-ID: <CAJZ5v0j5dMDSDjhuXaZd=_J5JOP4Z09WUXfjWX_iCcT4RDisCg@mail.gmail.com>

On Wed, Sep 1, 2021 at 10:35 AM Sean Nyekjaer <sean at geanix.com> wrote:
>
> This fixes an issue where data remains unwritten before suspend.

Well, it doesn't make the issue go away, it just hides it for you and
it may very well expose it for someone else.

In particular, note that you can compile the kernel with
CONFIG_SUSPEND_SKIP_SYNC set which makes it not sync at all during
system-wide suspend and this is a valid case expected to work.  It
looks like this case doesn't work for you.

> UBI tried to write data, before the mtd device had been unsuspended.

Well, that's the real problem and it can happen regardless of whether
or not this patch is there.

> Seen on an iMX6ULL board fitted with rawnand flash.
>
> Before:
> PM: suspend entry (deep)
> Filesystems sync: 0.088 seconds
> Freezing user space processes ... (elapsed 0.000 seconds) done.
> OOM killer disabled.
> Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
> printk: Suspending console(s) (use no_console_suspend to debug)
> PM: suspend devices took 0.030 seconds
> Disabling non-boot CPUs ...
> ubi0 error: ubi_io_write: error -16 while writing 4096 bytes to PEB 1762:94208, written 0 bytes
>
> After:
> PM: suspend entry (deep)
> Freezing user space processes ... (elapsed 0.001 seconds) done.
> OOM killer disabled.
> Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
> Filesystems sync: 0.060 seconds
> printk: Suspending console(s) (use no_console_suspend to debug)
> PM: suspend devices took 0.040 seconds
> Disabling non-boot CPUs ...
> PM: resume devices took 0.100 seconds
>
> Signed-off-by: Sean Nyekjaer <sean at geanix.com>
> ---
>
> Some explanation/discussion here:
> http://lists.infradead.org/pipermail/linux-mtd/2021-July/087390.html
>
>  kernel/power/suspend.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
> index 87331565e505..4ee3fcbb0e7a 100644
> --- a/kernel/power/suspend.c
> +++ b/kernel/power/suspend.c
> @@ -562,6 +562,12 @@ static int enter_state(suspend_state_t state)
>         if (state == PM_SUSPEND_TO_IDLE)
>                 s2idle_begin();
>
> +       pm_pr_dbg("Preparing system for sleep (%s)\n", mem_sleep_labels[state]);
> +       pm_suspend_clear_flags();
> +       error = suspend_prepare(state);
> +       if (error)
> +               goto Unlock;
> +
>  #ifndef CONFIG_SUSPEND_SKIP_SYNC
>         trace_suspend_resume(TPS("sync_filesystems"), 0, true);
>         pr_info("Syncing filesystems ... ");
> @@ -570,12 +576,6 @@ static int enter_state(suspend_state_t state)
>         trace_suspend_resume(TPS("sync_filesystems"), 0, false);
>  #endif
>
> -       pm_pr_dbg("Preparing system for sleep (%s)\n", mem_sleep_labels[state]);
> -       pm_suspend_clear_flags();
> -       error = suspend_prepare(state);
> -       if (error)
> -               goto Unlock;
> -
>         if (suspend_test(TEST_FREEZER))
>                 goto Finish;
>
> --
> 2.33.0
>


From mcgrof at kernel.org  Thu Sep  2 10:41:00 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Thu,  2 Sep 2021 10:41:00 -0700
Subject: [PATCH 4/9] rbd: add add_disk() error handling
In-Reply-To: <20210902174105.2418771-1-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
Message-ID: <20210902174105.2418771-5-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/rbd.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index e65c9d706f6f..341e5da6d029 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -7054,7 +7054,9 @@ static ssize_t do_rbd_add(struct bus_type *bus,
 	if (rc)
 		goto err_out_image_lock;
 
-	device_add_disk(&rbd_dev->dev, rbd_dev->disk, NULL);
+	rc = device_add_disk(&rbd_dev->dev, rbd_dev->disk, NULL);
+	if (rc)
+		goto err_out_cleanup_disk;
 
 	spin_lock(&rbd_dev_list_lock);
 	list_add_tail(&rbd_dev->node, &rbd_dev_list);
@@ -7068,6 +7070,8 @@ static ssize_t do_rbd_add(struct bus_type *bus,
 	module_put(THIS_MODULE);
 	return rc;
 
+err_out_cleanup_disk:
+	rbd_free_disk(rbd_dev);
 err_out_image_lock:
 	rbd_dev_image_unlock(rbd_dev);
 	rbd_dev_device_release(rbd_dev);
-- 
2.30.2



From mcgrof at kernel.org  Thu Sep  2 10:40:56 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Thu,  2 Sep 2021 10:40:56 -0700
Subject: [PATCH 0/9] block: 5th batch of add_disk() error handling conversions
Message-ID: <20210902174105.2418771-1-mcgrof@kernel.org>

This is the 5th of 7 set of driver conversion over to use the new
add_disk() error handling. Please let me know if you spot
any issues. This set deals with miscellaneous block drivers.

This patch set is based on axboe/master, you can find the
full set of changes on my 20210901-for-axboe-add-disk-error-handling
branch [0].

It would seem there are going to be a total of 7 sets of patches. The
next one will be the wonderful and exciting world of floppy drivers.
The last is the required changes to add a __must_check for the return
value for the caller.

[0] https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/log/?h=20210901-for-axboe-add-disk-error-handling

Luis Chamberlain (9):
  cdrom/gdrom: add error handling support for add_disk()
  ms_block: add error handling support for add_disk()
  mspro_block: add error handling support for add_disk()
  rbd: add add_disk() error handling
  mtd: add add_disk() error handling
  s390/block/dasd_genhd: add error handling support for add_disk()
  s390/block/dcssblk: add error handling support for add_disk()
  s390/block/scm_blk: add error handling support for add_disk()
  s390/block/xpram: add error handling support for add_disk()

 drivers/block/rbd.c                 | 6 +++++-
 drivers/cdrom/gdrom.c               | 7 ++++++-
 drivers/memstick/core/ms_block.c    | 6 +++++-
 drivers/memstick/core/mspro_block.c | 6 +++++-
 drivers/mtd/mtd_blkdevs.c           | 6 +++++-
 drivers/s390/block/dasd_genhd.c     | 8 ++++++--
 drivers/s390/block/dcssblk.c        | 4 +++-
 drivers/s390/block/scm_blk.c        | 7 ++++++-
 drivers/s390/block/xpram.c          | 4 +++-
 9 files changed, 44 insertions(+), 10 deletions(-)

-- 
2.30.2



From mcgrof at kernel.org  Thu Sep  2 10:40:59 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Thu,  2 Sep 2021 10:40:59 -0700
Subject: [PATCH 3/9] mspro_block: add error handling support for add_disk()
In-Reply-To: <20210902174105.2418771-1-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
Message-ID: <20210902174105.2418771-4-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Contrary to the typical removal which delays the put_disk()
until later, since we are failing on a probe we immediately
put the disk on failure from add_disk by using
blk_cleanup_disk().

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/memstick/core/mspro_block.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index 22778d0e24f5..c0450397b673 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -1239,10 +1239,14 @@ static int mspro_block_init_disk(struct memstick_dev *card)
 	set_capacity(msb->disk, capacity);
 	dev_dbg(&card->dev, "capacity set %ld\n", capacity);
 
-	device_add_disk(&card->dev, msb->disk, NULL);
+	rc = device_add_disk(&card->dev, msb->disk, NULL);
+	if (rc)
+		goto out_cleanup_disk;
 	msb->active = 1;
 	return 0;
 
+out_cleanup_disk:
+	blk_cleanup_disk(msb->disk);
 out_free_tag_set:
 	blk_mq_free_tag_set(&msb->tag_set);
 out_release_id:
-- 
2.30.2



From mcgrof at kernel.org  Thu Sep  2 10:41:01 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Thu,  2 Sep 2021 10:41:01 -0700
Subject: [PATCH 5/9] mtd: add add_disk() error handling
In-Reply-To: <20210902174105.2418771-1-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
Message-ID: <20210902174105.2418771-6-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/mtd/mtd_blkdevs.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 44bea3f65060..343ff96589cc 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -427,7 +427,9 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 	if (new->readonly)
 		set_disk_ro(gd, 1);
 
-	device_add_disk(&new->mtd->dev, gd, NULL);
+	ret = device_add_disk(&new->mtd->dev, gd, NULL);
+	if (ret)
+		goto out_cleanup_disk;
 
 	if (new->disk_attributes) {
 		ret = sysfs_create_group(&disk_to_dev(gd)->kobj,
@@ -436,6 +438,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 	}
 	return 0;
 
+out_cleanup_disk:
+	blk_cleanup_disk(new->disk);
 out_free_tag_set:
 	blk_mq_free_tag_set(new->tag_set);
 out_kfree_tag_set:
-- 
2.30.2



From mcgrof at kernel.org  Thu Sep  2 10:40:57 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Thu,  2 Sep 2021 10:40:57 -0700
Subject: [PATCH 1/9] cdrom/gdrom: add error handling support for add_disk()
In-Reply-To: <20210902174105.2418771-1-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
Message-ID: <20210902174105.2418771-2-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/cdrom/gdrom.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 8e1fe75af93f..d50cc1fd34d5 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -805,9 +805,14 @@ static int probe_gdrom(struct platform_device *devptr)
 		err = -ENOMEM;
 		goto probe_fail_free_irqs;
 	}
-	add_disk(gd.disk);
+	err = add_disk(gd.disk);
+	if (err)
+		goto probe_fail_add_disk;
+
 	return 0;
 
+probe_fail_add_disk:
+	kfree(gd.toc);
 probe_fail_free_irqs:
 	free_irq(HW_EVENT_GDROM_DMA, &gd);
 	free_irq(HW_EVENT_GDROM_CMD, &gd);
-- 
2.30.2



From mcgrof at kernel.org  Thu Sep  2 10:41:02 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Thu,  2 Sep 2021 10:41:02 -0700
Subject: [PATCH 6/9] s390/block/dasd_genhd: add error handling support for
 add_disk()
In-Reply-To: <20210902174105.2418771-1-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
Message-ID: <20210902174105.2418771-7-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/s390/block/dasd_genhd.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index fa966e0db6ca..ba07022283bc 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -33,7 +33,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
 {
 	struct gendisk *gdp;
 	struct dasd_device *base;
-	int len;
+	int len, rc;
 
 	/* Make sure the minor for this device exists. */
 	base = block->base;
@@ -79,7 +79,11 @@ int dasd_gendisk_alloc(struct dasd_block *block)
 	dasd_add_link_to_gendisk(gdp, base);
 	block->gdp = gdp;
 	set_capacity(block->gdp, 0);
-	device_add_disk(&base->cdev->dev, block->gdp, NULL);
+
+	rc = device_add_disk(&base->cdev->dev, block->gdp, NULL);
+	if (rc)
+		return rc;
+
 	return 0;
 }
 
-- 
2.30.2



From mcgrof at kernel.org  Thu Sep  2 10:40:58 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Thu,  2 Sep 2021 10:40:58 -0700
Subject: [PATCH 2/9] ms_block: add error handling support for add_disk()
In-Reply-To: <20210902174105.2418771-1-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
Message-ID: <20210902174105.2418771-3-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Contrary to the typical removal which delays the put_disk()
until later, since we are failing on a probe we immediately
put the disk on failure from add_disk by using
blk_cleanup_disk().

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/memstick/core/ms_block.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c
index 4a4573fa7b0f..86c626933c1a 100644
--- a/drivers/memstick/core/ms_block.c
+++ b/drivers/memstick/core/ms_block.c
@@ -2156,10 +2156,14 @@ static int msb_init_disk(struct memstick_dev *card)
 		set_disk_ro(msb->disk, 1);
 
 	msb_start(card);
-	device_add_disk(&card->dev, msb->disk, NULL);
+	rc = device_add_disk(&card->dev, msb->disk, NULL);
+	if (rc)
+		goto out_cleanup_disk;
 	dbg("Disk added");
 	return 0;
 
+out_cleanup_disk:
+	blk_cleanup_disk(msb->disk);
 out_free_tag_set:
 	blk_mq_free_tag_set(&msb->tag_set);
 out_release_id:
-- 
2.30.2



From mcgrof at kernel.org  Thu Sep  2 10:41:05 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Thu,  2 Sep 2021 10:41:05 -0700
Subject: [PATCH 9/9] s390/block/xpram: add error handling support for
 add_disk()
In-Reply-To: <20210902174105.2418771-1-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
Message-ID: <20210902174105.2418771-10-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/s390/block/xpram.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index ce98fab4d43c..ed3904b6a9c8 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -371,7 +371,9 @@ static int __init xpram_setup_blkdev(void)
 		disk->private_data = &xpram_devices[i];
 		sprintf(disk->disk_name, "slram%d", i);
 		set_capacity(disk, xpram_sizes[i] << 1);
-		add_disk(disk);
+		rc = add_disk(disk);
+		if (rc)
+			goto out;
 	}
 
 	return 0;
-- 
2.30.2



From mcgrof at kernel.org  Thu Sep  2 10:41:04 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Thu,  2 Sep 2021 10:41:04 -0700
Subject: [PATCH 8/9] s390/block/scm_blk: add error handling support for
 add_disk()
In-Reply-To: <20210902174105.2418771-1-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
Message-ID: <20210902174105.2418771-9-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/s390/block/scm_blk.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c
index 88cba6212ee2..61ecdcb2cc6a 100644
--- a/drivers/s390/block/scm_blk.c
+++ b/drivers/s390/block/scm_blk.c
@@ -495,9 +495,14 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev)
 
 	/* 512 byte sectors */
 	set_capacity(bdev->gendisk, scmdev->size >> 9);
-	device_add_disk(&scmdev->dev, bdev->gendisk, NULL);
+	ret = device_add_disk(&scmdev->dev, bdev->gendisk, NULL);
+	if (ret)
+		goto out_cleanup_disk;
+
 	return 0;
 
+out_cleanup_disk:
+	blk_cleanup_disk(bdev->gendisk);
 out_tag:
 	blk_mq_free_tag_set(&bdev->tag_set);
 out:
-- 
2.30.2



From mcgrof at kernel.org  Thu Sep  2 10:41:03 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Thu,  2 Sep 2021 10:41:03 -0700
Subject: [PATCH 7/9] s390/block/dcssblk: add error handling support for
 add_disk()
In-Reply-To: <20210902174105.2418771-1-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
Message-ID: <20210902174105.2418771-8-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/s390/block/dcssblk.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 5be3d1c39a78..b0fd5009a12e 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -696,7 +696,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
 	}
 
 	get_device(&dev_info->dev);
-	device_add_disk(&dev_info->dev, dev_info->gd, NULL);
+	rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL);
+	if (rc)
+		goto put_dev;
 
 	switch (dev_info->segment_type) {
 		case SEG_TYPE_SR:
-- 
2.30.2



From miquel.raynal at bootlin.com  Thu Sep  2 12:09:17 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 2 Sep 2021 21:09:17 +0200
Subject: [PATCH 5/9] mtd: add add_disk() error handling
In-Reply-To: <20210902174105.2418771-6-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-6-mcgrof@kernel.org>
Message-ID: <20210902210917.54eb6e26@xps13>

Hi Luis,

Luis Chamberlain <mcgrof at kernel.org> wrote on Thu,  2 Sep 2021 10:41:01
-0700:

> We never checked for errors on add_disk() as this function
> returned void. Now that this is fixed, use the shiny new
> error handling.
> 
> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>

Acked-by: Miquel Raynal <miquel.raynal at bootlin.com>

Thanks,
Miqu?l


From robh at kernel.org  Thu Sep  2 12:56:56 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 2 Sep 2021 14:56:56 -0500
Subject: [PATCH v2 2/6] dt-bindings: memory-controllers: ti, gpmc: Convert
 to yaml
In-Reply-To: <20210902095609.16583-3-rogerq@kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
 <20210902095609.16583-3-rogerq@kernel.org>
Message-ID: <YTEsiJiLMRYon5s3@robh.at.kernel.org>

On Thu, Sep 02, 2021 at 12:56:05PM +0300, Roger Quadros wrote:
> Convert omap-gpmc.txt to ti,gpmc.yaml.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../bindings/memory-controllers/omap-gpmc.txt | 157 --------
>  .../bindings/memory-controllers/ti,gpmc.yaml  | 364 ++++++++++++++++++
>  .../devicetree/bindings/mtd/gpmc-nand.txt     |   2 +-
>  .../devicetree/bindings/mtd/gpmc-nor.txt      |   4 +-
>  .../devicetree/bindings/mtd/gpmc-onenand.txt  |   2 +-
>  .../devicetree/bindings/net/gpmc-eth.txt      |   4 +-
>  6 files changed, 370 insertions(+), 163 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml

> diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> new file mode 100644
> index 000000000000..b7d43370a95d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> @@ -0,0 +1,364 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/memory-controllers/ti,gpmc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Texas Instruments GPMC Memory Controller device-tree bindings
> +
> +maintainers:
> +  - Tony Lindgren <tony at atomide.com>
> +  - Roger Quadros <rogerq at kernel.org>
> +
> +description:
> +  The GPMC is a unified memory controller dedicated for interfacing
> +  with external memory devices like
> +  - Asynchronous SRAM-like memories and ASICs
> +  - Asynchronous, synchronous, and page mode burst NOR flash
> +  - NAND flash
> +  - Pseudo-SRAM devices
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - ti,omap2420-gpmc
> +          - ti,omap2430-gpmc
> +          - ti,omap3430-gpmc
> +          - ti,omap4430-gpmc
> +          - ti,am3352-gpmc
> +
> +  reg:
> +    items:
> +      - description:
> +          Configuration registers for the controller.

Just 'maxItems: 1' is sufficient.

> +
> +  interrupts: true

Need to define how many.

> +
> +  clocks:
> +    maxItems: 1
> +    description: |
> +      Functional clock. Used for bus timing calculations and
> +      GPMC configuration.
> +
> +  clock-names:
> +    items:
> +      - const: fck
> +
> +  dmas:
> +    items:
> +      - description: DMA channel for GPMC NAND prefetch
> +
> +  dma-names:
> +    items:
> +      - const: rxtx
> +
> +  "#address-cells":
> +    const: 2
> +
> +  "#size-cells":
> +    const: 1
> +
> +  gpmc,num-cs:
> +    description: maximum number of supported chip-select lines.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +
> +  gpmc,num-waitpins:
> +    description: maximum number of supported wait pins.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +
> +  ranges:
> +    minItems: 1
> +    description: |
> +      Must be set up to reflect the memory layout with four
> +      integer values for each chip-select line in use,
> +      <cs-number> 0 <physical address of mapping> <size>
> +
> +    items:
> +      - description: NAND bank 0
> +      - description: NOR/SRAM bank 0
> +      - description: NOR/SRAM bank 1
> +
> +  '#interrupt-cells':
> +    const: 2
> +
> +  interrupt-controller:
> +    description: |
> +      The GPMC driver implements and interrupt controller for
> +      the NAND events "fifoevent" and "termcount" plus the
> +      rising/falling edges on the GPMC_WAIT pins.
> +      The interrupt number mapping is as follows
> +      0 - NAND_fifoevent
> +      1 - NAND_termcount
> +      2 - GPMC_WAIT0 pin edge
> +      3 - GPMC_WAIT1 pin edge, and so on.
> +
> +  '#gpio-cells':
> +     const: 2
> +
> +  gpio-controller:
> +    description: |
> +      The GPMC driver implements a GPIO controller for the
> +      GPMC WAIT pins that can be used as general purpose inputs.
> +      0 maps to GPMC_WAIT0 pin.
> +
> +  ti,hwmods:
> +    description:
> +      Name of the HWMOD associated with GPMC. This is for legacy
> +      omap2/3 platforms only.
> +    $ref: /schemas/types.yaml#/definitions/string
> +    deprecated: true
> +
> +  ti,no-idle-on-init:
> +    description:
> +      Prevent idling the module at init. This is for legacy omap2/3
> +      platforms only.
> +    type: boolean
> +    deprecated: true
> +
> +patternProperties:
> +#  "@[0-3],[a-f0-9]+$":
> +  "^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-fA-F]+(,[0-9a-fA-F]+)*$":

Why the commented regex. There's no need for a full regex as we already 
do that elsewhere. You only need to define the unit-address format.

> +    type: object
> +    description: |
> +      The child device node represents the device connected to the GPMC
> +      bus. The device can be a NAND controller, SRAM device, NOR device
> +      or an ASIC.
> +
> +    properties:
> +      compatible:
> +        description:
> +          Compatible of attached device.

Duh. Drop.

> +
> +      reg:
> +        items:
> +        - description: Register access space for the device

A device with 2 register ranges isn't allowed?

> +
> +# GPMC Timing properties for child nodes. All are optional and default to 0.
> +
> +      gpmc,sync-clk-ps:
> +        description: Minimum clock period for synchronous mode, in picoseconds
> +        $ref: /schemas/types.yaml#/definitions/uint32
 
           default: 0

And elsewhere...

> +
> +# Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2:
> +      gpmc,cs-on-ns:
> +        description: Assertion time
> +        $ref: /schemas/types.yaml#/definitions/uint32

Blank line between DT properties.

Don't need a type ref with a standard unit suffix.

Is there a maximum value for all these?

> +      gpmc,cs-rd-off-ns:
> +        description: Read deassertion time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,cs-wr-off-ns:
> +        description: Write deassertion time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +
> +# ADV signal timings (in nanoseconds) corresponding to GPMC_CONFIG3:
> +      gpmc,adv-on-ns:
> +        description: Assertion time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,adv-rd-off-ns:
> +        description: Read deassertion time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,adv-wr-off-ns:
> +        description: Write deassertion time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,adv-aad-mux-on-ns:
> +        description: Assertion time for AAD
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,adv-aad-mux-rd-off-ns:
> +        description: Read deassertion time for AAD
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,adv-aad-mux-wr-off-ns:
> +        description: Write deassertion time for AAD
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +
> +# WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
> +      gpmc,we-on-ns:
> +        description: Assertion time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,we-off-ns:
> +        description: Deassertion time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +
> +# OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
> +      gpmc,oe-on-ns:
> +        description: Assertion time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,oe-off-ns:
> +        description: Deassertion time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,oe-aad-mux-on-ns:
> +        description:       Assertion time for AAD
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,oe-aad-mux-off-ns:
> +        description:      Deassertion time for AAD
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +
> +# Access time and cycle time timings (in nanoseconds) corresponding to
> +# GPMC_CONFIG5:
> +      gpmc,page-burst-access-ns:
> +        description:   Multiple access word delay
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,access-ns:
> +        description:              Start-cycle to first data valid delay
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,rd-cycle-ns:
> +        description:            Total read cycle time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,wr-cycle-ns:
> +        description:            Total write cycle time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,bus-turnaround-ns:
> +        description:      Turn-around time between successive accesses
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,cycle2cycle-delay-ns:
> +        description:   Delay between chip-select pulses
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,clk-activation-ns:
> +        description:      GPMC clock activation time
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,wait-monitoring-ns:
> +        description:     Start of wait monitoring with regard to valid data
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +
> +# Boolean timing parameters. If property is present, parameter is enabled
> +# otherwise disabled.
> +      gpmc,adv-extra-delay:
> +        description:        ADV signal is delayed by half GPMC clock
> +        type: boolean
> +      gpmc,cs-extra-delay:
> +        description:         CS signal is delayed by half GPMC clock
> +        type: boolean
> +      gpmc,cycle2cycle-diffcsen:
> +        description: |
> +          Add "cycle2cycle-delay" between successive accesses
> +          to a different CS
> +        type: boolean
> +      gpmc,cycle2cycle-samecsen:
> +        description: |
> +          Add "cycle2cycle-delay" between successive accesses
> +          to the same CS
> +        type: boolean
> +      gpmc,oe-extra-delay:
> +        description:         OE signal is delayed by half GPMC clock
> +        type: boolean
> +      gpmc,we-extra-delay:
> +        description:         WE signal is delayed by half GPMC clock
> +        type: boolean
> +      gpmc,time-para-granularity:
> +        description:  Multiply all access times by 2
> +        type: boolean
> +
> +# The following two properties are applicable only to OMAP3+ and AM335x:
> +      gpmc,wr-access-ns:
> +        description: |
> +          In synchronous write mode, for single or
> +          burst accesses, defines the number of
> +          GPMC_FCLK cycles from start access time
> +          to the GPMC_CLK rising edge used by the
> +          memory device for the first data capture.
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,wr-data-mux-bus-ns:
> +        description: |
> +          In address-data multiplex mode, specifies
> +          the time when the first data is driven on
> +          the address-data bus.
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +
> +# GPMC chip-select settings properties for child nodes. All are optional.
> +
> +      gpmc,burst-length:
> +        description:     Page/burst length. Must be 4, 8 or 16.
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        enum: [4, 8, 16]
> +      gpmc,burst-wrap:
> +        description:       Enables wrap bursting
> +        type: boolean
> +      gpmc,burst-read:
> +        description:       Enables read page/burst mode
> +        type: boolean
> +      gpmc,burst-write:
> +        description:      Enables write page/burst mode
> +        type: boolean
> +      gpmc,device-width:
> +        description: |
> +          Total width of device(s) connected to a GPMC
> +          chip-select in bytes. The GPMC supports 8-bit
> +          and 16-bit devices and so this property must be
> +          1 or 2.
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        enum: [1, 2]
> +      gpmc,mux-add-data:
> +        description: |
> +          Address and data multiplexing configuration.
> +          Valid values are:
> +          0 for Non multiplexed mode
> +          1 for address-address-data multiplexing mode and
> +          2 for address-data multiplexing mode.
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        enum: [0, 1, 2]
> +      gpmc,sync-read:
> +        description: |
> +          Enables synchronous read. Defaults to asynchronous
> +          is this is not set.
> +        type: boolean
> +      gpmc,sync-write:
> +        description: |
> +          Enables synchronous writes. Defaults to asynchronous
> +          is this is not set.
> +        type: boolean
> +      gpmc,wait-pin:
> +        description: |
> +          Wait-pin used by client. Must be less than "gpmc,num-waitpins".
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +      gpmc,wait-on-read:
> +        description:     Enables wait monitoring on reads.
> +        type: boolean
> +      gpmc,wait-on-write:
> +        description:    Enables wait monitoring on writes.
> +        type: boolean
> +
> +    required:
> +      - reg
> +
> +required:
> +  - compatible
> +  - reg
> +  - gpmc,num-cs
> +  - gpmc,num-waitpins
> +  - "#address-cells"
> +  - "#size-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    gpmc: memory-controller at 50000000 {
> +      compatible = "ti,am3352-gpmc";
> +      reg = <0x50000000 0x2000>;
> +      interrupts = <100>;
> +      clocks = <&l3s_clkctrl>;
> +      clock-names = "fck";
> +      dmas = <&edma 52 0>;
> +      dma-names = "rxtx";
> +      gpmc,num-cs = <8>;
> +      gpmc,num-waitpins = <2>;
> +      #address-cells = <2>;
> +      #size-cells = <1>;
> +      ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
> +      interrupt-controller;
> +      #interrupt-cells = <2>;
> +      gpio-controller;
> +      #gpio-cells = <2>;
> +
> +      nand at 0,0 {
> +        compatible = "ti,omap2-nand";
> +        reg = <0 0 4>;
> +        interrupt-parent = <&gpmc>;
> +        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
> +                     <1 IRQ_TYPE_NONE>; /* termcount */
> +        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */
> +      };
> +    };
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> index 44919d48d241..e439949d49e6 100644
> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> @@ -5,7 +5,7 @@ the GPMC controller with a name of "nand".
>  
>  All timing relevant properties as well as generic gpmc child properties are
>  explained in a separate documents - please refer to
> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> +Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>  
>  For NAND specific properties such as ECC modes or bus width, please refer to
>  Documentation/devicetree/bindings/mtd/nand-controller.yaml
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
> index c8567b40fe13..c9bea106ea65 100644
> --- a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
> +++ b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
> @@ -5,7 +5,7 @@ child nodes of the GPMC controller with a name of "nor".
>  
>  All timing relevant properties as well as generic GPMC child properties are
>  explained in a separate documents. Please refer to
> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> +Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>  
>  Required properties:
>  - bank-width: 		Width of NOR flash in bytes. GPMC supports 8-bit and
> @@ -28,7 +28,7 @@ Required properties:
>  
>  Optional properties:
>  - gpmc,XXX		Additional GPMC timings and settings parameters. See
> -			Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> +			Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>  
>  Optional properties for partition table parsing:
>  - #address-cells: should be set to 1
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
> index e9f01a963a0a..0da78cc4ccca 100644
> --- a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
> +++ b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
> @@ -5,7 +5,7 @@ the GPMC controller with a name of "onenand".
>  
>  All timing relevant properties as well as generic gpmc child properties are
>  explained in a separate documents - please refer to
> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> +Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>  
>  Required properties:
>  
> diff --git a/Documentation/devicetree/bindings/net/gpmc-eth.txt b/Documentation/devicetree/bindings/net/gpmc-eth.txt
> index 32821066a85b..5e2f610455fa 100644
> --- a/Documentation/devicetree/bindings/net/gpmc-eth.txt
> +++ b/Documentation/devicetree/bindings/net/gpmc-eth.txt
> @@ -9,7 +9,7 @@ the GPMC controller with an "ethernet" name.
>  
>  All timing relevant properties as well as generic GPMC child properties are
>  explained in a separate documents. Please refer to
> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> +Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>  
>  For the properties relevant to the ethernet controller connected to the GPMC
>  refer to the binding documentation of the device. For example, the documentation
> @@ -43,7 +43,7 @@ Required properties:
>  
>  Optional properties:
>  - gpmc,XXX		Additional GPMC timings and settings parameters. See
> -			Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> +			Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml

Perhaps delete this file first in the series so you don't have to 
update it.

Rob


From robh at kernel.org  Thu Sep  2 13:19:47 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 2 Sep 2021 15:19:47 -0500
Subject: [PATCH v2 2/6] dt-bindings: memory-controllers: ti, gpmc: Convert
 to yaml
In-Reply-To: <20210902095609.16583-3-rogerq@kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
 <20210902095609.16583-3-rogerq@kernel.org>
Message-ID: <YTEx44lPKf0jaIU3@robh.at.kernel.org>

On Thu, Sep 02, 2021 at 12:56:05PM +0300, Roger Quadros wrote:
> Convert omap-gpmc.txt to ti,gpmc.yaml.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../bindings/memory-controllers/omap-gpmc.txt | 157 --------
>  .../bindings/memory-controllers/ti,gpmc.yaml  | 364 ++++++++++++++++++
>  .../devicetree/bindings/mtd/gpmc-nand.txt     |   2 +-
>  .../devicetree/bindings/mtd/gpmc-nor.txt      |   4 +-
>  .../devicetree/bindings/mtd/gpmc-onenand.txt  |   2 +-
>  .../devicetree/bindings/net/gpmc-eth.txt      |   4 +-
>  6 files changed, 370 insertions(+), 163 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml

Also, please install yamllint and fix all the warnings:

../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:97:6: [warning] wrong indentation: expected 4 but found 5 (indentation)                                                                                                      
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:135:9: [warning] wrong indentation: expected 10 but found 8 (indentation)                                                                                                    
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:190:27: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:193:26: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:199:23: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:202:34: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:205:32: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:208:32: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:211:26: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:214:23: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:217:26: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:220:25: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:226:28: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:229:29: [warning] too many spaces after colon (colons)                                                                                                                       
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:242:29: [warning] too many spaces after colon (colons)
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:245:29: [warning] too many spaces after colon (colons)
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:248:22: [warning] too many spaces after colon (colons)
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:270:25: [warning] too many spaces after colon (colons)
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:274:27: [warning] too many spaces after colon (colons)
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:277:27: [warning] too many spaces after colon (colons)
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:280:26: [warning] too many spaces after colon (colons)
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:314:25: [warning] too many spaces after colon (colons)
../Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml:317:24: [warning] too many spaces after colon (colons)

Rob


From miquel.raynal at bootlin.com  Thu Sep  2 15:03:10 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri, 3 Sep 2021 00:03:10 +0200
Subject: [GIT PULL] mtd: nand: Changes for 5.15
Message-ID: <20210903000310.6cd0fbff@xps13>

Hello,

This is the NAND PR for 5.15.

Thanks,
Miqu?l

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git tags/nand/for-5.15

for you to fetch changes up to 6b430c7595e4eb95fae8fb54adc3c3ce002e75ae:

  mtd: rawnand: cafe: Fix a resource leak in the error handling path of 'cafe_nand_probe()' (2021-08-23 10:58:14 +0200)

----------------------------------------------------------------
NAND core changes:
* Repair Miquel Raynal's email address in MAINTAINERS
* Fix a couple of spelling mistakes in Kconfig
* bbt: Skip bad blocks when searching for the BBT in NAND
* Remove never changed ret variable

Raw NAND changes:
* cafe: Fix a resource leak in the error handling path of 'cafe_nand_probe()'
* intel: Fix error handling in probe
* omap: Fix kernel doc warning on 'calcuate' typo
* gpmc: Fix the ECC bytes vs. OOB bytes equation

SPI-NAND core changes:
* Properly fill the OOB area.
* Fix comment

SPI-NAND drivers changes:
* macronix: Add Quad support for serial NAND flash

----------------------------------------------------------------
Christophe JAILLET (1):
      mtd: rawnand: cafe: Fix a resource leak in the error handling path of 'cafe_nand_probe()'

Colin Ian King (1):
      mtd: rawnand: Fix a couple of spelling mistakes in Kconfig

Daniel Palmer (1):
      mtd: spinand: core: Properly fill the OOB area.

Evgeny Novikov (1):
      mtd: rawnand: intel: Fix error handling in probe

Jaime Liao (1):
      mtd: spinand: macronix: Add Quad support for serial NAND flash

Jason Wang (1):
      mtd: rawnand: remove never changed ret variable

Lukas Bulwahn (1):
      MAINTAINERS: repair Miquel Raynal's email address

Miquel Raynal (2):
      dt-bindings: mtd: gpmc: Fix the ECC bytes vs. OOB bytes equation
      mtd: spinand: Fix comment

Stefan Riedmueller (1):
      mtd: rawnand: nand_bbt: Skip bad blocks when searching for the BBT in NAND

Vladimir Molokov (1):
      mtd: rawnand: omap: Fix kernel doc warning on 'calcuate' typo

 Documentation/devicetree/bindings/mtd/gpmc-nand.txt |  2 +-
 MAINTAINERS                                         |  4 ++--
 drivers/mtd/nand/raw/Kconfig                        |  4 ++--
 drivers/mtd/nand/raw/cafe_nand.c                    |  4 +++-
 drivers/mtd/nand/raw/intel-nand-controller.c        | 27 ++++++++++++++++++---------
 drivers/mtd/nand/raw/meson_nand.c                   |  4 ++--
 drivers/mtd/nand/raw/nand_bbt.c                     | 33 +++++++++++++++++++++++++++++++++
 drivers/mtd/nand/raw/omap2.c                        |  2 +-
 drivers/mtd/nand/spi/core.c                         |  4 +++-
 drivers/mtd/nand/spi/macronix.c                     | 16 ++++++++--------
 10 files changed, 73 insertions(+), 27 deletions(-)


From miquel.raynal at bootlin.com  Thu Sep  2 15:10:50 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri, 3 Sep 2021 00:10:50 +0200
Subject: [GIT PULL] mtd: nand: Changes for 5.15
In-Reply-To: <20210903000310.6cd0fbff@xps13>
References: <20210903000310.6cd0fbff@xps13>
Message-ID: <20210903001050.5cc0c9be@xps13>


Miquel Raynal <miquel.raynal at bootlin.com> wrote on Fri, 3 Sep 2021
00:03:10 +0200:

> Hello,
> 
> This is the NAND PR for 5.15.
> 
> Thanks,
> Miqu?l
> 
> The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:
> 
>   Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git tags/nand/for-5.15
> 
> for you to fetch changes up to 6b430c7595e4eb95fae8fb54adc3c3ce002e75ae:
> 
>   mtd: rawnand: cafe: Fix a resource leak in the error handling path of 'cafe_nand_probe()' (2021-08-23 10:58:14 +0200)
> 
> ----------------------------------------------------------------
> NAND core changes:
> * Repair Miquel Raynal's email address in MAINTAINERS
> * Fix a couple of spelling mistakes in Kconfig
> * bbt: Skip bad blocks when searching for the BBT in NAND
> * Remove never changed ret variable
> 
> Raw NAND changes:
> * cafe: Fix a resource leak in the error handling path of 'cafe_nand_probe()'
> * intel: Fix error handling in probe
> * omap: Fix kernel doc warning on 'calcuate' typo
> * gpmc: Fix the ECC bytes vs. OOB bytes equation
> 
> SPI-NAND core changes:
> * Properly fill the OOB area.
> * Fix comment
> 
> SPI-NAND drivers changes:
> * macronix: Add Quad support for serial NAND flash
> 
> ----------------------------------------------------------------
> Christophe JAILLET (1):
>       mtd: rawnand: cafe: Fix a resource leak in the error handling path of 'cafe_nand_probe()'
> 
> Colin Ian King (1):
>       mtd: rawnand: Fix a couple of spelling mistakes in Kconfig
> 
> Daniel Palmer (1):
>       mtd: spinand: core: Properly fill the OOB area.
> 
> Evgeny Novikov (1):
>       mtd: rawnand: intel: Fix error handling in probe
> 
> Jaime Liao (1):
>       mtd: spinand: macronix: Add Quad support for serial NAND flash
> 
> Jason Wang (1):
>       mtd: rawnand: remove never changed ret variable
> 
> Lukas Bulwahn (1):
>       MAINTAINERS: repair Miquel Raynal's email address
> 
> Miquel Raynal (2):
>       dt-bindings: mtd: gpmc: Fix the ECC bytes vs. OOB bytes equation
>       mtd: spinand: Fix comment
> 
> Stefan Riedmueller (1):
>       mtd: rawnand: nand_bbt: Skip bad blocks when searching for the BBT in NAND
> 
> Vladimir Molokov (1):
>       mtd: rawnand: omap: Fix kernel doc warning on 'calcuate' typo
> 
>  Documentation/devicetree/bindings/mtd/gpmc-nand.txt |  2 +-
>  MAINTAINERS                                         |  4 ++--
>  drivers/mtd/nand/raw/Kconfig                        |  4 ++--
>  drivers/mtd/nand/raw/cafe_nand.c                    |  4 +++-
>  drivers/mtd/nand/raw/intel-nand-controller.c        | 27 ++++++++++++++++++---------
>  drivers/mtd/nand/raw/meson_nand.c                   |  4 ++--
>  drivers/mtd/nand/raw/nand_bbt.c                     | 33 +++++++++++++++++++++++++++++++++
>  drivers/mtd/nand/raw/omap2.c                        |  2 +-
>  drivers/mtd/nand/spi/core.c                         |  4 +++-
>  drivers/mtd/nand/spi/macronix.c                     | 16 ++++++++--------
>  10 files changed, 73 insertions(+), 27 deletions(-)

Pulled into mtd/next.


From sunhao.th at gmail.com  Fri Sep  3 00:50:57 2021
From: sunhao.th at gmail.com (Hao Sun)
Date: Fri, 3 Sep 2021 15:50:57 +0800
Subject: possible deadlock in blktrans_open
Message-ID: <CACkBjsbk01Cif47Bv+=DaXaOdGMbPXA5YmW0Yrf4y4tsKT9sZw@mail.gmail.com>

Hello,

When using Healer to fuzz the latest Linux kernel, the following crash
was triggered.

HEAD commit: 9e9fb7655ed58 Merge tag 'net-next-5.15'
git tree: upstream
console output:
https://drive.google.com/file/d/1Se_X6iW4GNQ5vqD4k_Bb_Sf8TqCx8eTz/view?usp=sharing
kernel config: https://drive.google.com/file/d/1zgxbwaYkrM26KEmJ-5sUZX57gfXtRrwA/view?usp=sharing
C reproducer:  https://drive.google.com/file/d/1BtlOcxuP74hrKEkaEx4RpOXYcsQq0N7q/view?usp=sharing
Syzlang reproducer:
https://drive.google.com/file/d/1Lb42gOp9KGtdcfLbsPUJjALcS8Vj5KlM/view?usp=sharing

If you fix this issue, please add the following tag to the commit:
Reported-by: Hao Sun <sunhao.th at gmail.com>

Simplified report:
======================================================
WARNING: possible circular locking dependency detected
5.14.0+ #12 Not tainted
------------------------------------------------------
systemd-udevd/6440 is trying to acquire lock:
ffffffff85ca4b68 (mtd_table_mutex){+.+.}-{3:3}, at:
blktrans_open+0x4b/0x260 drivers/mtd/mtd_blkdevs.c:210

Full Log:

[   19.853374][ T6440] ======================================================
[   19.854238][ T6440] WARNING: possible circular locking dependency detected
[   19.855232][ T6440] 5.14.0+ #12 Not tainted
[   19.855765][ T6440] ------------------------------------------------------
[   19.856628][ T6440] systemd-udevd/6440 is trying to acquire lock:
[   19.857463][ T6440] ffffffff85ca4b68 (mtd_table_mutex){+.+.}-{3:3},
at: blktrans_open+0x4b/0x260
[   19.858586][ T6440]
[   19.858586][ T6440] but task is already holding lock:
[   19.859525][ T6440] ffff88800e29c118
(&disk->open_mutex){+.+.}-{3:3}, at: blkdev_get_by_dev+0xe0/0x370
[   19.860768][ T6440]
[   19.860768][ T6440] which lock already depends on the new lock.
[   19.860768][ T6440]
[   19.862050][ T6440]
[   19.862050][ T6440] the existing dependency chain (in reverse order) is:
[   19.863208][ T6440]
[   19.863208][ T6440] -> #1 (&disk->open_mutex){+.+.}-{3:3}:
[   19.864226][ T6440]        __mutex_lock+0x98/0xa50
[   19.864841][ T6440]        bd_register_pending_holders+0x2c/0x140
[   19.865612][ T6440]        device_add_disk+0x2f5/0x4f0
[   19.866270][ T6440]        add_mtd_blktrans_dev+0x436/0x670
         Startin[   19.867011][ T6440]        mtdblock_add_mtd+0x73/0xa0
g Load/Save RF K[   19.867775][ T6440]        blktrans_notify_add+0x36/0x50
ill Switch Statu[   19.868519][ T6440]        add_mtd_device+0x3e1/0x670
s...[   19.869269][ T6440]        mtd_device_parse_register+0x26d/0x410
[   19.870131][ T6440]        mtdram_init_device+0xa9/0xd0

[   19.870881][ T6440]        init_mtdram+0xa9/0x104
[   19.871566][ T6440]        do_one_initcall+0x82/0x430
[   19.872289][ T6440]        kernel_init_freeable+0x370/0x3c3
[   19.873122][ T6440]        kernel_init+0x1b/0x180
[   19.873810][ T6440]        ret_from_fork+0x1f/0x30
[   19.874494][ T6440]
[   19.874494][ T6440] -> #0 (mtd_table_mutex){+.+.}-{3:3}:
[   19.875551][ T6440]        __lock_acquire+0x161f/0x1d60
[   19.876301][ T6440]        lock_acquire+0x1f9/0x340
[   19.876994][ T6440]        __mutex_lock+0x98/0xa50
[   19.877675][ T6440]        blktrans_open+0x4b/0x260
[   19.878365][ T6440]        blkdev_get_whole+0x36/0xd0
[   19.879081][ T6440]        blkdev_get_by_dev+0x173/0x370
[   19.879868][ T6440]        blkdev_open+0x95/0x100
[   19.880547][ T6440]        do_dentry_open+0x327/0x530
[   19.881265][ T6440]        path_openat+0xcf3/0xe20
[   19.881979][ T6440]        do_filp_open+0xe3/0x170
[   19.882673][ T6440]        do_sys_openat2+0x357/0x4a0
[   19.883348][ T6440]        do_sys_open+0x87/0xd0
[   19.883955][ T6440]        do_syscall_64+0x34/0xb0
[   19.884585][ T6440]        entry_SYSCALL_64_after_hwframe+0x44/0xae
[   19.885399][ T6440]
[   19.885399][ T6440] other info that might help us debug this:
[   19.885399][ T6440]
[   19.886711][ T6440]  Possible unsafe locking scenario:
[   19.886711][ T6440]
[   19.887661][ T6440]        CPU0                    CPU1
[   19.888324][ T6440]        ----                    ----
[   19.889006][ T6440]   lock(&disk->open_mutex);
[   19.889618][ T6440]                                lock(mtd_table_mutex);
[   19.890506][ T6440]                                lock(&disk->open_mutex);
[   19.891413][ T6440]   lock(mtd_table_mutex);
[   19.891987][ T6440]
[   19.891987][ T6440]  *** DEADLOCK ***
[   19.891987][ T6440]
[   19.893010][ T6440] 1 lock held by systemd-udevd/6440:
[   19.893687][ T6440]  #0: ffff88800e29c118
(&disk->open_mutex){+.+.}-{3:3}, at: blkdev_get_by_dev+0xe0/0x370
[   19.894902][ T6440]
[   19.894902][ T6440] stack backtrace:
[   19.895622][ T6440] CPU: 0 PID: 6440 Comm: systemd-udevd Not
tainted 5.14.0+ #12
[   19.896548][ T6440] Hardware name: QEMU Standard PC (i440FX + PIIX,
1996), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014
[   19.898068][ T6440] Call Trace:
[   19.898474][ T6440]  dump_stack_lvl+0x8d/0xcf
[   19.899029][ T6440]  check_noncircular+0x105/0x120
[   19.899668][ T6440]  ? __lock_acquire+0x161f/0x1d60
[   19.900312][ T6440]  __lock_acquire+0x161f/0x1d60
[   19.901027][ T6440]  lock_acquire+0x1f9/0x340
[   19.901622][ T6440]  ? blktrans_open+0x4b/0x260
[   19.902201][ T6440]  __mutex_lock+0x98/0xa50
[   19.902850][ T6440]  ? blktrans_open+0x4b/0x260
[   19.903538][ T6440]  ? blktrans_dev_get.isra.10+0x63/0xa0
[   19.904345][ T6440]  ? blktrans_open+0x4b/0x260
[   19.905026][ T6440]  ? __mutex_unlock_slowpath+0x3c/0x280
[   19.905820][ T6440]  ? blktrans_release+0x120/0x120
[   19.906557][ T6440]  ? blktrans_open+0x4b/0x260
[   19.907248][ T6440]  blktrans_open+0x4b/0x260
[   19.907894][ T6440]  ? blktrans_release+0x120/0x120
[   19.908628][ T6440]  blkdev_get_whole+0x36/0xd0
[   19.909309][ T6440]  blkdev_get_by_dev+0x173/0x370
[   19.910031][ T6440]  ? blkdev_get_by_dev+0x370/0x370
[   19.910766][ T6440]  blkdev_open+0x95/0x100
[   19.911347][ T6440]  do_dentry_open+0x327/0x530
[   19.911956][ T6440]  ? may_open+0x104/0x1d0
[   19.912520][ T6440]  path_openat+0xcf3/0xe20
[   19.913152][ T6440]  do_filp_open+0xe3/0x170
[   19.913775][ T6440]  ? alloc_fd+0x1a1/0x290
[   19.914385][ T6440]  ? _find_next_bit+0x10a/0x130
[   19.915042][ T6440]  ? do_sys_openat2+0x357/0x4a0
[   19.915690][ T6440]  do_sys_openat2+0x357/0x4a0
[   19.916318][ T6440]  do_sys_open+0x87/0xd0
[   19.916886][ T6440]  do_syscall_64+0x34/0xb0
[   19.917481][ T6440]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[   19.918263][ T6440] RIP: 0033:0x7f0db3d91840
[   19.918852][ T6440] Code: 73 01 c3 48 8b 0d 68 77 20 00 f7 d8 64 89
01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d 89 bb 20 00 00 75 10 b8 02
00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 1e f6 ff ff
48 89 04 24
[   19.921462][ T6440] RSP: 002b:00007ffdba846478 EFLAGS: 00000246
ORIG_RAX: 0000000000000002
[   19.922620][ T6440] RAX: ffffffffffffffda RBX: 000055a6edb8f690
RCX: 00007f0db3d91840
[   19.923703][ T6440] RDX: 000055a6ebc31fe3 RSI: 00000000000a0800
RDI: 000055a6edb83070
[   19.924749][ T6440] RBP: 00007ffdba8465f0 R08: 000055a6ebc31670
R09: 0000000000000020
[   19.925794][ T6440] R10: 000055a6ebc31d0c R11: 0000000000000246
R12: 00007ffdba846540
[   19.926850][ T6440] R13: 000055a6edb86c20 R14: 0000000000000003
R15: 000000000000000e


From sean at geanix.com  Fri Sep  3 01:17:51 2021
From: sean at geanix.com (Sean Nyekjaer)
Date: Fri, 3 Sep 2021 10:17:51 +0200
Subject: [PATCH] PM / suspend: move userspace freeze before disk sync
In-Reply-To: <CAJZ5v0j5dMDSDjhuXaZd=_J5JOP4Z09WUXfjWX_iCcT4RDisCg@mail.gmail.com>
References: <20210901083442.210230-1-sean@geanix.com>
 <CAJZ5v0j5dMDSDjhuXaZd=_J5JOP4Z09WUXfjWX_iCcT4RDisCg@mail.gmail.com>
Message-ID: <20210903081751.3qq36nrksucqthss@skn-laptop>

On Thu, Sep 02, 2021 at 06:28:14PM +0200, Rafael J. Wysocki wrote:
> On Wed, Sep 1, 2021 at 10:35 AM Sean Nyekjaer <sean at geanix.com> wrote:
> >
> > This fixes an issue where data remains unwritten before suspend.
> 
> Well, it doesn't make the issue go away, it just hides it for you and
> it may very well expose it for someone else.

OK

> 
> In particular, note that you can compile the kernel with
> CONFIG_SUSPEND_SKIP_SYNC set which makes it not sync at all during
> system-wide suspend and this is a valid case expected to work.  It
> looks like this case doesn't work for you.
> 
> > UBI tried to write data, before the mtd device had been unsuspended.
> 
> Well, that's the real problem and it can happen regardless of whether
> or not this patch is there.

How to fix it then?
We can't live with devices that bricks on unsuspend :/

/Sean

> 
> > Seen on an iMX6ULL board fitted with rawnand flash.
> >
> > Before:
> > PM: suspend entry (deep)
> > Filesystems sync: 0.088 seconds
> > Freezing user space processes ... (elapsed 0.000 seconds) done.
> > OOM killer disabled.
> > Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
> > printk: Suspending console(s) (use no_console_suspend to debug)
> > PM: suspend devices took 0.030 seconds
> > Disabling non-boot CPUs ...
> > ubi0 error: ubi_io_write: error -16 while writing 4096 bytes to PEB 1762:94208, written 0 bytes
> >
> > After:
> > PM: suspend entry (deep)
> > Freezing user space processes ... (elapsed 0.001 seconds) done.
> > OOM killer disabled.
> > Freezing remaining freezable tasks ... (elapsed 0.001 seconds) done.
> > Filesystems sync: 0.060 seconds
> > printk: Suspending console(s) (use no_console_suspend to debug)
> > PM: suspend devices took 0.040 seconds
> > Disabling non-boot CPUs ...
> > PM: resume devices took 0.100 seconds
> >
> > Signed-off-by: Sean Nyekjaer <sean at geanix.com>


From stefan at agner.ch  Fri Sep  3 01:23:22 2021
From: stefan at agner.ch (Stefan Agner)
Date: Fri, 03 Sep 2021 10:23:22 +0200
Subject: [PATCH] mtd: rawnand: vf610: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074245.9583-1-caihuoqing@baidu.com>
References: <20210901074245.9583-1-caihuoqing@baidu.com>
Message-ID: <26cdf34dbda1327f60da32b9c29130a6@agner.ch>

On 2021-09-01 09:42, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

Acked-by: Stefan Agner <stefan at agner.ch>

> ---
>  drivers/mtd/nand/raw/vf610_nfc.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c
> index 40d70f991d89..a2b89b75073f 100644
> --- a/drivers/mtd/nand/raw/vf610_nfc.c
> +++ b/drivers/mtd/nand/raw/vf610_nfc.c
> @@ -807,7 +807,6 @@ static const struct nand_controller_ops
> vf610_nfc_controller_ops = {
>  static int vf610_nfc_probe(struct platform_device *pdev)
>  {
>  	struct vf610_nfc *nfc;
> -	struct resource *res;
>  	struct mtd_info *mtd;
>  	struct nand_chip *chip;
>  	struct device_node *child;
> @@ -831,8 +830,7 @@ static int vf610_nfc_probe(struct platform_device *pdev)
>  	if (irq <= 0)
>  		return -EINVAL;
>  
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	nfc->regs = devm_ioremap_resource(nfc->dev, res);
> +	nfc->regs = devm_platform_ioremap_resource(pdev, 0);
>  	if (IS_ERR(nfc->regs))
>  		return PTR_ERR(nfc->regs);


From stefan at agner.ch  Fri Sep  3 01:23:45 2021
From: stefan at agner.ch (Stefan Agner)
Date: Fri, 03 Sep 2021 10:23:45 +0200
Subject: [PATCH] mtd: rawnand: tegra: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074230.9483-1-caihuoqing@baidu.com>
References: <20210901074230.9483-1-caihuoqing@baidu.com>
Message-ID: <fb7aec944e72f91a9a33d7d37d0cbb44@agner.ch>

On 2021-09-01 09:42, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

Acked-by: Stefan Agner <stefan at agner.ch>

> ---
>  drivers/mtd/nand/raw/tegra_nand.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/tegra_nand.c
> b/drivers/mtd/nand/raw/tegra_nand.c
> index fbf67722a049..32431bbe69b8 100644
> --- a/drivers/mtd/nand/raw/tegra_nand.c
> +++ b/drivers/mtd/nand/raw/tegra_nand.c
> @@ -1144,7 +1144,6 @@ static int tegra_nand_probe(struct platform_device *pdev)
>  {
>  	struct reset_control *rst;
>  	struct tegra_nand_controller *ctrl;
> -	struct resource *res;
>  	int err = 0;
>  
>  	ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
> @@ -1155,8 +1154,7 @@ static int tegra_nand_probe(struct platform_device *pdev)
>  	nand_controller_init(&ctrl->controller);
>  	ctrl->controller.ops = &tegra_nand_controller_ops;
>  
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	ctrl->regs = devm_ioremap_resource(&pdev->dev, res);
> +	ctrl->regs = devm_platform_ioremap_resource(pdev, 0);
>  	if (IS_ERR(ctrl->regs))
>  		return PTR_ERR(ctrl->regs);


From novikov at ispras.ru  Fri Sep  3 01:26:53 2021
From: novikov at ispras.ru (Evgeny Novikov)
Date: Fri,  3 Sep 2021 11:26:53 +0300
Subject: [PATCH] mtd: rawnand: intel: Fix potential buffer overflow in probe
Message-ID: <20210903082653.16441-1-novikov@ispras.ru>

ebu_nand_probe() read the value of u32 variable "cs" from the device
firmware description and used it as the index for array ebu_host->cs
that can contain MAX_CS (2) elements at most. That could result in
a buffer overflow and various bad consequences later.

Fix the potential buffer overflow by restricting values of "cs" with
MAX_CS in probe.

Found by Linux Driver Verification project (linuxtesting.org).

Fixes: 0b1039f016e8 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC")
Signed-off-by: Evgeny Novikov <novikov at ispras.ru>
Co-developed-by: Kirill Shilimanov <kirill.shilimanov at huawei.com>
Signed-off-by: Kirill Shilimanov <kirill.shilimanov at huawei.com>
Co-developed-by: Anton Vasilyev <vasilyev at ispras.ru>
Signed-off-by: Anton Vasilyev <vasilyev at ispras.ru>
---
 drivers/mtd/nand/raw/intel-nand-controller.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c
index 8b49fd56cf96..81678088fdca 100644
--- a/drivers/mtd/nand/raw/intel-nand-controller.c
+++ b/drivers/mtd/nand/raw/intel-nand-controller.c
@@ -609,6 +609,11 @@ static int ebu_nand_probe(struct platform_device *pdev)
 		dev_err(dev, "failed to get chip select: %d\n", ret);
 		return ret;
 	}
+	if (cs >= MAX_CS) {
+		dev_err(dev, "got invalid chip select: %d\n", cs);
+		return -EINVAL;
+	}
+
 	ebu_host->cs_num = cs;
 
 	resname = devm_kasprintf(dev, GFP_KERNEL, "nand_cs%d", cs);
-- 
2.26.2



From miquel.raynal at bootlin.com  Fri Sep  3 02:17:55 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri, 3 Sep 2021 11:17:55 +0200
Subject: [PATCH] PM / suspend: move userspace freeze before disk sync
In-Reply-To: <20210903081751.3qq36nrksucqthss@skn-laptop>
References: <20210901083442.210230-1-sean@geanix.com>
 <CAJZ5v0j5dMDSDjhuXaZd=_J5JOP4Z09WUXfjWX_iCcT4RDisCg@mail.gmail.com>
 <20210903081751.3qq36nrksucqthss@skn-laptop>
Message-ID: <20210903111755.0972850d@xps13>

Hi Sean,

sean at geanix.com wrote on Fri, 3 Sep 2021 10:17:51 +0200:

> On Thu, Sep 02, 2021 at 06:28:14PM +0200, Rafael J. Wysocki wrote:
> > On Wed, Sep 1, 2021 at 10:35 AM Sean Nyekjaer <sean at geanix.com> wrote:  
> > >
> > > This fixes an issue where data remains unwritten before suspend.  
> > 
> > Well, it doesn't make the issue go away, it just hides it for you and
> > it may very well expose it for someone else.  
> 
> OK
> 
> > 
> > In particular, note that you can compile the kernel with
> > CONFIG_SUSPEND_SKIP_SYNC set which makes it not sync at all during
> > system-wide suspend and this is a valid case expected to work.  It
> > looks like this case doesn't work for you.
> >   
> > > UBI tried to write data, before the mtd device had been unsuspended.  
> > 
> > Well, that's the real problem and it can happen regardless of whether
> > or not this patch is there.  
> 
> How to fix it then?
> We can't live with devices that bricks on unsuspend :/

We then need to focus on UBI/UBIFS implementation (Richard is currently
off), maybe there is more logic than just a basic retry to implement.

Thanks,
Miqu?l


From rogerq at kernel.org  Fri Sep  3 02:35:42 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 3 Sep 2021 12:35:42 +0300
Subject: [PATCH v2 2/6] dt-bindings: memory-controllers: ti, gpmc: Convert
 to yaml
In-Reply-To: <YTEsiJiLMRYon5s3@robh.at.kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
 <20210902095609.16583-3-rogerq@kernel.org>
 <YTEsiJiLMRYon5s3@robh.at.kernel.org>
Message-ID: <715fe0ee-a38c-c2ca-5e29-79fa0887bea0@kernel.org>

Hi Rob,

On 02/09/2021 22:56, Rob Herring wrote:
> On Thu, Sep 02, 2021 at 12:56:05PM +0300, Roger Quadros wrote:
>> Convert omap-gpmc.txt to ti,gpmc.yaml.
>>
>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>> ---
>>  .../bindings/memory-controllers/omap-gpmc.txt | 157 --------
>>  .../bindings/memory-controllers/ti,gpmc.yaml  | 364 ++++++++++++++++++
>>  .../devicetree/bindings/mtd/gpmc-nand.txt     |   2 +-
>>  .../devicetree/bindings/mtd/gpmc-nor.txt      |   4 +-
>>  .../devicetree/bindings/mtd/gpmc-onenand.txt  |   2 +-
>>  .../devicetree/bindings/net/gpmc-eth.txt      |   4 +-
>>  6 files changed, 370 insertions(+), 163 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> 
>> diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>> new file mode 100644
>> index 000000000000..b7d43370a95d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>> @@ -0,0 +1,364 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/memory-controllers/ti,gpmc.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Texas Instruments GPMC Memory Controller device-tree bindings
>> +
>> +maintainers:
>> +  - Tony Lindgren <tony at atomide.com>
>> +  - Roger Quadros <rogerq at kernel.org>
>> +
>> +description:
>> +  The GPMC is a unified memory controller dedicated for interfacing
>> +  with external memory devices like
>> +  - Asynchronous SRAM-like memories and ASICs
>> +  - Asynchronous, synchronous, and page mode burst NOR flash
>> +  - NAND flash
>> +  - Pseudo-SRAM devices
>> +
>> +properties:
>> +  compatible:
>> +    items:
>> +      - enum:
>> +          - ti,omap2420-gpmc
>> +          - ti,omap2430-gpmc
>> +          - ti,omap3430-gpmc
>> +          - ti,omap4430-gpmc
>> +          - ti,am3352-gpmc
>> +
>> +  reg:
>> +    items:
>> +      - description:
>> +          Configuration registers for the controller.
> 
> Just 'maxItems: 1' is sufficient.
> 
>> +
>> +  interrupts: true
> 
> Need to define how many.
> 
>> +
>> +  clocks:
>> +    maxItems: 1
>> +    description: |
>> +      Functional clock. Used for bus timing calculations and
>> +      GPMC configuration.
>> +
>> +  clock-names:
>> +    items:
>> +      - const: fck
>> +
>> +  dmas:
>> +    items:
>> +      - description: DMA channel for GPMC NAND prefetch
>> +
>> +  dma-names:
>> +    items:
>> +      - const: rxtx
>> +
>> +  "#address-cells":
>> +    const: 2
>> +
>> +  "#size-cells":
>> +    const: 1
>> +
>> +  gpmc,num-cs:
>> +    description: maximum number of supported chip-select lines.
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +
>> +  gpmc,num-waitpins:
>> +    description: maximum number of supported wait pins.
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +
>> +  ranges:
>> +    minItems: 1
>> +    description: |
>> +      Must be set up to reflect the memory layout with four
>> +      integer values for each chip-select line in use,
>> +      <cs-number> 0 <physical address of mapping> <size>
>> +
>> +    items:
>> +      - description: NAND bank 0
>> +      - description: NOR/SRAM bank 0
>> +      - description: NOR/SRAM bank 1
>> +
>> +  '#interrupt-cells':
>> +    const: 2
>> +
>> +  interrupt-controller:
>> +    description: |
>> +      The GPMC driver implements and interrupt controller for
>> +      the NAND events "fifoevent" and "termcount" plus the
>> +      rising/falling edges on the GPMC_WAIT pins.
>> +      The interrupt number mapping is as follows
>> +      0 - NAND_fifoevent
>> +      1 - NAND_termcount
>> +      2 - GPMC_WAIT0 pin edge
>> +      3 - GPMC_WAIT1 pin edge, and so on.
>> +
>> +  '#gpio-cells':
>> +     const: 2
>> +
>> +  gpio-controller:
>> +    description: |
>> +      The GPMC driver implements a GPIO controller for the
>> +      GPMC WAIT pins that can be used as general purpose inputs.
>> +      0 maps to GPMC_WAIT0 pin.
>> +
>> +  ti,hwmods:
>> +    description:
>> +      Name of the HWMOD associated with GPMC. This is for legacy
>> +      omap2/3 platforms only.
>> +    $ref: /schemas/types.yaml#/definitions/string
>> +    deprecated: true
>> +
>> +  ti,no-idle-on-init:
>> +    description:
>> +      Prevent idling the module at init. This is for legacy omap2/3
>> +      platforms only.
>> +    type: boolean
>> +    deprecated: true
>> +
>> +patternProperties:
>> +#  "@[0-3],[a-f0-9]+$":>> +  "^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-fA-F]+(,[0-9a-fA-F]+)*$":

> 
> Why the commented regex. There's no need for a full regex as we already 
> do that elsewhere. You only need to define the unit-address format.

This should be
  "@[0-7],[a-f0-9]+$":

I added the full regex during debug but forgot to take it off.

> 
>> +    type: object
>> +    description: |
>> +      The child device node represents the device connected to the GPMC
>> +      bus. The device can be a NAND controller, SRAM device, NOR device
>> +      or an ASIC.
>> +
>> +    properties:
>> +      compatible:
>> +        description:
>> +          Compatible of attached device.
> 
> Duh. Drop.
> 
>> +
>> +      reg:
>> +        items:
>> +        - description: Register access space for the device
> 
> A device with 2 register ranges isn't allowed?

GPMC is actually a memory controller and we are describing the children here.
Each child has to have a register range.

> 
>> +
>> +# GPMC Timing properties for child nodes. All are optional and default to 0.
>> +
>> +      gpmc,sync-clk-ps:
>> +        description: Minimum clock period for synchronous mode, in picoseconds
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>  
>            default: 0
> 
> And elsewhere...
> 
>> +
>> +# Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2:
>> +      gpmc,cs-on-ns:
>> +        description: Assertion time
>> +        $ref: /schemas/types.yaml#/definitions/uint32
> 
> Blank line between DT properties.
> 
> Don't need a type ref with a standard unit suffix.
> 
> Is there a maximum value for all these?
> 

There is a maximum value but it is not an absolute value in time unit (ns)
as it depends on the GPMC functional clock rate which is platform specific.

e.g. for gpmc,cs-on-ns
	maximum: GPMC clock period * 15

>> +      gpmc,cs-rd-off-ns:
>> +        description: Read deassertion time
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +      gpmc,cs-wr-off-ns:
>> +        description: Write deassertion time
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +

<snip>

>>  
>> diff --git a/Documentation/devicetree/bindings/net/gpmc-eth.txt b/Documentation/devicetree/bindings/net/gpmc-eth.txt
>> index 32821066a85b..5e2f610455fa 100644
>> --- a/Documentation/devicetree/bindings/net/gpmc-eth.txt
>> +++ b/Documentation/devicetree/bindings/net/gpmc-eth.txt
>> @@ -9,7 +9,7 @@ the GPMC controller with an "ethernet" name.
>>  
>>  All timing relevant properties as well as generic GPMC child properties are
>>  explained in a separate documents. Please refer to
>> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>> +Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>>  
>>  For the properties relevant to the ethernet controller connected to the GPMC
>>  refer to the binding documentation of the device. For example, the documentation
>> @@ -43,7 +43,7 @@ Required properties:
>>  
>>  Optional properties:
>>  - gpmc,XXX		Additional GPMC timings and settings parameters. See
>> -			Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>> +			Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> 
> Perhaps delete this file first in the series so you don't have to 
> update it.
> 

Yes. Thanks for review :)

cheers,
-roger


From miquel.raynal at bootlin.com  Fri Sep  3 02:49:46 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri, 3 Sep 2021 11:49:46 +0200
Subject: [GIT PULL] mtd: Changes for 5.15
Message-ID: <20210903114946.3f874e6e@xps13>

Hello Linus,

This is the MTD PR for 5.15.

Thanks,
Miqu?l

The following changes since commit
e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git
  tags/mtd/for-5.15

for you to fetch changes up to c1fe77e42440d2cad76055df6fb58caabf622d51:

  Merge tag 'nand/for-5.15' into mtd/next (2021-09-03 00:04:16 +0200)

----------------------------------------------------------------
MTD changes:
* blkdevs:
  - Simplify the refcounting in blktrans_{open, release}
  - Simplify blktrans_getgeo
  - Remove blktrans_ref_mutex
  - Simplify blktrans_dev_get
  - Use lockdep_assert_held
  - Don't hold del_mtd_blktrans_dev in blktrans_{open, release}
* ftl:
  - Don't cast away the type when calling add_mtd_blktrans_dev
  - Don't cast away the type when calling add_mtd_blktrans_dev
  - Use container_of() rather than cast
  - Fix use-after-free
  - Add discard support
  - Allow use of MTD_RAM for testing purposes
* concat:
  - Check _read, _write callbacks existence before assignment
  - Judge callback existence based on the master
* maps:
  - Maps: remove dead MTD map driver for PMC-Sierra MSP boards
* mtdblock:
  - Warn if added for a NAND device
  - Add comment about UBI block devices
  - Update old JFFS2 mention in Kconfig
* partitions:
  - Redboot: convert to YAML

NAND core changes:
* Repair Miquel Raynal's email address in MAINTAINERS
* Fix a couple of spelling mistakes in Kconfig
* bbt: Skip bad blocks when searching for the BBT in NAND
* Remove never changed ret variable

Raw NAND changes:
* cafe: Fix a resource leak in the error handling path of
'cafe_nand_probe()'
* intel: Fix error handling in probe
* omap: Fix kernel doc warning on 'calcuate' typo
* gpmc: Fix the ECC bytes vs. OOB bytes equation

SPI-NAND core changes:
* Properly fill the OOB area.
* Fix comment

SPI-NAND drivers changes:
* macronix: Add Quad support for serial NAND flash

----------------------------------------------------------------
Christoph Hellwig (8):
      mtd_blkdevs: don't hold del_mtd_blktrans_dev in blktrans_{open,
release} mtd_blkdevs: use lockdep_assert_held
      mtd/ftl: don't cast away the type when calling
add_mtd_blktrans_dev mtd/rfd_ftl: don't cast away the type when calling
add_mtd_blktrans_dev mtd_blkdevs: simplify blktrans_dev_get
      mtd_blkdevs: remove blktrans_ref_mutex
      mtd_blkdevs: simplify blktrans_getgeo
      mtd_blkdevs: simplify the refcounting in blktrans_{open, release}

Christophe JAILLET (1):
      mtd: rawnand: cafe: Fix a resource leak in the error handling
path of 'cafe_nand_probe()'

Colin Ian King (1):
      mtd: rawnand: Fix a couple of spelling mistakes in Kconfig

Corentin Labbe (1):
      dt_bindings: mtd: partitions: redboot: convert to YAML

Daniel Palmer (1):
      mtd: spinand: core: Properly fill the OOB area.

Evgeny Novikov (1):
      mtd: rawnand: intel: Fix error handling in probe

Ezequiel Garcia (3):
      mtdblock: Update old JFFS2 mention in Kconfig
      mtdblock: Add comment about UBI block devices
      mtdblock: Warn if added for a NAND device

Jaime Liao (1):
      mtd: spinand: macronix: Add Quad support for serial NAND flash

Jason Wang (1):
      mtd: rawnand: remove never changed ret variable

Lukas Bulwahn (2):
      MAINTAINERS: repair Miquel Raynal's email address
      mtd: maps: remove dead MTD map driver for PMC-Sierra MSP boards

Miquel Raynal (3):
      dt-bindings: mtd: gpmc: Fix the ECC bytes vs. OOB bytes equation
      mtd: spinand: Fix comment
      Merge tag 'nand/for-5.15' into mtd/next

Sean Young (4):
      mtd: rfd_ftl: allow use of MTD_RAM for testing purposes
      mtd: rfd_ftl: add discard support
      mtd: rfd_ftl: fix use-after-free
      mtd: rfd_ftl: use container_of() rather than cast

Stefan Riedmueller (1):
      mtd: rawnand: nand_bbt: Skip bad blocks when searching for the
BBT in NAND

Vladimir Molokov (1):
      mtd: rawnand: omap: Fix kernel doc warning on 'calcuate' typo

Zhihao Cheng (2):
      mtd: mtdconcat: Judge callback existence based on the master
      mtd: mtdconcat: Check _read, _write callbacks existence before
assignment

 Documentation/devicetree/bindings/mtd/gpmc-nand.txt               |
 2 +- Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt
 |  27 ----
 Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml |
 42 ++++++ MAINTAINERS
      |   4 +- drivers/mtd/Kconfig
          |  10 +- drivers/mtd/ftl.c
              |   2 +- drivers/mtd/maps/Kconfig
                  |  23 ---- drivers/mtd/maps/Makefile
                        |   1 - drivers/mtd/maps/pmcmsp-flash.c
                           | 227 -------------------------------
 drivers/mtd/mtd_blkdevs.c                                         |
 60 +------- drivers/mtd/mtdblock.c
        |   4 + drivers/mtd/mtdblock_ro.c
           |   4 + drivers/mtd/mtdconcat.c
              |  33 +++-- drivers/mtd/nand/raw/Kconfig
                     |   4 +- drivers/mtd/nand/raw/cafe_nand.c
                         |   4 +-
 drivers/mtd/nand/raw/intel-nand-controller.c                      |
 27 ++-- drivers/mtd/nand/raw/meson_nand.c
    |   4 +- drivers/mtd/nand/raw/nand_bbt.c
        |  33 +++++ drivers/mtd/nand/raw/omap2.c
               |   2 +- drivers/mtd/nand/spi/core.c
                   |   4 +- drivers/mtd/nand/spi/macronix.c
                       |  16 +-- drivers/mtd/rfd_ftl.c
                            |  46 +++++-- 22 files changed, 198
 insertions(+), 381 deletions(-) delete mode 100644
 Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt
 create mode 100644
 Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml
 delete mode 100644 drivers/mtd/maps/pmcmsp-flash.c


From michael at walle.cc  Fri Sep  3 04:47:29 2021
From: michael at walle.cc (Michael Walle)
Date: Fri, 03 Sep 2021 13:47:29 +0200
Subject: [PATCH] mtd: spi-nor: micron-st: added support for np8p128ax60
In-Reply-To: <CAGiusB29O+sNn9j2U9-VG0QV=9npUuWV=d5_sLyqD54SRgq9qA@mail.gmail.com>
References: <20210831081329.27420-1-andrea.zanotti@tyvak.eu>
 <3462300528bbe71207ef2164411e34d2@walle.cc>
 <CAGiusB1JvHkX7GSvD2JsqKWwC5xBePX_ruWk9nU9gugoroLnKA@mail.gmail.com>
 <CAGiusB0B5dN_K+bW1xudmT6UNmVOL=voBOuSVJeiYo3v6ywO8w@mail.gmail.com>
 <4bf9396505975e3fee2cc6396a6eeff7@walle.cc>
 <CAGiusB29O+sNn9j2U9-VG0QV=9npUuWV=d5_sLyqD54SRgq9qA@mail.gmail.com>
Message-ID: <0719218e274bdffdf76b8689072530d3@walle.cc>

Hi Andrea,

Am 2021-09-01 13:20, schrieb Andrea Zanotti:
> I performed the test with drivers/misc/eeprom/at25.c.
> 
> I configured the DTS as such:
> spi_pcm at 0 {
> compatible = "atmel,at25";
> reg = <0>;
> spi-max-frequency = <50000000>;
> size = <16777216>;
> pagesize = <64>;
> address-width = <24>;
> label = "micron_pcm";
> };
> and activated the driver itself in the kernel configuration.
> 
> I think the system is recognizing it:
> # ls -l /sys/bus/spi/devices/spi0.0/eeprom
> -rw-------    1 root     root      16777216 Jan  1 00:01
> /sys/bus/spi/devices/spi0.0/eeprom
> 
> However, if I am not wrong (again, please correct me if I am wrong)
> this driver does not
> work with the MTD layer (I am booting with the following cmdline 
> bootargs:
> mtdparts=micron_pcm:128k(bootstrap),128k(fdt),10M(kernel/rootfs),-(spare)
> and I expected to have the same partitions as before, but of course
> they are missing.)

You are correct, there is no mtd layer for an eeprom device. If you
need the partitioning, the at25 won't work.

> I am checking the Company ID on the document "JEP106BC", revisioned on
> June 2020,
> downloaded from here 
> https://www.jedec.org/system/files/docs/JEP106BC.pdf.

Btw theres one from Feb 2021, but it doesn't really matter.

> STMicroelectronics should be 20
> Micron should be 2C

which matches the micron_parts[] and st_parts[].

> Intel is advertised as 89, in Table 1 "Manufacturer's Identification 
> Code".
> 
> How do you suggest to proceed?

I'm not sure, it this flash was originally made by intel or if its a
mistake. If its made by intel it probably should go into intel.c

Tudor is working on a larger patchset which addresses flash id
collisions [1]. If it is a mistake, then it should probably go into
the new collisions table which is introduced in this patchset.

Btw. AFAIK new flash additions are delayed until that patchset
is merged.

[1] 
https://lore.kernel.org/linux-mtd/20210727045222.905056-1-tudor.ambarus at microchip.com/

-michael


From greg at kroah.com  Fri Sep  3 06:57:09 2021
From: greg at kroah.com (Greg KH)
Date: Fri, 3 Sep 2021 15:57:09 +0200
Subject: [PATCH 5.4 0/4] backport fscrypt symlink fixes to 5.4
In-Reply-To: <20210901164041.176238-1-ebiggers@kernel.org>
References: <20210901164041.176238-1-ebiggers@kernel.org>
Message-ID: <YTIptf2dFHf9sSIY@kroah.com>

On Wed, Sep 01, 2021 at 09:40:37AM -0700, Eric Biggers wrote:
> This series backports some patches that failed to apply to 5.4-stable
> due to the prototype of inode_operations::getattr having changed in
> v5.12, as well several other conflicts.  Please apply to 5.4-stable.
> 
> Eric Biggers (4):
>   fscrypt: add fscrypt_symlink_getattr() for computing st_size
>   ext4: report correct st_size for encrypted symlinks
>   f2fs: report correct st_size for encrypted symlinks
>   ubifs: report correct st_size for encrypted symlinks
> 
>  fs/crypto/hooks.c       | 44 +++++++++++++++++++++++++++++++++++++++++
>  fs/ext4/symlink.c       | 11 ++++++++++-
>  fs/f2fs/namei.c         | 11 ++++++++++-
>  fs/ubifs/file.c         | 12 ++++++++++-
>  include/linux/fscrypt.h |  7 +++++++
>  5 files changed, 82 insertions(+), 3 deletions(-)
> 
> -- 
> 2.33.0
> 

All now queued up, thanks.

greg k-h


From gregkh at linuxfoundation.org  Fri Sep  3 06:58:16 2021
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Fri, 03 Sep 2021 15:58:16 +0200
Subject: Patch "ext4: report correct st_size for encrypted symlinks" has been
 added to the 5.4-stable tree
In-Reply-To: <20210901164041.176238-3-ebiggers@kernel.org>
Message-ID: <1630677496202255@kroah.com>


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

    ext4: report correct st_size for encrypted symlinks

to the 5.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:
     ext4-report-correct-st_size-for-encrypted-symlinks.patch
and it can be found in the queue-5.4 subdirectory.

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


>From foo at baz Fri Sep  3 03:56:23 PM CEST 2021
From: Eric Biggers <ebiggers at kernel.org>
Date: Wed,  1 Sep 2021 09:40:39 -0700
Subject: ext4: report correct st_size for encrypted symlinks
To: stable at vger.kernel.org
Cc: linux-fscrypt at vger.kernel.org, linux-ext4 at vger.kernel.org, linux-f2fs-devel at lists.sourceforge.net, linux-mtd at lists.infradead.org
Message-ID: <20210901164041.176238-3-ebiggers at kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 8c4bca10ceafc43b1ca0a9fab5fa27e13cbce99e upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after ext4_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: f348c252320b ("ext4 crypto: add symlink encryption")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-3-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 fs/ext4/symlink.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

--- a/fs/ext4/symlink.c
+++ b/fs/ext4/symlink.c
@@ -52,10 +52,19 @@ static const char *ext4_encrypted_get_li
 	return paddr;
 }
 
+static int ext4_encrypted_symlink_getattr(const struct path *path,
+					  struct kstat *stat, u32 request_mask,
+					  unsigned int query_flags)
+{
+	ext4_getattr(path, stat, request_mask, query_flags);
+
+	return fscrypt_symlink_getattr(path, stat);
+}
+
 const struct inode_operations ext4_encrypted_symlink_inode_operations = {
 	.get_link	= ext4_encrypted_get_link,
 	.setattr	= ext4_setattr,
-	.getattr	= ext4_getattr,
+	.getattr	= ext4_encrypted_symlink_getattr,
 	.listxattr	= ext4_listxattr,
 };
 


Patches currently in stable-queue which might be from ebiggers at kernel.org are

queue-5.4/ubifs-report-correct-st_size-for-encrypted-symlinks.patch
queue-5.4/ext4-report-correct-st_size-for-encrypted-symlinks.patch
queue-5.4/fscrypt-add-fscrypt_symlink_getattr-for-computing-st_size.patch
queue-5.4/f2fs-report-correct-st_size-for-encrypted-symlinks.patch


From gregkh at linuxfoundation.org  Fri Sep  3 06:58:16 2021
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Fri, 03 Sep 2021 15:58:16 +0200
Subject: Patch "f2fs: report correct st_size for encrypted symlinks" has been
 added to the 5.4-stable tree
In-Reply-To: <20210901164041.176238-4-ebiggers@kernel.org>
Message-ID: <16306774969145@kroah.com>


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

    f2fs: report correct st_size for encrypted symlinks

to the 5.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:
     f2fs-report-correct-st_size-for-encrypted-symlinks.patch
and it can be found in the queue-5.4 subdirectory.

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


>From foo at baz Fri Sep  3 03:56:23 PM CEST 2021
From: Eric Biggers <ebiggers at kernel.org>
Date: Wed,  1 Sep 2021 09:40:40 -0700
Subject: f2fs: report correct st_size for encrypted symlinks
To: stable at vger.kernel.org
Cc: linux-fscrypt at vger.kernel.org, linux-ext4 at vger.kernel.org, linux-f2fs-devel at lists.sourceforge.net, linux-mtd at lists.infradead.org
Message-ID: <20210901164041.176238-4-ebiggers at kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 461b43a8f92e68e96c4424b31e15f2b35f1bbfa9 upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after f2fs_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: cbaf042a3cc6 ("f2fs crypto: add symlink encryption")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-4-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 fs/f2fs/namei.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -1256,9 +1256,18 @@ static const char *f2fs_encrypted_get_li
 	return target;
 }
 
+static int f2fs_encrypted_symlink_getattr(const struct path *path,
+					  struct kstat *stat, u32 request_mask,
+					  unsigned int query_flags)
+{
+	f2fs_getattr(path, stat, request_mask, query_flags);
+
+	return fscrypt_symlink_getattr(path, stat);
+}
+
 const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
 	.get_link       = f2fs_encrypted_get_link,
-	.getattr	= f2fs_getattr,
+	.getattr	= f2fs_encrypted_symlink_getattr,
 	.setattr	= f2fs_setattr,
 #ifdef CONFIG_F2FS_FS_XATTR
 	.listxattr	= f2fs_listxattr,


Patches currently in stable-queue which might be from ebiggers at kernel.org are

queue-5.4/ubifs-report-correct-st_size-for-encrypted-symlinks.patch
queue-5.4/ext4-report-correct-st_size-for-encrypted-symlinks.patch
queue-5.4/fscrypt-add-fscrypt_symlink_getattr-for-computing-st_size.patch
queue-5.4/f2fs-report-correct-st_size-for-encrypted-symlinks.patch


From gregkh at linuxfoundation.org  Fri Sep  3 06:58:16 2021
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Fri, 03 Sep 2021 15:58:16 +0200
Subject: Patch "fscrypt: add fscrypt_symlink_getattr() for computing st_size"
 has been added to the 5.4-stable tree
In-Reply-To: <20210901164041.176238-2-ebiggers@kernel.org>
Message-ID: <1630677496120@kroah.com>


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

    fscrypt: add fscrypt_symlink_getattr() for computing st_size

to the 5.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:
     fscrypt-add-fscrypt_symlink_getattr-for-computing-st_size.patch
and it can be found in the queue-5.4 subdirectory.

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


>From foo at baz Fri Sep  3 03:56:23 PM CEST 2021
From: Eric Biggers <ebiggers at kernel.org>
Date: Wed,  1 Sep 2021 09:40:38 -0700
Subject: fscrypt: add fscrypt_symlink_getattr() for computing st_size
To: stable at vger.kernel.org
Cc: linux-fscrypt at vger.kernel.org, linux-ext4 at vger.kernel.org, linux-f2fs-devel at lists.sourceforge.net, linux-mtd at lists.infradead.org
Message-ID: <20210901164041.176238-2-ebiggers at kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit d18760560593e5af921f51a8c9b64b6109d634c2 upstream.

Add a helper function fscrypt_symlink_getattr() which will be called
from the various filesystems' ->getattr() methods to read and decrypt
the target of encrypted symlinks in order to report the correct st_size.

Detailed explanation:

As required by POSIX and as documented in various man pages, st_size for
a symlink is supposed to be the length of the symlink target.
Unfortunately, st_size has always been wrong for encrypted symlinks
because st_size is populated from i_size from disk, which intentionally
contains the length of the encrypted symlink target.  That's slightly
greater than the length of the decrypted symlink target (which is the
symlink target that userspace usually sees), and usually won't match the
length of the no-key encoded symlink target either.

This hadn't been fixed yet because reporting the correct st_size would
require reading the symlink target from disk and decrypting or encoding
it, which historically has been considered too heavyweight to do in
->getattr().  Also historically, the wrong st_size had only broken a
test (LTP lstat03) and there were no known complaints from real users.
(This is probably because the st_size of symlinks isn't used too often,
and when it is, typically it's for a hint for what buffer size to pass
to readlink() -- which a slightly-too-large size still works for.)

However, a couple things have changed now.  First, there have recently
been complaints about the current behavior from real users:

- Breakage in rpmbuild:
  https://github.com/rpm-software-management/rpm/issues/1682
  https://github.com/google/fscrypt/issues/305

- Breakage in toybox cpio:
  https://www.mail-archive.com/toybox at lists.landley.net/msg07193.html

- Breakage in libgit2: https://issuetracker.google.com/issues/189629152
  (on Android public issue tracker, requires login)

Second, we now cache decrypted symlink targets in ->i_link.  Therefore,
taking the performance hit of reading and decrypting the symlink target
in ->getattr() wouldn't be as big a deal as it used to be, since usually
it will just save having to do the same thing later.

Also note that eCryptfs ended up having to read and decrypt symlink
targets in ->getattr() as well, to fix this same issue; see
commit 3a60a1686f0d ("eCryptfs: Decrypt symlink target for stat size").

So, let's just bite the bullet, and read and decrypt the symlink target
in ->getattr() in order to report the correct st_size.  Add a function
fscrypt_symlink_getattr() which the filesystems will call to do this.

(Alternatively, we could store the decrypted size of symlinks on-disk.
But there isn't a great place to do so, and encryption is meant to hide
the original size to some extent; that property would be lost.)

Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-2-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 fs/crypto/hooks.c       |   44 ++++++++++++++++++++++++++++++++++++++++++++
 include/linux/fscrypt.h |    7 +++++++
 2 files changed, 51 insertions(+)

--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -305,3 +305,47 @@ err_kfree:
 	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(fscrypt_get_symlink);
+
+/**
+ * fscrypt_symlink_getattr() - set the correct st_size for encrypted symlinks
+ * @path: the path for the encrypted symlink being queried
+ * @stat: the struct being filled with the symlink's attributes
+ *
+ * Override st_size of encrypted symlinks to be the length of the decrypted
+ * symlink target (or the no-key encoded symlink target, if the key is
+ * unavailable) rather than the length of the encrypted symlink target.  This is
+ * necessary for st_size to match the symlink target that userspace actually
+ * sees.  POSIX requires this, and some userspace programs depend on it.
+ *
+ * This requires reading the symlink target from disk if needed, setting up the
+ * inode's encryption key if possible, and then decrypting or encoding the
+ * symlink target.  This makes lstat() more heavyweight than is normally the
+ * case.  However, decrypted symlink targets will be cached in ->i_link, so
+ * usually the symlink won't have to be read and decrypted again later if/when
+ * it is actually followed, readlink() is called, or lstat() is called again.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat)
+{
+	struct dentry *dentry = path->dentry;
+	struct inode *inode = d_inode(dentry);
+	const char *link;
+	DEFINE_DELAYED_CALL(done);
+
+	/*
+	 * To get the symlink target that userspace will see (whether it's the
+	 * decrypted target or the no-key encoded target), we can just get it in
+	 * the same way the VFS does during path resolution and readlink().
+	 */
+	link = READ_ONCE(inode->i_link);
+	if (!link) {
+		link = inode->i_op->get_link(dentry, inode, &done);
+		if (IS_ERR(link))
+			return PTR_ERR(link);
+	}
+	stat->size = strlen(link);
+	do_delayed_call(&done);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fscrypt_symlink_getattr);
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -298,6 +298,7 @@ extern int __fscrypt_encrypt_symlink(str
 extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
 				       unsigned int max_size,
 				       struct delayed_call *done);
+int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat);
 static inline void fscrypt_set_ops(struct super_block *sb,
 				   const struct fscrypt_operations *s_cop)
 {
@@ -585,6 +586,12 @@ static inline const char *fscrypt_get_sy
 	return ERR_PTR(-EOPNOTSUPP);
 }
 
+static inline int fscrypt_symlink_getattr(const struct path *path,
+					  struct kstat *stat)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline void fscrypt_set_ops(struct super_block *sb,
 				   const struct fscrypt_operations *s_cop)
 {


Patches currently in stable-queue which might be from ebiggers at kernel.org are

queue-5.4/ubifs-report-correct-st_size-for-encrypted-symlinks.patch
queue-5.4/ext4-report-correct-st_size-for-encrypted-symlinks.patch
queue-5.4/fscrypt-add-fscrypt_symlink_getattr-for-computing-st_size.patch
queue-5.4/f2fs-report-correct-st_size-for-encrypted-symlinks.patch


From gregkh at linuxfoundation.org  Fri Sep  3 06:58:16 2021
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Fri, 03 Sep 2021 15:58:16 +0200
Subject: Patch "ubifs: report correct st_size for encrypted symlinks" has been
 added to the 5.4-stable tree
In-Reply-To: <20210901164041.176238-5-ebiggers@kernel.org>
Message-ID: <163067749626136@kroah.com>


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

    ubifs: report correct st_size for encrypted symlinks

to the 5.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:
     ubifs-report-correct-st_size-for-encrypted-symlinks.patch
and it can be found in the queue-5.4 subdirectory.

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


>From foo at baz Fri Sep  3 03:56:23 PM CEST 2021
From: Eric Biggers <ebiggers at kernel.org>
Date: Wed,  1 Sep 2021 09:40:41 -0700
Subject: ubifs: report correct st_size for encrypted symlinks
To: stable at vger.kernel.org
Cc: linux-fscrypt at vger.kernel.org, linux-ext4 at vger.kernel.org, linux-f2fs-devel at lists.sourceforge.net, linux-mtd at lists.infradead.org
Message-ID: <20210901164041.176238-5-ebiggers at kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 064c734986011390b4d111f1a99372b7f26c3850 upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after ubifs_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: ca7f85be8d6c ("ubifs: Add support for encrypted symlinks")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-5-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 fs/ubifs/file.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1629,6 +1629,16 @@ static const char *ubifs_get_link(struct
 	return fscrypt_get_symlink(inode, ui->data, ui->data_len, done);
 }
 
+static int ubifs_symlink_getattr(const struct path *path, struct kstat *stat,
+				 u32 request_mask, unsigned int query_flags)
+{
+	ubifs_getattr(path, stat, request_mask, query_flags);
+
+	if (IS_ENCRYPTED(d_inode(path->dentry)))
+		return fscrypt_symlink_getattr(path, stat);
+	return 0;
+}
+
 const struct address_space_operations ubifs_file_address_operations = {
 	.readpage       = ubifs_readpage,
 	.writepage      = ubifs_writepage,
@@ -1654,7 +1664,7 @@ const struct inode_operations ubifs_file
 const struct inode_operations ubifs_symlink_inode_operations = {
 	.get_link    = ubifs_get_link,
 	.setattr     = ubifs_setattr,
-	.getattr     = ubifs_getattr,
+	.getattr     = ubifs_symlink_getattr,
 #ifdef CONFIG_UBIFS_FS_XATTR
 	.listxattr   = ubifs_listxattr,
 #endif


Patches currently in stable-queue which might be from ebiggers at kernel.org are

queue-5.4/ubifs-report-correct-st_size-for-encrypted-symlinks.patch
queue-5.4/ext4-report-correct-st_size-for-encrypted-symlinks.patch
queue-5.4/fscrypt-add-fscrypt_symlink_getattr-for-computing-st_size.patch
queue-5.4/f2fs-report-correct-st_size-for-encrypted-symlinks.patch


From hca at linux.ibm.com  Fri Sep  3 07:06:15 2021
From: hca at linux.ibm.com (Heiko Carstens)
Date: Fri, 3 Sep 2021 16:06:15 +0200
Subject: [PATCH 9/9] s390/block/xpram: add error handling support for
 add_disk()
In-Reply-To: <20210902174105.2418771-10-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-10-mcgrof@kernel.org>
Message-ID: <YTIr1w/qPvgioUfL@osiris>

On Thu, Sep 02, 2021 at 10:41:05AM -0700, Luis Chamberlain wrote:
> We never checked for errors on add_disk() as this function
> returned void. Now that this is fixed, use the shiny new
> error handling.
> 
> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
> ---
>  drivers/s390/block/xpram.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
> index ce98fab4d43c..ed3904b6a9c8 100644
> --- a/drivers/s390/block/xpram.c
> +++ b/drivers/s390/block/xpram.c
> @@ -371,7 +371,9 @@ static int __init xpram_setup_blkdev(void)
>  		disk->private_data = &xpram_devices[i];
>  		sprintf(disk->disk_name, "slram%d", i);
>  		set_capacity(disk, xpram_sizes[i] << 1);
> -		add_disk(disk);
> +		rc = add_disk(disk);
> +		if (rc)
> +			goto out;

Hmm, this is a more or less dead device driver, and I'm wondering if
we shouldn't remove it instead. But anyway, your patch is not correct:

- del_gendisk for all registered disks has to be called
- unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME) is missing as well

That would be more or or less xpram_exit with parameter.

You can send a new patch or I can provide a proper one, whatever you
prefer.


From hca at linux.ibm.com  Fri Sep  3 07:08:48 2021
From: hca at linux.ibm.com (Heiko Carstens)
Date: Fri, 3 Sep 2021 16:08:48 +0200
Subject: [PATCH 7/9] s390/block/dcssblk: add error handling support for
 add_disk()
In-Reply-To: <20210902174105.2418771-8-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-8-mcgrof@kernel.org>
Message-ID: <YTIscKy+jg5L/TMh@osiris>

On Thu, Sep 02, 2021 at 10:41:03AM -0700, Luis Chamberlain wrote:
> We never checked for errors on add_disk() as this function
> returned void. Now that this is fixed, use the shiny new
> error handling.
> 
> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
> ---
>  drivers/s390/block/dcssblk.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
> index 5be3d1c39a78..b0fd5009a12e 100644
> --- a/drivers/s390/block/dcssblk.c
> +++ b/drivers/s390/block/dcssblk.c
> @@ -696,7 +696,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
>  	}
>  
>  	get_device(&dev_info->dev);
> -	device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> +	rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> +	if (rc)
> +		goto put_dev;

This looks not correct to me. We seem to have now in case of an error:

- reference count imbalance (= memory leak)
- dax cleanup is missing


From hca at linux.ibm.com  Fri Sep  3 07:30:38 2021
From: hca at linux.ibm.com (Heiko Carstens)
Date: Fri, 3 Sep 2021 16:30:38 +0200
Subject: [PATCH 8/9] s390/block/scm_blk: add error handling support for
 add_disk()
In-Reply-To: <20210902174105.2418771-9-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-9-mcgrof@kernel.org>
Message-ID: <YTIxjn1X0ES8my2a@osiris>

On Thu, Sep 02, 2021 at 10:41:04AM -0700, Luis Chamberlain wrote:
> We never checked for errors on add_disk() as this function
> returned void. Now that this is fixed, use the shiny new
> error handling.
> 
> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
> ---
>  drivers/s390/block/scm_blk.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)

Acked-by: Heiko Carstens <hca at linux.ibm.com>


From robh at kernel.org  Fri Sep  3 13:41:45 2021
From: robh at kernel.org (Rob Herring)
Date: Fri, 3 Sep 2021 15:41:45 -0500
Subject: [PATCH v2 2/6] dt-bindings: memory-controllers: ti, gpmc: Convert
 to yaml
In-Reply-To: <715fe0ee-a38c-c2ca-5e29-79fa0887bea0@kernel.org>
References: <20210902095609.16583-1-rogerq@kernel.org>
 <20210902095609.16583-3-rogerq@kernel.org>
 <YTEsiJiLMRYon5s3@robh.at.kernel.org>
 <715fe0ee-a38c-c2ca-5e29-79fa0887bea0@kernel.org>
Message-ID: <CAL_Jsq+HTJhVGrjJ9EdbE0_rpMtpa=nbm7CyObHHEpocy-A3+A@mail.gmail.com>

On Fri, Sep 3, 2021 at 4:35 AM Roger Quadros <rogerq at kernel.org> wrote:
>
> Hi Rob,
>
> On 02/09/2021 22:56, Rob Herring wrote:
> > On Thu, Sep 02, 2021 at 12:56:05PM +0300, Roger Quadros wrote:
> >> Convert omap-gpmc.txt to ti,gpmc.yaml.
> >>
> >> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> >> ---
> >>  .../bindings/memory-controllers/omap-gpmc.txt | 157 --------
> >>  .../bindings/memory-controllers/ti,gpmc.yaml  | 364 ++++++++++++++++++
> >>  .../devicetree/bindings/mtd/gpmc-nand.txt     |   2 +-
> >>  .../devicetree/bindings/mtd/gpmc-nor.txt      |   4 +-
> >>  .../devicetree/bindings/mtd/gpmc-onenand.txt  |   2 +-
> >>  .../devicetree/bindings/net/gpmc-eth.txt      |   4 +-
> >>  6 files changed, 370 insertions(+), 163 deletions(-)
> >>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> >>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> >
> >> diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> >> new file mode 100644
> >> index 000000000000..b7d43370a95d
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> >> @@ -0,0 +1,364 @@
> >> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/memory-controllers/ti,gpmc.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: Texas Instruments GPMC Memory Controller device-tree bindings
> >> +
> >> +maintainers:
> >> +  - Tony Lindgren <tony at atomide.com>
> >> +  - Roger Quadros <rogerq at kernel.org>
> >> +
> >> +description:
> >> +  The GPMC is a unified memory controller dedicated for interfacing
> >> +  with external memory devices like
> >> +  - Asynchronous SRAM-like memories and ASICs
> >> +  - Asynchronous, synchronous, and page mode burst NOR flash
> >> +  - NAND flash
> >> +  - Pseudo-SRAM devices
> >> +
> >> +properties:
> >> +  compatible:
> >> +    items:
> >> +      - enum:
> >> +          - ti,omap2420-gpmc
> >> +          - ti,omap2430-gpmc
> >> +          - ti,omap3430-gpmc
> >> +          - ti,omap4430-gpmc
> >> +          - ti,am3352-gpmc
> >> +
> >> +  reg:
> >> +    items:
> >> +      - description:
> >> +          Configuration registers for the controller.
> >
> > Just 'maxItems: 1' is sufficient.
> >
> >> +
> >> +  interrupts: true
> >
> > Need to define how many.
> >
> >> +
> >> +  clocks:
> >> +    maxItems: 1
> >> +    description: |
> >> +      Functional clock. Used for bus timing calculations and
> >> +      GPMC configuration.
> >> +
> >> +  clock-names:
> >> +    items:
> >> +      - const: fck
> >> +
> >> +  dmas:
> >> +    items:
> >> +      - description: DMA channel for GPMC NAND prefetch
> >> +
> >> +  dma-names:
> >> +    items:
> >> +      - const: rxtx
> >> +
> >> +  "#address-cells":
> >> +    const: 2
> >> +
> >> +  "#size-cells":
> >> +    const: 1
> >> +
> >> +  gpmc,num-cs:
> >> +    description: maximum number of supported chip-select lines.
> >> +    $ref: /schemas/types.yaml#/definitions/uint32
> >> +
> >> +  gpmc,num-waitpins:
> >> +    description: maximum number of supported wait pins.
> >> +    $ref: /schemas/types.yaml#/definitions/uint32
> >> +
> >> +  ranges:
> >> +    minItems: 1
> >> +    description: |
> >> +      Must be set up to reflect the memory layout with four
> >> +      integer values for each chip-select line in use,
> >> +      <cs-number> 0 <physical address of mapping> <size>
> >> +
> >> +    items:
> >> +      - description: NAND bank 0
> >> +      - description: NOR/SRAM bank 0
> >> +      - description: NOR/SRAM bank 1
> >> +
> >> +  '#interrupt-cells':
> >> +    const: 2
> >> +
> >> +  interrupt-controller:
> >> +    description: |
> >> +      The GPMC driver implements and interrupt controller for
> >> +      the NAND events "fifoevent" and "termcount" plus the
> >> +      rising/falling edges on the GPMC_WAIT pins.
> >> +      The interrupt number mapping is as follows
> >> +      0 - NAND_fifoevent
> >> +      1 - NAND_termcount
> >> +      2 - GPMC_WAIT0 pin edge
> >> +      3 - GPMC_WAIT1 pin edge, and so on.
> >> +
> >> +  '#gpio-cells':
> >> +     const: 2
> >> +
> >> +  gpio-controller:
> >> +    description: |
> >> +      The GPMC driver implements a GPIO controller for the
> >> +      GPMC WAIT pins that can be used as general purpose inputs.
> >> +      0 maps to GPMC_WAIT0 pin.
> >> +
> >> +  ti,hwmods:
> >> +    description:
> >> +      Name of the HWMOD associated with GPMC. This is for legacy
> >> +      omap2/3 platforms only.
> >> +    $ref: /schemas/types.yaml#/definitions/string
> >> +    deprecated: true
> >> +
> >> +  ti,no-idle-on-init:
> >> +    description:
> >> +      Prevent idling the module at init. This is for legacy omap2/3
> >> +      platforms only.
> >> +    type: boolean
> >> +    deprecated: true
> >> +
> >> +patternProperties:
> >> +#  "@[0-3],[a-f0-9]+$":>> +  "^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-fA-F]+(,[0-9a-fA-F]+)*$":
>
> >
> > Why the commented regex. There's no need for a full regex as we already
> > do that elsewhere. You only need to define the unit-address format.
>
> This should be
>   "@[0-7],[a-f0-9]+$":
>
> I added the full regex during debug but forgot to take it off.
>
> >
> >> +    type: object
> >> +    description: |
> >> +      The child device node represents the device connected to the GPMC
> >> +      bus. The device can be a NAND controller, SRAM device, NOR device
> >> +      or an ASIC.
> >> +
> >> +    properties:
> >> +      compatible:
> >> +        description:
> >> +          Compatible of attached device.
> >
> > Duh. Drop.
> >
> >> +
> >> +      reg:
> >> +        items:
> >> +        - description: Register access space for the device
> >
> > A device with 2 register ranges isn't allowed?
>
> GPMC is actually a memory controller and we are describing the children here.

Yes, I understand what it is.

> Each child has to have a register range.

What you are saying here with the schema is there is only 1 register
range allowed for the child node. You don't know how many a child
device may have. That's a property of the child device. You just need
'reg: true' here.

Rob


From mcgrof at kernel.org  Fri Sep  3 18:44:54 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Fri, 3 Sep 2021 18:44:54 -0700
Subject: [PATCH 9/9] s390/block/xpram: add error handling support for
 add_disk()
In-Reply-To: <YTIr1w/qPvgioUfL@osiris>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-10-mcgrof@kernel.org>
 <YTIr1w/qPvgioUfL@osiris>
Message-ID: <YTLPlmWMhL4+03UH@bombadil.infradead.org>

On Fri, Sep 03, 2021 at 04:06:15PM +0200, Heiko Carstens wrote:
> On Thu, Sep 02, 2021 at 10:41:05AM -0700, Luis Chamberlain wrote:
> > We never checked for errors on add_disk() as this function
> > returned void. Now that this is fixed, use the shiny new
> > error handling.
> > 
> > Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
> > ---
> >  drivers/s390/block/xpram.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
> > index ce98fab4d43c..ed3904b6a9c8 100644
> > --- a/drivers/s390/block/xpram.c
> > +++ b/drivers/s390/block/xpram.c
> > @@ -371,7 +371,9 @@ static int __init xpram_setup_blkdev(void)
> >  		disk->private_data = &xpram_devices[i];
> >  		sprintf(disk->disk_name, "slram%d", i);
> >  		set_capacity(disk, xpram_sizes[i] << 1);
> > -		add_disk(disk);
> > +		rc = add_disk(disk);
> > +		if (rc)
> > +			goto out;
> 
> Hmm, this is a more or less dead device driver, and I'm wondering if
> we shouldn't remove it instead. But anyway, your patch is not correct:
> 
> - del_gendisk for all registered disks has to be called
> - unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME) is missing as well
> 
> That would be more or or less xpram_exit with parameter.
> 
> You can send a new patch or I can provide a proper one, whatever you
> prefer.

You are more familiar with the code so it would be great if you can send
a patch replacement and I will drop mine. I have quite a bit of other
conversions to deal with.

 Luis


From mcgrof at kernel.org  Fri Sep  3 18:46:26 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Fri, 3 Sep 2021 18:46:26 -0700
Subject: [PATCH 7/9] s390/block/dcssblk: add error handling support for
 add_disk()
In-Reply-To: <YTIscKy+jg5L/TMh@osiris>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-8-mcgrof@kernel.org>
 <YTIscKy+jg5L/TMh@osiris>
Message-ID: <YTLP8mYBX37R++9E@bombadil.infradead.org>

On Fri, Sep 03, 2021 at 04:08:48PM +0200, Heiko Carstens wrote:
> On Thu, Sep 02, 2021 at 10:41:03AM -0700, Luis Chamberlain wrote:
> > We never checked for errors on add_disk() as this function
> > returned void. Now that this is fixed, use the shiny new
> > error handling.
> > 
> > Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
> > ---
> >  drivers/s390/block/dcssblk.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
> > index 5be3d1c39a78..b0fd5009a12e 100644
> > --- a/drivers/s390/block/dcssblk.c
> > +++ b/drivers/s390/block/dcssblk.c
> > @@ -696,7 +696,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
> >  	}
> >  
> >  	get_device(&dev_info->dev);
> > -	device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> > +	rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> > +	if (rc)
> > +		goto put_dev;
> 
> This looks not correct to me. We seem to have now in case of an error:
> 
> - reference count imbalance (= memory leak)
> - dax cleanup is missing

Care to provide an alternative?

  Luis


From miquel.raynal at bootlin.com  Sun Sep  5 03:08:45 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Sun, 5 Sep 2021 12:08:45 +0200
Subject: [GIT PULL] [v2] mtd: Changes for 5.15
Message-ID: <20210905120845.09877033@xps13>

Hello Linus,

I was checking why the pull request sent on Thursday 3rd did not
receive any reply and I figured out that the final push operation
did not make it to the kernel.org repository.

I just pushed once again the missing change (a merge commit) and
re-generated the below request.

This is the final MTD PR for 5.15.

Thanks,
Miqu?l

The following changes since commit e73f0f0ee7541171d89f2e2491130c7771ba58d3:

  Linux 5.14-rc1 (2021-07-11 15:07:40 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git tags/mtd/for-5.15

for you to fetch changes up to c1fe77e42440d2cad76055df6fb58caabf622d51:

  Merge tag 'nand/for-5.15' into mtd/next (2021-09-03 00:04:16 +0200)

----------------------------------------------------------------
MTD changes:
* blkdevs:
  - Simplify the refcounting in blktrans_{open, release}
  - Simplify blktrans_getgeo
  - Remove blktrans_ref_mutex
  - Simplify blktrans_dev_get
  - Use lockdep_assert_held
  - Don't hold del_mtd_blktrans_dev in blktrans_{open, release}
* ftl:
  - Don't cast away the type when calling add_mtd_blktrans_dev
  - Don't cast away the type when calling add_mtd_blktrans_dev
  - Use container_of() rather than cast
  - Fix use-after-free
  - Add discard support
  - Allow use of MTD_RAM for testing purposes
* concat:
  - Check _read, _write callbacks existence before assignment
  - Judge callback existence based on the master
* maps:
  - Maps: remove dead MTD map driver for PMC-Sierra MSP boards
* mtdblock:
  - Warn if added for a NAND device
  - Add comment about UBI block devices
  - Update old JFFS2 mention in Kconfig
* partitions:
  - Redboot: convert to YAML

NAND core changes:
* Repair Miquel Raynal's email address in MAINTAINERS
* Fix a couple of spelling mistakes in Kconfig
* bbt: Skip bad blocks when searching for the BBT in NAND
* Remove never changed ret variable

Raw NAND changes:
* cafe: Fix a resource leak in the error handling path of 'cafe_nand_probe()'
* intel: Fix error handling in probe
* omap: Fix kernel doc warning on 'calcuate' typo
* gpmc: Fix the ECC bytes vs. OOB bytes equation

SPI-NAND core changes:
* Properly fill the OOB area.
* Fix comment

SPI-NAND drivers changes:
* macronix: Add Quad support for serial NAND flash

----------------------------------------------------------------
Christoph Hellwig (8):
      mtd_blkdevs: don't hold del_mtd_blktrans_dev in blktrans_{open, release}
      mtd_blkdevs: use lockdep_assert_held
      mtd/ftl: don't cast away the type when calling add_mtd_blktrans_dev
      mtd/rfd_ftl: don't cast away the type when calling add_mtd_blktrans_dev
      mtd_blkdevs: simplify blktrans_dev_get
      mtd_blkdevs: remove blktrans_ref_mutex
      mtd_blkdevs: simplify blktrans_getgeo
      mtd_blkdevs: simplify the refcounting in blktrans_{open, release}

Christophe JAILLET (1):
      mtd: rawnand: cafe: Fix a resource leak in the error handling path of 'cafe_nand_probe()'

Colin Ian King (1):
      mtd: rawnand: Fix a couple of spelling mistakes in Kconfig

Corentin Labbe (1):
      dt_bindings: mtd: partitions: redboot: convert to YAML

Daniel Palmer (1):
      mtd: spinand: core: Properly fill the OOB area.

Evgeny Novikov (1):
      mtd: rawnand: intel: Fix error handling in probe

Ezequiel Garcia (3):
      mtdblock: Update old JFFS2 mention in Kconfig
      mtdblock: Add comment about UBI block devices
      mtdblock: Warn if added for a NAND device

Jaime Liao (1):
      mtd: spinand: macronix: Add Quad support for serial NAND flash

Jason Wang (1):
      mtd: rawnand: remove never changed ret variable

Lukas Bulwahn (2):
      MAINTAINERS: repair Miquel Raynal's email address
      mtd: maps: remove dead MTD map driver for PMC-Sierra MSP boards

Miquel Raynal (3):
      dt-bindings: mtd: gpmc: Fix the ECC bytes vs. OOB bytes equation
      mtd: spinand: Fix comment
      Merge tag 'nand/for-5.15' into mtd/next

Sean Young (4):
      mtd: rfd_ftl: allow use of MTD_RAM for testing purposes
      mtd: rfd_ftl: add discard support
      mtd: rfd_ftl: fix use-after-free
      mtd: rfd_ftl: use container_of() rather than cast

Stefan Riedmueller (1):
      mtd: rawnand: nand_bbt: Skip bad blocks when searching for the BBT in NAND

Vladimir Molokov (1):
      mtd: rawnand: omap: Fix kernel doc warning on 'calcuate' typo

Zhihao Cheng (2):
      mtd: mtdconcat: Judge callback existence based on the master
      mtd: mtdconcat: Check _read, _write callbacks existence before assignment

 Documentation/devicetree/bindings/mtd/gpmc-nand.txt               |   2 +-
 Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt  |  27 ----------
 Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml |  42 ++++++++++++++++
 MAINTAINERS                                                       |   4 +-
 drivers/mtd/Kconfig                                               |  10 ++--
 drivers/mtd/ftl.c                                                 |   2 +-
 drivers/mtd/maps/Kconfig                                          |  23 ---------
 drivers/mtd/maps/Makefile                                         |   1 -
 drivers/mtd/maps/pmcmsp-flash.c                                   | 227 -----------------------------------------------------------------------------------
 drivers/mtd/mtd_blkdevs.c                                         |  60 +++-------------------
 drivers/mtd/mtdblock.c                                            |   4 ++
 drivers/mtd/mtdblock_ro.c                                         |   4 ++
 drivers/mtd/mtdconcat.c                                           |  33 ++++++++----
 drivers/mtd/nand/raw/Kconfig                                      |   4 +-
 drivers/mtd/nand/raw/cafe_nand.c                                  |   4 +-
 drivers/mtd/nand/raw/intel-nand-controller.c                      |  27 ++++++----
 drivers/mtd/nand/raw/meson_nand.c                                 |   4 +-
 drivers/mtd/nand/raw/nand_bbt.c                                   |  33 ++++++++++++
 drivers/mtd/nand/raw/omap2.c                                      |   2 +-
 drivers/mtd/nand/spi/core.c                                       |   4 +-
 drivers/mtd/nand/spi/macronix.c                                   |  16 +++---
 drivers/mtd/rfd_ftl.c                                             |  46 ++++++++++++++---
 22 files changed, 198 insertions(+), 381 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/partitions/redboot-fis.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/partitions/redboot-fis.yaml
 delete mode 100644 drivers/mtd/maps/pmcmsp-flash.c


From pr-tracker-bot at kernel.org  Sun Sep  5 12:07:02 2021
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Sun, 05 Sep 2021 19:07:02 +0000
Subject: [GIT PULL] mtd: Changes for 5.15
In-Reply-To: <20210903114946.3f874e6e@xps13>
References: <20210903114946.3f874e6e@xps13>
Message-ID: <163086882283.6256.17944151994530666959.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 3 Sep 2021 11:49:46 +0200:

> git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git tags/mtd/for-5.15

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/6b6dc4f40c5264556223ba94693f20d83796ab1f

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From david.oberhollenzer at sigma-star.at  Sun Sep  5 23:26:39 2021
From: david.oberhollenzer at sigma-star.at (David Oberhollenzer)
Date: Mon, 06 Sep 2021 06:26:39 +0000
Subject: [PATCH] Add ubiscan utility
In-Reply-To: <20210817003802.3076-1-dismirlian@gmail.com>
References: <20210817003802.3076-1-dismirlian@gmail.com>
Message-ID: <f0f90cb8-de9e-24e4-64ed-46f2f6ac732c@sigma-star.at>

Hi,

this does sound like a useful utility to me. Sorry to leave you hanging there,
I was also hoping to maybe get some other feedback as well before applying it.

Applied to mtd-utils.git master.

Thanks,

David



From rogerq at kernel.org  Mon Sep  6 00:10:08 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Mon, 6 Sep 2021 10:10:08 +0300
Subject: [PATCH v2 2/6] dt-bindings: memory-controllers: ti, gpmc: Convert
 to yaml
In-Reply-To: <CAL_Jsq+HTJhVGrjJ9EdbE0_rpMtpa=nbm7CyObHHEpocy-A3+A@mail.gmail.com>
References: <20210902095609.16583-1-rogerq@kernel.org>
 <20210902095609.16583-3-rogerq@kernel.org>
 <YTEsiJiLMRYon5s3@robh.at.kernel.org>
 <715fe0ee-a38c-c2ca-5e29-79fa0887bea0@kernel.org>
 <CAL_Jsq+HTJhVGrjJ9EdbE0_rpMtpa=nbm7CyObHHEpocy-A3+A@mail.gmail.com>
Message-ID: <9def1538-fc7e-cc1b-fba4-cba6f230c037@kernel.org>



On 03/09/2021 23:41, Rob Herring wrote:
> On Fri, Sep 3, 2021 at 4:35 AM Roger Quadros <rogerq at kernel.org> wrote:
>>
>> Hi Rob,
>>
>> On 02/09/2021 22:56, Rob Herring wrote:
>>> On Thu, Sep 02, 2021 at 12:56:05PM +0300, Roger Quadros wrote:
>>>> Convert omap-gpmc.txt to ti,gpmc.yaml.
>>>>
>>>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>>>> ---
>>>>  .../bindings/memory-controllers/omap-gpmc.txt | 157 --------
>>>>  .../bindings/memory-controllers/ti,gpmc.yaml  | 364 ++++++++++++++++++
>>>>  .../devicetree/bindings/mtd/gpmc-nand.txt     |   2 +-
>>>>  .../devicetree/bindings/mtd/gpmc-nor.txt      |   4 +-
>>>>  .../devicetree/bindings/mtd/gpmc-onenand.txt  |   2 +-
>>>>  .../devicetree/bindings/net/gpmc-eth.txt      |   4 +-
>>>>  6 files changed, 370 insertions(+), 163 deletions(-)
>>>>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>>>>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>>>
>>>> diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>>>> new file mode 100644
>>>> index 000000000000..b7d43370a95d
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
>>>> @@ -0,0 +1,364 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/memory-controllers/ti,gpmc.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: Texas Instruments GPMC Memory Controller device-tree bindings
>>>> +
>>>> +maintainers:
>>>> +  - Tony Lindgren <tony at atomide.com>
>>>> +  - Roger Quadros <rogerq at kernel.org>
>>>> +
>>>> +description:
>>>> +  The GPMC is a unified memory controller dedicated for interfacing
>>>> +  with external memory devices like
>>>> +  - Asynchronous SRAM-like memories and ASICs
>>>> +  - Asynchronous, synchronous, and page mode burst NOR flash
>>>> +  - NAND flash
>>>> +  - Pseudo-SRAM devices
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    items:
>>>> +      - enum:
>>>> +          - ti,omap2420-gpmc
>>>> +          - ti,omap2430-gpmc
>>>> +          - ti,omap3430-gpmc
>>>> +          - ti,omap4430-gpmc
>>>> +          - ti,am3352-gpmc
>>>> +
>>>> +  reg:
>>>> +    items:
>>>> +      - description:
>>>> +          Configuration registers for the controller.
>>>
>>> Just 'maxItems: 1' is sufficient.
>>>
>>>> +
>>>> +  interrupts: true
>>>
>>> Need to define how many.
>>>
>>>> +
>>>> +  clocks:
>>>> +    maxItems: 1
>>>> +    description: |
>>>> +      Functional clock. Used for bus timing calculations and
>>>> +      GPMC configuration.
>>>> +
>>>> +  clock-names:
>>>> +    items:
>>>> +      - const: fck
>>>> +
>>>> +  dmas:
>>>> +    items:
>>>> +      - description: DMA channel for GPMC NAND prefetch
>>>> +
>>>> +  dma-names:
>>>> +    items:
>>>> +      - const: rxtx
>>>> +
>>>> +  "#address-cells":
>>>> +    const: 2
>>>> +
>>>> +  "#size-cells":
>>>> +    const: 1
>>>> +
>>>> +  gpmc,num-cs:
>>>> +    description: maximum number of supported chip-select lines.
>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>> +
>>>> +  gpmc,num-waitpins:
>>>> +    description: maximum number of supported wait pins.
>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>> +
>>>> +  ranges:
>>>> +    minItems: 1
>>>> +    description: |
>>>> +      Must be set up to reflect the memory layout with four
>>>> +      integer values for each chip-select line in use,
>>>> +      <cs-number> 0 <physical address of mapping> <size>
>>>> +
>>>> +    items:
>>>> +      - description: NAND bank 0
>>>> +      - description: NOR/SRAM bank 0
>>>> +      - description: NOR/SRAM bank 1
>>>> +
>>>> +  '#interrupt-cells':
>>>> +    const: 2
>>>> +
>>>> +  interrupt-controller:
>>>> +    description: |
>>>> +      The GPMC driver implements and interrupt controller for
>>>> +      the NAND events "fifoevent" and "termcount" plus the
>>>> +      rising/falling edges on the GPMC_WAIT pins.
>>>> +      The interrupt number mapping is as follows
>>>> +      0 - NAND_fifoevent
>>>> +      1 - NAND_termcount
>>>> +      2 - GPMC_WAIT0 pin edge
>>>> +      3 - GPMC_WAIT1 pin edge, and so on.
>>>> +
>>>> +  '#gpio-cells':
>>>> +     const: 2
>>>> +
>>>> +  gpio-controller:
>>>> +    description: |
>>>> +      The GPMC driver implements a GPIO controller for the
>>>> +      GPMC WAIT pins that can be used as general purpose inputs.
>>>> +      0 maps to GPMC_WAIT0 pin.
>>>> +
>>>> +  ti,hwmods:
>>>> +    description:
>>>> +      Name of the HWMOD associated with GPMC. This is for legacy
>>>> +      omap2/3 platforms only.
>>>> +    $ref: /schemas/types.yaml#/definitions/string
>>>> +    deprecated: true
>>>> +
>>>> +  ti,no-idle-on-init:
>>>> +    description:
>>>> +      Prevent idling the module at init. This is for legacy omap2/3
>>>> +      platforms only.
>>>> +    type: boolean
>>>> +    deprecated: true
>>>> +
>>>> +patternProperties:
>>>> +#  "@[0-3],[a-f0-9]+$":>> +  "^[a-zA-Z][a-zA-Z0-9,+\\-._]{0,63}@[0-9a-fA-F]+(,[0-9a-fA-F]+)*$":
>>
>>>
>>> Why the commented regex. There's no need for a full regex as we already
>>> do that elsewhere. You only need to define the unit-address format.
>>
>> This should be
>>   "@[0-7],[a-f0-9]+$":
>>
>> I added the full regex during debug but forgot to take it off.
>>
>>>
>>>> +    type: object
>>>> +    description: |
>>>> +      The child device node represents the device connected to the GPMC
>>>> +      bus. The device can be a NAND controller, SRAM device, NOR device
>>>> +      or an ASIC.
>>>> +
>>>> +    properties:
>>>> +      compatible:
>>>> +        description:
>>>> +          Compatible of attached device.
>>>
>>> Duh. Drop.
>>>
>>>> +
>>>> +      reg:
>>>> +        items:
>>>> +        - description: Register access space for the device
>>>
>>> A device with 2 register ranges isn't allowed?
>>
>> GPMC is actually a memory controller and we are describing the children here.
> 
> Yes, I understand what it is.
> 
>> Each child has to have a register range.
> 
> What you are saying here with the schema is there is only 1 register
> range allowed for the child node. You don't know how many a child
> device may have. That's a property of the child device. You just need
> 'reg: true' here.

Now I got it. You are right. Thanks for the explanation :)

cheers,
-roger


From hch at infradead.org  Mon Sep  6 02:15:40 2021
From: hch at infradead.org (Christoph Hellwig)
Date: Mon, 6 Sep 2021 10:15:40 +0100
Subject: [PATCH 9/9] s390/block/xpram: add error handling support for
 add_disk()
In-Reply-To: <YTIr1w/qPvgioUfL@osiris>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-10-mcgrof@kernel.org>
 <YTIr1w/qPvgioUfL@osiris>
Message-ID: <YTXcPBph323n2WJ8@infradead.org>

On Fri, Sep 03, 2021 at 04:06:15PM +0200, Heiko Carstens wrote:
> Hmm, this is a more or less dead device driver, and I'm wondering if
> we shouldn't remove it instead. But anyway, your patch is not correct:

I'm all for removing it.  I think we need to do a little more spring
cleaning on unmaintained and likely to be unused block drivers.


From gerald.schaefer at linux.ibm.com  Mon Sep  6 04:43:46 2021
From: gerald.schaefer at linux.ibm.com (Gerald Schaefer)
Date: Mon, 6 Sep 2021 13:43:46 +0200
Subject: [PATCH 7/9] s390/block/dcssblk: add error handling support for
 add_disk()
In-Reply-To: <YTLP8mYBX37R++9E@bombadil.infradead.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-8-mcgrof@kernel.org>
 <YTIscKy+jg5L/TMh@osiris> <YTLP8mYBX37R++9E@bombadil.infradead.org>
Message-ID: <20210906134346.19c14246@thinkpad>

On Fri, 3 Sep 2021 18:46:26 -0700
Luis Chamberlain <mcgrof at kernel.org> wrote:

> On Fri, Sep 03, 2021 at 04:08:48PM +0200, Heiko Carstens wrote:
> > On Thu, Sep 02, 2021 at 10:41:03AM -0700, Luis Chamberlain wrote:
> > > We never checked for errors on add_disk() as this function
> > > returned void. Now that this is fixed, use the shiny new
> > > error handling.
> > > 
> > > Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
> > > ---
> > >  drivers/s390/block/dcssblk.c | 4 +++-
> > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
> > > index 5be3d1c39a78..b0fd5009a12e 100644
> > > --- a/drivers/s390/block/dcssblk.c
> > > +++ b/drivers/s390/block/dcssblk.c
> > > @@ -696,7 +696,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
> > >  	}
> > >  
> > >  	get_device(&dev_info->dev);
> > > -	device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> > > +	rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> > > +	if (rc)
> > > +		goto put_dev;
> > 
> > This looks not correct to me. We seem to have now in case of an error:
> > 
> > - reference count imbalance (= memory leak)
> > - dax cleanup is missing
> 
> Care to provide an alternative?

See patch below:

From 7053b5f8c0a126c3ef450de3668d9963bd68ceaa Mon Sep 17 00:00:00 2001
From: Gerald Schaefer <gerald.schaefer at linux.ibm.com>
Date: Mon, 6 Sep 2021 13:18:53 +0200
Subject: [PATCH] s390/block/dcssblk: add error handling support for add_disk()

Signed-off-by: Gerald Schaefer <gerald.schaefer at linux.ibm.com>
---
 drivers/s390/block/dcssblk.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 5be3d1c39a78..0741a9321712 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -696,7 +696,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
 	}
 
 	get_device(&dev_info->dev);
-	device_add_disk(&dev_info->dev, dev_info->gd, NULL);
+	rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL);
+	if (rc)
+		goto out_dax;
 
 	switch (dev_info->segment_type) {
 		case SEG_TYPE_SR:
@@ -712,6 +714,10 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
 	rc = count;
 	goto out;
 
+out_dax:
+	put_device(&dev_info->dev);
+	kill_dax(dev_info->dax_dev);
+	put_dax(dev_info->dax_dev);
 put_dev:
 	list_del(&dev_info->lh);
 	blk_cleanup_disk(dev_info->gd);
-- 
2.25.1



From miquel.raynal at bootlin.com  Mon Sep  6 06:29:40 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon,  6 Sep 2021 15:29:40 +0200
Subject: [PATCH 1/3] mtd: rawnand: Add a helper to check if a
 CHANGE_READ_COLUMN is possible
Message-ID: <20210906132942.36972-1-miquel.raynal@bootlin.com>

Certain controllers are limited and cannot perform all type of
CHANGE_READ_COLUMN. Let's add a helper that allows checking this.

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/nand_base.c | 15 +++++++++++++++
 include/linux/mtd/rawnand.h      |  4 ++++
 2 files changed, 19 insertions(+)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 57a583149cc0..7f29f27bb6fd 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -1312,6 +1312,15 @@ int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf,
 int nand_change_read_column_op(struct nand_chip *chip,
 			       unsigned int offset_in_page, void *buf,
 			       unsigned int len, bool force_8bit)
+{
+	return nand_check_change_read_column_op(chip, offset_in_page, buf, len,
+						force_8bit, false);
+}
+
+int nand_check_change_read_column_op(struct nand_chip *chip,
+				     unsigned int offset_in_page, void *buf,
+				     unsigned int len, bool force_8bit,
+				     bool check_only)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 
@@ -1349,9 +1358,15 @@ int nand_change_read_column_op(struct nand_chip *chip,
 
 		instrs[3].ctx.data.force_8bit = force_8bit;
 
+		if (check_only)
+			return nand_check_op(chip, &op);
+
 		return nand_exec_op(chip, &op);
 	}
 
+	if (check_only)
+		return 0;
+
 	chip->legacy.cmdfunc(chip, NAND_CMD_RNDOUT, offset_in_page, -1);
 	if (len)
 		chip->legacy.read_buf(chip, buf, len);
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index b2f9dd3cbd69..a453386aee70 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1523,6 +1523,10 @@ int nand_read_page_op(struct nand_chip *chip, unsigned int page,
 int nand_change_read_column_op(struct nand_chip *chip,
 			       unsigned int offset_in_page, void *buf,
 			       unsigned int len, bool force_8bit);
+int nand_check_change_read_column_op(struct nand_chip *chip,
+				     unsigned int offset_in_page, void *buf,
+				     unsigned int len, bool force_8bit,
+				     bool check_only);
 int nand_read_oob_op(struct nand_chip *chip, unsigned int page,
 		     unsigned int offset_in_page, void *buf, unsigned int len);
 int nand_prog_page_begin_op(struct nand_chip *chip, unsigned int page,
-- 
2.27.0



From miquel.raynal at bootlin.com  Mon Sep  6 06:29:42 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon,  6 Sep 2021 15:29:42 +0200
Subject: [PATCH 3/3] mtd: rawnand: arasan: Provide an additional ->exec_op()
 check
In-Reply-To: <20210906132942.36972-1-miquel.raynal@bootlin.com>
References: <20210906132942.36972-1-miquel.raynal@bootlin.com>
Message-ID: <20210906132942.36972-3-miquel.raynal@bootlin.com>

The controller only supports data payload requests which are multiple of
4. Rounding up will not work if we reached the end of the device and the
controller will just refuse the request. Hence any unaligned data request
that ends at the device boundary should be refused.

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/arasan-nand-controller.c | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c
index 9cbcc698c64d..8377994f3c49 100644
--- a/drivers/mtd/nand/raw/arasan-nand-controller.c
+++ b/drivers/mtd/nand/raw/arasan-nand-controller.c
@@ -891,6 +891,7 @@ static const struct nand_op_parser anfc_op_parser = NAND_OP_PARSER(
 static int anfc_check_op(struct nand_chip *chip,
 			 const struct nand_operation *op)
 {
+	struct mtd_info *mtd = nand_to_mtd(chip);
 	const struct nand_op_instr *instr;
 	int op_id;
 
@@ -940,6 +941,35 @@ static int anfc_check_op(struct nand_chip *chip,
 	    op->instrs[1].type == NAND_OP_DATA_IN_INSTR)
 		return -ENOTSUPP;
 
+	/*
+	 * The controller only supports data payload requests which are a
+	 * multiple of 4. This may confuse the core as the core could request a
+	 * given number of bytes and then another number of bytes without
+	 * re-synchronizing the pointer. In practice, most data accesses are
+	 * 4-byte aligned and thus this is not an issue in practice. However,
+	 * rounding up will not work if we reached the end of the device. Any
+	 * unaligned data request that ends at the device boundary would confuse
+	 * the controller and cannot be performed.
+	 *
+	 * TODO: The nand_op_parser framework should be extended to
+	 * support custom checks on DATA instructions.
+	 */
+	if (op->ninstrs == 4 &&
+	    op->instrs[0].type == NAND_OP_CMD_INSTR &&
+	    op->instrs[1].type == NAND_OP_ADDR_INSTR &&
+	    op->instrs[1].ctx.addr.naddrs == 2 &&
+	    op->instrs[2].type == NAND_OP_CMD_INSTR &&
+	    op->instrs[3].type == NAND_OP_DATA_IN_INSTR) {
+		unsigned int start_off, end_off;
+
+		start_off = (op->instrs[1].ctx.addr.addrs[1] << 8) +
+			    op->instrs[1].ctx.addr.addrs[0];
+		end_off = start_off + round_up(op->instrs[3].ctx.data.len, 4);
+
+		if (end_off >= mtd->writesize + mtd->oobsize)
+			return -ENOTSUPP;
+	}
+
 	return nand_op_parser_exec_op(chip, &anfc_op_parser, op, true);
 }
 
-- 
2.27.0



From miquel.raynal at bootlin.com  Mon Sep  6 06:29:41 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon,  6 Sep 2021 15:29:41 +0200
Subject: [PATCH 2/3] mtd: rawnand: Check the CHANGE_READ_COLUMN from
 nand_read_subpage() is supported
In-Reply-To: <20210906132942.36972-1-miquel.raynal@bootlin.com>
References: <20210906132942.36972-1-miquel.raynal@bootlin.com>
Message-ID: <20210906132942.36972-2-miquel.raynal@bootlin.com>

There are constraint controllers which do not support
CHANGE_READ_COLUMNs at any offset. In particular, the offset alignment
might be an issue. Ensure that the operation is supported before trying
it.

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/nand_base.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 7f29f27bb6fd..8175635b9802 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -3065,10 +3065,19 @@ static int nand_read_subpage(struct nand_chip *chip, uint32_t data_offs,
 		    (busw - 1))
 			aligned_len++;
 
-		ret = nand_change_read_column_op(chip,
-						 mtd->writesize + aligned_pos,
-						 &chip->oob_poi[aligned_pos],
-						 aligned_len, false);
+		ret = nand_check_change_read_column_op(chip,
+						       mtd->writesize + aligned_pos,
+						       &chip->oob_poi[aligned_pos],
+						       aligned_len, false, true);
+		if (!ret)
+			ret = nand_change_read_column_op(chip,
+							 mtd->writesize + aligned_pos,
+							 &chip->oob_poi[aligned_pos],
+							 aligned_len, false);
+		else
+			ret = nand_change_read_column_op(chip, mtd->writesize,
+							 chip->oob_poi,
+							 mtd->oobsize, false);
 		if (ret)
 			return ret;
 	}
-- 
2.27.0



From hca at linux.ibm.com  Mon Sep  6 07:35:09 2021
From: hca at linux.ibm.com (Heiko Carstens)
Date: Mon, 6 Sep 2021 16:35:09 +0200
Subject: [PATCH 9/9] s390/block/xpram: add error handling support for
 add_disk()
In-Reply-To: <YTXcPBph323n2WJ8@infradead.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-10-mcgrof@kernel.org>
 <YTIr1w/qPvgioUfL@osiris> <YTXcPBph323n2WJ8@infradead.org>
Message-ID: <YTYnHUYSfB6YElnh@osiris>

On Mon, Sep 06, 2021 at 10:15:40AM +0100, Christoph Hellwig wrote:
> On Fri, Sep 03, 2021 at 04:06:15PM +0200, Heiko Carstens wrote:
> > Hmm, this is a more or less dead device driver, and I'm wondering if
> > we shouldn't remove it instead. But anyway, your patch is not correct:
> 
> I'm all for removing it.  I think we need to do a little more spring
> cleaning on unmaintained and likely to be unused block drivers.

Yes, we'll remove it. I'll schedule it even for this merge
window. Should be away with -rc1.


From hca at linux.ibm.com  Mon Sep  6 07:33:55 2021
From: hca at linux.ibm.com (Heiko Carstens)
Date: Mon, 6 Sep 2021 16:33:55 +0200
Subject: [PATCH 7/9] s390/block/dcssblk: add error handling support for
 add_disk()
In-Reply-To: <20210906134346.19c14246@thinkpad>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-8-mcgrof@kernel.org>
 <YTIscKy+jg5L/TMh@osiris> <YTLP8mYBX37R++9E@bombadil.infradead.org>
 <20210906134346.19c14246@thinkpad>
Message-ID: <YTYm09U6jZUDtB9l@osiris>

On Mon, Sep 06, 2021 at 01:43:46PM +0200, Gerald Schaefer wrote:
> On Fri, 3 Sep 2021 18:46:26 -0700
> Luis Chamberlain <mcgrof at kernel.org> wrote:
> > > > +	rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> > > > +	if (rc)
> > > > +		goto put_dev;
> > > 
> > > This looks not correct to me. We seem to have now in case of an error:
> > > 
> > > - reference count imbalance (= memory leak)
> > > - dax cleanup is missing
> > 
> > Care to provide an alternative?
> 
> See patch below:
> 
> From 7053b5f8c0a126c3ef450de3668d9963bd68ceaa Mon Sep 17 00:00:00 2001
> From: Gerald Schaefer <gerald.schaefer at linux.ibm.com>
> Date: Mon, 6 Sep 2021 13:18:53 +0200
> Subject: [PATCH] s390/block/dcssblk: add error handling support for add_disk()
> 
> Signed-off-by: Gerald Schaefer <gerald.schaefer at linux.ibm.com>
> ---
>  drivers/s390/block/dcssblk.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)

Thanks Gerald! FWIW:
Acked-by: Heiko Carstens <hca at linux.ibm.com>


From boris.brezillon at collabora.com  Mon Sep  6 08:08:27 2021
From: boris.brezillon at collabora.com (Boris Brezillon)
Date: Mon, 6 Sep 2021 17:08:27 +0200
Subject: [PATCH 2/3] mtd: rawnand: Check the CHANGE_READ_COLUMN from
 nand_read_subpage() is supported
In-Reply-To: <20210906132942.36972-2-miquel.raynal@bootlin.com>
References: <20210906132942.36972-1-miquel.raynal@bootlin.com>
 <20210906132942.36972-2-miquel.raynal@bootlin.com>
Message-ID: <20210906170827.02ab8b96@collabora.com>

On Mon,  6 Sep 2021 15:29:41 +0200
Miquel Raynal <miquel.raynal at bootlin.com> wrote:

> There are constraint controllers which do not support
> CHANGE_READ_COLUMNs at any offset. In particular, the offset alignment
> might be an issue. Ensure that the operation is supported before trying
> it.
> 
> Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
> ---
>  drivers/mtd/nand/raw/nand_base.c | 17 +++++++++++++----
>  1 file changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> index 7f29f27bb6fd..8175635b9802 100644
> --- a/drivers/mtd/nand/raw/nand_base.c
> +++ b/drivers/mtd/nand/raw/nand_base.c
> @@ -3065,10 +3065,19 @@ static int nand_read_subpage(struct nand_chip *chip, uint32_t data_offs,
>  		    (busw - 1))
>  			aligned_len++;
>  
> -		ret = nand_change_read_column_op(chip,
> -						 mtd->writesize + aligned_pos,
> -						 &chip->oob_poi[aligned_pos],
> -						 aligned_len, false);
> +		ret = nand_check_change_read_column_op(chip,
> +						       mtd->writesize + aligned_pos,
> +						       &chip->oob_poi[aligned_pos],
> +						       aligned_len, false, true);
> +		if (!ret)
> +			ret = nand_change_read_column_op(chip,
> +							 mtd->writesize + aligned_pos,
> +							 &chip->oob_poi[aligned_pos],
> +							 aligned_len, false);
> +		else
> +			ret = nand_change_read_column_op(chip, mtd->writesize,
> +							 chip->oob_poi,
> +							 mtd->oobsize, false);
>  		if (ret)
>  			return ret;

So you just fail if the CHANGE column op is not supported? Looks like
this check should be done before we assign ecc->read_subpage to
nand_read_subpage in
nand_set_ecc_on_host_ops()/nand_set_ecc_soft_ops()...

>  	}



From miquel.raynal at bootlin.com  Mon Sep  6 09:13:41 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 6 Sep 2021 18:13:41 +0200
Subject: [PATCH 2/3] mtd: rawnand: Check the CHANGE_READ_COLUMN from
 nand_read_subpage() is supported
In-Reply-To: <20210906170827.02ab8b96@collabora.com>
References: <20210906132942.36972-1-miquel.raynal@bootlin.com>
 <20210906132942.36972-2-miquel.raynal@bootlin.com>
 <20210906170827.02ab8b96@collabora.com>
Message-ID: <20210906181341.08619108@xps13>

Hi Boris,

boris.brezillon at collabora.com wrote on Mon, 6 Sep 2021 17:08:27 +0200:

> On Mon,  6 Sep 2021 15:29:41 +0200
> Miquel Raynal <miquel.raynal at bootlin.com> wrote:
> 
> > There are constraint controllers which do not support
> > CHANGE_READ_COLUMNs at any offset. In particular, the offset alignment
> > might be an issue. Ensure that the operation is supported before trying
> > it.
> > 
> > Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
> > ---
> >  drivers/mtd/nand/raw/nand_base.c | 17 +++++++++++++----
> >  1 file changed, 13 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> > index 7f29f27bb6fd..8175635b9802 100644
> > --- a/drivers/mtd/nand/raw/nand_base.c
> > +++ b/drivers/mtd/nand/raw/nand_base.c
> > @@ -3065,10 +3065,19 @@ static int nand_read_subpage(struct nand_chip *chip, uint32_t data_offs,
> >  		    (busw - 1))
> >  			aligned_len++;
> >  
> > -		ret = nand_change_read_column_op(chip,
> > -						 mtd->writesize + aligned_pos,
> > -						 &chip->oob_poi[aligned_pos],
> > -						 aligned_len, false);
> > +		ret = nand_check_change_read_column_op(chip,
> > +						       mtd->writesize + aligned_pos,
> > +						       &chip->oob_poi[aligned_pos],
> > +						       aligned_len, false, true);
> > +		if (!ret)
> > +			ret = nand_change_read_column_op(chip,
> > +							 mtd->writesize + aligned_pos,
> > +							 &chip->oob_poi[aligned_pos],
> > +							 aligned_len, false);
> > +		else
> > +			ret = nand_change_read_column_op(chip, mtd->writesize,
> > +							 chip->oob_poi,
> > +							 mtd->oobsize, false);
> >  		if (ret)
> >  			return ret;  
> 


The previous behavior was:

/*
 * gaps == true means we need to request the entire OOB area and we
 * will call an OOB layout helper to extract the ECC bytes.
 * gaps == false means there is no data interleaved, we can just read
 * the number of ECC bytes by starting at the right offset and no
 * extracting operation will be needed.
 */
gaps = ...;
if (!gaps)
	nand_change_read_column(at a specific offset and a specific
				length just to match the ECC bytes);
else
	nand_change_read_column(the entire OOB);

While the new behavior is:

if (!gaps) {
	op_supported = nand_check_change_read_column();
	if (!op_supported)
		// same operation as if gaps == true
		nand_change_read_column(the entire OOB);
	else
		nand_change_read_column(at a specific offset);
} else {
	nand_change_read_column(the entire OOB)
}

> So you just fail if the CHANGE column op is not supported? Looks like
> this check should be done before we assign ecc->read_subpage to
> nand_read_subpage in
> nand_set_ecc_on_host_ops()/nand_set_ecc_soft_ops()...

So I actually don't understand the above comment as the code is not
simply failing, it's actually falling back to second method which is
maybe slightly slower but still valid. Do you think it's wrong?

Thanks,
Miqu?l


From pintu.ping at gmail.com  Mon Sep  6 09:28:08 2021
From: pintu.ping at gmail.com (Pintu Agarwal)
Date: Mon, 6 Sep 2021 21:58:08 +0530
Subject: Kernel 4.14: Using dm-verity with squashfs rootfs - mounting issue
In-Reply-To: <CAOuPNLgMd0AThhmSknbmKqp3_P8PFhBGr-jW0Mqjb6K6NchEMg@mail.gmail.com>
References: <CAOuPNLhqSpaTm3u4kFsnuZ0PLDKuX8wsxuF=vUJ1TEG0EP+L1g@mail.gmail.com>
 <alpine.LRH.2.02.2107200737510.19984@file01.intranet.prod.int.rdu2.redhat.com>
 <CAOuPNLhh_LkLQ8mSA4eoUDLCLzHo5zHXsiQZXUB_-T_F1_v6-g@mail.gmail.com>
 <alpine.LRH.2.02.2107211300520.10897@file01.intranet.prod.int.rdu2.redhat.com>
 <CAOuPNLi-xz_4P+v45CHLx00ztbSwU3_maf4tuuyso5RHyeOytg@mail.gmail.com>
 <CAOuPNLg0m-Q7Vhp4srbQrjXHsxVhOr-K2dvnNqzdR6Dr4kioqA@mail.gmail.com>
 <20210830185541.715f6a39@windsurf>
 <CAOuPNLhTidgLNWUbtUgdESYcKcE1C4SOdzKeQVhFGQvEoc0QEg@mail.gmail.com>
 <20210830211224.76391708@windsurf>
 <CAOuPNLgMd0AThhmSknbmKqp3_P8PFhBGr-jW0Mqjb6K6NchEMg@mail.gmail.com>
Message-ID: <CAOuPNLiW10-E6F_Ndte7U9NPBKa9Y_UuLhgdwAYTc0eYMk5Mqg@mail.gmail.com>

Dear Thomas, Mikulas,
Need your help in root causing my dm-verity issue with squashfs.
Please see my comments inline.

On Tue, 31 Aug 2021 at 18:49, Pintu Agarwal <pintu.ping at gmail.com> wrote:

> > No, but you can backport it easily. Back at
> > http://lists.infradead.org/pipermail/openwrt-devel/2019-November/025967.html
> > I provided backports of this feature to OpenWrt, for the 4.14 and 4.19
> > kernels.
> >
> Yes, I can backport it to our 4.14 Kernel.
> Can you share the list of patches to be backported to make it work on 4.14 ?
> If it's backported also I need to report to our internal kernel, but
> it might be slightly easier.
> Please share the details.
>

I am interested to backport dm-mod.create related patches to our 4.14 kernel.
Please let me know where can I find all the patches ?
Is it already part of mainline 4.14 ?
Please share the list of commits (from mainline) that we need to pull
and backport.

> > > Here is our kernel command line:
> > >
> > > [    0.000000] Kernel command line: ro rootwait
> > > console=ttyMSM0,115200,n8 ....  verity="95384 11923
> > > 16da5e4bbc706e5d90511d2a3dae373b5d878f9aebd522cd614a4faaace6baa3 12026
> > > " rootfstype=squashfs ubi.mtd=40,0,30 ubi.block=0,0 root=/dev/dm-0
> > > .... init=/sbin/init root=/dev/dm-0 dm="rootfs none ro,0 95384 verity
> > > 1 /dev/ubiblock0_0 /dev/mtdblock53 4096 4096 11923 8 sha256
> > > 16da5e4bbc706e5d90511d2a3dae373b5d878f9aebd522cd614a4faaace6baa3
> > > aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7 10
> > > restart_on_corruption ignore_zero_blocks use_fec_from_device
> > > /dev/mtdblock53 fec_roots 2 fec_blocks 12026 fec_start 12026" ...
> >
> > I don't see how this can work without the dm-mod.create feature. Are
> > you sure the verity= and dm= kernel arguments exist?
>
I checked a little further and yes there is "dm=" command line in
kernel available.
This is already working with ext4 glue, but was never tried with squashfs.
I think it is mainline derived from Android.
https://patchwork.kernel.org/project/dm-devel/patch/2c01b2a43a46fab760208d7af3a7af37eec8c41a.1537936397.git.helen.koike at collabora.com/
https://github.com/projectceladon/device-androidia-kernel/blob/master/init/do_mounts_dm.c

Mostly, this is the main repo where our source might be derived:
https://github.com/android-linux-stable/msm-4.14

Can we backport the patches here ?
If I get the list I can try it.

>
> Also, you mentioned:
> >>> Here, it definitely worked to append the hash tree to the squashfs
> >>> image and store them in the same partition.
> Can you share some details about it ?
> How it can be done since squashfs is readonly.
Can you share your reference, how are you appending the hash tree ?
Let me try the same.

But it seems like the underlying concept is the same for both
"dm-mod.create" and "dm=".
However, I am not sure if there are any changes required for squashfs
as block device..

Errors:
Currently, we are getting this in boot logs:

[    4.962188] device-mapper: init: attempting early device configuration.
[    4.969699] device-mapper: init: created device '253:0'
[    4.975503] device-mapper: init: adding target '0 95384 verity 1
/dev/ubiblock0_0 /dev/mtdblock53 4096 4096 11923 8 sha256
8fc2e4bb751f4b3145a486a0f4f1b58149ba3eedc2a67312f31fbee131380dab
aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7 10
restart_on_corruption ignore_zero_blocks use_fec_from_device
/dev/mtdblock53 fec_roots 2 fec_blocks 12026 fec_start 12026'
[    4.992323] device-mapper: verity: sha256 using implementation
"sha256-generic"
[    5.015568] device-mapper: init: dm-0 is ready
[   10.080065] prepare_namespace: dm_run_setup - done
[   10.080093] prepare_namespace: saved_root_name: /dev/dm-0
[   10.083903] prepare_namespace: Inside: name_to_dev_t
[   10.089605] prepare_namespace: Calling - mount_root() ...
[   10.094519] [PINTU]: mount_block_root: called with input name:
/dev/root, fs_names: squashfs
[   10.263510] [PINTU]: do_mount_root: sys_mount failed: err: -22
[   10.263544] [PINTU]: mount_block_root: do_mount_root: err: -22, p:
squashfs, flags: 32769, root_mount_data: (null)
[..]
[   10.745672] No filesystem could mount root, tried:
[   10.745676]  squashfs
[   10.748015]
[   10.755232] Kernel panic - not syncing: VFS: Unable to mount root
fs on unknown-block(253,0)

It seems the rootfs could not mount due to invalid arguments.
Not sure which arguments are invalid here...


Thanks,
Pintu


From boris.brezillon at collabora.com  Mon Sep  6 09:33:44 2021
From: boris.brezillon at collabora.com (Boris Brezillon)
Date: Mon, 6 Sep 2021 18:33:44 +0200
Subject: [PATCH 2/3] mtd: rawnand: Check the CHANGE_READ_COLUMN from
 nand_read_subpage() is supported
In-Reply-To: <20210906181341.08619108@xps13>
References: <20210906132942.36972-1-miquel.raynal@bootlin.com>
 <20210906132942.36972-2-miquel.raynal@bootlin.com>
 <20210906170827.02ab8b96@collabora.com>
 <20210906181341.08619108@xps13>
Message-ID: <20210906183344.7fda2cf2@collabora.com>

On Mon, 6 Sep 2021 18:13:41 +0200
Miquel Raynal <miquel.raynal at bootlin.com> wrote:

> Hi Boris,
> 
> boris.brezillon at collabora.com wrote on Mon, 6 Sep 2021 17:08:27 +0200:
> 
> > On Mon,  6 Sep 2021 15:29:41 +0200
> > Miquel Raynal <miquel.raynal at bootlin.com> wrote:
> >   
> > > There are constraint controllers which do not support
> > > CHANGE_READ_COLUMNs at any offset. In particular, the offset alignment
> > > might be an issue. Ensure that the operation is supported before trying
> > > it.
> > > 
> > > Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
> > > ---
> > >  drivers/mtd/nand/raw/nand_base.c | 17 +++++++++++++----
> > >  1 file changed, 13 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> > > index 7f29f27bb6fd..8175635b9802 100644
> > > --- a/drivers/mtd/nand/raw/nand_base.c
> > > +++ b/drivers/mtd/nand/raw/nand_base.c
> > > @@ -3065,10 +3065,19 @@ static int nand_read_subpage(struct nand_chip *chip, uint32_t data_offs,
> > >  		    (busw - 1))
> > >  			aligned_len++;
> > >  
> > > -		ret = nand_change_read_column_op(chip,
> > > -						 mtd->writesize + aligned_pos,
> > > -						 &chip->oob_poi[aligned_pos],
> > > -						 aligned_len, false);
> > > +		ret = nand_check_change_read_column_op(chip,
> > > +						       mtd->writesize + aligned_pos,
> > > +						       &chip->oob_poi[aligned_pos],
> > > +						       aligned_len, false, true);
> > > +		if (!ret)
> > > +			ret = nand_change_read_column_op(chip,
> > > +							 mtd->writesize + aligned_pos,
> > > +							 &chip->oob_poi[aligned_pos],
> > > +							 aligned_len, false);
> > > +		else
> > > +			ret = nand_change_read_column_op(chip, mtd->writesize,
> > > +							 chip->oob_poi,
> > > +							 mtd->oobsize, false);
> > >  		if (ret)
> > >  			return ret;    
> >   
> 
> 
> The previous behavior was:
> 
> /*
>  * gaps == true means we need to request the entire OOB area and we
>  * will call an OOB layout helper to extract the ECC bytes.
>  * gaps == false means there is no data interleaved, we can just read
>  * the number of ECC bytes by starting at the right offset and no
>  * extracting operation will be needed.
>  */
> gaps = ...;
> if (!gaps)
> 	nand_change_read_column(at a specific offset and a specific
> 				length just to match the ECC bytes);
> else
> 	nand_change_read_column(the entire OOB);
> 
> While the new behavior is:
> 
> if (!gaps) {
> 	op_supported = nand_check_change_read_column();
> 	if (!op_supported)
> 		// same operation as if gaps == true
> 		nand_change_read_column(the entire OOB);

What if this one is not supported either?

> 	else
> 		nand_change_read_column(at a specific offset);
> } else {
> 	nand_change_read_column(the entire OOB)
> }
> 
> > So you just fail if the CHANGE column op is not supported? Looks like
> > this check should be done before we assign ecc->read_subpage to
> > nand_read_subpage in
> > nand_set_ecc_on_host_ops()/nand_set_ecc_soft_ops()...  
> 
> So I actually don't understand the above comment as the code is not
> simply failing, it's actually falling back to second method which is
> maybe slightly slower but still valid. Do you think it's wrong?

Well, it's falling back to a different method that might be unsupported
too, so it might still fail on other controllers. Moreover, I really
think this sort of things should be checked at probe time so you don't
spend time checking it every time you do a read.

Something like:

	if (nand_check_change_read_column(gaps=false))
		ecc->read_subpage = nand_read_subpage_nogaps;
	else if (nand_check_change_read_column(gaps=true))
		ecc->read_subpage = nand_read_subpage_gaps;
	else
		return -EOPNOTSUP;


From ulf.hansson at linaro.org  Mon Sep  6 10:10:20 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 6 Sep 2021 19:10:20 +0200
Subject: [PATCH 2/9] ms_block: add error handling support for add_disk()
In-Reply-To: <20210902174105.2418771-3-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-3-mcgrof@kernel.org>
Message-ID: <CAPDyKFoZ1QqPMYi=N=3s2058mnbzcXYPodNFkexCi0eTbD4NmQ@mail.gmail.com>

On Thu, 2 Sept 2021 at 19:41, Luis Chamberlain <mcgrof at kernel.org> wrote:
>
> We never checked for errors on add_disk() as this function
> returned void. Now that this is fixed, use the shiny new
> error handling.
>
> Contrary to the typical removal which delays the put_disk()
> until later, since we are failing on a probe we immediately
> put the disk on failure from add_disk by using
> blk_cleanup_disk().
>
> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>

Queued for v5.16 on the temporary devel branch, thanks!

Kind regards
Uffe


> ---
>  drivers/memstick/core/ms_block.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c
> index 4a4573fa7b0f..86c626933c1a 100644
> --- a/drivers/memstick/core/ms_block.c
> +++ b/drivers/memstick/core/ms_block.c
> @@ -2156,10 +2156,14 @@ static int msb_init_disk(struct memstick_dev *card)
>                 set_disk_ro(msb->disk, 1);
>
>         msb_start(card);
> -       device_add_disk(&card->dev, msb->disk, NULL);
> +       rc = device_add_disk(&card->dev, msb->disk, NULL);
> +       if (rc)
> +               goto out_cleanup_disk;
>         dbg("Disk added");
>         return 0;
>
> +out_cleanup_disk:
> +       blk_cleanup_disk(msb->disk);
>  out_free_tag_set:
>         blk_mq_free_tag_set(&msb->tag_set);
>  out_release_id:
> --
> 2.30.2
>


From ulf.hansson at linaro.org  Mon Sep  6 10:10:27 2021
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Mon, 6 Sep 2021 19:10:27 +0200
Subject: [PATCH 3/9] mspro_block: add error handling support for add_disk()
In-Reply-To: <20210902174105.2418771-4-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-4-mcgrof@kernel.org>
Message-ID: <CAPDyKFrwjJyLXfr48+Jujfp7VvxPu5JCGJAhZJn3-GzDb1Kh5A@mail.gmail.com>

On Thu, 2 Sept 2021 at 19:41, Luis Chamberlain <mcgrof at kernel.org> wrote:
>
> We never checked for errors on add_disk() as this function
> returned void. Now that this is fixed, use the shiny new
> error handling.
>
> Contrary to the typical removal which delays the put_disk()
> until later, since we are failing on a probe we immediately
> put the disk on failure from add_disk by using
> blk_cleanup_disk().
>
> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>

Queued for v5.16 on the temporary devel branch, thanks!

Kind regards
Uffe


> ---
>  drivers/memstick/core/mspro_block.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
> index 22778d0e24f5..c0450397b673 100644
> --- a/drivers/memstick/core/mspro_block.c
> +++ b/drivers/memstick/core/mspro_block.c
> @@ -1239,10 +1239,14 @@ static int mspro_block_init_disk(struct memstick_dev *card)
>         set_capacity(msb->disk, capacity);
>         dev_dbg(&card->dev, "capacity set %ld\n", capacity);
>
> -       device_add_disk(&card->dev, msb->disk, NULL);
> +       rc = device_add_disk(&card->dev, msb->disk, NULL);
> +       if (rc)
> +               goto out_cleanup_disk;
>         msb->active = 1;
>         return 0;
>
> +out_cleanup_disk:
> +       blk_cleanup_disk(msb->disk);
>  out_free_tag_set:
>         blk_mq_free_tag_set(&msb->tag_set);
>  out_release_id:
> --
> 2.30.2
>


From miquel.raynal at bootlin.com  Mon Sep  6 10:32:55 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 6 Sep 2021 19:32:55 +0200
Subject: [PATCH 2/3] mtd: rawnand: Check the CHANGE_READ_COLUMN from
 nand_read_subpage() is supported
In-Reply-To: <20210906183344.7fda2cf2@collabora.com>
References: <20210906132942.36972-1-miquel.raynal@bootlin.com>
 <20210906132942.36972-2-miquel.raynal@bootlin.com>
 <20210906170827.02ab8b96@collabora.com>
 <20210906181341.08619108@xps13>
 <20210906183344.7fda2cf2@collabora.com>
Message-ID: <20210906193255.05b7aa7c@xps13>


> > > > diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> > > > index 7f29f27bb6fd..8175635b9802 100644
> > > > --- a/drivers/mtd/nand/raw/nand_base.c
> > > > +++ b/drivers/mtd/nand/raw/nand_base.c
> > > > @@ -3065,10 +3065,19 @@ static int nand_read_subpage(struct nand_chip *chip, uint32_t data_offs,
> > > >  		    (busw - 1))
> > > >  			aligned_len++;
> > > >  
> > > > -		ret = nand_change_read_column_op(chip,
> > > > -						 mtd->writesize + aligned_pos,
> > > > -						 &chip->oob_poi[aligned_pos],
> > > > -						 aligned_len, false);
> > > > +		ret = nand_check_change_read_column_op(chip,
> > > > +						       mtd->writesize + aligned_pos,
> > > > +						       &chip->oob_poi[aligned_pos],
> > > > +						       aligned_len, false, true);
> > > > +		if (!ret)
> > > > +			ret = nand_change_read_column_op(chip,
> > > > +							 mtd->writesize + aligned_pos,
> > > > +							 &chip->oob_poi[aligned_pos],
> > > > +							 aligned_len, false);
> > > > +		else
> > > > +			ret = nand_change_read_column_op(chip, mtd->writesize,
> > > > +							 chip->oob_poi,
> > > > +							 mtd->oobsize, false);
> > > >  		if (ret)
> > > >  			return ret;      
> > >     
> > 
> > 
> > The previous behavior was:
> > 
> > /*
> >  * gaps == true means we need to request the entire OOB area and we
> >  * will call an OOB layout helper to extract the ECC bytes.
> >  * gaps == false means there is no data interleaved, we can just read
> >  * the number of ECC bytes by starting at the right offset and no
> >  * extracting operation will be needed.
> >  */
> > gaps = ...;
> > if (!gaps)
> > 	nand_change_read_column(at a specific offset and a specific
> > 				length just to match the ECC bytes);
> > else
> > 	nand_change_read_column(the entire OOB);
> > 
> > While the new behavior is:
> > 
> > if (!gaps) {
> > 	op_supported = nand_check_change_read_column();
> > 	if (!op_supported)
> > 		// same operation as if gaps == true
> > 		nand_change_read_column(the entire OOB);  
> 
> What if this one is not supported either?

If this one is not supported either I guess the entire software ECC
support cannot be used. But what I am trying to achieve here is more
complicated: the controller does not support one thing: reading the ECC
bytes until the OOB end minus 2. Only a call to
nand_change_read_column with these particular parameters would fail
because it depends on the actual offset and length that are requested.

> > 	else
> > 		nand_change_read_column(at a specific offset);
> > } else {
> > 	nand_change_read_column(the entire OOB)
> > }
> >   
> > > So you just fail if the CHANGE column op is not supported? Looks like
> > > this check should be done before we assign ecc->read_subpage to
> > > nand_read_subpage in
> > > nand_set_ecc_on_host_ops()/nand_set_ecc_soft_ops()...    
> > 
> > So I actually don't understand the above comment as the code is not
> > simply failing, it's actually falling back to second method which is
> > maybe slightly slower but still valid. Do you think it's wrong?  
> 
> Well, it's falling back to a different method that might be unsupported
> too, so it might still fail on other controllers.

Well, yes it may fail on other controllers but as I said, if
controllers do not support any type of nand_change_read_column() then
they cannot use software ECC at all (and are close to be almost
useless).

> Moreover, I really
> think this sort of things should be checked at probe time so you don't
> spend time checking it every time you do a read.

Agreed. I can certainly make something like this in theory, but what
would be the condition? I am describing it in patch 3/3 : there is
really a tiny set of conditions where this will fail so in the end I
would end-up writing a condition that precisely matches the Arasan
limitation.

Not mentioning that it only fails with NV-DDR enabled (also something
that I missed to capture in patch 3/3). The data interface being
initialized after the read_subpage() hook it means I couldn't use this
information. 

> Something like:
> 
> 	if (nand_check_change_read_column(gaps=false))
> 		ecc->read_subpage = nand_read_subpage_nogaps;
> 	else if (nand_check_change_read_column(gaps=true))
> 		ecc->read_subpage = nand_read_subpage_gaps;
> 	else
> 		return -EOPNOTSUP;



From boris.brezillon at collabora.com  Mon Sep  6 10:59:20 2021
From: boris.brezillon at collabora.com (Boris Brezillon)
Date: Mon, 6 Sep 2021 19:59:20 +0200
Subject: [PATCH 2/3] mtd: rawnand: Check the CHANGE_READ_COLUMN from
 nand_read_subpage() is supported
In-Reply-To: <20210906193255.05b7aa7c@xps13>
References: <20210906132942.36972-1-miquel.raynal@bootlin.com>
 <20210906132942.36972-2-miquel.raynal@bootlin.com>
 <20210906170827.02ab8b96@collabora.com>
 <20210906181341.08619108@xps13>
 <20210906183344.7fda2cf2@collabora.com>
 <20210906193255.05b7aa7c@xps13>
Message-ID: <20210906195920.41bbc6f8@collabora.com>

On Mon, 6 Sep 2021 19:32:55 +0200
Miquel Raynal <miquel.raynal at bootlin.com> wrote:

> > > > > diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> > > > > index 7f29f27bb6fd..8175635b9802 100644
> > > > > --- a/drivers/mtd/nand/raw/nand_base.c
> > > > > +++ b/drivers/mtd/nand/raw/nand_base.c
> > > > > @@ -3065,10 +3065,19 @@ static int nand_read_subpage(struct nand_chip *chip, uint32_t data_offs,
> > > > >  		    (busw - 1))
> > > > >  			aligned_len++;
> > > > >  
> > > > > -		ret = nand_change_read_column_op(chip,
> > > > > -						 mtd->writesize + aligned_pos,
> > > > > -						 &chip->oob_poi[aligned_pos],
> > > > > -						 aligned_len, false);
> > > > > +		ret = nand_check_change_read_column_op(chip,
> > > > > +						       mtd->writesize + aligned_pos,
> > > > > +						       &chip->oob_poi[aligned_pos],
> > > > > +						       aligned_len, false, true);
> > > > > +		if (!ret)
> > > > > +			ret = nand_change_read_column_op(chip,
> > > > > +							 mtd->writesize + aligned_pos,
> > > > > +							 &chip->oob_poi[aligned_pos],
> > > > > +							 aligned_len, false);
> > > > > +		else
> > > > > +			ret = nand_change_read_column_op(chip, mtd->writesize,
> > > > > +							 chip->oob_poi,
> > > > > +							 mtd->oobsize, false);
> > > > >  		if (ret)
> > > > >  			return ret;        
> > > >       
> > > 
> > > 
> > > The previous behavior was:
> > > 
> > > /*
> > >  * gaps == true means we need to request the entire OOB area and we
> > >  * will call an OOB layout helper to extract the ECC bytes.
> > >  * gaps == false means there is no data interleaved, we can just read
> > >  * the number of ECC bytes by starting at the right offset and no
> > >  * extracting operation will be needed.
> > >  */
> > > gaps = ...;
> > > if (!gaps)
> > > 	nand_change_read_column(at a specific offset and a specific
> > > 				length just to match the ECC bytes);
> > > else
> > > 	nand_change_read_column(the entire OOB);
> > > 
> > > While the new behavior is:
> > > 
> > > if (!gaps) {
> > > 	op_supported = nand_check_change_read_column();
> > > 	if (!op_supported)
> > > 		// same operation as if gaps == true
> > > 		nand_change_read_column(the entire OOB);    
> > 
> > What if this one is not supported either?  
> 
> If this one is not supported either I guess the entire software ECC
> support cannot be used. But what I am trying to achieve here is more
> complicated: the controller does not support one thing: reading the ECC
> bytes until the OOB end minus 2. Only a call to
> nand_change_read_column with these particular parameters would fail
> because it depends on the actual offset and length that are requested.

I suspect those parameters can be extracted from the NAND page size/ECC
config, which are known before the ECC initialization IIRC.

> 
> > > 	else
> > > 		nand_change_read_column(at a specific offset);
> > > } else {
> > > 	nand_change_read_column(the entire OOB)
> > > }
> > >     
> > > > So you just fail if the CHANGE column op is not supported? Looks like
> > > > this check should be done before we assign ecc->read_subpage to
> > > > nand_read_subpage in
> > > > nand_set_ecc_on_host_ops()/nand_set_ecc_soft_ops()...      
> > > 
> > > So I actually don't understand the above comment as the code is not
> > > simply failing, it's actually falling back to second method which is
> > > maybe slightly slower but still valid. Do you think it's wrong?    
> > 
> > Well, it's falling back to a different method that might be unsupported
> > too, so it might still fail on other controllers.  
> 
> Well, yes it may fail on other controllers but as I said, if
> controllers do not support any type of nand_change_read_column() then
> they cannot use software ECC at all (and are close to be almost
> useless).

Which would be good to detect at probe time, with a probe failure when
this happens.

> 
> > Moreover, I really
> > think this sort of things should be checked at probe time so you don't
> > spend time checking it every time you do a read.  
> 
> Agreed. I can certainly make something like this in theory, but what
> would be the condition? I am describing it in patch 3/3 : there is
> really a tiny set of conditions where this will fail so in the end I
> would end-up writing a condition that precisely matches the Arasan
> limitation.

I see. Maybe it's simpler to add NAND_NO_SUBPAGE_READ flag until you
find a better way to describe such limitations.

> 
> Not mentioning that it only fails with NV-DDR enabled (also something
> that I missed to capture in patch 3/3). The data interface being
> initialized after the read_subpage() hook it means I couldn't use this
> information.

Duh, this is nasty, indeed.

> 
> > Something like:
> > 
> > 	if (nand_check_change_read_column(gaps=false))
> > 		ecc->read_subpage = nand_read_subpage_nogaps;
> > 	else if (nand_check_change_read_column(gaps=true))
> > 		ecc->read_subpage = nand_read_subpage_gaps;
> > 	else
> > 		return -EOPNOTSUP;  
> 



From mdalam at codeaurora.org  Mon Sep  6 23:35:42 2021
From: mdalam at codeaurora.org (mdalam at codeaurora.org)
Date: Tue, 07 Sep 2021 12:05:42 +0530
Subject: [PATCH V4] mtd: rawnand: qcom: Update code word value for raw read
In-Reply-To: <20210902091730.GA10844@workstation>
References: <1630561763-18486-1-git-send-email-mdalam@codeaurora.org>
 <20210902091730.GA10844@workstation>
Message-ID: <3ea25e979fc8c965820596ec86c61172@codeaurora.org>

On 2021-09-02 14:47, Manivannan Sadhasivam wrote:
> On Thu, Sep 02, 2021 at 11:19:23AM +0530, Md Sadre Alam wrote:
>> From QPIC V2 onwards there is a separate register to read
>> last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".
>> 
>> qcom_nandc_read_cw_raw() is used to read only one code word
>> at a time. If we will configure number of code words to 1 in
>> in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
>> its reading the last code word, since from QPIC V2 onwards
>> we are having separate register to read the last code word,
>> we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
>> register to fetch data from controller buffer to system
>> memory.
>> 
>> Fixes: 503ee5aa ("mtd: rawnand: qcom: update last code word register")
> 
> Commit hash should be of 12 digits.

   Updated in patch V5
> 
>> Cc: stable at kernel.org
>> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
>> ---
>> [V4]
>>  * Added commit message
>>  * Added changelog
>> 
>>  In commit 503ee5aa added QPIC V2 support. Since QPIC V2 onwards there
>>  is separate register to get last CW data. If total number of CW 
>> configred is 1
>>  then , QPIC controller treat this as last CW and software shhould 
>> copy data to memory
>>  via QPIC_NAND_READ_LOCATION_LAST_CW_n register instead of 
>> QPIC_NAND_READ_LOCATION_n.
>>  Since in raw read we are configuring total number of CW 1, this 
>> change fixes
>>  this if total number of CW 1 then make this as last CW.  raw_cw = 
>> ecc->steps - 1;
>>  since ecc->steps holds total number of CWs.
>> 
> 
> This is not a changelog. Changelog should mention what has been changed
> between versions from v1 to v4. For example:
> 
> Changes in v4:
> 
> * Incorporated AAA comments from X
> * Changed a local variable
> 
> Changes in v3:
> 
> * Incorporated BBB comments from X
> 
> Changes in v2:
> 
> * Incorporated CCC comments from X

  Updated in patch V5
> 
>>  drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c 
>> b/drivers/mtd/nand/raw/qcom_nandc.c
>> index ef0bade..04e6f7b 100644
>> --- a/drivers/mtd/nand/raw/qcom_nandc.c
>> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
>> @@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>> struct nand_chip *chip,
>>  	struct nand_ecc_ctrl *ecc = &chip->ecc;
>>  	int data_size1, data_size2, oob_size1, oob_size2;
>>  	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
>> +	int raw_cw = cw;
>> 
>>  	nand_read_page_op(chip, page, 0, NULL, 0);
>>  	host->use_ecc = false;
>> 
>> +	if (nandc->props->qpic_v2)
>> +		raw_cw = ecc->steps - 1;
>> +
> 
> Sorry, I don't understand how it can work. For reading a codeword like
> 0, you are reading the last codeword here if the controller is v2. And
> you'll continue to read the last codeword only for any codeword
> requested :/

   This case is only applicable when we will configure number of code 
words to 1.
   These registers "QPIC_NAND_READ_LOCATION_LAST_CW_n" & 
"QPIC_NAND_READ_LOCATION_n"
   are only used to copy data into memory i.e our local buffer. So this 
last CW interpretation from
   QPIC controller to memory not for Flash to QPIC controller.
   If number of CW configured to 1 means QPIC will treat this a last CW , 
so copy the data from QPIC to local memory
   buffer , we have to use QPIC_NAND_READ_LOCATION_LAST_CW_n register 
instead of QPIC_NAND_READ_LOCATION_n regsiter,
   Since there is separate register from QPIC V2 onwards to read get last 
CW "QPIC_NAND_READ_LOCATION_LAST_CW_n".


> 
> Thanks,
> Mani
> 
>>  	clear_bam_transaction(nandc);
>>  	set_address(host, host->cw_size * cw, page);
>> -	update_rw_regs(host, 1, true, cw);
>> +	update_rw_regs(host, 1, true, raw_cw);
>>  	config_nand_page_read(chip);
>> 
>>  	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
>> @@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>> struct nand_chip *chip,
>>  		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
>>  	}
>> 
>> -	config_nand_cw_read(chip, false, cw);
>> +	config_nand_cw_read(chip, false, raw_cw);
>> 
>>  	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
>>  	reg_off += data_size1;
>> --
>> 2.7.4
>> 


From mdalam at codeaurora.org  Mon Sep  6 23:39:31 2021
From: mdalam at codeaurora.org (Md Sadre Alam)
Date: Tue,  7 Sep 2021 12:09:31 +0530
Subject: [PATCH V5] mtd: rawnand: qcom: Update code word value for raw read
Message-ID: <1630996771-29866-1-git-send-email-mdalam@codeaurora.org>

>From QPIC V2 onwards there is a separate register to read
last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".

qcom_nandc_read_cw_raw() is used to read only one code word
at a time. If we will configure number of code words to 1 in
in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
its reading the last code word, since from QPIC V2 onwards
we are having separate register to read the last code word,
we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
register to fetch data from controller buffer to system
memory.

Fixes: 503ee5aad43054a26cfd5cc592a31270c05539cd ("mtd: rawnand: qcom: update last code word register")
Cc: stable at kernel.org
Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
---
Changes in V5:

 * Incorporated "hash commit" comment from Mani.
 * Updated commit hash

Changes in V4:

 * Incorporated "Change log" comment from Miqu?l
 * Updated change log

Changes in V3:
 
 * Incorporated "Fixes tags are missing" comment from Miqu?l
 * Added Fixes tag Fixes:503ee5aa ("mtd: rawnand: qcom: update last code word register")


Changes in V2:

 * Incorporated "stable tags are missing" comment from Miqu?l
 * Added stable tags Cc:stable at kernel.org

  

 drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index ef0bade..04e6f7b 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
 	int data_size1, data_size2, oob_size1, oob_size2;
 	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
+	int raw_cw = cw;
 
 	nand_read_page_op(chip, page, 0, NULL, 0);
 	host->use_ecc = false;
 
+	if (nandc->props->qpic_v2)
+		raw_cw = ecc->steps - 1;
+
 	clear_bam_transaction(nandc);
 	set_address(host, host->cw_size * cw, page);
-	update_rw_regs(host, 1, true, cw);
+	update_rw_regs(host, 1, true, raw_cw);
 	config_nand_page_read(chip);
 
 	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
@@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
 		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
 	}
 
-	config_nand_cw_read(chip, false, cw);
+	config_nand_cw_read(chip, false, raw_cw);
 
 	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
 	reg_off += data_size1;
-- 
2.7.4



From miquel.raynal at bootlin.com  Mon Sep  6 23:48:44 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 7 Sep 2021 08:48:44 +0200
Subject: [PATCH V5] mtd: rawnand: qcom: Update code word value for raw read
In-Reply-To: <1630996771-29866-1-git-send-email-mdalam@codeaurora.org>
References: <1630996771-29866-1-git-send-email-mdalam@codeaurora.org>
Message-ID: <20210907084844.1ad92ef1@xps13>


mdalam at codeaurora.org wrote on Tue,  7 Sep 2021 12:09:31 +0530:

> From QPIC V2 onwards there is a separate register to read
> last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".
> 
> qcom_nandc_read_cw_raw() is used to read only one code word
> at a time. If we will configure number of code words to 1 in
> in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
> its reading the last code word, since from QPIC V2 onwards
> we are having separate register to read the last code word,
> we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
> register to fetch data from controller buffer to system
> memory.
> 
> Fixes: 503ee5aad43054a26cfd5cc592a31270c05539cd ("mtd: rawnand: qcom: update last code word register")

Still wrong. It's 12 digits, as reported by Manivannan.

> Cc: stable at kernel.org
> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> ---
> Changes in V5:
> 
>  * Incorporated "hash commit" comment from Mani.
>  * Updated commit hash
> 
> Changes in V4:
> 
>  * Incorporated "Change log" comment from Miqu?l
>  * Updated change log
> 
> Changes in V3:
>  
>  * Incorporated "Fixes tags are missing" comment from Miqu?l
>  * Added Fixes tag Fixes:503ee5aa ("mtd: rawnand: qcom: update last code word register")
> 
> 
> Changes in V2:
> 
>  * Incorporated "stable tags are missing" comment from Miqu?l
>  * Added stable tags Cc:stable at kernel.org
> 
>   
> 
>  drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
> index ef0bade..04e6f7b 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
>  	struct nand_ecc_ctrl *ecc = &chip->ecc;
>  	int data_size1, data_size2, oob_size1, oob_size2;
>  	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
> +	int raw_cw = cw;
>  
>  	nand_read_page_op(chip, page, 0, NULL, 0);
>  	host->use_ecc = false;
>  
> +	if (nandc->props->qpic_v2)
> +		raw_cw = ecc->steps - 1;
> +
>  	clear_bam_transaction(nandc);
>  	set_address(host, host->cw_size * cw, page);
> -	update_rw_regs(host, 1, true, cw);
> +	update_rw_regs(host, 1, true, raw_cw);
>  	config_nand_page_read(chip);
>  
>  	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
> @@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
>  		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
>  	}
>  
> -	config_nand_cw_read(chip, false, cw);
> +	config_nand_cw_read(chip, false, raw_cw);
>  
>  	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
>  	reg_off += data_size1;


Thanks,
Miqu?l


From mdalam at codeaurora.org  Tue Sep  7 00:05:57 2021
From: mdalam at codeaurora.org (Md Sadre Alam)
Date: Tue,  7 Sep 2021 12:35:57 +0530
Subject: [PATCH V6] mtd: rawnand: qcom: Update code word value for raw read
Message-ID: <1630998357-1359-1-git-send-email-mdalam@codeaurora.org>

>From QPIC V2 onwards there is a separate register to read
last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".

qcom_nandc_read_cw_raw() is used to read only one code word
at a time. If we will configure number of code words to 1 in
in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
its reading the last code word, since from QPIC V2 onwards
we are having separate register to read the last code word,
we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
register to fetch data from controller buffer to system
memory.

Fixes: 503ee5aad430 ("mtd: rawnand: qcom: update last code word register")
Cc: stable at kernel.org
Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
---
Changes in V6:

 * Incorporated "commit hash" comment from Miqu?l
 * updated commit hash to 12 digits in Fixes tag.

Changes in V5:

 * Incorporated "hash commit" comment from Mani.
 * Updated commit hash

Changes in V4:

 * Incorporated "Change log" comment from Miqu?l
 * Updated change log

Changes in V3:
 
 * Incorporated "Fixes tags are missing" comment from Miqu?l
 * Added Fixes tag Fixes:503ee5aa ("mtd: rawnand: qcom: update last code word register")


Changes in V2:

 * Incorporated "stable tags are missing" comment from Miqu?l
 * Added stable tags Cc:stable at kernel.org

 drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index ef0bade..04e6f7b 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
 	int data_size1, data_size2, oob_size1, oob_size2;
 	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
+	int raw_cw = cw;
 
 	nand_read_page_op(chip, page, 0, NULL, 0);
 	host->use_ecc = false;
 
+	if (nandc->props->qpic_v2)
+		raw_cw = ecc->steps - 1;
+
 	clear_bam_transaction(nandc);
 	set_address(host, host->cw_size * cw, page);
-	update_rw_regs(host, 1, true, cw);
+	update_rw_regs(host, 1, true, raw_cw);
 	config_nand_page_read(chip);
 
 	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
@@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
 		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
 	}
 
-	config_nand_cw_read(chip, false, cw);
+	config_nand_cw_read(chip, false, raw_cw);
 
 	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
 	reg_off += data_size1;
-- 
2.7.4



From mdalam at codeaurora.org  Tue Sep  7 00:07:14 2021
From: mdalam at codeaurora.org (mdalam at codeaurora.org)
Date: Tue, 07 Sep 2021 12:37:14 +0530
Subject: [PATCH V5] mtd: rawnand: qcom: Update code word value for raw read
In-Reply-To: <20210907084844.1ad92ef1@xps13>
References: <1630996771-29866-1-git-send-email-mdalam@codeaurora.org>
 <20210907084844.1ad92ef1@xps13>
Message-ID: <d351bff49b8438186f849214bb133abd@codeaurora.org>

On 2021-09-07 12:18, Miquel Raynal wrote:
> mdalam at codeaurora.org wrote on Tue,  7 Sep 2021 12:09:31 +0530:
> 
>> From QPIC V2 onwards there is a separate register to read
>> last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".
>> 
>> qcom_nandc_read_cw_raw() is used to read only one code word
>> at a time. If we will configure number of code words to 1 in
>> in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
>> its reading the last code word, since from QPIC V2 onwards
>> we are having separate register to read the last code word,
>> we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
>> register to fetch data from controller buffer to system
>> memory.
>> 
>> Fixes: 503ee5aad43054a26cfd5cc592a31270c05539cd ("mtd: rawnand: qcom: 
>> update last code word register")
> 
> Still wrong. It's 12 digits, as reported by Manivannan.

   Updated in patch V6.
> 
>> Cc: stable at kernel.org
>> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
>> ---
>> Changes in V5:
>> 
>>  * Incorporated "hash commit" comment from Mani.
>>  * Updated commit hash
>> 
>> Changes in V4:
>> 
>>  * Incorporated "Change log" comment from Miqu?l
>>  * Updated change log
>> 
>> Changes in V3:
>> 
>>  * Incorporated "Fixes tags are missing" comment from Miqu?l
>>  * Added Fixes tag Fixes:503ee5aa ("mtd: rawnand: qcom: update last 
>> code word register")
>> 
>> 
>> Changes in V2:
>> 
>>  * Incorporated "stable tags are missing" comment from Miqu?l
>>  * Added stable tags Cc:stable at kernel.org
>> 
>> 
>> 
>>  drivers/mtd/nand/raw/qcom_nandc.c | 8 ++++++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>> 
>> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c 
>> b/drivers/mtd/nand/raw/qcom_nandc.c
>> index ef0bade..04e6f7b 100644
>> --- a/drivers/mtd/nand/raw/qcom_nandc.c
>> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
>> @@ -1676,13 +1676,17 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>> struct nand_chip *chip,
>>  	struct nand_ecc_ctrl *ecc = &chip->ecc;
>>  	int data_size1, data_size2, oob_size1, oob_size2;
>>  	int ret, reg_off = FLASH_BUF_ACC, read_loc = 0;
>> +	int raw_cw = cw;
>> 
>>  	nand_read_page_op(chip, page, 0, NULL, 0);
>>  	host->use_ecc = false;
>> 
>> +	if (nandc->props->qpic_v2)
>> +		raw_cw = ecc->steps - 1;
>> +
>>  	clear_bam_transaction(nandc);
>>  	set_address(host, host->cw_size * cw, page);
>> -	update_rw_regs(host, 1, true, cw);
>> +	update_rw_regs(host, 1, true, raw_cw);
>>  	config_nand_page_read(chip);
>> 
>>  	data_size1 = mtd->writesize - host->cw_size * (ecc->steps - 1);
>> @@ -1711,7 +1715,7 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>> struct nand_chip *chip,
>>  		nandc_set_read_loc(chip, cw, 3, read_loc, oob_size2, 1);
>>  	}
>> 
>> -	config_nand_cw_read(chip, false, cw);
>> +	config_nand_cw_read(chip, false, raw_cw);
>> 
>>  	read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
>>  	reg_off += data_size1;
> 
> 
> Thanks,
> Miqu?l


From rogerq at kernel.org  Tue Sep  7 04:32:18 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue,  7 Sep 2021 14:32:18 +0300
Subject: [PATCH v3 0/8] dt-bindings: memory-controllers: ti,
 gpmc: Convert to yaml
Message-ID: <20210907113226.31876-1-rogerq@kernel.org>

Hi,

This series converts ti,gpmc memory controller and ti,gpmc-nand and
ti,gpmc-onenand MTD controller bindings to yaml.

cheers,
-roger

Changelog:
v3:
- fix indentation
- split GPMC child timings/settings into ti,gpmc-child.yaml
This allows us to refer to it at 3 places and avoid use of
'additionalProperties: true' at 2 places.
- specify defaults where applicable
- reordered patches
- added patch for making "gpmc,device-width" optional with defaults.
- address all review comments.

v2:
- Fix all errors in dtbs_check and dt_bindings_check
- remove references to gpmc-omap.txt
- Convert ti,gpmc-nand and ti,gpmc-onenand bindings to yaml as well

Roger Quadros (8):
  ARM: dts: omap: Fixup GPMC child nodes
  dt-bindings: mtd: Remove gpmc-nor.txt
  dt-bindings: net: Remove gpmc-eth.txt
  dt-bindings: memory-controllers: Introduce ti,gpmc-child
  dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
  dt-bindings: mtd: ti,gpmc-onenand: Convert to yaml
  dt-bindings: memory-controllers: ti,gpmc: Convert to yaml
  memory: gpmc-omap: "gpmc,device-width" DT property is optional

 .../bindings/memory-controllers/omap-gpmc.txt | 157 -----------
 .../memory-controllers/ti,gpmc-child.yaml     | 245 ++++++++++++++++++
 .../bindings/memory-controllers/ti,gpmc.yaml  | 174 +++++++++++++
 .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 -----------
 .../devicetree/bindings/mtd/gpmc-nor.txt      |  98 -------
 .../devicetree/bindings/mtd/gpmc-onenand.txt  |  48 ----
 .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 110 ++++++++
 .../bindings/mtd/ti,gpmc-onenand.yaml         |  69 +++++
 .../devicetree/bindings/net/gpmc-eth.txt      |  97 -------
 .../boot/dts/logicpd-som-lv-baseboard.dtsi    |   2 +-
 .../boot/dts/logicpd-torpedo-37xx-devkit.dts  |   2 +-
 .../boot/dts/logicpd-torpedo-baseboard.dtsi   |   2 +-
 arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi     |  62 +++--
 arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi     |  59 ++---
 arch/arm/boot/dts/omap-zoom-common.dtsi       |  16 +-
 arch/arm/boot/dts/omap2430-sdp.dts            |   6 +-
 arch/arm/boot/dts/omap3-cm-t3x30.dtsi         |   6 +-
 .../arm/boot/dts/omap3-devkit8000-common.dtsi |   4 +-
 arch/arm/boot/dts/omap3-evm-37xx.dts          |   1 +
 arch/arm/boot/dts/omap3-evm-common.dtsi       |   9 -
 .../boot/dts/omap3-evm-processor-common.dtsi  |   5 +-
 arch/arm/boot/dts/omap3-evm.dts               |   1 +
 arch/arm/boot/dts/omap3-igep0020-common.dtsi  |   5 +-
 arch/arm/boot/dts/omap3-ldp.dts               |   5 +-
 arch/arm/boot/dts/omap3-n900.dts              |   2 +-
 .../dts/omap3-overo-chestnut43-common.dtsi    |   6 +-
 .../arm/boot/dts/omap3-overo-tobi-common.dtsi |   6 +-
 .../boot/dts/omap3-overo-tobiduo-common.dtsi  |   8 +-
 arch/arm/boot/dts/omap3-sb-t35.dtsi           |   4 +-
 arch/arm/boot/dts/omap4-duovero-parlor.dts    |   6 +-
 drivers/memory/omap-gpmc.c                    |  41 +--
 31 files changed, 729 insertions(+), 674 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
 delete mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt

-- 
2.17.1



From rogerq at kernel.org  Tue Sep  7 04:32:19 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue,  7 Sep 2021 14:32:19 +0300
Subject: [PATCH v3 1/8] ARM: dts: omap: Fixup GPMC child nodes
In-Reply-To: <20210907113226.31876-1-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
Message-ID: <20210907113226.31876-2-rogerq@kernel.org>

Fixes up the GPMC child nodes to prevent dtbs_check errors
after device tree binding conversion to yaml.

- Use reg address as node name
- gpmc,cycle2cycle-samecsen and gpmc,cycle2cycle-diffcsen are
  boolean properties.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../boot/dts/logicpd-som-lv-baseboard.dtsi    |  2 +-
 .../boot/dts/logicpd-torpedo-37xx-devkit.dts  |  2 +-
 .../boot/dts/logicpd-torpedo-baseboard.dtsi   |  2 +-
 arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi     | 62 +++++++++----------
 arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi     | 59 +++++++++---------
 arch/arm/boot/dts/omap-zoom-common.dtsi       | 16 ++---
 arch/arm/boot/dts/omap2430-sdp.dts            |  6 +-
 arch/arm/boot/dts/omap3-cm-t3x30.dtsi         |  6 +-
 .../arm/boot/dts/omap3-devkit8000-common.dtsi |  4 +-
 arch/arm/boot/dts/omap3-evm-37xx.dts          |  1 +
 arch/arm/boot/dts/omap3-evm-common.dtsi       |  9 ---
 .../boot/dts/omap3-evm-processor-common.dtsi  |  5 +-
 arch/arm/boot/dts/omap3-evm.dts               |  1 +
 arch/arm/boot/dts/omap3-igep0020-common.dtsi  |  5 +-
 arch/arm/boot/dts/omap3-ldp.dts               |  5 +-
 arch/arm/boot/dts/omap3-n900.dts              |  2 +-
 .../dts/omap3-overo-chestnut43-common.dtsi    |  6 +-
 .../arm/boot/dts/omap3-overo-tobi-common.dtsi |  6 +-
 .../boot/dts/omap3-overo-tobiduo-common.dtsi  |  8 +--
 arch/arm/boot/dts/omap3-sb-t35.dtsi           |  4 +-
 arch/arm/boot/dts/omap4-duovero-parlor.dts    |  6 +-
 21 files changed, 105 insertions(+), 112 deletions(-)

diff --git a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
index 7d0468a23781..f2364cb114c5 100644
--- a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
+++ b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
@@ -65,7 +65,7 @@
 		  1 0 0x2c000000 0x1000000	/* CS1: 16MB for LAN9221 */
 		  2 0 0x10000000 0x2000000>;    /* CS2: 32MB for NOR */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 1,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&lan9221_pins>;
 		interrupt-parent = <&gpio5>;
diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
index 5532db04046c..6357915d207b 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
+++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
@@ -4,8 +4,8 @@
 
 #include "omap36xx.dtsi"
 #include "logicpd-torpedo-som.dtsi"
-#include "omap-gpmc-smsc9221.dtsi"
 #include "logicpd-torpedo-baseboard.dtsi"
+#include "omap-gpmc-smsc9221.dtsi"
 
 / {
 	model = "LogicPD Zoom DM3730 Torpedo + Wireless Development Kit";
diff --git a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
index 533a47bc4a53..05049a34b6f1 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
+++ b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
@@ -95,7 +95,7 @@
 	ranges = <0 0 0x30000000 0x1000000	/* CS0: 16MB for NAND */
 		  1 0 0x2c000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 1,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&lan9221_pins>;
 		interrupt-parent = <&gpio5>;
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
index ded7e8fec9eb..2a462cb65a7d 100644
--- a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
+++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
@@ -20,36 +20,34 @@
 	};
 };
 
-&gpmc {
-	ethernet at gpmc {
-		compatible = "smsc,lan9221", "smsc,lan9115";
-		bank-width = <2>;
-		gpmc,device-width = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
-		gpmc,cs-on-ns = <5>;
-		gpmc,cs-rd-off-ns = <150>;
-		gpmc,cs-wr-off-ns = <150>;
-		gpmc,adv-on-ns = <0>;
-		gpmc,adv-rd-off-ns = <15>;
-		gpmc,adv-wr-off-ns = <40>;
-		gpmc,oe-on-ns = <45>;
-		gpmc,oe-off-ns = <140>;
-		gpmc,we-on-ns = <45>;
-		gpmc,we-off-ns = <140>;
-		gpmc,rd-cycle-ns = <155>;
-		gpmc,wr-cycle-ns = <155>;
-		gpmc,access-ns = <120>;
-		gpmc,page-burst-access-ns = <20>;
-		gpmc,bus-turnaround-ns = <75>;
-		gpmc,cycle2cycle-delay-ns = <75>;
-		gpmc,wait-monitoring-ns = <0>;
-		gpmc,clk-activation-ns = <0>;
-		gpmc,wr-data-mux-bus-ns = <0>;
-		gpmc,wr-access-ns = <0>;
-		vddvario-supply = <&vddvario>;
-		vdd33a-supply = <&vdd33a>;
-		reg-io-width = <4>;
-		smsc,save-mac-address;
-	};
+&gpmc_ethernet {
+	compatible = "smsc,lan9221", "smsc,lan9115";
+	bank-width = <2>;
+	gpmc,device-width = <1>;
+	gpmc,cycle2cycle-samecsen;
+	gpmc,cycle2cycle-diffcsen;
+	gpmc,cs-on-ns = <5>;
+	gpmc,cs-rd-off-ns = <150>;
+	gpmc,cs-wr-off-ns = <150>;
+	gpmc,adv-on-ns = <0>;
+	gpmc,adv-rd-off-ns = <15>;
+	gpmc,adv-wr-off-ns = <40>;
+	gpmc,oe-on-ns = <45>;
+	gpmc,oe-off-ns = <140>;
+	gpmc,we-on-ns = <45>;
+	gpmc,we-off-ns = <140>;
+	gpmc,rd-cycle-ns = <155>;
+	gpmc,wr-cycle-ns = <155>;
+	gpmc,access-ns = <120>;
+	gpmc,page-burst-access-ns = <20>;
+	gpmc,bus-turnaround-ns = <75>;
+	gpmc,cycle2cycle-delay-ns = <75>;
+	gpmc,wait-monitoring-ns = <0>;
+	gpmc,clk-activation-ns = <0>;
+	gpmc,wr-data-mux-bus-ns = <0>;
+	gpmc,wr-access-ns = <0>;
+	vddvario-supply = <&vddvario>;
+	vdd33a-supply = <&vdd33a>;
+	reg-io-width = <4>;
+	smsc,save-mac-address;
 };
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
index 7f6aefd13451..c1e78f929d2b 100644
--- a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
+++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
@@ -24,36 +24,33 @@
 	};
 };
 
-&gpmc {
-	ethernet at gpmc {
-		compatible = "smsc,lan9221","smsc,lan9115";
-		bank-width = <2>;
+&gpmc_ethernet {
+	compatible = "smsc,lan9221","smsc,lan9115";
+	bank-width = <2>;
+	gpmc,mux-add-data = <0>;
+	gpmc,cs-on-ns = <0>;
+	gpmc,cs-rd-off-ns = <42>;
+	gpmc,cs-wr-off-ns = <36>;
+	gpmc,adv-on-ns = <6>;
+	gpmc,adv-rd-off-ns = <12>;
+	gpmc,adv-wr-off-ns = <12>;
+	gpmc,oe-on-ns = <0>;
+	gpmc,oe-off-ns = <42>;
+	gpmc,we-on-ns = <0>;
+	gpmc,we-off-ns = <36>;
+	gpmc,rd-cycle-ns = <60>;
+	gpmc,wr-cycle-ns = <54>;
+	gpmc,access-ns = <36>;
+	gpmc,page-burst-access-ns = <0>;
+	gpmc,bus-turnaround-ns = <0>;
+	gpmc,cycle2cycle-delay-ns = <0>;
+	gpmc,wr-data-mux-bus-ns = <18>;
+	gpmc,wr-access-ns = <42>;
+	gpmc,cycle2cycle-samecsen;
+	gpmc,cycle2cycle-diffcsen;
 
-		gpmc,mux-add-data;
-		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <42>;
-		gpmc,cs-wr-off-ns = <36>;
-		gpmc,adv-on-ns = <6>;
-		gpmc,adv-rd-off-ns = <12>;
-		gpmc,adv-wr-off-ns = <12>;
-		gpmc,oe-on-ns = <0>;
-		gpmc,oe-off-ns = <42>;
-		gpmc,we-on-ns = <0>;
-		gpmc,we-off-ns = <36>;
-		gpmc,rd-cycle-ns = <60>;
-		gpmc,wr-cycle-ns = <54>;
-		gpmc,access-ns = <36>;
-		gpmc,page-burst-access-ns = <0>;
-		gpmc,bus-turnaround-ns = <0>;
-		gpmc,cycle2cycle-delay-ns = <0>;
-		gpmc,wr-data-mux-bus-ns = <18>;
-		gpmc,wr-access-ns = <42>;
-		gpmc,cycle2cycle-samecsen;
-		gpmc,cycle2cycle-diffcsen;
-
-		vddvario-supply = <&vddvario>;
-		vdd33a-supply = <&vdd33a>;
-		reg-io-width = <4>;
-		smsc,save-mac-address;
-	};
+	vddvario-supply = <&vddvario>;
+	vdd33a-supply = <&vdd33a>;
+	reg-io-width = <4>;
+	smsc,save-mac-address;
 };
diff --git a/arch/arm/boot/dts/omap-zoom-common.dtsi b/arch/arm/boot/dts/omap-zoom-common.dtsi
index d4ad9e58b199..47192c617cd1 100644
--- a/arch/arm/boot/dts/omap-zoom-common.dtsi
+++ b/arch/arm/boot/dts/omap-zoom-common.dtsi
@@ -3,8 +3,6 @@
  * Common features on the Zoom debug board
  */
 
-#include "omap-gpmc-smsc911x.dtsi"
-
 &gpmc {
 	ranges = <3 0 0x10000000 0x1000000>,	/* CS3: 16MB for UART */
 		 <7 0 0x2c000000 0x01000000>;
@@ -27,8 +25,8 @@
 		gpmc,mux-add-data = <0>;
 		gpmc,device-width = <1>;
 		gpmc,wait-pin = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 		gpmc,cs-on-ns = <5>;
 		gpmc,cs-rd-off-ns = <155>;
 		gpmc,cs-wr-off-ns = <155>;
@@ -50,7 +48,7 @@
 		gpmc,wr-data-mux-bus-ns = <45>;
 		gpmc,wr-access-ns = <145>;
 	};
-	uart at 3,1 {
+	uart at 3,100 {
 		compatible = "ns16550a";
 		reg = <3 0x100 8>;	/* CS3, offset 0x100, IO size 8 */
 		bank-width = <2>;
@@ -61,7 +59,7 @@
 		clock-frequency = <1843200>;
 		current-speed = <115200>;
 	};
-	uart at 3,2 {
+	uart at 3,200 {
 		compatible = "ns16550a";
 		reg = <3 0x200 8>;	/* CS3, offset 0x200, IO size 8 */
 		bank-width = <2>;
@@ -72,7 +70,7 @@
 		clock-frequency = <1843200>;
 		current-speed = <115200>;
 	};
-	uart at 3,3 {
+	uart at 3,300 {
 		compatible = "ns16550a";
 		reg = <3 0x300 8>;	/* CS3, offset 0x300, IO size 8 */
 		bank-width = <2>;
@@ -84,9 +82,11 @@
 		current-speed = <115200>;
 	};
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 7,0 {
 		reg = <7 0 0xff>;
 		interrupt-parent = <&gpio5>;
 		interrupts = <30 IRQ_TYPE_LEVEL_LOW>;	/* gpio158 */
 	};
 };
+
+#include "omap-gpmc-smsc911x.dtsi"
diff --git a/arch/arm/boot/dts/omap2430-sdp.dts b/arch/arm/boot/dts/omap2430-sdp.dts
index 7d27e907533f..f74906e4721b 100644
--- a/arch/arm/boot/dts/omap2430-sdp.dts
+++ b/arch/arm/boot/dts/omap2430-sdp.dts
@@ -34,7 +34,7 @@
 
 &gpmc {
 	ranges = <5 0 0x08000000 0x01000000>;
-	ethernet at gpmc {
+	ethernet at 5,300 {
 		compatible = "smsc,lan91c94";
 		interrupt-parent = <&gpio5>;
 		interrupts = <21 IRQ_TYPE_LEVEL_LOW>;	/* gpio149 */
@@ -43,8 +43,8 @@
 		gpmc,sync-clk-ps = <0>;
 		gpmc,mux-add-data = <2>;
 		gpmc,device-width = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 		gpmc,cs-on-ns = <6>;
 		gpmc,cs-rd-off-ns = <187>;
 		gpmc,cs-wr-off-ns = <187>;
diff --git a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
index 5e8943539fcc..2059463de9d6 100644
--- a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
+++ b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
@@ -47,13 +47,11 @@
 	};
 };
 
-#include "omap-gpmc-smsc911x.dtsi"
-
 &gpmc {
 	ranges = <5 0 0x2c000000 0x01000000>, /* CM-T3x30 SMSC9x Eth */
 		 <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
 
-	smsc1: ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		compatible = "smsc,lan9221", "smsc,lan9115";
 		pinctrl-names = "default";
 		pinctrl-0 = <&smsc1_pins>;
@@ -63,6 +61,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc911x.dtsi"
+
 &i2c1 {
 	twl: twl at 48 {
 		reg = <0x48>;
diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
index 2c19d6e255bd..5e55198e4576 100644
--- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
@@ -267,8 +267,8 @@
 		gpmc,mux-add-data = <0>;
 		gpmc,device-width = <1>;
 		gpmc,wait-pin = <0>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 
 		gpmc,cs-on-ns = <6>;
 		gpmc,cs-rd-off-ns = <180>;
diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts
index c9332195d096..077b1a19f171 100644
--- a/arch/arm/boot/dts/omap3-evm-37xx.dts
+++ b/arch/arm/boot/dts/omap3-evm-37xx.dts
@@ -7,6 +7,7 @@
 #include "omap36xx.dtsi"
 #include "omap3-evm-common.dtsi"
 #include "omap3-evm-processor-common.dtsi"
+#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	model = "TI OMAP37XX EVM (TMDSEVM3730)";
diff --git a/arch/arm/boot/dts/omap3-evm-common.dtsi b/arch/arm/boot/dts/omap3-evm-common.dtsi
index 17c89df6ce6b..2f7bdb248a51 100644
--- a/arch/arm/boot/dts/omap3-evm-common.dtsi
+++ b/arch/arm/boot/dts/omap3-evm-common.dtsi
@@ -4,7 +4,6 @@
  */
 
 #include <dt-bindings/input/input.h>
-#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	cpus {
@@ -182,14 +181,6 @@
 	power = <50>;
 };
 
-&gpmc {
-	ethernet at gpmc {
-		interrupt-parent = <&gpio6>;
-		interrupts = <16 8>;
-		reg = <5 0 0xff>;
-	};
-};
-
 &vaux2 {
 	regulator-name = "usb_1v8";
 	regulator-min-microvolt = <1800000>;
diff --git a/arch/arm/boot/dts/omap3-evm-processor-common.dtsi b/arch/arm/boot/dts/omap3-evm-processor-common.dtsi
index e6ba30a21166..3adb967b96c4 100644
--- a/arch/arm/boot/dts/omap3-evm-processor-common.dtsi
+++ b/arch/arm/boot/dts/omap3-evm-processor-common.dtsi
@@ -217,8 +217,11 @@
 	ranges = <0 0 0x30000000 0x1000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;	/* CS5: 16MB for LAN9220 */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&smsc911x_pins>;
+		interrupt-parent = <&gpio6>;
+		interrupts = <16 8>;
+		reg = <5 0 0xff>;
 	};
 };
diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts
index 5cc0cf7cd16c..805856d47cda 100644
--- a/arch/arm/boot/dts/omap3-evm.dts
+++ b/arch/arm/boot/dts/omap3-evm.dts
@@ -7,6 +7,7 @@
 #include "omap34xx.dtsi"
 #include "omap3-evm-common.dtsi"
 #include "omap3-evm-processor-common.dtsi"
+#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	model = "TI OMAP35XX EVM (TMDSEVM3530)";
diff --git a/arch/arm/boot/dts/omap3-igep0020-common.dtsi b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
index 73d8f471b9ec..104df84ea720 100644
--- a/arch/arm/boot/dts/omap3-igep0020-common.dtsi
+++ b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
@@ -7,7 +7,6 @@
  */
 
 #include "omap3-igep.dtsi"
-#include "omap-gpmc-smsc9221.dtsi"
 
 / {
 
@@ -217,7 +216,7 @@
 	ranges = <0 0 0x30000000 0x01000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;	/* CS5: 16MB for ethernet */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&smsc9221_pins>;
 		reg = <5 0 0xff>;
@@ -226,6 +225,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &uart2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart2_pins>;
diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts
index 9c6a92724590..a299f04217fd 100644
--- a/arch/arm/boot/dts/omap3-ldp.dts
+++ b/arch/arm/boot/dts/omap3-ldp.dts
@@ -6,7 +6,6 @@
 
 #include <dt-bindings/input/input.h>
 #include "omap34xx.dtsi"
-#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	model = "TI OMAP3430 LDP (Zoom1 Labrador)";
@@ -148,13 +147,15 @@
 		};
 	};
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 1,0 {
 		interrupt-parent = <&gpio5>;
 		interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
 		reg = <1 0 0xff>;
 	};
 };
 
+#include "omap-gpmc-smsc911x.dtsi"
+
 &i2c1 {
 	clock-frequency = <2600000>;
 
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 32335d4ce478..35602d7876aa 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -936,7 +936,7 @@
 	};
 
 	/* Ethernet is on some early development boards and qemu */
-	ethernet at gpmc {
+	ethernet at 1,0 {
 		compatible = "smsc,lan91c94";
 		interrupt-parent = <&gpio2>;
 		interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;	/* gpio54 */
diff --git a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
index 2d2c61d7aa86..34b805851dd2 100644
--- a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
@@ -49,16 +49,16 @@
 	};
 };
 
-#include "omap-gpmc-smsc9221.dtsi"
-
 &gpmc {
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;	/* GPIO 176 */
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &lis33de {
 	status = "disabled";
 };
diff --git a/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
index 9bf4b88a4b50..895803654e3c 100644
--- a/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
@@ -21,16 +21,16 @@
 	};
 };
 
-#include "omap-gpmc-smsc9221.dtsi"
-
 &gpmc {
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;	/* GPIO 176 */
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &lis33de {
 	status = "disabled";
 };
diff --git a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
index e5da3bc6f105..c212d72dcfe9 100644
--- a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
@@ -9,10 +9,8 @@
 
 #include "omap3-overo-common-peripherals.dtsi"
 
-#include "omap-gpmc-smsc9221.dtsi"
-
 &gpmc {
-	smsc1: ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;	/* GPIO 176 */
@@ -22,7 +20,7 @@
 		compatible = "smsc,lan9221","smsc,lan9115";
 		bank-width = <2>;
 
-		gpmc,mux-add-data;
+		gpmc,mux-add-data = <0>;
 		gpmc,cs-on-ns = <0>;
 		gpmc,cs-rd-off-ns = <42>;
 		gpmc,cs-wr-off-ns = <36>;
@@ -54,6 +52,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &lis33de {
 	status = "disabled";
 };
diff --git a/arch/arm/boot/dts/omap3-sb-t35.dtsi b/arch/arm/boot/dts/omap3-sb-t35.dtsi
index fb9842fa922c..5ec0893415e0 100644
--- a/arch/arm/boot/dts/omap3-sb-t35.dtsi
+++ b/arch/arm/boot/dts/omap3-sb-t35.dtsi
@@ -108,8 +108,8 @@
 		reg = <4 0 0xff>;
 		bank-width = <2>;
 		gpmc,device-width = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 		gpmc,cs-on-ns = <5>;
 		gpmc,cs-rd-off-ns = <150>;
 		gpmc,cs-wr-off-ns = <150>;
diff --git a/arch/arm/boot/dts/omap4-duovero-parlor.dts b/arch/arm/boot/dts/omap4-duovero-parlor.dts
index b294c22177cb..dfc50764c405 100644
--- a/arch/arm/boot/dts/omap4-duovero-parlor.dts
+++ b/arch/arm/boot/dts/omap4-duovero-parlor.dts
@@ -131,12 +131,10 @@
 	status = "disabled";
 };
 
-#include "omap-gpmc-smsc911x.dtsi"
-
 &gpmc {
 	ranges = <5 0 0x2c000000 0x1000000>;			/* CS5 */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio2>;
 		interrupts = <12 IRQ_TYPE_LEVEL_LOW>;		/* gpio_44 */
@@ -170,6 +168,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc911x.dtsi"
+
 &dss {
 	status = "okay";
 };
-- 
2.17.1



From rogerq at kernel.org  Tue Sep  7 04:32:20 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue,  7 Sep 2021 14:32:20 +0300
Subject: [PATCH v3 2/8] dt-bindings: mtd: Remove gpmc-nor.txt
In-Reply-To: <20210907113226.31876-1-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
Message-ID: <20210907113226.31876-3-rogerq@kernel.org>

There is no GPMC NOR compatible or device driver. GPMC is just
a bus interface over which standard (CFI/JEDC) NOR Flash chips
can be attached.

For NOR chip bindings, please refer to
Documentation/devicetree/bindings/mtd/mtd-physmap.yaml

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/mtd/gpmc-nor.txt      | 98 -------------------
 1 file changed, 98 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
deleted file mode 100644
index c8567b40fe13..000000000000
--- a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-Device tree bindings for NOR flash connect to TI GPMC
-
-NOR flash connected to the TI GPMC (found on OMAP boards) are represented as
-child nodes of the GPMC controller with a name of "nor".
-
-All timing relevant properties as well as generic GPMC child properties are
-explained in a separate documents. Please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-Required properties:
-- bank-width: 		Width of NOR flash in bytes. GPMC supports 8-bit and
-			16-bit devices and so must be either 1 or 2 bytes.
-- compatible:		Documentation/devicetree/bindings/mtd/mtd-physmap.txt
-- gpmc,cs-on-ns:		Chip-select assertion time
-- gpmc,cs-rd-off-ns:	Chip-select de-assertion time for reads
-- gpmc,cs-wr-off-ns:	Chip-select de-assertion time for writes
-- gpmc,oe-on-ns:	Output-enable assertion time
-- gpmc,oe-off-ns:	Output-enable de-assertion time
-- gpmc,we-on-ns		Write-enable assertion time
-- gpmc,we-off-ns:	Write-enable de-assertion time
-- gpmc,access-ns:	Start cycle to first data capture (read access)
-- gpmc,rd-cycle-ns:	Total read cycle time
-- gpmc,wr-cycle-ns:	Total write cycle time
-- linux,mtd-name:	Documentation/devicetree/bindings/mtd/mtd-physmap.txt
-- reg:			Chip-select, base address (relative to chip-select)
-			and size of NOR flash. Note that base address will be
-			typically 0 as this is the start of the chip-select.
-
-Optional properties:
-- gpmc,XXX		Additional GPMC timings and settings parameters. See
-			Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-Optional properties for partition table parsing:
-- #address-cells: should be set to 1
-- #size-cells: should be set to 1
-
-Example:
-
-gpmc: gpmc at 6e000000 {
-	compatible = "ti,omap3430-gpmc", "simple-bus";
-	ti,hwmods = "gpmc";
-	reg = <0x6e000000 0x1000>;
-	interrupts = <20>;
-	gpmc,num-cs = <8>;
-	gpmc,num-waitpins = <4>;
-	#address-cells = <2>;
-	#size-cells = <1>;
-
-	ranges = <0 0 0x10000000 0x08000000>;
-
-	nor at 0,0 {
-		compatible = "cfi-flash";
-		linux,mtd-name= "intel,pf48f6000m0y1be";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		reg = <0 0 0x08000000>;
-		bank-width = <2>;
-
-		gpmc,mux-add-data;
-		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <186>;
-		gpmc,cs-wr-off-ns = <186>;
-		gpmc,adv-on-ns = <12>;
-		gpmc,adv-rd-off-ns = <48>;
-		gpmc,adv-wr-off-ns = <48>;
-		gpmc,oe-on-ns = <54>;
-		gpmc,oe-off-ns = <168>;
-		gpmc,we-on-ns = <54>;
-		gpmc,we-off-ns = <168>;
-		gpmc,rd-cycle-ns = <186>;
-		gpmc,wr-cycle-ns = <186>;
-		gpmc,access-ns = <114>;
-		gpmc,page-burst-access-ns = <6>;
-		gpmc,bus-turnaround-ns = <12>;
-		gpmc,cycle2cycle-delay-ns = <18>;
-		gpmc,wr-data-mux-bus-ns = <90>;
-		gpmc,wr-access-ns = <186>;
-		gpmc,cycle2cycle-samecsen;
-		gpmc,cycle2cycle-diffcsen;
-
-		partition at 0 {
-			label = "bootloader-nor";
-			reg = <0 0x40000>;
-		};
-		partition at 40000 {
-			label = "params-nor";
-			reg = <0x40000 0x40000>;
-		};
-		partition at 80000 {
-			label = "kernel-nor";
-			reg = <0x80000 0x200000>;
-		};
-		partition at 280000 {
-			label = "filesystem-nor";
-			reg = <0x240000 0x7d80000>;
-		};
-	};
-};
-- 
2.17.1



From rogerq at kernel.org  Tue Sep  7 04:32:21 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue,  7 Sep 2021 14:32:21 +0300
Subject: [PATCH v3 3/8] dt-bindings: net: Remove gpmc-eth.txt
In-Reply-To: <20210907113226.31876-1-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
Message-ID: <20210907113226.31876-4-rogerq@kernel.org>

There is no GPMC Ethernet compatible or device driver. GPMC is
just a bus interface over which devices like Ethernet controller
can be to.

For SMSC 911x Ethernet chip bindings, please refer to
Documentation/devicetree/bindings/net/smsc,lan9115.yaml

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/net/gpmc-eth.txt      | 97 -------------------
 1 file changed, 97 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt

diff --git a/Documentation/devicetree/bindings/net/gpmc-eth.txt b/Documentation/devicetree/bindings/net/gpmc-eth.txt
deleted file mode 100644
index 32821066a85b..000000000000
--- a/Documentation/devicetree/bindings/net/gpmc-eth.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-Device tree bindings for Ethernet chip connected to TI GPMC
-
-Besides being used to interface with external memory devices, the
-General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices
-such as ethernet controllers to processors using the TI GPMC as a data bus.
-
-Ethernet controllers connected to TI GPMC are represented as child nodes of
-the GPMC controller with an "ethernet" name.
-
-All timing relevant properties as well as generic GPMC child properties are
-explained in a separate documents. Please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-For the properties relevant to the ethernet controller connected to the GPMC
-refer to the binding documentation of the device. For example, the documentation
-for the SMSC 911x is Documentation/devicetree/bindings/net/smsc,lan9115.yaml
-
-Child nodes need to specify the GPMC bus address width using the "bank-width"
-property but is possible that an ethernet controller also has a property to
-specify the I/O registers address width. Even when the GPMC has a maximum 16-bit
-address width, it supports devices with 32-bit word registers.
-For example with an SMSC LAN911x/912x controller connected to the TI GPMC on an
-OMAP2+ board, "bank-width = <2>;" and "reg-io-width = <4>;".
-
-Required properties:
-- bank-width: 		Address width of the device in bytes. GPMC supports 8-bit
-			and 16-bit devices and so must be either 1 or 2 bytes.
-- compatible:		Compatible string property for the ethernet child device.
-- gpmc,cs-on-ns:	Chip-select assertion time
-- gpmc,cs-rd-off-ns:	Chip-select de-assertion time for reads
-- gpmc,cs-wr-off-ns:	Chip-select de-assertion time for writes
-- gpmc,oe-on-ns:	Output-enable assertion time
-- gpmc,oe-off-ns:	Output-enable de-assertion time
-- gpmc,we-on-ns:	Write-enable assertion time
-- gpmc,we-off-ns:	Write-enable de-assertion time
-- gpmc,access-ns:	Start cycle to first data capture (read access)
-- gpmc,rd-cycle-ns:	Total read cycle time
-- gpmc,wr-cycle-ns:	Total write cycle time
-- reg:			Chip-select, base address (relative to chip-select)
-			and size of the memory mapped for the device.
-			Note that base address will be typically 0 as this
-			is the start of the chip-select.
-
-Optional properties:
-- gpmc,XXX		Additional GPMC timings and settings parameters. See
-			Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-Example:
-
-gpmc: gpmc at 6e000000 {
-	compatible = "ti,omap3430-gpmc";
-	ti,hwmods = "gpmc";
-	reg = <0x6e000000 0x1000>;
-	interrupts = <20>;
-	gpmc,num-cs = <8>;
-	gpmc,num-waitpins = <4>;
-	#address-cells = <2>;
-	#size-cells = <1>;
-
-	ranges = <5 0 0x2c000000 0x1000000>;
-
-	ethernet at 5,0 {
-		compatible = "smsc,lan9221", "smsc,lan9115";
-		reg = <5 0 0xff>;
-		bank-width = <2>;
-
-		gpmc,mux-add-data;
-		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <186>;
-		gpmc,cs-wr-off-ns = <186>;
-		gpmc,adv-on-ns = <12>;
-		gpmc,adv-rd-off-ns = <48>;
-		gpmc,adv-wr-off-ns = <48>;
-		gpmc,oe-on-ns = <54>;
-		gpmc,oe-off-ns = <168>;
-		gpmc,we-on-ns = <54>;
-		gpmc,we-off-ns = <168>;
-		gpmc,rd-cycle-ns = <186>;
-		gpmc,wr-cycle-ns = <186>;
-		gpmc,access-ns = <114>;
-		gpmc,page-burst-access-ns = <6>;
-		gpmc,bus-turnaround-ns = <12>;
-		gpmc,cycle2cycle-delay-ns = <18>;
-		gpmc,wr-data-mux-bus-ns = <90>;
-		gpmc,wr-access-ns = <186>;
-		gpmc,cycle2cycle-samecsen;
-		gpmc,cycle2cycle-diffcsen;
-
-		interrupt-parent = <&gpio6>;
-		interrupts = <16>;
-		vmmc-supply = <&vddvario>;
-		vmmc_aux-supply = <&vdd33a>;
-		reg-io-width = <4>;
-
-		smsc,save-mac-address;
-	};
-};
-- 
2.17.1



From rogerq at kernel.org  Tue Sep  7 04:32:22 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue,  7 Sep 2021 14:32:22 +0300
Subject: [PATCH v3 4/8] dt-bindings: memory-controllers: Introduce ti,
 gpmc-child
In-Reply-To: <20210907113226.31876-1-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
Message-ID: <20210907113226.31876-5-rogerq@kernel.org>

This binding is meant for the child nodes of the TI GPMC node. The node
represents any device connected to the GPMC bus. It may be a Flash chip,
RAM chip or Ethernet controller, etc. These properties are meant for
configuring the GPMC settings/timings and will accompany the bindings
supported by the respective device.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../memory-controllers/ti,gpmc-child.yaml     | 245 ++++++++++++++++++
 1 file changed, 245 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml
new file mode 100644
index 000000000000..6e3995bb1630
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml
@@ -0,0 +1,245 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/ti,gpmc-child.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: device tree bindings for children of the Texas Instruments GPMC
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+  This binding is meant for the child nodes of the GPMC node. The node
+  represents any device connected to the GPMC bus. It may be a Flash chip,
+  RAM chip or Ethernet controller, etc. These properties are meant for
+  configuring the GPMC settings/timings and will accompany the bindings
+  supported by the respective device.
+
+properties:
+  reg: true
+
+# GPMC Timing properties for child nodes. All are optional and default to 0.
+  gpmc,sync-clk-ps:
+    description: Minimum clock period for synchronous mode
+    default: 0
+
+# Chip-select signal timings corresponding to GPMC_CONFIG2:
+  gpmc,cs-on-ns:
+    description: Assertion time
+    default: 0
+
+  gpmc,cs-rd-off-ns:
+    description: Read deassertion time
+    default: 0
+
+  gpmc,cs-wr-off-ns:
+    description: Write deassertion time
+    default: 0
+
+# ADV signal timings corresponding to GPMC_CONFIG3:
+  gpmc,adv-on-ns:
+    description: Assertion time
+    default: 0
+
+  gpmc,adv-rd-off-ns:
+    description: Read deassertion time
+    default: 0
+
+  gpmc,adv-wr-off-ns:
+    description: Write deassertion time
+    default: 0
+
+  gpmc,adv-aad-mux-on-ns:
+    description: Assertion time for AAD
+    default: 0
+
+  gpmc,adv-aad-mux-rd-off-ns:
+    description: Read deassertion time for AAD
+    default: 0
+
+  gpmc,adv-aad-mux-wr-off-ns:
+    description: Write deassertion time for AAD
+    default: 0
+
+# WE signals timings corresponding to GPMC_CONFIG4:
+  gpmc,we-on-ns:
+    description: Assertion time
+    default: 0
+
+  gpmc,we-off-ns:
+    description: Deassertion time
+    default: 0
+
+# OE signals timings corresponding to GPMC_CONFIG4:
+  gpmc,oe-on-ns:
+    description: Assertion time
+    default: 0
+
+  gpmc,oe-off-ns:
+    description: Deassertion time
+    default: 0
+
+  gpmc,oe-aad-mux-on-ns:
+    description: Assertion time for AAD
+    default: 0
+
+  gpmc,oe-aad-mux-off-ns:
+    description: Deassertion time for AAD
+    default: 0
+
+# Access time and cycle time timings (in nanoseconds) corresponding to
+# GPMC_CONFIG5:
+  gpmc,page-burst-access-ns:
+    description: Multiple access word delay
+    default: 0
+
+  gpmc,access-ns:
+    description: Start-cycle to first data valid delay
+    default: 0
+
+  gpmc,rd-cycle-ns:
+    description: Total read cycle time
+    default: 0
+
+  gpmc,wr-cycle-ns:
+    description: Total write cycle time
+    default: 0
+
+  gpmc,bus-turnaround-ns:
+    description: Turn-around time between successive accesses
+    default: 0
+
+  gpmc,cycle2cycle-delay-ns:
+    description: Delay between chip-select pulses
+    default: 0
+
+  gpmc,clk-activation-ns:
+    description: GPMC clock activation time
+    default: 0
+
+  gpmc,wait-monitoring-ns:
+    description: Start of wait monitoring with regard to valid data
+    default: 0
+
+# Boolean timing parameters. If property is present, parameter is enabled
+# otherwise disabled.
+  gpmc,adv-extra-delay:
+    description: ADV signal is delayed by half GPMC clock
+    type: boolean
+
+  gpmc,cs-extra-delay:
+    description: CS signal is delayed by half GPMC clock
+    type: boolean
+
+  gpmc,cycle2cycle-diffcsen:
+    description: |
+      Add "cycle2cycle-delay" between successive accesses
+      to a different CS
+    type: boolean
+
+  gpmc,cycle2cycle-samecsen:
+    description: |
+      Add "cycle2cycle-delay" between successive accesses
+      to the same CS
+    type: boolean
+
+  gpmc,oe-extra-delay:
+    description: OE signal is delayed by half GPMC clock
+    type: boolean
+
+  gpmc,we-extra-delay:
+    description: WE signal is delayed by half GPMC clock
+    type: boolean
+
+  gpmc,time-para-granularity:
+    description: Multiply all access times by 2
+    type: boolean
+
+# The following two properties are applicable only to OMAP3+ and AM335x:
+  gpmc,wr-access-ns:
+    description: |
+      In synchronous write mode, for single or
+      burst accesses, defines the number of
+      GPMC_FCLK cycles from start access time
+      to the GPMC_CLK rising edge used by the
+      memory device for the first data capture.
+    default: 0
+
+  gpmc,wr-data-mux-bus-ns:
+    description: |
+      In address-data multiplex mode, specifies
+      the time when the first data is driven on
+      the address-data bus.
+    default: 0
+
+# GPMC chip-select settings properties for child nodes. All are optional.
+  gpmc,burst-length:
+    description: Page/burst length.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 4, 8, 16]
+    default: 0
+
+  gpmc,burst-wrap:
+    description: Enables wrap bursting
+    type: boolean
+
+  gpmc,burst-read:
+    description: Enables read page/burst mode
+    type: boolean
+
+  gpmc,burst-write:
+    description: Enables write page/burst mode
+    type: boolean
+
+  gpmc,device-width:
+    description: |
+      Total width of device(s) connected to a GPMC
+      chip-select in bytes. The GPMC supports 8-bit
+      and 16-bit devices and so this property must be
+      1 or 2.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2]
+    default: 1
+
+  gpmc,mux-add-data:
+    description: |
+      Address and data multiplexing configuration.
+      Valid values are
+      0 for Non multiplexed mode
+      1 for address-address-data multiplexing mode and
+      2 for address-data multiplexing mode.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1, 2]
+
+  gpmc,sync-read:
+    description: |
+      Enables synchronous read. Defaults to asynchronous
+      is this is not set.
+    type: boolean
+
+  gpmc,sync-write:
+    description: |
+      Enables synchronous writes. Defaults to asynchronous
+      is this is not set.
+    type: boolean
+
+  gpmc,wait-pin:
+    description: |
+      Wait-pin used by client. Must be less than "gpmc,num-waitpins".
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  gpmc,wait-on-read:
+    description: Enables wait monitoring on reads.
+    type: boolean
+
+  gpmc,wait-on-write:
+    description: Enables wait monitoring on writes.
+    type: boolean
+
+required:
+  - reg
+
+# the GPMC child will have its own native properties
+additionalProperties: true
-- 
2.17.1



From rogerq at kernel.org  Tue Sep  7 04:32:23 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue,  7 Sep 2021 14:32:23 +0300
Subject: [PATCH v3 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <20210907113226.31876-1-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
Message-ID: <20210907113226.31876-6-rogerq@kernel.org>

Convert gpmc-nand.txt to ti,gpmc-nand.yaml.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 ------------------
 .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 110 +++++++++++++
 2 files changed, 110 insertions(+), 147 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
deleted file mode 100644
index 44919d48d241..000000000000
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-Device tree bindings for GPMC connected NANDs
-
-GPMC connected NAND (found on OMAP boards) are represented as child nodes of
-the GPMC controller with a name of "nand".
-
-All timing relevant properties as well as generic gpmc child properties are
-explained in a separate documents - please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-For NAND specific properties such as ECC modes or bus width, please refer to
-Documentation/devicetree/bindings/mtd/nand-controller.yaml
-
-
-Required properties:
-
- - compatible:	"ti,omap2-nand"
- - reg:		range id (CS number), base offset and length of the
-		NAND I/O space
- - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
-
-Optional properties:
-
- - nand-bus-width: 		Set this numeric value to 16 if the hardware
-				is wired that way. If not specified, a bus
-				width of 8 is assumed.
-
- - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
-		"sw"		1-bit Hamming ecc code via software
-		"hw"		<deprecated> use "ham1" instead
-		"hw-romcode"	<deprecated> use "ham1" instead
-		"ham1"		1-bit Hamming ecc code
-		"bch4"		4-bit BCH ecc code
-		"bch8"		8-bit BCH ecc code
-		"bch16"		16-bit BCH ECC code
-		Refer below "How to select correct ECC scheme for your device ?"
-
- - ti,nand-xfer-type:		A string setting the data transfer type. One of:
-
-		"prefetch-polled"	Prefetch polled mode (default)
-		"polled"		Polled mode, without prefetch
-		"prefetch-dma"		Prefetch enabled DMA mode
-		"prefetch-irq"		Prefetch enabled irq mode
-
- - elm_id:	<deprecated> use "ti,elm-id" instead
- - ti,elm-id:	Specifies phandle of the ELM devicetree node.
-		ELM is an on-chip hardware engine on TI SoC which is used for
-		locating ECC errors for BCHx algorithms. SoC devices which have
-		ELM hardware engines should specify this device node in .dtsi
-		Using ELM for ECC error correction frees some CPU cycles.
- - rb-gpios:	GPIO specifier for the ready/busy# pin.
-
-For inline partition table parsing (optional):
-
- - #address-cells: should be set to 1
- - #size-cells: should be set to 1
-
-Example for an AM33xx board:
-
-	gpmc: gpmc at 50000000 {
-		compatible = "ti,am3352-gpmc";
-		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x36c>;
-		interrupts = <100>;
-		gpmc,num-cs = <8>;
-		gpmc,num-waitpins = <2>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
-		elm_id = <&elm>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-
-		nand at 0,0 {
-			compatible = "ti,omap2-nand";
-			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
-			interrupt-parent = <&gpmc>;
-			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
-			nand-bus-width = <16>;
-			ti,nand-ecc-opt = "bch8";
-			ti,nand-xfer-type = "polled";
-			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
-
-			gpmc,sync-clk-ps = <0>;
-			gpmc,cs-on-ns = <0>;
-			gpmc,cs-rd-off-ns = <44>;
-			gpmc,cs-wr-off-ns = <44>;
-			gpmc,adv-on-ns = <6>;
-			gpmc,adv-rd-off-ns = <34>;
-			gpmc,adv-wr-off-ns = <44>;
-			gpmc,we-off-ns = <40>;
-			gpmc,oe-off-ns = <54>;
-			gpmc,access-ns = <64>;
-			gpmc,rd-cycle-ns = <82>;
-			gpmc,wr-cycle-ns = <82>;
-			gpmc,wr-access-ns = <40>;
-			gpmc,wr-data-mux-bus-ns = <0>;
-
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			/* partitions go here */
-		};
-	};
-
-How to select correct ECC scheme for your device ?
---------------------------------------------------
-Higher ECC scheme usually means better protection against bit-flips and
-increased system lifetime. However, selection of ECC scheme is dependent
-on various other factors also like;
-
-(1) support of built in hardware engines.
-	Some legacy OMAP SoC do not have ELM harware engine, so those SoC cannot
-	support ecc-schemes with hardware error-correction (BCHx_HW). However
-	such SoC can use ecc-schemes with software library for error-correction
-	(BCHx_HW_DETECTION_SW). The error correction capability with software
-	library remains equivalent to their hardware counter-part, but there is
-	slight CPU penalty when too many bit-flips are detected during reads.
-
-(2) Device parameters like OOBSIZE.
-	Other factor which governs the selection of ecc-scheme is oob-size.
-	Higher ECC schemes require more OOB/Spare area to store ECC syndrome,
-	so the device should have enough free bytes available its OOB/Spare
-	area to accommodate ECC for entire page. In general following expression
-	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
-	where
-		OOBSIZE		number of bytes in OOB/spare area
-		PAGESIZE	number of bytes in main-area of device page
-		ECC_BYTES	number of ECC bytes generated to protect
-		                512 bytes of data, which is:
-				'3' for HAM1_xx ecc schemes
-				'7' for BCH4_xx ecc schemes
-				'14' for BCH8_xx ecc schemes
-				'26' for BCH16_xx ecc schemes
-
-	Example(a): For a device with PAGESIZE = 2048 and OOBSIZE = 64 and
-		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
-		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
-		which is greater than capacity of NAND device (OOBSIZE=64)
-		Hence, BCH16 cannot be supported on given device. But it can
-		probably use lower ecc-schemes like BCH8.
-
-	Example(b): For a device with PAGESIZE = 2048 and OOBSIZE = 128 and
-		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
-		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
-		which can be accommodated in the OOB/Spare area of this device
-		(OOBSIZE=128). So this device can use BCH16 ecc-scheme.
diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
new file mode 100644
index 000000000000..db36f2e944ef
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
@@ -0,0 +1,110 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/ti,gpmc-nand.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments GPMC NAND Flash controller.
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+  GPMC NAND controller/Flash is represented as a child of the
+  GPMC controller node.
+
+properties:
+  compatible:
+    const: ti,omap2-nand
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Interrupt for fifoevent
+      - description: Interrupt for termcount
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ti,nand-ecc-opt:
+    description: Desired ECC algorithm
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [sw, ham1, bch4, bch8, bch16]
+
+  ti,nand-xfer-type:
+    description: Data transfer method between controller and chip.
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [prefetch-polled, polled, prefetch-dma, prefetch-irq]
+    default: prefetch-polled
+
+  ti,elm-id:
+    description:
+      phandle to the ELM (Error Location Module).
+    $ref: /schemas/types.yaml#/definitions/phandle
+
+  nand-bus-width:
+    description:
+      Bus width to the NAND chip
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [8, 16]
+    default: 8
+
+allOf:
+  - $ref: "../memory-controllers/ti,gpmc-child.yaml"
+
+required:
+  - compatible
+  - reg
+  - ti,nand-ecc-opt
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    gpmc: memory-controller at 50000000 {
+      compatible = "ti,am3352-gpmc";
+      dmas = <&edma 52 0>;
+      dma-names = "rxtx";
+      clocks = <&l3s_gclk>;
+      clock-names = "fck";
+      reg = <0x50000000 0x2000>;
+      interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+      gpmc,num-cs = <7>;
+      gpmc,num-waitpins = <2>;
+      #address-cells = <2>;
+      #size-cells = <1>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      gpio-controller;
+      #gpio-cells = <2>;
+
+      ranges = <0 0 0x08000000 0x01000000>;   /* CS0 space. Min partition = 16MB */
+      nand at 0,0 {
+        compatible = "ti,omap2-nand";
+        reg = <0 0 4>;          /* device IO registers */
+        interrupt-parent = <&gpmc>;
+        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+                     <1 IRQ_TYPE_NONE>; /* termcount */
+        ti,nand-xfer-type = "prefetch-dma";
+        ti,nand-ecc-opt = "bch16";
+        ti,elm-id = <&elm>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        /* NAND generic properties */
+        nand-bus-width = <8>;
+        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>;  /* gpmc_wait0 */
+
+        /* GPMC properties*/
+        gpmc,device-width = <1>;
+      };
+    };
-- 
2.17.1



From rogerq at kernel.org  Tue Sep  7 04:32:24 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue,  7 Sep 2021 14:32:24 +0300
Subject: [PATCH v3 6/8] dt-bindings: mtd: ti,gpmc-onenand: Convert to yaml
In-Reply-To: <20210907113226.31876-1-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
Message-ID: <20210907113226.31876-7-rogerq@kernel.org>

Convert gpmc-onenand.txt to ti,gpmc-onenand.yaml.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/mtd/gpmc-onenand.txt  | 48 -------------
 .../bindings/mtd/ti,gpmc-onenand.yaml         | 69 +++++++++++++++++++
 2 files changed, 69 insertions(+), 48 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
deleted file mode 100644
index e9f01a963a0a..000000000000
--- a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-Device tree bindings for GPMC connected OneNANDs
-
-GPMC connected OneNAND (found on OMAP boards) are represented as child nodes of
-the GPMC controller with a name of "onenand".
-
-All timing relevant properties as well as generic gpmc child properties are
-explained in a separate documents - please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-Required properties:
-
- - compatible:		"ti,omap2-onenand"
- - reg:			The CS line the peripheral is connected to
- - gpmc,device-width:	Width of the ONENAND device connected to the GPMC
-			in bytes. Must be 1 or 2.
-
-Optional properties:
-
- - int-gpios:		GPIO specifier for the INT pin.
-
-For inline partition table parsing (optional):
-
- - #address-cells: should be set to 1
- - #size-cells: should be set to 1
-
-Example for an OMAP3430 board:
-
-	gpmc: gpmc at 6e000000 {
-		compatible = "ti,omap3430-gpmc";
-		ti,hwmods = "gpmc";
-		reg = <0x6e000000 0x1000000>;
-		interrupts = <20>;
-		gpmc,num-cs = <8>;
-		gpmc,num-waitpins = <4>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-
-		onenand at 0 {
-			compatible = "ti,omap2-onenand";
-			reg = <0 0 0>; /* CS0, offset 0 */
-			gpmc,device-width = <2>;
-
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			/* partitions go here */
-		};
-	};
diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
new file mode 100644
index 000000000000..44001364092e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/ti,gpmc-onenand.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: OneNAND over Texas Instruments GPMC bus.
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+  GPMC connected OneNAND (found on OMAP boards) are represented
+  as child nodes of the GPMC controller.
+
+properties:
+  compatible:
+    const: ti,omap2-onenand
+
+  reg:
+    items:
+      - description: |
+          Chip Select number, register offset and size of
+          OneNAND register window.
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  int-gpios:
+    description: GPIO specifier for the INT pin.
+
+allOf:
+  - $ref: "../memory-controllers/ti,gpmc-child.yaml"
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    gpmc: memory-controller at 6e000000 {
+      compatible = "ti,omap3430-gpmc";
+      reg = <0x6e000000 0x02d0>;
+      interrupts = <20>;
+      gpmc,num-cs = <8>;
+      gpmc,num-waitpins = <4>;
+      clocks = <&l3s_clkctrl>;
+      clock-names = "fck";
+      #address-cells = <2>;
+      #size-cells = <1>;
+
+      ranges = <0 0 0x01000000 0x01000000>,   /* 16 MB for OneNAND */
+               <1 0 0x02000000 0x01000000>;   /* 16 MB for smc91c96 */
+
+      onenand at 0,0 {
+        compatible = "ti,omap2-onenand";
+        reg = <0 0 0x20000>;    /* CS0, offset 0, IO size 128K */
+        #address-cells = <1>;
+        #size-cells = <1>;
+      };
+    };
-- 
2.17.1



From rogerq at kernel.org  Tue Sep  7 04:32:25 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue,  7 Sep 2021 14:32:25 +0300
Subject: [PATCH v3 7/8] dt-bindings: memory-controllers: ti,
 gpmc: Convert to yaml
In-Reply-To: <20210907113226.31876-1-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
Message-ID: <20210907113226.31876-8-rogerq@kernel.org>

Convert omap-gpmc.txt to ti,gpmc.yaml.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../bindings/memory-controllers/omap-gpmc.txt | 157 ----------------
 .../bindings/memory-controllers/ti,gpmc.yaml  | 174 ++++++++++++++++++
 2 files changed, 174 insertions(+), 157 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt b/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
deleted file mode 100644
index c1359f4d48d7..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
+++ /dev/null
@@ -1,157 +0,0 @@
-Device tree bindings for OMAP general purpose memory controllers (GPMC)
-
-The actual devices are instantiated from the child nodes of a GPMC node.
-
-Required properties:
-
- - compatible:		Should be set to one of the following:
-
-			ti,omap2420-gpmc (omap2420)
-			ti,omap2430-gpmc (omap2430)
-			ti,omap3430-gpmc (omap3430 & omap3630)
-			ti,omap4430-gpmc (omap4430 & omap4460 & omap543x)
-			ti,am3352-gpmc   (am335x devices)
-
- - reg:			A resource specifier for the register space
-			(see the example below)
- - ti,hwmods:		Should be set to "ti,gpmc" until the DT transition is
-			completed.
- - #address-cells:	Must be set to 2 to allow memory address translation
- - #size-cells:		Must be set to 1 to allow CS address passing
- - gpmc,num-cs:		The maximum number of chip-select lines that controller
-			can support.
- - gpmc,num-waitpins:	The maximum number of wait pins that controller can
-			support.
- - ranges:		Must be set up to reflect the memory layout with four
-			integer values for each chip-select line in use:
-
-			   <cs-number> 0 <physical address of mapping> <size>
-
-			Currently, calculated values derived from the contents
-			of the per-CS register GPMC_CONFIG7 (as set up by the
-			bootloader) are used for the physical address decoding.
-			As this will change in the future, filling correct
-			values here is a requirement.
- - interrupt-controller: The GPMC driver implements and interrupt controller for
-			the NAND events "fifoevent" and "termcount" plus the
-			rising/falling edges on the GPMC_WAIT pins.
-			The interrupt number mapping is as follows
-			0 - NAND_fifoevent
-			1 - NAND_termcount
-			2 - GPMC_WAIT0 pin edge
-			3 - GPMC_WAIT1 pin edge, and so on.
- - interrupt-cells:	Must be set to 2
- - gpio-controller:	The GPMC driver implements a GPIO controller for the
-			GPMC WAIT pins that can be used as general purpose inputs.
-			0 maps to GPMC_WAIT0 pin.
- - gpio-cells:		Must be set to 2
-
-Required properties when using NAND prefetch dma:
- - dmas			GPMC NAND prefetch dma channel
- - dma-names		Must be set to "rxtx"
-
-Timing properties for child nodes. All are optional and default to 0.
-
- - gpmc,sync-clk-ps:	Minimum clock period for synchronous mode, in picoseconds
-
- Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2:
- - gpmc,cs-on-ns:	Assertion time
- - gpmc,cs-rd-off-ns:	Read deassertion time
- - gpmc,cs-wr-off-ns:	Write deassertion time
-
- ADV signal timings (in nanoseconds) corresponding to GPMC_CONFIG3:
- - gpmc,adv-on-ns:	Assertion time
- - gpmc,adv-rd-off-ns:	Read deassertion time
- - gpmc,adv-wr-off-ns:	Write deassertion time
- - gpmc,adv-aad-mux-on-ns:	Assertion time for AAD
- - gpmc,adv-aad-mux-rd-off-ns:	Read deassertion time for AAD
- - gpmc,adv-aad-mux-wr-off-ns:	Write deassertion time for AAD
-
- WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
- - gpmc,we-on-ns	Assertion time
- - gpmc,we-off-ns:	Deassertion time
-
- OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
- - gpmc,oe-on-ns:	Assertion time
- - gpmc,oe-off-ns:	Deassertion time
- - gpmc,oe-aad-mux-on-ns:	Assertion time for AAD
- - gpmc,oe-aad-mux-off-ns:	Deassertion time for AAD
-
- Access time and cycle time timings (in nanoseconds) corresponding to
- GPMC_CONFIG5:
- - gpmc,page-burst-access-ns: 	Multiple access word delay
- - gpmc,access-ns:		Start-cycle to first data valid delay
- - gpmc,rd-cycle-ns:		Total read cycle time
- - gpmc,wr-cycle-ns:		Total write cycle time
- - gpmc,bus-turnaround-ns:	Turn-around time between successive accesses
- - gpmc,cycle2cycle-delay-ns:	Delay between chip-select pulses
- - gpmc,clk-activation-ns: 	GPMC clock activation time
- - gpmc,wait-monitoring-ns:	Start of wait monitoring with regard to valid
-				data
-
-Boolean timing parameters. If property is present parameter enabled and
-disabled if omitted:
- - gpmc,adv-extra-delay:	ADV signal is delayed by half GPMC clock
- - gpmc,cs-extra-delay:		CS signal is delayed by half GPMC clock
- - gpmc,cycle2cycle-diffcsen:	Add "cycle2cycle-delay" between successive
-				accesses to a different CS
- - gpmc,cycle2cycle-samecsen:	Add "cycle2cycle-delay" between successive
-				accesses to the same CS
- - gpmc,oe-extra-delay:		OE signal is delayed by half GPMC clock
- - gpmc,we-extra-delay:		WE signal is delayed by half GPMC clock
- - gpmc,time-para-granularity:	Multiply all access times by 2
-
-The following are only applicable to OMAP3+ and AM335x:
- - gpmc,wr-access-ns:		In synchronous write mode, for single or
-				burst accesses, defines the number of
-				GPMC_FCLK cycles from start access time
-				to the GPMC_CLK rising edge used by the
-				memory device for the first data capture.
- - gpmc,wr-data-mux-bus-ns:	In address-data multiplex mode, specifies
-				the time when the first data is driven on
-				the address-data bus.
-
-GPMC chip-select settings properties for child nodes. All are optional.
-
-- gpmc,burst-length	Page/burst length. Must be 4, 8 or 16.
-- gpmc,burst-wrap	Enables wrap bursting
-- gpmc,burst-read	Enables read page/burst mode
-- gpmc,burst-write	Enables write page/burst mode
-- gpmc,device-width	Total width of device(s) connected to a GPMC
-			chip-select in bytes. The GPMC supports 8-bit
-			and 16-bit devices and so this property must be
-			1 or 2.
-- gpmc,mux-add-data	Address and data multiplexing configuration.
-			Valid values are 1 for address-address-data
-			multiplexing mode and 2 for address-data
-			multiplexing mode.
-- gpmc,sync-read	Enables synchronous read. Defaults to asynchronous
-			is this is not set.
-- gpmc,sync-write	Enables synchronous writes. Defaults to asynchronous
-			is this is not set.
-- gpmc,wait-pin		Wait-pin used by client. Must be less than
-			"gpmc,num-waitpins".
-- gpmc,wait-on-read	Enables wait monitoring on reads.
-- gpmc,wait-on-write	Enables wait monitoring on writes.
-
-Example for an AM33xx board:
-
-	gpmc: gpmc at 50000000 {
-		compatible = "ti,am3352-gpmc";
-		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x2000>;
-		interrupts = <100>;
-		dmas = <&edma 52 0>;
-		dma-names = "rxtx";
-		gpmc,num-cs = <8>;
-		gpmc,num-waitpins = <2>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		gpio-controller;
-		#gpio-cells = <2>;
-
-		/* child nodes go here */
-	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
new file mode 100644
index 000000000000..3062e8cfdf89
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
@@ -0,0 +1,174 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/ti,gpmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments GPMC Memory Controller device-tree bindings
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+  The GPMC is a unified memory controller dedicated for interfacing
+  with external memory devices like
+  - Asynchronous SRAM-like memories and ASICs
+  - Asynchronous, synchronous, and page mode burst NOR flash
+  - NAND flash
+  - Pseudo-SRAM devices
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - ti,omap2420-gpmc
+          - ti,omap2430-gpmc
+          - ti,omap3430-gpmc
+          - ti,omap4430-gpmc
+          - ti,am3352-gpmc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: |
+      Functional clock. Used for bus timing calculations and
+      GPMC configuration.
+
+  clock-names:
+    items:
+      - const: fck
+
+  dmas:
+    items:
+      - description: DMA channel for GPMC NAND prefetch
+
+  dma-names:
+    items:
+      - const: rxtx
+
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 1
+
+  gpmc,num-cs:
+    description: maximum number of supported chip-select lines.
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  gpmc,num-waitpins:
+    description: maximum number of supported wait pins.
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  ranges:
+    minItems: 1
+    description: |
+      Must be set up to reflect the memory layout with four
+      integer values for each chip-select line in use,
+      <cs-number> 0 <physical address of mapping> <size>
+    items:
+      - description: NAND bank 0
+      - description: NOR/SRAM bank 0
+      - description: NOR/SRAM bank 1
+
+  '#interrupt-cells':
+    const: 2
+
+  interrupt-controller:
+    description: |
+      The GPMC driver implements and interrupt controller for
+      the NAND events "fifoevent" and "termcount" plus the
+      rising/falling edges on the GPMC_WAIT pins.
+      The interrupt number mapping is as follows
+      0 - NAND_fifoevent
+      1 - NAND_termcount
+      2 - GPMC_WAIT0 pin edge
+      3 - GPMC_WAIT1 pin edge, and so on.
+
+  '#gpio-cells':
+    const: 2
+
+  gpio-controller:
+    description: |
+      The GPMC driver implements a GPIO controller for the
+      GPMC WAIT pins that can be used as general purpose inputs.
+      0 maps to GPMC_WAIT0 pin.
+
+  ti,hwmods:
+    description:
+      Name of the HWMOD associated with GPMC. This is for legacy
+      omap2/3 platforms only.
+    $ref: /schemas/types.yaml#/definitions/string
+    deprecated: true
+
+  ti,no-idle-on-init:
+    description:
+      Prevent idling the module at init. This is for legacy omap2/3
+      platforms only.
+    type: boolean
+    deprecated: true
+
+patternProperties:
+  "@[0-7],[a-f0-9]+$":
+    type: object
+    description: |
+      The child device node represents the device connected to the GPMC
+      bus. The device can be a NAND chip, SRAM device, NOR device
+      or an ASIC.
+
+    allOf:
+      - $ref: "ti,gpmc-child.yaml"
+
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - gpmc,num-cs
+  - gpmc,num-waitpins
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    gpmc: memory-controller at 50000000 {
+      compatible = "ti,am3352-gpmc";
+      reg = <0x50000000 0x2000>;
+      interrupts = <100>;
+      clocks = <&l3s_clkctrl>;
+      clock-names = "fck";
+      dmas = <&edma 52 0>;
+      dma-names = "rxtx";
+      gpmc,num-cs = <8>;
+      gpmc,num-waitpins = <2>;
+      #address-cells = <2>;
+      #size-cells = <1>;
+      ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      gpio-controller;
+      #gpio-cells = <2>;
+
+      nand at 0,0 {
+        compatible = "ti,omap2-nand";
+        reg = <0 0 4>;
+        interrupt-parent = <&gpmc>;
+        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+                     <1 IRQ_TYPE_NONE>; /* termcount */
+        ti,nand-xfer-type = "prefetch-dma";
+        ti,nand-ecc-opt = "bch16";
+        ti,elm-id = <&elm>;
+        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */
+      };
+    };
-- 
2.17.1



From rogerq at kernel.org  Tue Sep  7 04:32:26 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue,  7 Sep 2021 14:32:26 +0300
Subject: [PATCH v3 8/8] memory: gpmc-omap: "gpmc,
 device-width" DT property is optional
In-Reply-To: <20210907113226.31876-1-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
Message-ID: <20210907113226.31876-9-rogerq@kernel.org>

Check for valid gpmc,device-width, nand-bus-width and bank-width
at one place. Default to 8-bit width if none present.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 drivers/memory/omap-gpmc.c | 41 ++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index f80c2ea39ca4..32d7c665f33c 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -2171,10 +2171,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		}
 	}
 
-	if (of_device_is_compatible(child, "ti,omap2-nand")) {
-		/* NAND specific setup */
-		val = 8;
-		of_property_read_u32(child, "nand-bus-width", &val);
+	/* DT node can have "nand-bus-width" or "bank-width" or "gpmc,device-width" */
+	if (!of_property_read_u32(child, "nand-bus-width", &val)) {
 		switch (val) {
 		case 8:
 			gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
@@ -2183,24 +2181,37 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 			gpmc_s.device_width = GPMC_DEVWIDTH_16BIT;
 			break;
 		default:
-			dev_err(&pdev->dev, "%pOFn: invalid 'nand-bus-width'\n",
-				child);
+			dev_err(&pdev->dev,
+				"%pOFn: invalid 'nand-bus-width':%d\n", child, val);
+			ret = -EINVAL;
+			goto err;
+		}
+	} else if (!of_property_read_u32(child, "bank-width", &val)) {
+		if (val != 1 && val != 2) {
+			dev_err(&pdev->dev,
+				"%pOFn: invalid 'bank-width':%d\n", child, val);
 			ret = -EINVAL;
 			goto err;
 		}
+		gpmc_s.device_width = val;
+	} else if (!of_property_read_u32(child, "gpmc,device-width", &val)) {
+		if (val != 1 && val != 2) {
+			dev_err(&pdev->dev,
+				"%pOFn: invalid 'gpmc,device-width':%d\n", child, val);
+			ret = -EINVAL;
+			goto err;
+		}
+		gpmc_s.device_width = val;
+	} else {
+		/* default to 8-bit */
+		gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
+	}
 
+	if (of_device_is_compatible(child, "ti,omap2-nand")) {
+		/* NAND specific setup */
 		/* disable write protect */
 		gpmc_configure(GPMC_CONFIG_WP, 0);
 		gpmc_s.device_nand = true;
-	} else {
-		ret = of_property_read_u32(child, "bank-width",
-					   &gpmc_s.device_width);
-		if (ret < 0 && !gpmc_s.device_width) {
-			dev_err(&pdev->dev,
-				"%pOF has no 'gpmc,device-width' property\n",
-				child);
-			goto err;
-		}
 	}
 
 	/* Reserve wait pin if it is required and valid */
-- 
2.17.1



From krzysztof.kozlowski at canonical.com  Tue Sep  7 05:36:46 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 7 Sep 2021 14:36:46 +0200
Subject: [PATCH v3 8/8] memory: gpmc-omap: "gpmc, device-width" DT property
 is optional
In-Reply-To: <20210907113226.31876-9-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-9-rogerq@kernel.org>
Message-ID: <aa465bd9-b3d5-8d75-3e59-e86c2cd093cd@canonical.com>

On 07/09/2021 13:32, Roger Quadros wrote:
> Check for valid gpmc,device-width, nand-bus-width and bank-width
> at one place. Default to 8-bit width if none present.

I don't understand the message in the context of the patch. The title
says one property is optional - that's it. The message says you
consolidate checks. How is this related to the title?

The patch itself moves around checking of properties and reads
nand-bus-width *always*. It does not "check at one place" but rather
"check always". In the same time, the patch does not remove
gpmc,device-width check in other place.

All three elements - the title, message and patch - do different things.
What did you want to achieve here? Can you help in clarifying it?


Best regards,
Krzysztof


> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  drivers/memory/omap-gpmc.c | 41 ++++++++++++++++++++++++--------------
>  1 file changed, 26 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
> index f80c2ea39ca4..32d7c665f33c 100644
> --- a/drivers/memory/omap-gpmc.c
> +++ b/drivers/memory/omap-gpmc.c
> @@ -2171,10 +2171,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
>  		}
>  	}
>  
> -	if (of_device_is_compatible(child, "ti,omap2-nand")) {
> -		/* NAND specific setup */
> -		val = 8;
> -		of_property_read_u32(child, "nand-bus-width", &val);
> +	/* DT node can have "nand-bus-width" or "bank-width" or "gpmc,device-width" */
> +	if (!of_property_read_u32(child, "nand-bus-width", &val)) {
>  		switch (val) {
>  		case 8:
>  			gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
> @@ -2183,24 +2181,37 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
>  			gpmc_s.device_width = GPMC_DEVWIDTH_16BIT;
>  			break;
>  		default:
> -			dev_err(&pdev->dev, "%pOFn: invalid 'nand-bus-width'\n",
> -				child);
> +			dev_err(&pdev->dev,
> +				"%pOFn: invalid 'nand-bus-width':%d\n", child, val);
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +	} else if (!of_property_read_u32(child, "bank-width", &val)) {
> +		if (val != 1 && val != 2) {
> +			dev_err(&pdev->dev,
> +				"%pOFn: invalid 'bank-width':%d\n", child, val);
>  			ret = -EINVAL;
>  			goto err;
>  		}
> +		gpmc_s.device_width = val;
> +	} else if (!of_property_read_u32(child, "gpmc,device-width", &val)) {
> +		if (val != 1 && val != 2) {
> +			dev_err(&pdev->dev,
> +				"%pOFn: invalid 'gpmc,device-width':%d\n", child, val);
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +		gpmc_s.device_width = val;
> +	} else {
> +		/* default to 8-bit */
> +		gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
> +	}
>  
> +	if (of_device_is_compatible(child, "ti,omap2-nand")) {
> +		/* NAND specific setup */
>  		/* disable write protect */
>  		gpmc_configure(GPMC_CONFIG_WP, 0);
>  		gpmc_s.device_nand = true;
> -	} else {
> -		ret = of_property_read_u32(child, "bank-width",
> -					   &gpmc_s.device_width);
> -		if (ret < 0 && !gpmc_s.device_width) {
> -			dev_err(&pdev->dev,
> -				"%pOF has no 'gpmc,device-width' property\n",
> -				child);
> -			goto err;
> -		}
>  	}
>  
>  	/* Reserve wait pin if it is required and valid */
> 




From krzysztof.kozlowski at canonical.com  Tue Sep  7 05:44:43 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 7 Sep 2021 14:44:43 +0200
Subject: [PATCH v3 1/8] ARM: dts: omap: Fixup GPMC child nodes
In-Reply-To: <20210907113226.31876-2-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-2-rogerq@kernel.org>
Message-ID: <8e29cf74-313f-b8c5-7514-60b5e404833d@canonical.com>

On 07/09/2021 13:32, Roger Quadros wrote:
> Fixes up the GPMC child nodes to prevent dtbs_check errors
> after device tree binding conversion to yaml.
> 
> - Use reg address as node name
> - gpmc,cycle2cycle-samecsen and gpmc,cycle2cycle-diffcsen are
>   boolean properties.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../boot/dts/logicpd-som-lv-baseboard.dtsi    |  2 +-
>  .../boot/dts/logicpd-torpedo-37xx-devkit.dts  |  2 +-
>  .../boot/dts/logicpd-torpedo-baseboard.dtsi   |  2 +-
>  arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi     | 62 +++++++++----------
>  arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi     | 59 +++++++++---------
>  arch/arm/boot/dts/omap-zoom-common.dtsi       | 16 ++---
>  arch/arm/boot/dts/omap2430-sdp.dts            |  6 +-
>  arch/arm/boot/dts/omap3-cm-t3x30.dtsi         |  6 +-
>  .../arm/boot/dts/omap3-devkit8000-common.dtsi |  4 +-
>  arch/arm/boot/dts/omap3-evm-37xx.dts          |  1 +
>  arch/arm/boot/dts/omap3-evm-common.dtsi       |  9 ---
>  .../boot/dts/omap3-evm-processor-common.dtsi  |  5 +-
>  arch/arm/boot/dts/omap3-evm.dts               |  1 +
>  arch/arm/boot/dts/omap3-igep0020-common.dtsi  |  5 +-
>  arch/arm/boot/dts/omap3-ldp.dts               |  5 +-
>  arch/arm/boot/dts/omap3-n900.dts              |  2 +-
>  .../dts/omap3-overo-chestnut43-common.dtsi    |  6 +-
>  .../arm/boot/dts/omap3-overo-tobi-common.dtsi |  6 +-
>  .../boot/dts/omap3-overo-tobiduo-common.dtsi  |  8 +--
>  arch/arm/boot/dts/omap3-sb-t35.dtsi           |  4 +-
>  arch/arm/boot/dts/omap4-duovero-parlor.dts    |  6 +-
>  21 files changed, 105 insertions(+), 112 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
> index 7d0468a23781..f2364cb114c5 100644
> --- a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
> +++ b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
> @@ -65,7 +65,7 @@
>  		  1 0 0x2c000000 0x1000000	/* CS1: 16MB for LAN9221 */
>  		  2 0 0x10000000 0x2000000>;    /* CS2: 32MB for NOR */
>  
> -	ethernet at gpmc {
> +	gpmc_ethernet: ethernet at 1,0 {
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&lan9221_pins>;
>  		interrupt-parent = <&gpio5>;
> diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
> index 5532db04046c..6357915d207b 100644
> --- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
> +++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
> @@ -4,8 +4,8 @@
>  
>  #include "omap36xx.dtsi"
>  #include "logicpd-torpedo-som.dtsi"
> -#include "omap-gpmc-smsc9221.dtsi"
>  #include "logicpd-torpedo-baseboard.dtsi"
> +#include "omap-gpmc-smsc9221.dtsi"
>  
>  / {
>  	model = "LogicPD Zoom DM3730 Torpedo + Wireless Development Kit";
> diff --git a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
> index 533a47bc4a53..05049a34b6f1 100644
> --- a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
> +++ b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
> @@ -95,7 +95,7 @@
>  	ranges = <0 0 0x30000000 0x1000000	/* CS0: 16MB for NAND */
>  		  1 0 0x2c000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
>  
> -	ethernet at gpmc {
> +	gpmc_ethernet: ethernet at 1,0 {
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&lan9221_pins>;
>  		interrupt-parent = <&gpio5>;
> diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
> index ded7e8fec9eb..2a462cb65a7d 100644
> --- a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
> +++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
> @@ -20,36 +20,34 @@
>  	};
>  };
>  
> -&gpmc {
> -	ethernet at gpmc {
> -		compatible = "smsc,lan9221", "smsc,lan9115";
> -		bank-width = <2>;
> -		gpmc,device-width = <1>;
> -		gpmc,cycle2cycle-samecsen = <1>;
> -		gpmc,cycle2cycle-diffcsen = <1>;
> -		gpmc,cs-on-ns = <5>;
> -		gpmc,cs-rd-off-ns = <150>;
> -		gpmc,cs-wr-off-ns = <150>;
> -		gpmc,adv-on-ns = <0>;
> -		gpmc,adv-rd-off-ns = <15>;
> -		gpmc,adv-wr-off-ns = <40>;
> -		gpmc,oe-on-ns = <45>;
> -		gpmc,oe-off-ns = <140>;
> -		gpmc,we-on-ns = <45>;
> -		gpmc,we-off-ns = <140>;
> -		gpmc,rd-cycle-ns = <155>;
> -		gpmc,wr-cycle-ns = <155>;
> -		gpmc,access-ns = <120>;
> -		gpmc,page-burst-access-ns = <20>;
> -		gpmc,bus-turnaround-ns = <75>;
> -		gpmc,cycle2cycle-delay-ns = <75>;
> -		gpmc,wait-monitoring-ns = <0>;
> -		gpmc,clk-activation-ns = <0>;
> -		gpmc,wr-data-mux-bus-ns = <0>;
> -		gpmc,wr-access-ns = <0>;
> -		vddvario-supply = <&vddvario>;
> -		vdd33a-supply = <&vdd33a>;
> -		reg-io-width = <4>;
> -		smsc,save-mac-address;
> -	};
> +&gpmc_ethernet {
> +	compatible = "smsc,lan9221", "smsc,lan9115";

This looks like regular override-by-label instead of full path.
Unfortunately change of the indentation causes difficulties to find the
real difference - if there is such. Can you split it into separate patch?

The point is that override-by-label should have zero effect on
functionality and produce same dtb. This is easy to compare with
dtx_diff or fdt-decompile but if you mix it with other changes, the
comparison is not straight-forward.

> +	bank-width = <2>;
> +	gpmc,device-width = <1>;
> +	gpmc,cycle2cycle-samecsen;
> +	gpmc,cycle2cycle-diffcsen;
> +	gpmc,cs-on-ns = <5>;
> +	gpmc,cs-rd-off-ns = <150>;
> +	gpmc,cs-wr-off-ns = <150>;
> +	gpmc,adv-on-ns = <0>;
> +	gpmc,adv-rd-off-ns = <15>;
> +	gpmc,adv-wr-off-ns = <40>;
> +	gpmc,oe-on-ns = <45>;
> +	gpmc,oe-off-ns = <140>;
> +	gpmc,we-on-ns = <45>;
> +	gpmc,we-off-ns = <140>;
> +	gpmc,rd-cycle-ns = <155>;
> +	gpmc,wr-cycle-ns = <155>;
> +	gpmc,access-ns = <120>;
> +	gpmc,page-burst-access-ns = <20>;
> +	gpmc,bus-turnaround-ns = <75>;
> +	gpmc,cycle2cycle-delay-ns = <75>;
> +	gpmc,wait-monitoring-ns = <0>;
> +	gpmc,clk-activation-ns = <0>;
> +	gpmc,wr-data-mux-bus-ns = <0>;
> +	gpmc,wr-access-ns = <0>;
> +	vddvario-supply = <&vddvario>;
> +	vdd33a-supply = <&vdd33a>;
> +	reg-io-width = <4>;
> +	smsc,save-mac-address;
>  };
> diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
> index 7f6aefd13451..c1e78f929d2b 100644
> --- a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
> +++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
> @@ -24,36 +24,33 @@
>  	};
>  };
>  
> -&gpmc {
> -	ethernet at gpmc {
> -		compatible = "smsc,lan9221","smsc,lan9115";
> -		bank-width = <2>;
> +&gpmc_ethernet {
> +	compatible = "smsc,lan9221","smsc,lan9115";
> +	bank-width = <2>;
> +	gpmc,mux-add-data = <0>;
> +	gpmc,cs-on-ns = <0>;
> +	gpmc,cs-rd-off-ns = <42>;
> +	gpmc,cs-wr-off-ns = <36>;
> +	gpmc,adv-on-ns = <6>;
> +	gpmc,adv-rd-off-ns = <12>;
> +	gpmc,adv-wr-off-ns = <12>;
> +	gpmc,oe-on-ns = <0>;
> +	gpmc,oe-off-ns = <42>;
> +	gpmc,we-on-ns = <0>;
> +	gpmc,we-off-ns = <36>;
> +	gpmc,rd-cycle-ns = <60>;
> +	gpmc,wr-cycle-ns = <54>;
> +	gpmc,access-ns = <36>;
> +	gpmc,page-burst-access-ns = <0>;
> +	gpmc,bus-turnaround-ns = <0>;
> +	gpmc,cycle2cycle-delay-ns = <0>;
> +	gpmc,wr-data-mux-bus-ns = <18>;
> +	gpmc,wr-access-ns = <42>;
> +	gpmc,cycle2cycle-samecsen;
> +	gpmc,cycle2cycle-diffcsen;
>  
> -		gpmc,mux-add-data;

Same here and in other places. Actually here a sneaky change is visible
- different property.

Best regards,
Krzysztof


From miquel.raynal at bootlin.com  Tue Sep  7 07:03:17 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 7 Sep 2021 16:03:17 +0200
Subject: [PATCH v3 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <20210907113226.31876-6-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-6-rogerq@kernel.org>
Message-ID: <20210907160317.2ec5304a@xps13>

Hi Roger,

rogerq at kernel.org wrote on Tue,  7 Sep 2021 14:32:23 +0300:

> Convert gpmc-nand.txt to ti,gpmc-nand.yaml.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 ------------------
>  .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 110 +++++++++++++
>  2 files changed, 110 insertions(+), 147 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
>  create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> deleted file mode 100644
> index 44919d48d241..000000000000
> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> +++ /dev/null
> @@ -1,147 +0,0 @@
> -Device tree bindings for GPMC connected NANDs
> -
> -GPMC connected NAND (found on OMAP boards) are represented as child nodes of
> -the GPMC controller with a name of "nand".
> -
> -All timing relevant properties as well as generic gpmc child properties are
> -explained in a separate documents - please refer to
> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> -
> -For NAND specific properties such as ECC modes or bus width, please refer to
> -Documentation/devicetree/bindings/mtd/nand-controller.yaml
> -
> -
> -Required properties:
> -
> - - compatible:	"ti,omap2-nand"
> - - reg:		range id (CS number), base offset and length of the
> -		NAND I/O space
> - - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
> -
> -Optional properties:
> -
> - - nand-bus-width: 		Set this numeric value to 16 if the hardware
> -				is wired that way. If not specified, a bus
> -				width of 8 is assumed.
> -
> - - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
> -		"sw"		1-bit Hamming ecc code via software
> -		"hw"		<deprecated> use "ham1" instead
> -		"hw-romcode"	<deprecated> use "ham1" instead
> -		"ham1"		1-bit Hamming ecc code
> -		"bch4"		4-bit BCH ecc code
> -		"bch8"		8-bit BCH ecc code
> -		"bch16"		16-bit BCH ECC code
> -		Refer below "How to select correct ECC scheme for your device ?"
> -
> - - ti,nand-xfer-type:		A string setting the data transfer type. One of:
> -
> -		"prefetch-polled"	Prefetch polled mode (default)
> -		"polled"		Polled mode, without prefetch
> -		"prefetch-dma"		Prefetch enabled DMA mode
> -		"prefetch-irq"		Prefetch enabled irq mode
> -
> - - elm_id:	<deprecated> use "ti,elm-id" instead
> - - ti,elm-id:	Specifies phandle of the ELM devicetree node.
> -		ELM is an on-chip hardware engine on TI SoC which is used for
> -		locating ECC errors for BCHx algorithms. SoC devices which have
> -		ELM hardware engines should specify this device node in .dtsi
> -		Using ELM for ECC error correction frees some CPU cycles.
> - - rb-gpios:	GPIO specifier for the ready/busy# pin.
> -
> -For inline partition table parsing (optional):
> -
> - - #address-cells: should be set to 1
> - - #size-cells: should be set to 1
> -
> -Example for an AM33xx board:
> -
> -	gpmc: gpmc at 50000000 {
> -		compatible = "ti,am3352-gpmc";
> -		ti,hwmods = "gpmc";
> -		reg = <0x50000000 0x36c>;
> -		interrupts = <100>;
> -		gpmc,num-cs = <8>;
> -		gpmc,num-waitpins = <2>;
> -		#address-cells = <2>;
> -		#size-cells = <1>;
> -		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
> -		elm_id = <&elm>;
> -		interrupt-controller;
> -		#interrupt-cells = <2>;
> -
> -		nand at 0,0 {
> -			compatible = "ti,omap2-nand";
> -			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
> -			interrupt-parent = <&gpmc>;
> -			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
> -			nand-bus-width = <16>;
> -			ti,nand-ecc-opt = "bch8";
> -			ti,nand-xfer-type = "polled";
> -			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
> -
> -			gpmc,sync-clk-ps = <0>;
> -			gpmc,cs-on-ns = <0>;
> -			gpmc,cs-rd-off-ns = <44>;
> -			gpmc,cs-wr-off-ns = <44>;
> -			gpmc,adv-on-ns = <6>;
> -			gpmc,adv-rd-off-ns = <34>;
> -			gpmc,adv-wr-off-ns = <44>;
> -			gpmc,we-off-ns = <40>;
> -			gpmc,oe-off-ns = <54>;
> -			gpmc,access-ns = <64>;
> -			gpmc,rd-cycle-ns = <82>;
> -			gpmc,wr-cycle-ns = <82>;
> -			gpmc,wr-access-ns = <40>;
> -			gpmc,wr-data-mux-bus-ns = <0>;
> -
> -			#address-cells = <1>;
> -			#size-cells = <1>;
> -
> -			/* partitions go here */
> -		};
> -	};
> -
> -How to select correct ECC scheme for your device ?
> ---------------------------------------------------
> -Higher ECC scheme usually means better protection against bit-flips and
> -increased system lifetime. However, selection of ECC scheme is dependent
> -on various other factors also like;
> -
> -(1) support of built in hardware engines.
> -	Some legacy OMAP SoC do not have ELM harware engine, so those SoC cannot
> -	support ecc-schemes with hardware error-correction (BCHx_HW). However
> -	such SoC can use ecc-schemes with software library for error-correction
> -	(BCHx_HW_DETECTION_SW). The error correction capability with software
> -	library remains equivalent to their hardware counter-part, but there is
> -	slight CPU penalty when too many bit-flips are detected during reads.
> -
> -(2) Device parameters like OOBSIZE.
> -	Other factor which governs the selection of ecc-scheme is oob-size.
> -	Higher ECC schemes require more OOB/Spare area to store ECC syndrome,
> -	so the device should have enough free bytes available its OOB/Spare
> -	area to accommodate ECC for entire page. In general following expression
> -	helps in determining if given device can accommodate ECC syndrome:
> -	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
> -	where
> -		OOBSIZE		number of bytes in OOB/spare area
> -		PAGESIZE	number of bytes in main-area of device page
> -		ECC_BYTES	number of ECC bytes generated to protect
> -		                512 bytes of data, which is:
> -				'3' for HAM1_xx ecc schemes
> -				'7' for BCH4_xx ecc schemes
> -				'14' for BCH8_xx ecc schemes
> -				'26' for BCH16_xx ecc schemes
> -
> -	Example(a): For a device with PAGESIZE = 2048 and OOBSIZE = 64 and
> -		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
> -		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
> -		which is greater than capacity of NAND device (OOBSIZE=64)
> -		Hence, BCH16 cannot be supported on given device. But it can
> -		probably use lower ecc-schemes like BCH8.
> -
> -	Example(b): For a device with PAGESIZE = 2048 and OOBSIZE = 128 and
> -		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
> -		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
> -		which can be accommodated in the OOB/Spare area of this device
> -		(OOBSIZE=128). So this device can use BCH16 ecc-scheme.
> diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
> new file mode 100644
> index 000000000000..db36f2e944ef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
> @@ -0,0 +1,110 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mtd/ti,gpmc-nand.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Texas Instruments GPMC NAND Flash controller.
> +
> +maintainers:
> +  - Tony Lindgren <tony at atomide.com>
> +  - Roger Quadros <rogerq at kernel.org>
> +
> +description:
> +  GPMC NAND controller/Flash is represented as a child of the
> +  GPMC controller node.
> +
> +properties:
> +  compatible:
> +    const: ti,omap2-nand
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    items:
> +      - description: Interrupt for fifoevent
> +      - description: Interrupt for termcount
> +
> +  "#address-cells":
> +    const: 1
> +
> +  "#size-cells":
> +    const: 1
> +
> +  ti,nand-ecc-opt:
> +    description: Desired ECC algorithm
> +    $ref: /schemas/types.yaml#/definitions/string
> +    enum: [sw, ham1, bch4, bch8, bch16]
> +
> +  ti,nand-xfer-type:
> +    description: Data transfer method between controller and chip.
> +    $ref: /schemas/types.yaml#/definitions/string
> +    enum: [prefetch-polled, polled, prefetch-dma, prefetch-irq]
> +    default: prefetch-polled
> +
> +  ti,elm-id:
> +    description:
> +      phandle to the ELM (Error Location Module).
> +    $ref: /schemas/types.yaml#/definitions/phandle

Should perhaps keep the elm-id property documented but set to
'deprecated'.

> +
> +  nand-bus-width:
> +    description:
> +      Bus width to the NAND chip
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [8, 16]
> +    default: 8

This is part of nand-controller.yaml binding and should not be there.

> +
> +allOf:
> +  - $ref: "../memory-controllers/ti,gpmc-child.yaml"

Maybe you need to reference the nand controller bindings as well

> +
> +required:
> +  - compatible
> +  - reg
> +  - ti,nand-ecc-opt
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    gpmc: memory-controller at 50000000 {
> +      compatible = "ti,am3352-gpmc";
> +      dmas = <&edma 52 0>;
> +      dma-names = "rxtx";
> +      clocks = <&l3s_gclk>;
> +      clock-names = "fck";
> +      reg = <0x50000000 0x2000>;
> +      interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
> +      gpmc,num-cs = <7>;
> +      gpmc,num-waitpins = <2>;
> +      #address-cells = <2>;
> +      #size-cells = <1>;
> +      interrupt-controller;
> +      #interrupt-cells = <2>;
> +      gpio-controller;
> +      #gpio-cells = <2>;
> +
> +      ranges = <0 0 0x08000000 0x01000000>;   /* CS0 space. Min partition = 16MB */
> +      nand at 0,0 {
> +        compatible = "ti,omap2-nand";
> +        reg = <0 0 4>;          /* device IO registers */
> +        interrupt-parent = <&gpmc>;
> +        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
> +                     <1 IRQ_TYPE_NONE>; /* termcount */
> +        ti,nand-xfer-type = "prefetch-dma";
> +        ti,nand-ecc-opt = "bch16";
> +        ti,elm-id = <&elm>;
> +        #address-cells = <1>;
> +        #size-cells = <1>;
> +
> +        /* NAND generic properties */
> +        nand-bus-width = <8>;
> +        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>;  /* gpmc_wait0 */
> +
> +        /* GPMC properties*/
> +        gpmc,device-width = <1>;
> +      };
> +    };


Thanks,
Miqu?l


From grygorii.strashko at ti.com  Tue Sep  7 08:27:32 2021
From: grygorii.strashko at ti.com (Grygorii Strashko)
Date: Tue, 7 Sep 2021 18:27:32 +0300
Subject: [PATCH v3 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <20210907160317.2ec5304a@xps13>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-6-rogerq@kernel.org> <20210907160317.2ec5304a@xps13>
Message-ID: <dc3d465f-50d5-31e5-07e6-f83223b90800@ti.com>



On 07/09/2021 17:03, Miquel Raynal wrote:
> Hi Roger,
> 
> rogerq at kernel.org wrote on Tue,  7 Sep 2021 14:32:23 +0300:
> 
>> Convert gpmc-nand.txt to ti,gpmc-nand.yaml.
>>
>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>> ---
>>   .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 ------------------
>>   .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 110 +++++++++++++
>>   2 files changed, 110 insertions(+), 147 deletions(-)
>>   delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
>>   create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
>> deleted file mode 100644
>> index 44919d48d241..000000000000
>> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
>> +++ /dev/null
>> @@ -1,147 +0,0 @@
>> -Device tree bindings for GPMC connected NANDs
>> -
>> -GPMC connected NAND (found on OMAP boards) are represented as child nodes of
>> -the GPMC controller with a name of "nand".
>> -
>> -All timing relevant properties as well as generic gpmc child properties are
>> -explained in a separate documents - please refer to
>> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>> -
>> -For NAND specific properties such as ECC modes or bus width, please refer to
>> -Documentation/devicetree/bindings/mtd/nand-controller.yaml
>> -
>> -
>> -Required properties:
>> -
>> - - compatible:	"ti,omap2-nand"
>> - - reg:		range id (CS number), base offset and length of the
>> -		NAND I/O space
>> - - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
>> -
>> -Optional properties:
>> -
>> - - nand-bus-width: 		Set this numeric value to 16 if the hardware
>> -				is wired that way. If not specified, a bus
>> -				width of 8 is assumed.
>> -
>> - - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
>> -		"sw"		1-bit Hamming ecc code via software
>> -		"hw"		<deprecated> use "ham1" instead
>> -		"hw-romcode"	<deprecated> use "ham1" instead
>> -		"ham1"		1-bit Hamming ecc code
>> -		"bch4"		4-bit BCH ecc code
>> -		"bch8"		8-bit BCH ecc code
>> -		"bch16"		16-bit BCH ECC code
>> -		Refer below "How to select correct ECC scheme for your device ?"
>> -
>> - - ti,nand-xfer-type:		A string setting the data transfer type. One of:
>> -
>> -		"prefetch-polled"	Prefetch polled mode (default)
>> -		"polled"		Polled mode, without prefetch
>> -		"prefetch-dma"		Prefetch enabled DMA mode
>> -		"prefetch-irq"		Prefetch enabled irq mode
>> -
>> - - elm_id:	<deprecated> use "ti,elm-id" instead
>> - - ti,elm-id:	Specifies phandle of the ELM devicetree node.
>> -		ELM is an on-chip hardware engine on TI SoC which is used for
>> -		locating ECC errors for BCHx algorithms. SoC devices which have
>> -		ELM hardware engines should specify this device node in .dtsi
>> -		Using ELM for ECC error correction frees some CPU cycles.
>> - - rb-gpios:	GPIO specifier for the ready/busy# pin.
>> -
>> -For inline partition table parsing (optional):
>> -
>> - - #address-cells: should be set to 1
>> - - #size-cells: should be set to 1
>> -
>> -Example for an AM33xx board:
>> -
>> -	gpmc: gpmc at 50000000 {
>> -		compatible = "ti,am3352-gpmc";
>> -		ti,hwmods = "gpmc";
>> -		reg = <0x50000000 0x36c>;
>> -		interrupts = <100>;
>> -		gpmc,num-cs = <8>;
>> -		gpmc,num-waitpins = <2>;
>> -		#address-cells = <2>;
>> -		#size-cells = <1>;
>> -		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
>> -		elm_id = <&elm>;
>> -		interrupt-controller;
>> -		#interrupt-cells = <2>;
>> -
>> -		nand at 0,0 {
>> -			compatible = "ti,omap2-nand";
>> -			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
>> -			interrupt-parent = <&gpmc>;
>> -			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
>> -			nand-bus-width = <16>;
>> -			ti,nand-ecc-opt = "bch8";
>> -			ti,nand-xfer-type = "polled";
>> -			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
>> -
>> -			gpmc,sync-clk-ps = <0>;
>> -			gpmc,cs-on-ns = <0>;
>> -			gpmc,cs-rd-off-ns = <44>;
>> -			gpmc,cs-wr-off-ns = <44>;
>> -			gpmc,adv-on-ns = <6>;
>> -			gpmc,adv-rd-off-ns = <34>;
>> -			gpmc,adv-wr-off-ns = <44>;
>> -			gpmc,we-off-ns = <40>;
>> -			gpmc,oe-off-ns = <54>;
>> -			gpmc,access-ns = <64>;
>> -			gpmc,rd-cycle-ns = <82>;
>> -			gpmc,wr-cycle-ns = <82>;
>> -			gpmc,wr-access-ns = <40>;
>> -			gpmc,wr-data-mux-bus-ns = <0>;
>> -
>> -			#address-cells = <1>;
>> -			#size-cells = <1>;
>> -
>> -			/* partitions go here */
>> -		};
>> -	};
>> -
>> -How to select correct ECC scheme for your device ?
>> ---------------------------------------------------
>> -Higher ECC scheme usually means better protection against bit-flips and
>> -increased system lifetime. However, selection of ECC scheme is dependent
>> -on various other factors also like;
>> -
>> -(1) support of built in hardware engines.
>> -	Some legacy OMAP SoC do not have ELM harware engine, so those SoC cannot
>> -	support ecc-schemes with hardware error-correction (BCHx_HW). However
>> -	such SoC can use ecc-schemes with software library for error-correction
>> -	(BCHx_HW_DETECTION_SW). The error correction capability with software
>> -	library remains equivalent to their hardware counter-part, but there is
>> -	slight CPU penalty when too many bit-flips are detected during reads.
>> -
>> -(2) Device parameters like OOBSIZE.
>> -	Other factor which governs the selection of ecc-scheme is oob-size.
>> -	Higher ECC schemes require more OOB/Spare area to store ECC syndrome,
>> -	so the device should have enough free bytes available its OOB/Spare
>> -	area to accommodate ECC for entire page. In general following expression
>> -	helps in determining if given device can accommodate ECC syndrome:
>> -	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
>> -	where
>> -		OOBSIZE		number of bytes in OOB/spare area
>> -		PAGESIZE	number of bytes in main-area of device page
>> -		ECC_BYTES	number of ECC bytes generated to protect
>> -		                512 bytes of data, which is:
>> -				'3' for HAM1_xx ecc schemes
>> -				'7' for BCH4_xx ecc schemes
>> -				'14' for BCH8_xx ecc schemes
>> -				'26' for BCH16_xx ecc schemes
>> -
>> -	Example(a): For a device with PAGESIZE = 2048 and OOBSIZE = 64 and
>> -		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
>> -		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
>> -		which is greater than capacity of NAND device (OOBSIZE=64)
>> -		Hence, BCH16 cannot be supported on given device. But it can
>> -		probably use lower ecc-schemes like BCH8.
>> -
>> -	Example(b): For a device with PAGESIZE = 2048 and OOBSIZE = 128 and
>> -		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
>> -		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
>> -		which can be accommodated in the OOB/Spare area of this device
>> -		(OOBSIZE=128). So this device can use BCH16 ecc-scheme.
>> diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
>> new file mode 100644
>> index 000000000000..db36f2e944ef
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
>> @@ -0,0 +1,110 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/mtd/ti,gpmc-nand.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Texas Instruments GPMC NAND Flash controller.
>> +
>> +maintainers:
>> +  - Tony Lindgren <tony at atomide.com>
>> +  - Roger Quadros <rogerq at kernel.org>
>> +
>> +description:
>> +  GPMC NAND controller/Flash is represented as a child of the
>> +  GPMC controller node.
>> +
>> +properties:
>> +  compatible:
>> +    const: ti,omap2-nand
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  interrupts:
>> +    items:
>> +      - description: Interrupt for fifoevent
>> +      - description: Interrupt for termcount
>> +
>> +  "#address-cells":
>> +    const: 1
>> +
>> +  "#size-cells":
>> +    const: 1
>> +
>> +  ti,nand-ecc-opt:
>> +    description: Desired ECC algorithm
>> +    $ref: /schemas/types.yaml#/definitions/string
>> +    enum: [sw, ham1, bch4, bch8, bch16]
>> +
>> +  ti,nand-xfer-type:
>> +    description: Data transfer method between controller and chip.
>> +    $ref: /schemas/types.yaml#/definitions/string
>> +    enum: [prefetch-polled, polled, prefetch-dma, prefetch-irq]
>> +    default: prefetch-polled
>> +
>> +  ti,elm-id:
>> +    description:
>> +      phandle to the ELM (Error Location Module).
>> +    $ref: /schemas/types.yaml#/definitions/phandle
> 
> Should perhaps keep the elm-id property documented but set to
> 'deprecated'.
> 
>> +
>> +  nand-bus-width:
>> +    description:
>> +      Bus width to the NAND chip
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    enum: [8, 16]
>> +    default: 8
> 
> This is part of nand-controller.yaml binding and should not be there.
> 
>> +
>> +allOf:
>> +  - $ref: "../memory-controllers/ti,gpmc-child.yaml"
> 
> Maybe you need to reference the nand controller bindings as well
> 

This will not work out of the box :( as nand-controller.yaml defines both
  nand controller and nand memory. It potentially might work if it will be possible to split
nand memory definition (or nand memory properties) out of and-controller.yaml, similarly to
ti,gpmc-child.yaml from this series.

-- 
Best regards,
grygorii


From miquel.raynal at bootlin.com  Tue Sep  7 09:35:45 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 7 Sep 2021 18:35:45 +0200
Subject: [PATCH v3 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <dc3d465f-50d5-31e5-07e6-f83223b90800@ti.com>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-6-rogerq@kernel.org>
 <20210907160317.2ec5304a@xps13>
 <dc3d465f-50d5-31e5-07e6-f83223b90800@ti.com>
Message-ID: <20210907183545.3e281b7d@xps13>

Hi Grygorii,

> >   
> >> +
> >> +  nand-bus-width:
> >> +    description:
> >> +      Bus width to the NAND chip
> >> +    $ref: /schemas/types.yaml#/definitions/uint32
> >> +    enum: [8, 16]
> >> +    default: 8  
> > 
> > This is part of nand-controller.yaml binding and should not be there.
> >   
> >> +
> >> +allOf:
> >> +  - $ref: "../memory-controllers/ti,gpmc-child.yaml"  
> > 
> > Maybe you need to reference the nand controller bindings as well
> >   
> 
> This will not work out of the box :( as nand-controller.yaml defines both
>   nand controller and nand memory. It potentially might work if it will be possible to split
> nand memory definition (or nand memory properties) out of and-controller.yaml, similarly to
> ti,gpmc-child.yaml from this series.

What you think would be the issue?

I am not opposed to split nand-controller.yaml into
nand-controller.yaml and nand-chip.yaml if it simplifies the
description of controllers but I don't get why it would be needed. In
particular since we expect all drivers to support the

nand-controller {
	controller-props;
	nand-chip {
		chip-props;
	}
}

organization which has been enforced since at least 2018. Having a
controller vs. chip representation is fundamentally right. But here I
see how "legacy" are these bindings with so much unneeded specific "ti,"
properties... On one side it would be good to verify that the driver
supports this representation (which I believe is true) and on the other
side maybe it's time to advertise "better" bindings as well.


Thanks,
Miqu?l


From rogerq at kernel.org  Tue Sep  7 09:57:16 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 7 Sep 2021 19:57:16 +0300
Subject: [PATCH v3 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <20210907183545.3e281b7d@xps13>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-6-rogerq@kernel.org> <20210907160317.2ec5304a@xps13>
 <dc3d465f-50d5-31e5-07e6-f83223b90800@ti.com> <20210907183545.3e281b7d@xps13>
Message-ID: <2c6491c2-dae8-c8b3-9f8c-14a7583720f1@kernel.org>

Hi Miquel,

On 07/09/2021 19:35, Miquel Raynal wrote:
> Hi Grygorii,
> 
>>>   
>>>> +
>>>> +  nand-bus-width:
>>>> +    description:
>>>> +      Bus width to the NAND chip
>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>> +    enum: [8, 16]
>>>> +    default: 8  
>>>
>>> This is part of nand-controller.yaml binding and should not be there.
>>>   
>>>> +
>>>> +allOf:
>>>> +  - $ref: "../memory-controllers/ti,gpmc-child.yaml"  
>>>
>>> Maybe you need to reference the nand controller bindings as well
>>>   
>>
>> This will not work out of the box :( as nand-controller.yaml defines both
>>   nand controller and nand memory. It potentially might work if it will be possible to split
>> nand memory definition (or nand memory properties) out of and-controller.yaml, similarly to
>> ti,gpmc-child.yaml from this series.
> 
> What you think would be the issue?

The issue is that dt_binding checks will fail if I reference nand-controller.yaml
as we currently represent the controller as follows

memory-controller { /* GPMC controller */
	memory-controller-props;
	nand-chip {
		/* @chip select 0 */
		nand-controller-props;
		memory-controller-timing-props;
		chip-props;
	}
	nand-chip {
		/* @chip select 1 */
		nand-controller-props;
		memory-controller-timing-props;
		chip-props;
	}
	nor-chip {
		/* @chip select 2 */
		memory-controller-timing-props;
		chip-props;
	}
}

The NAND controller IO registers are at different addresses for different
chip select regions. Also, this is one way we can specify GPMC settings/timings
for different chip selects.

> 
> I am not opposed to split nand-controller.yaml into
> nand-controller.yaml and nand-chip.yaml if it simplifies the
> description of controllers but I don't get why it would be needed. In
> particular since we expect all drivers to support the
> 
> nand-controller {
> 	controller-props;
> 	nand-chip {
> 		chip-props;
> 	}
> }

Changing to this format will cause a lot of churn in DT files, which I'm not sure
if it gives enough benefit. 
TI platforms will never have 2 NAND chips in the same chip select region.

> 
> organization which has been enforced since at least 2018. Having a
> controller vs. chip representation is fundamentally right. But here I
> see how "legacy" are these bindings with so much unneeded specific "ti,"
> properties... On one side it would be good to verify that the driver
> supports this representation (which I believe is true) and on the other
> side maybe it's time to advertise "better" bindings as well.

Yes, I'm OK to mark ti specific properties deprecated and use standard NAND chip
bindings.

cheers,
-roger


From robh at kernel.org  Tue Sep  7 10:01:48 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 7 Sep 2021 12:01:48 -0500
Subject: [PATCH v3 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <20210907113226.31876-6-rogerq@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-6-rogerq@kernel.org>
Message-ID: <YTea/Ium7TptHlnV@robh.at.kernel.org>

On Tue, Sep 07, 2021 at 02:32:23PM +0300, Roger Quadros wrote:
> Convert gpmc-nand.txt to ti,gpmc-nand.yaml.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 ------------------
>  .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 110 +++++++++++++
>  2 files changed, 110 insertions(+), 147 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
>  create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> deleted file mode 100644
> index 44919d48d241..000000000000
> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> +++ /dev/null
> @@ -1,147 +0,0 @@
> -Device tree bindings for GPMC connected NANDs
> -
> -GPMC connected NAND (found on OMAP boards) are represented as child nodes of
> -the GPMC controller with a name of "nand".
> -
> -All timing relevant properties as well as generic gpmc child properties are
> -explained in a separate documents - please refer to
> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> -
> -For NAND specific properties such as ECC modes or bus width, please refer to
> -Documentation/devicetree/bindings/mtd/nand-controller.yaml
> -
> -
> -Required properties:
> -
> - - compatible:	"ti,omap2-nand"
> - - reg:		range id (CS number), base offset and length of the
> -		NAND I/O space
> - - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
> -
> -Optional properties:
> -
> - - nand-bus-width: 		Set this numeric value to 16 if the hardware
> -				is wired that way. If not specified, a bus
> -				width of 8 is assumed.
> -
> - - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
> -		"sw"		1-bit Hamming ecc code via software
> -		"hw"		<deprecated> use "ham1" instead
> -		"hw-romcode"	<deprecated> use "ham1" instead
> -		"ham1"		1-bit Hamming ecc code
> -		"bch4"		4-bit BCH ecc code
> -		"bch8"		8-bit BCH ecc code
> -		"bch16"		16-bit BCH ECC code
> -		Refer below "How to select correct ECC scheme for your device ?"
> -
> - - ti,nand-xfer-type:		A string setting the data transfer type. One of:
> -
> -		"prefetch-polled"	Prefetch polled mode (default)
> -		"polled"		Polled mode, without prefetch
> -		"prefetch-dma"		Prefetch enabled DMA mode
> -		"prefetch-irq"		Prefetch enabled irq mode
> -
> - - elm_id:	<deprecated> use "ti,elm-id" instead
> - - ti,elm-id:	Specifies phandle of the ELM devicetree node.
> -		ELM is an on-chip hardware engine on TI SoC which is used for
> -		locating ECC errors for BCHx algorithms. SoC devices which have
> -		ELM hardware engines should specify this device node in .dtsi
> -		Using ELM for ECC error correction frees some CPU cycles.
> - - rb-gpios:	GPIO specifier for the ready/busy# pin.
> -
> -For inline partition table parsing (optional):
> -
> - - #address-cells: should be set to 1
> - - #size-cells: should be set to 1
> -
> -Example for an AM33xx board:
> -
> -	gpmc: gpmc at 50000000 {
> -		compatible = "ti,am3352-gpmc";
> -		ti,hwmods = "gpmc";
> -		reg = <0x50000000 0x36c>;
> -		interrupts = <100>;
> -		gpmc,num-cs = <8>;
> -		gpmc,num-waitpins = <2>;
> -		#address-cells = <2>;
> -		#size-cells = <1>;
> -		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
> -		elm_id = <&elm>;
> -		interrupt-controller;
> -		#interrupt-cells = <2>;
> -
> -		nand at 0,0 {
> -			compatible = "ti,omap2-nand";
> -			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
> -			interrupt-parent = <&gpmc>;
> -			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
> -			nand-bus-width = <16>;
> -			ti,nand-ecc-opt = "bch8";
> -			ti,nand-xfer-type = "polled";
> -			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
> -
> -			gpmc,sync-clk-ps = <0>;
> -			gpmc,cs-on-ns = <0>;
> -			gpmc,cs-rd-off-ns = <44>;
> -			gpmc,cs-wr-off-ns = <44>;
> -			gpmc,adv-on-ns = <6>;
> -			gpmc,adv-rd-off-ns = <34>;
> -			gpmc,adv-wr-off-ns = <44>;
> -			gpmc,we-off-ns = <40>;
> -			gpmc,oe-off-ns = <54>;
> -			gpmc,access-ns = <64>;
> -			gpmc,rd-cycle-ns = <82>;
> -			gpmc,wr-cycle-ns = <82>;
> -			gpmc,wr-access-ns = <40>;
> -			gpmc,wr-data-mux-bus-ns = <0>;
> -
> -			#address-cells = <1>;
> -			#size-cells = <1>;
> -
> -			/* partitions go here */
> -		};
> -	};
> -
> -How to select correct ECC scheme for your device ?
> ---------------------------------------------------
> -Higher ECC scheme usually means better protection against bit-flips and
> -increased system lifetime. However, selection of ECC scheme is dependent
> -on various other factors also like;
> -
> -(1) support of built in hardware engines.
> -	Some legacy OMAP SoC do not have ELM harware engine, so those SoC cannot
> -	support ecc-schemes with hardware error-correction (BCHx_HW). However
> -	such SoC can use ecc-schemes with software library for error-correction
> -	(BCHx_HW_DETECTION_SW). The error correction capability with software
> -	library remains equivalent to their hardware counter-part, but there is
> -	slight CPU penalty when too many bit-flips are detected during reads.
> -
> -(2) Device parameters like OOBSIZE.
> -	Other factor which governs the selection of ecc-scheme is oob-size.
> -	Higher ECC schemes require more OOB/Spare area to store ECC syndrome,
> -	so the device should have enough free bytes available its OOB/Spare
> -	area to accommodate ECC for entire page. In general following expression
> -	helps in determining if given device can accommodate ECC syndrome:
> -	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
> -	where
> -		OOBSIZE		number of bytes in OOB/spare area
> -		PAGESIZE	number of bytes in main-area of device page
> -		ECC_BYTES	number of ECC bytes generated to protect
> -		                512 bytes of data, which is:
> -				'3' for HAM1_xx ecc schemes
> -				'7' for BCH4_xx ecc schemes
> -				'14' for BCH8_xx ecc schemes
> -				'26' for BCH16_xx ecc schemes
> -
> -	Example(a): For a device with PAGESIZE = 2048 and OOBSIZE = 64 and
> -		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
> -		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
> -		which is greater than capacity of NAND device (OOBSIZE=64)
> -		Hence, BCH16 cannot be supported on given device. But it can
> -		probably use lower ecc-schemes like BCH8.
> -
> -	Example(b): For a device with PAGESIZE = 2048 and OOBSIZE = 128 and
> -		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
> -		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
> -		which can be accommodated in the OOB/Spare area of this device
> -		(OOBSIZE=128). So this device can use BCH16 ecc-scheme.
> diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
> new file mode 100644
> index 000000000000..db36f2e944ef
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
> @@ -0,0 +1,110 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mtd/ti,gpmc-nand.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Texas Instruments GPMC NAND Flash controller.
> +
> +maintainers:
> +  - Tony Lindgren <tony at atomide.com>
> +  - Roger Quadros <rogerq at kernel.org>
> +
> +description:
> +  GPMC NAND controller/Flash is represented as a child of the
> +  GPMC controller node.
> +
> +properties:
> +  compatible:
> +    const: ti,omap2-nand
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    items:
> +      - description: Interrupt for fifoevent
> +      - description: Interrupt for termcount
> +
> +  "#address-cells":
> +    const: 1
> +
> +  "#size-cells":
> +    const: 1
> +
> +  ti,nand-ecc-opt:
> +    description: Desired ECC algorithm
> +    $ref: /schemas/types.yaml#/definitions/string
> +    enum: [sw, ham1, bch4, bch8, bch16]
> +
> +  ti,nand-xfer-type:
> +    description: Data transfer method between controller and chip.
> +    $ref: /schemas/types.yaml#/definitions/string
> +    enum: [prefetch-polled, polled, prefetch-dma, prefetch-irq]
> +    default: prefetch-polled
> +
> +  ti,elm-id:
> +    description:
> +      phandle to the ELM (Error Location Module).
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +
> +  nand-bus-width:
> +    description:
> +      Bus width to the NAND chip
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [8, 16]
> +    default: 8
> +
> +allOf:
> +  - $ref: "../memory-controllers/ti,gpmc-child.yaml"

Use /schemas/... rather than '..'

> +
> +required:
> +  - compatible
> +  - reg
> +  - ti,nand-ecc-opt
> +
> +unevaluatedProperties: false

This will throw errors if you have partition nodes. You need to 
reference the partitions schema.

Or minimally restrict to nodes with: 

unevaluatedProperties:
  type: object

> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    gpmc: memory-controller at 50000000 {
> +      compatible = "ti,am3352-gpmc";
> +      dmas = <&edma 52 0>;
> +      dma-names = "rxtx";
> +      clocks = <&l3s_gclk>;
> +      clock-names = "fck";
> +      reg = <0x50000000 0x2000>;
> +      interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
> +      gpmc,num-cs = <7>;
> +      gpmc,num-waitpins = <2>;
> +      #address-cells = <2>;
> +      #size-cells = <1>;
> +      interrupt-controller;
> +      #interrupt-cells = <2>;
> +      gpio-controller;
> +      #gpio-cells = <2>;
> +
> +      ranges = <0 0 0x08000000 0x01000000>;   /* CS0 space. Min partition = 16MB */
> +      nand at 0,0 {
> +        compatible = "ti,omap2-nand";
> +        reg = <0 0 4>;          /* device IO registers */
> +        interrupt-parent = <&gpmc>;
> +        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
> +                     <1 IRQ_TYPE_NONE>; /* termcount */
> +        ti,nand-xfer-type = "prefetch-dma";
> +        ti,nand-ecc-opt = "bch16";
> +        ti,elm-id = <&elm>;
> +        #address-cells = <1>;
> +        #size-cells = <1>;
> +
> +        /* NAND generic properties */
> +        nand-bus-width = <8>;
> +        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>;  /* gpmc_wait0 */
> +
> +        /* GPMC properties*/
> +        gpmc,device-width = <1>;
> +      };
> +    };
> -- 
> 2.17.1
> 
> 


From schaecsn at gmx.net  Tue Sep  7 14:40:33 2021
From: schaecsn at gmx.net (Stefan Schaeckeler)
Date: Tue,  7 Sep 2021 14:40:33 -0700
Subject: [PATCH 0/1] ubifs: ubifs to export filesystem error counters
Message-ID: <20210907214034.11676-1-schaecsn@gmx.net>

Not all ubifs filesystem errors are propagated to userspace, here is one
that is not propagaged to ls:

[node0_RP0_CPU0:~]$ls -la /mnt/mtd0
[562009.111309] UBIFS error (ubi0:0 pid 21670): ubifs_check_node [ubifs]: bad CRC: calculated 0x1b205ba3, read 0xb6eff0d9
[562009.123231] UBIFS error (ubi0:0 pid 21670): ubifs_check_node [ubifs]: bad node at LEB 112:29768
[562009.133042] magic          0x6101831
[562009.137312] crc            0xb6eff0d9
[562009.141678] node_type      2 (direntry node)
[562009.146706] group_type     1 (in node group)
[562009.151734] sqnum          334966
[562009.155709] len            82
[562009.159304] key            (1, direntry, 0xe933a79)
[562009.164999] inum           546
[562009.168687] type           0
[562009.172186] nlen           25
[562009.175779] name           inventor\xffffffff\xffffffff\xffffffff\xffffffffcal_log_4.txt
[562009.185308] CPU: 1 PID: 21670 Comm: ls Tainted: G           O    4.8.28-WR9.0.0.20_cgl #1
[562009.185309] Hardware name: Insyde Harrisonville/Type2 - Board Product Name1, BIOS 00.01.017 10/26/2018
[562009.185312]  0000000000000286 00000000f877ad2e ffffbb5b8e357c50 ffffffff9b3cfaab
[562009.185316]  00000000ffffff8b 0000000000007448 ffffbb5b8e357c90 ffffffffc022c0dd
[562009.185320]  00000000687aa008 0000000000007448 0000000000000070 0000000000000052
[562009.185324] Call Trace:
[562009.185332]  [<ffffffff9b3cfaab>] dump_stack+0x63/0x88
[562009.185345]  [<ffffffffc022c0dd>] ubifs_check_node+0xbd/0x270 [ubifs]
[562009.185357]  [<ffffffffc022db25>] ubifs_read_node+0x285/0x300 [ubifs]
[562009.185370]  [<ffffffffc024dfc7>] ubifs_tnc_read_node+0x127/0x1c0 [ubifs]
[562009.185382]  [<ffffffffc0230115>] ? matches_name+0x45/0xf0 [ubifs]
[562009.185394]  [<ffffffffc022ed9a>] tnc_read_node_nm+0xfa/0x220 [ubifs]
[562009.185407]  [<ffffffffc02330a4>] ubifs_tnc_next_ent+0x1f4/0x2a0 [ubifs]
[562009.185411]  [<ffffffff9b1f405e>] ? filldir+0xce/0x150
[562009.185422]  [<ffffffffc02244f8>] ubifs_readdir+0x188/0x4d0 [ubifs]
[562009.185425]  [<ffffffff9b1f3e62>] iterate_dir+0x172/0x190
[562009.185429]  [<ffffffff9b124e4a>] ? __audit_syscall_entry+0xba/0x100
[562009.185432]  [<ffffffff9b1f4399>] SyS_getdents+0x99/0x120
[562009.185434]  [<ffffffff9b1f3f90>] ? fillonedir+0x110/0x110
[562009.185437]  [<ffffffff9b002b76>] do_syscall_64+0x66/0x180
[562009.185441]  [<ffffffff9b8b9fce>] entry_SYSCALL_64_after_swapgs+0x58/0xc6
[562009.185454] UBIFS error (ubi0:0 pid 21670): ubifs_read_node [ubifs]: expected node type 2
[562009.194705] UBIFS error (ubi0:0 pid 21670): ubifs_readdir [ubifs]: cannot find next direntry, error -117
total 1080
drwxr-xr-x. 2 root root   3728 Jul  3 10:36 .
drwxrwxrwt. 5 root root    120 Jul  3 10:36 ..
-rw-rw-rw-. 1 root root   5413 May 24 10:59 alarm_0_PM1_remote_log_1.txt
-rw-rw-rw-. 1 root root      1 Sep 19  2020 alarm_banner.txt
-rw-rw-rw-. 1 root root  65465 Nov  5  2020 alarm_local_log_29.txt
-rw-rw-rw-. 1 root root  55441 Dec 18  2020 alarm_local_log_30.txt
-rw-rw-rw-. 1 root root  64826 Sep 20  2020 alarm_local_log_31.txt
-rw-rw-rw-. 1 root root  65019 Oct 25  2020 alarm_local_log_32.txt
-rw-rw-rw-. 1 root root  65880 Oct 26  2020 alarm_local_log_33.txt
-rw-rw-rw-. 1 root root  66296 Apr 17 10:35 alarm_local_log_34.txt
-rw-rw-rw-. 1 root test  64734 May  5 20:35 alarm_local_log_35.txt
-rw-rw-rw-. 1 root root  64924 Jun  4 07:39 alarm_local_log_36.txt
-rw-rw-rw-. 1 root root  50830 Jul  8 13:21 alarm_local_log_37.txt
-rw-rw-rw-. 1 root root      1 Sep 21  2020 fpd_banner.txt
-rw-rw-rw-. 1 root root  28518 Jul  2 23:19 fpd_local_log_2.txt
-rw-rw-rw-. 1 root root     96 Jul  9 22:37 int_uptime_dashboard.dat
-rw-rw-rw-. 1 root iosxr   540 Jun  8 00:06 inventory_local_log_1.txt
-rw-rw-rw-. 1 root iosxr   540 Jul  2 23:26 inventory_local_log_2.txt
-rw-rw-rw-. 1 root root  79293 Jul  3 10:37 inventory_local_log_3.txt
-rw-rw-rw-. 1 root test      4 Apr 17 10:33 obfl_data_version.dat
-rw-rw-rw-. 1 root root    364 Sep 19  2020 temperature_banner.txt
-rw-rw-rw-. 1 root root  19567 Dec 18  2020 temperature_local_log_3.txt
-rw-rw-rw-. 1 root root  65607 Sep 20  2020 temperature_local_log_4.txt
-rw-rw-rw-. 1 root root  66410 Apr 17 10:34 temperature_local_log_5.txt
-rw-rw-rw-. 1 root test  65607 Jun  1 21:26 temperature_local_log_6.txt
-rw-rw-rw-. 1 root root  54097 Jul  3 10:37 temperature_local_log_7.txt
-rw-rw-rw-. 1 root root  65160 Jun 25 23:56 voltage_local_log_10.txt
-rw-rw-rw-. 1 root root  28236 Jul  3 10:37 voltage_local_log_11.txt
[node0_RP0_CPU0:~]$echo $?
0

A direntry node got corrupted. The filename inventory_local_log_4.txt got
corrupted to inventor\xffffffff\xffffffff\xffffffff\xffffffffcal_log_4.txt
and is not passed down to ls. ls exits with a clean exit code of 0.

We can't really detect this corruption from user space. This is required to
take action such as for a fresh start with re-creating the filesystem.

Every access to the mounted filesystem results in a kernel backtrace. This
trashes the dmesg buffer and the systemd journal over time.


This patch introduces a sysfs filesystem for ubifs. The first three sysfs
nodes are error counters:

 /sys/fs/ubifs/ubiX_Y/errors_magic
 /sys/fs/ubifs/ubiX_Y/errors_node
 /sys/fs/ubifs/ubiX_Y/errors_crc

This allows userspace to notice filesystem corruption. Over time, more
sysfs nodes can be added.

Stefan Schaeckeler (1):
  ubifs: ubifs to export filesystem error counters

 fs/ubifs/Makefile |   2 +-
 fs/ubifs/io.c     |   6 ++
 fs/ubifs/super.c  |  17 ++++-
 fs/ubifs/sysfs.c  | 187 ++++++++++++++++++++++++++++++++++++++++++++++
 fs/ubifs/sysfs.h  |  39 ++++++++++
 fs/ubifs/ubifs.h  |  11 +++
 6 files changed, 260 insertions(+), 2 deletions(-)
 create mode 100644 fs/ubifs/sysfs.c
 create mode 100644 fs/ubifs/sysfs.h

--
2.32.0



From schaecsn at gmx.net  Tue Sep  7 14:40:34 2021
From: schaecsn at gmx.net (Stefan Schaeckeler)
Date: Tue,  7 Sep 2021 14:40:34 -0700
Subject: [PATCH 1/1] ubifs: ubifs to export filesystem error counters
In-Reply-To: <20210907214034.11676-1-schaecsn@gmx.net>
References: <20210907214034.11676-1-schaecsn@gmx.net>
Message-ID: <20210907214034.11676-2-schaecsn@gmx.net>

Not all ubifs filesystem errors are propagated to userspace.

Export bad magic, bad node and crc errors via sysfs. This allows userspace
to notice filesystem errors:

 /sys/fs/ubifs/ubiX_Y/errors_magic
 /sys/fs/ubifs/ubiX_Y/errors_node
 /sys/fs/ubifs/ubiX_Y/errors_crc

The counters are reset to 0 with a remount. Writing anything into the
counters also clears them.

Signed-off-by: Stefan Schaeckeler <sschaeck at cisco.com>
---
 fs/ubifs/Makefile |   2 +-
 fs/ubifs/io.c     |   6 ++
 fs/ubifs/super.c  |  17 ++++-
 fs/ubifs/sysfs.c  | 187 ++++++++++++++++++++++++++++++++++++++++++++++
 fs/ubifs/sysfs.h  |  39 ++++++++++
 fs/ubifs/ubifs.h  |  11 +++
 6 files changed, 260 insertions(+), 2 deletions(-)
 create mode 100644 fs/ubifs/sysfs.c
 create mode 100644 fs/ubifs/sysfs.h

diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile
index 5c4b845754a7..314c80b24a76 100644
--- a/fs/ubifs/Makefile
+++ b/fs/ubifs/Makefile
@@ -5,7 +5,7 @@ ubifs-y += shrinker.o journal.o file.o dir.o super.o sb.o io.o
 ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
 ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
 ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o debug.o
-ubifs-y += misc.o
+ubifs-y += misc.o sysfs.o
 ubifs-$(CONFIG_FS_ENCRYPTION) += crypto.o
 ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o
 ubifs-$(CONFIG_UBIFS_FS_AUTHENTICATION) += auth.o
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 00b61dba62b7..0b158e420cc1 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -238,6 +238,8 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int len,
 		if (!quiet)
 			ubifs_err(c, "bad magic %#08x, expected %#08x",
 				  magic, UBIFS_NODE_MAGIC);
+		if (c->stats)
+			c->stats->magic_errors++;
 		err = -EUCLEAN;
 		goto out;
 	}
@@ -246,6 +248,8 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int len,
 	if (type < 0 || type >= UBIFS_NODE_TYPES_CNT) {
 		if (!quiet)
 			ubifs_err(c, "bad node type %d", type);
+		if (c->stats)
+			c->stats->node_errors++;
 		goto out;
 	}

@@ -270,6 +274,8 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int len,
 		if (!quiet)
 			ubifs_err(c, "bad CRC: calculated %#08x, read %#08x",
 				  crc, node_crc);
+		if (c->stats)
+			c->stats->crc_errors++;
 		err = -EUCLEAN;
 		goto out;
 	}
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index f0fb25727d96..50b934854a84 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -24,6 +24,7 @@
 #include <linux/mount.h>
 #include <linux/math64.h>
 #include <linux/writeback.h>
+#include "sysfs.h"
 #include "ubifs.h"

 static int ubifs_default_version_set(const char *val, const struct kernel_param *kp)
@@ -1264,6 +1265,10 @@ static int mount_ubifs(struct ubifs_info *c)
 	if (err)
 		return err;

+	err = ubifs_sysfs_register(c);
+	if (err)
+		goto out_debugging;
+
 	err = check_volume_empty(c);
 	if (err)
 		goto out_free;
@@ -1641,6 +1646,8 @@ static int mount_ubifs(struct ubifs_info *c)
 	vfree(c->sbuf);
 	kfree(c->bottom_up_buf);
 	kfree(c->sup_node);
+	ubifs_sysfs_unregister(c);
+out_debugging:
 	ubifs_debugging_exit(c);
 	return err;
 }
@@ -1684,6 +1691,7 @@ static void ubifs_umount(struct ubifs_info *c)
 	kfree(c->bottom_up_buf);
 	kfree(c->sup_node);
 	ubifs_debugging_exit(c);
+	ubifs_sysfs_unregister(c);
 }

 /**
@@ -2436,14 +2444,20 @@ static int __init ubifs_init(void)

 	dbg_debugfs_init();

+	err = ubifs_sysfs_init();
+	if (err)
+		goto out_dbg;
+
 	err = register_filesystem(&ubifs_fs_type);
 	if (err) {
 		pr_err("UBIFS error (pid %d): cannot register file system, error %d",
 		       current->pid, err);
-		goto out_dbg;
+		goto out_sysfs;
 	}
 	return 0;

+out_sysfs:
+	ubifs_sysfs_exit();
 out_dbg:
 	dbg_debugfs_exit();
 	ubifs_compressors_exit();
@@ -2462,6 +2476,7 @@ static void __exit ubifs_exit(void)
 	WARN_ON(atomic_long_read(&ubifs_clean_zn_cnt) != 0);

 	dbg_debugfs_exit();
+	ubifs_sysfs_exit();
 	ubifs_compressors_exit();
 	unregister_shrinker(&ubifs_shrinker_info);

diff --git a/fs/ubifs/sysfs.c b/fs/ubifs/sysfs.c
new file mode 100644
index 000000000000..bac53a0f0451
--- /dev/null
+++ b/fs/ubifs/sysfs.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file is part of UBIFS.
+ *
+ * Copyright (C) 2021 Cisco Systems
+ *
+ * Author: Stefan Schaeckeler
+ */
+
+
+#include <linux/fs.h>
+
+#include "sysfs.h"
+#include "ubifs.h"
+
+
+enum attr_id_t {
+	attr_errors_magic,
+	attr_errors_node,
+	attr_errors_crc,
+};
+
+struct ubifs_attr {
+	struct attribute attr;
+	enum attr_id_t attr_id;
+};
+
+#define UBIFS_ATTR(_name, _mode, _id)					\
+static struct ubifs_attr ubifs_attr_##_name = {				\
+	.attr = {.name = __stringify(_name), .mode = _mode },		\
+	.attr_id = attr_##_id,						\
+}
+
+#define UBIFS_ATTR_FUNC(_name, _mode) UBIFS_ATTR(_name, _mode, _name)
+
+UBIFS_ATTR_FUNC(errors_magic, 0644);
+UBIFS_ATTR_FUNC(errors_crc, 0644);
+UBIFS_ATTR_FUNC(errors_node, 0644);
+
+#define ATTR_LIST(name) (&ubifs_attr_##name.attr)
+
+static struct attribute *ubifs_attrs[] = {
+	ATTR_LIST(errors_magic),
+	ATTR_LIST(errors_node),
+	ATTR_LIST(errors_crc),
+	NULL,
+};
+
+
+static ssize_t ubifs_attr_show(struct kobject *kobj,
+			       struct attribute *attr, char *buf)
+{
+	struct ubifs_info *sbi = container_of(kobj, struct ubifs_info,
+					      kobj);
+
+	struct ubifs_attr *a = container_of(attr, struct ubifs_attr, attr);
+
+	switch (a->attr_id) {
+	case attr_errors_magic:
+		return snprintf(buf, PAGE_SIZE, "%u\n",
+				sbi->stats->magic_errors);
+	case attr_errors_node:
+		return snprintf(buf, PAGE_SIZE, "%u\n",
+				sbi->stats->node_errors);
+	case attr_errors_crc:
+		return snprintf(buf, PAGE_SIZE, "%u\n",
+				sbi->stats->crc_errors);
+	}
+	return 0;
+};
+
+
+static ssize_t ubifs_attr_store(struct kobject *kobj,
+			       struct attribute *attr,
+			       const char *buf, size_t len)
+{
+	struct ubifs_info *sbi = container_of(kobj, struct ubifs_info,
+					      kobj);
+
+	struct ubifs_attr *a = container_of(attr, struct ubifs_attr, attr);
+
+	switch (a->attr_id) {
+	case attr_errors_magic:
+		sbi->stats->magic_errors = 0;
+		break;
+	case attr_errors_node:
+		sbi->stats->node_errors = 0;
+		break;
+	case attr_errors_crc:
+		sbi->stats->crc_errors = 0;
+		break;
+	}
+	return len;
+}
+
+
+static void ubifs_sb_release(struct kobject *kobj)
+{
+	struct ubifs_info *c = container_of(kobj, struct ubifs_info, kobj);
+
+	complete(&c->kobj_unregister);
+}
+
+
+static const struct sysfs_ops ubifs_attr_ops = {
+	.show	= ubifs_attr_show,
+	.store	= ubifs_attr_store,
+};
+
+static struct kobj_type ubifs_sb_ktype = {
+	.default_attrs	= ubifs_attrs,
+	.sysfs_ops	= &ubifs_attr_ops,
+	.release	= ubifs_sb_release,
+};
+
+static struct kobj_type ubifs_ktype = {
+	.sysfs_ops	= &ubifs_attr_ops,
+};
+
+static struct kset ubifs_kset = {
+	.kobj	= {.ktype = &ubifs_ktype},
+};
+
+
+int ubifs_sysfs_register(struct ubifs_info *c)
+{
+	int ret, n;
+	char dfs_dir_name[UBIFS_DFS_DIR_LEN+1];
+
+	c->stats = kzalloc(sizeof(struct ubifs_stats_info), GFP_KERNEL);
+	if (!c->stats) {
+		ret = -ENOMEM;
+		goto out_last;
+	}
+	n = snprintf(dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME,
+		     c->vi.ubi_num, c->vi.vol_id);
+
+	if (n == UBIFS_DFS_DIR_LEN) {
+		/* The array size is too small */
+		ret = -EINVAL;
+		goto out_last;
+	}
+
+	c->kobj.kset = &ubifs_kset;
+	init_completion(&c->kobj_unregister);
+
+
+	ret = kobject_init_and_add(&c->kobj, &ubifs_sb_ktype, NULL,
+				   "%s", dfs_dir_name);
+	if (ret)
+		goto out_put;
+
+	return 0;
+
+out_put:
+	kobject_put(&c->kobj);
+	wait_for_completion(&c->kobj_unregister);
+out_last:
+	ubifs_err(c, "cannot create sysfs entry for ubifs%d_%d, error %d\n",
+		  c->vi.ubi_num, c->vi.vol_id, ret);
+	return ret;
+}
+
+void ubifs_sysfs_unregister(struct ubifs_info *c)
+{
+	kobject_del(&c->kobj);
+	kobject_put(&c->kobj);
+	wait_for_completion(&c->kobj_unregister);
+
+	kfree(c->stats);
+}
+
+int __init ubifs_sysfs_init(void)
+{
+	int ret;
+
+	kobject_set_name(&ubifs_kset.kobj, "ubifs");
+	ubifs_kset.kobj.parent = fs_kobj;
+	ret = kset_register(&ubifs_kset);
+
+	return ret;
+}
+
+void ubifs_sysfs_exit(void)
+{
+	kset_unregister(&ubifs_kset);
+}
diff --git a/fs/ubifs/sysfs.h b/fs/ubifs/sysfs.h
new file mode 100644
index 000000000000..a10a82585af8
--- /dev/null
+++ b/fs/ubifs/sysfs.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * This file is part of UBIFS.
+ *
+ * Copyright (C) 2021 Cisco Systems
+ *
+ * Author: Stefan Schaeckeler
+ */
+
+#ifndef __UBIFS_SYSFS_H__
+#define __UBIFS_SYSFS_H__
+
+struct ubifs_info;
+
+/*
+ * The UBIFS sysfs directory name pattern and maximum name length (3 for "ubi"
+ * + 1 for "_" and plus 2x2 for 2 UBI numbers and 1 for the trailing zero byte.
+ */
+#define UBIFS_DFS_DIR_NAME "ubi%d_%d"
+#define UBIFS_DFS_DIR_LEN  (3 + 1 + 2*2 + 1)
+
+/**
+ * ubifs_stats_info - per-FS statistics information.
+ * @magic_errors: number of bad magic numbers (will be reset with a new mount).
+ * @node_errors: number of bad nodes (will be reset with a new mount).
+ * @crc_errors: number of bad crcs (will be reset with a new mount).
+ */
+struct ubifs_stats_info {
+	unsigned int magic_errors;
+	unsigned int node_errors;
+	unsigned int crc_errors;
+};
+
+int ubifs_sysfs_init(void);
+void ubifs_sysfs_exit(void);
+int ubifs_sysfs_register(struct ubifs_info *c);
+void ubifs_sysfs_unregister(struct ubifs_info *c);
+
+#endif
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index c38066ce9ab0..bfc0f20b41a1 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -27,12 +27,15 @@
 #include <linux/security.h>
 #include <linux/xattr.h>
 #include <linux/random.h>
+#include <linux/sysfs.h>
+#include <linux/completion.h>
 #include <crypto/hash_info.h>
 #include <crypto/hash.h>
 #include <crypto/algapi.h>

 #include <linux/fscrypt.h>

+#include "sysfs.h"
 #include "ubifs-media.h"

 /* Version of this UBIFS implementation */
@@ -1251,6 +1254,10 @@ struct ubifs_debug_info;
  * @mount_opts: UBIFS-specific mount options
  *
  * @dbg: debugging-related information
+ * @stats: statistics exported over sysfs
+ *
+ * @kobj: kobject for /sys/fs/ubifs/
+ * @kobj_unregister: completion to unregister sysfs kobject
  */
 struct ubifs_info {
 	struct super_block *vfs_sb;
@@ -1286,6 +1293,9 @@ struct ubifs_info {
 	spinlock_t cs_lock;
 	wait_queue_head_t cmt_wq;

+	struct kobject kobj;
+	struct completion kobj_unregister;
+
 	unsigned int big_lpt:1;
 	unsigned int space_fixup:1;
 	unsigned int double_hash:1;
@@ -1493,6 +1503,7 @@ struct ubifs_info {
 	struct ubifs_mount_opts mount_opts;

 	struct ubifs_debug_info *dbg;
+	struct ubifs_stats_info *stats;
 };

 extern struct list_head ubifs_infos;
--
2.32.0



From robh+dt at kernel.org  Tue Sep  7 15:24:52 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Tue, 7 Sep 2021 17:24:52 -0500
Subject: [PATCH v3 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <2c6491c2-dae8-c8b3-9f8c-14a7583720f1@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-6-rogerq@kernel.org>
 <20210907160317.2ec5304a@xps13> <dc3d465f-50d5-31e5-07e6-f83223b90800@ti.com>
 <20210907183545.3e281b7d@xps13>
 <2c6491c2-dae8-c8b3-9f8c-14a7583720f1@kernel.org>
Message-ID: <CAL_JsqJPnUawYafrk4XmeVBETf-Lr+MZn+j_0nGfJTpvfzbkRA@mail.gmail.com>

On Tue, Sep 7, 2021 at 11:57 AM Roger Quadros <rogerq at kernel.org> wrote:
>
> Hi Miquel,
>
> On 07/09/2021 19:35, Miquel Raynal wrote:
> > Hi Grygorii,
> >
> >>>
> >>>> +
> >>>> +  nand-bus-width:
> >>>> +    description:
> >>>> +      Bus width to the NAND chip
> >>>> +    $ref: /schemas/types.yaml#/definitions/uint32
> >>>> +    enum: [8, 16]
> >>>> +    default: 8
> >>>
> >>> This is part of nand-controller.yaml binding and should not be there.
> >>>
> >>>> +
> >>>> +allOf:
> >>>> +  - $ref: "../memory-controllers/ti,gpmc-child.yaml"
> >>>
> >>> Maybe you need to reference the nand controller bindings as well
> >>>
> >>
> >> This will not work out of the box :( as nand-controller.yaml defines both
> >>   nand controller and nand memory. It potentially might work if it will be possible to split
> >> nand memory definition (or nand memory properties) out of and-controller.yaml, similarly to
> >> ti,gpmc-child.yaml from this series.
> >
> > What you think would be the issue?
>
> The issue is that dt_binding checks will fail if I reference nand-controller.yaml
> as we currently represent the controller as follows
>
> memory-controller { /* GPMC controller */
>         memory-controller-props;
>         nand-chip {
>                 /* @chip select 0 */
>                 nand-controller-props;
>                 memory-controller-timing-props;
>                 chip-props;
>         }
>         nand-chip {
>                 /* @chip select 1 */
>                 nand-controller-props;
>                 memory-controller-timing-props;
>                 chip-props;
>         }
>         nor-chip {
>                 /* @chip select 2 */
>                 memory-controller-timing-props;
>                 chip-props;
>         }
> }
>
> The NAND controller IO registers are at different addresses for different
> chip select regions. Also, this is one way we can specify GPMC settings/timings
> for different chip selects.
>
> >
> > I am not opposed to split nand-controller.yaml into
> > nand-controller.yaml and nand-chip.yaml if it simplifies the
> > description of controllers but I don't get why it would be needed. In
> > particular since we expect all drivers to support the
> >
> > nand-controller {
> >       controller-props;
> >       nand-chip {
> >               chip-props;
> >       }
> > }
>
> Changing to this format will cause a lot of churn in DT files, which I'm not sure
> if it gives enough benefit.
> TI platforms will never have 2 NAND chips in the same chip select region.

Probably best to just leave this alone. Unless this is getting used in
new chips? If so, I'd say it's a separate change.

> > organization which has been enforced since at least 2018. Having a
> > controller vs. chip representation is fundamentally right. But here I
> > see how "legacy" are these bindings with so much unneeded specific "ti,"
> > properties... On one side it would be good to verify that the driver
> > supports this representation (which I believe is true) and on the other
> > side maybe it's time to advertise "better" bindings as well.
>
> Yes, I'm OK to mark ti specific properties deprecated and use standard NAND chip
> bindings.

I don't think it's really worth it to go half way using common
properties but not the common structure.

Rob


From syzbot+f676029927929bee165f at syzkaller.appspotmail.com  Tue Sep  7 15:44:25 2021
From: syzbot+f676029927929bee165f at syzkaller.appspotmail.com (syzbot)
Date: Tue, 07 Sep 2021 15:44:25 -0700
Subject: [syzbot] upstream boot error: possible deadlock in blktrans_open
Message-ID: <000000000000ee215105cb6f8117@google.com>

Hello,

syzbot found the following issue on:

HEAD commit:    7cca308cfdc0 Merge tag 'powerpc-5.15-1' of git://git.kerne..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=10235915300000
kernel config:  https://syzkaller.appspot.com/x/.config?x=8aa56a640db99eb1
dashboard link: https://syzkaller.appspot.com/bug?extid=f676029927929bee165f
compiler:       gcc (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.1

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+f676029927929bee165f at syzkaller.appspotmail.com


======================================================
WARNING: possible circular locking dependency detected
5.14.0-syzkaller #0 Not tainted
------------------------------------------------------
systemd-udevd/6382 is trying to acquire lock:
ffffffff8c5db488 (mtd_table_mutex){+.+.}-{3:3}, at: blktrans_open+0x69/0x600 drivers/mtd/mtd_blkdevs.c:210

but task is already holding lock:
ffff888020ba7118 (&disk->open_mutex){+.+.}-{3:3}, at: blkdev_get_by_dev.part.0+0x9b/0xb60 fs/block_dev.c:1227

which lock already depends on the new lock.


the existing dependency chain (in reverse order) is:

-> #1 (&disk->open_mutex){+.+.}-{3:3}:
       __mutex_lock_common kernel/locking/mutex.c:596 [inline]
       __mutex_lock+0x131/0x12f0 kernel/locking/mutex.c:729
       bd_register_pending_holders+0x2c/0x470 block/holder.c:160
       device_add_disk+0x74c/0xfc0 block/genhd.c:470
       add_mtd_blktrans_dev+0xdae/0x15f0 drivers/mtd/mtd_blkdevs.c:430
       mtdblock_add_mtd+0x1c9/0x260 drivers/mtd/mtdblock.c:325
       blktrans_notify_add drivers/mtd/mtd_blkdevs.c:510 [inline]
       blktrans_notify_add+0x7a/0xc0 drivers/mtd/mtd_blkdevs.c:502
       add_mtd_device+0xa8e/0x1170 drivers/mtd/mtdcore.c:690
       mtd_device_parse_register+0x50c/0x860 drivers/mtd/mtdcore.c:979
       mtdram_init_device+0x291/0x350 drivers/mtd/devices/mtdram.c:146
       init_mtdram+0xe5/0x177 drivers/mtd/devices/mtdram.c:171
       do_one_initcall+0x103/0x650 init/main.c:1287
       do_initcall_level init/main.c:1360 [inline]
       do_initcalls init/main.c:1376 [inline]
       do_basic_setup init/main.c:1396 [inline]
       kernel_init_freeable+0x6b8/0x741 init/main.c:1598
       kernel_init+0x1a/0x1d0 init/main.c:1490
       ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295

-> #0 (mtd_table_mutex){+.+.}-{3:3}:
       check_prev_add kernel/locking/lockdep.c:3051 [inline]
       check_prevs_add kernel/locking/lockdep.c:3174 [inline]
       validate_chain kernel/locking/lockdep.c:3789 [inline]
       __lock_acquire+0x2a07/0x54a0 kernel/locking/lockdep.c:5015
       lock_acquire kernel/locking/lockdep.c:5625 [inline]
       lock_acquire+0x1ab/0x510 kernel/locking/lockdep.c:5590
       __mutex_lock_common kernel/locking/mutex.c:596 [inline]
       __mutex_lock+0x131/0x12f0 kernel/locking/mutex.c:729
       blktrans_open+0x69/0x600 drivers/mtd/mtd_blkdevs.c:210
       blkdev_get_whole+0x99/0x2a0 fs/block_dev.c:1079
       blkdev_get_by_dev.part.0+0x354/0xb60 fs/block_dev.c:1234
       blkdev_get_by_dev fs/block_dev.c:1323 [inline]
       blkdev_open+0x295/0x300 fs/block_dev.c:1329
       do_dentry_open+0x4c8/0x11d0 fs/open.c:822
       do_open fs/namei.c:3426 [inline]
       path_openat+0x1c9a/0x2740 fs/namei.c:3559
       do_filp_open+0x1aa/0x400 fs/namei.c:3586
       do_sys_openat2+0x16d/0x4d0 fs/open.c:1200
       do_sys_open fs/open.c:1216 [inline]
       __do_sys_open fs/open.c:1224 [inline]
       __se_sys_open fs/open.c:1220 [inline]
       __x64_sys_open+0x119/0x1c0 fs/open.c:1220
       do_syscall_x64 arch/x86/entry/common.c:50 [inline]
       do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
       entry_SYSCALL_64_after_hwframe+0x44/0xae

other info that might help us debug this:

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(&disk->open_mutex);
                               lock(mtd_table_mutex);
                               lock(&disk->open_mutex);
  lock(mtd_table_mutex);

 *** DEADLOCK ***

1 lock held by systemd-udevd/6382:
 #0: ffff888020ba7118 (&disk->open_mutex){+.+.}-{3:3}, at: blkdev_get_by_dev.part.0+0x9b/0xb60 fs/block_dev.c:1227

stack backtrace:
CPU: 0 PID: 6382 Comm: systemd-udevd Not tainted 5.14.0-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:88 [inline]
 dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:105
 check_noncircular+0x25f/0x2e0 kernel/locking/lockdep.c:2131
 check_prev_add kernel/locking/lockdep.c:3051 [inline]
 check_prevs_add kernel/locking/lockdep.c:3174 [inline]
 validate_chain kernel/locking/lockdep.c:3789 [inline]
 __lock_acquire+0x2a07/0x54a0 kernel/locking/lockdep.c:5015
 lock_acquire kernel/locking/lockdep.c:5625 [inline]
 lock_acquire+0x1ab/0x510 kernel/locking/lockdep.c:5590
 __mutex_lock_common kernel/locking/mutex.c:596 [inline]
 __mutex_lock+0x131/0x12f0 kernel/locking/mutex.c:729
 blktrans_open+0x69/0x600 drivers/mtd/mtd_blkdevs.c:210
 blkdev_get_whole+0x99/0x2a0 fs/block_dev.c:1079
 blkdev_get_by_dev.part.0+0x354/0xb60 fs/block_dev.c:1234
 blkdev_get_by_dev fs/block_dev.c:1323 [inline]
 blkdev_open+0x295/0x300 fs/block_dev.c:1329
 do_dentry_open+0x4c8/0x11d0 fs/open.c:822
 do_open fs/namei.c:3426 [inline]
 path_openat+0x1c9a/0x2740 fs/namei.c:3559
 do_filp_open+0x1aa/0x400 fs/namei.c:3586
 do_sys_openat2+0x16d/0x4d0 fs/open.c:1200
 do_sys_open fs/open.c:1216 [inline]
 __do_sys_open fs/open.c:1224 [inline]
 __se_sys_open fs/open.c:1220 [inline]
 __x64_sys_open+0x119/0x1c0 fs/open.c:1220
 do_syscall_x64 arch/x86/entry/common.c:50 [inline]
 do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
 entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7fc8603b3840
Code: 73 01 c3 48 8b 0d 68 77 20 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d 89 bb 20 00 00 75 10 b8 02 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 1e f6 ff ff 48 89 04 24
RSP: 002b:00007ffe4d0d43b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000002
RAX: ffffffffffffffda RBX: 000055da6177ec20 RCX: 00007fc8603b3840
RDX: 000055da60055fe3 RSI: 00000000000a0800 RDI: 000055da61793030
RBP: 00007ffe4d0d4530 R08: 000055da60055670 R09: 0000000000000020
R10: 000055da60055d0c R11: 0000000000000246 R12: 00007ffe4d0d4480
R13: 000055da6178f3f0 R14: 0000000000000003 R15: 000000000000000e


---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller at googlegroups.com.

syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.


From rogerq at kernel.org  Tue Sep  7 23:55:36 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 8 Sep 2021 09:55:36 +0300
Subject: [PATCH v3 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <CAL_JsqJPnUawYafrk4XmeVBETf-Lr+MZn+j_0nGfJTpvfzbkRA@mail.gmail.com>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-6-rogerq@kernel.org> <20210907160317.2ec5304a@xps13>
 <dc3d465f-50d5-31e5-07e6-f83223b90800@ti.com> <20210907183545.3e281b7d@xps13>
 <2c6491c2-dae8-c8b3-9f8c-14a7583720f1@kernel.org>
 <CAL_JsqJPnUawYafrk4XmeVBETf-Lr+MZn+j_0nGfJTpvfzbkRA@mail.gmail.com>
Message-ID: <1afc71e6-5104-2ce1-f176-97f4583507ef@kernel.org>



On 08/09/2021 01:24, Rob Herring wrote:
> On Tue, Sep 7, 2021 at 11:57 AM Roger Quadros <rogerq at kernel.org> wrote:
>>
>> Hi Miquel,
>>
>> On 07/09/2021 19:35, Miquel Raynal wrote:
>>> Hi Grygorii,
>>>
>>>>>
>>>>>> +
>>>>>> +  nand-bus-width:
>>>>>> +    description:
>>>>>> +      Bus width to the NAND chip
>>>>>> +    $ref: /schemas/types.yaml#/definitions/uint32
>>>>>> +    enum: [8, 16]
>>>>>> +    default: 8
>>>>>
>>>>> This is part of nand-controller.yaml binding and should not be there.
>>>>>
>>>>>> +
>>>>>> +allOf:
>>>>>> +  - $ref: "../memory-controllers/ti,gpmc-child.yaml"
>>>>>
>>>>> Maybe you need to reference the nand controller bindings as well
>>>>>
>>>>
>>>> This will not work out of the box :( as nand-controller.yaml defines both
>>>>   nand controller and nand memory. It potentially might work if it will be possible to split
>>>> nand memory definition (or nand memory properties) out of and-controller.yaml, similarly to
>>>> ti,gpmc-child.yaml from this series.
>>>
>>> What you think would be the issue?
>>
>> The issue is that dt_binding checks will fail if I reference nand-controller.yaml
>> as we currently represent the controller as follows
>>
>> memory-controller { /* GPMC controller */
>>         memory-controller-props;
>>         nand-chip {
>>                 /* @chip select 0 */
>>                 nand-controller-props;
>>                 memory-controller-timing-props;
>>                 chip-props;
>>         }
>>         nand-chip {
>>                 /* @chip select 1 */
>>                 nand-controller-props;
>>                 memory-controller-timing-props;
>>                 chip-props;
>>         }
>>         nor-chip {
>>                 /* @chip select 2 */
>>                 memory-controller-timing-props;
>>                 chip-props;
>>         }
>> }
>>
>> The NAND controller IO registers are at different addresses for different
>> chip select regions. Also, this is one way we can specify GPMC settings/timings
>> for different chip selects.
>>
>>>
>>> I am not opposed to split nand-controller.yaml into
>>> nand-controller.yaml and nand-chip.yaml if it simplifies the
>>> description of controllers but I don't get why it would be needed. In
>>> particular since we expect all drivers to support the
>>>
>>> nand-controller {
>>>       controller-props;
>>>       nand-chip {
>>>               chip-props;
>>>       }
>>> }
>>
>> Changing to this format will cause a lot of churn in DT files, which I'm not sure
>> if it gives enough benefit.
>> TI platforms will never have 2 NAND chips in the same chip select region.
> 
> Probably best to just leave this alone. Unless this is getting used in
> new chips? If so, I'd say it's a separate change.
> 
>>> organization which has been enforced since at least 2018. Having a
>>> controller vs. chip representation is fundamentally right. But here I
>>> see how "legacy" are these bindings with so much unneeded specific "ti,"
>>> properties... On one side it would be good to verify that the driver
>>> supports this representation (which I believe is true) and on the other
>>> side maybe it's time to advertise "better" bindings as well.
>>
>> Yes, I'm OK to mark ti specific properties deprecated and use standard NAND chip
>> bindings.
> 
> I don't think it's really worth it to go half way using common
> properties but not the common structure.

I agree.
We will be having new chips that will use this driver but we will migrate to new
common structure when adding support for those chips.

So I will leave this patch as it is for now.

cheers,
-roger


From rogerq at kernel.org  Wed Sep  8 04:14:12 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 8 Sep 2021 14:14:12 +0300
Subject: [PATCH v3 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <YTea/Ium7TptHlnV@robh.at.kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-6-rogerq@kernel.org>
 <YTea/Ium7TptHlnV@robh.at.kernel.org>
Message-ID: <5b7787ce-d51f-e79c-fa7a-0113acda5648@kernel.org>



On 07/09/2021 20:01, Rob Herring wrote:
> On Tue, Sep 07, 2021 at 02:32:23PM +0300, Roger Quadros wrote:
>> Convert gpmc-nand.txt to ti,gpmc-nand.yaml.
>>
>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>> ---
>>  .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 ------------------
>>  .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 110 +++++++++++++
>>  2 files changed, 110 insertions(+), 147 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
>>  create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
>> deleted file mode 100644
>> index 44919d48d241..000000000000
>> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
>> +++ /dev/null
>> @@ -1,147 +0,0 @@
>> -Device tree bindings for GPMC connected NANDs
>> -
>> -GPMC connected NAND (found on OMAP boards) are represented as child nodes of
>> -the GPMC controller with a name of "nand".
>> -
>> -All timing relevant properties as well as generic gpmc child properties are
>> -explained in a separate documents - please refer to
>> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>> -
>> -For NAND specific properties such as ECC modes or bus width, please refer to
>> -Documentation/devicetree/bindings/mtd/nand-controller.yaml
>> -
>> -
>> -Required properties:
>> -
>> - - compatible:	"ti,omap2-nand"
>> - - reg:		range id (CS number), base offset and length of the
>> -		NAND I/O space
>> - - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
>> -
>> -Optional properties:
>> -
>> - - nand-bus-width: 		Set this numeric value to 16 if the hardware
>> -				is wired that way. If not specified, a bus
>> -				width of 8 is assumed.
>> -
>> - - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
>> -		"sw"		1-bit Hamming ecc code via software
>> -		"hw"		<deprecated> use "ham1" instead
>> -		"hw-romcode"	<deprecated> use "ham1" instead
>> -		"ham1"		1-bit Hamming ecc code
>> -		"bch4"		4-bit BCH ecc code
>> -		"bch8"		8-bit BCH ecc code
>> -		"bch16"		16-bit BCH ECC code
>> -		Refer below "How to select correct ECC scheme for your device ?"
>> -
>> - - ti,nand-xfer-type:		A string setting the data transfer type. One of:
>> -
>> -		"prefetch-polled"	Prefetch polled mode (default)
>> -		"polled"		Polled mode, without prefetch
>> -		"prefetch-dma"		Prefetch enabled DMA mode
>> -		"prefetch-irq"		Prefetch enabled irq mode
>> -
>> - - elm_id:	<deprecated> use "ti,elm-id" instead
>> - - ti,elm-id:	Specifies phandle of the ELM devicetree node.
>> -		ELM is an on-chip hardware engine on TI SoC which is used for
>> -		locating ECC errors for BCHx algorithms. SoC devices which have
>> -		ELM hardware engines should specify this device node in .dtsi
>> -		Using ELM for ECC error correction frees some CPU cycles.
>> - - rb-gpios:	GPIO specifier for the ready/busy# pin.
>> -
>> -For inline partition table parsing (optional):
>> -
>> - - #address-cells: should be set to 1
>> - - #size-cells: should be set to 1
>> -
>> -Example for an AM33xx board:
>> -
>> -	gpmc: gpmc at 50000000 {
>> -		compatible = "ti,am3352-gpmc";
>> -		ti,hwmods = "gpmc";
>> -		reg = <0x50000000 0x36c>;
>> -		interrupts = <100>;
>> -		gpmc,num-cs = <8>;
>> -		gpmc,num-waitpins = <2>;
>> -		#address-cells = <2>;
>> -		#size-cells = <1>;
>> -		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
>> -		elm_id = <&elm>;
>> -		interrupt-controller;
>> -		#interrupt-cells = <2>;
>> -
>> -		nand at 0,0 {
>> -			compatible = "ti,omap2-nand";
>> -			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
>> -			interrupt-parent = <&gpmc>;
>> -			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
>> -			nand-bus-width = <16>;
>> -			ti,nand-ecc-opt = "bch8";
>> -			ti,nand-xfer-type = "polled";
>> -			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
>> -
>> -			gpmc,sync-clk-ps = <0>;
>> -			gpmc,cs-on-ns = <0>;
>> -			gpmc,cs-rd-off-ns = <44>;
>> -			gpmc,cs-wr-off-ns = <44>;
>> -			gpmc,adv-on-ns = <6>;
>> -			gpmc,adv-rd-off-ns = <34>;
>> -			gpmc,adv-wr-off-ns = <44>;
>> -			gpmc,we-off-ns = <40>;
>> -			gpmc,oe-off-ns = <54>;
>> -			gpmc,access-ns = <64>;
>> -			gpmc,rd-cycle-ns = <82>;
>> -			gpmc,wr-cycle-ns = <82>;
>> -			gpmc,wr-access-ns = <40>;
>> -			gpmc,wr-data-mux-bus-ns = <0>;
>> -
>> -			#address-cells = <1>;
>> -			#size-cells = <1>;
>> -
>> -			/* partitions go here */
>> -		};
>> -	};
>> -
>> -How to select correct ECC scheme for your device ?
>> ---------------------------------------------------
>> -Higher ECC scheme usually means better protection against bit-flips and
>> -increased system lifetime. However, selection of ECC scheme is dependent
>> -on various other factors also like;
>> -
>> -(1) support of built in hardware engines.
>> -	Some legacy OMAP SoC do not have ELM harware engine, so those SoC cannot
>> -	support ecc-schemes with hardware error-correction (BCHx_HW). However
>> -	such SoC can use ecc-schemes with software library for error-correction
>> -	(BCHx_HW_DETECTION_SW). The error correction capability with software
>> -	library remains equivalent to their hardware counter-part, but there is
>> -	slight CPU penalty when too many bit-flips are detected during reads.
>> -
>> -(2) Device parameters like OOBSIZE.
>> -	Other factor which governs the selection of ecc-scheme is oob-size.
>> -	Higher ECC schemes require more OOB/Spare area to store ECC syndrome,
>> -	so the device should have enough free bytes available its OOB/Spare
>> -	area to accommodate ECC for entire page. In general following expression
>> -	helps in determining if given device can accommodate ECC syndrome:
>> -	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
>> -	where
>> -		OOBSIZE		number of bytes in OOB/spare area
>> -		PAGESIZE	number of bytes in main-area of device page
>> -		ECC_BYTES	number of ECC bytes generated to protect
>> -		                512 bytes of data, which is:
>> -				'3' for HAM1_xx ecc schemes
>> -				'7' for BCH4_xx ecc schemes
>> -				'14' for BCH8_xx ecc schemes
>> -				'26' for BCH16_xx ecc schemes
>> -
>> -	Example(a): For a device with PAGESIZE = 2048 and OOBSIZE = 64 and
>> -		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
>> -		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
>> -		which is greater than capacity of NAND device (OOBSIZE=64)
>> -		Hence, BCH16 cannot be supported on given device. But it can
>> -		probably use lower ecc-schemes like BCH8.
>> -
>> -	Example(b): For a device with PAGESIZE = 2048 and OOBSIZE = 128 and
>> -		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
>> -		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
>> -		which can be accommodated in the OOB/Spare area of this device
>> -		(OOBSIZE=128). So this device can use BCH16 ecc-scheme.
>> diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
>> new file mode 100644
>> index 000000000000..db36f2e944ef
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
>> @@ -0,0 +1,110 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/mtd/ti,gpmc-nand.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Texas Instruments GPMC NAND Flash controller.
>> +
>> +maintainers:
>> +  - Tony Lindgren <tony at atomide.com>
>> +  - Roger Quadros <rogerq at kernel.org>
>> +
>> +description:
>> +  GPMC NAND controller/Flash is represented as a child of the
>> +  GPMC controller node.
>> +
>> +properties:
>> +  compatible:
>> +    const: ti,omap2-nand
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  interrupts:
>> +    items:
>> +      - description: Interrupt for fifoevent
>> +      - description: Interrupt for termcount
>> +
>> +  "#address-cells":
>> +    const: 1
>> +
>> +  "#size-cells":
>> +    const: 1
>> +
>> +  ti,nand-ecc-opt:
>> +    description: Desired ECC algorithm
>> +    $ref: /schemas/types.yaml#/definitions/string
>> +    enum: [sw, ham1, bch4, bch8, bch16]
>> +
>> +  ti,nand-xfer-type:
>> +    description: Data transfer method between controller and chip.
>> +    $ref: /schemas/types.yaml#/definitions/string
>> +    enum: [prefetch-polled, polled, prefetch-dma, prefetch-irq]
>> +    default: prefetch-polled
>> +
>> +  ti,elm-id:
>> +    description:
>> +      phandle to the ELM (Error Location Module).
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +
>> +  nand-bus-width:
>> +    description:
>> +      Bus width to the NAND chip
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    enum: [8, 16]
>> +    default: 8
>> +
>> +allOf:
>> +  - $ref: "../memory-controllers/ti,gpmc-child.yaml"
> 
> Use /schemas/... rather than '..'

ok.

> 
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - ti,nand-ecc-opt
>> +
>> +unevaluatedProperties: false
> 
> This will throw errors if you have partition nodes. You need to 
> reference the partitions schema.

I didn't get any errors with dtbs_check so far. But I will
try referencing the partition schema here.

> 
> Or minimally restrict to nodes with: 
> 
> unevaluatedProperties:
>   type: object
> 
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>> +    #include <dt-bindings/gpio/gpio.h>
>> +
>> +    gpmc: memory-controller at 50000000 {
>> +      compatible = "ti,am3352-gpmc";
>> +      dmas = <&edma 52 0>;
>> +      dma-names = "rxtx";
>> +      clocks = <&l3s_gclk>;
>> +      clock-names = "fck";
>> +      reg = <0x50000000 0x2000>;
>> +      interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
>> +      gpmc,num-cs = <7>;
>> +      gpmc,num-waitpins = <2>;
>> +      #address-cells = <2>;
>> +      #size-cells = <1>;
>> +      interrupt-controller;
>> +      #interrupt-cells = <2>;
>> +      gpio-controller;
>> +      #gpio-cells = <2>;
>> +
>> +      ranges = <0 0 0x08000000 0x01000000>;   /* CS0 space. Min partition = 16MB */
>> +      nand at 0,0 {
>> +        compatible = "ti,omap2-nand";
>> +        reg = <0 0 4>;          /* device IO registers */
>> +        interrupt-parent = <&gpmc>;
>> +        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
>> +                     <1 IRQ_TYPE_NONE>; /* termcount */
>> +        ti,nand-xfer-type = "prefetch-dma";
>> +        ti,nand-ecc-opt = "bch16";
>> +        ti,elm-id = <&elm>;
>> +        #address-cells = <1>;
>> +        #size-cells = <1>;
>> +
>> +        /* NAND generic properties */
>> +        nand-bus-width = <8>;
>> +        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>;  /* gpmc_wait0 */
>> +
>> +        /* GPMC properties*/
>> +        gpmc,device-width = <1>;
>> +      };
>> +    };
>> -- 
>> 2.17.1
>>
>>

cheers,
-roger


From pintu.ping at gmail.com  Wed Sep  8 04:27:45 2021
From: pintu.ping at gmail.com (Pintu Agarwal)
Date: Wed, 8 Sep 2021 16:57:45 +0530
Subject: Kernel 4.14: Using dm-verity with squashfs rootfs - mounting issue
In-Reply-To: <CAOuPNLiW10-E6F_Ndte7U9NPBKa9Y_UuLhgdwAYTc0eYMk5Mqg@mail.gmail.com>
References: <CAOuPNLhqSpaTm3u4kFsnuZ0PLDKuX8wsxuF=vUJ1TEG0EP+L1g@mail.gmail.com>
 <alpine.LRH.2.02.2107200737510.19984@file01.intranet.prod.int.rdu2.redhat.com>
 <CAOuPNLhh_LkLQ8mSA4eoUDLCLzHo5zHXsiQZXUB_-T_F1_v6-g@mail.gmail.com>
 <alpine.LRH.2.02.2107211300520.10897@file01.intranet.prod.int.rdu2.redhat.com>
 <CAOuPNLi-xz_4P+v45CHLx00ztbSwU3_maf4tuuyso5RHyeOytg@mail.gmail.com>
 <CAOuPNLg0m-Q7Vhp4srbQrjXHsxVhOr-K2dvnNqzdR6Dr4kioqA@mail.gmail.com>
 <20210830185541.715f6a39@windsurf>
 <CAOuPNLhTidgLNWUbtUgdESYcKcE1C4SOdzKeQVhFGQvEoc0QEg@mail.gmail.com>
 <20210830211224.76391708@windsurf>
 <CAOuPNLgMd0AThhmSknbmKqp3_P8PFhBGr-jW0Mqjb6K6NchEMg@mail.gmail.com>
 <CAOuPNLiW10-E6F_Ndte7U9NPBKa9Y_UuLhgdwAYTc0eYMk5Mqg@mail.gmail.com>
Message-ID: <CAOuPNLj2Xmx52Gtzx5oEKif4Qz-Tz=vaxhRvHQG-5emO7ewRhg@mail.gmail.com>

Hi,

On Mon, 6 Sept 2021 at 21:58, Pintu Agarwal <pintu.ping at gmail.com> wrote:

> On Tue, 31 Aug 2021 at 18:49, Pintu Agarwal <pintu.ping at gmail.com> wrote:
>
> > > No, but you can backport it easily. Back at
> > > http://lists.infradead.org/pipermail/openwrt-devel/2019-November/025967.html
> > > I provided backports of this feature to OpenWrt, for the 4.14 and 4.19
> > > kernels.

Can you please let me know where to get the below patches for
backporting to our kernel:
 create mode 100644
target/linux/generic/backport-4.14/390-dm-add-support-to-directly-boot-to-a-mapped-device.patch
 create mode 100644
target/linux/generic/backport-4.14/391-dm-init-fix-max-devices-targets-checks.patch
 create mode 100644
target/linux/generic/backport-4.14/392-dm-ioctl-fix-hang-in-early-create-error-condition.patch
 create mode 100644
target/linux/generic/backport-4.14/393-Documentation-dm-init-fix-multi-device-example.patch


From gregkh at linuxfoundation.org  Wed Sep  8 05:08:10 2021
From: gregkh at linuxfoundation.org (Greg KH)
Date: Wed, 8 Sep 2021 14:08:10 +0200
Subject: Kernel 4.14: Using dm-verity with squashfs rootfs - mounting issue
In-Reply-To: <CAOuPNLj2Xmx52Gtzx5oEKif4Qz-Tz=vaxhRvHQG-5emO7ewRhg@mail.gmail.com>
References: <CAOuPNLhh_LkLQ8mSA4eoUDLCLzHo5zHXsiQZXUB_-T_F1_v6-g@mail.gmail.com>
 <alpine.LRH.2.02.2107211300520.10897@file01.intranet.prod.int.rdu2.redhat.com>
 <CAOuPNLi-xz_4P+v45CHLx00ztbSwU3_maf4tuuyso5RHyeOytg@mail.gmail.com>
 <CAOuPNLg0m-Q7Vhp4srbQrjXHsxVhOr-K2dvnNqzdR6Dr4kioqA@mail.gmail.com>
 <20210830185541.715f6a39@windsurf>
 <CAOuPNLhTidgLNWUbtUgdESYcKcE1C4SOdzKeQVhFGQvEoc0QEg@mail.gmail.com>
 <20210830211224.76391708@windsurf>
 <CAOuPNLgMd0AThhmSknbmKqp3_P8PFhBGr-jW0Mqjb6K6NchEMg@mail.gmail.com>
 <CAOuPNLiW10-E6F_Ndte7U9NPBKa9Y_UuLhgdwAYTc0eYMk5Mqg@mail.gmail.com>
 <CAOuPNLj2Xmx52Gtzx5oEKif4Qz-Tz=vaxhRvHQG-5emO7ewRhg@mail.gmail.com>
Message-ID: <YTinqiH9h+Q9bYsr@kroah.com>

On Wed, Sep 08, 2021 at 04:57:45PM +0530, Pintu Agarwal wrote:
> Hi,
> 
> On Mon, 6 Sept 2021 at 21:58, Pintu Agarwal <pintu.ping at gmail.com> wrote:
> 
> > On Tue, 31 Aug 2021 at 18:49, Pintu Agarwal <pintu.ping at gmail.com> wrote:
> >
> > > > No, but you can backport it easily. Back at
> > > > http://lists.infradead.org/pipermail/openwrt-devel/2019-November/025967.html
> > > > I provided backports of this feature to OpenWrt, for the 4.14 and 4.19
> > > > kernels.
> 
> Can you please let me know where to get the below patches for
> backporting to our kernel:
>  create mode 100644
> target/linux/generic/backport-4.14/390-dm-add-support-to-directly-boot-to-a-mapped-device.patch
>  create mode 100644
> target/linux/generic/backport-4.14/391-dm-init-fix-max-devices-targets-checks.patch
>  create mode 100644
> target/linux/generic/backport-4.14/392-dm-ioctl-fix-hang-in-early-create-error-condition.patch
>  create mode 100644
> target/linux/generic/backport-4.14/393-Documentation-dm-init-fix-multi-device-example.patch

If you are stuck on an older kernel version, then you need to get
support from the vendor that is forcing you to be on that kernel
version, as you are already paying them for support.  Please take
advantage of that, as no one knows what is really in "your kernel".

thanks,

greg k-h


From robh at kernel.org  Wed Sep  8 05:46:47 2021
From: robh at kernel.org (Rob Herring)
Date: Wed, 8 Sep 2021 07:46:47 -0500
Subject: [PATCH v3 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <5b7787ce-d51f-e79c-fa7a-0113acda5648@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-6-rogerq@kernel.org>
 <YTea/Ium7TptHlnV@robh.at.kernel.org>
 <5b7787ce-d51f-e79c-fa7a-0113acda5648@kernel.org>
Message-ID: <CAL_Jsq+Nz3V4yri8QqaGoNOjL6dObPPV4dM1B2uzDMp6Fvw=SA@mail.gmail.com>

On Wed, Sep 8, 2021 at 6:14 AM Roger Quadros <rogerq at kernel.org> wrote:
>
>
>
> On 07/09/2021 20:01, Rob Herring wrote:
> > On Tue, Sep 07, 2021 at 02:32:23PM +0300, Roger Quadros wrote:
> >> Convert gpmc-nand.txt to ti,gpmc-nand.yaml.
> >>
> >> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> >> ---
> >>  .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 ------------------
> >>  .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 110 +++++++++++++
> >>  2 files changed, 110 insertions(+), 147 deletions(-)
> >>  delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> >>  create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
> >>
> >> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> >> deleted file mode 100644
> >> index 44919d48d241..000000000000
> >> --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
> >> +++ /dev/null
> >> @@ -1,147 +0,0 @@
> >> -Device tree bindings for GPMC connected NANDs
> >> -
> >> -GPMC connected NAND (found on OMAP boards) are represented as child nodes of
> >> -the GPMC controller with a name of "nand".
> >> -
> >> -All timing relevant properties as well as generic gpmc child properties are
> >> -explained in a separate documents - please refer to
> >> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> >> -
> >> -For NAND specific properties such as ECC modes or bus width, please refer to
> >> -Documentation/devicetree/bindings/mtd/nand-controller.yaml
> >> -
> >> -
> >> -Required properties:
> >> -
> >> - - compatible:      "ti,omap2-nand"
> >> - - reg:             range id (CS number), base offset and length of the
> >> -            NAND I/O space
> >> - - interrupts:      Two interrupt specifiers, one for fifoevent, one for termcount.
> >> -
> >> -Optional properties:
> >> -
> >> - - nand-bus-width:          Set this numeric value to 16 if the hardware
> >> -                            is wired that way. If not specified, a bus
> >> -                            width of 8 is assumed.
> >> -
> >> - - ti,nand-ecc-opt:         A string setting the ECC layout to use. One of:
> >> -            "sw"            1-bit Hamming ecc code via software
> >> -            "hw"            <deprecated> use "ham1" instead
> >> -            "hw-romcode"    <deprecated> use "ham1" instead
> >> -            "ham1"          1-bit Hamming ecc code
> >> -            "bch4"          4-bit BCH ecc code
> >> -            "bch8"          8-bit BCH ecc code
> >> -            "bch16"         16-bit BCH ECC code
> >> -            Refer below "How to select correct ECC scheme for your device ?"
> >> -
> >> - - ti,nand-xfer-type:               A string setting the data transfer type. One of:
> >> -
> >> -            "prefetch-polled"       Prefetch polled mode (default)
> >> -            "polled"                Polled mode, without prefetch
> >> -            "prefetch-dma"          Prefetch enabled DMA mode
> >> -            "prefetch-irq"          Prefetch enabled irq mode
> >> -
> >> - - elm_id:  <deprecated> use "ti,elm-id" instead
> >> - - ti,elm-id:       Specifies phandle of the ELM devicetree node.
> >> -            ELM is an on-chip hardware engine on TI SoC which is used for
> >> -            locating ECC errors for BCHx algorithms. SoC devices which have
> >> -            ELM hardware engines should specify this device node in .dtsi
> >> -            Using ELM for ECC error correction frees some CPU cycles.
> >> - - rb-gpios:        GPIO specifier for the ready/busy# pin.
> >> -
> >> -For inline partition table parsing (optional):
> >> -
> >> - - #address-cells: should be set to 1
> >> - - #size-cells: should be set to 1
> >> -
> >> -Example for an AM33xx board:
> >> -
> >> -    gpmc: gpmc at 50000000 {
> >> -            compatible = "ti,am3352-gpmc";
> >> -            ti,hwmods = "gpmc";
> >> -            reg = <0x50000000 0x36c>;
> >> -            interrupts = <100>;
> >> -            gpmc,num-cs = <8>;
> >> -            gpmc,num-waitpins = <2>;
> >> -            #address-cells = <2>;
> >> -            #size-cells = <1>;
> >> -            ranges = <0 0 0x08000000 0x1000000>;    /* CS0 space, 16MB */
> >> -            elm_id = <&elm>;
> >> -            interrupt-controller;
> >> -            #interrupt-cells = <2>;
> >> -
> >> -            nand at 0,0 {
> >> -                    compatible = "ti,omap2-nand";
> >> -                    reg = <0 0 4>;          /* CS0, offset 0, NAND I/O window 4 */
> >> -                    interrupt-parent = <&gpmc>;
> >> -                    interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
> >> -                    nand-bus-width = <16>;
> >> -                    ti,nand-ecc-opt = "bch8";
> >> -                    ti,nand-xfer-type = "polled";
> >> -                    rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
> >> -
> >> -                    gpmc,sync-clk-ps = <0>;
> >> -                    gpmc,cs-on-ns = <0>;
> >> -                    gpmc,cs-rd-off-ns = <44>;
> >> -                    gpmc,cs-wr-off-ns = <44>;
> >> -                    gpmc,adv-on-ns = <6>;
> >> -                    gpmc,adv-rd-off-ns = <34>;
> >> -                    gpmc,adv-wr-off-ns = <44>;
> >> -                    gpmc,we-off-ns = <40>;
> >> -                    gpmc,oe-off-ns = <54>;
> >> -                    gpmc,access-ns = <64>;
> >> -                    gpmc,rd-cycle-ns = <82>;
> >> -                    gpmc,wr-cycle-ns = <82>;
> >> -                    gpmc,wr-access-ns = <40>;
> >> -                    gpmc,wr-data-mux-bus-ns = <0>;
> >> -
> >> -                    #address-cells = <1>;
> >> -                    #size-cells = <1>;
> >> -
> >> -                    /* partitions go here */
> >> -            };
> >> -    };
> >> -
> >> -How to select correct ECC scheme for your device ?
> >> ---------------------------------------------------
> >> -Higher ECC scheme usually means better protection against bit-flips and
> >> -increased system lifetime. However, selection of ECC scheme is dependent
> >> -on various other factors also like;
> >> -
> >> -(1) support of built in hardware engines.
> >> -    Some legacy OMAP SoC do not have ELM harware engine, so those SoC cannot
> >> -    support ecc-schemes with hardware error-correction (BCHx_HW). However
> >> -    such SoC can use ecc-schemes with software library for error-correction
> >> -    (BCHx_HW_DETECTION_SW). The error correction capability with software
> >> -    library remains equivalent to their hardware counter-part, but there is
> >> -    slight CPU penalty when too many bit-flips are detected during reads.
> >> -
> >> -(2) Device parameters like OOBSIZE.
> >> -    Other factor which governs the selection of ecc-scheme is oob-size.
> >> -    Higher ECC schemes require more OOB/Spare area to store ECC syndrome,
> >> -    so the device should have enough free bytes available its OOB/Spare
> >> -    area to accommodate ECC for entire page. In general following expression
> >> -    helps in determining if given device can accommodate ECC syndrome:
> >> -    "2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
> >> -    where
> >> -            OOBSIZE         number of bytes in OOB/spare area
> >> -            PAGESIZE        number of bytes in main-area of device page
> >> -            ECC_BYTES       number of ECC bytes generated to protect
> >> -                            512 bytes of data, which is:
> >> -                            '3' for HAM1_xx ecc schemes
> >> -                            '7' for BCH4_xx ecc schemes
> >> -                            '14' for BCH8_xx ecc schemes
> >> -                            '26' for BCH16_xx ecc schemes
> >> -
> >> -    Example(a): For a device with PAGESIZE = 2048 and OOBSIZE = 64 and
> >> -            trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
> >> -            Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
> >> -            which is greater than capacity of NAND device (OOBSIZE=64)
> >> -            Hence, BCH16 cannot be supported on given device. But it can
> >> -            probably use lower ecc-schemes like BCH8.
> >> -
> >> -    Example(b): For a device with PAGESIZE = 2048 and OOBSIZE = 128 and
> >> -            trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
> >> -            Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
> >> -            which can be accommodated in the OOB/Spare area of this device
> >> -            (OOBSIZE=128). So this device can use BCH16 ecc-scheme.
> >> diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
> >> new file mode 100644
> >> index 000000000000..db36f2e944ef
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
> >> @@ -0,0 +1,110 @@
> >> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/mtd/ti,gpmc-nand.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: Texas Instruments GPMC NAND Flash controller.
> >> +
> >> +maintainers:
> >> +  - Tony Lindgren <tony at atomide.com>
> >> +  - Roger Quadros <rogerq at kernel.org>
> >> +
> >> +description:
> >> +  GPMC NAND controller/Flash is represented as a child of the
> >> +  GPMC controller node.
> >> +
> >> +properties:
> >> +  compatible:
> >> +    const: ti,omap2-nand
> >> +
> >> +  reg:
> >> +    maxItems: 1
> >> +
> >> +  interrupts:
> >> +    items:
> >> +      - description: Interrupt for fifoevent
> >> +      - description: Interrupt for termcount
> >> +
> >> +  "#address-cells":
> >> +    const: 1
> >> +
> >> +  "#size-cells":
> >> +    const: 1
> >> +
> >> +  ti,nand-ecc-opt:
> >> +    description: Desired ECC algorithm
> >> +    $ref: /schemas/types.yaml#/definitions/string
> >> +    enum: [sw, ham1, bch4, bch8, bch16]
> >> +
> >> +  ti,nand-xfer-type:
> >> +    description: Data transfer method between controller and chip.
> >> +    $ref: /schemas/types.yaml#/definitions/string
> >> +    enum: [prefetch-polled, polled, prefetch-dma, prefetch-irq]
> >> +    default: prefetch-polled
> >> +
> >> +  ti,elm-id:
> >> +    description:
> >> +      phandle to the ELM (Error Location Module).
> >> +    $ref: /schemas/types.yaml#/definitions/phandle
> >> +
> >> +  nand-bus-width:
> >> +    description:
> >> +      Bus width to the NAND chip
> >> +    $ref: /schemas/types.yaml#/definitions/uint32
> >> +    enum: [8, 16]
> >> +    default: 8
> >> +
> >> +allOf:
> >> +  - $ref: "../memory-controllers/ti,gpmc-child.yaml"
> >
> > Use /schemas/... rather than '..'
>
> ok.
>
> >
> >> +
> >> +required:
> >> +  - compatible
> >> +  - reg
> >> +  - ti,nand-ecc-opt
> >> +
> >> +unevaluatedProperties: false
> >
> > This will throw errors if you have partition nodes. You need to
> > reference the partitions schema.
>
> I didn't get any errors with dtbs_check so far. But I will
> try referencing the partition schema here.

Not yet because 'unevaluatedProperties' isn't actually supported in
the jsonschema package yet. It will be in the next release which I
expect soonish.

Rob


From bert at biot.com  Wed Sep  8 13:16:19 2021
From: bert at biot.com (Bert Vermeulen)
Date: Wed,  8 Sep 2021 22:16:19 +0200
Subject: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
Message-ID: <20210908201624.237634-1-bert@biot.com>

This adds a new vendor Etron, and support for a 2Gb chip.

The datasheet is available at
https://www.etron.com/cn/products/EM73%5B8%5DC%5BD_E_F%5DVC%20SPI%20NAND%20Flash_Promotion_Rev%201_00A.pdf

Signed-off-by: Bert Vermeulen <bert at biot.com>
---
v2:
- Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
  hardcoded to this 2Gb chip only
- Fixed manufacturer ordering
- Fixed minor formatting issues as reported
- Removed debug comment

 drivers/mtd/nand/spi/Makefile |   2 +-
 drivers/mtd/nand/spi/core.c   |   1 +
 drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
 include/linux/mtd/spinand.h   |   1 +
 4 files changed, 107 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/nand/spi/etron.c

diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
index 9662b9c1d5a9..cc3c4e046ea9 100644
--- a/drivers/mtd/nand/spi/Makefile
+++ b/drivers/mtd/nand/spi/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
-spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
+spinand-objs := core.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
 obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 446ba8d43fbc..2cbf25b8caa2 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -894,6 +894,7 @@ static const struct nand_ops spinand_ops = {
 };
 
 static const struct spinand_manufacturer *spinand_manufacturers[] = {
+	&etron_spinand_manufacturer,
 	&gigadevice_spinand_manufacturer,
 	&macronix_spinand_manufacturer,
 	&micron_spinand_manufacturer,
diff --git a/drivers/mtd/nand/spi/etron.c b/drivers/mtd/nand/spi/etron.c
new file mode 100644
index 000000000000..1a92b9cf3043
--- /dev/null
+++ b/drivers/mtd/nand/spi/etron.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mtd/spinand.h>
+
+#define SPINAND_MFR_ETRON			0xd5
+
+static SPINAND_OP_VARIANTS(read_cache_variants,
+		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+static SPINAND_OP_VARIANTS(write_cache_variants,
+		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+		SPINAND_PROG_LOAD(true, 0, NULL, 0));
+
+static SPINAND_OP_VARIANTS(update_cache_variants,
+		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+		SPINAND_PROG_LOAD(false, 0, NULL, 0));
+
+static int etron_oob_spare(struct mtd_info *mtd)
+{
+	if (mtd->size < 0x10000000)
+		return mtd->oobsize / 2;
+	else
+		return mtd->oobsize / 2 + mtd->oobsize / 16;
+}
+
+static int etron_ooblayout_ecc(struct mtd_info *mtd, int section,
+					struct mtd_oob_region *oobregion)
+{
+	if (section)
+		return -ERANGE;
+
+	oobregion->offset = etron_oob_spare(mtd);
+	oobregion->length = mtd->oobsize - oobregion->offset;
+
+	return 0;
+}
+
+static int etron_ooblayout_free(struct mtd_info *mtd, int section,
+			   struct mtd_oob_region *oobregion)
+{
+	if (section)
+		return -ERANGE;
+
+	oobregion->offset = 2;
+	oobregion->length = etron_oob_spare(mtd) - 2;
+
+	return 0;
+}
+
+static const struct mtd_ooblayout_ops etron_ooblayout = {
+	.ecc = etron_ooblayout_ecc,
+	.free = etron_ooblayout_free,
+};
+
+static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
+{
+	switch (status & STATUS_ECC_MASK) {
+	case STATUS_ECC_NO_BITFLIPS:
+		return 0;
+
+	case STATUS_ECC_HAS_BITFLIPS:
+		/* Between 1-7 bitflips were corrected */
+		return 7;
+
+	case STATUS_ECC_MASK:
+		/* Maximum bitflips were corrected */
+		return 8;
+
+	case STATUS_ECC_UNCOR_ERROR:
+		return -EBADMSG;
+	}
+
+	return -EINVAL;
+}
+
+static const struct spinand_info etron_spinand_table[] = {
+	SPINAND_INFO("EM73D044VCx",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f),
+		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+		     NAND_ECCREQ(8, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
+};
+
+static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = {
+};
+
+const struct spinand_manufacturer etron_spinand_manufacturer = {
+	.id = SPINAND_MFR_ETRON,
+	.name = "Etron",
+	.chips = etron_spinand_table,
+	.nchips = ARRAY_SIZE(etron_spinand_table),
+	.ops = &etron_spinand_manuf_ops,
+};
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 6988956b8492..d7c0a0439652 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -260,6 +260,7 @@ struct spinand_manufacturer {
 };
 
 /* SPI NAND manufacturers */
+extern const struct spinand_manufacturer etron_spinand_manufacturer;
 extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
 extern const struct spinand_manufacturer macronix_spinand_manufacturer;
 extern const struct spinand_manufacturer micron_spinand_manufacturer;
-- 
2.25.1



From ebiggers at kernel.org  Wed Sep  8 14:50:29 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed,  8 Sep 2021 14:50:29 -0700
Subject: [PATCH 0/4] backport fscrypt symlink fixes to 4.19
Message-ID: <20210908215033.1122580-1-ebiggers@kernel.org>

This series backports some patches that failed to apply to 4.19-stable
due to the prototype of inode_operations::getattr having changed in
v5.12, as well as several other conflicts.  Please apply to 4.19-stable.

Eric Biggers (4):
  fscrypt: add fscrypt_symlink_getattr() for computing st_size
  ext4: report correct st_size for encrypted symlinks
  f2fs: report correct st_size for encrypted symlinks
  ubifs: report correct st_size for encrypted symlinks

 fs/crypto/hooks.c               | 44 +++++++++++++++++++++++++++++++++
 fs/ext4/symlink.c               | 11 ++++++++-
 fs/f2fs/namei.c                 | 11 ++++++++-
 fs/ubifs/file.c                 | 12 ++++++++-
 include/linux/fscrypt_notsupp.h |  6 +++++
 include/linux/fscrypt_supp.h    |  1 +
 6 files changed, 82 insertions(+), 3 deletions(-)

-- 
2.33.0.153.gba50c8fa24-goog



From ebiggers at kernel.org  Wed Sep  8 14:50:31 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed,  8 Sep 2021 14:50:31 -0700
Subject: [PATCH 2/4] ext4: report correct st_size for encrypted symlinks
In-Reply-To: <20210908215033.1122580-1-ebiggers@kernel.org>
References: <20210908215033.1122580-1-ebiggers@kernel.org>
Message-ID: <20210908215033.1122580-3-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 8c4bca10ceafc43b1ca0a9fab5fa27e13cbce99e upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after ext4_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: f348c252320b ("ext4 crypto: add symlink encryption")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-3-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/ext4/symlink.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
index dd05af983092..a9457fed351e 100644
--- a/fs/ext4/symlink.c
+++ b/fs/ext4/symlink.c
@@ -52,10 +52,19 @@ static const char *ext4_encrypted_get_link(struct dentry *dentry,
 	return paddr;
 }
 
+static int ext4_encrypted_symlink_getattr(const struct path *path,
+					  struct kstat *stat, u32 request_mask,
+					  unsigned int query_flags)
+{
+	ext4_getattr(path, stat, request_mask, query_flags);
+
+	return fscrypt_symlink_getattr(path, stat);
+}
+
 const struct inode_operations ext4_encrypted_symlink_inode_operations = {
 	.get_link	= ext4_encrypted_get_link,
 	.setattr	= ext4_setattr,
-	.getattr	= ext4_getattr,
+	.getattr	= ext4_encrypted_symlink_getattr,
 	.listxattr	= ext4_listxattr,
 };
 
-- 
2.33.0.153.gba50c8fa24-goog



From ebiggers at kernel.org  Wed Sep  8 14:50:33 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed,  8 Sep 2021 14:50:33 -0700
Subject: [PATCH 4/4] ubifs: report correct st_size for encrypted symlinks
In-Reply-To: <20210908215033.1122580-1-ebiggers@kernel.org>
References: <20210908215033.1122580-1-ebiggers@kernel.org>
Message-ID: <20210908215033.1122580-5-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 064c734986011390b4d111f1a99372b7f26c3850 upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after ubifs_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: ca7f85be8d6c ("ubifs: Add support for encrypted symlinks")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-5-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/ubifs/file.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index d7d2fdda4bbd..3dbb5ac630e4 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1642,6 +1642,16 @@ static const char *ubifs_get_link(struct dentry *dentry,
 	return fscrypt_get_symlink(inode, ui->data, ui->data_len, done);
 }
 
+static int ubifs_symlink_getattr(const struct path *path, struct kstat *stat,
+				 u32 request_mask, unsigned int query_flags)
+{
+	ubifs_getattr(path, stat, request_mask, query_flags);
+
+	if (IS_ENCRYPTED(d_inode(path->dentry)))
+		return fscrypt_symlink_getattr(path, stat);
+	return 0;
+}
+
 const struct address_space_operations ubifs_file_address_operations = {
 	.readpage       = ubifs_readpage,
 	.writepage      = ubifs_writepage,
@@ -1669,7 +1679,7 @@ const struct inode_operations ubifs_file_inode_operations = {
 const struct inode_operations ubifs_symlink_inode_operations = {
 	.get_link    = ubifs_get_link,
 	.setattr     = ubifs_setattr,
-	.getattr     = ubifs_getattr,
+	.getattr     = ubifs_symlink_getattr,
 #ifdef CONFIG_UBIFS_FS_XATTR
 	.listxattr   = ubifs_listxattr,
 #endif
-- 
2.33.0.153.gba50c8fa24-goog



From ebiggers at kernel.org  Wed Sep  8 14:50:32 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed,  8 Sep 2021 14:50:32 -0700
Subject: [PATCH 3/4] f2fs: report correct st_size for encrypted symlinks
In-Reply-To: <20210908215033.1122580-1-ebiggers@kernel.org>
References: <20210908215033.1122580-1-ebiggers@kernel.org>
Message-ID: <20210908215033.1122580-4-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 461b43a8f92e68e96c4424b31e15f2b35f1bbfa9 upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after f2fs_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: cbaf042a3cc6 ("f2fs crypto: add symlink encryption")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-4-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/f2fs/namei.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index e20a0f9e6845..edc80855974a 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -1219,9 +1219,18 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry,
 	return target;
 }
 
+static int f2fs_encrypted_symlink_getattr(const struct path *path,
+					  struct kstat *stat, u32 request_mask,
+					  unsigned int query_flags)
+{
+	f2fs_getattr(path, stat, request_mask, query_flags);
+
+	return fscrypt_symlink_getattr(path, stat);
+}
+
 const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
 	.get_link       = f2fs_encrypted_get_link,
-	.getattr	= f2fs_getattr,
+	.getattr	= f2fs_encrypted_symlink_getattr,
 	.setattr	= f2fs_setattr,
 #ifdef CONFIG_F2FS_FS_XATTR
 	.listxattr	= f2fs_listxattr,
-- 
2.33.0.153.gba50c8fa24-goog



From ebiggers at kernel.org  Wed Sep  8 14:50:30 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed,  8 Sep 2021 14:50:30 -0700
Subject: [PATCH 1/4] fscrypt: add fscrypt_symlink_getattr() for computing
 st_size
In-Reply-To: <20210908215033.1122580-1-ebiggers@kernel.org>
References: <20210908215033.1122580-1-ebiggers@kernel.org>
Message-ID: <20210908215033.1122580-2-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit d18760560593e5af921f51a8c9b64b6109d634c2 upstream.

Add a helper function fscrypt_symlink_getattr() which will be called
from the various filesystems' ->getattr() methods to read and decrypt
the target of encrypted symlinks in order to report the correct st_size.

Detailed explanation:

As required by POSIX and as documented in various man pages, st_size for
a symlink is supposed to be the length of the symlink target.
Unfortunately, st_size has always been wrong for encrypted symlinks
because st_size is populated from i_size from disk, which intentionally
contains the length of the encrypted symlink target.  That's slightly
greater than the length of the decrypted symlink target (which is the
symlink target that userspace usually sees), and usually won't match the
length of the no-key encoded symlink target either.

This hadn't been fixed yet because reporting the correct st_size would
require reading the symlink target from disk and decrypting or encoding
it, which historically has been considered too heavyweight to do in
->getattr().  Also historically, the wrong st_size had only broken a
test (LTP lstat03) and there were no known complaints from real users.
(This is probably because the st_size of symlinks isn't used too often,
and when it is, typically it's for a hint for what buffer size to pass
to readlink() -- which a slightly-too-large size still works for.)

However, a couple things have changed now.  First, there have recently
been complaints about the current behavior from real users:

- Breakage in rpmbuild:
  https://github.com/rpm-software-management/rpm/issues/1682
  https://github.com/google/fscrypt/issues/305

- Breakage in toybox cpio:
  https://www.mail-archive.com/toybox at lists.landley.net/msg07193.html

- Breakage in libgit2: https://issuetracker.google.com/issues/189629152
  (on Android public issue tracker, requires login)

Second, we now cache decrypted symlink targets in ->i_link.  Therefore,
taking the performance hit of reading and decrypting the symlink target
in ->getattr() wouldn't be as big a deal as it used to be, since usually
it will just save having to do the same thing later.

Also note that eCryptfs ended up having to read and decrypt symlink
targets in ->getattr() as well, to fix this same issue; see
commit 3a60a1686f0d ("eCryptfs: Decrypt symlink target for stat size").

So, let's just bite the bullet, and read and decrypt the symlink target
in ->getattr() in order to report the correct st_size.  Add a function
fscrypt_symlink_getattr() which the filesystems will call to do this.

(Alternatively, we could store the decrypted size of symlinks on-disk.
But there isn't a great place to do so, and encryption is meant to hide
the original size to some extent; that property would be lost.)

Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-2-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/crypto/hooks.c               | 44 +++++++++++++++++++++++++++++++++
 include/linux/fscrypt_notsupp.h |  6 +++++
 include/linux/fscrypt_supp.h    |  1 +
 3 files changed, 51 insertions(+)

diff --git a/fs/crypto/hooks.c b/fs/crypto/hooks.c
index aa86cb2db823..ae7a413c0bdd 100644
--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -279,3 +279,47 @@ const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
 	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(fscrypt_get_symlink);
+
+/**
+ * fscrypt_symlink_getattr() - set the correct st_size for encrypted symlinks
+ * @path: the path for the encrypted symlink being queried
+ * @stat: the struct being filled with the symlink's attributes
+ *
+ * Override st_size of encrypted symlinks to be the length of the decrypted
+ * symlink target (or the no-key encoded symlink target, if the key is
+ * unavailable) rather than the length of the encrypted symlink target.  This is
+ * necessary for st_size to match the symlink target that userspace actually
+ * sees.  POSIX requires this, and some userspace programs depend on it.
+ *
+ * This requires reading the symlink target from disk if needed, setting up the
+ * inode's encryption key if possible, and then decrypting or encoding the
+ * symlink target.  This makes lstat() more heavyweight than is normally the
+ * case.  However, decrypted symlink targets will be cached in ->i_link, so
+ * usually the symlink won't have to be read and decrypted again later if/when
+ * it is actually followed, readlink() is called, or lstat() is called again.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat)
+{
+	struct dentry *dentry = path->dentry;
+	struct inode *inode = d_inode(dentry);
+	const char *link;
+	DEFINE_DELAYED_CALL(done);
+
+	/*
+	 * To get the symlink target that userspace will see (whether it's the
+	 * decrypted target or the no-key encoded target), we can just get it in
+	 * the same way the VFS does during path resolution and readlink().
+	 */
+	link = READ_ONCE(inode->i_link);
+	if (!link) {
+		link = inode->i_op->get_link(dentry, inode, &done);
+		if (IS_ERR(link))
+			return PTR_ERR(link);
+	}
+	stat->size = strlen(link);
+	do_delayed_call(&done);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fscrypt_symlink_getattr);
diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h
index 93304cfeb601..6e95c5a9b7fa 100644
--- a/include/linux/fscrypt_notsupp.h
+++ b/include/linux/fscrypt_notsupp.h
@@ -234,4 +234,10 @@ static inline const char *fscrypt_get_symlink(struct inode *inode,
 	return ERR_PTR(-EOPNOTSUPP);
 }
 
+static inline int fscrypt_symlink_getattr(const struct path *path,
+					  struct kstat *stat)
+{
+	return -EOPNOTSUPP;
+}
+
 #endif	/* _LINUX_FSCRYPT_NOTSUPP_H */
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
index 0409c14ae1de..f4cb4871a987 100644
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -231,5 +231,6 @@ extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
 extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
 				       unsigned int max_size,
 				       struct delayed_call *done);
+int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat);
 
 #endif	/* _LINUX_FSCRYPT_SUPP_H */
-- 
2.33.0.153.gba50c8fa24-goog



From michael at walle.cc  Wed Sep  8 16:32:18 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 09 Sep 2021 01:32:18 +0200
Subject: S25FL512 vs S25FS512
In-Reply-To: <MN2PR16MB313511219F7BFB2692C4C8B191CD9@MN2PR16MB3135.namprd16.prod.outlook.com>
References: <MN2PR16MB313511219F7BFB2692C4C8B191CD9@MN2PR16MB3135.namprd16.prod.outlook.com>
Message-ID: <a0388e5c6676b9cf4a5decc00a8da6f5@walle.cc>

Hi Renaud,

Am 2021-09-01 18:51, schrieb Barbier, Renaud:
> Hello,
> I bought a NXP ls1046ard evaluation board and saw some issues erasing
> the SPI NOR from my boot loader or ICE.
> The boot loader reported the flash as being a S25FL512 which is a
> uniform (256KiB) sector SPI NOR as per manufacturing ID 1 and device
> id 2
> 
> The eval board has in fact a S25FS512 SPI NOR which is by default a
> bottom boot flash. This can be disabled through a configuration
> register in the SPI NOR.

So you're saying the bootloader is wrong by reporting a S25FL512?

> I also see that Linux describes both the S25FL512 and S25FS512 as
> uniform sector flash:
> { "s25fl512s",  INFO6(0x010220, 0x4d0080, 256 * 1024, 256,
> 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> 			      SPI_NOR_HAS_LOCK | USE_CLSR) },
> 
> { "s25fs512s",  INFO6(0x010220, 0x4d0081, 256 * 1024, 256,
> 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR)
> 
> 
> 
> According to Cypress PDF https://www.cypress.com/file/177971/download,
> this SPI NOR S25FL512 is indeed a uniform sector flash but with a
> device ID of 0x19.

You lost me here. According to Table 52. The device id is 02h.

> While the Spansion documentation I found
> (https://datasheetspdf.com/pdf-file/831993/SPANSION/S25FL512S/1 )
> described it with a Device ID of 0x2.

Likewise.

> The S25FS512S has Device ID 0x2 according to Cypress documentation
> https://www.cypress.com/file/216376/download  and is a bottom boot
> flash.

And also for this flash, the device id is 02h. But the family code
at offset 05h is 81h here (instead of 80h for the s25fl512s).

> Is the SPI support for S25FS512 in Linux 5.14 disabling the bottom
> boot feature? I have not found it in the code. Only something related
> to page size.

What is a bottom boot feature? Are you talking about locking?

-michael


From renaud.barbier at abaco.com  Thu Sep  9 01:37:57 2021
From: renaud.barbier at abaco.com (Barbier, Renaud)
Date: Thu, 9 Sep 2021 08:37:57 +0000
Subject: S25FL512 vs S25FS512
In-Reply-To: <a0388e5c6676b9cf4a5decc00a8da6f5@walle.cc>
References: <MN2PR16MB313511219F7BFB2692C4C8B191CD9@MN2PR16MB3135.namprd16.prod.outlook.com>
 <a0388e5c6676b9cf4a5decc00a8da6f5@walle.cc>
Message-ID: <MN2PR16MB31351FBE06F4D9383F02480D91D59@MN2PR16MB3135.namprd16.prod.outlook.com>

>You lost me here. According to Table 52. The device id is 02h.
I was looking at Table 40 page 68. Hence, the confusion.


>> Is the SPI support for S25FS512 in Linux 5.14 disabling the bottom 
>> boot feature? I have not found it in the code. Only something related 
>> to page size.

>What is a bottom boot feature? Are you talking about locking?
This flash S25FS512 is configured by default  to have the first 256KiB sector divided into 8*4KiB + 224KiB.
This could be the top sector or disable with the configuration register.
Erasing 8 4KiB sectors requires a different command than erasing the 256KiB sectors.

I have now found the code in U-boot supporting those 8 sectors. 

Thanks for your answer.




-michael


From filip at kubicz.engineer  Thu Sep  9 09:41:24 2021
From: filip at kubicz.engineer (Filip Kubicz)
Date: Thu, 09 Sep 2021 18:41:24 +0200
Subject: MLC NAND support in ubifs
Message-ID: <17bcb6f7393.103451039732021.7530952965250426754@kubicz.engineer>

Hi!

I would like to ask about MLC NAND support in UBIFS.

I was recently bringing up a device with IMX6ULL and raw MLC NAND flash. I have built Linux 5.4 kernel, u-boot and rootfs (using buildroot), flashed them to my device with MLC NAND flash, and learned from dmesg error that MLC is unsupported by ubifs. Support removed in this commit: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b5094b7f135be

Then I followed the story from Richard and Boris and watched the talk where they explain the issues with MLC, and propose an alternative: https://www.youtube.com/watch?v=9j2pOIiJqYw&ab_channel=TheLinuxFoundation
Alternative available since Linux 5.8: https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.8-NAND-MLC-SLC-Emulate

My questions:
1. Is NAND MLC (+ubifs) reliable to use with SLC emulate mode introduced in kernel 5.8? Or should I rather switch to eMMC for this design? SLC NAND is too costly at my required size.

2. If the MLC NAND is not supported, can you update these pages:
- http://www.linux-mtd.infradead.org/doc/ubifs.html
- https://www.kernel.org/doc/html/latest/filesystems/ubifs.html
- http://www.linux-mtd.infradead.org/faq/ubifs.html
Each of the documentation pages mention MLC, so you can get an idea that it is supported. But it looks like the MLC NAND flash is not supported by UBIFS.

Kind regards,
Filip Kubicz

filip at kubicz.engineer
tel. (+48) 697 088 078





From ebiggers at kernel.org  Thu Sep  9 11:45:13 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Thu,  9 Sep 2021 11:45:13 -0700
Subject: [PATCH] fscrypt: remove fscrypt_operations::max_namelen
Message-ID: <20210909184513.139281-1-ebiggers@kernel.org>

From: Eric Biggers <ebiggers at google.com>

The max_namelen field is unnecessary, as it is set to 255 (NAME_MAX) on
all filesystems that support fscrypt (or plan to support fscrypt).  For
simplicity, just use NAME_MAX directly instead.

Signed-off-by: Eric Biggers <ebiggers at google.com>
---
 fs/crypto/fname.c       | 3 +--
 fs/ext4/super.c         | 1 -
 fs/f2fs/super.c         | 1 -
 fs/ubifs/crypto.c       | 1 -
 include/linux/fscrypt.h | 3 ---
 5 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c
index eb538c28df940..a9be4bc74a94a 100644
--- a/fs/crypto/fname.c
+++ b/fs/crypto/fname.c
@@ -429,8 +429,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
 
 	if (fscrypt_has_encryption_key(dir)) {
 		if (!fscrypt_fname_encrypted_size(&dir->i_crypt_info->ci_policy,
-						  iname->len,
-						  dir->i_sb->s_cop->max_namelen,
+						  iname->len, NAME_MAX,
 						  &fname->crypto_buf.len))
 			return -ENAMETOOLONG;
 		fname->crypto_buf.name = kmalloc(fname->crypto_buf.len,
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 136940af00b88..47212d7c02b84 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1566,7 +1566,6 @@ static const struct fscrypt_operations ext4_cryptops = {
 	.set_context		= ext4_set_context,
 	.get_dummy_policy	= ext4_get_dummy_policy,
 	.empty_dir		= ext4_empty_dir,
-	.max_namelen		= EXT4_NAME_LEN,
 	.has_stable_inodes	= ext4_has_stable_inodes,
 	.get_ino_and_lblk_bits	= ext4_get_ino_and_lblk_bits,
 };
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 78ebc306ee2b5..cf049a042482b 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2976,7 +2976,6 @@ static const struct fscrypt_operations f2fs_cryptops = {
 	.set_context		= f2fs_set_context,
 	.get_dummy_policy	= f2fs_get_dummy_policy,
 	.empty_dir		= f2fs_empty_dir,
-	.max_namelen		= F2FS_NAME_LEN,
 	.has_stable_inodes	= f2fs_has_stable_inodes,
 	.get_ino_and_lblk_bits	= f2fs_get_ino_and_lblk_bits,
 	.get_num_devices	= f2fs_get_num_devices,
diff --git a/fs/ubifs/crypto.c b/fs/ubifs/crypto.c
index 22be7aeb96c4f..c57b46a352d8f 100644
--- a/fs/ubifs/crypto.c
+++ b/fs/ubifs/crypto.c
@@ -82,5 +82,4 @@ const struct fscrypt_operations ubifs_crypt_operations = {
 	.get_context		= ubifs_crypt_get_context,
 	.set_context		= ubifs_crypt_set_context,
 	.empty_dir		= ubifs_crypt_empty_dir,
-	.max_namelen		= UBIFS_MAX_NLEN,
 };
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index e912ed9141d9d..91ea9477e9bd2 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -118,9 +118,6 @@ struct fscrypt_operations {
 	 */
 	bool (*empty_dir)(struct inode *inode);
 
-	/* The filesystem's maximum ciphertext filename length, in bytes */
-	unsigned int max_namelen;
-
 	/*
 	 * Check whether the filesystem's inode numbers and UUID are stable,
 	 * meaning that they will never be changed even by offline operations
-- 
2.33.0



From michael at walle.cc  Thu Sep  9 14:40:44 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 09 Sep 2021 23:40:44 +0200
Subject: [PATCH v2 08/35] mtd: spi-nor: core: Introduce the ate_init() hook
In-Reply-To: <20210816185446.topxrgwmvpt6n4ct@ti.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-9-tudor.ambarus@microchip.com>
 <20210816185446.topxrgwmvpt6n4ct@ti.com>
Message-ID: <1176aa457faf4ef5b60558a70c9b70b5@walle.cc>

Am 2021-08-16 20:54, schrieb Pratyush Yadav:
> Hi Tudor,
> 
>> Subject: [PATCH v2 08/35] mtd: spi-nor: core: Introduce the ate_init() 
>> hook
>                                                               ^^^^^^^^
> You ate the 'l' ;-)
> 
> On 27/07/21 07:51AM, Tudor Ambarus wrote:
>> The goal is to get rid of the spaghetti way of initializing the flash
>> parameters and settings. late_init() hook will be used to tweak 
>> various
>> parameters that are not defined by the SFDP standard. Can be used by
>> non SFDP compliant flashes in order to tweak flash parameters that
>> are not/shouldn't be handled by the flash_info flags. Will replace the
>> default_init() hook.
>> 
>> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
>> ---
>>  drivers/mtd/spi-nor/core.c | 15 +++++++++++----
>>  drivers/mtd/spi-nor/core.h |  8 ++++++++
>>  2 files changed, 19 insertions(+), 4 deletions(-)
>> 
>> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
>> index d30c8f350dc1..15ccc9994215 100644
>> --- a/drivers/mtd/spi-nor/core.c
>> +++ b/drivers/mtd/spi-nor/core.c
>> @@ -2667,11 +2667,18 @@ static void spi_nor_post_sfdp_fixups(struct 
>> spi_nor *nor)
>>   * spi_nor_late_init_params() - Late initialization of default flash 
>> parameters.
>>   * @nor:	pointer to a 'struct spi_nor'
>>   *
>> - * Used to set default flash parameters and settings when the 
>> ->default_init()
>> - * hook or the SFDP parser let voids.
>> + * Used to tweak various flash parameters that are not defined by the 
>> SFDP
>> + * standard. Can be used by non SFDP compliant flashes in order to 
>> tweek flash
>> + * parameters that are not handled by the flash_info flags.
> 
> What about flashes that do have the SFDP table, but not all of them? 
> For
> example, the Micron MT35XU512ABA flash currently uses the post_sfdp()
> hook to populate 8D-8D-8D fast read settings, command extension type,
> etc. These are supposed to be obtained from the xSPI Profile 1.0 table
> (like we do for Spansion/Cypress S28HS512T). But the flash does not
> populate this table. Should these go into the late_init() hook or the
> post_sfdp() hook?
> 
> FWIW, I think it should go into late_init(). post_sfdp() should only be
> used for correcting info obtained from the SFDP table. For populating
> the info not present in SFDP at all, late_init() should be used.
> 
> Thoughts?

Is there any difference between these? According to the description
in spi_nor_init_params() your case should go into post_sfdp(). Mh
or maybe not. It says "incomplete tables", one could interpret it
either way. We should clarify which fixup goes where, esp. this case
here where there should be a table describing it, but there isn't.

-michael

>>   */
>>  static void spi_nor_late_init_params(struct spi_nor *nor)
>>  {
>> +	if (nor->manufacturer && nor->manufacturer->late_init)
>> +		nor->manufacturer->late_init(nor);
>> +
>> +	if (nor->info->late_init)
>> +		nor->info->late_init(nor);
> 
> Manufacturer late_init goes before flash late_init. Makes sense.
> 
>> +
>>  	/*
>>  	 * NOR protection support. When locking_ops are not provided, we 
>> pick
>>  	 * the default ones.
>> @@ -2713,8 +2720,8 @@ static void spi_nor_late_init_params(struct 
>> spi_nor *nor)
>>   *    wrong).
>>   *		spi_nor_post_sfdp_fixups()
>>   *
>> - * 5/ Late default flash parameters initialization, used when the
>> - * ->default_init() hook or the SFDP parser do not set specific 
>> params.
>> + * 5/ Late flash parameters initialization, used to initialize flash
>> + * parameters that are not declared in the JESD216 SFDP standard.
>>   *		spi_nor_late_init_params()
>>   */
>>  static int spi_nor_init_params(struct spi_nor *nor)
>> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
>> index e9896cd60695..13d5c5edfd27 100644
>> --- a/drivers/mtd/spi-nor/core.h
>> +++ b/drivers/mtd/spi-nor/core.h
>> @@ -391,6 +391,11 @@ struct flash_info {
>> 
>>  	/* Part specific fixup hooks. */
>>  	const struct spi_nor_fixups *fixups;
>> +	/*
>> +	 * Init flash parameters that are not declared in the JESD216 SFDP
>> +	 * standard.
>> +	 */
>> +	void (* const late_init)(struct spi_nor *nor);
>>  };
>> 
>>  /* Used when the "_ext_id" is two bytes at most */
>> @@ -457,12 +462,15 @@ struct flash_info {
>>   * @parts: array of parts supported by this manufacturer
>>   * @nparts: number of entries in the parts array
>>   * @fixups: hooks called at various points in time during 
>> spi_nor_scan()
>> + * @late_init: used to init flash parameters that are not declared in 
>> the
>> + *             JESD216 SFDP standard.
>>   */
>>  struct spi_nor_manufacturer {
>>  	const char *name;
>>  	const struct flash_info *parts;
>>  	unsigned int nparts;
>>  	const struct spi_nor_fixups *fixups;
>> +	void (* const late_init)(struct spi_nor *nor);
> 
> The patch looks good to me other than the comments above.
> 
>>  };
>> 
>>  /**
>> --
>> 2.25.1
>> 

-- 
-michael


From michael at walle.cc  Thu Sep  9 14:44:50 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 09 Sep 2021 23:44:50 +0200
Subject: [PATCH v2 09/35] mtd: spi-nor: atmel: Use flash late_init() for
 locking
In-Reply-To: <20210816190629.3kg4cbf5d7h7gyk5@ti.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-10-tudor.ambarus@microchip.com>
 <20210816190629.3kg4cbf5d7h7gyk5@ti.com>
Message-ID: <a9d41aa96a8749b599d4479f18479c5d@walle.cc>

Am 2021-08-16 21:06, schrieb Pratyush Yadav:
> On 27/07/21 07:51AM, Tudor Ambarus wrote:
>> Locking is not described in JESD216 SFDP standard, place the locking
>> init in late_init().

Btw, we should differentiate between the block protection
bits and individual block locking. At least the latter is described
in the SFDP (I've seen it in the XTX SFDP, haven't checked the
standard yet).

> You are chaning the order of setting the locking ops here. Earlier, 
> they
> were set before we parsed SFDP. Now they are set after we parse SFDP.
> Though I don't see it making much of a difference.
> 
>> 
>> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
>> ---
>>  drivers/mtd/spi-nor/atmel.c | 30 +++++++++++-------------------
>>  1 file changed, 11 insertions(+), 19 deletions(-)
>> 
>> diff --git a/drivers/mtd/spi-nor/atmel.c b/drivers/mtd/spi-nor/atmel.c
>> index 1fea5cab492c..b937ef734e55 100644
>> --- a/drivers/mtd/spi-nor/atmel.c
>> +++ b/drivers/mtd/spi-nor/atmel.c
>> @@ -48,15 +48,11 @@ static const struct spi_nor_locking_ops 
>> atmel_at25fs_locking_ops = {
>>  	.is_locked = atmel_at25fs_is_locked,
>>  };
>> 
>> -static void atmel_at25fs_default_init(struct spi_nor *nor)
>> +static void atmel_at25fs_late_init(struct spi_nor *nor)
>>  {
>>  	nor->params->locking_ops = &atmel_at25fs_locking_ops;
>>  }
>> 
>> -static const struct spi_nor_fixups atmel_at25fs_fixups = {
>> -	.default_init = atmel_at25fs_default_init,
>> -};
>> -
>>  /**
>>   * atmel_set_global_protection - Do a Global Protect or Unprotect 
>> command
>>   * @nor:	pointer to 'struct spi_nor'
>> @@ -146,34 +142,30 @@ static const struct spi_nor_locking_ops 
>> atmel_global_protection_ops = {
>>  	.is_locked = atmel_is_global_protected,
>>  };
>> 
>> -static void atmel_global_protection_default_init(struct spi_nor *nor)
>> +static void atmel_global_protection_late_init(struct spi_nor *nor)
>>  {
>>  	nor->params->locking_ops = &atmel_global_protection_ops;
>>  }
>> 
>> -static const struct spi_nor_fixups atmel_global_protection_fixups = {
>> -	.default_init = atmel_global_protection_default_init,
>> -};
>> -
>>  static const struct flash_info atmel_parts[] = {
>>  	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
>>  	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K | 
>> SPI_NOR_HAS_LOCK)
>> -		.fixups = &atmel_at25fs_fixups },
>> +		.late_init = atmel_at25fs_late_init },
>>  	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K | 
>> SPI_NOR_HAS_LOCK)
>> -		.fixups = &atmel_at25fs_fixups },
>> +		.late_init = atmel_at25fs_late_init },
>> 
>>  	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8,
>>  			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
>> -			.fixups = &atmel_global_protection_fixups },
>> +		.late_init = atmel_global_protection_late_init },
> 
> Won't you be better off setting this in the manufacturer late_init()? 
> It
> seems common for most atmel flashes.
> 
> Of course, this would cause a problem for atmel flashes that don't have
> this at all, since we would set locking for those as well. But I think
> we can avoid that by checking for SNOR_F_HAS_LOCK in
> spi_nor_register_locking_ops().

+1

-michael


From michael at walle.cc  Thu Sep  9 14:50:33 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 09 Sep 2021 23:50:33 +0200
Subject: [PATCH v2 11/35] mtd: spi-nor: winbond: Use manufacturer
 late_init() for OTP ops
In-Reply-To: <20210816191744.k6ufbgrrwh6whhnc@ti.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-12-tudor.ambarus@microchip.com>
 <20210816191744.k6ufbgrrwh6whhnc@ti.com>
Message-ID: <a8e4b2d96b13c862e242e8009c7c6861@walle.cc>

Am 2021-08-16 21:17, schrieb Pratyush Yadav:
> On 27/07/21 07:51AM, Tudor Ambarus wrote:
>> OTP info is not yet discoverable via SFDP, use late_init() to init
>> the OTP ops.
> 
> What do you mean by the "yet"? Does it mean that OTP info is planned to
> be added to the next SFDP version? Or does it mean that it is possible
> to discover it via SFDP but we just don't support it yet?

I've seen a bit (again in the XTX SFDP) which indicates it supports
OTP. But thats all. It doesn't mention _how_ you can actually use it.
And there are at least two different variants.

-michael

> If it is neither and it just means "SFDP does not mention OTP at all",
> like it is for locking, then you should just drop the "yet". I know 
> this
> is very nitpicky but it just caught my eye.


From michael at walle.cc  Thu Sep  9 14:52:01 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 09 Sep 2021 23:52:01 +0200
Subject: [PATCH v2 10/35] mtd: spi-nor: sst: Use flash late_init() for
 locking
In-Reply-To: <20210727045222.905056-11-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-11-tudor.ambarus@microchip.com>
Message-ID: <b90644c99554a18972a3e4abcfaa8fc0@walle.cc>

Am 2021-07-27 06:51, schrieb Tudor Ambarus:
> Locking ops are not discoverable via SFDP, use late_init() call.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Michael Walle <michael at walle.cc>


From michael at walle.cc  Thu Sep  9 14:53:17 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 09 Sep 2021 23:53:17 +0200
Subject: [PATCH v2 12/35] mtd: spi-nor: xilinx: Use manufacturer
 late_init() to set setup method
In-Reply-To: <20210727045222.905056-13-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-13-tudor.ambarus@microchip.com>
Message-ID: <978db7ad9cfedb7e32503e37ece19934@walle.cc>

Am 2021-07-27 06:51, schrieb Tudor Ambarus:
> post_sfdp was misleading in this case, as SFDP is not supported by
> xilinx. Plus, there's no fixup here, just setting the correct
> setup method, as required by xilinx parts.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Michael Walle <michael at walle.cc>


From michael at walle.cc  Thu Sep  9 14:54:35 2021
From: michael at walle.cc (Michael Walle)
Date: Thu, 09 Sep 2021 23:54:35 +0200
Subject: [PATCH v2 13/35] mtd: spi-nor: sst: Use manufacturer late_init()
 to set _write()
In-Reply-To: <20210727045222.905056-14-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-14-tudor.ambarus@microchip.com>
Message-ID: <ec441127820affdeebb62493a1ab5814@walle.cc>

Am 2021-07-27 06:52, schrieb Tudor Ambarus:
> Setting the correct nor->mtd._write in a fixup hook was misleading,
> since this is not a fixup, just a specific setting for SST, that 
> differs
> from the SPI NOR core default init.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Michael Walle <michael at walle.cc>


From michael at walle.cc  Thu Sep  9 15:02:30 2021
From: michael at walle.cc (Michael Walle)
Date: Fri, 10 Sep 2021 00:02:30 +0200
Subject: [PATCH v2 14/35] mtd: spi-nor: spansion: Use manufacturer
 late_init()
In-Reply-To: <20210727045222.905056-15-tudor.ambarus@microchip.com>
References: <20210727045222.905056-1-tudor.ambarus@microchip.com>
 <20210727045222.905056-15-tudor.ambarus@microchip.com>
Message-ID: <ebfc420928ef28bb508148b41f55b0e6@walle.cc>

Am 2021-07-27 06:52, schrieb Tudor Ambarus:
> spansion_post_sfdp_fixups() was called regardless if the flash defined
> SFDP tables or not. A better place for this kind of parameters init is
> in manufacturer's late_init() hook. post_sfdp() should be called only
> when SFDP is defined. No functional change in this patch.
> 
> Instead of doing the 4b opcodes settings at manufacturer level, thus
> also for every flash that will be introduced, this should be done
> just where it is needed, per flash. I'll let this for other patch.

Mh, then why does some flashes define SPI_NOR_4B_OPCODES. It's
unclear to me when you would use SPI_NOR_4B_OPCODES and when
this individual fixup. Also right now, these SPI_NOR_4B_OPCODES
flags for the spansion flashes are superfluous, no?

-michael


From colin.king at canonical.com  Fri Sep 10 05:00:23 2021
From: colin.king at canonical.com (Colin King)
Date: Fri, 10 Sep 2021 13:00:23 +0100
Subject: [PATCH] mtd: mtdswap: Remove redundant assignment of pointer eb
Message-ID: <20210910120023.46308-1-colin.king@canonical.com>

From: Colin Ian King <colin.king at canonical.com>

The pointer eb is being assigned a value that is never read, it is
being updated later on. The assignment is redundant and can be removed.

Addresses-Coverity: ("Unused value")
Signed-off-by: Colin Ian King <colin.king at canonical.com>
---
 drivers/mtd/mtdswap.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c
index 7e309270ddd4..e86b04bc1d6b 100644
--- a/drivers/mtd/mtdswap.c
+++ b/drivers/mtd/mtdswap.c
@@ -716,7 +716,6 @@ static int mtdswap_move_block(struct mtdswap_dev *d, unsigned int oldblock,
 		return ret;
 	}
 
-	eb = d->eb_data + *newblock / d->pages_per_eblk;
 	d->page_data[page] = *newblock;
 	d->revmap[oldblock] = PAGE_UNDEF;
 	eb = d->eb_data + oldblock / d->pages_per_eblk;
-- 
2.32.0



From xiongx18 at fudan.edu.cn  Fri Sep 10 09:53:16 2021
From: xiongx18 at fudan.edu.cn (Xin Xiong)
Date: Sat, 11 Sep 2021 00:53:16 +0800
Subject: [PATCH] drivers/mtd/nand: fix reference count leaks in ebu_nand_probe
Message-ID: <20210910165316.2500-1-xiongx18@fudan.edu.cn>

The reference counting issue happens in several error handling paths
on two refcounted object related to the "ebu_host" object (dma_tx,
dma_rx). In these paths, the function forgets to balance one or both
objects' reference count. For example, when request dma tx chan fails,
the function forgets to decrease the refcount of "ebu_host->dma_rx"
increased by dma_request_chan(), causing refcount leaks. What's more,
the "ebu_host->clk" object also need to be handled correctly.

Fix this issue by keeping the return value and jumping to
"err_cleanup_dma" label.

Signed-off-by: Xin Xiong <xiongx18 at fudan.edu.cn>
Signed-off-by: Xiyu Yang <xiyuyang19 at fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf at gmail.com>
---
 drivers/mtd/nand/raw/intel-nand-controller.c | 23 ++++++++++++++------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c
index 8b49fd56c..d5148f220 100644
--- a/drivers/mtd/nand/raw/intel-nand-controller.c
+++ b/drivers/mtd/nand/raw/intel-nand-controller.c
@@ -631,19 +631,27 @@ static int ebu_nand_probe(struct platform_device *pdev)
 	ebu_host->clk_rate = clk_get_rate(ebu_host->clk);
 
 	ebu_host->dma_tx = dma_request_chan(dev, "tx");
-	if (IS_ERR(ebu_host->dma_tx))
-		return dev_err_probe(dev, PTR_ERR(ebu_host->dma_tx),
+	if (IS_ERR(ebu_host->dma_tx)) {
+		ret = dev_err_probe(dev, PTR_ERR(ebu_host->dma_tx),
 				     "failed to request DMA tx chan!.\n");
+		ebu_host->dma_tx = NULL;
+		goto err_cleanup_dma;
+	}
 
 	ebu_host->dma_rx = dma_request_chan(dev, "rx");
-	if (IS_ERR(ebu_host->dma_rx))
-		return dev_err_probe(dev, PTR_ERR(ebu_host->dma_rx),
+	if (IS_ERR(ebu_host->dma_rx)) {
+		ret = dev_err_probe(dev, PTR_ERR(ebu_host->dma_rx),
 				     "failed to request DMA rx chan!.\n");
+		ebu_host->dma_rx = NULL;
+		goto err_cleanup_dma;
+	}
 
 	resname = devm_kasprintf(dev, GFP_KERNEL, "addr_sel%d", cs);
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname);
-	if (!res)
-		return -EINVAL;
+	if (!res) {
+		ret = -EINVAL;
+		goto err_cleanup_dma;
+	}
 	ebu_host->cs[cs].addr_sel = res->start;
 	writel(ebu_host->cs[cs].addr_sel | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN,
 	       ebu_host->ebu + EBU_ADDR_SEL(cs));
@@ -653,7 +661,8 @@ static int ebu_nand_probe(struct platform_device *pdev)
 	mtd = nand_to_mtd(&ebu_host->chip);
 	if (!mtd->name) {
 		dev_err(ebu_host->dev, "NAND label property is mandatory\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_cleanup_dma;
 	}
 
 	mtd->dev.parent = dev;
-- 
2.25.1



From mauro.lima at eclypsium.com  Fri Sep 10 14:13:44 2021
From: mauro.lima at eclypsium.com (Mauro Lima)
Date: Fri, 10 Sep 2021 18:13:44 -0300
Subject: [PATCH 0/4] mtd: intel-spi: split read/write modes
Message-ID: <20210910211348.642103-1-mauro.lima@eclypsium.com>

The purpose of the following patchset is to split read/write
functionality from the Intel PCH/PCU SPI flash driver.
Being able to use the driver in read-only mode (harmless), the users
can get important firmware information from userspace which also
includes being able to perform firmware attestation to verify
integrity.

Currently fwupd is accessing to firmware information but only
with SecureBoot disabled. With this driver the fwupd project could
get such information with SecureBoot enabled.

Mauro Lima (4):
  mtd: intel-spi: rename intel-spi to intel-spi-base
  mtd: intel-spi: move chip internals into a defs.h
  mtd: intel-spi: moving write/erase functions
  mtd: intel-spi: add read only stubs

 drivers/mtd/spi-nor/controllers/Kconfig       |  50 +-
 drivers/mtd/spi-nor/controllers/Makefile      |   3 +
 .../{intel-spi.c => intel-spi-base.c}         | 442 ++----------------
 .../{intel-spi.h => intel-spi-base.h}         |   1 +
 .../mtd/spi-nor/controllers/intel-spi-defs.h  | 157 +++++++
 .../mtd/spi-nor/controllers/intel-spi-pci.c   |   2 +-
 .../spi-nor/controllers/intel-spi-platform.c  |   2 +-
 .../mtd/spi-nor/controllers/intel-spi-ro.c    |  50 ++
 .../mtd/spi-nor/controllers/intel-spi-rw.h    |  24 +
 drivers/mtd/spi-nor/controllers/intel-spi-w.c | 289 ++++++++++++
 include/linux/platform_data/x86/intel-spi.h   |   2 +
 11 files changed, 595 insertions(+), 427 deletions(-)
 rename drivers/mtd/spi-nor/controllers/{intel-spi.c => intel-spi-base.c} (54%)
 rename drivers/mtd/spi-nor/controllers/{intel-spi.h => intel-spi-base.h} (97%)
 create mode 100644 drivers/mtd/spi-nor/controllers/intel-spi-defs.h
 create mode 100644 drivers/mtd/spi-nor/controllers/intel-spi-ro.c
 create mode 100644 drivers/mtd/spi-nor/controllers/intel-spi-rw.h
 create mode 100644 drivers/mtd/spi-nor/controllers/intel-spi-w.c

-- 
2.31.1


-- 


This e-mail and any attachments may contain information that is 
privileged, confidential,  and/or exempt from disclosure under applicable 
law.  If you are not the intended recipient, you are hereby notified that 
any disclosure, copying, distribution or use of any information contained 
herein is strictly prohibited. If you have received this transmission in 
error, please immediately notify the sender and destroy the original 
transmission and any attachments, whether in electronic or hard copy 
format, without reading or saving.














From mauro.lima at eclypsium.com  Fri Sep 10 14:13:45 2021
From: mauro.lima at eclypsium.com (Mauro Lima)
Date: Fri, 10 Sep 2021 18:13:45 -0300
Subject: [PATCH 1/4] mtd: intel-spi: rename intel-spi to intel-spi-base
In-Reply-To: <20210910211348.642103-1-mauro.lima@eclypsium.com>
References: <20210910211348.642103-1-mauro.lima@eclypsium.com>
Message-ID: <20210910211348.642103-2-mauro.lima@eclypsium.com>

Rename the files we want to split as base files.
Include the new files in intel-spi-{pci|platform}.c.
Change the intel-spi obj Makefile to be built with
intel-spi-base.

Suggested-by: Daniel Gutson <daniel.gutson at eclypsium.com>
Suggested-by: Richard Hughes <richard at hughsie.com>
Signed-off-by: Mauro Lima <mauro.lima at eclypsium.com>
---
 drivers/mtd/spi-nor/controllers/Makefile                        | 1 +
 .../mtd/spi-nor/controllers/{intel-spi.c => intel-spi-base.c}   | 2 +-
 .../mtd/spi-nor/controllers/{intel-spi.h => intel-spi-base.h}   | 0
 drivers/mtd/spi-nor/controllers/intel-spi-pci.c                 | 2 +-
 drivers/mtd/spi-nor/controllers/intel-spi-platform.c            | 2 +-
 5 files changed, 4 insertions(+), 3 deletions(-)
 rename drivers/mtd/spi-nor/controllers/{intel-spi.c => intel-spi-base.c} (99%)
 rename drivers/mtd/spi-nor/controllers/{intel-spi.h => intel-spi-base.h} (100%)

diff --git a/drivers/mtd/spi-nor/controllers/Makefile b/drivers/mtd/spi-nor/controllers/Makefile
index e7abba491d98..fa2dc480d2c8 100644
--- a/drivers/mtd/spi-nor/controllers/Makefile
+++ b/drivers/mtd/spi-nor/controllers/Makefile
@@ -3,5 +3,6 @@ obj-$(CONFIG_SPI_ASPEED_SMC)	+= aspeed-smc.o
 obj-$(CONFIG_SPI_HISI_SFC)	+= hisi-sfc.o
 obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
 obj-$(CONFIG_SPI_INTEL_SPI)	+= intel-spi.o
+intel-spi-y := intel-spi-base.o
 obj-$(CONFIG_SPI_INTEL_SPI_PCI)	+= intel-spi-pci.o
 obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM)	+= intel-spi-platform.o
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.c b/drivers/mtd/spi-nor/controllers/intel-spi-base.c
similarity index 99%
rename from drivers/mtd/spi-nor/controllers/intel-spi.c
rename to drivers/mtd/spi-nor/controllers/intel-spi-base.c
index a413892ff449..362fb41b969e 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi.c
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-base.c
@@ -16,7 +16,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/spi-nor.h>
 
-#include "intel-spi.h"
+#include "intel-spi-base.h"
 
 /* Offsets are from @ispi->base */
 #define BFPREG				0x00
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.h b/drivers/mtd/spi-nor/controllers/intel-spi-base.h
similarity index 100%
rename from drivers/mtd/spi-nor/controllers/intel-spi.h
rename to drivers/mtd/spi-nor/controllers/intel-spi-base.h
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c
index 1bc53b8bb88a..46db2743e244 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c
@@ -11,7 +11,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 
-#include "intel-spi.h"
+#include "intel-spi-base.h"
 
 #define BCR		0xdc
 #define BCR_WPD		BIT(0)
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-platform.c b/drivers/mtd/spi-nor/controllers/intel-spi-platform.c
index f80f1086f928..5d6b6125c4b5 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi-platform.c
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-platform.c
@@ -10,7 +10,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include "intel-spi.h"
+#include "intel-spi-base.h"
 
 static int intel_spi_platform_probe(struct platform_device *pdev)
 {
-- 
2.31.1


-- 


This e-mail and any attachments may contain information that is 
privileged, confidential,  and/or exempt from disclosure under applicable 
law.  If you are not the intended recipient, you are hereby notified that 
any disclosure, copying, distribution or use of any information contained 
herein is strictly prohibited. If you have received this transmission in 
error, please immediately notify the sender and destroy the original 
transmission and any attachments, whether in electronic or hard copy 
format, without reading or saving.














From mauro.lima at eclypsium.com  Fri Sep 10 14:13:46 2021
From: mauro.lima at eclypsium.com (Mauro Lima)
Date: Fri, 10 Sep 2021 18:13:46 -0300
Subject: [PATCH 2/4] mtd: intel-spi: move chip internals into a defs.h
In-Reply-To: <20210910211348.642103-1-mauro.lima@eclypsium.com>
References: <20210910211348.642103-1-mauro.lima@eclypsium.com>
Message-ID: <20210910211348.642103-3-mauro.lima@eclypsium.com>

Move definitions about chip and internal spi structure to a defs
header file.
Add types.h to .../platform_data/x86/intel-spi.h so it doesn't
depends in the order of include files from intel-spi-base.
Forward declare struct device to be able to compile.

Suggested-by: Daniel Gutson <daniel.gutson at eclypsium.com>
Suggested-by: Richard Hughes <richard at hughsie.com>
Signed-off-by: Mauro Lima <mauro.lima at eclypsium.com>
---
 .../mtd/spi-nor/controllers/intel-spi-base.c  | 151 +----------------
 .../mtd/spi-nor/controllers/intel-spi-base.h  |   1 +
 .../mtd/spi-nor/controllers/intel-spi-defs.h  | 157 ++++++++++++++++++
 include/linux/platform_data/x86/intel-spi.h   |   2 +
 4 files changed, 161 insertions(+), 150 deletions(-)
 create mode 100644 drivers/mtd/spi-nor/controllers/intel-spi-defs.h

diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-base.c b/drivers/mtd/spi-nor/controllers/intel-spi-base.c
index 362fb41b969e..04ff1c381f1d 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi-base.c
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-base.c
@@ -6,157 +6,8 @@
  * Author: Mika Westerberg <mika.westerberg at linux.intel.com>
  */
 
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/iopoll.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/sizes.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/spi-nor.h>
-
 #include "intel-spi-base.h"
-
-/* Offsets are from @ispi->base */
-#define BFPREG				0x00
-
-#define HSFSTS_CTL			0x04
-#define HSFSTS_CTL_FSMIE		BIT(31)
-#define HSFSTS_CTL_FDBC_SHIFT		24
-#define HSFSTS_CTL_FDBC_MASK		(0x3f << HSFSTS_CTL_FDBC_SHIFT)
-
-#define HSFSTS_CTL_FCYCLE_SHIFT		17
-#define HSFSTS_CTL_FCYCLE_MASK		(0x0f << HSFSTS_CTL_FCYCLE_SHIFT)
-/* HW sequencer opcodes */
-#define HSFSTS_CTL_FCYCLE_READ		(0x00 << HSFSTS_CTL_FCYCLE_SHIFT)
-#define HSFSTS_CTL_FCYCLE_WRITE		(0x02 << HSFSTS_CTL_FCYCLE_SHIFT)
-#define HSFSTS_CTL_FCYCLE_ERASE		(0x03 << HSFSTS_CTL_FCYCLE_SHIFT)
-#define HSFSTS_CTL_FCYCLE_ERASE_64K	(0x04 << HSFSTS_CTL_FCYCLE_SHIFT)
-#define HSFSTS_CTL_FCYCLE_RDID		(0x06 << HSFSTS_CTL_FCYCLE_SHIFT)
-#define HSFSTS_CTL_FCYCLE_WRSR		(0x07 << HSFSTS_CTL_FCYCLE_SHIFT)
-#define HSFSTS_CTL_FCYCLE_RDSR		(0x08 << HSFSTS_CTL_FCYCLE_SHIFT)
-
-#define HSFSTS_CTL_FGO			BIT(16)
-#define HSFSTS_CTL_FLOCKDN		BIT(15)
-#define HSFSTS_CTL_FDV			BIT(14)
-#define HSFSTS_CTL_SCIP			BIT(5)
-#define HSFSTS_CTL_AEL			BIT(2)
-#define HSFSTS_CTL_FCERR		BIT(1)
-#define HSFSTS_CTL_FDONE		BIT(0)
-
-#define FADDR				0x08
-#define DLOCK				0x0c
-#define FDATA(n)			(0x10 + ((n) * 4))
-
-#define FRACC				0x50
-
-#define FREG(n)				(0x54 + ((n) * 4))
-#define FREG_BASE_MASK			0x3fff
-#define FREG_LIMIT_SHIFT		16
-#define FREG_LIMIT_MASK			(0x03fff << FREG_LIMIT_SHIFT)
-
-/* Offset is from @ispi->pregs */
-#define PR(n)				((n) * 4)
-#define PR_WPE				BIT(31)
-#define PR_LIMIT_SHIFT			16
-#define PR_LIMIT_MASK			(0x3fff << PR_LIMIT_SHIFT)
-#define PR_RPE				BIT(15)
-#define PR_BASE_MASK			0x3fff
-
-/* Offsets are from @ispi->sregs */
-#define SSFSTS_CTL			0x00
-#define SSFSTS_CTL_FSMIE		BIT(23)
-#define SSFSTS_CTL_DS			BIT(22)
-#define SSFSTS_CTL_DBC_SHIFT		16
-#define SSFSTS_CTL_SPOP			BIT(11)
-#define SSFSTS_CTL_ACS			BIT(10)
-#define SSFSTS_CTL_SCGO			BIT(9)
-#define SSFSTS_CTL_COP_SHIFT		12
-#define SSFSTS_CTL_FRS			BIT(7)
-#define SSFSTS_CTL_DOFRS		BIT(6)
-#define SSFSTS_CTL_AEL			BIT(4)
-#define SSFSTS_CTL_FCERR		BIT(3)
-#define SSFSTS_CTL_FDONE		BIT(2)
-#define SSFSTS_CTL_SCIP			BIT(0)
-
-#define PREOP_OPTYPE			0x04
-#define OPMENU0				0x08
-#define OPMENU1				0x0c
-
-#define OPTYPE_READ_NO_ADDR		0
-#define OPTYPE_WRITE_NO_ADDR		1
-#define OPTYPE_READ_WITH_ADDR		2
-#define OPTYPE_WRITE_WITH_ADDR		3
-
-/* CPU specifics */
-#define BYT_PR				0x74
-#define BYT_SSFSTS_CTL			0x90
-#define BYT_BCR				0xfc
-#define BYT_BCR_WPD			BIT(0)
-#define BYT_FREG_NUM			5
-#define BYT_PR_NUM			5
-
-#define LPT_PR				0x74
-#define LPT_SSFSTS_CTL			0x90
-#define LPT_FREG_NUM			5
-#define LPT_PR_NUM			5
-
-#define BXT_PR				0x84
-#define BXT_SSFSTS_CTL			0xa0
-#define BXT_FREG_NUM			12
-#define BXT_PR_NUM			6
-
-#define CNL_PR				0x84
-#define CNL_FREG_NUM			6
-#define CNL_PR_NUM			5
-
-#define LVSCC				0xc4
-#define UVSCC				0xc8
-#define ERASE_OPCODE_SHIFT		8
-#define ERASE_OPCODE_MASK		(0xff << ERASE_OPCODE_SHIFT)
-#define ERASE_64K_OPCODE_SHIFT		16
-#define ERASE_64K_OPCODE_MASK		(0xff << ERASE_OPCODE_SHIFT)
-
-#define INTEL_SPI_TIMEOUT		5000 /* ms */
-#define INTEL_SPI_FIFO_SZ		64
-
-/**
- * struct intel_spi - Driver private data
- * @dev: Device pointer
- * @info: Pointer to board specific info
- * @nor: SPI NOR layer structure
- * @base: Beginning of MMIO space
- * @pregs: Start of protection registers
- * @sregs: Start of software sequencer registers
- * @nregions: Maximum number of regions
- * @pr_num: Maximum number of protected range registers
- * @writeable: Is the chip writeable
- * @locked: Is SPI setting locked
- * @swseq_reg: Use SW sequencer in register reads/writes
- * @swseq_erase: Use SW sequencer in erase operation
- * @erase_64k: 64k erase supported
- * @atomic_preopcode: Holds preopcode when atomic sequence is requested
- * @opcodes: Opcodes which are supported. This are programmed by BIOS
- *           before it locks down the controller.
- */
-struct intel_spi {
-	struct device *dev;
-	const struct intel_spi_boardinfo *info;
-	struct spi_nor nor;
-	void __iomem *base;
-	void __iomem *pregs;
-	void __iomem *sregs;
-	size_t nregions;
-	size_t pr_num;
-	bool writeable;
-	bool locked;
-	bool swseq_reg;
-	bool swseq_erase;
-	bool erase_64k;
-	u8 atomic_preopcode;
-	u8 opcodes[8];
-};
+#include "intel-spi-defs.h"
 
 static bool writeable;
 module_param(writeable, bool, 0);
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-base.h b/drivers/mtd/spi-nor/controllers/intel-spi-base.h
index f2871179fd34..ac01c0756888 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi-base.h
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-base.h
@@ -11,6 +11,7 @@
 
 #include <linux/platform_data/x86/intel-spi.h>
 
+struct device;
 struct intel_spi;
 struct resource;
 
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-defs.h b/drivers/mtd/spi-nor/controllers/intel-spi-defs.h
new file mode 100644
index 000000000000..89da3f38fdbe
--- /dev/null
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-defs.h
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Intel PCH/PCU SPI flash driver.
+ *
+ * Copyright (C) 2016, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/sizes.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/spi-nor.h>
+
+/* Offsets are from @ispi->base */
+#define BFPREG				0x00
+
+#define HSFSTS_CTL			0x04
+#define HSFSTS_CTL_FSMIE		BIT(31)
+#define HSFSTS_CTL_FDBC_SHIFT		24
+#define HSFSTS_CTL_FDBC_MASK		(0x3f << HSFSTS_CTL_FDBC_SHIFT)
+
+#define HSFSTS_CTL_FCYCLE_SHIFT		17
+#define HSFSTS_CTL_FCYCLE_MASK		(0x0f << HSFSTS_CTL_FCYCLE_SHIFT)
+/* HW sequencer opcodes */
+#define HSFSTS_CTL_FCYCLE_READ		(0x00 << HSFSTS_CTL_FCYCLE_SHIFT)
+#define HSFSTS_CTL_FCYCLE_WRITE		(0x02 << HSFSTS_CTL_FCYCLE_SHIFT)
+#define HSFSTS_CTL_FCYCLE_ERASE		(0x03 << HSFSTS_CTL_FCYCLE_SHIFT)
+#define HSFSTS_CTL_FCYCLE_ERASE_64K	(0x04 << HSFSTS_CTL_FCYCLE_SHIFT)
+#define HSFSTS_CTL_FCYCLE_RDID		(0x06 << HSFSTS_CTL_FCYCLE_SHIFT)
+#define HSFSTS_CTL_FCYCLE_WRSR		(0x07 << HSFSTS_CTL_FCYCLE_SHIFT)
+#define HSFSTS_CTL_FCYCLE_RDSR		(0x08 << HSFSTS_CTL_FCYCLE_SHIFT)
+
+#define HSFSTS_CTL_FGO			BIT(16)
+#define HSFSTS_CTL_FLOCKDN		BIT(15)
+#define HSFSTS_CTL_FDV			BIT(14)
+#define HSFSTS_CTL_SCIP			BIT(5)
+#define HSFSTS_CTL_AEL			BIT(2)
+#define HSFSTS_CTL_FCERR		BIT(1)
+#define HSFSTS_CTL_FDONE		BIT(0)
+
+#define FADDR				0x08
+#define DLOCK				0x0c
+#define FDATA(n)			(0x10 + ((n) * 4))
+
+#define FRACC				0x50
+
+#define FREG(n)				(0x54 + ((n) * 4))
+#define FREG_BASE_MASK			0x3fff
+#define FREG_LIMIT_SHIFT		16
+#define FREG_LIMIT_MASK			(0x03fff << FREG_LIMIT_SHIFT)
+
+/* Offset is from @ispi->pregs */
+#define PR(n)				((n) * 4)
+#define PR_WPE				BIT(31)
+#define PR_LIMIT_SHIFT			16
+#define PR_LIMIT_MASK			(0x3fff << PR_LIMIT_SHIFT)
+#define PR_RPE				BIT(15)
+#define PR_BASE_MASK			0x3fff
+
+/* Offsets are from @ispi->sregs */
+#define SSFSTS_CTL			0x00
+#define SSFSTS_CTL_FSMIE		BIT(23)
+#define SSFSTS_CTL_DS			BIT(22)
+#define SSFSTS_CTL_DBC_SHIFT		16
+#define SSFSTS_CTL_SPOP			BIT(11)
+#define SSFSTS_CTL_ACS			BIT(10)
+#define SSFSTS_CTL_SCGO			BIT(9)
+#define SSFSTS_CTL_COP_SHIFT		12
+#define SSFSTS_CTL_FRS			BIT(7)
+#define SSFSTS_CTL_DOFRS		BIT(6)
+#define SSFSTS_CTL_AEL			BIT(4)
+#define SSFSTS_CTL_FCERR		BIT(3)
+#define SSFSTS_CTL_FDONE		BIT(2)
+#define SSFSTS_CTL_SCIP			BIT(0)
+
+#define PREOP_OPTYPE			0x04
+#define OPMENU0				0x08
+#define OPMENU1				0x0c
+
+#define OPTYPE_READ_NO_ADDR		0
+#define OPTYPE_WRITE_NO_ADDR		1
+#define OPTYPE_READ_WITH_ADDR		2
+#define OPTYPE_WRITE_WITH_ADDR		3
+
+/* CPU specifics */
+#define BYT_PR				0x74
+#define BYT_SSFSTS_CTL			0x90
+#define BYT_BCR				0xfc
+#define BYT_BCR_WPD			BIT(0)
+#define BYT_FREG_NUM			5
+#define BYT_PR_NUM			5
+
+#define LPT_PR				0x74
+#define LPT_SSFSTS_CTL			0x90
+#define LPT_FREG_NUM			5
+#define LPT_PR_NUM			5
+
+#define BXT_PR				0x84
+#define BXT_SSFSTS_CTL			0xa0
+#define BXT_FREG_NUM			12
+#define BXT_PR_NUM			6
+
+#define CNL_PR				0x84
+#define CNL_FREG_NUM			6
+#define CNL_PR_NUM			5
+
+#define LVSCC				0xc4
+#define UVSCC				0xc8
+#define ERASE_OPCODE_SHIFT		8
+#define ERASE_OPCODE_MASK		(0xff << ERASE_OPCODE_SHIFT)
+#define ERASE_64K_OPCODE_SHIFT		16
+#define ERASE_64K_OPCODE_MASK		(0xff << ERASE_OPCODE_SHIFT)
+
+#define INTEL_SPI_TIMEOUT		5000 /* ms */
+#define INTEL_SPI_FIFO_SZ		64
+
+/**
+ * struct intel_spi - Driver private data
+ * @dev: Device pointer
+ * @info: Pointer to board specific info
+ * @nor: SPI NOR layer structure
+ * @base: Beginning of MMIO space
+ * @pregs: Start of protection registers
+ * @sregs: Start of software sequencer registers
+ * @nregions: Maximum number of regions
+ * @pr_num: Maximum number of protected range registers
+ * @writeable: Is the chip writeable
+ * @locked: Is SPI setting locked
+ * @swseq_reg: Use SW sequencer in register reads/writes
+ * @swseq_erase: Use SW sequencer in erase operation
+ * @erase_64k: 64k erase supported
+ * @atomic_preopcode: Holds preopcode when atomic sequence is requested
+ * @opcodes: Opcodes which are supported. This are programmed by BIOS
+ *           before it locks down the controller.
+ */
+struct intel_spi {
+	struct device *dev;
+	const struct intel_spi_boardinfo *info;
+	struct spi_nor nor;
+	void __iomem *base;
+	void __iomem *pregs;
+	void __iomem *sregs;
+	size_t nregions;
+	size_t pr_num;
+	bool writeable;
+	bool locked;
+	bool swseq_reg;
+	bool swseq_erase;
+	bool erase_64k;
+	u8 atomic_preopcode;
+	u8 opcodes[8];
+};
diff --git a/include/linux/platform_data/x86/intel-spi.h b/include/linux/platform_data/x86/intel-spi.h
index 7f53a5c6f35e..4092a104f266 100644
--- a/include/linux/platform_data/x86/intel-spi.h
+++ b/include/linux/platform_data/x86/intel-spi.h
@@ -9,6 +9,8 @@
 #ifndef INTEL_SPI_PDATA_H
 #define INTEL_SPI_PDATA_H
 
+#include <linux/types.h>
+
 enum intel_spi_type {
 	INTEL_SPI_BYT = 1,
 	INTEL_SPI_LPT,
-- 
2.31.1


-- 


This e-mail and any attachments may contain information that is 
privileged, confidential,  and/or exempt from disclosure under applicable 
law.  If you are not the intended recipient, you are hereby notified that 
any disclosure, copying, distribution or use of any information contained 
herein is strictly prohibited. If you have received this transmission in 
error, please immediately notify the sender and destroy the original 
transmission and any attachments, whether in electronic or hard copy 
format, without reading or saving.














From mauro.lima at eclypsium.com  Fri Sep 10 14:13:47 2021
From: mauro.lima at eclypsium.com (Mauro Lima)
Date: Fri, 10 Sep 2021 18:13:47 -0300
Subject: [PATCH 3/4] mtd: intel-spi: moving write/erase functions
In-Reply-To: <20210910211348.642103-1-mauro.lima@eclypsium.com>
References: <20210910211348.642103-1-mauro.lima@eclypsium.com>
Message-ID: <20210910211348.642103-4-mauro.lima@eclypsium.com>

Split the write/erase behavior. In order to avoid code duplication,
we are going to move all the write/erase functionality to a new
file 'intel-spi-w.c' and left the base file as a common place for
both write and read only ops.
Change the make of intel-spi so we don't have to export
all the symbols used between 'intel-spi-w' and 'intel-spi-base'.
Add MODULE_LICENSE() to be able to compile as M.
Remove the module param flag, this will be set through menuconfig.

This is the new include diagram:

                    +--------------------+
                    |/include/intel-spi.h|
                    +--------^-----------+
                             |
                             |                  intel-spi-defs.h
                             |                         ^
                             |                         |
{pci|platform} -----> intel-spi-base.h          intel-spi-rw.h
                              ^                 ^       ^
                              |       +---------+       |
                              |       |                 |
                              |       |                 |
                              |       |                 |
                        intel-spi-base.c         intel-spi-w.c

Suggested-by: Daniel Gutson <daniel.gutson at eclypsium.com>
Suggested-by: Richard Hughes <richard at hughsie.com>
Signed-off-by: Mauro Lima <mauro.lima at eclypsium.com>
---
 drivers/mtd/spi-nor/controllers/Makefile      |   2 +-
 .../mtd/spi-nor/controllers/intel-spi-base.c  | 291 ++----------------
 .../mtd/spi-nor/controllers/intel-spi-rw.h    |  23 ++
 drivers/mtd/spi-nor/controllers/intel-spi-w.c | 289 +++++++++++++++++
 4 files changed, 345 insertions(+), 260 deletions(-)
 create mode 100644 drivers/mtd/spi-nor/controllers/intel-spi-rw.h
 create mode 100644 drivers/mtd/spi-nor/controllers/intel-spi-w.c

diff --git a/drivers/mtd/spi-nor/controllers/Makefile b/drivers/mtd/spi-nor/controllers/Makefile
index fa2dc480d2c8..1933a7c2c30b 100644
--- a/drivers/mtd/spi-nor/controllers/Makefile
+++ b/drivers/mtd/spi-nor/controllers/Makefile
@@ -3,6 +3,6 @@ obj-$(CONFIG_SPI_ASPEED_SMC)	+= aspeed-smc.o
 obj-$(CONFIG_SPI_HISI_SFC)	+= hisi-sfc.o
 obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
 obj-$(CONFIG_SPI_INTEL_SPI)	+= intel-spi.o
-intel-spi-y := intel-spi-base.o
+intel-spi-y := intel-spi-base.o intel-spi-w.o
 obj-$(CONFIG_SPI_INTEL_SPI_PCI)	+= intel-spi-pci.o
 obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM)	+= intel-spi-platform.o
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-base.c b/drivers/mtd/spi-nor/controllers/intel-spi-base.c
index 04ff1c381f1d..7cb5109ad0d4 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi-base.c
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-base.c
@@ -7,11 +7,8 @@
  */
 
 #include "intel-spi-base.h"
-#include "intel-spi-defs.h"
 
-static bool writeable;
-module_param(writeable, bool, 0);
-MODULE_PARM_DESC(writeable, "Enable write access to SPI flash chip (default=0)");
+#include "intel-spi-rw.h"
 
 static void intel_spi_dump_regs(struct intel_spi *ispi)
 {
@@ -116,28 +113,7 @@ static int intel_spi_read_block(struct intel_spi *ispi, void *buf, size_t size)
 	return 0;
 }
 
-/* Writes max INTEL_SPI_FIFO_SZ bytes to the device fifo */
-static int intel_spi_write_block(struct intel_spi *ispi, const void *buf,
-				 size_t size)
-{
-	size_t bytes;
-	int i = 0;
-
-	if (size > INTEL_SPI_FIFO_SZ)
-		return -EINVAL;
-
-	while (size > 0) {
-		bytes = min_t(size_t, size, 4);
-		memcpy_toio(ispi->base + FDATA(i), buf, bytes);
-		size -= bytes;
-		buf += bytes;
-		i++;
-	}
-
-	return 0;
-}
-
-static int intel_spi_wait_hw_busy(struct intel_spi *ispi)
+int intel_spi_wait_hw_busy(struct intel_spi *ispi)
 {
 	u32 val;
 
@@ -157,8 +133,8 @@ static int intel_spi_wait_sw_busy(struct intel_spi *ispi)
 
 static int intel_spi_init(struct intel_spi *ispi)
 {
-	u32 opmenu0, opmenu1, lvscc, uvscc, val;
-	int i;
+	u32 opmenu0, opmenu1, val;
+	int i, ret;
 
 	switch (ispi->info->type) {
 	case INTEL_SPI_BYT:
@@ -168,17 +144,7 @@ static int intel_spi_init(struct intel_spi *ispi)
 		ispi->pr_num = BYT_PR_NUM;
 		ispi->swseq_reg = true;
 
-		if (writeable) {
-			/* Disable write protection */
-			val = readl(ispi->base + BYT_BCR);
-			if (!(val & BYT_BCR_WPD)) {
-				val |= BYT_BCR_WPD;
-				writel(val, ispi->base + BYT_BCR);
-				val = readl(ispi->base + BYT_BCR);
-			}
-
-			ispi->writeable = !!(val & BYT_BCR_WPD);
-		}
+		__intel_byt_rw_config(ispi);
 
 		break;
 
@@ -195,7 +161,9 @@ static int intel_spi_init(struct intel_spi *ispi)
 		ispi->pregs = ispi->base + BXT_PR;
 		ispi->nregions = BXT_FREG_NUM;
 		ispi->pr_num = BXT_PR_NUM;
-		ispi->erase_64k = true;
+
+		__intel_bxt_rw_config(ispi);
+
 		break;
 
 	case INTEL_SPI_CNL:
@@ -214,28 +182,9 @@ static int intel_spi_init(struct intel_spi *ispi)
 	val &= ~HSFSTS_CTL_FSMIE;
 	writel(val, ispi->base + HSFSTS_CTL);
 
-	/*
-	 * Determine whether erase operation should use HW or SW sequencer.
-	 *
-	 * The HW sequencer has a predefined list of opcodes, with only the
-	 * erase opcode being programmable in LVSCC and UVSCC registers.
-	 * If these registers don't contain a valid erase opcode, erase
-	 * cannot be done using HW sequencer.
-	 */
-	lvscc = readl(ispi->base + LVSCC);
-	uvscc = readl(ispi->base + UVSCC);
-	if (!(lvscc & ERASE_OPCODE_MASK) || !(uvscc & ERASE_OPCODE_MASK))
-		ispi->swseq_erase = true;
-	/* SPI controller on Intel BXT supports 64K erase opcode */
-	if (ispi->info->type == INTEL_SPI_BXT && !ispi->swseq_erase)
-		if (!(lvscc & ERASE_64K_OPCODE_MASK) ||
-		    !(uvscc & ERASE_64K_OPCODE_MASK))
-			ispi->erase_64k = false;
-
-	if (ispi->sregs == NULL && (ispi->swseq_reg || ispi->swseq_erase)) {
-		dev_err(ispi->dev, "software sequencer not supported, but required\n");
-		return -EINVAL;
-	}
+	ret = __configure_lvscc_uvscc(ispi);
+	if (ret < 0)
+		return ret;
 
 	/*
 	 * Some controllers can only do basic operations using hardware
@@ -296,7 +245,7 @@ static int intel_spi_opcode_index(struct intel_spi *ispi, u8 opcode, int optype)
 	return 0;
 }
 
-static int intel_spi_hw_cycle(struct intel_spi *ispi, u8 opcode, size_t len)
+int intel_spi_hw_cycle(struct intel_spi *ispi, u8 opcode, size_t len)
 {
 	u32 val, status;
 	int ret;
@@ -309,7 +258,10 @@ static int intel_spi_hw_cycle(struct intel_spi *ispi, u8 opcode, size_t len)
 		val |= HSFSTS_CTL_FCYCLE_RDID;
 		break;
 	case SPINOR_OP_WRSR:
-		val |= HSFSTS_CTL_FCYCLE_WRSR;
+		if (is_write_enabled())
+			val |= HSFSTS_CTL_FCYCLE_WRSR;
+		else
+			return -EINVAL;
 		break;
 	case SPINOR_OP_RDSR:
 		val |= HSFSTS_CTL_FCYCLE_RDSR;
@@ -339,8 +291,8 @@ static int intel_spi_hw_cycle(struct intel_spi *ispi, u8 opcode, size_t len)
 	return 0;
 }
 
-static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len,
-			      int optype)
+int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len,
+		       int optype)
 {
 	u32 val = 0, status;
 	u8 atomic_preopcode;
@@ -367,29 +319,12 @@ static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len,
 	val |= SSFSTS_CTL_FCERR | SSFSTS_CTL_FDONE;
 	val |= SSFSTS_CTL_SCGO;
 	if (atomic_preopcode) {
-		u16 preop;
-
-		switch (optype) {
-		case OPTYPE_WRITE_NO_ADDR:
-		case OPTYPE_WRITE_WITH_ADDR:
-			/* Pick matching preopcode for the atomic sequence */
-			preop = readw(ispi->sregs + PREOP_OPTYPE);
-			if ((preop & 0xff) == atomic_preopcode)
-				; /* Do nothing */
-			else if ((preop >> 8) == atomic_preopcode)
-				val |= SSFSTS_CTL_SPOP;
-			else
-				return -EINVAL;
-
-			/* Enable atomic sequence */
-			val |= SSFSTS_CTL_ACS;
-			break;
-
-		default:
-			return -EINVAL;
-		}
-
+		ret = __intel_sw_cycle_write(ispi, optype, atomic_preopcode);
+		if (ret < 0)
+			return ret;
+		val |= ret;
 	}
+
 	writel(val, ispi->sregs + SSFSTS_CTL);
 
 	ret = intel_spi_wait_sw_busy(ispi);
@@ -429,59 +364,7 @@ static int intel_spi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
 static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
 			       size_t len)
 {
-	struct intel_spi *ispi = nor->priv;
-	int ret;
-
-	/*
-	 * This is handled with atomic operation and preop code in Intel
-	 * controller so we only verify that it is available. If the
-	 * controller is not locked, program the opcode to the PREOP
-	 * register for later use.
-	 *
-	 * When hardware sequencer is used there is no need to program
-	 * any opcodes (it handles them automatically as part of a command).
-	 */
-	if (opcode == SPINOR_OP_WREN) {
-		u16 preop;
-
-		if (!ispi->swseq_reg)
-			return 0;
-
-		preop = readw(ispi->sregs + PREOP_OPTYPE);
-		if ((preop & 0xff) != opcode && (preop >> 8) != opcode) {
-			if (ispi->locked)
-				return -EINVAL;
-			writel(opcode, ispi->sregs + PREOP_OPTYPE);
-		}
-
-		/*
-		 * This enables atomic sequence on next SW sycle. Will
-		 * be cleared after next operation.
-		 */
-		ispi->atomic_preopcode = opcode;
-		return 0;
-	}
-
-	/*
-	 * We hope that HW sequencer will do the right thing automatically and
-	 * with the SW sequencer we cannot use preopcode anyway, so just ignore
-	 * the Write Disable operation and pretend it was completed
-	 * successfully.
-	 */
-	if (opcode == SPINOR_OP_WRDI)
-		return 0;
-
-	writel(0, ispi->base + FADDR);
-
-	/* Write the value beforehand */
-	ret = intel_spi_write_block(ispi, buf, len);
-	if (ret)
-		return ret;
-
-	if (ispi->swseq_reg)
-		return intel_spi_sw_cycle(ispi, opcode, len,
-					  OPTYPE_WRITE_NO_ADDR);
-	return intel_spi_hw_cycle(ispi, opcode, len);
+	return __intel_spi_write_reg(nor, opcode, buf, len);
 }
 
 static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len,
@@ -558,126 +441,12 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len,
 static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len,
 			       const u_char *write_buf)
 {
-	struct intel_spi *ispi = nor->priv;
-	size_t block_size, retlen = 0;
-	u32 val, status;
-	ssize_t ret;
-
-	/* Not needed with HW sequencer write, make sure it is cleared */
-	ispi->atomic_preopcode = 0;
-
-	while (len > 0) {
-		block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
-
-		/* Write cannot cross 4K boundary */
-		block_size = min_t(loff_t, to + block_size,
-				   round_up(to + 1, SZ_4K)) - to;
-
-		writel(to, ispi->base + FADDR);
-
-		val = readl(ispi->base + HSFSTS_CTL);
-		val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK);
-		val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE;
-		val |= (block_size - 1) << HSFSTS_CTL_FDBC_SHIFT;
-		val |= HSFSTS_CTL_FCYCLE_WRITE;
-
-		ret = intel_spi_write_block(ispi, write_buf, block_size);
-		if (ret) {
-			dev_err(ispi->dev, "failed to write block\n");
-			return ret;
-		}
-
-		/* Start the write now */
-		val |= HSFSTS_CTL_FGO;
-		writel(val, ispi->base + HSFSTS_CTL);
-
-		ret = intel_spi_wait_hw_busy(ispi);
-		if (ret) {
-			dev_err(ispi->dev, "timeout\n");
-			return ret;
-		}
-
-		status = readl(ispi->base + HSFSTS_CTL);
-		if (status & HSFSTS_CTL_FCERR)
-			ret = -EIO;
-		else if (status & HSFSTS_CTL_AEL)
-			ret = -EACCES;
-
-		if (ret < 0) {
-			dev_err(ispi->dev, "write error: %llx: %#x\n", to,
-				status);
-			return ret;
-		}
-
-		len -= block_size;
-		to += block_size;
-		retlen += block_size;
-		write_buf += block_size;
-	}
-
-	return retlen;
+	return __intel_spi_write(nor, to, len, write_buf);
 }
 
 static int intel_spi_erase(struct spi_nor *nor, loff_t offs)
 {
-	size_t erase_size, len = nor->mtd.erasesize;
-	struct intel_spi *ispi = nor->priv;
-	u32 val, status, cmd;
-	int ret;
-
-	/* If the hardware can do 64k erase use that when possible */
-	if (len >= SZ_64K && ispi->erase_64k) {
-		cmd = HSFSTS_CTL_FCYCLE_ERASE_64K;
-		erase_size = SZ_64K;
-	} else {
-		cmd = HSFSTS_CTL_FCYCLE_ERASE;
-		erase_size = SZ_4K;
-	}
-
-	if (ispi->swseq_erase) {
-		while (len > 0) {
-			writel(offs, ispi->base + FADDR);
-
-			ret = intel_spi_sw_cycle(ispi, nor->erase_opcode,
-						 0, OPTYPE_WRITE_WITH_ADDR);
-			if (ret)
-				return ret;
-
-			offs += erase_size;
-			len -= erase_size;
-		}
-
-		return 0;
-	}
-
-	/* Not needed with HW sequencer erase, make sure it is cleared */
-	ispi->atomic_preopcode = 0;
-
-	while (len > 0) {
-		writel(offs, ispi->base + FADDR);
-
-		val = readl(ispi->base + HSFSTS_CTL);
-		val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK);
-		val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE;
-		val |= cmd;
-		val |= HSFSTS_CTL_FGO;
-		writel(val, ispi->base + HSFSTS_CTL);
-
-		ret = intel_spi_wait_hw_busy(ispi);
-		if (ret)
-			return ret;
-
-		status = readl(ispi->base + HSFSTS_CTL);
-		if (status & HSFSTS_CTL_FCERR)
-			return -EIO;
-		else if (status & HSFSTS_CTL_AEL)
-			return -EACCES;
-
-		offs += erase_size;
-		len -= erase_size;
-	}
-
-	return 0;
+	return __intel_spi_erase(nor, offs);
 }
 
 static bool intel_spi_is_protected(const struct intel_spi *ispi,
@@ -778,7 +547,11 @@ struct intel_spi *intel_spi_probe(struct device *dev,
 
 	ispi->dev = dev;
 	ispi->info = info;
-	ispi->writeable = info->writeable;
+
+	if (is_write_enabled())
+		ispi->writeable = info->writeable;
+	else
+		ispi->writeable = false;
 
 	ret = intel_spi_init(ispi);
 	if (ret)
@@ -797,7 +570,7 @@ struct intel_spi *intel_spi_probe(struct device *dev,
 	intel_spi_fill_partition(ispi, &part);
 
 	/* Prevent writes if not explicitly enabled */
-	if (!ispi->writeable || !writeable)
+	if (!ispi->writeable || !is_write_enabled())
 		ispi->nor.mtd.flags &= ~MTD_WRITEABLE;
 
 	ret = mtd_device_register(&ispi->nor.mtd, &part, 1);
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-rw.h b/drivers/mtd/spi-nor/controllers/intel-spi-rw.h
new file mode 100644
index 000000000000..46c6461a8a7b
--- /dev/null
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-rw.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef INTEL_SPI_RW_H
+#define INTEL_SPI_RW_H
+
+#include "intel-spi-defs.h"
+
+#include <linux/platform_data/x86/intel-spi.h>
+
+int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len, int optype);
+int intel_spi_wait_hw_busy(struct intel_spi *ispi);
+int intel_spi_hw_cycle(struct intel_spi *ispi, u8 opcode, size_t len);
+
+bool is_write_enabled(void);
+int  __intel_spi_erase(struct spi_nor *nor, loff_t offs);
+ssize_t  __intel_spi_write(struct spi_nor *nor, loff_t to, size_t len, const u_char *write_buf);
+int  __intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
+			   size_t len);
+int  __configure_lvscc_uvscc(struct intel_spi *ispi);
+int  __intel_sw_cycle_write(struct intel_spi *ispi, int optype, u8 atomic_preopcode);
+void  __intel_bxt_rw_config(struct intel_spi *ispi);
+void  __intel_byt_rw_config(struct intel_spi *ispi);
+
+#endif /* INTEL_SPI_RW_H */
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-w.c b/drivers/mtd/spi-nor/controllers/intel-spi-w.c
new file mode 100644
index 000000000000..ffe940611b57
--- /dev/null
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-w.c
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "intel-spi-rw.h"
+
+bool is_write_enabled(void)
+{
+	return true;
+}
+
+/* Writes max INTEL_SPI_FIFO_SZ bytes to the device fifo */
+static int intel_spi_write_block(struct intel_spi *ispi, const void *buf,
+				 size_t size)
+{
+	size_t bytes;
+	int i = 0;
+
+	if (size > INTEL_SPI_FIFO_SZ)
+		return -EINVAL;
+
+	while (size > 0) {
+		bytes = min_t(size_t, size, 4);
+		memcpy_toio(ispi->base + FDATA(i), buf, bytes);
+		size -= bytes;
+		buf += bytes;
+		i++;
+	}
+
+	return 0;
+}
+
+int __intel_spi_erase(struct spi_nor *nor, loff_t offs)
+{
+	size_t erase_size, len = nor->mtd.erasesize;
+	struct intel_spi *ispi = nor->priv;
+	u32 val, status, cmd;
+	int ret;
+
+	/* If the hardware can do 64k erase use that when possible */
+	if (len >= SZ_64K && ispi->erase_64k) {
+		cmd = HSFSTS_CTL_FCYCLE_ERASE_64K;
+		erase_size = SZ_64K;
+	} else {
+		cmd = HSFSTS_CTL_FCYCLE_ERASE;
+		erase_size = SZ_4K;
+	}
+
+	if (ispi->swseq_erase) {
+		while (len > 0) {
+			writel(offs, ispi->base + FADDR);
+
+			ret = intel_spi_sw_cycle(ispi, nor->erase_opcode,
+						 0, OPTYPE_WRITE_WITH_ADDR);
+			if (ret)
+				return ret;
+
+			offs += erase_size;
+			len -= erase_size;
+		}
+
+		return 0;
+	}
+
+	/* Not needed with HW sequencer erase, make sure it is cleared */
+	ispi->atomic_preopcode = 0;
+
+	while (len > 0) {
+		writel(offs, ispi->base + FADDR);
+
+		val = readl(ispi->base + HSFSTS_CTL);
+		val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK);
+		val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE;
+		val |= cmd;
+		val |= HSFSTS_CTL_FGO;
+		writel(val, ispi->base + HSFSTS_CTL);
+
+		ret = intel_spi_wait_hw_busy(ispi);
+		if (ret)
+			return ret;
+
+		status = readl(ispi->base + HSFSTS_CTL);
+		if (status & HSFSTS_CTL_FCERR)
+			return -EIO;
+		else if (status & HSFSTS_CTL_AEL)
+			return -EACCES;
+
+		offs += erase_size;
+		len -= erase_size;
+	}
+
+	return 0;
+}
+
+ssize_t __intel_spi_write(struct spi_nor *nor, loff_t to, size_t len,
+			  const u_char *write_buf)
+{
+	struct intel_spi *ispi = nor->priv;
+	size_t block_size, retlen = 0;
+	u32 val, status;
+	ssize_t ret;
+
+	/* Not needed with HW sequencer write, make sure it is cleared */
+	ispi->atomic_preopcode = 0;
+
+	while (len > 0) {
+		block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
+
+		/* Write cannot cross 4K boundary */
+		block_size = min_t(loff_t, to + block_size,
+				   round_up(to + 1, SZ_4K)) - to;
+
+		writel(to, ispi->base + FADDR);
+
+		val = readl(ispi->base + HSFSTS_CTL);
+		val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK);
+		val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE;
+		val |= (block_size - 1) << HSFSTS_CTL_FDBC_SHIFT;
+		val |= HSFSTS_CTL_FCYCLE_WRITE;
+
+		ret = intel_spi_write_block(ispi, write_buf, block_size);
+		if (ret) {
+			dev_err(ispi->dev, "failed to write block\n");
+			return ret;
+		}
+
+		/* Start the write now */
+		val |= HSFSTS_CTL_FGO;
+		writel(val, ispi->base + HSFSTS_CTL);
+
+		ret = intel_spi_wait_hw_busy(ispi);
+		if (ret) {
+			dev_err(ispi->dev, "timeout\n");
+			return ret;
+		}
+
+		status = readl(ispi->base + HSFSTS_CTL);
+		if (status & HSFSTS_CTL_FCERR)
+			ret = -EIO;
+		else if (status & HSFSTS_CTL_AEL)
+			ret = -EACCES;
+
+		if (ret < 0) {
+			dev_err(ispi->dev, "write error: %llx: %#x\n", to,
+				status);
+			return ret;
+		}
+
+		len -= block_size;
+		to += block_size;
+		retlen += block_size;
+		write_buf += block_size;
+	}
+
+	return retlen;
+}
+
+int __intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf, size_t len)
+{
+	struct intel_spi *ispi = nor->priv;
+	int ret;
+
+	/*
+	 * This is handled with atomic operation and preop code in Intel
+	 * controller so we only verify that it is available. If the
+	 * controller is not locked, program the opcode to the PREOP
+	 * register for later use.
+	 *
+	 * When hardware sequencer is used there is no need to program
+	 * any opcodes (it handles them automatically as part of a command).
+	 */
+	if (opcode == SPINOR_OP_WREN) {
+		u16 preop;
+
+		if (!ispi->swseq_reg)
+			return 0;
+
+		preop = readw(ispi->sregs + PREOP_OPTYPE);
+		if ((preop & 0xff) != opcode && (preop >> 8) != opcode) {
+			if (ispi->locked)
+				return -EINVAL;
+			writel(opcode, ispi->sregs + PREOP_OPTYPE);
+		}
+
+		/*
+		 * This enables atomic sequence on next SW sycle. Will
+		 * be cleared after next operation.
+		 */
+		ispi->atomic_preopcode = opcode;
+		return 0;
+	}
+
+	/*
+	 * We hope that HW sequencer will do the right thing automatically and
+	 * with the SW sequencer we cannot use preopcode anyway, so just ignore
+	 * the Write Disable operation and pretend it was completed
+	 * successfully.
+	 */
+	if (opcode == SPINOR_OP_WRDI)
+		return 0;
+
+	writel(0, ispi->base + FADDR);
+
+	/* Write the value beforehand */
+	ret = intel_spi_write_block(ispi, buf, len);
+	if (ret)
+		return ret;
+
+	if (ispi->swseq_reg)
+		return intel_spi_sw_cycle(ispi, opcode, len,
+					  OPTYPE_WRITE_NO_ADDR);
+	return intel_spi_hw_cycle(ispi, opcode, len);
+}
+
+int __configure_lvscc_uvscc(struct intel_spi *ispi)
+{
+	u32 lvscc, uvscc;
+	/*
+	 * Determine whether erase operation should use HW or SW sequencer.
+	 *
+	 * The HW sequencer has a predefined list of opcodes, with only the
+	 * erase opcode being programmable in LVSCC and UVSCC registers.
+	 * If these registers don't contain a valid erase opcode, erase
+	 * cannot be done using HW sequencer.
+	 */
+	lvscc = readl(ispi->base + LVSCC);
+	uvscc = readl(ispi->base + UVSCC);
+	if (!(lvscc & ERASE_OPCODE_MASK) || !(uvscc & ERASE_OPCODE_MASK))
+		ispi->swseq_erase = true;
+	/* SPI controller on Intel BXT supports 64K erase opcode */
+	if (ispi->info->type == INTEL_SPI_BXT && !ispi->swseq_erase)
+		if (!(lvscc & ERASE_64K_OPCODE_MASK) ||
+		    !(uvscc & ERASE_64K_OPCODE_MASK))
+			ispi->erase_64k = false;
+
+	if (ispi->sregs == NULL && (ispi->swseq_reg || ispi->swseq_erase)) {
+		dev_err(ispi->dev, "software sequencer not supported, but required\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int __intel_sw_cycle_write(struct intel_spi *ispi, int optype, u8 atomic_preopcode)
+{
+	u32 val = 0;
+	u16 preop;
+
+	switch (optype) {
+	case OPTYPE_WRITE_NO_ADDR:
+	case OPTYPE_WRITE_WITH_ADDR:
+		/* Pick matching preopcode for the atomic sequence */
+		preop = readw(ispi->sregs + PREOP_OPTYPE);
+		if ((preop & 0xff) == atomic_preopcode)
+			; /* Do nothing */
+		else if ((preop >> 8) == atomic_preopcode)
+			val |= SSFSTS_CTL_SPOP;
+		else
+			return -EINVAL;
+
+		/* Enable atomic sequence */
+		val |= SSFSTS_CTL_ACS;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return val;
+}
+
+void __intel_byt_rw_config(struct intel_spi *ispi)
+{
+	u32 val;
+
+	/* Disable write protection */
+	val = readl(ispi->base + BYT_BCR);
+	if (!(val & BYT_BCR_WPD)) {
+		val |= BYT_BCR_WPD;
+		writel(val, ispi->base + BYT_BCR);
+		val = readl(ispi->base + BYT_BCR);
+	}
+
+	ispi->writeable = !!(val & BYT_BCR_WPD);
+}
+
+void __intel_bxt_rw_config(struct intel_spi *ispi)
+{
+	ispi->erase_64k = true;
+}
+MODULE_LICENSE("GPL v2");
-- 
2.31.1


-- 


This e-mail and any attachments may contain information that is 
privileged, confidential,  and/or exempt from disclosure under applicable 
law.  If you are not the intended recipient, you are hereby notified that 
any disclosure, copying, distribution or use of any information contained 
herein is strictly prohibited. If you have received this transmission in 
error, please immediately notify the sender and destroy the original 
transmission and any attachments, whether in electronic or hard copy 
format, without reading or saving.














From mauro.lima at eclypsium.com  Fri Sep 10 14:13:48 2021
From: mauro.lima at eclypsium.com (Mauro Lima)
Date: Fri, 10 Sep 2021 18:13:48 -0300
Subject: [PATCH 4/4] mtd: intel-spi: add read only stubs
In-Reply-To: <20210910211348.642103-1-mauro.lima@eclypsium.com>
References: <20210910211348.642103-1-mauro.lima@eclypsium.com>
Message-ID: <20210910211348.642103-5-mauro.lima@eclypsium.com>

Add read only stub functions (as __weak) in read only mode,
so they can be override on read-write mode.
Remove the (DANGEROUS) tag in read only mode.
Add write mode option if pci or platform driver is selected.
Change the intel-spi recepie to be able to build read only
or read-write mode.

Suggested-by: Daniel Gutson <daniel.gutson at eclypsium.com>
Suggested-by: Richard Hughes <richard at hughsie.com>
Signed-off-by: Mauro Lima <mauro.lima at eclypsium.com>
---
 drivers/mtd/spi-nor/controllers/Kconfig       | 50 +++++++++++++------
 drivers/mtd/spi-nor/controllers/Makefile      |  4 +-
 .../mtd/spi-nor/controllers/intel-spi-ro.c    | 50 +++++++++++++++++++
 .../mtd/spi-nor/controllers/intel-spi-rw.h    |  1 +
 4 files changed, 88 insertions(+), 17 deletions(-)
 create mode 100644 drivers/mtd/spi-nor/controllers/intel-spi-ro.c

diff --git a/drivers/mtd/spi-nor/controllers/Kconfig b/drivers/mtd/spi-nor/controllers/Kconfig
index 5c0e0ec2e6d1..c4f2505c9302 100644
--- a/drivers/mtd/spi-nor/controllers/Kconfig
+++ b/drivers/mtd/spi-nor/controllers/Kconfig
@@ -30,35 +30,53 @@ config SPI_NXP_SPIFI
 config SPI_INTEL_SPI
 	tristate
 
+config SPI_INTEL_SPI_RO
+	bool
+	default y if !SPI_INTEL_SPI_W
+	select SPI_INTEL_SPI
+
 config SPI_INTEL_SPI_PCI
-	tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)"
+	tristate
+
+config SPI_INTEL_SPI_PLATFORM
+	tristate
+
+config SPI_INTEL_SPI_PCI_RO
+	tristate "Intel PCH/PCU SPI flash PCI driver"
 	depends on X86 && PCI
-	select SPI_INTEL_SPI
+	select SPI_INTEL_SPI_RO
+	select SPI_INTEL_SPI_PCI
 	help
 	  This enables PCI support for the Intel PCH/PCU SPI controller in
-	  master mode. This controller is present in modern Intel hardware
-	  and is used to hold BIOS and other persistent settings. Using
-	  this driver it is possible to upgrade BIOS directly from Linux.
-
-	  Say N here unless you know what you are doing. Overwriting the
-	  SPI flash may render the system unbootable.
+	  read only mode. This controller is present in modern Intel
+	  hardware and is used to hold BIOS and other persistent settings.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called intel-spi-pci.
 
-config SPI_INTEL_SPI_PLATFORM
-	tristate "Intel PCH/PCU SPI flash platform driver (DANGEROUS)"
+config SPI_INTEL_SPI_PLATFORM_RO
+	tristate "Intel PCH/PCU SPI flash platform driver"
 	depends on X86
+	select SPI_INTEL_SPI_RO
+	select SPI_INTEL_SPI_PLATFORM
+	help
+	  This enables PCI support for the Intel PCH/PCU SPI controller in
+	  read only mode. This controller is present in modern Intel
+	  hardware and is used to hold BIOS and other persistent settings.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called intel-spi-pci.
+
+config SPI_INTEL_SPI_W
+	bool "Enable Intel PCH/PCU SPI controller in write mode (DANGEROUS)"
 	select SPI_INTEL_SPI
+	default n if SPI_INTEL_SPI_PCI || SPI_INTEL_SPI_PLATFORM
+	depends on SPI_INTEL_SPI_PCI || SPI_INTEL_SPI_PLATFORM
 	help
-	  This enables platform support for the Intel PCH/PCU SPI
-	  controller in master mode. This controller is present in modern
-	  Intel hardware and is used to hold BIOS and other persistent
-	  settings. Using this driver it is possible to upgrade BIOS
+	  This enables {PCI|PLATFORM} support for the Intel PCH/PCU controller
+	  in master mode. Enabling this mode it is possible to upgrade BIOS
 	  directly from Linux.
 
 	  Say N here unless you know what you are doing. Overwriting the
 	  SPI flash may render the system unbootable.
 
-	  To compile this driver as a module, choose M here: the module
-	  will be called intel-spi-platform.
diff --git a/drivers/mtd/spi-nor/controllers/Makefile b/drivers/mtd/spi-nor/controllers/Makefile
index 1933a7c2c30b..a4faeace67fc 100644
--- a/drivers/mtd/spi-nor/controllers/Makefile
+++ b/drivers/mtd/spi-nor/controllers/Makefile
@@ -3,6 +3,8 @@ obj-$(CONFIG_SPI_ASPEED_SMC)	+= aspeed-smc.o
 obj-$(CONFIG_SPI_HISI_SFC)	+= hisi-sfc.o
 obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
 obj-$(CONFIG_SPI_INTEL_SPI)	+= intel-spi.o
-intel-spi-y := intel-spi-base.o intel-spi-w.o
+intel-spi-y := intel-spi-base.o
+intel-spi-$(CONFIG_SPI_INTEL_SPI_RO) += intel-spi-ro.o
+intel-spi-$(CONFIG_SPI_INTEL_SPI_W) += intel-spi-w.o
 obj-$(CONFIG_SPI_INTEL_SPI_PCI)	+= intel-spi-pci.o
 obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM)	+= intel-spi-platform.o
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-ro.c b/drivers/mtd/spi-nor/controllers/intel-spi-ro.c
new file mode 100644
index 000000000000..4c52c2bb65ef
--- /dev/null
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-ro.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "intel-spi-rw.h"
+
+bool __weak is_write_enabled(void)
+{
+	return false;
+}
+
+int __weak __intel_spi_erase(struct spi_nor *nor, loff_t offs)
+{
+	return -EINVAL;
+}
+
+ssize_t __weak __intel_spi_write(struct spi_nor *nor, loff_t to, size_t len,
+				 const u_char *write_buf)
+{
+	return -EINVAL;
+}
+
+int __weak __intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
+				 size_t len)
+{
+	return -EINVAL;
+}
+
+/* We don't need erase op */
+int __weak __configure_lvscc_uvscc(struct intel_spi *ispi)
+{
+	ispi->erase_64k = false;
+	return 0;
+}
+
+void __weak __intel_bxt_rw_config(struct intel_spi *ispi)
+{
+	(void)ispi;
+}
+
+void __weak __intel_byt_rw_config(struct intel_spi *ispi)
+{
+	(void)ispi;
+}
+
+int __weak __intel_sw_cycle_write(struct intel_spi *ispi, int optype, u8 atomic_preopcode)
+{
+	/* not supported op */
+	return -EINVAL;
+}
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-rw.h b/drivers/mtd/spi-nor/controllers/intel-spi-rw.h
index 46c6461a8a7b..b682db03f17a 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi-rw.h
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-rw.h
@@ -10,6 +10,7 @@ int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len, int optype
 int intel_spi_wait_hw_busy(struct intel_spi *ispi);
 int intel_spi_hw_cycle(struct intel_spi *ispi, u8 opcode, size_t len);
 
+void check_mode(void);
 bool is_write_enabled(void);
 int  __intel_spi_erase(struct spi_nor *nor, loff_t offs);
 ssize_t  __intel_spi_write(struct spi_nor *nor, loff_t to, size_t len, const u_char *write_buf);
-- 
2.31.1


-- 


This e-mail and any attachments may contain information that is 
privileged, confidential,  and/or exempt from disclosure under applicable 
law.  If you are not the intended recipient, you are hereby notified that 
any disclosure, copying, distribution or use of any information contained 
herein is strictly prohibited. If you have received this transmission in 
error, please immediately notify the sender and destroy the original 
transmission and any attachments, whether in electronic or hard copy 
format, without reading or saving.














From sashal at kernel.org  Sat Sep 11 06:11:18 2021
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 11 Sep 2021 09:11:18 -0400
Subject: [PATCH AUTOSEL 5.14 01/32] dt-bindings: mtd: gpmc: Fix the ECC bytes
 vs. OOB bytes equation
Message-ID: <20210911131149.284397-1-sashal@kernel.org>

From: Miquel Raynal <miquel.raynal at bootlin.com>

[ Upstream commit 778cb8e39f6ec252be50fc3850d66f3dcbd5dd5a ]

"PAGESIZE / 512" is the number of ECC chunks.
"ECC_BYTES" is the number of bytes needed to store a single ECC code.
"2" is the space reserved by the bad block marker.

"2 + (PAGESIZE / 512) * ECC_BYTES" should of course be lower or equal
than the total number of OOB bytes, otherwise it won't fit.

Fix the equation by substituting s/>=/<=/.

Suggested-by: Ryan J. Barnett <ryan.barnett at collins.com>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
Acked-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/linux-mtd/20210610143945.3504781-1-miquel.raynal at bootlin.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index 44919d48d241..c459f169a904 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -122,7 +122,7 @@ on various other factors also like;
 	so the device should have enough free bytes available its OOB/Spare
 	area to accommodate ECC for entire page. In general following expression
 	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
+	"2 + (PAGESIZE / 512) * ECC_BYTES" <= OOBSIZE"
 	where
 		OOBSIZE		number of bytes in OOB/spare area
 		PAGESIZE	number of bytes in main-area of device page
-- 
2.30.2



From sashal at kernel.org  Sat Sep 11 06:12:05 2021
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 11 Sep 2021 09:12:05 -0400
Subject: [PATCH AUTOSEL 5.13 01/29] dt-bindings: mtd: gpmc: Fix the ECC bytes
 vs. OOB bytes equation
Message-ID: <20210911131233.284800-1-sashal@kernel.org>

From: Miquel Raynal <miquel.raynal at bootlin.com>

[ Upstream commit 778cb8e39f6ec252be50fc3850d66f3dcbd5dd5a ]

"PAGESIZE / 512" is the number of ECC chunks.
"ECC_BYTES" is the number of bytes needed to store a single ECC code.
"2" is the space reserved by the bad block marker.

"2 + (PAGESIZE / 512) * ECC_BYTES" should of course be lower or equal
than the total number of OOB bytes, otherwise it won't fit.

Fix the equation by substituting s/>=/<=/.

Suggested-by: Ryan J. Barnett <ryan.barnett at collins.com>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
Acked-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/linux-mtd/20210610143945.3504781-1-miquel.raynal at bootlin.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index 44919d48d241..c459f169a904 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -122,7 +122,7 @@ on various other factors also like;
 	so the device should have enough free bytes available its OOB/Spare
 	area to accommodate ECC for entire page. In general following expression
 	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
+	"2 + (PAGESIZE / 512) * ECC_BYTES" <= OOBSIZE"
 	where
 		OOBSIZE		number of bytes in OOB/spare area
 		PAGESIZE	number of bytes in main-area of device page
-- 
2.30.2



From sashal at kernel.org  Sat Sep 11 06:12:48 2021
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 11 Sep 2021 09:12:48 -0400
Subject: [PATCH AUTOSEL 5.10 01/25] dt-bindings: mtd: gpmc: Fix the ECC bytes
 vs. OOB bytes equation
Message-ID: <20210911131312.285225-1-sashal@kernel.org>

From: Miquel Raynal <miquel.raynal at bootlin.com>

[ Upstream commit 778cb8e39f6ec252be50fc3850d66f3dcbd5dd5a ]

"PAGESIZE / 512" is the number of ECC chunks.
"ECC_BYTES" is the number of bytes needed to store a single ECC code.
"2" is the space reserved by the bad block marker.

"2 + (PAGESIZE / 512) * ECC_BYTES" should of course be lower or equal
than the total number of OOB bytes, otherwise it won't fit.

Fix the equation by substituting s/>=/<=/.

Suggested-by: Ryan J. Barnett <ryan.barnett at collins.com>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
Acked-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/linux-mtd/20210610143945.3504781-1-miquel.raynal at bootlin.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index 44919d48d241..c459f169a904 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -122,7 +122,7 @@ on various other factors also like;
 	so the device should have enough free bytes available its OOB/Spare
 	area to accommodate ECC for entire page. In general following expression
 	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
+	"2 + (PAGESIZE / 512) * ECC_BYTES" <= OOBSIZE"
 	where
 		OOBSIZE		number of bytes in OOB/spare area
 		PAGESIZE	number of bytes in main-area of device page
-- 
2.30.2



From sashal at kernel.org  Sat Sep 11 06:13:32 2021
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 11 Sep 2021 09:13:32 -0400
Subject: [PATCH AUTOSEL 5.4 01/14] dt-bindings: mtd: gpmc: Fix the ECC bytes
 vs. OOB bytes equation
Message-ID: <20210911131345.285564-1-sashal@kernel.org>

From: Miquel Raynal <miquel.raynal at bootlin.com>

[ Upstream commit 778cb8e39f6ec252be50fc3850d66f3dcbd5dd5a ]

"PAGESIZE / 512" is the number of ECC chunks.
"ECC_BYTES" is the number of bytes needed to store a single ECC code.
"2" is the space reserved by the bad block marker.

"2 + (PAGESIZE / 512) * ECC_BYTES" should of course be lower or equal
than the total number of OOB bytes, otherwise it won't fit.

Fix the equation by substituting s/>=/<=/.

Suggested-by: Ryan J. Barnett <ryan.barnett at collins.com>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
Acked-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/linux-mtd/20210610143945.3504781-1-miquel.raynal at bootlin.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index 44919d48d241..c459f169a904 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -122,7 +122,7 @@ on various other factors also like;
 	so the device should have enough free bytes available its OOB/Spare
 	area to accommodate ECC for entire page. In general following expression
 	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
+	"2 + (PAGESIZE / 512) * ECC_BYTES" <= OOBSIZE"
 	where
 		OOBSIZE		number of bytes in OOB/spare area
 		PAGESIZE	number of bytes in main-area of device page
-- 
2.30.2



From sashal at kernel.org  Sat Sep 11 06:13:58 2021
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 11 Sep 2021 09:13:58 -0400
Subject: [PATCH AUTOSEL 4.19 1/7] dt-bindings: mtd: gpmc: Fix the ECC bytes
 vs. OOB bytes equation
Message-ID: <20210911131404.286005-1-sashal@kernel.org>

From: Miquel Raynal <miquel.raynal at bootlin.com>

[ Upstream commit 778cb8e39f6ec252be50fc3850d66f3dcbd5dd5a ]

"PAGESIZE / 512" is the number of ECC chunks.
"ECC_BYTES" is the number of bytes needed to store a single ECC code.
"2" is the space reserved by the bad block marker.

"2 + (PAGESIZE / 512) * ECC_BYTES" should of course be lower or equal
than the total number of OOB bytes, otherwise it won't fit.

Fix the equation by substituting s/>=/<=/.

Suggested-by: Ryan J. Barnett <ryan.barnett at collins.com>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
Acked-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/linux-mtd/20210610143945.3504781-1-miquel.raynal at bootlin.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index c059ab74ed88..a4a75fa79524 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -122,7 +122,7 @@ on various other factors also like;
 	so the device should have enough free bytes available its OOB/Spare
 	area to accommodate ECC for entire page. In general following expression
 	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
+	"2 + (PAGESIZE / 512) * ECC_BYTES" <= OOBSIZE"
 	where
 		OOBSIZE		number of bytes in OOB/spare area
 		PAGESIZE	number of bytes in main-area of device page
-- 
2.30.2



From sashal at kernel.org  Sat Sep 11 06:14:10 2021
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 11 Sep 2021 09:14:10 -0400
Subject: [PATCH AUTOSEL 4.14 1/5] dt-bindings: mtd: gpmc: Fix the ECC bytes
 vs. OOB bytes equation
Message-ID: <20210911131415.286125-1-sashal@kernel.org>

From: Miquel Raynal <miquel.raynal at bootlin.com>

[ Upstream commit 778cb8e39f6ec252be50fc3850d66f3dcbd5dd5a ]

"PAGESIZE / 512" is the number of ECC chunks.
"ECC_BYTES" is the number of bytes needed to store a single ECC code.
"2" is the space reserved by the bad block marker.

"2 + (PAGESIZE / 512) * ECC_BYTES" should of course be lower or equal
than the total number of OOB bytes, otherwise it won't fit.

Fix the equation by substituting s/>=/<=/.

Suggested-by: Ryan J. Barnett <ryan.barnett at collins.com>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
Acked-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/linux-mtd/20210610143945.3504781-1-miquel.raynal at bootlin.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index dd559045593d..d2d1bae63a36 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -123,7 +123,7 @@ on various other factors also like;
 	so the device should have enough free bytes available its OOB/Spare
 	area to accommodate ECC for entire page. In general following expression
 	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
+	"2 + (PAGESIZE / 512) * ECC_BYTES" <= OOBSIZE"
 	where
 		OOBSIZE		number of bytes in OOB/spare area
 		PAGESIZE	number of bytes in main-area of device page
-- 
2.30.2



From sashal at kernel.org  Sat Sep 11 06:14:19 2021
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 11 Sep 2021 09:14:19 -0400
Subject: [PATCH AUTOSEL 4.9 1/4] dt-bindings: mtd: gpmc: Fix the ECC bytes vs.
 OOB bytes equation
Message-ID: <20210911131423.286235-1-sashal@kernel.org>

From: Miquel Raynal <miquel.raynal at bootlin.com>

[ Upstream commit 778cb8e39f6ec252be50fc3850d66f3dcbd5dd5a ]

"PAGESIZE / 512" is the number of ECC chunks.
"ECC_BYTES" is the number of bytes needed to store a single ECC code.
"2" is the space reserved by the bad block marker.

"2 + (PAGESIZE / 512) * ECC_BYTES" should of course be lower or equal
than the total number of OOB bytes, otherwise it won't fit.

Fix the equation by substituting s/>=/<=/.

Suggested-by: Ryan J. Barnett <ryan.barnett at collins.com>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
Acked-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/linux-mtd/20210610143945.3504781-1-miquel.raynal at bootlin.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index 174f68c26c1b..34981b98d807 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -123,7 +123,7 @@ on various other factors also like;
 	so the device should have enough free bytes available its OOB/Spare
 	area to accommodate ECC for entire page. In general following expression
 	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
+	"2 + (PAGESIZE / 512) * ECC_BYTES" <= OOBSIZE"
 	where
 		OOBSIZE		number of bytes in OOB/spare area
 		PAGESIZE	number of bytes in main-area of device page
-- 
2.30.2



From sashal at kernel.org  Sat Sep 11 06:14:28 2021
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 11 Sep 2021 09:14:28 -0400
Subject: [PATCH AUTOSEL 4.4 1/2] dt-bindings: mtd: gpmc: Fix the ECC bytes vs.
 OOB bytes equation
Message-ID: <20210911131429.286330-1-sashal@kernel.org>

From: Miquel Raynal <miquel.raynal at bootlin.com>

[ Upstream commit 778cb8e39f6ec252be50fc3850d66f3dcbd5dd5a ]

"PAGESIZE / 512" is the number of ECC chunks.
"ECC_BYTES" is the number of bytes needed to store a single ECC code.
"2" is the space reserved by the bad block marker.

"2 + (PAGESIZE / 512) * ECC_BYTES" should of course be lower or equal
than the total number of OOB bytes, otherwise it won't fit.

Fix the equation by substituting s/>=/<=/.

Suggested-by: Ryan J. Barnett <ryan.barnett at collins.com>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
Acked-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/linux-mtd/20210610143945.3504781-1-miquel.raynal at bootlin.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index fb733c4e1c11..3a58fdf0c566 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -112,7 +112,7 @@ on various other factors also like;
 	so the device should have enough free bytes available its OOB/Spare
 	area to accommodate ECC for entire page. In general following expression
 	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
+	"2 + (PAGESIZE / 512) * ECC_BYTES" <= OOBSIZE"
 	where
 		OOBSIZE		number of bytes in OOB/spare area
 		PAGESIZE	number of bytes in main-area of device page
-- 
2.30.2



From digetx at gmail.com  Sun Sep 12 13:08:00 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:00 +0300
Subject: [PATCH v11 02/34] soc/tegra: Add
 devm_tegra_core_dev_init_opp_table_common()
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-3-digetx@gmail.com>

Only couple drivers need to get the -ENODEV error code and majority of
drivers need to explicitly initialize the performance state. Add new
common helper which sets up OPP table for these drivers.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 include/soc/tegra/common.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/soc/tegra/common.h b/include/soc/tegra/common.h
index af41ad80ec21..5b4a042f60fb 100644
--- a/include/soc/tegra/common.h
+++ b/include/soc/tegra/common.h
@@ -39,4 +39,28 @@ devm_tegra_core_dev_init_opp_table(struct device *dev,
 }
 #endif
 
+/*
+ * This function should be invoked with the enabled runtime PM of the device
+ * in order to initialize performance state properly. Most of Tegra devices
+ * are assumed to be suspended at a probe time and GENPD require RPM to be
+ * enabled to set up the rpm-resume state, otherwise device is active and
+ * performance state is applied immediately. Note that it will initialize
+ * OPP bandwidth if it's wired in a device-tree for this device, which is
+ * undesirable for a suspended device.
+ */
+static inline int
+devm_tegra_core_dev_init_opp_table_common(struct device *dev)
+{
+	struct tegra_core_opp_params opp_params = {};
+	int err;
+
+	opp_params.init_state = true;
+
+	err = devm_tegra_core_dev_init_opp_table(dev, &opp_params);
+	if (err != -ENODEV)
+		return err;
+
+	return 0;
+}
+
 #endif /* __SOC_TEGRA_COMMON_H__ */
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:07:59 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:07:59 +0300
Subject: [PATCH v11 01/34] opp: Change type of dev_pm_opp_attach_genpd(names)
 argument
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-2-digetx@gmail.com>

Elements of the 'names' array are not changed by the code, constify them
for consistency.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/opp/core.c     | 6 +++---
 include/linux/pm_opp.h | 8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 04b4691a8aac..3057beabd370 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -2348,12 +2348,12 @@ static void _opp_detach_genpd(struct opp_table *opp_table)
  * "required-opps" are added in DT.
  */
 struct opp_table *dev_pm_opp_attach_genpd(struct device *dev,
-		const char **names, struct device ***virt_devs)
+		const char * const *names, struct device ***virt_devs)
 {
 	struct opp_table *opp_table;
 	struct device *virt_dev;
 	int index = 0, ret = -EINVAL;
-	const char **name = names;
+	const char * const *name = names;
 
 	opp_table = _add_opp_table(dev, false);
 	if (IS_ERR(opp_table))
@@ -2457,7 +2457,7 @@ static void devm_pm_opp_detach_genpd(void *data)
  *
  * Return: 0 on success and errorno otherwise.
  */
-int devm_pm_opp_attach_genpd(struct device *dev, const char **names,
+int devm_pm_opp_attach_genpd(struct device *dev, const char * const *names,
 			     struct device ***virt_devs)
 {
 	struct opp_table *opp_table;
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index a95d6fdd20b6..879c138c7b8e 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -156,9 +156,9 @@ int devm_pm_opp_set_clkname(struct device *dev, const char *name);
 struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
 void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table);
 int devm_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
-struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs);
+struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs);
 void dev_pm_opp_detach_genpd(struct opp_table *opp_table);
-int devm_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs);
+int devm_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs);
 struct dev_pm_opp *dev_pm_opp_xlate_required_opp(struct opp_table *src_table, struct opp_table *dst_table, struct dev_pm_opp *src_opp);
 int dev_pm_opp_xlate_performance_state(struct opp_table *src_table, struct opp_table *dst_table, unsigned int pstate);
 int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
@@ -376,7 +376,7 @@ static inline int devm_pm_opp_set_clkname(struct device *dev, const char *name)
 	return -EOPNOTSUPP;
 }
 
-static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char **names, struct device ***virt_devs)
+static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, const char * const *names, struct device ***virt_devs)
 {
 	return ERR_PTR(-EOPNOTSUPP);
 }
@@ -384,7 +384,7 @@ static inline struct opp_table *dev_pm_opp_attach_genpd(struct device *dev, cons
 static inline void dev_pm_opp_detach_genpd(struct opp_table *opp_table) {}
 
 static inline int devm_pm_opp_attach_genpd(struct device *dev,
-					   const char **names,
+					   const char * const *names,
 					   struct device ***virt_devs)
 {
 	return -EOPNOTSUPP;
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:07:58 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:07:58 +0300
Subject: [PATCH v11 00/34] NVIDIA Tegra power management patches for 5.16
Message-ID: <20210912200832.12312-1-digetx@gmail.com>

This series adds runtime PM support to Tegra drivers and enables core
voltage scaling for Tegra20/30 SoCs, resolving overheating troubles.

All patches in this series are interdependent and should go via Tegra tree.

Changelog:

v11: - Added acks and r-b from Rob Herring, Mark Brown and Miquel Raynal
       that were given to v8.

     - Corrected order of the new memory controller reset entry in
       device-trees and host1x DT binding patch, which was requested by
       Rob Herring.

     - Switched consumer drivers to use power domain state syncing done
       by new Tegra's common OPP-initialization helper.

     - Made use of new devm_pm_runtime_enable() helper that was added to
       v5.15 kernel, where appropriate.

     - Added "fuse: Use resource-managed helpers" patch.

     - Converted Tegra20/30 clk drivers to a proper platform drivers,
       which was requested by Thierry Reding.

     - Removed clk-bulk API usage from the MMC patch, which was requested
       by Thierry Reding.

     - Changed CORE power domain name to "core" in a new patch
       "Change name of core power domain".

     - Misc small fixes for problems that I found since v8, like couple
       typos in error code paths and restored working RPM for Tegra DRM
       UAPI v1 that was removed in v8 by accident.

v9-v10: Figured out remaining GENPD API changes with Ulf Hansson and
        Viresh Kumar. The OPP-sync helper that was used in v8 isn't needed
        anymore because GENPD API now allows consumer drivers to
        init rpm_pstate of power domains.

v8: - Added new generic dev_pm_opp_sync() helper that syncs OPP state with
      hardware. All drivers changed to use it. This replaces GENPD attach_dev
      callback hacks that were used in v7.

    - Added new patch patch "soc/tegra: regulators: Prepare for suspend"
      that fixes dying Tegra20 SoC after enabling VENC power domain during
      resume from suspend. It matches to what downstream kernel does on
      suspend/resume.

    - After a second thought, I dropped patches which added RPM to memory
      drivers since hardware is always-on and RPM not needed.

    - Replaced the "dummy host1x driver" patch with new "Disable unused
      host1x hardware" patch, since it's a cleaner solution.

Dmitry Osipenko (34):
  opp: Change type of dev_pm_opp_attach_genpd(names) argument
  soc/tegra: Add devm_tegra_core_dev_init_opp_table_common()
  soc/tegra: pmc: Disable PMC state syncing
  soc/tegra: Don't print error message when OPPs not available
  dt-bindings: clock: tegra-car: Document new clock sub-nodes
  clk: tegra: Support runtime PM and power domain
  dt-bindings: host1x: Document OPP and power domain properties
  dt-bindings: host1x: Document Memory Client resets of Host1x, GR2D and
    GR3D
  gpu: host1x: Add runtime PM and OPP support
  gpu: host1x: Add host1x_channel_stop()
  drm/tegra: dc: Support OPP and SoC core voltage scaling
  drm/tegra: hdmi: Add OPP support
  drm/tegra: gr2d: Support generic power domain and runtime PM
  drm/tegra: gr3d: Support generic power domain and runtime PM
  drm/tegra: vic: Support system suspend
  usb: chipidea: tegra: Add runtime PM and OPP support
  bus: tegra-gmi: Add runtime PM and OPP support
  pwm: tegra: Add runtime PM and OPP support
  mmc: sdhci-tegra: Add runtime PM and OPP support
  mtd: rawnand: tegra: Add runtime PM and OPP support
  spi: tegra20-slink: Add OPP support
  media: dt: bindings: tegra-vde: Convert to schema
  media: dt: bindings: tegra-vde: Document OPP and power domain
  media: staging: tegra-vde: Support generic power domain
  soc/tegra: fuse: Reset hardware
  soc/tegra: fuse: Use resource-managed helpers
  soc/tegra: regulators: Prepare for suspend
  soc/tegra: pmc: Change name of core power domain
  soc/tegra: pmc: Enable core domain support for Tegra20 and Tegra30
  ARM: tegra: Add OPP tables and power domains to Tegra20 device-trees
  ARM: tegra: Add OPP tables and power domains to Tegra30 device-trees
  ARM: tegra: Add Memory Client resets to Tegra20 GR2D, GR3D and Host1x
  ARM: tegra: Add Memory Client resets to Tegra30 GR2D, GR3D and Host1x
  ARM: tegra20/30: Disable unused host1x hardware

 .../bindings/clock/nvidia,tegra20-car.yaml    |   37 +
 .../display/tegra/nvidia,tegra20-host1x.txt   |   53 +
 .../bindings/media/nvidia,tegra-vde.txt       |   64 -
 .../bindings/media/nvidia,tegra-vde.yaml      |  119 ++
 .../boot/dts/tegra20-acer-a500-picasso.dts    |    1 +
 arch/arm/boot/dts/tegra20-colibri.dtsi        |    3 +-
 arch/arm/boot/dts/tegra20-harmony.dts         |    3 +-
 arch/arm/boot/dts/tegra20-paz00.dts           |    1 +
 .../arm/boot/dts/tegra20-peripherals-opp.dtsi |  941 +++++++++++
 arch/arm/boot/dts/tegra20-seaboard.dts        |    3 +-
 arch/arm/boot/dts/tegra20-tamonten.dtsi       |    3 +-
 arch/arm/boot/dts/tegra20-trimslice.dts       |    9 +
 arch/arm/boot/dts/tegra20-ventana.dts         |    1 +
 arch/arm/boot/dts/tegra20.dtsi                |  116 +-
 .../tegra30-asus-nexus7-grouper-common.dtsi   |    1 +
 arch/arm/boot/dts/tegra30-beaver.dts          |    1 +
 arch/arm/boot/dts/tegra30-cardhu.dtsi         |    1 +
 arch/arm/boot/dts/tegra30-colibri.dtsi        |   17 +-
 arch/arm/boot/dts/tegra30-ouya.dts            |    1 +
 .../arm/boot/dts/tegra30-peripherals-opp.dtsi | 1412 +++++++++++++++++
 arch/arm/boot/dts/tegra30.dtsi                |  175 +-
 drivers/bus/tegra-gmi.c                       |   52 +-
 drivers/clk/tegra/Makefile                    |    1 +
 drivers/clk/tegra/clk-device.c                |  222 +++
 drivers/clk/tegra/clk-pll.c                   |    2 +-
 drivers/clk/tegra/clk-super.c                 |    2 +-
 drivers/clk/tegra/clk-tegra20.c               |   77 +-
 drivers/clk/tegra/clk-tegra30.c               |  116 +-
 drivers/clk/tegra/clk.c                       |   75 +-
 drivers/clk/tegra/clk.h                       |    2 +
 drivers/gpu/drm/tegra/dc.c                    |   74 +
 drivers/gpu/drm/tegra/dc.h                    |    2 +
 drivers/gpu/drm/tegra/gr2d.c                  |  155 +-
 drivers/gpu/drm/tegra/gr3d.c                  |  388 ++++-
 drivers/gpu/drm/tegra/hdmi.c                  |   16 +-
 drivers/gpu/drm/tegra/vic.c                   |    4 +
 drivers/gpu/host1x/channel.c                  |    8 +
 drivers/gpu/host1x/debug.c                    |   15 +
 drivers/gpu/host1x/dev.c                      |  151 +-
 drivers/gpu/host1x/dev.h                      |    3 +-
 drivers/gpu/host1x/hw/channel_hw.c            |   44 +-
 drivers/gpu/host1x/intr.c                     |    3 -
 drivers/gpu/host1x/syncpt.c                   |    5 +-
 drivers/mmc/host/sdhci-tegra.c                |   82 +-
 drivers/mtd/nand/raw/tegra_nand.c             |   55 +-
 drivers/opp/core.c                            |    6 +-
 drivers/pwm/pwm-tegra.c                       |   88 +-
 drivers/soc/tegra/common.c                    |    4 +-
 drivers/soc/tegra/fuse/fuse-tegra.c           |   51 +-
 drivers/soc/tegra/fuse/fuse-tegra20.c         |   33 +-
 drivers/soc/tegra/fuse/fuse.h                 |    1 +
 drivers/soc/tegra/pmc.c                       |   19 +-
 drivers/soc/tegra/regulators-tegra20.c        |   99 ++
 drivers/soc/tegra/regulators-tegra30.c        |  122 ++
 drivers/spi/spi-tegra20-slink.c               |   10 +-
 drivers/staging/media/tegra-vde/vde.c         |   57 +-
 drivers/usb/chipidea/ci_hdrc_tegra.c          |   53 +-
 include/linux/host1x.h                        |    1 +
 include/linux/pm_opp.h                        |    8 +-
 include/soc/tegra/common.h                    |   24 +
 60 files changed, 4739 insertions(+), 353 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
 create mode 100644 Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
 create mode 100644 drivers/clk/tegra/clk-device.c

-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:01 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:01 +0300
Subject: [PATCH v11 03/34] soc/tegra: pmc: Disable PMC state syncing
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-4-digetx@gmail.com>

Disable PMC state syncing in order to ensure that we won't break older
kernels once device-trees will be updated with the addition of the power
domains. This also allows to apply device-tree PM patches independently
from the driver patches.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/soc/tegra/pmc.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 50091c4ec948..fb8faf7b226a 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -360,6 +360,7 @@ struct tegra_pmc_soc {
 	unsigned int num_pmc_clks;
 	bool has_blink_output;
 	bool has_usb_sleepwalk;
+	bool supports_core_domain;
 };
 
 /**
@@ -3041,6 +3042,7 @@ static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
 }
 
 static const struct tegra_pmc_soc tegra20_pmc_soc = {
+	.supports_core_domain = false,
 	.num_powergates = ARRAY_SIZE(tegra20_powergates),
 	.powergates = tegra20_powergates,
 	.num_cpu_powergates = 0,
@@ -3101,6 +3103,7 @@ static const char * const tegra30_reset_sources[] = {
 };
 
 static const struct tegra_pmc_soc tegra30_pmc_soc = {
+	.supports_core_domain = false,
 	.num_powergates = ARRAY_SIZE(tegra30_powergates),
 	.powergates = tegra30_powergates,
 	.num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),
@@ -3157,6 +3160,7 @@ static const u8 tegra114_cpu_powergates[] = {
 };
 
 static const struct tegra_pmc_soc tegra114_pmc_soc = {
+	.supports_core_domain = false,
 	.num_powergates = ARRAY_SIZE(tegra114_powergates),
 	.powergates = tegra114_powergates,
 	.num_cpu_powergates = ARRAY_SIZE(tegra114_cpu_powergates),
@@ -3273,6 +3277,7 @@ static const struct pinctrl_pin_desc tegra124_pin_descs[] = {
 };
 
 static const struct tegra_pmc_soc tegra124_pmc_soc = {
+	.supports_core_domain = false,
 	.num_powergates = ARRAY_SIZE(tegra124_powergates),
 	.powergates = tegra124_powergates,
 	.num_cpu_powergates = ARRAY_SIZE(tegra124_cpu_powergates),
@@ -3398,6 +3403,7 @@ static const struct tegra_wake_event tegra210_wake_events[] = {
 };
 
 static const struct tegra_pmc_soc tegra210_pmc_soc = {
+	.supports_core_domain = false,
 	.num_powergates = ARRAY_SIZE(tegra210_powergates),
 	.powergates = tegra210_powergates,
 	.num_cpu_powergates = ARRAY_SIZE(tegra210_cpu_powergates),
@@ -3555,6 +3561,7 @@ static const struct tegra_wake_event tegra186_wake_events[] = {
 };
 
 static const struct tegra_pmc_soc tegra186_pmc_soc = {
+	.supports_core_domain = false,
 	.num_powergates = 0,
 	.powergates = NULL,
 	.num_cpu_powergates = 0,
@@ -3689,6 +3696,7 @@ static const struct tegra_wake_event tegra194_wake_events[] = {
 };
 
 static const struct tegra_pmc_soc tegra194_pmc_soc = {
+	.supports_core_domain = false,
 	.num_powergates = 0,
 	.powergates = NULL,
 	.num_cpu_powergates = 0,
@@ -3757,6 +3765,7 @@ static const char * const tegra234_reset_sources[] = {
 };
 
 static const struct tegra_pmc_soc tegra234_pmc_soc = {
+	.supports_core_domain = false,
 	.num_powergates = 0,
 	.powergates = NULL,
 	.num_cpu_powergates = 0,
@@ -3803,6 +3812,14 @@ static void tegra_pmc_sync_state(struct device *dev)
 {
 	int err;
 
+	/*
+	 * Newer device-trees have power domains, but we need to prepare all
+	 * device drivers with runtime PM and OPP support first, otherwise
+	 * state syncing is unsafe.
+	 */
+	if (!pmc->soc->supports_core_domain)
+		return;
+
 	/*
 	 * Older device-trees don't have core PD, and thus, there are
 	 * no dependencies that will block the state syncing. We shouldn't
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:02 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:02 +0300
Subject: [PATCH v11 04/34] soc/tegra: Don't print error message when OPPs not
 available
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-5-digetx@gmail.com>

Previously we assumed that devm_tegra_core_dev_init_opp_table() will
be used only by drivers that will always have device with OPP table,
but this is not true anymore. For example now Tegra30 will have OPP table
for PWM, but Tegra20 not and both use the same driver. Hence let's not
print the error message about missing OPP table in the common helper,
we can print it elsewhere.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/soc/tegra/common.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/soc/tegra/common.c b/drivers/soc/tegra/common.c
index cd33e99249c3..a42d4f98c078 100644
--- a/drivers/soc/tegra/common.c
+++ b/drivers/soc/tegra/common.c
@@ -111,9 +111,7 @@ int devm_tegra_core_dev_init_opp_table(struct device *dev,
 	 */
 	err = devm_pm_opp_of_add_table(dev);
 	if (err) {
-		if (err == -ENODEV)
-			dev_err_once(dev, "OPP table not found, please update device-tree\n");
-		else
+		if (err != -ENODEV)
 			dev_err(dev, "failed to add OPP table: %d\n", err);
 
 		return err;
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:03 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:03 +0300
Subject: [PATCH v11 05/34] dt-bindings: clock: tegra-car: Document new clock
 sub-nodes
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-6-digetx@gmail.com>

Document sub-nodes which describe Tegra SoC clocks that require a higher
voltage of the core power domain in order to operate properly on a higher
clock rates.  Each node contains a phandle to OPP table and power domain.

The root PLLs and system clocks don't have any specific device dedicated
to them, clock controller is in charge of managing power for them.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 .../bindings/clock/nvidia,tegra20-car.yaml    | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml
index 459d2a525393..f832abb7f11a 100644
--- a/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml
+++ b/Documentation/devicetree/bindings/clock/nvidia,tegra20-car.yaml
@@ -42,6 +42,36 @@ properties:
   "#reset-cells":
     const: 1
 
+patternProperties:
+  "^(sclk)|(pll-[cem])$":
+    type: object
+    properties:
+      compatible:
+        enum:
+          - nvidia,tegra20-sclk
+          - nvidia,tegra30-sclk
+          - nvidia,tegra30-pllc
+          - nvidia,tegra30-plle
+          - nvidia,tegra30-pllm
+
+      operating-points-v2: true
+
+      clocks:
+        items:
+          - description: node's clock
+
+      power-domains:
+        maxItems: 1
+        description: phandle to the core SoC power domain
+
+    required:
+      - compatible
+      - operating-points-v2
+      - clocks
+      - power-domains
+
+    additionalProperties: false
+
 required:
   - compatible
   - reg
@@ -59,6 +89,13 @@ examples:
         reg = <0x60006000 0x1000>;
         #clock-cells = <1>;
         #reset-cells = <1>;
+
+        sclk {
+            compatible = "nvidia,tegra20-sclk";
+            operating-points-v2 = <&opp_table>;
+            clocks = <&tegra_car TEGRA20_CLK_SCLK>;
+            power-domains = <&domain>;
+        };
     };
 
     usb-controller at c5004000 {
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:04 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:04 +0300
Subject: [PATCH v11 06/34] clk: tegra: Support runtime PM and power domain
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-7-digetx@gmail.com>

The Clock-and-Reset controller resides in a core power domain on NVIDIA
Tegra SoCs.  In order to support voltage scaling of the core power domain,
we hook up DVFS-capable clocks to the core GENPD for managing of the
GENPD's performance state based on the clock changes.

Some clocks don't have any specific physical hardware unit that backs
them, like root PLLs and system clock and they have theirs own voltage
requirements.  This patch adds new clk-device driver that backs the clocks
and provides runtime PM functionality for them.  A virtual clk-device is
created for each such DVFS-capable clock at the clock's registration time
by the new tegra_clk_register() helper.  Driver changes clock's device
GENPD performance state based on clk-rate notifications.

In result we have this sequence of events:

  1. Clock driver creates virtual device for selective clocks, enables
     runtime PM for the created device and registers the clock.
  2. Clk-device driver starts to listen to clock rate changes.
  3. Something changes clk rate or enables/disables clk.
  4. CCF core propagates the change through the clk tree.
  5. Clk-device driver gets clock rate-change notification or GENPD core
     handles prepare/unprepare of the clock.
  6. Clk-device driver changes GENPD performance state on clock rate
     change.
  7. GENPD driver changes voltage regulator state change.
  8. The regulator state is committed to hardware via I2C.

We rely on fact that DVFS is not needed for Tegra I2C and that Tegra I2C
driver already keeps clock always-prepared.  Hence I2C subsystem stays
independent from the clk power management and there are no deadlock spots
in the sequence.

Currently all clocks are registered very early during kernel boot when the
device driver core isn't available yet.  The clk-device can't be created
at that time.  This patch splits the registration of the clocks in two
phases:

  1. Register all essential clocks which don't use RPM and are needed
     during early boot.

  2. Register at a later boot time the rest of clocks.

This patch adds power management support for Tegra20 and Tegra30 clocks.

Tested-by: Peter Geis <pgwipeout at gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav at gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart at gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar at protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/clk/tegra/Makefile      |   1 +
 drivers/clk/tegra/clk-device.c  | 222 ++++++++++++++++++++++++++++++++
 drivers/clk/tegra/clk-pll.c     |   2 +-
 drivers/clk/tegra/clk-super.c   |   2 +-
 drivers/clk/tegra/clk-tegra20.c |  77 ++++++++---
 drivers/clk/tegra/clk-tegra30.c | 116 ++++++++++++-----
 drivers/clk/tegra/clk.c         |  75 ++++++++++-
 drivers/clk/tegra/clk.h         |   2 +
 8 files changed, 443 insertions(+), 54 deletions(-)
 create mode 100644 drivers/clk/tegra/clk-device.c

diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index 7b1816856eb5..a0715cdfc1a4 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-y					+= clk.o
 obj-y					+= clk-audio-sync.o
+obj-y					+= clk-device.o
 obj-y					+= clk-dfll.o
 obj-y					+= clk-divider.o
 obj-y					+= clk-periph.o
diff --git a/drivers/clk/tegra/clk-device.c b/drivers/clk/tegra/clk-device.c
new file mode 100644
index 000000000000..9463c285b2a5
--- /dev/null
+++ b/drivers/clk/tegra/clk-device.c
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include <soc/tegra/common.h>
+
+#include "clk.h"
+
+/*
+ * This driver manages performance state of the core power domain for the
+ * independent PLLs and system clocks.  We created a virtual clock device
+ * for such clocks, see tegra_clk_dev_register().
+ */
+
+struct tegra_clk_device {
+	struct notifier_block clk_nb;
+	struct device *dev;
+	struct clk_hw *hw;
+	struct mutex lock;
+};
+
+static int tegra_clock_set_pd_state(struct tegra_clk_device *clk_dev,
+				    unsigned long rate)
+{
+	struct device *dev = clk_dev->dev;
+	struct dev_pm_opp *opp;
+	unsigned int pstate;
+
+	opp = dev_pm_opp_find_freq_ceil(dev, &rate);
+	if (opp == ERR_PTR(-ERANGE)) {
+		dev_dbg(dev, "failed to find ceil OPP for %luHz\n", rate);
+		opp = dev_pm_opp_find_freq_floor(dev, &rate);
+	}
+
+	if (IS_ERR(opp)) {
+		dev_err(dev, "failed to find OPP for %luHz: %pe\n", rate, opp);
+		return PTR_ERR(opp);
+	}
+
+	pstate = dev_pm_opp_get_required_pstate(opp, 0);
+	dev_pm_opp_put(opp);
+
+	return dev_pm_genpd_set_performance_state(dev, pstate);
+}
+
+static int tegra_clock_change_notify(struct notifier_block *nb,
+				     unsigned long msg, void *data)
+{
+	struct clk_notifier_data *cnd = data;
+	struct tegra_clk_device *clk_dev;
+	int err = 0;
+
+	clk_dev = container_of(nb, struct tegra_clk_device, clk_nb);
+
+	mutex_lock(&clk_dev->lock);
+	switch (msg) {
+	case PRE_RATE_CHANGE:
+		if (cnd->new_rate > cnd->old_rate)
+			err = tegra_clock_set_pd_state(clk_dev, cnd->new_rate);
+		break;
+
+	case ABORT_RATE_CHANGE:
+		err = tegra_clock_set_pd_state(clk_dev, cnd->old_rate);
+		break;
+
+	case POST_RATE_CHANGE:
+		if (cnd->new_rate < cnd->old_rate)
+			err = tegra_clock_set_pd_state(clk_dev, cnd->new_rate);
+		break;
+
+	default:
+		break;
+	}
+	mutex_unlock(&clk_dev->lock);
+
+	return notifier_from_errno(err);
+}
+
+static int tegra_clock_sync_pd_state(struct tegra_clk_device *clk_dev)
+{
+	unsigned long rate;
+	int ret = 0;
+
+	mutex_lock(&clk_dev->lock);
+
+	if (!pm_runtime_status_suspended(clk_dev->dev)) {
+		rate = clk_hw_get_rate(clk_dev->hw);
+		ret = tegra_clock_set_pd_state(clk_dev, rate);
+	}
+
+	mutex_unlock(&clk_dev->lock);
+
+	return ret;
+}
+
+static int tegra_clock_probe(struct platform_device *pdev)
+{
+	struct tegra_clk_device *clk_dev;
+	struct device *dev = &pdev->dev;
+	struct clk *clk;
+	int err;
+
+	if (!dev->pm_domain)
+		return -EINVAL;
+
+	clk_dev = devm_kzalloc(dev, sizeof(*clk_dev), GFP_KERNEL);
+	if (!clk_dev)
+		return -ENOMEM;
+
+	clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	clk_dev->dev = dev;
+	clk_dev->hw = __clk_get_hw(clk);
+	clk_dev->clk_nb.notifier_call = tegra_clock_change_notify;
+	mutex_init(&clk_dev->lock);
+
+	platform_set_drvdata(pdev, clk_dev);
+
+	err = devm_tegra_core_dev_init_opp_table_common(dev);
+	if (err)
+		return err;
+
+	err = clk_notifier_register(clk, &clk_dev->clk_nb);
+	if (err) {
+		dev_err(dev, "failed to register clk notifier: %d\n", err);
+		return err;
+	}
+
+	/*
+	 * The driver is attaching to a potentially active/resumed clock, hence
+	 * we need to sync the power domain performance state in a accordance to
+	 * the clock rate if clock is resumed.
+	 */
+	err = tegra_clock_sync_pd_state(clk_dev);
+	if (err)
+		goto unreg_clk;
+
+	return 0;
+
+unreg_clk:
+	clk_notifier_unregister(clk, &clk_dev->clk_nb);
+
+	return err;
+}
+
+static __maybe_unused int tegra_clock_pm_suspend(struct device *dev)
+{
+	struct tegra_clk_device *clk_dev = dev_get_drvdata(dev);
+
+	/*
+	 * Power management of the clock is entangled with the Tegra PMC
+	 * GENPD because PMC driver enables/disables clocks for toggling
+	 * of the PD's on/off state.
+	 *
+	 * The PMC GENPD is resumed in NOIRQ phase, before RPM of the clocks
+	 * becomes available, hence PMC can't use clocks at the early resume
+	 * phase if RPM is involved. For example when 3d clock is enabled,
+	 * it may enable the parent PLL clock that needs to be RPM-resumed.
+	 *
+	 * Secondly, the PLL clocks may be enabled by the low level suspend
+	 * code, so we need to assume that PLL is in enabled state during
+	 * suspend.
+	 *
+	 * We will keep PLLs and system clock resumed during suspend time.
+	 * All PLLs on all SoCs are low power and system clock is always-on,
+	 * so practically not much is changed here.
+	 */
+
+	return clk_prepare(clk_dev->hw->clk);
+}
+
+static __maybe_unused int tegra_clock_pm_resume(struct device *dev)
+{
+	struct tegra_clk_device *clk_dev = dev_get_drvdata(dev);
+
+	clk_unprepare(clk_dev->hw->clk);
+
+	return 0;
+}
+
+static void tegra_clock_shutdown(struct platform_device *pdev)
+{
+	struct tegra_clk_device *clk_dev = platform_get_drvdata(pdev);
+
+	clk_prepare(clk_dev->hw->clk);
+}
+
+static const struct dev_pm_ops tegra_clock_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(tegra_clock_pm_suspend,
+				tegra_clock_pm_resume)
+};
+
+static const struct of_device_id tegra_clock_match[] = {
+	{ .compatible = "nvidia,tegra20-sclk" },
+	{ .compatible = "nvidia,tegra30-sclk" },
+	{ .compatible = "nvidia,tegra30-pllc" },
+	{ .compatible = "nvidia,tegra30-plle" },
+	{ .compatible = "nvidia,tegra30-pllm" },
+	{ }
+};
+
+static struct platform_driver tegra_clock_driver = {
+	.driver = {
+		.name = "tegra-clock",
+		.of_match_table = tegra_clock_match,
+		.pm = &tegra_clock_pm,
+		.suppress_bind_attrs = true,
+	},
+	.probe = tegra_clock_probe,
+	.shutdown = tegra_clock_shutdown,
+};
+builtin_platform_driver(tegra_clock_driver);
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index eaa079c177c3..100b5d9b7e26 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -1914,7 +1914,7 @@ static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll,
 	/* Data in .init is copied by clk_register(), so stack variable OK */
 	pll->hw.init = &init;
 
-	return clk_register(NULL, &pll->hw);
+	return tegra_clk_dev_register(&pll->hw);
 }
 
 struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
index 6099c6e9acd4..a98a420398fa 100644
--- a/drivers/clk/tegra/clk-super.c
+++ b/drivers/clk/tegra/clk-super.c
@@ -226,7 +226,7 @@ struct clk *tegra_clk_register_super_mux(const char *name,
 	/* Data in .init is copied by clk_register(), so stack variable OK */
 	super->hw.init = &init;
 
-	clk = clk_register(NULL, &super->hw);
+	clk = tegra_clk_dev_register(&super->hw);
 	if (IS_ERR(clk))
 		kfree(super);
 
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 3664593a5ba4..be3c33441cfc 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -6,8 +6,11 @@
 #include <linux/io.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
+#include <linux/init.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 #include <linux/clk/tegra.h>
 #include <linux/delay.h>
 #include <dt-bindings/clock/tegra20-car.h>
@@ -414,7 +417,7 @@ static struct tegra_clk_pll_params pll_e_params = {
 	.fixed_rate = 100000000,
 };
 
-static struct tegra_devclk devclks[] __initdata = {
+static struct tegra_devclk devclks[] = {
 	{ .con_id = "pll_c", .dt_id = TEGRA20_CLK_PLL_C },
 	{ .con_id = "pll_c_out1", .dt_id = TEGRA20_CLK_PLL_C_OUT1 },
 	{ .con_id = "pll_p", .dt_id = TEGRA20_CLK_PLL_P },
@@ -710,13 +713,6 @@ static void tegra20_super_clk_init(void)
 			      NULL);
 	clks[TEGRA20_CLK_CCLK] = clk;
 
-	/* SCLK */
-	clk = tegra_clk_register_super_mux("sclk", sclk_parents,
-			      ARRAY_SIZE(sclk_parents),
-			      CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
-			      clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
-	clks[TEGRA20_CLK_SCLK] = clk;
-
 	/* twd */
 	clk = clk_register_fixed_factor(NULL, "twd", "cclk", 0, 1, 4);
 	clks[TEGRA20_CLK_TWD] = clk;
@@ -1014,7 +1010,7 @@ static struct tegra_cpu_car_ops tegra20_cpu_car_ops = {
 #endif
 };
 
-static struct tegra_clk_init_table init_table[] __initdata = {
+static struct tegra_clk_init_table init_table[] = {
 	{ TEGRA20_CLK_PLL_P, TEGRA20_CLK_CLK_MAX, 216000000, 1 },
 	{ TEGRA20_CLK_PLL_P_OUT1, TEGRA20_CLK_CLK_MAX, 28800000, 1 },
 	{ TEGRA20_CLK_PLL_P_OUT2, TEGRA20_CLK_CLK_MAX, 48000000, 1 },
@@ -1052,11 +1048,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
 	{ TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 },
 };
 
-static void __init tegra20_clock_apply_init_table(void)
-{
-	tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX);
-}
-
 /*
  * Some clocks may be used by different drivers depending on the board
  * configuration.  List those here to register them twice in the clock lookup
@@ -1076,6 +1067,8 @@ static const struct of_device_id pmc_match[] __initconst = {
 	{ },
 };
 
+static bool tegra20_car_initialized;
+
 static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
 					       void *data)
 {
@@ -1083,6 +1076,16 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
 	struct clk_hw *hw;
 	struct clk *clk;
 
+	/*
+	 * Timer clocks are needed early, the rest of the clocks shouldn't be
+	 * available to device drivers until clock tree is fully initialized.
+	 */
+	if (clkspec->args[0] != TEGRA20_CLK_RTC &&
+	    clkspec->args[0] != TEGRA20_CLK_TWD &&
+	    clkspec->args[0] != TEGRA20_CLK_TIMER &&
+	    !tegra20_car_initialized)
+		return ERR_PTR(-EPROBE_DEFER);
+
 	clk = of_clk_src_onecell_get(clkspec, data);
 	if (IS_ERR(clk))
 		return clk;
@@ -1149,10 +1152,48 @@ static void __init tegra20_clock_init(struct device_node *np)
 	tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX);
 
 	tegra_add_of_provider(np, tegra20_clk_src_onecell_get);
-	tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
-
-	tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
 
 	tegra_cpu_car_ops = &tegra20_cpu_car_ops;
 }
-CLK_OF_DECLARE(tegra20, "nvidia,tegra20-car", tegra20_clock_init);
+CLK_OF_DECLARE_DRIVER(tegra20, "nvidia,tegra20-car", tegra20_clock_init);
+
+/*
+ * Clocks that use runtime PM can't be created at the tegra20_clock_init
+ * time because drivers' base isn't initialized yet, and thus platform
+ * devices can't be created for the clocks.  Hence we need to split the
+ * registration of the clocks into two phases.  The first phase registers
+ * essential clocks which don't require RPM and are actually used during
+ * early boot.  The second phase registers clocks which use RPM and this
+ * is done when device drivers' core API is ready.
+ */
+static int tegra20_car_probe(struct platform_device *pdev)
+{
+	struct clk *clk;
+
+	clk = tegra_clk_register_super_mux("sclk", sclk_parents,
+			      ARRAY_SIZE(sclk_parents),
+			      CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+			      clk_base + SCLK_BURST_POLICY, 0, 4, 0, 0, NULL);
+	clks[TEGRA20_CLK_SCLK] = clk;
+
+	tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
+	tegra_init_from_table(init_table, clks, TEGRA20_CLK_CLK_MAX);
+	tegra20_car_initialized = true;
+
+	return 0;
+}
+
+static const struct of_device_id tegra20_car_match[] = {
+	{ .compatible = "nvidia,tegra20-car" },
+	{ }
+};
+
+static struct platform_driver tegra20_car_driver = {
+	.driver = {
+		.name = "tegra20-car",
+		.of_match_table = tegra20_car_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = tegra20_car_probe,
+};
+builtin_platform_driver(tegra20_car_driver);
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index 64121bc66d85..04b496123820 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -7,8 +7,11 @@
 #include <linux/delay.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
+#include <linux/init.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 #include <linux/clk/tegra.h>
 
 #include <soc/tegra/pmc.h>
@@ -532,7 +535,7 @@ static unsigned long tegra30_input_freq[] = {
 	[12] = 26000000,
 };
 
-static struct tegra_devclk devclks[] __initdata = {
+static struct tegra_devclk devclks[] = {
 	{ .con_id = "pll_c", .dt_id = TEGRA30_CLK_PLL_C },
 	{ .con_id = "pll_c_out1", .dt_id = TEGRA30_CLK_PLL_C_OUT1 },
 	{ .con_id = "pll_p", .dt_id = TEGRA30_CLK_PLL_P },
@@ -812,11 +815,6 @@ static void __init tegra30_pll_init(void)
 {
 	struct clk *clk;
 
-	/* PLLC */
-	clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0,
-				     &pll_c_params, NULL);
-	clks[TEGRA30_CLK_PLL_C] = clk;
-
 	/* PLLC_OUT1 */
 	clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c",
 				clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
@@ -826,11 +824,6 @@ static void __init tegra30_pll_init(void)
 				0, NULL);
 	clks[TEGRA30_CLK_PLL_C_OUT1] = clk;
 
-	/* PLLM */
-	clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base,
-			    CLK_SET_RATE_GATE, &pll_m_params, NULL);
-	clks[TEGRA30_CLK_PLL_M] = clk;
-
 	/* PLLM_OUT1 */
 	clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m",
 				clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
@@ -880,9 +873,6 @@ static void __init tegra30_pll_init(void)
 			       ARRAY_SIZE(pll_e_parents),
 			       CLK_SET_RATE_NO_REPARENT,
 			       clk_base + PLLE_AUX, 2, 1, 0, NULL);
-	clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base,
-			     CLK_GET_RATE_NOCACHE, &pll_e_params, NULL);
-	clks[TEGRA30_CLK_PLL_E] = clk;
 }
 
 static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
@@ -971,14 +961,6 @@ static void __init tegra30_super_clk_init(void)
 			      NULL);
 	clks[TEGRA30_CLK_CCLK_LP] = clk;
 
-	/* SCLK */
-	clk = tegra_clk_register_super_mux("sclk", sclk_parents,
-				  ARRAY_SIZE(sclk_parents),
-				  CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
-				  clk_base + SCLK_BURST_POLICY,
-				  0, 4, 0, 0, NULL);
-	clks[TEGRA30_CLK_SCLK] = clk;
-
 	/* twd */
 	clk = clk_register_fixed_factor(NULL, "twd", "cclk_g",
 					CLK_SET_RATE_PARENT, 1, 2);
@@ -1214,7 +1196,7 @@ static struct tegra_cpu_car_ops tegra30_cpu_car_ops = {
 #endif
 };
 
-static struct tegra_clk_init_table init_table[] __initdata = {
+static struct tegra_clk_init_table init_table[] = {
 	{ TEGRA30_CLK_UARTA, TEGRA30_CLK_PLL_P, 408000000, 0 },
 	{ TEGRA30_CLK_UARTB, TEGRA30_CLK_PLL_P, 408000000, 0 },
 	{ TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 408000000, 0 },
@@ -1259,11 +1241,6 @@ static struct tegra_clk_init_table init_table[] __initdata = {
 	{ TEGRA30_CLK_CLK_MAX, TEGRA30_CLK_CLK_MAX, 0, 0 },
 };
 
-static void __init tegra30_clock_apply_init_table(void)
-{
-	tegra_init_from_table(init_table, clks, TEGRA30_CLK_CLK_MAX);
-}
-
 /*
  * Some clocks may be used by different drivers depending on the board
  * configuration.  List those here to register them twice in the clock lookup
@@ -1294,12 +1271,24 @@ static struct tegra_audio_clk_info tegra30_audio_plls[] = {
 	{ "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
 };
 
+static bool tegra30_car_initialized;
+
 static struct clk *tegra30_clk_src_onecell_get(struct of_phandle_args *clkspec,
 					       void *data)
 {
 	struct clk_hw *hw;
 	struct clk *clk;
 
+	/*
+	 * Timer clocks are needed early, the rest of the clocks shouldn't be
+	 * available to device drivers until clock tree is fully initialized.
+	 */
+	if (clkspec->args[0] != TEGRA30_CLK_RTC &&
+	    clkspec->args[0] != TEGRA30_CLK_TWD &&
+	    clkspec->args[0] != TEGRA30_CLK_TIMER &&
+	    !tegra30_car_initialized)
+		return ERR_PTR(-EPROBE_DEFER);
+
 	clk = of_clk_src_onecell_get(clkspec, data);
 	if (IS_ERR(clk))
 		return clk;
@@ -1357,10 +1346,75 @@ static void __init tegra30_clock_init(struct device_node *np)
 	tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
 
 	tegra_add_of_provider(np, tegra30_clk_src_onecell_get);
+
+	tegra_cpu_car_ops = &tegra30_cpu_car_ops;
+}
+CLK_OF_DECLARE_DRIVER(tegra30, "nvidia,tegra30-car", tegra30_clock_init);
+
+/*
+ * Clocks that use runtime PM can't be created at the tegra30_clock_init
+ * time because drivers' base isn't initialized yet, and thus platform
+ * devices can't be created for the clocks.  Hence we need to split the
+ * registration of the clocks into two phases.  The first phase registers
+ * essential clocks which don't require RPM and are actually used during
+ * early boot.  The second phase registers clocks which use RPM and this
+ * is done when device drivers' core API is ready.
+ */
+static int tegra30_car_probe(struct platform_device *pdev)
+{
+	struct clk *clk;
+
+	/* PLLC */
+	clk = tegra_clk_register_pll("pll_c", "pll_ref", clk_base, pmc_base, 0,
+				     &pll_c_params, NULL);
+	clks[TEGRA30_CLK_PLL_C] = clk;
+
+	/* PLLE */
+	clk = tegra_clk_register_plle("pll_e", "pll_e_mux", clk_base, pmc_base,
+				      CLK_GET_RATE_NOCACHE, &pll_e_params, NULL);
+	clks[TEGRA30_CLK_PLL_E] = clk;
+
+	/* PLLM */
+	clk = tegra_clk_register_pll("pll_m", "pll_ref", clk_base, pmc_base,
+				     CLK_SET_RATE_GATE, &pll_m_params, NULL);
+	clks[TEGRA30_CLK_PLL_M] = clk;
+
+	/* SCLK */
+	clk = tegra_clk_register_super_mux("sclk", sclk_parents,
+					   ARRAY_SIZE(sclk_parents),
+					   CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+					   clk_base + SCLK_BURST_POLICY,
+					   0, 4, 0, 0, NULL);
+	clks[TEGRA30_CLK_SCLK] = clk;
+
 	tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
+	tegra_init_from_table(init_table, clks, TEGRA30_CLK_CLK_MAX);
+	tegra30_car_initialized = true;
 
-	tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
+	return 0;
+}
 
-	tegra_cpu_car_ops = &tegra30_cpu_car_ops;
+static const struct of_device_id tegra30_car_match[] = {
+	{ .compatible = "nvidia,tegra30-car" },
+	{ }
+};
+
+static struct platform_driver tegra30_car_driver = {
+	.driver = {
+		.name = "tegra30-car",
+		.of_match_table = tegra30_car_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = tegra30_car_probe,
+};
+
+/*
+ * Clock driver must be registered before memory controller driver,
+ * which doesn't support deferred probing for today and is registered
+ * from arch init-level.
+ */
+static int tegra30_car_init(void)
+{
+	return platform_driver_register(&tegra30_car_driver);
 }
-CLK_OF_DECLARE(tegra30, "nvidia,tegra30-car", tegra30_clock_init);
+postcore_initcall(tegra30_car_init);
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index f6cdce441cf7..26bda45813c0 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -9,14 +9,19 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/clk/tegra.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/reset-controller.h>
+#include <linux/string.h>
 
 #include <soc/tegra/fuse.h>
 
 #include "clk.h"
 
 /* Global data of Tegra CPU CAR ops */
+static struct device_node *tegra_car_np;
 static struct tegra_cpu_car_ops dummy_car_ops;
 struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
 
@@ -261,8 +266,8 @@ void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
 	}
 }
 
-void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
-				  struct clk *clks[], int clk_max)
+void tegra_init_from_table(struct tegra_clk_init_table *tbl,
+			   struct clk *clks[], int clk_max)
 {
 	struct clk *clk;
 
@@ -320,6 +325,8 @@ void __init tegra_add_of_provider(struct device_node *np,
 {
 	int i;
 
+	tegra_car_np = np;
+
 	for (i = 0; i < clk_num; i++) {
 		if (IS_ERR(clks[i])) {
 			pr_err
@@ -348,7 +355,7 @@ void __init tegra_init_special_resets(unsigned int num,
 	special_reset_deassert = deassert;
 }
 
-void __init tegra_register_devclks(struct tegra_devclk *dev_clks, int num)
+void tegra_register_devclks(struct tegra_devclk *dev_clks, int num)
 {
 	int i;
 
@@ -372,6 +379,68 @@ struct clk ** __init tegra_lookup_dt_id(int clk_id,
 		return NULL;
 }
 
+static struct device_node *tegra_clk_get_of_node(struct clk_hw *hw)
+{
+	struct device_node *np;
+	char *node_name;
+
+	node_name = kstrdup(hw->init->name, GFP_KERNEL);
+	if (!node_name)
+		return NULL;
+
+	strreplace(node_name, '_', '-');
+
+	for_each_child_of_node(tegra_car_np, np) {
+		if (!strcmp(np->name, node_name))
+			break;
+	}
+
+	kfree(node_name);
+
+	return np;
+}
+
+struct clk *tegra_clk_dev_register(struct clk_hw *hw)
+{
+	struct platform_device *pdev, *parent;
+	const char *dev_name = NULL;
+	struct device *dev = NULL;
+	struct device_node *np;
+
+	np = tegra_clk_get_of_node(hw);
+
+	if (!of_device_is_available(np))
+		goto put_node;
+
+	dev_name = kasprintf(GFP_KERNEL, "tegra_clk_%s", hw->init->name);
+	if (!dev_name)
+		goto put_node;
+
+	parent = of_find_device_by_node(tegra_car_np);
+	if (parent) {
+		pdev = of_platform_device_create(np, dev_name, &parent->dev);
+		put_device(&parent->dev);
+
+		if (!pdev) {
+			pr_err("%s: failed to create device for %pOF\n",
+			       __func__, np);
+			goto free_name;
+		}
+
+		dev = &pdev->dev;
+		pm_runtime_enable(dev);
+	} else {
+		WARN(1, "failed to find device for %pOF\n", tegra_car_np);
+	}
+
+free_name:
+	kfree(dev_name);
+put_node:
+	of_node_put(np);
+
+	return clk_register(dev, hw);
+}
+
 tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
 
 static int __init tegra_clocks_apply_init_table(void)
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 0c3ba0ccce1a..5d80d8b79b8e 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -927,4 +927,6 @@ struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter);
 struct clk *tegra210_clk_register_emc(struct device_node *np,
 				      void __iomem *regs);
 
+struct clk *tegra_clk_dev_register(struct clk_hw *hw);
+
 #endif /* TEGRA_CLK_H */
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:05 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:05 +0300
Subject: [PATCH v11 07/34] dt-bindings: host1x: Document OPP and power domain
 properties
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-8-digetx@gmail.com>

Document new DVFS OPP table and power domain properties of the Host1x bus
and devices sitting on the bus.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 .../display/tegra/nvidia,tegra20-host1x.txt   | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
index 8a6d3e1ee306..62861a8fb5c6 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
@@ -20,6 +20,18 @@ Required properties:
 - reset-names: Must include the following entries:
   - host1x
 
+Optional properties:
+- operating-points-v2: See ../bindings/opp/opp.txt for details.
+  - power-domains: Phandle to HEG or core power domain.
+
+For each opp entry in 'operating-points-v2' table of host1x and its modules:
+- opp-supported-hw: One bitfield indicating:
+	On Tegra20: SoC process ID mask
+	On Tegra30+: SoC speedo ID mask
+
+	A bitwise AND is performed against the value and if any bit
+	matches, the OPP gets enabled.
+
 Each host1x client module having to perform DMA through the Memory Controller
 should have the interconnect endpoints set to the Memory Client and External
 Memory respectively.
@@ -45,6 +57,8 @@ of the following host1x client modules:
   - interconnect-names: Must include name of the interconnect path for each
     interconnect entry. Consult TRM documentation for information about
     available memory clients, see MEMORY CONTROLLER section.
+  - operating-points-v2: See ../bindings/opp/opp.txt for details.
+  - power-domains: Phandle to MPE power domain.
 
 - vi: video input
 
@@ -128,6 +142,8 @@ of the following host1x client modules:
   - interconnect-names: Must include name of the interconnect path for each
     interconnect entry. Consult TRM documentation for information about
     available memory clients, see MEMORY CONTROLLER section.
+  - operating-points-v2: See ../bindings/opp/opp.txt for details.
+  - power-domains: Phandle to VENC power domain.
 
 - epp: encoder pre-processor
 
@@ -147,6 +163,8 @@ of the following host1x client modules:
   - interconnect-names: Must include name of the interconnect path for each
     interconnect entry. Consult TRM documentation for information about
     available memory clients, see MEMORY CONTROLLER section.
+  - operating-points-v2: See ../bindings/opp/opp.txt for details.
+  - power-domains: Phandle to HEG or core power domain.
 
 - isp: image signal processor
 
@@ -166,6 +184,7 @@ of the following host1x client modules:
   - interconnect-names: Must include name of the interconnect path for each
     interconnect entry. Consult TRM documentation for information about
     available memory clients, see MEMORY CONTROLLER section.
+  - power-domains: Phandle to VENC or core power domain.
 
 - gr2d: 2D graphics engine
 
@@ -185,6 +204,8 @@ of the following host1x client modules:
   - interconnect-names: Must include name of the interconnect path for each
     interconnect entry. Consult TRM documentation for information about
     available memory clients, see MEMORY CONTROLLER section.
+  - operating-points-v2: See ../bindings/opp/opp.txt for details.
+  - power-domains: Phandle to HEG or core power domain.
 
 - gr3d: 3D graphics engine
 
@@ -209,6 +230,8 @@ of the following host1x client modules:
   - interconnect-names: Must include name of the interconnect path for each
     interconnect entry. Consult TRM documentation for information about
     available memory clients, see MEMORY CONTROLLER section.
+  - operating-points-v2: See ../bindings/opp/opp.txt for details.
+  - power-domains: Phandles to 3D or core power domain.
 
 - dc: display controller
 
@@ -241,6 +264,8 @@ of the following host1x client modules:
   - interconnect-names: Must include name of the interconnect path for each
     interconnect entry. Consult TRM documentation for information about
     available memory clients, see MEMORY CONTROLLER section.
+  - operating-points-v2: See ../bindings/opp/opp.txt for details.
+  - power-domains: Phandle to core power domain.
 
 - hdmi: High Definition Multimedia Interface
 
@@ -267,6 +292,7 @@ of the following host1x client modules:
   - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
   - nvidia,edid: supplies a binary EDID blob
   - nvidia,panel: phandle of a display panel
+  - operating-points-v2: See ../bindings/opp/opp.txt for details.
 
 - tvo: TV encoder output
 
@@ -277,6 +303,10 @@ of the following host1x client modules:
   - clocks: Must contain one entry, for the module clock.
     See ../clocks/clock-bindings.txt for details.
 
+  Optional properties:
+  - operating-points-v2: See ../bindings/opp/opp.txt for details.
+  - power-domains: Phandle to core power domain.
+
 - dsi: display serial interface
 
   Required properties:
@@ -305,6 +335,7 @@ of the following host1x client modules:
   - nvidia,panel: phandle of a display panel
   - nvidia,ganged-mode: contains a phandle to a second DSI controller to gang
     up with in order to support up to 8 data lanes
+  - operating-points-v2: See ../bindings/opp/opp.txt for details.
 
 - sor: serial output resource
 
@@ -408,6 +439,8 @@ Example:
 		clocks = <&tegra_car TEGRA20_CLK_HOST1X>;
 		resets = <&tegra_car 28>;
 		reset-names = "host1x";
+		operating-points-v2 = <&dvfs_opp_table>;
+		power-domains = <&domain>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -421,6 +454,8 @@ Example:
 			clocks = <&tegra_car TEGRA20_CLK_MPE>;
 			resets = <&tegra_car 60>;
 			reset-names = "mpe";
+			operating-points-v2 = <&dvfs_opp_table>;
+			power-domains = <&domain>;
 		};
 
 		vi at 54080000 {
@@ -429,6 +464,7 @@ Example:
 			interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
 			assigned-clocks = <&tegra_car TEGRA210_CLK_VI>;
 			assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_C4_OUT0>;
+			operating-points-v2 = <&dvfs_opp_table>;
 
 			clocks = <&tegra_car TEGRA210_CLK_VI>;
 			power-domains = <&pd_venc>;
@@ -510,6 +546,8 @@ Example:
 			clocks = <&tegra_car TEGRA20_CLK_EPP>;
 			resets = <&tegra_car 19>;
 			reset-names = "epp";
+			operating-points-v2 = <&dvfs_opp_table>;
+			power-domains = <&domain>;
 		};
 
 		isp {
@@ -528,6 +566,8 @@ Example:
 			clocks = <&tegra_car TEGRA20_CLK_GR2D>;
 			resets = <&tegra_car 21>;
 			reset-names = "2d";
+			operating-points-v2 = <&dvfs_opp_table>;
+			power-domains = <&domain>;
 		};
 
 		gr3d {
@@ -536,6 +576,8 @@ Example:
 			clocks = <&tegra_car TEGRA20_CLK_GR3D>;
 			resets = <&tegra_car 24>;
 			reset-names = "3d";
+			operating-points-v2 = <&dvfs_opp_table>;
+			power-domains = <&domain>;
 		};
 
 		dc at 54200000 {
@@ -547,6 +589,8 @@ Example:
 			clock-names = "dc", "parent";
 			resets = <&tegra_car 27>;
 			reset-names = "dc";
+			operating-points-v2 = <&dvfs_opp_table>;
+			power-domains = <&domain>;
 
 			interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,
 					<&mc TEGRA20_MC_DISPLAY0B &emc>,
@@ -571,6 +615,8 @@ Example:
 			clock-names = "dc", "parent";
 			resets = <&tegra_car 26>;
 			reset-names = "dc";
+			operating-points-v2 = <&dvfs_opp_table>;
+			power-domains = <&domain>;
 
 			interconnects = <&mc TEGRA20_MC_DISPLAY0AB &emc>,
 					<&mc TEGRA20_MC_DISPLAY0BB &emc>,
@@ -596,6 +642,7 @@ Example:
 			resets = <&tegra_car 51>;
 			reset-names = "hdmi";
 			status = "disabled";
+			operating-points-v2 = <&dvfs_opp_table>;
 		};
 
 		tvo {
@@ -604,6 +651,7 @@ Example:
 			interrupts = <0 76 0x04>;
 			clocks = <&tegra_car TEGRA20_CLK_TVO>;
 			status = "disabled";
+			operating-points-v2 = <&dvfs_opp_table>;
 		};
 
 		dsi {
@@ -615,6 +663,7 @@ Example:
 			resets = <&tegra_car 48>;
 			reset-names = "dsi";
 			status = "disabled";
+			operating-points-v2 = <&dvfs_opp_table>;
 		};
 	};
 
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:06 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:06 +0300
Subject: [PATCH v11 08/34] dt-bindings: host1x: Document Memory Client resets
 of Host1x, GR2D and GR3D
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-9-digetx@gmail.com>

Memory Client should be blocked before hardware reset is asserted in order
to prevent memory corruption and hanging of memory controller.

Document Memory Client resets of Host1x, GR2D and GR3D hardware units.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 .../bindings/display/tegra/nvidia,tegra20-host1x.txt          | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
index 62861a8fb5c6..e61999ce54e9 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
@@ -19,6 +19,7 @@ Required properties:
   See ../reset/reset.txt for details.
 - reset-names: Must include the following entries:
   - host1x
+  - mc
 
 Optional properties:
 - operating-points-v2: See ../bindings/opp/opp.txt for details.
@@ -198,6 +199,7 @@ of the following host1x client modules:
     See ../reset/reset.txt for details.
   - reset-names: Must include the following entries:
     - 2d
+    - mc
 
   Optional properties:
   - interconnects: Must contain entry for the GR2D memory clients.
@@ -224,6 +226,8 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - 3d
     - 3d2 (Only required on SoCs with two 3D clocks)
+    - mc
+    - mc2 (Only required on SoCs with two 3D clocks)
 
   Optional properties:
   - interconnects: Must contain entry for the GR3D memory clients.
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:07 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:07 +0300
Subject: [PATCH v11 09/34] gpu: host1x: Add runtime PM and OPP support
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-10-digetx@gmail.com>

Add runtime PM and OPP support to the Host1x driver. For the starter we
will keep host1x always-on because dynamic power management require a major
refactoring of the driver code since lot's of code paths are missing the
RPM handling and we're going to remove some of these paths in the future.

Tested-by: Peter Geis <pgwipeout at gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav at gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart at gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar at protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/gpu/host1x/debug.c         |  15 +++
 drivers/gpu/host1x/dev.c           | 151 +++++++++++++++++++++++------
 drivers/gpu/host1x/dev.h           |   3 +-
 drivers/gpu/host1x/hw/channel_hw.c |  44 ++++-----
 drivers/gpu/host1x/intr.c          |   3 -
 drivers/gpu/host1x/syncpt.c        |   5 +-
 6 files changed, 165 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
index 8a14880c61bb..18d9c8d206e3 100644
--- a/drivers/gpu/host1x/debug.c
+++ b/drivers/gpu/host1x/debug.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/debugfs.h>
+#include <linux/pm_runtime.h>
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
 
@@ -52,6 +53,11 @@ static int show_channel(struct host1x_channel *ch, void *data, bool show_fifo)
 {
 	struct host1x *m = dev_get_drvdata(ch->dev->parent);
 	struct output *o = data;
+	int err;
+
+	err = pm_runtime_resume_and_get(m->dev);
+	if (err < 0)
+		return err;
 
 	mutex_lock(&ch->cdma.lock);
 	mutex_lock(&debug_lock);
@@ -64,6 +70,8 @@ static int show_channel(struct host1x_channel *ch, void *data, bool show_fifo)
 	mutex_unlock(&debug_lock);
 	mutex_unlock(&ch->cdma.lock);
 
+	pm_runtime_put(m->dev);
+
 	return 0;
 }
 
@@ -71,9 +79,14 @@ static void show_syncpts(struct host1x *m, struct output *o)
 {
 	struct list_head *pos;
 	unsigned int i;
+	int err;
 
 	host1x_debug_output(o, "---- syncpts ----\n");
 
+	err = pm_runtime_resume_and_get(m->dev);
+	if (err < 0)
+		return;
+
 	for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
 		u32 max = host1x_syncpt_read_max(m->syncpt + i);
 		u32 min = host1x_syncpt_load(m->syncpt + i);
@@ -101,6 +114,8 @@ static void show_syncpts(struct host1x *m, struct output *o)
 					    base_val);
 	}
 
+	pm_runtime_put(m->dev);
+
 	host1x_debug_output(o, "\n");
 }
 
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index fbb6447b8659..595b91099e3e 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -6,14 +6,18 @@
  */
 
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/of.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
+#include <soc/tegra/common.h>
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/host1x.h>
 #undef CREATE_TRACE_POINTS
@@ -190,6 +194,9 @@ static void host1x_setup_sid_table(struct host1x *host)
 	const struct host1x_info *info = host->info;
 	unsigned int i;
 
+	if (!info->has_hypervisor)
+		return;
+
 	for (i = 0; i < info->num_sid_entries; i++) {
 		const struct host1x_sid_entry *entry = &info->sid_table[i];
 
@@ -347,6 +354,27 @@ static void host1x_iommu_exit(struct host1x *host)
 	}
 }
 
+static int host1x_get_resets(struct host1x *host)
+{
+	int err;
+
+	host->resets[0].id = "mc";
+	host->resets[1].id = "host1x";
+	host->nresets = ARRAY_SIZE(host->resets);
+
+	err = devm_reset_control_bulk_get_optional_exclusive_released(
+				host->dev, host->nresets, host->resets);
+	if (err) {
+		dev_err(host->dev, "failed to get reset: %d\n", err);
+		return err;
+	}
+
+	if (WARN_ON(!host->resets[1].rstc))
+		return -ENOENT;
+
+	return 0;
+}
+
 static int host1x_probe(struct platform_device *pdev)
 {
 	struct host1x *host;
@@ -423,12 +451,9 @@ static int host1x_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	host->rst = devm_reset_control_get(&pdev->dev, "host1x");
-	if (IS_ERR(host->rst)) {
-		err = PTR_ERR(host->rst);
-		dev_err(&pdev->dev, "failed to get reset: %d\n", err);
+	err = host1x_get_resets(host);
+	if (err)
 		return err;
-	}
 
 	err = host1x_iommu_init(host);
 	if (err < 0) {
@@ -443,22 +468,10 @@ static int host1x_probe(struct platform_device *pdev)
 		goto iommu_exit;
 	}
 
-	err = clk_prepare_enable(host->clk);
-	if (err < 0) {
-		dev_err(&pdev->dev, "failed to enable clock\n");
-		goto free_channels;
-	}
-
-	err = reset_control_deassert(host->rst);
-	if (err < 0) {
-		dev_err(&pdev->dev, "failed to deassert reset: %d\n", err);
-		goto unprepare_disable;
-	}
-
 	err = host1x_syncpt_init(host);
 	if (err) {
 		dev_err(&pdev->dev, "failed to initialize syncpts\n");
-		goto reset_assert;
+		goto free_channels;
 	}
 
 	err = host1x_intr_init(host, syncpt_irq);
@@ -467,10 +480,18 @@ static int host1x_probe(struct platform_device *pdev)
 		goto deinit_syncpt;
 	}
 
-	host1x_debug_init(host);
+	pm_runtime_enable(&pdev->dev);
+
+	err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
+	if (err)
+		goto pm_disable;
 
-	if (host->info->has_hypervisor)
-		host1x_setup_sid_table(host);
+	/* the driver's code isn't ready yet for the dynamic RPM */
+	err = pm_runtime_resume_and_get(&pdev->dev);
+	if (err)
+		goto pm_disable;
+
+	host1x_debug_init(host);
 
 	err = host1x_register(host);
 	if (err < 0)
@@ -486,13 +507,14 @@ static int host1x_probe(struct platform_device *pdev)
 	host1x_unregister(host);
 deinit_debugfs:
 	host1x_debug_deinit(host);
+
+	pm_runtime_put(&pdev->dev);
+pm_disable:
+	pm_runtime_disable(&pdev->dev);
+
 	host1x_intr_deinit(host);
 deinit_syncpt:
 	host1x_syncpt_deinit(host);
-reset_assert:
-	reset_control_assert(host->rst);
-unprepare_disable:
-	clk_disable_unprepare(host->clk);
 free_channels:
 	host1x_channel_list_free(&host->channel_list);
 iommu_exit:
@@ -507,19 +529,94 @@ static int host1x_remove(struct platform_device *pdev)
 
 	host1x_unregister(host);
 	host1x_debug_deinit(host);
+
+	pm_runtime_put(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
 	host1x_intr_deinit(host);
 	host1x_syncpt_deinit(host);
-	reset_control_assert(host->rst);
-	clk_disable_unprepare(host->clk);
 	host1x_iommu_exit(host);
 
 	return 0;
 }
 
+static int __maybe_unused host1x_runtime_suspend(struct device *dev)
+{
+	struct host1x *host = dev_get_drvdata(dev);
+	int err;
+
+	host1x_intr_stop(host);
+	host1x_syncpt_save(host);
+
+	err = reset_control_bulk_assert(host->nresets, host->resets);
+	if (err) {
+		dev_err(dev, "failed to assert reset: %d\n", err);
+		goto resume_host1x;
+	}
+
+	usleep_range(1000, 2000);
+
+	clk_disable_unprepare(host->clk);
+	reset_control_bulk_release(host->nresets, host->resets);
+
+	return 0;
+
+resume_host1x:
+	host1x_setup_sid_table(host);
+	host1x_syncpt_restore(host);
+	host1x_intr_start(host);
+
+	return err;
+}
+
+static int __maybe_unused host1x_runtime_resume(struct device *dev)
+{
+	struct host1x *host = dev_get_drvdata(dev);
+	int err;
+
+	err = reset_control_bulk_acquire(host->nresets, host->resets);
+	if (err) {
+		dev_err(dev, "failed to acquire reset: %d\n", err);
+		return err;
+	}
+
+	err = clk_prepare_enable(host->clk);
+	if (err) {
+		dev_err(dev, "failed to enable clock: %d\n", err);
+		goto release_reset;
+	}
+
+	err = reset_control_bulk_deassert(host->nresets, host->resets);
+	if (err < 0) {
+		dev_err(dev, "failed to deassert reset: %d\n", err);
+		goto disable_clk;
+	}
+
+	host1x_setup_sid_table(host);
+	host1x_syncpt_restore(host);
+	host1x_intr_start(host);
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(host->clk);
+release_reset:
+	reset_control_bulk_release(host->nresets, host->resets);
+
+	return err;
+}
+
+static const struct dev_pm_ops host1x_pm = {
+	SET_RUNTIME_PM_OPS(host1x_runtime_suspend, host1x_runtime_resume,
+			   NULL)
+	/* TODO: add system suspend-resume once driver will be ready for that */
+};
+
 static struct platform_driver tegra_host1x_driver = {
 	.driver = {
 		.name = "tegra-host1x",
 		.of_match_table = host1x_of_match,
+		.pm = &host1x_pm,
 	},
 	.probe = host1x_probe,
 	.remove = host1x_remove,
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index fa6d4bc46e98..41a7a63514c4 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -118,7 +118,8 @@ struct host1x {
 	struct host1x_syncpt_base *bases;
 	struct device *dev;
 	struct clk *clk;
-	struct reset_control *rst;
+	struct reset_control_bulk_data resets[2];
+	unsigned int nresets;
 
 	struct iommu_group *group;
 	struct iommu_domain *domain;
diff --git a/drivers/gpu/host1x/hw/channel_hw.c b/drivers/gpu/host1x/hw/channel_hw.c
index 1999780a7203..6b40e9af1e88 100644
--- a/drivers/gpu/host1x/hw/channel_hw.c
+++ b/drivers/gpu/host1x/hw/channel_hw.c
@@ -159,6 +159,27 @@ static void host1x_channel_set_streamid(struct host1x_channel *channel)
 #endif
 }
 
+static void host1x_enable_gather_filter(struct host1x_channel *ch)
+{
+#if HOST1X_HW >= 6
+	struct host1x *host = dev_get_drvdata(ch->dev->parent);
+	u32 val;
+
+	if (!host->hv_regs)
+		return;
+
+	val = host1x_hypervisor_readl(
+		host, HOST1X_HV_CH_KERNEL_FILTER_GBUFFER(ch->id / 32));
+	val |= BIT(ch->id % 32);
+	host1x_hypervisor_writel(
+		host, val, HOST1X_HV_CH_KERNEL_FILTER_GBUFFER(ch->id / 32));
+#elif HOST1X_HW >= 4
+	host1x_ch_writel(ch,
+			 HOST1X_CHANNEL_CHANNELCTRL_KERNEL_FILTER_GBUFFER(1),
+			 HOST1X_CHANNEL_CHANNELCTRL);
+#endif
+}
+
 static int channel_submit(struct host1x_job *job)
 {
 	struct host1x_channel *ch = job->channel;
@@ -190,6 +211,7 @@ static int channel_submit(struct host1x_job *job)
 	}
 
 	host1x_channel_set_streamid(ch);
+	host1x_enable_gather_filter(ch);
 
 	/* begin a CDMA submit */
 	err = host1x_cdma_begin(&ch->cdma, job);
@@ -249,27 +271,6 @@ static int channel_submit(struct host1x_job *job)
 	return err;
 }
 
-static void enable_gather_filter(struct host1x *host,
-				 struct host1x_channel *ch)
-{
-#if HOST1X_HW >= 6
-	u32 val;
-
-	if (!host->hv_regs)
-		return;
-
-	val = host1x_hypervisor_readl(
-		host, HOST1X_HV_CH_KERNEL_FILTER_GBUFFER(ch->id / 32));
-	val |= BIT(ch->id % 32);
-	host1x_hypervisor_writel(
-		host, val, HOST1X_HV_CH_KERNEL_FILTER_GBUFFER(ch->id / 32));
-#elif HOST1X_HW >= 4
-	host1x_ch_writel(ch,
-			 HOST1X_CHANNEL_CHANNELCTRL_KERNEL_FILTER_GBUFFER(1),
-			 HOST1X_CHANNEL_CHANNELCTRL);
-#endif
-}
-
 static int host1x_channel_init(struct host1x_channel *ch, struct host1x *dev,
 			       unsigned int index)
 {
@@ -278,7 +279,6 @@ static int host1x_channel_init(struct host1x_channel *ch, struct host1x *dev,
 #else
 	ch->regs = dev->regs + index * 0x100;
 #endif
-	enable_gather_filter(dev, ch);
 	return 0;
 }
 
diff --git a/drivers/gpu/host1x/intr.c b/drivers/gpu/host1x/intr.c
index 45b6be927ec4..965ba21818b1 100644
--- a/drivers/gpu/host1x/intr.c
+++ b/drivers/gpu/host1x/intr.c
@@ -297,14 +297,11 @@ int host1x_intr_init(struct host1x *host, unsigned int irq_sync)
 			 "host1x_sp_%02u", id);
 	}
 
-	host1x_intr_start(host);
-
 	return 0;
 }
 
 void host1x_intr_deinit(struct host1x *host)
 {
-	host1x_intr_stop(host);
 }
 
 void host1x_intr_start(struct host1x *host)
diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
index d198a10848c6..e08e331e46ae 100644
--- a/drivers/gpu/host1x/syncpt.c
+++ b/drivers/gpu/host1x/syncpt.c
@@ -143,6 +143,8 @@ void host1x_syncpt_restore(struct host1x *host)
 	for (i = 0; i < host1x_syncpt_nb_bases(host); i++)
 		host1x_hw_syncpt_restore_wait_base(host, sp_base + i);
 
+	host1x_hw_syncpt_enable_protection(host);
+
 	wmb();
 }
 
@@ -366,9 +368,6 @@ int host1x_syncpt_init(struct host1x *host)
 	host->syncpt = syncpt;
 	host->bases = bases;
 
-	host1x_syncpt_restore(host);
-	host1x_hw_syncpt_enable_protection(host);
-
 	/* Allocate sync point to use for clearing waits for expired fences */
 	host->nop_sp = host1x_syncpt_alloc(host, 0, "reserved-nop");
 	if (!host->nop_sp)
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:08 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:08 +0300
Subject: [PATCH v11 10/34] gpu: host1x: Add host1x_channel_stop()
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-11-digetx@gmail.com>

Add host1x_channel_stop() which waits till channel becomes idle and then
stops the channel hardware. This is needed for supporting suspend/resume
by host1x drivers since the hardware state is lost after power-gating,
thus the channel needs to be stopped before client enters into suspend.

Tested-by: Peter Geis <pgwipeout at gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav at gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart at gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar at protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/gpu/host1x/channel.c | 8 ++++++++
 include/linux/host1x.h       | 1 +
 2 files changed, 9 insertions(+)

diff --git a/drivers/gpu/host1x/channel.c b/drivers/gpu/host1x/channel.c
index 4cd212bb570d..2a9a3a8d5931 100644
--- a/drivers/gpu/host1x/channel.c
+++ b/drivers/gpu/host1x/channel.c
@@ -75,6 +75,14 @@ struct host1x_channel *host1x_channel_get_index(struct host1x *host,
 	return ch;
 }
 
+void host1x_channel_stop(struct host1x_channel *channel)
+{
+	struct host1x *host = dev_get_drvdata(channel->dev->parent);
+
+	host1x_hw_cdma_stop(host, &channel->cdma);
+}
+EXPORT_SYMBOL(host1x_channel_stop);
+
 static void release_channel(struct kref *kref)
 {
 	struct host1x_channel *channel =
diff --git a/include/linux/host1x.h b/include/linux/host1x.h
index 7bccf589aba7..66473b5be0af 100644
--- a/include/linux/host1x.h
+++ b/include/linux/host1x.h
@@ -181,6 +181,7 @@ struct host1x_job;
 
 struct host1x_channel *host1x_channel_request(struct host1x_client *client);
 struct host1x_channel *host1x_channel_get(struct host1x_channel *channel);
+void host1x_channel_stop(struct host1x_channel *channel);
 void host1x_channel_put(struct host1x_channel *channel);
 int host1x_job_submit(struct host1x_job *job);
 
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:09 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:09 +0300
Subject: [PATCH v11 11/34] drm/tegra: dc: Support OPP and SoC core voltage
 scaling
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-12-digetx@gmail.com>

Add OPP and SoC core voltage scaling support to the display controller
driver. This is required for enabling system-wide DVFS on pre-Tegra186
SoCs.

Tested-by: Peter Geis <pgwipeout at gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav at gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart at gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar at protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/gpu/drm/tegra/dc.c | 74 ++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/tegra/dc.h |  2 ++
 2 files changed, 76 insertions(+)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index a29d64f87563..d4047a14e2b6 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -11,9 +11,12 @@
 #include <linux/interconnect.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
 #include <linux/pm_runtime.h>
 #include <linux/reset.h>
 
+#include <soc/tegra/common.h>
 #include <soc/tegra/pmc.h>
 
 #include <drm/drm_atomic.h>
@@ -1762,6 +1765,47 @@ int tegra_dc_state_setup_clock(struct tegra_dc *dc,
 	return 0;
 }
 
+static void tegra_dc_update_voltage_state(struct tegra_dc *dc,
+					  struct tegra_dc_state *state)
+{
+	unsigned long rate, pstate;
+	struct dev_pm_opp *opp;
+	int err;
+
+	if (!dc->has_opp_table)
+		return;
+
+	/* calculate actual pixel clock rate which depends on internal divider */
+	rate = DIV_ROUND_UP(clk_get_rate(dc->clk) * 2, state->div + 2);
+
+	/* find suitable OPP for the rate */
+	opp = dev_pm_opp_find_freq_ceil(dc->dev, &rate);
+
+	if (opp == ERR_PTR(-ERANGE))
+		opp = dev_pm_opp_find_freq_floor(dc->dev, &rate);
+
+	if (IS_ERR(opp)) {
+		dev_err(dc->dev, "failed to find OPP for %luHz: %pe\n",
+			rate, opp);
+		return;
+	}
+
+	pstate = dev_pm_opp_get_required_pstate(opp, 0);
+	dev_pm_opp_put(opp);
+
+	/*
+	 * The minimum core voltage depends on the pixel clock rate (which
+	 * depends on internal clock divider of the CRTC) and not on the
+	 * rate of the display controller clock. This is why we're not using
+	 * dev_pm_opp_set_rate() API and instead controlling the power domain
+	 * directly.
+	 */
+	err = dev_pm_genpd_set_performance_state(dc->dev, pstate);
+	if (err)
+		dev_err(dc->dev, "failed to set power domain state to %lu: %d\n",
+			pstate, err);
+}
+
 static void tegra_dc_commit_state(struct tegra_dc *dc,
 				  struct tegra_dc_state *state)
 {
@@ -1801,6 +1845,8 @@ static void tegra_dc_commit_state(struct tegra_dc *dc,
 		value = SHIFT_CLK_DIVIDER(state->div) | PIXEL_CLK_DIVIDER_PCD1;
 		tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
 	}
+
+	tegra_dc_update_voltage_state(dc, state);
 }
 
 static void tegra_dc_stop(struct tegra_dc *dc)
@@ -1991,6 +2037,13 @@ static void tegra_crtc_atomic_disable(struct drm_crtc *crtc,
 	err = host1x_client_suspend(&dc->client);
 	if (err < 0)
 		dev_err(dc->dev, "failed to suspend: %d\n", err);
+
+	if (dc->has_opp_table) {
+		err = dev_pm_genpd_set_performance_state(dc->dev, 0);
+		if (err)
+			dev_err(dc->dev,
+				"failed to clear power domain state: %d\n", err);
+	}
 }
 
 static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
@@ -2973,6 +3026,23 @@ static int tegra_dc_couple(struct tegra_dc *dc)
 	return 0;
 }
 
+static int tegra_dc_init_opp_table(struct tegra_dc *dc)
+{
+	struct tegra_core_opp_params opp_params = {};
+	int err;
+
+	err = devm_tegra_core_dev_init_opp_table(dc->dev, &opp_params);
+	if (err && err != -ENODEV)
+		return err;
+
+	if (err)
+		dc->has_opp_table = false;
+	else
+		dc->has_opp_table = true;
+
+	return 0;
+}
+
 static int tegra_dc_probe(struct platform_device *pdev)
 {
 	u64 dma_mask = dma_get_mask(pdev->dev.parent);
@@ -3038,6 +3108,10 @@ static int tegra_dc_probe(struct platform_device *pdev)
 		tegra_powergate_power_off(dc->powergate);
 	}
 
+	err = tegra_dc_init_opp_table(dc);
+	if (err < 0)
+		return err;
+
 	dc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dc->regs))
 		return PTR_ERR(dc->regs);
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 40378308d527..871cfb0cd31c 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -100,6 +100,8 @@ struct tegra_dc {
 	struct drm_info_list *debugfs_files;
 
 	const struct tegra_dc_soc_info *soc;
+
+	bool has_opp_table;
 };
 
 static inline struct tegra_dc *
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:10 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:10 +0300
Subject: [PATCH v11 12/34] drm/tegra: hdmi: Add OPP support
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-13-digetx@gmail.com>

The HDMI on Tegra belongs to the core power domain and we're going to
enable GENPD support for the core domain. Now HDMI driver must use
OPP API for driving the controller's clock rate because OPP API takes
care of reconfiguring the domain's performance state based on HDMI clock
rate. Add OPP support to the HDMI driver.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/gpu/drm/tegra/hdmi.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index e5d2a4026028..9a87d351a828 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -11,10 +11,13 @@
 #include <linux/math64.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_opp.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 
+#include <soc/tegra/common.h>
+
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_crtc.h>
 #include <drm/drm_debugfs.h>
@@ -1195,7 +1198,7 @@ static void tegra_hdmi_encoder_enable(struct drm_encoder *encoder)
 	h_back_porch = mode->htotal - mode->hsync_end;
 	h_front_porch = mode->hsync_start - mode->hdisplay;
 
-	err = clk_set_rate(hdmi->clk, hdmi->pixel_clock);
+	err = dev_pm_opp_set_rate(hdmi->dev, hdmi->pixel_clock);
 	if (err < 0) {
 		dev_err(hdmi->dev, "failed to set HDMI clock frequency: %d\n",
 			err);
@@ -1732,7 +1735,14 @@ static int tegra_hdmi_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, hdmi);
-	pm_runtime_enable(&pdev->dev);
+
+	err = devm_pm_runtime_enable(&pdev->dev);
+	if (err)
+		return err;
+
+	err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
+	if (err)
+		return err;
 
 	INIT_LIST_HEAD(&hdmi->client.list);
 	hdmi->client.ops = &hdmi_client_ops;
@@ -1753,8 +1763,6 @@ static int tegra_hdmi_remove(struct platform_device *pdev)
 	struct tegra_hdmi *hdmi = platform_get_drvdata(pdev);
 	int err;
 
-	pm_runtime_disable(&pdev->dev);
-
 	err = host1x_client_unregister(&hdmi->client);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:11 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:11 +0300
Subject: [PATCH v11 13/34] drm/tegra: gr2d: Support generic power domain and
 runtime PM
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-14-digetx@gmail.com>

Add runtime power management and support generic power domains.

Tested-by: Peter Geis <pgwipeout at gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav at gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart at gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar at protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/gpu/drm/tegra/gr2d.c | 155 +++++++++++++++++++++++++++++++++--
 1 file changed, 147 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
index de288cba3905..13df8f118f75 100644
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ b/drivers/gpu/drm/tegra/gr2d.c
@@ -7,11 +7,21 @@
 #include <linux/iommu.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include <soc/tegra/common.h>
 
 #include "drm.h"
 #include "gem.h"
 #include "gr2d.h"
 
+enum {
+	RST_MC,
+	RST_GR2D,
+	RST_GR2D_MAX,
+};
+
 struct gr2d_soc {
 	unsigned int version;
 };
@@ -21,6 +31,9 @@ struct gr2d {
 	struct host1x_channel *channel;
 	struct clk *clk;
 
+	struct reset_control_bulk_data resets[RST_GR2D_MAX];
+	unsigned int nresets;
+
 	const struct gr2d_soc *soc;
 
 	DECLARE_BITMAP(addr_regs, GR2D_NUM_REGS);
@@ -101,16 +114,24 @@ static int gr2d_open_channel(struct tegra_drm_client *client,
 			     struct tegra_drm_context *context)
 {
 	struct gr2d *gr2d = to_gr2d(client);
+	int err;
 
 	context->channel = host1x_channel_get(gr2d->channel);
 	if (!context->channel)
 		return -ENOMEM;
 
+	err = pm_runtime_resume_and_get(client->base.dev);
+	if (err) {
+		host1x_channel_put(context->channel);
+		return err;
+	}
+
 	return 0;
 }
 
 static void gr2d_close_channel(struct tegra_drm_context *context)
 {
+	pm_runtime_put_sync(context->client->base.dev);
 	host1x_channel_put(context->channel);
 }
 
@@ -190,6 +211,27 @@ static const u32 gr2d_addr_regs[] = {
 	GR2D_VA_BASE_ADDR_SB,
 };
 
+static int gr2d_get_resets(struct device *dev, struct gr2d *gr2d)
+{
+	int err;
+
+	gr2d->resets[RST_MC].id = "mc";
+	gr2d->resets[RST_GR2D].id = "2d";
+	gr2d->nresets = RST_GR2D_MAX;
+
+	err = devm_reset_control_bulk_get_optional_exclusive_released(
+				dev, gr2d->nresets, gr2d->resets);
+	if (err) {
+		dev_err(dev, "failed to get reset: %d\n", err);
+		return err;
+	}
+
+	if (WARN_ON(!gr2d->resets[RST_GR2D].rstc))
+		return -ENOENT;
+
+	return 0;
+}
+
 static int gr2d_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -202,6 +244,8 @@ static int gr2d_probe(struct platform_device *pdev)
 	if (!gr2d)
 		return -ENOMEM;
 
+	platform_set_drvdata(pdev, gr2d);
+
 	gr2d->soc = of_device_get_match_data(dev);
 
 	syncpts = devm_kzalloc(dev, sizeof(*syncpts), GFP_KERNEL);
@@ -214,11 +258,9 @@ static int gr2d_probe(struct platform_device *pdev)
 		return PTR_ERR(gr2d->clk);
 	}
 
-	err = clk_prepare_enable(gr2d->clk);
-	if (err) {
-		dev_err(dev, "cannot turn on clock\n");
+	err = gr2d_get_resets(dev, gr2d);
+	if (err)
 		return err;
-	}
 
 	INIT_LIST_HEAD(&gr2d->client.base.list);
 	gr2d->client.base.ops = &gr2d_client_ops;
@@ -231,20 +273,31 @@ static int gr2d_probe(struct platform_device *pdev)
 	gr2d->client.version = gr2d->soc->version;
 	gr2d->client.ops = &gr2d_ops;
 
+	pm_runtime_enable(dev);
+	pm_runtime_use_autosuspend(dev);
+	pm_runtime_set_autosuspend_delay(dev, 200);
+
+	err = devm_tegra_core_dev_init_opp_table_common(dev);
+	if (err)
+		goto disable_rpm;
+
 	err = host1x_client_register(&gr2d->client.base);
 	if (err < 0) {
 		dev_err(dev, "failed to register host1x client: %d\n", err);
-		clk_disable_unprepare(gr2d->clk);
-		return err;
+		goto disable_rpm;
 	}
 
 	/* initialize address register map */
 	for (i = 0; i < ARRAY_SIZE(gr2d_addr_regs); i++)
 		set_bit(gr2d_addr_regs[i], gr2d->addr_regs);
 
-	platform_set_drvdata(pdev, gr2d);
-
 	return 0;
+
+disable_rpm:
+	pm_runtime_dont_use_autosuspend(dev);
+	pm_runtime_disable(dev);
+
+	return err;
 }
 
 static int gr2d_remove(struct platform_device *pdev)
@@ -259,15 +312,101 @@ static int gr2d_remove(struct platform_device *pdev)
 		return err;
 	}
 
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static int __maybe_unused gr2d_runtime_suspend(struct device *dev)
+{
+	struct gr2d *gr2d = dev_get_drvdata(dev);
+	int err;
+
+	host1x_channel_stop(gr2d->channel);
+	reset_control_bulk_release(gr2d->nresets, gr2d->resets);
+
+	/*
+	 * GR2D module shouldn't be reset while hardware is idling, otherwise
+	 * host1x's cmdproc will stuck on trying to access any G2 register
+	 * after reset. GR2D module could be either hot-reset or reset after
+	 * power-gating of the HEG partition. Hence we will put in reset only
+	 * the memory client part of the module, the HEG GENPD will take care
+	 * of resetting GR2D module across power-gating.
+	 *
+	 * On Tegra20 there is no HEG partition, but it's okay to have
+	 * undetermined h/w state since userspace is expected to reprogram
+	 * the state on each job submission anyways.
+	 */
+	err = reset_control_acquire(gr2d->resets[RST_MC].rstc);
+	if (err) {
+		dev_err(dev, "failed to acquire MC reset: %d\n", err);
+		goto acquire_reset;
+	}
+
+	err = reset_control_assert(gr2d->resets[RST_MC].rstc);
+	reset_control_release(gr2d->resets[RST_MC].rstc);
+	if (err) {
+		dev_err(dev, "failed to assert MC reset: %d\n", err);
+		goto acquire_reset;
+	}
+
 	clk_disable_unprepare(gr2d->clk);
 
 	return 0;
+
+acquire_reset:
+	reset_control_bulk_acquire(gr2d->nresets, gr2d->resets);
+	reset_control_bulk_deassert(gr2d->nresets, gr2d->resets);
+
+	return err;
 }
 
+static int __maybe_unused gr2d_runtime_resume(struct device *dev)
+{
+	struct gr2d *gr2d = dev_get_drvdata(dev);
+	int err;
+
+	err = reset_control_bulk_acquire(gr2d->nresets, gr2d->resets);
+	if (err) {
+		dev_err(dev, "failed to acquire reset: %d\n", err);
+		return err;
+	}
+
+	err = clk_prepare_enable(gr2d->clk);
+	if (err) {
+		dev_err(dev, "failed to enable clock: %d\n", err);
+		goto release_reset;
+	}
+
+	/* this is a reset array which deasserts both 2D MC and 2D itself */
+	err = reset_control_bulk_deassert(gr2d->nresets, gr2d->resets);
+	if (err) {
+		dev_err(dev, "failed to deassert reset: %d\n", err);
+		goto disable_clk;
+	}
+
+	return 0;
+
+disable_clk:
+	clk_disable_unprepare(gr2d->clk);
+release_reset:
+	reset_control_bulk_release(gr2d->nresets, gr2d->resets);
+
+	return err;
+}
+
+static const struct dev_pm_ops tegra_gr2d_pm = {
+	SET_RUNTIME_PM_OPS(gr2d_runtime_suspend, gr2d_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
 struct platform_driver tegra_gr2d_driver = {
 	.driver = {
 		.name = "tegra-gr2d",
 		.of_match_table = gr2d_match,
+		.pm = &tegra_gr2d_pm,
 	},
 	.probe = gr2d_probe,
 	.remove = gr2d_remove,
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:12 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:12 +0300
Subject: [PATCH v11 14/34] drm/tegra: gr3d: Support generic power domain and
 runtime PM
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-15-digetx@gmail.com>

Add runtime power management and support generic power domains.

Tested-by: Peter Geis <pgwipeout at gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav at gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart at gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar at protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/gpu/drm/tegra/gr3d.c | 388 ++++++++++++++++++++++++++++++-----
 1 file changed, 332 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c
index 24442ade0da3..5879402ae55e 100644
--- a/drivers/gpu/drm/tegra/gr3d.c
+++ b/drivers/gpu/drm/tegra/gr3d.c
@@ -5,32 +5,47 @@
  */
 
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/host1x.h>
 #include <linux/iommu.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_runtime.h>
 #include <linux/reset.h>
 
+#include <soc/tegra/common.h>
 #include <soc/tegra/pmc.h>
 
 #include "drm.h"
 #include "gem.h"
 #include "gr3d.h"
 
+enum {
+	RST_MC,
+	RST_GR3D,
+	RST_MC2,
+	RST_GR3D2,
+	RST_GR3D_MAX,
+};
+
 struct gr3d_soc {
 	unsigned int version;
+	unsigned int num_clocks;
+	unsigned int num_resets;
 };
 
 struct gr3d {
 	struct tegra_drm_client client;
 	struct host1x_channel *channel;
-	struct clk *clk_secondary;
-	struct clk *clk;
-	struct reset_control *rst_secondary;
-	struct reset_control *rst;
 
 	const struct gr3d_soc *soc;
+	struct clk_bulk_data *clocks;
+	unsigned int nclocks;
+	struct reset_control_bulk_data resets[RST_GR3D_MAX];
+	unsigned int nresets;
 
 	DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS);
 };
@@ -109,16 +124,24 @@ static int gr3d_open_channel(struct tegra_drm_client *client,
 			     struct tegra_drm_context *context)
 {
 	struct gr3d *gr3d = to_gr3d(client);
+	int err;
 
 	context->channel = host1x_channel_get(gr3d->channel);
 	if (!context->channel)
 		return -ENOMEM;
 
+	err = pm_runtime_resume_and_get(client->base.dev);
+	if (err) {
+		host1x_channel_put(context->channel);
+		return err;
+	}
+
 	return 0;
 }
 
 static void gr3d_close_channel(struct tegra_drm_context *context)
 {
+	pm_runtime_put_sync(context->client->base.dev);
 	host1x_channel_put(context->channel);
 }
 
@@ -155,14 +178,20 @@ static const struct tegra_drm_client_ops gr3d_ops = {
 
 static const struct gr3d_soc tegra20_gr3d_soc = {
 	.version = 0x20,
+	.num_clocks = 1,
+	.num_resets = 2,
 };
 
 static const struct gr3d_soc tegra30_gr3d_soc = {
 	.version = 0x30,
+	.num_clocks = 2,
+	.num_resets = 4,
 };
 
 static const struct gr3d_soc tegra114_gr3d_soc = {
 	.version = 0x35,
+	.num_clocks = 1,
+	.num_resets = 2,
 };
 
 static const struct of_device_id tegra_gr3d_match[] = {
@@ -278,69 +307,240 @@ static const u32 gr3d_addr_regs[] = {
 	GR3D_GLOBAL_SAMP23SURFADDR(15),
 };
 
-static int gr3d_probe(struct platform_device *pdev)
+static int gr3d_power_up_legacy_domain(struct device *dev, const char *name,
+				       unsigned int id)
 {
-	struct device_node *np = pdev->dev.of_node;
-	struct host1x_syncpt **syncpts;
-	struct gr3d *gr3d;
+	struct gr3d *gr3d = dev_get_drvdata(dev);
+	struct reset_control *reset;
+	struct clk *clk;
 	unsigned int i;
 	int err;
 
-	gr3d = devm_kzalloc(&pdev->dev, sizeof(*gr3d), GFP_KERNEL);
-	if (!gr3d)
-		return -ENOMEM;
-
-	gr3d->soc = of_device_get_match_data(&pdev->dev);
+	/*
+	 * Tegra20 device-tree doesn't specify 3d clock name and there is only
+	 * one clock for Tegra20. Tegra30+ device-trees always specified names
+	 * for the clocks.
+	 */
+	if (gr3d->nclocks == 1) {
+		if (id == TEGRA_POWERGATE_3D1)
+			return 0;
+
+		clk = gr3d->clocks[0].clk;
+	} else {
+		for (i = 0; i < gr3d->nclocks; i++) {
+			if (WARN_ON(!gr3d->clocks[i].id))
+				continue;
+
+			if (!strcmp(gr3d->clocks[i].id, name)) {
+				clk = gr3d->clocks[i].clk;
+				break;
+			}
+		}
 
-	syncpts = devm_kzalloc(&pdev->dev, sizeof(*syncpts), GFP_KERNEL);
-	if (!syncpts)
-		return -ENOMEM;
+		if (WARN_ON(i == gr3d->nclocks))
+			return -EINVAL;
+	}
 
-	gr3d->clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(gr3d->clk)) {
-		dev_err(&pdev->dev, "cannot get clock\n");
-		return PTR_ERR(gr3d->clk);
+	/*
+	 * We use array of resets, which includes MC resets, and MC
+	 * reset shouldn't be asserted while hardware is gated because
+	 * MC flushing will fail for gated hardware. Hence for legacy
+	 * PD we request the individual reset separately.
+	 */
+	reset = reset_control_get_exclusive_released(dev, name);
+	if (IS_ERR(reset))
+		return PTR_ERR(reset);
+
+	err = reset_control_acquire(reset);
+	if (err) {
+		dev_err(dev, "failed to acquire %s reset: %d\n", name, err);
+	} else {
+		err = tegra_powergate_sequence_power_up(id, clk, reset);
+		reset_control_release(reset);
 	}
 
-	gr3d->rst = devm_reset_control_get(&pdev->dev, "3d");
-	if (IS_ERR(gr3d->rst)) {
-		dev_err(&pdev->dev, "cannot get reset\n");
-		return PTR_ERR(gr3d->rst);
+	reset_control_put(reset);
+	if (err)
+		return err;
+
+	/*
+	 * tegra_powergate_sequence_power_up() leaves clocks enabled
+	 * while GENPD not, hence keep clock-enable balanced.
+	 */
+	clk_disable_unprepare(clk);
+
+	return 0;
+}
+
+static void gr3d_del_link(void *link)
+{
+	device_link_del(link);
+}
+
+static int gr3d_init_power(struct device *dev, struct gr3d *gr3d)
+{
+	static const char * const opp_genpd_names[] = { "3d0", "3d1", NULL };
+	const u32 link_flags = DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME;
+	struct device **opp_virt_devs, *pd_dev;
+	struct device_link *link;
+	unsigned int i;
+	int err;
+
+	err = of_count_phandle_with_args(dev->of_node, "power-domains",
+					 "#power-domain-cells");
+	if (err < 0) {
+		if (err != -ENOENT)
+			return err;
+
+		/*
+		 * Older device-trees don't use GENPD. In this case we should
+		 * toggle power domain manually.
+		 */
+		err = gr3d_power_up_legacy_domain(dev, "3d",
+						  TEGRA_POWERGATE_3D);
+		if (err)
+			return err;
+
+		err = gr3d_power_up_legacy_domain(dev, "3d2",
+						  TEGRA_POWERGATE_3D1);
+		if (err)
+			return err;
+
+		return 0;
 	}
 
-	if (of_device_is_compatible(np, "nvidia,tegra30-gr3d")) {
-		gr3d->clk_secondary = devm_clk_get(&pdev->dev, "3d2");
-		if (IS_ERR(gr3d->clk_secondary)) {
-			dev_err(&pdev->dev, "cannot get secondary clock\n");
-			return PTR_ERR(gr3d->clk_secondary);
+	/*
+	 * The PM domain core automatically attaches a single power domain,
+	 * otherwise it skips attaching completely. We have a single domain
+	 * on Tegra20 and two domains on Tegra30+.
+	 */
+	if (dev->pm_domain)
+		return 0;
+
+	err = devm_pm_opp_attach_genpd(dev, opp_genpd_names, &opp_virt_devs);
+	if (err)
+		return err;
+
+	for (i = 0; opp_genpd_names[i]; i++) {
+		pd_dev = opp_virt_devs[i];
+		if (!pd_dev) {
+			dev_err(dev, "failed to get %s power domain\n",
+				opp_genpd_names[i]);
+			return -EINVAL;
 		}
 
-		gr3d->rst_secondary = devm_reset_control_get(&pdev->dev,
-								"3d2");
-		if (IS_ERR(gr3d->rst_secondary)) {
-			dev_err(&pdev->dev, "cannot get secondary reset\n");
-			return PTR_ERR(gr3d->rst_secondary);
+		link = device_link_add(dev, pd_dev, link_flags);
+		if (!link) {
+			dev_err(dev, "failed to link to %s\n", dev_name(pd_dev));
+			return -EINVAL;
 		}
+
+		err = devm_add_action_or_reset(dev, gr3d_del_link, link);
+		if (err)
+			return err;
 	}
 
-	err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D, gr3d->clk,
-						gr3d->rst);
+	return 0;
+}
+
+static int gr3d_set_opp(struct dev_pm_set_opp_data *data)
+{
+	struct gr3d *gr3d = dev_get_drvdata(data->dev);
+	unsigned int i;
+	int err;
+
+	for (i = 0; i < gr3d->nclocks; i++) {
+		err = clk_set_rate(gr3d->clocks[i].clk, data->new_opp.rate);
+		if (err) {
+			dev_err(data->dev, "failed to set %s rate to %lu: %d\n",
+				gr3d->clocks[i].id, data->new_opp.rate, err);
+			goto restore;
+		}
+	}
+
+	return 0;
+
+restore:
+	while (i--)
+		clk_set_rate(gr3d->clocks[i].clk, data->old_opp.rate);
+
+	return err;
+}
+
+static int gr3d_get_clocks(struct device *dev, struct gr3d *gr3d)
+{
+	int err;
+
+	err = devm_clk_bulk_get_all(dev, &gr3d->clocks);
 	if (err < 0) {
-		dev_err(&pdev->dev, "failed to power up 3D unit\n");
+		dev_err(dev, "failed to get clock: %d\n", err);
 		return err;
 	}
+	gr3d->nclocks = err;
 
-	if (gr3d->clk_secondary) {
-		err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_3D1,
-							gr3d->clk_secondary,
-							gr3d->rst_secondary);
-		if (err < 0) {
-			dev_err(&pdev->dev,
-				"failed to power up secondary 3D unit\n");
-			return err;
-		}
+	if (gr3d->nclocks != gr3d->soc->num_clocks) {
+		dev_err(dev, "invalid number of clocks: %u\n", gr3d->nclocks);
+		return -ENOENT;
 	}
 
+	return 0;
+}
+
+static int gr3d_get_resets(struct device *dev, struct gr3d *gr3d)
+{
+	int err;
+
+	gr3d->resets[RST_MC].id = "mc";
+	gr3d->resets[RST_MC2].id = "mc2";
+	gr3d->resets[RST_GR3D].id = "3d";
+	gr3d->resets[RST_GR3D2].id = "3d2";
+	gr3d->nresets = gr3d->soc->num_resets;
+
+	err = devm_reset_control_bulk_get_optional_exclusive_released(
+				dev, gr3d->nresets, gr3d->resets);
+	if (err) {
+		dev_err(dev, "failed to get reset: %d\n", err);
+		return err;
+	}
+
+	if (WARN_ON(!gr3d->resets[RST_GR3D].rstc) ||
+	    WARN_ON(!gr3d->resets[RST_GR3D2].rstc && gr3d->nresets == 4))
+		return -ENOENT;
+
+	return 0;
+}
+
+static int gr3d_probe(struct platform_device *pdev)
+{
+	struct host1x_syncpt **syncpts;
+	struct gr3d *gr3d;
+	unsigned int i;
+	int err;
+
+	gr3d = devm_kzalloc(&pdev->dev, sizeof(*gr3d), GFP_KERNEL);
+	if (!gr3d)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, gr3d);
+
+	gr3d->soc = of_device_get_match_data(&pdev->dev);
+
+	syncpts = devm_kzalloc(&pdev->dev, sizeof(*syncpts), GFP_KERNEL);
+	if (!syncpts)
+		return -ENOMEM;
+
+	err = gr3d_get_clocks(&pdev->dev, gr3d);
+	if (err)
+		return err;
+
+	err = gr3d_get_resets(&pdev->dev, gr3d);
+	if (err)
+		return err;
+
+	err = gr3d_init_power(&pdev->dev, gr3d);
+	if (err)
+		return err;
+
 	INIT_LIST_HEAD(&gr3d->client.base.list);
 	gr3d->client.base.ops = &gr3d_client_ops;
 	gr3d->client.base.dev = &pdev->dev;
@@ -352,20 +552,36 @@ static int gr3d_probe(struct platform_device *pdev)
 	gr3d->client.version = gr3d->soc->version;
 	gr3d->client.ops = &gr3d_ops;
 
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_autosuspend_delay(&pdev->dev, 200);
+
+	err = devm_pm_opp_register_set_opp_helper(&pdev->dev, gr3d_set_opp);
+	if (err)
+		goto disable_rpm;
+
+	err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
+	if (err)
+		goto disable_rpm;
+
 	err = host1x_client_register(&gr3d->client.base);
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to register host1x client: %d\n",
 			err);
-		return err;
+		goto disable_rpm;
 	}
 
 	/* initialize address register map */
 	for (i = 0; i < ARRAY_SIZE(gr3d_addr_regs); i++)
 		set_bit(gr3d_addr_regs[i], gr3d->addr_regs);
 
-	platform_set_drvdata(pdev, gr3d);
-
 	return 0;
+
+disable_rpm:
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+	return err;
 }
 
 static int gr3d_remove(struct platform_device *pdev)
@@ -380,23 +596,83 @@ static int gr3d_remove(struct platform_device *pdev)
 		return err;
 	}
 
-	if (gr3d->clk_secondary) {
-		reset_control_assert(gr3d->rst_secondary);
-		tegra_powergate_power_off(TEGRA_POWERGATE_3D1);
-		clk_disable_unprepare(gr3d->clk_secondary);
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static int __maybe_unused gr3d_runtime_suspend(struct device *dev)
+{
+	struct gr3d *gr3d = dev_get_drvdata(dev);
+	int err;
+
+	host1x_channel_stop(gr3d->channel);
+
+	err = reset_control_bulk_assert(gr3d->nresets, gr3d->resets);
+	if (err) {
+		dev_err(dev, "failed to assert reset: %d\n", err);
+		return err;
+	}
+
+	usleep_range(10, 20);
+
+	/*
+	 * Older device-trees don't specify MC resets and power-gating can't
+	 * be done safely in that case. Hence we will keep the power ungated
+	 * for older DTBs. For newer DTBs, GENPD will perform the power-gating.
+	 */
+
+	clk_bulk_disable_unprepare(gr3d->nclocks, gr3d->clocks);
+	reset_control_bulk_release(gr3d->nresets, gr3d->resets);
+
+	return 0;
+}
+
+static int __maybe_unused gr3d_runtime_resume(struct device *dev)
+{
+	struct gr3d *gr3d = dev_get_drvdata(dev);
+	int err;
+
+	err = reset_control_bulk_acquire(gr3d->nresets, gr3d->resets);
+	if (err) {
+		dev_err(dev, "failed to acquire reset: %d\n", err);
+		return err;
+	}
+
+	err = clk_bulk_prepare_enable(gr3d->nclocks, gr3d->clocks);
+	if (err) {
+		dev_err(dev, "failed to enable clock: %d\n", err);
+		goto release_reset;
 	}
 
-	reset_control_assert(gr3d->rst);
-	tegra_powergate_power_off(TEGRA_POWERGATE_3D);
-	clk_disable_unprepare(gr3d->clk);
+	err = reset_control_bulk_deassert(gr3d->nresets, gr3d->resets);
+	if (err) {
+		dev_err(dev, "failed to deassert reset: %d\n", err);
+		goto disable_clk;
+	}
 
 	return 0;
+
+disable_clk:
+	clk_bulk_disable_unprepare(gr3d->nclocks, gr3d->clocks);
+release_reset:
+	reset_control_bulk_release(gr3d->nresets, gr3d->resets);
+
+	return err;
 }
 
+static const struct dev_pm_ops tegra_gr3d_pm = {
+	SET_RUNTIME_PM_OPS(gr3d_runtime_suspend, gr3d_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
 struct platform_driver tegra_gr3d_driver = {
 	.driver = {
 		.name = "tegra-gr3d",
 		.of_match_table = tegra_gr3d_match,
+		.pm = &tegra_gr3d_pm,
 	},
 	.probe = gr3d_probe,
 	.remove = gr3d_remove,
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:13 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:13 +0300
Subject: [PATCH v11 15/34] drm/tegra: vic: Support system suspend
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-16-digetx@gmail.com>

Hardware must be stopped before system is suspended. Add suspend-resume
callbacks.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/gpu/drm/tegra/vic.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c
index c02010ff2b7f..359dd77f8b85 100644
--- a/drivers/gpu/drm/tegra/vic.c
+++ b/drivers/gpu/drm/tegra/vic.c
@@ -315,6 +315,8 @@ static int vic_runtime_suspend(struct device *dev)
 	struct vic *vic = dev_get_drvdata(dev);
 	int err;
 
+	host1x_channel_stop(vic->channel);
+
 	err = reset_control_assert(vic->rst);
 	if (err < 0)
 		return err;
@@ -517,6 +519,8 @@ static int vic_remove(struct platform_device *pdev)
 
 static const struct dev_pm_ops vic_pm_ops = {
 	SET_RUNTIME_PM_OPS(vic_runtime_suspend, vic_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
 };
 
 struct platform_driver tegra_vic_driver = {
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:14 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:14 +0300
Subject: [PATCH v11 16/34] usb: chipidea: tegra: Add runtime PM and OPP support
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-17-digetx@gmail.com>

The Tegra USB controller belongs to the core power domain and we're going
to enable GENPD support for the core domain. Now USB controller must be
resumed using runtime PM API in order to initialize the USB power state.
We already support runtime PM for the CI device, but CI's PM is separated
from the RPM managed by tegra-usb driver. Add runtime PM and OPP support
to the driver.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/usb/chipidea/ci_hdrc_tegra.c | 53 ++++++++++++++++++++++++----
 1 file changed, 46 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/chipidea/ci_hdrc_tegra.c b/drivers/usb/chipidea/ci_hdrc_tegra.c
index 60361141ac04..3142ef7ebe42 100644
--- a/drivers/usb/chipidea/ci_hdrc_tegra.c
+++ b/drivers/usb/chipidea/ci_hdrc_tegra.c
@@ -7,6 +7,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/reset.h>
 
 #include <linux/usb.h>
@@ -15,6 +16,8 @@
 #include <linux/usb/of.h>
 #include <linux/usb/phy.h>
 
+#include <soc/tegra/common.h>
+
 #include "../host/ehci.h"
 
 #include "ci.h"
@@ -278,6 +281,8 @@ static int tegra_usb_probe(struct platform_device *pdev)
 	if (!usb)
 		return -ENOMEM;
 
+	platform_set_drvdata(pdev, usb);
+
 	soc = of_device_get_match_data(&pdev->dev);
 	if (!soc) {
 		dev_err(&pdev->dev, "failed to match OF data\n");
@@ -296,11 +301,17 @@ static int tegra_usb_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	err = clk_prepare_enable(usb->clk);
-	if (err < 0) {
-		dev_err(&pdev->dev, "failed to enable clock: %d\n", err);
+	err = devm_pm_runtime_enable(&pdev->dev);
+	if (err)
+		return err;
+
+	err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
+	if (err)
+		return err;
+
+	err = pm_runtime_resume_and_get(&pdev->dev);
+	if (err)
 		return err;
-	}
 
 	if (device_property_present(&pdev->dev, "nvidia,needs-double-reset"))
 		usb->needs_double_reset = true;
@@ -320,8 +331,6 @@ static int tegra_usb_probe(struct platform_device *pdev)
 	if (err)
 		goto fail_power_off;
 
-	platform_set_drvdata(pdev, usb);
-
 	/* setup and register ChipIdea HDRC device */
 	usb->soc = soc;
 	usb->data.name = "tegra-usb";
@@ -350,7 +359,8 @@ static int tegra_usb_probe(struct platform_device *pdev)
 phy_shutdown:
 	usb_phy_shutdown(usb->phy);
 fail_power_off:
-	clk_disable_unprepare(usb->clk);
+	pm_runtime_put(&pdev->dev);
+
 	return err;
 }
 
@@ -360,15 +370,44 @@ static int tegra_usb_remove(struct platform_device *pdev)
 
 	ci_hdrc_remove_device(usb->dev);
 	usb_phy_shutdown(usb->phy);
+	pm_runtime_put(&pdev->dev);
+
+	return 0;
+}
+
+static int __maybe_unused tegra_usb_runtime_resume(struct device *dev)
+{
+	struct tegra_usb *usb = dev_get_drvdata(dev);
+	int err;
+
+	err = clk_prepare_enable(usb->clk);
+	if (err < 0) {
+		dev_err(dev, "failed to enable clock: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused tegra_usb_runtime_suspend(struct device *dev)
+{
+	struct tegra_usb *usb = dev_get_drvdata(dev);
+
 	clk_disable_unprepare(usb->clk);
 
 	return 0;
 }
 
+static const struct dev_pm_ops tegra_usb_pm = {
+	SET_RUNTIME_PM_OPS(tegra_usb_runtime_suspend, tegra_usb_runtime_resume,
+			   NULL)
+};
+
 static struct platform_driver tegra_usb_driver = {
 	.driver = {
 		.name = "tegra-usb",
 		.of_match_table = tegra_usb_of_match,
+		.pm = &tegra_usb_pm,
 	},
 	.probe = tegra_usb_probe,
 	.remove = tegra_usb_remove,
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:15 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:15 +0300
Subject: [PATCH v11 17/34] bus: tegra-gmi: Add runtime PM and OPP support
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-18-digetx@gmail.com>

The GMI bus on Tegra belongs to the core power domain and we're going to
enable GENPD support for the core domain. Now GMI must be resumed using
runtime PM API in order to initialize the GMI power state. Add runtime PM
and OPP support to the GMI driver.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/bus/tegra-gmi.c | 52 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 46 insertions(+), 6 deletions(-)

diff --git a/drivers/bus/tegra-gmi.c b/drivers/bus/tegra-gmi.c
index a6570789f7af..72ef8a8c236b 100644
--- a/drivers/bus/tegra-gmi.c
+++ b/drivers/bus/tegra-gmi.c
@@ -13,8 +13,11 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/reset.h>
 
+#include <soc/tegra/common.h>
+
 #define TEGRA_GMI_CONFIG		0x00
 #define TEGRA_GMI_CONFIG_GO		BIT(31)
 #define TEGRA_GMI_BUS_WIDTH_32BIT	BIT(30)
@@ -54,9 +57,9 @@ static int tegra_gmi_enable(struct tegra_gmi *gmi)
 {
 	int err;
 
-	err = clk_prepare_enable(gmi->clk);
-	if (err < 0) {
-		dev_err(gmi->dev, "failed to enable clock: %d\n", err);
+	err = pm_runtime_resume_and_get(gmi->dev);
+	if (err) {
+		pm_runtime_disable(gmi->dev);
 		return err;
 	}
 
@@ -83,7 +86,8 @@ static void tegra_gmi_disable(struct tegra_gmi *gmi)
 	writel(config, gmi->base + TEGRA_GMI_CONFIG);
 
 	reset_control_assert(gmi->rst);
-	clk_disable_unprepare(gmi->clk);
+
+	pm_runtime_put(gmi->dev);
 }
 
 static int tegra_gmi_parse_dt(struct tegra_gmi *gmi)
@@ -213,6 +217,7 @@ static int tegra_gmi_probe(struct platform_device *pdev)
 	if (!gmi)
 		return -ENOMEM;
 
+	platform_set_drvdata(pdev, gmi);
 	gmi->dev = dev;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -232,6 +237,14 @@ static int tegra_gmi_probe(struct platform_device *pdev)
 		return PTR_ERR(gmi->rst);
 	}
 
+	err = devm_pm_runtime_enable(gmi->dev);
+	if (err)
+		return err;
+
+	err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
+	if (err)
+		return err;
+
 	err = tegra_gmi_parse_dt(gmi);
 	if (err)
 		return err;
@@ -247,8 +260,6 @@ static int tegra_gmi_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	platform_set_drvdata(pdev, gmi);
-
 	return 0;
 }
 
@@ -262,6 +273,34 @@ static int tegra_gmi_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static int __maybe_unused tegra_gmi_runtime_resume(struct device *dev)
+{
+	struct tegra_gmi *gmi = dev_get_drvdata(dev);
+	int err;
+
+	err = clk_prepare_enable(gmi->clk);
+	if (err < 0) {
+		dev_err(gmi->dev, "failed to enable clock: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused tegra_gmi_runtime_suspend(struct device *dev)
+{
+	struct tegra_gmi *gmi = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(gmi->clk);
+
+	return 0;
+}
+
+static const struct dev_pm_ops tegra_gmi_pm = {
+	SET_RUNTIME_PM_OPS(tegra_gmi_runtime_suspend, tegra_gmi_runtime_resume,
+			   NULL)
+};
+
 static const struct of_device_id tegra_gmi_id_table[] = {
 	{ .compatible = "nvidia,tegra20-gmi", },
 	{ .compatible = "nvidia,tegra30-gmi", },
@@ -275,6 +314,7 @@ static struct platform_driver tegra_gmi_driver = {
 	.driver = {
 		.name		= "tegra-gmi",
 		.of_match_table	= tegra_gmi_id_table,
+		.pm = &tegra_gmi_pm,
 	},
 };
 module_platform_driver(tegra_gmi_driver);
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:16 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:16 +0300
Subject: [PATCH v11 18/34] pwm: tegra: Add runtime PM and OPP support
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-19-digetx@gmail.com>

The PWM on Tegra belongs to the core power domain and we're going to
enable GENPD support for the core domain. Now PWM must be resumed using
runtime PM API in order to initialize the PWM power state. The PWM clock
rate must be changed using OPP API that will reconfigure the power domain
performance state in accordance to the rate. Add runtime PM and OPP
support to the PWM driver.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/pwm/pwm-tegra.c | 88 ++++++++++++++++++++++++++++++++---------
 1 file changed, 70 insertions(+), 18 deletions(-)

diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index 11a10b575ace..afb5ecde007e 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -42,12 +42,16 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/pm_opp.h>
 #include <linux/pwm.h>
 #include <linux/platform_device.h>
 #include <linux/pinctrl/consumer.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/reset.h>
 
+#include <soc/tegra/common.h>
+
 #define PWM_ENABLE	(1 << 31)
 #define PWM_DUTY_WIDTH	8
 #define PWM_DUTY_SHIFT	16
@@ -145,7 +149,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 		required_clk_rate =
 			(NSEC_PER_SEC / period_ns) << PWM_DUTY_WIDTH;
 
-		err = clk_set_rate(pc->clk, required_clk_rate);
+		err = dev_pm_opp_set_rate(pc->dev, required_clk_rate);
 		if (err < 0)
 			return -EINVAL;
 
@@ -181,8 +185,8 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * before writing the register. Otherwise, keep it enabled.
 	 */
 	if (!pwm_is_enabled(pwm)) {
-		err = clk_prepare_enable(pc->clk);
-		if (err < 0)
+		err = pm_runtime_resume_and_get(pc->dev);
+		if (err)
 			return err;
 	} else
 		val |= PWM_ENABLE;
@@ -193,7 +197,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 	 * If the PWM is not enabled, turn the clock off again to save power.
 	 */
 	if (!pwm_is_enabled(pwm))
-		clk_disable_unprepare(pc->clk);
+		pm_runtime_put(pc->dev);
 
 	return 0;
 }
@@ -204,8 +208,8 @@ static int tegra_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 	int rc = 0;
 	u32 val;
 
-	rc = clk_prepare_enable(pc->clk);
-	if (rc < 0)
+	rc = pm_runtime_resume_and_get(pc->dev);
+	if (rc)
 		return rc;
 
 	val = pwm_readl(pc, pwm->hwpwm);
@@ -224,7 +228,7 @@ static void tegra_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 	val &= ~PWM_ENABLE;
 	pwm_writel(pc, pwm->hwpwm, val);
 
-	clk_disable_unprepare(pc->clk);
+	pm_runtime_put_sync(pc->dev);
 }
 
 static const struct pwm_ops tegra_pwm_ops = {
@@ -256,11 +260,23 @@ static int tegra_pwm_probe(struct platform_device *pdev)
 	if (IS_ERR(pwm->clk))
 		return PTR_ERR(pwm->clk);
 
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret)
+		return ret;
+
 	/* Set maximum frequency of the IP */
-	ret = clk_set_rate(pwm->clk, pwm->soc->max_frequency);
+	ret = dev_pm_opp_set_rate(pwm->dev, pwm->soc->max_frequency);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret);
-		return ret;
+		goto put_pm;
 	}
 
 	/*
@@ -278,7 +294,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
 	if (IS_ERR(pwm->rst)) {
 		ret = PTR_ERR(pwm->rst);
 		dev_err(&pdev->dev, "Reset control is not found: %d\n", ret);
-		return ret;
+		goto put_pm;
 	}
 
 	reset_control_deassert(pwm->rst);
@@ -291,34 +307,67 @@ static int tegra_pwm_probe(struct platform_device *pdev)
 	if (ret < 0) {
 		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
 		reset_control_assert(pwm->rst);
-		return ret;
+		goto put_pm;
 	}
 
+	pm_runtime_put(&pdev->dev);
+
 	return 0;
+put_pm:
+	pm_runtime_put(&pdev->dev);
+	return ret;
 }
 
 static int tegra_pwm_remove(struct platform_device *pdev)
 {
 	struct tegra_pwm_chip *pc = platform_get_drvdata(pdev);
+	int err;
 
 	pwmchip_remove(&pc->chip);
 
+	err = pm_runtime_resume_and_get(pc->dev);
+	if (err)
+		return err;
+
 	reset_control_assert(pc->rst);
+	pm_runtime_put(pc->dev);
 
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int tegra_pwm_suspend(struct device *dev)
+static int __maybe_unused tegra_pwm_runtime_suspend(struct device *dev)
 {
-	return pinctrl_pm_select_sleep_state(dev);
+	struct tegra_pwm_chip *pc = dev_get_drvdata(dev);
+	int err;
+
+	clk_disable_unprepare(pc->clk);
+
+	err = pinctrl_pm_select_sleep_state(dev);
+	if (err) {
+		clk_prepare_enable(pc->clk);
+		return err;
+	}
+
+	return 0;
 }
 
-static int tegra_pwm_resume(struct device *dev)
+static int __maybe_unused tegra_pwm_runtime_resume(struct device *dev)
 {
-	return pinctrl_pm_select_default_state(dev);
+	struct tegra_pwm_chip *pc = dev_get_drvdata(dev);
+	int err;
+
+	err = pinctrl_pm_select_default_state(dev);
+	if (err)
+		return err;
+
+	err = clk_prepare_enable(pc->clk);
+	if (err) {
+		pinctrl_pm_select_sleep_state(dev);
+		return err;
+	}
+
+	return 0;
 }
-#endif
 
 static const struct tegra_pwm_soc tegra20_pwm_soc = {
 	.num_channels = 4,
@@ -344,7 +393,10 @@ static const struct of_device_id tegra_pwm_of_match[] = {
 MODULE_DEVICE_TABLE(of, tegra_pwm_of_match);
 
 static const struct dev_pm_ops tegra_pwm_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(tegra_pwm_suspend, tegra_pwm_resume)
+	SET_RUNTIME_PM_OPS(tegra_pwm_runtime_suspend, tegra_pwm_runtime_resume,
+			   NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
 };
 
 static struct platform_driver tegra_pwm_driver = {
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:17 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:17 +0300
Subject: [PATCH v11 19/34] mmc: sdhci-tegra: Add runtime PM and OPP support
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-20-digetx@gmail.com>

The SDHCI on Tegra belongs to the core power domain and we're going to
enable GENPD support for the core domain. Now SDHCI must be resumed using
runtime PM API in order to initialize the SDHCI power state. The SDHCI
clock rate must be changed using OPP API that will reconfigure the power
domain performance state in accordance to the rate. Add runtime PM and OPP
support to the SDHCI driver.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/mmc/host/sdhci-tegra.c | 82 +++++++++++++++++++++++++++-------
 1 file changed, 66 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index a5001875876b..6cf3712bf0a6 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -15,6 +15,8 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/pinctrl/consumer.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 #include <linux/mmc/card.h>
@@ -24,6 +26,8 @@
 #include <linux/gpio/consumer.h>
 #include <linux/ktime.h>
 
+#include <soc/tegra/common.h>
+
 #include "sdhci-pltfm.h"
 #include "cqhci.h"
 
@@ -760,7 +764,9 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
+	struct device *dev = mmc_dev(host->mmc);
 	unsigned long host_clk;
+	int err;
 
 	if (!clock)
 		return sdhci_set_clock(host, clock);
@@ -778,7 +784,12 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	 * from clk_get_rate() is used.
 	 */
 	host_clk = tegra_host->ddr_signaling ? clock * 2 : clock;
-	clk_set_rate(pltfm_host->clk, host_clk);
+
+	err = dev_pm_opp_set_rate(dev, host_clk);
+	if (err)
+		dev_err(dev, "failed to set clk rate to %luHz: %d\n",
+			host_clk, err);
+
 	tegra_host->curr_clk_rate = host_clk;
 	if (tegra_host->ddr_signaling)
 		host->max_clk = host_clk;
@@ -1705,7 +1716,6 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
 				   "failed to get clock\n");
 		goto err_clk_get;
 	}
-	clk_prepare_enable(clk);
 	pltfm_host->clk = clk;
 
 	tegra_host->rst = devm_reset_control_get_exclusive(&pdev->dev,
@@ -1716,15 +1726,25 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
 		goto err_rst_get;
 	}
 
+	pm_runtime_enable(&pdev->dev);
+
+	rc = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
+	if (rc)
+		goto err_pm_get;
+
+	rc = pm_runtime_resume_and_get(&pdev->dev);
+	if (rc)
+		goto err_pm_get;
+
 	rc = reset_control_assert(tegra_host->rst);
 	if (rc)
-		goto err_rst_get;
+		goto err_rst_assert;
 
 	usleep_range(2000, 4000);
 
 	rc = reset_control_deassert(tegra_host->rst);
 	if (rc)
-		goto err_rst_get;
+		goto err_rst_assert;
 
 	usleep_range(2000, 4000);
 
@@ -1736,8 +1756,11 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
 
 err_add_host:
 	reset_control_assert(tegra_host->rst);
+err_rst_assert:
+	pm_runtime_put(&pdev->dev);
+err_pm_get:
+	pm_runtime_disable(&pdev->dev);
 err_rst_get:
-	clk_disable_unprepare(pltfm_host->clk);
 err_clk_get:
 	clk_disable_unprepare(tegra_host->tmclk);
 err_power_req:
@@ -1756,19 +1779,38 @@ static int sdhci_tegra_remove(struct platform_device *pdev)
 
 	reset_control_assert(tegra_host->rst);
 	usleep_range(2000, 4000);
-	clk_disable_unprepare(pltfm_host->clk);
-	clk_disable_unprepare(tegra_host->tmclk);
 
+	pm_runtime_put(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
+	clk_disable_unprepare(tegra_host->tmclk);
 	sdhci_pltfm_free(pdev);
 
 	return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int __maybe_unused sdhci_tegra_suspend(struct device *dev)
+static int __maybe_unused sdhci_tegra_runtime_suspend(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+	clk_disable_unprepare(pltfm_host->clk);
+
+	return 0;
+}
+
+static int __maybe_unused sdhci_tegra_runtime_resume(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+	return clk_prepare_enable(pltfm_host->clk);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int sdhci_tegra_suspend(struct device *dev)
+{
+	struct sdhci_host *host = dev_get_drvdata(dev);
 	int ret;
 
 	if (host->mmc->caps2 & MMC_CAP2_CQE) {
@@ -1783,17 +1825,22 @@ static int __maybe_unused sdhci_tegra_suspend(struct device *dev)
 		return ret;
 	}
 
-	clk_disable_unprepare(pltfm_host->clk);
+	ret = pm_runtime_force_suspend(dev);
+	if (ret) {
+		sdhci_resume_host(host);
+		cqhci_resume(host->mmc);
+		return ret;
+	}
+
 	return 0;
 }
 
-static int __maybe_unused sdhci_tegra_resume(struct device *dev)
+static int sdhci_tegra_resume(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
-	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	int ret;
 
-	ret = clk_prepare_enable(pltfm_host->clk);
+	ret = pm_runtime_force_resume(dev);
 	if (ret)
 		return ret;
 
@@ -1812,13 +1859,16 @@ static int __maybe_unused sdhci_tegra_resume(struct device *dev)
 suspend_host:
 	sdhci_suspend_host(host);
 disable_clk:
-	clk_disable_unprepare(pltfm_host->clk);
+	pm_runtime_force_suspend(dev);
 	return ret;
 }
 #endif
 
-static SIMPLE_DEV_PM_OPS(sdhci_tegra_dev_pm_ops, sdhci_tegra_suspend,
-			 sdhci_tegra_resume);
+static const struct dev_pm_ops sdhci_tegra_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(sdhci_tegra_runtime_suspend, sdhci_tegra_runtime_resume,
+			   NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(sdhci_tegra_suspend, sdhci_tegra_resume)
+};
 
 static struct platform_driver sdhci_tegra_driver = {
 	.driver		= {
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:18 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:18 +0300
Subject: [PATCH v11 20/34] mtd: rawnand: tegra: Add runtime PM and OPP support
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-21-digetx@gmail.com>

The NAND on Tegra belongs to the core power domain and we're going to
enable GENPD support for the core domain. Now NAND must be resumed using
runtime PM API in order to initialize the NAND power state. Add runtime PM
and OPP support to the NAND driver.

Acked-by: Miquel Raynal <miquel.raynal at bootlin.com>
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/mtd/nand/raw/tegra_nand.c | 55 ++++++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c
index fbf67722a049..2cce38c58a26 100644
--- a/drivers/mtd/nand/raw/tegra_nand.c
+++ b/drivers/mtd/nand/raw/tegra_nand.c
@@ -17,8 +17,11 @@
 #include <linux/mtd/rawnand.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/reset.h>
 
+#include <soc/tegra/common.h>
+
 #define COMMAND					0x00
 #define   COMMAND_GO				BIT(31)
 #define   COMMAND_CLE				BIT(30)
@@ -1152,6 +1155,7 @@ static int tegra_nand_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	ctrl->dev = &pdev->dev;
+	platform_set_drvdata(pdev, ctrl);
 	nand_controller_init(&ctrl->controller);
 	ctrl->controller.ops = &tegra_nand_controller_ops;
 
@@ -1168,14 +1172,22 @@ static int tegra_nand_probe(struct platform_device *pdev)
 	if (IS_ERR(ctrl->clk))
 		return PTR_ERR(ctrl->clk);
 
-	err = clk_prepare_enable(ctrl->clk);
+	err = devm_pm_runtime_enable(&pdev->dev);
+	if (err)
+		return err;
+
+	err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
+	if (err)
+		return err;
+
+	err = pm_runtime_resume_and_get(&pdev->dev);
 	if (err)
 		return err;
 
 	err = reset_control_reset(rst);
 	if (err) {
 		dev_err(ctrl->dev, "Failed to reset HW: %d\n", err);
-		goto err_disable_clk;
+		goto err_put_pm;
 	}
 
 	writel_relaxed(HWSTATUS_CMD_DEFAULT, ctrl->regs + HWSTATUS_CMD);
@@ -1190,21 +1202,19 @@ static int tegra_nand_probe(struct platform_device *pdev)
 			       dev_name(&pdev->dev), ctrl);
 	if (err) {
 		dev_err(ctrl->dev, "Failed to get IRQ: %d\n", err);
-		goto err_disable_clk;
+		goto err_put_pm;
 	}
 
 	writel_relaxed(DMA_MST_CTRL_IS_DONE, ctrl->regs + DMA_MST_CTRL);
 
 	err = tegra_nand_chips_init(ctrl->dev, ctrl);
 	if (err)
-		goto err_disable_clk;
-
-	platform_set_drvdata(pdev, ctrl);
+		goto err_put_pm;
 
 	return 0;
 
-err_disable_clk:
-	clk_disable_unprepare(ctrl->clk);
+err_put_pm:
+	pm_runtime_put(ctrl->dev);
 	return err;
 }
 
@@ -1221,11 +1231,39 @@ static int tegra_nand_remove(struct platform_device *pdev)
 
 	nand_cleanup(chip);
 
+	pm_runtime_put(ctrl->dev);
+
+	return 0;
+}
+
+static int __maybe_unused tegra_nand_runtime_resume(struct device *dev)
+{
+	struct tegra_nand_controller *ctrl = dev_get_drvdata(dev);
+	int err;
+
+	err = clk_prepare_enable(ctrl->clk);
+	if (err) {
+		dev_err(dev, "Failed to enable clock: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int __maybe_unused tegra_nand_runtime_suspend(struct device *dev)
+{
+	struct tegra_nand_controller *ctrl = dev_get_drvdata(dev);
+
 	clk_disable_unprepare(ctrl->clk);
 
 	return 0;
 }
 
+static const struct dev_pm_ops tegra_nand_pm = {
+	SET_RUNTIME_PM_OPS(tegra_nand_runtime_suspend, tegra_nand_runtime_resume,
+			   NULL)
+};
+
 static const struct of_device_id tegra_nand_of_match[] = {
 	{ .compatible = "nvidia,tegra20-nand" },
 	{ /* sentinel */ }
@@ -1236,6 +1274,7 @@ static struct platform_driver tegra_nand_driver = {
 	.driver = {
 		.name = "tegra-nand",
 		.of_match_table = tegra_nand_of_match,
+		.pm = &tegra_nand_pm,
 	},
 	.probe = tegra_nand_probe,
 	.remove = tegra_nand_remove,
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:19 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:19 +0300
Subject: [PATCH v11 21/34] spi: tegra20-slink: Add OPP support
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-22-digetx@gmail.com>

The SPI on Tegra belongs to the core power domain and we're going to
enable GENPD support for the core domain. Now SPI driver must use OPP
API for driving the controller's clock rate because OPP API takes care
of reconfiguring the domain's performance state in accordance to the
rate. Add OPP support to the driver.

Acked-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/spi/spi-tegra20-slink.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c
index 8ce840c7ecc8..1a92978d2120 100644
--- a/drivers/spi/spi-tegra20-slink.c
+++ b/drivers/spi/spi-tegra20-slink.c
@@ -18,12 +18,15 @@
 #include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/pm_opp.h>
 #include <linux/pm_runtime.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/reset.h>
 #include <linux/spi/spi.h>
 
+#include <soc/tegra/common.h>
+
 #define SLINK_COMMAND			0x000
 #define SLINK_BIT_LENGTH(x)		(((x) & 0x1f) << 0)
 #define SLINK_WORD_SIZE(x)		(((x) & 0x1f) << 5)
@@ -680,7 +683,7 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,
 	bits_per_word = t->bits_per_word;
 	speed = t->speed_hz;
 	if (speed != tspi->cur_speed) {
-		clk_set_rate(tspi->clk, speed * 4);
+		dev_pm_opp_set_rate(tspi->dev, speed * 4);
 		tspi->cur_speed = speed;
 	}
 
@@ -1082,6 +1085,11 @@ static int tegra_slink_probe(struct platform_device *pdev)
 	init_completion(&tspi->xfer_completion);
 
 	pm_runtime_enable(&pdev->dev);
+
+	ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
+	if (ret)
+		goto exit_pm_disable;
+
 	ret = pm_runtime_resume_and_get(&pdev->dev);
 	if (ret) {
 		dev_err(&pdev->dev, "pm runtime get failed, e = %d\n", ret);
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:20 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:20 +0300
Subject: [PATCH v11 22/34] media: dt: bindings: tegra-vde: Convert to schema
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-23-digetx@gmail.com>

Convert NVIDIA Tegra video decoder binding to schema.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 .../bindings/media/nvidia,tegra-vde.txt       |  64 -----------
 .../bindings/media/nvidia,tegra-vde.yaml      | 107 ++++++++++++++++++
 2 files changed, 107 insertions(+), 64 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
 create mode 100644 Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml

diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
deleted file mode 100644
index 602169b8aa19..000000000000
--- a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-NVIDIA Tegra Video Decoder Engine
-
-Required properties:
-- compatible : Must contain one of the following values:
-   - "nvidia,tegra20-vde"
-   - "nvidia,tegra30-vde"
-   - "nvidia,tegra114-vde"
-   - "nvidia,tegra124-vde"
-   - "nvidia,tegra132-vde"
-- reg : Must contain an entry for each entry in reg-names.
-- reg-names : Must include the following entries:
-  - sxe
-  - bsev
-  - mbe
-  - ppe
-  - mce
-  - tfe
-  - ppb
-  - vdma
-  - frameid
-- iram : Must contain phandle to the mmio-sram device node that represents
-         IRAM region used by VDE.
-- interrupts : Must contain an entry for each entry in interrupt-names.
-- interrupt-names : Must include the following entries:
-  - sync-token
-  - bsev
-  - sxe
-- clocks : Must include the following entries:
-  - vde
-- resets : Must contain an entry for each entry in reset-names.
-- reset-names : Should include the following entries:
-  - vde
-
-Optional properties:
-- resets : Must contain an entry for each entry in reset-names.
-- reset-names : Must include the following entries:
-  - mc
-- iommus: Must contain phandle to the IOMMU device node.
-
-Example:
-
-video-codec at 6001a000 {
-	compatible = "nvidia,tegra20-vde";
-	reg = <0x6001a000 0x1000 /* Syntax Engine */
-	       0x6001b000 0x1000 /* Video Bitstream Engine */
-	       0x6001c000  0x100 /* Macroblock Engine */
-	       0x6001c200  0x100 /* Post-processing Engine */
-	       0x6001c400  0x100 /* Motion Compensation Engine */
-	       0x6001c600  0x100 /* Transform Engine */
-	       0x6001c800  0x100 /* Pixel prediction block */
-	       0x6001ca00  0x100 /* Video DMA */
-	       0x6001d800  0x300 /* Video frame controls */>;
-	reg-names = "sxe", "bsev", "mbe", "ppe", "mce",
-		    "tfe", "ppb", "vdma", "frameid";
-	iram = <&vde_pool>; /* IRAM region */
-	interrupts = <GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>, /* Sync token interrupt */
-		     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, /* BSE-V interrupt */
-		     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; /* SXE interrupt */
-	interrupt-names = "sync-token", "bsev", "sxe";
-	clocks = <&tegra_car TEGRA20_CLK_VDE>;
-	reset-names = "vde", "mc";
-	resets = <&tegra_car 61>, <&mc TEGRA20_MC_RESET_VDE>;
-	iommus = <&mc TEGRA_SWGROUP_VDE>;
-};
diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
new file mode 100644
index 000000000000..3b6c1f031e04
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/nvidia,tegra-vde.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra Video Decoder Engine
+
+maintainers:
+  - Dmitry Osipenko <digetx at gmail.com>
+  - Jon Hunter <jonathanh at nvidia.com>
+  - Thierry Reding <thierry.reding at gmail.com>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - nvidia,tegra132-vde
+              - nvidia,tegra124-vde
+              - nvidia,tegra114-vde
+              - nvidia,tegra30-vde
+          - enum:
+              - nvidia,tegra20-vde
+      - items:
+          - const: nvidia,tegra20-vde
+
+  reg:
+    maxItems: 9
+
+  reg-names:
+    items:
+      - const: sxe
+      - const: bsev
+      - const: mbe
+      - const: ppe
+      - const: mce
+      - const: tfe
+      - const: ppb
+      - const: vdma
+      - const: frameid
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 2
+
+  reset-names:
+    items:
+      - const: vde
+      - const: mc
+
+  interrupts:
+    maxItems: 3
+
+  interrupt-names:
+    items:
+      - const: sync-token
+      - const: bsev
+      - const: sxe
+
+  iommus:
+    maxItems: 1
+
+  iram:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle of the SRAM MMIO node.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - resets
+  - reset-names
+  - interrupts
+  - interrupt-names
+
+additionalProperties: false
+
+examples:
+  - |
+    video-codec at 6001a000 {
+      compatible = "nvidia,tegra20-vde";
+      reg = <0x6001a000 0x1000>, /* Syntax Engine */
+            <0x6001b000 0x1000>, /* Video Bitstream Engine */
+            <0x6001c000  0x100>, /* Macroblock Engine */
+            <0x6001c200  0x100>, /* Post-processing Engine */
+            <0x6001c400  0x100>, /* Motion Compensation Engine */
+            <0x6001c600  0x100>, /* Transform Engine */
+            <0x6001c800  0x100>, /* Pixel prediction block */
+            <0x6001ca00  0x100>, /* Video DMA */
+            <0x6001d800  0x300>; /* Video frame controls */
+      reg-names = "sxe", "bsev", "mbe", "ppe", "mce",
+                  "tfe", "ppb", "vdma", "frameid";
+      iram = <&iram>; /* IRAM MMIO region */
+      interrupts = <0  9 4>, /* Sync token */
+                   <0 10 4>, /* BSE-V */
+                   <0 12 4>; /* SXE */
+      interrupt-names = "sync-token", "bsev", "sxe";
+      clocks = <&clk 61>;
+      reset-names = "vde", "mc";
+      resets = <&rst 61>, <&mem 13>;
+      iommus = <&mem 15>;
+    };
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:21 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:21 +0300
Subject: [PATCH v11 23/34] media: dt: bindings: tegra-vde: Document OPP and
 power domain
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-24-digetx@gmail.com>

Document new OPP table and power domain properties of the video decoder
hardware.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 .../devicetree/bindings/media/nvidia,tegra-vde.yaml  | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
index 3b6c1f031e04..0b7d4d815707 100644
--- a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
+++ b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
@@ -68,6 +68,16 @@ properties:
     description:
       Phandle of the SRAM MMIO node.
 
+  operating-points-v2:
+    description:
+      Should contain freqs and voltages and opp-supported-hw property,
+      which is a bitfield indicating SoC speedo or process ID mask.
+
+  power-domains:
+    maxItems: 1
+    description:
+      Phandle to the SoC core power domain.
+
 required:
   - compatible
   - reg
@@ -104,4 +114,6 @@ examples:
       reset-names = "vde", "mc";
       resets = <&rst 61>, <&mem 13>;
       iommus = <&mem 15>;
+      operating-points-v2 = <&dvfs_opp_table>;
+      power-domains = <&domain>;
     };
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:22 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:22 +0300
Subject: [PATCH v11 24/34] media: staging: tegra-vde: Support generic power
 domain
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-25-digetx@gmail.com>

Currently driver supports legacy power domain API, this patch adds generic
power domain support. This allows us to utilize a modern GENPD API for
newer device-trees.

Tested-by: Peter Geis <pgwipeout at gmail.com> # Ouya T30
Tested-by: Paul Fertser <fercerpav at gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart at gmail.com> # PAZ00 T20 and TK1 T124
Tested-by: Matt Merhar <mattmerhar at protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/staging/media/tegra-vde/vde.c | 57 +++++++++++++++++++++------
 1 file changed, 46 insertions(+), 11 deletions(-)

diff --git a/drivers/staging/media/tegra-vde/vde.c b/drivers/staging/media/tegra-vde/vde.c
index ed4c1250b303..bb3079a2c0b5 100644
--- a/drivers/staging/media/tegra-vde/vde.c
+++ b/drivers/staging/media/tegra-vde/vde.c
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 
+#include <soc/tegra/common.h>
 #include <soc/tegra/pmc.h>
 
 #include "uapi.h"
@@ -920,13 +921,17 @@ static __maybe_unused int tegra_vde_runtime_suspend(struct device *dev)
 	struct tegra_vde *vde = dev_get_drvdata(dev);
 	int err;
 
-	err = tegra_powergate_power_off(TEGRA_POWERGATE_VDEC);
-	if (err) {
-		dev_err(dev, "Failed to power down HW: %d\n", err);
-		return err;
+	if (!dev->pm_domain) {
+		err = tegra_powergate_power_off(TEGRA_POWERGATE_VDEC);
+		if (err) {
+			dev_err(dev, "Failed to power down HW: %d\n", err);
+			return err;
+		}
 	}
 
 	clk_disable_unprepare(vde->clk);
+	reset_control_release(vde->rst);
+	reset_control_release(vde->rst_mc);
 
 	return 0;
 }
@@ -936,14 +941,41 @@ static __maybe_unused int tegra_vde_runtime_resume(struct device *dev)
 	struct tegra_vde *vde = dev_get_drvdata(dev);
 	int err;
 
-	err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_VDEC,
-						vde->clk, vde->rst);
+	err = reset_control_acquire(vde->rst_mc);
 	if (err) {
-		dev_err(dev, "Failed to power up HW : %d\n", err);
+		dev_err(dev, "Failed to acquire mc reset: %d\n", err);
 		return err;
 	}
 
+	err = reset_control_acquire(vde->rst);
+	if (err) {
+		dev_err(dev, "Failed to acquire reset: %d\n", err);
+		goto release_mc_reset;
+	}
+
+	if (!dev->pm_domain) {
+		err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_VDEC,
+							vde->clk, vde->rst);
+		if (err) {
+			dev_err(dev, "Failed to power up HW : %d\n", err);
+			goto release_reset;
+		}
+	}
+
+	err = clk_prepare_enable(vde->clk);
+	if (err) {
+		dev_err(dev, "Failed to enable clock: %d\n", err);
+		goto release_reset;
+	}
+
 	return 0;
+
+release_reset:
+	reset_control_release(vde->rst);
+release_mc_reset:
+	reset_control_release(vde->rst_mc);
+
+	return err;
 }
 
 static int tegra_vde_probe(struct platform_device *pdev)
@@ -1001,14 +1033,14 @@ static int tegra_vde_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	vde->rst = devm_reset_control_get(dev, NULL);
+	vde->rst = devm_reset_control_get_exclusive_released(dev, NULL);
 	if (IS_ERR(vde->rst)) {
 		err = PTR_ERR(vde->rst);
 		dev_err(dev, "Could not get VDE reset %d\n", err);
 		return err;
 	}
 
-	vde->rst_mc = devm_reset_control_get_optional(dev, "mc");
+	vde->rst_mc = devm_reset_control_get_optional_exclusive_released(dev, "mc");
 	if (IS_ERR(vde->rst_mc)) {
 		err = PTR_ERR(vde->rst_mc);
 		dev_err(dev, "Could not get MC reset %d\n", err);
@@ -1066,6 +1098,10 @@ static int tegra_vde_probe(struct platform_device *pdev)
 	pm_runtime_use_autosuspend(dev);
 	pm_runtime_set_autosuspend_delay(dev, 300);
 
+	err = devm_tegra_core_dev_init_opp_table_common(dev);
+	if (err)
+		goto err_pm_runtime;
+
 	/*
 	 * VDE partition may be left ON after bootloader, hence let's
 	 * power-cycle it in order to put hardware into a predictable lower
@@ -1133,8 +1169,7 @@ static void tegra_vde_shutdown(struct platform_device *pdev)
 	 * On some devices bootloader isn't ready to a power-gated VDE on
 	 * a warm-reboot, machine will hang in that case.
 	 */
-	if (pm_runtime_status_suspended(&pdev->dev))
-		tegra_vde_runtime_resume(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
 }
 
 static __maybe_unused int tegra_vde_pm_suspend(struct device *dev)
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:23 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:23 +0300
Subject: [PATCH v11 25/34] soc/tegra: fuse: Reset hardware
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-26-digetx@gmail.com>

The FUSE controller is enabled at a boot time. Reset it in order to put
hardware and clock into clean and disabled state.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/soc/tegra/fuse/fuse-tegra.c | 25 +++++++++++++++++++++++++
 drivers/soc/tegra/fuse/fuse.h       |  1 +
 2 files changed, 26 insertions(+)

diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index f2151815db58..cc032729a143 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -14,6 +14,7 @@
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/reset.h>
 #include <linux/slab.h>
 #include <linux/sys_soc.h>
 
@@ -243,6 +244,30 @@ static int tegra_fuse_probe(struct platform_device *pdev)
 		goto restore;
 	}
 
+	fuse->rst = devm_reset_control_get_optional(&pdev->dev, "fuse");
+	if (IS_ERR(fuse->rst)) {
+		err = PTR_ERR(fuse->rst);
+		dev_err(&pdev->dev, "failed to get FUSE reset: %pe\n",
+			fuse->rst);
+		goto restore;
+	}
+
+	/*
+	 * FUSE clock is enabled at a boot time, hence this resume/suspend
+	 * disables the clock besides the h/w resetting.
+	 */
+	err = pm_runtime_resume_and_get(&pdev->dev);
+	if (err)
+		goto restore;
+
+	err = reset_control_reset(fuse->rst);
+	pm_runtime_put(&pdev->dev);
+
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed to reset FUSE: %d\n", err);
+		goto restore;
+	}
+
 	/* release the early I/O memory mapping */
 	iounmap(base);
 
diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h
index de58feba0435..1b719d85bd04 100644
--- a/drivers/soc/tegra/fuse/fuse.h
+++ b/drivers/soc/tegra/fuse/fuse.h
@@ -43,6 +43,7 @@ struct tegra_fuse {
 	void __iomem *base;
 	phys_addr_t phys;
 	struct clk *clk;
+	struct reset_control *rst;
 
 	u32 (*read_early)(struct tegra_fuse *fuse, unsigned int offset);
 	u32 (*read)(struct tegra_fuse *fuse, unsigned int offset);
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:24 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:24 +0300
Subject: [PATCH v11 26/34] soc/tegra: fuse: Use resource-managed helpers
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-27-digetx@gmail.com>

Use resource-managed helpers to make code cleaner and more correct,
properly releasing all resources in case of driver probe error.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/soc/tegra/fuse/fuse-tegra.c   | 32 ++++++++++++++------------
 drivers/soc/tegra/fuse/fuse-tegra20.c | 33 ++++++++++++++++++++++++---
 2 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c
index cc032729a143..fe4f935ce73a 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -182,6 +182,12 @@ static const struct nvmem_cell_info tegra_fuse_cells[] = {
 	},
 };
 
+static void tegra_fuse_restore(void *base)
+{
+	fuse->clk = NULL;
+	fuse->base = base;
+}
+
 static int tegra_fuse_probe(struct platform_device *pdev)
 {
 	void __iomem *base = fuse->base;
@@ -189,13 +195,16 @@ static int tegra_fuse_probe(struct platform_device *pdev)
 	struct resource *res;
 	int err;
 
+	err = devm_add_action(&pdev->dev, tegra_fuse_restore, base);
+	if (err)
+		return err;
+
 	/* take over the memory region from the early initialization */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	fuse->phys = res->start;
 	fuse->base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(fuse->base)) {
 		err = PTR_ERR(fuse->base);
-		fuse->base = base;
 		return err;
 	}
 
@@ -205,19 +214,20 @@ static int tegra_fuse_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev, "failed to get FUSE clock: %ld",
 				PTR_ERR(fuse->clk));
 
-		fuse->base = base;
 		return PTR_ERR(fuse->clk);
 	}
 
 	platform_set_drvdata(pdev, fuse);
 	fuse->dev = &pdev->dev;
 
-	pm_runtime_enable(&pdev->dev);
+	err = devm_pm_runtime_enable(&pdev->dev);
+	if (err)
+		return err;
 
 	if (fuse->soc->probe) {
 		err = fuse->soc->probe(fuse);
 		if (err < 0)
-			goto restore;
+			return err;
 	}
 
 	memset(&nvmem, 0, sizeof(nvmem));
@@ -241,7 +251,7 @@ static int tegra_fuse_probe(struct platform_device *pdev)
 		err = PTR_ERR(fuse->nvmem);
 		dev_err(&pdev->dev, "failed to register NVMEM device: %d\n",
 			err);
-		goto restore;
+		return err;
 	}
 
 	fuse->rst = devm_reset_control_get_optional(&pdev->dev, "fuse");
@@ -249,7 +259,7 @@ static int tegra_fuse_probe(struct platform_device *pdev)
 		err = PTR_ERR(fuse->rst);
 		dev_err(&pdev->dev, "failed to get FUSE reset: %pe\n",
 			fuse->rst);
-		goto restore;
+		return err;
 	}
 
 	/*
@@ -258,26 +268,20 @@ static int tegra_fuse_probe(struct platform_device *pdev)
 	 */
 	err = pm_runtime_resume_and_get(&pdev->dev);
 	if (err)
-		goto restore;
+		return err;
 
 	err = reset_control_reset(fuse->rst);
 	pm_runtime_put(&pdev->dev);
 
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to reset FUSE: %d\n", err);
-		goto restore;
+		return err;
 	}
 
 	/* release the early I/O memory mapping */
 	iounmap(base);
 
 	return 0;
-
-restore:
-	fuse->clk = NULL;
-	fuse->base = base;
-	pm_runtime_disable(&pdev->dev);
-	return err;
 }
 
 static int __maybe_unused tegra_fuse_runtime_resume(struct device *dev)
diff --git a/drivers/soc/tegra/fuse/fuse-tegra20.c b/drivers/soc/tegra/fuse/fuse-tegra20.c
index 8ec9fc5e5e4b..12503f563e36 100644
--- a/drivers/soc/tegra/fuse/fuse-tegra20.c
+++ b/drivers/soc/tegra/fuse/fuse-tegra20.c
@@ -94,9 +94,28 @@ static bool dma_filter(struct dma_chan *chan, void *filter_param)
 	return of_device_is_compatible(np, "nvidia,tegra20-apbdma");
 }
 
+static void tegra20_fuse_release_channel(void *data)
+{
+	struct tegra_fuse *fuse = data;
+
+	dma_release_channel(fuse->apbdma.chan);
+	fuse->apbdma.chan = NULL;
+}
+
+static void tegra20_fuse_free_coherent(void *data)
+{
+	struct tegra_fuse *fuse = data;
+
+	dma_free_coherent(fuse->dev, sizeof(u32), fuse->apbdma.virt,
+			  fuse->apbdma.phys);
+	fuse->apbdma.virt = NULL;
+	fuse->apbdma.phys = 0x0;
+}
+
 static int tegra20_fuse_probe(struct tegra_fuse *fuse)
 {
 	dma_cap_mask_t mask;
+	int err;
 
 	dma_cap_zero(mask);
 	dma_cap_set(DMA_SLAVE, mask);
@@ -105,13 +124,21 @@ static int tegra20_fuse_probe(struct tegra_fuse *fuse)
 	if (!fuse->apbdma.chan)
 		return -EPROBE_DEFER;
 
+	err = devm_add_action_or_reset(fuse->dev, tegra20_fuse_release_channel,
+				       fuse);
+	if (err)
+		return err;
+
 	fuse->apbdma.virt = dma_alloc_coherent(fuse->dev, sizeof(u32),
 					       &fuse->apbdma.phys,
 					       GFP_KERNEL);
-	if (!fuse->apbdma.virt) {
-		dma_release_channel(fuse->apbdma.chan);
+	if (!fuse->apbdma.virt)
 		return -ENOMEM;
-	}
+
+	err = devm_add_action_or_reset(fuse->dev, tegra20_fuse_free_coherent,
+				       fuse);
+	if (err)
+		return err;
 
 	fuse->apbdma.config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 	fuse->apbdma.config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:25 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:25 +0300
Subject: [PATCH v11 27/34] soc/tegra: regulators: Prepare for suspend
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-28-digetx@gmail.com>

Depending on hardware version, Tegra SoC may require a higher voltages
during resume from system suspend, otherwise hardware will crash. Set
SoC voltages to a nominal levels during suspend.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/soc/tegra/regulators-tegra20.c |  99 ++++++++++++++++++++
 drivers/soc/tegra/regulators-tegra30.c | 122 +++++++++++++++++++++++++
 2 files changed, 221 insertions(+)

diff --git a/drivers/soc/tegra/regulators-tegra20.c b/drivers/soc/tegra/regulators-tegra20.c
index b8ce9fd0650d..6a2f90ab9d3e 100644
--- a/drivers/soc/tegra/regulators-tegra20.c
+++ b/drivers/soc/tegra/regulators-tegra20.c
@@ -16,7 +16,9 @@
 #include <linux/regulator/coupler.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/suspend.h>
 
+#include <soc/tegra/fuse.h>
 #include <soc/tegra/pmc.h>
 
 struct tegra_regulator_coupler {
@@ -25,9 +27,12 @@ struct tegra_regulator_coupler {
 	struct regulator_dev *cpu_rdev;
 	struct regulator_dev *rtc_rdev;
 	struct notifier_block reboot_notifier;
+	struct notifier_block suspend_notifier;
 	int core_min_uV, cpu_min_uV;
 	bool sys_reboot_mode_req;
 	bool sys_reboot_mode;
+	bool sys_suspend_mode_req;
+	bool sys_suspend_mode;
 };
 
 static inline struct tegra_regulator_coupler *
@@ -105,6 +110,28 @@ static int tegra20_core_rtc_max_spread(struct regulator_dev *core_rdev,
 	return 150000;
 }
 
+static int tegra20_cpu_nominal_uV(void)
+{
+	switch (tegra_sku_info.soc_speedo_id) {
+	case 0:
+		return 1100000;
+	case 1:
+		return 1025000;
+	default:
+		return 1125000;
+	}
+}
+
+static int tegra20_core_nominal_uV(void)
+{
+	switch (tegra_sku_info.soc_speedo_id) {
+	default:
+		return 1225000;
+	case 2:
+		return 1300000;
+	}
+}
+
 static int tegra20_core_rtc_update(struct tegra_regulator_coupler *tegra,
 				   struct regulator_dev *core_rdev,
 				   struct regulator_dev *rtc_rdev,
@@ -144,6 +171,11 @@ static int tegra20_core_rtc_update(struct tegra_regulator_coupler *tegra,
 	if (err)
 		return err;
 
+	/* prepare voltage level for suspend */
+	if (tegra->sys_suspend_mode)
+		core_min_uV = clamp(tegra20_core_nominal_uV(),
+				    core_min_uV, core_max_uV);
+
 	core_uV = regulator_get_voltage_rdev(core_rdev);
 	if (core_uV < 0)
 		return core_uV;
@@ -279,6 +311,11 @@ static int tegra20_cpu_voltage_update(struct tegra_regulator_coupler *tegra,
 	if (tegra->sys_reboot_mode)
 		cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV);
 
+	/* prepare voltage level for suspend */
+	if (tegra->sys_suspend_mode)
+		cpu_min_uV = clamp(tegra20_cpu_nominal_uV(),
+				   cpu_min_uV, cpu_max_uV);
+
 	if (cpu_min_uV > cpu_uV) {
 		err = tegra20_core_rtc_update(tegra, core_rdev, rtc_rdev,
 					      cpu_uV, cpu_min_uV);
@@ -320,6 +357,7 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,
 	}
 
 	tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req);
+	tegra->sys_suspend_mode = READ_ONCE(tegra->sys_suspend_mode_req);
 
 	if (rdev == cpu_rdev)
 		return tegra20_cpu_voltage_update(tegra, cpu_rdev,
@@ -334,6 +372,63 @@ static int tegra20_regulator_balance_voltage(struct regulator_coupler *coupler,
 	return -EPERM;
 }
 
+static int tegra20_regulator_prepare_suspend(struct tegra_regulator_coupler *tegra,
+					     bool sys_suspend_mode)
+{
+	int err;
+
+	if (!tegra->core_rdev || !tegra->rtc_rdev || !tegra->cpu_rdev)
+		return 0;
+
+	/*
+	 * All power domains are enabled early during resume from suspend
+	 * by GENPD core.  Domains like VENC may require a higher voltage
+	 * when enabled during resume from suspend.  This also prepares
+	 * hardware for resuming from LP0.
+	 */
+
+	WRITE_ONCE(tegra->sys_suspend_mode_req, sys_suspend_mode);
+
+	err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
+	if (err)
+		return err;
+
+	err = regulator_sync_voltage_rdev(tegra->core_rdev);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int tegra20_regulator_suspend(struct notifier_block *notifier,
+				     unsigned long mode, void *arg)
+{
+	struct tegra_regulator_coupler *tegra;
+	int ret = 0;
+
+	tegra = container_of(notifier, struct tegra_regulator_coupler,
+			     suspend_notifier);
+
+	switch (mode) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_RESTORE_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		ret = tegra20_regulator_prepare_suspend(tegra, true);
+		break;
+
+	case PM_POST_HIBERNATION:
+	case PM_POST_RESTORE:
+	case PM_POST_SUSPEND:
+		ret = tegra20_regulator_prepare_suspend(tegra, false);
+		break;
+	}
+
+	if (ret)
+		pr_err("failed to prepare regulators: %d\n", ret);
+
+	return notifier_from_errno(ret);
+}
+
 static int tegra20_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra,
 					    bool sys_reboot_mode)
 {
@@ -444,6 +539,7 @@ static struct tegra_regulator_coupler tegra20_coupler = {
 		.balance_voltage = tegra20_regulator_balance_voltage,
 	},
 	.reboot_notifier.notifier_call = tegra20_regulator_reboot,
+	.suspend_notifier.notifier_call = tegra20_regulator_suspend,
 };
 
 static int __init tegra_regulator_coupler_init(void)
@@ -456,6 +552,9 @@ static int __init tegra_regulator_coupler_init(void)
 	err = register_reboot_notifier(&tegra20_coupler.reboot_notifier);
 	WARN_ON(err);
 
+	err = register_pm_notifier(&tegra20_coupler.suspend_notifier);
+	WARN_ON(err);
+
 	return regulator_coupler_register(&tegra20_coupler.coupler);
 }
 arch_initcall(tegra_regulator_coupler_init);
diff --git a/drivers/soc/tegra/regulators-tegra30.c b/drivers/soc/tegra/regulators-tegra30.c
index e74bbc9c7859..8fd43c689134 100644
--- a/drivers/soc/tegra/regulators-tegra30.c
+++ b/drivers/soc/tegra/regulators-tegra30.c
@@ -16,6 +16,7 @@
 #include <linux/regulator/coupler.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/suspend.h>
 
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/pmc.h>
@@ -25,9 +26,12 @@ struct tegra_regulator_coupler {
 	struct regulator_dev *core_rdev;
 	struct regulator_dev *cpu_rdev;
 	struct notifier_block reboot_notifier;
+	struct notifier_block suspend_notifier;
 	int core_min_uV, cpu_min_uV;
 	bool sys_reboot_mode_req;
 	bool sys_reboot_mode;
+	bool sys_suspend_mode_req;
+	bool sys_suspend_mode;
 };
 
 static inline struct tegra_regulator_coupler *
@@ -113,6 +117,52 @@ static int tegra30_core_cpu_limit(int cpu_uV)
 	return -EINVAL;
 }
 
+static int tegra30_cpu_nominal_uV(void)
+{
+	switch (tegra_sku_info.cpu_speedo_id) {
+	case 10 ... 11:
+		return  850000;
+
+	case 9:
+		return  912000;
+
+	case 1 ...  3:
+	case 7 ...  8:
+		return 1050000;
+
+	default:
+		return 1125000;
+
+	case  4 ...  6:
+	case 12 ... 13:
+		return 1237000;
+	}
+}
+
+static int tegra30_core_nominal_uV(void)
+{
+	switch (tegra_sku_info.soc_speedo_id) {
+	case 0:
+		return 1200000;
+
+	case 1:
+		if (tegra_sku_info.cpu_speedo_id != 7 &&
+		    tegra_sku_info.cpu_speedo_id != 8)
+			return 1200000;
+
+		fallthrough;
+
+	case 2:
+		if (tegra_sku_info.cpu_speedo_id != 13)
+			return 1300000;
+
+		return 1350000;
+
+	default:
+		return 1250000;
+	}
+}
+
 static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,
 				  struct regulator_dev *cpu_rdev,
 				  struct regulator_dev *core_rdev)
@@ -168,6 +218,11 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,
 	if (err)
 		return err;
 
+	/* prepare voltage level for suspend */
+	if (tegra->sys_suspend_mode)
+		core_min_uV = clamp(tegra30_core_nominal_uV(),
+				    core_min_uV, core_max_uV);
+
 	core_uV = regulator_get_voltage_rdev(core_rdev);
 	if (core_uV < 0)
 		return core_uV;
@@ -223,6 +278,11 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,
 	if (tegra->sys_reboot_mode)
 		cpu_min_uV = max(cpu_min_uV, tegra->cpu_min_uV);
 
+	/* prepare voltage level for suspend */
+	if (tegra->sys_suspend_mode)
+		cpu_min_uV = clamp(tegra30_cpu_nominal_uV(),
+				   cpu_min_uV, cpu_max_uV);
+
 	if (core_min_limited_uV > core_uV) {
 		pr_err("core voltage constraint violated: %d %d %d\n",
 		       core_uV, core_min_limited_uV, cpu_uV);
@@ -292,10 +352,68 @@ static int tegra30_regulator_balance_voltage(struct regulator_coupler *coupler,
 	}
 
 	tegra->sys_reboot_mode = READ_ONCE(tegra->sys_reboot_mode_req);
+	tegra->sys_suspend_mode = READ_ONCE(tegra->sys_suspend_mode_req);
 
 	return tegra30_voltage_update(tegra, cpu_rdev, core_rdev);
 }
 
+static int tegra30_regulator_prepare_suspend(struct tegra_regulator_coupler *tegra,
+					     bool sys_suspend_mode)
+{
+	int err;
+
+	if (!tegra->core_rdev || !tegra->cpu_rdev)
+		return 0;
+
+	/*
+	 * All power domains are enabled early during resume from suspend
+	 * by GENPD core.  Domains like VENC may require a higher voltage
+	 * when enabled during resume from suspend.  This also prepares
+	 * hardware for resuming from LP0.
+	 */
+
+	WRITE_ONCE(tegra->sys_suspend_mode_req, sys_suspend_mode);
+
+	err = regulator_sync_voltage_rdev(tegra->cpu_rdev);
+	if (err)
+		return err;
+
+	err = regulator_sync_voltage_rdev(tegra->core_rdev);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int tegra30_regulator_suspend(struct notifier_block *notifier,
+				     unsigned long mode, void *arg)
+{
+	struct tegra_regulator_coupler *tegra;
+	int ret = 0;
+
+	tegra = container_of(notifier, struct tegra_regulator_coupler,
+			     suspend_notifier);
+
+	switch (mode) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_RESTORE_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		ret = tegra30_regulator_prepare_suspend(tegra, true);
+		break;
+
+	case PM_POST_HIBERNATION:
+	case PM_POST_RESTORE:
+	case PM_POST_SUSPEND:
+		ret = tegra30_regulator_prepare_suspend(tegra, false);
+		break;
+	}
+
+	if (ret)
+		pr_err("failed to prepare regulators: %d\n", ret);
+
+	return notifier_from_errno(ret);
+}
+
 static int tegra30_regulator_prepare_reboot(struct tegra_regulator_coupler *tegra,
 					    bool sys_reboot_mode)
 {
@@ -395,6 +513,7 @@ static struct tegra_regulator_coupler tegra30_coupler = {
 		.balance_voltage = tegra30_regulator_balance_voltage,
 	},
 	.reboot_notifier.notifier_call = tegra30_regulator_reboot,
+	.suspend_notifier.notifier_call = tegra30_regulator_suspend,
 };
 
 static int __init tegra_regulator_coupler_init(void)
@@ -407,6 +526,9 @@ static int __init tegra_regulator_coupler_init(void)
 	err = register_reboot_notifier(&tegra30_coupler.reboot_notifier);
 	WARN_ON(err);
 
+	err = register_pm_notifier(&tegra30_coupler.suspend_notifier);
+	WARN_ON(err);
+
 	return regulator_coupler_register(&tegra30_coupler.coupler);
 }
 arch_initcall(tegra_regulator_coupler_init);
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:26 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:26 +0300
Subject: [PATCH v11 28/34] soc/tegra: pmc: Change name of core power domain
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-29-digetx@gmail.com>

CORE power domain uses name of device-tree node, which is inconsistent with
the names of PMC domains. Set the name to "core" to make it consistent.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/soc/tegra/pmc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index fb8faf7b226a..5e1fc873bf8f 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -1353,7 +1353,7 @@ static int tegra_pmc_core_pd_add(struct tegra_pmc *pmc, struct device_node *np)
 	if (!genpd)
 		return -ENOMEM;
 
-	genpd->name = np->name;
+	genpd->name = "core";
 	genpd->set_performance_state = tegra_pmc_core_pd_set_performance_state;
 	genpd->opp_to_performance_state = tegra_pmc_core_pd_opp_to_performance_state;
 
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:27 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:27 +0300
Subject: [PATCH v11 29/34] soc/tegra: pmc: Enable core domain support for
 Tegra20 and Tegra30
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-30-digetx@gmail.com>

All device drivers got runtime PM and OPP support. Flip the core domain
support status for Tegra20 and Tegra30 SoCs.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 drivers/soc/tegra/pmc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 5e1fc873bf8f..74de84a014e9 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -3042,7 +3042,7 @@ static void tegra20_pmc_setup_irq_polarity(struct tegra_pmc *pmc,
 }
 
 static const struct tegra_pmc_soc tegra20_pmc_soc = {
-	.supports_core_domain = false,
+	.supports_core_domain = true,
 	.num_powergates = ARRAY_SIZE(tegra20_powergates),
 	.powergates = tegra20_powergates,
 	.num_cpu_powergates = 0,
@@ -3103,7 +3103,7 @@ static const char * const tegra30_reset_sources[] = {
 };
 
 static const struct tegra_pmc_soc tegra30_pmc_soc = {
-	.supports_core_domain = false,
+	.supports_core_domain = true,
 	.num_powergates = ARRAY_SIZE(tegra30_powergates),
 	.powergates = tegra30_powergates,
 	.num_cpu_powergates = ARRAY_SIZE(tegra30_cpu_powergates),
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:28 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:28 +0300
Subject: [PATCH v11 30/34] ARM: tegra: Add OPP tables and power domains to
 Tegra20 device-trees
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-31-digetx@gmail.com>

Add OPP tables and power domains to all peripheral devices which
support power management on Tegra20 SoC.

Tested-by: Paul Fertser <fercerpav at gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart at gmail.com> # PAZ00 T20
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 .../boot/dts/tegra20-acer-a500-picasso.dts    |   1 +
 arch/arm/boot/dts/tegra20-colibri.dtsi        |   3 +-
 arch/arm/boot/dts/tegra20-harmony.dts         |   3 +-
 arch/arm/boot/dts/tegra20-paz00.dts           |   1 +
 .../arm/boot/dts/tegra20-peripherals-opp.dtsi | 941 ++++++++++++++++++
 arch/arm/boot/dts/tegra20-seaboard.dts        |   3 +-
 arch/arm/boot/dts/tegra20-tamonten.dtsi       |   3 +-
 arch/arm/boot/dts/tegra20-trimslice.dts       |   9 +
 arch/arm/boot/dts/tegra20-ventana.dts         |   1 +
 arch/arm/boot/dts/tegra20.dtsi                | 100 ++
 10 files changed, 1061 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
index 2280d75b66ab..1dbeabcb8b74 100644
--- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
+++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
@@ -713,6 +713,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-good-time = <3845 3845>;
 		nvidia,core-pwr-off-time = <458>;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 	};
 
 	usb at c5000000 {
diff --git a/arch/arm/boot/dts/tegra20-colibri.dtsi b/arch/arm/boot/dts/tegra20-colibri.dtsi
index 585a5b441cf6..4ec403aa5f2e 100644
--- a/arch/arm/boot/dts/tegra20-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra20-colibri.dtsi
@@ -495,7 +495,7 @@ reg_3v3_vsys: sys {
 					regulator-always-on;
 				};
 
-				sm0 {
+				vdd_core: sm0 {
 					regulator-name = "VDD_CORE_1.2V";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
@@ -601,6 +601,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-good-time = <3845 3845>;
 		nvidia,core-pwr-off-time = <3875>;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 
 		/* Set SLEEP MODE bit in SUPPLYENE register of TPS658643 PMIC */
 		i2c-thermtrip {
diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts
index ae4312eedcbd..b21bab437ebd 100644
--- a/arch/arm/boot/dts/tegra20-harmony.dts
+++ b/arch/arm/boot/dts/tegra20-harmony.dts
@@ -339,7 +339,7 @@ sys_reg: sys {
 					regulator-always-on;
 				};
 
-				sm0 {
+				vdd_core: sm0 {
 					regulator-name = "vdd_sm0,vdd_core";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
@@ -565,6 +565,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-good-time = <3845 3845>;
 		nvidia,core-pwr-off-time = <3875>;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 	};
 
 	pcie at 80003000 {
diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts
index acc816bfd233..c8e4439d3dfb 100644
--- a/arch/arm/boot/dts/tegra20-paz00.dts
+++ b/arch/arm/boot/dts/tegra20-paz00.dts
@@ -519,6 +519,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-good-time = <3845 3845>;
 		nvidia,core-pwr-off-time = <0>;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&core_vdd_reg>;
 	};
 
 	usb at c5000000 {
diff --git a/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
index ef3ad2e5f270..ff8c3dcba8e9 100644
--- a/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
+++ b/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
@@ -1,6 +1,46 @@
 // SPDX-License-Identifier: GPL-2.0
 
 / {
+	core_opp_table: core-power-domain-opp-table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		core_opp_950: opp at 950000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-level = <950000>;
+		};
+
+		core_opp_1000: opp at 1000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-level = <1000000>;
+		};
+
+		core_opp_1100: opp at 1100000 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-level = <1100000>;
+		};
+
+		core_opp_1200: opp at 1200000 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-level = <1200000>;
+		};
+
+		core_opp_1225: opp at 1225000 {
+			opp-microvolt = <1225000 1225000 1300000>;
+			opp-level = <1225000>;
+		};
+
+		core_opp_1275: opp at 1275000 {
+			opp-microvolt = <1275000 1275000 1300000>;
+			opp-level = <1275000>;
+		};
+
+		core_opp_1300: opp at 1300000 {
+			opp-microvolt = <1300000 1300000 1300000>;
+			opp-level = <1300000>;
+		};
+	};
+
 	emc_icc_dvfs_opp_table: emc-dvfs-opp-table {
 		compatible = "operating-points-v2";
 
@@ -8,66 +48,77 @@ opp at 36000000 {
 			opp-microvolt = <950000 950000 1300000>;
 			opp-hz = /bits/ 64 <36000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 47500000 {
 			opp-microvolt = <950000 950000 1300000>;
 			opp-hz = /bits/ 64 <47500000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 50000000 {
 			opp-microvolt = <950000 950000 1300000>;
 			opp-hz = /bits/ 64 <50000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 54000000 {
 			opp-microvolt = <950000 950000 1300000>;
 			opp-hz = /bits/ 64 <54000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 57000000 {
 			opp-microvolt = <950000 950000 1300000>;
 			opp-hz = /bits/ 64 <57000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 100000000 {
 			opp-microvolt = <1000000 1000000 1300000>;
 			opp-hz = /bits/ 64 <100000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 108000000 {
 			opp-microvolt = <1000000 1000000 1300000>;
 			opp-hz = /bits/ 64 <108000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 126666000 {
 			opp-microvolt = <1000000 1000000 1300000>;
 			opp-hz = /bits/ 64 <126666000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 150000000 {
 			opp-microvolt = <1000000 1000000 1300000>;
 			opp-hz = /bits/ 64 <150000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 190000000 {
 			opp-microvolt = <1000000 1000000 1300000>;
 			opp-hz = /bits/ 64 <190000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 216000000 {
 			opp-microvolt = <1000000 1000000 1300000>;
 			opp-hz = /bits/ 64 <216000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
 			opp-suspend;
 		};
 
@@ -75,36 +126,926 @@ opp at 300000000 {
 			opp-microvolt = <1000000 1000000 1300000>;
 			opp-hz = /bits/ 64 <300000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 333000000 {
 			opp-microvolt = <1000000 1000000 1300000>;
 			opp-hz = /bits/ 64 <333000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 380000000 {
 			opp-microvolt = <1100000 1100000 1300000>;
 			opp-hz = /bits/ 64 <380000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
 		};
 
 		opp at 600000000 {
 			opp-microvolt = <1200000 1200000 1300000>;
 			opp-hz = /bits/ 64 <600000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
 		};
 
 		opp at 666000000 {
 			opp-microvolt = <1200000 1200000 1300000>;
 			opp-hz = /bits/ 64 <666000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
 		};
 
 		opp at 760000000 {
 			opp-microvolt = <1300000 1300000 1300000>;
 			opp-hz = /bits/ 64 <760000000>;
 			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1300>;
+		};
+	};
+
+	gr2d_dvfs_opp_table: gr2d-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 133000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <133000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 171000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <171000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 247000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <247000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 300000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	gr3d_dvfs_opp_table: gr3d-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 114000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <114000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 161500000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <161500000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 161500000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <161500000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 209000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <209000000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 218500000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <218500000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 247000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <247000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 247000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <247000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 256500000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <256500000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 285000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <285000000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 285000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <285000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 304000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <304000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 323000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <323000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 333500000,1275 {
+			opp-microvolt = <1275000 1275000 1300000>;
+			opp-hz = /bits/ 64 <333500000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1275>;
+		};
+
+		opp at 333500000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <333500000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 351500000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <351500000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 361000000,1275 {
+			opp-microvolt = <1275000 1275000 1300000>;
+			opp-hz = /bits/ 64 <361000000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1275>;
+		};
+
+		opp at 380000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <380000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 400000000,1275 {
+			opp-microvolt = <1275000 1275000 1300000>;
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1275>;
+		};
+
+		opp at 400000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	disp1_dvfs_opp_table: disp1-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 158000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <158000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 190000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <190000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+	};
+
+	disp2_dvfs_opp_table: disp2-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 158000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <158000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 190000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <190000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+	};
+
+	dsi_dvfs_opp_table: dsi-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 100000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <100000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 500000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <500000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	epp_dvfs_opp_table: epp-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 133000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <133000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 171000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <171000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 247000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <247000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 300000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	hdmi_dvfs_opp_table: hdmi-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 148500000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <148500000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	host1x_dvfs_opp_table: host1x-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 104500000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <104500000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 133000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <133000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 166000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <166000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+	};
+
+	ide_dvfs_opp_table: ide-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 100000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <100000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+	};
+
+	mipi_dvfs_opp_table: mipi-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 40000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <40000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 60000000,1275 {
+			opp-microvolt = <1275000 1275000 1300000>;
+			opp-hz = /bits/ 64 <60000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1275>;
+		};
+	};
+
+	mpe_dvfs_opp_table: mpe-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 104500000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <104500000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 142500000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <142500000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 152000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <152000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 190000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <190000000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 190000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <190000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 228000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <228000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 228000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <228000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 237500000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <237500000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 266000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <266000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 275500000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <275500000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 300000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 300000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x000C>;
+			required-opps = <&core_opp_1100>;
+		};
+	};
+
+	ndflash_dvfs_opp_table: ndflash-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 130000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <130000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 150000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <150000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 158000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <158000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 164000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <164000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	nor_dvfs_opp_table: nor-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 92000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <92000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	pcie_dvfs_opp_table: pcie-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 250000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <250000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	sdmmc1_dvfs_opp_table: sdmmc1-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 44000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <44000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 52000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <52000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	sdmmc2_dvfs_opp_table: sdmmc2-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 44000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <44000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 52000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <52000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	sdmmc3_dvfs_opp_table: sdmmc3-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 44000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <44000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 52000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <52000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	sdmmc4_dvfs_opp_table: sdmmc4-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 44000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <44000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 52000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <52000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	sclk_dvfs_opp_table: sclk-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 95000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <95000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 123500000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <123500000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 133000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <133000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 152000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <152000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 159500000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <159500000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 171000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <171000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 180500000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <180500000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 190000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <190000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 207000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <207000000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 218500000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <218500000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 222500000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <222500000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 229500000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <229500000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 240000000,1225 {
+			opp-microvolt = <1225000 1225000 1300000>;
+			opp-hz = /bits/ 64 <240000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1225>;
+		};
+
+		opp at 240000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <240000000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 247000000,1275 {
+			opp-microvolt = <1275000 1275000 1300000>;
+			opp-hz = /bits/ 64 <247000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1275>;
+		};
+
+		opp at 256500000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <256500000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 260000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <260000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 262000000,1300 {
+			opp-microvolt = <1300000 1300000 1300000>;
+			opp-hz = /bits/ 64 <262000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1300>;
+		};
+
+		opp at 264000000,1275 {
+			opp-microvolt = <1275000 1275000 1300000>;
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1275>;
+		};
+
+		opp at 277500000,1300 {
+			opp-microvolt = <1300000 1300000 1300000>;
+			opp-hz = /bits/ 64 <277500000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1300>;
+		};
+
+		opp at 285000000,1275 {
+			opp-microvolt = <1275000 1275000 1300000>;
+			opp-hz = /bits/ 64 <285000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1275>;
+		};
+
+		opp at 292500000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <292500000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 300000000,1300 {
+			opp-microvolt = <1300000 1300000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1300>;
+		};
+
+		opp at 300000000,1275 {
+			opp-microvolt = <1275000 1275000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1275>;
+		};
+	};
+
+	tvo_dvfs_opp_table: tvo-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 250000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <250000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	usbd_dvfs_opp_table: usbd-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 480000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <480000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+	};
+
+	usb2_dvfs_opp_table: usb2-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 480000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <480000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+	};
+
+	usb3_dvfs_opp_table: usb3-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 480000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <480000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+	};
+
+	vde_dvfs_opp_table: vde-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 95000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <95000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 123500000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <123500000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 123500000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <123500000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 152000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <152000000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 152000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <152000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 171000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <171000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 209000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <209000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 209000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <209000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 218500000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <218500000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 237500000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <237500000>;
+			opp-supported-hw = <0x0002>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 275500000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <275500000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 285000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <285000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 300000000,1275 {
+			opp-microvolt = <1275000 1275000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1275>;
+		};
+
+		opp at 300000000,1200 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 300000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1100>;
+		};
+	};
+
+	vi_dvfs_opp_table: vi-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 85000000,950 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <85000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 100000000,1000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <100000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 150000000,1100 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <150000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
 		};
 	};
 };
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts
index 92d494b8c3d2..5aeb7bb6c415 100644
--- a/arch/arm/boot/dts/tegra20-seaboard.dts
+++ b/arch/arm/boot/dts/tegra20-seaboard.dts
@@ -444,7 +444,7 @@ sys_reg: sys {
 					regulator-always-on;
 				};
 
-				sm0 {
+				vdd_core: sm0 {
 					regulator-name = "vdd_sm0,vdd_core";
 					regulator-min-microvolt = <1300000>;
 					regulator-max-microvolt = <1300000>;
@@ -689,6 +689,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-good-time = <3845 3845>;
 		nvidia,core-pwr-off-time = <3875>;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 	};
 
 	memory-controller at 7000f400 {
diff --git a/arch/arm/boot/dts/tegra20-tamonten.dtsi b/arch/arm/boot/dts/tegra20-tamonten.dtsi
index dd4d506683de..d5888d958175 100644
--- a/arch/arm/boot/dts/tegra20-tamonten.dtsi
+++ b/arch/arm/boot/dts/tegra20-tamonten.dtsi
@@ -357,7 +357,7 @@ sys_reg: sys {
 					regulator-always-on;
 				};
 
-				sm0 {
+				vdd_core: sm0 {
 					regulator-name = "vdd_sys_sm0,vdd_core";
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
@@ -477,6 +477,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-good-time = <3845 3845>;
 		nvidia,core-pwr-off-time = <3875>;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 	};
 
 	pcie at 80003000 {
diff --git a/arch/arm/boot/dts/tegra20-trimslice.dts b/arch/arm/boot/dts/tegra20-trimslice.dts
index 4bc87bc0c2a4..582dc7910ff8 100644
--- a/arch/arm/boot/dts/tegra20-trimslice.dts
+++ b/arch/arm/boot/dts/tegra20-trimslice.dts
@@ -321,6 +321,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-good-time = <3845 3845>;
 		nvidia,core-pwr-off-time = <3875>;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 	};
 
 	pcie at 80003000 {
@@ -444,6 +445,14 @@ pci_vdd_reg: regulator at 4 {
 		regulator-always-on;
 	};
 
+	vdd_core: regulator at 5 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_core";
+		regulator-min-microvolt = <1300000>;
+		regulator-max-microvolt = <1300000>;
+		regulator-always-on;
+	};
+
 	sound {
 		compatible = "nvidia,tegra-audio-trimslice";
 		nvidia,i2s-controller = <&tegra_i2s1>;
diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts
index 5a2578b3707f..e41ce1b1ec3f 100644
--- a/arch/arm/boot/dts/tegra20-ventana.dts
+++ b/arch/arm/boot/dts/tegra20-ventana.dts
@@ -544,6 +544,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-good-time = <3845 3845>;
 		nvidia,core-pwr-off-time = <458>;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 	};
 
 	usb at c5000000 {
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 6ce498178105..4abb6634e8ae 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -42,6 +42,8 @@ host1x at 50000000 {
 		clock-names = "host1x";
 		resets = <&tegra_car 28>;
 		reset-names = "host1x";
+		operating-points-v2 = <&host1x_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -55,6 +57,8 @@ mpe at 54040000 {
 			clocks = <&tegra_car TEGRA20_CLK_MPE>;
 			resets = <&tegra_car 60>;
 			reset-names = "mpe";
+			operating-points-v2 = <&mpe_dvfs_opp_table>;
+			power-domains = <&pd_mpe>;
 		};
 
 		vi at 54080000 {
@@ -64,6 +68,8 @@ vi at 54080000 {
 			clocks = <&tegra_car TEGRA20_CLK_VI>;
 			resets = <&tegra_car 20>;
 			reset-names = "vi";
+			operating-points-v2 = <&vi_dvfs_opp_table>;
+			power-domains = <&pd_venc>;
 		};
 
 		epp at 540c0000 {
@@ -73,6 +79,8 @@ epp at 540c0000 {
 			clocks = <&tegra_car TEGRA20_CLK_EPP>;
 			resets = <&tegra_car 19>;
 			reset-names = "epp";
+			operating-points-v2 = <&epp_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 		};
 
 		isp at 54100000 {
@@ -82,6 +90,7 @@ isp at 54100000 {
 			clocks = <&tegra_car TEGRA20_CLK_ISP>;
 			resets = <&tegra_car 23>;
 			reset-names = "isp";
+			power-domains = <&pd_venc>;
 		};
 
 		gr2d at 54140000 {
@@ -91,6 +100,8 @@ gr2d at 54140000 {
 			clocks = <&tegra_car TEGRA20_CLK_GR2D>;
 			resets = <&tegra_car 21>;
 			reset-names = "2d";
+			operating-points-v2 = <&gr2d_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 		};
 
 		gr3d at 54180000 {
@@ -99,6 +110,8 @@ gr3d at 54180000 {
 			clocks = <&tegra_car TEGRA20_CLK_GR3D>;
 			resets = <&tegra_car 24>;
 			reset-names = "3d";
+			operating-points-v2 = <&gr3d_dvfs_opp_table>;
+			power-domains = <&pd_3d>;
 		};
 
 		dc at 54200000 {
@@ -110,6 +123,8 @@ dc at 54200000 {
 			clock-names = "dc", "parent";
 			resets = <&tegra_car 27>;
 			reset-names = "dc";
+			operating-points-v2 = <&disp1_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 
 			nvidia,head = <0>;
 
@@ -138,6 +153,8 @@ dc at 54240000 {
 			clock-names = "dc", "parent";
 			resets = <&tegra_car 26>;
 			reset-names = "dc";
+			operating-points-v2 = <&disp2_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 
 			nvidia,head = <1>;
 
@@ -166,6 +183,8 @@ hdmi at 54280000 {
 			clock-names = "hdmi", "parent";
 			resets = <&tegra_car 51>;
 			reset-names = "hdmi";
+			operating-points-v2 = <&hdmi_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 			status = "disabled";
 		};
 
@@ -174,6 +193,8 @@ tvo at 542c0000 {
 			reg = <0x542c0000 0x00040000>;
 			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&tegra_car TEGRA20_CLK_TVO>;
+			operating-points-v2 = <&tvo_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 			status = "disabled";
 		};
 
@@ -185,6 +206,8 @@ dsi at 54300000 {
 			clock-names = "dsi", "parent";
 			resets = <&tegra_car 48>;
 			reset-names = "dsi";
+			operating-points-v2 = <&dsi_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 			status = "disabled";
 		};
 	};
@@ -242,6 +265,13 @@ tegra_car: clock at 60006000 {
 		reg = <0x60006000 0x1000>;
 		#clock-cells = <1>;
 		#reset-cells = <1>;
+
+		sclk {
+			compatible = "nvidia,tegra20-sclk";
+			operating-points-v2 = <&sclk_dvfs_opp_table>;
+			clocks = <&tegra_car TEGRA20_CLK_SCLK>;
+			power-domains = <&pd_core>;
+		};
 	};
 
 	flow-controller at 60007000 {
@@ -319,6 +349,8 @@ vde at 6001a000 {
 		clocks = <&tegra_car TEGRA20_CLK_VDE>;
 		reset-names = "vde", "mc";
 		resets = <&tegra_car 61>, <&mc TEGRA20_MC_RESET_VDE>;
+		operating-points-v2 = <&vde_dvfs_opp_table>;
+		power-domains = <&pd_vde>;
 	};
 
 	apbmisc at 70000800 {
@@ -460,6 +492,8 @@ nand-controller at 70008000 {
 		reset-names = "nand";
 		assigned-clocks = <&tegra_car TEGRA20_CLK_NDFLASH>;
 		assigned-clock-rates = <150000000>;
+		operating-points-v2 = <&ndflash_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -473,6 +507,8 @@ gmi at 70009000 {
 		clock-names = "gmi";
 		resets = <&tegra_car 42>;
 		reset-names = "gmi";
+		operating-points-v2 = <&nor_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -643,6 +679,52 @@ tegra_pmc: pmc at 7000e400 {
 		clocks = <&tegra_car TEGRA20_CLK_PCLK>, <&clk32k_in>;
 		clock-names = "pclk", "clk32k_in";
 		#clock-cells = <1>;
+
+		pd_core: core-domain {
+			operating-points-v2 = <&core_opp_table>;
+			#power-domain-cells = <0>;
+		};
+
+		powergates {
+			pd_3d: 3d {
+				clocks = <&tegra_car TEGRA20_CLK_GR3D>;
+				resets = <&mc TEGRA20_MC_RESET_3D>,
+					 <&tegra_car TEGRA20_CLK_GR3D>;
+				power-domains = <&pd_core>;
+				#power-domain-cells = <0>;
+			};
+
+			pd_venc: venc {
+				clocks = <&tegra_car TEGRA20_CLK_ISP>,
+					 <&tegra_car TEGRA20_CLK_VI>,
+					 <&tegra_car TEGRA20_CLK_CSI>;
+				resets = <&mc TEGRA20_MC_RESET_ISP>,
+					 <&mc TEGRA20_MC_RESET_VI>,
+					 <&tegra_car TEGRA20_CLK_ISP>,
+					 <&tegra_car 20 /* VI */>,
+					 <&tegra_car TEGRA20_CLK_CSI>;
+				power-domains = <&pd_core>;
+				#power-domain-cells = <0>;
+			};
+
+			pd_vde: vdec {
+				clocks = <&tegra_car TEGRA20_CLK_VDE>;
+				resets = <&mc TEGRA20_MC_RESET_VDE>,
+					 <&tegra_car TEGRA20_CLK_VDE>;
+				power-domains = <&pd_core>;
+				#power-domain-cells = <0>;
+			};
+
+			pd_mpe: mpe {
+				clocks = <&tegra_car TEGRA20_CLK_MPE>;
+				resets = <&mc TEGRA20_MC_RESET_MPEA>,
+					 <&mc TEGRA20_MC_RESET_MPEB>,
+					 <&mc TEGRA20_MC_RESET_MPEC>,
+					 <&tegra_car TEGRA20_CLK_MPE>;
+				power-domains = <&pd_core>;
+				#power-domain-cells = <0>;
+			};
+		};
 	};
 
 	mc: memory-controller at 7000f000 {
@@ -662,6 +744,7 @@ emc: memory-controller at 7000f400 {
 		reg = <0x7000f400 0x400>;
 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
+		power-domains = <&pd_core>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interconnect-cells = <0>;
@@ -712,6 +795,9 @@ pcie at 80003000 {
 			 <&tegra_car 72>,
 			 <&tegra_car 74>;
 		reset-names = "pex", "afi", "pcie_x";
+		operating-points-v2 = <&pcie_dvfs_opp_table>;
+		power-domains = <&pd_core>;
+
 		status = "disabled";
 
 		pci at 1,0 {
@@ -754,6 +840,8 @@ usb at c5000000 {
 		reset-names = "usb";
 		nvidia,needs-double-reset;
 		nvidia,phy = <&phy1>;
+		operating-points-v2 = <&usbd_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -791,6 +879,8 @@ usb at c5004000 {
 		resets = <&tegra_car 58>;
 		reset-names = "usb";
 		nvidia,phy = <&phy2>;
+		operating-points-v2 = <&usb2_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -817,6 +907,8 @@ usb at c5008000 {
 		resets = <&tegra_car 59>;
 		reset-names = "usb";
 		nvidia,phy = <&phy3>;
+		operating-points-v2 = <&usb3_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -851,6 +943,8 @@ mmc at c8000000 {
 		clock-names = "sdhci";
 		resets = <&tegra_car 14>;
 		reset-names = "sdhci";
+		operating-points-v2 = <&sdmmc1_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -862,6 +956,8 @@ mmc at c8000200 {
 		clock-names = "sdhci";
 		resets = <&tegra_car 9>;
 		reset-names = "sdhci";
+		operating-points-v2 = <&sdmmc2_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -873,6 +969,8 @@ mmc at c8000400 {
 		clock-names = "sdhci";
 		resets = <&tegra_car 69>;
 		reset-names = "sdhci";
+		operating-points-v2 = <&sdmmc3_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -884,6 +982,8 @@ mmc at c8000600 {
 		clock-names = "sdhci";
 		resets = <&tegra_car 15>;
 		reset-names = "sdhci";
+		operating-points-v2 = <&sdmmc4_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:30 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:30 +0300
Subject: [PATCH v11 32/34] ARM: tegra: Add Memory Client resets to Tegra20
 GR2D, GR3D and Host1x
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-33-digetx@gmail.com>

Memory access must be blocked before hardware reset is asserted and before
power is gated, otherwise a serious hardware fault is inevitable. Add
reset for memory clients to the GR2D, GR3D and Host1x nodes.

Tested-by: Paul Fertser <fercerpav at gmail.com> # PAZ00 T20
Tested-by: Nicolas Chauvet <kwizart at gmail.com> # PAZ00 T20
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 arch/arm/boot/dts/tegra20.dtsi | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 4abb6634e8ae..8ab77583846b 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -40,8 +40,8 @@ host1x at 50000000 {
 		interrupt-names = "syncpt", "host1x";
 		clocks = <&tegra_car TEGRA20_CLK_HOST1X>;
 		clock-names = "host1x";
-		resets = <&tegra_car 28>;
-		reset-names = "host1x";
+		resets = <&tegra_car 28>, <&mc TEGRA20_MC_RESET_HC>;
+		reset-names = "host1x", "mc";
 		operating-points-v2 = <&host1x_dvfs_opp_table>;
 		power-domains = <&pd_core>;
 
@@ -98,8 +98,8 @@ gr2d at 54140000 {
 			reg = <0x54140000 0x00040000>;
 			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&tegra_car TEGRA20_CLK_GR2D>;
-			resets = <&tegra_car 21>;
-			reset-names = "2d";
+			resets = <&tegra_car 21>, <&mc TEGRA20_MC_RESET_2D>;
+			reset-names = "2d", "mc";
 			operating-points-v2 = <&gr2d_dvfs_opp_table>;
 			power-domains = <&pd_core>;
 		};
@@ -108,8 +108,8 @@ gr3d at 54180000 {
 			compatible = "nvidia,tegra20-gr3d";
 			reg = <0x54180000 0x00040000>;
 			clocks = <&tegra_car TEGRA20_CLK_GR3D>;
-			resets = <&tegra_car 24>;
-			reset-names = "3d";
+			resets = <&tegra_car 24>, <&mc TEGRA20_MC_RESET_3D>;
+			reset-names = "3d", "mc";
 			operating-points-v2 = <&gr3d_dvfs_opp_table>;
 			power-domains = <&pd_3d>;
 		};
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:32 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:32 +0300
Subject: [PATCH v11 34/34] ARM: tegra20/30: Disable unused host1x hardware
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-35-digetx@gmail.com>

MPE, VI, EPP and ISP were never used and we don't have drivers for them.
Since these modules are enabled by default in a device-tree, a device is
created for them, blocking voltage scaling because there is no driver to
bind, and thus, state of PMC driver is never synced. Disable them.

Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 arch/arm/boot/dts/tegra20.dtsi | 4 ++++
 arch/arm/boot/dts/tegra30.dtsi | 8 ++++++++
 2 files changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 8ab77583846b..6eb13da7f91f 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -59,6 +59,7 @@ mpe at 54040000 {
 			reset-names = "mpe";
 			operating-points-v2 = <&mpe_dvfs_opp_table>;
 			power-domains = <&pd_mpe>;
+			status = "disabled";
 		};
 
 		vi at 54080000 {
@@ -70,6 +71,7 @@ vi at 54080000 {
 			reset-names = "vi";
 			operating-points-v2 = <&vi_dvfs_opp_table>;
 			power-domains = <&pd_venc>;
+			status = "disabled";
 		};
 
 		epp at 540c0000 {
@@ -81,6 +83,7 @@ epp at 540c0000 {
 			reset-names = "epp";
 			operating-points-v2 = <&epp_dvfs_opp_table>;
 			power-domains = <&pd_core>;
+			status = "disabled";
 		};
 
 		isp at 54100000 {
@@ -91,6 +94,7 @@ isp at 54100000 {
 			resets = <&tegra_car 23>;
 			reset-names = "isp";
 			power-domains = <&pd_venc>;
+			status = "disabled";
 		};
 
 		gr2d at 54140000 {
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 58ef4983e511..61f74b7879bb 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -145,6 +145,8 @@ mpe at 54040000 {
 			power-domains = <&pd_mpe>;
 
 			iommus = <&mc TEGRA_SWGROUP_MPE>;
+
+			status = "disabled";
 		};
 
 		vi at 54080000 {
@@ -158,6 +160,8 @@ vi at 54080000 {
 			power-domains = <&pd_venc>;
 
 			iommus = <&mc TEGRA_SWGROUP_VI>;
+
+			status = "disabled";
 		};
 
 		epp at 540c0000 {
@@ -171,6 +175,8 @@ epp at 540c0000 {
 			power-domains = <&pd_heg>;
 
 			iommus = <&mc TEGRA_SWGROUP_EPP>;
+
+			status = "disabled";
 		};
 
 		isp at 54100000 {
@@ -183,6 +189,8 @@ isp at 54100000 {
 			power-domains = <&pd_venc>;
 
 			iommus = <&mc TEGRA_SWGROUP_ISP>;
+
+			status = "disabled";
 		};
 
 		gr2d at 54140000 {
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:29 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:29 +0300
Subject: [PATCH v11 31/34] ARM: tegra: Add OPP tables and power domains to
 Tegra30 device-trees
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-32-digetx@gmail.com>

Add OPP tables and power domains to all peripheral devices which
support power management on Tegra30 SoC.

Tested-by: Peter Geis <pgwipeout at gmail.com> # Ouya T30
Tested-by: Matt Merhar <mattmerhar at protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 .../tegra30-asus-nexus7-grouper-common.dtsi   |    1 +
 arch/arm/boot/dts/tegra30-beaver.dts          |    1 +
 arch/arm/boot/dts/tegra30-cardhu.dtsi         |    1 +
 arch/arm/boot/dts/tegra30-colibri.dtsi        |   17 +-
 arch/arm/boot/dts/tegra30-ouya.dts            |    1 +
 .../arm/boot/dts/tegra30-peripherals-opp.dtsi | 1412 +++++++++++++++++
 arch/arm/boot/dts/tegra30.dtsi                |  153 ++
 7 files changed, 1583 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi
index 9732cd6f20b7..4f116c26f6ce 100644
--- a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi
+++ b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi
@@ -957,6 +957,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-off-time = <0>;
 		nvidia,core-power-req-active-high;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 	};
 
 	ahub at 70080000 {
diff --git a/arch/arm/boot/dts/tegra30-beaver.dts b/arch/arm/boot/dts/tegra30-beaver.dts
index e159feeedef7..b54cbb24c4d3 100644
--- a/arch/arm/boot/dts/tegra30-beaver.dts
+++ b/arch/arm/boot/dts/tegra30-beaver.dts
@@ -1915,6 +1915,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-off-time = <0>;
 		nvidia,core-power-req-active-high;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&core_vdd_reg>;
 	};
 
 	ahub at 70080000 {
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
index 448f1397e64a..b2bba923eb93 100644
--- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -391,6 +391,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-off-time = <0>;
 		nvidia,core-power-req-active-high;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 	};
 
 	ahub at 70080000 {
diff --git a/arch/arm/boot/dts/tegra30-colibri.dtsi b/arch/arm/boot/dts/tegra30-colibri.dtsi
index 413e35215804..0627b64f044d 100644
--- a/arch/arm/boot/dts/tegra30-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra30-colibri.dtsi
@@ -765,9 +765,14 @@ vdd1_reg: vdd1 {
 
 				vddctrl_reg: vddctrl {
 					regulator-name = "+V1.0_VDD_CPU";
-					regulator-min-microvolt = <1150000>;
-					regulator-max-microvolt = <1150000>;
+					regulator-min-microvolt = <800000>;
+					regulator-max-microvolt = <1250000>;
+					regulator-coupled-with = <&vdd_core>;
+					regulator-coupled-max-spread = <300000>;
+					regulator-max-step-microvolt = <100000>;
 					regulator-always-on;
+
+					nvidia,tegra-cpu-regulator;
 				};
 
 				reg_1v8_vio: vio {
@@ -890,18 +895,23 @@ temp-sensor at 4c {
 		};
 
 		/* SW: +V1.2_VDD_CORE */
-		regulator at 60 {
+		vdd_core: regulator at 60 {
 			compatible = "ti,tps62362";
 			reg = <0x60>;
 
 			regulator-name = "tps62362-vout";
 			regulator-min-microvolt = <900000>;
 			regulator-max-microvolt = <1400000>;
+			regulator-coupled-with = <&vddctrl_reg>;
+			regulator-coupled-max-spread = <300000>;
+			regulator-max-step-microvolt = <100000>;
 			regulator-boot-on;
 			regulator-always-on;
 			ti,vsel0-state-low;
 			/* VSEL1: EN_CORE_DVFS_N low for DVFS */
 			ti,vsel1-state-low;
+
+			nvidia,tegra-core-regulator;
 		};
 	};
 
@@ -914,6 +924,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-off-time = <0>;
 		nvidia,core-power-req-active-high;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 
 		/* Set DEV_OFF bit in DCDC control register of TPS65911 PMIC */
 		i2c-thermtrip {
diff --git a/arch/arm/boot/dts/tegra30-ouya.dts b/arch/arm/boot/dts/tegra30-ouya.dts
index 90db5ff72537..2a79cd4662b1 100644
--- a/arch/arm/boot/dts/tegra30-ouya.dts
+++ b/arch/arm/boot/dts/tegra30-ouya.dts
@@ -274,6 +274,7 @@ pmc at 7000e400 {
 		nvidia,core-pwr-off-time = <458>;
 		nvidia,core-power-req-active-high;
 		nvidia,sys-clock-req-active-high;
+		core-supply = <&vdd_core>;
 	};
 
 	mc_timings: memory-controller at 7000f000 {
diff --git a/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi
index 2c9780319725..e77f0be7ade3 100644
--- a/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi
+++ b/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi
@@ -1,6 +1,56 @@
 // SPDX-License-Identifier: GPL-2.0
 
 / {
+	core_opp_table: core-power-domain-opp-table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		core_opp_950: opp at 950000 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-level = <950000>;
+		};
+
+		core_opp_1000: opp at 1000000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-level = <1000000>;
+		};
+
+		core_opp_1050: opp at 1050000 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-level = <1050000>;
+		};
+
+		core_opp_1100: opp at 1100000 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-level = <1100000>;
+		};
+
+		core_opp_1150: opp at 1150000 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-level = <1150000>;
+		};
+
+		core_opp_1200: opp at 1200000 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-level = <1200000>;
+		};
+
+		core_opp_1250: opp at 1250000 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-level = <1250000>;
+		};
+
+		core_opp_1300: opp at 1300000 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-level = <1300000>;
+		};
+
+		core_opp_1350: opp at 1350000 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-level = <1350000>;
+		};
+	};
+
 	emc_icc_dvfs_opp_table: emc-dvfs-opp-table {
 		compatible = "operating-points-v2";
 
@@ -8,126 +58,147 @@ opp at 12750000,950 {
 			opp-microvolt = <950000 950000 1350000>;
 			opp-hz = /bits/ 64 <12750000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 12750000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <12750000>;
 			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 12750000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <12750000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 25500000,950 {
 			opp-microvolt = <950000 950000 1350000>;
 			opp-hz = /bits/ 64 <25500000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 25500000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <25500000>;
 			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 25500000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <25500000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 27000000,950 {
 			opp-microvolt = <950000 950000 1350000>;
 			opp-hz = /bits/ 64 <27000000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 27000000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <27000000>;
 			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 27000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <27000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 51000000,950 {
 			opp-microvolt = <950000 950000 1350000>;
 			opp-hz = /bits/ 64 <51000000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 51000000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <51000000>;
 			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 51000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <51000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 54000000,950 {
 			opp-microvolt = <950000 950000 1350000>;
 			opp-hz = /bits/ 64 <54000000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 54000000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <54000000>;
 			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 54000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <54000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 102000000,950 {
 			opp-microvolt = <950000 950000 1350000>;
 			opp-hz = /bits/ 64 <102000000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_950>;
 		};
 
 		opp at 102000000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <102000000>;
 			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 102000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <102000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 108000000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <108000000>;
 			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 108000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <108000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 204000000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <204000000>;
 			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1000>;
 			opp-suspend;
 		};
 
@@ -135,6 +206,7 @@ opp at 204000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <204000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 			opp-suspend;
 		};
 
@@ -142,126 +214,147 @@ opp at 333500000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <333500000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 333500000,1200 {
 			opp-microvolt = <1200000 1200000 1350000>;
 			opp-hz = /bits/ 64 <333500000>;
 			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1200>;
 		};
 
 		opp at 333500000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <333500000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 375000000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <375000000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 375000000,1200 {
 			opp-microvolt = <1200000 1200000 1350000>;
 			opp-hz = /bits/ 64 <375000000>;
 			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1200>;
 		};
 
 		opp at 375000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <375000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 400000000,1000 {
 			opp-microvolt = <1000000 1000000 1350000>;
 			opp-hz = /bits/ 64 <400000000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1000>;
 		};
 
 		opp at 400000000,1200 {
 			opp-microvolt = <1200000 1200000 1350000>;
 			opp-hz = /bits/ 64 <400000000>;
 			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1200>;
 		};
 
 		opp at 400000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <400000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 416000000,1200 {
 			opp-microvolt = <1200000 1200000 1350000>;
 			opp-hz = /bits/ 64 <416000000>;
 			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1200>;
 		};
 
 		opp at 416000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <416000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 450000000,1200 {
 			opp-microvolt = <1200000 1200000 1350000>;
 			opp-hz = /bits/ 64 <450000000>;
 			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1200>;
 		};
 
 		opp at 450000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <450000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 533000000,1200 {
 			opp-microvolt = <1200000 1200000 1350000>;
 			opp-hz = /bits/ 64 <533000000>;
 			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1200>;
 		};
 
 		opp at 533000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <533000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 625000000,1200 {
 			opp-microvolt = <1200000 1200000 1350000>;
 			opp-hz = /bits/ 64 <625000000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1200>;
 		};
 
 		opp at 625000000,1250 {
 			opp-microvolt = <1250000 1250000 1350000>;
 			opp-hz = /bits/ 64 <625000000>;
 			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
 		};
 
 		opp at 667000000,1200 {
 			opp-microvolt = <1200000 1200000 1350000>;
 			opp-hz = /bits/ 64 <667000000>;
 			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1200>;
 		};
 
 		opp at 750000000,1300 {
 			opp-microvolt = <1300000 1300000 1350000>;
 			opp-hz = /bits/ 64 <750000000>;
 			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1300>;
 		};
 
 		opp at 800000000,1300 {
 			opp-microvolt = <1300000 1300000 1350000>;
 			opp-hz = /bits/ 64 <800000000>;
 			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1300>;
 		};
 
 		opp at 900000000,1350 {
 			opp-microvolt = <1350000 1350000 1350000>;
 			opp-hz = /bits/ 64 <900000000>;
 			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1350>;
 		};
 	};
 
@@ -383,4 +476,1323 @@ opp at 900000000 {
 			opp-peak-kBps = <7200000>;
 		};
 	};
+
+	gr2d_dvfs_opp_table: gr2d-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 267000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <267000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 285000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <285000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 304000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <304000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 332000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <332000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 361000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <361000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 380000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <380000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 408000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <408000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 416000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 446000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <446000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 484000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <484000000>;
+			opp-supported-hw = <0x000C>;
+			required-opps = <&core_opp_1250>;
+		};
+
+		opp at 520000000,1300 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-hz = /bits/ 64 <520000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1300>;
+		};
+
+		opp at 600000000,1350 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1350>;
+		};
+	};
+
+	gr3d_dvfs_opp_table: gr3d-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 234000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <234000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1000>, <&core_opp_1000>;
+		};
+
+		opp at 247000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <247000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1000>, <&core_opp_1000>;
+		};
+
+		opp at 285000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <285000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1050>, <&core_opp_1050>;
+		};
+
+		opp at 304000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <304000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1050>, <&core_opp_1050>;
+		};
+
+		opp at 332000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <332000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1100>, <&core_opp_1100>;
+		};
+
+		opp at 361000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <361000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1100>, <&core_opp_1100>;
+		};
+
+		opp at 380000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <380000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1150>, <&core_opp_1150>;
+		};
+
+		opp at 408000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <408000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1150>, <&core_opp_1150>;
+		};
+
+		opp at 416000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1200>, <&core_opp_1200>;
+		};
+
+		opp at 446000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <446000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1200>, <&core_opp_1200>;
+		};
+
+		opp at 484000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <484000000>;
+			opp-supported-hw = <0x000C>;
+			required-opps = <&core_opp_1250>, <&core_opp_1250>;
+		};
+
+		opp at 520000000,1300 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-hz = /bits/ 64 <520000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1300>, <&core_opp_1300>;
+		};
+
+		opp at 600000000,1350 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1350>, <&core_opp_1350>;
+		};
+	};
+
+	afi_dvfs_opp_table: afi-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 250000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <250000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	cve_dvfs_opp_table: cve-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 297000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <297000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1050>;
+		};
+	};
+
+	disp1_dvfs_opp_table: disp1-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 120000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <120000000>;
+			opp-supported-hw = <0x0009>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 155000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <155000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 190000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <190000000>;
+			opp-supported-hw = <0x0009>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 268000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <268000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1050>;
+		};
+	};
+
+	disp2_dvfs_opp_table: disp2-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 120000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <120000000>;
+			opp-supported-hw = <0x0009>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 155000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <155000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 190000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <190000000>;
+			opp-supported-hw = <0x0009>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 268000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <268000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1050>;
+		};
+	};
+
+	dsia_dvfs_opp_table: dsia-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 275000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <275000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	dsib_dvfs_opp_table: dsib-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 275000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <275000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	epp_dvfs_opp_table: epp-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 267000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <267000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 285000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <285000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 304000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <304000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 332000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <332000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 361000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <361000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 380000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <380000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 408000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <408000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 416000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 446000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <446000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 484000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <484000000>;
+			opp-supported-hw = <0x000C>;
+			required-opps = <&core_opp_1250>;
+		};
+
+		opp at 520000000,1300 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-hz = /bits/ 64 <520000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1300>;
+		};
+
+		opp at 600000000,1350 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1350>;
+		};
+	};
+
+	fuse_burn_dvfs_opp_table: fuse-burn-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 26000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <26000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1150>;
+		};
+	};
+
+	hdmi_dvfs_opp_table: hdmi-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 148500000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <148500000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	host1x_dvfs_opp_table: host1x-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 152000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <152000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 188000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <188000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 222000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <222000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 242000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <242000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
+		};
+
+		opp at 254000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <254000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 267000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <267000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 300000000,1350 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1350>;
+		};
+	};
+
+	mipi_dvfs_opp_table: mipi-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 60000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <60000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	mpe_dvfs_opp_table: mpe-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 234000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <234000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 247000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <247000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 285000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <285000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 304000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <304000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 332000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <332000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 361000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <361000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 380000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <380000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 408000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <408000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 416000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 446000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <446000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 484000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <484000000>;
+			opp-supported-hw = <0x000C>;
+			required-opps = <&core_opp_1250>;
+		};
+
+		opp at 520000000,1300 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-hz = /bits/ 64 <520000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1300>;
+		};
+
+		opp at 600000000,1350 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1350>;
+		};
+	};
+
+	sclk_dvfs_opp_table: sclk-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 51000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <51000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 136000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <136000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 164000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <164000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 191000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <191000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 205000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <205000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 216000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <216000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 227000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <227000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 267000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <267000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 334000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <334000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1250>;
+		};
+
+		opp at 378000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <378000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
+		};
+	};
+
+	se_dvfs_opp_table: se-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 267000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <267000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 285000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <285000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 304000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <304000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 332000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <332000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 361000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <361000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 380000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <380000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 408000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <408000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 416000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 446000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <446000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 484000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <484000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1250>;
+		};
+
+		opp at 520000000,1300 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-hz = /bits/ 64 <520000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1300>;
+		};
+
+		opp at 600000000,1350 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1350>;
+		};
+
+		opp at 625000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <625000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
+		};
+	};
+
+	ndflash_dvfs_opp_table: ndflash-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 120000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <120000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 200000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <200000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1150>;
+		};
+	};
+
+	nor_dvfs_opp_table: nor-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 108000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <108000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
+		};
+
+		opp at 115000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <115000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 130000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <130000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 133000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <133000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1150>;
+		};
+	};
+
+	pcie_dvfs_opp_table: pcie-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 250000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <250000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	pll_c_dvfs_opp_table: pllc-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 533000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <533000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 667000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <667000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 800000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <800000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 1066000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <1066000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 1200000000,1350 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1350>;
+		};
+	};
+
+	pll_e_dvfs_opp_table: plle-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 100000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <100000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	pll_m_dvfs_opp_table: pllm-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 533000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <533000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 667000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <667000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 800000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <800000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 1066000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <1066000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	pwm_dvfs_opp_table: pwm-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 408000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <408000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	sata_dvfs_opp_table: sata-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 216000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <216000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	sata_oob_dvfs_opp_table: sata-oob-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 216000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <216000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	sbc1_dvfs_opp_table: sbc1-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 52000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <52000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 60000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <60000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 100000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <100000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	sbc2_dvfs_opp_table: sbc2-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 52000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <52000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 60000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <60000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 100000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <100000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	sbc3_dvfs_opp_table: sbc3-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 52000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <52000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 60000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <60000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 100000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <100000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	sbc4_dvfs_opp_table: sbc4-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 52000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <52000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 60000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <60000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 100000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <100000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	sbc5_dvfs_opp_table: sbc5-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 52000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <52000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 60000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <60000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 100000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <100000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	sbc6_dvfs_opp_table: sbc6-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 52000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <52000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 60000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <60000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 100000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <100000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	sdmmc1_dvfs_opp_table: sdmmc1-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 104000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <104000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 208000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <208000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	sdmmc3_dvfs_opp_table: sdmmc3-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 104000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <104000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_950>;
+		};
+
+		opp at 208000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <208000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1200>;
+		};
+	};
+
+	spdif_out_dvfs_opp_table: spdif-out-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 26000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <26000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	tvdac_dvfs_opp_table: tvdac-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 220000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <220000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	tvo_dvfs_opp_table: tvo-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 297000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <297000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1050>;
+		};
+	};
+
+	usbd_dvfs_opp_table: usbd-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 480000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <480000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	usb2_dvfs_opp_table: usb2-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 480000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <480000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	usb3_dvfs_opp_table: usb3-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 480000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <480000000>;
+			opp-supported-hw = <0x000F>;
+			required-opps = <&core_opp_1000>;
+		};
+	};
+
+	vde_dvfs_opp_table: vde-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 228000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <228000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 247000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <247000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 275000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <275000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 304000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <304000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 332000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <332000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 352000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <352000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 380000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <380000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 400000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 416000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 437000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <437000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 484000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <484000000>;
+			opp-supported-hw = <0x000C>;
+			required-opps = <&core_opp_1250>;
+		};
+
+		opp at 520000000,1300 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-hz = /bits/ 64 <520000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1300>;
+		};
+
+		opp at 600000000,1350 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1350>;
+		};
+	};
+
+	vi_dvfs_opp_table: vi-opp-table {
+		compatible = "operating-points-v2";
+
+		opp at 216000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <216000000>;
+			opp-supported-hw = <0x0003>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 219000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <219000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1000>;
+		};
+
+		opp at 267000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <267000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 285000000,1050 {
+			opp-microvolt = <1050000 1050000 1350000>;
+			opp-hz = /bits/ 64 <285000000>;
+			opp-supported-hw = <0x0001>;
+			required-opps = <&core_opp_1050>;
+		};
+
+		opp at 300000000,1100 {
+			opp-microvolt = <1100000 1100000 1350000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0007>;
+			required-opps = <&core_opp_1100>;
+		};
+
+		opp at 371000000,1150 {
+			opp-microvolt = <1150000 1150000 1350000>;
+			opp-hz = /bits/ 64 <371000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1150>;
+		};
+
+		opp at 409000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <409000000>;
+			opp-supported-hw = <0x0006>;
+			required-opps = <&core_opp_1200>;
+		};
+
+		opp at 425000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <425000000>;
+			opp-supported-hw = <0x0004>;
+			required-opps = <&core_opp_1250>;
+		};
+
+		opp at 470000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <470000000>;
+			opp-supported-hw = <0x0008>;
+			required-opps = <&core_opp_1250>;
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index eaf4951d9ff8..9c7616abaa2e 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -55,6 +55,8 @@ pcie at 3000 {
 			 <&tegra_car 72>,
 			 <&tegra_car 74>;
 		reset-names = "pex", "afi", "pcie_x";
+		operating-points-v2 = <&pcie_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 
 		pci at 1,0 {
@@ -124,6 +126,8 @@ host1x at 50000000 {
 		resets = <&tegra_car 28>;
 		reset-names = "host1x";
 		iommus = <&mc TEGRA_SWGROUP_HC>;
+		operating-points-v2 = <&host1x_dvfs_opp_table>;
+		power-domains = <&pd_heg>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
@@ -137,6 +141,8 @@ mpe at 54040000 {
 			clocks = <&tegra_car TEGRA30_CLK_MPE>;
 			resets = <&tegra_car 60>;
 			reset-names = "mpe";
+			operating-points-v2 = <&mpe_dvfs_opp_table>;
+			power-domains = <&pd_mpe>;
 
 			iommus = <&mc TEGRA_SWGROUP_MPE>;
 		};
@@ -148,6 +154,8 @@ vi at 54080000 {
 			clocks = <&tegra_car TEGRA30_CLK_VI>;
 			resets = <&tegra_car 20>;
 			reset-names = "vi";
+			operating-points-v2 = <&vi_dvfs_opp_table>;
+			power-domains = <&pd_venc>;
 
 			iommus = <&mc TEGRA_SWGROUP_VI>;
 		};
@@ -159,6 +167,8 @@ epp at 540c0000 {
 			clocks = <&tegra_car TEGRA30_CLK_EPP>;
 			resets = <&tegra_car 19>;
 			reset-names = "epp";
+			operating-points-v2 = <&epp_dvfs_opp_table>;
+			power-domains = <&pd_heg>;
 
 			iommus = <&mc TEGRA_SWGROUP_EPP>;
 		};
@@ -170,6 +180,7 @@ isp at 54100000 {
 			clocks = <&tegra_car TEGRA30_CLK_ISP>;
 			resets = <&tegra_car 23>;
 			reset-names = "isp";
+			power-domains = <&pd_venc>;
 
 			iommus = <&mc TEGRA_SWGROUP_ISP>;
 		};
@@ -181,6 +192,8 @@ gr2d at 54140000 {
 			clocks = <&tegra_car TEGRA30_CLK_GR2D>;
 			resets = <&tegra_car 21>;
 			reset-names = "2d";
+			operating-points-v2 = <&gr2d_dvfs_opp_table>;
+			power-domains = <&pd_heg>;
 
 			iommus = <&mc TEGRA_SWGROUP_G2>;
 		};
@@ -194,6 +207,9 @@ gr3d at 54180000 {
 			resets = <&tegra_car 24>,
 				 <&tegra_car 98>;
 			reset-names = "3d", "3d2";
+			operating-points-v2 = <&gr3d_dvfs_opp_table>;
+			power-domains = <&pd_3d0>, <&pd_3d1>;
+			power-domain-names = "3d0", "3d1";
 
 			iommus = <&mc TEGRA_SWGROUP_NV>,
 				 <&mc TEGRA_SWGROUP_NV2>;
@@ -208,6 +224,8 @@ dc at 54200000 {
 			clock-names = "dc", "parent";
 			resets = <&tegra_car 27>;
 			reset-names = "dc";
+			operating-points-v2 = <&disp1_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 
 			iommus = <&mc TEGRA_SWGROUP_DC>;
 
@@ -238,6 +256,8 @@ dc at 54240000 {
 			clock-names = "dc", "parent";
 			resets = <&tegra_car 26>;
 			reset-names = "dc";
+			operating-points-v2 = <&disp2_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 
 			iommus = <&mc TEGRA_SWGROUP_DCB>;
 
@@ -268,6 +288,8 @@ hdmi at 54280000 {
 			clock-names = "hdmi", "parent";
 			resets = <&tegra_car 51>;
 			reset-names = "hdmi";
+			operating-points-v2 = <&hdmi_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 			status = "disabled";
 		};
 
@@ -276,6 +298,8 @@ tvo at 542c0000 {
 			reg = <0x542c0000 0x00040000>;
 			interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&tegra_car TEGRA30_CLK_TVO>;
+			operating-points-v2 = <&tvo_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 			status = "disabled";
 		};
 
@@ -287,6 +311,8 @@ dsi at 54300000 {
 			clock-names = "dsi", "parent";
 			resets = <&tegra_car 48>;
 			reset-names = "dsi";
+			operating-points-v2 = <&dsia_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 			status = "disabled";
 		};
 
@@ -298,6 +324,8 @@ dsi at 54400000 {
 			clock-names = "dsi", "parent";
 			resets = <&tegra_car 84>;
 			reset-names = "dsi";
+			operating-points-v2 = <&dsib_dvfs_opp_table>;
+			power-domains = <&pd_core>;
 			status = "disabled";
 		};
 	};
@@ -358,6 +386,34 @@ tegra_car: clock at 60006000 {
 		reg = <0x60006000 0x1000>;
 		#clock-cells = <1>;
 		#reset-cells = <1>;
+
+		sclk {
+			compatible = "nvidia,tegra30-sclk";
+			operating-points-v2 = <&sclk_dvfs_opp_table>;
+			clocks = <&tegra_car TEGRA30_CLK_SCLK>;
+			power-domains = <&pd_core>;
+		};
+
+		pll-c {
+			compatible = "nvidia,tegra30-pllc";
+			operating-points-v2 = <&pll_c_dvfs_opp_table>;
+			clocks = <&tegra_car TEGRA30_CLK_PLL_C>;
+			power-domains = <&pd_core>;
+		};
+
+		pll-e {
+			compatible = "nvidia,tegra30-plle";
+			operating-points-v2 = <&pll_e_dvfs_opp_table>;
+			clocks = <&tegra_car TEGRA30_CLK_PLL_E>;
+			power-domains = <&pd_core>;
+		};
+
+		pll-m {
+			compatible = "nvidia,tegra30-pllm";
+			operating-points-v2 = <&pll_m_dvfs_opp_table>;
+			clocks = <&tegra_car TEGRA30_CLK_PLL_M>;
+			power-domains = <&pd_core>;
+		};
 	};
 
 	flow-controller at 60007000 {
@@ -468,6 +524,8 @@ vde at 6001a000 {
 		reset-names = "vde", "mc";
 		resets = <&tegra_car 61>, <&mc TEGRA30_MC_RESET_VDE>;
 		iommus = <&mc TEGRA_SWGROUP_VDE>;
+		operating-points-v2 = <&vde_dvfs_opp_table>;
+		power-domains = <&pd_vde>;
 	};
 
 	apbmisc at 70000800 {
@@ -565,6 +623,8 @@ gmi at 70009000 {
 		clock-names = "gmi";
 		resets = <&tegra_car 42>;
 		reset-names = "gmi";
+		operating-points-v2 = <&nor_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -575,6 +635,8 @@ pwm: pwm at 7000a000 {
 		clocks = <&tegra_car TEGRA30_CLK_PWM>;
 		resets = <&tegra_car 17>;
 		reset-names = "pwm";
+		operating-points-v2 = <&pwm_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -676,6 +738,8 @@ spi at 7000d400 {
 		reset-names = "spi";
 		dmas = <&apbdma 15>, <&apbdma 15>;
 		dma-names = "rx", "tx";
+		operating-points-v2 = <&sbc1_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -690,6 +754,8 @@ spi at 7000d600 {
 		reset-names = "spi";
 		dmas = <&apbdma 16>, <&apbdma 16>;
 		dma-names = "rx", "tx";
+		operating-points-v2 = <&sbc2_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -704,6 +770,8 @@ spi at 7000d800 {
 		reset-names = "spi";
 		dmas = <&apbdma 17>, <&apbdma 17>;
 		dma-names = "rx", "tx";
+		operating-points-v2 = <&sbc3_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -718,6 +786,8 @@ spi at 7000da00 {
 		reset-names = "spi";
 		dmas = <&apbdma 18>, <&apbdma 18>;
 		dma-names = "rx", "tx";
+		operating-points-v2 = <&sbc4_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -732,6 +802,8 @@ spi at 7000dc00 {
 		reset-names = "spi";
 		dmas = <&apbdma 27>, <&apbdma 27>;
 		dma-names = "rx", "tx";
+		operating-points-v2 = <&sbc5_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -746,6 +818,8 @@ spi at 7000de00 {
 		reset-names = "spi";
 		dmas = <&apbdma 28>, <&apbdma 28>;
 		dma-names = "rx", "tx";
+		operating-points-v2 = <&sbc6_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -765,6 +839,72 @@ tegra_pmc: pmc at 7000e400 {
 		clocks = <&tegra_car TEGRA30_CLK_PCLK>, <&clk32k_in>;
 		clock-names = "pclk", "clk32k_in";
 		#clock-cells = <1>;
+
+		pd_core: core-domain {
+			operating-points-v2 = <&core_opp_table>;
+			#power-domain-cells = <0>;
+		};
+
+		powergates {
+			pd_3d0: 3d0 {
+				clocks = <&tegra_car TEGRA30_CLK_GR3D>;
+				resets = <&mc TEGRA30_MC_RESET_3D>,
+					 <&tegra_car TEGRA30_CLK_GR3D>;
+				power-domains = <&pd_core>;
+				#power-domain-cells = <0>;
+			};
+
+			pd_3d1: 3d1 {
+				clocks = <&tegra_car TEGRA30_CLK_GR3D2>;
+				resets = <&mc TEGRA30_MC_RESET_3D2>,
+					 <&tegra_car TEGRA30_CLK_GR3D2>;
+				power-domains = <&pd_core>;
+				#power-domain-cells = <0>;
+			};
+
+			pd_venc: venc {
+				clocks = <&tegra_car TEGRA30_CLK_ISP>,
+					 <&tegra_car TEGRA30_CLK_VI>,
+					 <&tegra_car TEGRA30_CLK_CSI>;
+				resets = <&mc TEGRA30_MC_RESET_ISP>,
+					 <&mc TEGRA30_MC_RESET_VI>,
+					 <&tegra_car TEGRA30_CLK_ISP>,
+					 <&tegra_car 20 /* VI */>,
+					 <&tegra_car TEGRA30_CLK_CSI>;
+				power-domains = <&pd_core>;
+				#power-domain-cells = <0>;
+			};
+
+			pd_vde: vdec {
+				clocks = <&tegra_car TEGRA30_CLK_VDE>;
+				resets = <&mc TEGRA30_MC_RESET_VDE>,
+					 <&tegra_car TEGRA30_CLK_VDE>;
+				power-domains = <&pd_core>;
+				#power-domain-cells = <0>;
+			};
+
+			pd_mpe: mpe {
+				clocks = <&tegra_car TEGRA30_CLK_MPE>;
+				resets = <&mc TEGRA30_MC_RESET_MPE>,
+					 <&tegra_car TEGRA30_CLK_MPE>;
+				power-domains = <&pd_core>;
+				#power-domain-cells = <0>;
+			};
+
+			pd_heg: heg {
+				clocks = <&tegra_car TEGRA30_CLK_GR2D>,
+					 <&tegra_car TEGRA30_CLK_EPP>,
+					 <&tegra_car TEGRA30_CLK_HOST1X>;
+				resets = <&mc TEGRA30_MC_RESET_2D>,
+					 <&mc TEGRA30_MC_RESET_EPP>,
+					 <&mc TEGRA30_MC_RESET_HC>,
+					 <&tegra_car TEGRA30_CLK_GR2D>,
+					 <&tegra_car TEGRA30_CLK_EPP>,
+					 <&tegra_car TEGRA30_CLK_HOST1X>;
+				power-domains = <&pd_core>;
+				#power-domain-cells = <0>;
+			};
+		};
 	};
 
 	mc: memory-controller at 7000f000 {
@@ -785,6 +925,7 @@ emc: memory-controller at 7000f400 {
 		reg = <0x7000f400 0x400>;
 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA30_CLK_EMC>;
+		power-domains = <&pd_core>;
 
 		nvidia,memory-controller = <&mc>;
 		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
@@ -799,6 +940,8 @@ fuse at 7000f800 {
 		clock-names = "fuse";
 		resets = <&tegra_car 39>;
 		reset-names = "fuse";
+		operating-points-v2 = <&fuse_burn_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 	};
 
 	tsensor: tsensor at 70014000 {
@@ -921,6 +1064,8 @@ mmc at 78000000 {
 		clock-names = "sdhci";
 		resets = <&tegra_car 14>;
 		reset-names = "sdhci";
+		operating-points-v2 = <&sdmmc1_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -943,6 +1088,8 @@ mmc at 78000400 {
 		clock-names = "sdhci";
 		resets = <&tegra_car 69>;
 		reset-names = "sdhci";
+		operating-points-v2 = <&sdmmc3_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -967,6 +1114,8 @@ usb at 7d000000 {
 		reset-names = "usb";
 		nvidia,needs-double-reset;
 		nvidia,phy = <&phy1>;
+		operating-points-v2 = <&usbd_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -1006,6 +1155,8 @@ usb at 7d004000 {
 		resets = <&tegra_car 58>;
 		reset-names = "usb";
 		nvidia,phy = <&phy2>;
+		operating-points-v2 = <&usb2_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
@@ -1044,6 +1195,8 @@ usb at 7d008000 {
 		resets = <&tegra_car 59>;
 		reset-names = "usb";
 		nvidia,phy = <&phy3>;
+		operating-points-v2 = <&usb3_dvfs_opp_table>;
+		power-domains = <&pd_core>;
 		status = "disabled";
 	};
 
-- 
2.32.0



From digetx at gmail.com  Sun Sep 12 13:08:31 2021
From: digetx at gmail.com (Dmitry Osipenko)
Date: Sun, 12 Sep 2021 23:08:31 +0300
Subject: [PATCH v11 33/34] ARM: tegra: Add Memory Client resets to Tegra30
 GR2D, GR3D and Host1x
In-Reply-To: <20210912200832.12312-1-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
Message-ID: <20210912200832.12312-34-digetx@gmail.com>

Memory access must be blocked before hardware reset is asserted and before
power is gated, otherwise a serious hardware fault is inevitable. Add
reset for memory clients to the GR2D, GR3D and Host1x nodes.

Tested-by: Peter Geis <pgwipeout at gmail.com> # Ouya T30
Tested-by: Matt Merhar <mattmerhar at protonmail.com> # Ouya T30
Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
---
 arch/arm/boot/dts/tegra30.dtsi | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 9c7616abaa2e..58ef4983e511 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -123,8 +123,8 @@ host1x at 50000000 {
 		interrupt-names = "syncpt", "host1x";
 		clocks = <&tegra_car TEGRA30_CLK_HOST1X>;
 		clock-names = "host1x";
-		resets = <&tegra_car 28>;
-		reset-names = "host1x";
+		resets = <&tegra_car 28>, <&mc TEGRA30_MC_RESET_HC>;
+		reset-names = "host1x", "mc";
 		iommus = <&mc TEGRA_SWGROUP_HC>;
 		operating-points-v2 = <&host1x_dvfs_opp_table>;
 		power-domains = <&pd_heg>;
@@ -190,8 +190,8 @@ gr2d at 54140000 {
 			reg = <0x54140000 0x00040000>;
 			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&tegra_car TEGRA30_CLK_GR2D>;
-			resets = <&tegra_car 21>;
-			reset-names = "2d";
+			resets = <&tegra_car 21>, <&mc TEGRA30_MC_RESET_2D>;
+			reset-names = "2d", "mc";
 			operating-points-v2 = <&gr2d_dvfs_opp_table>;
 			power-domains = <&pd_heg>;
 
@@ -205,8 +205,10 @@ gr3d at 54180000 {
 				 <&tegra_car TEGRA30_CLK_GR3D2>;
 			clock-names = "3d", "3d2";
 			resets = <&tegra_car 24>,
-				 <&tegra_car 98>;
-			reset-names = "3d", "3d2";
+				 <&tegra_car 98>,
+				 <&mc TEGRA30_MC_RESET_3D>,
+				 <&mc TEGRA30_MC_RESET_3D2>;
+			reset-names = "3d", "3d2", "mc", "mc2";
 			operating-points-v2 = <&gr3d_dvfs_opp_table>;
 			power-domains = <&pd_3d0>, <&pd_3d1>;
 			power-domain-names = "3d0", "3d1";
-- 
2.32.0



From hoeppner at linux.ibm.com  Mon Sep 13 01:17:48 2021
From: hoeppner at linux.ibm.com (=?UTF-8?Q?Jan_H=c3=b6ppner?=)
Date: Mon, 13 Sep 2021 10:17:48 +0200
Subject: [PATCH 6/9] s390/block/dasd_genhd: add error handling support for
 add_disk()
In-Reply-To: <20210902174105.2418771-7-mcgrof@kernel.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-7-mcgrof@kernel.org>
Message-ID: <d6140e40-a472-e732-9893-99e1839b717e@linux.ibm.com>

On 02/09/2021 19:41, Luis Chamberlain wrote:
> We never checked for errors on add_disk() as this function
> returned void. Now that this is fixed, use the shiny new
> error handling.
> 
> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
> ---
>  drivers/s390/block/dasd_genhd.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
> index fa966e0db6ca..ba07022283bc 100644
> --- a/drivers/s390/block/dasd_genhd.c
> +++ b/drivers/s390/block/dasd_genhd.c
> @@ -33,7 +33,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
>  {
>  	struct gendisk *gdp;
>  	struct dasd_device *base;
> -	int len;
> +	int len, rc;
>  
>  	/* Make sure the minor for this device exists. */
>  	base = block->base;
> @@ -79,7 +79,11 @@ int dasd_gendisk_alloc(struct dasd_block *block)
>  	dasd_add_link_to_gendisk(gdp, base);
>  	block->gdp = gdp;
>  	set_capacity(block->gdp, 0);
> -	device_add_disk(&base->cdev->dev, block->gdp, NULL);
> +
> +	rc = device_add_disk(&base->cdev->dev, block->gdp, NULL);
> +	if (rc)
> +		return rc;
> +

I think, just like with some of the other changes, there is some
cleanup required before returning. I'll prepare a patch and
come back to you.

>  	return 0;
>  }
>  
> 



From hch at infradead.org  Mon Sep 13 01:42:36 2021
From: hch at infradead.org (Christoph Hellwig)
Date: Mon, 13 Sep 2021 09:42:36 +0100
Subject: [PATCH 6/9] s390/block/dasd_genhd: add error handling support
 for add_disk()
In-Reply-To: <d6140e40-a472-e732-9893-99e1839b717e@linux.ibm.com>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-7-mcgrof@kernel.org>
 <d6140e40-a472-e732-9893-99e1839b717e@linux.ibm.com>
Message-ID: <YT8O/NL2pEGUjYj9@infradead.org>

On Mon, Sep 13, 2021 at 10:17:48AM +0200, Jan H??ppner wrote:
> I think, just like with some of the other changes, there is some
> cleanup required before returning. I'll prepare a patch and
> come back to you.

If you are touching the dasd probe path anyway, can you look insto
switching to use blk_mq_alloc_disk as well?  Right now dasd allocates
the request_queue and gendisk separately in different stages of
initialization, but unlike SCSI which needs to probe using just the
request_queue I can't find a good reason for that.


From gregkh at linuxfoundation.org  Mon Sep 13 02:33:36 2021
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Mon, 13 Sep 2021 11:33:36 +0200
Subject: Patch "ext4: report correct st_size for encrypted symlinks" has been
 added to the 4.19-stable tree
In-Reply-To: <20210908215033.1122580-3-ebiggers@kernel.org>
Message-ID: <163152561619799@kroah.com>


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

    ext4: report correct st_size for encrypted symlinks

to the 4.19-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:
     ext4-report-correct-st_size-for-encrypted-symlinks.patch
and it can be found in the queue-4.19 subdirectory.

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


>From foo at baz Mon Sep 13 11:31:12 AM CEST 2021
From: Eric Biggers <ebiggers at kernel.org>
Date: Wed,  8 Sep 2021 14:50:31 -0700
Subject: ext4: report correct st_size for encrypted symlinks
To: stable at vger.kernel.org
Cc: linux-fscrypt at vger.kernel.org, linux-ext4 at vger.kernel.org, linux-f2fs-devel at lists.sourceforge.net, linux-mtd at lists.infradead.org
Message-ID: <20210908215033.1122580-3-ebiggers at kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 8c4bca10ceafc43b1ca0a9fab5fa27e13cbce99e upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after ext4_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: f348c252320b ("ext4 crypto: add symlink encryption")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-3-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 fs/ext4/symlink.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

--- a/fs/ext4/symlink.c
+++ b/fs/ext4/symlink.c
@@ -52,10 +52,19 @@ static const char *ext4_encrypted_get_li
 	return paddr;
 }
 
+static int ext4_encrypted_symlink_getattr(const struct path *path,
+					  struct kstat *stat, u32 request_mask,
+					  unsigned int query_flags)
+{
+	ext4_getattr(path, stat, request_mask, query_flags);
+
+	return fscrypt_symlink_getattr(path, stat);
+}
+
 const struct inode_operations ext4_encrypted_symlink_inode_operations = {
 	.get_link	= ext4_encrypted_get_link,
 	.setattr	= ext4_setattr,
-	.getattr	= ext4_getattr,
+	.getattr	= ext4_encrypted_symlink_getattr,
 	.listxattr	= ext4_listxattr,
 };
 


Patches currently in stable-queue which might be from ebiggers at kernel.org are

queue-4.19/ubifs-report-correct-st_size-for-encrypted-symlinks.patch
queue-4.19/ext4-report-correct-st_size-for-encrypted-symlinks.patch
queue-4.19/fscrypt-add-fscrypt_symlink_getattr-for-computing-st_size.patch
queue-4.19/f2fs-report-correct-st_size-for-encrypted-symlinks.patch


From gregkh at linuxfoundation.org  Mon Sep 13 02:33:36 2021
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Mon, 13 Sep 2021 11:33:36 +0200
Subject: Patch "f2fs: report correct st_size for encrypted symlinks" has been
 added to the 4.19-stable tree
In-Reply-To: <20210908215033.1122580-4-ebiggers@kernel.org>
Message-ID: <16315256162465@kroah.com>


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

    f2fs: report correct st_size for encrypted symlinks

to the 4.19-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:
     f2fs-report-correct-st_size-for-encrypted-symlinks.patch
and it can be found in the queue-4.19 subdirectory.

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


>From foo at baz Mon Sep 13 11:31:12 AM CEST 2021
From: Eric Biggers <ebiggers at kernel.org>
Date: Wed,  8 Sep 2021 14:50:32 -0700
Subject: f2fs: report correct st_size for encrypted symlinks
To: stable at vger.kernel.org
Cc: linux-fscrypt at vger.kernel.org, linux-ext4 at vger.kernel.org, linux-f2fs-devel at lists.sourceforge.net, linux-mtd at lists.infradead.org
Message-ID: <20210908215033.1122580-4-ebiggers at kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 461b43a8f92e68e96c4424b31e15f2b35f1bbfa9 upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after f2fs_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: cbaf042a3cc6 ("f2fs crypto: add symlink encryption")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-4-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 fs/f2fs/namei.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -1219,9 +1219,18 @@ static const char *f2fs_encrypted_get_li
 	return target;
 }
 
+static int f2fs_encrypted_symlink_getattr(const struct path *path,
+					  struct kstat *stat, u32 request_mask,
+					  unsigned int query_flags)
+{
+	f2fs_getattr(path, stat, request_mask, query_flags);
+
+	return fscrypt_symlink_getattr(path, stat);
+}
+
 const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
 	.get_link       = f2fs_encrypted_get_link,
-	.getattr	= f2fs_getattr,
+	.getattr	= f2fs_encrypted_symlink_getattr,
 	.setattr	= f2fs_setattr,
 #ifdef CONFIG_F2FS_FS_XATTR
 	.listxattr	= f2fs_listxattr,


Patches currently in stable-queue which might be from ebiggers at kernel.org are

queue-4.19/ubifs-report-correct-st_size-for-encrypted-symlinks.patch
queue-4.19/ext4-report-correct-st_size-for-encrypted-symlinks.patch
queue-4.19/fscrypt-add-fscrypt_symlink_getattr-for-computing-st_size.patch
queue-4.19/f2fs-report-correct-st_size-for-encrypted-symlinks.patch


From gregkh at linuxfoundation.org  Mon Sep 13 02:33:36 2021
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Mon, 13 Sep 2021 11:33:36 +0200
Subject: Patch "fscrypt: add fscrypt_symlink_getattr() for computing st_size"
 has been added to the 4.19-stable tree
In-Reply-To: <20210908215033.1122580-2-ebiggers@kernel.org>
Message-ID: <163152561670165@kroah.com>


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

    fscrypt: add fscrypt_symlink_getattr() for computing st_size

to the 4.19-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:
     fscrypt-add-fscrypt_symlink_getattr-for-computing-st_size.patch
and it can be found in the queue-4.19 subdirectory.

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


>From foo at baz Mon Sep 13 11:31:12 AM CEST 2021
From: Eric Biggers <ebiggers at kernel.org>
Date: Wed,  8 Sep 2021 14:50:30 -0700
Subject: fscrypt: add fscrypt_symlink_getattr() for computing st_size
To: stable at vger.kernel.org
Cc: linux-fscrypt at vger.kernel.org, linux-ext4 at vger.kernel.org, linux-f2fs-devel at lists.sourceforge.net, linux-mtd at lists.infradead.org
Message-ID: <20210908215033.1122580-2-ebiggers at kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit d18760560593e5af921f51a8c9b64b6109d634c2 upstream.

Add a helper function fscrypt_symlink_getattr() which will be called
from the various filesystems' ->getattr() methods to read and decrypt
the target of encrypted symlinks in order to report the correct st_size.

Detailed explanation:

As required by POSIX and as documented in various man pages, st_size for
a symlink is supposed to be the length of the symlink target.
Unfortunately, st_size has always been wrong for encrypted symlinks
because st_size is populated from i_size from disk, which intentionally
contains the length of the encrypted symlink target.  That's slightly
greater than the length of the decrypted symlink target (which is the
symlink target that userspace usually sees), and usually won't match the
length of the no-key encoded symlink target either.

This hadn't been fixed yet because reporting the correct st_size would
require reading the symlink target from disk and decrypting or encoding
it, which historically has been considered too heavyweight to do in
->getattr().  Also historically, the wrong st_size had only broken a
test (LTP lstat03) and there were no known complaints from real users.
(This is probably because the st_size of symlinks isn't used too often,
and when it is, typically it's for a hint for what buffer size to pass
to readlink() -- which a slightly-too-large size still works for.)

However, a couple things have changed now.  First, there have recently
been complaints about the current behavior from real users:

- Breakage in rpmbuild:
  https://github.com/rpm-software-management/rpm/issues/1682
  https://github.com/google/fscrypt/issues/305

- Breakage in toybox cpio:
  https://www.mail-archive.com/toybox at lists.landley.net/msg07193.html

- Breakage in libgit2: https://issuetracker.google.com/issues/189629152
  (on Android public issue tracker, requires login)

Second, we now cache decrypted symlink targets in ->i_link.  Therefore,
taking the performance hit of reading and decrypting the symlink target
in ->getattr() wouldn't be as big a deal as it used to be, since usually
it will just save having to do the same thing later.

Also note that eCryptfs ended up having to read and decrypt symlink
targets in ->getattr() as well, to fix this same issue; see
commit 3a60a1686f0d ("eCryptfs: Decrypt symlink target for stat size").

So, let's just bite the bullet, and read and decrypt the symlink target
in ->getattr() in order to report the correct st_size.  Add a function
fscrypt_symlink_getattr() which the filesystems will call to do this.

(Alternatively, we could store the decrypted size of symlinks on-disk.
But there isn't a great place to do so, and encryption is meant to hide
the original size to some extent; that property would be lost.)

Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-2-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 fs/crypto/hooks.c               |   44 ++++++++++++++++++++++++++++++++++++++++
 include/linux/fscrypt_notsupp.h |    6 +++++
 include/linux/fscrypt_supp.h    |    1 
 3 files changed, 51 insertions(+)

--- a/fs/crypto/hooks.c
+++ b/fs/crypto/hooks.c
@@ -279,3 +279,47 @@ err_kfree:
 	return ERR_PTR(err);
 }
 EXPORT_SYMBOL_GPL(fscrypt_get_symlink);
+
+/**
+ * fscrypt_symlink_getattr() - set the correct st_size for encrypted symlinks
+ * @path: the path for the encrypted symlink being queried
+ * @stat: the struct being filled with the symlink's attributes
+ *
+ * Override st_size of encrypted symlinks to be the length of the decrypted
+ * symlink target (or the no-key encoded symlink target, if the key is
+ * unavailable) rather than the length of the encrypted symlink target.  This is
+ * necessary for st_size to match the symlink target that userspace actually
+ * sees.  POSIX requires this, and some userspace programs depend on it.
+ *
+ * This requires reading the symlink target from disk if needed, setting up the
+ * inode's encryption key if possible, and then decrypting or encoding the
+ * symlink target.  This makes lstat() more heavyweight than is normally the
+ * case.  However, decrypted symlink targets will be cached in ->i_link, so
+ * usually the symlink won't have to be read and decrypted again later if/when
+ * it is actually followed, readlink() is called, or lstat() is called again.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat)
+{
+	struct dentry *dentry = path->dentry;
+	struct inode *inode = d_inode(dentry);
+	const char *link;
+	DEFINE_DELAYED_CALL(done);
+
+	/*
+	 * To get the symlink target that userspace will see (whether it's the
+	 * decrypted target or the no-key encoded target), we can just get it in
+	 * the same way the VFS does during path resolution and readlink().
+	 */
+	link = READ_ONCE(inode->i_link);
+	if (!link) {
+		link = inode->i_op->get_link(dentry, inode, &done);
+		if (IS_ERR(link))
+			return PTR_ERR(link);
+	}
+	stat->size = strlen(link);
+	do_delayed_call(&done);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fscrypt_symlink_getattr);
--- a/include/linux/fscrypt_notsupp.h
+++ b/include/linux/fscrypt_notsupp.h
@@ -234,4 +234,10 @@ static inline const char *fscrypt_get_sy
 	return ERR_PTR(-EOPNOTSUPP);
 }
 
+static inline int fscrypt_symlink_getattr(const struct path *path,
+					  struct kstat *stat)
+{
+	return -EOPNOTSUPP;
+}
+
 #endif	/* _LINUX_FSCRYPT_NOTSUPP_H */
--- a/include/linux/fscrypt_supp.h
+++ b/include/linux/fscrypt_supp.h
@@ -231,5 +231,6 @@ extern int __fscrypt_encrypt_symlink(str
 extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
 				       unsigned int max_size,
 				       struct delayed_call *done);
+int fscrypt_symlink_getattr(const struct path *path, struct kstat *stat);
 
 #endif	/* _LINUX_FSCRYPT_SUPP_H */


Patches currently in stable-queue which might be from ebiggers at kernel.org are

queue-4.19/ubifs-report-correct-st_size-for-encrypted-symlinks.patch
queue-4.19/ext4-report-correct-st_size-for-encrypted-symlinks.patch
queue-4.19/fscrypt-add-fscrypt_symlink_getattr-for-computing-st_size.patch
queue-4.19/f2fs-report-correct-st_size-for-encrypted-symlinks.patch


From gregkh at linuxfoundation.org  Mon Sep 13 02:33:36 2021
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Mon, 13 Sep 2021 11:33:36 +0200
Subject: Patch "ubifs: report correct st_size for encrypted symlinks" has been
 added to the 4.19-stable tree
In-Reply-To: <20210908215033.1122580-5-ebiggers@kernel.org>
Message-ID: <1631525616523@kroah.com>


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

    ubifs: report correct st_size for encrypted symlinks

to the 4.19-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:
     ubifs-report-correct-st_size-for-encrypted-symlinks.patch
and it can be found in the queue-4.19 subdirectory.

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


>From foo at baz Mon Sep 13 11:31:12 AM CEST 2021
From: Eric Biggers <ebiggers at kernel.org>
Date: Wed,  8 Sep 2021 14:50:33 -0700
Subject: ubifs: report correct st_size for encrypted symlinks
To: stable at vger.kernel.org
Cc: linux-fscrypt at vger.kernel.org, linux-ext4 at vger.kernel.org, linux-f2fs-devel at lists.sourceforge.net, linux-mtd at lists.infradead.org
Message-ID: <20210908215033.1122580-5-ebiggers at kernel.org>

From: Eric Biggers <ebiggers at google.com>

commit 064c734986011390b4d111f1a99372b7f26c3850 upstream.

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after ubifs_getattr() for
encrypted symlinks.  This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: ca7f85be8d6c ("ubifs: Add support for encrypted symlinks")
Cc: stable at vger.kernel.org
Link: https://lore.kernel.org/r/20210702065350.209646-5-ebiggers at kernel.org
Signed-off-by: Eric Biggers <ebiggers at google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 fs/ubifs/file.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1642,6 +1642,16 @@ static const char *ubifs_get_link(struct
 	return fscrypt_get_symlink(inode, ui->data, ui->data_len, done);
 }
 
+static int ubifs_symlink_getattr(const struct path *path, struct kstat *stat,
+				 u32 request_mask, unsigned int query_flags)
+{
+	ubifs_getattr(path, stat, request_mask, query_flags);
+
+	if (IS_ENCRYPTED(d_inode(path->dentry)))
+		return fscrypt_symlink_getattr(path, stat);
+	return 0;
+}
+
 const struct address_space_operations ubifs_file_address_operations = {
 	.readpage       = ubifs_readpage,
 	.writepage      = ubifs_writepage,
@@ -1669,7 +1679,7 @@ const struct inode_operations ubifs_file
 const struct inode_operations ubifs_symlink_inode_operations = {
 	.get_link    = ubifs_get_link,
 	.setattr     = ubifs_setattr,
-	.getattr     = ubifs_getattr,
+	.getattr     = ubifs_symlink_getattr,
 #ifdef CONFIG_UBIFS_FS_XATTR
 	.listxattr   = ubifs_listxattr,
 #endif


Patches currently in stable-queue which might be from ebiggers at kernel.org are

queue-4.19/ubifs-report-correct-st_size-for-encrypted-symlinks.patch
queue-4.19/ext4-report-correct-st_size-for-encrypted-symlinks.patch
queue-4.19/fscrypt-add-fscrypt_symlink_getattr-for-computing-st_size.patch
queue-4.19/f2fs-report-correct-st_size-for-encrypted-symlinks.patch


From gregkh at linuxfoundation.org  Mon Sep 13 02:33:54 2021
From: gregkh at linuxfoundation.org (Greg KH)
Date: Mon, 13 Sep 2021 11:33:54 +0200
Subject: [PATCH 0/4] backport fscrypt symlink fixes to 4.19
In-Reply-To: <20210908215033.1122580-1-ebiggers@kernel.org>
References: <20210908215033.1122580-1-ebiggers@kernel.org>
Message-ID: <YT8bAlnKAYXMqFpe@kroah.com>

On Wed, Sep 08, 2021 at 02:50:29PM -0700, Eric Biggers wrote:
> This series backports some patches that failed to apply to 4.19-stable
> due to the prototype of inode_operations::getattr having changed in
> v5.12, as well as several other conflicts.  Please apply to 4.19-stable.
> 
> Eric Biggers (4):
>   fscrypt: add fscrypt_symlink_getattr() for computing st_size
>   ext4: report correct st_size for encrypted symlinks
>   f2fs: report correct st_size for encrypted symlinks
>   ubifs: report correct st_size for encrypted symlinks
> 
>  fs/crypto/hooks.c               | 44 +++++++++++++++++++++++++++++++++
>  fs/ext4/symlink.c               | 11 ++++++++-
>  fs/f2fs/namei.c                 | 11 ++++++++-
>  fs/ubifs/file.c                 | 12 ++++++++-
>  include/linux/fscrypt_notsupp.h |  6 +++++
>  include/linux/fscrypt_supp.h    |  1 +
>  6 files changed, 82 insertions(+), 3 deletions(-)
> 
> -- 
> 2.33.0.153.gba50c8fa24-goog
> 

All now queued up, thanks!

greg k-h


From mika.westerberg at linux.intel.com  Mon Sep 13 02:59:09 2021
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Mon, 13 Sep 2021 12:59:09 +0300
Subject: [PATCH 0/4] mtd: intel-spi: split read/write modes
In-Reply-To: <20210910211348.642103-1-mauro.lima@eclypsium.com>
References: <20210910211348.642103-1-mauro.lima@eclypsium.com>
Message-ID: <YT8g7Xm38cP4Todu@lahna>

Hi,

On Fri, Sep 10, 2021 at 06:13:44PM -0300, Mauro Lima wrote:
> The purpose of the following patchset is to split read/write
> functionality from the Intel PCH/PCU SPI flash driver.
> Being able to use the driver in read-only mode (harmless), the users
> can get important firmware information from userspace which also
> includes being able to perform firmware attestation to verify
> integrity.

The SPI-NOR maintainers wanted that the driver converted first to use
"SPI MEM" framework before any new features can be added. I'm currently
working on that.


From mika.westerberg at linux.intel.com  Mon Sep 13 03:00:59 2021
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Mon, 13 Sep 2021 13:00:59 +0300
Subject: [PATCH 1/4] mtd: intel-spi: rename intel-spi to intel-spi-base
In-Reply-To: <20210910211348.642103-2-mauro.lima@eclypsium.com>
References: <20210910211348.642103-1-mauro.lima@eclypsium.com>
 <20210910211348.642103-2-mauro.lima@eclypsium.com>
Message-ID: <YT8hWweR2NtpVX/R@lahna>

On Fri, Sep 10, 2021 at 06:13:45PM -0300, Mauro Lima wrote:
> Rename the files we want to split as base files.
> Include the new files in intel-spi-{pci|platform}.c.
> Change the intel-spi obj Makefile to be built with
> intel-spi-base.

I don't think this brings any benefits over the existing name.
Furthermore if this needs to be done, -core.c would make more sense.
IMHO.


From mika.westerberg at linux.intel.com  Mon Sep 13 03:06:00 2021
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Mon, 13 Sep 2021 13:06:00 +0300
Subject: [PATCH 4/4] mtd: intel-spi: add read only stubs
In-Reply-To: <20210910211348.642103-5-mauro.lima@eclypsium.com>
References: <20210910211348.642103-1-mauro.lima@eclypsium.com>
 <20210910211348.642103-5-mauro.lima@eclypsium.com>
Message-ID: <YT8iiCHFvhb1AEhp@lahna>

On Fri, Sep 10, 2021 at 06:13:48PM -0300, Mauro Lima wrote:
> Add read only stub functions (as __weak) in read only mode,
> so they can be override on read-write mode.
> Remove the (DANGEROUS) tag in read only mode.
> Add write mode option if pci or platform driver is selected.
> Change the intel-spi recepie to be able to build read only
> or read-write mode.

This looks pretty convoluted way to get rid of the "DANGEROUS" in the
name ;-)

What is the firmware information fwupd is looking for? Perhaps there are
other, better, ways to do this?


From hverkuil at xs4all.nl  Mon Sep 13 03:36:24 2021
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Mon, 13 Sep 2021 12:36:24 +0200
Subject: [PATCH v11 22/34] media: dt: bindings: tegra-vde: Convert to
 schema
In-Reply-To: <20210912200832.12312-23-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
 <20210912200832.12312-23-digetx@gmail.com>
Message-ID: <0feef7a8-932e-0190-1043-bba7912f9599@xs4all.nl>

On 12/09/2021 22:08, Dmitry Osipenko wrote:
> Convert NVIDIA Tegra video decoder binding to schema.
> 
> Reviewed-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Dmitry Osipenko <digetx at gmail.com>

Acked-by: Hans Verkuil <hverkuil-cisco at xs4all.nl>

Regards,

	Hans

> ---
>  .../bindings/media/nvidia,tegra-vde.txt       |  64 -----------
>  .../bindings/media/nvidia,tegra-vde.yaml      | 107 ++++++++++++++++++
>  2 files changed, 107 insertions(+), 64 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
>  create mode 100644 Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
> deleted file mode 100644
> index 602169b8aa19..000000000000
> --- a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
> +++ /dev/null
> @@ -1,64 +0,0 @@
> -NVIDIA Tegra Video Decoder Engine
> -
> -Required properties:
> -- compatible : Must contain one of the following values:
> -   - "nvidia,tegra20-vde"
> -   - "nvidia,tegra30-vde"
> -   - "nvidia,tegra114-vde"
> -   - "nvidia,tegra124-vde"
> -   - "nvidia,tegra132-vde"
> -- reg : Must contain an entry for each entry in reg-names.
> -- reg-names : Must include the following entries:
> -  - sxe
> -  - bsev
> -  - mbe
> -  - ppe
> -  - mce
> -  - tfe
> -  - ppb
> -  - vdma
> -  - frameid
> -- iram : Must contain phandle to the mmio-sram device node that represents
> -         IRAM region used by VDE.
> -- interrupts : Must contain an entry for each entry in interrupt-names.
> -- interrupt-names : Must include the following entries:
> -  - sync-token
> -  - bsev
> -  - sxe
> -- clocks : Must include the following entries:
> -  - vde
> -- resets : Must contain an entry for each entry in reset-names.
> -- reset-names : Should include the following entries:
> -  - vde
> -
> -Optional properties:
> -- resets : Must contain an entry for each entry in reset-names.
> -- reset-names : Must include the following entries:
> -  - mc
> -- iommus: Must contain phandle to the IOMMU device node.
> -
> -Example:
> -
> -video-codec at 6001a000 {
> -	compatible = "nvidia,tegra20-vde";
> -	reg = <0x6001a000 0x1000 /* Syntax Engine */
> -	       0x6001b000 0x1000 /* Video Bitstream Engine */
> -	       0x6001c000  0x100 /* Macroblock Engine */
> -	       0x6001c200  0x100 /* Post-processing Engine */
> -	       0x6001c400  0x100 /* Motion Compensation Engine */
> -	       0x6001c600  0x100 /* Transform Engine */
> -	       0x6001c800  0x100 /* Pixel prediction block */
> -	       0x6001ca00  0x100 /* Video DMA */
> -	       0x6001d800  0x300 /* Video frame controls */>;
> -	reg-names = "sxe", "bsev", "mbe", "ppe", "mce",
> -		    "tfe", "ppb", "vdma", "frameid";
> -	iram = <&vde_pool>; /* IRAM region */
> -	interrupts = <GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>, /* Sync token interrupt */
> -		     <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, /* BSE-V interrupt */
> -		     <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; /* SXE interrupt */
> -	interrupt-names = "sync-token", "bsev", "sxe";
> -	clocks = <&tegra_car TEGRA20_CLK_VDE>;
> -	reset-names = "vde", "mc";
> -	resets = <&tegra_car 61>, <&mc TEGRA20_MC_RESET_VDE>;
> -	iommus = <&mc TEGRA_SWGROUP_VDE>;
> -};
> diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
> new file mode 100644
> index 000000000000..3b6c1f031e04
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
> @@ -0,0 +1,107 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/nvidia,tegra-vde.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NVIDIA Tegra Video Decoder Engine
> +
> +maintainers:
> +  - Dmitry Osipenko <digetx at gmail.com>
> +  - Jon Hunter <jonathanh at nvidia.com>
> +  - Thierry Reding <thierry.reding at gmail.com>
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - enum:
> +              - nvidia,tegra132-vde
> +              - nvidia,tegra124-vde
> +              - nvidia,tegra114-vde
> +              - nvidia,tegra30-vde
> +          - enum:
> +              - nvidia,tegra20-vde
> +      - items:
> +          - const: nvidia,tegra20-vde
> +
> +  reg:
> +    maxItems: 9
> +
> +  reg-names:
> +    items:
> +      - const: sxe
> +      - const: bsev
> +      - const: mbe
> +      - const: ppe
> +      - const: mce
> +      - const: tfe
> +      - const: ppb
> +      - const: vdma
> +      - const: frameid
> +
> +  clocks:
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 2
> +
> +  reset-names:
> +    items:
> +      - const: vde
> +      - const: mc
> +
> +  interrupts:
> +    maxItems: 3
> +
> +  interrupt-names:
> +    items:
> +      - const: sync-token
> +      - const: bsev
> +      - const: sxe
> +
> +  iommus:
> +    maxItems: 1
> +
> +  iram:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle of the SRAM MMIO node.
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - clocks
> +  - resets
> +  - reset-names
> +  - interrupts
> +  - interrupt-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    video-codec at 6001a000 {
> +      compatible = "nvidia,tegra20-vde";
> +      reg = <0x6001a000 0x1000>, /* Syntax Engine */
> +            <0x6001b000 0x1000>, /* Video Bitstream Engine */
> +            <0x6001c000  0x100>, /* Macroblock Engine */
> +            <0x6001c200  0x100>, /* Post-processing Engine */
> +            <0x6001c400  0x100>, /* Motion Compensation Engine */
> +            <0x6001c600  0x100>, /* Transform Engine */
> +            <0x6001c800  0x100>, /* Pixel prediction block */
> +            <0x6001ca00  0x100>, /* Video DMA */
> +            <0x6001d800  0x300>; /* Video frame controls */
> +      reg-names = "sxe", "bsev", "mbe", "ppe", "mce",
> +                  "tfe", "ppb", "vdma", "frameid";
> +      iram = <&iram>; /* IRAM MMIO region */
> +      interrupts = <0  9 4>, /* Sync token */
> +                   <0 10 4>, /* BSE-V */
> +                   <0 12 4>; /* SXE */
> +      interrupt-names = "sync-token", "bsev", "sxe";
> +      clocks = <&clk 61>;
> +      reset-names = "vde", "mc";
> +      resets = <&rst 61>, <&mem 13>;
> +      iommus = <&mem 15>;
> +    };
> 



From hverkuil at xs4all.nl  Mon Sep 13 03:36:59 2021
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Mon, 13 Sep 2021 12:36:59 +0200
Subject: [PATCH v11 23/34] media: dt: bindings: tegra-vde: Document OPP
 and power domain
In-Reply-To: <20210912200832.12312-24-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
 <20210912200832.12312-24-digetx@gmail.com>
Message-ID: <03846b87-6235-4ec4-0f6b-a9a888e0452e@xs4all.nl>

On 12/09/2021 22:08, Dmitry Osipenko wrote:
> Document new OPP table and power domain properties of the video decoder
> hardware.
> 
> Reviewed-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Dmitry Osipenko <digetx at gmail.com>

Acked-by: Hans Verkuil <hverkuil-cisco at xs4all.nl>

Regards,

	Hans

> ---
>  .../devicetree/bindings/media/nvidia,tegra-vde.yaml  | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
> index 3b6c1f031e04..0b7d4d815707 100644
> --- a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
> +++ b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.yaml
> @@ -68,6 +68,16 @@ properties:
>      description:
>        Phandle of the SRAM MMIO node.
>  
> +  operating-points-v2:
> +    description:
> +      Should contain freqs and voltages and opp-supported-hw property,
> +      which is a bitfield indicating SoC speedo or process ID mask.
> +
> +  power-domains:
> +    maxItems: 1
> +    description:
> +      Phandle to the SoC core power domain.
> +
>  required:
>    - compatible
>    - reg
> @@ -104,4 +114,6 @@ examples:
>        reset-names = "vde", "mc";
>        resets = <&rst 61>, <&mem 13>;
>        iommus = <&mem 15>;
> +      operating-points-v2 = <&dvfs_opp_table>;
> +      power-domains = <&domain>;
>      };
> 



From hverkuil at xs4all.nl  Mon Sep 13 03:37:51 2021
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Mon, 13 Sep 2021 12:37:51 +0200
Subject: [PATCH v11 24/34] media: staging: tegra-vde: Support generic
 power domain
In-Reply-To: <20210912200832.12312-25-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
 <20210912200832.12312-25-digetx@gmail.com>
Message-ID: <77d205ef-469d-cfa3-f742-b009b2b05992@xs4all.nl>

On 12/09/2021 22:08, Dmitry Osipenko wrote:
> Currently driver supports legacy power domain API, this patch adds generic
> power domain support. This allows us to utilize a modern GENPD API for
> newer device-trees.
> 
> Tested-by: Peter Geis <pgwipeout at gmail.com> # Ouya T30
> Tested-by: Paul Fertser <fercerpav at gmail.com> # PAZ00 T20
> Tested-by: Nicolas Chauvet <kwizart at gmail.com> # PAZ00 T20 and TK1 T124
> Tested-by: Matt Merhar <mattmerhar at protonmail.com> # Ouya T30
> Signed-off-by: Dmitry Osipenko <digetx at gmail.com>

Acked-by: Hans Verkuil <hverkuil-cisco at xs4all.nl>

Regards,

	Hans

> ---
>  drivers/staging/media/tegra-vde/vde.c | 57 +++++++++++++++++++++------
>  1 file changed, 46 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/staging/media/tegra-vde/vde.c b/drivers/staging/media/tegra-vde/vde.c
> index ed4c1250b303..bb3079a2c0b5 100644
> --- a/drivers/staging/media/tegra-vde/vde.c
> +++ b/drivers/staging/media/tegra-vde/vde.c
> @@ -20,6 +20,7 @@
>  #include <linux/slab.h>
>  #include <linux/uaccess.h>
>  
> +#include <soc/tegra/common.h>
>  #include <soc/tegra/pmc.h>
>  
>  #include "uapi.h"
> @@ -920,13 +921,17 @@ static __maybe_unused int tegra_vde_runtime_suspend(struct device *dev)
>  	struct tegra_vde *vde = dev_get_drvdata(dev);
>  	int err;
>  
> -	err = tegra_powergate_power_off(TEGRA_POWERGATE_VDEC);
> -	if (err) {
> -		dev_err(dev, "Failed to power down HW: %d\n", err);
> -		return err;
> +	if (!dev->pm_domain) {
> +		err = tegra_powergate_power_off(TEGRA_POWERGATE_VDEC);
> +		if (err) {
> +			dev_err(dev, "Failed to power down HW: %d\n", err);
> +			return err;
> +		}
>  	}
>  
>  	clk_disable_unprepare(vde->clk);
> +	reset_control_release(vde->rst);
> +	reset_control_release(vde->rst_mc);
>  
>  	return 0;
>  }
> @@ -936,14 +941,41 @@ static __maybe_unused int tegra_vde_runtime_resume(struct device *dev)
>  	struct tegra_vde *vde = dev_get_drvdata(dev);
>  	int err;
>  
> -	err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_VDEC,
> -						vde->clk, vde->rst);
> +	err = reset_control_acquire(vde->rst_mc);
>  	if (err) {
> -		dev_err(dev, "Failed to power up HW : %d\n", err);
> +		dev_err(dev, "Failed to acquire mc reset: %d\n", err);
>  		return err;
>  	}
>  
> +	err = reset_control_acquire(vde->rst);
> +	if (err) {
> +		dev_err(dev, "Failed to acquire reset: %d\n", err);
> +		goto release_mc_reset;
> +	}
> +
> +	if (!dev->pm_domain) {
> +		err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_VDEC,
> +							vde->clk, vde->rst);
> +		if (err) {
> +			dev_err(dev, "Failed to power up HW : %d\n", err);
> +			goto release_reset;
> +		}
> +	}
> +
> +	err = clk_prepare_enable(vde->clk);
> +	if (err) {
> +		dev_err(dev, "Failed to enable clock: %d\n", err);
> +		goto release_reset;
> +	}
> +
>  	return 0;
> +
> +release_reset:
> +	reset_control_release(vde->rst);
> +release_mc_reset:
> +	reset_control_release(vde->rst_mc);
> +
> +	return err;
>  }
>  
>  static int tegra_vde_probe(struct platform_device *pdev)
> @@ -1001,14 +1033,14 @@ static int tegra_vde_probe(struct platform_device *pdev)
>  		return err;
>  	}
>  
> -	vde->rst = devm_reset_control_get(dev, NULL);
> +	vde->rst = devm_reset_control_get_exclusive_released(dev, NULL);
>  	if (IS_ERR(vde->rst)) {
>  		err = PTR_ERR(vde->rst);
>  		dev_err(dev, "Could not get VDE reset %d\n", err);
>  		return err;
>  	}
>  
> -	vde->rst_mc = devm_reset_control_get_optional(dev, "mc");
> +	vde->rst_mc = devm_reset_control_get_optional_exclusive_released(dev, "mc");
>  	if (IS_ERR(vde->rst_mc)) {
>  		err = PTR_ERR(vde->rst_mc);
>  		dev_err(dev, "Could not get MC reset %d\n", err);
> @@ -1066,6 +1098,10 @@ static int tegra_vde_probe(struct platform_device *pdev)
>  	pm_runtime_use_autosuspend(dev);
>  	pm_runtime_set_autosuspend_delay(dev, 300);
>  
> +	err = devm_tegra_core_dev_init_opp_table_common(dev);
> +	if (err)
> +		goto err_pm_runtime;
> +
>  	/*
>  	 * VDE partition may be left ON after bootloader, hence let's
>  	 * power-cycle it in order to put hardware into a predictable lower
> @@ -1133,8 +1169,7 @@ static void tegra_vde_shutdown(struct platform_device *pdev)
>  	 * On some devices bootloader isn't ready to a power-gated VDE on
>  	 * a warm-reboot, machine will hang in that case.
>  	 */
> -	if (pm_runtime_status_suspended(&pdev->dev))
> -		tegra_vde_runtime_resume(&pdev->dev);
> +	pm_runtime_get_sync(&pdev->dev);
>  }
>  
>  static __maybe_unused int tegra_vde_pm_suspend(struct device *dev)
> 



From hoeppner at linux.ibm.com  Mon Sep 13 05:15:10 2021
From: hoeppner at linux.ibm.com (=?UTF-8?Q?Jan_H=c3=b6ppner?=)
Date: Mon, 13 Sep 2021 14:15:10 +0200
Subject: [PATCH 6/9] s390/block/dasd_genhd: add error handling support for
 add_disk()
In-Reply-To: <YT8O/NL2pEGUjYj9@infradead.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-7-mcgrof@kernel.org>
 <d6140e40-a472-e732-9893-99e1839b717e@linux.ibm.com>
 <YT8O/NL2pEGUjYj9@infradead.org>
Message-ID: <93bfc4ce-62f1-e21c-5dca-82029b2fc388@linux.ibm.com>

On 13/09/2021 10:42, Christoph Hellwig wrote:
> On Mon, Sep 13, 2021 at 10:17:48AM +0200, Jan H??ppner wrote:
>> I think, just like with some of the other changes, there is some
>> cleanup required before returning. I'll prepare a patch and
>> come back to you.
> 
> If you are touching the dasd probe path anyway, can you look insto
> switching to use blk_mq_alloc_disk as well?  Right now dasd allocates
> the request_queue and gendisk separately in different stages of
> initialization, but unlike SCSI which needs to probe using just the
> request_queue I can't find a good reason for that.
> 

Thanks for the hint. We'll be working on it separately though, as
it seems to require a bit more effort from a first glance.
We'll send a separate patch (or patchset) soon.

regards,
Jan


From hoeppner at linux.ibm.com  Mon Sep 13 05:19:38 2021
From: hoeppner at linux.ibm.com (=?UTF-8?Q?Jan_H=c3=b6ppner?=)
Date: Mon, 13 Sep 2021 14:19:38 +0200
Subject: [PATCH 6/9] s390/block/dasd_genhd: add error handling support for
 add_disk()
In-Reply-To: <d6140e40-a472-e732-9893-99e1839b717e@linux.ibm.com>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-7-mcgrof@kernel.org>
 <d6140e40-a472-e732-9893-99e1839b717e@linux.ibm.com>
Message-ID: <f24da7d5-0b67-fa24-862f-0b27a2ab502c@linux.ibm.com>

On 13/09/2021 10:17, Jan H?ppner wrote:
> On 02/09/2021 19:41, Luis Chamberlain wrote:
>> We never checked for errors on add_disk() as this function
>> returned void. Now that this is fixed, use the shiny new
>> error handling.
>>
>> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
>> ---
>>  drivers/s390/block/dasd_genhd.c | 8 ++++++--
>>  1 file changed, 6 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
>> index fa966e0db6ca..ba07022283bc 100644
>> --- a/drivers/s390/block/dasd_genhd.c
>> +++ b/drivers/s390/block/dasd_genhd.c
>> @@ -33,7 +33,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
>>  {
>>  	struct gendisk *gdp;
>>  	struct dasd_device *base;
>> -	int len;
>> +	int len, rc;
>>  
>>  	/* Make sure the minor for this device exists. */
>>  	base = block->base;
>> @@ -79,7 +79,11 @@ int dasd_gendisk_alloc(struct dasd_block *block)
>>  	dasd_add_link_to_gendisk(gdp, base);
>>  	block->gdp = gdp;
>>  	set_capacity(block->gdp, 0);
>> -	device_add_disk(&base->cdev->dev, block->gdp, NULL);
>> +
>> +	rc = device_add_disk(&base->cdev->dev, block->gdp, NULL);
>> +	if (rc)
>> +		return rc;
>> +
> 
> I think, just like with some of the other changes, there is some
> cleanup required before returning. I'll prepare a patch and
> come back to you.
> 

It's actually just one call that is required. The patch should
look like this:

diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index fa966e0db6ca..80673dbfb1f9 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -33,7 +33,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
 {
        struct gendisk *gdp;
        struct dasd_device *base;
-       int len;
+       int len, rc;
 
        /* Make sure the minor for this device exists. */
        base = block->base;
@@ -79,7 +79,13 @@ int dasd_gendisk_alloc(struct dasd_block *block)
        dasd_add_link_to_gendisk(gdp, base);
        block->gdp = gdp;
        set_capacity(block->gdp, 0);
-       device_add_disk(&base->cdev->dev, block->gdp, NULL);
+
+       rc = device_add_disk(&base->cdev->dev, block->gdp, NULL);
+       if (rc) {
+               dasd_gendisk_free(block);
+               return rc;
+       }
+
        return 0;
 }

regards,
Jan


From mcgrof at kernel.org  Mon Sep 13 09:51:38 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 13 Sep 2021 09:51:38 -0700
Subject: [PATCH 6/9] s390/block/dasd_genhd: add error handling support
 for add_disk()
In-Reply-To: <f24da7d5-0b67-fa24-862f-0b27a2ab502c@linux.ibm.com>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-7-mcgrof@kernel.org>
 <d6140e40-a472-e732-9893-99e1839b717e@linux.ibm.com>
 <f24da7d5-0b67-fa24-862f-0b27a2ab502c@linux.ibm.com>
Message-ID: <YT+Bmvv3yXbuBddi@bombadil.infradead.org>

On Mon, Sep 13, 2021 at 02:19:38PM +0200, Jan H?ppner wrote:
> On 13/09/2021 10:17, Jan H?ppner wrote:
> > On 02/09/2021 19:41, Luis Chamberlain wrote:
> >> We never checked for errors on add_disk() as this function
> >> returned void. Now that this is fixed, use the shiny new
> >> error handling.
> >>
> >> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
> >> ---
> >>  drivers/s390/block/dasd_genhd.c | 8 ++++++--
> >>  1 file changed, 6 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
> >> index fa966e0db6ca..ba07022283bc 100644
> >> --- a/drivers/s390/block/dasd_genhd.c
> >> +++ b/drivers/s390/block/dasd_genhd.c
> >> @@ -33,7 +33,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
> >>  {
> >>  	struct gendisk *gdp;
> >>  	struct dasd_device *base;
> >> -	int len;
> >> +	int len, rc;
> >>  
> >>  	/* Make sure the minor for this device exists. */
> >>  	base = block->base;
> >> @@ -79,7 +79,11 @@ int dasd_gendisk_alloc(struct dasd_block *block)
> >>  	dasd_add_link_to_gendisk(gdp, base);
> >>  	block->gdp = gdp;
> >>  	set_capacity(block->gdp, 0);
> >> -	device_add_disk(&base->cdev->dev, block->gdp, NULL);
> >> +
> >> +	rc = device_add_disk(&base->cdev->dev, block->gdp, NULL);
> >> +	if (rc)
> >> +		return rc;
> >> +
> > 
> > I think, just like with some of the other changes, there is some
> > cleanup required before returning. I'll prepare a patch and
> > come back to you.
> > 
> 
> It's actually just one call that is required. The patch should
> look like this:
> 
> diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
> index fa966e0db6ca..80673dbfb1f9 100644
> --- a/drivers/s390/block/dasd_genhd.c
> +++ b/drivers/s390/block/dasd_genhd.c
> @@ -33,7 +33,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
>  {
>         struct gendisk *gdp;
>         struct dasd_device *base;
> -       int len;
> +       int len, rc;
>  
>         /* Make sure the minor for this device exists. */
>         base = block->base;
> @@ -79,7 +79,13 @@ int dasd_gendisk_alloc(struct dasd_block *block)
>         dasd_add_link_to_gendisk(gdp, base);
>         block->gdp = gdp;
>         set_capacity(block->gdp, 0);
> -       device_add_disk(&base->cdev->dev, block->gdp, NULL);
> +
> +       rc = device_add_disk(&base->cdev->dev, block->gdp, NULL);
> +       if (rc) {
> +               dasd_gendisk_free(block);
> +               return rc;
> +       }
> +

Thanks!

Would you like to to fold this fix into my patch and resend eventually?
Or will you send a replacement?

  Luis


From mcgrof at kernel.org  Mon Sep 13 09:53:14 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 13 Sep 2021 09:53:14 -0700
Subject: [PATCH 7/9] s390/block/dcssblk: add error handling support for
 add_disk()
In-Reply-To: <20210906134346.19c14246@thinkpad>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-8-mcgrof@kernel.org>
 <YTIscKy+jg5L/TMh@osiris> <YTLP8mYBX37R++9E@bombadil.infradead.org>
 <20210906134346.19c14246@thinkpad>
Message-ID: <YT+B+vCUcpZEq8hM@bombadil.infradead.org>

On Mon, Sep 06, 2021 at 01:43:46PM +0200, Gerald Schaefer wrote:
> On Fri, 3 Sep 2021 18:46:26 -0700
> Luis Chamberlain <mcgrof at kernel.org> wrote:
> 
> > On Fri, Sep 03, 2021 at 04:08:48PM +0200, Heiko Carstens wrote:
> > > On Thu, Sep 02, 2021 at 10:41:03AM -0700, Luis Chamberlain wrote:
> > > > We never checked for errors on add_disk() as this function
> > > > returned void. Now that this is fixed, use the shiny new
> > > > error handling.
> > > > 
> > > > Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
> > > > ---
> > > >  drivers/s390/block/dcssblk.c | 4 +++-
> > > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
> > > > index 5be3d1c39a78..b0fd5009a12e 100644
> > > > --- a/drivers/s390/block/dcssblk.c
> > > > +++ b/drivers/s390/block/dcssblk.c
> > > > @@ -696,7 +696,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
> > > >  	}
> > > >  
> > > >  	get_device(&dev_info->dev);
> > > > -	device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> > > > +	rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> > > > +	if (rc)
> > > > +		goto put_dev;
> > > 
> > > This looks not correct to me. We seem to have now in case of an error:
> > > 
> > > - reference count imbalance (= memory leak)
> > > - dax cleanup is missing
> > 
> > Care to provide an alternative?
> 
> See patch below:

Thanks! Will you queue this up on your end or do would you
prefer for me to roll this into my tree and eventually resend
with the rest?

  Luis


From rogerq at kernel.org  Tue Sep 14 05:26:57 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 14 Sep 2021 15:26:57 +0300
Subject: [PATCH v4 0/8] dt-bindings: memory-controllers: ti,
 gpmc: Convert to yaml
Message-ID: <20210914122705.15421-1-rogerq@kernel.org>

Hi,

This series converts ti,gpmc memory controller and ti,gpmc-nand and
ti,gpmc-onenand MTD controller bindings to yaml.

cheers,
-roger

Changelog:
v4
- reference partition.yaml in ti,gpmc-nand.yaml and ti,gpmc-onenenc.yaml
- use address-cells/size-cells: true instead of absolute size.

v3:
- fix indentation
- split GPMC child timings/settings into ti,gpmc-child.yaml
This allows us to refer to it at 3 places and avoid use of
'additionalProperties: true' at 2 places.
- specify defaults where applicable
- reordered patches
- added patch for making "gpmc,device-width" optional with defaults.
- address all review comments.

v2:
- Fix all errors in dtbs_check and dt_bindings_check
- remove references to gpmc-omap.txt
- Convert ti,gpmc-nand and ti,gpmc-onenand bindings to yaml as well

Roger Quadros (8):
  ARM: dts: omap: Fixup GPMC child nodes
  dt-bindings: mtd: Remove gpmc-nor.txt
  dt-bindings: net: Remove gpmc-eth.txt
  dt-bindings: memory-controllers: Introduce ti,gpmc-child
  dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
  dt-bindings: mtd: ti,gpmc-onenand: Convert to yaml
  dt-bindings: memory-controllers: ti,gpmc: Convert to yaml
  memory: gpmc-omap: "gpmc,device-width" DT property is optional

 .../bindings/memory-controllers/omap-gpmc.txt | 157 -----------
 .../memory-controllers/ti,gpmc-child.yaml     | 245 ++++++++++++++++++
 .../bindings/memory-controllers/ti,gpmc.yaml  | 172 ++++++++++++
 .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 -----------
 .../devicetree/bindings/mtd/gpmc-nor.txt      |  98 -------
 .../devicetree/bindings/mtd/gpmc-onenand.txt  |  48 ----
 .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 121 +++++++++
 .../bindings/mtd/ti,gpmc-onenand.yaml         |  81 ++++++
 .../devicetree/bindings/net/gpmc-eth.txt      |  97 -------
 .../boot/dts/logicpd-som-lv-baseboard.dtsi    |   2 +-
 .../boot/dts/logicpd-torpedo-37xx-devkit.dts  |   2 +-
 .../boot/dts/logicpd-torpedo-baseboard.dtsi   |   2 +-
 arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi     |  62 +++--
 arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi     |  59 ++---
 arch/arm/boot/dts/omap-zoom-common.dtsi       |  16 +-
 arch/arm/boot/dts/omap2430-sdp.dts            |   6 +-
 arch/arm/boot/dts/omap3-cm-t3x30.dtsi         |   6 +-
 .../arm/boot/dts/omap3-devkit8000-common.dtsi |   4 +-
 arch/arm/boot/dts/omap3-evm-37xx.dts          |   1 +
 arch/arm/boot/dts/omap3-evm-common.dtsi       |   9 -
 .../boot/dts/omap3-evm-processor-common.dtsi  |   5 +-
 arch/arm/boot/dts/omap3-evm.dts               |   1 +
 arch/arm/boot/dts/omap3-igep0020-common.dtsi  |   5 +-
 arch/arm/boot/dts/omap3-ldp.dts               |   5 +-
 arch/arm/boot/dts/omap3-n900.dts              |   2 +-
 .../dts/omap3-overo-chestnut43-common.dtsi    |   6 +-
 .../arm/boot/dts/omap3-overo-tobi-common.dtsi |   6 +-
 .../boot/dts/omap3-overo-tobiduo-common.dtsi  |   8 +-
 arch/arm/boot/dts/omap3-sb-t35.dtsi           |   4 +-
 arch/arm/boot/dts/omap4-duovero-parlor.dts    |   6 +-
 drivers/memory/omap-gpmc.c                    |  41 +--
 31 files changed, 750 insertions(+), 674 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
 delete mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt

-- 
2.17.1



From rogerq at kernel.org  Tue Sep 14 05:26:58 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 14 Sep 2021 15:26:58 +0300
Subject: [PATCH v4 1/8] ARM: dts: omap: Fixup GPMC child nodes
In-Reply-To: <20210914122705.15421-1-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
Message-ID: <20210914122705.15421-2-rogerq@kernel.org>

Fixes up the GPMC child nodes to prevent dtbs_check errors
after device tree binding conversion to yaml.

- Use reg address as node name
- gpmc,cycle2cycle-samecsen and gpmc,cycle2cycle-diffcsen are
  boolean properties.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../boot/dts/logicpd-som-lv-baseboard.dtsi    |  2 +-
 .../boot/dts/logicpd-torpedo-37xx-devkit.dts  |  2 +-
 .../boot/dts/logicpd-torpedo-baseboard.dtsi   |  2 +-
 arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi     | 62 +++++++++----------
 arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi     | 59 +++++++++---------
 arch/arm/boot/dts/omap-zoom-common.dtsi       | 16 ++---
 arch/arm/boot/dts/omap2430-sdp.dts            |  6 +-
 arch/arm/boot/dts/omap3-cm-t3x30.dtsi         |  6 +-
 .../arm/boot/dts/omap3-devkit8000-common.dtsi |  4 +-
 arch/arm/boot/dts/omap3-evm-37xx.dts          |  1 +
 arch/arm/boot/dts/omap3-evm-common.dtsi       |  9 ---
 .../boot/dts/omap3-evm-processor-common.dtsi  |  5 +-
 arch/arm/boot/dts/omap3-evm.dts               |  1 +
 arch/arm/boot/dts/omap3-igep0020-common.dtsi  |  5 +-
 arch/arm/boot/dts/omap3-ldp.dts               |  5 +-
 arch/arm/boot/dts/omap3-n900.dts              |  2 +-
 .../dts/omap3-overo-chestnut43-common.dtsi    |  6 +-
 .../arm/boot/dts/omap3-overo-tobi-common.dtsi |  6 +-
 .../boot/dts/omap3-overo-tobiduo-common.dtsi  |  8 +--
 arch/arm/boot/dts/omap3-sb-t35.dtsi           |  4 +-
 arch/arm/boot/dts/omap4-duovero-parlor.dts    |  6 +-
 21 files changed, 105 insertions(+), 112 deletions(-)

diff --git a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
index 7d0468a23781..f2364cb114c5 100644
--- a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
+++ b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
@@ -65,7 +65,7 @@
 		  1 0 0x2c000000 0x1000000	/* CS1: 16MB for LAN9221 */
 		  2 0 0x10000000 0x2000000>;    /* CS2: 32MB for NOR */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 1,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&lan9221_pins>;
 		interrupt-parent = <&gpio5>;
diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
index 5532db04046c..6357915d207b 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
+++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
@@ -4,8 +4,8 @@
 
 #include "omap36xx.dtsi"
 #include "logicpd-torpedo-som.dtsi"
-#include "omap-gpmc-smsc9221.dtsi"
 #include "logicpd-torpedo-baseboard.dtsi"
+#include "omap-gpmc-smsc9221.dtsi"
 
 / {
 	model = "LogicPD Zoom DM3730 Torpedo + Wireless Development Kit";
diff --git a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
index 533a47bc4a53..05049a34b6f1 100644
--- a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
+++ b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
@@ -95,7 +95,7 @@
 	ranges = <0 0 0x30000000 0x1000000	/* CS0: 16MB for NAND */
 		  1 0 0x2c000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 1,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&lan9221_pins>;
 		interrupt-parent = <&gpio5>;
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
index ded7e8fec9eb..2a462cb65a7d 100644
--- a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
+++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
@@ -20,36 +20,34 @@
 	};
 };
 
-&gpmc {
-	ethernet at gpmc {
-		compatible = "smsc,lan9221", "smsc,lan9115";
-		bank-width = <2>;
-		gpmc,device-width = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
-		gpmc,cs-on-ns = <5>;
-		gpmc,cs-rd-off-ns = <150>;
-		gpmc,cs-wr-off-ns = <150>;
-		gpmc,adv-on-ns = <0>;
-		gpmc,adv-rd-off-ns = <15>;
-		gpmc,adv-wr-off-ns = <40>;
-		gpmc,oe-on-ns = <45>;
-		gpmc,oe-off-ns = <140>;
-		gpmc,we-on-ns = <45>;
-		gpmc,we-off-ns = <140>;
-		gpmc,rd-cycle-ns = <155>;
-		gpmc,wr-cycle-ns = <155>;
-		gpmc,access-ns = <120>;
-		gpmc,page-burst-access-ns = <20>;
-		gpmc,bus-turnaround-ns = <75>;
-		gpmc,cycle2cycle-delay-ns = <75>;
-		gpmc,wait-monitoring-ns = <0>;
-		gpmc,clk-activation-ns = <0>;
-		gpmc,wr-data-mux-bus-ns = <0>;
-		gpmc,wr-access-ns = <0>;
-		vddvario-supply = <&vddvario>;
-		vdd33a-supply = <&vdd33a>;
-		reg-io-width = <4>;
-		smsc,save-mac-address;
-	};
+&gpmc_ethernet {
+	compatible = "smsc,lan9221", "smsc,lan9115";
+	bank-width = <2>;
+	gpmc,device-width = <1>;
+	gpmc,cycle2cycle-samecsen;
+	gpmc,cycle2cycle-diffcsen;
+	gpmc,cs-on-ns = <5>;
+	gpmc,cs-rd-off-ns = <150>;
+	gpmc,cs-wr-off-ns = <150>;
+	gpmc,adv-on-ns = <0>;
+	gpmc,adv-rd-off-ns = <15>;
+	gpmc,adv-wr-off-ns = <40>;
+	gpmc,oe-on-ns = <45>;
+	gpmc,oe-off-ns = <140>;
+	gpmc,we-on-ns = <45>;
+	gpmc,we-off-ns = <140>;
+	gpmc,rd-cycle-ns = <155>;
+	gpmc,wr-cycle-ns = <155>;
+	gpmc,access-ns = <120>;
+	gpmc,page-burst-access-ns = <20>;
+	gpmc,bus-turnaround-ns = <75>;
+	gpmc,cycle2cycle-delay-ns = <75>;
+	gpmc,wait-monitoring-ns = <0>;
+	gpmc,clk-activation-ns = <0>;
+	gpmc,wr-data-mux-bus-ns = <0>;
+	gpmc,wr-access-ns = <0>;
+	vddvario-supply = <&vddvario>;
+	vdd33a-supply = <&vdd33a>;
+	reg-io-width = <4>;
+	smsc,save-mac-address;
 };
diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
index 7f6aefd13451..c1e78f929d2b 100644
--- a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
+++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
@@ -24,36 +24,33 @@
 	};
 };
 
-&gpmc {
-	ethernet at gpmc {
-		compatible = "smsc,lan9221","smsc,lan9115";
-		bank-width = <2>;
+&gpmc_ethernet {
+	compatible = "smsc,lan9221","smsc,lan9115";
+	bank-width = <2>;
+	gpmc,mux-add-data = <0>;
+	gpmc,cs-on-ns = <0>;
+	gpmc,cs-rd-off-ns = <42>;
+	gpmc,cs-wr-off-ns = <36>;
+	gpmc,adv-on-ns = <6>;
+	gpmc,adv-rd-off-ns = <12>;
+	gpmc,adv-wr-off-ns = <12>;
+	gpmc,oe-on-ns = <0>;
+	gpmc,oe-off-ns = <42>;
+	gpmc,we-on-ns = <0>;
+	gpmc,we-off-ns = <36>;
+	gpmc,rd-cycle-ns = <60>;
+	gpmc,wr-cycle-ns = <54>;
+	gpmc,access-ns = <36>;
+	gpmc,page-burst-access-ns = <0>;
+	gpmc,bus-turnaround-ns = <0>;
+	gpmc,cycle2cycle-delay-ns = <0>;
+	gpmc,wr-data-mux-bus-ns = <18>;
+	gpmc,wr-access-ns = <42>;
+	gpmc,cycle2cycle-samecsen;
+	gpmc,cycle2cycle-diffcsen;
 
-		gpmc,mux-add-data;
-		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <42>;
-		gpmc,cs-wr-off-ns = <36>;
-		gpmc,adv-on-ns = <6>;
-		gpmc,adv-rd-off-ns = <12>;
-		gpmc,adv-wr-off-ns = <12>;
-		gpmc,oe-on-ns = <0>;
-		gpmc,oe-off-ns = <42>;
-		gpmc,we-on-ns = <0>;
-		gpmc,we-off-ns = <36>;
-		gpmc,rd-cycle-ns = <60>;
-		gpmc,wr-cycle-ns = <54>;
-		gpmc,access-ns = <36>;
-		gpmc,page-burst-access-ns = <0>;
-		gpmc,bus-turnaround-ns = <0>;
-		gpmc,cycle2cycle-delay-ns = <0>;
-		gpmc,wr-data-mux-bus-ns = <18>;
-		gpmc,wr-access-ns = <42>;
-		gpmc,cycle2cycle-samecsen;
-		gpmc,cycle2cycle-diffcsen;
-
-		vddvario-supply = <&vddvario>;
-		vdd33a-supply = <&vdd33a>;
-		reg-io-width = <4>;
-		smsc,save-mac-address;
-	};
+	vddvario-supply = <&vddvario>;
+	vdd33a-supply = <&vdd33a>;
+	reg-io-width = <4>;
+	smsc,save-mac-address;
 };
diff --git a/arch/arm/boot/dts/omap-zoom-common.dtsi b/arch/arm/boot/dts/omap-zoom-common.dtsi
index d4ad9e58b199..47192c617cd1 100644
--- a/arch/arm/boot/dts/omap-zoom-common.dtsi
+++ b/arch/arm/boot/dts/omap-zoom-common.dtsi
@@ -3,8 +3,6 @@
  * Common features on the Zoom debug board
  */
 
-#include "omap-gpmc-smsc911x.dtsi"
-
 &gpmc {
 	ranges = <3 0 0x10000000 0x1000000>,	/* CS3: 16MB for UART */
 		 <7 0 0x2c000000 0x01000000>;
@@ -27,8 +25,8 @@
 		gpmc,mux-add-data = <0>;
 		gpmc,device-width = <1>;
 		gpmc,wait-pin = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 		gpmc,cs-on-ns = <5>;
 		gpmc,cs-rd-off-ns = <155>;
 		gpmc,cs-wr-off-ns = <155>;
@@ -50,7 +48,7 @@
 		gpmc,wr-data-mux-bus-ns = <45>;
 		gpmc,wr-access-ns = <145>;
 	};
-	uart at 3,1 {
+	uart at 3,100 {
 		compatible = "ns16550a";
 		reg = <3 0x100 8>;	/* CS3, offset 0x100, IO size 8 */
 		bank-width = <2>;
@@ -61,7 +59,7 @@
 		clock-frequency = <1843200>;
 		current-speed = <115200>;
 	};
-	uart at 3,2 {
+	uart at 3,200 {
 		compatible = "ns16550a";
 		reg = <3 0x200 8>;	/* CS3, offset 0x200, IO size 8 */
 		bank-width = <2>;
@@ -72,7 +70,7 @@
 		clock-frequency = <1843200>;
 		current-speed = <115200>;
 	};
-	uart at 3,3 {
+	uart at 3,300 {
 		compatible = "ns16550a";
 		reg = <3 0x300 8>;	/* CS3, offset 0x300, IO size 8 */
 		bank-width = <2>;
@@ -84,9 +82,11 @@
 		current-speed = <115200>;
 	};
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 7,0 {
 		reg = <7 0 0xff>;
 		interrupt-parent = <&gpio5>;
 		interrupts = <30 IRQ_TYPE_LEVEL_LOW>;	/* gpio158 */
 	};
 };
+
+#include "omap-gpmc-smsc911x.dtsi"
diff --git a/arch/arm/boot/dts/omap2430-sdp.dts b/arch/arm/boot/dts/omap2430-sdp.dts
index 7d27e907533f..f74906e4721b 100644
--- a/arch/arm/boot/dts/omap2430-sdp.dts
+++ b/arch/arm/boot/dts/omap2430-sdp.dts
@@ -34,7 +34,7 @@
 
 &gpmc {
 	ranges = <5 0 0x08000000 0x01000000>;
-	ethernet at gpmc {
+	ethernet at 5,300 {
 		compatible = "smsc,lan91c94";
 		interrupt-parent = <&gpio5>;
 		interrupts = <21 IRQ_TYPE_LEVEL_LOW>;	/* gpio149 */
@@ -43,8 +43,8 @@
 		gpmc,sync-clk-ps = <0>;
 		gpmc,mux-add-data = <2>;
 		gpmc,device-width = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 		gpmc,cs-on-ns = <6>;
 		gpmc,cs-rd-off-ns = <187>;
 		gpmc,cs-wr-off-ns = <187>;
diff --git a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
index 5e8943539fcc..2059463de9d6 100644
--- a/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
+++ b/arch/arm/boot/dts/omap3-cm-t3x30.dtsi
@@ -47,13 +47,11 @@
 	};
 };
 
-#include "omap-gpmc-smsc911x.dtsi"
-
 &gpmc {
 	ranges = <5 0 0x2c000000 0x01000000>, /* CM-T3x30 SMSC9x Eth */
 		 <0 0 0x00000000 0x01000000>; /* CM-T3x NAND */
 
-	smsc1: ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		compatible = "smsc,lan9221", "smsc,lan9115";
 		pinctrl-names = "default";
 		pinctrl-0 = <&smsc1_pins>;
@@ -63,6 +61,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc911x.dtsi"
+
 &i2c1 {
 	twl: twl at 48 {
 		reg = <0x48>;
diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
index 2c19d6e255bd..5e55198e4576 100644
--- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
@@ -267,8 +267,8 @@
 		gpmc,mux-add-data = <0>;
 		gpmc,device-width = <1>;
 		gpmc,wait-pin = <0>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 
 		gpmc,cs-on-ns = <6>;
 		gpmc,cs-rd-off-ns = <180>;
diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts b/arch/arm/boot/dts/omap3-evm-37xx.dts
index c9332195d096..077b1a19f171 100644
--- a/arch/arm/boot/dts/omap3-evm-37xx.dts
+++ b/arch/arm/boot/dts/omap3-evm-37xx.dts
@@ -7,6 +7,7 @@
 #include "omap36xx.dtsi"
 #include "omap3-evm-common.dtsi"
 #include "omap3-evm-processor-common.dtsi"
+#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	model = "TI OMAP37XX EVM (TMDSEVM3730)";
diff --git a/arch/arm/boot/dts/omap3-evm-common.dtsi b/arch/arm/boot/dts/omap3-evm-common.dtsi
index 17c89df6ce6b..2f7bdb248a51 100644
--- a/arch/arm/boot/dts/omap3-evm-common.dtsi
+++ b/arch/arm/boot/dts/omap3-evm-common.dtsi
@@ -4,7 +4,6 @@
  */
 
 #include <dt-bindings/input/input.h>
-#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	cpus {
@@ -182,14 +181,6 @@
 	power = <50>;
 };
 
-&gpmc {
-	ethernet at gpmc {
-		interrupt-parent = <&gpio6>;
-		interrupts = <16 8>;
-		reg = <5 0 0xff>;
-	};
-};
-
 &vaux2 {
 	regulator-name = "usb_1v8";
 	regulator-min-microvolt = <1800000>;
diff --git a/arch/arm/boot/dts/omap3-evm-processor-common.dtsi b/arch/arm/boot/dts/omap3-evm-processor-common.dtsi
index e6ba30a21166..3adb967b96c4 100644
--- a/arch/arm/boot/dts/omap3-evm-processor-common.dtsi
+++ b/arch/arm/boot/dts/omap3-evm-processor-common.dtsi
@@ -217,8 +217,11 @@
 	ranges = <0 0 0x30000000 0x1000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;	/* CS5: 16MB for LAN9220 */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&smsc911x_pins>;
+		interrupt-parent = <&gpio6>;
+		interrupts = <16 8>;
+		reg = <5 0 0xff>;
 	};
 };
diff --git a/arch/arm/boot/dts/omap3-evm.dts b/arch/arm/boot/dts/omap3-evm.dts
index 5cc0cf7cd16c..805856d47cda 100644
--- a/arch/arm/boot/dts/omap3-evm.dts
+++ b/arch/arm/boot/dts/omap3-evm.dts
@@ -7,6 +7,7 @@
 #include "omap34xx.dtsi"
 #include "omap3-evm-common.dtsi"
 #include "omap3-evm-processor-common.dtsi"
+#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	model = "TI OMAP35XX EVM (TMDSEVM3530)";
diff --git a/arch/arm/boot/dts/omap3-igep0020-common.dtsi b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
index 73d8f471b9ec..104df84ea720 100644
--- a/arch/arm/boot/dts/omap3-igep0020-common.dtsi
+++ b/arch/arm/boot/dts/omap3-igep0020-common.dtsi
@@ -7,7 +7,6 @@
  */
 
 #include "omap3-igep.dtsi"
-#include "omap-gpmc-smsc9221.dtsi"
 
 / {
 
@@ -217,7 +216,7 @@
 	ranges = <0 0 0x30000000 0x01000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;	/* CS5: 16MB for ethernet */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&smsc9221_pins>;
 		reg = <5 0 0xff>;
@@ -226,6 +225,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &uart2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart2_pins>;
diff --git a/arch/arm/boot/dts/omap3-ldp.dts b/arch/arm/boot/dts/omap3-ldp.dts
index 9c6a92724590..a299f04217fd 100644
--- a/arch/arm/boot/dts/omap3-ldp.dts
+++ b/arch/arm/boot/dts/omap3-ldp.dts
@@ -6,7 +6,6 @@
 
 #include <dt-bindings/input/input.h>
 #include "omap34xx.dtsi"
-#include "omap-gpmc-smsc911x.dtsi"
 
 / {
 	model = "TI OMAP3430 LDP (Zoom1 Labrador)";
@@ -148,13 +147,15 @@
 		};
 	};
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 1,0 {
 		interrupt-parent = <&gpio5>;
 		interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
 		reg = <1 0 0xff>;
 	};
 };
 
+#include "omap-gpmc-smsc911x.dtsi"
+
 &i2c1 {
 	clock-frequency = <2600000>;
 
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 32335d4ce478..35602d7876aa 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -936,7 +936,7 @@
 	};
 
 	/* Ethernet is on some early development boards and qemu */
-	ethernet at gpmc {
+	ethernet at 1,0 {
 		compatible = "smsc,lan91c94";
 		interrupt-parent = <&gpio2>;
 		interrupts = <22 IRQ_TYPE_LEVEL_HIGH>;	/* gpio54 */
diff --git a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
index 2d2c61d7aa86..34b805851dd2 100644
--- a/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-chestnut43-common.dtsi
@@ -49,16 +49,16 @@
 	};
 };
 
-#include "omap-gpmc-smsc9221.dtsi"
-
 &gpmc {
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;	/* GPIO 176 */
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &lis33de {
 	status = "disabled";
 };
diff --git a/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
index 9bf4b88a4b50..895803654e3c 100644
--- a/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-tobi-common.dtsi
@@ -21,16 +21,16 @@
 	};
 };
 
-#include "omap-gpmc-smsc9221.dtsi"
-
 &gpmc {
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;	/* GPIO 176 */
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &lis33de {
 	status = "disabled";
 };
diff --git a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
index e5da3bc6f105..c212d72dcfe9 100644
--- a/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
+++ b/arch/arm/boot/dts/omap3-overo-tobiduo-common.dtsi
@@ -9,10 +9,8 @@
 
 #include "omap3-overo-common-peripherals.dtsi"
 
-#include "omap-gpmc-smsc9221.dtsi"
-
 &gpmc {
-	smsc1: ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio6>;
 		interrupts = <16 IRQ_TYPE_LEVEL_LOW>;	/* GPIO 176 */
@@ -22,7 +20,7 @@
 		compatible = "smsc,lan9221","smsc,lan9115";
 		bank-width = <2>;
 
-		gpmc,mux-add-data;
+		gpmc,mux-add-data = <0>;
 		gpmc,cs-on-ns = <0>;
 		gpmc,cs-rd-off-ns = <42>;
 		gpmc,cs-wr-off-ns = <36>;
@@ -54,6 +52,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc9221.dtsi"
+
 &lis33de {
 	status = "disabled";
 };
diff --git a/arch/arm/boot/dts/omap3-sb-t35.dtsi b/arch/arm/boot/dts/omap3-sb-t35.dtsi
index fb9842fa922c..5ec0893415e0 100644
--- a/arch/arm/boot/dts/omap3-sb-t35.dtsi
+++ b/arch/arm/boot/dts/omap3-sb-t35.dtsi
@@ -108,8 +108,8 @@
 		reg = <4 0 0xff>;
 		bank-width = <2>;
 		gpmc,device-width = <1>;
-		gpmc,cycle2cycle-samecsen = <1>;
-		gpmc,cycle2cycle-diffcsen = <1>;
+		gpmc,cycle2cycle-samecsen;
+		gpmc,cycle2cycle-diffcsen;
 		gpmc,cs-on-ns = <5>;
 		gpmc,cs-rd-off-ns = <150>;
 		gpmc,cs-wr-off-ns = <150>;
diff --git a/arch/arm/boot/dts/omap4-duovero-parlor.dts b/arch/arm/boot/dts/omap4-duovero-parlor.dts
index b294c22177cb..dfc50764c405 100644
--- a/arch/arm/boot/dts/omap4-duovero-parlor.dts
+++ b/arch/arm/boot/dts/omap4-duovero-parlor.dts
@@ -131,12 +131,10 @@
 	status = "disabled";
 };
 
-#include "omap-gpmc-smsc911x.dtsi"
-
 &gpmc {
 	ranges = <5 0 0x2c000000 0x1000000>;			/* CS5 */
 
-	ethernet at gpmc {
+	gpmc_ethernet: ethernet at 5,0 {
 		reg = <5 0 0xff>;
 		interrupt-parent = <&gpio2>;
 		interrupts = <12 IRQ_TYPE_LEVEL_LOW>;		/* gpio_44 */
@@ -170,6 +168,8 @@
 	};
 };
 
+#include "omap-gpmc-smsc911x.dtsi"
+
 &dss {
 	status = "okay";
 };
-- 
2.17.1



From rogerq at kernel.org  Tue Sep 14 05:26:59 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 14 Sep 2021 15:26:59 +0300
Subject: [PATCH v4 2/8] dt-bindings: mtd: Remove gpmc-nor.txt
In-Reply-To: <20210914122705.15421-1-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
Message-ID: <20210914122705.15421-3-rogerq@kernel.org>

There is no GPMC NOR compatible or device driver. GPMC is just
a bus interface over which standard (CFI/JEDC) NOR Flash chips
can be attached.

For NOR chip bindings, please refer to
Documentation/devicetree/bindings/mtd/mtd-physmap.yaml

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/mtd/gpmc-nor.txt      | 98 -------------------
 1 file changed, 98 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt b/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
deleted file mode 100644
index c8567b40fe13..000000000000
--- a/Documentation/devicetree/bindings/mtd/gpmc-nor.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-Device tree bindings for NOR flash connect to TI GPMC
-
-NOR flash connected to the TI GPMC (found on OMAP boards) are represented as
-child nodes of the GPMC controller with a name of "nor".
-
-All timing relevant properties as well as generic GPMC child properties are
-explained in a separate documents. Please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-Required properties:
-- bank-width: 		Width of NOR flash in bytes. GPMC supports 8-bit and
-			16-bit devices and so must be either 1 or 2 bytes.
-- compatible:		Documentation/devicetree/bindings/mtd/mtd-physmap.txt
-- gpmc,cs-on-ns:		Chip-select assertion time
-- gpmc,cs-rd-off-ns:	Chip-select de-assertion time for reads
-- gpmc,cs-wr-off-ns:	Chip-select de-assertion time for writes
-- gpmc,oe-on-ns:	Output-enable assertion time
-- gpmc,oe-off-ns:	Output-enable de-assertion time
-- gpmc,we-on-ns		Write-enable assertion time
-- gpmc,we-off-ns:	Write-enable de-assertion time
-- gpmc,access-ns:	Start cycle to first data capture (read access)
-- gpmc,rd-cycle-ns:	Total read cycle time
-- gpmc,wr-cycle-ns:	Total write cycle time
-- linux,mtd-name:	Documentation/devicetree/bindings/mtd/mtd-physmap.txt
-- reg:			Chip-select, base address (relative to chip-select)
-			and size of NOR flash. Note that base address will be
-			typically 0 as this is the start of the chip-select.
-
-Optional properties:
-- gpmc,XXX		Additional GPMC timings and settings parameters. See
-			Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-Optional properties for partition table parsing:
-- #address-cells: should be set to 1
-- #size-cells: should be set to 1
-
-Example:
-
-gpmc: gpmc at 6e000000 {
-	compatible = "ti,omap3430-gpmc", "simple-bus";
-	ti,hwmods = "gpmc";
-	reg = <0x6e000000 0x1000>;
-	interrupts = <20>;
-	gpmc,num-cs = <8>;
-	gpmc,num-waitpins = <4>;
-	#address-cells = <2>;
-	#size-cells = <1>;
-
-	ranges = <0 0 0x10000000 0x08000000>;
-
-	nor at 0,0 {
-		compatible = "cfi-flash";
-		linux,mtd-name= "intel,pf48f6000m0y1be";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		reg = <0 0 0x08000000>;
-		bank-width = <2>;
-
-		gpmc,mux-add-data;
-		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <186>;
-		gpmc,cs-wr-off-ns = <186>;
-		gpmc,adv-on-ns = <12>;
-		gpmc,adv-rd-off-ns = <48>;
-		gpmc,adv-wr-off-ns = <48>;
-		gpmc,oe-on-ns = <54>;
-		gpmc,oe-off-ns = <168>;
-		gpmc,we-on-ns = <54>;
-		gpmc,we-off-ns = <168>;
-		gpmc,rd-cycle-ns = <186>;
-		gpmc,wr-cycle-ns = <186>;
-		gpmc,access-ns = <114>;
-		gpmc,page-burst-access-ns = <6>;
-		gpmc,bus-turnaround-ns = <12>;
-		gpmc,cycle2cycle-delay-ns = <18>;
-		gpmc,wr-data-mux-bus-ns = <90>;
-		gpmc,wr-access-ns = <186>;
-		gpmc,cycle2cycle-samecsen;
-		gpmc,cycle2cycle-diffcsen;
-
-		partition at 0 {
-			label = "bootloader-nor";
-			reg = <0 0x40000>;
-		};
-		partition at 40000 {
-			label = "params-nor";
-			reg = <0x40000 0x40000>;
-		};
-		partition at 80000 {
-			label = "kernel-nor";
-			reg = <0x80000 0x200000>;
-		};
-		partition at 280000 {
-			label = "filesystem-nor";
-			reg = <0x240000 0x7d80000>;
-		};
-	};
-};
-- 
2.17.1



From rogerq at kernel.org  Tue Sep 14 05:27:00 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 14 Sep 2021 15:27:00 +0300
Subject: [PATCH v4 3/8] dt-bindings: net: Remove gpmc-eth.txt
In-Reply-To: <20210914122705.15421-1-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
Message-ID: <20210914122705.15421-4-rogerq@kernel.org>

There is no GPMC Ethernet compatible or device driver. GPMC is
just a bus interface over which devices like Ethernet controller
can be to.

For SMSC 911x Ethernet chip bindings, please refer to
Documentation/devicetree/bindings/net/smsc,lan9115.yaml

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/net/gpmc-eth.txt      | 97 -------------------
 1 file changed, 97 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt

diff --git a/Documentation/devicetree/bindings/net/gpmc-eth.txt b/Documentation/devicetree/bindings/net/gpmc-eth.txt
deleted file mode 100644
index 32821066a85b..000000000000
--- a/Documentation/devicetree/bindings/net/gpmc-eth.txt
+++ /dev/null
@@ -1,97 +0,0 @@
-Device tree bindings for Ethernet chip connected to TI GPMC
-
-Besides being used to interface with external memory devices, the
-General-Purpose Memory Controller can be used to connect Pseudo-SRAM devices
-such as ethernet controllers to processors using the TI GPMC as a data bus.
-
-Ethernet controllers connected to TI GPMC are represented as child nodes of
-the GPMC controller with an "ethernet" name.
-
-All timing relevant properties as well as generic GPMC child properties are
-explained in a separate documents. Please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-For the properties relevant to the ethernet controller connected to the GPMC
-refer to the binding documentation of the device. For example, the documentation
-for the SMSC 911x is Documentation/devicetree/bindings/net/smsc,lan9115.yaml
-
-Child nodes need to specify the GPMC bus address width using the "bank-width"
-property but is possible that an ethernet controller also has a property to
-specify the I/O registers address width. Even when the GPMC has a maximum 16-bit
-address width, it supports devices with 32-bit word registers.
-For example with an SMSC LAN911x/912x controller connected to the TI GPMC on an
-OMAP2+ board, "bank-width = <2>;" and "reg-io-width = <4>;".
-
-Required properties:
-- bank-width: 		Address width of the device in bytes. GPMC supports 8-bit
-			and 16-bit devices and so must be either 1 or 2 bytes.
-- compatible:		Compatible string property for the ethernet child device.
-- gpmc,cs-on-ns:	Chip-select assertion time
-- gpmc,cs-rd-off-ns:	Chip-select de-assertion time for reads
-- gpmc,cs-wr-off-ns:	Chip-select de-assertion time for writes
-- gpmc,oe-on-ns:	Output-enable assertion time
-- gpmc,oe-off-ns:	Output-enable de-assertion time
-- gpmc,we-on-ns:	Write-enable assertion time
-- gpmc,we-off-ns:	Write-enable de-assertion time
-- gpmc,access-ns:	Start cycle to first data capture (read access)
-- gpmc,rd-cycle-ns:	Total read cycle time
-- gpmc,wr-cycle-ns:	Total write cycle time
-- reg:			Chip-select, base address (relative to chip-select)
-			and size of the memory mapped for the device.
-			Note that base address will be typically 0 as this
-			is the start of the chip-select.
-
-Optional properties:
-- gpmc,XXX		Additional GPMC timings and settings parameters. See
-			Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-Example:
-
-gpmc: gpmc at 6e000000 {
-	compatible = "ti,omap3430-gpmc";
-	ti,hwmods = "gpmc";
-	reg = <0x6e000000 0x1000>;
-	interrupts = <20>;
-	gpmc,num-cs = <8>;
-	gpmc,num-waitpins = <4>;
-	#address-cells = <2>;
-	#size-cells = <1>;
-
-	ranges = <5 0 0x2c000000 0x1000000>;
-
-	ethernet at 5,0 {
-		compatible = "smsc,lan9221", "smsc,lan9115";
-		reg = <5 0 0xff>;
-		bank-width = <2>;
-
-		gpmc,mux-add-data;
-		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <186>;
-		gpmc,cs-wr-off-ns = <186>;
-		gpmc,adv-on-ns = <12>;
-		gpmc,adv-rd-off-ns = <48>;
-		gpmc,adv-wr-off-ns = <48>;
-		gpmc,oe-on-ns = <54>;
-		gpmc,oe-off-ns = <168>;
-		gpmc,we-on-ns = <54>;
-		gpmc,we-off-ns = <168>;
-		gpmc,rd-cycle-ns = <186>;
-		gpmc,wr-cycle-ns = <186>;
-		gpmc,access-ns = <114>;
-		gpmc,page-burst-access-ns = <6>;
-		gpmc,bus-turnaround-ns = <12>;
-		gpmc,cycle2cycle-delay-ns = <18>;
-		gpmc,wr-data-mux-bus-ns = <90>;
-		gpmc,wr-access-ns = <186>;
-		gpmc,cycle2cycle-samecsen;
-		gpmc,cycle2cycle-diffcsen;
-
-		interrupt-parent = <&gpio6>;
-		interrupts = <16>;
-		vmmc-supply = <&vddvario>;
-		vmmc_aux-supply = <&vdd33a>;
-		reg-io-width = <4>;
-
-		smsc,save-mac-address;
-	};
-};
-- 
2.17.1



From rogerq at kernel.org  Tue Sep 14 05:27:01 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 14 Sep 2021 15:27:01 +0300
Subject: [PATCH v4 4/8] dt-bindings: memory-controllers: Introduce ti,
 gpmc-child
In-Reply-To: <20210914122705.15421-1-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
Message-ID: <20210914122705.15421-5-rogerq@kernel.org>

This binding is meant for the child nodes of the TI GPMC node. The node
represents any device connected to the GPMC bus. It may be a Flash chip,
RAM chip or Ethernet controller, etc. These properties are meant for
configuring the GPMC settings/timings and will accompany the bindings
supported by the respective device.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../memory-controllers/ti,gpmc-child.yaml     | 245 ++++++++++++++++++
 1 file changed, 245 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml
new file mode 100644
index 000000000000..6e3995bb1630
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml
@@ -0,0 +1,245 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/ti,gpmc-child.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: device tree bindings for children of the Texas Instruments GPMC
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+  This binding is meant for the child nodes of the GPMC node. The node
+  represents any device connected to the GPMC bus. It may be a Flash chip,
+  RAM chip or Ethernet controller, etc. These properties are meant for
+  configuring the GPMC settings/timings and will accompany the bindings
+  supported by the respective device.
+
+properties:
+  reg: true
+
+# GPMC Timing properties for child nodes. All are optional and default to 0.
+  gpmc,sync-clk-ps:
+    description: Minimum clock period for synchronous mode
+    default: 0
+
+# Chip-select signal timings corresponding to GPMC_CONFIG2:
+  gpmc,cs-on-ns:
+    description: Assertion time
+    default: 0
+
+  gpmc,cs-rd-off-ns:
+    description: Read deassertion time
+    default: 0
+
+  gpmc,cs-wr-off-ns:
+    description: Write deassertion time
+    default: 0
+
+# ADV signal timings corresponding to GPMC_CONFIG3:
+  gpmc,adv-on-ns:
+    description: Assertion time
+    default: 0
+
+  gpmc,adv-rd-off-ns:
+    description: Read deassertion time
+    default: 0
+
+  gpmc,adv-wr-off-ns:
+    description: Write deassertion time
+    default: 0
+
+  gpmc,adv-aad-mux-on-ns:
+    description: Assertion time for AAD
+    default: 0
+
+  gpmc,adv-aad-mux-rd-off-ns:
+    description: Read deassertion time for AAD
+    default: 0
+
+  gpmc,adv-aad-mux-wr-off-ns:
+    description: Write deassertion time for AAD
+    default: 0
+
+# WE signals timings corresponding to GPMC_CONFIG4:
+  gpmc,we-on-ns:
+    description: Assertion time
+    default: 0
+
+  gpmc,we-off-ns:
+    description: Deassertion time
+    default: 0
+
+# OE signals timings corresponding to GPMC_CONFIG4:
+  gpmc,oe-on-ns:
+    description: Assertion time
+    default: 0
+
+  gpmc,oe-off-ns:
+    description: Deassertion time
+    default: 0
+
+  gpmc,oe-aad-mux-on-ns:
+    description: Assertion time for AAD
+    default: 0
+
+  gpmc,oe-aad-mux-off-ns:
+    description: Deassertion time for AAD
+    default: 0
+
+# Access time and cycle time timings (in nanoseconds) corresponding to
+# GPMC_CONFIG5:
+  gpmc,page-burst-access-ns:
+    description: Multiple access word delay
+    default: 0
+
+  gpmc,access-ns:
+    description: Start-cycle to first data valid delay
+    default: 0
+
+  gpmc,rd-cycle-ns:
+    description: Total read cycle time
+    default: 0
+
+  gpmc,wr-cycle-ns:
+    description: Total write cycle time
+    default: 0
+
+  gpmc,bus-turnaround-ns:
+    description: Turn-around time between successive accesses
+    default: 0
+
+  gpmc,cycle2cycle-delay-ns:
+    description: Delay between chip-select pulses
+    default: 0
+
+  gpmc,clk-activation-ns:
+    description: GPMC clock activation time
+    default: 0
+
+  gpmc,wait-monitoring-ns:
+    description: Start of wait monitoring with regard to valid data
+    default: 0
+
+# Boolean timing parameters. If property is present, parameter is enabled
+# otherwise disabled.
+  gpmc,adv-extra-delay:
+    description: ADV signal is delayed by half GPMC clock
+    type: boolean
+
+  gpmc,cs-extra-delay:
+    description: CS signal is delayed by half GPMC clock
+    type: boolean
+
+  gpmc,cycle2cycle-diffcsen:
+    description: |
+      Add "cycle2cycle-delay" between successive accesses
+      to a different CS
+    type: boolean
+
+  gpmc,cycle2cycle-samecsen:
+    description: |
+      Add "cycle2cycle-delay" between successive accesses
+      to the same CS
+    type: boolean
+
+  gpmc,oe-extra-delay:
+    description: OE signal is delayed by half GPMC clock
+    type: boolean
+
+  gpmc,we-extra-delay:
+    description: WE signal is delayed by half GPMC clock
+    type: boolean
+
+  gpmc,time-para-granularity:
+    description: Multiply all access times by 2
+    type: boolean
+
+# The following two properties are applicable only to OMAP3+ and AM335x:
+  gpmc,wr-access-ns:
+    description: |
+      In synchronous write mode, for single or
+      burst accesses, defines the number of
+      GPMC_FCLK cycles from start access time
+      to the GPMC_CLK rising edge used by the
+      memory device for the first data capture.
+    default: 0
+
+  gpmc,wr-data-mux-bus-ns:
+    description: |
+      In address-data multiplex mode, specifies
+      the time when the first data is driven on
+      the address-data bus.
+    default: 0
+
+# GPMC chip-select settings properties for child nodes. All are optional.
+  gpmc,burst-length:
+    description: Page/burst length.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 4, 8, 16]
+    default: 0
+
+  gpmc,burst-wrap:
+    description: Enables wrap bursting
+    type: boolean
+
+  gpmc,burst-read:
+    description: Enables read page/burst mode
+    type: boolean
+
+  gpmc,burst-write:
+    description: Enables write page/burst mode
+    type: boolean
+
+  gpmc,device-width:
+    description: |
+      Total width of device(s) connected to a GPMC
+      chip-select in bytes. The GPMC supports 8-bit
+      and 16-bit devices and so this property must be
+      1 or 2.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2]
+    default: 1
+
+  gpmc,mux-add-data:
+    description: |
+      Address and data multiplexing configuration.
+      Valid values are
+      0 for Non multiplexed mode
+      1 for address-address-data multiplexing mode and
+      2 for address-data multiplexing mode.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1, 2]
+
+  gpmc,sync-read:
+    description: |
+      Enables synchronous read. Defaults to asynchronous
+      is this is not set.
+    type: boolean
+
+  gpmc,sync-write:
+    description: |
+      Enables synchronous writes. Defaults to asynchronous
+      is this is not set.
+    type: boolean
+
+  gpmc,wait-pin:
+    description: |
+      Wait-pin used by client. Must be less than "gpmc,num-waitpins".
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  gpmc,wait-on-read:
+    description: Enables wait monitoring on reads.
+    type: boolean
+
+  gpmc,wait-on-write:
+    description: Enables wait monitoring on writes.
+    type: boolean
+
+required:
+  - reg
+
+# the GPMC child will have its own native properties
+additionalProperties: true
-- 
2.17.1



From rogerq at kernel.org  Tue Sep 14 05:27:02 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 14 Sep 2021 15:27:02 +0300
Subject: [PATCH v4 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <20210914122705.15421-1-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
Message-ID: <20210914122705.15421-6-rogerq@kernel.org>

Convert gpmc-nand.txt to ti,gpmc-nand.yaml.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 ------------------
 .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 121 ++++++++++++++
 2 files changed, 121 insertions(+), 147 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
deleted file mode 100644
index 44919d48d241..000000000000
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-Device tree bindings for GPMC connected NANDs
-
-GPMC connected NAND (found on OMAP boards) are represented as child nodes of
-the GPMC controller with a name of "nand".
-
-All timing relevant properties as well as generic gpmc child properties are
-explained in a separate documents - please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-For NAND specific properties such as ECC modes or bus width, please refer to
-Documentation/devicetree/bindings/mtd/nand-controller.yaml
-
-
-Required properties:
-
- - compatible:	"ti,omap2-nand"
- - reg:		range id (CS number), base offset and length of the
-		NAND I/O space
- - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
-
-Optional properties:
-
- - nand-bus-width: 		Set this numeric value to 16 if the hardware
-				is wired that way. If not specified, a bus
-				width of 8 is assumed.
-
- - ti,nand-ecc-opt:		A string setting the ECC layout to use. One of:
-		"sw"		1-bit Hamming ecc code via software
-		"hw"		<deprecated> use "ham1" instead
-		"hw-romcode"	<deprecated> use "ham1" instead
-		"ham1"		1-bit Hamming ecc code
-		"bch4"		4-bit BCH ecc code
-		"bch8"		8-bit BCH ecc code
-		"bch16"		16-bit BCH ECC code
-		Refer below "How to select correct ECC scheme for your device ?"
-
- - ti,nand-xfer-type:		A string setting the data transfer type. One of:
-
-		"prefetch-polled"	Prefetch polled mode (default)
-		"polled"		Polled mode, without prefetch
-		"prefetch-dma"		Prefetch enabled DMA mode
-		"prefetch-irq"		Prefetch enabled irq mode
-
- - elm_id:	<deprecated> use "ti,elm-id" instead
- - ti,elm-id:	Specifies phandle of the ELM devicetree node.
-		ELM is an on-chip hardware engine on TI SoC which is used for
-		locating ECC errors for BCHx algorithms. SoC devices which have
-		ELM hardware engines should specify this device node in .dtsi
-		Using ELM for ECC error correction frees some CPU cycles.
- - rb-gpios:	GPIO specifier for the ready/busy# pin.
-
-For inline partition table parsing (optional):
-
- - #address-cells: should be set to 1
- - #size-cells: should be set to 1
-
-Example for an AM33xx board:
-
-	gpmc: gpmc at 50000000 {
-		compatible = "ti,am3352-gpmc";
-		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x36c>;
-		interrupts = <100>;
-		gpmc,num-cs = <8>;
-		gpmc,num-waitpins = <2>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
-		elm_id = <&elm>;
-		interrupt-controller;
-		#interrupt-cells = <2>;
-
-		nand at 0,0 {
-			compatible = "ti,omap2-nand";
-			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
-			interrupt-parent = <&gpmc>;
-			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
-			nand-bus-width = <16>;
-			ti,nand-ecc-opt = "bch8";
-			ti,nand-xfer-type = "polled";
-			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
-
-			gpmc,sync-clk-ps = <0>;
-			gpmc,cs-on-ns = <0>;
-			gpmc,cs-rd-off-ns = <44>;
-			gpmc,cs-wr-off-ns = <44>;
-			gpmc,adv-on-ns = <6>;
-			gpmc,adv-rd-off-ns = <34>;
-			gpmc,adv-wr-off-ns = <44>;
-			gpmc,we-off-ns = <40>;
-			gpmc,oe-off-ns = <54>;
-			gpmc,access-ns = <64>;
-			gpmc,rd-cycle-ns = <82>;
-			gpmc,wr-cycle-ns = <82>;
-			gpmc,wr-access-ns = <40>;
-			gpmc,wr-data-mux-bus-ns = <0>;
-
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			/* partitions go here */
-		};
-	};
-
-How to select correct ECC scheme for your device ?
---------------------------------------------------
-Higher ECC scheme usually means better protection against bit-flips and
-increased system lifetime. However, selection of ECC scheme is dependent
-on various other factors also like;
-
-(1) support of built in hardware engines.
-	Some legacy OMAP SoC do not have ELM harware engine, so those SoC cannot
-	support ecc-schemes with hardware error-correction (BCHx_HW). However
-	such SoC can use ecc-schemes with software library for error-correction
-	(BCHx_HW_DETECTION_SW). The error correction capability with software
-	library remains equivalent to their hardware counter-part, but there is
-	slight CPU penalty when too many bit-flips are detected during reads.
-
-(2) Device parameters like OOBSIZE.
-	Other factor which governs the selection of ecc-scheme is oob-size.
-	Higher ECC schemes require more OOB/Spare area to store ECC syndrome,
-	so the device should have enough free bytes available its OOB/Spare
-	area to accommodate ECC for entire page. In general following expression
-	helps in determining if given device can accommodate ECC syndrome:
-	"2 + (PAGESIZE / 512) * ECC_BYTES" >= OOBSIZE"
-	where
-		OOBSIZE		number of bytes in OOB/spare area
-		PAGESIZE	number of bytes in main-area of device page
-		ECC_BYTES	number of ECC bytes generated to protect
-		                512 bytes of data, which is:
-				'3' for HAM1_xx ecc schemes
-				'7' for BCH4_xx ecc schemes
-				'14' for BCH8_xx ecc schemes
-				'26' for BCH16_xx ecc schemes
-
-	Example(a): For a device with PAGESIZE = 2048 and OOBSIZE = 64 and
-		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
-		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
-		which is greater than capacity of NAND device (OOBSIZE=64)
-		Hence, BCH16 cannot be supported on given device. But it can
-		probably use lower ecc-schemes like BCH8.
-
-	Example(b): For a device with PAGESIZE = 2048 and OOBSIZE = 128 and
-		trying to use BCH16 (ECC_BYTES=26) ecc-scheme.
-		Number of ECC bytes per page = (2 + (2048 / 512) * 26) = 106 B
-		which can be accommodated in the OOB/Spare area of this device
-		(OOBSIZE=128). So this device can use BCH16 ecc-scheme.
diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
new file mode 100644
index 000000000000..beb26b9bcfb2
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
@@ -0,0 +1,121 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/ti,gpmc-nand.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments GPMC NAND Flash controller.
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+  GPMC NAND controller/Flash is represented as a child of the
+  GPMC controller node.
+
+properties:
+  compatible:
+    const: ti,omap2-nand
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    items:
+      - description: Interrupt for fifoevent
+      - description: Interrupt for termcount
+
+  "#address-cells": true
+
+  "#size-cells": true
+
+  ti,nand-ecc-opt:
+    description: Desired ECC algorithm
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [sw, ham1, bch4, bch8, bch16]
+
+  ti,nand-xfer-type:
+    description: Data transfer method between controller and chip.
+    $ref: /schemas/types.yaml#/definitions/string
+    enum: [prefetch-polled, polled, prefetch-dma, prefetch-irq]
+    default: prefetch-polled
+
+  ti,elm-id:
+    description:
+      phandle to the ELM (Error Location Module).
+    $ref: /schemas/types.yaml#/definitions/phandle
+
+  nand-bus-width:
+    description:
+      Bus width to the NAND chip
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [8, 16]
+    default: 8
+
+patternProperties:
+  "@[0-9a-f]+$":
+    $ref: "/schemas/mtd/partitions/partition.yaml"
+
+allOf:
+  - $ref: "/schemas/memory-controllers/ti,gpmc-child.yaml"
+
+required:
+  - compatible
+  - reg
+  - ti,nand-ecc-opt
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    gpmc: memory-controller at 50000000 {
+      compatible = "ti,am3352-gpmc";
+      dmas = <&edma 52 0>;
+      dma-names = "rxtx";
+      clocks = <&l3s_gclk>;
+      clock-names = "fck";
+      reg = <0x50000000 0x2000>;
+      interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+      gpmc,num-cs = <7>;
+      gpmc,num-waitpins = <2>;
+      #address-cells = <2>;
+      #size-cells = <1>;
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      gpio-controller;
+      #gpio-cells = <2>;
+
+      ranges = <0 0 0x08000000 0x01000000>;   /* CS0 space. Min partition = 16MB */
+      nand at 0,0 {
+        compatible = "ti,omap2-nand";
+        reg = <0 0 4>;          /* device IO registers */
+        interrupt-parent = <&gpmc>;
+        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+                     <1 IRQ_TYPE_NONE>; /* termcount */
+        ti,nand-xfer-type = "prefetch-dma";
+        ti,nand-ecc-opt = "bch16";
+        ti,elm-id = <&elm>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        /* NAND generic properties */
+        nand-bus-width = <8>;
+        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>;  /* gpmc_wait0 */
+
+        /* GPMC properties*/
+        gpmc,device-width = <1>;
+
+        partition at 0 {
+          label = "NAND.SPL";
+          reg = <0x00000000 0x00040000>;
+        };
+        partition at 1 {
+          label = "NAND.SPL.backup1";
+          reg = <0x00040000 0x00040000>;
+        };
+      };
+    };
-- 
2.17.1



From rogerq at kernel.org  Tue Sep 14 05:27:03 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 14 Sep 2021 15:27:03 +0300
Subject: [PATCH v4 6/8] dt-bindings: mtd: ti,gpmc-onenand: Convert to yaml
In-Reply-To: <20210914122705.15421-1-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
Message-ID: <20210914122705.15421-7-rogerq@kernel.org>

Convert gpmc-onenand.txt to ti,gpmc-onenand.yaml.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../devicetree/bindings/mtd/gpmc-onenand.txt  | 48 -----------
 .../bindings/mtd/ti,gpmc-onenand.yaml         | 81 +++++++++++++++++++
 2 files changed, 81 insertions(+), 48 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
deleted file mode 100644
index e9f01a963a0a..000000000000
--- a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-Device tree bindings for GPMC connected OneNANDs
-
-GPMC connected OneNAND (found on OMAP boards) are represented as child nodes of
-the GPMC controller with a name of "onenand".
-
-All timing relevant properties as well as generic gpmc child properties are
-explained in a separate documents - please refer to
-Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
-
-Required properties:
-
- - compatible:		"ti,omap2-onenand"
- - reg:			The CS line the peripheral is connected to
- - gpmc,device-width:	Width of the ONENAND device connected to the GPMC
-			in bytes. Must be 1 or 2.
-
-Optional properties:
-
- - int-gpios:		GPIO specifier for the INT pin.
-
-For inline partition table parsing (optional):
-
- - #address-cells: should be set to 1
- - #size-cells: should be set to 1
-
-Example for an OMAP3430 board:
-
-	gpmc: gpmc at 6e000000 {
-		compatible = "ti,omap3430-gpmc";
-		ti,hwmods = "gpmc";
-		reg = <0x6e000000 0x1000000>;
-		interrupts = <20>;
-		gpmc,num-cs = <8>;
-		gpmc,num-waitpins = <4>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-
-		onenand at 0 {
-			compatible = "ti,omap2-onenand";
-			reg = <0 0 0>; /* CS0, offset 0 */
-			gpmc,device-width = <2>;
-
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			/* partitions go here */
-		};
-	};
diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
new file mode 100644
index 000000000000..42149a9c3a8d
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/ti,gpmc-onenand.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: OneNAND over Texas Instruments GPMC bus.
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+  GPMC connected OneNAND (found on OMAP boards) are represented
+  as child nodes of the GPMC controller.
+
+properties:
+  compatible:
+    const: ti,omap2-onenand
+
+  reg:
+    items:
+      - description: |
+          Chip Select number, register offset and size of
+          OneNAND register window.
+
+  "#address-cells": true
+
+  "#size-cells": true
+
+  int-gpios:
+    description: GPIO specifier for the INT pin.
+
+patternProperties:
+  "@[0-9a-f]+$":
+    $ref: "/schemas/mtd/partitions/partition.yaml"
+
+allOf:
+  - $ref: "/schemas/memory-controllers/ti,gpmc-child.yaml"
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    gpmc: memory-controller at 6e000000 {
+      compatible = "ti,omap3430-gpmc";
+      reg = <0x6e000000 0x02d0>;
+      interrupts = <20>;
+      gpmc,num-cs = <8>;
+      gpmc,num-waitpins = <4>;
+      clocks = <&l3s_clkctrl>;
+      clock-names = "fck";
+      #address-cells = <2>;
+      #size-cells = <1>;
+
+      ranges = <0 0 0x01000000 0x01000000>,   /* 16 MB for OneNAND */
+               <1 0 0x02000000 0x01000000>;   /* 16 MB for smc91c96 */
+
+      onenand at 0,0 {
+        compatible = "ti,omap2-onenand";
+        reg = <0 0 0x20000>;    /* CS0, offset 0, IO size 128K */
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        partition at 0 {
+          label = "bootloader";
+          reg = <0x00000000 0x00100000>;
+        };
+
+        partition at 1 {
+          label = "config";
+          reg = <0x00100000 0x002c0000>;
+        };
+      };
+    };
-- 
2.17.1



From rogerq at kernel.org  Tue Sep 14 05:27:04 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 14 Sep 2021 15:27:04 +0300
Subject: [PATCH v4 7/8] dt-bindings: memory-controllers: ti,
 gpmc: Convert to yaml
In-Reply-To: <20210914122705.15421-1-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
Message-ID: <20210914122705.15421-8-rogerq@kernel.org>

Convert omap-gpmc.txt to ti,gpmc.yaml.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 .../bindings/memory-controllers/omap-gpmc.txt | 157 ----------------
 .../bindings/memory-controllers/ti,gpmc.yaml  | 172 ++++++++++++++++++
 2 files changed, 172 insertions(+), 157 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml

diff --git a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt b/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
deleted file mode 100644
index c1359f4d48d7..000000000000
--- a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
+++ /dev/null
@@ -1,157 +0,0 @@
-Device tree bindings for OMAP general purpose memory controllers (GPMC)
-
-The actual devices are instantiated from the child nodes of a GPMC node.
-
-Required properties:
-
- - compatible:		Should be set to one of the following:
-
-			ti,omap2420-gpmc (omap2420)
-			ti,omap2430-gpmc (omap2430)
-			ti,omap3430-gpmc (omap3430 & omap3630)
-			ti,omap4430-gpmc (omap4430 & omap4460 & omap543x)
-			ti,am3352-gpmc   (am335x devices)
-
- - reg:			A resource specifier for the register space
-			(see the example below)
- - ti,hwmods:		Should be set to "ti,gpmc" until the DT transition is
-			completed.
- - #address-cells:	Must be set to 2 to allow memory address translation
- - #size-cells:		Must be set to 1 to allow CS address passing
- - gpmc,num-cs:		The maximum number of chip-select lines that controller
-			can support.
- - gpmc,num-waitpins:	The maximum number of wait pins that controller can
-			support.
- - ranges:		Must be set up to reflect the memory layout with four
-			integer values for each chip-select line in use:
-
-			   <cs-number> 0 <physical address of mapping> <size>
-
-			Currently, calculated values derived from the contents
-			of the per-CS register GPMC_CONFIG7 (as set up by the
-			bootloader) are used for the physical address decoding.
-			As this will change in the future, filling correct
-			values here is a requirement.
- - interrupt-controller: The GPMC driver implements and interrupt controller for
-			the NAND events "fifoevent" and "termcount" plus the
-			rising/falling edges on the GPMC_WAIT pins.
-			The interrupt number mapping is as follows
-			0 - NAND_fifoevent
-			1 - NAND_termcount
-			2 - GPMC_WAIT0 pin edge
-			3 - GPMC_WAIT1 pin edge, and so on.
- - interrupt-cells:	Must be set to 2
- - gpio-controller:	The GPMC driver implements a GPIO controller for the
-			GPMC WAIT pins that can be used as general purpose inputs.
-			0 maps to GPMC_WAIT0 pin.
- - gpio-cells:		Must be set to 2
-
-Required properties when using NAND prefetch dma:
- - dmas			GPMC NAND prefetch dma channel
- - dma-names		Must be set to "rxtx"
-
-Timing properties for child nodes. All are optional and default to 0.
-
- - gpmc,sync-clk-ps:	Minimum clock period for synchronous mode, in picoseconds
-
- Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2:
- - gpmc,cs-on-ns:	Assertion time
- - gpmc,cs-rd-off-ns:	Read deassertion time
- - gpmc,cs-wr-off-ns:	Write deassertion time
-
- ADV signal timings (in nanoseconds) corresponding to GPMC_CONFIG3:
- - gpmc,adv-on-ns:	Assertion time
- - gpmc,adv-rd-off-ns:	Read deassertion time
- - gpmc,adv-wr-off-ns:	Write deassertion time
- - gpmc,adv-aad-mux-on-ns:	Assertion time for AAD
- - gpmc,adv-aad-mux-rd-off-ns:	Read deassertion time for AAD
- - gpmc,adv-aad-mux-wr-off-ns:	Write deassertion time for AAD
-
- WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
- - gpmc,we-on-ns	Assertion time
- - gpmc,we-off-ns:	Deassertion time
-
- OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
- - gpmc,oe-on-ns:	Assertion time
- - gpmc,oe-off-ns:	Deassertion time
- - gpmc,oe-aad-mux-on-ns:	Assertion time for AAD
- - gpmc,oe-aad-mux-off-ns:	Deassertion time for AAD
-
- Access time and cycle time timings (in nanoseconds) corresponding to
- GPMC_CONFIG5:
- - gpmc,page-burst-access-ns: 	Multiple access word delay
- - gpmc,access-ns:		Start-cycle to first data valid delay
- - gpmc,rd-cycle-ns:		Total read cycle time
- - gpmc,wr-cycle-ns:		Total write cycle time
- - gpmc,bus-turnaround-ns:	Turn-around time between successive accesses
- - gpmc,cycle2cycle-delay-ns:	Delay between chip-select pulses
- - gpmc,clk-activation-ns: 	GPMC clock activation time
- - gpmc,wait-monitoring-ns:	Start of wait monitoring with regard to valid
-				data
-
-Boolean timing parameters. If property is present parameter enabled and
-disabled if omitted:
- - gpmc,adv-extra-delay:	ADV signal is delayed by half GPMC clock
- - gpmc,cs-extra-delay:		CS signal is delayed by half GPMC clock
- - gpmc,cycle2cycle-diffcsen:	Add "cycle2cycle-delay" between successive
-				accesses to a different CS
- - gpmc,cycle2cycle-samecsen:	Add "cycle2cycle-delay" between successive
-				accesses to the same CS
- - gpmc,oe-extra-delay:		OE signal is delayed by half GPMC clock
- - gpmc,we-extra-delay:		WE signal is delayed by half GPMC clock
- - gpmc,time-para-granularity:	Multiply all access times by 2
-
-The following are only applicable to OMAP3+ and AM335x:
- - gpmc,wr-access-ns:		In synchronous write mode, for single or
-				burst accesses, defines the number of
-				GPMC_FCLK cycles from start access time
-				to the GPMC_CLK rising edge used by the
-				memory device for the first data capture.
- - gpmc,wr-data-mux-bus-ns:	In address-data multiplex mode, specifies
-				the time when the first data is driven on
-				the address-data bus.
-
-GPMC chip-select settings properties for child nodes. All are optional.
-
-- gpmc,burst-length	Page/burst length. Must be 4, 8 or 16.
-- gpmc,burst-wrap	Enables wrap bursting
-- gpmc,burst-read	Enables read page/burst mode
-- gpmc,burst-write	Enables write page/burst mode
-- gpmc,device-width	Total width of device(s) connected to a GPMC
-			chip-select in bytes. The GPMC supports 8-bit
-			and 16-bit devices and so this property must be
-			1 or 2.
-- gpmc,mux-add-data	Address and data multiplexing configuration.
-			Valid values are 1 for address-address-data
-			multiplexing mode and 2 for address-data
-			multiplexing mode.
-- gpmc,sync-read	Enables synchronous read. Defaults to asynchronous
-			is this is not set.
-- gpmc,sync-write	Enables synchronous writes. Defaults to asynchronous
-			is this is not set.
-- gpmc,wait-pin		Wait-pin used by client. Must be less than
-			"gpmc,num-waitpins".
-- gpmc,wait-on-read	Enables wait monitoring on reads.
-- gpmc,wait-on-write	Enables wait monitoring on writes.
-
-Example for an AM33xx board:
-
-	gpmc: gpmc at 50000000 {
-		compatible = "ti,am3352-gpmc";
-		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x2000>;
-		interrupts = <100>;
-		dmas = <&edma 52 0>;
-		dma-names = "rxtx";
-		gpmc,num-cs = <8>;
-		gpmc,num-waitpins = <2>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
-		interrupt-controller;
-		#interrupt-cells = <2>;
-		gpio-controller;
-		#gpio-cells = <2>;
-
-		/* child nodes go here */
-	};
diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
new file mode 100644
index 000000000000..d6cd39bd3940
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
@@ -0,0 +1,172 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/ti,gpmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments GPMC Memory Controller device-tree bindings
+
+maintainers:
+  - Tony Lindgren <tony at atomide.com>
+  - Roger Quadros <rogerq at kernel.org>
+
+description:
+  The GPMC is a unified memory controller dedicated for interfacing
+  with external memory devices like
+  - Asynchronous SRAM-like memories and ASICs
+  - Asynchronous, synchronous, and page mode burst NOR flash
+  - NAND flash
+  - Pseudo-SRAM devices
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - ti,omap2420-gpmc
+          - ti,omap2430-gpmc
+          - ti,omap3430-gpmc
+          - ti,omap4430-gpmc
+          - ti,am3352-gpmc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: |
+      Functional clock. Used for bus timing calculations and
+      GPMC configuration.
+
+  clock-names:
+    items:
+      - const: fck
+
+  dmas:
+    items:
+      - description: DMA channel for GPMC NAND prefetch
+
+  dma-names:
+    items:
+      - const: rxtx
+
+  "#address-cells": true
+
+  "#size-cells": true
+
+  gpmc,num-cs:
+    description: maximum number of supported chip-select lines.
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  gpmc,num-waitpins:
+    description: maximum number of supported wait pins.
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  ranges:
+    minItems: 1
+    description: |
+      Must be set up to reflect the memory layout with four
+      integer values for each chip-select line in use,
+      <cs-number> 0 <physical address of mapping> <size>
+    items:
+      - description: NAND bank 0
+      - description: NOR/SRAM bank 0
+      - description: NOR/SRAM bank 1
+
+  '#interrupt-cells':
+    const: 2
+
+  interrupt-controller:
+    description: |
+      The GPMC driver implements and interrupt controller for
+      the NAND events "fifoevent" and "termcount" plus the
+      rising/falling edges on the GPMC_WAIT pins.
+      The interrupt number mapping is as follows
+      0 - NAND_fifoevent
+      1 - NAND_termcount
+      2 - GPMC_WAIT0 pin edge
+      3 - GPMC_WAIT1 pin edge, and so on.
+
+  '#gpio-cells':
+    const: 2
+
+  gpio-controller:
+    description: |
+      The GPMC driver implements a GPIO controller for the
+      GPMC WAIT pins that can be used as general purpose inputs.
+      0 maps to GPMC_WAIT0 pin.
+
+  ti,hwmods:
+    description:
+      Name of the HWMOD associated with GPMC. This is for legacy
+      omap2/3 platforms only.
+    $ref: /schemas/types.yaml#/definitions/string
+    deprecated: true
+
+  ti,no-idle-on-init:
+    description:
+      Prevent idling the module at init. This is for legacy omap2/3
+      platforms only.
+    type: boolean
+    deprecated: true
+
+patternProperties:
+  "@[0-7],[a-f0-9]+$":
+    type: object
+    description: |
+      The child device node represents the device connected to the GPMC
+      bus. The device can be a NAND chip, SRAM device, NOR device
+      or an ASIC.
+
+    allOf:
+      - $ref: "ti,gpmc-child.yaml"
+
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - gpmc,num-cs
+  - gpmc,num-waitpins
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    gpmc: memory-controller at 50000000 {
+      compatible = "ti,am3352-gpmc";
+      reg = <0x50000000 0x2000>;
+      interrupts = <100>;
+      clocks = <&l3s_clkctrl>;
+      clock-names = "fck";
+      dmas = <&edma 52 0>;
+      dma-names = "rxtx";
+      gpmc,num-cs = <8>;
+      gpmc,num-waitpins = <2>;
+      #address-cells = <2>;
+      #size-cells = <1>;
+      ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
+      interrupt-controller;
+      #interrupt-cells = <2>;
+      gpio-controller;
+      #gpio-cells = <2>;
+
+      nand at 0,0 {
+        compatible = "ti,omap2-nand";
+        reg = <0 0 4>;
+        interrupt-parent = <&gpmc>;
+        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+                     <1 IRQ_TYPE_NONE>; /* termcount */
+        ti,nand-xfer-type = "prefetch-dma";
+        ti,nand-ecc-opt = "bch16";
+        ti,elm-id = <&elm>;
+        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */
+      };
+    };
-- 
2.17.1



From rogerq at kernel.org  Tue Sep 14 05:27:05 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Tue, 14 Sep 2021 15:27:05 +0300
Subject: [PATCH v4 8/8] memory: gpmc-omap: "gpmc,
 device-width" DT property is optional
In-Reply-To: <20210914122705.15421-1-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
Message-ID: <20210914122705.15421-9-rogerq@kernel.org>

Check for valid gpmc,device-width, nand-bus-width and bank-width
at one place. Default to 8-bit width if none present.

Signed-off-by: Roger Quadros <rogerq at kernel.org>
---
 drivers/memory/omap-gpmc.c | 41 ++++++++++++++++++++++++--------------
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index f80c2ea39ca4..32d7c665f33c 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -2171,10 +2171,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		}
 	}
 
-	if (of_device_is_compatible(child, "ti,omap2-nand")) {
-		/* NAND specific setup */
-		val = 8;
-		of_property_read_u32(child, "nand-bus-width", &val);
+	/* DT node can have "nand-bus-width" or "bank-width" or "gpmc,device-width" */
+	if (!of_property_read_u32(child, "nand-bus-width", &val)) {
 		switch (val) {
 		case 8:
 			gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
@@ -2183,24 +2181,37 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 			gpmc_s.device_width = GPMC_DEVWIDTH_16BIT;
 			break;
 		default:
-			dev_err(&pdev->dev, "%pOFn: invalid 'nand-bus-width'\n",
-				child);
+			dev_err(&pdev->dev,
+				"%pOFn: invalid 'nand-bus-width':%d\n", child, val);
+			ret = -EINVAL;
+			goto err;
+		}
+	} else if (!of_property_read_u32(child, "bank-width", &val)) {
+		if (val != 1 && val != 2) {
+			dev_err(&pdev->dev,
+				"%pOFn: invalid 'bank-width':%d\n", child, val);
 			ret = -EINVAL;
 			goto err;
 		}
+		gpmc_s.device_width = val;
+	} else if (!of_property_read_u32(child, "gpmc,device-width", &val)) {
+		if (val != 1 && val != 2) {
+			dev_err(&pdev->dev,
+				"%pOFn: invalid 'gpmc,device-width':%d\n", child, val);
+			ret = -EINVAL;
+			goto err;
+		}
+		gpmc_s.device_width = val;
+	} else {
+		/* default to 8-bit */
+		gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
+	}
 
+	if (of_device_is_compatible(child, "ti,omap2-nand")) {
+		/* NAND specific setup */
 		/* disable write protect */
 		gpmc_configure(GPMC_CONFIG_WP, 0);
 		gpmc_s.device_nand = true;
-	} else {
-		ret = of_property_read_u32(child, "bank-width",
-					   &gpmc_s.device_width);
-		if (ret < 0 && !gpmc_s.device_width) {
-			dev_err(&pdev->dev,
-				"%pOF has no 'gpmc,device-width' property\n",
-				child);
-			goto err;
-		}
 	}
 
 	/* Reserve wait pin if it is required and valid */
-- 
2.17.1



From miquel.raynal at bootlin.com  Tue Sep 14 10:01:56 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:01:56 +0200
Subject: [PATCH] drivers/mtd/nand: fix reference count leaks in
 ebu_nand_probe
In-Reply-To: <20210910165316.2500-1-xiongx18@fudan.edu.cn>
References: <20210910165316.2500-1-xiongx18@fudan.edu.cn>
Message-ID: <20210914190156.56509462@xps13>

Hello,

xiongx18 at fudan.edu.cn wrote on Sat, 11 Sep 2021 00:53:16 +0800:

> The reference counting issue happens in several error handling paths
> on two refcounted object related to the "ebu_host" object (dma_tx,
> dma_rx). In these paths, the function forgets to balance one or both
> objects' reference count. For example, when request dma tx chan fails,
> the function forgets to decrease the refcount of "ebu_host->dma_rx"
> increased by dma_request_chan(), causing refcount leaks. What's more,
> the "ebu_host->clk" object also need to be handled correctly.
> 
> Fix this issue by keeping the return value and jumping to
> "err_cleanup_dma" label.

I think it has already been fixed upstream:
0792ec82175e ("mtd: rawnand: intel: Fix error handling in probe")

Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Tue Sep 14 10:31:08 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:31:08 +0200
Subject: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
In-Reply-To: <20210908201624.237634-1-bert@biot.com>
References: <20210908201624.237634-1-bert@biot.com>
Message-ID: <20210914193108.78df5367@xps13>

Hi Bert,

Richard, a question for you below!

bert at biot.com wrote on Wed,  8 Sep 2021 22:16:19 +0200:

> This adds a new vendor Etron, and support for a 2Gb chip.
> 
> The datasheet is available at
> https://www.etron.com/cn/products/EM73%5B8%5DC%5BD_E_F%5DVC%20SPI%20NAND%20Flash_Promotion_Rev%201_00A.pdf
> 
> Signed-off-by: Bert Vermeulen <bert at biot.com>
> ---
> v2:
> - Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
>   hardcoded to this 2Gb chip only
> - Fixed manufacturer ordering
> - Fixed minor formatting issues as reported
> - Removed debug comment
> 
>  drivers/mtd/nand/spi/Makefile |   2 +-
>  drivers/mtd/nand/spi/core.c   |   1 +
>  drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
>  include/linux/mtd/spinand.h   |   1 +
>  4 files changed, 107 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/mtd/nand/spi/etron.c

[...]

> +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
> +{
> +	switch (status & STATUS_ECC_MASK) {
> +	case STATUS_ECC_NO_BITFLIPS:
> +		return 0;
> +
> +	case STATUS_ECC_HAS_BITFLIPS:
> +		/* Between 1-7 bitflips were corrected */
> +		return 7;

Mmmh this is a bit problematic, having no intermediate value means a
single bitflip will trigger UBI to move the data around as its
threshold will be reached. Richard, any feedback on this?

> +
> +	case STATUS_ECC_MASK:
> +		/* Maximum bitflips were corrected */
> +		return 8;
> +
> +	case STATUS_ECC_UNCOR_ERROR:
> +		return -EBADMSG;
> +	}
> +
> +	return -EINVAL;
> +}

Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Tue Sep 14 10:37:32 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:37:32 +0200
Subject: [PATCH V6] mtd: rawnand: qcom: Update code word value for raw read
In-Reply-To: <1630998357-1359-1-git-send-email-mdalam@codeaurora.org>
Message-ID: <20210914173732.167846-1-miquel.raynal@bootlin.com>

On Tue, 2021-09-07 at 07:05:57 UTC, Md Sadre Alam wrote:
> From QPIC V2 onwards there is a separate register to read
> last code word "QPIC_NAND_READ_LOCATION_LAST_CW_n".
> 
> qcom_nandc_read_cw_raw() is used to read only one code word
> at a time. If we will configure number of code words to 1 in
> in QPIC_NAND_DEV0_CFG0 register then QPIC controller thinks
> its reading the last code word, since from QPIC V2 onwards
> we are having separate register to read the last code word,
> we have to configure "QPIC_NAND_READ_LOCATION_LAST_CW_n"
> register to fetch data from controller buffer to system
> memory.
> 
> Fixes: 503ee5aad430 ("mtd: rawnand: qcom: update last code word register")
> Cc: stable at kernel.org
> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:38:25 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:38:25 +0200
Subject: [PATCH] mtd: mtdswap: Remove redundant assignment of pointer eb
In-Reply-To: <20210910120023.46308-1-colin.king@canonical.com>
Message-ID: <20210914173825.234641-1-miquel.raynal@bootlin.com>

On Fri, 2021-09-10 at 12:00:23 UTC, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
> 
> The pointer eb is being assigned a value that is never read, it is
> being updated later on. The assignment is redundant and can be removed.
> 
> Addresses-Coverity: ("Unused value")
> Signed-off-by: Colin Ian King <colin.king at canonical.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:39:16 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:39:16 +0200
Subject: [PATCH] mtd: rawnand: intel: Fix potential buffer overflow in
 probe
In-Reply-To: <20210903082653.16441-1-novikov@ispras.ru>
Message-ID: <20210914173916.301250-1-miquel.raynal@bootlin.com>

On Fri, 2021-09-03 at 08:26:53 UTC, Evgeny Novikov wrote:
> ebu_nand_probe() read the value of u32 variable "cs" from the device
> firmware description and used it as the index for array ebu_host->cs
> that can contain MAX_CS (2) elements at most. That could result in
> a buffer overflow and various bad consequences later.
> 
> Fix the potential buffer overflow by restricting values of "cs" with
> MAX_CS in probe.
> 
> Found by Linux Driver Verification project (linuxtesting.org).
> 
> Fixes: 0b1039f016e8 ("mtd: rawnand: Add NAND controller support on Intel LGM SoC")
> Signed-off-by: Evgeny Novikov <novikov at ispras.ru>
> Co-developed-by: Kirill Shilimanov <kirill.shilimanov at huawei.com>
> Signed-off-by: Kirill Shilimanov <kirill.shilimanov at huawei.com>
> Co-developed-by: Anton Vasilyev <vasilyev at ispras.ru>
> Signed-off-by: Anton Vasilyev <vasilyev at ispras.ru>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:39:23 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:39:23 +0200
Subject: [PATCH] mtd: rawnand: xway: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074252.9633-1-caihuoqing@baidu.com>
Message-ID: <20210914173923.301316-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:42:51 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:39:28 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:39:28 +0200
Subject: [PATCH] mtd: rawnand: vf610: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074245.9583-1-caihuoqing@baidu.com>
Message-ID: <20210914173928.301381-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:42:44 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> Acked-by: Stefan Agner <stefan at agner.ch>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:39:35 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:39:35 +0200
Subject: [PATCH] mtd: rawnand: txx9ndfm: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074237.9533-1-caihuoqing@baidu.com>
Message-ID: <20210914173935.301460-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:42:37 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:39:40 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:39:40 +0200
Subject: [PATCH] mtd: rawnand: tegra: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074230.9483-1-caihuoqing@baidu.com>
Message-ID: <20210914173940.301524-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:42:29 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> Acked-by: Stefan Agner <stefan at agner.ch>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:39:45 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:39:45 +0200
Subject: [PATCH] mtd: rawnand: stm32_fmc2: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074222.9433-1-caihuoqing@baidu.com>
Message-ID: <20210914173945.301588-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:42:22 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> Reviewed-by: Christophe Kerello <christophe.kerello at foss.st.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:39:51 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:39:51 +0200
Subject: [PATCH] mtd: rawnand: plat_nand: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074215.9383-1-caihuoqing@baidu.com>
Message-ID: <20210914173951.301652-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:42:14 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:39:56 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:39:56 +0200
Subject: [PATCH] mtd: rawnand: oxnas: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074207.9333-1-caihuoqing@baidu.com>
Message-ID: <20210914173956.301717-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:42:07 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:40:01 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:40:01 +0200
Subject: [PATCH] mtd: rawnand: omap_elm: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074200.9283-1-caihuoqing@baidu.com>
Message-ID: <20210914174001.301781-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:41:59 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:40:07 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:40:07 +0200
Subject: [PATCH] mtd: rawnand: mtk_ecc: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074153.9233-1-caihuoqing@baidu.com>
Message-ID: <20210914174007.301850-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:41:52 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:40:12 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:40:12 +0200
Subject: [PATCH] mtd: rawnand: mtk: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074145.9183-1-caihuoqing@baidu.com>
Message-ID: <20210914174012.301914-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:41:44 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:40:17 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:40:17 +0200
Subject: [PATCH] mtd: rawnand: hisi504: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074138.9133-1-caihuoqing@baidu.com>
Message-ID: <20210914174017.301980-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:41:37 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:40:27 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:40:27 +0200
Subject: [PATCH] mtd: rawnand: gpio: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074123.9033-1-caihuoqing@baidu.com>
Message-ID: <20210914174027.302110-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:41:22 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:40:22 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:40:22 +0200
Subject: [PATCH] mtd: rawnand: gpmi: Make use of the helper function
 devm_platform_ioremap_resource_byname()
In-Reply-To: <20210901074130.9083-1-caihuoqing@baidu.com>
Message-ID: <20210914174022.302045-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:41:30 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource_byname() helper instead of
> calling platform_get_resource_byname() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:40:32 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:40:32 +0200
Subject: [PATCH] mtd: rawnand: denali: Make use of the helper function
 devm_platform_ioremap_resource_byname()
In-Reply-To: <20210901074116.8983-1-caihuoqing@baidu.com>
Message-ID: <20210914174032.302174-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:41:15 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource_byname() helper instead of
> calling platform_get_resource_byname() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:40:37 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:40:37 +0200
Subject: [PATCH] mtd: rawnand: bcm6368: Make use of the helper function
 devm_platform_ioremap_resource_byname()
In-Reply-To: <20210901074108.8933-1-caihuoqing@baidu.com>
Message-ID: <20210914174037.302238-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:40:38 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource_byname() helper instead of
> calling platform_get_resource_byname() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:40:41 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:40:41 +0200
Subject: [PATCH] mtd: rawnand: atmel: Make use of the helper function
 devm_platform_ioremap_resource()
In-Reply-To: <20210901074031.8883-1-caihuoqing@baidu.com>
Message-ID: <20210914174041.302304-1-miquel.raynal@bootlin.com>

On Wed, 2021-09-01 at 07:40:30 UTC, Cai Huoqing wrote:
> Use the devm_platform_ioremap_resource() helper instead of
> calling platform_get_resource() and devm_ioremap_resource()
> separately
> 
> Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>
> Reviewed-by: Nicolas Ferre <nicolas.ferre at microchip.com>

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

Miquel


From miquel.raynal at bootlin.com  Tue Sep 14 10:40:46 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 14 Sep 2021 19:40:46 +0200
Subject: [PATCH] mtd: Remove obsolete macros only used by the old
 nand_ecclayout struct
In-Reply-To: <20210830083356.31702-1-gongruiqi1@huawei.com>
Message-ID: <20210914174046.302368-1-miquel.raynal@bootlin.com>

On Mon, 2021-08-30 at 08:33:56 UTC, "GONG, Ruiqi" wrote:
> All uses of MTD_MAX_{OOBFREE,ECCPOS}_ENTRIES_LARGE have been removed as
> commit ef5eeea6e911 ("mtd: nand: brcm: switch to mtd_ooblayout_ops") and
> commit aab616e31d1c ("mtd: kill the nand_ecclayout struct") replaced
> struct nand_ecclayout by the new mtd_ooblayout_ops interface. Remove
> these two macros therefore.
> 
> Reported-by: Yi Yang <yiyang13 at huawei.com>
> Signed-off-by: GONG, Ruiqi <gongruiqi1 at huawei.com>

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

Miquel


From richard at nod.at  Tue Sep 14 10:49:48 2021
From: richard at nod.at (Richard Weinberger)
Date: Tue, 14 Sep 2021 19:49:48 +0200 (CEST)
Subject: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
In-Reply-To: <20210914193108.78df5367@xps13>
References: <20210908201624.237634-1-bert@biot.com>
 <20210914193108.78df5367@xps13>
Message-ID: <1517789471.73175.1631641788145.JavaMail.zimbra@nod.at>

----- Urspr?ngliche Mail -----
> Von: "Miquel Raynal" <miquel.raynal at bootlin.com>
> An: "richard" <richard at nod.at>
> CC: "Bert Vermeulen" <bert at biot.com>, "Vignesh Raghavendra" <vigneshr at ti.com>, "Patrice Chotard"
> <patrice.chotard at foss.st.com>, "Boris Brezillon" <boris.brezillon at collabora.com>, "Christophe Kerello"
> <christophe.kerello at foss.st.com>, "Mark Brown" <broonie at kernel.org>, "Alexander Lobakin" <alobakin at pm.me>,
> "linux-kernel" <linux-kernel at vger.kernel.org>, "linux-mtd" <linux-mtd at lists.infradead.org>
> Gesendet: Dienstag, 14. September 2021 19:31:08
> Betreff: Re: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx

> Hi Bert,
> 
> Richard, a question for you below!

:)
 
> bert at biot.com wrote on Wed,  8 Sep 2021 22:16:19 +0200:
> 
>> This adds a new vendor Etron, and support for a 2Gb chip.
>> 
>> The datasheet is available at
>> https://www.etron.com/cn/products/EM73%5B8%5DC%5BD_E_F%5DVC%20SPI%20NAND%20Flash_Promotion_Rev%201_00A.pdf
>> 
>> Signed-off-by: Bert Vermeulen <bert at biot.com>
>> ---
>> v2:
>> - Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
>>   hardcoded to this 2Gb chip only
>> - Fixed manufacturer ordering
>> - Fixed minor formatting issues as reported
>> - Removed debug comment
>> 
>>  drivers/mtd/nand/spi/Makefile |   2 +-
>>  drivers/mtd/nand/spi/core.c   |   1 +
>>  drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
>>  include/linux/mtd/spinand.h   |   1 +
>>  4 files changed, 107 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/mtd/nand/spi/etron.c
> 
> [...]
> 
>> +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
>> +{
>> +	switch (status & STATUS_ECC_MASK) {
>> +	case STATUS_ECC_NO_BITFLIPS:
>> +		return 0;
>> +
>> +	case STATUS_ECC_HAS_BITFLIPS:
>> +		/* Between 1-7 bitflips were corrected */
>> +		return 7;
> 
> Mmmh this is a bit problematic, having no intermediate value means a
> single bitflip will trigger UBI to move the data around as its
> threshold will be reached. Richard, any feedback on this?

So, the NAND controller can only report "no bitflips", "some bitflips", "maximum biflips" and "no way to fix"?
If so, yes, this is problematic for UBI because it will trigger wear-leveling way too often.
On a medium aged NAND I'd expect to see STATUS_ECC_HAS_BITFLIPS almost always set. :-(

Thanks,
//richard


From bert at biot.com  Tue Sep 14 13:03:49 2021
From: bert at biot.com (Bert Vermeulen)
Date: Tue, 14 Sep 2021 22:03:49 +0200
Subject: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
In-Reply-To: <1517789471.73175.1631641788145.JavaMail.zimbra@nod.at>
References: <20210908201624.237634-1-bert@biot.com>
 <20210914193108.78df5367@xps13>
 <1517789471.73175.1631641788145.JavaMail.zimbra@nod.at>
Message-ID: <927c7c75-c0d3-b3fb-6b85-13dbc3c6edbe@biot.com>

On 9/14/21 7:49 PM, Richard Weinberger wrote:
> ----- Urspr?ngliche Mail -----
>> bert at biot.com wrote on Wed,  8 Sep 2021 22:16:19 +0200:
>> 
>>> This adds a new vendor Etron, and support for a 2Gb chip.
>>> 
>>> The datasheet is available at
>>> https://www.etron.com/cn/products/EM73%5B8%5DC%5BD_E_F%5DVC%20SPI%20NAND%20Flash_Promotion_Rev%201_00A.pdf
>>> 
>>> Signed-off-by: Bert Vermeulen <bert at biot.com>
>>> ---
>>> v2:
>>> - Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
>>>   hardcoded to this 2Gb chip only
>>> - Fixed manufacturer ordering
>>> - Fixed minor formatting issues as reported
>>> - Removed debug comment
>>> 
>>>  drivers/mtd/nand/spi/Makefile |   2 +-
>>>  drivers/mtd/nand/spi/core.c   |   1 +
>>>  drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
>>>  include/linux/mtd/spinand.h   |   1 +
>>>  4 files changed, 107 insertions(+), 1 deletion(-)
>>>  create mode 100644 drivers/mtd/nand/spi/etron.c
>> 
>> [...]
>> 
>>> +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
>>> +{
>>> +	switch (status & STATUS_ECC_MASK) {
>>> +	case STATUS_ECC_NO_BITFLIPS:
>>> +		return 0;
>>> +
>>> +	case STATUS_ECC_HAS_BITFLIPS:
>>> +		/* Between 1-7 bitflips were corrected */
>>> +		return 7;
>> 
>> Mmmh this is a bit problematic, having no intermediate value means a
>> single bitflip will trigger UBI to move the data around as its
>> threshold will be reached. Richard, any feedback on this?
> 
> So, the NAND controller can only report "no bitflips", "some bitflips", "maximum biflips" and "no way to fix"?
> If so, yes, this is problematic for UBI because it will trigger wear-leveling way too often.
> On a medium aged NAND I'd expect to see STATUS_ECC_HAS_BITFLIPS almost always set. :-(

Yes, that's all there is according to the datasheet. Can't be _that_
unusual, since that's all the STATUS_ECC_* flags cover.

Incidentally I'm abusing STATUS_ECC_MASK here, since the 0b11 pattern is
missing from those flags.


-- 
Bert Vermeulen
bert at biot.com


From krzysztof.kozlowski at canonical.com  Tue Sep 14 23:53:36 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 15 Sep 2021 08:53:36 +0200
Subject: [PATCH v4 1/8] ARM: dts: omap: Fixup GPMC child nodes
In-Reply-To: <20210914122705.15421-2-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-2-rogerq@kernel.org>
Message-ID: <0f1f9c86-8375-5d4e-9514-76d27fc12afb@canonical.com>

On 14/09/2021 14:26, Roger Quadros wrote:
> Fixes up the GPMC child nodes to prevent dtbs_check errors
> after device tree binding conversion to yaml.
> 
> - Use reg address as node name
> - gpmc,cycle2cycle-samecsen and gpmc,cycle2cycle-diffcsen are
>   boolean properties.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../boot/dts/logicpd-som-lv-baseboard.dtsi    |  2 +-
>  .../boot/dts/logicpd-torpedo-37xx-devkit.dts  |  2 +-
>  .../boot/dts/logicpd-torpedo-baseboard.dtsi   |  2 +-
>  arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi     | 62 +++++++++----------
>  arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi     | 59 +++++++++---------
>  arch/arm/boot/dts/omap-zoom-common.dtsi       | 16 ++---
>  arch/arm/boot/dts/omap2430-sdp.dts            |  6 +-
>  arch/arm/boot/dts/omap3-cm-t3x30.dtsi         |  6 +-
>  .../arm/boot/dts/omap3-devkit8000-common.dtsi |  4 +-
>  arch/arm/boot/dts/omap3-evm-37xx.dts          |  1 +
>  arch/arm/boot/dts/omap3-evm-common.dtsi       |  9 ---
>  .../boot/dts/omap3-evm-processor-common.dtsi  |  5 +-
>  arch/arm/boot/dts/omap3-evm.dts               |  1 +
>  arch/arm/boot/dts/omap3-igep0020-common.dtsi  |  5 +-
>  arch/arm/boot/dts/omap3-ldp.dts               |  5 +-
>  arch/arm/boot/dts/omap3-n900.dts              |  2 +-
>  .../dts/omap3-overo-chestnut43-common.dtsi    |  6 +-
>  .../arm/boot/dts/omap3-overo-tobi-common.dtsi |  6 +-
>  .../boot/dts/omap3-overo-tobiduo-common.dtsi  |  8 +--
>  arch/arm/boot/dts/omap3-sb-t35.dtsi           |  4 +-
>  arch/arm/boot/dts/omap4-duovero-parlor.dts    |  6 +-
>  21 files changed, 105 insertions(+), 112 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
> index 7d0468a23781..f2364cb114c5 100644
> --- a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
> +++ b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
> @@ -65,7 +65,7 @@
>  		  1 0 0x2c000000 0x1000000	/* CS1: 16MB for LAN9221 */
>  		  2 0 0x10000000 0x2000000>;    /* CS2: 32MB for NOR */
>  
> -	ethernet at gpmc {
> +	gpmc_ethernet: ethernet at 1,0 {
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&lan9221_pins>;
>  		interrupt-parent = <&gpio5>;
> diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
> index 5532db04046c..6357915d207b 100644
> --- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
> +++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
> @@ -4,8 +4,8 @@
>  
>  #include "omap36xx.dtsi"
>  #include "logicpd-torpedo-som.dtsi"
> -#include "omap-gpmc-smsc9221.dtsi"
>  #include "logicpd-torpedo-baseboard.dtsi"
> +#include "omap-gpmc-smsc9221.dtsi"
>  
>  / {
>  	model = "LogicPD Zoom DM3730 Torpedo + Wireless Development Kit";
> diff --git a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
> index 533a47bc4a53..05049a34b6f1 100644
> --- a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
> +++ b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
> @@ -95,7 +95,7 @@
>  	ranges = <0 0 0x30000000 0x1000000	/* CS0: 16MB for NAND */
>  		  1 0 0x2c000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
>  
> -	ethernet at gpmc {
> +	gpmc_ethernet: ethernet at 1,0 {
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&lan9221_pins>;
>  		interrupt-parent = <&gpio5>;
> diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
> index ded7e8fec9eb..2a462cb65a7d 100644
> --- a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
> +++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
> @@ -20,36 +20,34 @@
>  	};
>  };
>  
> -&gpmc {
> -	ethernet at gpmc {
> -		compatible = "smsc,lan9221", "smsc,lan9115";
> -		bank-width = <2>;
> -		gpmc,device-width = <1>;
> -		gpmc,cycle2cycle-samecsen = <1>;
> -		gpmc,cycle2cycle-diffcsen = <1>;
> -		gpmc,cs-on-ns = <5>;
> -		gpmc,cs-rd-off-ns = <150>;
> -		gpmc,cs-wr-off-ns = <150>;
> -		gpmc,adv-on-ns = <0>;
> -		gpmc,adv-rd-off-ns = <15>;
> -		gpmc,adv-wr-off-ns = <40>;
> -		gpmc,oe-on-ns = <45>;
> -		gpmc,oe-off-ns = <140>;
> -		gpmc,we-on-ns = <45>;
> -		gpmc,we-off-ns = <140>;
> -		gpmc,rd-cycle-ns = <155>;
> -		gpmc,wr-cycle-ns = <155>;
> -		gpmc,access-ns = <120>;
> -		gpmc,page-burst-access-ns = <20>;
> -		gpmc,bus-turnaround-ns = <75>;
> -		gpmc,cycle2cycle-delay-ns = <75>;
> -		gpmc,wait-monitoring-ns = <0>;
> -		gpmc,clk-activation-ns = <0>;
> -		gpmc,wr-data-mux-bus-ns = <0>;
> -		gpmc,wr-access-ns = <0>;
> -		vddvario-supply = <&vddvario>;
> -		vdd33a-supply = <&vdd33a>;
> -		reg-io-width = <4>;
> -		smsc,save-mac-address;
> -	};
> +&gpmc_ethernet {

The same comments as before - this is difficult to review because you
mix up indentation. First, override by label, then do the fixup (or vice
versa). You ignored the comment last time.

Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Wed Sep 15 00:12:28 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 15 Sep 2021 09:12:28 +0200
Subject: [PATCH v4 8/8] memory: gpmc-omap: "gpmc, device-width" DT property
 is optional
In-Reply-To: <20210914122705.15421-9-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-9-rogerq@kernel.org>
Message-ID: <e0c4759b-7c2d-e32c-f912-8409c1f65b49@canonical.com>

On 14/09/2021 14:27, Roger Quadros wrote:
> Check for valid gpmc,device-width, nand-bus-width and bank-width
> at one place. Default to 8-bit width if none present.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  drivers/memory/omap-gpmc.c | 41 ++++++++++++++++++++++++--------------
>  1 file changed, 26 insertions(+), 15 deletions(-)
> 

All the comments from v3 are still applicable because it seems you
ignored them. Please respond to them.

It's the second patch where the reviewer's comments got lost, so it
creates rather poor impression.


Best regards,
Krzysztof


From miquel.raynal at bootlin.com  Wed Sep 15 00:13:15 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 15 Sep 2021 09:13:15 +0200
Subject: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
In-Reply-To: <927c7c75-c0d3-b3fb-6b85-13dbc3c6edbe@biot.com>
References: <20210908201624.237634-1-bert@biot.com>
 <20210914193108.78df5367@xps13>
 <1517789471.73175.1631641788145.JavaMail.zimbra@nod.at>
 <927c7c75-c0d3-b3fb-6b85-13dbc3c6edbe@biot.com>
Message-ID: <20210915091315.2768e9a3@xps13>

Hi Bert,

bert at biot.com wrote on Tue, 14 Sep 2021 22:03:49 +0200:

> On 9/14/21 7:49 PM, Richard Weinberger wrote:
> > ----- Urspr?ngliche Mail -----  
> >> bert at biot.com wrote on Wed,  8 Sep 2021 22:16:19 +0200:
> >>   
> >>> This adds a new vendor Etron, and support for a 2Gb chip.
> >>> 
> >>> The datasheet is available at
> >>> https://www.etron.com/cn/products/EM73%5B8%5DC%5BD_E_F%5DVC%20SPI%20NAND%20Flash_Promotion_Rev%201_00A.pdf
> >>> 
> >>> Signed-off-by: Bert Vermeulen <bert at biot.com>
> >>> ---
> >>> v2:
> >>> - Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
> >>>   hardcoded to this 2Gb chip only
> >>> - Fixed manufacturer ordering
> >>> - Fixed minor formatting issues as reported
> >>> - Removed debug comment
> >>> 
> >>>  drivers/mtd/nand/spi/Makefile |   2 +-
> >>>  drivers/mtd/nand/spi/core.c   |   1 +
> >>>  drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
> >>>  include/linux/mtd/spinand.h   |   1 +
> >>>  4 files changed, 107 insertions(+), 1 deletion(-)
> >>>  create mode 100644 drivers/mtd/nand/spi/etron.c  
> >> 
> >> [...]
> >>   
> >>> +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
> >>> +{
> >>> +	switch (status & STATUS_ECC_MASK) {
> >>> +	case STATUS_ECC_NO_BITFLIPS:
> >>> +		return 0;
> >>> +
> >>> +	case STATUS_ECC_HAS_BITFLIPS:
> >>> +		/* Between 1-7 bitflips were corrected */
> >>> +		return 7;  
> >> 
> >> Mmmh this is a bit problematic, having no intermediate value means a
> >> single bitflip will trigger UBI to move the data around as its
> >> threshold will be reached. Richard, any feedback on this?  
> > 
> > So, the NAND controller can only report "no bitflips", "some bitflips", "maximum biflips" and "no way to fix"?
> > If so, yes, this is problematic for UBI because it will trigger wear-leveling way too often.
> > On a medium aged NAND I'd expect to see STATUS_ECC_HAS_BITFLIPS almost always set. :-(  
> 
> Yes, that's all there is according to the datasheet. Can't be _that_
> unusual, since that's all the STATUS_ECC_* flags cover.

I forgot about that part which was reminded to me by Richard:

https://elixir.bootlin.com/linux/latest/source/drivers/mtd/mtdcore.c#L627
	/* default value if not set by driver */
	if (mtd->bitflip_threshold == 0)
		mtd->bitflip_threshold = mtd->ecc_strength;

So this is fine.

Thanks,
Miqu?l


From krzysztof.kozlowski at canonical.com  Wed Sep 15 00:20:45 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 15 Sep 2021 09:20:45 +0200
Subject: [PATCH v4 7/8] dt-bindings: memory-controllers: ti, gpmc: Convert
 to yaml
In-Reply-To: <20210914122705.15421-8-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-8-rogerq@kernel.org>
Message-ID: <654bb29d-5580-3035-fc43-546a7e88e224@canonical.com>

On 14/09/2021 14:27, Roger Quadros wrote:
> Convert omap-gpmc.txt to ti,gpmc.yaml.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../bindings/memory-controllers/omap-gpmc.txt | 157 ----------------
>  .../bindings/memory-controllers/ti,gpmc.yaml  | 172 ++++++++++++++++++
>  2 files changed, 172 insertions(+), 157 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt b/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> deleted file mode 100644
> index c1359f4d48d7..000000000000
> --- a/Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> +++ /dev/null
> @@ -1,157 +0,0 @@
> -Device tree bindings for OMAP general purpose memory controllers (GPMC)
> -
> -The actual devices are instantiated from the child nodes of a GPMC node.
> -
> -Required properties:
> -
> - - compatible:		Should be set to one of the following:
> -
> -			ti,omap2420-gpmc (omap2420)
> -			ti,omap2430-gpmc (omap2430)
> -			ti,omap3430-gpmc (omap3430 & omap3630)
> -			ti,omap4430-gpmc (omap4430 & omap4460 & omap543x)
> -			ti,am3352-gpmc   (am335x devices)
> -
> - - reg:			A resource specifier for the register space
> -			(see the example below)
> - - ti,hwmods:		Should be set to "ti,gpmc" until the DT transition is
> -			completed.
> - - #address-cells:	Must be set to 2 to allow memory address translation
> - - #size-cells:		Must be set to 1 to allow CS address passing
> - - gpmc,num-cs:		The maximum number of chip-select lines that controller
> -			can support.
> - - gpmc,num-waitpins:	The maximum number of wait pins that controller can
> -			support.
> - - ranges:		Must be set up to reflect the memory layout with four
> -			integer values for each chip-select line in use:
> -
> -			   <cs-number> 0 <physical address of mapping> <size>
> -
> -			Currently, calculated values derived from the contents
> -			of the per-CS register GPMC_CONFIG7 (as set up by the
> -			bootloader) are used for the physical address decoding.
> -			As this will change in the future, filling correct
> -			values here is a requirement.
> - - interrupt-controller: The GPMC driver implements and interrupt controller for
> -			the NAND events "fifoevent" and "termcount" plus the
> -			rising/falling edges on the GPMC_WAIT pins.
> -			The interrupt number mapping is as follows
> -			0 - NAND_fifoevent
> -			1 - NAND_termcount
> -			2 - GPMC_WAIT0 pin edge
> -			3 - GPMC_WAIT1 pin edge, and so on.
> - - interrupt-cells:	Must be set to 2
> - - gpio-controller:	The GPMC driver implements a GPIO controller for the
> -			GPMC WAIT pins that can be used as general purpose inputs.
> -			0 maps to GPMC_WAIT0 pin.
> - - gpio-cells:		Must be set to 2
> -
> -Required properties when using NAND prefetch dma:
> - - dmas			GPMC NAND prefetch dma channel
> - - dma-names		Must be set to "rxtx"
> -
> -Timing properties for child nodes. All are optional and default to 0.
> -
> - - gpmc,sync-clk-ps:	Minimum clock period for synchronous mode, in picoseconds
> -
> - Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2:
> - - gpmc,cs-on-ns:	Assertion time
> - - gpmc,cs-rd-off-ns:	Read deassertion time
> - - gpmc,cs-wr-off-ns:	Write deassertion time
> -
> - ADV signal timings (in nanoseconds) corresponding to GPMC_CONFIG3:
> - - gpmc,adv-on-ns:	Assertion time
> - - gpmc,adv-rd-off-ns:	Read deassertion time
> - - gpmc,adv-wr-off-ns:	Write deassertion time
> - - gpmc,adv-aad-mux-on-ns:	Assertion time for AAD
> - - gpmc,adv-aad-mux-rd-off-ns:	Read deassertion time for AAD
> - - gpmc,adv-aad-mux-wr-off-ns:	Write deassertion time for AAD
> -
> - WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
> - - gpmc,we-on-ns	Assertion time
> - - gpmc,we-off-ns:	Deassertion time
> -
> - OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
> - - gpmc,oe-on-ns:	Assertion time
> - - gpmc,oe-off-ns:	Deassertion time
> - - gpmc,oe-aad-mux-on-ns:	Assertion time for AAD
> - - gpmc,oe-aad-mux-off-ns:	Deassertion time for AAD
> -
> - Access time and cycle time timings (in nanoseconds) corresponding to
> - GPMC_CONFIG5:
> - - gpmc,page-burst-access-ns: 	Multiple access word delay
> - - gpmc,access-ns:		Start-cycle to first data valid delay
> - - gpmc,rd-cycle-ns:		Total read cycle time
> - - gpmc,wr-cycle-ns:		Total write cycle time
> - - gpmc,bus-turnaround-ns:	Turn-around time between successive accesses
> - - gpmc,cycle2cycle-delay-ns:	Delay between chip-select pulses
> - - gpmc,clk-activation-ns: 	GPMC clock activation time
> - - gpmc,wait-monitoring-ns:	Start of wait monitoring with regard to valid
> -				data
> -
> -Boolean timing parameters. If property is present parameter enabled and
> -disabled if omitted:
> - - gpmc,adv-extra-delay:	ADV signal is delayed by half GPMC clock
> - - gpmc,cs-extra-delay:		CS signal is delayed by half GPMC clock
> - - gpmc,cycle2cycle-diffcsen:	Add "cycle2cycle-delay" between successive
> -				accesses to a different CS
> - - gpmc,cycle2cycle-samecsen:	Add "cycle2cycle-delay" between successive
> -				accesses to the same CS
> - - gpmc,oe-extra-delay:		OE signal is delayed by half GPMC clock
> - - gpmc,we-extra-delay:		WE signal is delayed by half GPMC clock
> - - gpmc,time-para-granularity:	Multiply all access times by 2
> -
> -The following are only applicable to OMAP3+ and AM335x:
> - - gpmc,wr-access-ns:		In synchronous write mode, for single or
> -				burst accesses, defines the number of
> -				GPMC_FCLK cycles from start access time
> -				to the GPMC_CLK rising edge used by the
> -				memory device for the first data capture.
> - - gpmc,wr-data-mux-bus-ns:	In address-data multiplex mode, specifies
> -				the time when the first data is driven on
> -				the address-data bus.
> -
> -GPMC chip-select settings properties for child nodes. All are optional.
> -
> -- gpmc,burst-length	Page/burst length. Must be 4, 8 or 16.
> -- gpmc,burst-wrap	Enables wrap bursting
> -- gpmc,burst-read	Enables read page/burst mode
> -- gpmc,burst-write	Enables write page/burst mode
> -- gpmc,device-width	Total width of device(s) connected to a GPMC
> -			chip-select in bytes. The GPMC supports 8-bit
> -			and 16-bit devices and so this property must be
> -			1 or 2.
> -- gpmc,mux-add-data	Address and data multiplexing configuration.
> -			Valid values are 1 for address-address-data
> -			multiplexing mode and 2 for address-data
> -			multiplexing mode.
> -- gpmc,sync-read	Enables synchronous read. Defaults to asynchronous
> -			is this is not set.
> -- gpmc,sync-write	Enables synchronous writes. Defaults to asynchronous
> -			is this is not set.
> -- gpmc,wait-pin		Wait-pin used by client. Must be less than
> -			"gpmc,num-waitpins".
> -- gpmc,wait-on-read	Enables wait monitoring on reads.
> -- gpmc,wait-on-write	Enables wait monitoring on writes.
> -
> -Example for an AM33xx board:
> -
> -	gpmc: gpmc at 50000000 {
> -		compatible = "ti,am3352-gpmc";
> -		ti,hwmods = "gpmc";
> -		reg = <0x50000000 0x2000>;
> -		interrupts = <100>;
> -		dmas = <&edma 52 0>;
> -		dma-names = "rxtx";
> -		gpmc,num-cs = <8>;
> -		gpmc,num-waitpins = <2>;
> -		#address-cells = <2>;
> -		#size-cells = <1>;
> -		ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
> -		interrupt-controller;
> -		#interrupt-cells = <2>;
> -		gpio-controller;
> -		#gpio-cells = <2>;
> -
> -		/* child nodes go here */
> -	};
> diff --git a/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> new file mode 100644
> index 000000000000..d6cd39bd3940
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> @@ -0,0 +1,172 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/memory-controllers/ti,gpmc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Texas Instruments GPMC Memory Controller device-tree bindings
> +
> +maintainers:
> +  - Tony Lindgren <tony at atomide.com>
> +  - Roger Quadros <rogerq at kernel.org>
> +
> +description:
> +  The GPMC is a unified memory controller dedicated for interfacing
> +  with external memory devices like
> +  - Asynchronous SRAM-like memories and ASICs
> +  - Asynchronous, synchronous, and page mode burst NOR flash
> +  - NAND flash
> +  - Pseudo-SRAM devices
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - ti,omap2420-gpmc
> +          - ti,omap2430-gpmc
> +          - ti,omap3430-gpmc
> +          - ti,omap4430-gpmc
> +          - ti,am3352-gpmc

How about putting them in alphabetical order?

> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +    description: |
> +      Functional clock. Used for bus timing calculations and
> +      GPMC configuration.
> +
> +  clock-names:
> +    items:
> +      - const: fck
> +
> +  dmas:
> +    items:
> +      - description: DMA channel for GPMC NAND prefetch
> +
> +  dma-names:
> +    items:
> +      - const: rxtx
> +
> +  "#address-cells": true
> +
> +  "#size-cells": true
> +
> +  gpmc,num-cs:
> +    description: maximum number of supported chip-select lines.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +
> +  gpmc,num-waitpins:
> +    description: maximum number of supported wait pins.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +
> +  ranges:
> +    minItems: 1
> +    description: |
> +      Must be set up to reflect the memory layout with four
> +      integer values for each chip-select line in use,
> +      <cs-number> 0 <physical address of mapping> <size>
> +    items:
> +      - description: NAND bank 0
> +      - description: NOR/SRAM bank 0
> +      - description: NOR/SRAM bank 1
> +
> +  '#interrupt-cells':
> +    const: 2
> +
> +  interrupt-controller:
> +    description: |
> +      The GPMC driver implements and interrupt controller for
> +      the NAND events "fifoevent" and "termcount" plus the
> +      rising/falling edges on the GPMC_WAIT pins.
> +      The interrupt number mapping is as follows
> +      0 - NAND_fifoevent
> +      1 - NAND_termcount
> +      2 - GPMC_WAIT0 pin edge
> +      3 - GPMC_WAIT1 pin edge, and so on.
> +
> +  '#gpio-cells':
> +    const: 2
> +
> +  gpio-controller:
> +    description: |
> +      The GPMC driver implements a GPIO controller for the
> +      GPMC WAIT pins that can be used as general purpose inputs.
> +      0 maps to GPMC_WAIT0 pin.
> +
> +  ti,hwmods:
> +    description:
> +      Name of the HWMOD associated with GPMC. This is for legacy
> +      omap2/3 platforms only.
> +    $ref: /schemas/types.yaml#/definitions/string
> +    deprecated: true
> +
> +  ti,no-idle-on-init:
> +    description:
> +      Prevent idling the module at init. This is for legacy omap2/3
> +      platforms only.
> +    type: boolean
> +    deprecated: true
> +
> +patternProperties:
> +  "@[0-7],[a-f0-9]+$":
> +    type: object
> +    description: |
> +      The child device node represents the device connected to the GPMC
> +      bus. The device can be a NAND chip, SRAM device, NOR device
> +      or an ASIC.
> +
> +    allOf:
> +      - $ref: "ti,gpmc-child.yaml"
> +
> +    unevaluatedProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +  - gpmc,num-cs
> +  - gpmc,num-waitpins
> +  - "#address-cells"
> +  - "#size-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    gpmc: memory-controller at 50000000 {
> +      compatible = "ti,am3352-gpmc";
> +      reg = <0x50000000 0x2000>;
> +      interrupts = <100>;
> +      clocks = <&l3s_clkctrl>;
> +      clock-names = "fck";
> +      dmas = <&edma 52 0>;
> +      dma-names = "rxtx";
> +      gpmc,num-cs = <8>;
> +      gpmc,num-waitpins = <2>;
> +      #address-cells = <2>;
> +      #size-cells = <1>;
> +      ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
> +      interrupt-controller;
> +      #interrupt-cells = <2>;
> +      gpio-controller;
> +      #gpio-cells = <2>;
> +
> +      nand at 0,0 {
> +        compatible = "ti,omap2-nand";
> +        reg = <0 0 4>;
> +        interrupt-parent = <&gpmc>;
> +        interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
> +                     <1 IRQ_TYPE_NONE>; /* termcount */

Why these are interrupts of unspecified type (NONE)?

> +        ti,nand-xfer-type = "prefetch-dma";
> +        ti,nand-ecc-opt = "bch16";
> +        ti,elm-id = <&elm>;
> +        rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */
> +      };
> +    };
> 


Best regards,
Krzysztof


From frieder.schrempf at kontron.de  Wed Sep 15 01:13:12 2021
From: frieder.schrempf at kontron.de (Frieder Schrempf)
Date: Wed, 15 Sep 2021 10:13:12 +0200
Subject: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
In-Reply-To: <20210908201624.237634-1-bert@biot.com>
References: <20210908201624.237634-1-bert@biot.com>
Message-ID: <879e35bd-55ff-f43d-5780-24918d82bc5a@kontron.de>

Hi Bert,

On 08.09.21 22:16, Bert Vermeulen wrote:
> This adds a new vendor Etron, and support for a 2Gb chip.
> 
> The datasheet is available at
> https://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.etron.com%2Fcn%2Fproducts%2FEM73%255B8%255DC%255BD_E_F%255DVC%2520SPI%2520NAND%2520Flash_Promotion_Rev%25201_00A.pdf&amp;data=04%7C01%7Cfrieder.schrempf%40kontron.de%7C871fa2a364d8484bbc0d08d97305f2f4%7C8c9d3c973fd941c8a2b1646f3942daf1%7C0%7C0%7C637667293724201439%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=SeopP6Mvu1CHj6eB22XlO78NGnMc3hCFzM%2F5jKmJZxU%3D&amp;reserved=0
> 
> Signed-off-by: Bert Vermeulen <bert at biot.com>
> ---
> v2:
> - Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
>   hardcoded to this 2Gb chip only
> - Fixed manufacturer ordering
> - Fixed minor formatting issues as reported
> - Removed debug comment
> 
>  drivers/mtd/nand/spi/Makefile |   2 +-
>  drivers/mtd/nand/spi/core.c   |   1 +
>  drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
>  include/linux/mtd/spinand.h   |   1 +
>  4 files changed, 107 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/mtd/nand/spi/etron.c
> 
> diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
> index 9662b9c1d5a9..cc3c4e046ea9 100644
> --- a/drivers/mtd/nand/spi/Makefile
> +++ b/drivers/mtd/nand/spi/Makefile
> @@ -1,3 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0
> -spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
> +spinand-objs := core.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
>  obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
> index 446ba8d43fbc..2cbf25b8caa2 100644
> --- a/drivers/mtd/nand/spi/core.c
> +++ b/drivers/mtd/nand/spi/core.c
> @@ -894,6 +894,7 @@ static const struct nand_ops spinand_ops = {
>  };
>  
>  static const struct spinand_manufacturer *spinand_manufacturers[] = {
> +	&etron_spinand_manufacturer,
>  	&gigadevice_spinand_manufacturer,
>  	&macronix_spinand_manufacturer,
>  	&micron_spinand_manufacturer,
> diff --git a/drivers/mtd/nand/spi/etron.c b/drivers/mtd/nand/spi/etron.c
> new file mode 100644
> index 000000000000..1a92b9cf3043
> --- /dev/null
> +++ b/drivers/mtd/nand/spi/etron.c
> @@ -0,0 +1,104 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/mtd/spinand.h>
> +
> +#define SPINAND_MFR_ETRON			0xd5
> +
> +static SPINAND_OP_VARIANTS(read_cache_variants,
> +		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
> +
> +static SPINAND_OP_VARIANTS(write_cache_variants,
> +		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
> +		SPINAND_PROG_LOAD(true, 0, NULL, 0));
> +
> +static SPINAND_OP_VARIANTS(update_cache_variants,
> +		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
> +		SPINAND_PROG_LOAD(false, 0, NULL, 0));
> +
> +static int etron_oob_spare(struct mtd_info *mtd)
> +{
> +	if (mtd->size < 0x10000000)
> +		return mtd->oobsize / 2;
> +	else
> +		return mtd->oobsize / 2 + mtd->oobsize / 16;
> +}
> +
> +static int etron_ooblayout_ecc(struct mtd_info *mtd, int section,
> +					struct mtd_oob_region *oobregion)
> +{
> +	if (section)
> +		return -ERANGE;
> +
> +	oobregion->offset = etron_oob_spare(mtd);
> +	oobregion->length = mtd->oobsize - oobregion->offset;
> +
> +	return 0;
> +}
> +
> +static int etron_ooblayout_free(struct mtd_info *mtd, int section,
> +			   struct mtd_oob_region *oobregion)
> +{
> +	if (section)
> +		return -ERANGE;
> +
> +	oobregion->offset = 2;
> +	oobregion->length = etron_oob_spare(mtd) - 2;
> +
> +	return 0;
> +}
> +
> +static const struct mtd_ooblayout_ops etron_ooblayout = {
> +	.ecc = etron_ooblayout_ecc,
> +	.free = etron_ooblayout_free,
> +};
> +
> +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
> +{
> +	switch (status & STATUS_ECC_MASK) {
> +	case STATUS_ECC_NO_BITFLIPS:
> +		return 0;
> +
> +	case STATUS_ECC_HAS_BITFLIPS:
> +		/* Between 1-7 bitflips were corrected */
> +		return 7;
> +
> +	case STATUS_ECC_MASK:

I'm not sure if using STATUS_ECC_MASK here to check for the 0b11 pattern
is really a good idea. I'd rather introduce a vendor-specific define for
this as other drivers do (see toshiba.c, paragon.c or gigadevice.c). As
this seems to be a common pattern among vendors we could also think
about introducing a new common flag like STATUS_ECC_HAS_MAX_BITFLIPS or
something like that and use this instead.

> +		/* Maximum bitflips were corrected */
> +		return 8;
> +
> +	case STATUS_ECC_UNCOR_ERROR:
> +		return -EBADMSG;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct spinand_info etron_spinand_table[] = {
> +	SPINAND_INFO("EM73D044VCx",
> +		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f),

According to the datasheet, the device id of the EM73D044VCL is 0x2e and
not 0x1f. Am I missing something?

Best regards
Frieder

> +		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
> +		     NAND_ECCREQ(8, 512),
> +		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
> +					      &write_cache_variants,
> +					      &update_cache_variants),
> +		     SPINAND_HAS_QE_BIT,
> +		     SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
> +};
> +
> +static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = {
> +};
> +
> +const struct spinand_manufacturer etron_spinand_manufacturer = {
> +	.id = SPINAND_MFR_ETRON,
> +	.name = "Etron",
> +	.chips = etron_spinand_table,
> +	.nchips = ARRAY_SIZE(etron_spinand_table),
> +	.ops = &etron_spinand_manuf_ops,
> +};
> diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
> index 6988956b8492..d7c0a0439652 100644
> --- a/include/linux/mtd/spinand.h
> +++ b/include/linux/mtd/spinand.h
> @@ -260,6 +260,7 @@ struct spinand_manufacturer {
>  };
>  
>  /* SPI NAND manufacturers */
> +extern const struct spinand_manufacturer etron_spinand_manufacturer;
>  extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
>  extern const struct spinand_manufacturer macronix_spinand_manufacturer;
>  extern const struct spinand_manufacturer micron_spinand_manufacturer;
> 


From rogerq at kernel.org  Wed Sep 15 01:47:39 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 15 Sep 2021 11:47:39 +0300
Subject: [PATCH v4 8/8] memory: gpmc-omap: "gpmc, device-width" DT property
 is optional
In-Reply-To: <e0c4759b-7c2d-e32c-f912-8409c1f65b49@canonical.com>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-9-rogerq@kernel.org>
 <e0c4759b-7c2d-e32c-f912-8409c1f65b49@canonical.com>
Message-ID: <6a06f4bd-f20a-8b5a-c152-0877707670ff@kernel.org>

Hi Krzysztof,

On 15/09/2021 10:12, Krzysztof Kozlowski wrote:
> On 14/09/2021 14:27, Roger Quadros wrote:
>> Check for valid gpmc,device-width, nand-bus-width and bank-width
>> at one place. Default to 8-bit width if none present.
>>
>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>> ---
>>  drivers/memory/omap-gpmc.c | 41 ++++++++++++++++++++++++--------------
>>  1 file changed, 26 insertions(+), 15 deletions(-)
>>
> 
> All the comments from v3 are still applicable because it seems you
> ignored them. Please respond to them.
> 
> It's the second patch where the reviewer's comments got lost, so it
> creates rather poor impression.

I was wondering what comments and then realized that gmail server has put
all your messages into spam folder.

I'm very sorry about that. I will address your comments ASAP.

cheers,
-roger


From rogerq at kernel.org  Wed Sep 15 01:53:30 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 15 Sep 2021 11:53:30 +0300
Subject: [PATCH v3 1/8] ARM: dts: omap: Fixup GPMC child nodes
In-Reply-To: <8e29cf74-313f-b8c5-7514-60b5e404833d@canonical.com>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-2-rogerq@kernel.org>
 <8e29cf74-313f-b8c5-7514-60b5e404833d@canonical.com>
Message-ID: <ff88463e-50f7-7a65-0a40-09ba2e420885@kernel.org>

Hi Krzysztof,

On 07/09/2021 15:44, Krzysztof Kozlowski wrote:
> On 07/09/2021 13:32, Roger Quadros wrote:
>> Fixes up the GPMC child nodes to prevent dtbs_check errors
>> after device tree binding conversion to yaml.
>>
>> - Use reg address as node name
>> - gpmc,cycle2cycle-samecsen and gpmc,cycle2cycle-diffcsen are
>>   boolean properties.
>>
>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>> ---
>>  .../boot/dts/logicpd-som-lv-baseboard.dtsi    |  2 +-
>>  .../boot/dts/logicpd-torpedo-37xx-devkit.dts  |  2 +-
>>  .../boot/dts/logicpd-torpedo-baseboard.dtsi   |  2 +-
>>  arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi     | 62 +++++++++----------
>>  arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi     | 59 +++++++++---------
>>  arch/arm/boot/dts/omap-zoom-common.dtsi       | 16 ++---
>>  arch/arm/boot/dts/omap2430-sdp.dts            |  6 +-
>>  arch/arm/boot/dts/omap3-cm-t3x30.dtsi         |  6 +-
>>  .../arm/boot/dts/omap3-devkit8000-common.dtsi |  4 +-
>>  arch/arm/boot/dts/omap3-evm-37xx.dts          |  1 +
>>  arch/arm/boot/dts/omap3-evm-common.dtsi       |  9 ---
>>  .../boot/dts/omap3-evm-processor-common.dtsi  |  5 +-
>>  arch/arm/boot/dts/omap3-evm.dts               |  1 +
>>  arch/arm/boot/dts/omap3-igep0020-common.dtsi  |  5 +-
>>  arch/arm/boot/dts/omap3-ldp.dts               |  5 +-
>>  arch/arm/boot/dts/omap3-n900.dts              |  2 +-
>>  .../dts/omap3-overo-chestnut43-common.dtsi    |  6 +-
>>  .../arm/boot/dts/omap3-overo-tobi-common.dtsi |  6 +-
>>  .../boot/dts/omap3-overo-tobiduo-common.dtsi  |  8 +--
>>  arch/arm/boot/dts/omap3-sb-t35.dtsi           |  4 +-
>>  arch/arm/boot/dts/omap4-duovero-parlor.dts    |  6 +-
>>  21 files changed, 105 insertions(+), 112 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
>> index 7d0468a23781..f2364cb114c5 100644
>> --- a/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
>> +++ b/arch/arm/boot/dts/logicpd-som-lv-baseboard.dtsi
>> @@ -65,7 +65,7 @@
>>  		  1 0 0x2c000000 0x1000000	/* CS1: 16MB for LAN9221 */
>>  		  2 0 0x10000000 0x2000000>;    /* CS2: 32MB for NOR */
>>  
>> -	ethernet at gpmc {
>> +	gpmc_ethernet: ethernet at 1,0 {
>>  		pinctrl-names = "default";
>>  		pinctrl-0 = <&lan9221_pins>;
>>  		interrupt-parent = <&gpio5>;
>> diff --git a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
>> index 5532db04046c..6357915d207b 100644
>> --- a/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
>> +++ b/arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts
>> @@ -4,8 +4,8 @@
>>  
>>  #include "omap36xx.dtsi"
>>  #include "logicpd-torpedo-som.dtsi"
>> -#include "omap-gpmc-smsc9221.dtsi"
>>  #include "logicpd-torpedo-baseboard.dtsi"
>> +#include "omap-gpmc-smsc9221.dtsi"
>>  
>>  / {
>>  	model = "LogicPD Zoom DM3730 Torpedo + Wireless Development Kit";
>> diff --git a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
>> index 533a47bc4a53..05049a34b6f1 100644
>> --- a/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
>> +++ b/arch/arm/boot/dts/logicpd-torpedo-baseboard.dtsi
>> @@ -95,7 +95,7 @@
>>  	ranges = <0 0 0x30000000 0x1000000	/* CS0: 16MB for NAND */
>>  		  1 0 0x2c000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
>>  
>> -	ethernet at gpmc {
>> +	gpmc_ethernet: ethernet at 1,0 {
>>  		pinctrl-names = "default";
>>  		pinctrl-0 = <&lan9221_pins>;
>>  		interrupt-parent = <&gpio5>;
>> diff --git a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
>> index ded7e8fec9eb..2a462cb65a7d 100644
>> --- a/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
>> +++ b/arch/arm/boot/dts/omap-gpmc-smsc911x.dtsi
>> @@ -20,36 +20,34 @@
>>  	};
>>  };
>>  
>> -&gpmc {
>> -	ethernet at gpmc {
>> -		compatible = "smsc,lan9221", "smsc,lan9115";
>> -		bank-width = <2>;
>> -		gpmc,device-width = <1>;
>> -		gpmc,cycle2cycle-samecsen = <1>;
>> -		gpmc,cycle2cycle-diffcsen = <1>;
>> -		gpmc,cs-on-ns = <5>;
>> -		gpmc,cs-rd-off-ns = <150>;
>> -		gpmc,cs-wr-off-ns = <150>;
>> -		gpmc,adv-on-ns = <0>;
>> -		gpmc,adv-rd-off-ns = <15>;
>> -		gpmc,adv-wr-off-ns = <40>;
>> -		gpmc,oe-on-ns = <45>;
>> -		gpmc,oe-off-ns = <140>;
>> -		gpmc,we-on-ns = <45>;
>> -		gpmc,we-off-ns = <140>;
>> -		gpmc,rd-cycle-ns = <155>;
>> -		gpmc,wr-cycle-ns = <155>;
>> -		gpmc,access-ns = <120>;
>> -		gpmc,page-burst-access-ns = <20>;
>> -		gpmc,bus-turnaround-ns = <75>;
>> -		gpmc,cycle2cycle-delay-ns = <75>;
>> -		gpmc,wait-monitoring-ns = <0>;
>> -		gpmc,clk-activation-ns = <0>;
>> -		gpmc,wr-data-mux-bus-ns = <0>;
>> -		gpmc,wr-access-ns = <0>;
>> -		vddvario-supply = <&vddvario>;
>> -		vdd33a-supply = <&vdd33a>;
>> -		reg-io-width = <4>;
>> -		smsc,save-mac-address;
>> -	};
>> +&gpmc_ethernet {
>> +	compatible = "smsc,lan9221", "smsc,lan9115";
> 
> This looks like regular override-by-label instead of full path.
> Unfortunately change of the indentation causes difficulties to find the
> real difference - if there is such. Can you split it into separate patch?
> 
> The point is that override-by-label should have zero effect on
> functionality and produce same dtb. This is easy to compare with
> dtx_diff or fdt-decompile but if you mix it with other changes, the
> comparison is not straight-forward.

OK. I will split the overide-by-label to separate patch and ensure there is no
change in compiled dtb for that patch.

> 
>> +	bank-width = <2>;
>> +	gpmc,device-width = <1>;
>> +	gpmc,cycle2cycle-samecsen;
>> +	gpmc,cycle2cycle-diffcsen;
>> +	gpmc,cs-on-ns = <5>;
>> +	gpmc,cs-rd-off-ns = <150>;
>> +	gpmc,cs-wr-off-ns = <150>;
>> +	gpmc,adv-on-ns = <0>;
>> +	gpmc,adv-rd-off-ns = <15>;
>> +	gpmc,adv-wr-off-ns = <40>;
>> +	gpmc,oe-on-ns = <45>;
>> +	gpmc,oe-off-ns = <140>;
>> +	gpmc,we-on-ns = <45>;
>> +	gpmc,we-off-ns = <140>;
>> +	gpmc,rd-cycle-ns = <155>;
>> +	gpmc,wr-cycle-ns = <155>;
>> +	gpmc,access-ns = <120>;
>> +	gpmc,page-burst-access-ns = <20>;
>> +	gpmc,bus-turnaround-ns = <75>;
>> +	gpmc,cycle2cycle-delay-ns = <75>;
>> +	gpmc,wait-monitoring-ns = <0>;
>> +	gpmc,clk-activation-ns = <0>;
>> +	gpmc,wr-data-mux-bus-ns = <0>;
>> +	gpmc,wr-access-ns = <0>;
>> +	vddvario-supply = <&vddvario>;
>> +	vdd33a-supply = <&vdd33a>;
>> +	reg-io-width = <4>;
>> +	smsc,save-mac-address;
>>  };
>> diff --git a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
>> index 7f6aefd13451..c1e78f929d2b 100644
>> --- a/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
>> +++ b/arch/arm/boot/dts/omap-gpmc-smsc9221.dtsi
>> @@ -24,36 +24,33 @@
>>  	};
>>  };
>>  
>> -&gpmc {
>> -	ethernet at gpmc {
>> -		compatible = "smsc,lan9221","smsc,lan9115";
>> -		bank-width = <2>;
>> +&gpmc_ethernet {
>> +	compatible = "smsc,lan9221","smsc,lan9115";
>> +	bank-width = <2>;
>> +	gpmc,mux-add-data = <0>;
>> +	gpmc,cs-on-ns = <0>;
>> +	gpmc,cs-rd-off-ns = <42>;
>> +	gpmc,cs-wr-off-ns = <36>;
>> +	gpmc,adv-on-ns = <6>;
>> +	gpmc,adv-rd-off-ns = <12>;
>> +	gpmc,adv-wr-off-ns = <12>;
>> +	gpmc,oe-on-ns = <0>;
>> +	gpmc,oe-off-ns = <42>;
>> +	gpmc,we-on-ns = <0>;
>> +	gpmc,we-off-ns = <36>;
>> +	gpmc,rd-cycle-ns = <60>;
>> +	gpmc,wr-cycle-ns = <54>;
>> +	gpmc,access-ns = <36>;
>> +	gpmc,page-burst-access-ns = <0>;
>> +	gpmc,bus-turnaround-ns = <0>;
>> +	gpmc,cycle2cycle-delay-ns = <0>;
>> +	gpmc,wr-data-mux-bus-ns = <18>;
>> +	gpmc,wr-access-ns = <42>;
>> +	gpmc,cycle2cycle-samecsen;
>> +	gpmc,cycle2cycle-diffcsen;
>>  
>> -		gpmc,mux-add-data;
> 
> Same here and in other places. Actually here a sneaky change is visible
> - different property.
> 
> Best regards,
> Krzysztof
> 

cheers,
-roger


From krzysztof.kozlowski at canonical.com  Wed Sep 15 02:05:37 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 15 Sep 2021 11:05:37 +0200
Subject: [PATCH v4 8/8] memory: gpmc-omap: "gpmc, device-width" DT property
 is optional
In-Reply-To: <6a06f4bd-f20a-8b5a-c152-0877707670ff@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-9-rogerq@kernel.org>
 <e0c4759b-7c2d-e32c-f912-8409c1f65b49@canonical.com>
 <6a06f4bd-f20a-8b5a-c152-0877707670ff@kernel.org>
Message-ID: <1b915c39-fd6d-3c3c-e4bf-4df9a694dfb6@canonical.com>

On 15/09/2021 10:47, Roger Quadros wrote:
> Hi Krzysztof,
> 
> On 15/09/2021 10:12, Krzysztof Kozlowski wrote:
>> On 14/09/2021 14:27, Roger Quadros wrote:
>>> Check for valid gpmc,device-width, nand-bus-width and bank-width
>>> at one place. Default to 8-bit width if none present.
>>>
>>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>>> ---
>>>  drivers/memory/omap-gpmc.c | 41 ++++++++++++++++++++++++--------------
>>>  1 file changed, 26 insertions(+), 15 deletions(-)
>>>
>>
>> All the comments from v3 are still applicable because it seems you
>> ignored them. Please respond to them.
>>
>> It's the second patch where the reviewer's comments got lost, so it
>> creates rather poor impression.
> 
> I was wondering what comments and then realized that gmail server has put
> all your messages into spam folder.
> 
> I'm very sorry about that. I will address your comments ASAP.

Oops. There were just two emails from me for v3. Can you send me
(privately) the headers from my emails so I can investigate why they
ended up on Spam?

Best regards,
Krzysztof


From rogerq at kernel.org  Wed Sep 15 02:11:04 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Wed, 15 Sep 2021 12:11:04 +0300
Subject: [PATCH v3 8/8] memory: gpmc-omap: "gpmc, device-width" DT property
 is optional
In-Reply-To: <aa465bd9-b3d5-8d75-3e59-e86c2cd093cd@canonical.com>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-9-rogerq@kernel.org>
 <aa465bd9-b3d5-8d75-3e59-e86c2cd093cd@canonical.com>
Message-ID: <a881ac1f-2f00-e675-aea6-154b28ca6eff@kernel.org>

Hi Krzysztof,

On 07/09/2021 15:36, Krzysztof Kozlowski wrote:
> On 07/09/2021 13:32, Roger Quadros wrote:
>> Check for valid gpmc,device-width, nand-bus-width and bank-width
>> at one place. Default to 8-bit width if none present.
> 
> I don't understand the message in the context of the patch. The title
> says one property is optional - that's it. The message says you
> consolidate checks. How is this related to the title?
> 
> The patch itself moves around checking of properties and reads
> nand-bus-width *always*. It does not "check at one place" but rather
> "check always". In the same time, the patch does not remove
> gpmc,device-width check in other place.
> 
> All three elements - the title, message and patch - do different things.
> What did you want to achieve here? Can you help in clarifying it?
> 

OK I will explain it better in commit log in next revision. Let me explain here a bit.

Prior to this patch it was working like this

	/* in gpmc_read_settings_dt() */
	s->device_width = 0;	/* invalid width, should be 1 for 8-bit, 2 for 16-bit */
	of_property_read_u32(np, "gpmc,device-width", s->device_width);

	/* in gpmc_probe_generic_child () */
	if (of_device_is_compatible(child, "ti,omap2-nand")) {
		/* check for nand-bus-width, if absent set s->device_width to 1 (i.e. 8-bit) */
	} else {
		/* check for bank-width, if absent and s->device_width not set, error out */
	}

So that means if all three, "gpmc,device-width". "nand-bus-width" and "bank-width" are missing then
it would create an error situation.

The patch is doing 3 things.
1) Make sure all DT checks related to bus width are being done at one place for better readability.
2) even if all 3 width properties are absent, we will not treat it as error and default to 8-bit.
3) check for nand-bus-width regardless of whether compatible to "ti,omap2-nand" or not.

Hope this explains well.

cheers,
-roger

> 
> Best regards,
> Krzysztof
> 
> 
>>
>> Signed-off-by: Roger Quadros <rogerq at kernel.org>
>> ---
>>  drivers/memory/omap-gpmc.c | 41 ++++++++++++++++++++++++--------------
>>  1 file changed, 26 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
>> index f80c2ea39ca4..32d7c665f33c 100644
>> --- a/drivers/memory/omap-gpmc.c
>> +++ b/drivers/memory/omap-gpmc.c
>> @@ -2171,10 +2171,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
>>  		}
>>  	}
>>  
>> -	if (of_device_is_compatible(child, "ti,omap2-nand")) {
>> -		/* NAND specific setup */
>> -		val = 8;
>> -		of_property_read_u32(child, "nand-bus-width", &val);
>> +	/* DT node can have "nand-bus-width" or "bank-width" or "gpmc,device-width" */
>> +	if (!of_property_read_u32(child, "nand-bus-width", &val)) {
>>  		switch (val) {
>>  		case 8:
>>  			gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
>> @@ -2183,24 +2181,37 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
>>  			gpmc_s.device_width = GPMC_DEVWIDTH_16BIT;
>>  			break;
>>  		default:
>> -			dev_err(&pdev->dev, "%pOFn: invalid 'nand-bus-width'\n",
>> -				child);
>> +			dev_err(&pdev->dev,
>> +				"%pOFn: invalid 'nand-bus-width':%d\n", child, val);
>> +			ret = -EINVAL;
>> +			goto err;
>> +		}
>> +	} else if (!of_property_read_u32(child, "bank-width", &val)) {
>> +		if (val != 1 && val != 2) {
>> +			dev_err(&pdev->dev,
>> +				"%pOFn: invalid 'bank-width':%d\n", child, val);
>>  			ret = -EINVAL;
>>  			goto err;
>>  		}
>> +		gpmc_s.device_width = val;
>> +	} else if (!of_property_read_u32(child, "gpmc,device-width", &val)) {
>> +		if (val != 1 && val != 2) {
>> +			dev_err(&pdev->dev,
>> +				"%pOFn: invalid 'gpmc,device-width':%d\n", child, val);
>> +			ret = -EINVAL;
>> +			goto err;
>> +		}
>> +		gpmc_s.device_width = val;
>> +	} else {
>> +		/* default to 8-bit */
>> +		gpmc_s.device_width = GPMC_DEVWIDTH_8BIT;
>> +	}
>>  
>> +	if (of_device_is_compatible(child, "ti,omap2-nand")) {
>> +		/* NAND specific setup */
>>  		/* disable write protect */
>>  		gpmc_configure(GPMC_CONFIG_WP, 0);
>>  		gpmc_s.device_nand = true;
>> -	} else {
>> -		ret = of_property_read_u32(child, "bank-width",
>> -					   &gpmc_s.device_width);
>> -		if (ret < 0 && !gpmc_s.device_width) {
>> -			dev_err(&pdev->dev,
>> -				"%pOF has no 'gpmc,device-width' property\n",
>> -				child);
>> -			goto err;
>> -		}
>>  	}
>>  
>>  	/* Reserve wait pin if it is required and valid */
>>
> 
> 


From mdalam at codeaurora.org  Wed Sep 15 02:57:28 2021
From: mdalam at codeaurora.org (Md Sadre Alam)
Date: Wed, 15 Sep 2021 15:27:28 +0530
Subject: [PATCH 0/3] Add support for page scope read
Message-ID: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>

These series of patches to support page scope read.

In QPIC v1, SW is needed to write EXEC_CMD register
for each Code word and collect any Status related to
that CW before issueing EXEC_CMD for next CW.

Page scope command, currently supported only for read
commands in bam mode, is truly a page mode command where
SW is required to issue EXEC_CMD only once for a page.
Controller HW takes care of Codeword specific details
and automatically returns status associated with each
CW to BAM pipe, dedicated for status deposition.

Md Sadre Alam (3):
  mtd: rawnand: qcom: Add support for status pipe
  mtd: rawnand: qcom: Add sg list to handle status pipe request
  mtd: rawnand: qcom: Add support for page scope read

 drivers/mtd/nand/raw/qcom_nandc.c | 125 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 119 insertions(+), 6 deletions(-)

-- 
2.7.4



From mdalam at codeaurora.org  Wed Sep 15 02:57:29 2021
From: mdalam at codeaurora.org (Md Sadre Alam)
Date: Wed, 15 Sep 2021 15:27:29 +0530
Subject: [PATCH 1/3] mtd: rawnand: qcom: Add support for status pipe
In-Reply-To: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
Message-ID: <1631699851-12172-2-git-send-email-mdalam@codeaurora.org>

>From QPIC V2.0 onwards there is a separate pipe
to read status of each code word, called "status" pipe.

"status" pipe will use to read CW status in case of
enhanced read mode like page scope read, multi page read.

Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
---
 drivers/mtd/nand/raw/qcom_nandc.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 04e6f7b..42c6291 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -389,6 +389,7 @@ struct qcom_nand_controller {
 			struct dma_chan *tx_chan;
 			struct dma_chan *rx_chan;
 			struct dma_chan *cmd_chan;
+			struct dma_chan *sts_chan;
 		};
 
 		/* will be used only by EBI2 for ADM DMA */
@@ -2737,6 +2738,11 @@ static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
 
 		if (nandc->cmd_chan)
 			dma_release_channel(nandc->cmd_chan);
+
+		if (nandc->props->qpic_v2) {
+			if (nandc->sts_chan)
+				dma_release_channel(nandc->sts_chan);
+		}
 	} else {
 		if (nandc->chan)
 			dma_release_channel(nandc->chan);
@@ -2815,6 +2821,14 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
 			goto unalloc;
 		}
 
+		if (nandc->props->qpic_v2) {
+			nandc->sts_chan = dma_request_slave_channel(nandc->dev, "sts");
+			if (!nandc->sts_chan) {
+				dev_err(nandc->dev, "failed to request sts channel\n");
+				return -ENODEV;
+			}
+		}
+
 		/*
 		 * Initially allocate BAM transaction to read ONFI param page.
 		 * After detecting all the devices, this BAM transaction will
-- 
2.7.4



From mdalam at codeaurora.org  Wed Sep 15 02:57:30 2021
From: mdalam at codeaurora.org (Md Sadre Alam)
Date: Wed, 15 Sep 2021 15:27:30 +0530
Subject: [PATCH 2/3] mtd: rawnand: qcom: Add sg list to handle status pipe
 request
In-Reply-To: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
Message-ID: <1631699851-12172-3-git-send-email-mdalam@codeaurora.org>

>From QPIC V2.0 onwards there is separate pipe to read status
for each code word while reading in enhanced mode. page scope
read and multi page read.

This sgl list will be use to handle the request via status pipe
during page scope and multi page read.

Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
---
 drivers/mtd/nand/raw/qcom_nandc.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 42c6291..07448c4 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -213,6 +213,7 @@ nandc_set_reg(chip, reg,			\
 #define QPIC_PER_CW_CMD_ELEMENTS	32
 #define QPIC_PER_CW_CMD_SGL		32
 #define QPIC_PER_CW_DATA_SGL		8
+#define	QPIC_PER_CW_STS_SGL		8
 
 #define QPIC_NAND_COMPLETION_TIMEOUT	msecs_to_jiffies(2000)
 
@@ -258,6 +259,7 @@ struct bam_transaction {
 	struct bam_cmd_element *bam_ce;
 	struct scatterlist *cmd_sgl;
 	struct scatterlist *data_sgl;
+	struct scatterlist *sts_sgl;
 	u32 bam_ce_pos;
 	u32 bam_ce_start;
 	u32 cmd_sgl_pos;
@@ -266,6 +268,8 @@ struct bam_transaction {
 	u32 tx_sgl_start;
 	u32 rx_sgl_pos;
 	u32 rx_sgl_start;
+	u32 sts_sgl_pos;
+	u32 sts_sgl_start;
 	bool wait_second_completion;
 	struct completion txn_done;
 	struct dma_async_tx_descriptor *last_data_desc;
@@ -508,6 +512,8 @@ alloc_bam_transaction(struct qcom_nand_controller *nandc)
 		((sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS) +
 		(sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) +
 		(sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL));
+	if (nandc->props->qpic_v2)
+		bam_txn_size += (sizeof(*bam_txn->sts_sgl) * QPIC_PER_CW_STS_SGL);
 
 	bam_txn_buf = devm_kzalloc(nandc->dev, bam_txn_size, GFP_KERNEL);
 	if (!bam_txn_buf)
@@ -526,6 +532,12 @@ alloc_bam_transaction(struct qcom_nand_controller *nandc)
 
 	bam_txn->data_sgl = bam_txn_buf;
 
+	if (nandc->props->qpic_v2) {
+		bam_txn_buf +=
+			sizeof(*bam_txn->sts_sgl) * QPIC_PER_CW_STS_SGL * num_cw;
+		bam_txn->sts_sgl = bam_txn_buf;
+	}
+
 	init_completion(&bam_txn->txn_done);
 
 	return bam_txn;
@@ -554,6 +566,12 @@ static void clear_bam_transaction(struct qcom_nand_controller *nandc)
 		      QPIC_PER_CW_CMD_SGL);
 	sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage *
 		      QPIC_PER_CW_DATA_SGL);
+	if (nandc->props->qpic_v2) {
+		bam_txn->sts_sgl_pos = 0;
+		bam_txn->sts_sgl_start = 0;
+		sg_init_table(bam_txn->sts_sgl, nandc->max_cwperpage *
+				QPIC_PER_CW_STS_SGL);
+	}
 
 	reinit_completion(&bam_txn->txn_done);
 }
@@ -808,6 +826,12 @@ static int prepare_bam_async_desc(struct qcom_nand_controller *nandc,
 		bam_txn->tx_sgl_start = bam_txn->tx_sgl_pos;
 		dir_eng = DMA_MEM_TO_DEV;
 		desc->dir = DMA_TO_DEVICE;
+	} else if (nandc->props->qpic_v2 && chan == nandc->sts_chan) {
+		sgl = &bam_txn->sts_sgl[bam_txn->sts_sgl_start];
+		sgl_cnt = bam_txn->sts_sgl_pos - bam_txn->sts_sgl_start;
+		bam_txn->sts_sgl_start = bam_txn->sts_sgl_pos;
+		dir_eng = DMA_DEV_TO_MEM;
+		desc->dir = DMA_FROM_DEVICE;
 	} else {
 		sgl = &bam_txn->data_sgl[bam_txn->rx_sgl_start];
 		sgl_cnt = bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start;
@@ -1394,6 +1418,14 @@ static int submit_descs(struct qcom_nand_controller *nandc)
 			if (r)
 				return r;
 		}
+
+		if (nandc->props->qpic_v2) {
+			if (bam_txn->sts_sgl_pos > bam_txn->sts_sgl_start) {
+				r = prepare_bam_async_desc(nandc, nandc->sts_chan, 0);
+				if (r)
+					return r;
+			}
+		}
 	}
 
 	list_for_each_entry(desc, &nandc->desc_list, node)
@@ -1411,6 +1443,8 @@ static int submit_descs(struct qcom_nand_controller *nandc)
 		dma_async_issue_pending(nandc->tx_chan);
 		dma_async_issue_pending(nandc->rx_chan);
 		dma_async_issue_pending(nandc->cmd_chan);
+		if (nandc->props->qpic_v2)
+			dma_async_issue_pending(nandc->sts_chan);
 
 		if (!wait_for_completion_timeout(&bam_txn->txn_done,
 						 QPIC_NAND_COMPLETION_TIMEOUT))
-- 
2.7.4



From mdalam at codeaurora.org  Wed Sep 15 02:57:31 2021
From: mdalam at codeaurora.org (Md Sadre Alam)
Date: Wed, 15 Sep 2021 15:27:31 +0530
Subject: [PATCH 3/3] mtd: rawnand: qcom: Add support for page scope read
In-Reply-To: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
Message-ID: <1631699851-12172-4-git-send-email-mdalam@codeaurora.org>

QPIC V2.0 onwards QPIC controller support enhanced read mode
like page scope read and multi page read.

In QPIC V1, SW is needed to write EXEC_CMD register for each
Code word and collect any Status related to that CW before
issueing EXEC_CMD for next CW.

Page scope command is truly a page mode command where SW is
required to issue EXEC_CMD only once for a page. Controller
HW takes care of Codeword specific details and automatically
returns status associated with each CW to BAM pipe, dedicated
for status deposition.

With this command, SW now can issue one read command for a page
and upon receiving completion interrupt, can process status,
that have already been deposited in memory through status BAM pipe.

Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
---
 drivers/mtd/nand/raw/qcom_nandc.c | 77 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 71 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 07448c4..257dec7e 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -157,6 +157,10 @@
 #define	OP_FETCH_ID			0xb
 #define	OP_RESET_DEVICE			0xd
 
+/* Auto status val and mask */
+#define	AUTO_STS_VAL			0x000B000B
+#define PAGE_SCOPE_READ			BIT(23)
+
 /* Default Value for NAND_DEV_CMD_VLD */
 #define NAND_DEV_CMD_VLD_VAL		(READ_START_VLD | WRITE_START_VLD | \
 					 ERASE_START_VLD | SEQ_READ_START_VLD)
@@ -336,6 +340,8 @@ struct nandc_regs {
 
 	__le32 erased_cw_detect_cfg_clr;
 	__le32 erased_cw_detect_cfg_set;
+
+	__le32 auto_sts_en;
 };
 
 /*
@@ -421,6 +427,9 @@ struct qcom_nand_controller {
 
 	u32 cmd1, vld;
 	const struct qcom_nandc_props *props;
+
+	__le32 *status_buf;
+	int sts_buf_size;
 };
 
 /*
@@ -487,6 +496,7 @@ struct qcom_nandc_props {
 	bool is_bam;
 	bool is_qpic;
 	bool qpic_v2;
+	bool page_scope;
 	u32 dev_cmd_reg_start;
 };
 
@@ -656,6 +666,8 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset)
 		return &regs->cfg1;
 	case NAND_DEV0_ECC_CFG:
 		return &regs->ecc_bch_cfg;
+	case NAND_AUTO_STATUS_EN:
+		return &regs->auto_sts_en;
 	case NAND_READ_STATUS:
 		return &regs->clrreadstatus;
 	case NAND_DEV_CMD1:
@@ -756,10 +768,13 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, i
 	struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
 
 	if (read) {
-		if (host->use_ecc)
+		if (host->use_ecc) {
 			cmd = OP_PAGE_READ_WITH_ECC | PAGE_ACC | LAST_PAGE;
-		else
+			if (nandc->props->qpic_v2 && nandc->props->page_scope)
+				cmd |= PAGE_SCOPE_READ;
+		} else {
 			cmd = OP_PAGE_READ | PAGE_ACC | LAST_PAGE;
+		}
 	} else {
 		cmd = OP_PROGRAM_PAGE | PAGE_ACC | LAST_PAGE;
 	}
@@ -788,6 +803,9 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, i
 	nandc_set_reg(chip, NAND_READ_STATUS, host->clrreadstatus);
 	nandc_set_reg(chip, NAND_EXEC_CMD, 1);
 
+	if (nandc->props->qpic_v2 && nandc->props->page_scope)
+		nandc_set_reg(chip, NAND_AUTO_STATUS_EN, AUTO_STS_VAL);
+
 	if (read)
 		nandc_set_read_loc(chip, cw, 0, 0, host->use_ecc ?
 				   host->cw_data : host->cw_size, 1);
@@ -1040,6 +1058,26 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
 }
 
 /*
+ * read_status_data_dma: prepares a DMA descriptor to transfer status from the
+ *			 controller's status registers to buffer 'vaddr'
+ * @reg_off:             offset within the controller's data buffer
+ * @vaddr:               virtual address of the buffer we want to write to
+ * @size:                DMA transaction size in bytes
+ * @flags:               flags to control DMA descriptor preparation
+ */
+static int read_status_data_dma(struct qcom_nand_controller *nandc, int reg_off,
+				const u8 *vaddr, int size, unsigned int flags)
+{
+	struct bam_transaction *bam_txn = nandc->bam_txn;
+
+	sg_set_buf(&bam_txn->sts_sgl[bam_txn->sts_sgl_pos],
+		   vaddr, size);
+	bam_txn->sts_sgl_pos++;
+
+	return 0;
+}
+
+/*
  * read_reg_dma:	prepares a descriptor to read a given number of
  *			contiguous registers to the reg_read_buf pointer
  *
@@ -1186,13 +1224,20 @@ config_nand_cw_read(struct nand_chip *chip, bool use_ecc, int cw)
 		write_reg_dma(nandc, reg, 4, NAND_BAM_NEXT_SGL);
 
 	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
 	if (use_ecc) {
-		read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
-		read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
-			     NAND_BAM_NEXT_SGL);
+		if (nandc->props->qpic_v2 && nandc->props->page_scope) {
+			if (qcom_nandc_is_last_cw(ecc, cw))
+				write_reg_dma(nandc, NAND_EXEC_CMD, 1,
+					      NAND_BAM_NEXT_SGL);
+		} else {
+			write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
+			read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
+			read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
+				     NAND_BAM_NEXT_SGL);
+		}
 	} else {
+		write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 		read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
 	}
 }
@@ -1959,6 +2004,8 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
 	u8 *data_buf_start = data_buf, *oob_buf_start = oob_buf;
 	int i, ret;
+	__le32 *status_buf_start = nandc->status_buf;
+	__le32 *status_buf_cw = nandc->status_buf;
 
 	config_nand_page_read(chip);
 
@@ -1994,6 +2041,12 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
 			read_data_dma(nandc, FLASH_BUF_ACC, data_buf,
 				      data_size, 0);
 
+		if (nandc->props->qpic_v2 && nandc->props->page_scope) {
+			read_status_data_dma(nandc, FLASH_BUF_ACC, (void *)status_buf_cw,
+					     (nandc->sts_buf_size >> 2), 0);
+			status_buf_cw += (nandc->sts_buf_size >> 4);
+		}
+
 		/*
 		 * when ecc is enabled, the controller doesn't read the real
 		 * or dummy bad block markers in each chunk. To maintain a
@@ -2025,6 +2078,9 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
 		return ret;
 	}
 
+	if (nandc->props->qpic_v2 && nandc->props->page_scope)
+		memmove(nandc->reg_read_buf, status_buf_start, nandc->sts_buf_size);
+
 	return parse_read_errors(host, data_buf_start, oob_buf_start, page);
 }
 
@@ -3005,6 +3061,14 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
 		}
 	}
 
+	if (nandc->props->qpic_v2 && nandc->props->page_scope) {
+		nandc->sts_buf_size = mtd->writesize == SZ_2K ? 48 : 96;
+		nandc->status_buf = devm_kzalloc(nandc->dev, nandc->sts_buf_size,
+						 GFP_KERNEL);
+		if (!nandc->status_buf)
+			return -ENOMEM;
+	}
+
 	ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
 	if (ret)
 		nand_cleanup(chip);
@@ -3197,6 +3261,7 @@ static const struct qcom_nandc_props sdx55_nandc_props = {
 	.is_bam = true,
 	.is_qpic = true,
 	.qpic_v2 = true,
+	.page_scope = true,
 	.dev_cmd_reg_start = 0x7000,
 };
 
-- 
2.7.4



From mrts11223 at gmail.com  Wed Sep 15 05:31:06 2021
From: mrts11223 at gmail.com (Marilyn Robert)
Date: Wed, 15 Sep 2021 12:31:06 +0000
Subject: Liebste im Herrn
Message-ID: <CAFmVNYkgtbG_pJOhOgKeC3xZDdXR2A6eV8AU8thQ1c1qiKYh7g@mail.gmail.com>

Hallo
Mein Name ist Frau Marilyn Robert. Zur Zeit bin ich zur Behandlung
eines Hirntumors, an dem ich seit 5 Jahren leide, ins Krankenhaus
eingeliefert. Tats?chlich kontaktiere ich Sie, weil ich eine
humanit?re Geste an den Standort aller sensiblen Seelen machen m?chte.
Mein verstorbener Mann und ich hatten ein kleines Verm?gen
mobilisiert, das wir in humanit?re Arbeiten investieren wollten. Aber
in Anbetracht meines Gesundheitszustandes kann ich dieses Projekt
nicht mehr alleine erf?llen. Ich m?chte, dass Sie dieses Projekt in
meinem Namen abschlie?en. Ich kontaktiere Sie nach meinen wenigen
Tagen des Gebets mit dem Glauben, dass Sie Gottes Auserw?hlter sind,
um dieses Projekt in gutem Glauben abzuschlie?en. F?r eine positive
Meinung kontaktieren Sie mich bitte f?r weitere Informationen, da ich
nicht wei?, was als n?chstes passieren kann.
Sei gesegnet im Namen unseres Herrn.
Frau Marilyn Robert


From hoeppner at linux.ibm.com  Wed Sep 15 07:57:48 2021
From: hoeppner at linux.ibm.com (=?UTF-8?Q?Jan_H=c3=b6ppner?=)
Date: Wed, 15 Sep 2021 16:57:48 +0200
Subject: [PATCH 6/9] s390/block/dasd_genhd: add error handling support for
 add_disk()
In-Reply-To: <YT+Bmvv3yXbuBddi@bombadil.infradead.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-7-mcgrof@kernel.org>
 <d6140e40-a472-e732-9893-99e1839b717e@linux.ibm.com>
 <f24da7d5-0b67-fa24-862f-0b27a2ab502c@linux.ibm.com>
 <YT+Bmvv3yXbuBddi@bombadil.infradead.org>
Message-ID: <417cf368-6821-442b-0a14-006b27690591@linux.ibm.com>

On 13/09/2021 18:51, Luis Chamberlain wrote:
> On Mon, Sep 13, 2021 at 02:19:38PM +0200, Jan H?ppner wrote:
>> On 13/09/2021 10:17, Jan H?ppner wrote:
>>> On 02/09/2021 19:41, Luis Chamberlain wrote:
>>>> We never checked for errors on add_disk() as this function
>>>> returned void. Now that this is fixed, use the shiny new
>>>> error handling.
>>>>
>>>> Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
>>>> ---
>>>>  drivers/s390/block/dasd_genhd.c | 8 ++++++--
>>>>  1 file changed, 6 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
>>>> index fa966e0db6ca..ba07022283bc 100644
>>>> --- a/drivers/s390/block/dasd_genhd.c
>>>> +++ b/drivers/s390/block/dasd_genhd.c
>>>> @@ -33,7 +33,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
>>>>  {
>>>>  	struct gendisk *gdp;
>>>>  	struct dasd_device *base;
>>>> -	int len;
>>>> +	int len, rc;
>>>>  
>>>>  	/* Make sure the minor for this device exists. */
>>>>  	base = block->base;
>>>> @@ -79,7 +79,11 @@ int dasd_gendisk_alloc(struct dasd_block *block)
>>>>  	dasd_add_link_to_gendisk(gdp, base);
>>>>  	block->gdp = gdp;
>>>>  	set_capacity(block->gdp, 0);
>>>> -	device_add_disk(&base->cdev->dev, block->gdp, NULL);
>>>> +
>>>> +	rc = device_add_disk(&base->cdev->dev, block->gdp, NULL);
>>>> +	if (rc)
>>>> +		return rc;
>>>> +
>>>
>>> I think, just like with some of the other changes, there is some
>>> cleanup required before returning. I'll prepare a patch and
>>> come back to you.
>>>
>>
>> It's actually just one call that is required. The patch should
>> look like this:
>>
>> diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
>> index fa966e0db6ca..80673dbfb1f9 100644
>> --- a/drivers/s390/block/dasd_genhd.c
>> +++ b/drivers/s390/block/dasd_genhd.c
>> @@ -33,7 +33,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
>>  {
>>         struct gendisk *gdp;
>>         struct dasd_device *base;
>> -       int len;
>> +       int len, rc;
>>  
>>         /* Make sure the minor for this device exists. */
>>         base = block->base;
>> @@ -79,7 +79,13 @@ int dasd_gendisk_alloc(struct dasd_block *block)
>>         dasd_add_link_to_gendisk(gdp, base);
>>         block->gdp = gdp;
>>         set_capacity(block->gdp, 0);
>> -       device_add_disk(&base->cdev->dev, block->gdp, NULL);
>> +
>> +       rc = device_add_disk(&base->cdev->dev, block->gdp, NULL);
>> +       if (rc) {
>> +               dasd_gendisk_free(block);
>> +               return rc;
>> +       }
>> +
> 
> Thanks!
> 
> Would you like to to fold this fix into my patch and resend eventually?
> Or will you send a replacement?
> 
>   Luis
> 

I'd be fine with you just taking the changes for your patchset.
Once you've resent the whole patchset I'll review it and send
the usual ack or r-b.

regards,
Jan


From krzysztof.kozlowski at canonical.com  Thu Sep 16 03:48:19 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 16 Sep 2021 12:48:19 +0200
Subject: [PATCH v3 8/8] memory: gpmc-omap: "gpmc, device-width" DT property
 is optional
In-Reply-To: <a881ac1f-2f00-e675-aea6-154b28ca6eff@kernel.org>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-9-rogerq@kernel.org>
 <aa465bd9-b3d5-8d75-3e59-e86c2cd093cd@canonical.com>
 <a881ac1f-2f00-e675-aea6-154b28ca6eff@kernel.org>
Message-ID: <35643319-e3b0-bde1-c51b-57c3b5474146@canonical.com>

On 15/09/2021 11:11, Roger Quadros wrote:
> Hi Krzysztof,
> 
> On 07/09/2021 15:36, Krzysztof Kozlowski wrote:
>> On 07/09/2021 13:32, Roger Quadros wrote:
>>> Check for valid gpmc,device-width, nand-bus-width and bank-width
>>> at one place. Default to 8-bit width if none present.
>>
>> I don't understand the message in the context of the patch. The title
>> says one property is optional - that's it. The message says you
>> consolidate checks. How is this related to the title?
>>
>> The patch itself moves around checking of properties and reads
>> nand-bus-width *always*. It does not "check at one place" but rather
>> "check always". In the same time, the patch does not remove
>> gpmc,device-width check in other place.
>>
>> All three elements - the title, message and patch - do different things.
>> What did you want to achieve here? Can you help in clarifying it?
>>
> 
> OK I will explain it better in commit log in next revision. Let me explain here a bit.
> 
> Prior to this patch it was working like this
> 
> 	/* in gpmc_read_settings_dt() */
> 	s->device_width = 0;	/* invalid width, should be 1 for 8-bit, 2 for 16-bit */
> 	of_property_read_u32(np, "gpmc,device-width", s->device_width);
> 
> 	/* in gpmc_probe_generic_child () */
> 	if (of_device_is_compatible(child, "ti,omap2-nand")) {
> 		/* check for nand-bus-width, if absent set s->device_width to 1 (i.e. 8-bit) */
> 	} else {
> 		/* check for bank-width, if absent and s->device_width not set, error out */
> 	}
> 
> So that means if all three, "gpmc,device-width". "nand-bus-width" and "bank-width" are missing then
> it would create an error situation.
> 
> The patch is doing 3 things.
> 1) Make sure all DT checks related to bus width are being done at one place for better readability.

Not entirely. The gpmc,device-width is still done in the other place
because you did not remove it from the code. Unless you meant parsing of
gpmc,device-width not reading from DT? But then another round of checks
is in gpmc_cs_program_settings() so not in one place.

If you consolidate the checks to one place, I would expect the code to
be removed from other places, so from gpmc_cs_program_settings() and
gpmc_read_settings_dt(). Since this is not happening, the message
confuses me.

> 2) even if all 3 width properties are absent, we will not treat it as error and default to 8-bit.

This is not mentioned in commit msg.

> 3) check for nand-bus-width regardless of whether compatible to "ti,omap2-nand" or not.

Also not mentioned in commit msg.

Your commit reorganizes parsing and validating the child DT properties
but it does not change from "multiple place" to "one place".

At least I don't see it.

Best regards,
Krzysztof


From thtssqc002 at gmail.com  Thu Sep 16 05:28:59 2021
From: thtssqc002 at gmail.com (yugyuui gf7yu)
Date: Thu, 16 Sep 2021 20:28:59 +0800
Subject: =?UTF-8?B?56Wd5L2g5bmz5a6J?=
Message-ID: <CAJpPCrmH2MQTqh5MBhwnVg=mDM4vgu6z4da4Hp9VPHsL9xn=GQ@mail.gmail.com>

                                    ????



                                 ???????
                                 ???????
                                 ?????

                                 ???????
                                 ???????
                                 ?????








?? > ???? > ????



                             ???????????????



???????????????????????????????????????Juc?????????????????????????????????????????????????????????????Jemma?????????????????????????????????????
????????????????????????????????????????????????????????????????????????????????????

???????????????????????????????????????????????????????????????????????????????????????????????????????

?????????????????????

?????????????

????????????????????????????????????????????????????????????

??????????????????????????????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????

?????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???????????????????????????????????????????????????????????????????????????????????????????????????????????

???????????????

?????????????????????????????????????????????????????????

??????????????????????????????????????????????????????????????????????????????????????

?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

????????????????????????????????

????????????

?????????????????????????????????????????????????????????????????????????????????????????????????????????

???????????????????????????????????????????????????????????????????????

??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

??????????

?????????????????????????????????????????

?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????[1]

?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????[2]

??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

???????????

???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

????????????????????????????????????????????

???????

????????????????????????????????????????????????????????????????????????????????????

???????????????????????????????????????????????????????????????

??
[1] ????????????????????? ?
[2] ????????????????????? ?


http://www.minghui.org/mh/articles/2021/2/19/????????-??????-421107.html

??????????

Email ??? ?????????freeget.one at gmail.com ?
xiazai at upup.info????????????????
???? ???????????????
????https://git.io/fgp88 https://git.io/umexe
????https://git.io/fgm88
https://s3.amazonaws.com/693/um.apk
?????????????????????
????IE?Edge?Chrome ????????
????
??APP ??
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ????-read.pdf
Type: application/pdf
Size: 3471535 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210916/6c6e3c09/attachment-0004.pdf>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ????-read.pdf
Type: application/pdf
Size: 6973212 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210916/6c6e3c09/attachment-0005.pdf>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ????-?????????????? ??.doc
Type: application/msword
Size: 5767680 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210916/6c6e3c09/attachment-0004.doc>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ???????????????????.doc
Type: application/msword
Size: 56320 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210916/6c6e3c09/attachment-0005.doc>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ??????-read.pdf
Type: application/pdf
Size: 2340903 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210916/6c6e3c09/attachment-0006.pdf>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ?????_doc.doc
Type: application/msword
Size: 429056 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210916/6c6e3c09/attachment-0006.doc>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ?????????.pdf
Type: application/pdf
Size: 5369264 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210916/6c6e3c09/attachment-0007.pdf>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ?????.doc
Type: application/msword
Size: 173568 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210916/6c6e3c09/attachment-0007.doc>

From jan at 3e8.eu  Thu Sep 16 12:38:26 2021
From: jan at 3e8.eu (Jan Hoffmann)
Date: Thu, 16 Sep 2021 21:38:26 +0200
Subject: [PATCH v2] mtd: rawnand: xway: No hardcoded ECC engine, use
 device tree setting
In-Reply-To: <20210808072643.GA5084@ubuntu>
References: <20210808072643.GA5084@ubuntu>
Message-ID: <51f2ebf4-6df1-eba5-99f1-1ec88e475d20@3e8.eu>

Hello,

Configuration of the ECC engine type using device tree has actually
worked before. I am using OpenWrt on a Fritzbox 7362 SL, which has a
Micron 29F1G08ABADA flash chip. The bootloader of the device uses on-die
ECC, so that has to be used for Linux as well. It is configured in DTS
using "nand-ecc-mode = "on-die";". This worked fine with kernel 5.4.
However, after switching to kernel 5.10 it is ignored and software ECC
is used instead.

If I understand this correctly, the situation is as follows:

Originally, xway-nand did set defaults for ECC mode and algorithm, but
different values could be configured using device tree.

Commit d7157ff49a5b ("mtd: rawnand: Use the ECC framework user input
parsing bits") broke these default values, as the ECC algorithm is now
unconditionally set from the user configuration in rawnand_dt_init.
Previously, the default value was only overwritten if the device tree
actually contained a value.

This is fixed in d525914b5bd8 ("mtd: rawnand: xway: Move the ECC
initialization to ->attach_chip()"). However, this makes it impossible
to configure the ECC engine type in the device tree, as it is now
overwritten by the default value in xway_attach_chip.

I am not sure if this patch is the best approach for fixing this, as it
would again cause breakage for anyone who relies on the existing
default value. And this kind of breakage seems to have been the reason
for moving the default values to attach_chip in the first place (see
https://lore.kernel.org/lkml/20201105084939.72ea6bfd at xps13/ ).

As similar changes were applied to other NAND drivers, the same issue
probably also exists there. Maybe it makes sense to add a proper fix
for all of them?

Thanks,
Jan


From robh at kernel.org  Thu Sep 16 12:49:11 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 16 Sep 2021 14:49:11 -0500
Subject: [PATCH v11 08/34] dt-bindings: host1x: Document Memory Client
 resets of Host1x, GR2D and GR3D
In-Reply-To: <20210912200832.12312-9-digetx@gmail.com>
References: <20210912200832.12312-1-digetx@gmail.com>
 <20210912200832.12312-9-digetx@gmail.com>
Message-ID: <YUOftwuVt7EqtA5I@robh.at.kernel.org>

On Sun, 12 Sep 2021 23:08:06 +0300, Dmitry Osipenko wrote:
> Memory Client should be blocked before hardware reset is asserted in order
> to prevent memory corruption and hanging of memory controller.
> 
> Document Memory Client resets of Host1x, GR2D and GR3D hardware units.
> 
> Signed-off-by: Dmitry Osipenko <digetx at gmail.com>
> ---
>  .../bindings/display/tegra/nvidia,tegra20-host1x.txt          | 4 ++++
>  1 file changed, 4 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From rogerq at kernel.org  Fri Sep 17 00:17:10 2021
From: rogerq at kernel.org (Roger Quadros)
Date: Fri, 17 Sep 2021 10:17:10 +0300
Subject: [PATCH v3 8/8] memory: gpmc-omap: "gpmc, device-width" DT property
 is optional
In-Reply-To: <35643319-e3b0-bde1-c51b-57c3b5474146@canonical.com>
References: <20210907113226.31876-1-rogerq@kernel.org>
 <20210907113226.31876-9-rogerq@kernel.org>
 <aa465bd9-b3d5-8d75-3e59-e86c2cd093cd@canonical.com>
 <a881ac1f-2f00-e675-aea6-154b28ca6eff@kernel.org>
 <35643319-e3b0-bde1-c51b-57c3b5474146@canonical.com>
Message-ID: <d574837c-b42a-53be-7885-9feb7183ce96@kernel.org>


On 16/09/2021 13:48, Krzysztof Kozlowski wrote:
> On 15/09/2021 11:11, Roger Quadros wrote:
>> Hi Krzysztof,
>>
>> On 07/09/2021 15:36, Krzysztof Kozlowski wrote:
>>> On 07/09/2021 13:32, Roger Quadros wrote:
>>>> Check for valid gpmc,device-width, nand-bus-width and bank-width
>>>> at one place. Default to 8-bit width if none present.
>>>
>>> I don't understand the message in the context of the patch. The title
>>> says one property is optional - that's it. The message says you
>>> consolidate checks. How is this related to the title?
>>>
>>> The patch itself moves around checking of properties and reads
>>> nand-bus-width *always*. It does not "check at one place" but rather
>>> "check always". In the same time, the patch does not remove
>>> gpmc,device-width check in other place.
>>>
>>> All three elements - the title, message and patch - do different things.
>>> What did you want to achieve here? Can you help in clarifying it?
>>>
>>
>> OK I will explain it better in commit log in next revision. Let me explain here a bit.
>>
>> Prior to this patch it was working like this
>>
>> 	/* in gpmc_read_settings_dt() */
>> 	s->device_width = 0;	/* invalid width, should be 1 for 8-bit, 2 for 16-bit */
>> 	of_property_read_u32(np, "gpmc,device-width", s->device_width);
>>
>> 	/* in gpmc_probe_generic_child () */
>> 	if (of_device_is_compatible(child, "ti,omap2-nand")) {
>> 		/* check for nand-bus-width, if absent set s->device_width to 1 (i.e. 8-bit) */
>> 	} else {
>> 		/* check for bank-width, if absent and s->device_width not set, error out */
>> 	}
>>
>> So that means if all three, "gpmc,device-width". "nand-bus-width" and "bank-width" are missing then
>> it would create an error situation.
>>
>> The patch is doing 3 things.
>> 1) Make sure all DT checks related to bus width are being done at one place for better readability.
> 
> Not entirely. The gpmc,device-width is still done in the other place
> because you did not remove it from the code. Unless you meant parsing of
> gpmc,device-width not reading from DT? But then another round of checks
> is in gpmc_cs_program_settings() so not in one place.

By checking I meant parsing. But you are right, I missed the part in gpmc_cs_program_settings().

> 
> If you consolidate the checks to one place, I would expect the code to
> be removed from other places, so from gpmc_cs_program_settings() and
> gpmc_read_settings_dt(). Since this is not happening, the message
> confuses me.
> 
>> 2) even if all 3 width properties are absent, we will not treat it as error and default to 8-bit.
> 
> This is not mentioned in commit msg.
> 
>> 3) check for nand-bus-width regardless of whether compatible to "ti,omap2-nand" or not.
> 
> Also not mentioned in commit msg.
> 
> Your commit reorganizes parsing and validating the child DT properties
> but it does not change from "multiple place" to "one place".
> 
> At least I don't see it.

OK. I will write a better commit log next time. Thanks for the review :)

cheers,
-roger


From miquel.raynal at bootlin.com  Fri Sep 17 10:01:54 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri, 17 Sep 2021 19:01:54 +0200
Subject: [PATCH v2] mtd: rawnand: xway: No hardcoded ECC engine, use
 device tree setting
In-Reply-To: <51f2ebf4-6df1-eba5-99f1-1ec88e475d20@3e8.eu>
References: <20210808072643.GA5084@ubuntu>
 <51f2ebf4-6df1-eba5-99f1-1ec88e475d20@3e8.eu>
Message-ID: <20210917190154.76203a9a@xps13>

Hi Jan,

jan at 3e8.eu wrote on Thu, 16 Sep 2021 21:38:26 +0200:

> Hello,
> 
> Configuration of the ECC engine type using device tree has actually
> worked before. I am using OpenWrt on a Fritzbox 7362 SL, which has a
> Micron 29F1G08ABADA flash chip. The bootloader of the device uses on-die
> ECC, so that has to be used for Linux as well. It is configured in DTS
> using "nand-ecc-mode = "on-die";". This worked fine with kernel 5.4.
> However, after switching to kernel 5.10 it is ignored and software ECC
> is used instead.
> 
> If I understand this correctly, the situation is as follows:
> 
> Originally, xway-nand did set defaults for ECC mode and algorithm, but
> different values could be configured using device tree.
> 
> Commit d7157ff49a5b ("mtd: rawnand: Use the ECC framework user input
> parsing bits") broke these default values, as the ECC algorithm is now
> unconditionally set from the user configuration in rawnand_dt_init.
> Previously, the default value was only overwritten if the device tree
> actually contained a value.
> 
> This is fixed in d525914b5bd8 ("mtd: rawnand: xway: Move the ECC
> initialization to ->attach_chip()"). However, this makes it impossible
> to configure the ECC engine type in the device tree, as it is now
> overwritten by the default value in xway_attach_chip.
> 
> I am not sure if this patch is the best approach for fixing this, as it
> would again cause breakage for anyone who relies on the existing
> default value. And this kind of breakage seems to have been the reason
> for moving the default values to attach_chip in the first place (see
> https://lore.kernel.org/lkml/20201105084939.72ea6bfd at xps13/ ).
> 
> As similar changes were applied to other NAND drivers, the same issue
> probably also exists there. Maybe it makes sense to add a proper fix
> for all of them?

I am not sure to understand your message as answer to this thread.
There are two problems here:
1/ The DT values not being taken into account
2/ Kestrel's issue with two different integrations with no way to
distinguish between them.

1/ Has already been fixed (at least that is what I think)
2/ Cannot easily be fixed and I don't think there is anything we can do
besides the manufacturer "fixing" the board description.

Am I missing something?

Thanks,
Miqu?l


From jan at 3e8.eu  Fri Sep 17 10:45:33 2021
From: jan at 3e8.eu (Jan Hoffmann)
Date: Fri, 17 Sep 2021 19:45:33 +0200
Subject: [PATCH v2] mtd: rawnand: xway: No hardcoded ECC engine, use
 device tree setting
In-Reply-To: <20210917190154.76203a9a@xps13>
References: <20210808072643.GA5084@ubuntu>
 <51f2ebf4-6df1-eba5-99f1-1ec88e475d20@3e8.eu> <20210917190154.76203a9a@xps13>
Message-ID: <e9dd0653-139f-749b-c088-e756ee2d2132@3e8.eu>

Hi Miqu?l,

> I am not sure to understand your message as answer to this thread.
> There are two problems here:
> 1/ The DT values not being taken into account

This is the issue I'm referring to.

> 1/ Has already been fixed (at least that is what I think)

This is not fixed in kernel 5.10. And unless I am missing something
there also doesn't seem be a fix in more recent kernels.

I am aware of commit 33d974e76e21 ("mtd: rawnand: xway: Do not force a
particular software ECC engine"), but that only fixes the ECC
algorithm. The ECC engine type is still hard-coded in xway_attach_chip.

Thanks,
Jan


From miquel.raynal at bootlin.com  Fri Sep 17 12:32:46 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri, 17 Sep 2021 21:32:46 +0200
Subject: [PATCH v2] mtd: rawnand: xway: No hardcoded ECC engine, use
 device tree setting
In-Reply-To: <e9dd0653-139f-749b-c088-e756ee2d2132@3e8.eu>
References: <20210808072643.GA5084@ubuntu>
 <51f2ebf4-6df1-eba5-99f1-1ec88e475d20@3e8.eu>
 <20210917190154.76203a9a@xps13>
 <e9dd0653-139f-749b-c088-e756ee2d2132@3e8.eu>
Message-ID: <20210917213246.319e60cb@xps13>

Hi Jan,

jan at 3e8.eu wrote on Fri, 17 Sep 2021 19:45:33 +0200:

> Hi Miqu?l,
> 
> > I am not sure to understand your message as answer to this thread.
> > There are two problems here:
> > 1/ The DT values not being taken into account  
> 
> This is the issue I'm referring to.
> 
> > 1/ Has already been fixed (at least that is what I think)  
> 
> This is not fixed in kernel 5.10. And unless I am missing something
> there also doesn't seem be a fix in more recent kernels.
> 
> I am aware of commit 33d974e76e21 ("mtd: rawnand: xway: Do not force a
> particular software ECC engine"), but that only fixes the ECC
> algorithm. The ECC engine type is still hard-coded in xway_attach_chip.

Yes this was my understanding, that only software ECC engine was
supported. The mainline driver shows absolutely no signs of hardware
ECC engine support.

Perhaps however you mean that on-die ECC engine are not supported
anymore because of the engine_type being set in attach_chip()? If yes
then indeed there is something to do, perhaps checking if an engine has
been already set is enough? You can try something like:

if (engine_type == unknown)
	engine_type = soft;
 
Thanks,
Miqu?l


From daniel at 0x0f.com  Sat Sep 18 00:22:56 2021
From: daniel at 0x0f.com (Daniel Palmer)
Date: Sat, 18 Sep 2021 16:22:56 +0900
Subject: [PATCH] mtd: spi-nor: Add support for ZB25VQ128
Message-ID: <20210918072256.3505379-1-daniel@0x0f.com>

Add support for the ZBIT ZB25VQ128 128MBit SPI NOR
flash.

Link: http://www.cipatelje.eu/pdf/ZB25VQ128.pdf
Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 drivers/mtd/spi-nor/Makefile |  1 +
 drivers/mtd/spi-nor/core.c   |  1 +
 drivers/mtd/spi-nor/core.h   |  1 +
 drivers/mtd/spi-nor/zbit.c   | 21 +++++++++++++++++++++
 4 files changed, 24 insertions(+)
 create mode 100644 drivers/mtd/spi-nor/zbit.c

diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index 6b904e439372..a6f3646824cb 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -17,6 +17,7 @@ spi-nor-objs			+= sst.o
 spi-nor-objs			+= winbond.o
 spi-nor-objs			+= xilinx.o
 spi-nor-objs			+= xmc.o
+spi-nor-objs			+= zbit.o
 obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
 
 obj-$(CONFIG_MTD_SPI_NOR)	+= controllers/
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index cc08bd707378..75f6ac9485b9 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1846,6 +1846,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = {
 	&spi_nor_winbond,
 	&spi_nor_xilinx,
 	&spi_nor_xmc,
+	&spi_nor_zbit,
 };
 
 static const struct flash_info *
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 3348e1dd1445..ad3b34a3b80f 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -489,6 +489,7 @@ extern const struct spi_nor_manufacturer spi_nor_sst;
 extern const struct spi_nor_manufacturer spi_nor_winbond;
 extern const struct spi_nor_manufacturer spi_nor_xilinx;
 extern const struct spi_nor_manufacturer spi_nor_xmc;
+extern const struct spi_nor_manufacturer spi_nor_zbit;
 
 extern const struct attribute_group *spi_nor_sysfs_groups[];
 
diff --git a/drivers/mtd/spi-nor/zbit.c b/drivers/mtd/spi-nor/zbit.c
new file mode 100644
index 000000000000..d240dd65d249
--- /dev/null
+++ b/drivers/mtd/spi-nor/zbit.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021, Daniel Palmer<daniel at thingy.jp>
+ */
+
+#include <linux/mtd/spi-nor.h>
+
+#include "core.h"
+
+static const struct flash_info zbit_parts[] = {
+	/* zbit */
+	{ "zb25vq128", INFO(0x5e4018, 0, 64 * 1024, 256,
+			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+			    SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
+};
+
+const struct spi_nor_manufacturer spi_nor_zbit = {
+	.name = "zbit",
+	.parts = zbit_parts,
+	.nparts = ARRAY_SIZE(zbit_parts),
+};
-- 
2.33.0



From jan at 3e8.eu  Sat Sep 18 14:26:48 2021
From: jan at 3e8.eu (Jan Hoffmann)
Date: Sat, 18 Sep 2021 23:26:48 +0200
Subject: [PATCH v2] mtd: rawnand: xway: No hardcoded ECC engine, use
 device tree setting
In-Reply-To: <20210917213246.319e60cb@xps13>
References: <20210808072643.GA5084@ubuntu>
 <51f2ebf4-6df1-eba5-99f1-1ec88e475d20@3e8.eu> <20210917190154.76203a9a@xps13>
 <e9dd0653-139f-749b-c088-e756ee2d2132@3e8.eu> <20210917213246.319e60cb@xps13>
Message-ID: <14eb0cb7-b0af-87bf-b9a5-3e35eeb43f54@3e8.eu>

Hi Miqu?l,

> Yes this was my understanding, that only software ECC engine was
> supported. The mainline driver shows absolutely no signs of hardware
> ECC engine support.
> 
> Perhaps however you mean that on-die ECC engine are not supported
> anymore because of the engine_type being set in attach_chip()?

Yes, this is exactly the issue.

> If yes then indeed there is something to do, perhaps checking if an
> engine has been already set is enough? You can try something like:
> 
> if (engine_type == unknown)
> 	engine_type = soft;

Checking for NAND_ECC_ENGINE_TYPE_INVALID doesn't work, as the engine
type is already set to NAND_ECC_ENGINE_TYPE_ON_HOST by rawnand_dt_init.
The code there seems to expect that chip->ecc.engine_type contains the
default value, which is no longer the case after commit 525914b5bd8
("mtd: rawnand: xway: Move the ECC initialization to ->attach_chip()").

The following in attach_chip works:

if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST)
	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;

However, this will also silently use the software ECC engine if anyone
actually configures the on-host hardware ECC engine in the device tree
(which is of course unsupported for xway).

Thanks,
Jan


From schaecsn at gmx.net  Sun Sep 19 19:48:24 2021
From: schaecsn at gmx.net (Stefan Schaeckeler)
Date: Sun, 19 Sep 2021 19:48:24 -0700 (PDT)
Subject: [PATCH 0/1] ubifs: ubifs to export filesystem error counters
In-Reply-To: <20210907214034.11676-1-schaecsn@gmx.net> (message from Stefan
 Schaeckeler on Tue, 7 Sep 2021 14:40:33 -0700)
References: <20210907214034.11676-1-schaecsn@gmx.net>
Message-ID: <20210920024824.9E053899858@corona.crabdance.com>

Hello mtd/ubifs,

I just want to check back on what you think about having a sysfs for ubifs and
starting with these three callbacks

/sys/fs/ubifs/ubiX_Y/errors_magic
/sys/fs/ubifs/ubiX_Y/errors_node
/sys/fs/ubifs/ubiX_Y/errors_crc

 Stefan

> From: Stefan Schaeckeler <schaecsn at gmx.net>
>
> Not all ubifs filesystem errors are propagated to userspace, here is one
> that is not propagaged to ls:
>
> [node0_RP0_CPU0:~]$ls -la /mnt/mtd0
> [562009.111309] UBIFS error (ubi0:0 pid 21670): ubifs_check_node [ubifs]: bad CRC: calculated 0x1b205ba3, read 0xb6eff0d9
> [562009.123231] UBIFS error (ubi0:0 pid 21670): ubifs_check_node [ubifs]: bad node at LEB 112:29768
> [562009.133042] magic          0x6101831
> [562009.137312] crc            0xb6eff0d9
> [562009.141678] node_type      2 (direntry node)
> [562009.146706] group_type     1 (in node group)
> [562009.151734] sqnum          334966
> [562009.155709] len            82
> [562009.159304] key            (1, direntry, 0xe933a79)
> [562009.164999] inum           546
> [562009.168687] type           0
> [562009.172186] nlen           25
> [562009.175779] name           inventor\xffffffff\xffffffff\xffffffff\xffffffffcal_log_4.txt
> [562009.185308] CPU: 1 PID: 21670 Comm: ls Tainted: G           O    4.8.28-WR9.0.0.20_cgl #1
> [562009.185309] Hardware name: Insyde Harrisonville/Type2 - Board Product Name1, BIOS 00.01.017 10/26/2018
> [562009.185312]  0000000000000286 00000000f877ad2e ffffbb5b8e357c50 ffffffff9b3cfaab
> [562009.185316]  00000000ffffff8b 0000000000007448 ffffbb5b8e357c90 ffffffffc022c0dd
> [562009.185320]  00000000687aa008 0000000000007448 0000000000000070 0000000000000052
> [562009.185324] Call Trace:
> [562009.185332]  [<ffffffff9b3cfaab>] dump_stack+0x63/0x88
> [562009.185345]  [<ffffffffc022c0dd>] ubifs_check_node+0xbd/0x270 [ubifs]
> [562009.185357]  [<ffffffffc022db25>] ubifs_read_node+0x285/0x300 [ubifs]
> [562009.185370]  [<ffffffffc024dfc7>] ubifs_tnc_read_node+0x127/0x1c0 [ubifs]
> [562009.185382]  [<ffffffffc0230115>] ? matches_name+0x45/0xf0 [ubifs]
> [562009.185394]  [<ffffffffc022ed9a>] tnc_read_node_nm+0xfa/0x220 [ubifs]
> [562009.185407]  [<ffffffffc02330a4>] ubifs_tnc_next_ent+0x1f4/0x2a0 [ubifs]
> [562009.185411]  [<ffffffff9b1f405e>] ? filldir+0xce/0x150
> [562009.185422]  [<ffffffffc02244f8>] ubifs_readdir+0x188/0x4d0 [ubifs]
> [562009.185425]  [<ffffffff9b1f3e62>] iterate_dir+0x172/0x190
> [562009.185429]  [<ffffffff9b124e4a>] ? __audit_syscall_entry+0xba/0x100
> [562009.185432]  [<ffffffff9b1f4399>] SyS_getdents+0x99/0x120
> [562009.185434]  [<ffffffff9b1f3f90>] ? fillonedir+0x110/0x110
> [562009.185437]  [<ffffffff9b002b76>] do_syscall_64+0x66/0x180
> [562009.185441]  [<ffffffff9b8b9fce>] entry_SYSCALL_64_after_swapgs+0x58/0xc6
> [562009.185454] UBIFS error (ubi0:0 pid 21670): ubifs_read_node [ubifs]: expected node type 2
> [562009.194705] UBIFS error (ubi0:0 pid 21670): ubifs_readdir [ubifs]: cannot find next direntry, error -117
> total 1080
> drwxr-xr-x. 2 root root   3728 Jul  3 10:36 .
> drwxrwxrwt. 5 root root    120 Jul  3 10:36 ..
> -rw-rw-rw-. 1 root root   5413 May 24 10:59 alarm_0_PM1_remote_log_1.txt
> -rw-rw-rw-. 1 root root      1 Sep 19  2020 alarm_banner.txt
> -rw-rw-rw-. 1 root root  65465 Nov  5  2020 alarm_local_log_29.txt
> -rw-rw-rw-. 1 root root  55441 Dec 18  2020 alarm_local_log_30.txt
> -rw-rw-rw-. 1 root root  64826 Sep 20  2020 alarm_local_log_31.txt
> -rw-rw-rw-. 1 root root  65019 Oct 25  2020 alarm_local_log_32.txt
> -rw-rw-rw-. 1 root root  65880 Oct 26  2020 alarm_local_log_33.txt
> -rw-rw-rw-. 1 root root  66296 Apr 17 10:35 alarm_local_log_34.txt
> -rw-rw-rw-. 1 root test  64734 May  5 20:35 alarm_local_log_35.txt
> -rw-rw-rw-. 1 root root  64924 Jun  4 07:39 alarm_local_log_36.txt
> -rw-rw-rw-. 1 root root  50830 Jul  8 13:21 alarm_local_log_37.txt
> -rw-rw-rw-. 1 root root      1 Sep 21  2020 fpd_banner.txt
> -rw-rw-rw-. 1 root root  28518 Jul  2 23:19 fpd_local_log_2.txt
> -rw-rw-rw-. 1 root root     96 Jul  9 22:37 int_uptime_dashboard.dat
> -rw-rw-rw-. 1 root iosxr   540 Jun  8 00:06 inventory_local_log_1.txt
> -rw-rw-rw-. 1 root iosxr   540 Jul  2 23:26 inventory_local_log_2.txt
> -rw-rw-rw-. 1 root root  79293 Jul  3 10:37 inventory_local_log_3.txt
> -rw-rw-rw-. 1 root test      4 Apr 17 10:33 obfl_data_version.dat
> -rw-rw-rw-. 1 root root    364 Sep 19  2020 temperature_banner.txt
> -rw-rw-rw-. 1 root root  19567 Dec 18  2020 temperature_local_log_3.txt
> -rw-rw-rw-. 1 root root  65607 Sep 20  2020 temperature_local_log_4.txt
> -rw-rw-rw-. 1 root root  66410 Apr 17 10:34 temperature_local_log_5.txt
> -rw-rw-rw-. 1 root test  65607 Jun  1 21:26 temperature_local_log_6.txt
> -rw-rw-rw-. 1 root root  54097 Jul  3 10:37 temperature_local_log_7.txt
> -rw-rw-rw-. 1 root root  65160 Jun 25 23:56 voltage_local_log_10.txt
> -rw-rw-rw-. 1 root root  28236 Jul  3 10:37 voltage_local_log_11.txt
> [node0_RP0_CPU0:~]$echo $?
> 0
>
> A direntry node got corrupted. The filename inventory_local_log_4.txt got
> corrupted to inventor\xffffffff\xffffffff\xffffffff\xffffffffcal_log_4.txt
> and is not passed down to ls. ls exits with a clean exit code of 0.
>
> We can't really detect this corruption from user space. This is required to
> take action such as for a fresh start with re-creating the filesystem.
>
> Every access to the mounted filesystem results in a kernel backtrace. This
> trashes the dmesg buffer and the systemd journal over time.
>
>
> This patch introduces a sysfs filesystem for ubifs. The first three sysfs
> nodes are error counters:
>
>  /sys/fs/ubifs/ubiX_Y/errors_magic
>  /sys/fs/ubifs/ubiX_Y/errors_node
>  /sys/fs/ubifs/ubiX_Y/errors_crc
>
> This allows userspace to notice filesystem corruption. Over time, more
> sysfs nodes can be added.
>
> Stefan Schaeckeler (1):
>   ubifs: ubifs to export filesystem error counters
>
>  fs/ubifs/Makefile |   2 +-
>  fs/ubifs/io.c     |   6 ++
>  fs/ubifs/super.c  |  17 ++++-
>  fs/ubifs/sysfs.c  | 187 ++++++++++++++++++++++++++++++++++++++++++++++
>  fs/ubifs/sysfs.h  |  39 ++++++++++
>  fs/ubifs/ubifs.h  |  11 +++
>  6 files changed, 260 insertions(+), 2 deletions(-)
>  create mode 100644 fs/ubifs/sysfs.c
>  create mode 100644 fs/ubifs/sysfs.h
>
> --
> 2.32.0


From kernel at kempniu.pl  Mon Sep 20 00:02:21 2021
From: kernel at kempniu.pl (=?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?=)
Date: Mon, 20 Sep 2021 09:02:21 +0200
Subject: [PATCH] mtd: add MEMREAD ioctl
Message-ID: <20210920070221.10173-1-kernel@kempniu.pl>

User-space applications making use of MTD devices via /dev/mtd*
character devices currently have limited capabilities for reading data:

  - only deprecated methods of accessing OOB layout information exist,

  - there is no way to explicitly specify MTD operation mode to use; it
    is auto-selected based on the MTD file mode (MTD_FILE_MODE_*) set
    for the character device; in particular, this prevents using
    MTD_OPS_AUTO_OOB for reads,

  - all existing user-space interfaces which cause mtd_read() or
    mtd_read_oob() to be called (via mtdchar_read() and
    mtdchar_read_oob(), respectively) return success even when those
    functions return -EUCLEAN or -EBADMSG; this renders user-space
    applications using these interfaces unaware of any corrected
    bitflips or uncorrectable ECC errors detected during reads.

Note that the existing MEMWRITE ioctl allows the MTD operation mode to
be explicitly set, allowing user-space applications to write page data
and OOB data without requiring them to know anything about the OOB
layout of the MTD device they are writing to (MTD_OPS_AUTO_OOB).  Also,
the MEMWRITE ioctl does not mangle the return value of mtd_write_oob().

Add a new ioctl, MEMREAD, which addresses the above issues.  It is
intended to be a read-side counterpart of the existing MEMWRITE ioctl.

Update include/uapi/mtd/mtd-abi.h accordingly.

Signed-off-by: Micha? K?pie? <kernel at kempniu.pl>
---
This patch is a shameless calque^W^W^Wheavily inspired by MEMWRITE code,
so quite a lot of copy-pasting happened.  I guess it is somewhat
expected when adding a read-side counterpart of existing code which
takes care of writes, but please excuse me if I went too far.

Note that "scripts/checkpatch.pl --strict" returns two alignment
warnings for this patch.  Given that existing code triggers the same
warnings, I assumed that local consistency trumps checkpatch.pl's
complaints.

 drivers/mtd/mtdchar.c      | 60 ++++++++++++++++++++++++++++++++++++++
 include/uapi/mtd/mtd-abi.h | 43 +++++++++++++++++++++++----
 2 files changed, 98 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 155e991d9d75..92e0024bdcf7 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -621,6 +621,58 @@ static int mtdchar_write_ioctl(struct mtd_info *mtd,
 	return ret;
 }
 
+static int mtdchar_read_ioctl(struct mtd_info *mtd,
+		struct mtd_read_req __user *argp)
+{
+	struct mtd_info *master = mtd_get_master(mtd);
+	struct mtd_read_req req;
+	struct mtd_oob_ops ops = {};
+	void __user *usr_data, *usr_oob;
+	int ret;
+
+	if (copy_from_user(&req, argp, sizeof(req)))
+		return -EFAULT;
+
+	usr_data = (void __user *)(uintptr_t)req.usr_data;
+	usr_oob = (void __user *)(uintptr_t)req.usr_oob;
+
+	if (!master->_read_oob)
+		return -EOPNOTSUPP;
+	ops.mode = req.mode;
+	ops.len = (size_t)req.len;
+	ops.ooblen = (size_t)req.ooblen;
+	ops.ooboffs = 0;
+
+	if (usr_data) {
+		ops.datbuf = kmalloc(ops.len, GFP_KERNEL);
+		if (IS_ERR(ops.datbuf))
+			return PTR_ERR(ops.datbuf);
+	} else {
+		ops.datbuf = NULL;
+	}
+
+	if (usr_oob) {
+		ops.oobbuf = kmalloc(ops.ooblen, GFP_KERNEL);
+		if (IS_ERR(ops.oobbuf)) {
+			kfree(ops.datbuf);
+			return PTR_ERR(ops.oobbuf);
+		}
+	} else {
+		ops.oobbuf = NULL;
+	}
+
+	ret = mtd_read_oob(mtd, (loff_t)req.start, &ops);
+
+	if (copy_to_user(usr_data, ops.datbuf, ops.retlen) ||
+	    copy_to_user(usr_oob, ops.oobbuf, ops.oobretlen))
+		ret = -EFAULT;
+
+	kfree(ops.datbuf);
+	kfree(ops.oobbuf);
+
+	return ret;
+}
+
 static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 {
 	struct mtd_file_info *mfi = file->private_data;
@@ -643,6 +695,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 	case MEMGETINFO:
 	case MEMREADOOB:
 	case MEMREADOOB64:
+	case MEMREAD:
 	case MEMISLOCKED:
 	case MEMGETOOBSEL:
 	case MEMGETBADBLOCK:
@@ -817,6 +870,13 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
 		break;
 	}
 
+	case MEMREAD:
+	{
+		ret = mtdchar_read_ioctl(mtd,
+		      (struct mtd_read_req __user *)arg);
+		break;
+	}
+
 	case MEMLOCK:
 	{
 		struct erase_info_user einfo;
diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
index b869990c2db2..337e6e597fad 100644
--- a/include/uapi/mtd/mtd-abi.h
+++ b/include/uapi/mtd/mtd-abi.h
@@ -55,9 +55,9 @@ struct mtd_oob_buf64 {
  * @MTD_OPS_RAW:	data are transferred as-is, with no error correction;
  *			this mode implies %MTD_OPS_PLACE_OOB
  *
- * These modes can be passed to ioctl(MEMWRITE) and are also used internally.
- * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs.
- * %MTD_FILE_MODE_RAW.
+ * These modes can be passed to ioctl(MEMWRITE) and ioctl(MEMREAD); they are
+ * also used internally. See notes on "MTD file modes" for discussion on
+ * %MTD_OPS_RAW vs. %MTD_FILE_MODE_RAW.
  */
 enum {
 	MTD_OPS_PLACE_OOB = 0,
@@ -91,6 +91,32 @@ struct mtd_write_req {
 	__u8 padding[7];
 };
 
+/**
+ * struct mtd_read_req - data structure for requesting a read operation
+ *
+ * @start:	start address
+ * @len:	length of data buffer
+ * @ooblen:	length of OOB buffer
+ * @usr_data:	user-provided data buffer
+ * @usr_oob:	user-provided OOB buffer
+ * @mode:	MTD mode (see "MTD operation modes")
+ * @padding:	reserved, must be set to 0
+ *
+ * This structure supports ioctl(MEMREAD) operations, allowing data and/or OOB
+ * reads in various modes. To read from OOB-only, set @usr_data == NULL, and to
+ * read data-only, set @usr_oob == NULL. However, setting both @usr_data and
+ * @usr_oob to NULL is not allowed.
+ */
+struct mtd_read_req {
+	__u64 start;
+	__u64 len;
+	__u64 ooblen;
+	__u64 usr_data;
+	__u64 usr_oob;
+	__u8 mode;
+	__u8 padding[7];
+};
+
 #define MTD_ABSENT		0
 #define MTD_RAM			1
 #define MTD_ROM			2
@@ -207,6 +233,12 @@ struct otp_info {
 #define MEMWRITE		_IOWR('M', 24, struct mtd_write_req)
 /* Erase a given range of user data (must be in mode %MTD_FILE_MODE_OTP_USER) */
 #define OTPERASE		_IOW('M', 25, struct otp_info)
+/*
+ * Most generic read interface; can read in-band and/or out-of-band in various
+ * modes (see "struct mtd_read_req"). This ioctl is not supported for flashes
+ * without OOB, e.g., NOR flash.
+ */
+#define MEMREAD			_IOWR('M', 26, struct mtd_read_req)
 
 /*
  * Obsolete legacy interface. Keep it in order not to break userspace
@@ -270,8 +302,9 @@ struct mtd_ecc_stats {
  * Note: %MTD_FILE_MODE_RAW provides the same functionality as %MTD_OPS_RAW -
  * raw access to the flash, without error correction or autoplacement schemes.
  * Wherever possible, the MTD_OPS_* mode will override the MTD_FILE_MODE_* mode
- * (e.g., when using ioctl(MEMWRITE)), but in some cases, the MTD_FILE_MODE is
- * used out of necessity (e.g., `write()', ioctl(MEMWRITEOOB64)).
+ * (e.g., when using ioctl(MEMWRITE) or ioctl(MEMREAD)), but in some cases, the
+ * MTD_FILE_MODE is used out of necessity (e.g., `write()',
+ * ioctl(MEMWRITEOOB64)).
  */
 enum mtd_file_modes {
 	MTD_FILE_MODE_NORMAL = MTD_OTP_OFF,
-- 
2.33.0



From ada at thorsis.com  Mon Sep 20 00:05:55 2021
From: ada at thorsis.com (Alexander Dahl)
Date: Mon, 20 Sep 2021 09:05:55 +0200
Subject: [PATCH] ubifs: Fix spelling mistakes
Message-ID: <20210920070555.6474-1-ada@thorsis.com>

Found with `codespell -i 3 -w fs/ubifs/**` and proof reading that parts.

Signed-off-by: Alexander Dahl <ada at thorsis.com>
---
 fs/ubifs/dir.c    | 4 ++--
 fs/ubifs/replay.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 7c61d0ec0159..dbe72f664abf 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -1207,7 +1207,7 @@ static int ubifs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
  * @inode1: first inode
  * @inode2: second inode
  * @inode3: third inode
- * @inode4: fouth inode
+ * @inode4: fourth inode
  *
  * This function is used for 'ubifs_rename()' and @inode1 may be the same as
  * @inode2 whereas @inode3 and @inode4 may be %NULL.
@@ -1233,7 +1233,7 @@ static void lock_4_inodes(struct inode *inode1, struct inode *inode2,
  * @inode1: first inode
  * @inode2: second inode
  * @inode3: third inode
- * @inode4: fouth inode
+ * @inode4: fourth inode
  */
 static void unlock_4_inodes(struct inode *inode1, struct inode *inode2,
 			    struct inode *inode3, struct inode *inode4)
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 5260d3e531bb..4211e4456b1e 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -106,7 +106,7 @@ static int set_bud_lprops(struct ubifs_info *c, struct bud_entry *b)
 		 * property values should be @lp->free == @c->leb_size and
 		 * @lp->dirty == 0, but that is not the case. The reason is that
 		 * the LEB had been garbage collected before it became the bud,
-		 * and there was not commit inbetween. The garbage collector
+		 * and there was no commit in between. The garbage collector
 		 * resets the free and dirty space without recording it
 		 * anywhere except lprops, so if there was no commit then
 		 * lprops does not have that information.

base-commit: e4e737bb5c170df6135a127739a9e6148ee3da82
-- 
2.30.2



From sean at geanix.com  Mon Sep 20 00:48:19 2021
From: sean at geanix.com (Sean Nyekjaer)
Date: Mon, 20 Sep 2021 09:48:19 +0200
Subject: [PATCH] mtd: ubi: io: add retries mtd_write
In-Reply-To: <20210901085637.210572-1-sean@geanix.com>
References: <20210901085637.210572-1-sean@geanix.com>
Message-ID: <20210920074819.jduvfemhztrioddx@skn-laptop>

On Wed, Sep 01, 2021 at 10:56:37AM +0200, Sean Nyekjaer wrote:
> Fix "Device or resource busy" when resuming from suspend. Sometimes ubi
> tries to call mtd_write before the rawnand is resumed.
> 
> So add 3 retries to the mtd_write call:
> PM: suspend devices took 0.030 seconds
> ubi0 warning: ubi_io_write: error -16 while writing 4096 bytes to PEB 1762:94208, written 0 bytes
> Disabling non-boot CPUs ...
> ubi0 warning: ubi_io_write: error -16 while writing 4096 bytes to PEB 1762:94208, written 0 bytes
> ubi0 warning: ubi_io_write: error -16 while writing 4096 bytes to PEB 1762:94208, written 0 bytes
> PM: resume devices took 0.110 seconds
> OOM killer enabled.
> Restarting tasks ... done.
> PM: suspend exit
> 
> Signed-off-by: Sean Nyekjaer <sean at geanix.com>
> ---
> 
> Some explanation/discussion here:
> http://lists.infradead.org/pipermail/linux-mtd/2021-July/087390.html
> 

This is still an issue... Anyway to block ubi from accessing a suspended
rawnand?

Richard do you have an idea to solve this?

/Sean


From p.yadav at ti.com  Mon Sep 20 04:26:27 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Mon, 20 Sep 2021 16:56:27 +0530
Subject: [PATCH] mtd: spi-nor: Add support for ZB25VQ128
In-Reply-To: <20210918072256.3505379-1-daniel@0x0f.com>
References: <20210918072256.3505379-1-daniel@0x0f.com>
Message-ID: <20210920112625.fnqayim5mg5iggag@ti.com>

On 18/09/21 04:22PM, Daniel Palmer wrote:
> Add support for the ZBIT ZB25VQ128 128MBit SPI NOR
> flash.
> 
> Link: http://www.cipatelje.eu/pdf/ZB25VQ128.pdf
> Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
> ---
>  drivers/mtd/spi-nor/Makefile |  1 +
>  drivers/mtd/spi-nor/core.c   |  1 +
>  drivers/mtd/spi-nor/core.h   |  1 +
>  drivers/mtd/spi-nor/zbit.c   | 21 +++++++++++++++++++++
>  4 files changed, 24 insertions(+)
>  create mode 100644 drivers/mtd/spi-nor/zbit.c
> 
> diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
> index 6b904e439372..a6f3646824cb 100644
> --- a/drivers/mtd/spi-nor/Makefile
> +++ b/drivers/mtd/spi-nor/Makefile
> @@ -17,6 +17,7 @@ spi-nor-objs			+= sst.o
>  spi-nor-objs			+= winbond.o
>  spi-nor-objs			+= xilinx.o
>  spi-nor-objs			+= xmc.o
> +spi-nor-objs			+= zbit.o
>  obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
>  
>  obj-$(CONFIG_MTD_SPI_NOR)	+= controllers/
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index cc08bd707378..75f6ac9485b9 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -1846,6 +1846,7 @@ static const struct spi_nor_manufacturer *manufacturers[] = {
>  	&spi_nor_winbond,
>  	&spi_nor_xilinx,
>  	&spi_nor_xmc,
> +	&spi_nor_zbit,
>  };
>  
>  static const struct flash_info *
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index 3348e1dd1445..ad3b34a3b80f 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -489,6 +489,7 @@ extern const struct spi_nor_manufacturer spi_nor_sst;
>  extern const struct spi_nor_manufacturer spi_nor_winbond;
>  extern const struct spi_nor_manufacturer spi_nor_xilinx;
>  extern const struct spi_nor_manufacturer spi_nor_xmc;
> +extern const struct spi_nor_manufacturer spi_nor_zbit;
>  
>  extern const struct attribute_group *spi_nor_sysfs_groups[];
>  
> diff --git a/drivers/mtd/spi-nor/zbit.c b/drivers/mtd/spi-nor/zbit.c
> new file mode 100644
> index 000000000000..d240dd65d249
> --- /dev/null
> +++ b/drivers/mtd/spi-nor/zbit.c
> @@ -0,0 +1,21 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2021, Daniel Palmer<daniel at thingy.jp>
> + */
> +
> +#include <linux/mtd/spi-nor.h>
> +
> +#include "core.h"
> +
> +static const struct flash_info zbit_parts[] = {
> +	/* zbit */
> +	{ "zb25vq128", INFO(0x5e4018, 0, 64 * 1024, 256,

Zbit should be in bank 10, so it should be preceeded by 9 0x7f bytes, 
correct? I don't see any logic to handle that in SPI NOR currently so I 
assume this manufacturer does not implement the continuation codes.

In that case, it should go to the manufacturer collisions driver 
proposed here [0].

[0] https://patchwork.ozlabs.org/project/linux-mtd/patch/20210727045222.905056-6-tudor.ambarus at microchip.com/

> +			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
> +			    SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
> +};
> +
> +const struct spi_nor_manufacturer spi_nor_zbit = {
> +	.name = "zbit",
> +	.parts = zbit_parts,
> +	.nparts = ARRAY_SIZE(zbit_parts),
> +};
> -- 
> 2.33.0
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From pan at semihalf.com  Mon Sep 20 05:41:38 2021
From: pan at semihalf.com (=?UTF-8?q?Pawe=C5=82=20Anikiel?=)
Date: Mon, 20 Sep 2021 14:41:38 +0200
Subject: [PATCH 0/3] Add support for the Mercury+ AA1 module
Message-ID: <20210920124141.1166544-1-pan@semihalf.com>

The following patches add support for the Mercury+ AA1 with an
Arria 10 SoCFPGA, namely a device tree, and a fix regarding the
Arria 10 reset manager driver.

Pawe? Anikiel (3):
  dt-bindings: mtd: spi-nor: add n25q00 schema
  dts: socfpga: Add Mercury+ AA1 devicetree
  reset: socfpga: add empty driver allowing consumers to probe

 .../bindings/mtd/jedec,spi-nor.yaml           |   2 +-
 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/socfpga_arria10_mercury_aa1.dts  | 127 ++++++++++++++++++
 drivers/reset/reset-socfpga.c                 |  26 ++++
 4 files changed, 155 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts

-- 
2.25.1



From pan at semihalf.com  Mon Sep 20 05:41:39 2021
From: pan at semihalf.com (=?UTF-8?q?Pawe=C5=82=20Anikiel?=)
Date: Mon, 20 Sep 2021 14:41:39 +0200
Subject: [PATCH 1/3] dt-bindings: mtd: spi-nor: add n25q00 schema
In-Reply-To: <20210920124141.1166544-1-pan@semihalf.com>
References: <20210920124141.1166544-1-pan@semihalf.com>
Message-ID: <20210920124141.1166544-2-pan@semihalf.com>

Add schema for the n25q00 NOR flash memory.

Signed-off-by: Pawe? Anikiel <pan at semihalf.com>
---
 Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
index ed590d7c6e37..efb3c5e05c5a 100644
--- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
+++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
@@ -18,7 +18,7 @@ properties:
       - items:
           - pattern: "^((((micron|spansion|st),)?\
               (m25p(40|80|16|32|64|128)|\
-              n25q(32b|064|128a11|128a13|256a|512a|164k)))|\
+              n25q(00|32b|064|128a11|128a13|256a|512a|164k)))|\
               atmel,at25df(321a|641|081a)|\
               everspin,mr25h(10|40|128|256)|\
               (mxicy|macronix),mx25l(4005a|1606e|6405d|8005|12805d|25635e)|\
-- 
2.25.1



From pan at semihalf.com  Mon Sep 20 05:41:40 2021
From: pan at semihalf.com (=?UTF-8?q?Pawe=C5=82=20Anikiel?=)
Date: Mon, 20 Sep 2021 14:41:40 +0200
Subject: [PATCH 2/3] dts: socfpga: Add Mercury+ AA1 devicetree
In-Reply-To: <20210920124141.1166544-1-pan@semihalf.com>
References: <20210920124141.1166544-1-pan@semihalf.com>
Message-ID: <20210920124141.1166544-3-pan@semihalf.com>

Add support for the Mercury+ AA1 module for Arria 10 SoC FPGA.

Signed-off-by: Pawe? Anikiel <pan at semihalf.com>
Signed-off-by: Joanna Brozek <jbrozek at antmicro.com>
Signed-off-by: Mariusz Glebocki <mglebocki at antmicro.com>
Signed-off-by: Tomasz Gorochowik <tgorochowik at antmicro.com>
Signed-off-by: Maciej Mikunda <mmikunda at antmicro.com>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/socfpga_arria10_mercury_aa1.dts  | 127 ++++++++++++++++++
 2 files changed, 128 insertions(+)
 create mode 100644 arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 7e0934180724..0a7809eb3795 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1078,6 +1078,7 @@ dtb-$(CONFIG_ARCH_INTEL_SOCFPGA) += \
 	socfpga_arria10_socdk_nand.dtb \
 	socfpga_arria10_socdk_qspi.dtb \
 	socfpga_arria10_socdk_sdmmc.dtb \
+	socfpga_arria10_mercury_aa1.dtb \
 	socfpga_cyclone5_chameleon96.dtb \
 	socfpga_cyclone5_mcvevk.dtb \
 	socfpga_cyclone5_socdk.dtb \
diff --git a/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts b/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts
new file mode 100644
index 000000000000..c13f16afa72f
--- /dev/null
+++ b/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "socfpga_arria10.dtsi"
+
+/ {
+
+	model = "Enclustra Mercury AA1";
+	compatible = "altr,socfpga-arria10", "altr,socfpga";
+
+	aliases {
+		ethernet0 = &gmac0;
+		serial1 = &uart1;
+	};
+
+	memory {
+		name = "memory";
+		device_type = "memory";
+		reg = <0x0 0x80000000>; /* 2GB */
+	};
+
+	chosen {
+		stdout-path = "serial1:115200n8";
+	};
+};
+
+&osc1 {
+	clock-frequency = <33330000>;
+};
+
+&usb0 {
+	status = "okay";
+	dr_mode = "host";
+};
+
+/* Following mappings are taken from arria10 socdk dts */
+&mmc {
+	status = "okay";
+	cap-sd-highspeed;
+	broken-cd;
+	bus-width = <4>;
+};
+
+&eccmgr {
+	sdmmca-ecc at ff8c2c00 {
+		compatible = "altr,socfpga-sdmmc-ecc";
+		reg = <0xff8c2c00 0x400>;
+		altr,ecc-parent = <&mmc>;
+		interrupts = <15 IRQ_TYPE_LEVEL_HIGH>,
+			     <47 IRQ_TYPE_LEVEL_HIGH>,
+			     <16 IRQ_TYPE_LEVEL_HIGH>,
+			     <48 IRQ_TYPE_LEVEL_HIGH>;
+	};
+};
+
+&gmac0 {
+	phy-mode = "rgmii";
+	phy-addr = <0xffffffff>; /* probe for phy addr */
+
+	max-frame-size = <3800>;
+	status = "okay";
+
+	phy-handle = <&phy3>;
+
+	mdio0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,dwmac-mdio";
+		phy3: ethernet-phy at 3 {
+			txd0-skew-ps = <0>; /* -420ps */
+			txd1-skew-ps = <0>; /* -420ps */
+			txd2-skew-ps = <0>; /* -420ps */
+			txd3-skew-ps = <0>; /* -420ps */
+			rxd0-skew-ps = <420>; /* 0ps */
+			rxd1-skew-ps = <420>; /* 0ps */
+			rxd2-skew-ps = <420>; /* 0ps */
+			rxd3-skew-ps = <420>; /* 0ps */
+			txen-skew-ps = <0>; /* -420ps */
+			txc-skew-ps = <1860>; /* 960ps */
+			rxdv-skew-ps = <420>; /* 0ps */
+			rxc-skew-ps = <1680>; /* 780ps */
+			reg = <3>;
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+	isl12022: isl12022 at 6f {
+		status = "okay";
+		compatible = "isil,isl12022";
+		reg = <0x6f>;
+	};
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&qspi {
+	status = "disabled";
+
+	flash0: n25q00 at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "n25q00";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+		cdns,page-size = <256>;
+		cdns,block-size = <16>;
+		m25p,fast-read;
+		cdns,read-delay = <4>;
+		cdns,tshsl-ns = <200>;
+		cdns,tsd2d-ns = <255>;
+		cdns,tchsh-ns = <20>;
+		cdns,tslch-ns = <20>;
+
+		part0: qspi-boot at 0 {
+			label = "Flash 0 Raw Data";
+			reg = <0x0 0x01340000>;
+		};
+		part1: qspi-rootfs at 1320000 {
+			label = "Flash 1 jffs2 Filesystem";
+			reg = <0x01340000 0x2cc0000>;
+		};
+	};
+};
-- 
2.25.1



From pan at semihalf.com  Mon Sep 20 05:41:41 2021
From: pan at semihalf.com (=?UTF-8?q?Pawe=C5=82=20Anikiel?=)
Date: Mon, 20 Sep 2021 14:41:41 +0200
Subject: [PATCH 3/3] reset: socfpga: add empty driver allowing consumers to
 probe
In-Reply-To: <20210920124141.1166544-1-pan@semihalf.com>
References: <20210920124141.1166544-1-pan@semihalf.com>
Message-ID: <20210920124141.1166544-4-pan@semihalf.com>

The early reset driver doesn't ever probe, which causes consuming
devices to be unable to probe. Add an empty driver to set this device
as available, allowing consumers to probe.

Signed-off-by: Pawe? Anikiel <pan at semihalf.com>
---
 drivers/reset/reset-socfpga.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c
index 2a72f861f798..8c6492e5693c 100644
--- a/drivers/reset/reset-socfpga.c
+++ b/drivers/reset/reset-socfpga.c
@@ -92,3 +92,29 @@ void __init socfpga_reset_init(void)
 	for_each_matching_node(np, socfpga_early_reset_dt_ids)
 		a10_reset_init(np);
 }
+
+/*
+ * The early driver is problematic, because it doesn't register
+ * itself as a driver. This causes certain device links to prevent
+ * consumer devices from probing. The hacky solution is to register
+ * an empty driver, whose only job is to attach itself to the reset
+ * manager and call probe.
+ */
+static const struct of_device_id socfpga_reset_dt_ids[] = {
+	{ .compatible = "altr,rst-mgr", },
+	{ /* sentinel */ },
+};
+
+static int reset_simple_probe(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static struct platform_driver reset_socfpga_driver = {
+	.probe	= reset_simple_probe,
+	.driver = {
+		.name		= "socfpga-reset",
+		.of_match_table	= socfpga_reset_dt_ids,
+	},
+};
+builtin_platform_driver(reset_socfpga_driver);
-- 
2.25.1



From krzysztof.kozlowski at canonical.com  Mon Sep 20 06:28:26 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 20 Sep 2021 15:28:26 +0200
Subject: [PATCH v2 1/5] riscv: dts: microchip: drop duplicated nodes
Message-ID: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>

The DTSI file defines soc node and address/size cells, so there is no
point in duplicating it in DTS file.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts b/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts
index b254c60589a1..3b04ef17e8da 100644
--- a/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts
+++ b/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts
@@ -9,8 +9,6 @@
 #define RTCCLK_FREQ		1000000
 
 / {
-	#address-cells = <2>;
-	#size-cells = <2>;
 	model = "Microchip PolarFire-SoC Icicle Kit";
 	compatible = "microchip,mpfs-icicle-kit";
 
@@ -35,9 +33,6 @@ memory at 80000000 {
 		reg = <0x0 0x80000000 0x0 0x40000000>;
 		clocks = <&clkcfg 26>;
 	};
-
-	soc {
-	};
 };
 
 &serial0 {
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Sep 20 06:28:27 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 20 Sep 2021 15:28:27 +0200
Subject: [PATCH v2 2/5] riscv: dts: microchip: fix board compatible
In-Reply-To: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>
References: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210920132830.152802-2-krzysztof.kozlowski@canonical.com>

According to bindings, the compatible must include microchip,mpfs.  This
fixes dtbs_check warning:

  arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dt.yaml: /: compatible: ['microchip,mpfs-icicle-kit'] is too short

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes since v1:
1. Use microchip,mpfs for microchip-mpfs.dtsi, suggested by Geert.
---
 arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts | 2 +-
 arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts b/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts
index 3b04ef17e8da..07f1f3cab686 100644
--- a/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts
+++ b/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts
@@ -10,7 +10,7 @@
 
 / {
 	model = "Microchip PolarFire-SoC Icicle Kit";
-	compatible = "microchip,mpfs-icicle-kit";
+	compatible = "microchip,mpfs-icicle-kit", "microchip,mpfs";
 
 	aliases {
 		ethernet0 = &emac1;
diff --git a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
index 93730afe6c58..5084b93188f0 100644
--- a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
+++ b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
@@ -7,7 +7,7 @@ / {
 	#address-cells = <2>;
 	#size-cells = <2>;
 	model = "Microchip MPFS Icicle Kit";
-	compatible = "microchip,mpfs-icicle-kit";
+	compatible = "microchip,mpfs";
 
 	chosen {
 	};
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Sep 20 06:28:28 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 20 Sep 2021 15:28:28 +0200
Subject: [PATCH v2 3/5] riscv: dts: microchip: drop duplicated MMC/SDHC node
In-Reply-To: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>
References: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210920132830.152802-3-krzysztof.kozlowski@canonical.com>

Devicetree source is a description of hardware and hardware has only one
block @20008000 which can be configured either as eMMC or SDHC.  Having
two node for different modes is an obscure, unusual and confusing way to
configure it.  Instead the board file is supposed to customize the block
to its needs, e.g. to SDHC mode.

This fixes dtbs_check warning:
  arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dt.yaml: sdhc at 20008000: $nodename:0: 'sdhc at 20008000' does not match '^mmc(@.*)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes since v1:
1. Move also bus-width, suggested by Geert.
---
 .../microchip/microchip-mpfs-icicle-kit.dts   | 11 +++++++-
 .../boot/dts/microchip/microchip-mpfs.dtsi    | 28 +------------------
 2 files changed, 11 insertions(+), 28 deletions(-)

diff --git a/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts b/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts
index 07f1f3cab686..fc1e5869df1b 100644
--- a/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts
+++ b/arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dts
@@ -51,8 +51,17 @@ &serial3 {
 	status = "okay";
 };
 
-&sdcard {
+&mmc {
 	status = "okay";
+
+	bus-width = <4>;
+	disable-wp;
+	cap-sd-highspeed;
+	card-detect-delay = <200>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
 };
 
 &emac0 {
diff --git a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
index 5084b93188f0..83bc14860960 100644
--- a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
+++ b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
@@ -262,39 +262,13 @@ serial3: serial at 20104000 {
 			status = "disabled";
 		};
 
-		emmc: mmc at 20008000 {
-			compatible = "cdns,sd4hc";
-			reg = <0x0 0x20008000 0x0 0x1000>;
-			interrupt-parent = <&plic>;
-			interrupts = <88 89>;
-			pinctrl-names = "default";
-			clocks = <&clkcfg 6>;
-			bus-width = <4>;
-			cap-mmc-highspeed;
-			mmc-ddr-3_3v;
-			max-frequency = <200000000>;
-			non-removable;
-			no-sd;
-			no-sdio;
-			voltage-ranges = <3300 3300>;
-			status = "disabled";
-		};
-
-		sdcard: sdhc at 20008000 {
+		mmc: mmc at 20008000 {
 			compatible = "cdns,sd4hc";
 			reg = <0x0 0x20008000 0x0 0x1000>;
 			interrupt-parent = <&plic>;
 			interrupts = <88>;
 			pinctrl-names = "default";
 			clocks = <&clkcfg 6>;
-			bus-width = <4>;
-			disable-wp;
-			cap-sd-highspeed;
-			card-detect-delay = <200>;
-			sd-uhs-sdr12;
-			sd-uhs-sdr25;
-			sd-uhs-sdr50;
-			sd-uhs-sdr104;
 			max-frequency = <200000000>;
 			status = "disabled";
 		};
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Sep 20 06:28:29 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 20 Sep 2021 15:28:29 +0200
Subject: [PATCH v2 4/5] riscv: dts: microchip: drop unused pinctrl-names
In-Reply-To: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>
References: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210920132830.152802-4-krzysztof.kozlowski@canonical.com>

pinctrl-names without pinctrl-0 does not have any sense:

  arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dt.yaml: sdhc at 20008000: 'pinctrl-0' is a dependency of 'pinctrl-names'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Geert Uytterhoeven <geert at linux-m68k.org>

---

Changes since v1:
1. Add review.
---
 Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml | 1 +
 arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi        | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
index ed590d7c6e37..0db64ac7dc33 100644
--- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
+++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
@@ -33,6 +33,7 @@ properties:
       - items:
           - enum:
               - issi,is25lp016d
+              - issi,is25wp256
               - micron,mt25qu02g
               - mxicy,mx25r1635f
               - mxicy,mx25u6435f
diff --git a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
index 83bc14860960..55d86b078c53 100644
--- a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
+++ b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
@@ -267,7 +267,6 @@ mmc: mmc at 20008000 {
 			reg = <0x0 0x20008000 0x0 0x1000>;
 			interrupt-parent = <&plic>;
 			interrupts = <88>;
-			pinctrl-names = "default";
 			clocks = <&clkcfg 6>;
 			max-frequency = <200000000>;
 			status = "disabled";
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Mon Sep 20 06:28:30 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 20 Sep 2021 15:28:30 +0200
Subject: [PATCH v2 5/5] riscv: dts: microchip: use vendor compatible for
 Cadence SD4HC
In-Reply-To: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>
References: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210920132830.152802-5-krzysztof.kozlowski@canonical.com>

Licensed IP blocks should have their own vendor compatible.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes since v1:
1. New patch
---
 arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
index 55d86b078c53..7948c4249de5 100644
--- a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
+++ b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi
@@ -263,7 +263,7 @@ serial3: serial at 20104000 {
 		};
 
 		mmc: mmc at 20008000 {
-			compatible = "cdns,sd4hc";
+			compatible = "microchip,mpfs-sd4hc", "cdns,sd4hc";
 			reg = <0x0 0x20008000 0x0 0x1000>;
 			interrupt-parent = <&plic>;
 			interrupts = <88>;
-- 
2.30.2



From a-nandan at ti.com  Mon Sep 20 07:27:12 2021
From: a-nandan at ti.com (Apurva Nandan)
Date: Mon, 20 Sep 2021 19:57:12 +0530
Subject: [PATCH v2 1/2] dt-bindings: mtd: spi-nand: Convert to DT schema format
In-Reply-To: <20210920142713.129295-1-a-nandan@ti.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
Message-ID: <20210920142713.129295-2-a-nandan@ti.com>

Convert spi-nand.txt binding to YAML format with an added example.

Signed-off-by: Apurva Nandan <a-nandan at ti.com>
---
 .../devicetree/bindings/mtd/spi-nand.txt      |  5 --
 .../devicetree/bindings/mtd/spi-nand.yaml     | 62 +++++++++++++++++++
 2 files changed, 62 insertions(+), 5 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.txt b/Documentation/devicetree/bindings/mtd/spi-nand.txt
deleted file mode 100644
index 8b51f3b6d55c..000000000000
--- a/Documentation/devicetree/bindings/mtd/spi-nand.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-SPI NAND flash
-
-Required properties:
-- compatible: should be "spi-nand"
-- reg: should encode the chip-select line used to access the NAND chip
diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.yaml b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
new file mode 100644
index 000000000000..601beba8d971
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mtd/spi-nand.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPI NAND flash
+
+maintainers:
+  - Apurva Nandan <a-nandan at ti.com>
+
+allOf:
+  - $ref: "mtd.yaml#"
+
+properties:
+  compatible:
+    const: spi-nand
+
+  reg:
+    maxItems: 1
+
+  spi-max-frequency: true
+  spi-rx-bus-width: true
+  spi-tx-bus-width: true
+  rx-sample-delay-ns: true
+
+  '#address-cells': true
+  '#size-cells': true
+
+additionalProperties:
+  type: object
+
+examples:
+  - |
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        flash at 6 {
+            #address-cells = <1>;
+            #size-cells = <1>;
+            compatible = "spi-nand";
+            reg = <0x6>;
+            spi-max-frequency = <42000000>;
+
+            partitions {
+                compatible = "fixed-partitions";
+                #address-cells = <1>;
+                #size-cells = <1>;
+
+                partition at 0 {
+                    label = "boot";
+                    reg = <0 0x200000>;
+                };
+
+                partition at 200000 {
+                    label = "rootfs";
+                    reg = <0x200000 0xce0000>;
+                };
+            };
+        };
+    };
-- 
2.25.1



From a-nandan at ti.com  Mon Sep 20 07:27:11 2021
From: a-nandan at ti.com (Apurva Nandan)
Date: Mon, 20 Sep 2021 19:57:11 +0530
Subject: [PATCH v2 0/2] dt-bindings: mtd: spi-nand: Convert to DT schema
Message-ID: <20210920142713.129295-1-a-nandan@ti.com>

Series to convert spi-nand.txt binding to YAML format and also fix up
snps-dw-apb-ssi for related dt_schema errors.

Changes in v2:
- Fixed dtschema erros in snps-dw-apb-ssi.
- Improved additionalProperties, reg, and compatible fields in
  spi-nand.yaml.

Apurva Nandan (2):
  dt-bindings: mtd: spi-nand: Convert to DT schema format
  dt-bindings: snps,dw-apb-ssi: Use 'flash' node name instead of
    'spi-flash' in example

 .../devicetree/bindings/mtd/spi-nand.txt      |  5 --
 .../devicetree/bindings/mtd/spi-nand.yaml     | 62 +++++++++++++++++++
 .../bindings/spi/snps,dw-apb-ssi.yaml         |  2 +-
 3 files changed, 63 insertions(+), 6 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.yaml

-- 
2.25.1



From a-nandan at ti.com  Mon Sep 20 07:27:13 2021
From: a-nandan at ti.com (Apurva Nandan)
Date: Mon, 20 Sep 2021 19:57:13 +0530
Subject: [PATCH v2 2/2] dt-bindings: snps,
 dw-apb-ssi: Use 'flash' node name instead of 'spi-flash' in example
In-Reply-To: <20210920142713.129295-1-a-nandan@ti.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
Message-ID: <20210920142713.129295-3-a-nandan@ti.com>

Change the nodename in the example with spi-nand from 'spi-flash at 1'
to 'flash at 1' to make the schema uniform with both spi-nand and spi-nor
flashes. jedec,spi-nor.yaml uses 'flash@' nodename for spi-nor flashes,
so make the spi-nand examples in dt-bindings use it too for uniformity.

Signed-off-by: Apurva Nandan <a-nandan at ti.com>
---
 Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
index ca91201a9926..d7e08b03e204 100644
--- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
+++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
@@ -171,7 +171,7 @@ examples:
       cs-gpios = <&gpio0 13 0>,
                  <&gpio0 14 0>;
       rx-sample-delay-ns = <3>;
-      spi-flash at 1 {
+      flash at 1 {
         compatible = "spi-nand";
         reg = <1>;
         rx-sample-delay-ns = <7>;
-- 
2.25.1



From geert at linux-m68k.org  Mon Sep 20 07:32:34 2021
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Mon, 20 Sep 2021 16:32:34 +0200
Subject: [PATCH v2 4/5] riscv: dts: microchip: drop unused pinctrl-names
In-Reply-To: <20210920132830.152802-4-krzysztof.kozlowski@canonical.com>
References: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>
 <20210920132830.152802-4-krzysztof.kozlowski@canonical.com>
Message-ID: <CAMuHMdX5vhihbKrXh4x_VyA2Cc=nR+53g_fZPHsuHVF56rBvMQ@mail.gmail.com>

Hi Krzysztof,

On Mon, Sep 20, 2021 at 3:28 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
> pinctrl-names without pinctrl-0 does not have any sense:
>
>   arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dt.yaml: sdhc at 20008000: 'pinctrl-0' is a dependency of 'pinctrl-names'
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Geert Uytterhoeven <geert at linux-m68k.org>
>
> ---
>
> Changes since v1:
> 1. Add review.

> --- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
> +++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
> @@ -33,6 +33,7 @@ properties:
>        - items:
>            - enum:
>                - issi,is25lp016d
> +              - issi,is25wp256
>                - micron,mt25qu02g
>                - mxicy,mx25r1635f
>                - mxicy,mx25u6435f

This one looks like an accidental addition?

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

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


From broonie at kernel.org  Mon Sep 20 07:44:18 2021
From: broonie at kernel.org (Mark Brown)
Date: Mon, 20 Sep 2021 15:44:18 +0100
Subject: [PATCH v2 2/2] dt-bindings: snps,dw-apb-ssi: Use 'flash' node
 name instead of 'spi-flash' in example
In-Reply-To: <20210920142713.129295-3-a-nandan@ti.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-3-a-nandan@ti.com>
Message-ID: <20210920144418.GI4192@sirena.org.uk>

On Mon, Sep 20, 2021 at 07:57:13PM +0530, Apurva Nandan wrote:
> Change the nodename in the example with spi-nand from 'spi-flash at 1'
> to 'flash at 1' to make the schema uniform with both spi-nand and spi-nor
> flashes. jedec,spi-nor.yaml uses 'flash@' nodename for spi-nor flashes,
> so make the spi-nand examples in dt-bindings use it too for uniformity.

Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
There's no need to resubmit to fix this alone.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210920/d2e3480f/attachment.sig>

From fancer.lancer at gmail.com  Mon Sep 20 07:44:04 2021
From: fancer.lancer at gmail.com (Serge Semin)
Date: Mon, 20 Sep 2021 17:44:04 +0300
Subject: [PATCH v2 2/2] dt-bindings: snps,dw-apb-ssi: Use 'flash' node
 name instead of 'spi-flash' in example
In-Reply-To: <20210920142713.129295-3-a-nandan@ti.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-3-a-nandan@ti.com>
Message-ID: <20210920144404.5vhynfdfukabxgav@mobilestation>

On Mon, Sep 20, 2021 at 07:57:13PM +0530, Apurva Nandan wrote:
> Change the nodename in the example with spi-nand from 'spi-flash at 1'
> to 'flash at 1' to make the schema uniform with both spi-nand and spi-nor
> flashes. jedec,spi-nor.yaml uses 'flash@' nodename for spi-nor flashes,
> so make the spi-nand examples in dt-bindings use it too for uniformity.
> 
> Signed-off-by: Apurva Nandan <a-nandan at ti.com>
> ---
>  Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Seems reasonable.
Reviewed-by: Serge Semin <fancer.lancer at gmail.com>

-Sergey

> 
> diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
> index ca91201a9926..d7e08b03e204 100644
> --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
> +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
> @@ -171,7 +171,7 @@ examples:
>        cs-gpios = <&gpio0 13 0>,
>                   <&gpio0 14 0>;
>        rx-sample-delay-ns = <3>;
> -      spi-flash at 1 {
> +      flash at 1 {
>          compatible = "spi-nand";
>          reg = <1>;
>          rx-sample-delay-ns = <7>;
> -- 
> 2.25.1
> 


From krzysztof.kozlowski at canonical.com  Mon Sep 20 07:54:03 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 20 Sep 2021 16:54:03 +0200
Subject: [PATCH v2 4/5] riscv: dts: microchip: drop unused pinctrl-names
In-Reply-To: <CAMuHMdX5vhihbKrXh4x_VyA2Cc=nR+53g_fZPHsuHVF56rBvMQ@mail.gmail.com>
References: <20210920132830.152802-1-krzysztof.kozlowski@canonical.com>
 <20210920132830.152802-4-krzysztof.kozlowski@canonical.com>
 <CAMuHMdX5vhihbKrXh4x_VyA2Cc=nR+53g_fZPHsuHVF56rBvMQ@mail.gmail.com>
Message-ID: <ef5771df-86fa-524a-8a5c-c519e913330b@canonical.com>

On 20/09/2021 16:32, Geert Uytterhoeven wrote:
> Hi Krzysztof,
> 
> On Mon, Sep 20, 2021 at 3:28 PM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>> pinctrl-names without pinctrl-0 does not have any sense:
>>
>>   arch/riscv/boot/dts/microchip/microchip-mpfs-icicle-kit.dt.yaml: sdhc at 20008000: 'pinctrl-0' is a dependency of 'pinctrl-names'
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> Reviewed-by: Geert Uytterhoeven <geert at linux-m68k.org>
>>
>> ---
>>
>> Changes since v1:
>> 1. Add review.
> 
>> --- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
>> +++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
>> @@ -33,6 +33,7 @@ properties:
>>        - items:
>>            - enum:
>>                - issi,is25lp016d
>> +              - issi,is25wp256
>>                - micron,mt25qu02g
>>                - mxicy,mx25r1635f
>>                - mxicy,mx25u6435f
> 
> This one looks like an accidental addition?

Thanks, I screwed up something during rebase... I'll send a v3.

Best regards,
Krzysztof


From fancer.lancer at gmail.com  Mon Sep 20 08:06:51 2021
From: fancer.lancer at gmail.com (Serge Semin)
Date: Mon, 20 Sep 2021 18:06:51 +0300
Subject: [PATCH v2 1/2] dt-bindings: mtd: spi-nand: Convert to DT schema
 format
In-Reply-To: <20210920142713.129295-2-a-nandan@ti.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-2-a-nandan@ti.com>
Message-ID: <20210920150651.vvdhennblwhdi3jw@mobilestation>

Hello Apurva

On Mon, Sep 20, 2021 at 07:57:12PM +0530, Apurva Nandan wrote:
> Convert spi-nand.txt binding to YAML format with an added example.
> 
> Signed-off-by: Apurva Nandan <a-nandan at ti.com>
> ---
>  .../devicetree/bindings/mtd/spi-nand.txt      |  5 --
>  .../devicetree/bindings/mtd/spi-nand.yaml     | 62 +++++++++++++++++++
>  2 files changed, 62 insertions(+), 5 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.txt
>  create mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.yaml

Thanks for the bindings conversion patch. There are several comments
below. But before addressing them it would be better to also get a
response from Rob.

> 
> diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.txt b/Documentation/devicetree/bindings/mtd/spi-nand.txt
> deleted file mode 100644
> index 8b51f3b6d55c..000000000000
> --- a/Documentation/devicetree/bindings/mtd/spi-nand.txt
> +++ /dev/null
> @@ -1,5 +0,0 @@
> -SPI NAND flash
> -
> -Required properties:
> -- compatible: should be "spi-nand"
> -- reg: should encode the chip-select line used to access the NAND chip
> diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.yaml b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
> new file mode 100644
> index 000000000000..601beba8d971
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
> @@ -0,0 +1,62 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mtd/spi-nand.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: SPI NAND flash
> +
> +maintainers:
> +  - Apurva Nandan <a-nandan at ti.com>
> +
> +allOf:
> +  - $ref: "mtd.yaml#"
> +
> +properties:
> +  compatible:
> +    const: spi-nand
> +
> +  reg:
> +    maxItems: 1
> +

> +  spi-max-frequency: true
> +  spi-rx-bus-width: true
> +  spi-tx-bus-width: true
> +  rx-sample-delay-ns: true

Since it's an SPI-client device there are more than these properties
could be set for it. See the SPI-controller bindings schema:
Documentation/devicetree/bindings/spi/spi-controller.yaml
So there is two possible ways to make it more generic:
1) Detach the spi-client part from the spi-controller.yaml bindings
into a dedicated DT-schema file and refer to that new scheme from
here.
2) Forget about these controller-specific properties and let the
parental SPI-controller bindings parsing them. Of course there must be
at least one of the next properties declared for it to work:
{unevaluatedProperties, additionalProperties}.

It's up to Rob to decided which approach is better though...

> +
> +  '#address-cells': true
> +  '#size-cells': true

Aren't they always equal to 1?

> +
> +additionalProperties:
> +  type: object

I'd suggest to elaborate the way the partition sub-nodes looks
like, for instance, the node names, supported compatible names,
labels, etc.

-Sergey

> +
> +examples:
> +  - |
> +    spi {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        flash at 6 {
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +            compatible = "spi-nand";
> +            reg = <0x6>;
> +            spi-max-frequency = <42000000>;
> +
> +            partitions {
> +                compatible = "fixed-partitions";
> +                #address-cells = <1>;
> +                #size-cells = <1>;
> +
> +                partition at 0 {
> +                    label = "boot";
> +                    reg = <0 0x200000>;
> +                };
> +
> +                partition at 200000 {
> +                    label = "rootfs";
> +                    reg = <0x200000 0xce0000>;
> +                };
> +            };
> +        };
> +    };
> -- 
> 2.25.1
> 


From p.yadav at ti.com  Mon Sep 20 10:36:15 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Mon, 20 Sep 2021 23:06:15 +0530
Subject: [PATCH v2 1/2] dt-bindings: mtd: spi-nand: Convert to DT schema
 format
In-Reply-To: <20210920150651.vvdhennblwhdi3jw@mobilestation>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-2-a-nandan@ti.com>
 <20210920150651.vvdhennblwhdi3jw@mobilestation>
Message-ID: <20210920173613.oqk6lnmipabkt25s@ti.com>

On 20/09/21 06:06PM, Serge Semin wrote:
> Hello Apurva
> 
> On Mon, Sep 20, 2021 at 07:57:12PM +0530, Apurva Nandan wrote:
> > Convert spi-nand.txt binding to YAML format with an added example.
> > 
> > Signed-off-by: Apurva Nandan <a-nandan at ti.com>
> > ---
> >  .../devicetree/bindings/mtd/spi-nand.txt      |  5 --
> >  .../devicetree/bindings/mtd/spi-nand.yaml     | 62 +++++++++++++++++++
> >  2 files changed, 62 insertions(+), 5 deletions(-)
> >  delete mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.txt
> >  create mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.yaml
[...]
> 
> > +  spi-max-frequency: true
> > +  spi-rx-bus-width: true
> > +  spi-tx-bus-width: true
> > +  rx-sample-delay-ns: true
> 
> Since it's an SPI-client device there are more than these properties
> could be set for it. See the SPI-controller bindings schema:
> Documentation/devicetree/bindings/spi/spi-controller.yaml
> So there is two possible ways to make it more generic:
> 1) Detach the spi-client part from the spi-controller.yaml bindings
> into a dedicated DT-schema file and refer to that new scheme from
> here.
> 2) Forget about these controller-specific properties and let the
> parental SPI-controller bindings parsing them. Of course there must be
> at least one of the next properties declared for it to work:
> {unevaluatedProperties, additionalProperties}.

I proposed a patch series [0] to fix this for SPI NOR, which can be used 
here as well. A re-roll is long overdue though. Let me see when I can 
find time to get to it. In the meantime, this should be fine IMO.

[0] https://patchwork.kernel.org/project/spi-devel-general/list/?series=497129&state=%2A&archive=both


-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From robh at kernel.org  Mon Sep 20 12:26:55 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 20 Sep 2021 14:26:55 -0500
Subject: [PATCH v2 1/2] dt-bindings: mtd: spi-nand: Convert to DT schema
 format
In-Reply-To: <20210920142713.129295-2-a-nandan@ti.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-2-a-nandan@ti.com>
Message-ID: <1632166015.061759.586174.nullmailer@robh.at.kernel.org>

On Mon, 20 Sep 2021 19:57:12 +0530, Apurva Nandan wrote:
> Convert spi-nand.txt binding to YAML format with an added example.
> 
> Signed-off-by: Apurva Nandan <a-nandan at ti.com>
> ---
>  .../devicetree/bindings/mtd/spi-nand.txt      |  5 --
>  .../devicetree/bindings/mtd/spi-nand.yaml     | 62 +++++++++++++++++++
>  2 files changed, 62 insertions(+), 5 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.txt
>  create mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.example.dt.yaml: spi-flash at 1: $nodename:0: 'spi-flash at 1' does not match '^flash(@.*)?$'
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/mtd/spi-nand.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1530166

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Mon Sep 20 12:26:55 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 20 Sep 2021 14:26:55 -0500
Subject: [PATCH v2 2/2] dt-bindings: snps,
 dw-apb-ssi: Use 'flash' node name instead of 'spi-flash' in example
In-Reply-To: <20210920142713.129295-3-a-nandan@ti.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-3-a-nandan@ti.com>
Message-ID: <1632166015.080380.586177.nullmailer@robh.at.kernel.org>

On Mon, 20 Sep 2021 19:57:13 +0530, Apurva Nandan wrote:
> Change the nodename in the example with spi-nand from 'spi-flash at 1'
> to 'flash at 1' to make the schema uniform with both spi-nand and spi-nor
> flashes. jedec,spi-nor.yaml uses 'flash@' nodename for spi-nor flashes,
> so make the spi-nand examples in dt-bindings use it too for uniformity.
> 
> Signed-off-by: Apurva Nandan <a-nandan at ti.com>
> ---
>  Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.example.dt.yaml:0:0: /example-0/spi at fff00000/flash at 1: failed to match any schema with compatible: ['spi-nand']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1530168

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From filip at kubicz.engineer  Mon Sep 20 12:33:22 2021
From: filip at kubicz.engineer (Filip Kubicz)
Date: Mon, 20 Sep 2021 21:33:22 +0200
Subject: =?UTF-8?Q?Re:=C2=A0MLC_NAND_support_in_ubifs?=
Message-ID: <17c04b2db3f.11955d8ed102190.1977520078612166881@kubicz.engineer>

Hi All,

I'm bumping up the question about NAND support since it looks like it slipped unnoticed between emails with patches. Does anyone know the answer?

Thank you in advance,
Filip

filip at kubicz.engineer
tel. (+48) 697 088 078


---- On Thu, 09 Sep 2021 18:41:24 +0200 filip at kubicz.engineer  wrote ----

 > Hi! 
 >  
 > I would like to ask about MLC NAND support in UBIFS. 
 >  
 > I was recently bringing up a device with IMX6ULL and raw MLC NAND flash. I have built Linux 5.4 kernel, u-boot and rootfs (using buildroot), flashed them to my device with MLC NAND flash, and learned from dmesg error that MLC is unsupported by ubifs. Support removed in this commit: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b5094b7f135be 
 >  
 > Then I followed the story from Richard and Boris and watched the talk where they explain the issues with MLC, and propose an alternative: https://www.youtube.com/watch?v=9j2pOIiJqYw&ab_channel=TheLinuxFoundation 
 > Alternative available since Linux 5.8: https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.8-NAND-MLC-SLC-Emulate 
 >  
 > My questions: 
 > 1. Is NAND MLC (+ubifs) reliable to use with SLC emulate mode introduced in kernel 5.8? Or should I rather switch to eMMC for this design? SLC NAND is too costly at my required size. 
 >  
 > 2. If the MLC NAND is not supported, can you update these pages: 
 > - http://www.linux-mtd.infradead.org/doc/ubifs.html 
 > - https://www.kernel.org/doc/html/latest/filesystems/ubifs.html 
 > - http://www.linux-mtd.infradead.org/faq/ubifs.html 
 > Each of the documentation pages mention MLC, so you can get an idea that it is supported. But it looks like the MLC NAND flash is not supported by UBIFS. 
 >  
 > Kind regards, 
 > Filip Kubicz 
 >  
 > filip at kubicz.engineer 
 > tel. (+48) 697 088 078 
 >  
 >  
 >  
 > 



From robh at kernel.org  Mon Sep 20 14:16:53 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 20 Sep 2021 16:16:53 -0500
Subject: [PATCH v2 1/2] dt-bindings: mtd: spi-nand: Convert to DT schema
 format
In-Reply-To: <20210920150651.vvdhennblwhdi3jw@mobilestation>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-2-a-nandan@ti.com>
 <20210920150651.vvdhennblwhdi3jw@mobilestation>
Message-ID: <YUj6RUNYDoWA30Ln@robh.at.kernel.org>

On Mon, Sep 20, 2021 at 06:06:51PM +0300, Serge Semin wrote:
> Hello Apurva
> 
> On Mon, Sep 20, 2021 at 07:57:12PM +0530, Apurva Nandan wrote:
> > Convert spi-nand.txt binding to YAML format with an added example.
> > 
> > Signed-off-by: Apurva Nandan <a-nandan at ti.com>
> > ---
> >  .../devicetree/bindings/mtd/spi-nand.txt      |  5 --
> >  .../devicetree/bindings/mtd/spi-nand.yaml     | 62 +++++++++++++++++++
> >  2 files changed, 62 insertions(+), 5 deletions(-)
> >  delete mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.txt
> >  create mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.yaml
> 
> Thanks for the bindings conversion patch. There are several comments
> below. But before addressing them it would be better to also get a
> response from Rob.
> 
> > 
> > diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.txt b/Documentation/devicetree/bindings/mtd/spi-nand.txt
> > deleted file mode 100644
> > index 8b51f3b6d55c..000000000000
> > --- a/Documentation/devicetree/bindings/mtd/spi-nand.txt
> > +++ /dev/null
> > @@ -1,5 +0,0 @@
> > -SPI NAND flash
> > -
> > -Required properties:
> > -- compatible: should be "spi-nand"
> > -- reg: should encode the chip-select line used to access the NAND chip
> > diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.yaml b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
> > new file mode 100644
> > index 000000000000..601beba8d971
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
> > @@ -0,0 +1,62 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/mtd/spi-nand.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: SPI NAND flash
> > +
> > +maintainers:
> > +  - Apurva Nandan <a-nandan at ti.com>
> > +
> > +allOf:
> > +  - $ref: "mtd.yaml#"
> > +
> > +properties:
> > +  compatible:
> > +    const: spi-nand
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> 
> > +  spi-max-frequency: true
> > +  spi-rx-bus-width: true
> > +  spi-tx-bus-width: true
> > +  rx-sample-delay-ns: true
> 
> Since it's an SPI-client device there are more than these properties
> could be set for it. See the SPI-controller bindings schema:
> Documentation/devicetree/bindings/spi/spi-controller.yaml
> So there is two possible ways to make it more generic:
> 1) Detach the spi-client part from the spi-controller.yaml bindings
> into a dedicated DT-schema file and refer to that new scheme from
> here.

Yes, as mentioned there's patches doing this. But the above is fine. 
There's some value in defining here which properties are valid.

> 2) Forget about these controller-specific properties and let the
> parental SPI-controller bindings parsing them. Of course there must be
> at least one of the next properties declared for it to work:
> {unevaluatedProperties, additionalProperties}.
> 
> It's up to Rob to decided which approach is better though...
> 
> > +
> > +  '#address-cells': true
> > +  '#size-cells': true
> 
> Aren't they always equal to 1?

No SPI nand devices >4GB?

> 
> > +
> > +additionalProperties:
> > +  type: object
> 
> I'd suggest to elaborate the way the partition sub-nodes looks
> like, for instance, the node names, supported compatible names,
> labels, etc.

That should probably all be in mtd.yaml. The question here is whether 
partitions are always under a 'partitions' node. Maybe this is new 
enough that only the new way has to be supported. Though if mtd.yaml 
supported both forms, allowing both all the time is okay IMO.

Rob


From robh at kernel.org  Mon Sep 20 14:19:05 2021
From: robh at kernel.org (Rob Herring)
Date: Mon, 20 Sep 2021 16:19:05 -0500
Subject: [PATCH v2 2/2] dt-bindings: snps,dw-apb-ssi: Use 'flash' node
 name instead of 'spi-flash' in example
In-Reply-To: <20210920142713.129295-3-a-nandan@ti.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-3-a-nandan@ti.com>
Message-ID: <YUj6yUBx0xCY9QGj@robh.at.kernel.org>

On Mon, Sep 20, 2021 at 07:57:13PM +0530, Apurva Nandan wrote:
> Change the nodename in the example with spi-nand from 'spi-flash at 1'
> to 'flash at 1' to make the schema uniform with both spi-nand and spi-nor
> flashes. jedec,spi-nor.yaml uses 'flash@' nodename for spi-nor flashes,
> so make the spi-nand examples in dt-bindings use it too for uniformity.
> 
> Signed-off-by: Apurva Nandan <a-nandan at ti.com>
> ---
>  Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Fixes should come first. Maybe Mark can apply this before you respin.

Acked-by: Rob Herring <robh at kernel.org>

> 
> diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
> index ca91201a9926..d7e08b03e204 100644
> --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
> +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
> @@ -171,7 +171,7 @@ examples:
>        cs-gpios = <&gpio0 13 0>,
>                   <&gpio0 14 0>;
>        rx-sample-delay-ns = <3>;
> -      spi-flash at 1 {
> +      flash at 1 {
>          compatible = "spi-nand";
>          reg = <1>;
>          rx-sample-delay-ns = <7>;
> -- 
> 2.25.1
> 
> 


From richard at nod.at  Mon Sep 20 14:57:49 2021
From: richard at nod.at (Richard Weinberger)
Date: Mon, 20 Sep 2021 23:57:49 +0200 (CEST)
Subject: [PATCH 0/1] ubifs: ubifs to export filesystem error counters
In-Reply-To: <20210920024824.9E053899858@corona.crabdance.com>
References: <20210907214034.11676-1-schaecsn@gmx.net>
 <20210920024824.9E053899858@corona.crabdance.com>
Message-ID: <160773399.91203.1632175069460.JavaMail.zimbra@nod.at>

Hi!

----- Urspr?ngliche Mail -----
> Von: "Stefan Schaeckeler" <schaecsn at gmx.net>
> An: "richard" <richard at nod.at>, "linux-mtd" <linux-mtd at lists.infradead.org>, "linux-kernel"
> <linux-kernel at vger.kernel.org>
> Gesendet: Montag, 20. September 2021 04:48:24
> Betreff: Re: [PATCH 0/1] ubifs: ubifs to export filesystem error counters

> Hello mtd/ubifs,
> 
> I just want to check back on what you think about having a sysfs for ubifs and
> starting with these three callbacks
> 
> /sys/fs/ubifs/ubiX_Y/errors_magic
> /sys/fs/ubifs/ubiX_Y/errors_node
> /sys/fs/ubifs/ubiX_Y/errors_crc

I didn't have a chance to review your changes to far but in general I like the idea
if exposing such an interface.
Sorry for being a slow maintainer.

Thanks,
//richard


From ebiggers at kernel.org  Mon Sep 20 20:17:42 2021
From: ebiggers at kernel.org (Eric Biggers)
Date: Mon, 20 Sep 2021 20:17:42 -0700
Subject: [PATCH] fscrypt: remove fscrypt_operations::max_namelen
In-Reply-To: <20210909184513.139281-1-ebiggers@kernel.org>
References: <20210909184513.139281-1-ebiggers@kernel.org>
Message-ID: <YUlO1vmMXRaHHpTK@sol.localdomain>

On Thu, Sep 09, 2021 at 11:45:13AM -0700, Eric Biggers wrote:
> From: Eric Biggers <ebiggers at google.com>
> 
> The max_namelen field is unnecessary, as it is set to 255 (NAME_MAX) on
> all filesystems that support fscrypt (or plan to support fscrypt).  For
> simplicity, just use NAME_MAX directly instead.
> 
> Signed-off-by: Eric Biggers <ebiggers at google.com>
> ---
>  fs/crypto/fname.c       | 3 +--
>  fs/ext4/super.c         | 1 -
>  fs/f2fs/super.c         | 1 -
>  fs/ubifs/crypto.c       | 1 -
>  include/linux/fscrypt.h | 3 ---
>  5 files changed, 1 insertion(+), 8 deletions(-)

Applied to fscrypt.git#master for 5.16.

- Eric


From anders.roxell at linaro.org  Tue Sep 21 05:42:29 2021
From: anders.roxell at linaro.org (Anders Roxell)
Date: Tue, 21 Sep 2021 14:42:29 +0200
Subject: physmap warning on next-20210921
Message-ID: <CADYN=9Kjw_3cDGAvh9=+nNwdYof1kUPKG-SUOP5FsQhZ+gz62Q@mail.gmail.com>

Hi,

When I'm building an allmodconfig kernel (arm64) with
KCONFIG_ALLCONFIG=arch/arm64/configs/defconfig all the bootselftests
turned off also.
I see the following warning.

[   51.296773][    T1] physmap-flash 0.flash: physmap platform flash
device: [mem 0x00000000-0x03ffffff]
[   51.312682][    T1] 0.flash: Found 2 x16 devices at 0x0 in 32-bit
bank. Manufacturer ID 0x000000 Chip ID 0x000000
[   51.319200][    T1] Intel/Sharp Extended Query Table at 0x0031
[   51.325766][    T1] Using buffer write method
[   51.669918][    T1] physmap-flash 0.flash: physmap platform flash
device: [mem 0x04000000-0x07ffffff]
[   51.685287][    T1] 0.flash: Found 2 x16 devices at 0x0 in 32-bit
bank. Manufacturer ID 0x000000 Chip ID 0x000000
[   51.691522][    T1] Intel/Sharp Extended Query Table at 0x0031
[   51.697787][    T1] Using buffer write method
[   51.700958][    T1] Concatenating MTD devices:
[   51.703307][    T1] (0): "0.flash"
[   51.704752][    T1] (1): "0.flash"
[   51.706205][    T1] into device "0.flash"
[   51.946281][    T9] _warn_unseeded_randomness: 3 callbacks suppressed
[   51.946331][    T9] random: get_random_u64 called from
dup_task_struct+0x184/0x340 with crng_init=0
[   51.980825][  T114] kworker/u2:1 (114) used greatest stack depth:
26576 bytes left
[   52.087262][    T1] platform physmap-flash.0: failed to claim
resource 0: [mem 0x08000000-0x07ffffff]
[   52.092697][    T1] Deleting MTD partitions on "0.flash":
[   52.111033][    T1] random: get_random_u32 called from
kobject_release+0x44/0x180 with crng_init=0
[   52.111193][    T1] kobject: 'integrity' (ffff00001019f198):
kobject_release, parent 0000000000000000 (delayed 500)
[   52.151410][    T1] kobject: '31:0' (ffff00000f14b800):
kobject_release, parent 0000000000000000 (delayed 250)
[   52.197408][    T1] kobject: 'holders' (ffff00000f0fc500):
kobject_release, parent ffff00000be10f90 (delayed 750)
[   52.202305][    T1] kobject: 'slaves' (ffff00000f0fd900):
kobject_release, parent ffff00000be10f90 (delayed 750)
[   52.240140][    T1] random: get_random_u32 called from
shuffle_freelist+0x44/0x1c0 with crng_init=0
[   52.476276][    T1] kobject: 'mtd0' (ffff00000f14d008):
kobject_release, parent 0000000000000000 (delayed 1000)
[   52.510094][    T1] kobject: 'mtd0' (ffff00000f1411a0):
kobject_release, parent 0000000000000000 (delayed 500)
[   52.515268][    T1] ------------[ cut here ]------------
[   52.517264][    T1] ODEBUG: free active (active state 0) object
type: timer_list hint: delayed_work_timer_fn+0x0/0x80
[   52.522813][    T1] WARNING: CPU: 0 PID: 1 at
lib/debugobjects.c:505 debug_print_object+0xe8/0x140
[   52.526642][    T1] Modules linked in:
[   52.528416][    T1] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G
        T 5.15.0-rc2-next-20210921 #1
c5f525bba77d859d4ce569d244b0730e944cd9ea
[   52.533761][    T1] Hardware name: linux,dummy-virt (DT)
[   52.536052][    T1] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT
-SSBS BTYPE=--)
[   52.539277][    T1] pc : debug_print_object+0xe8/0x140
[   52.541579][    T1] lr : debug_print_object+0xe8/0x140
[   52.543830][    T1] sp : ffff800016327930
[   52.545641][    T1] x29: ffff800016327930 x28: ffff80001620dc48
x27: 0000000000000000
[   52.549114][    T1] x26: ffff8000102748c0 x25: ffff80001013f780
x24: ffff800011fdc200
[   52.552577][    T1] x23: ffff80001223e740 x22: ffff80001223e1c0
x21: ffff80001223d960
[   52.556073][    T1] x20: ffff80001397ee60 x19: 0000000000000000
x18: 0000000000000000
[   52.559538][    T1] x17: 0000000000000000 x16: 0000000000000000
x15: 6570797420746365
[   52.563021][    T1] x14: 6a626f2029302065 x13: 0000000000041c40
x12: 0000000000041bd8
[   52.566491][    T1] x11: 0000000000000000 x10: 0000000000000000 x9
: 0000000000000000
[   52.569961][    T1] x8 : 0000000000000000 x7 : 0000000000000000 x6
: 0000000000000000
[   52.573445][    T1] x5 : 0000000000000000 x4 : 0000000000000000 x3
: 0000000000000000
[   52.576912][    T1] x2 : 0000000000000000 x1 : 0000000000000000 x0
: 0000000000000000
[   52.580369][    T1] Call trace:
[   52.581845][    T1]  debug_print_object+0xe8/0x140
[   52.583979][    T1]  __debug_check_no_obj_freed+0x11c/0x2c0
[   52.586437][    T1]  debug_check_no_obj_freed+0x30/0xc0
[   52.588729][    T1]  slab_free_freelist_hook+0x154/0x2c0
[   52.591078][    T1]  kfree+0x14c/0x2c0
[   52.592819][    T1]  mtd_concat_destroy+0x3c/0x80
[   52.594918][    T1]  physmap_flash_remove+0x88/0x180
[   52.597134][    T1]  platform_remove+0x3c/0x80
[   52.599129][    T1]  __device_release_driver+0x1d4/0x340
[   52.601471][    T1]  driver_detach+0x130/0x200
[   52.603457][    T1]  bus_remove_driver+0xf4/0x180
[   52.605550][    T1]  driver_unregister+0x58/0x80
[   52.607599][    T1]  platform_driver_unregister+0x1c/0x40
[   52.609969][    T1]  physmap_init+0xb8/0xf0
[   52.611863][    T1]  do_one_initcall+0xa4/0x2c0
[   52.613893][    T1]  do_initcalls+0x174/0x23c
[   52.615854][    T1]  kernel_init_freeable+0x2cc/0x370
[   52.618094][    T1]  kernel_init+0x24/0x180
[   52.620005][    T1]  ret_from_fork+0x10/0x20
[   52.621948][    T1] irq event stamp: 687638
[   52.623797][    T1] hardirqs last  enabled at (687637):
[<ffff800010208d60>] __up_console_sem+0x60/0xc0
[   52.627698][    T1] hardirqs last disabled at (687638):
[<ffff800011ef5b28>] el1_dbg+0x28/0x80
[   52.631304][    T1] softirqs last  enabled at (687634):
[<ffff800010010518>] __do_softirq+0x418/0x4f8
[   52.635126][    T1] softirqs last disabled at (687627):
[<ffff8000101079f8>] __irq_exit_rcu+0x1b8/0x280
[   52.639116][    T1] ---[ end trace 5aee148b589c1673 ]---
[   53.261155][   T13] _warn_unseeded_randomness: 2 callbacks suppressed
[   53.261201][   T13] random: get_random_u32 called from
shuffle_freelist+0x44/0x1c0 with crng_init=0
[   54.367115][    T1] random: get_random_u32 called from
kobject_release+0x44/0x180 with crng_init=0
[   54.367240][    T1] kobject: 'physmap-flash' (ffff00000efe3200):
kobject_release, parent ffff000008171a00 (delayed 750)
[   54.377889][    T1] random: get_random_u32 called from
shuffle_freelist+0x44/0x1c0 with crng_init=0


This is my qemu cmd line:
qemu-system-aarch64 --enable-kvm -cpu cortex-a53 -kernel
Image-20210921-3.gz -serial stdio -monitor none -nographic -m 2G -M
virt -fsdev local,id=root,path=/srv/kvm/tmp/stretch/arm64,security_model=none,writeout=immediate
-device virtio-rng-pci -device
virtio-9p-pci,fsdev=root,mount_tag=/dev/root -append "root=/dev/root
rootfstype=9p rootflags=trans=virtio console=ttyAMA0,38400n8
earlycon=pl011,0x9000000 initcall_debug softlockup_panic=0
security=none kpti=no"

I did not expect the physmp-flash device to be used at all.
Does anyone see what might be wrong here ?

Cheers,
Anders


From a-nandan at ti.com  Tue Sep 21 06:42:49 2021
From: a-nandan at ti.com (Apurva Nandan)
Date: Tue, 21 Sep 2021 19:12:49 +0530
Subject: [PATCH v2 1/2] dt-bindings: mtd: spi-nand: Convert to DT schema
 format
In-Reply-To: <YUj6RUNYDoWA30Ln@robh.at.kernel.org>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-2-a-nandan@ti.com>
 <20210920150651.vvdhennblwhdi3jw@mobilestation>
 <YUj6RUNYDoWA30Ln@robh.at.kernel.org>
Message-ID: <3c03fcdd-b015-8fda-eadc-e1b6d24ba88d@ti.com>

Hi Rob,

On 21/09/21 2:46 am, Rob Herring wrote:
> On Mon, Sep 20, 2021 at 06:06:51PM +0300, Serge Semin wrote:
>> Hello Apurva
>>
>> On Mon, Sep 20, 2021 at 07:57:12PM +0530, Apurva Nandan wrote:
>>> Convert spi-nand.txt binding to YAML format with an added example.
>>>
>>> Signed-off-by: Apurva Nandan <a-nandan at ti.com>
>>> ---
>>>   .../devicetree/bindings/mtd/spi-nand.txt      |  5 --
>>>   .../devicetree/bindings/mtd/spi-nand.yaml     | 62 +++++++++++++++++++
>>>   2 files changed, 62 insertions(+), 5 deletions(-)
>>>   delete mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.txt
>>>   create mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.yaml
>> Thanks for the bindings conversion patch. There are several comments
>> below. But before addressing them it would be better to also get a
>> response from Rob.
>>
>>> diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.txt b/Documentation/devicetree/bindings/mtd/spi-nand.txt
>>> deleted file mode 100644
>>> index 8b51f3b6d55c..000000000000
>>> --- a/Documentation/devicetree/bindings/mtd/spi-nand.txt
>>> +++ /dev/null
>>> @@ -1,5 +0,0 @@
>>> -SPI NAND flash
>>> -
>>> -Required properties:
>>> -- compatible: should be "spi-nand"
>>> -- reg: should encode the chip-select line used to access the NAND chip
>>> diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.yaml b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
>>> new file mode 100644
>>> index 000000000000..601beba8d971
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
>>> @@ -0,0 +1,62 @@
>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/mtd/spi-nand.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: SPI NAND flash
>>> +
>>> +maintainers:
>>> +  - Apurva Nandan <a-nandan at ti.com>
>>> +
>>> +allOf:
>>> +  - $ref: "mtd.yaml#"
>>> +
>>> +properties:
>>> +  compatible:
>>> +    const: spi-nand
>>> +
>>> +  reg:
>>> +    maxItems: 1
>>> +
>>> +  spi-max-frequency: true
>>> +  spi-rx-bus-width: true
>>> +  spi-tx-bus-width: true
>>> +  rx-sample-delay-ns: true
>> Since it's an SPI-client device there are more than these properties
>> could be set for it. See the SPI-controller bindings schema:
>> Documentation/devicetree/bindings/spi/spi-controller.yaml
>> So there is two possible ways to make it more generic:
>> 1) Detach the spi-client part from the spi-controller.yaml bindings
>> into a dedicated DT-schema file and refer to that new scheme from
>> here.
> Yes, as mentioned there's patches doing this. But the above is fine.
> There's some value in defining here which properties are valid.
Yeah right
>> 2) Forget about these controller-specific properties and let the
>> parental SPI-controller bindings parsing them. Of course there must be
>> at least one of the next properties declared for it to work:
>> {unevaluatedProperties, additionalProperties}.
>>
>> It's up to Rob to decided which approach is better though...
>>
>>> +
>>> +  '#address-cells': true
>>> +  '#size-cells': true
>> Aren't they always equal to 1?
> No SPI nand devices >4GB?
Yeah, we have SPI NANDs >4GB, and "'#address-cells': true" allows those 
sizes.
>
>>> +
>>> +additionalProperties:
>>> +  type: object
>> I'd suggest to elaborate the way the partition sub-nodes looks
>> like, for instance, the node names, supported compatible names,
>> labels, etc.
> That should probably all be in mtd.yaml. The question here is whether
> partitions are always under a 'partitions' node. Maybe this is new
> enough that only the new way has to be supported. Though if mtd.yaml
> supported both forms, allowing both all the time is okay IMO.
>
> Rob

I had added the "partition" node properties in the v1 patch, but as per 
the reviews I removed it.
I think we can prefer having them in mtd.yaml if needed, in a separate 
patch series.
Do you prefer the mtd.yaml changes as a part of this series or as a 
separate patch?

Other than that, I don't find any need for a v3 patch re-roll, do you agree?

Thanks,
Apurva Nandan



From a-nandan at ti.com  Tue Sep 21 06:44:35 2021
From: a-nandan at ti.com (Apurva Nandan)
Date: Tue, 21 Sep 2021 19:14:35 +0530
Subject: [PATCH v2 2/2] dt-bindings: snps,dw-apb-ssi: Use 'flash' node
 name instead of 'spi-flash' in example
In-Reply-To: <YUj6yUBx0xCY9QGj@robh.at.kernel.org>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-3-a-nandan@ti.com>
 <YUj6yUBx0xCY9QGj@robh.at.kernel.org>
Message-ID: <408954fa-aa71-6f35-3b02-0e7a078658f0@ti.com>


On 21/09/21 2:49 am, Rob Herring wrote:
> On Mon, Sep 20, 2021 at 07:57:13PM +0530, Apurva Nandan wrote:
>> Change the nodename in the example with spi-nand from 'spi-flash at 1'
>> to 'flash at 1' to make the schema uniform with both spi-nand and spi-nor
>> flashes. jedec,spi-nor.yaml uses 'flash@' nodename for spi-nor flashes,
>> so make the spi-nand examples in dt-bindings use it too for uniformity.
>>
>> Signed-off-by: Apurva Nandan <a-nandan at ti.com>
>> ---
>>   Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
> Fixes should come first. Maybe Mark can apply this before you respin.
>
> Acked-by: Rob Herring <robh at kernel.org>
Please tell if I need to re-roll this series for changing the order of 
the two patches.
>> diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
>> index ca91201a9926..d7e08b03e204 100644
>> --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
>> +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml
>> @@ -171,7 +171,7 @@ examples:
>>         cs-gpios = <&gpio0 13 0>,
>>                    <&gpio0 14 0>;
>>         rx-sample-delay-ns = <3>;
>> -      spi-flash at 1 {
>> +      flash at 1 {
>>           compatible = "spi-nand";
>>           reg = <1>;
>>           rx-sample-delay-ns = <7>;
>> -- 
>> 2.25.1
>>
>>
Thanks,
Apurva Nandan


From broonie at kernel.org  Tue Sep 21 08:25:07 2021
From: broonie at kernel.org (Mark Brown)
Date: Tue, 21 Sep 2021 16:25:07 +0100
Subject: (subset) [PATCH v2 0/2] dt-bindings: mtd: spi-nand: Convert to DT
 schema
In-Reply-To: <20210920142713.129295-1-a-nandan@ti.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
Message-ID: <163223675481.32536.11593084094057981568.b4-ty@kernel.org>

On Mon, 20 Sep 2021 19:57:11 +0530, Apurva Nandan wrote:
> Series to convert spi-nand.txt binding to YAML format and also fix up
> snps-dw-apb-ssi for related dt_schema errors.
> 
> Changes in v2:
> - Fixed dtschema erros in snps-dw-apb-ssi.
> - Improved additionalProperties, reg, and compatible fields in
>   spi-nand.yaml.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[2/2] dt-bindings: snps,dw-apb-ssi: Use 'flash' node name instead of 'spi-flash' in example
      commit: d7a48e27b38a94bf73c973c236461234610256d5

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From robh at kernel.org  Tue Sep 21 12:16:02 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 21 Sep 2021 14:16:02 -0500
Subject: [PATCH v2 1/2] dt-bindings: mtd: spi-nand: Convert to DT schema
 format
In-Reply-To: <3c03fcdd-b015-8fda-eadc-e1b6d24ba88d@ti.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-2-a-nandan@ti.com>
 <20210920150651.vvdhennblwhdi3jw@mobilestation>
 <YUj6RUNYDoWA30Ln@robh.at.kernel.org>
 <3c03fcdd-b015-8fda-eadc-e1b6d24ba88d@ti.com>
Message-ID: <CAL_Jsq+sg7f4pJGBhU48a4=uR7cYQmXsoSjbrktovV94m3+qFw@mail.gmail.com>

On Tue, Sep 21, 2021 at 8:43 AM Apurva Nandan <a-nandan at ti.com> wrote:
>
> Hi Rob,
>
> On 21/09/21 2:46 am, Rob Herring wrote:
> > On Mon, Sep 20, 2021 at 06:06:51PM +0300, Serge Semin wrote:
> >> Hello Apurva
> >>
> >> On Mon, Sep 20, 2021 at 07:57:12PM +0530, Apurva Nandan wrote:
> >>> Convert spi-nand.txt binding to YAML format with an added example.
> >>>
> >>> Signed-off-by: Apurva Nandan <a-nandan at ti.com>
> >>> ---
> >>>   .../devicetree/bindings/mtd/spi-nand.txt      |  5 --
> >>>   .../devicetree/bindings/mtd/spi-nand.yaml     | 62 +++++++++++++++++++
> >>>   2 files changed, 62 insertions(+), 5 deletions(-)
> >>>   delete mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.txt
> >>>   create mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.yaml
> >> Thanks for the bindings conversion patch. There are several comments
> >> below. But before addressing them it would be better to also get a
> >> response from Rob.
> >>
> >>> diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.txt b/Documentation/devicetree/bindings/mtd/spi-nand.txt
> >>> deleted file mode 100644
> >>> index 8b51f3b6d55c..000000000000
> >>> --- a/Documentation/devicetree/bindings/mtd/spi-nand.txt
> >>> +++ /dev/null
> >>> @@ -1,5 +0,0 @@
> >>> -SPI NAND flash
> >>> -
> >>> -Required properties:
> >>> -- compatible: should be "spi-nand"
> >>> -- reg: should encode the chip-select line used to access the NAND chip
> >>> diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.yaml b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
> >>> new file mode 100644
> >>> index 000000000000..601beba8d971
> >>> --- /dev/null
> >>> +++ b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
> >>> @@ -0,0 +1,62 @@
> >>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> >>> +%YAML 1.2
> >>> +---
> >>> +$id: http://devicetree.org/schemas/mtd/spi-nand.yaml#
> >>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >>> +
> >>> +title: SPI NAND flash
> >>> +
> >>> +maintainers:
> >>> +  - Apurva Nandan <a-nandan at ti.com>
> >>> +
> >>> +allOf:
> >>> +  - $ref: "mtd.yaml#"
> >>> +
> >>> +properties:
> >>> +  compatible:
> >>> +    const: spi-nand
> >>> +
> >>> +  reg:
> >>> +    maxItems: 1
> >>> +
> >>> +  spi-max-frequency: true
> >>> +  spi-rx-bus-width: true
> >>> +  spi-tx-bus-width: true
> >>> +  rx-sample-delay-ns: true
> >> Since it's an SPI-client device there are more than these properties
> >> could be set for it. See the SPI-controller bindings schema:
> >> Documentation/devicetree/bindings/spi/spi-controller.yaml
> >> So there is two possible ways to make it more generic:
> >> 1) Detach the spi-client part from the spi-controller.yaml bindings
> >> into a dedicated DT-schema file and refer to that new scheme from
> >> here.
> > Yes, as mentioned there's patches doing this. But the above is fine.
> > There's some value in defining here which properties are valid.
> Yeah right
> >> 2) Forget about these controller-specific properties and let the
> >> parental SPI-controller bindings parsing them. Of course there must be
> >> at least one of the next properties declared for it to work:
> >> {unevaluatedProperties, additionalProperties}.
> >>
> >> It's up to Rob to decided which approach is better though...
> >>
> >>> +
> >>> +  '#address-cells': true
> >>> +  '#size-cells': true
> >> Aren't they always equal to 1?
> > No SPI nand devices >4GB?
> Yeah, we have SPI NANDs >4GB, and "'#address-cells': true" allows those
> sizes.
> >
> >>> +
> >>> +additionalProperties:
> >>> +  type: object
> >> I'd suggest to elaborate the way the partition sub-nodes looks
> >> like, for instance, the node names, supported compatible names,
> >> labels, etc.
> > That should probably all be in mtd.yaml. The question here is whether
> > partitions are always under a 'partitions' node. Maybe this is new
> > enough that only the new way has to be supported. Though if mtd.yaml
> > supported both forms, allowing both all the time is okay IMO.
> >
> > Rob
>
> I had added the "partition" node properties in the v1 patch, but as per
> the reviews I removed it.
> I think we can prefer having them in mtd.yaml if needed, in a separate
> patch series.
> Do you prefer the mtd.yaml changes as a part of this series or as a
> separate patch?
>
> Other than that, I don't find any need for a v3 patch re-roll, do you agree?

Yeah, I suppose not.

Reviewed-by: Rob Herring <robh at kernel.org>

And actually, it's Miquel that should apply these 2 rather than Mark.

Rob


From robh at kernel.org  Tue Sep 21 13:38:08 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 21 Sep 2021 15:38:08 -0500
Subject: [PATCH v4 2/8] dt-bindings: mtd: Remove gpmc-nor.txt
In-Reply-To: <20210914122705.15421-3-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-3-rogerq@kernel.org>
Message-ID: <YUpCsBdVcoLv2BH4@robh.at.kernel.org>

On Tue, 14 Sep 2021 15:26:59 +0300, Roger Quadros wrote:
> There is no GPMC NOR compatible or device driver. GPMC is just
> a bus interface over which standard (CFI/JEDC) NOR Flash chips
> can be attached.
> 
> For NOR chip bindings, please refer to
> Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../devicetree/bindings/mtd/gpmc-nor.txt      | 98 -------------------
>  1 file changed, 98 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nor.txt
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Sep 21 13:38:21 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 21 Sep 2021 15:38:21 -0500
Subject: [PATCH v4 3/8] dt-bindings: net: Remove gpmc-eth.txt
In-Reply-To: <20210914122705.15421-4-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-4-rogerq@kernel.org>
Message-ID: <YUpCvdZ+z7P4fZED@robh.at.kernel.org>

On Tue, 14 Sep 2021 15:27:00 +0300, Roger Quadros wrote:
> There is no GPMC Ethernet compatible or device driver. GPMC is
> just a bus interface over which devices like Ethernet controller
> can be to.
> 
> For SMSC 911x Ethernet chip bindings, please refer to
> Documentation/devicetree/bindings/net/smsc,lan9115.yaml
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../devicetree/bindings/net/gpmc-eth.txt      | 97 -------------------
>  1 file changed, 97 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/net/gpmc-eth.txt
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Sep 21 13:40:38 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 21 Sep 2021 15:40:38 -0500
Subject: [PATCH v4 4/8] dt-bindings: memory-controllers: Introduce
 ti,gpmc-child
In-Reply-To: <20210914122705.15421-5-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-5-rogerq@kernel.org>
Message-ID: <YUpDRkZqQjmfKZgz@robh.at.kernel.org>

On Tue, 14 Sep 2021 15:27:01 +0300, Roger Quadros wrote:
> This binding is meant for the child nodes of the TI GPMC node. The node
> represents any device connected to the GPMC bus. It may be a Flash chip,
> RAM chip or Ethernet controller, etc. These properties are meant for
> configuring the GPMC settings/timings and will accompany the bindings
> supported by the respective device.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../memory-controllers/ti,gpmc-child.yaml     | 245 ++++++++++++++++++
>  1 file changed, 245 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc-child.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Sep 21 13:43:40 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 21 Sep 2021 15:43:40 -0500
Subject: [PATCH v4 5/8] dt-bindings: mtd: ti,gpmc-nand: Convert to yaml
In-Reply-To: <20210914122705.15421-6-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-6-rogerq@kernel.org>
Message-ID: <YUpD/CvFZ8WO7pI/@robh.at.kernel.org>

On Tue, 14 Sep 2021 15:27:02 +0300, Roger Quadros wrote:
> Convert gpmc-nand.txt to ti,gpmc-nand.yaml.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../devicetree/bindings/mtd/gpmc-nand.txt     | 147 ------------------
>  .../devicetree/bindings/mtd/ti,gpmc-nand.yaml | 121 ++++++++++++++
>  2 files changed, 121 insertions(+), 147 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-nand.txt
>  create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-nand.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Sep 21 13:45:14 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 21 Sep 2021 15:45:14 -0500
Subject: [PATCH v4 6/8] dt-bindings: mtd: ti, gpmc-onenand: Convert to yaml
In-Reply-To: <20210914122705.15421-7-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-7-rogerq@kernel.org>
Message-ID: <YUpEWslQSEbppnBk@robh.at.kernel.org>

On Tue, Sep 14, 2021 at 03:27:03PM +0300, Roger Quadros wrote:
> Convert gpmc-onenand.txt to ti,gpmc-onenand.yaml.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../devicetree/bindings/mtd/gpmc-onenand.txt  | 48 -----------
>  .../bindings/mtd/ti,gpmc-onenand.yaml         | 81 +++++++++++++++++++
>  2 files changed, 81 insertions(+), 48 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
>  create mode 100644 Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
> deleted file mode 100644
> index e9f01a963a0a..000000000000
> --- a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
> +++ /dev/null
> @@ -1,48 +0,0 @@
> -Device tree bindings for GPMC connected OneNANDs
> -
> -GPMC connected OneNAND (found on OMAP boards) are represented as child nodes of
> -the GPMC controller with a name of "onenand".
> -
> -All timing relevant properties as well as generic gpmc child properties are
> -explained in a separate documents - please refer to
> -Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
> -
> -Required properties:
> -
> - - compatible:		"ti,omap2-onenand"
> - - reg:			The CS line the peripheral is connected to
> - - gpmc,device-width:	Width of the ONENAND device connected to the GPMC
> -			in bytes. Must be 1 or 2.
> -
> -Optional properties:
> -
> - - int-gpios:		GPIO specifier for the INT pin.
> -
> -For inline partition table parsing (optional):
> -
> - - #address-cells: should be set to 1
> - - #size-cells: should be set to 1
> -
> -Example for an OMAP3430 board:
> -
> -	gpmc: gpmc at 6e000000 {
> -		compatible = "ti,omap3430-gpmc";
> -		ti,hwmods = "gpmc";
> -		reg = <0x6e000000 0x1000000>;
> -		interrupts = <20>;
> -		gpmc,num-cs = <8>;
> -		gpmc,num-waitpins = <4>;
> -		#address-cells = <2>;
> -		#size-cells = <1>;
> -
> -		onenand at 0 {
> -			compatible = "ti,omap2-onenand";
> -			reg = <0 0 0>; /* CS0, offset 0 */
> -			gpmc,device-width = <2>;
> -
> -			#address-cells = <1>;
> -			#size-cells = <1>;
> -
> -			/* partitions go here */
> -		};
> -	};
> diff --git a/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml b/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
> new file mode 100644
> index 000000000000..42149a9c3a8d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mtd/ti,gpmc-onenand.yaml
> @@ -0,0 +1,81 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mtd/ti,gpmc-onenand.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: OneNAND over Texas Instruments GPMC bus.
> +
> +maintainers:
> +  - Tony Lindgren <tony at atomide.com>
> +  - Roger Quadros <rogerq at kernel.org>
> +
> +description:
> +  GPMC connected OneNAND (found on OMAP boards) are represented
> +  as child nodes of the GPMC controller.
> +
> +properties:
> +  compatible:
> +    const: ti,omap2-onenand
> +
> +  reg:
> +    items:
> +      - description: |
> +          Chip Select number, register offset and size of
> +          OneNAND register window.
> +
> +  "#address-cells": true
> +
> +  "#size-cells": true
> +
> +  int-gpios:
> +    description: GPIO specifier for the INT pin.
> +
> +patternProperties:
> +  "@[0-9a-f]+$":
> +    $ref: "/schemas/mtd/partitions/partition.yaml"
> +
> +allOf:
> +  - $ref: "/schemas/memory-controllers/ti,gpmc-child.yaml"
> +
> +required:
> +  - compatible
> +  - reg
> +  - "#address-cells"
> +  - "#size-cells"
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    gpmc: memory-controller at 6e000000 {
> +      compatible = "ti,omap3430-gpmc";
> +      reg = <0x6e000000 0x02d0>;
> +      interrupts = <20>;
> +      gpmc,num-cs = <8>;
> +      gpmc,num-waitpins = <4>;
> +      clocks = <&l3s_clkctrl>;
> +      clock-names = "fck";
> +      #address-cells = <2>;
> +      #size-cells = <1>;
> +
> +      ranges = <0 0 0x01000000 0x01000000>,   /* 16 MB for OneNAND */
> +               <1 0 0x02000000 0x01000000>;   /* 16 MB for smc91c96 */
> +
> +      onenand at 0,0 {
> +        compatible = "ti,omap2-onenand";
> +        reg = <0 0 0x20000>;    /* CS0, offset 0, IO size 128K */
> +        #address-cells = <1>;
> +        #size-cells = <1>;
> +
> +        partition at 0 {
> +          label = "bootloader";
> +          reg = <0x00000000 0x00100000>;
> +        };
> +
> +        partition at 1 {

partition at 100000

With that,

Reviewed-by: Rob Herring <robh at kernel.org>

> +          label = "config";
> +          reg = <0x00100000 0x002c0000>;
> +        };
> +      };
> +    };
> -- 
> 2.17.1
> 
> 


From robh at kernel.org  Tue Sep 21 13:47:18 2021
From: robh at kernel.org (Rob Herring)
Date: Tue, 21 Sep 2021 15:47:18 -0500
Subject: [PATCH v4 7/8] dt-bindings: memory-controllers: ti, gpmc: Convert
 to yaml
In-Reply-To: <20210914122705.15421-8-rogerq@kernel.org>
References: <20210914122705.15421-1-rogerq@kernel.org>
 <20210914122705.15421-8-rogerq@kernel.org>
Message-ID: <YUpE1mBqElmjv+wV@robh.at.kernel.org>

On Tue, 14 Sep 2021 15:27:04 +0300, Roger Quadros wrote:
> Convert omap-gpmc.txt to ti,gpmc.yaml.
> 
> Signed-off-by: Roger Quadros <rogerq at kernel.org>
> ---
>  .../bindings/memory-controllers/omap-gpmc.txt | 157 ----------------
>  .../bindings/memory-controllers/ti,gpmc.yaml  | 172 ++++++++++++++++++
>  2 files changed, 172 insertions(+), 157 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
>  create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti,gpmc.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From miquel.raynal at bootlin.com  Wed Sep 22 01:31:21 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 22 Sep 2021 10:31:21 +0200
Subject: [PATCH v2 1/2] dt-bindings: mtd: spi-nand: Convert to DT schema
 format
In-Reply-To: <CAL_Jsq+sg7f4pJGBhU48a4=uR7cYQmXsoSjbrktovV94m3+qFw@mail.gmail.com>
References: <20210920142713.129295-1-a-nandan@ti.com>
 <20210920142713.129295-2-a-nandan@ti.com>
 <20210920150651.vvdhennblwhdi3jw@mobilestation>
 <YUj6RUNYDoWA30Ln@robh.at.kernel.org>
 <3c03fcdd-b015-8fda-eadc-e1b6d24ba88d@ti.com>
 <CAL_Jsq+sg7f4pJGBhU48a4=uR7cYQmXsoSjbrktovV94m3+qFw@mail.gmail.com>
Message-ID: <20210922103121.28d489ef@xps13>

Hello Rob, Mark,

robh at kernel.org wrote on Tue, 21 Sep 2021 14:16:02 -0500:

> On Tue, Sep 21, 2021 at 8:43 AM Apurva Nandan <a-nandan at ti.com> wrote:
> >
> > Hi Rob,
> >
> > On 21/09/21 2:46 am, Rob Herring wrote:  
> > > On Mon, Sep 20, 2021 at 06:06:51PM +0300, Serge Semin wrote:  
> > >> Hello Apurva
> > >>
> > >> On Mon, Sep 20, 2021 at 07:57:12PM +0530, Apurva Nandan wrote:  
> > >>> Convert spi-nand.txt binding to YAML format with an added example.
> > >>>
> > >>> Signed-off-by: Apurva Nandan <a-nandan at ti.com>
> > >>> ---
> > >>>   .../devicetree/bindings/mtd/spi-nand.txt      |  5 --
> > >>>   .../devicetree/bindings/mtd/spi-nand.yaml     | 62 +++++++++++++++++++
> > >>>   2 files changed, 62 insertions(+), 5 deletions(-)
> > >>>   delete mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.txt
> > >>>   create mode 100644 Documentation/devicetree/bindings/mtd/spi-nand.yaml  
> > >> Thanks for the bindings conversion patch. There are several comments
> > >> below. But before addressing them it would be better to also get a
> > >> response from Rob.
> > >>  
> > >>> diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.txt b/Documentation/devicetree/bindings/mtd/spi-nand.txt
> > >>> deleted file mode 100644
> > >>> index 8b51f3b6d55c..000000000000
> > >>> --- a/Documentation/devicetree/bindings/mtd/spi-nand.txt
> > >>> +++ /dev/null
> > >>> @@ -1,5 +0,0 @@
> > >>> -SPI NAND flash
> > >>> -
> > >>> -Required properties:
> > >>> -- compatible: should be "spi-nand"
> > >>> -- reg: should encode the chip-select line used to access the NAND chip
> > >>> diff --git a/Documentation/devicetree/bindings/mtd/spi-nand.yaml b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
> > >>> new file mode 100644
> > >>> index 000000000000..601beba8d971
> > >>> --- /dev/null
> > >>> +++ b/Documentation/devicetree/bindings/mtd/spi-nand.yaml
> > >>> @@ -0,0 +1,62 @@
> > >>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > >>> +%YAML 1.2
> > >>> +---
> > >>> +$id: http://devicetree.org/schemas/mtd/spi-nand.yaml#
> > >>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > >>> +
> > >>> +title: SPI NAND flash
> > >>> +
> > >>> +maintainers:
> > >>> +  - Apurva Nandan <a-nandan at ti.com>
> > >>> +
> > >>> +allOf:
> > >>> +  - $ref: "mtd.yaml#"
> > >>> +
> > >>> +properties:
> > >>> +  compatible:
> > >>> +    const: spi-nand
> > >>> +
> > >>> +  reg:
> > >>> +    maxItems: 1
> > >>> +
> > >>> +  spi-max-frequency: true
> > >>> +  spi-rx-bus-width: true
> > >>> +  spi-tx-bus-width: true
> > >>> +  rx-sample-delay-ns: true  
> > >> Since it's an SPI-client device there are more than these properties
> > >> could be set for it. See the SPI-controller bindings schema:
> > >> Documentation/devicetree/bindings/spi/spi-controller.yaml
> > >> So there is two possible ways to make it more generic:
> > >> 1) Detach the spi-client part from the spi-controller.yaml bindings
> > >> into a dedicated DT-schema file and refer to that new scheme from
> > >> here.  
> > > Yes, as mentioned there's patches doing this. But the above is fine.
> > > There's some value in defining here which properties are valid.  
> > Yeah right  
> > >> 2) Forget about these controller-specific properties and let the
> > >> parental SPI-controller bindings parsing them. Of course there must be
> > >> at least one of the next properties declared for it to work:
> > >> {unevaluatedProperties, additionalProperties}.
> > >>
> > >> It's up to Rob to decided which approach is better though...
> > >>  
> > >>> +
> > >>> +  '#address-cells': true
> > >>> +  '#size-cells': true  
> > >> Aren't they always equal to 1?  
> > > No SPI nand devices >4GB?  
> > Yeah, we have SPI NANDs >4GB, and "'#address-cells': true" allows those
> > sizes.  
> > >  
> > >>> +
> > >>> +additionalProperties:
> > >>> +  type: object  
> > >> I'd suggest to elaborate the way the partition sub-nodes looks
> > >> like, for instance, the node names, supported compatible names,
> > >> labels, etc.  
> > > That should probably all be in mtd.yaml. The question here is whether
> > > partitions are always under a 'partitions' node. Maybe this is new
> > > enough that only the new way has to be supported. Though if mtd.yaml
> > > supported both forms, allowing both all the time is okay IMO.
> > >
> > > Rob  
> >
> > I had added the "partition" node properties in the v1 patch, but as per
> > the reviews I removed it.
> > I think we can prefer having them in mtd.yaml if needed, in a separate
> > patch series.
> > Do you prefer the mtd.yaml changes as a part of this series or as a
> > separate patch?
> >
> > Other than that, I don't find any need for a v3 patch re-roll, do you agree?  
> 
> Yeah, I suppose not.
> 
> Reviewed-by: Rob Herring <robh at kernel.org>
> 
> And actually, it's Miquel that should apply these 2 rather than Mark.

Yeah, but that's fine for this one, I don't expect conflicts anyway.

Acked-by: Miquel Raynal <miquel.raynal at bootlin.com>

Thanks,
Miqu?l


From cgel.zte at gmail.com  Wed Sep 22 18:52:41 2021
From: cgel.zte at gmail.com (CGEL)
Date: Thu, 23 Sep 2021 01:52:41 +0000
Subject: [PATCH] mtd: spinand: add merge-two-spinand function
Message-ID: <20210923015241.248910-1-ren.xiaohui@zte.com.cn>

From: Ren Xiaohui <ren.xiaohui at zte.com.cn>

Combine the two SPI NAND flash in the MTD layer

Signed-off-by: Ren Xiaohui <ren.xiaohui at zte.com.cn>
---
 drivers/mtd/nand/spi/Kconfig          |   8 +
 drivers/mtd/nand/spi/Makefile         |   2 +-
 drivers/mtd/nand/spi/core.c           |  36 +++-
 drivers/mtd/nand/spi/spi_nand_merge.c | 350 ++++++++++++++++++++++++++++++++++
 include/linux/mtd/spinand.h           |  14 +-
 5 files changed, 400 insertions(+), 10 deletions(-)
 create mode 100644 drivers/mtd/nand/spi/spi_nand_merge.c

diff --git a/drivers/mtd/nand/spi/Kconfig b/drivers/mtd/nand/spi/Kconfig
index 3d7649a..6aec3ef 100644
--- a/drivers/mtd/nand/spi/Kconfig
+++ b/drivers/mtd/nand/spi/Kconfig
@@ -7,3 +7,11 @@ menuconfig MTD_SPI_NAND
 	select SPI_MEM
 	help
 	  This is the framework for the SPI NAND device drivers.
+
+menuconfig MTD_SPI_NAND_MERGE
+	tristate "Two SPI NAND merge a mtd device"
+	select MTD_NAND_CORE
+	depends on MTD_SPI_NAND
+	select SPI_MEM
+	help
+	  This is the framework for Two SPI NAND merge a mtd device.
diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
index 9662b9c..5d6475d 100644
--- a/drivers/mtd/nand/spi/Makefile
+++ b/drivers/mtd/nand/spi/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
-spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
+spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o spi_nand_merge.o toshiba.o winbond.o
 obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 2c8685f..ee5e653 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -624,7 +624,7 @@ static int spinand_write_page(struct spinand_device *spinand,
 	return nand_ecc_finish_io_req(nand, (struct nand_page_io_req *)req);
 }
 
-static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
+int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
 			    struct mtd_oob_ops *ops)
 {
 	struct spinand_device *spinand = mtd_to_spinand(mtd);
@@ -669,8 +669,9 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
 
 	return ret ? ret : max_bitflips;
 }
+EXPORT_SYMBOL(spinand_mtd_read);
 
-static int spinand_mtd_write(struct mtd_info *mtd, loff_t to,
+int spinand_mtd_write(struct mtd_info *mtd, loff_t to,
 			     struct mtd_oob_ops *ops)
 {
 	struct spinand_device *spinand = mtd_to_spinand(mtd);
@@ -704,6 +705,7 @@ static int spinand_mtd_write(struct mtd_info *mtd, loff_t to,
 
 	return ret;
 }
+EXPORT_SYMBOL(spinand_mtd_write);
 
 static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos)
 {
@@ -725,7 +727,7 @@ static bool spinand_isbad(struct nand_device *nand, const struct nand_pos *pos)
 	return false;
 }
 
-static int spinand_mtd_block_isbad(struct mtd_info *mtd, loff_t offs)
+int spinand_mtd_block_isbad(struct mtd_info *mtd, loff_t offs)
 {
 	struct nand_device *nand = mtd_to_nanddev(mtd);
 	struct spinand_device *spinand = nand_to_spinand(nand);
@@ -739,6 +741,7 @@ static int spinand_mtd_block_isbad(struct mtd_info *mtd, loff_t offs)
 
 	return ret;
 }
+EXPORT_SYMBOL(spinand_mtd_block_isbad);
 
 static int spinand_markbad(struct nand_device *nand, const struct nand_pos *pos)
 {
@@ -764,7 +767,7 @@ static int spinand_markbad(struct nand_device *nand, const struct nand_pos *pos)
 	return spinand_write_page(spinand, &req);
 }
 
-static int spinand_mtd_block_markbad(struct mtd_info *mtd, loff_t offs)
+int spinand_mtd_block_markbad(struct mtd_info *mtd, loff_t offs)
 {
 	struct nand_device *nand = mtd_to_nanddev(mtd);
 	struct spinand_device *spinand = nand_to_spinand(nand);
@@ -778,6 +781,7 @@ static int spinand_mtd_block_markbad(struct mtd_info *mtd, loff_t offs)
 
 	return ret;
 }
+EXPORT_SYMBOL(spinand_mtd_block_markbad);
 
 static int spinand_erase(struct nand_device *nand, const struct nand_pos *pos)
 {
@@ -808,8 +812,7 @@ static int spinand_erase(struct nand_device *nand, const struct nand_pos *pos)
 	return ret;
 }
 
-static int spinand_mtd_erase(struct mtd_info *mtd,
-			     struct erase_info *einfo)
+int spinand_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo)
 {
 	struct spinand_device *spinand = mtd_to_spinand(mtd);
 	int ret;
@@ -820,8 +823,9 @@ static int spinand_mtd_erase(struct mtd_info *mtd,
 
 	return ret;
 }
+EXPORT_SYMBOL(spinand_mtd_erase);
 
-static int spinand_mtd_block_isreserved(struct mtd_info *mtd, loff_t offs)
+int spinand_mtd_block_isreserved(struct mtd_info *mtd, loff_t offs)
 {
 	struct spinand_device *spinand = mtd_to_spinand(mtd);
 	struct nand_device *nand = mtd_to_nanddev(mtd);
@@ -835,6 +839,7 @@ static int spinand_mtd_block_isreserved(struct mtd_info *mtd, loff_t offs)
 
 	return ret;
 }
+EXPORT_SYMBOL(spinand_mtd_block_isreserved);
 
 static int spinand_create_dirmap(struct spinand_device *spinand,
 				 unsigned int plane)
@@ -1017,7 +1022,8 @@ spinand_select_op_variant(struct spinand_device *spinand,
  * @table_size: size of the device description table
  * @rdid_method: read id method to match
  *
- * Match between a device ID retrieved through the READ_ID command and an
+ * Should be used by SPI NAND manufacturer drivers when they want to find a
+ * match between a device ID retrieved through the READ_ID command and an
  * entry in the SPI NAND description table. If a match is found, the spinand
  * object will be initialized with information provided by the matching
  * spinand_info entry.
@@ -1295,6 +1301,10 @@ static int spinand_probe(struct spi_mem *mem)
 	mtd = spinand_to_mtd(spinand);
 	mtd->dev.parent = &mem->spi->dev;
 
+#ifdef CONFIG_MTD_SPI_NAND_MERGE
+	merge_mtd_register(mtd);
+#endif
+
 	ret = spinand_init(spinand);
 	if (ret)
 		return ret;
@@ -1320,10 +1330,20 @@ static int spinand_remove(struct spi_mem *mem)
 	spinand = spi_mem_get_drvdata(mem);
 	mtd = spinand_to_mtd(spinand);
 
+#ifdef CONFIG_MTD_SPI_NAND_MERGE
+	if (mtd == get_merge_mtd(0) || mtd == get_merge_mtd(1)) {
+		pr_warn("this mtd device is merging, It is illegal.");
+		return 0;
+	}
 	ret = mtd_device_unregister(mtd);
 	if (ret)
 		return ret;
+	spinand_cleanup(spinand);
+#endif
 
+	ret = mtd_device_unregister(mtd);
+	if (ret)
+		return ret;
 	spinand_cleanup(spinand);
 
 	return 0;
diff --git a/drivers/mtd/nand/spi/spi_nand_merge.c b/drivers/mtd/nand/spi/spi_nand_merge.c
new file mode 100644
index 0000000..fde1810
--- /dev/null
+++ b/drivers/mtd/nand/spi/spi_nand_merge.c
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Merge Nand Chips driver
+ *
+ * Copyright 2021 - 2099 ZTE, Inc
+ *
+ * Author:
+ * Ren Xiaohui <ren.xiaohui at zte.com.cn>
+ */
+#include <linux/string.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/mtd/spinand.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
+
+struct merge_mtd_info {
+	struct mtd_info *merge_spinand_mtd[2];
+	int merge_mtd_count;
+};
+static struct merge_mtd_info merge_mtd = {0};
+
+struct mtd_info *merge_mtd_register(struct mtd_info *mtd)
+{
+	if (merge_mtd.merge_mtd_count < 2)
+		merge_mtd.merge_spinand_mtd[merge_mtd.merge_mtd_count++] = mtd;
+
+	return 0;
+}
+EXPORT_SYMBOL(merge_mtd_register);
+
+struct mtd_info *get_merge_mtd(int index)
+{
+	return merge_mtd.merge_spinand_mtd[index];
+}
+EXPORT_SYMBOL(get_merge_mtd);
+
+static inline loff_t second_chip_addr(loff_t from)
+{
+	return from - merge_mtd.merge_spinand_mtd[0]->size;
+}
+
+static inline int select_chip(loff_t from, size_t len)
+{
+	int chip;
+	loff_t size = merge_mtd.merge_spinand_mtd[0]->size;
+
+	if ((from + len) <= size)
+		chip = 0;
+	else if (from >= size)
+		chip = 1;
+	else
+		chip = 2;
+
+	return chip;
+}
+
+static int merge_nand_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+	int ret, chip;
+	struct erase_info *erase_idx = NULL;
+
+	erase_idx = instr;
+	erase_idx->fail_addr = 0;
+
+	chip = select_chip(erase_idx->addr, erase_idx->len);
+	if (chip == 0) {
+		ret = spinand_mtd_erase(merge_mtd.merge_spinand_mtd[chip], erase_idx);
+	} else if (chip == 1) {
+
+		/* second chip */
+		instr->addr = second_chip_addr(erase_idx->addr);
+		instr->len = erase_idx->len;
+		ret =
+			spinand_mtd_erase(merge_mtd.merge_spinand_mtd[chip], erase_idx);
+	} else {
+		size_t len;
+		/* cross boundary */
+		len = erase_idx->len;
+		erase_idx->len =
+			merge_mtd.merge_spinand_mtd[0]->size - erase_idx->addr;
+		ret = spinand_mtd_erase(merge_mtd.merge_spinand_mtd[0], erase_idx);
+		if (ret)
+			goto bail_out;
+		erase_idx->addr = 0;
+		erase_idx->len = len - erase_idx->len;
+		ret = spinand_mtd_erase(merge_mtd.merge_spinand_mtd[1], erase_idx);
+	}
+
+bail_out:
+	return ret;
+}
+
+static int merge_spinand_read_oob(struct mtd_info *mtd, loff_t from,
+			 struct mtd_oob_ops *ops)
+{
+	int ret, chip;
+	size_t len = 0;
+
+	if (ops->datbuf)
+		len = ops->len;
+	else {
+		pr_warn("This ops->datbuf is NULL!\n");
+		return 0;
+	}
+
+	chip = select_chip(from, len);
+	if (chip == 0) {
+		ret = spinand_mtd_read(merge_mtd.merge_spinand_mtd[chip], from, ops);
+	} else if (chip == 1) {
+		/* second chip */
+		ret = spinand_mtd_read(merge_mtd.merge_spinand_mtd[chip],
+					second_chip_addr(from), ops);
+	} else {
+		loff_t _from[2];
+		size_t orig_len = ops->len;
+		uint8_t	*orig_datbuf = ops->datbuf;
+		size_t	retlen[2];
+		size_t	oobretlen[2];
+
+		/* cross boundary */
+		WARN_ON(ops->datbuf == NULL);
+		_from[0] = from;
+		ops->len = merge_mtd.merge_spinand_mtd[0]->size - from;
+		ret = spinand_mtd_read(merge_mtd.merge_spinand_mtd[0], _from[0], ops);
+		retlen[0] = ops->retlen;
+		oobretlen[0] = ops->oobretlen;
+		if (ret) {
+			ops->len = orig_len;
+			pr_warn("first chip read oob %llu err %d, abort read second chip\n",
+						_from[0], ret);
+			goto bail_out;
+		}
+
+		_from[1] = 0;
+		ops->len = orig_len - ops->len;
+		ops->datbuf += (merge_mtd.merge_spinand_mtd[1]->size - from);
+		ret = spinand_mtd_read(merge_mtd.merge_spinand_mtd[1], _from[1], ops);
+		retlen[1] = ops->retlen;
+		oobretlen[1] = ops->oobretlen;
+		ops->len = orig_len;
+		ops->datbuf = orig_datbuf;
+		ops->retlen = retlen[0] + retlen[1];
+		ops->oobretlen = oobretlen[0] + oobretlen[1];
+	}
+bail_out:
+	return ret;
+}
+
+static int merge_spinand_write_oob(struct mtd_info *mtd, loff_t to,
+			 struct mtd_oob_ops *ops)
+{
+	int ret, chip;
+	size_t len = 0;
+
+	if (ops->datbuf)
+		len = ops->len;
+	else {
+		pr_warn("This ops->datbuf is NULL!\n");
+		return 0;
+	}
+
+	chip = select_chip(to, len);
+	if (chip == 0) {
+		ret =
+				spinand_mtd_write(merge_mtd.merge_spinand_mtd[chip], to, ops);
+	} else if (chip == 1) {
+		/* second chip */
+		ret = spinand_mtd_write(merge_mtd.merge_spinand_mtd[chip],
+					second_chip_addr(to), ops);
+	} else {
+		loff_t _to[2];
+		size_t orig_len = ops->len;
+		uint8_t	*orig_datbuf = ops->datbuf;
+		size_t	retlen[2];
+		size_t	oobretlen[2];
+
+		/* cross boundary */
+		WARN_ON(ops->datbuf == NULL);
+		_to[0] = to;
+		ops->len = merge_mtd.merge_spinand_mtd[0]->size - to;
+		ret = spinand_mtd_write(merge_mtd.merge_spinand_mtd[0], _to[0], ops);
+		retlen[0] = ops->retlen;
+		oobretlen[0] = ops->oobretlen;
+		if (ret) {
+			ops->len = orig_len;
+			pr_warn("first chip write oob %llu err %d, abort write second chip\n",
+						_to[0], ret);
+			goto bail_out;
+		}
+
+		_to[1] = 0;
+		ops->len = orig_len - ops->len;
+		ops->datbuf += (merge_mtd.merge_spinand_mtd[0]->size - to);
+		ret = spinand_mtd_write(merge_mtd.merge_spinand_mtd[1], _to[1], ops);
+		retlen[1] = ops->retlen;
+		oobretlen[1] = ops->oobretlen;
+		ops->len = orig_len;
+		ops->datbuf = orig_datbuf;
+		ops->retlen = retlen[0] + retlen[1];
+		ops->oobretlen = oobretlen[0] + oobretlen[1];
+	}
+bail_out:
+	return ret;
+}
+
+static int merge_spinand_block_isreserved(struct mtd_info *mtd, loff_t ofs)
+{
+	int chip = select_chip(ofs, 0);
+
+	if (chip == 0)
+		return spinand_mtd_block_isreserved(merge_mtd.merge_spinand_mtd[0], ofs);
+	else
+		return spinand_mtd_block_isreserved(merge_mtd.merge_spinand_mtd[1],
+					second_chip_addr(ofs));
+}
+
+static int merge_spinand_block_isbad(struct mtd_info *mtd, loff_t ofs)
+{
+	int chip = select_chip(ofs, 0);
+
+	if (chip == 0)
+		return spinand_mtd_block_isbad(merge_mtd.merge_spinand_mtd[0],
+						ofs);
+	else
+		return spinand_mtd_block_isbad(merge_mtd.merge_spinand_mtd[1],
+					second_chip_addr(ofs));
+}
+
+static int merge_spinand_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+	int chip = select_chip(ofs, 0);
+
+	if (chip == 0)
+		return spinand_mtd_block_markbad(merge_mtd.merge_spinand_mtd[0], ofs);
+	else
+		return spinand_mtd_block_markbad(merge_mtd.merge_spinand_mtd[1],
+					second_chip_addr(ofs));
+}
+
+static int merge_nanddev_mtd_max_bad_blocks(struct mtd_info *mtd,
+					loff_t offs, size_t len)
+{
+	int chip = select_chip(offs, len);
+
+	if (chip == 0)
+		return nanddev_mtd_max_bad_blocks(merge_mtd.merge_spinand_mtd[0],
+						offs, len);
+	else
+		return nanddev_mtd_max_bad_blocks(merge_mtd.merge_spinand_mtd[1],
+					second_chip_addr(offs), len);
+}
+
+static int merge_mtds(void)
+{
+	int ret = 0;
+	struct mtd_info *merge_dev = NULL;
+
+	merge_dev = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
+	if (!merge_dev) {
+		pr_warn("The reason of merge failure\n");
+		ret = -ENOMEM;
+		return ret;
+	}
+
+	merge_dev->name = "merge_mtd";
+	merge_dev->size =
+		merge_mtd.merge_spinand_mtd[0]->size + merge_mtd.merge_spinand_mtd[1]->size;
+
+	if (merge_mtd.merge_spinand_mtd[0]->erasesize ==
+				merge_mtd.merge_spinand_mtd[1]->erasesize)
+		merge_dev->erasesize = merge_mtd.merge_spinand_mtd[0]->erasesize;
+	else {
+		pr_warn("error: These two spinands have different erasesize!\n");
+		return -1;
+	}
+
+	if (merge_mtd.merge_spinand_mtd[0]->writesize ==
+				merge_mtd.merge_spinand_mtd[1]->writesize)
+		merge_dev->writesize = merge_mtd.merge_spinand_mtd[0]->writesize;
+	else {
+		pr_warn("error: These two spinands have different writesize!\n");
+		return -1;
+	}
+	merge_dev->writebufsize = merge_mtd.merge_spinand_mtd[0]->writebufsize;
+	merge_dev->type = MTD_NANDFLASH;
+	merge_dev->flags = MTD_CAP_NANDFLASH;
+	merge_dev->_read_oob = merge_spinand_read_oob;
+	merge_dev->_write_oob = merge_spinand_write_oob;
+	merge_dev->_block_isbad = merge_spinand_block_isbad;
+	merge_dev->_block_markbad = merge_spinand_block_markbad;
+	merge_dev->_block_isreserved = merge_spinand_block_isreserved;
+	merge_dev->_erase = merge_nand_erase;
+	merge_dev->_max_bad_blocks = merge_nanddev_mtd_max_bad_blocks;
+
+	mtd_device_register(merge_dev, NULL, 0);
+	pr_notice("mtd%d: [%s] erase_size = %dKiB [%d], total_size = %lldKiB [%lld] ",
+				merge_dev->index,
+				merge_dev->name + strlen("merge_mtd: "),
+				merge_dev->erasesize >> 10, merge_dev->erasesize,
+				merge_dev->size >> 10, merge_dev->size);
+
+	return 0;
+}
+
+static int __init merge_mtd_init(void)
+{
+	int ret = 0;
+
+	pr_notice("merge starting...\n");
+
+	if (merge_mtd.merge_spinand_mtd[0] == NULL ||
+				merge_mtd.merge_spinand_mtd[1] == NULL) {
+		pr_warn("whoo...can not get any mtd device\n");
+		return -1;
+	}
+
+	if (merge_mtd.merge_spinand_mtd[0]->name == NULL ||
+		merge_mtd.merge_spinand_mtd[1]->name == NULL) {
+		pr_warn("error:Can not get mtd device name.");
+		pr_warn("the first spinand name:%s, second spinand name:%s.\n",
+			merge_mtd.merge_spinand_mtd[0]->name, merge_mtd.merge_spinand_mtd[1]->name);
+		return -1;
+	}
+	pr_notice("merge_spinand_mtd[0]->name = %s, merge_mtd.merge_spinand_mtd[1]->name = %s\n",
+		merge_mtd.merge_spinand_mtd[0]->name, merge_mtd.merge_spinand_mtd[1]->name);
+
+
+	ret = merge_mtds();
+
+	return ret;
+}
+
+
+static void merge_mtd_exit(void)
+{
+	pr_notice("exit ");
+	mtd_device_unregister(merge_mtd.merge_spinand_mtd[0]);
+	mtd_device_unregister(merge_mtd.merge_spinand_mtd[1]);
+}
+
+late_initcall(merge_mtd_init);
+module_exit(merge_mtd_exit);
+
+MODULE_DESCRIPTION("Merge two spi nand chips under one mtd device");
+MODULE_AUTHOR("renxiaohui <ren.xiaohui at zte.com.cn>");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 6988956..9c5fb0f 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -504,12 +504,24 @@ static inline void spinand_set_of_node(struct spinand_device *spinand,
 	nanddev_set_of_node(&spinand->base, np);
 }
 
-int spinand_match_and_init(struct spinand_device *spinand,
+
+struct mtd_info *merge_mtd_register(struct mtd_info *mtd);
+struct mtd_info *get_merge_mtd(int index);
+
+int spinand_match_and_init(struct spinand_device *dev,
 			   const struct spinand_info *table,
 			   unsigned int table_size,
 			   enum spinand_readid_method rdid_method);
 
 int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
 int spinand_select_target(struct spinand_device *spinand, unsigned int target);
+int spinand_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo);
+int spinand_mtd_block_isreserved(struct mtd_info *mtd, loff_t offs);
+int spinand_mtd_block_markbad(struct mtd_info *mtd, loff_t offs);
+int spinand_mtd_block_isbad(struct mtd_info *mtd, loff_t offs);
+int spinand_mtd_write(struct mtd_info *mtd, loff_t to,
+			     struct mtd_oob_ops *ops);
+int spinand_mtd_read(struct mtd_info *mtd, loff_t from,
+			    struct mtd_oob_ops *ops);
 
 #endif /* __LINUX_MTD_SPINAND_H */
-- 
2.15.2




From boris.brezillon at collabora.com  Wed Sep 22 23:42:44 2021
From: boris.brezillon at collabora.com (Boris Brezillon)
Date: Thu, 23 Sep 2021 08:42:44 +0200
Subject: [PATCH] mtd: spinand: add merge-two-spinand function
In-Reply-To: <20210923015241.248910-1-ren.xiaohui@zte.com.cn>
References: <20210923015241.248910-1-ren.xiaohui@zte.com.cn>
Message-ID: <20210923084244.54a6a899@collabora.com>

On Thu, 23 Sep 2021 01:52:41 +0000
CGEL <cgel.zte at gmail.com> wrote:

> From: Ren Xiaohui <ren.xiaohui at zte.com.cn>
> 
> Combine the two SPI NAND flash in the MTD layer

Just had a quick look, but it looks like you're re-implementing
mtdconcat. Maybe you should just extend mtdconcat to cover your use
cases.


From hca at linux.ibm.com  Thu Sep 23 01:52:08 2021
From: hca at linux.ibm.com (Heiko Carstens)
Date: Thu, 23 Sep 2021 10:52:08 +0200
Subject: [PATCH 7/9] s390/block/dcssblk: add error handling support for
 add_disk()
In-Reply-To: <YT+B+vCUcpZEq8hM@bombadil.infradead.org>
References: <20210902174105.2418771-1-mcgrof@kernel.org>
 <20210902174105.2418771-8-mcgrof@kernel.org>
 <YTIscKy+jg5L/TMh@osiris> <YTLP8mYBX37R++9E@bombadil.infradead.org>
 <20210906134346.19c14246@thinkpad>
 <YT+B+vCUcpZEq8hM@bombadil.infradead.org>
Message-ID: <YUxAOKY7dXZAABhI@osiris>

On Mon, Sep 13, 2021 at 09:53:14AM -0700, Luis Chamberlain wrote:
> On Mon, Sep 06, 2021 at 01:43:46PM +0200, Gerald Schaefer wrote:
> > On Fri, 3 Sep 2021 18:46:26 -0700
> > Luis Chamberlain <mcgrof at kernel.org> wrote:
> > 
> > > On Fri, Sep 03, 2021 at 04:08:48PM +0200, Heiko Carstens wrote:
> > > > On Thu, Sep 02, 2021 at 10:41:03AM -0700, Luis Chamberlain wrote:
> > > > > We never checked for errors on add_disk() as this function
> > > > > returned void. Now that this is fixed, use the shiny new
> > > > > error handling.
> > > > > 
> > > > > Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
> > > > > ---
> > > > >  drivers/s390/block/dcssblk.c | 4 +++-
> > > > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
> > > > > index 5be3d1c39a78..b0fd5009a12e 100644
> > > > > --- a/drivers/s390/block/dcssblk.c
> > > > > +++ b/drivers/s390/block/dcssblk.c
> > > > > @@ -696,7 +696,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
> > > > >  	}
> > > > >  
> > > > >  	get_device(&dev_info->dev);
> > > > > -	device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> > > > > +	rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL);
> > > > > +	if (rc)
> > > > > +		goto put_dev;
> > > > 
> > > > This looks not correct to me. We seem to have now in case of an error:
> > > > 
> > > > - reference count imbalance (= memory leak)
> > > > - dax cleanup is missing
> > > 
> > > Care to provide an alternative?
> > 
> > See patch below:
> 
> Thanks! Will you queue this up on your end or do would you
> prefer for me to roll this into my tree and eventually resend
> with the rest?

Please add the patch to your tree.


From robh at kernel.org  Thu Sep 23 09:56:24 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 23 Sep 2021 11:56:24 -0500
Subject: [PATCH 2/3] dts: socfpga: Add Mercury+ AA1 devicetree
In-Reply-To: <20210920124140.u56dOOGofORjfYeTSsKGqD2HNw-7gu5UqvN2ocHwr-g@z>
References: <20210920124141.1166544-1-pan@semihalf.com>
 <20210920124140.u56dOOGofORjfYeTSsKGqD2HNw-7gu5UqvN2ocHwr-g@z>
Message-ID: <YUyxuIVcjS5h+3cT@robh.at.kernel.org>

On Mon, Sep 20, 2021 at 02:41:40PM +0200, Pawe? Anikiel wrote:
> Add support for the Mercury+ AA1 module for Arria 10 SoC FPGA.
> 
> Signed-off-by: Pawe? Anikiel <pan at semihalf.com>
> Signed-off-by: Joanna Brozek <jbrozek at antmicro.com>
> Signed-off-by: Mariusz Glebocki <mglebocki at antmicro.com>
> Signed-off-by: Tomasz Gorochowik <tgorochowik at antmicro.com>
> Signed-off-by: Maciej Mikunda <mmikunda at antmicro.com>
> ---
>  arch/arm/boot/dts/Makefile                    |   1 +
>  .../boot/dts/socfpga_arria10_mercury_aa1.dts  | 127 ++++++++++++++++++
>  2 files changed, 128 insertions(+)
>  create mode 100644 arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 7e0934180724..0a7809eb3795 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1078,6 +1078,7 @@ dtb-$(CONFIG_ARCH_INTEL_SOCFPGA) += \
>  	socfpga_arria10_socdk_nand.dtb \
>  	socfpga_arria10_socdk_qspi.dtb \
>  	socfpga_arria10_socdk_sdmmc.dtb \
> +	socfpga_arria10_mercury_aa1.dtb \
>  	socfpga_cyclone5_chameleon96.dtb \
>  	socfpga_cyclone5_mcvevk.dtb \
>  	socfpga_cyclone5_socdk.dtb \
> diff --git a/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts b/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts
> new file mode 100644
> index 000000000000..c13f16afa72f
> --- /dev/null
> +++ b/arch/arm/boot/dts/socfpga_arria10_mercury_aa1.dts
> @@ -0,0 +1,127 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/dts-v1/;
> +
> +#include "socfpga_arria10.dtsi"
> +
> +/ {
> +
> +	model = "Enclustra Mercury AA1";
> +	compatible = "altr,socfpga-arria10", "altr,socfpga";
> +
> +	aliases {
> +		ethernet0 = &gmac0;
> +		serial1 = &uart1;
> +	};
> +
> +	memory {

memory at 0

> +		name = "memory";
> +		device_type = "memory";
> +		reg = <0x0 0x80000000>; /* 2GB */
> +	};
> +
> +	chosen {
> +		stdout-path = "serial1:115200n8";
> +	};
> +};
> +
> +&osc1 {
> +	clock-frequency = <33330000>;
> +};
> +
> +&usb0 {
> +	status = "okay";
> +	dr_mode = "host";
> +};
> +
> +/* Following mappings are taken from arria10 socdk dts */
> +&mmc {
> +	status = "okay";
> +	cap-sd-highspeed;
> +	broken-cd;
> +	bus-width = <4>;
> +};
> +
> +&eccmgr {
> +	sdmmca-ecc at ff8c2c00 {
> +		compatible = "altr,socfpga-sdmmc-ecc";
> +		reg = <0xff8c2c00 0x400>;
> +		altr,ecc-parent = <&mmc>;
> +		interrupts = <15 IRQ_TYPE_LEVEL_HIGH>,
> +			     <47 IRQ_TYPE_LEVEL_HIGH>,
> +			     <16 IRQ_TYPE_LEVEL_HIGH>,
> +			     <48 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +};
> +
> +&gmac0 {
> +	phy-mode = "rgmii";
> +	phy-addr = <0xffffffff>; /* probe for phy addr */
> +
> +	max-frame-size = <3800>;
> +	status = "okay";
> +
> +	phy-handle = <&phy3>;
> +
> +	mdio0 {

'mdio' doesn't work?

> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		compatible = "snps,dwmac-mdio";
> +		phy3: ethernet-phy at 3 {
> +			txd0-skew-ps = <0>; /* -420ps */
> +			txd1-skew-ps = <0>; /* -420ps */
> +			txd2-skew-ps = <0>; /* -420ps */
> +			txd3-skew-ps = <0>; /* -420ps */
> +			rxd0-skew-ps = <420>; /* 0ps */
> +			rxd1-skew-ps = <420>; /* 0ps */
> +			rxd2-skew-ps = <420>; /* 0ps */
> +			rxd3-skew-ps = <420>; /* 0ps */
> +			txen-skew-ps = <0>; /* -420ps */
> +			txc-skew-ps = <1860>; /* 960ps */
> +			rxdv-skew-ps = <420>; /* 0ps */
> +			rxc-skew-ps = <1680>; /* 780ps */
> +			reg = <3>;
> +		};
> +	};
> +};
> +
> +&i2c1 {
> +	status = "okay";
> +	isl12022: isl12022 at 6f {
> +		status = "okay";
> +		compatible = "isil,isl12022";
> +		reg = <0x6f>;
> +	};
> +};
> +
> +&uart1 {
> +	status = "okay";
> +};
> +
> +&qspi {
> +	status = "disabled";
> +
> +	flash0: n25q00 at 0 {

flash at 0

> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "n25q00";
> +		reg = <0>;
> +		spi-max-frequency = <50000000>;
> +		cdns,page-size = <256>;
> +		cdns,block-size = <16>;
> +		m25p,fast-read;
> +		cdns,read-delay = <4>;
> +		cdns,tshsl-ns = <200>;
> +		cdns,tsd2d-ns = <255>;
> +		cdns,tchsh-ns = <20>;
> +		cdns,tslch-ns = <20>;
> +
> +		part0: qspi-boot at 0 {

Put these under a 'partitions' node.

> +			label = "Flash 0 Raw Data";
> +			reg = <0x0 0x01340000>;
> +		};
> +		part1: qspi-rootfs at 1320000 {
> +			label = "Flash 1 jffs2 Filesystem";
> +			reg = <0x01340000 0x2cc0000>;
> +		};
> +	};
> +};
> -- 
> 2.25.1
> 
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/


From robh at kernel.org  Thu Sep 23 09:56:48 2021
From: robh at kernel.org (Rob Herring)
Date: Thu, 23 Sep 2021 11:56:48 -0500
Subject: [PATCH 1/3] dt-bindings: mtd: spi-nor: add n25q00 schema
In-Reply-To: <20210920124141.1166544-2-pan@semihalf.com>
References: <20210920124141.1166544-1-pan@semihalf.com>
 <20210920124141.1166544-2-pan@semihalf.com>
Message-ID: <YUyx0K9M7wspVl+E@robh.at.kernel.org>

On Mon, 20 Sep 2021 14:41:39 +0200, Pawe? Anikiel wrote:
> Add schema for the n25q00 NOR flash memory.
> 
> Signed-off-by: Pawe? Anikiel <pan at semihalf.com>
> ---
>  Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Acked-by: Rob Herring <robh at kernel.org>


From p.yadav at ti.com  Thu Sep 23 11:59:04 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Fri, 24 Sep 2021 00:29:04 +0530
Subject: [PATCH 1/3] dt-bindings: mtd: spi-nor: add n25q00 schema
In-Reply-To: <20210920124141.1166544-2-pan@semihalf.com>
References: <20210920124141.1166544-1-pan@semihalf.com>
 <20210920124141.1166544-2-pan@semihalf.com>
Message-ID: <20210923185902.6wgkuz4jcelcawrq@ti.com>

+Tudor

On 20/09/21 02:41PM, Pawe? Anikiel wrote:
> Add schema for the n25q00 NOR flash memory.
> 
> Signed-off-by: Pawe? Anikiel <pan at semihalf.com>
> ---
>  Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
> index ed590d7c6e37..efb3c5e05c5a 100644
> --- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
> +++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
> @@ -18,7 +18,7 @@ properties:
>        - items:
>            - pattern: "^((((micron|spansion|st),)?\
>                (m25p(40|80|16|32|64|128)|\
> -              n25q(32b|064|128a11|128a13|256a|512a|164k)))|\
> +              n25q(00|32b|064|128a11|128a13|256a|512a|164k)))|\

IIUC this is supposed to only be for legacy/old flashes that started out 
using flash-specific compatibles. Any new flashes should simply use 
jedec,spi-nor unless there is a legitimate reason to do so.

Until you justify that reason,

Nacked-by: Pratyush Yadav <p.yadav at ti.com>

>                atmel,at25df(321a|641|081a)|\
>                everspin,mr25h(10|40|128|256)|\
>                (mxicy|macronix),mx25l(4005a|1606e|6405d|8005|12805d|25635e)|\
> -- 
> 2.25.1

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From p.yadav at ti.com  Thu Sep 23 12:10:26 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Fri, 24 Sep 2021 00:40:26 +0530
Subject: [PATCH] MAINTAINERS: Add spi-nor device tree binding under SPI NOR
 maintainers
Message-ID: <20210923191026.19184-1-p.yadav@ti.com>

The binding is for the SPI NOR subsystem so the patches should be sent
to its maintainers. Currently the patches get sent to Rob Herring and
MTD maintainers who might not always have the full picture.

Signed-off-by: Pratyush Yadav <p.yadav at ti.com>
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2bfdb06fe2b3..d64912d7e9f5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17745,6 +17745,7 @@ W:	http://www.linux-mtd.infradead.org/
 Q:	http://patchwork.ozlabs.org/project/linux-mtd/list/
 C:	irc://irc.oftc.net/mtd
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git spi-nor/next
+F:	Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
 F:	drivers/mtd/spi-nor/
 F:	include/linux/mtd/spi-nor.h
 
-- 
2.33.0



From broonie at kernel.org  Thu Sep 23 12:48:24 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 23 Sep 2021 20:48:24 +0100
Subject: [PATCH v1 0/3] mtd: Ensure DT compatibles have SPI device IDs
Message-ID: <20210923194827.53229-1-broonie@kernel.org>

Currently autoloading for SPI devices does not use the DT ID table, it uses
SPI modalises. Supporting OF modalises is going to be difficult if not
impractical, an attempt was made but has been reverted, so this series
adds SPI IDs where they aren't provided for a given modalias.

Mark Brown (3):
  mtd: dataflash: Add SPI ID table
  mtd: mchp23k256: Add SPI ID table
  mtd: mchp48l640: Add SPI ID table

 drivers/mtd/devices/mchp23k256.c    | 14 ++++++++++++++
 drivers/mtd/devices/mchp48l640.c    | 10 ++++++++++
 drivers/mtd/devices/mtd_dataflash.c |  8 ++++++++
 3 files changed, 32 insertions(+)


base-commit: e73f0f0ee7541171d89f2e2491130c7771ba58d3
-- 
2.20.1



From broonie at kernel.org  Thu Sep 23 12:48:25 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 23 Sep 2021 20:48:25 +0100
Subject: [PATCH v1 1/3] mtd: dataflash: Add SPI ID table
In-Reply-To: <20210923194827.53229-1-broonie@kernel.org>
References: <20210923194827.53229-1-broonie@kernel.org>
Message-ID: <20210923194827.53229-2-broonie@kernel.org>

Currently autoloading for SPI devices does not use the DT ID table, it uses
SPI modalises. Supporting OF modalises is going to be difficult if not
impractical, an attempt was made but has been reverted, so ensure that
module autoloading works for this driver by adding an id_table listing the
SPI IDs for everything.

Fixes: 96c8395e2166 ("spi: Revert modalias changes")
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 drivers/mtd/devices/mtd_dataflash.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 9802e265fca8..9fc0146013ee 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -105,6 +105,13 @@ static const struct of_device_id dataflash_dt_ids[] = {
 MODULE_DEVICE_TABLE(of, dataflash_dt_ids);
 #endif
 
+static const struct spi_device_id dataflash_spi_ids[] = {
+	{ .name = "at45", },
+	{ .name = "dataflash", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(spi, dataflash_spi_ids);
+
 /* ......................................................................... */
 
 /*
@@ -930,6 +937,7 @@ static struct spi_driver dataflash_driver = {
 
 	.probe		= dataflash_probe,
 	.remove		= dataflash_remove,
+	.id_table	= dataflash_spi_ids,
 
 	/* FIXME:  investigate suspend and resume... */
 };
-- 
2.20.1



From broonie at kernel.org  Thu Sep 23 12:48:26 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 23 Sep 2021 20:48:26 +0100
Subject: [PATCH v1 2/3] mtd: mchp23k256: Add SPI ID table
In-Reply-To: <20210923194827.53229-1-broonie@kernel.org>
References: <20210923194827.53229-1-broonie@kernel.org>
Message-ID: <20210923194827.53229-3-broonie@kernel.org>

Currently autoloading for SPI devices does not use the DT ID table, it uses
SPI modalises. Supporting OF modalises is going to be difficult if not
impractical, an attempt was made but has been reverted, so ensure that
module autoloading works for this driver by adding an id_table listing the
SPI IDs for everything.

Fixes: 96c8395e2166 ("spi: Revert modalias changes")
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 drivers/mtd/devices/mchp23k256.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mtd/devices/mchp23k256.c b/drivers/mtd/devices/mchp23k256.c
index 77c872fd3d83..7d188cdff6a2 100644
--- a/drivers/mtd/devices/mchp23k256.c
+++ b/drivers/mtd/devices/mchp23k256.c
@@ -229,6 +229,19 @@ static const struct of_device_id mchp23k256_of_table[] = {
 };
 MODULE_DEVICE_TABLE(of, mchp23k256_of_table);
 
+static const struct spi_device_id mchp23k256_spi_ids[] = {
+	{
+		.name = "mchp23k256",
+		.driver_data = (kernel_ulong_t)&mchp23k256_caps,
+	},
+	{
+		.name = "mchp23lcv1024",
+		.driver_data = (kernel_ulong_t)&mchp23lcv1024_caps,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(spi, mchp23k256_spi_ids);
+
 static struct spi_driver mchp23k256_driver = {
 	.driver = {
 		.name	= "mchp23k256",
@@ -236,6 +249,7 @@ static struct spi_driver mchp23k256_driver = {
 	},
 	.probe		= mchp23k256_probe,
 	.remove		= mchp23k256_remove,
+	.id_table	= mchp23k256_spi_ids,
 };
 
 module_spi_driver(mchp23k256_driver);
-- 
2.20.1



From broonie at kernel.org  Thu Sep 23 12:48:27 2021
From: broonie at kernel.org (Mark Brown)
Date: Thu, 23 Sep 2021 20:48:27 +0100
Subject: [PATCH v1 3/3] mtd: mchp48l640: Add SPI ID table
In-Reply-To: <20210923194827.53229-1-broonie@kernel.org>
References: <20210923194827.53229-1-broonie@kernel.org>
Message-ID: <20210923194827.53229-4-broonie@kernel.org>

Currently autoloading for SPI devices does not use the DT ID table, it uses
SPI modalises. Supporting OF modalises is going to be difficult if not
impractical, an attempt was made but has been reverted, so ensure that
module autoloading works for this driver by adding an id_table listing the
SPI IDs for everything.

Fixes: 96c8395e2166 ("spi: Revert modalias changes")
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 drivers/mtd/devices/mchp48l640.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/mtd/devices/mchp48l640.c b/drivers/mtd/devices/mchp48l640.c
index efc2003bd13a..3434322dad58 100644
--- a/drivers/mtd/devices/mchp48l640.c
+++ b/drivers/mtd/devices/mchp48l640.c
@@ -356,6 +356,15 @@ static const struct of_device_id mchp48l640_of_table[] = {
 };
 MODULE_DEVICE_TABLE(of, mchp48l640_of_table);
 
+static const struct spi_device_id mchp48l640_spi_ids[] = {
+	{
+		.name = "48l640",
+		.driver_data = (kernel_ulong_t)&mchp48l640_caps,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(spi, mchp48l640_spi_ids);
+
 static struct spi_driver mchp48l640_driver = {
 	.driver = {
 		.name	= "mchp48l640",
@@ -363,6 +372,7 @@ static struct spi_driver mchp48l640_driver = {
 	},
 	.probe		= mchp48l640_probe,
 	.remove		= mchp48l640_remove,
+	.id_table	= mchp48l640_spi_ids,
 };
 
 module_spi_driver(mchp48l640_driver);
-- 
2.20.1



From xiangsheng.hou at mediatek.com  Fri Sep 24 00:05:39 2021
From: xiangsheng.hou at mediatek.com (xiangsheng.hou)
Date: Fri, 24 Sep 2021 15:05:39 +0800
Subject: Mediatek SPI Nand controller driver design for upstream
In-Reply-To: <SG2PR03MB4565B0B2724EA7A0F3F3A9ECF9CD9@SG2PR03MB4565.apcprd03.prod.outlook.com>
References: <7657953e8f5948b1959124e8f13ed1d1@MTKMBS31N1.mediatek.inc>
 <20210622230925.2c4f535a@xps13>
 <65cadbd0c9a34cc6bcf0f3216f983ef2@MTKMBS31N1.mediatek.inc>
 <20210630134353.5b5d65f3@xps13>
 <e6a457fdef0f40789c1d375ba8129199@MTKMBS31N1.mediatek.inc>
 <20210823173235.214228d1@xps13>
 <SG2PR03MB4565B0B2724EA7A0F3F3A9ECF9CD9@SG2PR03MB4565.apcprd03.prod.outlook.com>
Message-ID: <f8f837ad3e4f4e6a3aead2d56b26812635231407.camel@mediatek.com>

Retitle

Hi Miquel,

As talked before, I developed the 1st driver for Mediatek SPI Nand
controller. However, there have performance issue in 1st version(read
speed reduce 42% and write speed reduce 15%).

The controller consists of two parts snfi(stand for serial nand flash
interface) for spim and hw ecc for generic ecc engine. They can cowrok
or work independent.

The 1st driver realized in the way of working independently, due to the
cowork need get nand parameter(page size and spare size) for snfi and
hw ecc. However, the snfi in spi subsystem seems difficult to get nand
parameter.

Therefore, I thought of two ways let snfi in spi subsystem get nand
parameter to improve performance.

1) Export some function in mediatek hw ecc driver. And called by snfi
driver in spi subsystem to let snfi get nand parameter and ecc disable
or not.

2) Add snfi reg in ecc dts node, config snfi regs(get by of_iomap) with
nand parameter in hw ecc driver. And snfi driver parse nand parameter
in snfi regs to use.

May I have your opinion about whether they are suitable and which maybe
better.

Thanks

On Wed, 2021-09-01 at 18:20 +0800, Xiangsheng Hou (???) wrote:
> Hi Miquel,
> 
> > Actually I don't have the time to dig into this problem, would you
> > mind proposing a patch on the mailing list? Or maybe if you don't
> > have the resources internally we could open a contracting
> > discussion?
> 
> I`m coding and testing based on Mediatek SPI Nand controller by some
> workaround with the auto oob issue for now.  
> I will check the issue thoroughly, but use HW ECC on my board.
> 
> In addition,  I found performance issue when force Mediatek SPI Nand
> controller fit to current ECC & SPI Nand  & SPI Mem framework.
> 
> 1. Introduction about Mediatek SPI Nand controller
> The Mediatek SPI Nand controller consists of two parts HW ECC and nfi
> (stand for nand flash interface)
> The HW ECC have 3 source data mode:
> 1) pio mode: means source data is written by MCU
> 2) dma mode: means source data from AHB Bus
> 3) nfi mode: means source data from NFI module, can automatically
> generate ECC syndrome bits when programming or reading the device.
> 
> 2. ECC nfi mode & dma mode data flow
> 1) dma mode (read flow for example)
> 
> The HW ECC engine get source data after the nfi engine get data from
> nand device. And, the HW ECC engine decode/encode data by sector for
> each.
> 
> 2)nfi mode(read flow for example)
>                              
> The nfi and HW ECC can cooperation with HW share buf in nfi mode
> without another dma transfer. 
> HW ECC can get source data and decode/encode during nfi data
> transmission from nand device.
> And, the HW ECC engine decode/encode by sector in pipeline.
> 
> 3. Current driver implementation
> Mode 1) & 2) means the HW ECC engine can work independent to nfi
> engine. HW ECC responsible for data encode/decode. nfi responsible
> for data transfer.
> These look like can fit to current SPI Nand framework. The HW ECC
> driver realize the ecc engine at mtd layer, the nfi realize spi
> driver at spi layer.
> Of course, the ecc driver choose the mode 2) dma mode for high
> performance.
> 
> 4.Performance comparison
> However, the ecc and nfi driver which fit to upstream framework have
> poor performance compare with the driver(private driver direct
> realize mtd function ) use ECC nfi mode which not fit framework.
> Take some performance information tested by mtd_speedtest, read speed
> reduce 42% and write speed reduce 15%.
> 
> May I have your some suggestion for the performance issue with the
> realization of Mediatek SPI Nand controller driver.
> 
> Thanks
> Xiangsheng Hou

From krzysztof.kozlowski at canonical.com  Fri Sep 24 06:32:23 2021
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 24 Sep 2021 15:32:23 +0200
Subject: [PATCH] mtd: onenand: samsung: drop Exynos4 and describe driver in
 KConfig
Message-ID: <20210924133223.111930-1-krzysztof.kozlowski@canonical.com>

None of supported Samsung Exynos4 SoCs (Exynos4210, Exynos4412) seem to
use OneNAND driver so drop it.  Describe better which driver applies to
which SoC, to make configuring kernel for Samsung SoC easier.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 drivers/mtd/nand/onenand/Kconfig | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/onenand/Kconfig b/drivers/mtd/nand/onenand/Kconfig
index 1a0e65bc246e..34d9a7a82ad4 100644
--- a/drivers/mtd/nand/onenand/Kconfig
+++ b/drivers/mtd/nand/onenand/Kconfig
@@ -33,11 +33,12 @@ config MTD_ONENAND_OMAP2
 
 config MTD_ONENAND_SAMSUNG
 	tristate "OneNAND on Samsung SOC controller support"
-	depends on ARCH_S3C64XX || ARCH_S5PV210 || ARCH_EXYNOS4 || COMPILE_TEST
+	depends on ARCH_S3C64XX || ARCH_S5PV210 || COMPILE_TEST
 	help
-	  Support for a OneNAND flash device connected to an Samsung SOC.
-	  S3C64XX uses command mapping method.
-	  S5PC110/S5PC210 use generic OneNAND method.
+	  Support for a OneNAND flash device connected to Samsung S3C64XX
+	  (using command mapping method) and S5PC110/S5PC210 (using generic
+	  OneNAND method) SoCs.
+	  Choose Y here only if you build for such Samsung SoC.
 
 config MTD_ONENAND_OTP
 	bool "OneNAND OTP Support"
-- 
2.30.2



From p.yadav at ti.com  Fri Sep 24 11:07:05 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Fri, 24 Sep 2021 23:37:05 +0530
Subject: [PATCH v1] dt-bindings: mtd: spi-nor: use unevaluatedProperties: false
Message-ID: <20210924180705.14021-1-p.yadav@ti.com>

Many SPI controllers need to add properties to slave devices. This could
be the delay in clock or data lines, etc. These properties are
controller specific but need to be defined in the slave node because
they are per-slave and there can be multiple slaves attached to a
controller.

If these properties are not added to the slave binding, then the dtbs
check emits a warning. But these properties do not make much sense in
the slave binding because they are controller-specific and they will
just pollute every slave binding.

One option is to add a separate schema that collects all such properties
from all such controllers. Slave bindings can simply refer to this
binding and they should be rid of the warnings.

There are some limitations with this approach:

1. There is no way to specify required properties. The schema would
contain properties for all controllers and there would be no way to know
which controller is being used.

2. There would be no way to restrict additional properties. Since this
schema will be used with an allOf operator, additionalProperties would
need to be true. In addition, the slave schema will have to set
unevaluatedProperties: false.

A much simpler option would be to make controller schemas specify those
properties in patternProperties and set unevaluatedProperties to false
on slave schemas, which is done in the previous approach anyway. This
approach would have the same limitations as the 2nd limitation in the
previous approach. But it does not have the 1st limitation since the
properties of all controllers are not collected in a single schema, but
instead reside in the same schema as the controller. It also has the
added benefit of being much simpler.

The SPI NOR binding is taken as the first one to follow this. Other
bindings like SPI NAND can follow in later patches.

Signed-off-by: Pratyush Yadav <p.yadav at ti.com>

---
I sent the first approach mentioned in the commit message some time ago
[0]. When re-rolling this series I realized that if we are going to use
unevaluatedProperties: false, then it would be much simpler to just keep
everything else as-is. This has clear positives with no negatives
relative to [0], as explained in the commit message.

[0] https://lore.kernel.org/all/20210609111707.9555-1-p.yadav at ti.com/T/#u

 Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
index ed590d7c6e37..81be0620b264 100644
--- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
+++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
@@ -88,7 +88,7 @@ patternProperties:
   "^otp(-[0-9]+)?$":
     type: object

-additionalProperties: false
+unevaluatedProperties: false

 examples:
   - |
--
2.33.0



From xiangsheng.hou at mediatek.com  Sun Sep 26 22:36:25 2021
From: xiangsheng.hou at mediatek.com (Xiangsheng Hou)
Date: Mon, 27 Sep 2021 13:36:25 +0800
Subject: [RFC,v1 0/4] Add a driver for Mediatek SPI Nand controller
Message-ID: <20210927053629.17847-1-xiangsheng.hou@mediatek.com>

Add a driver for Mediatek SPI Nand controller

Mediatek SPI Nand controller cosists of two parts: on-host HW ECC and
snfi(stand for spi nand flash interface). They can cowork with high
performance which called ECC nfi mode. The nfi stand for nand flash
interfacei(snfi a one part of nfi) which can support SPI Nand flash
and raw nand flash.

However, the snfi driver in spi subsytem need to be aware of nand
parameter(page/spare size) and ecc status(enable/disable) when work
at ECC nfi mode. The snfi driver in spi subsystem seems difficult to
know these.

Therefore, consider two ways to let snfi can get these information.
The RFC patch send to review whether they are suitable and which
solution maybe better.

RFC patch v1:
Add nfi register base at bch(ecc) dts node and config nand parameter
and ecc status into nfi registers in ecc driver, then parse these
information at snfi driver to use.

RFC patch v2:
Export some function in HW ECC driver and snfi driver.
In HW ECC driver, export function include get nand page/spare size, HW
ECC status(enable/disable) and fdm(oob free per sector in ooblayout) size.
In snfi driver need export empty page status which the nfi can be aware
when in ECC nfi mode(the spim framework can not return this information).

This series patch is the v1 solution, and only take mt7622 board for dts
node example.

Xiangsheng Hou (4):
  mtd: ecc: move mediatek HW ECC driver
  mtd: ecc: realize Mediatek HW ECC driver
  spi: add Mediatek SPI Nand controller driver
  arm64: dts: add snfi node for spi nand

 arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts  |   16 +
 arch/arm64/boot/dts/mediatek/mt7622.dtsi      |   15 +-
 drivers/mtd/nand/Kconfig                      |    9 +
 drivers/mtd/nand/Makefile                     |    1 +
 drivers/mtd/nand/core.c                       |    2 +-
 drivers/mtd/nand/ecc.c                        |   19 +
 drivers/mtd/nand/{raw => }/mtk_ecc.c          |  321 ++++-
 drivers/mtd/nand/raw/Kconfig                  |    1 +
 drivers/mtd/nand/raw/Makefile                 |    2 +-
 drivers/mtd/nand/raw/mtk_nand.c               |    2 +-
 drivers/spi/Kconfig                           |   11 +
 drivers/spi/Makefile                          |    1 +
 drivers/spi/spi-mtk-snfi.c                    | 1043 +++++++++++++++++
 .../nand/raw => include/linux/mtd}/mtk_ecc.h  |    0
 include/linux/mtd/nand.h                      |   12 +
 15 files changed, 1450 insertions(+), 5 deletions(-)
 rename drivers/mtd/nand/{raw => }/mtk_ecc.c (63%)
 create mode 100644 drivers/spi/spi-mtk-snfi.c
 rename {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h (100%)

-- 
2.25.1



From xiangsheng.hou at mediatek.com  Sun Sep 26 22:36:29 2021
From: xiangsheng.hou at mediatek.com (Xiangsheng Hou)
Date: Mon, 27 Sep 2021 13:36:29 +0800
Subject: [RFC,v1 4/4] arm64: dts: add snfi node for spi nand
In-Reply-To: <20210927053629.17847-1-xiangsheng.hou@mediatek.com>
References: <20210927053629.17847-1-xiangsheng.hou@mediatek.com>
Message-ID: <20210927053629.17847-5-xiangsheng.hou@mediatek.com>

Add snfi node and this version add nfi register base
at bch(ecc) node.

Signed-off-by: Xiangsheng Hou <xiangsheng.hou at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 16 ++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7622.dtsi     | 15 ++++++++++++++-
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
index f2dc850010f1..ddd759da4805 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -223,6 +223,22 @@ &nandc {
 	status = "disabled";
 };
 
+&snfi {
+	pinctrl-names = "default";
+	/* pin shared with spic */
+	pinctrl-0 = <&snfi_pins>;
+	status = "disabled";
+
+	spi_nand at 0 {
+		compatible = "spi-nand";
+		reg = <0>;
+		spi-max-frequency = <104000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+		nand-ecc-engine = <&bch>;
+		nand-ecc-algo = "ecc-mtk";
+	};
+};
 &nor_flash {
 	pinctrl-names = "default";
 	pinctrl-0 = <&spi_nor_pins>;
diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
index 890a942ec608..e916011b1804 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -545,9 +545,22 @@ nandc: nfi at 1100d000 {
 		status = "disabled";
 	};
 
+	snfi: spi at 1100d000 {
+		compatible = "mediatek,mt7622-snfi";
+		reg = <0 0x1100D000 0 0x1000>;
+		interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&infracfg_ao CK_INFRA_NFI1_CK>,
+			 <&infracfg_ao CK_INFRA_SPINFI1_CK>,
+			 <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
+		clock-names = "nfi_clk", "snfi_clk", "hclk";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	bch: ecc at 1100e000 {
 		compatible = "mediatek,mt7622-ecc";
-		reg = <0 0x1100e000 0 0x1000>;
+		reg = <0 0x1100e000 0 0x1000>, <0 0x1100D000 0 0x1000>;
 		interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&pericfg CLK_PERI_NFIECC_PD>;
 		clock-names = "nfiecc_clk";
-- 
2.25.1



From xiangsheng.hou at mediatek.com  Sun Sep 26 22:36:28 2021
From: xiangsheng.hou at mediatek.com (Xiangsheng Hou)
Date: Mon, 27 Sep 2021 13:36:28 +0800
Subject: [RFC,v1 3/4] spi: add Mediatek SPI Nand controller driver
In-Reply-To: <20210927053629.17847-1-xiangsheng.hou@mediatek.com>
References: <20210927053629.17847-1-xiangsheng.hou@mediatek.com>
Message-ID: <20210927053629.17847-4-xiangsheng.hou@mediatek.com>

This version parse nand parameter and ecc status from
nfi reg, which have been config at ecc driver due to
the snfi driver can not get these information.

Signed-off-by: Xiangsheng Hou <xiangsheng.hou at mediatek.com>
---
 drivers/spi/Kconfig        |   11 +
 drivers/spi/Makefile       |    1 +
 drivers/spi/spi-mtk-snfi.c | 1043 ++++++++++++++++++++++++++++++++++++
 3 files changed, 1055 insertions(+)
 create mode 100644 drivers/spi/spi-mtk-snfi.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 83e352b0c8f9..6768cd510f77 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -514,6 +514,17 @@ config SPI_MT65XX
 	  say Y or M here.If you are not sure, say N.
 	  SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs.
 
+config SPI_MTK_SNFI
+	tristate "MediaTek SPI NAND interface"
+	depends on MTD
+	select MTD_SPI_NAND
+	select MTD_NAND_ECC_MTK
+	help
+	  This selects the SPI NAND FLASH interface(SNFI),
+	  which could be found on MediaTek Soc.
+	  Say Y or M here.If you are not sure, say N.
+	  Note Parallel Nand and SPI NAND is alternative on MediaTek SoCs.
+
 config SPI_MT7621
 	tristate "MediaTek MT7621 SPI Controller"
 	depends on RALINK || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 699db95c8441..0435624905d9 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_SPI_MPC512x_PSC)		+= spi-mpc512x-psc.o
 obj-$(CONFIG_SPI_MPC52xx_PSC)		+= spi-mpc52xx-psc.o
 obj-$(CONFIG_SPI_MPC52xx)		+= spi-mpc52xx.o
 obj-$(CONFIG_SPI_MT65XX)                += spi-mt65xx.o
+obj-$(CONFIG_SPI_MTK_SNFI)              += spi-mtk-snfi.o
 obj-$(CONFIG_SPI_MT7621)		+= spi-mt7621.o
 obj-$(CONFIG_SPI_MTK_NOR)		+= spi-mtk-nor.o
 obj-$(CONFIG_SPI_MXIC)			+= spi-mxic.o
diff --git a/drivers/spi/spi-mtk-snfi.c b/drivers/spi/spi-mtk-snfi.c
new file mode 100644
index 000000000000..afc93410975e
--- /dev/null
+++ b/drivers/spi/spi-mtk-snfi.c
@@ -0,0 +1,1043 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for MediaTek SPI Nand interface
+ *
+ * Copyright (C) 2021 MediaTek Inc.
+ * Authors:	Xiangsheng Hou	<xiangsheng.hou at mediatek.com>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
+
+/* Registers used by the driver */
+#define NFI_CNFG		0x00
+#define		CNFG_DMA			BIT(0)
+#define		CNFG_READ_EN		BIT(1)
+#define		CNFG_DMA_BURST_EN	BIT(2)
+#define		CNFG_HW_ECC_EN		BIT(8)
+#define		CNFG_AUTO_FMT_EN	BIT(9)
+#define		CNFG_OP_CUST		GENMASK(14, 13)
+#define NFI_PAGEFMT		(0x04)
+#define		PAGEFMT_SPARE_MASK	GENMASK(21, 16)
+#define		PAGEFMT_SPARE_SHIFT		(16)
+#define		PAGEFMT_FDM_ECC_SHIFT	(12)
+#define		PAGEFMT_FDM_SHIFT	(8)
+#define		PAGEFMT_FDM_MASK	GENMASK(11, 8)
+#define		PAGEFMT_SEC_SEL_512	BIT(2)
+#define		PAGEFMT_512_2K		(0)
+#define		PAGEFMT_2K_4K		(1)
+#define		PAGEFMT_4K_8K		(2)
+#define		PAGEFMT_8K_16K		(3)
+#define		PAGEFMT_PAGE_MASK	GENMASK(1, 0)
+#define NFI_CON			0x08
+#define		CON_FIFO_FLUSH		BIT(0)
+#define		CON_NFI_RST			BIT(1)
+#define		CON_BRD				BIT(8)
+#define		CON_BWR				BIT(9)
+#define		CON_SEC_SHIFT		12
+#define		CON_SEC_MASK		GENMASK(16, 12)
+#define NFI_INTR_EN		0x10
+#define		INTR_CUS_PROG_EN	BIT(7)
+#define		INTR_CUS_READ_EN	BIT(8)
+#define		INTR_IRQ_EN			BIT(31)
+#define NFI_INTR_STA	0x14
+#define NFI_CMD			0x20
+#define NFI_STRDATA		0x40
+#define		STAR_EN				BIT(0)
+#define NFI_STA			0x60
+#define		NFI_FSM_MASK		GENMASK(19, 16)
+#define		STA_EMP_PAGE		BIT(12)
+#define NFI_ADDRCNTR	0x70
+#define		CNTR_MASK			GENMASK(16, 12)
+#define		ADDRCNTR_SEC_SHIFT	12
+#define		ADDRCNTR_SEC(val) \
+		(((val) & CNTR_MASK) >> ADDRCNTR_SEC_SHIFT)
+#define NFI_STRADDR		0x80
+#define NFI_BYTELEN		0x84
+#define NFI_FDML(x)		(0xA0 + (x) * sizeof(u32) * 2)
+#define NFI_FDMM(x)		(0xA4 + (x) * sizeof(u32) * 2)
+#define NFI_MASTERSTA	0x224
+#define		AHB_BUS_BUSY		BIT(1)
+#define		BUS_BUSY			BIT(0)
+#define SNFI_MAC_OUTL	0x504
+#define SNFI_MAC_INL	0x508
+#define SNFI_RD_CTL2	0x510
+#define		RD_CMD_MASK			0x00ff
+#define		RD_DUMMY_SHIFT		8
+#define SNFI_RD_CTL3			0x514
+#define		RD_ADDR_MASK		0xffff
+#define SNFI_MISC_CTL	0x538
+#define		RD_MODE_MASK		GENMASK(18, 16)
+#define		LATCH_LAT_MASK		GENMASK(9, 8)
+#define		LATCH_LAT_SHIFT		8
+#define		RD_MODE_X2			BIT(16)
+#define		RD_MODE_X4			BIT(17)
+#define		RD_MODE_DQUAL		BIT(18)
+#define		RD_CUSTOM_EN		BIT(6)
+#define		WR_CUSTOM_EN		BIT(7)
+#define		WR_X4_EN			BIT(20)
+#define		SW_RST				BIT(28)
+#define SNFI_MISC_CTL2	0x53c
+#define		WR_LEN_SHIFT		16
+#define SNFI_PG_CTL1	0x524
+#define		WR_LOAD_CMD_MASK	GENMASK(15, 8)
+#define		WR_LOAD_CMD_SHIFT	8
+#define SNFI_PG_CTL2	0x528
+#define		WR_LOAD_ADDR_MASK	GENMASK(15, 0)
+#define SNFI_MAC_CTL	0x500
+#define		MAC_WIP				BIT(0)
+#define		MAC_WIP_READY		BIT(1)
+#define		MAC_TRIG			BIT(2)
+#define		MAC_EN				BIT(3)
+#define		MAC_SIO_SEL			BIT(4)
+#define SNFI_DLY_CTL3	0x548
+#define		SAM_DLY_MASK		GENMASK(5, 0)
+#define SNFI_STA_CTL1	0x550
+#define		CUS_PROG_DONE		BIT(28)
+#define		CUS_READ_DONE		BIT(27)
+#define		SPI_STATE			GENMASK(3, 0)
+#define SNFI_CNFG		0x55c
+#define		SNFI_MODE_EN		BIT(0)
+#define SNFI_GPRAM_DATA	0x800
+#define		SNFI_GPRAM_MAX_LEN	160
+
+#define MTK_SNFI_TIMEOUT			500000
+#define MTK_SNFI_RESET_TIMEOUT		1000000
+#define MTK_SNFI_AUTOSUSPEND_DELAY	1000
+#define KB(x)			((x) * 1024UL)
+
+/* supported spare size of each IP */
+static const u8 spare_size_mt7622[] = {
+	16, 26, 27, 28
+};
+
+struct mtk_snfi_caps {
+	const u8 *spare_size;
+	u8 num_spare_size;
+	u8 pageformat_spare_shift;
+};
+
+struct mtk_snfi {
+	struct clk *nfi_clk;
+	struct clk *snfi_clk;
+	struct clk *hclk;
+	struct device *dev;
+	struct completion done;
+
+	const struct mtk_snfi_caps *caps;
+
+	bool ecc_en;
+	u32 page_size;
+	u32 fdm_size;
+	u32 spare_size;
+	u32 sectors;
+	u32 sector_size;
+
+	u32 sample_delay;
+	u32 read_latency;
+
+	void *tx_buf;
+	dma_addr_t dma_addr;
+	void __iomem *regs;
+};
+
+static void mtk_snfi_mac_enable(struct mtk_snfi *snfi)
+{
+	u32 val;
+
+	val = readl(snfi->regs + SNFI_MAC_CTL);
+	val &= ~MAC_SIO_SEL;
+	val |= MAC_EN;
+
+	writel(val, snfi->regs + SNFI_MAC_CTL);
+}
+
+static int mtk_snfi_mac_trigger(struct mtk_snfi *snfi)
+{
+	u32 val;
+	int ret = 0;
+
+	val = readl(snfi->regs + SNFI_MAC_CTL);
+	val |= MAC_TRIG;
+	writel(val, snfi->regs + SNFI_MAC_CTL);
+
+	ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, val,
+					val & MAC_WIP_READY, 0,
+					MTK_SNFI_TIMEOUT);
+	if (ret < 0) {
+		dev_err(snfi->dev, "wait for wip ready timeout\n");
+		return -EIO;
+	}
+
+	ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, val,
+					!(val & MAC_WIP), 0,
+					MTK_SNFI_TIMEOUT);
+	if (ret < 0) {
+		dev_err(snfi->dev, "wait for flash update finish timeout\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void mtk_snfi_mac_disable(struct mtk_snfi *snfi)
+{
+	u32 val;
+
+	val = readl(snfi->regs + SNFI_MAC_CTL);
+	val &= ~(MAC_TRIG | MAC_EN);
+	writel(val, snfi->regs + SNFI_MAC_CTL);
+}
+
+static int mtk_snfi_mac_op(struct mtk_snfi *snfi)
+{
+	int ret = 0;
+
+	mtk_snfi_mac_enable(snfi);
+	ret = mtk_snfi_mac_trigger(snfi);
+	mtk_snfi_mac_disable(snfi);
+
+	return ret;
+}
+
+static inline void mtk_snfi_read_fdm(struct mtk_snfi *snfi,
+			const struct spi_mem_op *op)
+{
+	u32 vall, valm;
+	u8 *oobptr = op->data.buf.in;
+	int i, j;
+
+	oobptr += snfi->page_size;
+	for (i = 0; i < snfi->sectors; i++) {
+		vall = readl(snfi->regs + NFI_FDML(i));
+		valm = readl(snfi->regs + NFI_FDMM(i));
+
+		for (j = 0; j < snfi->fdm_size; j++)
+			oobptr[j] = (j >= 4 ? valm : vall) >> ((j % 4) * 8);
+
+		oobptr += snfi->fdm_size;
+	}
+}
+
+static inline void mtk_snfi_write_fdm(struct mtk_snfi *snfi,
+			const struct spi_mem_op *op)
+{
+	const u8 *oobptr = op->data.buf.out;
+	u32 vall, valm;
+	int i, j;
+
+	oobptr += snfi->page_size;
+	for (i = 0; i < snfi->sectors; i++) {
+		vall = 0;
+		valm = 0;
+		for (j = 0; j < 8; j++) {
+			if (j < 4)
+				vall |= (j < snfi->fdm_size ? oobptr[j] : 0xff)
+						<< (j * 8);
+			else
+				valm |= (j < snfi->fdm_size ? oobptr[j] : 0xff)
+						<< ((j - 4) * 8);
+		}
+		writel(vall, snfi->regs + NFI_FDML(i));
+		writel(valm, snfi->regs + NFI_FDMM(i));
+
+		oobptr += snfi->fdm_size;
+	}
+}
+
+static irqreturn_t mtk_snfi_irq(int irq, void *id)
+{
+	struct mtk_snfi *snfi = id;
+	u32 sta, ien;
+
+	sta = readl(snfi->regs + NFI_INTR_STA);
+	ien = readl(snfi->regs + NFI_INTR_EN);
+
+	if (!(sta & ien))
+		return IRQ_NONE;
+
+	writel(0, snfi->regs + NFI_INTR_EN);
+	complete(&snfi->done);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_snfi_enable_clk(struct device *dev, struct mtk_snfi *snfi)
+{
+	int ret;
+
+	ret = clk_prepare_enable(snfi->nfi_clk);
+	if (ret) {
+		dev_err(dev, "failed to enable nfi clk\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(snfi->snfi_clk);
+	if (ret) {
+		dev_err(dev, "failed to enable snfi clk\n");
+		clk_disable_unprepare(snfi->nfi_clk);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(snfi->hclk);
+	if (ret) {
+		dev_err(dev, "failed to enable hclk\n");
+		clk_disable_unprepare(snfi->nfi_clk);
+		clk_disable_unprepare(snfi->snfi_clk);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void mtk_snfi_disable_clk(struct mtk_snfi *snfi)
+{
+	clk_disable_unprepare(snfi->nfi_clk);
+	clk_disable_unprepare(snfi->snfi_clk);
+	clk_disable_unprepare(snfi->hclk);
+}
+
+static int mtk_snfi_reset(struct mtk_snfi *snfi)
+{
+	u32 val;
+	int ret;
+
+	val = readl(snfi->regs + SNFI_MISC_CTL) | SW_RST;
+	writel(val, snfi->regs + SNFI_MISC_CTL);
+
+	ret = readw_poll_timeout(snfi->regs + SNFI_STA_CTL1, val,
+				 !(val & SPI_STATE), 0,
+				 MTK_SNFI_RESET_TIMEOUT);
+	if (ret) {
+		dev_warn(snfi->dev, "spi state not idle 0x%x\n", val);
+		return ret;
+	}
+
+	val = readl(snfi->regs + SNFI_MISC_CTL);
+	val &= ~SW_RST;
+	writel(val, snfi->regs + SNFI_MISC_CTL);
+
+	writew(CON_FIFO_FLUSH | CON_NFI_RST, snfi->regs + NFI_CON);
+	ret = readw_poll_timeout(snfi->regs + NFI_STA, val,
+				 !(val & NFI_FSM_MASK), 0,
+				 MTK_SNFI_RESET_TIMEOUT);
+	if (ret) {
+		dev_warn(snfi->dev, "nfi fsm not idle 0x%x\n", val);
+		return ret;
+	}
+
+	val = readl(snfi->regs + NFI_STRDATA);
+	val &= ~STAR_EN;
+	writew(val, snfi->regs + NFI_STRDATA);
+
+	return 0;
+}
+
+/*
+ * Due to the snfi driver at spi subsystem can not get nand parameter.
+ * Therefore, parse nand parameter from nfi register which have been
+ * config at ecc driver.
+ */
+static int mtk_snfi_config(struct mtk_snfi *snfi)
+{
+	u32 val, config;
+
+	writel(SNFI_MODE_EN, snfi->regs + SNFI_CNFG);
+
+	if (snfi->sample_delay) {
+		val = readl(snfi->regs + SNFI_DLY_CTL3);
+		val &= ~SAM_DLY_MASK;
+		val |= snfi->sample_delay;
+		writel(val, snfi->regs + SNFI_DLY_CTL3);
+	}
+
+	if (snfi->read_latency) {
+		val = readl(snfi->regs + SNFI_MISC_CTL);
+		val &= ~LATCH_LAT_MASK;
+		val |= (snfi->read_latency << LATCH_LAT_SHIFT);
+		writel(val, snfi->regs + SNFI_MISC_CTL);
+	}
+
+	val = readl(snfi->regs + NFI_CNFG);
+	if (val & CNFG_HW_ECC_EN)
+		snfi->ecc_en = true;
+
+	val = readl(snfi->regs + NFI_PAGEFMT);
+	if (val & PAGEFMT_SEC_SEL_512)
+		snfi->sector_size = 512;
+	else
+		snfi->sector_size = 1024;
+
+	config = val & PAGEFMT_PAGE_MASK;
+	switch (config) {
+	case PAGEFMT_512_2K:
+		snfi->page_size = KB(2);
+		if (val & PAGEFMT_SEC_SEL_512)	
+			snfi->page_size = 512;
+		break;
+	case PAGEFMT_2K_4K:
+		snfi->page_size = KB(4);
+		if (val & PAGEFMT_SEC_SEL_512)	
+			snfi->page_size = KB(2);
+		break;
+	case PAGEFMT_4K_8K:
+		snfi->page_size = KB(8);
+		if (val & PAGEFMT_SEC_SEL_512)	
+			snfi->page_size = KB(4);
+		break;
+	case PAGEFMT_8K_16K:
+		snfi->page_size = KB(16);
+		break;
+	}
+
+	config = val & PAGEFMT_SPARE_MASK;
+	config >>= snfi->caps->pageformat_spare_shift;
+	snfi->spare_size = snfi->caps->spare_size[config];
+
+	config = val & PAGEFMT_FDM_MASK;
+	snfi->fdm_size = config >> PAGEFMT_FDM_SHIFT;
+
+	if (!(val & PAGEFMT_SEC_SEL_512))
+		snfi->spare_size <<= 1;
+
+	snfi->sectors = snfi->page_size / snfi->sector_size;
+	
+	return 0;
+}
+
+static int mtk_snfi_init(struct mtk_snfi *snfi)
+{
+	int ret;
+
+	ret = mtk_snfi_reset(snfi);
+	if (ret)
+		return ret;
+
+	ret = mtk_snfi_config(snfi);
+
+	return ret;
+}
+
+static void mtk_snfi_prepare_for_tx(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op)
+{
+	u32 val;
+
+	writel(0x80, snfi->regs + NFI_CMD);
+	val = readl(snfi->regs + SNFI_PG_CTL1);
+	val &= ~WR_LOAD_CMD_MASK;
+	val |= op->cmd.opcode << WR_LOAD_CMD_SHIFT;
+	writel(val, snfi->regs + SNFI_PG_CTL1);
+
+	writel(op->addr.val & WR_LOAD_ADDR_MASK,
+		   snfi->regs + SNFI_PG_CTL2);
+
+	val = readl(snfi->regs + SNFI_MISC_CTL);
+	val |= WR_CUSTOM_EN;
+	if (op->data.buswidth == 4)
+		val |= WR_X4_EN;
+	writel(val, snfi->regs + SNFI_MISC_CTL);
+
+	val = snfi->page_size + snfi->sectors * snfi->spare_size;
+
+	writel(val << WR_LEN_SHIFT,
+		snfi->regs + SNFI_MISC_CTL2);
+	writel(INTR_CUS_PROG_EN | INTR_IRQ_EN,
+		snfi->regs + NFI_INTR_EN);
+}
+
+static void mtk_snfi_prepare_for_rx(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op)
+{
+	u32 val, dummy_cycle;
+
+	writel(0x00, snfi->regs + NFI_CMD);
+	dummy_cycle = (op->dummy.nbytes << 3) >>
+				  (ffs(op->dummy.buswidth) - 1);
+	val = (op->cmd.opcode & RD_CMD_MASK) |
+		  (dummy_cycle << RD_DUMMY_SHIFT);
+	writel(val, snfi->regs + SNFI_RD_CTL2);
+
+	writel(op->addr.val & RD_ADDR_MASK,
+		   snfi->regs + SNFI_RD_CTL3);
+
+	val = readl(snfi->regs + SNFI_MISC_CTL);
+	val |= RD_CUSTOM_EN;
+	val &= ~RD_MODE_MASK;
+	if (op->data.buswidth == 4)
+		val |= RD_MODE_X4;
+	else if (op->data.buswidth == 2)
+		val |= RD_MODE_X2;
+
+	if (op->addr.buswidth != 1)
+		val |= RD_MODE_DQUAL;
+	writel(val, snfi->regs + SNFI_MISC_CTL);
+
+	val = snfi->page_size + snfi->sectors * snfi->spare_size;
+	writel(val, snfi->regs + SNFI_MISC_CTL2);
+	writel(INTR_CUS_READ_EN | INTR_IRQ_EN,
+		   snfi->regs + NFI_INTR_EN);
+}
+
+static int mtk_snfi_prepare(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op, bool rx)
+{
+	int ret;
+	dma_addr_t addr;
+	u32 val;
+
+	addr = dma_map_single(snfi->dev,
+				op->data.buf.in, op->data.nbytes,
+				rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+	ret = dma_mapping_error(snfi->dev, addr);
+	if (ret) {
+		dev_err(snfi->dev, "dma mapping error\n");
+		return -EINVAL;
+	}
+
+	snfi->dma_addr = addr;
+	writel(lower_32_bits(addr), snfi->regs + NFI_STRADDR);
+
+	if (snfi->ecc_en && !rx)
+		mtk_snfi_write_fdm(snfi, op);
+
+	val = readw(snfi->regs + NFI_CNFG);
+	val |= CNFG_DMA | CNFG_DMA_BURST_EN | CNFG_OP_CUST;
+	val |= rx ? CNFG_READ_EN : 0;
+	writew(val, snfi->regs + NFI_CNFG);
+
+	writel(snfi->sectors << CON_SEC_SHIFT, snfi->regs + NFI_CON);
+
+	init_completion(&snfi->done);
+
+	if (rx)
+		mtk_snfi_prepare_for_rx(snfi, op);
+	else
+		mtk_snfi_prepare_for_tx(snfi, op);
+
+	return 0;
+}
+
+static void mtk_snfi_trigger(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op, bool rx)
+{
+	u32 val;
+
+	val = readl(snfi->regs + NFI_CON);
+	val |= rx ? CON_BRD : CON_BWR;
+	writew(val, snfi->regs + NFI_CON);
+
+	writew(STAR_EN, snfi->regs + NFI_STRDATA);
+}
+
+static int mtk_snfi_wait_done(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op, bool rx)
+{
+	u32 val;
+	int ret;
+
+	ret = wait_for_completion_timeout(&snfi->done, msecs_to_jiffies(500));
+	if (!ret) {
+		dev_err(snfi->dev, "wait for %d completion done timeout\n", rx);
+		dump_register(snfi);
+		return -ETIMEDOUT;
+	}
+
+	if (rx) {
+		ret = readl_poll_timeout_atomic(snfi->regs + NFI_BYTELEN, val,
+						ADDRCNTR_SEC(val) >= snfi->sectors, 0,
+						MTK_SNFI_TIMEOUT);
+		if (ret < 0) {
+			dev_err(snfi->dev, "wait for read sector count timeout\n");
+			dump_register(snfi);
+			return -ETIMEDOUT;
+		}
+
+		ret = readl_poll_timeout_atomic(snfi->regs + NFI_MASTERSTA, val,
+					!(val & (AHB_BUS_BUSY | BUS_BUSY)),
+					0, MTK_SNFI_TIMEOUT);
+		if (ret) {
+			dev_err(snfi->dev, "wait for bus busy timeout\n");
+			dump_register(snfi);
+			return -ETIMEDOUT;
+		}
+	} else {
+		ret = readl_poll_timeout_atomic(snfi->regs + NFI_ADDRCNTR, val,
+						ADDRCNTR_SEC(val) >= snfi->sectors,
+						0, MTK_SNFI_TIMEOUT);
+		if (ret) {
+			dev_err(snfi->dev, "wait for program sector count timeout\n");
+			dump_register(snfi);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void mtk_snfi_complete(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op, bool rx)
+{
+	u32 val;
+
+	dma_unmap_single(snfi->dev,
+					 snfi->dma_addr, op->data.nbytes,
+					 rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+
+	if (snfi->ecc_en && rx)
+		mtk_snfi_read_fdm(snfi, op);
+
+	val = readl(snfi->regs + SNFI_MISC_CTL);
+	val &= rx ? ~RD_CUSTOM_EN : ~WR_CUSTOM_EN;
+	writel(val, snfi->regs + SNFI_MISC_CTL);
+
+	val = readl(snfi->regs + SNFI_STA_CTL1);
+	val |= rx ? CUS_READ_DONE : CUS_PROG_DONE;
+	writew(val, snfi->regs + SNFI_STA_CTL1);
+	val &= rx ? ~CUS_READ_DONE : ~CUS_PROG_DONE;
+	writew(val, snfi->regs + SNFI_STA_CTL1);
+
+	/* Disable interrupt */
+	val = readl(snfi->regs + NFI_INTR_EN);
+	val &= rx ? ~INTR_CUS_READ_EN : ~INTR_CUS_PROG_EN;
+	writew(val, snfi->regs + NFI_INTR_EN);
+
+	writew(0, snfi->regs + NFI_CNFG);
+	writew(0, snfi->regs + NFI_CON);
+}
+
+static int mtk_snfi_transfer_dma(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op, bool rx)
+{
+	int ret;
+
+	ret = mtk_snfi_prepare(snfi, op, rx);
+	if (ret)
+		return ret;
+
+	mtk_snfi_trigger(snfi, op, rx);
+
+	ret = mtk_snfi_wait_done(snfi, op, rx);
+
+	mtk_snfi_complete(snfi, op, rx);
+
+	return ret;
+}
+
+static int mtk_snfi_transfer_mac(struct mtk_snfi *snfi,
+			    const u8 *txbuf, u8 *rxbuf,
+			    const u32 txlen, const u32 rxlen)
+{
+	u32 i, j, val, tmp;
+	u8 *p_tmp = (u8 *)(&tmp);
+	u32 addr_offset = 0;
+	int ret = 0;
+
+	/* Move tx data to snfi gpram */
+	for (i = 0; i < txlen; ) {
+		for (j = 0, tmp = 0; i < txlen && j < 4; i++, j++)
+			p_tmp[j] = txbuf[i];
+
+		writel(tmp, snfi->regs + SNFI_GPRAM_DATA + addr_offset);
+		addr_offset += 4;
+	}
+
+	writel(txlen, snfi->regs + SNFI_MAC_OUTL);
+	writel(rxlen, snfi->regs + SNFI_MAC_INL);
+
+	ret = mtk_snfi_mac_op(snfi);
+	if (ret) {
+		dev_warn(snfi->dev, "snfi mac operation fail\n");
+		return ret;
+	}
+
+	/* Get tx data from snfi gpram */
+	if (rxlen) {
+		for (i = 0, addr_offset = rounddown(txlen, 4); i < rxlen; ) {
+			val = readl(snfi->regs +
+					    SNFI_GPRAM_DATA + addr_offset);
+			for (j = 0; i < rxlen && j < 4; i++, j++, rxbuf++) {
+				if (i == 0)
+					j = txlen % 4;
+				*rxbuf = (val >> (j * 8)) & 0xff;
+			}
+			addr_offset += 4;
+		}
+	}
+
+	return ret;
+}
+
+static int mtk_snfi_exec_op(struct spi_mem *mem,
+			    const struct spi_mem_op *op)
+
+{
+	struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
+	u8 *buf, *txbuf = snfi->tx_buf, *rxbuf = NULL;
+	u32 txlen = 0, rxlen = 0;
+	int i, ret = 0;
+	bool rx;
+
+	rx = op->data.dir == SPI_MEM_DATA_IN;
+	
+	ret = mtk_snfi_init(snfi);
+	if (ret) {
+		dev_warn(snfi->dev, "reset snfi fail\n");
+		return ret;
+	}
+
+	/*
+	 * If tx/rx data buswidth is not 1, use snfi DMA mode.
+	 * Otherwise, use snfi mac mode.
+	 */
+	if ((op->data.buswidth != 1) && (op->data.buswidth != 0)) {
+		ret = mtk_snfi_transfer_dma(snfi, op, rx);
+		if (ret)
+			dev_warn(snfi->dev, "snfi dma transfer %d fail %d\n",
+					 rx, ret);
+		return ret;
+	}
+
+	txbuf[txlen++] = op->cmd.opcode;
+
+	if (op->addr.nbytes)
+		for (i = 0; i < op->addr.nbytes; i++)
+			txbuf[txlen++] = op->addr.val >>
+					(8 * (op->addr.nbytes - i - 1));
+
+	txlen += op->dummy.nbytes;
+
+	if (op->data.dir == SPI_MEM_DATA_OUT) {
+		buf = (u8 *)op->data.buf.out;
+		for (i = 0; i < op->data.nbytes; i++)
+			txbuf[txlen++] = buf[i];
+	}
+
+	if (op->data.dir == SPI_MEM_DATA_IN) {
+		rxbuf = (u8 *)op->data.buf.in;
+		rxlen = op->data.nbytes;
+	}
+
+	ret = mtk_snfi_transfer_mac(snfi, txbuf, rxbuf, txlen, rxlen);
+	if (ret)
+		dev_warn(snfi->dev, "snfi mac transfer %d fail %d\n",
+				 op->data.dir, ret);
+	return ret;
+}
+
+static int mtk_snfi_check_buswidth(u8 width)
+{
+	switch (width) {
+	case 1:
+	case 2:
+	case 4:
+		return 0;
+
+	default:
+		break;
+	}
+
+	return -ENOTSUPP;
+}
+
+static bool mtk_snfi_supports_op(struct spi_mem *mem,
+				 const struct spi_mem_op *op)
+{
+	struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
+	int ret = 0;
+	u32 val;
+
+	if (!spi_mem_default_supports_op(mem, op))
+		return false;
+
+	if (op->cmd.buswidth != 1)
+		return false;
+
+	val = readl(snfi->regs + NFI_CNFG);
+	if (val & CNFG_HW_ECC_EN)
+		snfi->ecc_en = true;
+	else
+		snfi->ecc_en = false;
+
+	/*
+	 * For current design, the operation will use mac mode when data
+	 * buswidth is 1. However, the HW ECC can not be used in mac mode.
+	 */
+	if (snfi->ecc_en && op->data.buswidth == 1 &&
+			op->data.nbytes >= SNFI_GPRAM_MAX_LEN)
+		return false;
+
+	switch (op->data.dir) {
+	case SPI_MEM_DATA_IN:
+		if (op->addr.nbytes)
+			ret |= mtk_snfi_check_buswidth(op->addr.buswidth);
+
+		if (op->dummy.nbytes)
+			ret |= mtk_snfi_check_buswidth(op->dummy.buswidth);
+
+		if (op->data.nbytes)
+			ret |= mtk_snfi_check_buswidth(op->data.buswidth);
+
+		if (ret)
+			return false;
+
+		break;
+	case SPI_MEM_DATA_OUT:
+		if ((op->addr.buswidth != 0) && (op->addr.buswidth != 1))
+			return false;
+
+		if ((op->dummy.buswidth != 0) && (op->dummy.buswidth != 1))
+			return false;
+
+		if ((op->data.buswidth != 1) && (op->data.buswidth != 4))
+			return false;
+
+		break;
+	default:
+		break;
+	}
+
+	return true;
+}
+
+static int mtk_snfi_adjust_op_size(struct spi_mem *mem,
+				   struct spi_mem_op *op)
+{
+	u32 len, max_len;
+
+	if ((op->data.buswidth == 1) || (op->data.buswidth == 0))
+		max_len = SNFI_GPRAM_MAX_LEN;
+	else
+		max_len = KB(16);
+
+	len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
+	if (len > max_len)
+		return -ENOTSUPP;
+
+	if ((len + op->data.nbytes) > max_len)
+		op->data.nbytes = max_len - len;
+
+	return 0;
+}
+
+static const struct mtk_snfi_caps mtk_snfi_caps_mt7622 = {
+	.spare_size = spare_size_mt7622,
+	.num_spare_size = 4,
+	.pageformat_spare_shift = 16,
+};
+
+static const struct spi_controller_mem_ops mtk_snfi_ops = {
+	.adjust_op_size = mtk_snfi_adjust_op_size,
+	.supports_op = mtk_snfi_supports_op,
+	.exec_op = mtk_snfi_exec_op,
+};
+
+static const struct of_device_id mtk_snfi_id_table[] = {
+	{ .compatible = "mediatek,mt7622-snfi",
+	  .data = &mtk_snfi_caps_mt7622,
+	},
+	{  /* sentinel */ }
+};
+
+static int mtk_snfi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct spi_controller *ctlr;
+	struct mtk_snfi *snfi;
+	struct resource *res;
+	int ret, irq;
+	u32 val;
+
+	ctlr = spi_alloc_master(&pdev->dev, sizeof(*snfi));
+	if (!ctlr)
+		return -ENOMEM;
+
+	snfi = spi_controller_get_devdata(ctlr);
+	snfi->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	snfi->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(snfi->regs)) {
+		ret = PTR_ERR(snfi->regs);
+		goto err_put_master;
+	}
+
+	ret = of_property_read_u32(np, "sample-delay", &val);
+	if (ret) {
+		dev_err(dev, "no sample-delay property\n");
+		return ret;
+	}
+	snfi->sample_delay = val;
+
+	ret = of_property_read_u32(np, "read-latency", &val);
+	if (ret) {
+		dev_err(dev, "no read-latency property\n");
+		return ret;
+	}
+	snfi->read_latency = val;
+
+	snfi->nfi_clk = devm_clk_get(dev, "nfi_clk");
+	if (IS_ERR(snfi->nfi_clk)) {
+		dev_err(dev, "no nfi clk\n");
+		ret = PTR_ERR(snfi->nfi_clk);
+		goto err_put_master;
+	}
+
+	snfi->snfi_clk = devm_clk_get(dev, "snfi_clk");
+	if (IS_ERR(snfi->snfi_clk)) {
+		dev_err(dev, "no snfi clk\n");
+		ret = PTR_ERR(snfi->snfi_clk);
+		goto err_put_master;
+	}
+
+	snfi->hclk = devm_clk_get(dev, "hclk");
+	if (IS_ERR(snfi->hclk)) {
+		dev_err(dev, "no hclk\n");
+		ret = PTR_ERR(snfi->hclk);
+		goto err_put_master;
+	}
+
+	ret = mtk_snfi_enable_clk(dev, snfi);
+	if (ret)
+		goto err_put_master;
+
+	snfi->caps = of_device_get_match_data(dev);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(dev, "no snfi irq resource\n");
+		ret = -EINVAL;
+		goto clk_disable;
+	}
+
+	ret = devm_request_irq(dev, irq, mtk_snfi_irq, 0, "mtk-snfi", snfi);
+	if (ret) {
+		dev_err(dev, "failed to request snfi irq\n");
+		goto clk_disable;
+	}
+
+	ret = dma_set_mask(dev, DMA_BIT_MASK(32));
+	if (ret) {
+		dev_err(dev, "failed to set dma mask\n");
+		goto clk_disable;
+	}
+
+	snfi->tx_buf = kzalloc(SNFI_GPRAM_MAX_LEN, GFP_KERNEL);
+	if (!snfi->tx_buf) {
+		ret = -ENOMEM;
+		goto clk_disable;
+	}
+
+	ctlr->dev.of_node = np;
+	ctlr->mem_ops = &mtk_snfi_ops;
+	ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_QUAD;
+	ctlr->auto_runtime_pm = false;
+
+	dev_set_drvdata(&pdev->dev, ctlr);
+
+	ret = mtk_snfi_init(snfi);
+	if (ret) {
+		dev_err(dev, "failed to init snfi\n");
+		goto free_buf;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	ret = devm_spi_register_master(dev, ctlr);
+	if (ret) {
+		dev_err(dev, "failed to register spi master\n");
+		goto disable_pm_runtime;
+	}
+
+	return 0;
+
+disable_pm_runtime:
+	pm_runtime_disable(&pdev->dev);
+
+free_buf:
+	kfree(snfi->tx_buf);
+
+clk_disable:
+	mtk_snfi_disable_clk(snfi);
+
+err_put_master:
+	spi_master_put(ctlr);
+
+	return ret;
+}
+
+static int mtk_snfi_remove(struct platform_device *pdev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
+	struct mtk_snfi *snfi = spi_controller_get_devdata(ctlr);
+
+	pm_runtime_disable(&pdev->dev);
+	kfree(snfi->tx_buf);
+	spi_master_put(ctlr);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mtk_snfi_runtime_suspend(struct device *dev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+	struct mtk_snfi *snfi = spi_controller_get_devdata(ctlr);
+
+	mtk_snfi_disable_clk(snfi);
+
+	return 0;
+}
+
+static int mtk_snfi_runtime_resume(struct device *dev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+	struct mtk_snfi *snfi = spi_controller_get_devdata(ctlr);
+	int ret;
+
+	ret = mtk_snfi_enable_clk(dev, snfi);
+	if (ret)
+		return ret;
+
+	ret = mtk_snfi_init(snfi);
+	if (ret)
+		dev_err(dev, "failed to init snfi\n");
+
+	return ret;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops mtk_snfi_pm_ops = {
+	SET_RUNTIME_PM_OPS(mtk_snfi_runtime_suspend,
+			   mtk_snfi_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+			   pm_runtime_force_resume)
+};
+
+static struct platform_driver mtk_snfi_driver = {
+	.driver = {
+		.name	= "mtk-snfi",
+		.of_match_table = mtk_snfi_id_table,
+		.pm = &mtk_snfi_pm_ops,
+	},
+	.probe		= mtk_snfi_probe,
+	.remove		= mtk_snfi_remove,
+};
+
+module_platform_driver(mtk_snfi_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Xiangsheng Hou <xiangsheng.hou at mediatek.com>");
+MODULE_DESCRIPTION("Mediatek SPI Nand Interface Driver");
+
-- 
2.25.1



From xiangsheng.hou at mediatek.com  Sun Sep 26 22:42:04 2021
From: xiangsheng.hou at mediatek.com (Xiangsheng Hou)
Date: Mon, 27 Sep 2021 13:42:04 +0800
Subject: [RFC,v2 3/4] spi: add Mediatek SPI Nand controller driver
In-Reply-To: <20210927054205.17960-1-xiangsheng.hou@mediatek.com>
References: <20210927054205.17960-1-xiangsheng.hou@mediatek.com>
Message-ID: <20210927054205.17960-4-xiangsheng.hou@mediatek.com>

This version parse nand parameter and ecc status from nfi reg,
which have been config at ecc driver due to the snfi driver
can not get nand parameter. Also need export nfi read empty
status to ecc driver for check read empty or not.

Signed-off-by: Xiangsheng Hou <xiangsheng.hou at mediatek.com>
---
 drivers/spi/Kconfig        |   11 +
 drivers/spi/Makefile       |    1 +
 drivers/spi/spi-mtk-snfi.c | 1087 ++++++++++++++++++++++++++++++++++++
 3 files changed, 1099 insertions(+)
 create mode 100644 drivers/spi/spi-mtk-snfi.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 83e352b0c8f9..6768cd510f77 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -514,6 +514,17 @@ config SPI_MT65XX
 	  say Y or M here.If you are not sure, say N.
 	  SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs.
 
+config SPI_MTK_SNFI
+	tristate "MediaTek SPI NAND interface"
+	depends on MTD
+	select MTD_SPI_NAND
+	select MTD_NAND_ECC_MTK
+	help
+	  This selects the SPI NAND FLASH interface(SNFI),
+	  which could be found on MediaTek Soc.
+	  Say Y or M here.If you are not sure, say N.
+	  Note Parallel Nand and SPI NAND is alternative on MediaTek SoCs.
+
 config SPI_MT7621
 	tristate "MediaTek MT7621 SPI Controller"
 	depends on RALINK || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 699db95c8441..0435624905d9 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_SPI_MPC512x_PSC)		+= spi-mpc512x-psc.o
 obj-$(CONFIG_SPI_MPC52xx_PSC)		+= spi-mpc52xx-psc.o
 obj-$(CONFIG_SPI_MPC52xx)		+= spi-mpc52xx.o
 obj-$(CONFIG_SPI_MT65XX)                += spi-mt65xx.o
+obj-$(CONFIG_SPI_MTK_SNFI)              += spi-mtk-snfi.o
 obj-$(CONFIG_SPI_MT7621)		+= spi-mt7621.o
 obj-$(CONFIG_SPI_MTK_NOR)		+= spi-mtk-nor.o
 obj-$(CONFIG_SPI_MXIC)			+= spi-mxic.o
diff --git a/drivers/spi/spi-mtk-snfi.c b/drivers/spi/spi-mtk-snfi.c
new file mode 100644
index 000000000000..ed59c6cfc91a
--- /dev/null
+++ b/drivers/spi/spi-mtk-snfi.c
@@ -0,0 +1,1087 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for MediaTek SPI Nand interface
+ *
+ * Copyright (C) 2021 MediaTek Inc.
+ * Authors:	Xiangsheng Hou	<xiangsheng.hou at mediatek.com>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
+
+/* Registers used by the driver */
+#define NFI_CNFG		0x00
+#define		CNFG_DMA			BIT(0)
+#define		CNFG_READ_EN		BIT(1)
+#define		CNFG_DMA_BURST_EN	BIT(2)
+#define		CNFG_HW_ECC_EN		BIT(8)
+#define		CNFG_AUTO_FMT_EN	BIT(9)
+#define		CNFG_OP_CUST		GENMASK(14, 13)
+#define NFI_PAGEFMT		(0x04)
+#define		PAGEFMT_SPARE_MASK	GENMASK(21, 16)
+#define		PAGEFMT_SPARE_SHIFT		(16)
+#define		PAGEFMT_FDM_ECC_SHIFT	(12)
+#define		PAGEFMT_FDM_SHIFT	(8)
+#define		PAGEFMT_FDM_MASK	GENMASK(11, 8)
+#define		PAGEFMT_SEC_SEL_512	BIT(2)
+#define		PAGEFMT_512_2K		(0)
+#define		PAGEFMT_2K_4K		(1)
+#define		PAGEFMT_4K_8K		(2)
+#define		PAGEFMT_8K_16K		(3)
+#define		PAGEFMT_PAGE_MASK	GENMASK(1, 0)
+#define NFI_CON			0x08
+#define		CON_FIFO_FLUSH		BIT(0)
+#define		CON_NFI_RST			BIT(1)
+#define		CON_BRD				BIT(8)
+#define		CON_BWR				BIT(9)
+#define		CON_SEC_SHIFT		12
+#define		CON_SEC_MASK		GENMASK(16, 12)
+#define NFI_INTR_EN		0x10
+#define		INTR_CUS_PROG_EN	BIT(7)
+#define		INTR_CUS_READ_EN	BIT(8)
+#define		INTR_IRQ_EN			BIT(31)
+#define NFI_INTR_STA	0x14
+#define NFI_CMD			0x20
+#define NFI_STRDATA		0x40
+#define		STAR_EN				BIT(0)
+#define NFI_STA			0x60
+#define		NFI_FSM_MASK		GENMASK(19, 16)
+#define		STA_EMP_PAGE		BIT(12)
+#define NFI_ADDRCNTR	0x70
+#define		CNTR_MASK			GENMASK(16, 12)
+#define		ADDRCNTR_SEC_SHIFT	12
+#define		ADDRCNTR_SEC(val) \
+		(((val) & CNTR_MASK) >> ADDRCNTR_SEC_SHIFT)
+#define NFI_STRADDR		0x80
+#define NFI_BYTELEN		0x84
+#define NFI_FDML(x)		(0xA0 + (x) * sizeof(u32) * 2)
+#define NFI_FDMM(x)		(0xA4 + (x) * sizeof(u32) * 2)
+#define NFI_MASTERSTA	0x224
+#define		AHB_BUS_BUSY		BIT(1)
+#define		BUS_BUSY			BIT(0)
+#define SNFI_MAC_OUTL	0x504
+#define SNFI_MAC_INL	0x508
+#define SNFI_RD_CTL2	0x510
+#define		RD_CMD_MASK			0x00ff
+#define		RD_DUMMY_SHIFT		8
+#define SNFI_RD_CTL3			0x514
+#define		RD_ADDR_MASK		0xffff
+#define SNFI_MISC_CTL	0x538
+#define		RD_MODE_MASK		GENMASK(18, 16)
+#define		LATCH_LAT_MASK		GENMASK(9, 8)
+#define		LATCH_LAT_SHIFT		8
+#define		RD_MODE_X2			BIT(16)
+#define		RD_MODE_X4			BIT(17)
+#define		RD_MODE_DQUAL		BIT(18)
+#define		RD_CUSTOM_EN		BIT(6)
+#define		WR_CUSTOM_EN		BIT(7)
+#define		WR_X4_EN			BIT(20)
+#define		SW_RST				BIT(28)
+#define SNFI_MISC_CTL2	0x53c
+#define		WR_LEN_SHIFT		16
+#define SNFI_PG_CTL1	0x524
+#define		WR_LOAD_CMD_MASK	GENMASK(15, 8)
+#define		WR_LOAD_CMD_SHIFT	8
+#define SNFI_PG_CTL2	0x528
+#define		WR_LOAD_ADDR_MASK	GENMASK(15, 0)
+#define SNFI_MAC_CTL	0x500
+#define		MAC_WIP				BIT(0)
+#define		MAC_WIP_READY		BIT(1)
+#define		MAC_TRIG			BIT(2)
+#define		MAC_EN				BIT(3)
+#define		MAC_SIO_SEL			BIT(4)
+#define SNFI_DLY_CTL3	0x548
+#define		SAM_DLY_MASK		GENMASK(5, 0)
+#define SNFI_STA_CTL1	0x550
+#define		CUS_PROG_DONE		BIT(28)
+#define		CUS_READ_DONE		BIT(27)
+#define		SPI_STATE			GENMASK(3, 0)
+#define SNFI_CNFG		0x55c
+#define		SNFI_MODE_EN		BIT(0)
+#define SNFI_GPRAM_DATA	0x800
+#define		SNFI_GPRAM_MAX_LEN	160
+
+#define MTK_SNFI_TIMEOUT			500000
+#define MTK_SNFI_RESET_TIMEOUT		1000000
+#define MTK_SNFI_AUTOSUSPEND_DELAY	1000
+#define KB(x)			((x) * 1024UL)
+
+/* supported spare size of each IP */
+static const u8 spare_size_mt7622[] = {
+	16, 26, 27, 28
+};
+
+struct mtk_snfi_caps {
+	const u8 *spare_size;
+	u8 num_spare_size;
+	u8 pageformat_spare_shift;
+};
+
+struct mtk_snfi {
+	struct clk *nfi_clk;
+	struct clk *snfi_clk;
+	struct clk *hclk;
+	struct device *dev;
+	struct completion done;
+
+	const struct mtk_snfi_caps *caps;
+
+	bool ecc_en;
+	u32 page_size;
+	u32 fdm_size;
+	u32 spare_size_per_sector;
+	u32 spare_size_idx;
+	u32 sectors;
+	u32 sector_size;
+
+	u32 sample_delay;
+	u32 read_latency;
+
+	void *tx_buf;
+	dma_addr_t dma_addr;
+	void __iomem *regs;
+};
+
+static void mtk_snfi_mac_enable(struct mtk_snfi *snfi)
+{
+	u32 val;
+
+	val = readl(snfi->regs + SNFI_MAC_CTL);
+	val &= ~MAC_SIO_SEL;
+	val |= MAC_EN;
+
+	writel(val, snfi->regs + SNFI_MAC_CTL);
+}
+
+static int mtk_snfi_mac_trigger(struct mtk_snfi *snfi)
+{
+	u32 val;
+	int ret = 0;
+
+	val = readl(snfi->regs + SNFI_MAC_CTL);
+	val |= MAC_TRIG;
+	writel(val, snfi->regs + SNFI_MAC_CTL);
+
+	ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, val,
+					val & MAC_WIP_READY, 0,
+					MTK_SNFI_TIMEOUT);
+	if (ret < 0) {
+		dev_err(snfi->dev, "wait for wip ready timeout\n");
+		return -EIO;
+	}
+
+	ret = readl_poll_timeout_atomic(snfi->regs + SNFI_MAC_CTL, val,
+					!(val & MAC_WIP), 0,
+					MTK_SNFI_TIMEOUT);
+	if (ret < 0) {
+		dev_err(snfi->dev, "wait for flash update finish timeout\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void mtk_snfi_mac_disable(struct mtk_snfi *snfi)
+{
+	u32 val;
+
+	val = readl(snfi->regs + SNFI_MAC_CTL);
+	val &= ~(MAC_TRIG | MAC_EN);
+	writel(val, snfi->regs + SNFI_MAC_CTL);
+}
+
+static int mtk_snfi_mac_op(struct mtk_snfi *snfi)
+{
+	int ret = 0;
+
+	mtk_snfi_mac_enable(snfi);
+	ret = mtk_snfi_mac_trigger(snfi);
+	mtk_snfi_mac_disable(snfi);
+
+	return ret;
+}
+
+static inline void mtk_snfi_read_fdm(struct mtk_snfi *snfi,
+			const struct spi_mem_op *op)
+{
+	u32 vall, valm;
+	u8 *oobptr = op->data.buf.in;
+	int i, j;
+
+	oobptr += snfi->page_size;
+	for (i = 0; i < snfi->sectors; i++) {
+		vall = readl(snfi->regs + NFI_FDML(i));
+		valm = readl(snfi->regs + NFI_FDMM(i));
+
+		for (j = 0; j < snfi->fdm_size; j++)
+			oobptr[j] = (j >= 4 ? valm : vall) >> ((j % 4) * 8);
+
+		oobptr += snfi->fdm_size;
+	}
+}
+
+static inline void mtk_snfi_write_fdm(struct mtk_snfi *snfi,
+			const struct spi_mem_op *op)
+{
+	const u8 *oobptr = op->data.buf.out;
+	u32 vall, valm;
+	int i, j;
+
+	oobptr += snfi->page_size;
+	for (i = 0; i < snfi->sectors; i++) {
+		vall = 0;
+		valm = 0;
+		for (j = 0; j < 8; j++) {
+			if (j < 4)
+				vall |= (j < snfi->fdm_size ? oobptr[j] : 0xff)
+						<< (j * 8);
+			else
+				valm |= (j < snfi->fdm_size ? oobptr[j] : 0xff)
+						<< ((j - 4) * 8);
+		}
+		writel(vall, snfi->regs + NFI_FDML(i));
+		writel(valm, snfi->regs + NFI_FDMM(i));
+
+		oobptr += snfi->fdm_size;
+	}
+}
+
+static irqreturn_t mtk_snfi_irq(int irq, void *id)
+{
+	struct mtk_snfi *snfi = id;
+	u32 sta, ien;
+
+	sta = readl(snfi->regs + NFI_INTR_STA);
+	ien = readl(snfi->regs + NFI_INTR_EN);
+
+	if (!(sta & ien))
+		return IRQ_NONE;
+
+	writel(0, snfi->regs + NFI_INTR_EN);
+	complete(&snfi->done);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_snfi_enable_clk(struct device *dev, struct mtk_snfi *snfi)
+{
+	int ret;
+
+	ret = clk_prepare_enable(snfi->nfi_clk);
+	if (ret) {
+		dev_err(dev, "failed to enable nfi clk\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(snfi->snfi_clk);
+	if (ret) {
+		dev_err(dev, "failed to enable snfi clk\n");
+		clk_disable_unprepare(snfi->nfi_clk);
+		return ret;
+	}
+
+	ret = clk_prepare_enable(snfi->hclk);
+	if (ret) {
+		dev_err(dev, "failed to enable hclk\n");
+		clk_disable_unprepare(snfi->nfi_clk);
+		clk_disable_unprepare(snfi->snfi_clk);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void mtk_snfi_disable_clk(struct mtk_snfi *snfi)
+{
+	clk_disable_unprepare(snfi->nfi_clk);
+	clk_disable_unprepare(snfi->snfi_clk);
+	clk_disable_unprepare(snfi->hclk);
+}
+
+static int mtk_snfi_reset(struct mtk_snfi *snfi)
+{
+	u32 val;
+	int ret;
+
+	val = readl(snfi->regs + SNFI_MISC_CTL) | SW_RST;
+	writel(val, snfi->regs + SNFI_MISC_CTL);
+
+	ret = readw_poll_timeout(snfi->regs + SNFI_STA_CTL1, val,
+				 !(val & SPI_STATE), 0,
+				 MTK_SNFI_RESET_TIMEOUT);
+	if (ret) {
+		dev_warn(snfi->dev, "spi state not idle 0x%x\n", val);
+		return ret;
+	}
+
+	val = readl(snfi->regs + SNFI_MISC_CTL);
+	val &= ~SW_RST;
+	writel(val, snfi->regs + SNFI_MISC_CTL);
+
+	writew(CON_FIFO_FLUSH | CON_NFI_RST, snfi->regs + NFI_CON);
+	ret = readw_poll_timeout(snfi->regs + NFI_STA, val,
+				 !(val & NFI_FSM_MASK), 0,
+				 MTK_SNFI_RESET_TIMEOUT);
+	if (ret) {
+		dev_warn(snfi->dev, "nfi fsm not idle 0x%x\n", val);
+		return ret;
+	}
+
+	val = readl(snfi->regs + NFI_STRDATA);
+	val &= ~STAR_EN;
+	writew(val, snfi->regs + NFI_STRDATA);
+
+	return 0;
+}
+
+/*
+ * Due to the snfi driver at spi subsystem can not get nand parameter.
+ * Therefore, parse nand parameter from nfi register which have been
+ * config at ecc driver.
+ */
+static int mtk_snfi_config(struct mtk_snfi *snfi)
+{
+	u32 val, config;
+
+	writel(SNFI_MODE_EN, snfi->regs + SNFI_CNFG);
+
+	if (snfi->sample_delay) {
+		val = readl(snfi->regs + SNFI_DLY_CTL3);
+		val &= ~SAM_DLY_MASK;
+		val |= snfi->sample_delay;
+		writel(val, snfi->regs + SNFI_DLY_CTL3);
+	}
+
+	if (snfi->read_latency) {
+		val = readl(snfi->regs + SNFI_MISC_CTL);
+		val &= ~LATCH_LAT_MASK;
+		val |= (snfi->read_latency << LATCH_LAT_SHIFT);
+		writel(val, snfi->regs + SNFI_MISC_CTL);
+	}
+
+	/*
+	 * Get nand parameter and ecc status from the function
+	 * export by ecc driver
+	 */
+	snfi->ecc_en = mtk_ecc_get_status(snfi->dev->of_node);
+	snfi->sector_size = mtk_ecc_get_sectorsize(snfi->dev->of_node);
+	snfi->page_size = mtk_ecc_get_pagesize(snfi->dev->of_node);
+	snfi->spare_size_per_sector = mtk_ecc_get_sparesize(snfi->dev->of_node);
+	snfi->fdm_size = mtk_ecc_get_fdmsize(snfi->dev->of_node);
+	snfi->spare_size_idx = mtk_ecc_get_spare_idx(snfi->dev->of_node);
+	snfi->sectors = snfi->page_size / snfi->sector_size;
+
+	/* config nfi regs with nand parameter and ecc status */
+	switch (snfi->page_size) {
+	case 512:
+		val = PAGEFMT_512_2K | PAGEFMT_SEC_SEL_512;
+		break;
+	case KB(2):
+		if (snfi->sector_size == 512)
+			val = PAGEFMT_2K_4K | PAGEFMT_SEC_SEL_512;
+		else
+			val = PAGEFMT_512_2K;
+		break;
+	case KB(4):
+		if (snfi->sector_size == 512)
+			val = PAGEFMT_4K_8K | PAGEFMT_SEC_SEL_512;
+		else
+			val = PAGEFMT_2K_4K;
+		break;
+	case KB(8):
+		if (snfi->sector_size == 512)
+			val = PAGEFMT_8K_16K | PAGEFMT_SEC_SEL_512;
+		else
+			val = PAGEFMT_4K_8K;
+		break;
+	case KB(16):
+		val = PAGEFMT_8K_16K;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	val |= snfi->spare_size_idx << PAGEFMT_SPARE_SHIFT;
+	val |= snfi->fdm_size << PAGEFMT_FDM_SHIFT;
+	/* fdm size equal to fdm ecc size */
+	val |= snfi->fdm_size << PAGEFMT_FDM_ECC_SHIFT;
+	writel(val, snfi->regs + NFI_PAGEFMT);
+
+	return 0;
+}
+
+static int mtk_snfi_init(struct mtk_snfi *snfi)
+{
+	int ret;
+
+	ret = mtk_snfi_reset(snfi);
+	if (ret)
+		return ret;
+
+	ret = mtk_snfi_config(snfi);
+
+	return ret;
+}
+
+static void mtk_snfi_prepare_for_tx(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op)
+{
+	u32 val;
+
+	writel(0x80, snfi->regs + NFI_CMD);
+	val = readl(snfi->regs + SNFI_PG_CTL1);
+	val &= ~WR_LOAD_CMD_MASK;
+	val |= op->cmd.opcode << WR_LOAD_CMD_SHIFT;
+	writel(val, snfi->regs + SNFI_PG_CTL1);
+
+	writel(op->addr.val & WR_LOAD_ADDR_MASK,
+		   snfi->regs + SNFI_PG_CTL2);
+
+	val = readl(snfi->regs + SNFI_MISC_CTL);
+	val |= WR_CUSTOM_EN;
+	if (op->data.buswidth == 4)
+		val |= WR_X4_EN;
+	writel(val, snfi->regs + SNFI_MISC_CTL);
+
+	val = snfi->page_size + snfi->sectors * snfi->spare_size;
+
+	writel(val << WR_LEN_SHIFT,
+		snfi->regs + SNFI_MISC_CTL2);
+	writel(INTR_CUS_PROG_EN | INTR_IRQ_EN,
+		snfi->regs + NFI_INTR_EN);
+}
+
+static void mtk_snfi_prepare_for_rx(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op)
+{
+	u32 val, dummy_cycle;
+
+	writel(0x00, snfi->regs + NFI_CMD);
+	dummy_cycle = (op->dummy.nbytes << 3) >>
+				  (ffs(op->dummy.buswidth) - 1);
+	val = (op->cmd.opcode & RD_CMD_MASK) |
+		  (dummy_cycle << RD_DUMMY_SHIFT);
+	writel(val, snfi->regs + SNFI_RD_CTL2);
+
+	writel(op->addr.val & RD_ADDR_MASK,
+		   snfi->regs + SNFI_RD_CTL3);
+
+	val = readl(snfi->regs + SNFI_MISC_CTL);
+	val |= RD_CUSTOM_EN;
+	val &= ~RD_MODE_MASK;
+	if (op->data.buswidth == 4)
+		val |= RD_MODE_X4;
+	else if (op->data.buswidth == 2)
+		val |= RD_MODE_X2;
+
+	if (op->addr.buswidth != 1)
+		val |= RD_MODE_DQUAL;
+	writel(val, snfi->regs + SNFI_MISC_CTL);
+
+	val = snfi->page_size + snfi->sectors * snfi->spare_size;
+	writel(val, snfi->regs + SNFI_MISC_CTL2);
+	writel(INTR_CUS_READ_EN | INTR_IRQ_EN,
+		   snfi->regs + NFI_INTR_EN);
+}
+
+static int mtk_snfi_prepare(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op, bool rx)
+{
+	int ret;
+	dma_addr_t addr;
+	u32 val;
+
+	addr = dma_map_single(snfi->dev,
+				op->data.buf.in, op->data.nbytes,
+				rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+	ret = dma_mapping_error(snfi->dev, addr);
+	if (ret) {
+		dev_err(snfi->dev, "dma mapping error\n");
+		return -EINVAL;
+	}
+
+	snfi->dma_addr = addr;
+	writel(lower_32_bits(addr), snfi->regs + NFI_STRADDR);
+
+	if (snfi->ecc_en && !rx)
+		mtk_snfi_write_fdm(snfi, op);
+
+	val = readw(snfi->regs + NFI_CNFG);
+	val |= CNFG_DMA | CNFG_DMA_BURST_EN | CNFG_OP_CUST;
+	val |= rx ? CNFG_READ_EN : 0;
+	writew(val, snfi->regs + NFI_CNFG);
+
+	writel(snfi->sectors << CON_SEC_SHIFT, snfi->regs + NFI_CON);
+
+	init_completion(&snfi->done);
+
+	if (rx)
+		mtk_snfi_prepare_for_rx(snfi, op);
+	else
+		mtk_snfi_prepare_for_tx(snfi, op);
+
+	return 0;
+}
+
+static void mtk_snfi_trigger(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op, bool rx)
+{
+	u32 val;
+
+	val = readl(snfi->regs + NFI_CON);
+	val |= rx ? CON_BRD : CON_BWR;
+	writew(val, snfi->regs + NFI_CON);
+
+	writew(STAR_EN, snfi->regs + NFI_STRDATA);
+}
+
+static int mtk_snfi_wait_done(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op, bool rx)
+{
+	u32 val;
+	int ret;
+
+	ret = wait_for_completion_timeout(&snfi->done, msecs_to_jiffies(500));
+	if (!ret) {
+		dev_err(snfi->dev, "wait for %d completion done timeout\n", rx);
+		dump_register(snfi);
+		return -ETIMEDOUT;
+	}
+
+	if (rx) {
+		ret = readl_poll_timeout_atomic(snfi->regs + NFI_BYTELEN, val,
+						ADDRCNTR_SEC(val) >= snfi->sectors, 0,
+						MTK_SNFI_TIMEOUT);
+		if (ret < 0) {
+			dev_err(snfi->dev, "wait for read sector count timeout\n");
+			dump_register(snfi);
+			return -ETIMEDOUT;
+		}
+
+		ret = readl_poll_timeout_atomic(snfi->regs + NFI_MASTERSTA, val,
+					!(val & (AHB_BUS_BUSY | BUS_BUSY)),
+					0, MTK_SNFI_TIMEOUT);
+		if (ret) {
+			dev_err(snfi->dev, "wait for bus busy timeout\n");
+			dump_register(snfi);
+			return -ETIMEDOUT;
+		}
+	} else {
+		ret = readl_poll_timeout_atomic(snfi->regs + NFI_ADDRCNTR, val,
+						ADDRCNTR_SEC(val) >= snfi->sectors,
+						0, MTK_SNFI_TIMEOUT);
+		if (ret) {
+			dev_err(snfi->dev, "wait for program sector count timeout\n");
+			dump_register(snfi);
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+static void mtk_snfi_complete(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op, bool rx)
+{
+	u32 val;
+
+	dma_unmap_single(snfi->dev,
+					 snfi->dma_addr, op->data.nbytes,
+					 rx ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+
+	if (snfi->ecc_en && rx)
+		mtk_snfi_read_fdm(snfi, op);
+
+	val = readl(snfi->regs + SNFI_MISC_CTL);
+	val &= rx ? ~RD_CUSTOM_EN : ~WR_CUSTOM_EN;
+	writel(val, snfi->regs + SNFI_MISC_CTL);
+
+	val = readl(snfi->regs + SNFI_STA_CTL1);
+	val |= rx ? CUS_READ_DONE : CUS_PROG_DONE;
+	writew(val, snfi->regs + SNFI_STA_CTL1);
+	val &= rx ? ~CUS_READ_DONE : ~CUS_PROG_DONE;
+	writew(val, snfi->regs + SNFI_STA_CTL1);
+
+	/* Disable interrupt */
+	val = readl(snfi->regs + NFI_INTR_EN);
+	val &= rx ? ~INTR_CUS_READ_EN : ~INTR_CUS_PROG_EN;
+	writew(val, snfi->regs + NFI_INTR_EN);
+
+	writew(0, snfi->regs + NFI_CNFG);
+	writew(0, snfi->regs + NFI_CON);
+}
+
+static int mtk_snfi_transfer_dma(struct mtk_snfi *snfi,
+			   const struct spi_mem_op *op, bool rx)
+{
+	int ret;
+
+	ret = mtk_snfi_prepare(snfi, op, rx);
+	if (ret)
+		return ret;
+
+	mtk_snfi_trigger(snfi, op, rx);
+
+	ret = mtk_snfi_wait_done(snfi, op, rx);
+
+	mtk_snfi_complete(snfi, op, rx);
+
+	return ret;
+}
+
+static int mtk_snfi_transfer_mac(struct mtk_snfi *snfi,
+			    const u8 *txbuf, u8 *rxbuf,
+			    const u32 txlen, const u32 rxlen)
+{
+	u32 i, j, val, tmp;
+	u8 *p_tmp = (u8 *)(&tmp);
+	u32 addr_offset = 0;
+	int ret = 0;
+
+	/* Move tx data to snfi gpram */
+	for (i = 0; i < txlen; ) {
+		for (j = 0, tmp = 0; i < txlen && j < 4; i++, j++)
+			p_tmp[j] = txbuf[i];
+
+		writel(tmp, snfi->regs + SNFI_GPRAM_DATA + addr_offset);
+		addr_offset += 4;
+	}
+
+	writel(txlen, snfi->regs + SNFI_MAC_OUTL);
+	writel(rxlen, snfi->regs + SNFI_MAC_INL);
+
+	ret = mtk_snfi_mac_op(snfi);
+	if (ret) {
+		dev_warn(snfi->dev, "snfi mac operation fail\n");
+		return ret;
+	}
+
+	/* Get tx data from snfi gpram */
+	if (rxlen) {
+		for (i = 0, addr_offset = rounddown(txlen, 4); i < rxlen; ) {
+			val = readl(snfi->regs +
+					    SNFI_GPRAM_DATA + addr_offset);
+			for (j = 0; i < rxlen && j < 4; i++, j++, rxbuf++) {
+				if (i == 0)
+					j = txlen % 4;
+				*rxbuf = (val >> (j * 8)) & 0xff;
+			}
+			addr_offset += 4;
+		}
+	}
+
+	return ret;
+}
+
+static int mtk_snfi_exec_op(struct spi_mem *mem,
+			    const struct spi_mem_op *op)
+
+{
+	struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
+	u8 *buf, *txbuf = snfi->tx_buf, *rxbuf = NULL;
+	u32 txlen = 0, rxlen = 0;
+	int i, ret = 0;
+	bool rx;
+
+	rx = op->data.dir == SPI_MEM_DATA_IN;
+
+	ret = mtk_snfi_init(snfi);
+	if (ret) {
+		dev_warn(snfi->dev, "reset snfi fail\n");
+		return ret;
+	}
+
+	/*
+	 * If tx/rx data buswidth is not 1, use snfi DMA mode.
+	 * Otherwise, use snfi mac mode.
+	 */
+	if ((op->data.buswidth != 1) && (op->data.buswidth != 0)) {
+		ret = mtk_snfi_transfer_dma(snfi, op, rx);
+		if (ret)
+			dev_warn(snfi->dev, "snfi dma transfer %d fail %d\n",
+					 rx, ret);
+		return ret;
+	}
+
+	txbuf[txlen++] = op->cmd.opcode;
+
+	if (op->addr.nbytes)
+		for (i = 0; i < op->addr.nbytes; i++)
+			txbuf[txlen++] = op->addr.val >>
+					(8 * (op->addr.nbytes - i - 1));
+
+	txlen += op->dummy.nbytes;
+
+	if (op->data.dir == SPI_MEM_DATA_OUT) {
+		buf = (u8 *)op->data.buf.out;
+		for (i = 0; i < op->data.nbytes; i++)
+			txbuf[txlen++] = buf[i];
+	}
+
+	if (op->data.dir == SPI_MEM_DATA_IN) {
+		rxbuf = (u8 *)op->data.buf.in;
+		rxlen = op->data.nbytes;
+	}
+
+	ret = mtk_snfi_transfer_mac(snfi, txbuf, rxbuf, txlen, rxlen);
+	if (ret)
+		dev_warn(snfi->dev, "snfi mac transfer %d fail %d\n",
+				 op->data.dir, ret);
+	return ret;
+}
+
+static int mtk_snfi_check_buswidth(u8 width)
+{
+	switch (width) {
+	case 1:
+	case 2:
+	case 4:
+		return 0;
+
+	default:
+		break;
+	}
+
+	return -ENOTSUPP;
+}
+
+static bool mtk_snfi_supports_op(struct spi_mem *mem,
+				 const struct spi_mem_op *op)
+{
+	struct mtk_snfi *snfi = spi_controller_get_devdata(mem->spi->master);
+	int ret = 0;
+	u32 val;
+
+	if (!spi_mem_default_supports_op(mem, op))
+		return false;
+
+	if (op->cmd.buswidth != 1)
+		return false;
+
+	val = readl(snfi->regs + NFI_CNFG);
+	if (val & CNFG_HW_ECC_EN)
+		snfi->ecc_en = true;
+	else
+		snfi->ecc_en = false;
+
+	/*
+	 * For current design, the operation will use mac mode when data
+	 * buswidth is 1. However, the HW ECC can not be used in mac mode.
+	 */
+	if (snfi->ecc_en && op->data.buswidth == 1 &&
+			op->data.nbytes >= SNFI_GPRAM_MAX_LEN)
+		return false;
+
+	switch (op->data.dir) {
+	case SPI_MEM_DATA_IN:
+		if (op->addr.nbytes)
+			ret |= mtk_snfi_check_buswidth(op->addr.buswidth);
+
+		if (op->dummy.nbytes)
+			ret |= mtk_snfi_check_buswidth(op->dummy.buswidth);
+
+		if (op->data.nbytes)
+			ret |= mtk_snfi_check_buswidth(op->data.buswidth);
+
+		if (ret)
+			return false;
+
+		break;
+	case SPI_MEM_DATA_OUT:
+		if ((op->addr.buswidth != 0) && (op->addr.buswidth != 1))
+			return false;
+
+		if ((op->dummy.buswidth != 0) && (op->dummy.buswidth != 1))
+			return false;
+
+		if ((op->data.buswidth != 1) && (op->data.buswidth != 4))
+			return false;
+
+		break;
+	default:
+		break;
+	}
+
+	return true;
+}
+
+static int mtk_snfi_adjust_op_size(struct spi_mem *mem,
+				   struct spi_mem_op *op)
+{
+	u32 len, max_len;
+
+	if ((op->data.buswidth == 1) || (op->data.buswidth == 0))
+		max_len = SNFI_GPRAM_MAX_LEN;
+	else
+		max_len = KB(16);
+
+	len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
+	if (len > max_len)
+		return -ENOTSUPP;
+
+	if ((len + op->data.nbytes) > max_len)
+		op->data.nbytes = max_len - len;
+
+	return 0;
+}
+
+static struct mtk_snfi *mtk_snfi_get(struct device_node *np)
+{
+	struct platform_device *pdev;
+	struct spi_controller *ctlr;
+	struct mtk_snfi *snfi = NULL;
+
+	pdev = of_find_device_by_node(np);
+	if (!pdev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	ctlr = spi_controller_get(platform_get_drvdata(pdev));
+	if (!ctlr) {
+		put_device(&pdev->dev);
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	snfi = spi_controller_get_devdata(ctlr);
+
+	return snfi;
+}
+
+/*
+ * export this function for HW ECC to use,
+ * due to the spim can not return this status
+ */
+bool mtk_snfi_check_empty(struct device_node *dn)
+{
+	struct device_node *parent_dn;
+	struct mtk_snfi *snfi;
+	bool read_empty;
+
+	parent_dn = of_get_parent(dn);
+	snfi = mtk_snfi_get(parent_dn);
+
+	read_empty = readl(snfi->regs + NFI_STA) & STA_EMP_PAGE;
+
+	return read_empty;
+}
+EXPORT_SYMBOL(mtk_snfi_check_empty);
+
+static const struct mtk_snfi_caps mtk_snfi_caps_mt7622 = {
+	.spare_size = spare_size_mt7622,
+	.num_spare_size = 4,
+	.pageformat_spare_shift = 16,
+};
+
+static const struct spi_controller_mem_ops mtk_snfi_ops = {
+	.adjust_op_size = mtk_snfi_adjust_op_size,
+	.supports_op = mtk_snfi_supports_op,
+	.exec_op = mtk_snfi_exec_op,
+};
+
+static const struct of_device_id mtk_snfi_id_table[] = {
+	{ .compatible = "mediatek,mt7622-snfi",
+	  .data = &mtk_snfi_caps_mt7622,
+	},
+	{  /* sentinel */ }
+};
+
+static int mtk_snfi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct spi_controller *ctlr;
+	struct mtk_snfi *snfi;
+	struct resource *res;
+	int ret, irq;
+	u32 val;
+
+	ctlr = spi_alloc_master(&pdev->dev, sizeof(*snfi));
+	if (!ctlr)
+		return -ENOMEM;
+
+	snfi = spi_controller_get_devdata(ctlr);
+	snfi->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	snfi->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(snfi->regs)) {
+		ret = PTR_ERR(snfi->regs);
+		goto err_put_master;
+	}
+
+	ret = of_property_read_u32(np, "sample-delay", &val);
+	if (ret) {
+		dev_err(dev, "no sample-delay property\n");
+		return ret;
+	}
+	snfi->sample_delay = val;
+
+	ret = of_property_read_u32(np, "read-latency", &val);
+	if (ret) {
+		dev_err(dev, "no read-latency property\n");
+		return ret;
+	}
+	snfi->read_latency = val;
+
+	snfi->nfi_clk = devm_clk_get(dev, "nfi_clk");
+	if (IS_ERR(snfi->nfi_clk)) {
+		dev_err(dev, "no nfi clk\n");
+		ret = PTR_ERR(snfi->nfi_clk);
+		goto err_put_master;
+	}
+
+	snfi->snfi_clk = devm_clk_get(dev, "snfi_clk");
+	if (IS_ERR(snfi->snfi_clk)) {
+		dev_err(dev, "no snfi clk\n");
+		ret = PTR_ERR(snfi->snfi_clk);
+		goto err_put_master;
+	}
+
+	snfi->hclk = devm_clk_get(dev, "hclk");
+	if (IS_ERR(snfi->hclk)) {
+		dev_err(dev, "no hclk\n");
+		ret = PTR_ERR(snfi->hclk);
+		goto err_put_master;
+	}
+
+	ret = mtk_snfi_enable_clk(dev, snfi);
+	if (ret)
+		goto err_put_master;
+
+	snfi->caps = of_device_get_match_data(dev);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(dev, "no snfi irq resource\n");
+		ret = -EINVAL;
+		goto clk_disable;
+	}
+
+	ret = devm_request_irq(dev, irq, mtk_snfi_irq, 0, "mtk-snfi", snfi);
+	if (ret) {
+		dev_err(dev, "failed to request snfi irq\n");
+		goto clk_disable;
+	}
+
+	ret = dma_set_mask(dev, DMA_BIT_MASK(32));
+	if (ret) {
+		dev_err(dev, "failed to set dma mask\n");
+		goto clk_disable;
+	}
+
+	snfi->tx_buf = kzalloc(SNFI_GPRAM_MAX_LEN, GFP_KERNEL);
+	if (!snfi->tx_buf) {
+		ret = -ENOMEM;
+		goto clk_disable;
+	}
+
+	ctlr->dev.of_node = np;
+	ctlr->mem_ops = &mtk_snfi_ops;
+	ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_QUAD;
+	ctlr->auto_runtime_pm = false;
+
+	dev_set_drvdata(&pdev->dev, ctlr);
+
+	ret = mtk_snfi_init(snfi);
+	if (ret) {
+		dev_err(dev, "failed to init snfi\n");
+		goto free_buf;
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	ret = devm_spi_register_master(dev, ctlr);
+	if (ret) {
+		dev_err(dev, "failed to register spi master\n");
+		goto disable_pm_runtime;
+	}
+
+	return 0;
+
+disable_pm_runtime:
+	pm_runtime_disable(&pdev->dev);
+
+free_buf:
+	kfree(snfi->tx_buf);
+
+clk_disable:
+	mtk_snfi_disable_clk(snfi);
+
+err_put_master:
+	spi_master_put(ctlr);
+
+	return ret;
+}
+
+static int mtk_snfi_remove(struct platform_device *pdev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
+	struct mtk_snfi *snfi = spi_controller_get_devdata(ctlr);
+
+	pm_runtime_disable(&pdev->dev);
+	kfree(snfi->tx_buf);
+	spi_master_put(ctlr);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int mtk_snfi_runtime_suspend(struct device *dev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+	struct mtk_snfi *snfi = spi_controller_get_devdata(ctlr);
+
+	mtk_snfi_disable_clk(snfi);
+
+	return 0;
+}
+
+static int mtk_snfi_runtime_resume(struct device *dev)
+{
+	struct spi_controller *ctlr = dev_get_drvdata(dev);
+	struct mtk_snfi *snfi = spi_controller_get_devdata(ctlr);
+	int ret;
+
+	ret = mtk_snfi_enable_clk(dev, snfi);
+	if (ret)
+		return ret;
+
+	ret = mtk_snfi_init(snfi);
+	if (ret)
+		dev_err(dev, "failed to init snfi\n");
+
+	return ret;
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops mtk_snfi_pm_ops = {
+	SET_RUNTIME_PM_OPS(mtk_snfi_runtime_suspend,
+			   mtk_snfi_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+			   pm_runtime_force_resume)
+};
+
+static struct platform_driver mtk_snfi_driver = {
+	.driver = {
+		.name	= "mtk-snfi",
+		.of_match_table = mtk_snfi_id_table,
+		.pm = &mtk_snfi_pm_ops,
+	},
+	.probe		= mtk_snfi_probe,
+	.remove		= mtk_snfi_remove,
+};
+
+module_platform_driver(mtk_snfi_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Xiangsheng Hou <xiangsheng.hou at mediatek.com>");
+MODULE_DESCRIPTION("Mediatek SPI Nand Interface Driver");
-- 
2.25.1



From xiangsheng.hou at mediatek.com  Sun Sep 26 22:42:02 2021
From: xiangsheng.hou at mediatek.com (Xiangsheng Hou)
Date: Mon, 27 Sep 2021 13:42:02 +0800
Subject: [RFC,v2 1/4] mtd: ecc: move mediatek HW ECC driver
In-Reply-To: <20210927054205.17960-1-xiangsheng.hou@mediatek.com>
References: <20210927054205.17960-1-xiangsheng.hou@mediatek.com>
Message-ID: <20210927054205.17960-2-xiangsheng.hou@mediatek.com>

Move Mediatek HW ECC source driver to mtd nand folder and the header
file to include linux mtd folder.
The HW ECC driver can be used by Mediatek raw nand and spi nand
controller.

Signed-off-by: Xiangsheng Hou <xiangsheng.hou at mediatek.com>
---
 drivers/mtd/nand/Kconfig                              | 9 +++++++++
 drivers/mtd/nand/Makefile                             | 1 +
 drivers/mtd/nand/{raw => }/mtk_ecc.c                  | 2 +-
 drivers/mtd/nand/raw/Kconfig                          | 1 +
 drivers/mtd/nand/raw/Makefile                         | 2 +-
 drivers/mtd/nand/raw/mtk_nand.c                       | 2 +-
 {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h | 0
 7 files changed, 14 insertions(+), 3 deletions(-)
 rename drivers/mtd/nand/{raw => }/mtk_ecc.c (99%)
 rename {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h (100%)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index b40455234cbd..e657823329d2 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -46,6 +46,15 @@ config MTD_NAND_ECC_SW_BCH
 	  ECC codes. They are used with NAND devices requiring more than 1 bit
 	  of error correction.
 
+config MTD_NAND_ECC_MTK
+	bool "Mediatek hardware ECC engine"
+	select MTD_NAND_ECC
+	help
+	  This enables support for Mediatek hardware ECC engine which
+	  used for error correction. This correction strength depends
+	  on different project. The ECC engine can be used with Mediatek
+	  raw nand and spi nand controller driver.
+
 endmenu
 
 endmenu
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 1c0b46960eb1..66d1741fe7ff 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -10,3 +10,4 @@ obj-y	+= spi/
 nandcore-$(CONFIG_MTD_NAND_ECC) += ecc.o
 nandcore-$(CONFIG_MTD_NAND_ECC_SW_HAMMING) += ecc-sw-hamming.o
 nandcore-$(CONFIG_MTD_NAND_ECC_SW_BCH) += ecc-sw-bch.o
+nandcore-$(CONFIG_MTD_NAND_ECC_MTK) += mtk_ecc.o
diff --git a/drivers/mtd/nand/raw/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c
similarity index 99%
rename from drivers/mtd/nand/raw/mtk_ecc.c
rename to drivers/mtd/nand/mtk_ecc.c
index c437d97debb8..ce0f8b491e5d 100644
--- a/drivers/mtd/nand/raw/mtk_ecc.c
+++ b/drivers/mtd/nand/mtk_ecc.c
@@ -16,7 +16,7 @@
 #include <linux/of_platform.h>
 #include <linux/mutex.h>
 
-#include "mtk_ecc.h"
+#include <linux/mtd/mtk_ecc.h>
 
 #define ECC_IDLE_MASK		BIT(0)
 #define ECC_IRQ_EN		BIT(0)
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 67b7cb67c030..c90bc166034b 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -362,6 +362,7 @@ config MTD_NAND_MTK
 	tristate "MTK NAND controller"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
 	depends on HAS_IOMEM
+	select MTD_NAND_ECC_MTK
 	help
 	  Enables support for NAND controller on MTK SoCs.
 	  This controller is found on mt27xx, mt81xx, mt65xx SoCs.
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index 2f97958c3a33..49d3946c166b 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -48,7 +48,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI)		+= sunxi_nand.o
 obj-$(CONFIG_MTD_NAND_HISI504)	        += hisi504_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmnand/
 obj-$(CONFIG_MTD_NAND_QCOM)		+= qcom_nandc.o
-obj-$(CONFIG_MTD_NAND_MTK)		+= mtk_ecc.o mtk_nand.o
+obj-$(CONFIG_MTD_NAND_MTK)		+= mtk_nand.o
 obj-$(CONFIG_MTD_NAND_MXIC)		+= mxic_nand.o
 obj-$(CONFIG_MTD_NAND_TEGRA)		+= tegra_nand.o
 obj-$(CONFIG_MTD_NAND_STM32_FMC2)	+= stm32_fmc2_nand.o
diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
index 5c5c92132287..7d8a6b35c102 100644
--- a/drivers/mtd/nand/raw/mtk_nand.c
+++ b/drivers/mtd/nand/raw/mtk_nand.c
@@ -17,7 +17,7 @@
 #include <linux/iopoll.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include "mtk_ecc.h"
+#include <linux/mtd/mtk_ecc.h>
 
 /* NAND controller register definition */
 #define NFI_CNFG		(0x00)
diff --git a/drivers/mtd/nand/raw/mtk_ecc.h b/include/linux/mtd/mtk_ecc.h
similarity index 100%
rename from drivers/mtd/nand/raw/mtk_ecc.h
rename to include/linux/mtd/mtk_ecc.h
-- 
2.25.1



From xiangsheng.hou at mediatek.com  Sun Sep 26 22:36:26 2021
From: xiangsheng.hou at mediatek.com (Xiangsheng Hou)
Date: Mon, 27 Sep 2021 13:36:26 +0800
Subject: [RFC,v1 1/4] mtd: ecc: move mediatek HW ECC driver
In-Reply-To: <20210927053629.17847-1-xiangsheng.hou@mediatek.com>
References: <20210927053629.17847-1-xiangsheng.hou@mediatek.com>
Message-ID: <20210927053629.17847-2-xiangsheng.hou@mediatek.com>

Move Mediatek HW ECC source driver to mtd nand folder and the header
file to include linux mtd folder.
The HW ECC driver can be used by Mediatek raw nand and spi nand
controller.

Signed-off-by: Xiangsheng Hou <xiangsheng.hou at mediatek.com>
---
 drivers/mtd/nand/Kconfig                              | 9 +++++++++
 drivers/mtd/nand/Makefile                             | 1 +
 drivers/mtd/nand/{raw => }/mtk_ecc.c                  | 2 +-
 drivers/mtd/nand/raw/Kconfig                          | 1 +
 drivers/mtd/nand/raw/Makefile                         | 2 +-
 drivers/mtd/nand/raw/mtk_nand.c                       | 2 +-
 {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h | 0
 7 files changed, 14 insertions(+), 3 deletions(-)
 rename drivers/mtd/nand/{raw => }/mtk_ecc.c (99%)
 rename {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h (100%)

diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index b40455234cbd..e657823329d2 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -46,6 +46,15 @@ config MTD_NAND_ECC_SW_BCH
 	  ECC codes. They are used with NAND devices requiring more than 1 bit
 	  of error correction.
 
+config MTD_NAND_ECC_MTK
+	bool "Mediatek hardware ECC engine"
+	select MTD_NAND_ECC
+	help
+	  This enables support for Mediatek hardware ECC engine which
+	  used for error correction. This correction strength depends
+	  on different project. The ECC engine can be used with Mediatek
+	  raw nand and spi nand controller driver.
+
 endmenu
 
 endmenu
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 1c0b46960eb1..66d1741fe7ff 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -10,3 +10,4 @@ obj-y	+= spi/
 nandcore-$(CONFIG_MTD_NAND_ECC) += ecc.o
 nandcore-$(CONFIG_MTD_NAND_ECC_SW_HAMMING) += ecc-sw-hamming.o
 nandcore-$(CONFIG_MTD_NAND_ECC_SW_BCH) += ecc-sw-bch.o
+nandcore-$(CONFIG_MTD_NAND_ECC_MTK) += mtk_ecc.o
diff --git a/drivers/mtd/nand/raw/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c
similarity index 99%
rename from drivers/mtd/nand/raw/mtk_ecc.c
rename to drivers/mtd/nand/mtk_ecc.c
index c437d97debb8..ce0f8b491e5d 100644
--- a/drivers/mtd/nand/raw/mtk_ecc.c
+++ b/drivers/mtd/nand/mtk_ecc.c
@@ -16,7 +16,7 @@
 #include <linux/of_platform.h>
 #include <linux/mutex.h>
 
-#include "mtk_ecc.h"
+#include <linux/mtd/mtk_ecc.h>
 
 #define ECC_IDLE_MASK		BIT(0)
 #define ECC_IRQ_EN		BIT(0)
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 67b7cb67c030..c90bc166034b 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -362,6 +362,7 @@ config MTD_NAND_MTK
 	tristate "MTK NAND controller"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
 	depends on HAS_IOMEM
+	select MTD_NAND_ECC_MTK
 	help
 	  Enables support for NAND controller on MTK SoCs.
 	  This controller is found on mt27xx, mt81xx, mt65xx SoCs.
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index 2f97958c3a33..49d3946c166b 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -48,7 +48,7 @@ obj-$(CONFIG_MTD_NAND_SUNXI)		+= sunxi_nand.o
 obj-$(CONFIG_MTD_NAND_HISI504)	        += hisi504_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmnand/
 obj-$(CONFIG_MTD_NAND_QCOM)		+= qcom_nandc.o
-obj-$(CONFIG_MTD_NAND_MTK)		+= mtk_ecc.o mtk_nand.o
+obj-$(CONFIG_MTD_NAND_MTK)		+= mtk_nand.o
 obj-$(CONFIG_MTD_NAND_MXIC)		+= mxic_nand.o
 obj-$(CONFIG_MTD_NAND_TEGRA)		+= tegra_nand.o
 obj-$(CONFIG_MTD_NAND_STM32_FMC2)	+= stm32_fmc2_nand.o
diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
index 5c5c92132287..7d8a6b35c102 100644
--- a/drivers/mtd/nand/raw/mtk_nand.c
+++ b/drivers/mtd/nand/raw/mtk_nand.c
@@ -17,7 +17,7 @@
 #include <linux/iopoll.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include "mtk_ecc.h"
+#include <linux/mtd/mtk_ecc.h>
 
 /* NAND controller register definition */
 #define NFI_CNFG		(0x00)
diff --git a/drivers/mtd/nand/raw/mtk_ecc.h b/include/linux/mtd/mtk_ecc.h
similarity index 100%
rename from drivers/mtd/nand/raw/mtk_ecc.h
rename to include/linux/mtd/mtk_ecc.h
-- 
2.25.1



From xiangsheng.hou at mediatek.com  Sun Sep 26 22:42:03 2021
From: xiangsheng.hou at mediatek.com (Xiangsheng Hou)
Date: Mon, 27 Sep 2021 13:42:03 +0800
Subject: [RFC,v2 2/4] mtd: ecc: realize Mediatek HW ECC driver
In-Reply-To: <20210927054205.17960-1-xiangsheng.hou@mediatek.com>
References: <20210927054205.17960-1-xiangsheng.hou@mediatek.com>
Message-ID: <20210927054205.17960-3-xiangsheng.hou@mediatek.com>

The v2 driver export some function for snfi driver in spi
subsystem to use, include nand parameter(page/spare size)
and ecc status(enable/disable).Also need empty page check
function export from snfi driver.

Signed-off-by: Xiangsheng Hou <xiangsheng.hou at mediatek.com>
---
 drivers/mtd/nand/core.c    |   2 +-
 drivers/mtd/nand/ecc.c     |  19 +++
 drivers/mtd/nand/mtk_ecc.c | 315 +++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h   |  12 ++
 4 files changed, 347 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
index 5e13a03d2b32..3db410de3ba2 100644
--- a/drivers/mtd/nand/core.c
+++ b/drivers/mtd/nand/core.c
@@ -232,7 +232,7 @@ static int nanddev_get_ecc_engine(struct nand_device *nand)
 		nand->ecc.engine = nand_ecc_get_on_die_hw_engine(nand);
 		break;
 	case NAND_ECC_ENGINE_TYPE_ON_HOST:
-		pr_err("On-host hardware ECC engines not supported yet\n");
+		nand->ecc.engine = nand_ecc_get_on_host_hw_engine(nand);
 		break;
 	default:
 		pr_err("Missing ECC engine type\n");
diff --git a/drivers/mtd/nand/ecc.c b/drivers/mtd/nand/ecc.c
index 6c43dfda01d4..b334cd88c038 100644
--- a/drivers/mtd/nand/ecc.c
+++ b/drivers/mtd/nand/ecc.c
@@ -380,6 +380,7 @@ static const char * const nand_ecc_algos[] = {
 	[NAND_ECC_ALGO_HAMMING] = "hamming",
 	[NAND_ECC_ALGO_BCH] = "bch",
 	[NAND_ECC_ALGO_RS] = "rs",
+	[NAND_ECC_ALGO_MTK_HWECC] = "ecc-mtk",
 };
 
 static enum nand_ecc_algo of_get_nand_ecc_algo(struct device_node *np)
@@ -611,6 +612,24 @@ struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand)
 }
 EXPORT_SYMBOL(nand_ecc_get_on_die_hw_engine);
 
+struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand)
+{
+	unsigned int algo = nand->ecc.user_conf.algo;
+
+	if (algo == NAND_ECC_ALGO_UNKNOWN)
+		algo = nand->ecc.defaults.algo;
+
+	switch (algo) {
+	case NAND_ECC_ALGO_MTK_HWECC:
+		return mtk_nand_ecc_get_engine();
+	default:
+		break;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(nand_ecc_get_on_host_hw_engine);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Miquel Raynal <miquel.raynal at bootlin.com>");
 MODULE_DESCRIPTION("Generic ECC engine");
diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c
index ce0f8b491e5d..33c660f094f3 100644
--- a/drivers/mtd/nand/mtk_ecc.c
+++ b/drivers/mtd/nand/mtk_ecc.c
@@ -61,9 +61,36 @@ struct mtk_ecc {
 	struct mutex lock;
 	u32 sectors;
 
+	u32 page_size;
+	u32 spare_size_per_sector;
+	u32 spare_size_idx;
+	u32 fdm_size;
+	u32 sector_size;
+	bool ecc_en;
+
 	u8 *eccdata;
 };
 
+struct mtk_ecc_bad_mark_ctl {
+	void (*bm_swap)(struct nand_device *, u8 *databuf, u8* oobbuf);
+	u32 sec;
+	u32 pos;
+};
+
+struct mtk_ecc_conf {
+	struct nand_ecc_req_tweak_ctx req_ctx;
+	unsigned int code_size;
+	unsigned int nsteps;
+
+	u8 *spare_databuf;
+	u8 *code_buf;
+	u8 *oob_buf;
+
+	struct mtk_ecc *ecc;
+	struct mtk_ecc_config ecc_cfg;
+	struct mtk_ecc_bad_mark_ctl bad_mark;
+};
+
 /* ecc strength that each IP supports */
 static const u8 ecc_strength_mt2701[] = {
 	4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
@@ -79,6 +106,11 @@ static const u8 ecc_strength_mt7622[] = {
 	4, 6, 8, 10, 12, 14, 16
 };
 
+/* supported spare size of each IP */
+static const u8 spare_size_mt7622[] = {
+	16, 26, 27, 28
+};
+
 enum mtk_ecc_regs {
 	ECC_ENCPAR00,
 	ECC_ENCIRQ_EN,
@@ -447,6 +479,289 @@ unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc)
 }
 EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
 
+u32 mtk_ecc_get_pagesize(struct device_node *dn)
+{
+	struct mtk_ecc *ecc = NULL;
+	struct device_node *child_np;
+
+	child_np = of_get_compatible_child(dn, "spi-nand");
+
+	ecc = of_mtk_ecc_get(child_np);
+
+	return ecc->page_size;
+}
+EXPORT_SYMBOL(mtk_ecc_get_pagesize);
+
+u32 mtk_ecc_get_sparesize(struct device_node *dn)
+{
+	struct mtk_ecc *ecc = NULL;
+	struct device_node *child_np;
+
+	child_np = of_get_compatible_child(dn, "spi-nand");
+
+	ecc = of_mtk_ecc_get(child_np);
+
+	return ecc->spare_size_per_sector;
+}
+EXPORT_SYMBOL(mtk_ecc_get_sparesize);
+
+u32 mtk_ecc_get_spare_idx(struct device_node *dn)
+{
+	struct mtk_ecc *ecc = NULL;
+	struct device_node *child_np;
+
+	child_np = of_get_compatible_child(dn, "spi-nand");
+
+	ecc = of_mtk_ecc_get(child_np);
+
+	return ecc->spare_size_idx;
+}
+EXPORT_SYMBOL(mtk_ecc_get_spare_idx);
+
+u32 mtk_ecc_get_fdmsize(struct device_node *dn)
+{
+	struct mtk_ecc *ecc = NULL;
+	struct device_node *child_np;
+
+	child_np = of_get_compatible_child(dn, "spi-nand");
+
+	ecc = of_mtk_ecc_get(child_np);
+
+	return ecc->fdm_size;
+}
+EXPORT_SYMBOL(mtk_ecc_get_fdmsize);
+
+u32 mtk_ecc_get_sectorsize(struct device_node *dn)
+{
+	struct mtk_ecc *ecc = NULL;
+	struct device_node *child_np;
+
+	child_np = of_get_compatible_child(dn, "spi-nand");
+
+	ecc = of_mtk_ecc_get(child_np);
+
+	return ecc->sector_size;
+}
+EXPORT_SYMBOL(mtk_ecc_get_sectorsize);
+
+bool mtk_ecc_get_status(struct device_node *dn)
+{
+	struct mtk_ecc *ecc = NULL;
+	struct device_node *child_np;
+
+	child_np = of_get_compatible_child(dn, "spi-nand");
+
+	ecc = of_mtk_ecc_get(child_np);
+
+	return ecc->ecc_en;
+}
+EXPORT_SYMBOL(mtk_ecc_get_status);
+
+int mtk_ecc_prepare_io_req(struct nand_device *nand,
+					  struct nand_page_io_req *req)
+{
+	struct mtk_ecc_conf *engine_conf = nand->ecc.ctx.priv;
+	int ret = 0;
+	u32 val;
+
+	nand_ecc_tweak_req(&engine_conf->req_ctx, req);
+
+	if (req->mode == MTD_OPS_RAW) {
+		/* set ecc status to disable */
+		engine_conf->ecc->ecc_en = false;
+		if (req->type == NAND_PAGE_WRITE) {
+			/*
+			 * format data and oob buf to Mediatek nand flash
+			 * data format
+			 */
+			mtk_ecc_format_page();
+		}
+	} else {
+		/* set ecc status to enable */
+		engine_conf->ecc->ecc_en = true;
+		engine_conf->ecc_cfg.op = ECC_DECODE;
+		if (req->type == NAND_PAGE_WRITE) {
+			/*
+			 * format oob buf
+			 * 1) set data bytes according to mtd ooblayout
+			 * 2) bad mark swap to ensure badmark position
+			 * consistent with nand device spec
+			 */
+			mtd_ooblayout_set_databytes();
+			engine_conf->bad_mark.bm_swap();
+
+			engine_conf->ecc_cfg.op = ECC_ENCODE;
+		}
+
+		ret = mtk_ecc_enable(engine_conf->ecc, &engine_conf->ecc_cfg);
+	}
+
+	return ret;
+}
+
+int mtk_ecc_finish_io_req(struct nand_device *nand,
+					  struct nand_page_io_req *req)
+{
+	struct mtk_ecc_conf *engine_conf = nand->ecc.ctx.priv;
+	struct device_node *dn = nanddev_get_of_node(nand);
+	struct mtd_info *mtd = nanddev_to_mtd(nand);
+	u8 *spare_databuf = engine_conf->spare_databuf;
+	int ret;
+
+	if (req->type == NAND_PAGE_WRITE) {
+		if (req->mode != MTD_OPS_RAW)
+			mtk_ecc_disable(engine_conf->ecc);
+
+		nand_ecc_restore_req(&engine_conf->req_ctx, req);
+
+		return 0;
+	}
+
+	if (req->mode == MTD_OPS_RAW) {
+		/* format data and oob buf from Mediatek nand flash data format */
+		mtk_ecc_format_page();
+		nand_ecc_restore_req(&engine_conf->req_ctx, req);
+		return 0;
+	}
+
+	/* set ecc status to default disable */
+	engine_conf->ecc->ecc_en = false;
+	ret = mtk_ecc_wait_done(engine_conf->ecc, ECC_DECODE);
+	if (ret)
+		return -ETIMEDOUT;
+
+	/* check whether read empty by check nfi export function */
+	ret = mtk_snfi_check_empty(dn);
+	if (ret) {
+		memset(req->databuf.in, 0xff, mtd->writesize);
+		memset(req->oobbuf.in, 0xff, mtd->oobsize);
+		ret = 0;
+	} else {
+		/* check the bitflips or uncorrect error */
+		ret = mtk_ecc_update_status(nand, req);
+
+		/*
+		 * format oob buf
+		 * 1) bad mark swap
+		 * 2) get data bytes according to mtd ooblayout
+		 */
+		engine_conf->bad_mark.bm_swap();
+		mtd_ooblayout_get_databytes();
+	}
+
+	mtk_ecc_disable(engine_conf->ecc);
+	nand_ecc_restore_req(&engine_conf->req_ctx, req);
+
+	return ret;
+}
+
+void mtk_ecc_cleanup_ctx(struct nand_device *nand)
+{
+	struct mtk_ecc_conf *engine_conf = nand->ecc.ctx.priv;
+
+	if (engine_conf) {
+		kfree(engine_conf->ecc);
+		kfree(engine_conf);
+	}
+}
+
+
+static void mtk_ecc_set_bad_mark_ctl(struct mtk_ecc_bad_mark_ctl *bm_ctl,
+				     struct mtd_info *mtd)
+{
+	/* todo */
+}
+
+/* calcute spare size per sector according to nand parameter */
+static int mtk_ecc_set_spare_per_sector(struct nand_device *nand,
+			u32 *sps, u32 *idx)
+{
+	/* todo */
+}
+
+static int mtk_ecc_config_init(struct nand_device *nand)
+{
+	struct mtk_ecc_conf *engine_conf = nand->ecc.ctx.priv;
+	struct nand_ecc_props *conf = &nand->ecc.ctx.conf;
+	struct mtd_info *mtd = nanddev_to_mtd(nand);
+	u32 sps, idx;
+
+	conf->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
+	conf->algo = NAND_ECC_ALGO_MTK_HWECC;
+	conf->step_size = nand->ecc.user_conf.step_size;
+	conf->strength = nand->ecc.user_conf.strength;
+
+	mtk_ecc_set_spare_per_sector(nand, &sps, &idx);
+
+	/* calculate ecc strength per sector */
+	mtk_ecc_adjust_strength(engine_conf->ecc, &conf->strength);
+
+	/*
+	 * set ecc sector size, spare per sector and spare idx
+	 * in nfi cnfg which will be get by snfi driver
+	 */
+	engine_conf->ecc->sector_size = conf->step_size;
+	engine_conf->ecc->spare_size_per_sector = *sps;
+	engine_conf->ecc->spare_size_idx = idx;
+
+	return 0;
+}
+
+int mtk_ecc_init_ctx(struct nand_device *nand)
+{
+	struct device_node *dn = nanddev_get_of_node(nand);
+	struct mtk_ecc_conf *engine_conf;
+	int ret;
+
+	engine_conf = kzalloc(sizeof(*engine_conf), GFP_KERNEL);
+	engine_conf->ecc = of_mtk_ecc_get(dn);
+
+	mtd_set_ooblayout();
+
+	nand->ecc.ctx.priv = engine_conf;
+	ret = mtk_ecc_config_init(nand);
+	if (ret)
+		goto free_engine_conf;
+
+	/*
+	 * the snfi driver need get nand parameter
+	 * when work in ECC nfi mode
+	 */
+	engine_conf->ecc->page_size = nand->memorg.pagesize;
+	engine_conf->ecc->spare_size = nand->memorg.oobsize;
+
+	/*
+	 * bad mark setting to ensure the badmark position
+	 * in Mediatek nand flash data format consistent
+	 * with nand device spec
+	 */
+	mtk_ecc_set_bad_mark_ctl();
+
+	return 0;
+
+free_engine_conf:
+	kfree(engine_conf);
+
+	return ret;
+}
+
+static struct nand_ecc_engine_ops mtk_nand_ecc_engine_ops = {
+	.init_ctx = mtk_ecc_init_ctx,
+	.cleanup_ctx = mtk_ecc_cleanup_ctx,
+	.prepare_io_req = mtk_ecc_prepare_io_req,
+	.finish_io_req = mtk_ecc_finish_io_req,
+};
+
+static struct nand_ecc_engine mtk_nand_ecc_engine = {
+	.ops = &mtk_nand_ecc_engine_ops,
+};
+
+struct nand_ecc_engine *mtk_nand_ecc_get_engine(void)
+{
+	return &mtk_nand_ecc_engine;
+}
+EXPORT_SYMBOL(mtk_nand_ecc_get_engine);
+
 static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
 	.err_mask = 0x3f,
 	.ecc_strength = ecc_strength_mt2701,
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 32fc7edf65b3..fccca85f34ea 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -167,12 +167,14 @@ enum nand_ecc_placement {
  * @NAND_ECC_ALGO_HAMMING: Hamming algorithm
  * @NAND_ECC_ALGO_BCH: Bose-Chaudhuri-Hocquenghem algorithm
  * @NAND_ECC_ALGO_RS: Reed-Solomon algorithm
+ * @NAND_ECC_ALGO_MTK: Mediatek on-host HW BCH algorithm
  */
 enum nand_ecc_algo {
 	NAND_ECC_ALGO_UNKNOWN,
 	NAND_ECC_ALGO_HAMMING,
 	NAND_ECC_ALGO_BCH,
 	NAND_ECC_ALGO_RS,
+	NAND_ECC_ALGO_MTK_HWECC,
 };
 
 /**
@@ -281,6 +283,7 @@ int nand_ecc_finish_io_req(struct nand_device *nand,
 bool nand_ecc_is_strong_enough(struct nand_device *nand);
 struct nand_ecc_engine *nand_ecc_get_sw_engine(struct nand_device *nand);
 struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand);
+struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand);
 
 #if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING)
 struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void);
@@ -300,6 +303,15 @@ static inline struct nand_ecc_engine *nand_ecc_sw_bch_get_engine(void)
 }
 #endif /* CONFIG_MTD_NAND_ECC_SW_BCH */
 
+#if IS_ENABLED(CONFIG_MTD_NAND_ECC_MTK)
+struct nand_ecc_engine *mtk_nand_ecc_get_engine(void);
+#else
+static inline struct nand_ecc_engine *mtk_nand_ecc_get_engine(void)
+{
+	return NULL;
+}
+#endif /* CONFIG_MTD_NAND_ECC_MTK */
+
 /**
  * struct nand_ecc_req_tweak_ctx - Help for automatically tweaking requests
  * @orig_req: Pointer to the original IO request
-- 
2.25.1



From xiangsheng.hou at mediatek.com  Sun Sep 26 22:36:27 2021
From: xiangsheng.hou at mediatek.com (Xiangsheng Hou)
Date: Mon, 27 Sep 2021 13:36:27 +0800
Subject: [RFC,v1 2/4] mtd: ecc: realize Mediatek HW ECC driver
In-Reply-To: <20210927053629.17847-1-xiangsheng.hou@mediatek.com>
References: <20210927053629.17847-1-xiangsheng.hou@mediatek.com>
Message-ID: <20210927053629.17847-3-xiangsheng.hou@mediatek.com>

The v1 driver add nfi register base in ecc dts node, due
to the nfi driver(for spinand) at spi subsystem can not
get nand parameter and ecc status.

Signed-off-by: Xiangsheng Hou <xiangsheng.hou at mediatek.com>
---
 drivers/mtd/nand/core.c    |   2 +-
 drivers/mtd/nand/ecc.c     |  19 +++
 drivers/mtd/nand/mtk_ecc.c | 319 +++++++++++++++++++++++++++++++++++++
 include/linux/mtd/nand.h   |  12 ++
 4 files changed, 351 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
index 5e13a03d2b32..3db410de3ba2 100644
--- a/drivers/mtd/nand/core.c
+++ b/drivers/mtd/nand/core.c
@@ -232,7 +232,7 @@ static int nanddev_get_ecc_engine(struct nand_device *nand)
 		nand->ecc.engine = nand_ecc_get_on_die_hw_engine(nand);
 		break;
 	case NAND_ECC_ENGINE_TYPE_ON_HOST:
-		pr_err("On-host hardware ECC engines not supported yet\n");
+		nand->ecc.engine = nand_ecc_get_on_host_hw_engine(nand);
 		break;
 	default:
 		pr_err("Missing ECC engine type\n");
diff --git a/drivers/mtd/nand/ecc.c b/drivers/mtd/nand/ecc.c
index 6c43dfda01d4..b334cd88c038 100644
--- a/drivers/mtd/nand/ecc.c
+++ b/drivers/mtd/nand/ecc.c
@@ -380,6 +380,7 @@ static const char * const nand_ecc_algos[] = {
 	[NAND_ECC_ALGO_HAMMING] = "hamming",
 	[NAND_ECC_ALGO_BCH] = "bch",
 	[NAND_ECC_ALGO_RS] = "rs",
+	[NAND_ECC_ALGO_MTK_HWECC] = "ecc-mtk",
 };
 
 static enum nand_ecc_algo of_get_nand_ecc_algo(struct device_node *np)
@@ -611,6 +612,24 @@ struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand)
 }
 EXPORT_SYMBOL(nand_ecc_get_on_die_hw_engine);
 
+struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand)
+{
+	unsigned int algo = nand->ecc.user_conf.algo;
+
+	if (algo == NAND_ECC_ALGO_UNKNOWN)
+		algo = nand->ecc.defaults.algo;
+
+	switch (algo) {
+	case NAND_ECC_ALGO_MTK_HWECC:
+		return mtk_nand_ecc_get_engine();
+	default:
+		break;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(nand_ecc_get_on_host_hw_engine);
+
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Miquel Raynal <miquel.raynal at bootlin.com>");
 MODULE_DESCRIPTION("Generic ECC engine");
diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/mtk_ecc.c
index ce0f8b491e5d..db72343adcdf 100644
--- a/drivers/mtd/nand/mtk_ecc.c
+++ b/drivers/mtd/nand/mtk_ecc.c
@@ -41,10 +41,28 @@
 #define ECC_IDLE_REG(op)	((op) == ECC_ENCODE ? ECC_ENCIDLE : ECC_DECIDLE)
 #define ECC_CTL_REG(op)		((op) == ECC_ENCODE ? ECC_ENCCON : ECC_DECCON)
 
+/* nfi regs will be used in ecc driver */
+#define NFI_CNFG		0x00
+#define		CNFG_HW_ECC_EN		BIT(8)
+#define		CNFG_AUTO_FMT_EN	BIT(9)
+#define NFI_PAGEFMT		(0x04)
+#define		PAGEFMT_SPARE_SHIFT		(16)
+#define		PAGEFMT_FDM_ECC_SHIFT	(12)
+#define		PAGEFMT_FDM_SHIFT	(8)
+#define		PAGEFMT_SEC_SEL_512	BIT(2)
+#define		PAGEFMT_512_2K		(0)
+#define		PAGEFMT_2K_4K		(1)
+#define		PAGEFMT_4K_8K		(2)
+#define		PAGEFMT_8K_16K		(3)
+#define NFI_STA			0x60
+#define		STA_EMP_PAGE		BIT(12)
+
 struct mtk_ecc_caps {
 	u32 err_mask;
 	const u8 *ecc_strength;
 	const u32 *ecc_regs;
+	const u8 *spare_size;
+	u8 num_spare_size;
 	u8 num_ecc_strength;
 	u8 ecc_mode_shift;
 	u32 parity_bits;
@@ -55,15 +73,37 @@ struct mtk_ecc {
 	struct device *dev;
 	const struct mtk_ecc_caps *caps;
 	void __iomem *regs;
+	void __iomem *nfi_regs;
 	struct clk *clk;
 
 	struct completion done;
 	struct mutex lock;
 	u32 sectors;
+	u32 fdm_size;
 
 	u8 *eccdata;
 };
 
+struct mtk_ecc_bad_mark_ctl {
+	void (*bm_swap)(struct nand_device *, u8 *databuf, u8* oobbuf);
+	u32 sec;
+	u32 pos;
+};
+
+struct mtk_ecc_conf {
+	struct nand_ecc_req_tweak_ctx req_ctx;
+	unsigned int code_size;
+	unsigned int nsteps;
+
+	u8 *spare_databuf;
+	u8 *code_buf;
+	u8 *oob_buf;
+
+	struct mtk_ecc *ecc;
+	struct mtk_ecc_config ecc_cfg;
+	struct mtk_ecc_bad_mark_ctl bad_mark;
+};
+
 /* ecc strength that each IP supports */
 static const u8 ecc_strength_mt2701[] = {
 	4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36,
@@ -79,6 +119,11 @@ static const u8 ecc_strength_mt7622[] = {
 	4, 6, 8, 10, 12, 14, 16
 };
 
+/* supported spare size of each IP */
+static const u8 spare_size_mt7622[] = {
+	16, 26, 27, 28
+};
+
 enum mtk_ecc_regs {
 	ECC_ENCPAR00,
 	ECC_ENCIRQ_EN,
@@ -447,6 +492,278 @@ unsigned int mtk_ecc_get_parity_bits(struct mtk_ecc *ecc)
 }
 EXPORT_SYMBOL(mtk_ecc_get_parity_bits);
 
+int mtk_ecc_prepare_io_req(struct nand_device *nand,
+					  struct nand_page_io_req *req)
+{
+	struct mtk_ecc_conf *engine_conf = nand->ecc.ctx.priv;
+	int ret = 0;
+	u32 val;
+
+	nand_ecc_tweak_req(&engine_conf->req_ctx, req);
+
+	if (req->mode == MTD_OPS_RAW) {
+		if (req->type == NAND_PAGE_WRITE) {
+			/*
+			 * format data and oob buf to Mediatek nand flash
+			 * data format
+			 */
+			mtk_ecc_format_page();
+		}
+	} else {
+		engine_conf->ecc_cfg.op = ECC_DECODE;
+		if (req->type == NAND_PAGE_WRITE) {
+			/*
+			 * format oob buf
+			 * 1) set data bytes according to mtd ooblayout
+			 * 2) bad mark swap to ensure badmark position
+			 * consistent with nand device spec
+			 */
+			mtd_ooblayout_set_databytes();
+			engine_conf->bad_mark.bm_swap();
+
+			engine_conf->ecc_cfg.op = ECC_ENCODE;
+		}
+
+		/*
+		 * this mainly config the nfi to be aware of
+		 * the operation is ecc enable
+		 */
+		val = CNFG_HW_ECC_EN | CNFG_AUTO_FMT_EN;
+		writew(val, engine_conf->ecc->nfi_regs + NFI_CNFG);
+
+		ret = mtk_ecc_enable(engine_conf->ecc, &engine_conf->ecc_cfg);
+	}
+
+	return ret;
+}
+
+int mtk_ecc_finish_io_req(struct nand_device *nand,
+					  struct nand_page_io_req *req)
+{
+	struct mtk_ecc_conf *engine_conf = nand->ecc.ctx.priv;
+	struct mtd_info *mtd = nanddev_to_mtd(nand);
+	u8 *spare_databuf = engine_conf->spare_databuf;
+	int ret;
+
+	if (req->type == NAND_PAGE_WRITE) {
+		if (req->mode != MTD_OPS_RAW)
+			mtk_ecc_disable(engine_conf->ecc);
+
+		nand_ecc_restore_req(&engine_conf->req_ctx, req);
+
+		return 0;
+	}
+
+	if (req->mode == MTD_OPS_RAW) {
+		/* format data and oob buf from Mediatek nand flash data format */
+		mtk_ecc_format_page();
+		nand_ecc_restore_req(&engine_conf->req_ctx, req);
+		return 0;
+	}
+
+	ret = mtk_ecc_wait_done(engine_conf->ecc, ECC_DECODE);
+	if (ret)
+		return -ETIMEDOUT;
+
+	/* check whether read empty by check nfi regs */
+	ret = readl(engine_conf->ecc->nfi_regs + NFI_STA) & STA_EMP_PAGE;
+	if (ret) {
+		memset(req->databuf.in, 0xff, mtd->writesize);
+		memset(req->oobbuf.in, 0xff, mtd->oobsize);
+		ret = 0;
+	} else {
+		/* check the bitflips or uncorrect error */
+		ret = mtk_ecc_update_status(nand, req);
+
+		/*
+		 * format oob buf
+		 * 1) bad mark swap
+		 * 2) get data bytes according to mtd ooblayout
+		 */
+		engine_conf->bad_mark.bm_swap();
+		mtd_ooblayout_get_databytes();
+	}
+
+	mtk_ecc_disable(engine_conf->ecc);
+	nand_ecc_restore_req(&engine_conf->req_ctx, req);
+
+	return ret;
+}
+
+void mtk_ecc_cleanup_ctx(struct nand_device *nand)
+{
+	struct mtk_ecc_conf *engine_conf = nand->ecc.ctx.priv;
+
+	if (engine_conf) {
+		kfree(engine_conf->ecc);
+		kfree(engine_conf);
+	}
+}
+
+
+static void mtk_ecc_set_bad_mark_ctl(struct mtk_ecc_bad_mark_ctl *bm_ctl,
+				     struct mtd_info *mtd)
+{
+	/* todo */
+}
+
+/* calcute spare size per sector according to nand parameter */
+static int mtk_ecc_set_spare_per_sector(struct nand_device *nand,
+			u32 *sps, u32 *idx)
+{
+	/* todo */
+}
+
+/*
+ * config nfi with nand parameter
+ * the nfi can not get nand parameter, due to the snfi
+ * driver in spi subsystem
+ */
+static int mtk_ecc_nfi_config(struct nand_device *nand)
+{
+	struct mtk_ecc_conf *engine_conf = nand->ecc.ctx.priv;
+	struct nand_ecc_props *conf = &nand->ecc.ctx.conf;
+	struct mtd_info *mtd = nanddev_to_mtd(nand);
+	int oob_free, oob_ecc, spare, ret;
+	u32 val, idx;
+
+	/* calculate the spare size per sector */
+	ret = mtk_ecc_set_spare_per_sector(nand, &spare, &idx);
+	if (ret)
+		return ret;
+
+	/* calculate ecc strength per sector */
+	mtk_ecc_adjust_strength(engine_conf->ecc, &conf->strength);
+
+	/* config nfi with nand page size and spare size */
+	switch (mtd->writesize) {
+	case 512:
+		val = PAGEFMT_512_2K | PAGEFMT_SEC_SEL_512;
+		break;
+	case KB(2):
+		if (conf->step_size == 512)
+			val = PAGEFMT_2K_4K | PAGEFMT_SEC_SEL_512;
+		else
+			val = PAGEFMT_512_2K;
+		break;
+	case KB(4):
+		if (conf->step_size == 512)
+			val = PAGEFMT_4K_8K | PAGEFMT_SEC_SEL_512;
+		else
+			val = PAGEFMT_2K_4K;
+		break;
+	case KB(8):
+		if (conf->step_size == 512)
+			val = PAGEFMT_8K_16K | PAGEFMT_SEC_SEL_512;
+		else
+			val = PAGEFMT_4K_8K;
+		break;
+	case KB(16):
+		val = PAGEFMT_8K_16K;
+		break;
+	default:
+		dev_err(engine_conf->ecc->dev,
+			"invalid page len: %d\n", mtd->writesize);
+		return -EINVAL;
+	}
+
+	val |= idx << PAGEFMT_SPARE_SHIFT;
+	val |= engine_conf->ecc->fdm_size << PAGEFMT_FDM_SHIFT;
+	/* fdm size equal to fdm ecc size */
+	val |= engine_conf->ecc->fdm_size << PAGEFMT_FDM_ECC_SHIFT;
+	writel(val, engine_conf->ecc->nfi_regs + NFI_PAGEFMT);
+
+	return 0;
+}
+
+static int mtk_ecc_config_init(struct nand_device *nand)
+{
+
+	struct nand_ecc_props *conf = &nand->ecc.ctx.conf;
+	struct mtd_info *mtd = nanddev_to_mtd(nand);
+
+	conf->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
+	conf->algo = NAND_ECC_ALGO_MTK_HWECC;
+	conf->step_size = nand->ecc.user_conf.step_size;
+	conf->strength = nand->ecc.user_conf.strength;
+
+	return mtk_ecc_nfi_config(nand);
+}
+
+/*
+ * Get nfi register base from ecc node
+ * The nfi controller need get nand parameter when cowork with this
+ * HW ECC driver for high performance.
+ * However, the snfi(part of nfi) driver at spi subsystem, which
+ * can not get these information.
+ * Therefore, config nfi reg base at ecc node, and config nand parameter
+ * to nfi regs.
+ */
+static void __iomem *of_mtk_ecc_get_nfi_reg(struct device_node *of_node)
+{
+	void __iomem *reg = NULL;
+	struct device_node *np;
+
+	np = of_parse_phandle(of_node, "nand-ecc-engine", 0);
+	if (np) {
+		reg = of_iomap(np, 1);
+		of_node_put(np);
+	}
+
+	return reg;
+}
+
+int mtk_ecc_init_ctx(struct nand_device *nand)
+{
+	struct device_node *dn = nanddev_get_of_node(nand);
+	struct mtk_ecc_conf *engine_conf;
+	int ret;
+
+	engine_conf = kzalloc(sizeof(*engine_conf), GFP_KERNEL);
+	engine_conf->ecc = of_mtk_ecc_get(dn);
+
+	/* get nfi register base from ecc node */
+	engine_conf->ecc->nfi_regs = of_mtk_ecc_get_nfi_reg(dn);
+
+	mtd_set_ooblayout();
+
+	nand->ecc.ctx.priv = engine_conf;
+	ret = mtk_ecc_config_init(nand);
+	if (ret)
+		goto free_engine_conf;
+
+	/*
+	 * bad mark setting to ensure the badmark position
+	 * in Mediatek nand flash data format consistent
+	 * with nand device spec
+	 */
+	mtk_ecc_set_bad_mark_ctl();
+
+	return 0;
+
+free_engine_conf:
+	kfree(engine_conf);
+
+	return ret;
+}
+
+static struct nand_ecc_engine_ops mtk_nand_ecc_engine_ops = {
+	.init_ctx = mtk_ecc_init_ctx,
+	.cleanup_ctx = mtk_ecc_cleanup_ctx,
+	.prepare_io_req = mtk_ecc_prepare_io_req,
+	.finish_io_req = mtk_ecc_finish_io_req,
+};
+
+static struct nand_ecc_engine mtk_nand_ecc_engine = {
+	.ops = &mtk_nand_ecc_engine_ops,
+};
+
+struct nand_ecc_engine *mtk_nand_ecc_get_engine(void)
+{
+	return &mtk_nand_ecc_engine;
+}
+EXPORT_SYMBOL(mtk_nand_ecc_get_engine);
+
 static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = {
 	.err_mask = 0x3f,
 	.ecc_strength = ecc_strength_mt2701,
@@ -471,6 +788,8 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = {
 	.err_mask = 0x3f,
 	.ecc_strength = ecc_strength_mt7622,
 	.ecc_regs = mt7622_ecc_regs,
+	.spare_size = spare_size_mt7622,
+	.num_spare_size = 4,
 	.num_ecc_strength = 7,
 	.ecc_mode_shift = 4,
 	.parity_bits = 13,
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 32fc7edf65b3..fccca85f34ea 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -167,12 +167,14 @@ enum nand_ecc_placement {
  * @NAND_ECC_ALGO_HAMMING: Hamming algorithm
  * @NAND_ECC_ALGO_BCH: Bose-Chaudhuri-Hocquenghem algorithm
  * @NAND_ECC_ALGO_RS: Reed-Solomon algorithm
+ * @NAND_ECC_ALGO_MTK: Mediatek on-host HW BCH algorithm
  */
 enum nand_ecc_algo {
 	NAND_ECC_ALGO_UNKNOWN,
 	NAND_ECC_ALGO_HAMMING,
 	NAND_ECC_ALGO_BCH,
 	NAND_ECC_ALGO_RS,
+	NAND_ECC_ALGO_MTK_HWECC,
 };
 
 /**
@@ -281,6 +283,7 @@ int nand_ecc_finish_io_req(struct nand_device *nand,
 bool nand_ecc_is_strong_enough(struct nand_device *nand);
 struct nand_ecc_engine *nand_ecc_get_sw_engine(struct nand_device *nand);
 struct nand_ecc_engine *nand_ecc_get_on_die_hw_engine(struct nand_device *nand);
+struct nand_ecc_engine *nand_ecc_get_on_host_hw_engine(struct nand_device *nand);
 
 #if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING)
 struct nand_ecc_engine *nand_ecc_sw_hamming_get_engine(void);
@@ -300,6 +303,15 @@ static inline struct nand_ecc_engine *nand_ecc_sw_bch_get_engine(void)
 }
 #endif /* CONFIG_MTD_NAND_ECC_SW_BCH */
 
+#if IS_ENABLED(CONFIG_MTD_NAND_ECC_MTK)
+struct nand_ecc_engine *mtk_nand_ecc_get_engine(void);
+#else
+static inline struct nand_ecc_engine *mtk_nand_ecc_get_engine(void)
+{
+	return NULL;
+}
+#endif /* CONFIG_MTD_NAND_ECC_MTK */
+
 /**
  * struct nand_ecc_req_tweak_ctx - Help for automatically tweaking requests
  * @orig_req: Pointer to the original IO request
-- 
2.25.1



From xiangsheng.hou at mediatek.com  Sun Sep 26 22:42:05 2021
From: xiangsheng.hou at mediatek.com (Xiangsheng Hou)
Date: Mon, 27 Sep 2021 13:42:05 +0800
Subject: [RFC,v2 4/4] arm64: dts: add snfi node for spi nand
In-Reply-To: <20210927054205.17960-1-xiangsheng.hou@mediatek.com>
References: <20210927054205.17960-1-xiangsheng.hou@mediatek.com>
Message-ID: <20210927054205.17960-5-xiangsheng.hou@mediatek.com>

Signed-off-by: Xiangsheng Hou <xiangsheng.hou at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts | 17 +++++++++++++++++
 arch/arm64/boot/dts/mediatek/mt7622.dtsi     | 13 +++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
index f2dc850010f1..6df575acf290 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -223,6 +223,23 @@ &nandc {
 	status = "disabled";
 };
 
+&snfi {
+	pinctrl-names = "default";
+	/* pin shared with spic */
+	pinctrl-0 = <&snfi_pins>;
+	status = "disabled";
+
+	spi_nand at 0 {
+		compatible = "spi-nand";
+		reg = <0>;
+		spi-max-frequency = <104000000>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
+		nand-ecc-engine = <&bch>;
+		nand-ecc-algo = "ecc-mtk";
+	};
+};
+
 &nor_flash {
 	pinctrl-names = "default";
 	pinctrl-0 = <&spi_nor_pins>;
diff --git a/arch/arm64/boot/dts/mediatek/mt7622.dtsi b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
index 890a942ec608..0525e4de5ec0 100644
--- a/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -545,6 +545,19 @@ nandc: nfi at 1100d000 {
 		status = "disabled";
 	};
 
+	snfi: spi at 1100d000 {
+		compatible = "mediatek,mt7622-snfi";
+		reg = <0 0x1100D000 0 0x1000>;
+		interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_LOW>;
+		clocks = <&infracfg_ao CK_INFRA_NFI1_CK>,
+			 <&infracfg_ao CK_INFRA_SPINFI1_CK>,
+			 <&infracfg_ao CK_INFRA_NFI_HCK_CK>;
+		clock-names = "nfi_clk", "snfi_clk", "hclk";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	bch: ecc at 1100e000 {
 		compatible = "mediatek,mt7622-ecc";
 		reg = <0 0x1100e000 0 0x1000>;
-- 
2.25.1



From xiangsheng.hou at mediatek.com  Sun Sep 26 22:42:01 2021
From: xiangsheng.hou at mediatek.com (Xiangsheng Hou)
Date: Mon, 27 Sep 2021 13:42:01 +0800
Subject: [RFC,v2 0/4] Add a driver for Mediatek SPI Nand controller
Message-ID: <20210927054205.17960-1-xiangsheng.hou@mediatek.com>

Add a driver for Mediatek SPI Nand controller

Mediatek SPI Nand controller cosists of two parts: on-host HW ECC and
snfi(stand for spi nand flash interface). They can cowork with high
performance which called ECC nfi mode. The nfi stand for nand flash
interfacei(snfi a one part of nfi) which can support SPI Nand flash
and raw nand flash.

However, the snfi driver in spi subsytem need to be aware of nand
parameter(page/spare size) and ecc status(enable/disable) when work
at ECC nfi mode. The snfi driver in spi subsystem seems difficult to
know these.

Therefore, consider two ways to let snfi can get these information.
The RFC patch send to review whether they are suitable and which
solution maybe better.

RFC patch v1:
Add nfi register base at bch(ecc) dts node and config nand parameter
and ecc status into nfi registers in ecc driver, then parse these
information at snfi driver to use.

RFC patch v2:
Export some function in HW ECC driver and snfi driver.
In HW ECC driver, export function include get nand page/spare size, HW
ECC status(enable/disable) and fdm(oob free per sector in ooblayout) size.
In snfi driver need export empty page status which the nfi can be aware
when in ECC nfi mode(the spim framework can not return this information).

This series patch is the v2 solution, and only take mt7622 board for dts
node example.

Xiangsheng Hou (4):
  mtd: ecc: move mediatek HW ECC driver
  mtd: ecc: realize Mediatek HW ECC driver
  spi: add Mediatek SPI Nand controller driver
  arm64: dts: add snfi node for spi nand

 arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts  |   17 +
 arch/arm64/boot/dts/mediatek/mt7622.dtsi      |   13 +
 drivers/mtd/nand/Kconfig                      |    9 +
 drivers/mtd/nand/Makefile                     |    1 +
 drivers/mtd/nand/core.c                       |    2 +-
 drivers/mtd/nand/ecc.c                        |   19 +
 drivers/mtd/nand/{raw => }/mtk_ecc.c          |  317 ++++-
 drivers/mtd/nand/raw/Kconfig                  |    1 +
 drivers/mtd/nand/raw/Makefile                 |    2 +-
 drivers/mtd/nand/raw/mtk_nand.c               |    2 +-
 drivers/spi/Kconfig                           |   11 +
 drivers/spi/Makefile                          |    1 +
 drivers/spi/spi-mtk-snfi.c                    | 1087 +++++++++++++++++
 .../nand/raw => include/linux/mtd}/mtk_ecc.h  |    0
 include/linux/mtd/nand.h                      |   12 +
 15 files changed, 1490 insertions(+), 4 deletions(-)
 rename drivers/mtd/nand/{raw => }/mtk_ecc.c (65%)
 create mode 100644 drivers/spi/spi-mtk-snfi.c
 rename {drivers/mtd/nand/raw => include/linux/mtd}/mtk_ecc.h (100%)

-- 
2.25.1



From arnd at kernel.org  Mon Sep 27 07:10:37 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 27 Sep 2021 16:10:37 +0200
Subject: [PATCH] [RFC] mtd: fixup CFI on ixp4xx
Message-ID: <20210927141045.1597593-1-arnd@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

drivers/mtd/maps/ixp4xx.c requires MTD_CFI_BE_BYTE_SWAP to be set
in order to compile.

drivers/mtd/maps/ixp4xx.c:57:4: error: #error CONFIG_MTD_CFI_BE_BYTE_SWAP required

This patch avoids the #error output by enforcing the policy in
Kconfig. Not sure if this is the right approach, but it helps doing
randconfig builds.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
Any other ideas for how to address it?
---
 drivers/mtd/chips/Kconfig | 2 ++
 drivers/mtd/maps/Kconfig  | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index aef14990e5f7..19726ebd973d 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -55,12 +55,14 @@ choice
 	  LITTLE_ENDIAN_BYTE, if the bytes are reversed.
 
 config MTD_CFI_NOSWAP
+	depends on !ARCH_IXP4XX || CPU_BIG_ENDIAN
 	bool "NO"
 
 config MTD_CFI_BE_BYTE_SWAP
 	bool "BIG_ENDIAN_BYTE"
 
 config MTD_CFI_LE_BYTE_SWAP
+	depends on !ARCH_IXP4XX
 	bool "LITTLE_ENDIAN_BYTE"
 
 endchoice
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index aaa164b977fe..4945caa88345 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -302,7 +302,7 @@ config MTD_DC21285
 
 config MTD_IXP4XX
 	tristate "CFI Flash device mapped on Intel IXP4xx based systems"
-	depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX
+	depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX && MTD_CFI_ADV_OPTIONS
 	help
 	  This enables MTD access to flash devices on platforms based
 	  on Intel's IXP4xx family of network processors such as the
-- 
2.29.2



From miquel.raynal at bootlin.com  Mon Sep 27 09:31:50 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 27 Sep 2021 18:31:50 +0200
Subject: [PATCH v2] mtd: rawnand: xway: No hardcoded ECC engine, use
 device tree setting
In-Reply-To: <14eb0cb7-b0af-87bf-b9a5-3e35eeb43f54@3e8.eu>
References: <20210808072643.GA5084@ubuntu>
 <51f2ebf4-6df1-eba5-99f1-1ec88e475d20@3e8.eu>
 <20210917190154.76203a9a@xps13>
 <e9dd0653-139f-749b-c088-e756ee2d2132@3e8.eu>
 <20210917213246.319e60cb@xps13>
 <14eb0cb7-b0af-87bf-b9a5-3e35eeb43f54@3e8.eu>
Message-ID: <20210927183150.4be87140@xps13>

Hi Jan,

Sorry for the delay, I had to rethink about the problem first.

jan at 3e8.eu wrote on Sat, 18 Sep 2021 23:26:48 +0200:

> Hi Miqu?l,
> 
> > Yes this was my understanding, that only software ECC engine was
> > supported. The mainline driver shows absolutely no signs of hardware
> > ECC engine support.
> > 
> > Perhaps however you mean that on-die ECC engine are not supported
> > anymore because of the engine_type being set in attach_chip()?  
> 
> Yes, this is exactly the issue.
> 
> > If yes then indeed there is something to do, perhaps checking if an
> > engine has been already set is enough? You can try something like:
> > 
> > if (engine_type == unknown)
> > 	engine_type = soft;  
> 
> Checking for NAND_ECC_ENGINE_TYPE_INVALID doesn't work, as the engine
> type is already set to NAND_ECC_ENGINE_TYPE_ON_HOST by rawnand_dt_init.
> The code there seems to expect that chip->ecc.engine_type contains the
> default value, which is no longer the case after commit 525914b5bd8
> ("mtd: rawnand: xway: Move the ECC initialization to ->attach_chip()").

This is indeed an issue and should be fixed. However the solution is I
think already available in the raw NAND core (but I had to dig into the
code again to remember how I wanted to handle this).

> The following in attach_chip works:
> 
> if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST)
> 	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;

If you look at the rawnand_dt_init() function [1] the logic is:

Is the user configuration (DT) valid ? if yes take it.
Is the NAND controller driver setting a default mode? if yes take it.
Otherwise take the raw NAND subsystem default: ON_HOST.

This logic happens very soon in the init process so the default mode
for the driver should be provided before the nand_scan() call.

So what I propose is:
- in the driver probe: set the default to software ECC
- in the attach() hook: drop the line setting the engine_type to SOFT.

Please check the below diff and tell me if it works for you. I'll then
propose a wider series fixing the other drivers as well.

> However, this will also silently use the software ECC engine if anyone
> actually configures the on-host hardware ECC engine in the device tree
> (which is of course unsupported for xway).
> 
> Thanks,
> Jan


[1] https://elixir.bootlin.com/linux/latest/source/drivers/mtd/nand/raw/nand_base.c#L5328

Thanks,
Miqu?l

---
diff --git a/drivers/mtd/nand/raw/xway_nand.c b/drivers/mtd/nand/raw/xway_nand.c
index 26751976e502..d9e167dbb717 100644
--- a/drivers/mtd/nand/raw/xway_nand.c
+++ b/drivers/mtd/nand/raw/xway_nand.c
@@ -148,9 +148,8 @@ static void xway_write_buf(struct nand_chip *chip, const u_char *buf, int len)
 
 static int xway_attach_chip(struct nand_chip *chip)
 {
-       chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-       if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+       if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+           chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
                chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
        return 0;
@@ -219,6 +218,14 @@ static int xway_nand_probe(struct platform_device *pdev)
                    | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P
                    | cs_flag, EBU_NAND_CON);
 
+       /*
+        * This controller has no hardware ECC engine and the driver assumes
+        * that the default ECC engine should be TYPE_SOFT. Set ->engine_type
+        * before the NAND registration in order to provide a default value.
+        */
+       data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
+
        /* Scan to find existence of the device */
        err = nand_scan(&data->chip, 1);
        if (err)


From miquel.raynal at bootlin.com  Mon Sep 27 09:33:28 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 27 Sep 2021 18:33:28 +0200
Subject: [PATCH] [RFC] mtd: fixup CFI on ixp4xx
In-Reply-To: <20210927141045.1597593-1-arnd@kernel.org>
References: <20210927141045.1597593-1-arnd@kernel.org>
Message-ID: <20210927183328.2f200fc2@xps13>

Hi Arnd,

arnd at kernel.org wrote on Mon, 27 Sep 2021 16:10:37 +0200:

> From: Arnd Bergmann <arnd at arndb.de>
> 
> drivers/mtd/maps/ixp4xx.c requires MTD_CFI_BE_BYTE_SWAP to be set
> in order to compile.
> 
> drivers/mtd/maps/ixp4xx.c:57:4: error: #error CONFIG_MTD_CFI_BE_BYTE_SWAP required
> 
> This patch avoids the #error output by enforcing the policy in
> Kconfig. Not sure if this is the right approach, but it helps doing
> randconfig builds.
> 
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> ---
> Any other ideas for how to address it?

I am fine with the approach. Should I wait for someone else's Ack?

Thanks,
Miqu?l

> ---
>  drivers/mtd/chips/Kconfig | 2 ++
>  drivers/mtd/maps/Kconfig  | 2 +-
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
> index aef14990e5f7..19726ebd973d 100644
> --- a/drivers/mtd/chips/Kconfig
> +++ b/drivers/mtd/chips/Kconfig
> @@ -55,12 +55,14 @@ choice
>  	  LITTLE_ENDIAN_BYTE, if the bytes are reversed.
>  
>  config MTD_CFI_NOSWAP
> +	depends on !ARCH_IXP4XX || CPU_BIG_ENDIAN
>  	bool "NO"
>  
>  config MTD_CFI_BE_BYTE_SWAP
>  	bool "BIG_ENDIAN_BYTE"
>  
>  config MTD_CFI_LE_BYTE_SWAP
> +	depends on !ARCH_IXP4XX
>  	bool "LITTLE_ENDIAN_BYTE"
>  
>  endchoice
> diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
> index aaa164b977fe..4945caa88345 100644
> --- a/drivers/mtd/maps/Kconfig
> +++ b/drivers/mtd/maps/Kconfig
> @@ -302,7 +302,7 @@ config MTD_DC21285
>  
>  config MTD_IXP4XX
>  	tristate "CFI Flash device mapped on Intel IXP4xx based systems"
> -	depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX
> +	depends on MTD_CFI && MTD_COMPLEX_MAPPINGS && ARCH_IXP4XX && MTD_CFI_ADV_OPTIONS
>  	help
>  	  This enables MTD access to flash devices on platforms based
>  	  on Intel's IXP4xx family of network processors such as the



From arnd at kernel.org  Mon Sep 27 13:30:58 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Mon, 27 Sep 2021 22:30:58 +0200
Subject: [PATCH] [RFC] mtd: fixup CFI on ixp4xx
In-Reply-To: <20210927183328.2f200fc2@xps13>
References: <20210927141045.1597593-1-arnd@kernel.org>
 <20210927183328.2f200fc2@xps13>
Message-ID: <CAK8P3a0WnM7_6o0FE3=iY+0J1-qU5gCGH6qWCfLygGTkH0TA+w@mail.gmail.com>

On Mon, Sep 27, 2021 at 6:33 PM Miquel Raynal <miquel.raynal at bootlin.com> wrote:
>
> Hi Arnd,
>
> arnd at kernel.org wrote on Mon, 27 Sep 2021 16:10:37 +0200:
>
> > From: Arnd Bergmann <arnd at arndb.de>
> >
> > drivers/mtd/maps/ixp4xx.c requires MTD_CFI_BE_BYTE_SWAP to be set
> > in order to compile.
> >
> > drivers/mtd/maps/ixp4xx.c:57:4: error: #error CONFIG_MTD_CFI_BE_BYTE_SWAP required
> >
> > This patch avoids the #error output by enforcing the policy in
> > Kconfig. Not sure if this is the right approach, but it helps doing
> > randconfig builds.
> >
> > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> > ---
> > Any other ideas for how to address it?
>
> I am fine with the approach. Should I wait for someone else's Ack?

Maybe wait a few days to see if there are objections or any better
ideas then. I'd certainly be happy to never run into this problem again.

         Arnd


From jan at 3e8.eu  Mon Sep 27 13:32:13 2021
From: jan at 3e8.eu (Jan Hoffmann)
Date: Mon, 27 Sep 2021 22:32:13 +0200
Subject: [PATCH v2] mtd: rawnand: xway: No hardcoded ECC engine, use
 device tree setting
In-Reply-To: <20210927183150.4be87140@xps13>
References: <20210808072643.GA5084@ubuntu>
 <51f2ebf4-6df1-eba5-99f1-1ec88e475d20@3e8.eu> <20210917190154.76203a9a@xps13>
 <e9dd0653-139f-749b-c088-e756ee2d2132@3e8.eu> <20210917213246.319e60cb@xps13>
 <14eb0cb7-b0af-87bf-b9a5-3e35eeb43f54@3e8.eu> <20210927183150.4be87140@xps13>
Message-ID: <f800c48f-8e4a-ecdc-3198-c52be0425823@3e8.eu>

Hi Miqu?l,

> So what I propose is:
> - in the driver probe: set the default to software ECC
> - in the attach() hook: drop the line setting the engine_type to SOFT.
> 
> Please check the below diff and tell me if it works for you. I'll then
> propose a wider series fixing the other drivers as well.

I can confirm that your patch fixes the issue.

I tested using kernel 5.10 on a Fritzbox 7362 SL (with on-die ECC
configured via device tree which was broken before). I also checked on
a Fritzbox 7412 (this device uses software ECC). Both are working with
this patch.

Thanks,
Jan


From mcgrof at kernel.org  Mon Sep 27 15:01:55 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:55 -0700
Subject: [PATCH v2 08/10] block/sx8: add error handling support for add_disk()
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <20210927220157.1069658-9-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

A completion is used to notify the initial probe what is
happening and so we must defer error handling on completion.
Do this by remembering the error and using the shared cleanup
function.

The tags are shared and so are hanlded later for the
driver already.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/sx8.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 420cd952ddc4..1c79248c4826 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -297,6 +297,7 @@ struct carm_host {
 
 	struct work_struct		fsm_task;
 
+	int probe_err;
 	struct completion		probe_comp;
 };
 
@@ -1181,8 +1182,11 @@ static void carm_fsm_task (struct work_struct *work)
 				struct gendisk *disk = port->disk;
 
 				set_capacity(disk, port->capacity);
-				add_disk(disk);
-				activated++;
+				host->probe_err = add_disk(disk);
+				if (!host->probe_err)
+					activated++;
+				else
+					break;
 			}
 
 		printk(KERN_INFO DRV_NAME "(%s): %d ports activated\n",
@@ -1192,11 +1196,9 @@ static void carm_fsm_task (struct work_struct *work)
 		reschedule = 1;
 		break;
 	}
-
 	case HST_PROBE_FINISHED:
 		complete(&host->probe_comp);
 		break;
-
 	case HST_ERROR:
 		/* FIXME: TODO */
 		break;
@@ -1507,7 +1509,10 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto err_out_free_irq;
 
 	DPRINTK("waiting for probe_comp\n");
+	host->probe_err = -ENODEV;
 	wait_for_completion(&host->probe_comp);
+	if (host->probe_err)
+		goto err_out_free_irq;
 
 	printk(KERN_INFO "%s: pci %s, ports %d, io %llx, irq %u, major %d\n",
 	       host->name, pci_name(pdev), (int) CARM_MAX_PORTS,
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:01:51 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:51 -0700
Subject: [PATCH v2 04/10] ps3vram: add error handling support for add_disk()
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <20210927220157.1069658-5-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/ps3vram.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index c7b19e128b03..af2a0d09c598 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -755,9 +755,14 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev)
 	dev_info(&dev->core, "%s: Using %llu MiB of GPU memory\n",
 		 gendisk->disk_name, get_capacity(gendisk) >> 11);
 
-	device_add_disk(&dev->core, gendisk, NULL);
+	error = device_add_disk(&dev->core, gendisk, NULL);
+	if (error)
+		goto out_cleanup_disk;
+
 	return 0;
 
+out_cleanup_disk:
+	blk_cleanup_disk(gendisk);
 out_cache_cleanup:
 	remove_proc_entry(DEVICE_NAME, NULL);
 	ps3vram_cache_cleanup(dev);
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:01:56 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:56 -0700
Subject: [PATCH v2 09/10] pf: add error handling support for add_disk()
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <20210927220157.1069658-10-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/paride/pf.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index f471d48a87bc..380d80e507c7 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -962,7 +962,9 @@ static int __init pf_init_unit(struct pf_unit *pf, bool autoprobe, int port,
 	if (pf_probe(pf))
 		goto out_pi_release;
 
-	add_disk(disk);
+	ret = add_disk(disk);
+	if (ret)
+		goto out_pi_release;
 	pf->present = 1;
 	return 0;
 
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:01:57 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:57 -0700
Subject: [PATCH v2 10/10] mtd/ubi/block: add error handling support for
 add_disk()
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <20210927220157.1069658-11-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/mtd/ubi/block.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c
index e003b4b44ffa..062e6c2c45f5 100644
--- a/drivers/mtd/ubi/block.c
+++ b/drivers/mtd/ubi/block.c
@@ -447,12 +447,18 @@ int ubiblock_create(struct ubi_volume_info *vi)
 	list_add_tail(&dev->list, &ubiblock_devices);
 
 	/* Must be the last step: anyone can call file ops from now on */
-	add_disk(dev->gd);
+	ret = add_disk(dev->gd);
+	if (ret)
+		goto out_destroy_wq;
+
 	dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
 		 dev->ubi_num, dev->vol_id, vi->name);
 	mutex_unlock(&devices_mutex);
 	return 0;
 
+out_destroy_wq:
+	list_del(&dev->list);
+	destroy_workqueue(dev->wq);
 out_remove_minor:
 	idr_remove(&ubiblock_minor_idr, gd->first_minor);
 out_cleanup_disk:
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:01:48 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:48 -0700
Subject: [PATCH v2 01/10] mtip32xx: add error handling support for add_disk()
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <20210927220157.1069658-2-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

The read_capacity_error error label already does what we need,
so just re-use that.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/mtip32xx/mtip32xx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 901855717cb5..d0b40309f47e 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -3633,7 +3633,9 @@ static int mtip_block_initialize(struct driver_data *dd)
 	set_capacity(dd->disk, capacity);
 
 	/* Enable the block device and add it to /dev */
-	device_add_disk(&dd->pdev->dev, dd->disk, mtip_disk_attr_groups);
+	rv = device_add_disk(&dd->pdev->dev, dd->disk, mtip_disk_attr_groups);
+	if (rv)
+		goto read_capacity_error;
 
 	if (dd->mtip_svc_handler) {
 		set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag);
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:01:52 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:52 -0700
Subject: [PATCH v2 05/10] rnbd: add error handling support for add_disk()
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <20210927220157.1069658-6-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Acked-by: Jack Wang <jinpu.wang at ionos.com>
Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/rnbd/rnbd-clt.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c
index bd4a41afbbfc..1ba1c868535a 100644
--- a/drivers/block/rnbd/rnbd-clt.c
+++ b/drivers/block/rnbd/rnbd-clt.c
@@ -1384,8 +1384,10 @@ static void setup_request_queue(struct rnbd_clt_dev *dev)
 	blk_queue_write_cache(dev->queue, dev->wc, dev->fua);
 }
 
-static void rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx)
+static int rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx)
 {
+	int err;
+
 	dev->gd->major		= rnbd_client_major;
 	dev->gd->first_minor	= idx << RNBD_PART_BITS;
 	dev->gd->minors		= 1 << RNBD_PART_BITS;
@@ -1410,7 +1412,11 @@ static void rnbd_clt_setup_gen_disk(struct rnbd_clt_dev *dev, int idx)
 
 	if (!dev->rotational)
 		blk_queue_flag_set(QUEUE_FLAG_NONROT, dev->queue);
-	add_disk(dev->gd);
+	err = add_disk(dev->gd);
+	if (err)
+		blk_cleanup_disk(dev->gd);
+
+	return err;
 }
 
 static int rnbd_client_setup_device(struct rnbd_clt_dev *dev)
@@ -1426,8 +1432,7 @@ static int rnbd_client_setup_device(struct rnbd_clt_dev *dev)
 	rnbd_init_mq_hw_queues(dev);
 
 	setup_request_queue(dev);
-	rnbd_clt_setup_gen_disk(dev, idx);
-	return 0;
+	return rnbd_clt_setup_gen_disk(dev, idx);
 }
 
 static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess,
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:01:53 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:53 -0700
Subject: [PATCH v2 06/10] block/rsxx: add error handling support for add_disk()
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <20210927220157.1069658-7-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/rsxx/core.c |  4 +++-
 drivers/block/rsxx/dev.c  | 12 +++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c
index 83636714b8d7..8d9d69f5dfbc 100644
--- a/drivers/block/rsxx/core.c
+++ b/drivers/block/rsxx/core.c
@@ -935,7 +935,9 @@ static int rsxx_pci_probe(struct pci_dev *dev,
 			card->size8 = 0;
 	}
 
-	rsxx_attach_dev(card);
+	st = rsxx_attach_dev(card);
+	if (st)
+		goto failed_create_dev;
 
 	/************* Setup Debugfs *************/
 	rsxx_debugfs_dev_new(card);
diff --git a/drivers/block/rsxx/dev.c b/drivers/block/rsxx/dev.c
index 1cc40b0ea761..b2d3ac3efce2 100644
--- a/drivers/block/rsxx/dev.c
+++ b/drivers/block/rsxx/dev.c
@@ -192,6 +192,8 @@ static bool rsxx_discard_supported(struct rsxx_cardinfo *card)
 
 int rsxx_attach_dev(struct rsxx_cardinfo *card)
 {
+	int err = 0;
+
 	mutex_lock(&card->dev_lock);
 
 	/* The block device requires the stripe size from the config. */
@@ -200,13 +202,17 @@ int rsxx_attach_dev(struct rsxx_cardinfo *card)
 			set_capacity(card->gendisk, card->size8 >> 9);
 		else
 			set_capacity(card->gendisk, 0);
-		device_add_disk(CARD_TO_DEV(card), card->gendisk, NULL);
-		card->bdev_attached = 1;
+		err = device_add_disk(CARD_TO_DEV(card), card->gendisk, NULL);
+		if (err == 0)
+			card->bdev_attached = 1;
 	}
 
 	mutex_unlock(&card->dev_lock);
 
-	return 0;
+	if (err)
+		blk_cleanup_disk(card->gendisk);
+
+	return err;
 }
 
 void rsxx_detach_dev(struct rsxx_cardinfo *card)
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:01:54 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:54 -0700
Subject: [PATCH v2 07/10] block/sunvdc: add error handling support for
 add_disk()
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <20210927220157.1069658-8-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

We re-use the same free tag call, so we also add a label for
that as well.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/sunvdc.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 4d4bb810c2ae..6f45a53f7cbf 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -826,8 +826,8 @@ static int probe_disk(struct vdc_port *port)
 	if (IS_ERR(g)) {
 		printk(KERN_ERR PFX "%s: Could not allocate gendisk.\n",
 		       port->vio.name);
-		blk_mq_free_tag_set(&port->tag_set);
-		return PTR_ERR(g);
+		err = PTR_ERR(g);
+		goto out_free_tag;
 	}
 
 	port->disk = g;
@@ -879,9 +879,17 @@ static int probe_disk(struct vdc_port *port)
 	       port->vdisk_size, (port->vdisk_size >> (20 - 9)),
 	       port->vio.ver.major, port->vio.ver.minor);
 
-	device_add_disk(&port->vio.vdev->dev, g, NULL);
+	err = device_add_disk(&port->vio.vdev->dev, g, NULL);
+	if (err)
+		goto out_cleanup_disk;
 
 	return 0;
+
+out_cleanup_disk:
+	blk_cleanup_disk(g);
+out_free_tag:
+	blk_mq_free_tag_set(&port->tag_set);
+	return err;
 }
 
 static struct ldc_channel_config vdc_ldc_cfg = {
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:01:47 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:47 -0700
Subject: [PATCH v2 00/10] block: fourth batch of add_disk() error handling
 conversions
Message-ID: <20210927220157.1069658-1-mcgrof@kernel.org>

This is the fourth batch of add_disk() error handling driver
conversions. This set along with the entire 7 set of driver conversions
can be found on my 20210927-for-axboe-add-disk-error-handling branch
[0].

On this v2 series the following modifications have been made since the
last v1 series of this patch set:

  - rebased onto linux-next tag 20210927
  - added the only reviewed-by tag for this series for rnbd Jack Wang

[0] https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/log/?h=20210927-for-axboe-add-disk-error-handling

Luis Chamberlain (10):
  mtip32xx: add error handling support for add_disk()
  pktcdvd: add error handling support for add_disk()
  ps3disk: add error handling support for add_disk()
  ps3vram: add error handling support for add_disk()
  rnbd: add error handling support for add_disk()
  block/rsxx: add error handling support for add_disk()
  block/sunvdc: add error handling support for add_disk()
  block/sx8: add error handling support for add_disk()
  pf: add error handling support for add_disk()
  mtd/ubi/block: add error handling support for add_disk()

 drivers/block/mtip32xx/mtip32xx.c |  4 +++-
 drivers/block/paride/pf.c         |  4 +++-
 drivers/block/pktcdvd.c           |  4 +++-
 drivers/block/ps3disk.c           |  8 ++++++--
 drivers/block/ps3vram.c           |  7 ++++++-
 drivers/block/rnbd/rnbd-clt.c     | 13 +++++++++----
 drivers/block/rsxx/core.c         |  4 +++-
 drivers/block/rsxx/dev.c          | 12 +++++++++---
 drivers/block/sunvdc.c            | 14 +++++++++++---
 drivers/block/sx8.c               | 13 +++++++++----
 drivers/mtd/ubi/block.c           |  8 +++++++-
 11 files changed, 69 insertions(+), 22 deletions(-)

-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:01:50 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:50 -0700
Subject: [PATCH v2 03/10] ps3disk: add error handling support for add_disk()
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <20210927220157.1069658-4-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/ps3disk.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 8d51efbe045d..3054adf77460 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -467,9 +467,13 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev)
 		 gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
 		 get_capacity(gendisk) >> 11);
 
-	device_add_disk(&dev->sbd.core, gendisk, NULL);
-	return 0;
+	error = device_add_disk(&dev->sbd.core, gendisk, NULL);
+	if (error)
+		goto fail_cleanup_disk;
 
+	return 0;
+fail_cleanup_disk:
+	blk_cleanup_disk(gendisk);
 fail_free_tag_set:
 	blk_mq_free_tag_set(&priv->tag_set);
 fail_teardown:
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:01:49 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:01:49 -0700
Subject: [PATCH v2 02/10] pktcdvd: add error handling support for add_disk()
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <20210927220157.1069658-3-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

The out_mem2 error label already does what we need so
re-use that.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/pktcdvd.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 0f26b2510a75..415248962e67 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2729,7 +2729,9 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev)
 	/* inherit events of the host device */
 	disk->events = pd->bdev->bd_disk->events;
 
-	add_disk(disk);
+	ret = add_disk(disk);
+	if (ret)
+		goto out_mem2;
 
 	pkt_sysfs_dev_new(pd);
 	pkt_debugfs_dev_new(pd);
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:02:28 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:02:28 -0700
Subject: [PATCH v2 2/6] rbd: add add_disk() error handling
In-Reply-To: <20210927220232.1071926-1-mcgrof@kernel.org>
References: <20210927220232.1071926-1-mcgrof@kernel.org>
Message-ID: <20210927220232.1071926-3-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/block/rbd.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index e65c9d706f6f..341e5da6d029 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -7054,7 +7054,9 @@ static ssize_t do_rbd_add(struct bus_type *bus,
 	if (rc)
 		goto err_out_image_lock;
 
-	device_add_disk(&rbd_dev->dev, rbd_dev->disk, NULL);
+	rc = device_add_disk(&rbd_dev->dev, rbd_dev->disk, NULL);
+	if (rc)
+		goto err_out_cleanup_disk;
 
 	spin_lock(&rbd_dev_list_lock);
 	list_add_tail(&rbd_dev->node, &rbd_dev_list);
@@ -7068,6 +7070,8 @@ static ssize_t do_rbd_add(struct bus_type *bus,
 	module_put(THIS_MODULE);
 	return rc;
 
+err_out_cleanup_disk:
+	rbd_free_disk(rbd_dev);
 err_out_image_lock:
 	rbd_dev_image_unlock(rbd_dev);
 	rbd_dev_device_release(rbd_dev);
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:02:30 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:02:30 -0700
Subject: [PATCH v2 4/6] s390/block/dasd_genhd: add error handling support for
 add_disk()
In-Reply-To: <20210927220232.1071926-1-mcgrof@kernel.org>
References: <20210927220232.1071926-1-mcgrof@kernel.org>
Message-ID: <20210927220232.1071926-5-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Be sure to call dasd_gendisk_free() on error.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/s390/block/dasd_genhd.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index fa966e0db6ca..80673dbfb1f9 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -33,7 +33,7 @@ int dasd_gendisk_alloc(struct dasd_block *block)
 {
 	struct gendisk *gdp;
 	struct dasd_device *base;
-	int len;
+	int len, rc;
 
 	/* Make sure the minor for this device exists. */
 	base = block->base;
@@ -79,7 +79,13 @@ int dasd_gendisk_alloc(struct dasd_block *block)
 	dasd_add_link_to_gendisk(gdp, base);
 	block->gdp = gdp;
 	set_capacity(block->gdp, 0);
-	device_add_disk(&base->cdev->dev, block->gdp, NULL);
+
+	rc = device_add_disk(&base->cdev->dev, block->gdp, NULL);
+	if (rc) {
+		dasd_gendisk_free(block);
+		return rc;
+	}
+
 	return 0;
 }
 
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:02:27 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:02:27 -0700
Subject: [PATCH v2 1/6] cdrom/gdrom: add error handling support for add_disk()
In-Reply-To: <20210927220232.1071926-1-mcgrof@kernel.org>
References: <20210927220232.1071926-1-mcgrof@kernel.org>
Message-ID: <20210927220232.1071926-2-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/cdrom/gdrom.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c
index 8e1fe75af93f..d50cc1fd34d5 100644
--- a/drivers/cdrom/gdrom.c
+++ b/drivers/cdrom/gdrom.c
@@ -805,9 +805,14 @@ static int probe_gdrom(struct platform_device *devptr)
 		err = -ENOMEM;
 		goto probe_fail_free_irqs;
 	}
-	add_disk(gd.disk);
+	err = add_disk(gd.disk);
+	if (err)
+		goto probe_fail_add_disk;
+
 	return 0;
 
+probe_fail_add_disk:
+	kfree(gd.toc);
 probe_fail_free_irqs:
 	free_irq(HW_EVENT_GDROM_DMA, &gd);
 	free_irq(HW_EVENT_GDROM_CMD, &gd);
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:02:31 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:02:31 -0700
Subject: [PATCH v2 5/6] s390/block/dcssblk: add error handling support for
 add_disk()
In-Reply-To: <20210927220232.1071926-1-mcgrof@kernel.org>
References: <20210927220232.1071926-1-mcgrof@kernel.org>
Message-ID: <20210927220232.1071926-6-mcgrof@kernel.org>

From: Gerald Schaefer <gerald.schaefer at linux.ibm.com>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
Signed-off-by: Gerald Schaefer <gerald.schaefer at linux.ibm.com>
---
 drivers/s390/block/dcssblk.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 5be3d1c39a78..0741a9321712 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -696,7 +696,9 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
 	}
 
 	get_device(&dev_info->dev);
-	device_add_disk(&dev_info->dev, dev_info->gd, NULL);
+	rc = device_add_disk(&dev_info->dev, dev_info->gd, NULL);
+	if (rc)
+		goto out_dax;
 
 	switch (dev_info->segment_type) {
 		case SEG_TYPE_SR:
@@ -712,6 +714,10 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
 	rc = count;
 	goto out;
 
+out_dax:
+	put_device(&dev_info->dev);
+	kill_dax(dev_info->dax_dev);
+	put_dax(dev_info->dax_dev);
 put_dev:
 	list_del(&dev_info->lh);
 	blk_cleanup_disk(dev_info->gd);
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:02:26 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:02:26 -0700
Subject: [PATCH v2 0/6] block: 5th batch of add_disk() error handling
 conversions
Message-ID: <20210927220232.1071926-1-mcgrof@kernel.org>

This is the 5th series of driver conversions for add_disk() error
handling. This set along with the entire 7th set of patches can be
found on my 20210927-for-axboe-add-disk-error-handling branch [0].

On this v2 series the following changes have been made
since the first iteration of this patchset:

  - rebased onto linux-next tag 20210927
  - ms_block: dropped this patch as its already merged on linux-next
  - mspro_block: dropped this patch as its already merged on linux-next
  - dropped the s390/block/xpram patch as that driver is now removed
  - s390/block/dcssblk: dropped my patch in favor of Gerald Schaefer's
  - added respective reviewed-by/acked-by tags

[0] https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/log/?h=20210927-for-axboe-add-disk-error-handling

Gerald Schaefer (1):
  s390/block/dcssblk: add error handling support for add_disk()

Luis Chamberlain (5):
  cdrom/gdrom: add error handling support for add_disk()
  rbd: add add_disk() error handling
  mtd: add add_disk() error handling
  s390/block/dasd_genhd: add error handling support for add_disk()
  s390/block/scm_blk: add error handling support for add_disk()

 drivers/block/rbd.c             |  6 +++++-
 drivers/cdrom/gdrom.c           |  7 ++++++-
 drivers/mtd/mtd_blkdevs.c       |  6 +++++-
 drivers/s390/block/dasd_genhd.c | 10 ++++++++--
 drivers/s390/block/dcssblk.c    |  8 +++++++-
 drivers/s390/block/scm_blk.c    |  7 ++++++-
 6 files changed, 37 insertions(+), 7 deletions(-)

-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:02:32 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:02:32 -0700
Subject: [PATCH v2 6/6] s390/block/scm_blk: add error handling support for
 add_disk()
In-Reply-To: <20210927220232.1071926-1-mcgrof@kernel.org>
References: <20210927220232.1071926-1-mcgrof@kernel.org>
Message-ID: <20210927220232.1071926-7-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Acked-by: Heiko Carstens <hca at linux.ibm.com>
Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/s390/block/scm_blk.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c
index 88cba6212ee2..61ecdcb2cc6a 100644
--- a/drivers/s390/block/scm_blk.c
+++ b/drivers/s390/block/scm_blk.c
@@ -495,9 +495,14 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev)
 
 	/* 512 byte sectors */
 	set_capacity(bdev->gendisk, scmdev->size >> 9);
-	device_add_disk(&scmdev->dev, bdev->gendisk, NULL);
+	ret = device_add_disk(&scmdev->dev, bdev->gendisk, NULL);
+	if (ret)
+		goto out_cleanup_disk;
+
 	return 0;
 
+out_cleanup_disk:
+	blk_cleanup_disk(bdev->gendisk);
 out_tag:
 	blk_mq_free_tag_set(&bdev->tag_set);
 out:
-- 
2.30.2



From mcgrof at kernel.org  Mon Sep 27 15:02:29 2021
From: mcgrof at kernel.org (Luis Chamberlain)
Date: Mon, 27 Sep 2021 15:02:29 -0700
Subject: [PATCH v2 3/6] mtd: add add_disk() error handling
In-Reply-To: <20210927220232.1071926-1-mcgrof@kernel.org>
References: <20210927220232.1071926-1-mcgrof@kernel.org>
Message-ID: <20210927220232.1071926-4-mcgrof@kernel.org>

We never checked for errors on add_disk() as this function
returned void. Now that this is fixed, use the shiny new
error handling.

Acked-by: Miquel Raynal <miquel.raynal at bootlin.com>
Signed-off-by: Luis Chamberlain <mcgrof at kernel.org>
---
 drivers/mtd/mtd_blkdevs.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index b8ae1ec14e17..4eaba6f4ec68 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -384,7 +384,9 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 	if (new->readonly)
 		set_disk_ro(gd, 1);
 
-	device_add_disk(&new->mtd->dev, gd, NULL);
+	ret = device_add_disk(&new->mtd->dev, gd, NULL);
+	if (ret)
+		goto out_cleanup_disk;
 
 	if (new->disk_attributes) {
 		ret = sysfs_create_group(&disk_to_dev(gd)->kobj,
@@ -393,6 +395,8 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
 	}
 	return 0;
 
+out_cleanup_disk:
+	blk_cleanup_disk(new->disk);
 out_free_tag_set:
 	blk_mq_free_tag_set(new->tag_set);
 out_kfree_tag_set:
-- 
2.30.2



From richard.weinberger at gmail.com  Mon Sep 27 15:11:55 2021
From: richard.weinberger at gmail.com (Richard Weinberger)
Date: Tue, 28 Sep 2021 00:11:55 +0200
Subject: MLC NAND support in ubifs
In-Reply-To: <17c04b2db3f.11955d8ed102190.1977520078612166881@kubicz.engineer>
References: <17c04b2db3f.11955d8ed102190.1977520078612166881@kubicz.engineer>
Message-ID: <CAFLxGvxKhKjgqO=_6dgTHcnGpkaapeyvOO6zmGvHLwo6X+-aHw@mail.gmail.com>

On Mon, Sep 20, 2021 at 9:39 PM Filip Kubicz <filip at kubicz.engineer> wrote:
>
> Hi All,
>
> I'm bumping up the question about NAND support since it looks like it slipped unnoticed between emails with patches. Does anyone know the answer?
>
> Thank you in advance,
> Filip
>
> filip at kubicz.engineer
> tel. (+48) 697 088 078
>
>
> ---- On Thu, 09 Sep 2021 18:41:24 +0200 filip at kubicz.engineer  wrote ----
>
>  > Hi!
>  >
>  > I would like to ask about MLC NAND support in UBIFS.
>  >
>  > I was recently bringing up a device with IMX6ULL and raw MLC NAND flash. I have built Linux 5.4 kernel, u-boot and rootfs (using buildroot), flashed them to my device with MLC NAND flash, and learned from dmesg error that MLC is unsupported by ubifs. Support removed in this commit: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b5094b7f135be
>  >
>  > Then I followed the story from Richard and Boris and watched the talk where they explain the issues with MLC, and propose an alternative: https://www.youtube.com/watch?v=9j2pOIiJqYw&ab_channel=TheLinuxFoundation
>  > Alternative available since Linux 5.8: https://www.phoronix.com/scan.php?page=news_item&px=Linux-5.8-NAND-MLC-SLC-Emulate
>  >
>  > My questions:
>  > 1. Is NAND MLC (+ubifs) reliable to use with SLC emulate mode introduced in kernel 5.8? Or should I rather switch to eMMC for this design? SLC NAND is too costly at my required size.

SLC emulation solves only the paired pages problem. You still get all
other downsides of MLC. I'd not use it unless I'm forced to.

>  > 2. If the MLC NAND is not supported, can you update these pages:
>  > - http://www.linux-mtd.infradead.org/doc/ubifs.html
>  > - https://www.kernel.org/doc/html/latest/filesystems/ubifs.html
>  > - http://www.linux-mtd.infradead.org/faq/ubifs.html
>  > Each of the documentation pages mention MLC, so you can get an idea that it is supported. But it looks like the MLC NAND flash is not supported by UBIFS.

Good point!

-- 
Thanks,
//richard


From axboe at kernel.dk  Mon Sep 27 15:31:29 2021
From: axboe at kernel.dk (Jens Axboe)
Date: Mon, 27 Sep 2021 16:31:29 -0600
Subject: [PATCH v2 00/10] block: fourth batch of add_disk() error handling
 conversions
In-Reply-To: <20210927220157.1069658-1-mcgrof@kernel.org>
References: <20210927220157.1069658-1-mcgrof@kernel.org>
Message-ID: <529d5e4a-82a4-2498-f63d-34c177ca4ab4@kernel.dk>

On 9/27/21 4:01 PM, Luis Chamberlain wrote:
> This is the fourth batch of add_disk() error handling driver
> conversions. This set along with the entire 7 set of driver conversions
> can be found on my 20210927-for-axboe-add-disk-error-handling branch
> [0].

Applied 1-2, 6, 8-9, thanks.

-- 
Jens Axboe



From axboe at kernel.dk  Mon Sep 27 15:32:17 2021
From: axboe at kernel.dk (Jens Axboe)
Date: Mon, 27 Sep 2021 16:32:17 -0600
Subject: [PATCH v2 0/6] block: 5th batch of add_disk() error handling
 conversions
In-Reply-To: <20210927220232.1071926-1-mcgrof@kernel.org>
References: <20210927220232.1071926-1-mcgrof@kernel.org>
Message-ID: <25afa23b-52af-9b79-8bd8-5e31da62c291@kernel.dk>

On 9/27/21 4:02 PM, Luis Chamberlain wrote:
> This is the 5th series of driver conversions for add_disk() error
> handling. This set along with the entire 7th set of patches can be
> found on my 20210927-for-axboe-add-disk-error-handling branch [0].

Applied 1-2.

-- 
Jens Axboe



From linus.walleij at linaro.org  Mon Sep 27 16:27:41 2021
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 28 Sep 2021 01:27:41 +0200
Subject: [PATCH] [RFC] mtd: fixup CFI on ixp4xx
In-Reply-To: <20210927141045.1597593-1-arnd@kernel.org>
References: <20210927141045.1597593-1-arnd@kernel.org>
Message-ID: <CACRpkdbirEZiKQxSWSsiwwvpui5Pw6vON-C-=BLJei0s8znLxg@mail.gmail.com>

On Mon, Sep 27, 2021 at 4:10 PM Arnd Bergmann <arnd at kernel.org> wrote:

> From: Arnd Bergmann <arnd at arndb.de>
>
> drivers/mtd/maps/ixp4xx.c requires MTD_CFI_BE_BYTE_SWAP to be set
> in order to compile.
>
> drivers/mtd/maps/ixp4xx.c:57:4: error: #error CONFIG_MTD_CFI_BE_BYTE_SWAP required
>
> This patch avoids the #error output by enforcing the policy in
> Kconfig. Not sure if this is the right approach, but it helps doing
> randconfig builds.
>
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

Acked-by: Linus Walleij <linus.walleij at linaro.org>

> Any other ideas for how to address it?

We will "soon" have IXP4xx transitioned to device tree and then
physmap-ixp4xx.c is used instead, and this entire driver can be
deleted. I will get there, we just need to remember to mop of cruft
like this at the end of it.

Yours,
Linus Walleij


From hch at lst.de  Mon Sep 27 22:22:06 2021
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 28 Sep 2021 07:22:06 +0200
Subject: remove ->rq_disk
Message-ID: <20210928052211.112801-1-hch@lst.de>

Hi Jens,

this series removes the rq_disk field in struct request, which isn't
needed now that we can get the disk from the request_queue.

Diffstat:
 block/blk-core.c                   |   10 ++++----
 block/blk-exec.c                   |   10 ++------
 block/blk-flush.c                  |    3 --
 block/blk-merge.c                  |    7 ------
 block/blk-mq.c                     |    1 
 block/blk.h                        |    2 -
 block/bsg-lib.c                    |    2 -
 drivers/block/amiflop.c            |    2 -
 drivers/block/ataflop.c            |    6 ++---
 drivers/block/floppy.c             |    6 ++---
 drivers/block/mtip32xx/mtip32xx.c  |    2 -
 drivers/block/null_blk/trace.h     |    2 -
 drivers/block/paride/pcd.c         |    2 -
 drivers/block/paride/pd.c          |    6 ++---
 drivers/block/paride/pf.c          |    4 +--
 drivers/block/pktcdvd.c            |    2 -
 drivers/block/rnbd/rnbd-clt.c      |    4 +--
 drivers/block/sunvdc.c             |    2 -
 drivers/block/sx8.c                |    4 +--
 drivers/block/virtio_blk.c         |    2 -
 drivers/md/dm-mpath.c              |    1 
 drivers/mmc/core/block.c           |   12 +++++-----
 drivers/mtd/mtd_blkdevs.c          |   10 +-------
 drivers/nvme/host/core.c           |    4 +--
 drivers/nvme/host/fault_inject.c   |    2 -
 drivers/nvme/host/pci.c            |    7 ++----
 drivers/nvme/host/trace.h          |    6 ++---
 drivers/nvme/target/passthru.c     |    3 --
 drivers/scsi/ch.c                  |    2 -
 drivers/scsi/scsi_bsg.c            |    2 -
 drivers/scsi/scsi_error.c          |    2 -
 drivers/scsi/scsi_ioctl.c          |   43 ++++++++++++++-----------------------
 drivers/scsi/scsi_lib.c            |    5 ++--
 drivers/scsi/scsi_logging.c        |    4 ++-
 drivers/scsi/sd.c                  |   26 +++++++++++-----------
 drivers/scsi/sd_zbc.c              |    8 +++---
 drivers/scsi/sg.c                  |    6 ++---
 drivers/scsi/sr.c                  |   11 ++++-----
 drivers/scsi/st.c                  |    4 +--
 drivers/scsi/ufs/ufshcd.c          |    3 --
 drivers/scsi/ufs/ufshpb.c          |    5 +---
 drivers/scsi/virtio_scsi.c         |    2 -
 drivers/target/target_core_pscsi.c |    2 -
 drivers/usb/storage/transport.c    |    2 -
 fs/nfsd/blocklayout.c              |    2 -
 include/linux/blk-mq.h             |   11 ++-------
 include/scsi/scsi_cmnd.h           |    2 -
 include/scsi/scsi_device.h         |    4 +--
 include/scsi/scsi_ioctl.h          |    4 +--
 include/trace/events/block.h       |    8 +++---
 kernel/trace/blktrace.c            |    2 -
 51 files changed, 125 insertions(+), 159 deletions(-)


From hch at lst.de  Mon Sep 27 22:22:07 2021
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 28 Sep 2021 07:22:07 +0200
Subject: [PATCH 1/5] mtd_blkdevs: remove the sector out of range check in
 do_blktrans_request
In-Reply-To: <20210928052211.112801-1-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
Message-ID: <20210928052211.112801-2-hch@lst.de>

The block layer already performs this check, no need to duplicate it in
the driver.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 drivers/mtd/mtd_blkdevs.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index b8ae1ec14e178..5ce5da705ac00 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -52,17 +52,11 @@ static blk_status_t do_blktrans_request(struct mtd_blktrans_ops *tr,
 	block = blk_rq_pos(req) << 9 >> tr->blkshift;
 	nsect = blk_rq_cur_bytes(req) >> tr->blkshift;
 
-	if (req_op(req) == REQ_OP_FLUSH) {
+	switch (req_op(req)) {
+	case REQ_OP_FLUSH:
 		if (tr->flush(dev))
 			return BLK_STS_IOERR;
 		return BLK_STS_OK;
-	}
-
-	if (blk_rq_pos(req) + blk_rq_cur_sectors(req) >
-	    get_capacity(req->rq_disk))
-		return BLK_STS_IOERR;
-
-	switch (req_op(req)) {
 	case REQ_OP_DISCARD:
 		if (tr->discard(dev, block, nsect))
 			return BLK_STS_IOERR;
-- 
2.30.2



From hch at lst.de  Mon Sep 27 22:22:08 2021
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 28 Sep 2021 07:22:08 +0200
Subject: [PATCH 2/5] block: don't check ->rq_disk in merges
In-Reply-To: <20210928052211.112801-1-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
Message-ID: <20210928052211.112801-3-hch@lst.de>

There is a 1:1 relationship between request_queues and gendisks now, so
no need for these extra checks.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 block/blk-merge.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/block/blk-merge.c b/block/blk-merge.c
index 5b4f23014df8a..6b62415452f82 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -756,8 +756,7 @@ static struct request *attempt_merge(struct request_queue *q,
 	if (req_op(req) != req_op(next))
 		return NULL;
 
-	if (rq_data_dir(req) != rq_data_dir(next)
-	    || req->rq_disk != next->rq_disk)
+	if (rq_data_dir(req) != rq_data_dir(next))
 		return NULL;
 
 	if (req_op(req) == REQ_OP_WRITE_SAME &&
@@ -884,10 +883,6 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 	if (bio_data_dir(bio) != rq_data_dir(rq))
 		return false;
 
-	/* must be same device */
-	if (rq->rq_disk != bio->bi_bdev->bd_disk)
-		return false;
-
 	/* only merge integrity protected bio into ditto rq */
 	if (blk_integrity_merge_bio(rq->q, rq, bio) == false)
 		return false;
-- 
2.30.2



From hch at lst.de  Mon Sep 27 22:22:09 2021
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 28 Sep 2021 07:22:09 +0200
Subject: [PATCH 3/5] block: remove the ->rq_disk field in struct request
In-Reply-To: <20210928052211.112801-1-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
Message-ID: <20210928052211.112801-4-hch@lst.de>

Just use the disk attached to the request_queue instead.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 block/blk-core.c                 | 10 +++++-----
 block/blk-exec.c                 |  5 ++---
 block/blk-flush.c                |  3 +--
 block/blk-mq.c                   |  1 -
 block/blk.h                      |  2 +-
 drivers/block/amiflop.c          |  2 +-
 drivers/block/ataflop.c          |  6 +++---
 drivers/block/floppy.c           |  6 +++---
 drivers/block/null_blk/trace.h   |  2 +-
 drivers/block/paride/pcd.c       |  2 +-
 drivers/block/paride/pd.c        |  4 ++--
 drivers/block/paride/pf.c        |  4 ++--
 drivers/block/rnbd/rnbd-clt.c    |  4 ++--
 drivers/block/sunvdc.c           |  2 +-
 drivers/md/dm-mpath.c            |  1 -
 drivers/mmc/core/block.c         |  2 +-
 drivers/nvme/host/fault_inject.c |  2 +-
 drivers/nvme/host/trace.h        |  6 +++---
 drivers/scsi/scsi_lib.c          |  3 ++-
 drivers/scsi/scsi_logging.c      |  4 +++-
 drivers/scsi/sd.c                | 24 ++++++++++++------------
 drivers/scsi/sd_zbc.c            |  8 ++++----
 drivers/scsi/sr.c                |  4 ++--
 drivers/scsi/ufs/ufshpb.c        |  1 -
 drivers/scsi/virtio_scsi.c       |  2 +-
 drivers/usb/storage/transport.c  |  2 +-
 include/linux/blk-mq.h           |  4 ----
 include/scsi/scsi_cmnd.h         |  2 +-
 include/scsi/scsi_device.h       |  4 ++--
 include/trace/events/block.h     |  8 ++++----
 kernel/trace/blktrace.c          |  2 +-
 31 files changed, 63 insertions(+), 69 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 22c2982bb0bdf..7b0ab63fa227a 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -228,7 +228,7 @@ static void print_req_error(struct request *req, blk_status_t status,
 		"%s: %s error, dev %s, sector %llu op 0x%x:(%s) flags 0x%x "
 		"phys_seg %u prio class %u\n",
 		caller, blk_errors[idx].name,
-		req->rq_disk ? req->rq_disk->disk_name : "?",
+		req->q->disk ? req->q->disk->disk_name : "?",
 		blk_rq_pos(req), req_op(req), blk_op_str(req_op(req)),
 		req->cmd_flags & ~REQ_OP_MASK,
 		req->nr_phys_segments,
@@ -265,7 +265,7 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
 void blk_dump_rq_flags(struct request *rq, char *msg)
 {
 	printk(KERN_INFO "%s: dev %s: flags=%llx\n", msg,
-		rq->rq_disk ? rq->rq_disk->disk_name : "?",
+		rq->q->disk ? rq->q->disk->disk_name : "?",
 		(unsigned long long) rq->cmd_flags);
 
 	printk(KERN_INFO "  sector %llu, nr/cnr %u/%u\n",
@@ -1163,8 +1163,8 @@ blk_status_t blk_insert_cloned_request(struct request_queue *q, struct request *
 	if (ret != BLK_STS_OK)
 		return ret;
 
-	if (rq->rq_disk &&
-	    should_fail_request(rq->rq_disk->part0, blk_rq_bytes(rq)))
+	if (rq->q->disk &&
+	    should_fail_request(rq->q->disk->part0, blk_rq_bytes(rq)))
 		return BLK_STS_IOERR;
 
 	if (blk_crypto_insert_cloned_request(rq))
@@ -1278,7 +1278,7 @@ void blk_account_io_start(struct request *rq)
 	if (rq->bio && rq->bio->bi_bdev)
 		rq->part = rq->bio->bi_bdev;
 	else
-		rq->part = rq->rq_disk->part0;
+		rq->part = rq->q->disk->part0;
 
 	part_stat_lock();
 	update_io_ticks(rq->part, jiffies, false);
diff --git a/block/blk-exec.c b/block/blk-exec.c
index d6cd501c0d348..9832655bd2662 100644
--- a/block/blk-exec.c
+++ b/block/blk-exec.c
@@ -32,7 +32,7 @@ static void blk_end_sync_rq(struct request *rq, blk_status_t error)
 
 /**
  * blk_execute_rq_nowait - insert a request to I/O scheduler for execution
- * @bd_disk:	matching gendisk
+ * @bd_disk:	unused
  * @rq:		request to insert
  * @at_head:    insert request at head or tail of queue
  * @done:	I/O completion handler
@@ -50,7 +50,6 @@ void blk_execute_rq_nowait(struct gendisk *bd_disk, struct request *rq,
 	WARN_ON(irqs_disabled());
 	WARN_ON(!blk_rq_is_passthrough(rq));
 
-	rq->rq_disk = bd_disk;
 	rq->end_io = done;
 
 	blk_account_io_start(rq);
@@ -78,7 +77,7 @@ static void blk_rq_poll_completion(struct request *rq, struct completion *wait)
 
 /**
  * blk_execute_rq - insert a request into queue for execution
- * @bd_disk:	matching gendisk
+ * @bd_disk:	unused
  * @rq:		request to insert
  * @at_head:    insert request at head or tail of queue
  *
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 4201728bf3a5a..f0647b41222a7 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -138,7 +138,7 @@ static void blk_flush_queue_rq(struct request *rq, bool add_front)
 
 static void blk_account_io_flush(struct request *rq)
 {
-	struct block_device *part = rq->rq_disk->part0;
+	struct block_device *part = rq->q->disk->part0;
 
 	part_stat_lock();
 	part_stat_inc(part, ios[STAT_FLUSH]);
@@ -332,7 +332,6 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
 	flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
 	flush_rq->cmd_flags |= (flags & REQ_DRV) | (flags & REQ_FAILFAST_MASK);
 	flush_rq->rq_flags |= RQF_FLUSH_SEQ;
-	flush_rq->rq_disk = first_rq->rq_disk;
 	flush_rq->end_io = flush_end_io;
 	/*
 	 * Order WRITE ->end_io and WRITE rq->ref, and its pair is the one
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 21bf4c3f08259..4d04628e45348 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -303,7 +303,6 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data,
 	INIT_LIST_HEAD(&rq->queuelist);
 	INIT_HLIST_NODE(&rq->hash);
 	RB_CLEAR_NODE(&rq->rb_node);
-	rq->rq_disk = NULL;
 	rq->part = NULL;
 #ifdef CONFIG_BLK_RQ_ALLOC_TIME
 	rq->alloc_time_ns = alloc_time_ns;
diff --git a/block/blk.h b/block/blk.h
index deb8393e34eec..3bab7f784ec13 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -278,7 +278,7 @@ int blk_dev_init(void);
  */
 static inline bool blk_do_io_stat(struct request *rq)
 {
-	return rq->rq_disk && (rq->rq_flags & RQF_IO_STAT);
+	return rq->q->disk && (rq->rq_flags & RQF_IO_STAT);
 }
 
 static inline void req_set_nomerge(struct request_queue *q, struct request *req)
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 2909fd9e72fb8..ff91ca480bf5a 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -1505,7 +1505,7 @@ static blk_status_t amiflop_queue_rq(struct blk_mq_hw_ctx *hctx,
 				     const struct blk_mq_queue_data *bd)
 {
 	struct request *rq = bd->rq;
-	struct amiga_floppy_struct *floppy = rq->rq_disk->private_data;
+	struct amiga_floppy_struct *floppy = rq->q->disk->private_data;
 	blk_status_t err;
 
 	if (!spin_trylock_irq(&amiflop_lock))
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c
index 58e921ab57298..2e8b84cedbb9a 100644
--- a/drivers/block/ataflop.c
+++ b/drivers/block/ataflop.c
@@ -1488,7 +1488,7 @@ static void ataflop_commit_rqs(struct blk_mq_hw_ctx *hctx)
 static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
 				     const struct blk_mq_queue_data *bd)
 {
-	struct atari_floppy_struct *floppy = bd->rq->rq_disk->private_data;
+	struct atari_floppy_struct *floppy = bd->rq->q->disk->private_data;
 	int drive = floppy - unit;
 	int type = floppy->type;
 
@@ -1519,7 +1519,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
 		if (!UDT) {
 			Probing = 1;
 			UDT = atari_disk_type + StartDiskType[DriveType];
-			set_capacity(bd->rq->rq_disk, UDT->blocks);
+			set_capacity(bd->rq->q->disk, UDT->blocks);
 			UD.autoprobe = 1;
 		}
 	} 
@@ -1537,7 +1537,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx,
 		}
 		type = minor2disktype[type].index;
 		UDT = &atari_disk_type[type];
-		set_capacity(bd->rq->rq_disk, UDT->blocks);
+		set_capacity(bd->rq->q->disk, UDT->blocks);
 		UD.autoprobe = 0;
 	}
 
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 6288ce8884147..c071142e26d71 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -2259,7 +2259,7 @@ static int do_format(int drive, struct format_descr *tmp_format_req)
 static void floppy_end_request(struct request *req, blk_status_t error)
 {
 	unsigned int nr_sectors = current_count_sectors;
-	unsigned int drive = (unsigned long)req->rq_disk->private_data;
+	unsigned int drive = (unsigned long)req->q->disk->private_data;
 
 	/* current_count_sectors can be zero if transfer failed */
 	if (error)
@@ -2550,7 +2550,7 @@ static int make_raw_rw_request(void)
 	if (WARN(max_buffer_sectors == 0, "VFS: Block I/O scheduled on unopened device\n"))
 		return 0;
 
-	set_fdc((long)current_req->rq_disk->private_data);
+	set_fdc((long)current_req->q->disk->private_data);
 
 	raw_cmd = &default_raw_cmd;
 	raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_SEEK;
@@ -2792,7 +2792,7 @@ static void redo_fd_request(void)
 			return;
 		}
 	}
-	drive = (long)current_req->rq_disk->private_data;
+	drive = (long)current_req->q->disk->private_data;
 	set_fdc(drive);
 	reschedule_timeout(current_drive, "redo fd request");
 
diff --git a/drivers/block/null_blk/trace.h b/drivers/block/null_blk/trace.h
index ce3b430e88c57..86d6c12c603cc 100644
--- a/drivers/block/null_blk/trace.h
+++ b/drivers/block/null_blk/trace.h
@@ -44,7 +44,7 @@ TRACE_EVENT(nullb_zone_op,
 		__entry->op = req_op(cmd->rq);
 		__entry->zone_no = zone_no;
 		__entry->zone_cond = zone_cond;
-		__assign_disk_name(__entry->disk, cmd->rq->rq_disk);
+		__assign_disk_name(__entry->disk, cmd->rq->q->disk);
 	    ),
 	    TP_printk("%s req=%-15s zone_no=%u zone_cond=%-10s",
 		      __print_disk_name(__entry->disk),
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index f9cdd11f02f58..f8dcde353a6f6 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -799,7 +799,7 @@ static void pcd_request(void)
 	if (!pcd_req && !set_next_request())
 		return;
 
-	cd = pcd_req->rq_disk->private_data;
+	cd = pcd_req->q->disk->private_data;
 	if (cd != pcd_current)
 		pcd_bufblk = -1;
 	pcd_current = cd;
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 675327df6aff9..ab9d336d7b79c 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -430,7 +430,7 @@ static void run_fsm(void)
 		int stop = 0;
 
 		if (!phase) {
-			pd_current = pd_req->rq_disk->private_data;
+			pd_current = pd_req->q->disk->private_data;
 			pi_current = pd_current->pi;
 			phase = do_pd_io_start;
 		}
@@ -492,7 +492,7 @@ static enum action do_pd_io_start(void)
 	case REQ_OP_WRITE:
 		pd_block = blk_rq_pos(pd_req);
 		pd_count = blk_rq_cur_sectors(pd_req);
-		if (pd_block + pd_count > get_capacity(pd_req->rq_disk))
+		if (pd_block + pd_count > get_capacity(pd_req->q->disk))
 			return Fail;
 		pd_run = blk_rq_sectors(pd_req);
 		pd_buf = bio_data(pd_req->bio);
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index d5b9c88ba76fa..79bd00b24337e 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -839,12 +839,12 @@ static void pf_request(void)
 	if (!pf_req && !set_next_request())
 		return;
 
-	pf_current = pf_req->rq_disk->private_data;
+	pf_current = pf_req->q->disk->private_data;
 	pf_block = blk_rq_pos(pf_req);
 	pf_run = blk_rq_sectors(pf_req);
 	pf_count = blk_rq_cur_sectors(pf_req);
 
-	if (pf_block + pf_count > get_capacity(pf_req->rq_disk)) {
+	if (pf_block + pf_count > get_capacity(pf_req->q->disk)) {
 		pf_end_request(BLK_STS_IOERR);
 		goto repeat;
 	}
diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c
index bd4a41afbbfc9..4ed7db305b975 100644
--- a/drivers/block/rnbd/rnbd-clt.c
+++ b/drivers/block/rnbd/rnbd-clt.c
@@ -393,7 +393,7 @@ static void rnbd_put_iu(struct rnbd_clt_session *sess, struct rnbd_iu *iu)
 
 static void rnbd_softirq_done_fn(struct request *rq)
 {
-	struct rnbd_clt_dev *dev	= rq->rq_disk->private_data;
+	struct rnbd_clt_dev *dev	= rq->q->disk->private_data;
 	struct rnbd_clt_session *sess	= dev->sess;
 	struct rnbd_iu *iu;
 
@@ -1133,7 +1133,7 @@ static blk_status_t rnbd_queue_rq(struct blk_mq_hw_ctx *hctx,
 				   const struct blk_mq_queue_data *bd)
 {
 	struct request *rq = bd->rq;
-	struct rnbd_clt_dev *dev = rq->rq_disk->private_data;
+	struct rnbd_clt_dev *dev = rq->q->disk->private_data;
 	struct rnbd_iu *iu = blk_mq_rq_to_pdu(rq);
 	int err;
 	blk_status_t ret = BLK_STS_IOERR;
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 4d4bb810c2aea..cdd33ab61da85 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -459,7 +459,7 @@ static int __vdc_tx_trigger(struct vdc_port *port)
 
 static int __send_request(struct request *req)
 {
-	struct vdc_port *port = req->rq_disk->private_data;
+	struct vdc_port *port = req->q->disk->private_data;
 	struct vio_dring_state *dr = &port->vio.drings[VIO_DRIVER_TX_RING];
 	struct scatterlist sg[MAX_RING_COOKIES];
 	struct vdc_req_entry *rqe;
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 694aaca4eea24..bf9deeaba7b7f 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -550,7 +550,6 @@ static int multipath_clone_and_map(struct dm_target *ti, struct request *rq,
 		return DM_MAPIO_REQUEUE;
 	}
 	clone->bio = clone->biotail = NULL;
-	clone->rq_disk = bdev->bd_disk;
 	clone->cmd_flags |= REQ_FAILFAST_TRANSPORT;
 	*__clone = clone;
 
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 431af5e8be2f8..835220d34fabf 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -1837,7 +1837,7 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
 	/* Reset if the card is in a bad state */
 	if (!mmc_host_is_spi(mq->card->host) &&
 	    err && mmc_blk_reset(md, card->host, type)) {
-		pr_err("%s: recovery failed!\n", req->rq_disk->disk_name);
+		pr_err("%s: recovery failed!\n", req->q->disk->disk_name);
 		mqrq->retries = MMC_NO_RETRIES;
 		return;
 	}
diff --git a/drivers/nvme/host/fault_inject.c b/drivers/nvme/host/fault_inject.c
index 1352159733b08..83d2e6860d388 100644
--- a/drivers/nvme/host/fault_inject.c
+++ b/drivers/nvme/host/fault_inject.c
@@ -56,7 +56,7 @@ void nvme_fault_inject_fini(struct nvme_fault_inject *fault_inject)
 
 void nvme_should_fail(struct request *req)
 {
-	struct gendisk *disk = req->rq_disk;
+	struct gendisk *disk = req->q->disk;
 	struct nvme_fault_inject *fault_inject = NULL;
 	u16 status;
 
diff --git a/drivers/nvme/host/trace.h b/drivers/nvme/host/trace.h
index 35bac7a254227..b5f85259461a6 100644
--- a/drivers/nvme/host/trace.h
+++ b/drivers/nvme/host/trace.h
@@ -68,7 +68,7 @@ TRACE_EVENT(nvme_setup_cmd,
 		__entry->nsid = le32_to_cpu(cmd->common.nsid);
 		__entry->metadata = !!blk_integrity_rq(req);
 		__entry->fctype = cmd->fabrics.fctype;
-		__assign_disk_name(__entry->disk, req->rq_disk);
+		__assign_disk_name(__entry->disk, req->q->disk);
 		memcpy(__entry->cdw10, &cmd->common.cdw10,
 			sizeof(__entry->cdw10));
 	    ),
@@ -103,7 +103,7 @@ TRACE_EVENT(nvme_complete_rq,
 		__entry->retries = nvme_req(req)->retries;
 		__entry->flags = nvme_req(req)->flags;
 		__entry->status = nvme_req(req)->status;
-		__assign_disk_name(__entry->disk, req->rq_disk);
+		__assign_disk_name(__entry->disk, req->q->disk);
 	    ),
 	    TP_printk("nvme%d: %sqid=%d, cmdid=%u, res=%#llx, retries=%u, flags=0x%x, status=%#x",
 		      __entry->ctrl_id, __print_disk_name(__entry->disk),
@@ -153,7 +153,7 @@ TRACE_EVENT(nvme_sq,
 	),
 	TP_fast_assign(
 		__entry->ctrl_id = nvme_req(req)->ctrl->instance;
-		__assign_disk_name(__entry->disk, req->rq_disk);
+		__assign_disk_name(__entry->disk, req->q->disk);
 		__entry->qid = nvme_req_qid(req);
 		__entry->sq_head = le16_to_cpu(sq_head);
 		__entry->sq_tail = sq_tail;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 33fd9a01330ce..a701d17b16146 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -543,8 +543,9 @@ static bool scsi_end_request(struct request *req, blk_status_t error,
 	if (blk_update_request(req, error, bytes))
 		return true;
 
+	// XXX:
 	if (blk_queue_add_random(q))
-		add_disk_randomness(req->rq_disk);
+		add_disk_randomness(req->q->disk);
 
 	if (!blk_rq_is_passthrough(req)) {
 		WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED));
diff --git a/drivers/scsi/scsi_logging.c b/drivers/scsi/scsi_logging.c
index ed9572252a426..1f8f80b2dbfcb 100644
--- a/drivers/scsi/scsi_logging.c
+++ b/drivers/scsi/scsi_logging.c
@@ -30,7 +30,9 @@ static inline const char *scmd_name(const struct scsi_cmnd *scmd)
 {
 	struct request *rq = scsi_cmd_to_rq((struct scsi_cmnd *)scmd);
 
-	return rq->rq_disk ? rq->rq_disk->disk_name : NULL;
+	if (!rq->q->disk)
+		return NULL;
+	return rq->q->disk->disk_name;
 }
 
 static size_t sdev_format_header(char *logbuf, size_t logbuf_len,
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index d8f6add416c0a..b6846e1fc97fd 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -872,7 +872,7 @@ static blk_status_t sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
 {
 	struct scsi_device *sdp = cmd->device;
 	struct request *rq = scsi_cmd_to_rq(cmd);
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 	u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
 	u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
 	unsigned int data_len = 24;
@@ -908,7 +908,7 @@ static blk_status_t sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd,
 {
 	struct scsi_device *sdp = cmd->device;
 	struct request *rq = scsi_cmd_to_rq(cmd);
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 	u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
 	u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
 	u32 data_len = sdp->sector_size;
@@ -940,7 +940,7 @@ static blk_status_t sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd,
 {
 	struct scsi_device *sdp = cmd->device;
 	struct request *rq = scsi_cmd_to_rq(cmd);
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 	u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
 	u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
 	u32 data_len = sdp->sector_size;
@@ -971,7 +971,7 @@ static blk_status_t sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd)
 {
 	struct request *rq = scsi_cmd_to_rq(cmd);
 	struct scsi_device *sdp = cmd->device;
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 	u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
 	u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
 
@@ -1068,7 +1068,7 @@ static blk_status_t sd_setup_write_same_cmnd(struct scsi_cmnd *cmd)
 {
 	struct request *rq = scsi_cmd_to_rq(cmd);
 	struct scsi_device *sdp = cmd->device;
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 	struct bio *bio = rq->bio;
 	u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
 	u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
@@ -1116,7 +1116,7 @@ static blk_status_t sd_setup_write_same_cmnd(struct scsi_cmnd *cmd)
 static blk_status_t sd_setup_flush_cmnd(struct scsi_cmnd *cmd)
 {
 	struct request *rq = scsi_cmd_to_rq(cmd);
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 
 	/* flush requests don't perform I/O, zero the S/G table */
 	memset(&cmd->sdb, 0, sizeof(cmd->sdb));
@@ -1215,7 +1215,7 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd)
 {
 	struct request *rq = scsi_cmd_to_rq(cmd);
 	struct scsi_device *sdp = cmd->device;
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 	sector_t lba = sectors_to_logical(sdp, blk_rq_pos(rq));
 	sector_t threshold;
 	unsigned int nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
@@ -1236,7 +1236,7 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd)
 		goto fail;
 	}
 
-	if (blk_rq_pos(rq) + blk_rq_sectors(rq) > get_capacity(rq->rq_disk)) {
+	if (blk_rq_pos(rq) + blk_rq_sectors(rq) > get_capacity(rq->q->disk)) {
 		scmd_printk(KERN_ERR, cmd, "access beyond end of device\n");
 		goto fail;
 	}
@@ -1331,7 +1331,7 @@ static blk_status_t sd_init_command(struct scsi_cmnd *cmd)
 
 	switch (req_op(rq)) {
 	case REQ_OP_DISCARD:
-		switch (scsi_disk(rq->rq_disk)->provisioning_mode) {
+		switch (scsi_disk(rq->q->disk)->provisioning_mode) {
 		case SD_LBP_UNMAP:
 			return sd_setup_unmap_cmnd(cmd);
 		case SD_LBP_WS16:
@@ -1878,7 +1878,7 @@ static const struct block_device_operations sd_fops = {
  **/
 static void sd_eh_reset(struct scsi_cmnd *scmd)
 {
-	struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->q->disk);
 
 	/* New SCSI EH run, reset gate variable */
 	sdkp->ignore_medium_access_errors = false;
@@ -1898,7 +1898,7 @@ static void sd_eh_reset(struct scsi_cmnd *scmd)
  **/
 static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp)
 {
-	struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->q->disk);
 	struct scsi_device *sdev = scmd->device;
 
 	if (!scsi_device_online(sdev) ||
@@ -1995,7 +1995,7 @@ static int sd_done(struct scsi_cmnd *SCpnt)
 	unsigned int resid;
 	struct scsi_sense_hdr sshdr;
 	struct request *req = scsi_cmd_to_rq(SCpnt);
-	struct scsi_disk *sdkp = scsi_disk(req->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(req->q->disk);
 	int sense_valid = 0;
 	int sense_deferred = 0;
 
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index ed06798983f87..65bfd1e170da9 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -244,7 +244,7 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector,
 static blk_status_t sd_zbc_cmnd_checks(struct scsi_cmnd *cmd)
 {
 	struct request *rq = scsi_cmd_to_rq(cmd);
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 	sector_t sector = blk_rq_pos(rq);
 
 	if (!sd_is_zoned(sdkp))
@@ -322,7 +322,7 @@ blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba,
 					unsigned int nr_blocks)
 {
 	struct request *rq = scsi_cmd_to_rq(cmd);
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 	unsigned int wp_offset, zno = blk_rq_zone_no(rq);
 	unsigned long flags;
 	blk_status_t ret;
@@ -388,7 +388,7 @@ blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd,
 {
 	struct request *rq = scsi_cmd_to_rq(cmd);
 	sector_t sector = blk_rq_pos(rq);
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 	sector_t block = sectors_to_logical(sdkp->device, sector);
 	blk_status_t ret;
 
@@ -443,7 +443,7 @@ static unsigned int sd_zbc_zone_wp_update(struct scsi_cmnd *cmd,
 {
 	int result = cmd->result;
 	struct request *rq = scsi_cmd_to_rq(cmd);
-	struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
+	struct scsi_disk *sdkp = scsi_disk(rq->q->disk);
 	unsigned int zno = blk_rq_zone_no(rq);
 	enum req_opf op = req_op(rq);
 	unsigned long flags;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 115f7ef7a5def..9cd8152aea5b3 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -335,7 +335,7 @@ static int sr_done(struct scsi_cmnd *SCpnt)
 	int block_sectors = 0;
 	long error_sector;
 	struct request *rq = scsi_cmd_to_rq(SCpnt);
-	struct scsi_cd *cd = scsi_cd(rq->rq_disk);
+	struct scsi_cd *cd = scsi_cd(rq->q->disk);
 
 #ifdef DEBUG
 	scmd_printk(KERN_INFO, SCpnt, "done: %x\n", result);
@@ -402,7 +402,7 @@ static blk_status_t sr_init_command(struct scsi_cmnd *SCpnt)
 	ret = scsi_alloc_sgtables(SCpnt);
 	if (ret != BLK_STS_OK)
 		return ret;
-	cd = scsi_cd(rq->rq_disk);
+	cd = scsi_cd(rq->q->disk);
 
 	SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt,
 		"Doing sr request, block = %d\n", block));
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index 589af5f6b940a..b20a058004eca 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -535,7 +535,6 @@ static int ufshpb_execute_pre_req(struct ufshpb_lu *hpb, struct scsi_cmnd *cmd,
 
 	/* 1. request setup */
 	blk_rq_append_bio(req, bio);
-	req->rq_disk = NULL;
 	req->end_io_data = (void *)pre_req;
 	req->end_io = ufshpb_pre_req_compl_fn;
 
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index b7c69b97f43ab..802c699e282a4 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -528,7 +528,7 @@ static void virtio_scsi_init_hdr_pi(struct virtio_device *vdev,
 	if (!rq || !scsi_prot_sg_count(sc))
 		return;
 
-	bi = blk_get_integrity(rq->rq_disk);
+	bi = blk_get_integrity(rq->q->disk);
 
 	if (sc->sc_data_direction == DMA_TO_DEVICE)
 		cmd_pi->pi_bytesout = cpu_to_virtio32(vdev,
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 4c5a0a49035fc..1928b39182425 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -551,7 +551,7 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb)
 	/* Did this command access the last sector? */
 	sector = (srb->cmnd[2] << 24) | (srb->cmnd[3] << 16) |
 			(srb->cmnd[4] << 8) | (srb->cmnd[5]);
-	disk = scsi_cmd_to_rq(srb)->rq_disk;
+	disk = scsi_cmd_to_rq(srb)->q->disk;
 	if (!disk)
 		goto done;
 	sdkp = scsi_disk(disk);
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index bd4086a6f28e0..bcda9c702d302 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -135,7 +135,6 @@ struct request {
 		} flush;
 	};
 
-	struct gendisk *rq_disk;
 	struct block_device *part;
 #ifdef CONFIG_BLK_RQ_ALLOC_TIME
 	/* Time that the first bio started allocating this request. */
@@ -836,9 +835,6 @@ static inline void blk_rq_bio_prep(struct request *rq, struct bio *bio,
 	rq->__data_len = bio->bi_iter.bi_size;
 	rq->bio = rq->biotail = bio;
 	rq->ioprio = bio_prio(bio);
-
-	if (bio->bi_bdev)
-		rq->rq_disk = bio->bi_bdev->bd_disk;
 }
 
 blk_qc_t blk_mq_submit_bio(struct bio *bio);
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index eaf04c9a1dfcb..f671c62cfe651 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -162,7 +162,7 @@ static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
 {
 	struct request *rq = scsi_cmd_to_rq(cmd);
 
-	return *(struct scsi_driver **)rq->rq_disk->private_data;
+	return *(struct scsi_driver **)rq->q->disk->private_data;
 }
 
 extern void scsi_finish_command(struct scsi_cmnd *cmd);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 430b73bd02ac1..23b848f82337f 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -274,9 +274,9 @@ scmd_printk(const char *, const struct scsi_cmnd *, const char *, ...);
 	do {								\
 		struct request *__rq = scsi_cmd_to_rq((scmd));		\
 									\
-		if (__rq->rq_disk)					\
+		if (__rq->q->disk)					\
 			sdev_dbg((scmd)->device, "[%s] " fmt,		\
-				 __rq->rq_disk->disk_name, ##a);	\
+				 __rq->q->disk->disk_name, ##a);	\
 		else							\
 			sdev_dbg((scmd)->device, fmt, ##a);		\
 	} while (0)
diff --git a/include/trace/events/block.h b/include/trace/events/block.h
index cc5ab96a7471f..e56b8e442f765 100644
--- a/include/trace/events/block.h
+++ b/include/trace/events/block.h
@@ -85,7 +85,7 @@ TRACE_EVENT(block_rq_requeue,
 	),
 
 	TP_fast_assign(
-		__entry->dev	   = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
+		__entry->dev	   = rq->q->disk ? disk_devt(rq->q->disk) : 0;
 		__entry->sector    = blk_rq_trace_sector(rq);
 		__entry->nr_sector = blk_rq_trace_nr_sectors(rq);
 
@@ -128,7 +128,7 @@ TRACE_EVENT(block_rq_complete,
 	),
 
 	TP_fast_assign(
-		__entry->dev	   = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
+		__entry->dev	   = rq->q->disk ? disk_devt(rq->q->disk) : 0;
 		__entry->sector    = blk_rq_pos(rq);
 		__entry->nr_sector = nr_bytes >> 9;
 		__entry->error     = error;
@@ -161,7 +161,7 @@ DECLARE_EVENT_CLASS(block_rq,
 	),
 
 	TP_fast_assign(
-		__entry->dev	   = rq->rq_disk ? disk_devt(rq->rq_disk) : 0;
+		__entry->dev	   = rq->q->disk ? disk_devt(rq->q->disk) : 0;
 		__entry->sector    = blk_rq_trace_sector(rq);
 		__entry->nr_sector = blk_rq_trace_nr_sectors(rq);
 		__entry->bytes     = blk_rq_bytes(rq);
@@ -512,7 +512,7 @@ TRACE_EVENT(block_rq_remap,
 	),
 
 	TP_fast_assign(
-		__entry->dev		= disk_devt(rq->rq_disk);
+		__entry->dev		= disk_devt(rq->q->disk);
 		__entry->sector		= blk_rq_pos(rq);
 		__entry->nr_sector	= blk_rq_sectors(rq);
 		__entry->old_dev	= dev;
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index fa91f398f28b7..0f3ec8df5a348 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -1044,7 +1044,7 @@ static void blk_add_trace_rq_remap(void *ignore, struct request *rq, dev_t dev,
 	}
 
 	r.device_from = cpu_to_be32(dev);
-	r.device_to   = cpu_to_be32(disk_devt(rq->rq_disk));
+	r.device_to   = cpu_to_be32(disk_devt(rq->q->disk));
 	r.sector_from = cpu_to_be64(from);
 
 	__blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
-- 
2.30.2



From hch at lst.de  Mon Sep 27 22:22:10 2021
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 28 Sep 2021 07:22:10 +0200
Subject: [PATCH 4/5] block: remove the gendisk argument to blk_execute_rq
In-Reply-To: <20210928052211.112801-1-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
Message-ID: <20210928052211.112801-5-hch@lst.de>

Remove the gendisk aregument to blk_execute_rq and blk_execute_rq_nowait
given that it is unused now.  Also convert the boolean at_head parameter
to actually use the bool type while touching the prototype.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 block/blk-exec.c                   |  9 +++------
 block/bsg-lib.c                    |  2 +-
 drivers/block/mtip32xx/mtip32xx.c  |  2 +-
 drivers/block/paride/pd.c          |  2 +-
 drivers/block/pktcdvd.c            |  2 +-
 drivers/block/sx8.c                |  4 ++--
 drivers/block/virtio_blk.c         |  2 +-
 drivers/mmc/core/block.c           | 10 +++++-----
 drivers/nvme/host/core.c           |  4 ++--
 drivers/nvme/host/pci.c            |  7 +++----
 drivers/nvme/target/passthru.c     |  3 +--
 drivers/scsi/scsi_bsg.c            |  2 +-
 drivers/scsi/scsi_error.c          |  2 +-
 drivers/scsi/scsi_ioctl.c          |  4 ++--
 drivers/scsi/scsi_lib.c            |  2 +-
 drivers/scsi/sg.c                  |  2 +-
 drivers/scsi/sr.c                  |  2 +-
 drivers/scsi/st.c                  |  2 +-
 drivers/scsi/ufs/ufshcd.c          |  3 +--
 drivers/scsi/ufs/ufshpb.c          |  4 ++--
 drivers/target/target_core_pscsi.c |  2 +-
 fs/nfsd/blocklayout.c              |  2 +-
 include/linux/blk-mq.h             |  7 +++----
 23 files changed, 37 insertions(+), 44 deletions(-)

diff --git a/block/blk-exec.c b/block/blk-exec.c
index 9832655bd2662..60a4939b1ef03 100644
--- a/block/blk-exec.c
+++ b/block/blk-exec.c
@@ -32,7 +32,6 @@ static void blk_end_sync_rq(struct request *rq, blk_status_t error)
 
 /**
  * blk_execute_rq_nowait - insert a request to I/O scheduler for execution
- * @bd_disk:	unused
  * @rq:		request to insert
  * @at_head:    insert request at head or tail of queue
  * @done:	I/O completion handler
@@ -44,8 +43,7 @@ static void blk_end_sync_rq(struct request *rq, blk_status_t error)
  * Note:
  *    This function will invoke @done directly if the queue is dead.
  */
-void blk_execute_rq_nowait(struct gendisk *bd_disk, struct request *rq,
-			   int at_head, rq_end_io_fn *done)
+void blk_execute_rq_nowait(struct request *rq, bool at_head, rq_end_io_fn *done)
 {
 	WARN_ON(irqs_disabled());
 	WARN_ON(!blk_rq_is_passthrough(rq));
@@ -77,7 +75,6 @@ static void blk_rq_poll_completion(struct request *rq, struct completion *wait)
 
 /**
  * blk_execute_rq - insert a request into queue for execution
- * @bd_disk:	unused
  * @rq:		request to insert
  * @at_head:    insert request at head or tail of queue
  *
@@ -86,13 +83,13 @@ static void blk_rq_poll_completion(struct request *rq, struct completion *wait)
  *    for execution and wait for completion.
  * Return: The blk_status_t result provided to blk_mq_end_request().
  */
-blk_status_t blk_execute_rq(struct gendisk *bd_disk, struct request *rq, int at_head)
+blk_status_t blk_execute_rq(struct request *rq, bool at_head)
 {
 	DECLARE_COMPLETION_ONSTACK(wait);
 	unsigned long hang_check;
 
 	rq->end_io_data = &wait;
-	blk_execute_rq_nowait(bd_disk, rq, at_head, blk_end_sync_rq);
+	blk_execute_rq_nowait(rq, at_head, blk_end_sync_rq);
 
 	/* Prevent hang_check timer from firing at us during very long I/O */
 	hang_check = sysctl_hung_task_timeout_secs;
diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index ccb98276c964a..b7d37509606a5 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -85,7 +85,7 @@ static int bsg_transport_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
 		goto out_unmap_bidi_rq;
 
 	bio = rq->bio;
-	blk_execute_rq(NULL, rq, !(hdr->flags & BSG_FLAG_Q_AT_TAIL));
+	blk_execute_rq(rq, !(hdr->flags & BSG_FLAG_Q_AT_TAIL));
 
 	/*
 	 * The assignments below don't make much sense, but are kept for
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 901855717cb53..f15c5ddd2a8df 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -1015,7 +1015,7 @@ static int mtip_exec_internal_command(struct mtip_port *port,
 	rq->timeout = timeout;
 
 	/* insert request and run queue */
-	blk_execute_rq(NULL, rq, true);
+	blk_execute_rq(rq, true);
 
 	if (int_cmd->status) {
 		dev_err(&dd->pdev->dev, "Internal command [%02X] failed %d\n",
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index ab9d336d7b79c..4a1a24761affe 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -781,7 +781,7 @@ static int pd_special_command(struct pd_unit *disk,
 	req = blk_mq_rq_to_pdu(rq);
 
 	req->func = func;
-	blk_execute_rq(disk->gd, rq, 0);
+	blk_execute_rq(rq, false);
 	blk_put_request(rq);
 	return 0;
 }
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 0f26b2510a756..3c99e0992deb6 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -722,7 +722,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
 	if (cgc->quiet)
 		rq->rq_flags |= RQF_QUIET;
 
-	blk_execute_rq(pd->bdev->bd_disk, rq, 0);
+	blk_execute_rq(rq, false);
 	if (scsi_req(rq)->result)
 		ret = -EIO;
 out:
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 420cd952ddc4b..2fcbca777a4b5 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -539,7 +539,7 @@ static int carm_array_info (struct carm_host *host, unsigned int array_idx)
 	spin_unlock_irq(&host->lock);
 
 	DPRINTK("blk_execute_rq_nowait, tag == %u\n", rq->tag);
-	blk_execute_rq_nowait(NULL, rq, true, NULL);
+	blk_execute_rq_nowait(rq, true, NULL);
 
 	return 0;
 
@@ -578,7 +578,7 @@ static int carm_send_special (struct carm_host *host, carm_sspc_t func)
 	crq->msg_bucket = (u32) rc;
 
 	DPRINTK("blk_execute_rq_nowait, tag == %u\n", rq->tag);
-	blk_execute_rq_nowait(NULL, rq, true, NULL);
+	blk_execute_rq_nowait(rq, true, NULL);
 
 	return 0;
 }
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 9b3bd083b411f..06efeb7d5156d 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -320,7 +320,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str)
 	if (err)
 		goto out;
 
-	blk_execute_rq(vblk->disk, req, false);
+	blk_execute_rq(req, false);
 	err = blk_status_to_errno(virtblk_result(blk_mq_rq_to_pdu(req)));
 out:
 	blk_put_request(req);
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 835220d34fabf..a91908d36c01d 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -264,7 +264,7 @@ static ssize_t power_ro_lock_store(struct device *dev,
 		goto out_put;
 	}
 	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_BOOT_WP;
-	blk_execute_rq(NULL, req, 0);
+	blk_execute_rq(req, false);
 	ret = req_to_mmc_queue_req(req)->drv_op_result;
 	blk_put_request(req);
 
@@ -657,7 +657,7 @@ static int mmc_blk_ioctl_cmd(struct mmc_blk_data *md,
 		rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;
 	req_to_mmc_queue_req(req)->drv_op_data = idatas;
 	req_to_mmc_queue_req(req)->ioc_count = 1;
-	blk_execute_rq(NULL, req, 0);
+	blk_execute_rq(req, false);
 	ioc_err = req_to_mmc_queue_req(req)->drv_op_result;
 	err = mmc_blk_ioctl_copy_to_user(ic_ptr, idata);
 	blk_put_request(req);
@@ -726,7 +726,7 @@ static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md,
 		rpmb ? MMC_DRV_OP_IOCTL_RPMB : MMC_DRV_OP_IOCTL;
 	req_to_mmc_queue_req(req)->drv_op_data = idata;
 	req_to_mmc_queue_req(req)->ioc_count = num_of_cmds;
-	blk_execute_rq(NULL, req, 0);
+	blk_execute_rq(req, false);
 	ioc_err = req_to_mmc_queue_req(req)->drv_op_result;
 
 	/* copy to user if data and response */
@@ -2734,7 +2734,7 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)
 	if (IS_ERR(req))
 		return PTR_ERR(req);
 	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_CARD_STATUS;
-	blk_execute_rq(NULL, req, 0);
+	blk_execute_rq(req, false);
 	ret = req_to_mmc_queue_req(req)->drv_op_result;
 	if (ret >= 0) {
 		*val = ret;
@@ -2773,7 +2773,7 @@ static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
 	}
 	req_to_mmc_queue_req(req)->drv_op = MMC_DRV_OP_GET_EXT_CSD;
 	req_to_mmc_queue_req(req)->drv_op_data = &ext_csd;
-	blk_execute_rq(NULL, req, 0);
+	blk_execute_rq(req, false);
 	err = req_to_mmc_queue_req(req)->drv_op_result;
 	blk_put_request(req);
 	if (err) {
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 7fa75433c0361..b2c4d2c4c92f4 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1045,7 +1045,7 @@ static int nvme_execute_rq(struct gendisk *disk, struct request *rq,
 {
 	blk_status_t status;
 
-	status = blk_execute_rq(disk, rq, at_head);
+	status = blk_execute_rq(rq, at_head);
 	if (nvme_req(rq)->flags & NVME_REQ_CANCELLED)
 		return -EINTR;
 	if (nvme_req(rq)->status)
@@ -1272,7 +1272,7 @@ static void nvme_keep_alive_work(struct work_struct *work)
 
 	rq->timeout = ctrl->kato * HZ;
 	rq->end_io_data = ctrl;
-	blk_execute_rq_nowait(NULL, rq, 0, nvme_keep_alive_end_io);
+	blk_execute_rq_nowait(rq, false, nvme_keep_alive_end_io);
 }
 
 static void nvme_start_keep_alive(struct nvme_ctrl *ctrl)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index ca5bda26226ae..331667f54e91e 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1346,7 +1346,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
 	}
 
 	abort_req->end_io_data = NULL;
-	blk_execute_rq_nowait(NULL, abort_req, 0, abort_endio);
+	blk_execute_rq_nowait(abort_req, false, abort_endio);
 
 	/*
 	 * The aborted req will be completed on receiving the abort req.
@@ -2391,9 +2391,8 @@ static int nvme_delete_queue(struct nvme_queue *nvmeq, u8 opcode)
 	req->end_io_data = nvmeq;
 
 	init_completion(&nvmeq->delete_done);
-	blk_execute_rq_nowait(NULL, req, false,
-			opcode == nvme_admin_delete_cq ?
-				nvme_del_cq_end : nvme_del_queue_end);
+	blk_execute_rq_nowait(req, false, opcode == nvme_admin_delete_cq ?
+			nvme_del_cq_end : nvme_del_queue_end);
 	return 0;
 }
 
diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c
index f0efb35379898..9e5b89ae29dfe 100644
--- a/drivers/nvme/target/passthru.c
+++ b/drivers/nvme/target/passthru.c
@@ -284,8 +284,7 @@ static void nvmet_passthru_execute_cmd(struct nvmet_req *req)
 		schedule_work(&req->p.work);
 	} else {
 		rq->end_io_data = req;
-		blk_execute_rq_nowait(ns ? ns->disk : NULL, rq, 0,
-				      nvmet_passthru_req_done);
+		blk_execute_rq_nowait(rq, false, nvmet_passthru_req_done);
 	}
 
 	if (ns)
diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index 81c3853a2a800..b67675a139e87 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -60,7 +60,7 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
 		goto out_free_cmd;
 
 	bio = rq->bio;
-	blk_execute_rq(NULL, rq, !(hdr->flags & BSG_FLAG_Q_AT_TAIL));
+	blk_execute_rq(rq, !(hdr->flags & BSG_FLAG_Q_AT_TAIL));
 
 	/*
 	 * fill in all the output members
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index b6c86cce57bfa..a41bb1eef8633 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -2015,7 +2015,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
 	req->timeout = 10 * HZ;
 	rq->retries = 5;
 
-	blk_execute_rq_nowait(NULL, req, 1, eh_lock_door_done);
+	blk_execute_rq_nowait(req, true, eh_lock_door_done);
 }
 
 /**
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 6ff2207bd45a0..4a93f2c1d1afb 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -481,7 +481,7 @@ static int sg_io(struct scsi_device *sdev, struct gendisk *disk,
 
 	start_time = jiffies;
 
-	blk_execute_rq(disk, rq, at_head);
+	blk_execute_rq(rq, at_head);
 
 	hdr->duration = jiffies_to_msecs(jiffies - start_time);
 
@@ -618,7 +618,7 @@ static int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk,
 			goto error;
 	}
 
-	blk_execute_rq(disk, rq, 0);
+	blk_execute_rq(rq, false);
 
 	err = req->result & 0xff;	/* only 8 bit SCSI status */
 	if (err) {
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index a701d17b16146..9352799d729b0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -241,7 +241,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
 	/*
 	 * head injection *required* here otherwise quiesce won't work
 	 */
-	blk_execute_rq(NULL, req, 1);
+	blk_execute_rq(req, true);
 
 	/*
 	 * Some devices (USB mass-storage in particular) may transfer
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 3c98f08dc25d9..24196ea7e0d76 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -833,7 +833,7 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp,
 
 	srp->rq->timeout = timeout;
 	kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */
-	blk_execute_rq_nowait(NULL, srp->rq, at_head, sg_rq_end_io);
+	blk_execute_rq_nowait(srp->rq, at_head, sg_rq_end_io);
 	return 0;
 }
 
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 9cd8152aea5b3..eddb153a536d7 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -990,7 +990,7 @@ static int sr_read_cdda_bpc(struct cdrom_device_info *cdi, void __user *ubuf,
 	rq->timeout = 60 * HZ;
 	bio = rq->bio;
 
-	blk_execute_rq(disk, rq, 0);
+	blk_execute_rq(rq, false);
 	if (scsi_req(rq)->result) {
 		struct scsi_sense_hdr sshdr;
 
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 9933722acfd96..1d2855fe5faf8 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -581,7 +581,7 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
 	rq->retries = retries;
 	req->end_io_data = SRpnt;
 
-	blk_execute_rq_nowait(NULL, req, 1, st_scsi_execute_end);
+	blk_execute_rq_nowait(req, true, st_scsi_execute_end);
 	return 0;
 }
 
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 029c9631ec2bf..e2d7cd70a9ddc 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7967,8 +7967,7 @@ ufshcd_request_sense_async(struct ufs_hba *hba, struct scsi_device *sdev)
 	req->rq_flags |= RQF_PM | RQF_QUIET;
 	req->end_io_data = buffer;
 
-	blk_execute_rq_nowait(/*bd_disk=*/NULL, req, /*at_head=*/true,
-			      ufshcd_request_sense_done);
+	blk_execute_rq_nowait(req, true, ufshcd_request_sense_done);
 	return 0;
 
 out_put:
diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
index b20a058004eca..a3c56787f8f25 100644
--- a/drivers/scsi/ufs/ufshpb.c
+++ b/drivers/scsi/ufs/ufshpb.c
@@ -950,7 +950,7 @@ static void ufshpb_execute_umap_req(struct ufshpb_lu *hpb,
 	ufshpb_set_unmap_cmd(rq->cmd, rgn);
 	rq->cmd_len = HPB_WRITE_BUFFER_CMD_LENGTH;
 
-	blk_execute_rq_nowait(NULL, req, 1, ufshpb_umap_req_compl_fn);
+	blk_execute_rq_nowait(req, true, ufshpb_umap_req_compl_fn);
 
 	hpb->stats.umap_req_cnt++;
 }
@@ -992,7 +992,7 @@ static int ufshpb_execute_map_req(struct ufshpb_lu *hpb,
 				map_req->rb.srgn_idx, mem_size);
 	rq->cmd_len = HPB_READ_BUFFER_CMD_LENGTH;
 
-	blk_execute_rq_nowait(NULL, req, 1, ufshpb_map_req_compl_fn);
+	blk_execute_rq_nowait(req, true, ufshpb_map_req_compl_fn);
 
 	hpb->stats.map_req_cnt++;
 	return 0;
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 75ef52f008ff6..3722464f323fc 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -1006,7 +1006,7 @@ pscsi_execute_cmd(struct se_cmd *cmd)
 		req->timeout = PS_TIMEOUT_OTHER;
 	scsi_req(req)->retries = PS_RETRY;
 
-	blk_execute_rq_nowait(NULL, req, (cmd->sam_task_attr == TCM_HEAD_TAG),
+	blk_execute_rq_nowait(req, cmd->sam_task_attr == TCM_HEAD_TAG,
 			pscsi_req_done);
 
 	return 0;
diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c
index c99dee99a3c15..dc021afe14340 100644
--- a/fs/nfsd/blocklayout.c
+++ b/fs/nfsd/blocklayout.c
@@ -254,7 +254,7 @@ static int nfsd4_scsi_identify_device(struct block_device *bdev,
 	req->cmd[4] = bufflen & 0xff;
 	req->cmd_len = COMMAND_SIZE(INQUIRY);
 
-	blk_execute_rq(NULL, rq, 1);
+	blk_execute_rq(rq, true);
 	if (req->result) {
 		pr_err("pNFS: INQUIRY 0x83 failed with: %x\n",
 			req->result);
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index bcda9c702d302..68f2efa65d906 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -874,10 +874,9 @@ int blk_rq_unmap_user(struct bio *);
 int blk_rq_map_kern(struct request_queue *, struct request *, void *,
 		unsigned int, gfp_t);
 int blk_rq_append_bio(struct request *rq, struct bio *bio);
-void blk_execute_rq_nowait(struct gendisk *, struct request *, int,
-		rq_end_io_fn *);
-blk_status_t blk_execute_rq(struct gendisk *bd_disk, struct request *rq,
-		int at_head);
+void blk_execute_rq_nowait(struct request *rq, bool at_head,
+		rq_end_io_fn *end_io);
+blk_status_t blk_execute_rq(struct request *rq, bool at_head);
 
 struct req_iterator {
 	struct bvec_iter iter;
-- 
2.30.2



From hch at lst.de  Mon Sep 27 22:22:11 2021
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 28 Sep 2021 07:22:11 +0200
Subject: [PATCH 5/5] scsi: remove the gendisk argument to scsi_ioctl
In-Reply-To: <20210928052211.112801-1-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
Message-ID: <20210928052211.112801-6-hch@lst.de>

Now that blk_execute_rq does not take a gendisk argument there is no need
to pass it through the scsi_ioctl callchain either.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 drivers/scsi/ch.c         |  2 +-
 drivers/scsi/scsi_ioctl.c | 39 +++++++++++++++------------------------
 drivers/scsi/sd.c         |  2 +-
 drivers/scsi/sg.c         |  4 ++--
 drivers/scsi/sr.c         |  5 ++---
 drivers/scsi/st.c         |  2 +-
 include/scsi/scsi_ioctl.h |  4 ++--
 7 files changed, 24 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 27012908b5861..6fa300daa31ea 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -877,7 +877,7 @@ static long ch_ioctl(struct file *file,
 	}
 
 	default:
-		return scsi_ioctl(ch->device, NULL, file->f_mode, cmd, argp);
+		return scsi_ioctl(ch->device, file->f_mode, cmd, argp);
 
 	}
 }
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 4a93f2c1d1afb..77201af00f670 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -406,8 +406,7 @@ static int scsi_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
 	return ret;
 }
 
-static int sg_io(struct scsi_device *sdev, struct gendisk *disk,
-		struct sg_io_hdr *hdr, fmode_t mode)
+static int sg_io(struct scsi_device *sdev, struct sg_io_hdr *hdr, fmode_t mode)
 {
 	unsigned long start_time;
 	ssize_t ret = 0;
@@ -497,19 +496,12 @@ static int sg_io(struct scsi_device *sdev, struct gendisk *disk,
 /**
  * sg_scsi_ioctl  --  handle deprecated SCSI_IOCTL_SEND_COMMAND ioctl
  * @q:		request queue to send scsi commands down
- * @disk:	gendisk to operate on (option)
  * @mode:	mode used to open the file through which the ioctl has been
  *		submitted
  * @sic:	userspace structure describing the command to perform
  *
  * Send down the scsi command described by @sic to the device below
- * the request queue @q.  If @file is non-NULL it's used to perform
- * fine-grained permission checks that allow users to send down
- * non-destructive SCSI commands.  If the caller has a struct gendisk
- * available it should be passed in as @disk to allow the low level
- * driver to use the information contained in it.  A non-NULL @disk
- * is only allowed if the caller knows that the low level driver doesn't
- * need it (e.g. in the scsi subsystem).
+ * the request queue @q.
  *
  * Notes:
  *   -  This interface is deprecated - users should use the SG_IO
@@ -528,8 +520,8 @@ static int sg_io(struct scsi_device *sdev, struct gendisk *disk,
  *      Positive numbers returned are the compacted SCSI error codes (4
  *      bytes in one int) where the lowest byte is the SCSI status.
  */
-static int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk,
-		fmode_t mode, struct scsi_ioctl_command __user *sic)
+static int sg_scsi_ioctl(struct request_queue *q, fmode_t mode,
+		struct scsi_ioctl_command __user *sic)
 {
 	enum { OMAX_SB_LEN = 16 };	/* For backward compatibility */
 	struct request *rq;
@@ -804,8 +796,8 @@ static int scsi_put_cdrom_generic_arg(const struct cdrom_generic_command *cgc,
 	return 0;
 }
 
-static int scsi_cdrom_send_packet(struct scsi_device *sdev, struct gendisk *disk,
-		fmode_t mode, void __user *arg)
+static int scsi_cdrom_send_packet(struct scsi_device *sdev, fmode_t mode,
+		void __user *arg)
 {
 	struct cdrom_generic_command cgc;
 	struct sg_io_hdr hdr;
@@ -845,7 +837,7 @@ static int scsi_cdrom_send_packet(struct scsi_device *sdev, struct gendisk *disk
 	hdr.cmdp = ((struct cdrom_generic_command __user *) arg)->cmd;
 	hdr.cmd_len = sizeof(cgc.cmd);
 
-	err = sg_io(sdev, disk, &hdr, mode);
+	err = sg_io(sdev, &hdr, mode);
 	if (err == -EFAULT)
 		return -EFAULT;
 
@@ -860,8 +852,8 @@ static int scsi_cdrom_send_packet(struct scsi_device *sdev, struct gendisk *disk
 	return err;
 }
 
-static int scsi_ioctl_sg_io(struct scsi_device *sdev, struct gendisk *disk,
-		fmode_t mode, void __user *argp)
+static int scsi_ioctl_sg_io(struct scsi_device *sdev, fmode_t mode,
+		void __user *argp)
 {
 	struct sg_io_hdr hdr;
 	int error;
@@ -869,7 +861,7 @@ static int scsi_ioctl_sg_io(struct scsi_device *sdev, struct gendisk *disk,
 	error = get_sg_io_hdr(&hdr, argp);
 	if (error)
 		return error;
-	error = sg_io(sdev, disk, &hdr, mode);
+	error = sg_io(sdev, &hdr, mode);
 	if (error == -EFAULT)
 		return error;
 	if (put_sg_io_hdr(&hdr, argp))
@@ -880,7 +872,6 @@ static int scsi_ioctl_sg_io(struct scsi_device *sdev, struct gendisk *disk,
 /**
  * scsi_ioctl - Dispatch ioctl to scsi device
  * @sdev: scsi device receiving ioctl
- * @disk: disk receiving the ioctl
  * @mode: mode the block/char device is opened with
  * @cmd: which ioctl is it
  * @arg: data associated with ioctl
@@ -889,8 +880,8 @@ static int scsi_ioctl_sg_io(struct scsi_device *sdev, struct gendisk *disk,
  * does not take a major/minor number as the dev field.  Rather, it takes
  * a pointer to a &struct scsi_device.
  */
-int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode,
-		int cmd, void __user *arg)
+int scsi_ioctl(struct scsi_device *sdev, fmode_t mode, int cmd,
+		void __user *arg)
 {
 	struct request_queue *q = sdev->request_queue;
 	struct scsi_sense_hdr sense_hdr;
@@ -925,11 +916,11 @@ int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode,
 	case SG_EMULATED_HOST:
 		return sg_emulated_host(q, arg);
 	case SG_IO:
-		return scsi_ioctl_sg_io(sdev, disk, mode, arg);
+		return scsi_ioctl_sg_io(sdev, mode, arg);
 	case SCSI_IOCTL_SEND_COMMAND:
-		return sg_scsi_ioctl(q, disk, mode, arg);
+		return sg_scsi_ioctl(q, mode, arg);
 	case CDROM_SEND_PACKET:
-		return scsi_cdrom_send_packet(sdev, disk, mode, arg);
+		return scsi_cdrom_send_packet(sdev, mode, arg);
 	case CDROMCLOSETRAY:
 		return scsi_send_start_stop(sdev, 3);
 	case CDROMEJECT:
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b6846e1fc97fd..171e098f3816e 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1574,7 +1574,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
 
 	if (is_sed_ioctl(cmd))
 		return sed_ioctl(sdkp->opal_dev, cmd, p);
-	return scsi_ioctl(sdp, disk, mode, cmd, p);
+	return scsi_ioctl(sdp, mode, cmd, p);
 }
 
 static void set_media_not_present(struct scsi_disk *sdkp)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 24196ea7e0d76..d2c9035443d9f 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1109,7 +1109,7 @@ sg_ioctl_common(struct file *filp, Sg_device *sdp, Sg_fd *sfp,
 	case SCSI_IOCTL_SEND_COMMAND:
 		if (atomic_read(&sdp->detaching))
 			return -ENODEV;
-		return scsi_ioctl(sdp->device, NULL, filp->f_mode, cmd_in, p);
+		return scsi_ioctl(sdp->device, filp->f_mode, cmd_in, p);
 	case SG_SET_DEBUG:
 		result = get_user(val, ip);
 		if (result)
@@ -1165,7 +1165,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
 	ret = sg_ioctl_common(filp, sdp, sfp, cmd_in, p);
 	if (ret != -ENOIOCTLCMD)
 		return ret;
-	return scsi_ioctl(sdp->device, NULL, filp->f_mode, cmd_in, p);
+	return scsi_ioctl(sdp->device, filp->f_mode, cmd_in, p);
 }
 
 static __poll_t
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index eddb153a536d7..73ac5ad368234 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -561,8 +561,7 @@ static void sr_block_release(struct gendisk *disk, fmode_t mode)
 static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 			  unsigned long arg)
 {
-	struct gendisk *disk = bdev->bd_disk;
-	struct scsi_cd *cd = scsi_cd(disk);
+	struct scsi_cd *cd = scsi_cd(bdev->bd_disk);
 	struct scsi_device *sdev = cd->device;
 	void __user *argp = (void __user *)arg;
 	int ret;
@@ -584,7 +583,7 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 		if (ret != -ENOSYS)
 			goto put;
 	}
-	ret = scsi_ioctl(sdev, disk, mode, cmd, argp);
+	ret = scsi_ioctl(sdev, mode, cmd, argp);
 
 put:
 	scsi_autopm_put_device(sdev);
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 1d2855fe5faf8..8c87cb9395699 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3829,7 +3829,7 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg)
 		break;
 	}
 
-	retval = scsi_ioctl(STp->device, NULL, file->f_mode, cmd_in, p);
+	retval = scsi_ioctl(STp->device, file->f_mode, cmd_in, p);
 	if (!retval && cmd_in == SCSI_IOCTL_STOP_UNIT) {
 		/* unload */
 		STp->rew_at_close = 0;
diff --git a/include/scsi/scsi_ioctl.h b/include/scsi/scsi_ioctl.h
index d2cb9aeaf1f16..beac64e38b874 100644
--- a/include/scsi/scsi_ioctl.h
+++ b/include/scsi/scsi_ioctl.h
@@ -45,8 +45,8 @@ typedef struct scsi_fctargaddress {
 
 int scsi_ioctl_block_when_processing_errors(struct scsi_device *sdev,
 		int cmd, bool ndelay);
-int scsi_ioctl(struct scsi_device *sdev, struct gendisk *disk, fmode_t mode,
-		int cmd, void __user *arg);
+int scsi_ioctl(struct scsi_device *sdev, fmode_t mode, int cmd,
+		void __user *arg);
 int get_sg_io_hdr(struct sg_io_hdr *hdr, const void __user *argp);
 int put_sg_io_hdr(const struct sg_io_hdr *hdr, void __user *argp);
 bool scsi_cmd_allowed(unsigned char *cmd, fmode_t mode);
-- 
2.30.2



From arnd at kernel.org  Tue Sep 28 00:21:07 2021
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 28 Sep 2021 09:21:07 +0200
Subject: [PATCH] [RFC] mtd: fixup CFI on ixp4xx
In-Reply-To: <CACRpkdbirEZiKQxSWSsiwwvpui5Pw6vON-C-=BLJei0s8znLxg@mail.gmail.com>
References: <20210927141045.1597593-1-arnd@kernel.org>
 <CACRpkdbirEZiKQxSWSsiwwvpui5Pw6vON-C-=BLJei0s8znLxg@mail.gmail.com>
Message-ID: <CAK8P3a1=u+iUXshuGu72N63ME5cD4PX_H2C1+rtTOEtN_rdddg@mail.gmail.com>

On Tue, Sep 28, 2021 at 1:28 AM Linus Walleij <linus.walleij at linaro.org> wrote:
> On Mon, Sep 27, 2021 at 4:10 PM Arnd Bergmann <arnd at kernel.org> wrote:

> > Any other ideas for how to address it?
>
> We will "soon" have IXP4xx transitioned to device tree and then
> physmap-ixp4xx.c is used instead, and this entire driver can be
> deleted. I will get there, we just need to remember to mop of cruft
> like this at the end of it.

Ah, perfect. In that case I'm not worried about my patch doing anything
wrong at all, and we can just backport that to stable kernels after it's
merged, while future kernels will won't even need it.

      Arnd


From hca at linux.ibm.com  Tue Sep 28 01:44:14 2021
From: hca at linux.ibm.com (Heiko Carstens)
Date: Tue, 28 Sep 2021 10:44:14 +0200
Subject: [PATCH v2 0/6] block: 5th batch of add_disk() error handling
 conversions
In-Reply-To: <25afa23b-52af-9b79-8bd8-5e31da62c291@kernel.dk>
References: <20210927220232.1071926-1-mcgrof@kernel.org>
 <25afa23b-52af-9b79-8bd8-5e31da62c291@kernel.dk>
Message-ID: <YVLV3s66GVVSQ+tj@osiris>

On Mon, Sep 27, 2021 at 04:32:17PM -0600, Jens Axboe wrote:
> On 9/27/21 4:02 PM, Luis Chamberlain wrote:
> > This is the 5th series of driver conversions for add_disk() error
> > handling. This set along with the entire 7th set of patches can be
> > found on my 20210927-for-axboe-add-disk-error-handling branch [0].
> 
> Applied 1-2.

Hmm.. naturally I would have expected that the dasd patch also would
go via block tree. But let's not spend too much time figuring out what
gets routed where.
Applied 4-6. Thanks!


From miquel.raynal at bootlin.com  Tue Sep 28 01:49:14 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 28 Sep 2021 10:49:14 +0200
Subject: [PATCH v2] mtd: rawnand: xway: No hardcoded ECC engine, use
 device tree setting
In-Reply-To: <f800c48f-8e4a-ecdc-3198-c52be0425823@3e8.eu>
References: <20210808072643.GA5084@ubuntu>
 <51f2ebf4-6df1-eba5-99f1-1ec88e475d20@3e8.eu>
 <20210917190154.76203a9a@xps13>
 <e9dd0653-139f-749b-c088-e756ee2d2132@3e8.eu>
 <20210917213246.319e60cb@xps13>
 <14eb0cb7-b0af-87bf-b9a5-3e35eeb43f54@3e8.eu>
 <20210927183150.4be87140@xps13>
 <f800c48f-8e4a-ecdc-3198-c52be0425823@3e8.eu>
Message-ID: <20210928104914.44a90b63@xps13>

Hi Jan,

jan at 3e8.eu wrote on Mon, 27 Sep 2021 22:32:13 +0200:

> Hi Miqu?l,
> 
> > So what I propose is:
> > - in the driver probe: set the default to software ECC
> > - in the attach() hook: drop the line setting the engine_type to SOFT.
> > 
> > Please check the below diff and tell me if it works for you. I'll then
> > propose a wider series fixing the other drivers as well.  
> 
> I can confirm that your patch fixes the issue.
> 
> I tested using kernel 5.10 on a Fritzbox 7362 SL (with on-die ECC
> configured via device tree which was broken before). I also checked on
> a Fritzbox 7412 (this device uses software ECC). Both are working with
> this patch.

Great, thanks for the quick feedback.

Cheers,
Miqu?l


From miquel.raynal at bootlin.com  Tue Sep 28 01:51:33 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 28 Sep 2021 10:51:33 +0200
Subject: [PATCH 1/5] mtd_blkdevs: remove the sector out of range check
 in do_blktrans_request
In-Reply-To: <20210928052211.112801-2-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
 <20210928052211.112801-2-hch@lst.de>
Message-ID: <20210928105133.606b6eed@xps13>

Hi Christoph,

hch at lst.de wrote on Tue, 28 Sep 2021 07:22:07 +0200:

> The block layer already performs this check, no need to duplicate it in
> the driver.
> 
> Signed-off-by: Christoph Hellwig <hch at lst.de>

Reviewed-by: Miquel Raynal <miquel.raynal at bootlin.com>

Thanks,
Miqu?l


From mdalam at codeaurora.org  Tue Sep 28 05:17:27 2021
From: mdalam at codeaurora.org (mdalam at codeaurora.org)
Date: Tue, 28 Sep 2021 17:47:27 +0530
Subject: [PATCH 1/3] mtd: rawnand: qcom: Add support for status pipe
In-Reply-To: <1631699851-12172-2-git-send-email-mdalam@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
 <1631699851-12172-2-git-send-email-mdalam@codeaurora.org>
Message-ID: <97df48e5505c4e6ae3bc6b7e953c156c@codeaurora.org>

On 2021-09-15 15:27, Md Sadre Alam wrote:
> From QPIC V2.0 onwards there is a separate pipe
> to read status of each code word, called "status" pipe.
> 
> "status" pipe will use to read CW status in case of
> enhanced read mode like page scope read, multi page read.
> 
> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> ---
>  drivers/mtd/nand/raw/qcom_nandc.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c
> b/drivers/mtd/nand/raw/qcom_nandc.c
> index 04e6f7b..42c6291 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -389,6 +389,7 @@ struct qcom_nand_controller {
>  			struct dma_chan *tx_chan;
>  			struct dma_chan *rx_chan;
>  			struct dma_chan *cmd_chan;
> +			struct dma_chan *sts_chan;
>  		};
> 
>  		/* will be used only by EBI2 for ADM DMA */
> @@ -2737,6 +2738,11 @@ static void qcom_nandc_unalloc(struct
> qcom_nand_controller *nandc)
> 
>  		if (nandc->cmd_chan)
>  			dma_release_channel(nandc->cmd_chan);
> +
> +		if (nandc->props->qpic_v2) {
> +			if (nandc->sts_chan)
> +				dma_release_channel(nandc->sts_chan);
> +		}
>  	} else {
>  		if (nandc->chan)
>  			dma_release_channel(nandc->chan);
> @@ -2815,6 +2821,14 @@ static int qcom_nandc_alloc(struct
> qcom_nand_controller *nandc)
>  			goto unalloc;
>  		}
> 
> +		if (nandc->props->qpic_v2) {
> +			nandc->sts_chan = dma_request_slave_channel(nandc->dev, "sts");
> +			if (!nandc->sts_chan) {
> +				dev_err(nandc->dev, "failed to request sts channel\n");
> +				return -ENODEV;
> +			}
> +		}
> +
>  		/*
>  		 * Initially allocate BAM transaction to read ONFI param page.
>  		 * After detecting all the devices, this BAM transaction will

Ping! Please provide me some updates on this patch.


From mdalam at codeaurora.org  Tue Sep 28 05:20:06 2021
From: mdalam at codeaurora.org (mdalam at codeaurora.org)
Date: Tue, 28 Sep 2021 17:50:06 +0530
Subject: [PATCH 2/3] mtd: rawnand: qcom: Add sg list to handle status pipe
 request
In-Reply-To: <1631699851-12172-3-git-send-email-mdalam@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
 <1631699851-12172-3-git-send-email-mdalam@codeaurora.org>
Message-ID: <07b52169db478045d409def2b5f55b01@codeaurora.org>

On 2021-09-15 15:27, Md Sadre Alam wrote:
> From QPIC V2.0 onwards there is separate pipe to read status
> for each code word while reading in enhanced mode. page scope
> read and multi page read.
> 
> This sgl list will be use to handle the request via status pipe
> during page scope and multi page read.
> 
> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> ---
>  drivers/mtd/nand/raw/qcom_nandc.c | 34 
> ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c
> b/drivers/mtd/nand/raw/qcom_nandc.c
> index 42c6291..07448c4 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -213,6 +213,7 @@ nandc_set_reg(chip, reg,			\
>  #define QPIC_PER_CW_CMD_ELEMENTS	32
>  #define QPIC_PER_CW_CMD_SGL		32
>  #define QPIC_PER_CW_DATA_SGL		8
> +#define	QPIC_PER_CW_STS_SGL		8
> 
>  #define QPIC_NAND_COMPLETION_TIMEOUT	msecs_to_jiffies(2000)
> 
> @@ -258,6 +259,7 @@ struct bam_transaction {
>  	struct bam_cmd_element *bam_ce;
>  	struct scatterlist *cmd_sgl;
>  	struct scatterlist *data_sgl;
> +	struct scatterlist *sts_sgl;
>  	u32 bam_ce_pos;
>  	u32 bam_ce_start;
>  	u32 cmd_sgl_pos;
> @@ -266,6 +268,8 @@ struct bam_transaction {
>  	u32 tx_sgl_start;
>  	u32 rx_sgl_pos;
>  	u32 rx_sgl_start;
> +	u32 sts_sgl_pos;
> +	u32 sts_sgl_start;
>  	bool wait_second_completion;
>  	struct completion txn_done;
>  	struct dma_async_tx_descriptor *last_data_desc;
> @@ -508,6 +512,8 @@ alloc_bam_transaction(struct qcom_nand_controller 
> *nandc)
>  		((sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS) +
>  		(sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) +
>  		(sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL));
> +	if (nandc->props->qpic_v2)
> +		bam_txn_size += (sizeof(*bam_txn->sts_sgl) * QPIC_PER_CW_STS_SGL);
> 
>  	bam_txn_buf = devm_kzalloc(nandc->dev, bam_txn_size, GFP_KERNEL);
>  	if (!bam_txn_buf)
> @@ -526,6 +532,12 @@ alloc_bam_transaction(struct qcom_nand_controller 
> *nandc)
> 
>  	bam_txn->data_sgl = bam_txn_buf;
> 
> +	if (nandc->props->qpic_v2) {
> +		bam_txn_buf +=
> +			sizeof(*bam_txn->sts_sgl) * QPIC_PER_CW_STS_SGL * num_cw;
> +		bam_txn->sts_sgl = bam_txn_buf;
> +	}
> +
>  	init_completion(&bam_txn->txn_done);
> 
>  	return bam_txn;
> @@ -554,6 +566,12 @@ static void clear_bam_transaction(struct
> qcom_nand_controller *nandc)
>  		      QPIC_PER_CW_CMD_SGL);
>  	sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage *
>  		      QPIC_PER_CW_DATA_SGL);
> +	if (nandc->props->qpic_v2) {
> +		bam_txn->sts_sgl_pos = 0;
> +		bam_txn->sts_sgl_start = 0;
> +		sg_init_table(bam_txn->sts_sgl, nandc->max_cwperpage *
> +				QPIC_PER_CW_STS_SGL);
> +	}
> 
>  	reinit_completion(&bam_txn->txn_done);
>  }
> @@ -808,6 +826,12 @@ static int prepare_bam_async_desc(struct
> qcom_nand_controller *nandc,
>  		bam_txn->tx_sgl_start = bam_txn->tx_sgl_pos;
>  		dir_eng = DMA_MEM_TO_DEV;
>  		desc->dir = DMA_TO_DEVICE;
> +	} else if (nandc->props->qpic_v2 && chan == nandc->sts_chan) {
> +		sgl = &bam_txn->sts_sgl[bam_txn->sts_sgl_start];
> +		sgl_cnt = bam_txn->sts_sgl_pos - bam_txn->sts_sgl_start;
> +		bam_txn->sts_sgl_start = bam_txn->sts_sgl_pos;
> +		dir_eng = DMA_DEV_TO_MEM;
> +		desc->dir = DMA_FROM_DEVICE;
>  	} else {
>  		sgl = &bam_txn->data_sgl[bam_txn->rx_sgl_start];
>  		sgl_cnt = bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start;
> @@ -1394,6 +1418,14 @@ static int submit_descs(struct
> qcom_nand_controller *nandc)
>  			if (r)
>  				return r;
>  		}
> +
> +		if (nandc->props->qpic_v2) {
> +			if (bam_txn->sts_sgl_pos > bam_txn->sts_sgl_start) {
> +				r = prepare_bam_async_desc(nandc, nandc->sts_chan, 0);
> +				if (r)
> +					return r;
> +			}
> +		}
>  	}
> 
>  	list_for_each_entry(desc, &nandc->desc_list, node)
> @@ -1411,6 +1443,8 @@ static int submit_descs(struct
> qcom_nand_controller *nandc)
>  		dma_async_issue_pending(nandc->tx_chan);
>  		dma_async_issue_pending(nandc->rx_chan);
>  		dma_async_issue_pending(nandc->cmd_chan);
> +		if (nandc->props->qpic_v2)
> +			dma_async_issue_pending(nandc->sts_chan);
> 
>  		if (!wait_for_completion_timeout(&bam_txn->txn_done,
>  						 QPIC_NAND_COMPLETION_TIMEOUT))


Ping! Please provide me some updates on this patch.


From mdalam at codeaurora.org  Tue Sep 28 05:21:00 2021
From: mdalam at codeaurora.org (mdalam at codeaurora.org)
Date: Tue, 28 Sep 2021 17:51:00 +0530
Subject: [PATCH 3/3] mtd: rawnand: qcom: Add support for page scope read
In-Reply-To: <1631699851-12172-4-git-send-email-mdalam@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
 <1631699851-12172-4-git-send-email-mdalam@codeaurora.org>
Message-ID: <8765976685ca3a04af1c102a69c9ca63@codeaurora.org>

On 2021-09-15 15:27, Md Sadre Alam wrote:
> QPIC V2.0 onwards QPIC controller support enhanced read mode
> like page scope read and multi page read.
> 
> In QPIC V1, SW is needed to write EXEC_CMD register for each
> Code word and collect any Status related to that CW before
> issueing EXEC_CMD for next CW.
> 
> Page scope command is truly a page mode command where SW is
> required to issue EXEC_CMD only once for a page. Controller
> HW takes care of Codeword specific details and automatically
> returns status associated with each CW to BAM pipe, dedicated
> for status deposition.
> 
> With this command, SW now can issue one read command for a page
> and upon receiving completion interrupt, can process status,
> that have already been deposited in memory through status BAM pipe.
> 
> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> ---
>  drivers/mtd/nand/raw/qcom_nandc.c | 77 
> ++++++++++++++++++++++++++++++++++++---
>  1 file changed, 71 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c
> b/drivers/mtd/nand/raw/qcom_nandc.c
> index 07448c4..257dec7e 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -157,6 +157,10 @@
>  #define	OP_FETCH_ID			0xb
>  #define	OP_RESET_DEVICE			0xd
> 
> +/* Auto status val and mask */
> +#define	AUTO_STS_VAL			0x000B000B
> +#define PAGE_SCOPE_READ			BIT(23)
> +
>  /* Default Value for NAND_DEV_CMD_VLD */
>  #define NAND_DEV_CMD_VLD_VAL		(READ_START_VLD | WRITE_START_VLD | \
>  					 ERASE_START_VLD | SEQ_READ_START_VLD)
> @@ -336,6 +340,8 @@ struct nandc_regs {
> 
>  	__le32 erased_cw_detect_cfg_clr;
>  	__le32 erased_cw_detect_cfg_set;
> +
> +	__le32 auto_sts_en;
>  };
> 
>  /*
> @@ -421,6 +427,9 @@ struct qcom_nand_controller {
> 
>  	u32 cmd1, vld;
>  	const struct qcom_nandc_props *props;
> +
> +	__le32 *status_buf;
> +	int sts_buf_size;
>  };
> 
>  /*
> @@ -487,6 +496,7 @@ struct qcom_nandc_props {
>  	bool is_bam;
>  	bool is_qpic;
>  	bool qpic_v2;
> +	bool page_scope;
>  	u32 dev_cmd_reg_start;
>  };
> 
> @@ -656,6 +666,8 @@ static __le32 *offset_to_nandc_reg(struct
> nandc_regs *regs, int offset)
>  		return &regs->cfg1;
>  	case NAND_DEV0_ECC_CFG:
>  		return &regs->ecc_bch_cfg;
> +	case NAND_AUTO_STATUS_EN:
> +		return &regs->auto_sts_en;
>  	case NAND_READ_STATUS:
>  		return &regs->clrreadstatus;
>  	case NAND_DEV_CMD1:
> @@ -756,10 +768,13 @@ static void update_rw_regs(struct qcom_nand_host
> *host, int num_cw, bool read, i
>  	struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
> 
>  	if (read) {
> -		if (host->use_ecc)
> +		if (host->use_ecc) {
>  			cmd = OP_PAGE_READ_WITH_ECC | PAGE_ACC | LAST_PAGE;
> -		else
> +			if (nandc->props->qpic_v2 && nandc->props->page_scope)
> +				cmd |= PAGE_SCOPE_READ;
> +		} else {
>  			cmd = OP_PAGE_READ | PAGE_ACC | LAST_PAGE;
> +		}
>  	} else {
>  		cmd = OP_PROGRAM_PAGE | PAGE_ACC | LAST_PAGE;
>  	}
> @@ -788,6 +803,9 @@ static void update_rw_regs(struct qcom_nand_host
> *host, int num_cw, bool read, i
>  	nandc_set_reg(chip, NAND_READ_STATUS, host->clrreadstatus);
>  	nandc_set_reg(chip, NAND_EXEC_CMD, 1);
> 
> +	if (nandc->props->qpic_v2 && nandc->props->page_scope)
> +		nandc_set_reg(chip, NAND_AUTO_STATUS_EN, AUTO_STS_VAL);
> +
>  	if (read)
>  		nandc_set_read_loc(chip, cw, 0, 0, host->use_ecc ?
>  				   host->cw_data : host->cw_size, 1);
> @@ -1040,6 +1058,26 @@ static int prep_adm_dma_desc(struct
> qcom_nand_controller *nandc, bool read,
>  }
> 
>  /*
> + * read_status_data_dma: prepares a DMA descriptor to transfer status 
> from the
> + *			 controller's status registers to buffer 'vaddr'
> + * @reg_off:             offset within the controller's data buffer
> + * @vaddr:               virtual address of the buffer we want to 
> write to
> + * @size:                DMA transaction size in bytes
> + * @flags:               flags to control DMA descriptor preparation
> + */
> +static int read_status_data_dma(struct qcom_nand_controller *nandc,
> int reg_off,
> +				const u8 *vaddr, int size, unsigned int flags)
> +{
> +	struct bam_transaction *bam_txn = nandc->bam_txn;
> +
> +	sg_set_buf(&bam_txn->sts_sgl[bam_txn->sts_sgl_pos],
> +		   vaddr, size);
> +	bam_txn->sts_sgl_pos++;
> +
> +	return 0;
> +}
> +
> +/*
>   * read_reg_dma:	prepares a descriptor to read a given number of
>   *			contiguous registers to the reg_read_buf pointer
>   *
> @@ -1186,13 +1224,20 @@ config_nand_cw_read(struct nand_chip *chip,
> bool use_ecc, int cw)
>  		write_reg_dma(nandc, reg, 4, NAND_BAM_NEXT_SGL);
> 
>  	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
> -	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
> 
>  	if (use_ecc) {
> -		read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
> -		read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
> -			     NAND_BAM_NEXT_SGL);
> +		if (nandc->props->qpic_v2 && nandc->props->page_scope) {
> +			if (qcom_nandc_is_last_cw(ecc, cw))
> +				write_reg_dma(nandc, NAND_EXEC_CMD, 1,
> +					      NAND_BAM_NEXT_SGL);
> +		} else {
> +			write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
> +			read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
> +			read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
> +				     NAND_BAM_NEXT_SGL);
> +		}
>  	} else {
> +		write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
>  		read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
>  	}
>  }
> @@ -1959,6 +2004,8 @@ static int read_page_ecc(struct qcom_nand_host
> *host, u8 *data_buf,
>  	struct nand_ecc_ctrl *ecc = &chip->ecc;
>  	u8 *data_buf_start = data_buf, *oob_buf_start = oob_buf;
>  	int i, ret;
> +	__le32 *status_buf_start = nandc->status_buf;
> +	__le32 *status_buf_cw = nandc->status_buf;
> 
>  	config_nand_page_read(chip);
> 
> @@ -1994,6 +2041,12 @@ static int read_page_ecc(struct qcom_nand_host
> *host, u8 *data_buf,
>  			read_data_dma(nandc, FLASH_BUF_ACC, data_buf,
>  				      data_size, 0);
> 
> +		if (nandc->props->qpic_v2 && nandc->props->page_scope) {
> +			read_status_data_dma(nandc, FLASH_BUF_ACC, (void *)status_buf_cw,
> +					     (nandc->sts_buf_size >> 2), 0);
> +			status_buf_cw += (nandc->sts_buf_size >> 4);
> +		}
> +
>  		/*
>  		 * when ecc is enabled, the controller doesn't read the real
>  		 * or dummy bad block markers in each chunk. To maintain a
> @@ -2025,6 +2078,9 @@ static int read_page_ecc(struct qcom_nand_host
> *host, u8 *data_buf,
>  		return ret;
>  	}
> 
> +	if (nandc->props->qpic_v2 && nandc->props->page_scope)
> +		memmove(nandc->reg_read_buf, status_buf_start, nandc->sts_buf_size);
> +
>  	return parse_read_errors(host, data_buf_start, oob_buf_start, page);
>  }
> 
> @@ -3005,6 +3061,14 @@ static int
> qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc,
>  		}
>  	}
> 
> +	if (nandc->props->qpic_v2 && nandc->props->page_scope) {
> +		nandc->sts_buf_size = mtd->writesize == SZ_2K ? 48 : 96;
> +		nandc->status_buf = devm_kzalloc(nandc->dev, nandc->sts_buf_size,
> +						 GFP_KERNEL);
> +		if (!nandc->status_buf)
> +			return -ENOMEM;
> +	}
> +
>  	ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0);
>  	if (ret)
>  		nand_cleanup(chip);
> @@ -3197,6 +3261,7 @@ static const struct qcom_nandc_props 
> sdx55_nandc_props = {
>  	.is_bam = true,
>  	.is_qpic = true,
>  	.qpic_v2 = true,
> +	.page_scope = true,
>  	.dev_cmd_reg_start = 0x7000,
>  };

Ping! Please provide me some updates on this patch.


From axboe at kernel.dk  Tue Sep 28 05:28:11 2021
From: axboe at kernel.dk (Jens Axboe)
Date: Tue, 28 Sep 2021 06:28:11 -0600
Subject: [PATCH v2 0/6] block: 5th batch of add_disk() error handling
 conversions
In-Reply-To: <YVLV3s66GVVSQ+tj@osiris>
References: <20210927220232.1071926-1-mcgrof@kernel.org>
 <25afa23b-52af-9b79-8bd8-5e31da62c291@kernel.dk> <YVLV3s66GVVSQ+tj@osiris>
Message-ID: <bfd9f85a-d6fb-c05a-5ec3-2e15ee08062d@kernel.dk>

On 9/28/21 2:44 AM, Heiko Carstens wrote:
> On Mon, Sep 27, 2021 at 04:32:17PM -0600, Jens Axboe wrote:
>> On 9/27/21 4:02 PM, Luis Chamberlain wrote:
>>> This is the 5th series of driver conversions for add_disk() error
>>> handling. This set along with the entire 7th set of patches can be
>>> found on my 20210927-for-axboe-add-disk-error-handling branch [0].
>>
>> Applied 1-2.
> 
> Hmm.. naturally I would have expected that the dasd patch also would
> go via block tree. But let's not spend too much time figuring out what
> gets routed where.
> Applied 4-6. Thanks!

I left the ones that have active maintainers for them to pick. Unless
someone has already acked/reviwed it, in which case I picked it up.
I've got no problems picking them up directly, but unless it's been
reviewed by the maintainer, I prefer if they either do so or pick
them up.

-- 
Jens Axboe



From miquel.raynal at bootlin.com  Tue Sep 28 05:46:45 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 28 Sep 2021 14:46:45 +0200
Subject: [PATCH 1/3] mtd: rawnand: qcom: Add support for status pipe
In-Reply-To: <97df48e5505c4e6ae3bc6b7e953c156c@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
 <1631699851-12172-2-git-send-email-mdalam@codeaurora.org>
 <97df48e5505c4e6ae3bc6b7e953c156c@codeaurora.org>
Message-ID: <20210928144645.40209af0@xps13>

Hello,

mdalam at codeaurora.org wrote on Tue, 28 Sep 2021 17:47:27 +0530:

> On 2021-09-15 15:27, Md Sadre Alam wrote:
> > From QPIC V2.0 onwards there is a separate pipe
> > to read status of each code word, called "status" pipe.
> > 
> > "status" pipe will use to read CW status in case of

What is a CW status?

> > enhanced read mode like page scope read, multi page read.

What is a page scope read?

> > 
> > Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> > ---
> >  drivers/mtd/nand/raw/qcom_nandc.c | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> > 
> > diff --git a/drivers/mtd/nand/raw/qcom_nandc.c
> > b/drivers/mtd/nand/raw/qcom_nandc.c
> > index 04e6f7b..42c6291 100644
> > --- a/drivers/mtd/nand/raw/qcom_nandc.c
> > +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> > @@ -389,6 +389,7 @@ struct qcom_nand_controller {
> >  			struct dma_chan *tx_chan;
> >  			struct dma_chan *rx_chan;
> >  			struct dma_chan *cmd_chan;
> > +			struct dma_chan *sts_chan;
> >  		};
> > 
> >  		/* will be used only by EBI2 for ADM DMA */
> > @@ -2737,6 +2738,11 @@ static void qcom_nandc_unalloc(struct
> > qcom_nand_controller *nandc)
> > 
> >  		if (nandc->cmd_chan)
> >  			dma_release_channel(nandc->cmd_chan);
> > +
> > +		if (nandc->props->qpic_v2) {
> > +			if (nandc->sts_chan)
> > +				dma_release_channel(nandc->sts_chan);
> > +		}
> >  	} else {
> >  		if (nandc->chan)
> >  			dma_release_channel(nandc->chan);
> > @@ -2815,6 +2821,14 @@ static int qcom_nandc_alloc(struct
> > qcom_nand_controller *nandc)
> >  			goto unalloc;
> >  		}
> > 
> > +		if (nandc->props->qpic_v2) {
> > +			nandc->sts_chan = dma_request_slave_channel(nandc->dev, "sts");
> > +			if (!nandc->sts_chan) {
> > +				dev_err(nandc->dev, "failed to request sts channel\n");
> > +				return -ENODEV;
> > +			}
> > +		}
> > +
> >  		/*
> >  		 * Initially allocate BAM transaction to read ONFI param page.
> >  		 * After detecting all the devices, this BAM transaction will  
> 
> Ping! Please provide me some updates on this patch.

I don't think you need to ping me on all your patches. This is
irritating given the time that I allocated to all your contributions so
far.

This being said, I had no particular comment regarding the
implementation of the series but giving it a second look I still don't
fully understand the goal of this "additional pipe" so, as my comments
above say, please elaborate a little bit.

Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Tue Sep 28 05:48:32 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 28 Sep 2021 14:48:32 +0200
Subject: [PATCH 2/3] mtd: rawnand: qcom: Add sg list to handle status
 pipe request
In-Reply-To: <07b52169db478045d409def2b5f55b01@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
 <1631699851-12172-3-git-send-email-mdalam@codeaurora.org>
 <07b52169db478045d409def2b5f55b01@codeaurora.org>
Message-ID: <20210928144832.02e86fe1@xps13>

Hello,

mdalam at codeaurora.org wrote on Tue, 28 Sep 2021 17:50:06 +0530:

> On 2021-09-15 15:27, Md Sadre Alam wrote:
> > From QPIC V2.0 onwards there is separate pipe to read status
> > for each code word while reading in enhanced mode.

What is enhanced mode?

> page scope read and multi page read.

This is not a correct sentence.

> > This sgl list will be use to handle the request via status pipe

         ^^^              used                          the

Please use plain english in the commit description.

> > during page scope and multi page read.

What is page scope?

> > Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>

Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Tue Sep 28 05:54:40 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 28 Sep 2021 14:54:40 +0200
Subject: [PATCH 3/3] mtd: rawnand: qcom: Add support for page scope read
In-Reply-To: <8765976685ca3a04af1c102a69c9ca63@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
 <1631699851-12172-4-git-send-email-mdalam@codeaurora.org>
 <8765976685ca3a04af1c102a69c9ca63@codeaurora.org>
Message-ID: <20210928145440.758ead6b@xps13>

Hello,

mdalam at codeaurora.org wrote on Tue, 28 Sep 2021 17:51:00 +0530:

> On 2021-09-15 15:27, Md Sadre Alam wrote:
> > QPIC V2.0 onwards QPIC controller support enhanced read mode
> > like page scope read and multi page read.
> > 
> > In QPIC V1, SW is needed to write EXEC_CMD register for each

                the driver needs to (same below)

> > Code word and collect any Status related to that CW before
> > issueing EXEC_CMD for next CW.
> > 
> > Page scope command is truly a page mode command where SW is
> > required to issue EXEC_CMD only once for a page. Controller
> > HW takes care of Codeword specific details and automatically
> > returns status associated with each CW to BAM pipe, dedicated
> > for status deposition.
> > 
> > With this command, SW now can issue one read command for a page
> > and upon receiving completion interrupt, can process status,
> > that have already been deposited in memory through status BAM pipe.
> > 
> > Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> > ---
> >  drivers/mtd/nand/raw/qcom_nandc.c | 77 > ++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 71 insertions(+), 6 deletions(-)
> > 

Thanks,
Miqu?l


From daniel at 0x0f.com  Tue Sep 28 06:15:55 2021
From: daniel at 0x0f.com (Daniel Palmer)
Date: Tue, 28 Sep 2021 22:15:55 +0900
Subject: [PATCH] mtd: spi-nor: Add support for ZB25VQ128
In-Reply-To: <20210920112625.fnqayim5mg5iggag@ti.com>
References: <20210918072256.3505379-1-daniel@0x0f.com>
 <20210920112625.fnqayim5mg5iggag@ti.com>
Message-ID: <CAFr9PX=xKoa9fCbYf6Mpn=oudnY7A=6meKBSmzNHYLFad364tw@mail.gmail.com>

Hi Pratyush,

On Mon, 20 Sept 2021 at 20:26, Pratyush Yadav <p.yadav at ti.com> wrote:
>
> Zbit should be in bank 10, so it should be preceeded by 9 0x7f bytes,
> correct? I don't see any logic to handle that in SPI NOR currently so I
> assume this manufacturer does not implement the continuation codes.
>
> In that case, it should go to the manufacturer collisions driver
> proposed here [0].
>
> [0] https://patchwork.ozlabs.org/project/linux-mtd/patch/20210727045222.905056-6-tudor.ambarus at microchip.com/

Sorry, I'm not sure what I should do with this information. I didn't
even know about the continuation codes thing until now.
Is there something I need to do here or do I just need to wait for the
collision handling code to get merged?

Thanks,

Daniel


From miquel.raynal at bootlin.com  Tue Sep 28 06:58:59 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 28 Sep 2021 15:58:59 +0200
Subject: [PATCH] mtd: add MEMREAD ioctl
In-Reply-To: <20210920070221.10173-1-kernel@kempniu.pl>
References: <20210920070221.10173-1-kernel@kempniu.pl>
Message-ID: <20210928155859.433844cb@xps13>

Hi Micha?,

+ Boris just in case you have anything obvious that pops up in your
  head when reading the description, otherwise no need to thoroughfully
  review this ;)

kernel at kempniu.pl wrote on Mon, 20 Sep 2021 09:02:21 +0200:

> User-space applications making use of MTD devices via /dev/mtd*
> character devices currently have limited capabilities for reading data:
> 
>   - only deprecated methods of accessing OOB layout information exist,
> 
>   - there is no way to explicitly specify MTD operation mode to use; it
>     is auto-selected based on the MTD file mode (MTD_FILE_MODE_*) set
>     for the character device; in particular, this prevents using
>     MTD_OPS_AUTO_OOB for reads,
> 
>   - all existing user-space interfaces which cause mtd_read() or
>     mtd_read_oob() to be called (via mtdchar_read() and
>     mtdchar_read_oob(), respectively) return success even when those
>     functions return -EUCLEAN or -EBADMSG; this renders user-space
>     applications using these interfaces unaware of any corrected
>     bitflips or uncorrectable ECC errors detected during reads.
> 
> Note that the existing MEMWRITE ioctl allows the MTD operation mode to
> be explicitly set, allowing user-space applications to write page data
> and OOB data without requiring them to know anything about the OOB
> layout of the MTD device they are writing to (MTD_OPS_AUTO_OOB).  Also,
> the MEMWRITE ioctl does not mangle the return value of mtd_write_oob().
> 
> Add a new ioctl, MEMREAD, which addresses the above issues.  It is
> intended to be a read-side counterpart of the existing MEMWRITE ioctl.
> 
> Update include/uapi/mtd/mtd-abi.h accordingly.

I have to admit I am generally scared whenever something touches this
file. While I am really open to anything internally I know we need to be
careful with these additions, hence I will only merge this patch with
all other MTD maintainers acks.

On my side I am fine with the approach though.

Thanks,
Miqu?l

> Signed-off-by: Micha? K?pie? <kernel at kempniu.pl>
> ---
> This patch is a shameless calque^W^W^Wheavily inspired by MEMWRITE code,
> so quite a lot of copy-pasting happened.  I guess it is somewhat
> expected when adding a read-side counterpart of existing code which
> takes care of writes, but please excuse me if I went too far.
> 
> Note that "scripts/checkpatch.pl --strict" returns two alignment
> warnings for this patch.  Given that existing code triggers the same
> warnings, I assumed that local consistency trumps checkpatch.pl's
> complaints.
> 
>  drivers/mtd/mtdchar.c      | 60 ++++++++++++++++++++++++++++++++++++++
>  include/uapi/mtd/mtd-abi.h | 43 +++++++++++++++++++++++----
>  2 files changed, 98 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
> index 155e991d9d75..92e0024bdcf7 100644
> --- a/drivers/mtd/mtdchar.c
> +++ b/drivers/mtd/mtdchar.c
> @@ -621,6 +621,58 @@ static int mtdchar_write_ioctl(struct mtd_info *mtd,
>  	return ret;
>  }
>  
> +static int mtdchar_read_ioctl(struct mtd_info *mtd,
> +		struct mtd_read_req __user *argp)
> +{
> +	struct mtd_info *master = mtd_get_master(mtd);
> +	struct mtd_read_req req;
> +	struct mtd_oob_ops ops = {};
> +	void __user *usr_data, *usr_oob;
> +	int ret;
> +
> +	if (copy_from_user(&req, argp, sizeof(req)))
> +		return -EFAULT;
> +
> +	usr_data = (void __user *)(uintptr_t)req.usr_data;
> +	usr_oob = (void __user *)(uintptr_t)req.usr_oob;
> +
> +	if (!master->_read_oob)
> +		return -EOPNOTSUPP;
> +	ops.mode = req.mode;
> +	ops.len = (size_t)req.len;
> +	ops.ooblen = (size_t)req.ooblen;
> +	ops.ooboffs = 0;
> +
> +	if (usr_data) {
> +		ops.datbuf = kmalloc(ops.len, GFP_KERNEL);
> +		if (IS_ERR(ops.datbuf))
> +			return PTR_ERR(ops.datbuf);
> +	} else {
> +		ops.datbuf = NULL;
> +	}
> +
> +	if (usr_oob) {
> +		ops.oobbuf = kmalloc(ops.ooblen, GFP_KERNEL);
> +		if (IS_ERR(ops.oobbuf)) {
> +			kfree(ops.datbuf);
> +			return PTR_ERR(ops.oobbuf);
> +		}
> +	} else {
> +		ops.oobbuf = NULL;
> +	}
> +
> +	ret = mtd_read_oob(mtd, (loff_t)req.start, &ops);
> +
> +	if (copy_to_user(usr_data, ops.datbuf, ops.retlen) ||
> +	    copy_to_user(usr_oob, ops.oobbuf, ops.oobretlen))
> +		ret = -EFAULT;
> +
> +	kfree(ops.datbuf);
> +	kfree(ops.oobbuf);
> +
> +	return ret;
> +}
> +
>  static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
>  {
>  	struct mtd_file_info *mfi = file->private_data;
> @@ -643,6 +695,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
>  	case MEMGETINFO:
>  	case MEMREADOOB:
>  	case MEMREADOOB64:
> +	case MEMREAD:
>  	case MEMISLOCKED:
>  	case MEMGETOOBSEL:
>  	case MEMGETBADBLOCK:
> @@ -817,6 +870,13 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
>  		break;
>  	}
>  
> +	case MEMREAD:
> +	{
> +		ret = mtdchar_read_ioctl(mtd,
> +		      (struct mtd_read_req __user *)arg);
> +		break;
> +	}
> +
>  	case MEMLOCK:
>  	{
>  		struct erase_info_user einfo;
> diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
> index b869990c2db2..337e6e597fad 100644
> --- a/include/uapi/mtd/mtd-abi.h
> +++ b/include/uapi/mtd/mtd-abi.h
> @@ -55,9 +55,9 @@ struct mtd_oob_buf64 {
>   * @MTD_OPS_RAW:	data are transferred as-is, with no error correction;
>   *			this mode implies %MTD_OPS_PLACE_OOB
>   *
> - * These modes can be passed to ioctl(MEMWRITE) and are also used internally.
> - * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs.
> - * %MTD_FILE_MODE_RAW.
> + * These modes can be passed to ioctl(MEMWRITE) and ioctl(MEMREAD); they are
> + * also used internally. See notes on "MTD file modes" for discussion on
> + * %MTD_OPS_RAW vs. %MTD_FILE_MODE_RAW.
>   */
>  enum {
>  	MTD_OPS_PLACE_OOB = 0,
> @@ -91,6 +91,32 @@ struct mtd_write_req {
>  	__u8 padding[7];
>  };
>  
> +/**
> + * struct mtd_read_req - data structure for requesting a read operation
> + *
> + * @start:	start address
> + * @len:	length of data buffer
> + * @ooblen:	length of OOB buffer
> + * @usr_data:	user-provided data buffer
> + * @usr_oob:	user-provided OOB buffer
> + * @mode:	MTD mode (see "MTD operation modes")
> + * @padding:	reserved, must be set to 0
> + *
> + * This structure supports ioctl(MEMREAD) operations, allowing data and/or OOB
> + * reads in various modes. To read from OOB-only, set @usr_data == NULL, and to
> + * read data-only, set @usr_oob == NULL. However, setting both @usr_data and
> + * @usr_oob to NULL is not allowed.
> + */
> +struct mtd_read_req {
> +	__u64 start;
> +	__u64 len;
> +	__u64 ooblen;
> +	__u64 usr_data;
> +	__u64 usr_oob;
> +	__u8 mode;
> +	__u8 padding[7];
> +};
> +
>  #define MTD_ABSENT		0
>  #define MTD_RAM			1
>  #define MTD_ROM			2
> @@ -207,6 +233,12 @@ struct otp_info {
>  #define MEMWRITE		_IOWR('M', 24, struct mtd_write_req)
>  /* Erase a given range of user data (must be in mode %MTD_FILE_MODE_OTP_USER) */
>  #define OTPERASE		_IOW('M', 25, struct otp_info)
> +/*
> + * Most generic read interface; can read in-band and/or out-of-band in various
> + * modes (see "struct mtd_read_req"). This ioctl is not supported for flashes
> + * without OOB, e.g., NOR flash.
> + */
> +#define MEMREAD			_IOWR('M', 26, struct mtd_read_req)
>  
>  /*
>   * Obsolete legacy interface. Keep it in order not to break userspace
> @@ -270,8 +302,9 @@ struct mtd_ecc_stats {
>   * Note: %MTD_FILE_MODE_RAW provides the same functionality as %MTD_OPS_RAW -
>   * raw access to the flash, without error correction or autoplacement schemes.
>   * Wherever possible, the MTD_OPS_* mode will override the MTD_FILE_MODE_* mode
> - * (e.g., when using ioctl(MEMWRITE)), but in some cases, the MTD_FILE_MODE is
> - * used out of necessity (e.g., `write()', ioctl(MEMWRITEOOB64)).
> + * (e.g., when using ioctl(MEMWRITE) or ioctl(MEMREAD)), but in some cases, the
> + * MTD_FILE_MODE is used out of necessity (e.g., `write()',
> + * ioctl(MEMWRITEOOB64)).
>   */
>  enum mtd_file_modes {
>  	MTD_FILE_MODE_NORMAL = MTD_OTP_OFF,



From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Sep 28 07:07:15 2021
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 28 Sep 2021 15:07:15 +0100
Subject: [PATCH 0/6] Add SPI Multi I/O Bus Controller support for RZ/G2L
Message-ID: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

Hi All,

This patch series adds a couple of fixes for rpc-if driver and
adds support for RZ/G2L SoC, where the SPI Multi I/O Bus Controller
is identical to the RPC-IF block found on R-Car Gen3 SoC's.

Note: patch applies on top of [1].

[1] https://patchwork.kernel.org/project/linux-renesas-soc/patch/
20210922091007.5516-1-wsa+renesas at sang-engineering.com/

Cheers,
Prabhakar

Lad Prabhakar (6):
  dt-bindings: memory: renesas,rpc-if: Add support for the R9A07G044
  dt-bindings: memory: renesas,rpc-if: Add optional interrupts property
  spi: spi-rpc-if: Check return value of rpcif_sw_init()
  mtd: hyperbus: rpc-if: Check return value of rpcif_sw_init()
  memory: renesas-rpc-if: Drop usage of RPCIF_DIRMAP_SIZE macro
  memory: renesas-rpc-if: Add support for RZ/G2L

 .../memory-controllers/renesas,rpc-if.yaml    | 52 +++++++++----
 drivers/memory/renesas-rpc-if.c               | 73 +++++++++++++++----
 drivers/mtd/hyperbus/rpc-if.c                 |  8 +-
 drivers/spi/spi-rpc-if.c                      |  8 +-
 include/memory/renesas-rpc-if.h               |  8 +-
 5 files changed, 116 insertions(+), 33 deletions(-)

-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Sep 28 07:07:16 2021
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 28 Sep 2021 15:07:16 +0100
Subject: [PATCH 1/6] dt-bindings: memory: renesas,
 rpc-if: Add support for the R9A07G044
In-Reply-To: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20210928140721.8805-2-prabhakar.mahadev-lad.rj@bp.renesas.com>

SPI Multi I/O Bus Controller on RZ/G2L SoC is almost identical to
the RPC-IF interface found on R-Car Gen3 SoC's.

This patch adds a new compatible string to identify the RZ/G2L family
so that the timing values on RZ/G2L can be adjusted.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
---
 .../memory-controllers/renesas,rpc-if.yaml    | 51 ++++++++++++++-----
 1 file changed, 37 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml b/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
index d25072c414e4..105b5157989b 100644
--- a/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
@@ -24,16 +24,22 @@ allOf:
 
 properties:
   compatible:
-    items:
-      - enum:
-          - renesas,r8a774a1-rpc-if       # RZ/G2M
-          - renesas,r8a774b1-rpc-if       # RZ/G2N
-          - renesas,r8a774c0-rpc-if       # RZ/G2E
-          - renesas,r8a774e1-rpc-if       # RZ/G2H
-          - renesas,r8a77970-rpc-if       # R-Car V3M
-          - renesas,r8a77980-rpc-if       # R-Car V3H
-          - renesas,r8a77995-rpc-if       # R-Car D3
-      - const: renesas,rcar-gen3-rpc-if   # a generic R-Car gen3 or RZ/G2 device
+    oneOf:
+      - items:
+          - enum:
+              - renesas,r8a774a1-rpc-if       # RZ/G2M
+              - renesas,r8a774b1-rpc-if       # RZ/G2N
+              - renesas,r8a774c0-rpc-if       # RZ/G2E
+              - renesas,r8a774e1-rpc-if       # RZ/G2H
+              - renesas,r8a77970-rpc-if       # R-Car V3M
+              - renesas,r8a77980-rpc-if       # R-Car V3H
+              - renesas,r8a77995-rpc-if       # R-Car D3
+          - const: renesas,rcar-gen3-rpc-if   # a generic R-Car gen3 or RZ/G2{E,H,M,N} device
+
+      - items:
+          - enum:
+              - renesas,r9a07g044-rpc-if      # RZ/G2{L,LC}
+          - const: renesas,rzg2l-rpc-if       # RZ/G2L family
 
   reg:
     items:
@@ -47,8 +53,7 @@ properties:
       - const: dirmap
       - const: wbuf
 
-  clocks:
-    maxItems: 1
+  clocks: true
 
   power-domains:
     maxItems: 1
@@ -66,8 +71,6 @@ patternProperties:
             - cfi-flash
             - jedec,spi-nor
 
-unevaluatedProperties: false
-
 required:
   - compatible
   - reg
@@ -78,6 +81,26 @@ required:
   - '#address-cells'
   - '#size-cells'
 
+if:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - renesas,rzg2l-rpc-if
+then:
+  properties:
+    clocks:
+      items:
+        - description: SPI Multi IO Register access clock (SPI_CLK2)
+        - description: SPI Multi IO Main clock (SPI_CLK).
+
+else:
+  properties:
+    clocks:
+      maxItems: 1
+
+unevaluatedProperties: false
+
 examples:
   - |
     #include <dt-bindings/clock/renesas-cpg-mssr.h>
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Sep 28 07:07:17 2021
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 28 Sep 2021 15:07:17 +0100
Subject: [PATCH 2/6] dt-bindings: memory: renesas,
 rpc-if: Add optional interrupts property
In-Reply-To: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20210928140721.8805-3-prabhakar.mahadev-lad.rj@bp.renesas.com>

For completeness add optional interrupts property.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
---
 .../devicetree/bindings/memory-controllers/renesas,rpc-if.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml b/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
index 105b5157989b..fd1ecbb6c94d 100644
--- a/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
@@ -55,6 +55,9 @@ properties:
 
   clocks: true
 
+  interrupts:
+    maxItems: 1
+
   power-domains:
     maxItems: 1
 
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Sep 28 07:07:18 2021
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 28 Sep 2021 15:07:18 +0100
Subject: [PATCH 3/6] spi: spi-rpc-if: Check return value of rpcif_sw_init()
In-Reply-To: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20210928140721.8805-4-prabhakar.mahadev-lad.rj@bp.renesas.com>

rpcif_sw_init() can fail so make sure we check the return value
of it and on error exit rpcif_spi_probe() callback with error code.

Fixes: eb8d6d464a27 ("spi: add Renesas RPC-IF driver")
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
---
 drivers/spi/spi-rpc-if.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-rpc-if.c b/drivers/spi/spi-rpc-if.c
index c53138ce0030..83796a4ead34 100644
--- a/drivers/spi/spi-rpc-if.c
+++ b/drivers/spi/spi-rpc-if.c
@@ -139,7 +139,9 @@ static int rpcif_spi_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	rpc = spi_controller_get_devdata(ctlr);
-	rpcif_sw_init(rpc, parent);
+	error = rpcif_sw_init(rpc, parent);
+	if (error)
+		return error;
 
 	platform_set_drvdata(pdev, ctlr);
 
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Sep 28 07:07:19 2021
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 28 Sep 2021 15:07:19 +0100
Subject: [PATCH 4/6] mtd: hyperbus: rpc-if: Check return value of
 rpcif_sw_init()
In-Reply-To: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20210928140721.8805-5-prabhakar.mahadev-lad.rj@bp.renesas.com>

rpcif_sw_init() can fail so make sure we check the return value
of it and on error exit rpcif_hb_probe() callback with error code.

Fixes: 5de15b610f78 ("mtd: hyperbus: add Renesas RPC-IF driver")
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
---
 drivers/mtd/hyperbus/rpc-if.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/hyperbus/rpc-if.c b/drivers/mtd/hyperbus/rpc-if.c
index ecb050ba95cd..367b0d72bf62 100644
--- a/drivers/mtd/hyperbus/rpc-if.c
+++ b/drivers/mtd/hyperbus/rpc-if.c
@@ -124,7 +124,9 @@ static int rpcif_hb_probe(struct platform_device *pdev)
 	if (!hyperbus)
 		return -ENOMEM;
 
-	rpcif_sw_init(&hyperbus->rpc, pdev->dev.parent);
+	error = rpcif_sw_init(&hyperbus->rpc, pdev->dev.parent);
+	if (error)
+		return error;
 
 	platform_set_drvdata(pdev, hyperbus);
 
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Sep 28 07:07:20 2021
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 28 Sep 2021 15:07:20 +0100
Subject: [PATCH 5/6] memory: renesas-rpc-if: Drop usage of RPCIF_DIRMAP_SIZE
 macro
In-Reply-To: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20210928140721.8805-6-prabhakar.mahadev-lad.rj@bp.renesas.com>

RPCIF_DIRMAP_SIZE may differ on various SoC's. Instead of using
RPCIF_DIRMAP_SIZE macro use resource size to get dirmap size
which is already part of struct rpcif.

Also make sure we return error in case devm_ioremap_resource()
fails for dirmap.

Fixes: ca7d8b980b67 ("memory: add Renesas RPC-IF driver")
Fixes: 59e27d7c94aa ("memory: renesas-rpc-if: fix possible NULL pointer dereference of resource")
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
---
 drivers/memory/renesas-rpc-if.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c
index 77a011d5ff8c..140cb4e2b789 100644
--- a/drivers/memory/renesas-rpc-if.c
+++ b/drivers/memory/renesas-rpc-if.c
@@ -147,8 +147,6 @@
 #define RPCIF_PHYINT		0x0088	/* R/W */
 #define RPCIF_PHYINT_WPVAL	BIT(1)
 
-#define RPCIF_DIRMAP_SIZE	0x4000000
-
 static const struct regmap_range rpcif_volatile_ranges[] = {
 	regmap_reg_range(RPCIF_SMRDR0, RPCIF_SMRDR1),
 	regmap_reg_range(RPCIF_SMWDR0, RPCIF_SMWDR1),
@@ -244,7 +242,7 @@ int rpcif_sw_init(struct rpcif *rpc, struct device *dev)
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap");
 	rpc->dirmap = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(rpc->dirmap))
-		rpc->dirmap = NULL;
+		return PTR_ERR(rpc->dirmap);
 	rpc->size = resource_size(res);
 
 	rpc->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
@@ -547,8 +545,8 @@ EXPORT_SYMBOL(rpcif_manual_xfer);
 
 ssize_t rpcif_dirmap_read(struct rpcif *rpc, u64 offs, size_t len, void *buf)
 {
-	loff_t from = offs & (RPCIF_DIRMAP_SIZE - 1);
-	size_t size = RPCIF_DIRMAP_SIZE - from;
+	loff_t from = offs & (rpc->size - 1);
+	size_t size = rpc->size - from;
 
 	if (len > size)
 		len = size;
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Sep 28 07:07:21 2021
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 28 Sep 2021 15:07:21 +0100
Subject: [PATCH 6/6] memory: renesas-rpc-if: Add support for RZ/G2L
In-Reply-To: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20210928140721.8805-7-prabhakar.mahadev-lad.rj@bp.renesas.com>

SPI Multi I/O Bus Controller on RZ/G2L SoC is almost identical to
the RPC-IF interface found on R-Car Gen3 SoC's.

This patch adds a new compatible string for the RZ/G2L family so
that the timing values on RZ/G2L can be adjusted.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
---
 drivers/memory/renesas-rpc-if.c | 65 ++++++++++++++++++++++++++++-----
 drivers/mtd/hyperbus/rpc-if.c   |  4 +-
 drivers/spi/spi-rpc-if.c        |  4 +-
 include/memory/renesas-rpc-if.h |  8 +++-
 4 files changed, 68 insertions(+), 13 deletions(-)

diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c
index 140cb4e2b789..47dce166b328 100644
--- a/drivers/memory/renesas-rpc-if.c
+++ b/drivers/memory/renesas-rpc-if.c
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
 
@@ -24,14 +25,14 @@
 #define RPCIF_CMNCR_MOIIO2(val)	(((val) & 0x3) << 20)
 #define RPCIF_CMNCR_MOIIO1(val)	(((val) & 0x3) << 18)
 #define RPCIF_CMNCR_MOIIO0(val)	(((val) & 0x3) << 16)
-#define RPCIF_CMNCR_MOIIO_HIZ	(RPCIF_CMNCR_MOIIO0(3) | \
-				 RPCIF_CMNCR_MOIIO1(3) | \
-				 RPCIF_CMNCR_MOIIO2(3) | RPCIF_CMNCR_MOIIO3(3))
+#define RPCIF_CMNCR_MOIIO_HIZ(val) (RPCIF_CMNCR_MOIIO0(val) | \
+				 RPCIF_CMNCR_MOIIO1(val) | \
+				 RPCIF_CMNCR_MOIIO2(val) | RPCIF_CMNCR_MOIIO3(val))
 #define RPCIF_CMNCR_IO3FV(val)	(((val) & 0x3) << 14) /* undocumented */
 #define RPCIF_CMNCR_IO2FV(val)	(((val) & 0x3) << 12) /* undocumented */
 #define RPCIF_CMNCR_IO0FV(val)	(((val) & 0x3) << 8)
-#define RPCIF_CMNCR_IOFV_HIZ	(RPCIF_CMNCR_IO0FV(3) | RPCIF_CMNCR_IO2FV(3) | \
-				 RPCIF_CMNCR_IO3FV(3))
+#define RPCIF_CMNCR_IOFV_HIZ(val) (RPCIF_CMNCR_IO0FV(val) | RPCIF_CMNCR_IO2FV(val) | \
+				 RPCIF_CMNCR_IO3FV(val))
 #define RPCIF_CMNCR_BSZ(val)	(((val) & 0x3) << 0)
 
 #define RPCIF_SSLDR		0x0004	/* R/W */
@@ -126,6 +127,9 @@
 #define RPCIF_SMDRENR_OPDRE	BIT(4)
 #define RPCIF_SMDRENR_SPIDRE	BIT(0)
 
+#define RPCIF_PHYADJ1		0x0070	/* R/W */
+#define RPCIF_PHYADJ2		0x0074	/* R/W */
+
 #define RPCIF_PHYCNT		0x007C	/* R/W */
 #define RPCIF_PHYCNT_CAL	BIT(31)
 #define RPCIF_PHYCNT_OCTA(v)	(((v) & 0x3) << 22)
@@ -133,10 +137,12 @@
 #define RPCIF_PHYCNT_OCT	BIT(20)
 #define RPCIF_PHYCNT_DDRCAL	BIT(19)
 #define RPCIF_PHYCNT_HS		BIT(18)
+#define RPCIF_PHYCNT_CKSEL(v)	(((v) & 0x3) << 16)
 #define RPCIF_PHYCNT_STRTIM(v)	(((v) & 0x7) << 15)
 #define RPCIF_PHYCNT_WBUF2	BIT(4)
 #define RPCIF_PHYCNT_WBUF	BIT(2)
 #define RPCIF_PHYCNT_PHYMEM(v)	(((v) & 0x3) << 0)
+#define RPCIF_PHYCNT_PHYMEM_MASK GENMASK(1, 0)
 
 #define RPCIF_PHYOFFSET1	0x0080	/* R/W */
 #define RPCIF_PHYOFFSET1_DDRTMG(v) (((v) & 0x3) << 28)
@@ -245,18 +251,46 @@ int rpcif_sw_init(struct rpcif *rpc, struct device *dev)
 		return PTR_ERR(rpc->dirmap);
 	rpc->size = resource_size(res);
 
+	rpc->type = (enum rpcif_type)of_device_get_match_data(dev);
 	rpc->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 
 	return PTR_ERR_OR_ZERO(rpc->rstc);
 }
 EXPORT_SYMBOL(rpcif_sw_init);
 
-void rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
+static void rpcif_timing_adjust_sdr(struct rpcif *rpc)
+{
+	u32 data;
+
+	regmap_write(rpc->regmap, RPCIF_PHYADJ2, 0xA5390000);
+	regmap_write(rpc->regmap, RPCIF_PHYADJ1, 0x80000000);
+	regmap_write(rpc->regmap, RPCIF_PHYADJ2, 0x00008080);
+	regmap_write(rpc->regmap, RPCIF_PHYADJ1, 0x80000022);
+	regmap_write(rpc->regmap, RPCIF_PHYADJ2, 0x00008080);
+	regmap_write(rpc->regmap, RPCIF_PHYADJ1, 0x80000024);
+
+	regmap_read(rpc->regmap, RPCIF_PHYCNT, &data);
+	regmap_write(rpc->regmap, RPCIF_PHYCNT, data | RPCIF_PHYCNT_CKSEL(3));
+	regmap_write(rpc->regmap, RPCIF_PHYADJ2, 0x00000030);
+	regmap_write(rpc->regmap, RPCIF_PHYADJ1, 0x80000032);
+}
+
+int rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
 {
 	u32 dummy;
 
 	pm_runtime_get_sync(rpc->dev);
 
+	if (rpc->type == RPCIF_RZ_G2L) {
+		int ret;
+
+		ret = reset_control_reset(rpc->rstc);
+		if (ret)
+			return ret;
+		usleep_range(200, 300);
+		rpcif_timing_adjust_sdr(rpc);
+	}
+
 	/*
 	 * NOTE: The 0x260 are undocumented bits, but they must be set.
 	 *	 RPCIF_PHYCNT_STRTIM is strobe timing adjustment bits,
@@ -265,8 +299,15 @@ void rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
 	 *	 On H3 ES1.x, the value should be 0, while on others,
 	 *	 the value should be 7.
 	 */
-	regmap_write(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_STRTIM(7) |
-		     RPCIF_PHYCNT_PHYMEM(hyperflash ? 3 : 0) | 0x260);
+	if (rpc->type == RPCIF_RCAR_GEN3) {
+		regmap_write(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_STRTIM(7) |
+			     RPCIF_PHYCNT_PHYMEM(hyperflash ? 3 : 0) | 0x260);
+	} else {
+		regmap_read(rpc->regmap, RPCIF_PHYCNT, &dummy);
+		dummy &= ~RPCIF_PHYCNT_PHYMEM_MASK;
+		dummy |= RPCIF_PHYCNT_PHYMEM(hyperflash ? 3 : 0) | 0x260;
+		regmap_write(rpc->regmap, RPCIF_PHYCNT, dummy);
+	}
 
 	/*
 	 * NOTE: The 0x1511144 are undocumented bits, but they must be set
@@ -284,7 +325,8 @@ void rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
 				   RPCIF_PHYINT_WPVAL, 0);
 
 	regmap_write(rpc->regmap, RPCIF_CMNCR, RPCIF_CMNCR_SFDE |
-		     RPCIF_CMNCR_MOIIO_HIZ | RPCIF_CMNCR_IOFV_HIZ |
+		     RPCIF_CMNCR_MOIIO_HIZ(rpc->type == RPCIF_RZ_G2L ? 1 : 3) |
+		     RPCIF_CMNCR_IOFV_HIZ(rpc->type == RPCIF_RZ_G2L ? 2 : 3) |
 		     RPCIF_CMNCR_BSZ(hyperflash ? 1 : 0));
 	/* Set RCF after BSZ update */
 	regmap_write(rpc->regmap, RPCIF_DRCR, RPCIF_DRCR_RCF);
@@ -296,6 +338,8 @@ void rpcif_hw_init(struct rpcif *rpc, bool hyperflash)
 	pm_runtime_put(rpc->dev);
 
 	rpc->bus_size = hyperflash ? 2 : 1;
+
+	return 0;
 }
 EXPORT_SYMBOL(rpcif_hw_init);
 
@@ -613,7 +657,8 @@ static int rpcif_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id rpcif_of_match[] = {
-	{ .compatible = "renesas,rcar-gen3-rpc-if", },
+	{ .compatible = "renesas,rcar-gen3-rpc-if", .data = (void *)RPCIF_RCAR_GEN3 },
+	{ .compatible = "renesas,rzg2l-rpc-if", .data = (void *)RPCIF_RZ_G2L },
 	{},
 };
 MODULE_DEVICE_TABLE(of, rpcif_of_match);
diff --git a/drivers/mtd/hyperbus/rpc-if.c b/drivers/mtd/hyperbus/rpc-if.c
index 367b0d72bf62..40bca89268c3 100644
--- a/drivers/mtd/hyperbus/rpc-if.c
+++ b/drivers/mtd/hyperbus/rpc-if.c
@@ -132,7 +132,9 @@ static int rpcif_hb_probe(struct platform_device *pdev)
 
 	rpcif_enable_rpm(&hyperbus->rpc);
 
-	rpcif_hw_init(&hyperbus->rpc, true);
+	error = rpcif_hw_init(&hyperbus->rpc, true);
+	if (error)
+		return error;
 
 	hyperbus->hbdev.map.size = hyperbus->rpc.size;
 	hyperbus->hbdev.map.virt = hyperbus->rpc.dirmap;
diff --git a/drivers/spi/spi-rpc-if.c b/drivers/spi/spi-rpc-if.c
index 83796a4ead34..fe82f3575df4 100644
--- a/drivers/spi/spi-rpc-if.c
+++ b/drivers/spi/spi-rpc-if.c
@@ -156,7 +156,9 @@ static int rpcif_spi_probe(struct platform_device *pdev)
 	ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_QUAD | SPI_RX_QUAD;
 	ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX;
 
-	rpcif_hw_init(rpc, false);
+	error = rpcif_hw_init(rpc, false);
+	if (error)
+		return error;
 
 	error = spi_register_controller(ctlr);
 	if (error) {
diff --git a/include/memory/renesas-rpc-if.h b/include/memory/renesas-rpc-if.h
index 77c694a19149..7c93f5177532 100644
--- a/include/memory/renesas-rpc-if.h
+++ b/include/memory/renesas-rpc-if.h
@@ -57,6 +57,11 @@ struct rpcif_op {
 	} data;
 };
 
+enum rpcif_type {
+	RPCIF_RCAR_GEN3,
+	RPCIF_RZ_G2L,
+};
+
 struct rpcif {
 	struct device *dev;
 	void __iomem *base;
@@ -64,6 +69,7 @@ struct rpcif {
 	struct regmap *regmap;
 	struct reset_control *rstc;
 	size_t size;
+	enum rpcif_type type;
 	enum rpcif_data_dir dir;
 	u8 bus_size;
 	void *buffer;
@@ -78,7 +84,7 @@ struct rpcif {
 };
 
 int rpcif_sw_init(struct rpcif *rpc, struct device *dev);
-void rpcif_hw_init(struct rpcif *rpc, bool hyperflash);
+int rpcif_hw_init(struct rpcif *rpc, bool hyperflash);
 void rpcif_prepare(struct rpcif *rpc, const struct rpcif_op *op, u64 *offs,
 		   size_t *len);
 int rpcif_manual_xfer(struct rpcif *rpc);
-- 
2.17.1



From boris.brezillon at collabora.com  Tue Sep 28 07:24:02 2021
From: boris.brezillon at collabora.com (Boris Brezillon)
Date: Tue, 28 Sep 2021 16:24:02 +0200
Subject: [PATCH] mtd: add MEMREAD ioctl
In-Reply-To: <20210928155859.433844cb@xps13>
References: <20210920070221.10173-1-kernel@kempniu.pl>
 <20210928155859.433844cb@xps13>
Message-ID: <20210928162402.6bb64fcf@collabora.com>

Hi Miquel, Michal,

On Tue, 28 Sep 2021 15:58:59 +0200
Miquel Raynal <miquel.raynal at bootlin.com> wrote:

> Hi Micha?,
> 
> + Boris just in case you have anything obvious that pops up in your
>   head when reading the description, otherwise no need to thoroughfully
>   review this ;)

Couple of comment below.


> > Signed-off-by: Micha? K?pie? <kernel at kempniu.pl>
> > ---
> > This patch is a shameless calque^W^W^Wheavily inspired by MEMWRITE code,
> > so quite a lot of copy-pasting happened.  I guess it is somewhat
> > expected when adding a read-side counterpart of existing code which
> > takes care of writes, but please excuse me if I went too far.
> > 
> > Note that "scripts/checkpatch.pl --strict" returns two alignment
> > warnings for this patch.  Given that existing code triggers the same
> > warnings, I assumed that local consistency trumps checkpatch.pl's
> > complaints.
> > 
> >  drivers/mtd/mtdchar.c      | 60 ++++++++++++++++++++++++++++++++++++++
> >  include/uapi/mtd/mtd-abi.h | 43 +++++++++++++++++++++++----
> >  2 files changed, 98 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
> > index 155e991d9d75..92e0024bdcf7 100644
> > --- a/drivers/mtd/mtdchar.c
> > +++ b/drivers/mtd/mtdchar.c
> > @@ -621,6 +621,58 @@ static int mtdchar_write_ioctl(struct mtd_info *mtd,
> >  	return ret;
> >  }
> >  
> > +static int mtdchar_read_ioctl(struct mtd_info *mtd,
> > +		struct mtd_read_req __user *argp)
> > +{
> > +	struct mtd_info *master = mtd_get_master(mtd);
> > +	struct mtd_read_req req;
> > +	struct mtd_oob_ops ops = {};
> > +	void __user *usr_data, *usr_oob;
> > +	int ret;
> > +
> > +	if (copy_from_user(&req, argp, sizeof(req)))
> > +		return -EFAULT;
> > +
> > +	usr_data = (void __user *)(uintptr_t)req.usr_data;
> > +	usr_oob = (void __user *)(uintptr_t)req.usr_oob;
> > +
> > +	if (!master->_read_oob)
> > +		return -EOPNOTSUPP;
> > +	ops.mode = req.mode;
> > +	ops.len = (size_t)req.len;
> > +	ops.ooblen = (size_t)req.ooblen;
> > +	ops.ooboffs = 0;
> > +
> > +	if (usr_data) {
> > +		ops.datbuf = kmalloc(ops.len, GFP_KERNEL);

Hm, I know the write path does that, but I'm really not sure
kmalloc()-ing a buffer of the requested read length is a good
idea. Having a loop doing reads with an erasesize granularity would
avoid this unbounded allocation while keeping performance acceptable in
most cases.

> > +		if (IS_ERR(ops.datbuf))
> > +			return PTR_ERR(ops.datbuf);
> > +	} else {
> > +		ops.datbuf = NULL;
> > +	}
> > +
> > +	if (usr_oob) {
> > +		ops.oobbuf = kmalloc(ops.ooblen, GFP_KERNEL);
> > +		if (IS_ERR(ops.oobbuf)) {
> > +			kfree(ops.datbuf);
> > +			return PTR_ERR(ops.oobbuf);
> > +		}
> > +	} else {
> > +		ops.oobbuf = NULL;
> > +	}
> > +
> > +	ret = mtd_read_oob(mtd, (loff_t)req.start, &ops);
> > +
> > +	if (copy_to_user(usr_data, ops.datbuf, ops.retlen) ||
> > +	    copy_to_user(usr_oob, ops.oobbuf, ops.oobretlen))
> > +		ret = -EFAULT;
> > +
> > +	kfree(ops.datbuf);
> > +	kfree(ops.oobbuf);
> > +
> > +	return ret;
> > +}
> > +
> >  static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
> >  {
> >  	struct mtd_file_info *mfi = file->private_data;
> > @@ -643,6 +695,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
> >  	case MEMGETINFO:
> >  	case MEMREADOOB:
> >  	case MEMREADOOB64:
> > +	case MEMREAD:
> >  	case MEMISLOCKED:
> >  	case MEMGETOOBSEL:
> >  	case MEMGETBADBLOCK:
> > @@ -817,6 +870,13 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
> >  		break;
> >  	}
> >  
> > +	case MEMREAD:
> > +	{
> > +		ret = mtdchar_read_ioctl(mtd,
> > +		      (struct mtd_read_req __user *)arg);
> > +		break;
> > +	}
> > +
> >  	case MEMLOCK:
> >  	{
> >  		struct erase_info_user einfo;
> > diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
> > index b869990c2db2..337e6e597fad 100644
> > --- a/include/uapi/mtd/mtd-abi.h
> > +++ b/include/uapi/mtd/mtd-abi.h
> > @@ -55,9 +55,9 @@ struct mtd_oob_buf64 {
> >   * @MTD_OPS_RAW:	data are transferred as-is, with no error correction;
> >   *			this mode implies %MTD_OPS_PLACE_OOB
> >   *
> > - * These modes can be passed to ioctl(MEMWRITE) and are also used internally.
> > - * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs.
> > - * %MTD_FILE_MODE_RAW.
> > + * These modes can be passed to ioctl(MEMWRITE) and ioctl(MEMREAD); they are
> > + * also used internally. See notes on "MTD file modes" for discussion on
> > + * %MTD_OPS_RAW vs. %MTD_FILE_MODE_RAW.
> >   */
> >  enum {
> >  	MTD_OPS_PLACE_OOB = 0,
> > @@ -91,6 +91,32 @@ struct mtd_write_req {
> >  	__u8 padding[7];
> >  };
> >  
> > +/**
> > + * struct mtd_read_req - data structure for requesting a read operation
> > + *
> > + * @start:	start address
> > + * @len:	length of data buffer
> > + * @ooblen:	length of OOB buffer
> > + * @usr_data:	user-provided data buffer
> > + * @usr_oob:	user-provided OOB buffer
> > + * @mode:	MTD mode (see "MTD operation modes")
> > + * @padding:	reserved, must be set to 0
> > + *
> > + * This structure supports ioctl(MEMREAD) operations, allowing data and/or OOB
> > + * reads in various modes. To read from OOB-only, set @usr_data == NULL, and to
> > + * read data-only, set @usr_oob == NULL. However, setting both @usr_data and
> > + * @usr_oob to NULL is not allowed.
> > + */
> > +struct mtd_read_req {
> > +	__u64 start;
> > +	__u64 len;
> > +	__u64 ooblen;
> > +	__u64 usr_data;
> > +	__u64 usr_oob;
> > +	__u8 mode;
> > +	__u8 padding[7];
> > +};

I do agree that a new interface is needed, but if we're adding a new
entry point, let's make sure it covers all possible use cases we have
now. At the very least, I think we're missing info about the maximum
number of corrected bits per ECC region on the portion being read.
Propagating EUCLEAN errors is nice, but it's not precise enough IMHO.

I remember discussing search a new READ ioctl with Sascha Hauer a few
years back, but I can't find the discussion...

Regards,

Boris


From ming.lei at redhat.com  Tue Sep 28 07:32:51 2021
From: ming.lei at redhat.com (Ming Lei)
Date: Tue, 28 Sep 2021 22:32:51 +0800
Subject: remove ->rq_disk
In-Reply-To: <20210928052211.112801-1-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
Message-ID: <YVMnk/8HIR/yhWYr@T590>

Hello Christoph,

On Tue, Sep 28, 2021 at 07:22:06AM +0200, Christoph Hellwig wrote:
> Hi Jens,
> 
> this series removes the rq_disk field in struct request, which isn't
> needed now that we can get the disk from the request_queue.

Can we hold on this series until q->disk becomes really reliable[1][2]?

[1] https://lore.kernel.org/linux-block/20210922172222.2453343-1-hch at lst.de/T/#t
[2] https://lore.kernel.org/linux-block/YUQOBKa67R9pEunr at T590.Home/#r


Thanks,
Ming



From miquel.raynal at bootlin.com  Tue Sep 28 07:35:19 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 28 Sep 2021 16:35:19 +0200
Subject: [PATCH] mtd: add MEMREAD ioctl
In-Reply-To: <20210928162402.6bb64fcf@collabora.com>
References: <20210920070221.10173-1-kernel@kempniu.pl>
 <20210928155859.433844cb@xps13>
 <20210928162402.6bb64fcf@collabora.com>
Message-ID: <20210928163519.08cd1138@xps13>

Hi Boris,

boris.brezillon at collabora.com wrote on Tue, 28 Sep 2021 16:24:02 +0200:

> Hi Miquel, Michal,
> 
> On Tue, 28 Sep 2021 15:58:59 +0200
> Miquel Raynal <miquel.raynal at bootlin.com> wrote:
> 
> > Hi Micha?,
> > 
> > + Boris just in case you have anything obvious that pops up in your
> >   head when reading the description, otherwise no need to thoroughfully
> >   review this ;)  
> 
> Couple of comment below.
> 
> 
> > > Signed-off-by: Micha? K?pie? <kernel at kempniu.pl>
> > > ---
> > > This patch is a shameless calque^W^W^Wheavily inspired by MEMWRITE code,
> > > so quite a lot of copy-pasting happened.  I guess it is somewhat
> > > expected when adding a read-side counterpart of existing code which
> > > takes care of writes, but please excuse me if I went too far.
> > > 
> > > Note that "scripts/checkpatch.pl --strict" returns two alignment
> > > warnings for this patch.  Given that existing code triggers the same
> > > warnings, I assumed that local consistency trumps checkpatch.pl's
> > > complaints.
> > > 
> > >  drivers/mtd/mtdchar.c      | 60 ++++++++++++++++++++++++++++++++++++++
> > >  include/uapi/mtd/mtd-abi.h | 43 +++++++++++++++++++++++----
> > >  2 files changed, 98 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
> > > index 155e991d9d75..92e0024bdcf7 100644
> > > --- a/drivers/mtd/mtdchar.c
> > > +++ b/drivers/mtd/mtdchar.c
> > > @@ -621,6 +621,58 @@ static int mtdchar_write_ioctl(struct mtd_info *mtd,
> > >  	return ret;
> > >  }
> > >  
> > > +static int mtdchar_read_ioctl(struct mtd_info *mtd,
> > > +		struct mtd_read_req __user *argp)
> > > +{
> > > +	struct mtd_info *master = mtd_get_master(mtd);
> > > +	struct mtd_read_req req;
> > > +	struct mtd_oob_ops ops = {};
> > > +	void __user *usr_data, *usr_oob;
> > > +	int ret;
> > > +
> > > +	if (copy_from_user(&req, argp, sizeof(req)))
> > > +		return -EFAULT;
> > > +
> > > +	usr_data = (void __user *)(uintptr_t)req.usr_data;
> > > +	usr_oob = (void __user *)(uintptr_t)req.usr_oob;
> > > +
> > > +	if (!master->_read_oob)
> > > +		return -EOPNOTSUPP;
> > > +	ops.mode = req.mode;
> > > +	ops.len = (size_t)req.len;
> > > +	ops.ooblen = (size_t)req.ooblen;
> > > +	ops.ooboffs = 0;
> > > +
> > > +	if (usr_data) {
> > > +		ops.datbuf = kmalloc(ops.len, GFP_KERNEL);  
> 
> Hm, I know the write path does that, but I'm really not sure
> kmalloc()-ing a buffer of the requested read length is a good
> idea. Having a loop doing reads with an erasesize granularity would
> avoid this unbounded allocation while keeping performance acceptable in
> most cases.

Right.

> 
> > > +		if (IS_ERR(ops.datbuf))
> > > +			return PTR_ERR(ops.datbuf);
> > > +	} else {
> > > +		ops.datbuf = NULL;
> > > +	}
> > > +
> > > +	if (usr_oob) {
> > > +		ops.oobbuf = kmalloc(ops.ooblen, GFP_KERNEL);
> > > +		if (IS_ERR(ops.oobbuf)) {
> > > +			kfree(ops.datbuf);
> > > +			return PTR_ERR(ops.oobbuf);
> > > +		}
> > > +	} else {
> > > +		ops.oobbuf = NULL;
> > > +	}
> > > +
> > > +	ret = mtd_read_oob(mtd, (loff_t)req.start, &ops);
> > > +
> > > +	if (copy_to_user(usr_data, ops.datbuf, ops.retlen) ||
> > > +	    copy_to_user(usr_oob, ops.oobbuf, ops.oobretlen))
> > > +		ret = -EFAULT;
> > > +
> > > +	kfree(ops.datbuf);
> > > +	kfree(ops.oobbuf);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > >  static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
> > >  {
> > >  	struct mtd_file_info *mfi = file->private_data;
> > > @@ -643,6 +695,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
> > >  	case MEMGETINFO:
> > >  	case MEMREADOOB:
> > >  	case MEMREADOOB64:
> > > +	case MEMREAD:
> > >  	case MEMISLOCKED:
> > >  	case MEMGETOOBSEL:
> > >  	case MEMGETBADBLOCK:
> > > @@ -817,6 +870,13 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
> > >  		break;
> > >  	}
> > >  
> > > +	case MEMREAD:
> > > +	{
> > > +		ret = mtdchar_read_ioctl(mtd,
> > > +		      (struct mtd_read_req __user *)arg);
> > > +		break;
> > > +	}
> > > +
> > >  	case MEMLOCK:
> > >  	{
> > >  		struct erase_info_user einfo;
> > > diff --git a/include/uapi/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
> > > index b869990c2db2..337e6e597fad 100644
> > > --- a/include/uapi/mtd/mtd-abi.h
> > > +++ b/include/uapi/mtd/mtd-abi.h
> > > @@ -55,9 +55,9 @@ struct mtd_oob_buf64 {
> > >   * @MTD_OPS_RAW:	data are transferred as-is, with no error correction;
> > >   *			this mode implies %MTD_OPS_PLACE_OOB
> > >   *
> > > - * These modes can be passed to ioctl(MEMWRITE) and are also used internally.
> > > - * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs.
> > > - * %MTD_FILE_MODE_RAW.
> > > + * These modes can be passed to ioctl(MEMWRITE) and ioctl(MEMREAD); they are
> > > + * also used internally. See notes on "MTD file modes" for discussion on
> > > + * %MTD_OPS_RAW vs. %MTD_FILE_MODE_RAW.
> > >   */
> > >  enum {
> > >  	MTD_OPS_PLACE_OOB = 0,
> > > @@ -91,6 +91,32 @@ struct mtd_write_req {
> > >  	__u8 padding[7];
> > >  };
> > >  
> > > +/**
> > > + * struct mtd_read_req - data structure for requesting a read operation
> > > + *
> > > + * @start:	start address
> > > + * @len:	length of data buffer
> > > + * @ooblen:	length of OOB buffer
> > > + * @usr_data:	user-provided data buffer
> > > + * @usr_oob:	user-provided OOB buffer
> > > + * @mode:	MTD mode (see "MTD operation modes")
> > > + * @padding:	reserved, must be set to 0
> > > + *
> > > + * This structure supports ioctl(MEMREAD) operations, allowing data and/or OOB
> > > + * reads in various modes. To read from OOB-only, set @usr_data == NULL, and to
> > > + * read data-only, set @usr_oob == NULL. However, setting both @usr_data and
> > > + * @usr_oob to NULL is not allowed.
> > > + */
> > > +struct mtd_read_req {
> > > +	__u64 start;
> > > +	__u64 len;
> > > +	__u64 ooblen;
> > > +	__u64 usr_data;
> > > +	__u64 usr_oob;
> > > +	__u8 mode;
> > > +	__u8 padding[7];
> > > +};  
> 
> I do agree that a new interface is needed, but if we're adding a new
> entry point, let's make sure it covers all possible use cases we have
> now. At the very least, I think we're missing info about the maximum
> number of corrected bits per ECC region on the portion being read.
> Propagating EUCLEAN errors is nice, but it's not precise enough IMHO.
> 
> I remember discussing search a new READ ioctl with Sascha Hauer a few
> years back, but I can't find the discussion...

We also discussed a mtd_io_op some time ago, which would equivalently
replace mtd_oob_ops at some point, including more information such as
the bitflips which happened on every chunk instead of the information
regarding the maximum number of bitflips in one of the chunks only.
IIRC the point was to get rid of the mtd_{read,write}{,_oob} hooks and
structures in favor of a more robust and complete set of operations.



From kari at americanagent.com  Tue Sep 28 07:29:37 2021
From: kari at americanagent.com (Kari Koivuniemi)
Date: 28 Sep 2021 16:29:37 +0200
Subject: New Order
Message-ID: <20210928162937.A8B1F8401CF91F41@americanagent.com>

Hi

Kindly find our PO attached for your reference. 
Send us Invoice with Payment details for payment processing.




Mr. Kari Koivuniemi
American Agent (LLC)
www.AmericanAgent.com
E-mail: kari at americanagent.com
Tel: 312.239.0893
SKYPE: americanagent
Chicago-NYC-Philadelphia
-----------------------------------------
Distributor Search - Direct to market - Representative Search - 
Logistics - Legal - Tradeshow marketing and support
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Order specification & Drawing_Docx.z
Type: application/octet-stream
Size: 54973 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210928/c4ce1d28/attachment-0001.obj>

From mani at kernel.org  Tue Sep 28 08:17:37 2021
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 28 Sep 2021 20:47:37 +0530
Subject: [PATCH 0/3] Add support for page scope read
In-Reply-To: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
Message-ID: <20210928151737.GA12183@thinkpad>

Hi,

On Wed, Sep 15, 2021 at 03:27:28PM +0530, Md Sadre Alam wrote:
> These series of patches to support page scope read.
> 
> In QPIC v1, SW is needed to write EXEC_CMD register
> for each Code word and collect any Status related to
> that CW before issueing EXEC_CMD for next CW.
> 
> Page scope command, currently supported only for read
> commands in bam mode, is truly a page mode command where
> SW is required to issue EXEC_CMD only once for a page.
> Controller HW takes care of Codeword specific details
> and automatically returns status associated with each
> CW to BAM pipe, dedicated for status deposition.
> 

This description doesn't clearly convey the intention of the patches. Please
take time to write the cover letter describing what the patches do and how
they solve a problem.

If possible, do mention the platform on which the patches were tested.

And please avoid using Qualcomm specific acronymns such as CW as it only makes
sense to limited amount of people who has access to technical documents.

Thanks,
Mani

> Md Sadre Alam (3):
>   mtd: rawnand: qcom: Add support for status pipe
>   mtd: rawnand: qcom: Add sg list to handle status pipe request
>   mtd: rawnand: qcom: Add support for page scope read
> 
>  drivers/mtd/nand/raw/qcom_nandc.c | 125 ++++++++++++++++++++++++++++++++++++--
>  1 file changed, 119 insertions(+), 6 deletions(-)
> 
> -- 
> 2.7.4
> 


From troglobit at gmail.com  Tue Sep 28 08:49:38 2021
From: troglobit at gmail.com (Joachim Wiberg)
Date: Tue, 28 Sep 2021 17:49:38 +0200
Subject: [RFC PATCH 1/1] mtd: block2mtd: add support for an optional custom
 MTD label
Message-ID: <20210928154937.2668575-1-troglobit@gmail.com>

This patch adds support for an optional MTD label for mtd2block emulated
MTD devices.  Useful when, e.g. testing device images using Qemu.  The
following /etc/fstab line in can then be used to mount a file system
regardless of the actual MTD partition number:

    mtd:Config  /mnt    jffs2   noatime,nodiratime      0    0

Kernel command line syntax:

    block2mtd.block2mtd=/dev/sda,,Config

The ',,' is the optional erase_size, which like before this patch,
defaults to PAGE_SIZE when omitted.

Signed-off-by: Joachim Wiberg <troglobit at gmail.com>
---
 drivers/mtd/devices/block2mtd.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
index c08721b11642..87cdf041a218 100644
--- a/drivers/mtd/devices/block2mtd.c
+++ b/drivers/mtd/devices/block2mtd.c
@@ -214,7 +214,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
 
 
 static struct block2mtd_dev *add_device(char *devname, int erase_size,
-		int timeout)
+		char *label, int timeout)
 {
 #ifndef MODULE
 	int i;
@@ -278,7 +278,10 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
 
 	/* Setup the MTD structure */
 	/* make the name contain the block device in */
-	name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname);
+	if (!label)
+		name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname);
+	else
+		name = kstrdup(label, GFP_KERNEL);
 	if (!name)
 		goto err_destroy_mutex;
 
@@ -304,7 +307,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
 
 	list_add(&dev->list, &blkmtd_device_list);
 	pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n",
-		dev->mtd.index,
+		dev->mtd.index, label ? label :
 		dev->mtd.name + strlen("block2mtd: "),
 		dev->mtd.erasesize >> 10, dev->mtd.erasesize);
 	return dev;
@@ -381,8 +384,8 @@ static int block2mtd_setup2(const char *val)
 	/* 80 for device, 12 for erase size, 80 for name, 8 for timeout */
 	char buf[80 + 12 + 80 + 8];
 	char *str = buf;
-	char *token[2];
-	char *name;
+	char *token[3];
+	char *name, *label = NULL;
 	size_t erase_size = PAGE_SIZE;
 	unsigned long timeout = MTD_DEFAULT_TIMEOUT;
 	int i, ret;
@@ -395,7 +398,7 @@ static int block2mtd_setup2(const char *val)
 	strcpy(str, val);
 	kill_final_newline(str);
 
-	for (i = 0; i < 2; i++)
+	for (i = 0; i < 3; i++)
 		token[i] = strsep(&str, ",");
 
 	if (str) {
@@ -414,7 +417,7 @@ static int block2mtd_setup2(const char *val)
 		return 0;
 	}
 
-	if (token[1]) {
+	if (token[1] && strlen(token[1])) {
 		ret = parse_num(&erase_size, token[1]);
 		if (ret) {
 			pr_err("illegal erase size\n");
@@ -422,7 +425,12 @@ static int block2mtd_setup2(const char *val)
 		}
 	}
 
-	add_device(name, erase_size, timeout);
+	if (token[2]) {
+		label = token[2];
+		pr_info("Using custom MTD label '%s' for dev %s\n", label, name);
+	}
+
+	add_device(name, erase_size, label, timeout);
 
 	return 0;
 }
@@ -456,7 +464,7 @@ static int block2mtd_setup(const char *val, const struct kernel_param *kp)
 
 
 module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200);
-MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\"");
+MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,[<erasesize>][,<name>]]\"");
 
 static int __init block2mtd_init(void)
 {
-- 
2.25.1



From mani at kernel.org  Tue Sep 28 08:52:05 2021
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 28 Sep 2021 21:22:05 +0530
Subject: [PATCH 1/3] mtd: rawnand: qcom: Add support for status pipe
In-Reply-To: <1631699851-12172-2-git-send-email-mdalam@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
 <1631699851-12172-2-git-send-email-mdalam@codeaurora.org>
Message-ID: <20210928155205.GB12183@thinkpad>

On Wed, Sep 15, 2021 at 03:27:29PM +0530, Md Sadre Alam wrote:
> From QPIC V2.0 onwards there is a separate pipe
> to read status of each code word, called "status" pipe.
> 
> "status" pipe will use to read CW status in case of
> enhanced read mode like page scope read, multi page read.
> 

The pipe you are referring to is a DMA pipe (channel). So it should be mentioned
here.

> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> ---
>  drivers/mtd/nand/raw/qcom_nandc.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
> index 04e6f7b..42c6291 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -389,6 +389,7 @@ struct qcom_nand_controller {
>  			struct dma_chan *tx_chan;
>  			struct dma_chan *rx_chan;
>  			struct dma_chan *cmd_chan;
> +			struct dma_chan *sts_chan;
>  		};
>  
>  		/* will be used only by EBI2 for ADM DMA */
> @@ -2737,6 +2738,11 @@ static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
>  
>  		if (nandc->cmd_chan)
>  			dma_release_channel(nandc->cmd_chan);
> +
> +		if (nandc->props->qpic_v2) {
> +			if (nandc->sts_chan)
> +				dma_release_channel(nandc->sts_chan);
> +		}
>  	} else {
>  		if (nandc->chan)
>  			dma_release_channel(nandc->chan);
> @@ -2815,6 +2821,14 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
>  			goto unalloc;
>  		}
>  
> +		if (nandc->props->qpic_v2) {
> +			nandc->sts_chan = dma_request_slave_channel(nandc->dev, "sts");
> +			if (!nandc->sts_chan) {
> +				dev_err(nandc->dev, "failed to request sts channel\n");
> +				return -ENODEV;
> +			}

If you are forcing the need of status pipe, then you should also update the
devicetree of relevant SoCs using the QPIC v2 controller. Else, they will fail
to probe.

Thanks,
Mani

> +		}
> +
>  		/*
>  		 * Initially allocate BAM transaction to read ONFI param page.
>  		 * After detecting all the devices, this BAM transaction will
> -- 
> 2.7.4
> 


From mani at kernel.org  Tue Sep 28 09:03:15 2021
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 28 Sep 2021 21:33:15 +0530
Subject: [PATCH 2/3] mtd: rawnand: qcom: Add sg list to handle status
 pipe request
In-Reply-To: <1631699851-12172-3-git-send-email-mdalam@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
 <1631699851-12172-3-git-send-email-mdalam@codeaurora.org>
Message-ID: <20210928160315.GC12183@thinkpad>

On Wed, Sep 15, 2021 at 03:27:30PM +0530, Md Sadre Alam wrote:
> From QPIC V2.0 onwards there is separate pipe to read status
> for each code word while reading in enhanced mode. page scope
> read and multi page read.
> 
> This sgl list will be use to handle the request via status pipe
> during page scope and multi page read.
> 
> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> ---
>  drivers/mtd/nand/raw/qcom_nandc.c | 34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
> index 42c6291..07448c4 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -213,6 +213,7 @@ nandc_set_reg(chip, reg,			\
>  #define QPIC_PER_CW_CMD_ELEMENTS	32
>  #define QPIC_PER_CW_CMD_SGL		32
>  #define QPIC_PER_CW_DATA_SGL		8
> +#define	QPIC_PER_CW_STS_SGL		8

Use space after #define

>  
>  #define QPIC_NAND_COMPLETION_TIMEOUT	msecs_to_jiffies(2000)
>  
> @@ -258,6 +259,7 @@ struct bam_transaction {
>  	struct bam_cmd_element *bam_ce;
>  	struct scatterlist *cmd_sgl;
>  	struct scatterlist *data_sgl;
> +	struct scatterlist *sts_sgl;
>  	u32 bam_ce_pos;
>  	u32 bam_ce_start;
>  	u32 cmd_sgl_pos;
> @@ -266,6 +268,8 @@ struct bam_transaction {
>  	u32 tx_sgl_start;
>  	u32 rx_sgl_pos;
>  	u32 rx_sgl_start;
> +	u32 sts_sgl_pos;
> +	u32 sts_sgl_start;
>  	bool wait_second_completion;
>  	struct completion txn_done;
>  	struct dma_async_tx_descriptor *last_data_desc;
> @@ -508,6 +512,8 @@ alloc_bam_transaction(struct qcom_nand_controller *nandc)
>  		((sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS) +
>  		(sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) +
>  		(sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL));
> +	if (nandc->props->qpic_v2)
> +		bam_txn_size += (sizeof(*bam_txn->sts_sgl) * QPIC_PER_CW_STS_SGL);
>  
>  	bam_txn_buf = devm_kzalloc(nandc->dev, bam_txn_size, GFP_KERNEL);
>  	if (!bam_txn_buf)
> @@ -526,6 +532,12 @@ alloc_bam_transaction(struct qcom_nand_controller *nandc)
>  
>  	bam_txn->data_sgl = bam_txn_buf;
>  
> +	if (nandc->props->qpic_v2) {
> +		bam_txn_buf +=
> +			sizeof(*bam_txn->sts_sgl) * QPIC_PER_CW_STS_SGL * num_cw;
> +		bam_txn->sts_sgl = bam_txn_buf;
> +	}
> +
>  	init_completion(&bam_txn->txn_done);
>  
>  	return bam_txn;
> @@ -554,6 +566,12 @@ static void clear_bam_transaction(struct qcom_nand_controller *nandc)
>  		      QPIC_PER_CW_CMD_SGL);
>  	sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage *
>  		      QPIC_PER_CW_DATA_SGL);
> +	if (nandc->props->qpic_v2) {
> +		bam_txn->sts_sgl_pos = 0;
> +		bam_txn->sts_sgl_start = 0;
> +		sg_init_table(bam_txn->sts_sgl, nandc->max_cwperpage *
> +				QPIC_PER_CW_STS_SGL);
> +	}
>  
>  	reinit_completion(&bam_txn->txn_done);
>  }
> @@ -808,6 +826,12 @@ static int prepare_bam_async_desc(struct qcom_nand_controller *nandc,
>  		bam_txn->tx_sgl_start = bam_txn->tx_sgl_pos;
>  		dir_eng = DMA_MEM_TO_DEV;
>  		desc->dir = DMA_TO_DEVICE;
> +	} else if (nandc->props->qpic_v2 && chan == nandc->sts_chan) {

These two are mutually inclusive, so why can't you simply check for the
existence of "nanc->sts_chan"?

> +		sgl = &bam_txn->sts_sgl[bam_txn->sts_sgl_start];
> +		sgl_cnt = bam_txn->sts_sgl_pos - bam_txn->sts_sgl_start;
> +		bam_txn->sts_sgl_start = bam_txn->sts_sgl_pos;
> +		dir_eng = DMA_DEV_TO_MEM;
> +		desc->dir = DMA_FROM_DEVICE;
>  	} else {
>  		sgl = &bam_txn->data_sgl[bam_txn->rx_sgl_start];
>  		sgl_cnt = bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start;
> @@ -1394,6 +1418,14 @@ static int submit_descs(struct qcom_nand_controller *nandc)
>  			if (r)
>  				return r;
>  		}
> +
> +		if (nandc->props->qpic_v2) {

I feel like you should just check for "nandc->sts_chan" instead of qpic_v2. This
will make the driver work with future revisions of the IP as well.

> +			if (bam_txn->sts_sgl_pos > bam_txn->sts_sgl_start) {
> +				r = prepare_bam_async_desc(nandc, nandc->sts_chan, 0);
> +				if (r)
> +					return r;
> +			}
> +		}
>  	}
>  
>  	list_for_each_entry(desc, &nandc->desc_list, node)
> @@ -1411,6 +1443,8 @@ static int submit_descs(struct qcom_nand_controller *nandc)
>  		dma_async_issue_pending(nandc->tx_chan);
>  		dma_async_issue_pending(nandc->rx_chan);
>  		dma_async_issue_pending(nandc->cmd_chan);
> +		if (nandc->props->qpic_v2)
> +			dma_async_issue_pending(nandc->sts_chan);

Same here.

Thanks,
Mani

>  
>  		if (!wait_for_completion_timeout(&bam_txn->txn_done,
>  						 QPIC_NAND_COMPLETION_TIMEOUT))
> -- 
> 2.7.4
> 


From miquel.raynal at bootlin.com  Tue Sep 28 09:05:21 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 28 Sep 2021 18:05:21 +0200
Subject: [RFC PATCH 1/1] mtd: block2mtd: add support for an optional
 custom MTD label
In-Reply-To: <20210928154937.2668575-1-troglobit@gmail.com>
References: <20210928154937.2668575-1-troglobit@gmail.com>
Message-ID: <20210928180521.4516405c@xps13>

Hi Joachim,

troglobit at gmail.com wrote on Tue, 28 Sep 2021 17:49:38 +0200:

> This patch adds support for an optional MTD label for mtd2block emulated
> MTD devices.  Useful when, e.g. testing device images using Qemu.  The
> following /etc/fstab line in can then be used to mount a file system
> regardless of the actual MTD partition number:
> 
>     mtd:Config  /mnt    jffs2   noatime,nodiratime      0    0
> 
> Kernel command line syntax:
> 
>     block2mtd.block2mtd=/dev/sda,,Config
> 
> The ',,' is the optional erase_size, which like before this patch,
> defaults to PAGE_SIZE when omitted.

We already have a label property that can be added in the DT, isn't
it enough?

Thanks,
Miqu?l

> 
> Signed-off-by: Joachim Wiberg <troglobit at gmail.com>
> ---
>  drivers/mtd/devices/block2mtd.c | 26 +++++++++++++++++---------
>  1 file changed, 17 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
> index c08721b11642..87cdf041a218 100644
> --- a/drivers/mtd/devices/block2mtd.c
> +++ b/drivers/mtd/devices/block2mtd.c
> @@ -214,7 +214,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev)
>  
>  
>  static struct block2mtd_dev *add_device(char *devname, int erase_size,
> -		int timeout)
> +		char *label, int timeout)
>  {
>  #ifndef MODULE
>  	int i;
> @@ -278,7 +278,10 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
>  
>  	/* Setup the MTD structure */
>  	/* make the name contain the block device in */
> -	name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname);
> +	if (!label)
> +		name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname);
> +	else
> +		name = kstrdup(label, GFP_KERNEL);
>  	if (!name)
>  		goto err_destroy_mutex;
>  
> @@ -304,7 +307,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size,
>  
>  	list_add(&dev->list, &blkmtd_device_list);
>  	pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n",
> -		dev->mtd.index,
> +		dev->mtd.index, label ? label :
>  		dev->mtd.name + strlen("block2mtd: "),
>  		dev->mtd.erasesize >> 10, dev->mtd.erasesize);
>  	return dev;
> @@ -381,8 +384,8 @@ static int block2mtd_setup2(const char *val)
>  	/* 80 for device, 12 for erase size, 80 for name, 8 for timeout */
>  	char buf[80 + 12 + 80 + 8];
>  	char *str = buf;
> -	char *token[2];
> -	char *name;
> +	char *token[3];
> +	char *name, *label = NULL;
>  	size_t erase_size = PAGE_SIZE;
>  	unsigned long timeout = MTD_DEFAULT_TIMEOUT;
>  	int i, ret;
> @@ -395,7 +398,7 @@ static int block2mtd_setup2(const char *val)
>  	strcpy(str, val);
>  	kill_final_newline(str);
>  
> -	for (i = 0; i < 2; i++)
> +	for (i = 0; i < 3; i++)
>  		token[i] = strsep(&str, ",");
>  
>  	if (str) {
> @@ -414,7 +417,7 @@ static int block2mtd_setup2(const char *val)
>  		return 0;
>  	}
>  
> -	if (token[1]) {
> +	if (token[1] && strlen(token[1])) {
>  		ret = parse_num(&erase_size, token[1]);
>  		if (ret) {
>  			pr_err("illegal erase size\n");
> @@ -422,7 +425,12 @@ static int block2mtd_setup2(const char *val)
>  		}
>  	}
>  
> -	add_device(name, erase_size, timeout);
> +	if (token[2]) {
> +		label = token[2];
> +		pr_info("Using custom MTD label '%s' for dev %s\n", label, name);
> +	}
> +
> +	add_device(name, erase_size, label, timeout);
>  
>  	return 0;
>  }
> @@ -456,7 +464,7 @@ static int block2mtd_setup(const char *val, const struct kernel_param *kp)
>  
>  
>  module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200);
> -MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\"");
> +MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,[<erasesize>][,<name>]]\"");
>  
>  static int __init block2mtd_init(void)
>  {



From mani at kernel.org  Tue Sep 28 09:12:19 2021
From: mani at kernel.org (Manivannan Sadhasivam)
Date: Tue, 28 Sep 2021 21:42:19 +0530
Subject: [PATCH 3/3] mtd: rawnand: qcom: Add support for page scope read
In-Reply-To: <1631699851-12172-4-git-send-email-mdalam@codeaurora.org>
References: <1631699851-12172-1-git-send-email-mdalam@codeaurora.org>
 <1631699851-12172-4-git-send-email-mdalam@codeaurora.org>
Message-ID: <20210928161219.GD12183@thinkpad>

On Wed, Sep 15, 2021 at 03:27:31PM +0530, Md Sadre Alam wrote:
> QPIC V2.0 onwards QPIC controller support enhanced read mode
> like page scope read and multi page read.
> 

Define page scope read.

> In QPIC V1, SW is needed to write EXEC_CMD register for each
> Code word and collect any Status related to that CW before
> issueing EXEC_CMD for next CW.
> 
> Page scope command is truly a page mode command where SW is
> required to issue EXEC_CMD only once for a page. Controller
> HW takes care of Codeword specific details and automatically
> returns status associated with each CW to BAM pipe, dedicated
> for status deposition.
> 
> With this command, SW now can issue one read command for a page
> and upon receiving completion interrupt, can process status,
> that have already been deposited in memory through status BAM pipe.
> 
> Signed-off-by: Md Sadre Alam <mdalam at codeaurora.org>
> ---
>  drivers/mtd/nand/raw/qcom_nandc.c | 77 ++++++++++++++++++++++++++++++++++++---
>  1 file changed, 71 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
> index 07448c4..257dec7e 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -157,6 +157,10 @@
>  #define	OP_FETCH_ID			0xb
>  #define	OP_RESET_DEVICE			0xd
>  
> +/* Auto status val and mask */
> +#define	AUTO_STS_VAL			0x000B000B

Use non-cap hex.

> +#define PAGE_SCOPE_READ			BIT(23)
> +
>  /* Default Value for NAND_DEV_CMD_VLD */
>  #define NAND_DEV_CMD_VLD_VAL		(READ_START_VLD | WRITE_START_VLD | \
>  					 ERASE_START_VLD | SEQ_READ_START_VLD)
> @@ -336,6 +340,8 @@ struct nandc_regs {
>  
>  	__le32 erased_cw_detect_cfg_clr;
>  	__le32 erased_cw_detect_cfg_set;
> +
> +	__le32 auto_sts_en;
>  };
>  
>  /*
> @@ -421,6 +427,9 @@ struct qcom_nand_controller {
>  
>  	u32 cmd1, vld;
>  	const struct qcom_nandc_props *props;
> +
> +	__le32 *status_buf;
> +	int sts_buf_size;

Add kdoc for these two members.

>  };
>  
>  /*
> @@ -487,6 +496,7 @@ struct qcom_nandc_props {
>  	bool is_bam;
>  	bool is_qpic;
>  	bool qpic_v2;
> +	bool page_scope;
>  	u32 dev_cmd_reg_start;
>  };
>  
> @@ -656,6 +666,8 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset)
>  		return &regs->cfg1;
>  	case NAND_DEV0_ECC_CFG:
>  		return &regs->ecc_bch_cfg;
> +	case NAND_AUTO_STATUS_EN:
> +		return &regs->auto_sts_en;
>  	case NAND_READ_STATUS:
>  		return &regs->clrreadstatus;
>  	case NAND_DEV_CMD1:
> @@ -756,10 +768,13 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read, i
>  	struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
>  
>  	if (read) {
> -		if (host->use_ecc)
> +		if (host->use_ecc) {
>  			cmd = OP_PAGE_READ_WITH_ECC | PAGE_ACC | LAST_PAGE;
> -		else
> +			if (nandc->props->qpic_v2 && nandc->props->page_scope)

Again, why you are checking for both conditions? Using "page_scope" is
sufficient enough.

> +				cmd |= PAGE_SCOPE_READ;
> +		} else {
>  			cmd = OP_PAGE_READ | PAGE_ACC | LAST_PAGE;
> +		}
>  	} else {
>  		cmd = OP_PROGRAM_PAGE | PAGE_ACC | LAST_PAGE;
>  	}

[...]

>  	if (use_ecc) {
> -		read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
> -		read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
> -			     NAND_BAM_NEXT_SGL);
> +		if (nandc->props->qpic_v2 && nandc->props->page_scope) {
> +			if (qcom_nandc_is_last_cw(ecc, cw))
> +				write_reg_dma(nandc, NAND_EXEC_CMD, 1,
> +					      NAND_BAM_NEXT_SGL);
> +		} else {
> +			write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
> +			read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
> +			read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
> +				     NAND_BAM_NEXT_SGL);
> +		}

You need to add a comment for this.

Thanks,
Mani


From p.yadav at ti.com  Tue Sep 28 09:34:05 2021
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 28 Sep 2021 22:04:05 +0530
Subject: [PATCH] mtd: spi-nor: Add support for ZB25VQ128
In-Reply-To: <CAFr9PX=xKoa9fCbYf6Mpn=oudnY7A=6meKBSmzNHYLFad364tw@mail.gmail.com>
References: <20210918072256.3505379-1-daniel@0x0f.com>
 <20210920112625.fnqayim5mg5iggag@ti.com>
 <CAFr9PX=xKoa9fCbYf6Mpn=oudnY7A=6meKBSmzNHYLFad364tw@mail.gmail.com>
Message-ID: <20210928163403.iufy6rgn7imiebpz@ti.com>

On 28/09/21 10:15PM, Daniel Palmer wrote:
> Hi Pratyush,
> 
> On Mon, 20 Sept 2021 at 20:26, Pratyush Yadav <p.yadav at ti.com> wrote:
> >
> > Zbit should be in bank 10, so it should be preceeded by 9 0x7f bytes,
> > correct? I don't see any logic to handle that in SPI NOR currently so I
> > assume this manufacturer does not implement the continuation codes.
> >
> > In that case, it should go to the manufacturer collisions driver
> > proposed here [0].
> >
> > [0] https://patchwork.ozlabs.org/project/linux-mtd/patch/20210727045222.905056-6-tudor.ambarus at microchip.com/
> 
> Sorry, I'm not sure what I should do with this information. I didn't
> even know about the continuation codes thing until now.
> Is there something I need to do here or do I just need to wait for the
> collision handling code to get merged?

I think that should be what you need to do. Tudor, any plans on 
re-rolling that patch series in the near future?

> 
> Thanks,
> 
> Daniel

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From chaitanyak at nvidia.com  Tue Sep 28 14:11:50 2021
From: chaitanyak at nvidia.com (Chaitanya Kulkarni)
Date: Tue, 28 Sep 2021 21:11:50 +0000
Subject: [PATCH 3/5] block: remove the ->rq_disk field in struct request
In-Reply-To: <20210928052211.112801-4-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
 <20210928052211.112801-4-hch@lst.de>
Message-ID: <e88de776-fae9-7241-b741-9cf467f0965a@nvidia.com>

On 9/27/21 10:22 PM, Christoph Hellwig wrote:
> Just use the disk attached to the request_queue instead.
> 
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---

Please consider adding :-

root at dev linux-block (for-next) # git diff drivers/mtd
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index b8ae1ec14e17..f0488694afdb 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -59,7 +59,7 @@ static blk_status_t do_blktrans_request(struct 
mtd_blktrans_ops *tr,
         }

         if (blk_rq_pos(req) + blk_rq_cur_sectors(req) >
-           get_capacity(req->rq_disk))
+           get_capacity(req->q->disk))
                 return BLK_STS_IOERR;

         switch (req_op(req)) {

* Without above patch :-

root at dev linux-block (for-next) # makej drivers/mtd/
   DESCEND objtool
   CALL    scripts/atomic/check-atomics.sh
   CALL    scripts/checksyscalls.sh
   CC [M]  drivers/mtd/mtd_blkdevs.o
   CC [M]  drivers/mtd/mtdblock.o
   LD [M]  drivers/mtd/mtd.o
drivers/mtd/mtd_blkdevs.c: In function ?do_blktrans_request?:
drivers/mtd/mtd_blkdevs.c:62:29: error: ?struct request? has no member 
named ?rq_disk?
    62 |             get_capacity(req->rq_disk))
       |                             ^~
make[2]: *** [scripts/Makefile.build:277: drivers/mtd/mtd_blkdevs.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [scripts/Makefile.build:540: drivers/mtd] Error 2
make: *** [Makefile:1868: drivers] Error 2
root at dev linux-block (for-next) #

* With above patch :-

root at dev linux-block (for-next) # makej drivers/mtd/
   DESCEND objtool
   CALL    scripts/atomic/check-atomics.sh
   CALL    scripts/checksyscalls.sh
   CC [M]  drivers/mtd/mtd_blkdevs.o

-ck

From chaitanyak at nvidia.com  Tue Sep 28 14:21:25 2021
From: chaitanyak at nvidia.com (Chaitanya Kulkarni)
Date: Tue, 28 Sep 2021 21:21:25 +0000
Subject: [PATCH 3/5] block: remove the ->rq_disk field in struct request
In-Reply-To: <e88de776-fae9-7241-b741-9cf467f0965a@nvidia.com>
References: <20210928052211.112801-1-hch@lst.de>
 <20210928052211.112801-4-hch@lst.de>
 <e88de776-fae9-7241-b741-9cf467f0965a@nvidia.com>
Message-ID: <e9a6e00f-60e1-c604-9e08-3789fd057df9@nvidia.com>

On 9/28/21 2:11 PM, Chaitanya Kulkarni wrote:
> External email: Use caution opening links or attachments
> 
> 
> On 9/27/21 10:22 PM, Christoph Hellwig wrote:
>> Just use the disk attached to the request_queue instead.
>>
>> Signed-off-by: Christoph Hellwig <hch at lst.de>
>> ---
> 
> Please consider adding :-
> 
> root at dev linux-block (for-next) # git diff drivers/mtd
> diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
> index b8ae1ec14e17..f0488694afdb 100644
> --- a/drivers/mtd/mtd_blkdevs.c
> +++ b/drivers/mtd/mtd_blkdevs.c
> @@ -59,7 +59,7 @@ static blk_status_t do_blktrans_request(struct
> mtd_blktrans_ops *tr,
>           }
> 
>           if (blk_rq_pos(req) + blk_rq_cur_sectors(req) >
> -           get_capacity(req->rq_disk))
> +           get_capacity(req->q->disk))
>                   return BLK_STS_IOERR;
> 
>           switch (req_op(req)) {
> 

sorry for the noise, you have already done it in patch 1,
when I applied patch 1 it failed on my tree due to copy paste
error and I missed it ..





From chaitanyak at nvidia.com  Tue Sep 28 14:22:12 2021
From: chaitanyak at nvidia.com (Chaitanya Kulkarni)
Date: Tue, 28 Sep 2021 21:22:12 +0000
Subject: [PATCH 3/5] block: remove the ->rq_disk field in struct request
In-Reply-To: <20210928052211.112801-4-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
 <20210928052211.112801-4-hch@lst.de>
Message-ID: <244ce3f6-5391-de3a-3ba0-70d4605d32a7@nvidia.com>

On 9/27/21 10:22 PM, Christoph Hellwig wrote:
> Just use the disk attached to the request_queue instead.
> 
> Signed-off-by: Christoph Hellwig <hch at lst.de>

Looks good.

Reviewed-by: Chaitanya Kulkarni <kch at nvidia.com>


From chaitanyak at nvidia.com  Tue Sep 28 14:23:36 2021
From: chaitanyak at nvidia.com (Chaitanya Kulkarni)
Date: Tue, 28 Sep 2021 21:23:36 +0000
Subject: [PATCH 4/5] block: remove the gendisk argument to blk_execute_rq
In-Reply-To: <20210928052211.112801-5-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
 <20210928052211.112801-5-hch@lst.de>
Message-ID: <095ef848-5161-cf85-d043-7c784fa0871a@nvidia.com>

On 9/27/21 10:22 PM, Christoph Hellwig wrote:
> Remove the gendisk aregument to blk_execute_rq and blk_execute_rq_nowait
> given that it is unused now.  Also convert the boolean at_head parameter
> to actually use the bool type while touching the prototype.
> 
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---

Looks good.

Reviewed-by: Chaitanya Kulkarni <kch at nvidia.com>




From chaitanyak at nvidia.com  Tue Sep 28 14:24:33 2021
From: chaitanyak at nvidia.com (Chaitanya Kulkarni)
Date: Tue, 28 Sep 2021 21:24:33 +0000
Subject: [PATCH 5/5] scsi: remove the gendisk argument to scsi_ioctl
In-Reply-To: <20210928052211.112801-6-hch@lst.de>
References: <20210928052211.112801-1-hch@lst.de>
 <20210928052211.112801-6-hch@lst.de>
Message-ID: <802e76e8-0bee-5154-01d8-6570d87caa38@nvidia.com>

On 9/27/21 10:22 PM, Christoph Hellwig wrote:
> Now that blk_execute_rq does not take a gendisk argument there is no need
> to pass it through the scsi_ioctl callchain either.
> 
> Signed-off-by: Christoph Hellwig <hch at lst.de>

Looks good.

Reviewed-by: Chaitanya Kulkarni <kch at nvidia.com>




From miquel.raynal at bootlin.com  Tue Sep 28 15:14:59 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:14:59 +0200
Subject: [PATCH 0/8] Cleanup series about Hamming helpers 
Message-ID: <20210928221507.199198-1-miquel.raynal@bootlin.com>

Hello,

The detailed description is available in each patch description but
basically:
* The FSMC driver was (I believe) still broken so here is a patch for
  that.
* As requested by Linus when he pulled a series of fixes during the 5.13
  cycle, the need for declaring individual indentical helpers in each
  driver using the "raw" Hamming ECC helpers was unjustified:
  - Here is a proposal for simplifying the situation
  - Followed by a series of revert (no need to backport these, it's just
    general cleanup).

Thanks,
Miqu?l

Miquel Raynal (8):
  mtd: rawnand: fsmc: Fix use of SM ORDER
  mtd: rawnand: Let callers use the bare Hamming helpers
  Revert "mtd: rawnand: txx9ndfmc: Fix external use of SW Hamming ECC
    helper"
  Revert "mtd: rawnand: tmio: Fix external use of SW Hamming ECC helper"
  Revert "mtd: rawnand: sharpsl: Fix external use of SW Hamming ECC
    helper"
  Revert "mtd: rawnand: ndfc: Fix external use of SW Hamming ECC helper"
  Revert "mtd: rawnand: lpc32xx_slc: Fix external use of SW Hamming ECC
    helper"
  Revert "mtd: rawnand: cs553x: Fix external use of SW Hamming ECC
    helper"

 drivers/mtd/nand/ecc-sw-hamming.c  |  7 ++++---
 drivers/mtd/nand/raw/cs553x_nand.c | 12 +-----------
 drivers/mtd/nand/raw/fsmc_nand.c   |  4 +++-
 drivers/mtd/nand/raw/lpc32xx_slc.c | 15 +--------------
 drivers/mtd/nand/raw/ndfc.c        | 12 +-----------
 drivers/mtd/nand/raw/sharpsl.c     | 12 +-----------
 drivers/mtd/nand/raw/tmio_nand.c   |  8 +++-----
 drivers/mtd/nand/raw/txx9ndfmc.c   |  5 ++---
 8 files changed, 16 insertions(+), 59 deletions(-)

-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:15:00 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:15:00 +0200
Subject: [PATCH 1/8] mtd: rawnand: fsmc: Fix use of SM ORDER
In-Reply-To: <20210928221507.199198-1-miquel.raynal@bootlin.com>
References: <20210928221507.199198-1-miquel.raynal@bootlin.com>
Message-ID: <20210928221507.199198-2-miquel.raynal@bootlin.com>

The introduction of the generic ECC engine API lead to a number of
changes in various drivers which broke some of them. Here is a typical
example: I expected the SM_ORDER option to be handled by the Hamming ECC
engine internals. Problem: the fsmc driver does not instantiate (yet) a
real ECC engine object so we had to use a 'bare' ECC helper instead of
the shiny rawnand functions. However, when not intializing this engine
properly and using the bare helpers, we do not get the SM ORDER feature
handled automatically. It looks like this was lost in the process so
let's ensure we use the right SM ORDER now.

Fixes: ad9ffdce4539 ("mtd: rawnand: fsmc: Fix external use of SW Hamming ECC helper")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/fsmc_nand.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c
index a3e66155ae40..658f0cbe7ce8 100644
--- a/drivers/mtd/nand/raw/fsmc_nand.c
+++ b/drivers/mtd/nand/raw/fsmc_nand.c
@@ -438,8 +438,10 @@ static int fsmc_correct_ecc1(struct nand_chip *chip,
 			     unsigned char *read_ecc,
 			     unsigned char *calc_ecc)
 {
+	bool sm_order = chip->ecc.options & NAND_ECC_SOFT_HAMMING_SM_ORDER;
+
 	return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc,
-				      chip->ecc.size, false);
+				      chip->ecc.size, sm_order);
 }
 
 /* Count the number of 0's in buff upto a max of max_bits */
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:15:04 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:15:04 +0200
Subject: [PATCH 5/8] Revert "mtd: rawnand: sharpsl: Fix external use of SW
 Hamming ECC helper"
In-Reply-To: <20210928221507.199198-1-miquel.raynal@bootlin.com>
References: <20210928221507.199198-1-miquel.raynal@bootlin.com>
Message-ID: <20210928221507.199198-6-miquel.raynal@bootlin.com>

This reverts commit 46fcb57e6b7283533ebf8ba17a6bd30fa88bdc9f.

Before the introduction of the ECC framework infrastructure, many
drivers used the ->calculate/correct() Hamming helpers directly. The
point of this framework was to avoid this kind of hackish calls and use a
proper and generic API but it is true that in certain cases, drivers
still need to use these helpers in order to do ECC computations on
behalf of their limited hardware.

Right after the introduction of the ECC engine core introduction, it was
spotted that it was not possible to use the shiny rawnand software ECC
helpers so easily because an ECC engine object should have been
allocated and initialized first. While this works well in most cases,
for these drivers just leveraging the power of a single helper in
conjunction with some pretty old and limited hardware, it did not fit.

The idea back then was to declare intermediate helpers which would make
use of the exported software ECC engine bare functions while keeping the
rawnand layer compatibility. As there was already functions with the
rawnand_sw_hamming_ prefix it was decided to declare new local helpers
for this purpose in each driver needing one.

Besides being far from optimal, this design choice was blamed by Linus
when he pulled the "fixes" pull request [1] so that is why now it is
time to clean this mess up.

The implementation of the rawnand_ecc_sw_* helpers has now been enhanced
to support both cases, when the ECC object is instantiated and when it is
not. This way, we can still use the existing and exported rawnand
helpers while avoiding the need for each driver to declare its own
helper, thus this fix from [2] can now be safely reverted.

[1] https://lore.kernel.org/lkml/CAHk-=wh_ZHF685Fni8V9is17mj=pFisUaZ_0=gq6nbK+ZcyQmg at mail.gmail.com/
[2] https://lore.kernel.org/linux-mtd/20210413161840.345208-1-miquel.raynal at bootlin.com

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/sharpsl.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/raw/sharpsl.c b/drivers/mtd/nand/raw/sharpsl.c
index 2f1fe464e663..5612ee628425 100644
--- a/drivers/mtd/nand/raw/sharpsl.c
+++ b/drivers/mtd/nand/raw/sharpsl.c
@@ -11,7 +11,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/nand-ecc-sw-hamming.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/sharpsl.h>
@@ -97,15 +96,6 @@ static int sharpsl_nand_calculate_ecc(struct nand_chip *chip,
 	return readb(sharpsl->io + ECCCNTR) != 0;
 }
 
-static int sharpsl_nand_correct_ecc(struct nand_chip *chip,
-				    unsigned char *buf,
-				    unsigned char *read_ecc,
-				    unsigned char *calc_ecc)
-{
-	return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc,
-				      chip->ecc.size, false);
-}
-
 static int sharpsl_attach_chip(struct nand_chip *chip)
 {
 	if (chip->ecc.engine_type != NAND_ECC_ENGINE_TYPE_ON_HOST)
@@ -116,7 +106,7 @@ static int sharpsl_attach_chip(struct nand_chip *chip)
 	chip->ecc.strength = 1;
 	chip->ecc.hwctl = sharpsl_nand_enable_hwecc;
 	chip->ecc.calculate = sharpsl_nand_calculate_ecc;
-	chip->ecc.correct = sharpsl_nand_correct_ecc;
+	chip->ecc.correct = rawnand_sw_hamming_correct;
 
 	return 0;
 }
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:15:01 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:15:01 +0200
Subject: [PATCH 2/8] mtd: rawnand: Let callers use the bare Hamming helpers
In-Reply-To: <20210928221507.199198-1-miquel.raynal@bootlin.com>
References: <20210928221507.199198-1-miquel.raynal@bootlin.com>
Message-ID: <20210928221507.199198-3-miquel.raynal@bootlin.com>

Before the introduction of the ECC framework infrastructure, many
drivers used the ->calculate/correct() Hamming helpers directly. The
point of this framework was to avoid this kind of hackish calls and use a
proper and generic API but it is true that in certain cases, drivers
still need to use these helpers in order to do ECC computations on
behalf of their limited hardware.

Right after the introduction of the ECC engine core introduction, it was
spotted that it was not possible to use the shiny rawnand software ECC
helpers so easily because an ECC engine object should have been
allocated and initialized first. While this works well in most cases,
for these drivers just leveraging the power of a single helper in
conjunction with some pretty old and limited hardware, it did not fit.

The idea back then was to declare intermediate helpers which would make
use of the exported software ECC engine bare functions while keeping the
rawnand layer compatibility. As there was already functions with the
rawnand_sw_hamming_ prefix it was decided to declare new local helpers
for this purpose in each driver needing one.

Besides being far from optimal, this design choice was blamed by Linus
when he pulled the "fixes" pull request [1] so that is why now it is
time to clean this mess up.

Enhancing the implementation of the rawnand_ecc_sw_* helpers to support
both cases, when the ECC object is instantiated and when it is not is a
quite elegant way to solve this situation. This way, we can still use
the existing and exported rawnand helpers while avoiding the need for
each driver to declare its own helper.

Following this change, most of the fixes sent in [2] can now be safely
reverted. Only the fsmc fix will need to be kept because there is
actually something specific to the driver to do in its ->correct()
helper.

[1] https://lore.kernel.org/lkml/CAHk-=wh_ZHF685Fni8V9is17mj=pFisUaZ_0=gq6nbK+ZcyQmg at mail.gmail.com/
[2] https://lore.kernel.org/linux-mtd/20210413161840.345208-1-miquel.raynal at bootlin.com/

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/ecc-sw-hamming.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/ecc-sw-hamming.c b/drivers/mtd/nand/ecc-sw-hamming.c
index a7655b668f32..254db2e7f8bb 100644
--- a/drivers/mtd/nand/ecc-sw-hamming.c
+++ b/drivers/mtd/nand/ecc-sw-hamming.c
@@ -364,9 +364,9 @@ int nand_ecc_sw_hamming_calculate(struct nand_device *nand,
 {
 	struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
 	unsigned int step_size = nand->ecc.ctx.conf.step_size;
+	bool sm_order = engine_conf ? engine_conf->sm_order : false;
 
-	return ecc_sw_hamming_calculate(buf, step_size, code,
-					engine_conf->sm_order);
+	return ecc_sw_hamming_calculate(buf, step_size, code, sm_order);
 }
 EXPORT_SYMBOL(nand_ecc_sw_hamming_calculate);
 
@@ -457,9 +457,10 @@ int nand_ecc_sw_hamming_correct(struct nand_device *nand, unsigned char *buf,
 {
 	struct nand_ecc_sw_hamming_conf *engine_conf = nand->ecc.ctx.priv;
 	unsigned int step_size = nand->ecc.ctx.conf.step_size;
+	bool sm_order = engine_conf ? engine_conf->sm_order : false;
 
 	return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc, step_size,
-				      engine_conf->sm_order);
+				      sm_order);
 }
 EXPORT_SYMBOL(nand_ecc_sw_hamming_correct);
 
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:15:02 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:15:02 +0200
Subject: [PATCH 3/8] Revert "mtd: rawnand: txx9ndfmc: Fix external use of SW
 Hamming ECC helper"
In-Reply-To: <20210928221507.199198-1-miquel.raynal@bootlin.com>
References: <20210928221507.199198-1-miquel.raynal@bootlin.com>
Message-ID: <20210928221507.199198-4-miquel.raynal@bootlin.com>

This reverts commit 3d227a0b0ce319edbff6fd0d8af4d66689e477cc.

Before the introduction of the ECC framework infrastructure, many
drivers used the ->calculate/correct() Hamming helpers directly. The
point of this framework was to avoid this kind of hackish calls and use a
proper and generic API but it is true that in certain cases, drivers
still need to use these helpers in order to do ECC computations on
behalf of their limited hardware.

Right after the introduction of the ECC engine core introduction, it was
spotted that it was not possible to use the shiny rawnand software ECC
helpers so easily because an ECC engine object should have been
allocated and initialized first. While this works well in most cases,
for these drivers just leveraging the power of a single helper in
conjunction with some pretty old and limited hardware, it did not fit.

The idea back then was to declare intermediate helpers which would make
use of the exported software ECC engine bare functions while keeping the
rawnand layer compatibility. As there was already functions with the
rawnand_sw_hamming_ prefix it was decided to declare new local helpers
for this purpose in each driver needing one.

Besides being far from optimal, this design choice was blamed by Linus
when he pulled the "fixes" pull request [1] so that is why now it is
time to clean this mess up.

The implementation of the rawnand_ecc_sw_* helpers has now been enhanced
to support both cases, when the ECC object is instantiated and when it is
not. This way, we can still use the existing and exported rawnand
helpers while avoiding the need for each driver to declare its own
helper, thus this fix from [2] can now be safely reverted.

[1] https://lore.kernel.org/lkml/CAHk-=wh_ZHF685Fni8V9is17mj=pFisUaZ_0=gq6nbK+ZcyQmg at mail.gmail.com/
[2] https://lore.kernel.org/linux-mtd/20210413161840.345208-1-miquel.raynal at bootlin.com

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/txx9ndfmc.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/txx9ndfmc.c b/drivers/mtd/nand/raw/txx9ndfmc.c
index b8894ac27073..1a9449e53bf9 100644
--- a/drivers/mtd/nand/raw/txx9ndfmc.c
+++ b/drivers/mtd/nand/raw/txx9ndfmc.c
@@ -13,7 +13,6 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/nand-ecc-sw-hamming.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/io.h>
@@ -194,8 +193,8 @@ static int txx9ndfmc_correct_data(struct nand_chip *chip, unsigned char *buf,
 	int stat;
 
 	for (eccsize = chip->ecc.size; eccsize > 0; eccsize -= 256) {
-		stat = ecc_sw_hamming_correct(buf, read_ecc, calc_ecc,
-					      chip->ecc.size, false);
+		stat = rawnand_sw_hamming_correct(chip, buf, read_ecc,
+						  calc_ecc);
 		if (stat < 0)
 			return stat;
 		corrected += stat;
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:15:03 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:15:03 +0200
Subject: [PATCH 4/8] Revert "mtd: rawnand: tmio: Fix external use of SW
 Hamming ECC helper"
In-Reply-To: <20210928221507.199198-1-miquel.raynal@bootlin.com>
References: <20210928221507.199198-1-miquel.raynal@bootlin.com>
Message-ID: <20210928221507.199198-5-miquel.raynal@bootlin.com>

This reverts commit 6a4c5ada577467a5f79e06f2c5e69c09983c22fb.

Before the introduction of the ECC framework infrastructure, many
drivers used the ->calculate/correct() Hamming helpers directly. The
point of this framework was to avoid this kind of hackish calls and use a
proper and generic API but it is true that in certain cases, drivers
still need to use these helpers in order to do ECC computations on
behalf of their limited hardware.

Right after the introduction of the ECC engine core introduction, it was
spotted that it was not possible to use the shiny rawnand software ECC
helpers so easily because an ECC engine object should have been
allocated and initialized first. While this works well in most cases,
for these drivers just leveraging the power of a single helper in
conjunction with some pretty old and limited hardware, it did not fit.

The idea back then was to declare intermediate helpers which would make
use of the exported software ECC engine bare functions while keeping the
rawnand layer compatibility. As there was already functions with the
rawnand_sw_hamming_ prefix it was decided to declare new local helpers
for this purpose in each driver needing one.

Besides being far from optimal, this design choice was blamed by Linus
when he pulled the "fixes" pull request [1] so that is why now it is
time to clean this mess up.

The implementation of the rawnand_ecc_sw_* helpers has now been enhanced
to support both cases, when the ECC object is instantiated and when it is
not. This way, we can still use the existing and exported rawnand
helpers while avoiding the need for each driver to declare its own
helper, thus this fix from [2] can now be safely reverted.

[1] https://lore.kernel.org/lkml/CAHk-=wh_ZHF685Fni8V9is17mj=pFisUaZ_0=gq6nbK+ZcyQmg at mail.gmail.com/
[2] https://lore.kernel.org/linux-mtd/20210413161840.345208-1-miquel.raynal at bootlin.com

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/tmio_nand.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/nand/raw/tmio_nand.c b/drivers/mtd/nand/raw/tmio_nand.c
index 6d93dd31969b..de8e919d0ebe 100644
--- a/drivers/mtd/nand/raw/tmio_nand.c
+++ b/drivers/mtd/nand/raw/tmio_nand.c
@@ -34,7 +34,6 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/nand-ecc-sw-hamming.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/slab.h>
@@ -293,12 +292,11 @@ static int tmio_nand_correct_data(struct nand_chip *chip, unsigned char *buf,
 	int r0, r1;
 
 	/* assume ecc.size = 512 and ecc.bytes = 6 */
-	r0 = ecc_sw_hamming_correct(buf, read_ecc, calc_ecc,
-				    chip->ecc.size, false);
+	r0 = rawnand_sw_hamming_correct(chip, buf, read_ecc, calc_ecc);
 	if (r0 < 0)
 		return r0;
-	r1 = ecc_sw_hamming_correct(buf + 256, read_ecc + 3, calc_ecc + 3,
-				    chip->ecc.size, false);
+	r1 = rawnand_sw_hamming_correct(chip, buf + 256, read_ecc + 3,
+					calc_ecc + 3);
 	if (r1 < 0)
 		return r1;
 	return r0 + r1;
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:15:05 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:15:05 +0200
Subject: [PATCH 6/8] Revert "mtd: rawnand: ndfc: Fix external use of SW
 Hamming ECC helper"
In-Reply-To: <20210928221507.199198-1-miquel.raynal@bootlin.com>
References: <20210928221507.199198-1-miquel.raynal@bootlin.com>
Message-ID: <20210928221507.199198-7-miquel.raynal@bootlin.com>

This reverts commit 3e09c0252501829b14b10f14e1982aaab77d0b80.

Before the introduction of the ECC framework infrastructure, many
drivers used the ->calculate/correct() Hamming helpers directly. The
point of this framework was to avoid this kind of hackish calls and use a
proper and generic API but it is true that in certain cases, drivers
still need to use these helpers in order to do ECC computations on
behalf of their limited hardware.

Right after the introduction of the ECC engine core introduction, it was
spotted that it was not possible to use the shiny rawnand software ECC
helpers so easily because an ECC engine object should have been
allocated and initialized first. While this works well in most cases,
for these drivers just leveraging the power of a single helper in
conjunction with some pretty old and limited hardware, it did not fit.

The idea back then was to declare intermediate helpers which would make
use of the exported software ECC engine bare functions while keeping the
rawnand layer compatibility. As there was already functions with the
rawnand_sw_hamming_ prefix it was decided to declare new local helpers
for this purpose in each driver needing one.

Besides being far from optimal, this design choice was blamed by Linus
when he pulled the "fixes" pull request [1] so that is why now it is
time to clean this mess up.

The implementation of the rawnand_ecc_sw_* helpers has now been enhanced
to support both cases, when the ECC object is instantiated and when it is
not. This way, we can still use the existing and exported rawnand
helpers while avoiding the need for each driver to declare its own
helper, thus this fix from [2] can now be safely reverted.

[1] https://lore.kernel.org/lkml/CAHk-=wh_ZHF685Fni8V9is17mj=pFisUaZ_0=gq6nbK+ZcyQmg at mail.gmail.com/
[2] https://lore.kernel.org/linux-mtd/20210413161840.345208-1-miquel.raynal at bootlin.com

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/ndfc.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/raw/ndfc.c b/drivers/mtd/nand/raw/ndfc.c
index 98d5a94c3a24..338d6b1a189e 100644
--- a/drivers/mtd/nand/raw/ndfc.c
+++ b/drivers/mtd/nand/raw/ndfc.c
@@ -22,7 +22,6 @@
 #include <linux/mtd/ndfc.h>
 #include <linux/slab.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/nand-ecc-sw-hamming.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <asm/io.h>
@@ -101,15 +100,6 @@ static int ndfc_calculate_ecc(struct nand_chip *chip,
 	return 0;
 }
 
-static int ndfc_correct_ecc(struct nand_chip *chip,
-			    unsigned char *buf,
-			    unsigned char *read_ecc,
-			    unsigned char *calc_ecc)
-{
-	return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc,
-				      chip->ecc.size, false);
-}
-
 /*
  * Speedups for buffer read/write/verify
  *
@@ -155,7 +145,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
 	chip->controller = &ndfc->ndfc_control;
 	chip->legacy.read_buf = ndfc_read_buf;
 	chip->legacy.write_buf = ndfc_write_buf;
-	chip->ecc.correct = ndfc_correct_ecc;
+	chip->ecc.correct = rawnand_sw_hamming_correct;
 	chip->ecc.hwctl = ndfc_enable_hwecc;
 	chip->ecc.calculate = ndfc_calculate_ecc;
 	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:15:06 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:15:06 +0200
Subject: [PATCH 7/8] Revert "mtd: rawnand: lpc32xx_slc: Fix external use of SW
 Hamming ECC helper"
In-Reply-To: <20210928221507.199198-1-miquel.raynal@bootlin.com>
References: <20210928221507.199198-1-miquel.raynal@bootlin.com>
Message-ID: <20210928221507.199198-8-miquel.raynal@bootlin.com>

This reverts commit c4b7d7c480d607e4f52d310d9d16b194868d0917.

Before the introduction of the ECC framework infrastructure, many
drivers used the ->calculate/correct() Hamming helpers directly. The
point of this framework was to avoid this kind of hackish calls and use a
proper and generic API but it is true that in certain cases, drivers
still need to use these helpers in order to do ECC computations on
behalf of their limited hardware.

Right after the introduction of the ECC engine core introduction, it was
spotted that it was not possible to use the shiny rawnand software ECC
helpers so easily because an ECC engine object should have been
allocated and initialized first. While this works well in most cases,
for these drivers just leveraging the power of a single helper in
conjunction with some pretty old and limited hardware, it did not fit.

The idea back then was to declare intermediate helpers which would make
use of the exported software ECC engine bare functions while keeping the
rawnand layer compatibility. As there was already functions with the
rawnand_sw_hamming_ prefix it was decided to declare new local helpers
for this purpose in each driver needing one.

Besides being far from optimal, this design choice was blamed by Linus
when he pulled the "fixes" pull request [1] so that is why now it is
time to clean this mess up.

The implementation of the rawnand_ecc_sw_* helpers has now been enhanced
to support both cases, when the ECC object is instantiated and when it is
not. This way, we can still use the existing and exported rawnand
helpers while avoiding the need for each driver to declare its own
helper, thus this fix from [2] can now be safely reverted.

[1] https://lore.kernel.org/lkml/CAHk-=wh_ZHF685Fni8V9is17mj=pFisUaZ_0=gq6nbK+ZcyQmg at mail.gmail.com/
[2] https://lore.kernel.org/linux-mtd/20210413161840.345208-1-miquel.raynal at bootlin.com

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/lpc32xx_slc.c | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c
index d7dfc6fd85ca..6b7269cfb7d8 100644
--- a/drivers/mtd/nand/raw/lpc32xx_slc.c
+++ b/drivers/mtd/nand/raw/lpc32xx_slc.c
@@ -27,7 +27,6 @@
 #include <linux/of.h>
 #include <linux/of_gpio.h>
 #include <linux/mtd/lpc32xx_slc.h>
-#include <linux/mtd/nand-ecc-sw-hamming.h>
 
 #define LPC32XX_MODNAME		"lpc32xx-nand"
 
@@ -345,18 +344,6 @@ static int lpc32xx_nand_ecc_calculate(struct nand_chip *chip,
 	return 0;
 }
 
-/*
- * Corrects the data
- */
-static int lpc32xx_nand_ecc_correct(struct nand_chip *chip,
-				    unsigned char *buf,
-				    unsigned char *read_ecc,
-				    unsigned char *calc_ecc)
-{
-	return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc,
-				      chip->ecc.size, false);
-}
-
 /*
  * Read a single byte from NAND device
  */
@@ -815,7 +802,7 @@ static int lpc32xx_nand_attach_chip(struct nand_chip *chip)
 	chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome;
 	chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome;
 	chip->ecc.calculate = lpc32xx_nand_ecc_calculate;
-	chip->ecc.correct = lpc32xx_nand_ecc_correct;
+	chip->ecc.correct = rawnand_sw_hamming_correct;
 	chip->ecc.hwctl = lpc32xx_nand_ecc_enable;
 
 	/*
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:15:07 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:15:07 +0200
Subject: [PATCH 8/8] Revert "mtd: rawnand: cs553x: Fix external use of SW
 Hamming ECC helper"
In-Reply-To: <20210928221507.199198-1-miquel.raynal@bootlin.com>
References: <20210928221507.199198-1-miquel.raynal@bootlin.com>
Message-ID: <20210928221507.199198-9-miquel.raynal@bootlin.com>

This reverts commit 56a8d3fd1f342d10ee7b27e9ac0f4d00b5fbb91c.

Before the introduction of the ECC framework infrastructure, many
drivers used the ->calculate/correct() Hamming helpers directly. The
point of this framework was to avoid this kind of hackish calls and use a
proper and generic API but it is true that in certain cases, drivers
still need to use these helpers in order to do ECC computations on
behalf of their limited hardware.

Right after the introduction of the ECC engine core introduction, it was
spotted that it was not possible to use the shiny rawnand software ECC
helpers so easily because an ECC engine object should have been
allocated and initialized first. While this works well in most cases,
for these drivers just leveraging the power of a single helper in
conjunction with some pretty old and limited hardware, it did not fit.

The idea back then was to declare intermediate helpers which would make
use of the exported software ECC engine bare functions while keeping the
rawnand layer compatibility. As there was already functions with the
rawnand_sw_hamming_ prefix it was decided to declare new local helpers
for this purpose in each driver needing one.

Besides being far from optimal, this design choice was blamed by Linus
when he pulled the "fixes" pull request [1] so that is why now it is
time to clean this mess up.

The implementation of the rawnand_ecc_sw_* helpers has now been enhanced
to support both cases, when the ECC object is instantiated and when it is
not. This way, we can still use the existing and exported rawnand
helpers while avoiding the need for each driver to declare its own
helper, thus this fix from [2] can now be safely reverted.

[1] https://lore.kernel.org/lkml/CAHk-=wh_ZHF685Fni8V9is17mj=pFisUaZ_0=gq6nbK+ZcyQmg at mail.gmail.com/
[2] https://lore.kernel.org/linux-mtd/20210413161840.345208-1-miquel.raynal at bootlin.com

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/cs553x_nand.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/mtd/nand/raw/cs553x_nand.c b/drivers/mtd/nand/raw/cs553x_nand.c
index df40927e5678..6edf78c16fc8 100644
--- a/drivers/mtd/nand/raw/cs553x_nand.c
+++ b/drivers/mtd/nand/raw/cs553x_nand.c
@@ -18,7 +18,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/mtd/mtd.h>
-#include <linux/mtd/nand-ecc-sw-hamming.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/iopoll.h>
@@ -241,15 +240,6 @@ static int cs_calculate_ecc(struct nand_chip *this, const u_char *dat,
 	return 0;
 }
 
-static int cs553x_ecc_correct(struct nand_chip *chip,
-			      unsigned char *buf,
-			      unsigned char *read_ecc,
-			      unsigned char *calc_ecc)
-{
-	return ecc_sw_hamming_correct(buf, read_ecc, calc_ecc,
-				      chip->ecc.size, false);
-}
-
 static struct cs553x_nand_controller *controllers[4];
 
 static int cs553x_attach_chip(struct nand_chip *chip)
@@ -261,7 +251,7 @@ static int cs553x_attach_chip(struct nand_chip *chip)
 	chip->ecc.bytes = 3;
 	chip->ecc.hwctl  = cs_enable_hwecc;
 	chip->ecc.calculate = cs_calculate_ecc;
-	chip->ecc.correct  = cs553x_ecc_correct;
+	chip->ecc.correct  = rawnand_sw_hamming_correct;
 	chip->ecc.strength = 1;
 
 	return 0;
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:40 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:40 +0200
Subject: [PATCH 1/9] mtd: rawnand: ams-delta: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-2-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: 59d93473323a ("mtd: rawnand: ams-delta: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/ams-delta.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index ff1697f899ba..13de39aa3288 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -217,9 +217,8 @@ static int gpio_nand_setup_interface(struct nand_chip *this, int csline,
 
 static int gpio_nand_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -370,6 +369,13 @@ static int gpio_nand_probe(struct platform_device *pdev)
 	/* Release write protection */
 	gpiod_set_value(priv->gpiod_nwp, 0);
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	/* Scan to find existence of the device */
 	err = nand_scan(this, 1);
 	if (err)
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:39 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:39 +0200
Subject: [PATCH 0/9] Keep on-die ECC engines compatibility
Message-ID: <20210928222258.199726-1-miquel.raynal@bootlin.com>

Recent changes broke the possibility to set the desired ECC engine type
from DT, this is of course an error and needed to be fixed. The fix
applies to all drivers which already received a previous incomplete fix
(about SW support). Hopefully this time we should be good. Sorry for the
noise.

Miquel Raynal (9):
  mtd: rawnand: ams-delta: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: au1550nd: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: gpio: Keep the driver compatible with on-die ECC engines
  mtd: rawnand: mpc5121: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: orion: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: pasemi: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: plat_nand: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: socrates: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: xway: Keep the driver compatible with on-die ECC engines

 drivers/mtd/nand/raw/ams-delta.c     | 12 +++++++++---
 drivers/mtd/nand/raw/au1550nd.c      | 12 +++++++++---
 drivers/mtd/nand/raw/gpio.c          | 12 +++++++++---
 drivers/mtd/nand/raw/mpc5121_nfc.c   | 12 +++++++++---
 drivers/mtd/nand/raw/orion_nand.c    | 12 +++++++++---
 drivers/mtd/nand/raw/pasemi_nand.c   | 12 +++++++++---
 drivers/mtd/nand/raw/plat_nand.c     | 12 +++++++++---
 drivers/mtd/nand/raw/socrates_nand.c | 12 +++++++++---
 drivers/mtd/nand/raw/xway_nand.c     | 12 +++++++++---
 9 files changed, 81 insertions(+), 27 deletions(-)

-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:41 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:41 +0200
Subject: [PATCH 2/9] mtd: rawnand: au1550nd: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-3-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: dbffc8ccdf3a ("mtd: rawnand: au1550: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/au1550nd.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/au1550nd.c b/drivers/mtd/nand/raw/au1550nd.c
index 99116896cfd6..5aa3a06d740c 100644
--- a/drivers/mtd/nand/raw/au1550nd.c
+++ b/drivers/mtd/nand/raw/au1550nd.c
@@ -239,9 +239,8 @@ static int au1550nd_exec_op(struct nand_chip *this,
 
 static int au1550nd_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -310,6 +309,13 @@ static int au1550nd_probe(struct platform_device *pdev)
 	if (pd->devwidth)
 		this->options |= NAND_BUSWIDTH_16;
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	ret = nand_scan(this, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "NAND scan failed with %d\n", ret);
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:42 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:42 +0200
Subject: [PATCH 3/9] mtd: rawnand: gpio: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-4-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: f6341f6448e0 ("mtd: rawnand: gpio: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/gpio.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/gpio.c b/drivers/mtd/nand/raw/gpio.c
index fb7a086de35e..fdf073d2e1b6 100644
--- a/drivers/mtd/nand/raw/gpio.c
+++ b/drivers/mtd/nand/raw/gpio.c
@@ -163,9 +163,8 @@ static int gpio_nand_exec_op(struct nand_chip *chip,
 
 static int gpio_nand_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -365,6 +364,13 @@ static int gpio_nand_probe(struct platform_device *pdev)
 	if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp))
 		gpiod_direction_output(gpiomtd->nwp, 1);
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	ret = nand_scan(chip, 1);
 	if (ret)
 		goto err_wp;
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:44 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:44 +0200
Subject: [PATCH 5/9] mtd: rawnand: orion: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-6-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: 553508cec2e8 ("mtd: rawnand: orion: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/orion_nand.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/orion_nand.c b/drivers/mtd/nand/raw/orion_nand.c
index 66211c9311d2..2c87c7d89205 100644
--- a/drivers/mtd/nand/raw/orion_nand.c
+++ b/drivers/mtd/nand/raw/orion_nand.c
@@ -85,9 +85,8 @@ static void orion_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
 
 static int orion_nand_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -190,6 +189,13 @@ static int __init orion_nand_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	nc->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	ret = nand_scan(nc, 1);
 	if (ret)
 		goto no_dev;
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:43 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:43 +0200
Subject: [PATCH 4/9] mtd: rawnand: mpc5121: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-5-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: 6dd09f775b72 ("mtd: rawnand: mpc5121: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/mpc5121_nfc.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/mpc5121_nfc.c b/drivers/mtd/nand/raw/mpc5121_nfc.c
index bcd4a556c959..cb293c50acb8 100644
--- a/drivers/mtd/nand/raw/mpc5121_nfc.c
+++ b/drivers/mtd/nand/raw/mpc5121_nfc.c
@@ -605,9 +605,8 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd)
 
 static int mpc5121_nfc_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -772,6 +771,13 @@ static int mpc5121_nfc_probe(struct platform_device *op)
 		goto error;
 	}
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	/* Detect NAND chips */
 	retval = nand_scan(chip, be32_to_cpup(chips_no));
 	if (retval) {
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:45 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:45 +0200
Subject: [PATCH 6/9] mtd: rawnand: pasemi: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-7-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: 8fc6f1f042b2 ("mtd: rawnand: pasemi: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/pasemi_nand.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/pasemi_nand.c b/drivers/mtd/nand/raw/pasemi_nand.c
index 789f33312c15..c176036453ed 100644
--- a/drivers/mtd/nand/raw/pasemi_nand.c
+++ b/drivers/mtd/nand/raw/pasemi_nand.c
@@ -75,9 +75,8 @@ static int pasemi_device_ready(struct nand_chip *chip)
 
 static int pasemi_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -154,6 +153,13 @@ static int pasemi_nand_probe(struct platform_device *ofdev)
 	/* Enable the following for a flash based bad block table */
 	chip->bbt_options = NAND_BBT_USE_FLASH;
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	/* Scan to find existence of the device */
 	err = nand_scan(chip, 1);
 	if (err)
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:47 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:47 +0200
Subject: [PATCH 8/9] mtd: rawnand: socrates: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-9-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: b36bf0a0fe5d ("mtd: rawnand: socrates: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/socrates_nand.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/socrates_nand.c b/drivers/mtd/nand/raw/socrates_nand.c
index 70f8305c9b6e..fb39cc7ebce0 100644
--- a/drivers/mtd/nand/raw/socrates_nand.c
+++ b/drivers/mtd/nand/raw/socrates_nand.c
@@ -119,9 +119,8 @@ static int socrates_nand_device_ready(struct nand_chip *nand_chip)
 
 static int socrates_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -175,6 +174,13 @@ static int socrates_nand_probe(struct platform_device *ofdev)
 	/* TODO: I have no idea what real delay is. */
 	nand_chip->legacy.chip_delay = 20;	/* 20us command delay time */
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	nand_chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	dev_set_drvdata(&ofdev->dev, host);
 
 	res = nand_scan(nand_chip, 1);
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:46 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:46 +0200
Subject: [PATCH 7/9] mtd: rawnand: plat_nand: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-8-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: 612e048e6aab ("mtd: rawnand: plat_nand: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/plat_nand.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/plat_nand.c b/drivers/mtd/nand/raw/plat_nand.c
index 7711e1020c21..0ee08c42cc35 100644
--- a/drivers/mtd/nand/raw/plat_nand.c
+++ b/drivers/mtd/nand/raw/plat_nand.c
@@ -21,9 +21,8 @@ struct plat_nand_data {
 
 static int plat_nand_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -94,6 +93,13 @@ static int plat_nand_probe(struct platform_device *pdev)
 			goto out;
 	}
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	/* Scan to find existence of the device */
 	err = nand_scan(&data->chip, pdata->chip.nr_chips);
 	if (err)
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:48 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:48 +0200
Subject: [PATCH 9/9] mtd: rawnand: xway: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-10-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: d525914b5bd8 ("mtd: rawnand: xway: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Cc: Jan Hoffmann <jan at 3e8.eu>
Cc: Kestrel seventyfour <kestrelseventyfour at gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/xway_nand.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/xway_nand.c b/drivers/mtd/nand/raw/xway_nand.c
index 26751976e502..236fd8c5a958 100644
--- a/drivers/mtd/nand/raw/xway_nand.c
+++ b/drivers/mtd/nand/raw/xway_nand.c
@@ -148,9 +148,8 @@ static void xway_write_buf(struct nand_chip *chip, const u_char *buf, int len)
 
 static int xway_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -219,6 +218,13 @@ static int xway_nand_probe(struct platform_device *pdev)
 		    | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P
 		    | cs_flag, EBU_NAND_CON);
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	/* Scan to find existence of the device */
 	err = nand_scan(&data->chip, 1);
 	if (err)
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:49 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:49 +0200
Subject: [PATCH 0/9] Keep on-die ECC engines compatibility
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-11-miquel.raynal@bootlin.com>

Recent changes broke the possibility to set the desired ECC engine type
from DT, this is of course an error and needed to be fixed. The fix
applies to all drivers which already received a previous incomplete fix
(about SW support). Hopefully this time we should be good. Sorry for the
noise.

Miquel Raynal (9):
  mtd: rawnand: ams-delta: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: au1550nd: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: gpio: Keep the driver compatible with on-die ECC engines
  mtd: rawnand: mpc5121: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: orion: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: pasemi: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: plat_nand: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: socrates: Keep the driver compatible with on-die ECC
    engines
  mtd: rawnand: xway: Keep the driver compatible with on-die ECC engines

 drivers/mtd/nand/raw/ams-delta.c     | 12 +++++++++---
 drivers/mtd/nand/raw/au1550nd.c      | 12 +++++++++---
 drivers/mtd/nand/raw/gpio.c          | 12 +++++++++---
 drivers/mtd/nand/raw/mpc5121_nfc.c   | 12 +++++++++---
 drivers/mtd/nand/raw/orion_nand.c    | 12 +++++++++---
 drivers/mtd/nand/raw/pasemi_nand.c   | 12 +++++++++---
 drivers/mtd/nand/raw/plat_nand.c     | 12 +++++++++---
 drivers/mtd/nand/raw/socrates_nand.c | 12 +++++++++---
 drivers/mtd/nand/raw/xway_nand.c     | 12 +++++++++---
 9 files changed, 81 insertions(+), 27 deletions(-)

-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:50 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:50 +0200
Subject: [PATCH 1/9] mtd: rawnand: ams-delta: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-12-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: 59d93473323a ("mtd: rawnand: ams-delta: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/ams-delta.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c
index ff1697f899ba..13de39aa3288 100644
--- a/drivers/mtd/nand/raw/ams-delta.c
+++ b/drivers/mtd/nand/raw/ams-delta.c
@@ -217,9 +217,8 @@ static int gpio_nand_setup_interface(struct nand_chip *this, int csline,
 
 static int gpio_nand_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -370,6 +369,13 @@ static int gpio_nand_probe(struct platform_device *pdev)
 	/* Release write protection */
 	gpiod_set_value(priv->gpiod_nwp, 0);
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	/* Scan to find existence of the device */
 	err = nand_scan(this, 1);
 	if (err)
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:53 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:53 +0200
Subject: [PATCH 4/9] mtd: rawnand: mpc5121: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-15-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: 6dd09f775b72 ("mtd: rawnand: mpc5121: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/mpc5121_nfc.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/mpc5121_nfc.c b/drivers/mtd/nand/raw/mpc5121_nfc.c
index bcd4a556c959..cb293c50acb8 100644
--- a/drivers/mtd/nand/raw/mpc5121_nfc.c
+++ b/drivers/mtd/nand/raw/mpc5121_nfc.c
@@ -605,9 +605,8 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd)
 
 static int mpc5121_nfc_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -772,6 +771,13 @@ static int mpc5121_nfc_probe(struct platform_device *op)
 		goto error;
 	}
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	/* Detect NAND chips */
 	retval = nand_scan(chip, be32_to_cpup(chips_no));
 	if (retval) {
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:51 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:51 +0200
Subject: [PATCH 2/9] mtd: rawnand: au1550nd: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-13-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: dbffc8ccdf3a ("mtd: rawnand: au1550: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/au1550nd.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/au1550nd.c b/drivers/mtd/nand/raw/au1550nd.c
index 99116896cfd6..5aa3a06d740c 100644
--- a/drivers/mtd/nand/raw/au1550nd.c
+++ b/drivers/mtd/nand/raw/au1550nd.c
@@ -239,9 +239,8 @@ static int au1550nd_exec_op(struct nand_chip *this,
 
 static int au1550nd_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -310,6 +309,13 @@ static int au1550nd_probe(struct platform_device *pdev)
 	if (pd->devwidth)
 		this->options |= NAND_BUSWIDTH_16;
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	this->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	ret = nand_scan(this, 1);
 	if (ret) {
 		dev_err(&pdev->dev, "NAND scan failed with %d\n", ret);
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:52 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:52 +0200
Subject: [PATCH 3/9] mtd: rawnand: gpio: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-14-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: f6341f6448e0 ("mtd: rawnand: gpio: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/gpio.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/gpio.c b/drivers/mtd/nand/raw/gpio.c
index fb7a086de35e..fdf073d2e1b6 100644
--- a/drivers/mtd/nand/raw/gpio.c
+++ b/drivers/mtd/nand/raw/gpio.c
@@ -163,9 +163,8 @@ static int gpio_nand_exec_op(struct nand_chip *chip,
 
 static int gpio_nand_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -365,6 +364,13 @@ static int gpio_nand_probe(struct platform_device *pdev)
 	if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp))
 		gpiod_direction_output(gpiomtd->nwp, 1);
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	ret = nand_scan(chip, 1);
 	if (ret)
 		goto err_wp;
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:55 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:55 +0200
Subject: [PATCH 6/9] mtd: rawnand: pasemi: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-17-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: 8fc6f1f042b2 ("mtd: rawnand: pasemi: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/pasemi_nand.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/pasemi_nand.c b/drivers/mtd/nand/raw/pasemi_nand.c
index 789f33312c15..c176036453ed 100644
--- a/drivers/mtd/nand/raw/pasemi_nand.c
+++ b/drivers/mtd/nand/raw/pasemi_nand.c
@@ -75,9 +75,8 @@ static int pasemi_device_ready(struct nand_chip *chip)
 
 static int pasemi_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -154,6 +153,13 @@ static int pasemi_nand_probe(struct platform_device *ofdev)
 	/* Enable the following for a flash based bad block table */
 	chip->bbt_options = NAND_BBT_USE_FLASH;
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	/* Scan to find existence of the device */
 	err = nand_scan(chip, 1);
 	if (err)
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:54 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:54 +0200
Subject: [PATCH 5/9] mtd: rawnand: orion: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-16-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: 553508cec2e8 ("mtd: rawnand: orion: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/orion_nand.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/orion_nand.c b/drivers/mtd/nand/raw/orion_nand.c
index 66211c9311d2..2c87c7d89205 100644
--- a/drivers/mtd/nand/raw/orion_nand.c
+++ b/drivers/mtd/nand/raw/orion_nand.c
@@ -85,9 +85,8 @@ static void orion_nand_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
 
 static int orion_nand_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -190,6 +189,13 @@ static int __init orion_nand_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	nc->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	ret = nand_scan(nc, 1);
 	if (ret)
 		goto no_dev;
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:56 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:56 +0200
Subject: [PATCH 7/9] mtd: rawnand: plat_nand: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-18-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: 612e048e6aab ("mtd: rawnand: plat_nand: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/plat_nand.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/plat_nand.c b/drivers/mtd/nand/raw/plat_nand.c
index 7711e1020c21..0ee08c42cc35 100644
--- a/drivers/mtd/nand/raw/plat_nand.c
+++ b/drivers/mtd/nand/raw/plat_nand.c
@@ -21,9 +21,8 @@ struct plat_nand_data {
 
 static int plat_nand_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -94,6 +93,13 @@ static int plat_nand_probe(struct platform_device *pdev)
 			goto out;
 	}
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	/* Scan to find existence of the device */
 	err = nand_scan(&data->chip, pdata->chip.nr_chips);
 	if (err)
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:57 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:57 +0200
Subject: [PATCH 8/9] mtd: rawnand: socrates: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-19-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: b36bf0a0fe5d ("mtd: rawnand: socrates: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/socrates_nand.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/socrates_nand.c b/drivers/mtd/nand/raw/socrates_nand.c
index 70f8305c9b6e..fb39cc7ebce0 100644
--- a/drivers/mtd/nand/raw/socrates_nand.c
+++ b/drivers/mtd/nand/raw/socrates_nand.c
@@ -119,9 +119,8 @@ static int socrates_nand_device_ready(struct nand_chip *nand_chip)
 
 static int socrates_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -175,6 +174,13 @@ static int socrates_nand_probe(struct platform_device *ofdev)
 	/* TODO: I have no idea what real delay is. */
 	nand_chip->legacy.chip_delay = 20;	/* 20us command delay time */
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	nand_chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	dev_set_drvdata(&ofdev->dev, host);
 
 	res = nand_scan(nand_chip, 1);
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:22:58 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:22:58 +0200
Subject: [PATCH 9/9] mtd: rawnand: xway: Keep the driver compatible with
 on-die ECC engines
In-Reply-To: <20210928222258.199726-1-miquel.raynal@bootlin.com>
References: <20210928222258.199726-1-miquel.raynal@bootlin.com>
Message-ID: <20210928222258.199726-20-miquel.raynal@bootlin.com>

Following the introduction of the generic ECC engine infrastructure, it
was necessary to reorganize the code and move the ECC configuration in
the ->attach_chip() hook. Failing to do that properly lead to a first
series of fixes supposed to stabilize the situation. Unfortunately, this
only fixed the use of software ECC engines, preventing any other kind of
engine to be used, including on-die ones.

It is now time to (finally) fix the situation by ensuring that we still
provide a default (eg. software ECC) but will still support different
ECC engines such as on-die ECC engines if properly described in the
device tree.

There are no changes needed on the core side in order to do this, but we
just need to leverage the logic there which allows:
1- a subsystem default (set to Host engines in the raw NAND world)
2- a driver specific default (here set to software ECC engines)
3- any type of engine requested by the user (ie. described in the DT)

As the raw NAND subsystem has not yet been fully converted to the ECC
engine infrastructure, in order to provide a default ECC engine for this
driver we need to set chip->ecc.engine_type *before* calling
nand_scan(). During the initialization step, the core will consider this
entry as the default engine for this driver. This value may of course
be overloaded by the user if the usual DT properties are provided.

Fixes: d525914b5bd8 ("mtd: rawnand: xway: Move the ECC initialization to ->attach_chip()")
Cc: stable at vger.kernel.org
Cc: Jan Hoffmann <jan at 3e8.eu>
Cc: Kestrel seventyfour <kestrelseventyfour at gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 drivers/mtd/nand/raw/xway_nand.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/xway_nand.c b/drivers/mtd/nand/raw/xway_nand.c
index 26751976e502..236fd8c5a958 100644
--- a/drivers/mtd/nand/raw/xway_nand.c
+++ b/drivers/mtd/nand/raw/xway_nand.c
@@ -148,9 +148,8 @@ static void xway_write_buf(struct nand_chip *chip, const u_char *buf, int len)
 
 static int xway_attach_chip(struct nand_chip *chip)
 {
-	chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
-
-	if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT &&
+	    chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
 		chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
 
 	return 0;
@@ -219,6 +218,13 @@ static int xway_nand_probe(struct platform_device *pdev)
 		    | NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P
 		    | cs_flag, EBU_NAND_CON);
 
+	/*
+	 * This driver assumes that the default ECC engine should be TYPE_SOFT.
+	 * Set ->engine_type before registering the NAND devices in order to
+	 * provide a driver specific default value.
+	 */
+	data->chip.ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT;
+
 	/* Scan to find existence of the device */
 	err = nand_scan(&data->chip, 1);
 	if (err)
-- 
2.27.0



From miquel.raynal at bootlin.com  Tue Sep 28 15:24:35 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:24:35 +0200
Subject: [GIT PULL] mtd: Changes for v5.13-rc4
In-Reply-To: <20210526184612.751e7e5c@xps13>
References: <20210526175924.4f9ab124@xps13>
 <CAHk-=wh_ZHF685Fni8V9is17mj=pFisUaZ_0=gq6nbK+ZcyQmg@mail.gmail.com>
 <20210526184612.751e7e5c@xps13>
Message-ID: <20210929002435.4d0b437c@xps13>

Hi Linus,

miquel.raynal at bootlin.com wrote on Wed, 26 May 2021 18:46:12 +0200:

> Hi Linus,
> 
> Linus Torvalds <torvalds at linux-foundation.org> wrote on Wed, 26 May
> 2021 06:20:35 -1000:
> 
> > On Wed, May 26, 2021 at 5:59 AM Miquel Raynal <miquel.raynal at bootlin.com> wrote:  
> > >
> > > Raw NAND:
> > > * txx9ndfmc, tmio, sharpsl, ndfc, lpc32xx_slc, fsmc, cs553x:
> > >   - Fix external use of SW Hamming ECC helper    
> > 
> > Why are these guys all pointlessly duplicating the ecc wrapper
> > functions for their ecc 'correct' functions?
> > 
> > The whole "the Hamming software ECC engine has been updated to become
> > a proper and independent ECC engine" excuse makes no sense. If
> > multiple chips just want a basic sw hamming helper, then they should
> > have one. Not have to be forced to each write their own pointless
> > wrapper like this.
> > 
> > These chip drivers just want 'ecc_sw_hamming_correct()' with the
> > proper arguments, and it seems entirely wrong to duplicate the helper
> > five times or whatever. There should just be a generic helper - the
> > way there used to be.
> > 
> > In fact, I would generally strongly recommend that if there used to be
> > a generic helper that different chip drivers used (ie the old
> > rawnand_sw_hamming_correct()), then such a helper should be left alone
> > and not change the semantics of it.  
> 
> I am not happy neither with the fix (which I wrote myself) as my first
> goal was to uniformize the way the Hamming helpers are being called (as
> part of a much bigger work). I assumed that all drivers either used the
> Hamming software engine or simply didn't, without thinking about the
> "intermediate" situations where a particular driver would just want to
> call a particular Hamming helper to workaround its "missing" hardware
> capabilities.
> 
> Unfortunately when I spotted that many drivers were broken by my rework
> I decided to provide per-driver fixes, while, as you suggest, I should
> probably have declared a generic 'hamming correct' core helper and use
> that directly instead of duplicating the logic in each broken driver.
> 
> > The new "proper independent ECC engine" that had new semantics should
> > have been the one that got a new name, rather than breaking an old and
> > existing helper function and then making the chip drivers pointlessly
> > write their own new helper functions.
> > 
> > I've pulled this, but under protest. The patch honestly just looks
> > like mindless duplication.  

Just to let you know that I proposed there [1] a series to clean this
up.

[1] https://lore.kernel.org/linux-mtd/20210928221507.199198-1-miquel.raynal at bootlin.com/T/#t

Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Tue Sep 28 15:36:16 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Wed, 29 Sep 2021 00:36:16 +0200
Subject: [PATCH] mtd: onenand: samsung: drop Exynos4 and describe driver
 in KConfig
In-Reply-To: <20210924133223.111930-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20210928223616.200628-1-miquel.raynal@bootlin.com>

On Fri, 2021-09-24 at 13:32:23 UTC, Krzysztof Kozlowski wrote:
> None of supported Samsung Exynos4 SoCs (Exynos4210, Exynos4412) seem to
> use OneNAND driver so drop it.  Describe better which driver applies to
> which SoC, to make configuring kernel for Samsung SoC easier.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

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

Miquel


From Tudor.Ambarus at microchip.com  Tue Sep 28 22:16:52 2021
From: Tudor.Ambarus at microchip.com (Tudor.Ambarus at microchip.com)
Date: Wed, 29 Sep 2021 05:16:52 +0000
Subject: [PATCH] mtd: spi-nor: Add support for ZB25VQ128
In-Reply-To: <20210928163403.iufy6rgn7imiebpz@ti.com>
References: <20210918072256.3505379-1-daniel@0x0f.com>
 <20210920112625.fnqayim5mg5iggag@ti.com>
 <CAFr9PX=xKoa9fCbYf6Mpn=oudnY7A=6meKBSmzNHYLFad364tw@mail.gmail.com>
 <20210928163403.iufy6rgn7imiebpz@ti.com>
Message-ID: <4a57745e-dd0e-7890-0767-e6eaabeecd63@microchip.com>

On 9/28/21 7:34 PM, Pratyush Yadav wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> On 28/09/21 10:15PM, Daniel Palmer wrote:
>> Hi Pratyush,
>>
>> On Mon, 20 Sept 2021 at 20:26, Pratyush Yadav <p.yadav at ti.com> wrote:
>>>
>>> Zbit should be in bank 10, so it should be preceeded by 9 0x7f bytes,
>>> correct? I don't see any logic to handle that in SPI NOR currently so I
>>> assume this manufacturer does not implement the continuation codes.
>>>
>>> In that case, it should go to the manufacturer collisions driver
>>> proposed here [0].
>>>
>>> [0] https://patchwork.ozlabs.org/project/linux-mtd/patch/20210727045222.905056-6-tudor.ambarus at microchip.com/
>>
>> Sorry, I'm not sure what I should do with this information. I didn't
>> even know about the continuation codes thing until now.
>> Is there something I need to do here or do I just need to wait for the
>> collision handling code to get merged?
> 
> I think that should be what you need to do. Tudor, any plans on
> re-rolling that patch series in the near future?
> 
Hi, all,

Yes, I was out of office for a month, today I got back. I'll handle it.

Cheers,
ta

From hch at lst.de  Wed Sep 29 00:07:33 2021
From: hch at lst.de (Christoph Hellwig)
Date: Wed, 29 Sep 2021 09:07:33 +0200
Subject: remove ->rq_disk
In-Reply-To: <YVMnk/8HIR/yhWYr@T590>
References: <20210928052211.112801-1-hch@lst.de> <YVMnk/8HIR/yhWYr@T590>
Message-ID: <20210929070733.GA31869@lst.de>

On Tue, Sep 28, 2021 at 10:32:51PM +0800, Ming Lei wrote:
> Hello Christoph,
> 
> On Tue, Sep 28, 2021 at 07:22:06AM +0200, Christoph Hellwig wrote:
> > Hi Jens,
> > 
> > this series removes the rq_disk field in struct request, which isn't
> > needed now that we can get the disk from the request_queue.
> 
> Can we hold on this series until q->disk becomes really reliable[1][2]?

It's not like q->disk isn't reliable.  It is that we don't kill all bios
when tearing down the gendisk, which is an old problem that got worse.

That being said I'm resending this again.


From ming.lei at redhat.com  Wed Sep 29 01:04:25 2021
From: ming.lei at redhat.com (Ming Lei)
Date: Wed, 29 Sep 2021 16:04:25 +0800
Subject: remove ->rq_disk
In-Reply-To: <20210929070733.GA31869@lst.de>
References: <20210928052211.112801-1-hch@lst.de> <YVMnk/8HIR/yhWYr@T590>
 <20210929070733.GA31869@lst.de>
Message-ID: <YVQeCdF/kT46pkC5@T590>

On Wed, Sep 29, 2021 at 09:07:33AM +0200, Christoph Hellwig wrote:
> On Tue, Sep 28, 2021 at 10:32:51PM +0800, Ming Lei wrote:
> > Hello Christoph,
> > 
> > On Tue, Sep 28, 2021 at 07:22:06AM +0200, Christoph Hellwig wrote:
> > > Hi Jens,
> > > 
> > > this series removes the rq_disk field in struct request, which isn't
> > > needed now that we can get the disk from the request_queue.
> > 
> > Can we hold on this series until q->disk becomes really reliable[1][2]?
> 
> It's not like q->disk isn't reliable.  It is that we don't kill all bios

q->disk will be cleaned in gendisk's release handler, which may happen before
or after blk_cleanup_queue().

> when tearing down the gendisk, which is an old problem that got worse.

It is fine to not kill all bios when tearing down gendisk if BDI isn't
retrieved from q->disk->bdi since gendisk has same lifetime with bdev.

So what is the old problem?

> That being said I'm resending this again.

No, either your patch or mine can't fix the issue, and I will comment on
your resending.


Thanks, 
Ming



From zev at bewilderbeest.net  Wed Sep 29 04:54:04 2021
From: zev at bewilderbeest.net (Zev Weiss)
Date: Wed, 29 Sep 2021 04:54:04 -0700
Subject: [PATCH 2/6] mtd: core: clear out unregistered devices a bit more
In-Reply-To: <20210929115409.21254-1-zev@bewilderbeest.net>
References: <20210929115409.21254-1-zev@bewilderbeest.net>
Message-ID: <20210929115409.21254-3-zev@bewilderbeest.net>

This allows an MTD device that has been unregistered to be easily
re-registered later without triggering "already registered" warnings in
mtd_device_parse_register() and add_mtd_device().

Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
---
 drivers/mtd/mtdcore.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index c8fd7f758938..e22266f63ae9 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -747,6 +747,9 @@ int del_mtd_device(struct mtd_info *mtd)
 
 		device_unregister(&mtd->dev);
 
+		/* Clear dev so mtd can be safely re-registered later if desired */
+		memset(&mtd->dev, 0, sizeof(mtd->dev));
+
 		idr_remove(&mtd_idr, mtd->index);
 		of_node_put(mtd_get_of_node(mtd));
 
@@ -1018,8 +1021,10 @@ int mtd_device_unregister(struct mtd_info *master)
 {
 	int err;
 
-	if (master->_reboot)
+	if (master->_reboot) {
 		unregister_reboot_notifier(&master->reboot_notifier);
+		memset(&master->reboot_notifier, 0, sizeof(master->reboot_notifier));
+	}
 
 	if (master->otp_user_nvmem)
 		nvmem_unregister(master->otp_user_nvmem);
-- 
2.33.0



From zev at bewilderbeest.net  Wed Sep 29 04:54:02 2021
From: zev at bewilderbeest.net (Zev Weiss)
Date: Wed, 29 Sep 2021 04:54:02 -0700
Subject: [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT status
Message-ID: <20210929115409.21254-1-zev@bewilderbeest.net>

Hello,

This patch series aims to improve a scenario that arises in OpenBMC
and which isn't handled very well at the moment.  Certain devices, the
example at hand being the flash chip used to store the host's firmware
(e.g. the BIOS), may be shared between the BMC and the host system but
only available to one or the other at any given time.  The device may
thus be effectively off-limits to the BMC when it boots, and only
usable after userspace performs the necessary steps to coordinate
appropriately with the host (tracking its power state, twiddling
GPIOs, sending IPMI commands, etc.).

Neither the "okay" nor the "disabled" device-tree status values works
nicely for the flash device this case -- an "okay" device gets probed
automatically as soon as the device and a driver for it are available,
and a "disabled" one gets forgotten about entirely, whereas we want
the BMC's kernel to be aware of the existence of the device, but not
try to actually do anything with it (i.e. probe it) until explicitly
requested to do so by userspace.

However, while there's no support for it currently in the kernel tree,
the device-tree spec [0] also lists "reserved" as a possible status
value, and its description seems like a fairly reasonable fit for this
situation:

  Indicates that the device is operational, but should not be used.
  Typically this is used for devices that are controlled by another
  software component, such as platform firmware.

These patches start making use of this status value in the aspeed-smc
driver.  The first patch adds a companion routine to
of_device_is_available() that checks for a "reserved" status instead
of "okay".  The second patch is a small MTD adjustment to allow an
unregistered device to be cleanly re-registered.  Patches 3 through 5
modify the aspeed-smc driver to allow individual chips to be attached
and detached at runtime, and to avoid automatically attaching any
marked as reserved.  Finally, patch 6 employs the newly-supported
status in adding support for the BIOS flash device to the ASRock Rack
e3c246d4i BMC.


Thanks,
Zev

[0] https://github.com/devicetree-org/devicetree-specification/releases/download/v0.3/devicetree-specification-v0.3.pdf

Zev Weiss (6):
  of: base: Add function to check for status = "reserved"
  mtd: core: clear out unregistered devices a bit more
  mtd: spi-nor: aspeed: Refactor registration/unregistration
  mtd: spi-nor: aspeed: Allow attaching & detaching chips at runtime
  mtd: spi-nor: aspeed: Don't automatically attach reserved chips
  ARM: dts: aspeed: Add e3c246d4i BIOS flash device

 .../ABI/stable/sysfs-driver-aspeed-smc        |  17 ++
 .../boot/dts/aspeed-bmc-asrock-e3c246d4i.dts  |  16 ++
 drivers/mtd/mtdcore.c                         |   7 +-
 drivers/mtd/spi-nor/controllers/aspeed-smc.c  | 177 +++++++++++++++---
 drivers/of/base.c                             |  53 +++++-
 include/linux/of.h                            |   6 +
 6 files changed, 238 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/ABI/stable/sysfs-driver-aspeed-smc

-- 
2.33.0



From zev at bewilderbeest.net  Wed Sep 29 04:54:05 2021
From: zev at bewilderbeest.net (Zev Weiss)
Date: Wed, 29 Sep 2021 04:54:05 -0700
Subject: [PATCH 3/6] mtd: spi-nor: aspeed: Refactor registration/unregistration
In-Reply-To: <20210929115409.21254-1-zev@bewilderbeest.net>
References: <20210929115409.21254-1-zev@bewilderbeest.net>
Message-ID: <20210929115409.21254-4-zev@bewilderbeest.net>

We now have separate functions for registering and unregistering
individual flash chips, instead of the entire controller.  This is a
preparatory step for allowing userspace to request that a specific
chip be attached or detached at runtime.

Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
---
 drivers/mtd/spi-nor/controllers/aspeed-smc.c | 73 ++++++++++++--------
 1 file changed, 45 insertions(+), 28 deletions(-)

diff --git a/drivers/mtd/spi-nor/controllers/aspeed-smc.c b/drivers/mtd/spi-nor/controllers/aspeed-smc.c
index 7225870e8b18..3c153104a905 100644
--- a/drivers/mtd/spi-nor/controllers/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/controllers/aspeed-smc.c
@@ -107,9 +107,10 @@ struct aspeed_smc_controller {
 	const struct aspeed_smc_info *info;	/* type info of controller */
 	void __iomem *regs;			/* controller registers */
 	void __iomem *ahb_base;			/* per-chip windows resource */
+	struct resource *ahb_res;		/* resource for AHB address space */
 	u32 ahb_window_size;			/* full mapping window size */
 
-	struct aspeed_smc_chip *chips[];	/* pointers to attached chips */
+	struct aspeed_smc_chip *chips[];	/* pointers to connected chips */
 };
 
 /*
@@ -399,15 +400,24 @@ static ssize_t aspeed_smc_write_user(struct spi_nor *nor, loff_t to,
 	return len;
 }
 
+static int aspeed_smc_unregister_chip(struct aspeed_smc_chip *chip)
+{
+	return mtd_device_unregister(&chip->nor.mtd);
+}
+
 static int aspeed_smc_unregister(struct aspeed_smc_controller *controller)
 {
 	struct aspeed_smc_chip *chip;
-	int n;
+	int n, ret;
 
 	for (n = 0; n < controller->info->nce; n++) {
 		chip = controller->chips[n];
-		if (chip)
-			mtd_device_unregister(&chip->nor.mtd);
+		if (chip) {
+			ret = aspeed_smc_unregister_chip(chip);
+			if (ret)
+				dev_warn(controller->dev, "failed to unregister CS%d: %d\n",
+				         n, ret);
+		}
 	}
 
 	return 0;
@@ -756,14 +766,39 @@ static const struct spi_nor_controller_ops aspeed_smc_controller_ops = {
 	.write = aspeed_smc_write_user,
 };
 
-static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
-				  struct device_node *np, struct resource *r)
+static int aspeed_smc_register_chip(struct aspeed_smc_chip *chip)
 {
-	const struct spi_nor_hwcaps hwcaps = {
+	static const struct spi_nor_hwcaps hwcaps = {
 		.mask = SNOR_HWCAPS_READ |
 			SNOR_HWCAPS_READ_FAST |
 			SNOR_HWCAPS_PP,
 	};
+	int ret;
+
+	ret = aspeed_smc_chip_setup_init(chip, chip->controller->ahb_res);
+	if (ret)
+		goto out;
+
+	/*
+	 * TODO: Add support for Dual and Quad SPI protocols attach when board
+	 * support is present as determined by of property.
+	 */
+	ret = spi_nor_scan(&chip->nor, NULL, &hwcaps);
+	if (ret)
+		goto out;
+
+	ret = aspeed_smc_chip_setup_finish(chip);
+	if (ret)
+		goto out;
+
+	ret = mtd_device_register(&chip->nor.mtd, NULL, 0);
+out:
+	return ret;
+}
+
+static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
+				  struct device_node *np, struct resource *r)
+{
 	const struct aspeed_smc_info *info = controller->info;
 	struct device *dev = controller->dev;
 	struct device_node *child;
@@ -773,7 +808,6 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
 	for_each_available_child_of_node(np, child) {
 		struct aspeed_smc_chip *chip;
 		struct spi_nor *nor;
-		struct mtd_info *mtd;
 
 		/* This driver does not support NAND or NOR flash devices. */
 		if (!of_device_is_compatible(child, "jedec,spi-nor"))
@@ -810,35 +844,17 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
 		chip->cs = cs;
 
 		nor = &chip->nor;
-		mtd = &nor->mtd;
 
 		nor->dev = dev;
 		nor->priv = chip;
 		spi_nor_set_flash_node(nor, child);
 		nor->controller_ops = &aspeed_smc_controller_ops;
 
-		ret = aspeed_smc_chip_setup_init(chip, r);
-		if (ret)
-			break;
-
-		/*
-		 * TODO: Add support for Dual and Quad SPI protocols
-		 * attach when board support is present as determined
-		 * by of property.
-		 */
-		ret = spi_nor_scan(nor, NULL, &hwcaps);
-		if (ret)
-			break;
-
-		ret = aspeed_smc_chip_setup_finish(chip);
-		if (ret)
-			break;
+		controller->chips[cs] = chip;
 
-		ret = mtd_device_register(mtd, NULL, 0);
+		ret = aspeed_smc_register_chip(chip);
 		if (ret)
 			break;
-
-		controller->chips[cs] = chip;
 	}
 
 	if (ret) {
@@ -881,6 +897,7 @@ static int aspeed_smc_probe(struct platform_device *pdev)
 		return PTR_ERR(controller->regs);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	controller->ahb_res = res;
 	controller->ahb_base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(controller->ahb_base))
 		return PTR_ERR(controller->ahb_base);
-- 
2.33.0



From zev at bewilderbeest.net  Wed Sep 29 04:54:06 2021
From: zev at bewilderbeest.net (Zev Weiss)
Date: Wed, 29 Sep 2021 04:54:06 -0700
Subject: [PATCH 4/6] mtd: spi-nor: aspeed: Allow attaching & detaching chips
 at runtime
In-Reply-To: <20210929115409.21254-1-zev@bewilderbeest.net>
References: <20210929115409.21254-1-zev@bewilderbeest.net>
Message-ID: <20210929115409.21254-5-zev@bewilderbeest.net>

There are now two new sysfs attributes, attach_chip and detach_chip,
into which a chip select number can be written to attach or detach the
corresponding chip.

Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
---
 .../ABI/stable/sysfs-driver-aspeed-smc        |  17 +++
 drivers/mtd/spi-nor/controllers/aspeed-smc.c  | 101 +++++++++++++++++-
 2 files changed, 115 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/ABI/stable/sysfs-driver-aspeed-smc

diff --git a/Documentation/ABI/stable/sysfs-driver-aspeed-smc b/Documentation/ABI/stable/sysfs-driver-aspeed-smc
new file mode 100644
index 000000000000..871b4d65ccb2
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-driver-aspeed-smc
@@ -0,0 +1,17 @@
+What:		/sys/bus/platform/drivers/aspeed-smc/*/attach_chip
+Date:		September 2021
+Contact:	Zev Weiss <zev at bewilderbeest.net>
+Description:	A chip select number may be written into this file to
+		request that the corresponding chip be attached by the
+		driver.
+Users:		OpenBMC.  Proposed changes should be mailed to
+		openbmc at lists.ozlabs.org
+
+What:		/sys/bus/platform/drivers/aspeed-smc/*/detach_chip
+Date:		September 2021
+Contact:	Zev Weiss <zev at bewilderbeest.net>
+Description:	A chip select number may be written into this file to
+		request that the corresponding chip be detached by the
+		driver.
+Users:		OpenBMC.  Proposed changes should be mailed to
+		openbmc at lists.ozlabs.org
diff --git a/drivers/mtd/spi-nor/controllers/aspeed-smc.c b/drivers/mtd/spi-nor/controllers/aspeed-smc.c
index 3c153104a905..da49192a8220 100644
--- a/drivers/mtd/spi-nor/controllers/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/controllers/aspeed-smc.c
@@ -91,6 +91,7 @@ struct aspeed_smc_controller;
 
 struct aspeed_smc_chip {
 	int cs;
+	bool attached;
 	struct aspeed_smc_controller *controller;
 	void __iomem *ctl;			/* control register */
 	void __iomem *ahb_base;			/* base of chip window */
@@ -402,7 +403,15 @@ static ssize_t aspeed_smc_write_user(struct spi_nor *nor, loff_t to,
 
 static int aspeed_smc_unregister_chip(struct aspeed_smc_chip *chip)
 {
-	return mtd_device_unregister(&chip->nor.mtd);
+	int ret = -ENOENT;
+	mutex_lock(&chip->controller->mutex);
+	if (chip->attached) {
+		ret = mtd_device_unregister(&chip->nor.mtd);
+		if (!ret)
+			chip->attached = false;
+	}
+	mutex_unlock(&chip->controller->mutex);
+	return ret;
 }
 
 static int aspeed_smc_unregister(struct aspeed_smc_controller *controller)
@@ -412,7 +421,7 @@ static int aspeed_smc_unregister(struct aspeed_smc_controller *controller)
 
 	for (n = 0; n < controller->info->nce; n++) {
 		chip = controller->chips[n];
-		if (chip) {
+		if (chip && chip->attached) {
 			ret = aspeed_smc_unregister_chip(chip);
 			if (ret)
 				dev_warn(controller->dev, "failed to unregister CS%d: %d\n",
@@ -775,6 +784,13 @@ static int aspeed_smc_register_chip(struct aspeed_smc_chip *chip)
 	};
 	int ret;
 
+	mutex_lock(&chip->controller->mutex);
+
+	if (chip->attached) {
+		ret = -EEXIST;
+		goto out;
+	}
+
 	ret = aspeed_smc_chip_setup_init(chip, chip->controller->ahb_res);
 	if (ret)
 		goto out;
@@ -792,7 +808,12 @@ static int aspeed_smc_register_chip(struct aspeed_smc_chip *chip)
 		goto out;
 
 	ret = mtd_device_register(&chip->nor.mtd, NULL, 0);
+	if (ret)
+		goto out;
+
+	chip->attached = true;
 out:
+	mutex_unlock(&chip->controller->mutex);
 	return ret;
 }
 
@@ -865,6 +886,72 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
 	return ret;
 }
 
+static inline struct aspeed_smc_controller *to_aspeed_smc_controller(struct device *dev)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device, dev);
+	return platform_get_drvdata(pdev);
+}
+
+static ssize_t attach_chip_store(struct device *dev, struct device_attribute *attr,
+                                 const char *buf, size_t count)
+{
+	unsigned long cs;
+	struct aspeed_smc_controller *controller;
+	struct aspeed_smc_chip *chip;
+	ssize_t ret = kstrtoul(buf, 0, &cs);
+	if (ret)
+		return ret;
+
+	controller = to_aspeed_smc_controller(dev);
+	if (cs >= controller->info->nce)
+		return -EINVAL;
+
+	chip = controller->chips[cs];
+
+	if (!chip)
+		return -ENODEV;
+
+	ret = aspeed_smc_register_chip(chip);
+
+	return ret ? ret : count;
+}
+static DEVICE_ATTR_WO(attach_chip);
+
+static ssize_t detach_chip_store(struct device *dev, struct device_attribute *attr,
+                                 const char *buf, size_t count)
+{
+	unsigned long cs;
+	struct aspeed_smc_controller *controller;
+	struct aspeed_smc_chip *chip;
+	ssize_t ret = kstrtoul(buf, 0, &cs);
+	if (ret)
+		return ret;
+
+	controller = to_aspeed_smc_controller(dev);
+	if (cs >= controller->info->nce)
+		return -EINVAL;
+
+	chip = controller->chips[cs];
+
+	if (!chip)
+		return -ENODEV;
+
+	ret = aspeed_smc_unregister_chip(chip);
+
+	return ret ? ret : count;
+}
+static DEVICE_ATTR_WO(detach_chip);
+
+static struct attribute *aspeed_smc_sysfs_attrs[] = {
+	&dev_attr_attach_chip.attr,
+	&dev_attr_detach_chip.attr,
+	NULL,
+};
+
+static const struct attribute_group aspeed_smc_sysfs_attr_group = {
+	.attrs = aspeed_smc_sysfs_attrs,
+};
+
 static int aspeed_smc_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
@@ -905,8 +992,16 @@ static int aspeed_smc_probe(struct platform_device *pdev)
 	controller->ahb_window_size = resource_size(res);
 
 	ret = aspeed_smc_setup_flash(controller, np, res);
-	if (ret)
+	if (ret) {
 		dev_err(dev, "Aspeed SMC probe failed %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_device_add_group(dev, &aspeed_smc_sysfs_attr_group);
+	if (ret) {
+		dev_err(dev, "Failed to create sysfs files\n");
+		aspeed_smc_unregister(controller);
+	}
 
 	return ret;
 }
-- 
2.33.0



From zev at bewilderbeest.net  Wed Sep 29 04:54:07 2021
From: zev at bewilderbeest.net (Zev Weiss)
Date: Wed, 29 Sep 2021 04:54:07 -0700
Subject: [PATCH 5/6] mtd: spi-nor: aspeed: Don't automatically attach reserved
 chips
In-Reply-To: <20210929115409.21254-1-zev@bewilderbeest.net>
References: <20210929115409.21254-1-zev@bewilderbeest.net>
Message-ID: <20210929115409.21254-6-zev@bewilderbeest.net>

With this change, any flash chips under the controller that are marked
with a DT status of "reserved" will be created, but not automatically
attached.  Userspace can later request that they be attached using the
attach_chip sysfs file.

This is to accommodate situations where a chip may be (for example)
shared with another controller external to the SoC and require
userspace to arbitrate access to it prior to actually attaching it.
(such as a firmware SPI flash shared between a BMC and the host
system).

Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
---
 drivers/mtd/spi-nor/controllers/aspeed-smc.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/controllers/aspeed-smc.c b/drivers/mtd/spi-nor/controllers/aspeed-smc.c
index da49192a8220..328b008fafb2 100644
--- a/drivers/mtd/spi-nor/controllers/aspeed-smc.c
+++ b/drivers/mtd/spi-nor/controllers/aspeed-smc.c
@@ -826,10 +826,14 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
 	unsigned int cs;
 	int ret = -ENODEV;
 
-	for_each_available_child_of_node(np, child) {
+	for_each_child_of_node(np, child) {
 		struct aspeed_smc_chip *chip;
 		struct spi_nor *nor;
 
+		/* Skip disabled nodes, but include reserved ones for later attachment */
+		if (!of_device_is_available(child) && !of_device_is_reserved(child))
+			continue;
+
 		/* This driver does not support NAND or NOR flash devices. */
 		if (!of_device_is_compatible(child, "jedec,spi-nor"))
 			continue;
@@ -873,6 +877,9 @@ static int aspeed_smc_setup_flash(struct aspeed_smc_controller *controller,
 
 		controller->chips[cs] = chip;
 
+		if (of_device_is_reserved(child))
+			continue;
+
 		ret = aspeed_smc_register_chip(chip);
 		if (ret)
 			break;
-- 
2.33.0



From troglobit at gmail.com  Wed Sep 29 08:27:20 2021
From: troglobit at gmail.com (Joachim Wiberg)
Date: Wed, 29 Sep 2021 17:27:20 +0200
Subject: [RFC PATCH 1/1] mtd: block2mtd: add support for an optional
 custom MTD label
In-Reply-To: <20210928180521.4516405c@xps13>
References: <20210928154937.2668575-1-troglobit@gmail.com>
 <20210928180521.4516405c@xps13>
Message-ID: <87h7e32yhz.fsf@gmail.com>


Hi Miquel!

On Tue, Sep 28, 2021 at 18:05, Miquel Raynal <miquel.raynal at bootlin.com> wrote:
> Hi Joachim,
> troglobit at gmail.com wrote on Tue, 28 Sep 2021 17:49:38 +0200:
>> This patch adds support for an optional MTD label for mtd2block emulated
>> MTD devices.  Useful when, e.g. testing device images using Qemu.  The
>> following /etc/fstab line in can then be used to mount a file system
>> regardless of the actual MTD partition number:
>> 
>>     mtd:Config  /mnt    jffs2   noatime,nodiratime      0    0
>> 
>> Kernel command line syntax:
>> 
>>     block2mtd.block2mtd=/dev/sda,,Config
>> 
>> The ',,' is the optional erase_size, which like before this patch,
>> defaults to PAGE_SIZE when omitted.
> We already have a label property that can be added in the DT, isn't
> it enough?

Unless I'm missing something, no.  Sorry if if the description was a bit
unclear.  Let me try expanding on it a bit.

The block2mtd driver is used a lot when emulating proper MTDs, I'm sure
we are not alone in building system images that a flashed to an MTD
device, which we want to be able to test in Qemu before deploying.

So what we typically do is have a read-only rootfs (squashfs) on one
partition, and another for config data that uses overlayfs to get a
writable /etc, for instance.  This is a reduced example, and the order
of parititions sometimes differ, so we use parition labels. When we test
in Qemu there's only the automatic DTB from Qemu itself that's injected,
e.g.

  qemu-system-aarch64 -M virt -cpu cortex-a53 -nographic       \
	-kernel Image -initrd rootfs.img -append               \
          "root=/dev/ram block2mtd.block2mtd=/dev/vda"         \
        -drive file=config.img,if=none,format=raw,id=hd0       \
        -device virtio-blk-device,drive=hd0

With the default blockt2mtd args we convert the emulated disk to be
used as an MTD partition, but the name we get in Linux is not the
name we have in our /etc/fstab on a real target.

  # cat /proc/mtd 
  dev:    size   erasesize  name
  mtd0: 00f00000 00001000 "block2mtd: /dev/vda"

With the patch we can align the two cases; the embedded system and the
emulated one, by using the same paritition label.  I.e., with the patch
and the new argument to the kernel cmdline:

  qemu-system-aarch64 -M virt -cpu cortex-a53 -nographic       \
	-kernel Image -initrd rootfs.img -append               \
          "root=/dev/ram block2mtd.block2mtd=/dev/vda,,Config" \
        -drive file=config.img,if=none,format=raw,id=hd0       \
        -device virtio-blk-device,drive=hd0

Linux gives the emulated MTD the same partition name we use in the
real embedded system:

  # cat /proc/mtd 
  dev:    size   erasesize  name
  mtd0: 00f00000 00001000 "Config"


Best regards
 /Joachim


From robh+dt at kernel.org  Wed Sep 29 09:08:03 2021
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 29 Sep 2021 11:08:03 -0500
Subject: [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT
 status
In-Reply-To: <20210929115409.21254-1-zev@bewilderbeest.net>
References: <20210929115409.21254-1-zev@bewilderbeest.net>
Message-ID: <CAL_JsqJH+b5oFuSP+KBLBsN5QTA6xASuqXJWXUaDkHhugXPpnQ@mail.gmail.com>

On Wed, Sep 29, 2021 at 6:54 AM Zev Weiss <zev at bewilderbeest.net> wrote:
>
> Hello,
>
> This patch series aims to improve a scenario that arises in OpenBMC
> and which isn't handled very well at the moment.  Certain devices, the
> example at hand being the flash chip used to store the host's firmware
> (e.g. the BIOS), may be shared between the BMC and the host system but
> only available to one or the other at any given time.  The device may
> thus be effectively off-limits to the BMC when it boots, and only
> usable after userspace performs the necessary steps to coordinate
> appropriately with the host (tracking its power state, twiddling
> GPIOs, sending IPMI commands, etc.).
>
> Neither the "okay" nor the "disabled" device-tree status values works
> nicely for the flash device this case -- an "okay" device gets probed
> automatically as soon as the device and a driver for it are available,
> and a "disabled" one gets forgotten about entirely, whereas we want
> the BMC's kernel to be aware of the existence of the device, but not
> try to actually do anything with it (i.e. probe it) until explicitly
> requested to do so by userspace.

While Linux treats 'disabled' as gone forever, that's not exactly what
the spec says. Either disabled or reserved could change in theory. But
I do agree 'reserved' is the right choice for your use.

> However, while there's no support for it currently in the kernel tree,
> the device-tree spec [0] also lists "reserved" as a possible status
> value, and its description seems like a fairly reasonable fit for this
> situation:
>
>   Indicates that the device is operational, but should not be used.
>   Typically this is used for devices that are controlled by another
>   software component, such as platform firmware.
>
> These patches start making use of this status value in the aspeed-smc
> driver.  The first patch adds a companion routine to
> of_device_is_available() that checks for a "reserved" status instead
> of "okay".  The second patch is a small MTD adjustment to allow an
> unregistered device to be cleanly re-registered.  Patches 3 through 5
> modify the aspeed-smc driver to allow individual chips to be attached
> and detached at runtime, and to avoid automatically attaching any
> marked as reserved.  Finally, patch 6 employs the newly-supported
> status in adding support for the BIOS flash device to the ASRock Rack
> e3c246d4i BMC.

I'm not sure this should be MTD specific. There's other cases where we
may want devices to become available. So the question is whether there
should be a more generic mechanism rather than each subsystem coming
up with their own thing.

There's out of tree support for applying overlays which could be used
here. The issue with it is we don't want it to be unconstrained where
an overlay can make any change anywhere in a DT.

Another possibility is making 'status' writeable from userspace. It is
just a sysfs file. That too may need to be opt-in.

Rob


From kernel at kempniu.pl  Wed Sep 29 12:42:24 2021
From: kernel at kempniu.pl (=?utf-8?B?TWljaGHFgiBLxJlwaWXFhA==?=)
Date: Wed, 29 Sep 2021 21:42:24 +0200
Subject: [PATCH] mtd: add MEMREAD ioctl
In-Reply-To: <20210928163519.08cd1138@xps13>
References: <20210920070221.10173-1-kernel@kempniu.pl>
 <20210928155859.433844cb@xps13>
 <20210928162402.6bb64fcf@collabora.com>
 <20210928163519.08cd1138@xps13>
Message-ID: <YVTBoAnQKYLNpOPc@larwa.hq.kempniu.pl>

Miquel, Boris,

Thank you both for your input.

> > I do agree that a new interface is needed, but if we're adding a new
> > entry point, let's make sure it covers all possible use cases we have
> > now. At the very least, I think we're missing info about the maximum
> > number of corrected bits per ECC region on the portion being read.
> > Propagating EUCLEAN errors is nice, but it's not precise enough IMHO.
> > 
> > I remember discussing search a new READ ioctl with Sascha Hauer a few
> > years back, but I can't find the discussion...

I think this is the thread in question:

    https://www.infradead.org/pipermail/linux-mtd/2016-April/thread.html#67085

In fact, it looks like Boris beat me to preparing a draft patch adding a
MEMREAD ioctl by some five years:

    https://www.infradead.org/pipermail/linux-mtd/2016-April/067187.html

It is apparently true that "everything that can be invented has been
invented"... :-)  I did search the web for existing mentions of a
MEMREAD ioctl before submitting my patch, but this thread did not turn
up in the results :(

Anyway, back in 2016, Sascha hinted that he might move forward with the
draft prepared by Boris:

    https://www.infradead.org/pipermail/linux-mtd/2016-April/067215.html

but I cannot find any related submissions from Sascha in linux-mtd's
Patchwork.

> We also discussed a mtd_io_op some time ago, which would equivalently
> replace mtd_oob_ops at some point, including more information such as
> the bitflips which happened on every chunk instead of the information
> regarding the maximum number of bitflips in one of the chunks only.

Is that discussion available online?  Search engines seem to be
oblivious to that term, which makes it hard for me to get acquainted
with that idea and/or to comment on it ;)

> IIRC the point was to get rid of the mtd_{read,write}{,_oob} hooks and
> structures in favor of a more robust and complete set of operations.

That sounds like a major overhaul, right?

I guess the big question from my perspective is: should I revive Boris'
original effort on the MEMREAD ioctl (which returns more detailed
bitflip stats in the structure passed by user space) or would that be a
waste of time because the subsystem will be switched over wholesale to a
new way of doing I/O (mtd_io_op) in the foreseeable future and therefore
exposing yet another ioctl to user space today would be frowned upon?

-- 
Best regards,
Micha? K?pie?


From zweiss at equinix.com  Wed Sep 29 15:00:39 2021
From: zweiss at equinix.com (Zev Weiss)
Date: Wed, 29 Sep 2021 22:00:39 +0000
Subject: [PATCH 0/6] Dynamic aspeed-smc flash chips via "reserved" DT
 status
In-Reply-To: <CAL_JsqJH+b5oFuSP+KBLBsN5QTA6xASuqXJWXUaDkHhugXPpnQ@mail.gmail.com>
References: <20210929115409.21254-1-zev@bewilderbeest.net>
 <CAL_JsqJH+b5oFuSP+KBLBsN5QTA6xASuqXJWXUaDkHhugXPpnQ@mail.gmail.com>
Message-ID: <20210929220038.GS17315@packtop>

On Wed, Sep 29, 2021 at 09:08:03AM PDT, Rob Herring wrote:
>On Wed, Sep 29, 2021 at 6:54 AM Zev Weiss <zev at bewilderbeest.net> wrote:
>>
>> Hello,
>>
>> This patch series aims to improve a scenario that arises in OpenBMC
>> and which isn't handled very well at the moment.  Certain devices, the
>> example at hand being the flash chip used to store the host's firmware
>> (e.g. the BIOS), may be shared between the BMC and the host system but
>> only available to one or the other at any given time.  The device may
>> thus be effectively off-limits to the BMC when it boots, and only
>> usable after userspace performs the necessary steps to coordinate
>> appropriately with the host (tracking its power state, twiddling
>> GPIOs, sending IPMI commands, etc.).
>>
>> Neither the "okay" nor the "disabled" device-tree status values works
>> nicely for the flash device this case -- an "okay" device gets probed
>> automatically as soon as the device and a driver for it are available,
>> and a "disabled" one gets forgotten about entirely, whereas we want
>> the BMC's kernel to be aware of the existence of the device, but not
>> try to actually do anything with it (i.e. probe it) until explicitly
>> requested to do so by userspace.
>
>While Linux treats 'disabled' as gone forever, that's not exactly what
>the spec says. Either disabled or reserved could change in theory. But
>I do agree 'reserved' is the right choice for your use.

True -- the spec's description of "disabled" also sounds like it could
be an appropriate fit for this case, but the existing (somewhat
different) interpretation in the kernel is well-established enough that
I figured that ship had sailed.

>
>> However, while there's no support for it currently in the kernel tree,
>> the device-tree spec [0] also lists "reserved" as a possible status
>> value, and its description seems like a fairly reasonable fit for this
>> situation:
>>
>>   Indicates that the device is operational, but should not be used.
>>   Typically this is used for devices that are controlled by another
>>   software component, such as platform firmware.
>>
>> These patches start making use of this status value in the aspeed-smc
>> driver.  The first patch adds a companion routine to
>> of_device_is_available() that checks for a "reserved" status instead
>> of "okay".  The second patch is a small MTD adjustment to allow an
>> unregistered device to be cleanly re-registered.  Patches 3 through 5
>> modify the aspeed-smc driver to allow individual chips to be attached
>> and detached at runtime, and to avoid automatically attaching any
>> marked as reserved.  Finally, patch 6 employs the newly-supported
>> status in adding support for the BIOS flash device to the ASRock Rack
>> e3c246d4i BMC.
>
>I'm not sure this should be MTD specific. There's other cases where we
>may want devices to become available. So the question is whether there
>should be a more generic mechanism rather than each subsystem coming
>up with their own thing.
>

Agreed, and in fact in an earlier version of these patches I had
approached this via a more generic tweak to the driver-core code to
inhibit attaching drivers to devices marked as reserved.  The problem I
had with that is that it ended up being kind of limited in how far down
the device tree it would actually take effect.  For example in this
particular case, I could mark the entire aspeed-smc controller as
reserved and prevent the driver core from binding the driver to it, but
nothing more fine-grained than that.  If I marked an individual flash
chip behind that controller as reserved, the aspeed-smc driver would get
attached (as expected), but that driver (not the driver core) is
responsible for inspecting its child devices and attaching them, and its
existing probe routine only checks of_device_is_available() and hence
can't distinguish between reserved and disabled.

So while I should probably reincorporate the corresponding driver-core
change, I don't see it as a complete solution, and I don't see an
obvious way to achieve one centrally without requiring modifications in
individual drivers, unfortunately.

>There's out of tree support for applying overlays which could be used
>here. The issue with it is we don't want it to be unconstrained where
>an overlay can make any change anywhere in a DT.
>

Yeah, I'm vaguely aware of the dt-overlay patches, but had been under
the impression that their prospects for mainlining were fairly dim and
hence was looking at alternate approaches (of somewhat more limited scope).

>Another possibility is making 'status' writeable from userspace. It is
>just a sysfs file. That too may need to be opt-in.
>

The sysfs file you're referring to being those under
/sys/firmware/devicetree I assume?  That's an interesting idea...in
addition to making it opt-in, we'd presumably need to restrict what
state transitions are allowed (maybe only okay<->reserved?).  Keeping
/sys/firmware/fdt in sync with that seems like it might be a bit of a
headache though...perhaps that would just remain a static reflection of
whatever the state was at boot?


Thanks,
Zev


From boris.brezillon at collabora.com  Wed Sep 29 23:51:33 2021
From: boris.brezillon at collabora.com (Boris Brezillon)
Date: Thu, 30 Sep 2021 08:51:33 +0200
Subject: [PATCH] mtd: add MEMREAD ioctl
In-Reply-To: <YVTBoAnQKYLNpOPc@larwa.hq.kempniu.pl>
References: <20210920070221.10173-1-kernel@kempniu.pl>
 <20210928155859.433844cb@xps13>
 <20210928162402.6bb64fcf@collabora.com>
 <20210928163519.08cd1138@xps13>
 <YVTBoAnQKYLNpOPc@larwa.hq.kempniu.pl>
Message-ID: <20210930085133.13b5a228@collabora.com>

Hu Michal,

On Wed, 29 Sep 2021 21:42:24 +0200
Micha? K?pie? <kernel at kempniu.pl> wrote:

> Miquel, Boris,
> 
> Thank you both for your input.
> 
> > > I do agree that a new interface is needed, but if we're adding a new
> > > entry point, let's make sure it covers all possible use cases we have
> > > now. At the very least, I think we're missing info about the maximum
> > > number of corrected bits per ECC region on the portion being read.
> > > Propagating EUCLEAN errors is nice, but it's not precise enough IMHO.
> > > 
> > > I remember discussing search a new READ ioctl with Sascha Hauer a few
> > > years back, but I can't find the discussion...  
> 
> I think this is the thread in question:
> 
>     https://www.infradead.org/pipermail/linux-mtd/2016-April/thread.html#67085
> 
> In fact, it looks like Boris beat me to preparing a draft patch adding a
> MEMREAD ioctl by some five years:
> 
>     https://www.infradead.org/pipermail/linux-mtd/2016-April/067187.html

Exactly the one I was referring to. Note that this patch still contains
the unbounded malloc which I think is worth fixing, but other than
that and the addition of ECC stats, it looks pretty similar to yours.

> 
> It is apparently true that "everything that can be invented has been
> invented"... :-)  I did search the web for existing mentions of a
> MEMREAD ioctl before submitting my patch, but this thread did not turn
> up in the results :(
> 
> Anyway, back in 2016, Sascha hinted that he might move forward with the
> draft prepared by Boris:
> 
>     https://www.infradead.org/pipermail/linux-mtd/2016-April/067215.html
> 
> but I cannot find any related submissions from Sascha in linux-mtd's
> Patchwork.
> 
> > We also discussed a mtd_io_op some time ago, which would equivalently
> > replace mtd_oob_ops at some point, including more information such as
> > the bitflips which happened on every chunk instead of the information
> > regarding the maximum number of bitflips in one of the chunks only.  
> 
> Is that discussion available online?  Search engines seem to be
> oblivious to that term, which makes it hard for me to get acquainted
> with that idea and/or to comment on it ;)

Not sure this has been discussed publicly, but I remember suggesting
that to Miquel a while ago to simplify the in-kernel MTD interface.

> 
> > IIRC the point was to get rid of the mtd_{read,write}{,_oob} hooks and
> > structures in favor of a more robust and complete set of operations.  
> 
> That sounds like a major overhaul, right?
> 
> I guess the big question from my perspective is: should I revive Boris'
> original effort on the MEMREAD ioctl (which returns more detailed
> bitflip stats in the structure passed by user space) or would that be a
> waste of time because the subsystem will be switched over wholesale to a
> new way of doing I/O (mtd_io_op) in the foreseeable future and therefore
> exposing yet another ioctl to user space today would be frowned upon?
> 

That's not my call to make, but I think those 2 things are orthogonal
and can be addressed separately.

Regards,

Boris


From richard.weinberger at gmail.com  Thu Sep 30 00:29:21 2021
From: richard.weinberger at gmail.com (Richard Weinberger)
Date: Thu, 30 Sep 2021 09:29:21 +0200
Subject: ubifs: corrupted dirent (ENOENT), problably related to O_TMPFILE
 and linkat
In-Reply-To: <4178a54d-3574-1650-6fa6-55cf2981a46c@emlix.com>
References: <YPkj9NUxNLGG5tjL@emlix.com>
 <2125418384.6749.1626942814175.JavaMail.zimbra@nod.at>
 <3b009a01-1f13-e029-0341-9728d4dc16ea@emlix.com>
 <CAFLxGvwPCvtVKf9zCcU5DaTah3jeuiCX7-S-CPNkK0Zdd92nXQ@mail.gmail.com>
 <4178a54d-3574-1650-6fa6-55cf2981a46c@emlix.com>
Message-ID: <CAFLxGvyh99cEbxVvH0RwSWZ9o-V1K8s-UgfxOTyNiX=JkNOiMA@mail.gmail.com>

Sebastian,

On Thu, Aug 12, 2021 at 2:01 PM Sebastian Gross
<sebastian.gross at emlix.com> wrote:
> > If you enable /sys/kernel/debug/ubifs/chk_fs, it will do a full scan
> > upon mount time.
>  > This can detect such problems. But not fix them.
>
> Much appreciated, thanks. This did in fact discover the missing inode though the dirent was there (ls did work, ls -l not).
>
> (On a related note the local ubifs_debug_info has also an entry for chk_fs but it will never be used :\)
>
>
> With the method above I was able to "poor-man's" bisect the minor kernel versions.
>
> The replay was fixed in v5.3. From there I bisected down to ee1438ce5dc4d67dd8dd1ff51583122a61f5bd9e.
> This one might be a candidate to integrate into the LTS branches.

Ohh. Right. In the past I assumed that a Fixes-Tag qualifies a patch
for stable trees, which did not work
always. :-(

> For 4.19.202 I had to pull in 988bec41318f3fa897e2f8af271bd456936d6caf also.

Be careful. This commit caused other problems that needed fixes. See
"Fixes:" tags.
I'm looking right now into rewriting ee1438 for 4.19.x such that it
can work without 988bec.

Thanks,
//richard


From miquel.raynal at bootlin.com  Thu Sep 30 01:47:21 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 30 Sep 2021 10:47:21 +0200
Subject: [PATCH] mtd: add MEMREAD ioctl
In-Reply-To: <20210930085133.13b5a228@collabora.com>
References: <20210920070221.10173-1-kernel@kempniu.pl>
 <20210928155859.433844cb@xps13>
 <20210928162402.6bb64fcf@collabora.com>
 <20210928163519.08cd1138@xps13>
 <YVTBoAnQKYLNpOPc@larwa.hq.kempniu.pl>
 <20210930085133.13b5a228@collabora.com>
Message-ID: <20210930104721.03dc45bb@xps13>


boris.brezillon at collabora.com wrote on Thu, 30 Sep 2021 08:51:33 +0200:

> Hu Michal,
> 
> On Wed, 29 Sep 2021 21:42:24 +0200
> Micha? K?pie? <kernel at kempniu.pl> wrote:
> 
> > Miquel, Boris,
> > 
> > Thank you both for your input.
> >   
> > > > I do agree that a new interface is needed, but if we're adding a new
> > > > entry point, let's make sure it covers all possible use cases we have
> > > > now. At the very least, I think we're missing info about the maximum
> > > > number of corrected bits per ECC region on the portion being read.
> > > > Propagating EUCLEAN errors is nice, but it's not precise enough IMHO.
> > > > 
> > > > I remember discussing search a new READ ioctl with Sascha Hauer a few
> > > > years back, but I can't find the discussion...    
> > 
> > I think this is the thread in question:
> > 
> >     https://www.infradead.org/pipermail/linux-mtd/2016-April/thread.html#67085
> > 
> > In fact, it looks like Boris beat me to preparing a draft patch adding a
> > MEMREAD ioctl by some five years:
> > 
> >     https://www.infradead.org/pipermail/linux-mtd/2016-April/067187.html  
> 
> Exactly the one I was referring to. Note that this patch still contains
> the unbounded malloc which I think is worth fixing, but other than
> that and the addition of ECC stats, it looks pretty similar to yours.
> 
> > 
> > It is apparently true that "everything that can be invented has been
> > invented"... :-)  I did search the web for existing mentions of a
> > MEMREAD ioctl before submitting my patch, but this thread did not turn
> > up in the results :(
> > 
> > Anyway, back in 2016, Sascha hinted that he might move forward with the
> > draft prepared by Boris:
> > 
> >     https://www.infradead.org/pipermail/linux-mtd/2016-April/067215.html
> > 
> > but I cannot find any related submissions from Sascha in linux-mtd's
> > Patchwork.
> >   
> > > We also discussed a mtd_io_op some time ago, which would equivalently
> > > replace mtd_oob_ops at some point, including more information such as
> > > the bitflips which happened on every chunk instead of the information
> > > regarding the maximum number of bitflips in one of the chunks only.    
> > 
> > Is that discussion available online?  Search engines seem to be
> > oblivious to that term, which makes it hard for me to get acquainted
> > with that idea and/or to comment on it ;)  
> 
> Not sure this has been discussed publicly, but I remember suggesting
> that to Miquel a while ago to simplify the in-kernel MTD interface.

It certainly happened on IRC indeed.

> > > IIRC the point was to get rid of the mtd_{read,write}{,_oob} hooks and
> > > structures in favor of a more robust and complete set of operations.    
> > 
> > That sounds like a major overhaul, right?
> > 
> > I guess the big question from my perspective is: should I revive Boris'
> > original effort on the MEMREAD ioctl (which returns more detailed
> > bitflip stats in the structure passed by user space) or would that be a
> > waste of time because the subsystem will be switched over wholesale to a
> > new way of doing I/O (mtd_io_op) in the foreseeable future and therefore
> > exposing yet another ioctl to user space today would be frowned upon?
> >   
> 
> That's not my call to make, but I think those 2 things are orthogonal
> and can be addressed separately.

Agreed.

Thanks,
Miqu?l


From mika.westerberg at linux.intel.com  Thu Sep 30 03:07:17 2021
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Thu, 30 Sep 2021 13:07:17 +0300
Subject: [PATCH 1/3] mtd: spi-nor: intel-spi: Disable write protection only if
 asked
In-Reply-To: <20210930100719.2176-1-mika.westerberg@linux.intel.com>
References: <20210930100719.2176-1-mika.westerberg@linux.intel.com>
Message-ID: <20210930100719.2176-2-mika.westerberg@linux.intel.com>

Currently the driver tries to disable the BIOS write protection
automatically even if this is not what the user wants. For this reason
modify the driver so that by default it does not touch the write
protection. Only if specifically asked by the user (setting writeable=1
command line parameter) the driver tries to disable the BIOS write
protection.

Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
---
 drivers/mfd/lpc_ich.c                         | 59 +++++++++++++++++--
 .../mtd/spi-nor/controllers/intel-spi-pci.c   | 29 +++++----
 drivers/mtd/spi-nor/controllers/intel-spi.c   | 41 ++++++-------
 include/linux/platform_data/x86/intel-spi.h   |  6 +-
 4 files changed, 96 insertions(+), 39 deletions(-)

diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index f10e53187f67..9ffab9aafd81 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -63,6 +63,8 @@
 #define SPIBASE_BYT		0x54
 #define SPIBASE_BYT_SZ		512
 #define SPIBASE_BYT_EN		BIT(1)
+#define BYT_BCR			0xfc
+#define BYT_BCR_WPD		BIT(0)
 
 #define SPIBASE_LPT		0x3800
 #define SPIBASE_LPT_SZ		512
@@ -1084,12 +1086,57 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
 	return ret;
 }
 
+static bool lpc_ich_byt_set_writeable(void __iomem *base, void *data)
+{
+	u32 val;
+
+	val = readl(base + BYT_BCR);
+	if (!(val & BYT_BCR_WPD)) {
+		val |= BYT_BCR_WPD;
+		writel(val, base + BYT_BCR);
+		val = readl(base + BYT_BCR);
+	}
+
+	return val & BYT_BCR_WPD;
+}
+
+static bool lpc_ich_lpt_set_writeable(void __iomem *base, void *data)
+{
+	struct pci_dev *pdev = data;
+	u32 bcr;
+
+	pci_read_config_dword(pdev, BCR, &bcr);
+	if (!(bcr & BCR_WPD)) {
+		bcr |= BCR_WPD;
+		pci_write_config_dword(pdev, BCR, bcr);
+		pci_read_config_dword(pdev, BCR, &bcr);
+	}
+
+	return bcr & BCR_WPD;
+}
+
+static bool lpc_ich_bxt_set_writeable(void __iomem *base, void *data)
+{
+	unsigned int spi = PCI_DEVFN(13, 2);
+	struct pci_bus *bus = data;
+	u32 bcr;
+
+	pci_bus_read_config_dword(bus, spi, BCR, &bcr);
+	if (!(bcr & BCR_WPD)) {
+		bcr |= BCR_WPD;
+		pci_bus_write_config_dword(bus, spi, BCR, bcr);
+		pci_bus_read_config_dword(bus, spi, BCR, &bcr);
+	}
+
+	return bcr & BCR_WPD;
+}
+
 static int lpc_ich_init_spi(struct pci_dev *dev)
 {
 	struct lpc_ich_priv *priv = pci_get_drvdata(dev);
 	struct resource *res = &intel_spi_res[0];
 	struct intel_spi_boardinfo *info;
-	u32 spi_base, rcba, bcr;
+	u32 spi_base, rcba;
 
 	info = devm_kzalloc(&dev->dev, sizeof(*info), GFP_KERNEL);
 	if (!info)
@@ -1103,6 +1150,8 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
 		if (spi_base & SPIBASE_BYT_EN) {
 			res->start = spi_base & ~(SPIBASE_BYT_SZ - 1);
 			res->end = res->start + SPIBASE_BYT_SZ - 1;
+
+			info->set_writeable = lpc_ich_byt_set_writeable;
 		}
 		break;
 
@@ -1113,8 +1162,8 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
 			res->start = spi_base + SPIBASE_LPT;
 			res->end = res->start + SPIBASE_LPT_SZ - 1;
 
-			pci_read_config_dword(dev, BCR, &bcr);
-			info->writeable = !!(bcr & BCR_WPD);
+			info->set_writeable = lpc_ich_lpt_set_writeable;
+			info->data = dev;
 		}
 		break;
 
@@ -1135,8 +1184,8 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
 			res->start = spi_base & 0xfffffff0;
 			res->end = res->start + SPIBASE_APL_SZ - 1;
 
-			pci_bus_read_config_dword(bus, spi, BCR, &bcr);
-			info->writeable = !!(bcr & BCR_WPD);
+			info->set_writeable = lpc_ich_bxt_set_writeable;
+			info->data = bus;
 		}
 
 		pci_bus_write_config_byte(bus, p2sb, 0xe1, 0x1);
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c
index 1bc53b8bb88a..508f7ca098ef 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c
+++ b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c
@@ -16,12 +16,30 @@
 #define BCR		0xdc
 #define BCR_WPD		BIT(0)
 
+static bool intel_spi_pci_set_writeable(void __iomem *base, void *data)
+{
+	struct pci_dev *pdev = data;
+	u32 bcr;
+
+	/* Try to make the chip read/write */
+	pci_read_config_dword(pdev, BCR, &bcr);
+	if (!(bcr & BCR_WPD)) {
+		bcr |= BCR_WPD;
+		pci_write_config_dword(pdev, BCR, bcr);
+		pci_read_config_dword(pdev, BCR, &bcr);
+	}
+
+	return bcr & BCR_WPD;
+}
+
 static const struct intel_spi_boardinfo bxt_info = {
 	.type = INTEL_SPI_BXT,
+	.set_writeable = intel_spi_pci_set_writeable,
 };
 
 static const struct intel_spi_boardinfo cnl_info = {
 	.type = INTEL_SPI_CNL,
+	.set_writeable = intel_spi_pci_set_writeable,
 };
 
 static int intel_spi_pci_probe(struct pci_dev *pdev,
@@ -29,7 +47,6 @@ static int intel_spi_pci_probe(struct pci_dev *pdev,
 {
 	struct intel_spi_boardinfo *info;
 	struct intel_spi *ispi;
-	u32 bcr;
 	int ret;
 
 	ret = pcim_enable_device(pdev);
@@ -41,15 +58,7 @@ static int intel_spi_pci_probe(struct pci_dev *pdev,
 	if (!info)
 		return -ENOMEM;
 
-	/* Try to make the chip read/write */
-	pci_read_config_dword(pdev, BCR, &bcr);
-	if (!(bcr & BCR_WPD)) {
-		bcr |= BCR_WPD;
-		pci_write_config_dword(pdev, BCR, bcr);
-		pci_read_config_dword(pdev, BCR, &bcr);
-	}
-	info->writeable = !!(bcr & BCR_WPD);
-
+	info->data = pdev;
 	ispi = intel_spi_probe(&pdev->dev, &pdev->resource[0], info);
 	if (IS_ERR(ispi))
 		return PTR_ERR(ispi);
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.c b/drivers/mtd/spi-nor/controllers/intel-spi.c
index a413892ff449..f35597cbea0c 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi.c
+++ b/drivers/mtd/spi-nor/controllers/intel-spi.c
@@ -131,7 +131,6 @@
  * @sregs: Start of software sequencer registers
  * @nregions: Maximum number of regions
  * @pr_num: Maximum number of protected range registers
- * @writeable: Is the chip writeable
  * @locked: Is SPI setting locked
  * @swseq_reg: Use SW sequencer in register reads/writes
  * @swseq_erase: Use SW sequencer in erase operation
@@ -149,7 +148,6 @@ struct intel_spi {
 	void __iomem *sregs;
 	size_t nregions;
 	size_t pr_num;
-	bool writeable;
 	bool locked;
 	bool swseq_reg;
 	bool swseq_erase;
@@ -304,6 +302,14 @@ static int intel_spi_wait_sw_busy(struct intel_spi *ispi)
 				  INTEL_SPI_TIMEOUT * 1000);
 }
 
+static bool intel_spi_set_writeable(struct intel_spi *ispi)
+{
+	if (!ispi->info->set_writeable)
+		return false;
+
+	return ispi->info->set_writeable(ispi->base, ispi->info->data);
+}
+
 static int intel_spi_init(struct intel_spi *ispi)
 {
 	u32 opmenu0, opmenu1, lvscc, uvscc, val;
@@ -316,19 +322,6 @@ static int intel_spi_init(struct intel_spi *ispi)
 		ispi->nregions = BYT_FREG_NUM;
 		ispi->pr_num = BYT_PR_NUM;
 		ispi->swseq_reg = true;
-
-		if (writeable) {
-			/* Disable write protection */
-			val = readl(ispi->base + BYT_BCR);
-			if (!(val & BYT_BCR_WPD)) {
-				val |= BYT_BCR_WPD;
-				writel(val, ispi->base + BYT_BCR);
-				val = readl(ispi->base + BYT_BCR);
-			}
-
-			ispi->writeable = !!(val & BYT_BCR_WPD);
-		}
-
 		break;
 
 	case INTEL_SPI_LPT:
@@ -358,6 +351,12 @@ static int intel_spi_init(struct intel_spi *ispi)
 		return -EINVAL;
 	}
 
+	/* Try to disable write protection if user asked to do so */
+	if (writeable && !intel_spi_set_writeable(ispi)) {
+		dev_warn(ispi->dev, "can't disable chip write protection\n");
+		writeable = false;
+	}
+
 	/* Disable #SMI generation from HW sequencer */
 	val = readl(ispi->base + HSFSTS_CTL);
 	val &= ~HSFSTS_CTL_FSMIE;
@@ -884,9 +883,12 @@ static void intel_spi_fill_partition(struct intel_spi *ispi,
 		/*
 		 * If any of the regions have protection bits set, make the
 		 * whole partition read-only to be on the safe side.
+		 *
+		 * Also if the user did not ask the chip to be writeable
+		 * mask the bit too.
 		 */
-		if (intel_spi_is_protected(ispi, base, limit))
-			ispi->writeable = false;
+		if (!writeable || intel_spi_is_protected(ispi, base, limit))
+			part->mask_flags |= MTD_WRITEABLE;
 
 		end = (limit << 12) + 4096;
 		if (end > part->size)
@@ -927,7 +929,6 @@ struct intel_spi *intel_spi_probe(struct device *dev,
 
 	ispi->dev = dev;
 	ispi->info = info;
-	ispi->writeable = info->writeable;
 
 	ret = intel_spi_init(ispi);
 	if (ret)
@@ -945,10 +946,6 @@ struct intel_spi *intel_spi_probe(struct device *dev,
 
 	intel_spi_fill_partition(ispi, &part);
 
-	/* Prevent writes if not explicitly enabled */
-	if (!ispi->writeable || !writeable)
-		ispi->nor.mtd.flags &= ~MTD_WRITEABLE;
-
 	ret = mtd_device_register(&ispi->nor.mtd, &part, 1);
 	if (ret)
 		return ERR_PTR(ret);
diff --git a/include/linux/platform_data/x86/intel-spi.h b/include/linux/platform_data/x86/intel-spi.h
index 7f53a5c6f35e..7dda3f690465 100644
--- a/include/linux/platform_data/x86/intel-spi.h
+++ b/include/linux/platform_data/x86/intel-spi.h
@@ -19,11 +19,13 @@ enum intel_spi_type {
 /**
  * struct intel_spi_boardinfo - Board specific data for Intel SPI driver
  * @type: Type which this controller is compatible with
- * @writeable: The chip is writeable
+ * @set_writeable: Try to make the chip writeable (optional)
+ * @data: Data to be passed to @set_writeable can be %NULL
  */
 struct intel_spi_boardinfo {
 	enum intel_spi_type type;
-	bool writeable;
+	bool (*set_writeable)(void __iomem *base, void *data);
+	void *data;
 };
 
 #endif /* INTEL_SPI_PDATA_H */
-- 
2.33.0



From mika.westerberg at linux.intel.com  Thu Sep 30 03:07:16 2021
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Thu, 30 Sep 2021 13:07:16 +0300
Subject: [PATCH 0/3] mtd: spi-nor / spi / MFD: Convert intel-spi to SPI MEM
Message-ID: <20210930100719.2176-1-mika.westerberg@linux.intel.com>

Hi all,

Based on discussion on the patch I sent some time ago here:

  http://lists.infradead.org/pipermail/linux-mtd/2021-June/086867.html

it turns out that the preferred way to deal with the SPI flash controller
drivers is through SPI MEM which is part of Linux SPI subsystem.

This series does that for the intel-spi driver. This also renames the
driver to follow the convention used in the SPI subsystem. The first patch
improves the write protection handling to be slightly more safer. The
following two patches do the conversion itself. Note the Intel SPI flash
controller only allows commands such as read, write and so on and it
internally uses whatever addressing etc. it figured from the SFDP on the
flash device.

I have tested this series on two systems with hardware sequencer (full
erase, write) and on a laptop with software sequencer (read only since I
don't have any means to restore the flash contents if something goes
wrong).

Let me know if it is better to send the full patches without rename
detection.

Mika Westerberg (3):
  mtd: spi-nor: intel-spi: Disable write protection only if asked
  mtd: spi-nor: intel-spi: Convert to SPI MEM
  Documentation / MTD: Rename the intel-spi driver

 Documentation/driver-api/mtd/index.rst        |   2 +-
 .../mtd/{intel-spi.rst => spi-intel.rst}      |   8 +-
 drivers/mfd/lpc_ich.c                         |  59 ++-
 drivers/mtd/spi-nor/controllers/Kconfig       |  36 --
 drivers/mtd/spi-nor/controllers/Makefile      |   3 -
 drivers/mtd/spi-nor/controllers/intel-spi.h   |  21 --
 drivers/spi/Kconfig                           |  38 ++
 drivers/spi/Makefile                          |   3 +
 .../intel-spi-pci.c => spi/spi-intel-pci.c}   |  49 ++-
 .../spi-intel-platform.c}                     |  21 +-
 .../intel-spi.c => spi/spi-intel.c}           | 341 +++++++++++-------
 drivers/spi/spi-intel.h                       |  19 +
 include/linux/mfd/lpc_ich.h                   |   2 +-
 .../x86/{intel-spi.h => spi-intel.h}          |  12 +-
 14 files changed, 353 insertions(+), 261 deletions(-)
 rename Documentation/driver-api/mtd/{intel-spi.rst => spi-intel.rst} (94%)
 delete mode 100644 drivers/mtd/spi-nor/controllers/intel-spi.h
 rename drivers/{mtd/spi-nor/controllers/intel-spi-pci.c => spi/spi-intel-pci.c} (84%)
 rename drivers/{mtd/spi-nor/controllers/intel-spi-platform.c => spi/spi-intel-platform.c} (65%)
 rename drivers/{mtd/spi-nor/controllers/intel-spi.c => spi/spi-intel.c} (78%)
 create mode 100644 drivers/spi/spi-intel.h
 rename include/linux/platform_data/x86/{intel-spi.h => spi-intel.h} (64%)

-- 
2.33.0



From mika.westerberg at linux.intel.com  Thu Sep 30 03:07:18 2021
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Thu, 30 Sep 2021 13:07:18 +0300
Subject: [PATCH 2/3] mtd: spi-nor: intel-spi: Convert to SPI MEM
In-Reply-To: <20210930100719.2176-1-mika.westerberg@linux.intel.com>
References: <20210930100719.2176-1-mika.westerberg@linux.intel.com>
Message-ID: <20210930100719.2176-3-mika.westerberg@linux.intel.com>

The preferred way to implement SPI-NOR controller drivers is through SPI
subsubsystem utilizing the SPI MEM core functions. This converts the
Intel SPI flash controller driver over the SPI MEM by moving the driver
from SPI-NOR subsystem to SPI subsystem and in one go make it use the
SPI MEM functions. The driver name will be changed from intel-spi to
spi-intel to match the convention used in the SPI subsystem.

Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
---
 drivers/mtd/spi-nor/controllers/Kconfig       |  36 ---
 drivers/mtd/spi-nor/controllers/Makefile      |   3 -
 drivers/mtd/spi-nor/controllers/intel-spi.h   |  21 --
 drivers/spi/Kconfig                           |  38 +++
 drivers/spi/Makefile                          |   3 +
 .../intel-spi-pci.c => spi/spi-intel-pci.c}   |  20 +-
 .../spi-intel-platform.c}                     |  21 +-
 .../intel-spi.c => spi/spi-intel.c}           | 300 +++++++++++-------
 drivers/spi/spi-intel.h                       |  19 ++
 include/linux/mfd/lpc_ich.h                   |   2 +-
 .../x86/{intel-spi.h => spi-intel.h}          |   6 +-
 11 files changed, 252 insertions(+), 217 deletions(-)
 delete mode 100644 drivers/mtd/spi-nor/controllers/intel-spi.h
 rename drivers/{mtd/spi-nor/controllers/intel-spi-pci.c => spi/spi-intel-pci.c} (86%)
 rename drivers/{mtd/spi-nor/controllers/intel-spi-platform.c => spi/spi-intel-platform.c} (65%)
 rename drivers/{mtd/spi-nor/controllers/intel-spi.c => spi/spi-intel.c} (80%)
 create mode 100644 drivers/spi/spi-intel.h
 rename include/linux/platform_data/x86/{intel-spi.h => spi-intel.h} (89%)

diff --git a/drivers/mtd/spi-nor/controllers/Kconfig b/drivers/mtd/spi-nor/controllers/Kconfig
index 5c0e0ec2e6d1..50f4f3484d42 100644
--- a/drivers/mtd/spi-nor/controllers/Kconfig
+++ b/drivers/mtd/spi-nor/controllers/Kconfig
@@ -26,39 +26,3 @@ config SPI_NXP_SPIFI
 	  SPIFI is a specialized controller for connecting serial SPI
 	  Flash. Enable this option if you have a device with a SPIFI
 	  controller and want to access the Flash as a mtd device.
-
-config SPI_INTEL_SPI
-	tristate
-
-config SPI_INTEL_SPI_PCI
-	tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)"
-	depends on X86 && PCI
-	select SPI_INTEL_SPI
-	help
-	  This enables PCI support for the Intel PCH/PCU SPI controller in
-	  master mode. This controller is present in modern Intel hardware
-	  and is used to hold BIOS and other persistent settings. Using
-	  this driver it is possible to upgrade BIOS directly from Linux.
-
-	  Say N here unless you know what you are doing. Overwriting the
-	  SPI flash may render the system unbootable.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called intel-spi-pci.
-
-config SPI_INTEL_SPI_PLATFORM
-	tristate "Intel PCH/PCU SPI flash platform driver (DANGEROUS)"
-	depends on X86
-	select SPI_INTEL_SPI
-	help
-	  This enables platform support for the Intel PCH/PCU SPI
-	  controller in master mode. This controller is present in modern
-	  Intel hardware and is used to hold BIOS and other persistent
-	  settings. Using this driver it is possible to upgrade BIOS
-	  directly from Linux.
-
-	  Say N here unless you know what you are doing. Overwriting the
-	  SPI flash may render the system unbootable.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called intel-spi-platform.
diff --git a/drivers/mtd/spi-nor/controllers/Makefile b/drivers/mtd/spi-nor/controllers/Makefile
index e7abba491d98..6e2a1dc68466 100644
--- a/drivers/mtd/spi-nor/controllers/Makefile
+++ b/drivers/mtd/spi-nor/controllers/Makefile
@@ -2,6 +2,3 @@
 obj-$(CONFIG_SPI_ASPEED_SMC)	+= aspeed-smc.o
 obj-$(CONFIG_SPI_HISI_SFC)	+= hisi-sfc.o
 obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
-obj-$(CONFIG_SPI_INTEL_SPI)	+= intel-spi.o
-obj-$(CONFIG_SPI_INTEL_SPI_PCI)	+= intel-spi-pci.o
-obj-$(CONFIG_SPI_INTEL_SPI_PLATFORM)	+= intel-spi-platform.o
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.h b/drivers/mtd/spi-nor/controllers/intel-spi.h
deleted file mode 100644
index f2871179fd34..000000000000
--- a/drivers/mtd/spi-nor/controllers/intel-spi.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Intel PCH/PCU SPI flash driver.
- *
- * Copyright (C) 2016, Intel Corporation
- * Author: Mika Westerberg <mika.westerberg at linux.intel.com>
- */
-
-#ifndef INTEL_SPI_H
-#define INTEL_SPI_H
-
-#include <linux/platform_data/x86/intel-spi.h>
-
-struct intel_spi;
-struct resource;
-
-struct intel_spi *intel_spi_probe(struct device *dev,
-	struct resource *mem, const struct intel_spi_boardinfo *info);
-int intel_spi_remove(struct intel_spi *ispi);
-
-#endif /* INTEL_SPI_H */
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 83e352b0c8f9..8c9d5a119046 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -406,6 +406,44 @@ config SPI_IMX
 	help
 	  This enables support for the Freescale i.MX SPI controllers.
 
+config SPI_INTEL
+	tristate
+
+config SPI_INTEL_PCI
+	tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)"
+	depends on PCI && (X86 || COMPILE_TEST)
+	depends on SPI_MEM
+	select SPI_INTEL
+	help
+	  This enables PCI support for the Intel PCH/PCU SPI controller in
+	  master mode. This controller is present in modern Intel hardware
+	  and is used to hold BIOS and other persistent settings. Using
+	  this driver it is possible to upgrade BIOS directly from Linux.
+
+	  Say N here unless you know what you are doing. Overwriting the
+	  SPI flash may render the system unbootable.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called spi-intel-pci.
+
+config SPI_INTEL_PLATFORM
+	tristate "Intel PCH/PCU SPI flash platform driver (DANGEROUS)"
+	depends on X86 || COMPILE_TEST
+	depends on SPI_MEM
+	select SPI_INTEL
+	help
+	  This enables platform support for the Intel PCH/PCU SPI
+	  controller in master mode. This controller is present in modern
+	  Intel hardware and is used to hold BIOS and other persistent
+	  settings. Using this driver it is possible to upgrade BIOS
+	  directly from Linux.
+
+	  Say N here unless you know what you are doing. Overwriting the
+	  SPI flash may render the system unbootable.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called spi-intel-platform.
+
 config SPI_JCORE
 	tristate "J-Core SPI Master"
 	depends on OF && (SUPERH || COMPILE_TEST)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 699db95c8441..070918a79362 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -59,6 +59,9 @@ obj-$(CONFIG_SPI_HISI_KUNPENG)		+= spi-hisi-kunpeng.o
 obj-$(CONFIG_SPI_HISI_SFC_V3XX)		+= spi-hisi-sfc-v3xx.o
 obj-$(CONFIG_SPI_IMG_SPFI)		+= spi-img-spfi.o
 obj-$(CONFIG_SPI_IMX)			+= spi-imx.o
+obj-$(CONFIG_SPI_INTEL)			+= spi-intel.o
+obj-$(CONFIG_SPI_INTEL_PCI)		+= spi-intel-pci.o
+obj-$(CONFIG_SPI_INTEL_PLATFORM)	+= spi-intel-platform.o
 obj-$(CONFIG_SPI_LANTIQ_SSC)		+= spi-lantiq-ssc.o
 obj-$(CONFIG_SPI_JCORE)			+= spi-jcore.o
 obj-$(CONFIG_SPI_LM70_LLP)		+= spi-lm70llp.o
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c b/drivers/spi/spi-intel-pci.c
similarity index 86%
rename from drivers/mtd/spi-nor/controllers/intel-spi-pci.c
rename to drivers/spi/spi-intel-pci.c
index 508f7ca098ef..a177b10bc288 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c
+++ b/drivers/spi/spi-intel-pci.c
@@ -2,16 +2,14 @@
 /*
  * Intel PCH/PCU SPI flash PCI driver.
  *
- * Copyright (C) 2016, Intel Corporation
+ * Copyright (C) 2016 - 2021 Intel Corporation
  * Author: Mika Westerberg <mika.westerberg at linux.intel.com>
  */
 
-#include <linux/ioport.h>
-#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 
-#include "intel-spi.h"
+#include "spi-intel.h"
 
 #define BCR		0xdc
 #define BCR_WPD		BIT(0)
@@ -46,7 +44,6 @@ static int intel_spi_pci_probe(struct pci_dev *pdev,
 			       const struct pci_device_id *id)
 {
 	struct intel_spi_boardinfo *info;
-	struct intel_spi *ispi;
 	int ret;
 
 	ret = pcim_enable_device(pdev);
@@ -59,17 +56,7 @@ static int intel_spi_pci_probe(struct pci_dev *pdev,
 		return -ENOMEM;
 
 	info->data = pdev;
-	ispi = intel_spi_probe(&pdev->dev, &pdev->resource[0], info);
-	if (IS_ERR(ispi))
-		return PTR_ERR(ispi);
-
-	pci_set_drvdata(pdev, ispi);
-	return 0;
-}
-
-static void intel_spi_pci_remove(struct pci_dev *pdev)
-{
-	intel_spi_remove(pci_get_drvdata(pdev));
+	return intel_spi_probe(&pdev->dev, &pdev->resource[0], info);
 }
 
 static const struct pci_device_id intel_spi_pci_ids[] = {
@@ -98,7 +85,6 @@ static struct pci_driver intel_spi_pci_driver = {
 	.name = "intel-spi",
 	.id_table = intel_spi_pci_ids,
 	.probe = intel_spi_pci_probe,
-	.remove = intel_spi_pci_remove,
 };
 
 module_pci_driver(intel_spi_pci_driver);
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-platform.c b/drivers/spi/spi-intel-platform.c
similarity index 65%
rename from drivers/mtd/spi-nor/controllers/intel-spi-platform.c
rename to drivers/spi/spi-intel-platform.c
index f80f1086f928..293e03f239de 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi-platform.c
+++ b/drivers/spi/spi-intel-platform.c
@@ -2,20 +2,18 @@
 /*
  * Intel PCH/PCU SPI flash platform driver.
  *
- * Copyright (C) 2016, Intel Corporation
+ * Copyright (C) 2016 - 2021 Intel Corporation
  * Author: Mika Westerberg <mika.westerberg at linux.intel.com>
  */
 
-#include <linux/ioport.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
-#include "intel-spi.h"
+#include "spi-intel.h"
 
 static int intel_spi_platform_probe(struct platform_device *pdev)
 {
 	struct intel_spi_boardinfo *info;
-	struct intel_spi *ispi;
 	struct resource *mem;
 
 	info = dev_get_platdata(&pdev->dev);
@@ -23,24 +21,11 @@ static int intel_spi_platform_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	ispi = intel_spi_probe(&pdev->dev, mem, info);
-	if (IS_ERR(ispi))
-		return PTR_ERR(ispi);
-
-	platform_set_drvdata(pdev, ispi);
-	return 0;
-}
-
-static int intel_spi_platform_remove(struct platform_device *pdev)
-{
-	struct intel_spi *ispi = platform_get_drvdata(pdev);
-
-	return intel_spi_remove(ispi);
+	return intel_spi_probe(&pdev->dev, mem, info);
 }
 
 static struct platform_driver intel_spi_platform_driver = {
 	.probe = intel_spi_platform_probe,
-	.remove = intel_spi_platform_remove,
 	.driver = {
 		.name = "intel-spi",
 	},
diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.c b/drivers/spi/spi-intel.c
similarity index 80%
rename from drivers/mtd/spi-nor/controllers/intel-spi.c
rename to drivers/spi/spi-intel.c
index f35597cbea0c..e299710bafa9 100644
--- a/drivers/mtd/spi-nor/controllers/intel-spi.c
+++ b/drivers/spi/spi-intel.c
@@ -2,21 +2,19 @@
 /*
  * Intel PCH/PCU SPI flash driver.
  *
- * Copyright (C) 2016, Intel Corporation
+ * Copyright (C) 2016 - 2021 Intel Corporation
  * Author: Mika Westerberg <mika.westerberg at linux.intel.com>
  */
 
-#include <linux/err.h>
-#include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/sizes.h>
-#include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/spi-nor.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
 
-#include "intel-spi.h"
+#include "spi-intel.h"
 
 /* Offsets are from @ispi->base */
 #define BFPREG				0x00
@@ -92,8 +90,6 @@
 /* CPU specifics */
 #define BYT_PR				0x74
 #define BYT_SSFSTS_CTL			0x90
-#define BYT_BCR				0xfc
-#define BYT_BCR_WPD			BIT(0)
 #define BYT_FREG_NUM			5
 #define BYT_PR_NUM			5
 
@@ -125,10 +121,10 @@
  * struct intel_spi - Driver private data
  * @dev: Device pointer
  * @info: Pointer to board specific info
- * @nor: SPI NOR layer structure
  * @base: Beginning of MMIO space
  * @pregs: Start of protection registers
  * @sregs: Start of software sequencer registers
+ * @master: Pointer to the SPI controller structure
  * @nregions: Maximum number of regions
  * @pr_num: Maximum number of protected range registers
  * @locked: Is SPI setting locked
@@ -142,10 +138,10 @@
 struct intel_spi {
 	struct device *dev;
 	const struct intel_spi_boardinfo *info;
-	struct spi_nor nor;
 	void __iomem *base;
 	void __iomem *pregs;
 	void __iomem *sregs;
+	struct spi_controller *master;
 	size_t nregions;
 	size_t pr_num;
 	bool locked;
@@ -199,9 +195,6 @@ static void intel_spi_dump_regs(struct intel_spi *ispi)
 			readl(ispi->sregs + OPMENU1));
 	}
 
-	if (ispi->info->type == INTEL_SPI_BYT)
-		dev_dbg(ispi->dev, "BCR=0x%08x\n", readl(ispi->base + BYT_BCR));
-
 	dev_dbg(ispi->dev, "LVSCC=0x%08x\n", readl(ispi->base + LVSCC));
 	dev_dbg(ispi->dev, "UVSCC=0x%08x\n", readl(ispi->base + UVSCC));
 
@@ -419,7 +412,6 @@ static int intel_spi_init(struct intel_spi *ispi)
 	}
 
 	intel_spi_dump_regs(ispi);
-
 	return 0;
 }
 
@@ -553,10 +545,9 @@ static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len,
 	return 0;
 }
 
-static int intel_spi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
+static int intel_spi_read_reg(struct intel_spi *ispi, u8 opcode, void *buf,
 			      size_t len)
 {
-	struct intel_spi *ispi = nor->priv;
 	int ret;
 
 	/* Address of the first chip */
@@ -574,10 +565,9 @@ static int intel_spi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
 	return intel_spi_read_block(ispi, buf, len);
 }
 
-static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
+static int intel_spi_write_reg(struct intel_spi *ispi, u8 opcode, const void *buf,
 			       size_t len)
 {
-	struct intel_spi *ispi = nor->priv;
 	int ret;
 
 	/*
@@ -632,10 +622,9 @@ static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
 	return intel_spi_hw_cycle(ispi, opcode, len);
 }
 
-static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len,
-			      u_char *read_buf)
+static ssize_t intel_spi_read(struct intel_spi *ispi, u32 from, size_t len,
+			      void *read_buf)
 {
-	struct intel_spi *ispi = nor->priv;
 	size_t block_size, retlen = 0;
 	u32 val, status;
 	ssize_t ret;
@@ -647,16 +636,6 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len,
 	if (WARN_ON_ONCE(ispi->atomic_preopcode))
 		ispi->atomic_preopcode = 0;
 
-	switch (nor->read_opcode) {
-	case SPINOR_OP_READ:
-	case SPINOR_OP_READ_FAST:
-	case SPINOR_OP_READ_4B:
-	case SPINOR_OP_READ_FAST_4B:
-		break;
-	default:
-		return -EINVAL;
-	}
-
 	while (len > 0) {
 		block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
 
@@ -685,7 +664,7 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len,
 			ret = -EACCES;
 
 		if (ret < 0) {
-			dev_err(ispi->dev, "read error: %llx: %#x\n", from,
+			dev_err(ispi->dev, "read error: %x: %#x\n", from,
 				status);
 			return ret;
 		}
@@ -703,10 +682,9 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len,
 	return retlen;
 }
 
-static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len,
-			       const u_char *write_buf)
+static ssize_t intel_spi_write(struct intel_spi *ispi, u32 to, size_t len,
+			       const void *write_buf)
 {
-	struct intel_spi *ispi = nor->priv;
 	size_t block_size, retlen = 0;
 	u32 val, status;
 	ssize_t ret;
@@ -752,7 +730,7 @@ static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len,
 			ret = -EACCES;
 
 		if (ret < 0) {
-			dev_err(ispi->dev, "write error: %llx: %#x\n", to,
+			dev_err(ispi->dev, "write error: %x: %#x\n", to,
 				status);
 			return ret;
 		}
@@ -766,68 +744,150 @@ static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len,
 	return retlen;
 }
 
-static int intel_spi_erase(struct spi_nor *nor, loff_t offs)
+static int intel_spi_erase(struct intel_spi *ispi, u8 opcode, u32 offs)
 {
-	size_t erase_size, len = nor->mtd.erasesize;
-	struct intel_spi *ispi = nor->priv;
 	u32 val, status, cmd;
 	int ret;
 
-	/* If the hardware can do 64k erase use that when possible */
-	if (len >= SZ_64K && ispi->erase_64k) {
+	switch (opcode) {
+	case SPINOR_OP_SE:
 		cmd = HSFSTS_CTL_FCYCLE_ERASE_64K;
-		erase_size = SZ_64K;
-	} else {
+		break;
+
+	case SPINOR_OP_BE_4K:
 		cmd = HSFSTS_CTL_FCYCLE_ERASE;
-		erase_size = SZ_4K;
+		break;
+
+	default:
+		return -EINVAL;
 	}
 
+	writel(offs, ispi->base + FADDR);
+
 	if (ispi->swseq_erase) {
-		while (len > 0) {
-			writel(offs, ispi->base + FADDR);
+		ret = intel_spi_sw_cycle(ispi, opcode, 0,
+					 OPTYPE_WRITE_WITH_ADDR);
+		return ret ? ret : 0;
+	}
+
+	/* Not needed with HW sequencer erase, make sure it is cleared */
+	ispi->atomic_preopcode = 0;
+
+	val = readl(ispi->base + HSFSTS_CTL);
+	val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK);
+	val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE;
+	val |= cmd;
+	val |= HSFSTS_CTL_FGO;
+	writel(val, ispi->base + HSFSTS_CTL);
+
+	ret = intel_spi_wait_hw_busy(ispi);
+	if (ret)
+		return ret;
+
+	status = readl(ispi->base + HSFSTS_CTL);
+	if (status & HSFSTS_CTL_FCERR)
+		return -EIO;
+	else if (status & HSFSTS_CTL_AEL)
+		return -EACCES;
+
+	return 0;
+}
 
-			ret = intel_spi_sw_cycle(ispi, nor->erase_opcode,
-						 0, OPTYPE_WRITE_WITH_ADDR);
-			if (ret)
-				return ret;
+static bool intel_spi_supports_mem_op(struct spi_mem *mem,
+				      const struct spi_mem_op *op)
+{
+	struct intel_spi *ispi = spi_master_get_devdata(mem->spi->master);
 
-			offs += erase_size;
-			len -= erase_size;
+	if (op->cmd.dtr)
+		return false;
+
+	if (ispi->swseq_reg && ispi->locked) {
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(ispi->opcodes); i++) {
+			if (ispi->opcodes[i] == op->cmd.opcode)
+				return true;
 		}
 
-		return 0;
+		return false;
 	}
 
-	/* Not needed with HW sequencer erase, make sure it is cleared */
-	ispi->atomic_preopcode = 0;
+	switch (op->cmd.opcode) {
+	case SPINOR_OP_RDID:
+	case SPINOR_OP_RDSR:
+	case SPINOR_OP_WRSR:
+		return true;
 
-	while (len > 0) {
-		writel(offs, ispi->base + FADDR);
+	case SPINOR_OP_READ:
+	case SPINOR_OP_READ_FAST:
+	case SPINOR_OP_READ_4B:
+	case SPINOR_OP_READ_FAST_4B:
+		return true;
 
-		val = readl(ispi->base + HSFSTS_CTL);
-		val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK);
-		val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE;
-		val |= cmd;
-		val |= HSFSTS_CTL_FGO;
-		writel(val, ispi->base + HSFSTS_CTL);
+	case SPINOR_OP_PP:
+	case SPINOR_OP_PP_4B:
+	case SPINOR_OP_WREN:
+	case SPINOR_OP_WRDI:
+		return true;
 
-		ret = intel_spi_wait_hw_busy(ispi);
-		if (ret)
-			return ret;
+	case SPINOR_OP_SE:
+	case SPINOR_OP_SE_4B:
+		return ispi->erase_64k;
 
-		status = readl(ispi->base + HSFSTS_CTL);
-		if (status & HSFSTS_CTL_FCERR)
-			return -EIO;
-		else if (status & HSFSTS_CTL_AEL)
-			return -EACCES;
+	case SPINOR_OP_BE_4K:
+	case SPINOR_OP_BE_4K_4B:
+		return true;
+	}
+
+	return false;
+}
 
-		offs += erase_size;
-		len -= erase_size;
+static int intel_spi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
+{
+	struct intel_spi *ispi = spi_master_get_devdata(mem->spi->master);
+	size_t nbytes = op->data.nbytes;
+	u8 opcode = op->cmd.opcode;
+
+	if (op->addr.nbytes) {
+		if  (op->data.dir == SPI_MEM_DATA_IN)
+			return intel_spi_read(ispi, op->addr.val, nbytes,
+					      op->data.buf.in);
+		else if (op->data.dir == SPI_MEM_DATA_OUT)
+			return intel_spi_write(ispi, op->addr.val, nbytes,
+					       op->data.buf.out);
+		else if (op->data.dir == SPI_MEM_NO_DATA)
+			return intel_spi_erase(ispi, opcode, op->addr.val);
+	} else {
+		if  (op->data.dir == SPI_MEM_DATA_IN)
+			return intel_spi_read_reg(ispi, opcode, op->data.buf.in,
+						  nbytes);
+		else if (op->data.dir == SPI_MEM_DATA_OUT)
+			return intel_spi_write_reg(ispi, opcode, op->data.buf.out,
+						   nbytes);
+		else if (op->data.dir == SPI_MEM_NO_DATA)
+			return intel_spi_write_reg(ispi, opcode, NULL, 0);
 	}
 
-	return 0;
+	return -EINVAL;
+}
+
+static const char *intel_spi_get_name(struct spi_mem *mem)
+{
+	const struct intel_spi *ispi = spi_master_get_devdata(mem->spi->master);
+
+	/*
+	 * Return name of the flash controller device to be compatible
+	 * with the MTD version.
+	 */
+	return dev_name(ispi->dev);
 }
 
+static const struct spi_controller_mem_ops intel_spi_mem_ops = {
+	.supports_op = intel_spi_supports_mem_op,
+	.exec_op = intel_spi_exec_mem_op,
+	.get_name = intel_spi_get_name,
+};
+
 static bool intel_spi_is_protected(const struct intel_spi *ispi,
 				   unsigned int base, unsigned int limit)
 {
@@ -896,70 +956,74 @@ static void intel_spi_fill_partition(struct intel_spi *ispi,
 	}
 }
 
-static const struct spi_nor_controller_ops intel_spi_controller_ops = {
-	.read_reg = intel_spi_read_reg,
-	.write_reg = intel_spi_write_reg,
-	.read = intel_spi_read,
-	.write = intel_spi_write,
-	.erase = intel_spi_erase,
-};
+static int intel_spi_populate_chip(struct intel_spi *ispi)
+{
+	struct flash_platform_data *pdata;
+	struct spi_board_info chip;
+
+	pdata = devm_kzalloc(ispi->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	pdata->nr_parts = 1;
+	pdata->parts = devm_kcalloc(ispi->dev, sizeof(*pdata->parts),
+				    pdata->nr_parts, GFP_KERNEL);
+	if (!pdata->parts)
+		return -ENOMEM;
+
+	intel_spi_fill_partition(ispi, pdata->parts);
+
+	memset(&chip, 0, sizeof(chip));
+	snprintf(chip.modalias, 8, "spi-nor");
+	chip.platform_data = pdata;
+
+	return spi_new_device(ispi->master, &chip) ? 0 : -ENODEV;
+}
 
-struct intel_spi *intel_spi_probe(struct device *dev,
-	struct resource *mem, const struct intel_spi_boardinfo *info)
+/**
+ * intel_spi_probe() - Probe the Intel SPI flash controller
+ * @dev: Pointer to the parent device
+ * @mem: MMIO resource
+ * @info: Platform spefific information
+ *
+ * Probes Intel SPI flash controller and creates the flash chip device.
+ * Returns %0 on success and negative errno in case of failure.
+ */
+int intel_spi_probe(struct device *dev, struct resource *mem,
+		    const struct intel_spi_boardinfo *info)
 {
-	const struct spi_nor_hwcaps hwcaps = {
-		.mask = SNOR_HWCAPS_READ |
-			SNOR_HWCAPS_READ_FAST |
-			SNOR_HWCAPS_PP,
-	};
-	struct mtd_partition part;
+	struct spi_controller *master;
 	struct intel_spi *ispi;
 	int ret;
 
-	if (!info || !mem)
-		return ERR_PTR(-EINVAL);
+	master = devm_spi_alloc_master(dev, sizeof(*ispi));
+	if (!master)
+		return -ENOMEM;
+
+	master->mem_ops = &intel_spi_mem_ops;
 
-	ispi = devm_kzalloc(dev, sizeof(*ispi), GFP_KERNEL);
-	if (!ispi)
-		return ERR_PTR(-ENOMEM);
+	ispi = spi_master_get_devdata(master);
 
 	ispi->base = devm_ioremap_resource(dev, mem);
 	if (IS_ERR(ispi->base))
-		return ERR_CAST(ispi->base);
+		return PTR_ERR(ispi->base);
 
 	ispi->dev = dev;
+	ispi->master = master;
 	ispi->info = info;
 
 	ret = intel_spi_init(ispi);
 	if (ret)
-		return ERR_PTR(ret);
-
-	ispi->nor.dev = ispi->dev;
-	ispi->nor.priv = ispi;
-	ispi->nor.controller_ops = &intel_spi_controller_ops;
-
-	ret = spi_nor_scan(&ispi->nor, NULL, &hwcaps);
-	if (ret) {
-		dev_info(dev, "failed to locate the chip\n");
-		return ERR_PTR(ret);
-	}
-
-	intel_spi_fill_partition(ispi, &part);
+		return ret;
 
-	ret = mtd_device_register(&ispi->nor.mtd, &part, 1);
+	ret = devm_spi_register_master(dev, master);
 	if (ret)
-		return ERR_PTR(ret);
+		return ret;
 
-	return ispi;
+	return intel_spi_populate_chip(ispi);
 }
 EXPORT_SYMBOL_GPL(intel_spi_probe);
 
-int intel_spi_remove(struct intel_spi *ispi)
-{
-	return mtd_device_unregister(&ispi->nor.mtd);
-}
-EXPORT_SYMBOL_GPL(intel_spi_remove);
-
 MODULE_DESCRIPTION("Intel PCH/PCU SPI flash core driver");
 MODULE_AUTHOR("Mika Westerberg <mika.westerberg at linux.intel.com>");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/spi/spi-intel.h b/drivers/spi/spi-intel.h
new file mode 100644
index 000000000000..40f947f6941a
--- /dev/null
+++ b/drivers/spi/spi-intel.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Intel PCH/PCU SPI flash driver.
+ *
+ * Copyright (C) 2016 - 2021, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg at linux.intel.com>
+ */
+
+#ifndef SPI_INTEL_H
+#define SPI_INTEL_H
+
+#include <linux/platform_data/x86/spi-intel.h>
+
+struct resource;
+
+int intel_spi_probe(struct device *dev, struct resource *mem,
+		    const struct intel_spi_boardinfo *info);
+
+#endif /* SPI_INTEL_H */
diff --git a/include/linux/mfd/lpc_ich.h b/include/linux/mfd/lpc_ich.h
index 39967a5eca6d..ea4a4b1b246a 100644
--- a/include/linux/mfd/lpc_ich.h
+++ b/include/linux/mfd/lpc_ich.h
@@ -8,7 +8,7 @@
 #ifndef LPC_ICH_H
 #define LPC_ICH_H
 
-#include <linux/platform_data/x86/intel-spi.h>
+#include <linux/platform_data/x86/spi-intel.h>
 
 /* GPIO resources */
 #define ICH_RES_GPIO	0
diff --git a/include/linux/platform_data/x86/intel-spi.h b/include/linux/platform_data/x86/spi-intel.h
similarity index 89%
rename from include/linux/platform_data/x86/intel-spi.h
rename to include/linux/platform_data/x86/spi-intel.h
index 7dda3f690465..a512ec37abbb 100644
--- a/include/linux/platform_data/x86/intel-spi.h
+++ b/include/linux/platform_data/x86/spi-intel.h
@@ -6,8 +6,8 @@
  * Author: Mika Westerberg <mika.westerberg at linux.intel.com>
  */
 
-#ifndef INTEL_SPI_PDATA_H
-#define INTEL_SPI_PDATA_H
+#ifndef SPI_INTEL_PDATA_H
+#define SPI_INTEL_PDATA_H
 
 enum intel_spi_type {
 	INTEL_SPI_BYT = 1,
@@ -28,4 +28,4 @@ struct intel_spi_boardinfo {
 	void *data;
 };
 
-#endif /* INTEL_SPI_PDATA_H */
+#endif /* SPI_INTEL_PDATA_H */
-- 
2.33.0



From mika.westerberg at linux.intel.com  Thu Sep 30 03:07:19 2021
From: mika.westerberg at linux.intel.com (Mika Westerberg)
Date: Thu, 30 Sep 2021 13:07:19 +0300
Subject: [PATCH 3/3] Documentation / MTD: Rename the intel-spi driver
In-Reply-To: <20210930100719.2176-1-mika.westerberg@linux.intel.com>
References: <20210930100719.2176-1-mika.westerberg@linux.intel.com>
Message-ID: <20210930100719.2176-4-mika.westerberg@linux.intel.com>

Since the driver is renamed (and moved) update the BIOS upgrade guide
accordingly from intel-spi to intel-spi. Keep the guide under MTD
documentation because this is pretty much still about MTD and SPI-NOR.

Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
---
 Documentation/driver-api/mtd/index.rst                    | 2 +-
 .../driver-api/mtd/{intel-spi.rst => spi-intel.rst}       | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)
 rename Documentation/driver-api/mtd/{intel-spi.rst => spi-intel.rst} (94%)

diff --git a/Documentation/driver-api/mtd/index.rst b/Documentation/driver-api/mtd/index.rst
index 436ba5a851d7..6a4278f409d7 100644
--- a/Documentation/driver-api/mtd/index.rst
+++ b/Documentation/driver-api/mtd/index.rst
@@ -7,6 +7,6 @@ Memory Technology Device (MTD)
 .. toctree::
    :maxdepth: 1
 
-   intel-spi
+   spi-intel
    nand_ecc
    spi-nor
diff --git a/Documentation/driver-api/mtd/intel-spi.rst b/Documentation/driver-api/mtd/spi-intel.rst
similarity index 94%
rename from Documentation/driver-api/mtd/intel-spi.rst
rename to Documentation/driver-api/mtd/spi-intel.rst
index 0465f6879262..df854f20ead1 100644
--- a/Documentation/driver-api/mtd/intel-spi.rst
+++ b/Documentation/driver-api/mtd/spi-intel.rst
@@ -1,5 +1,5 @@
 ==============================
-Upgrading BIOS using intel-spi
+Upgrading BIOS using spi-intel
 ==============================
 
 Many Intel CPUs like Baytrail and Braswell include SPI serial flash host
@@ -11,12 +11,12 @@ avoid accidental (or on purpose) overwrite of the content.
 Not all manufacturers protect the SPI serial flash, mainly because it
 allows upgrading the BIOS image directly from an OS.
 
-The intel-spi driver makes it possible to read and write the SPI serial
+The spi-intel driver makes it possible to read and write the SPI serial
 flash, if certain protection bits are not set and locked. If it finds
 any of them set, the whole MTD device is made read-only to prevent
 partial overwrites. By default the driver exposes SPI serial flash
 contents as read-only but it can be changed from kernel command line,
-passing "intel-spi.writeable=1".
+passing "spi_intel.writeable=1".
 
 Please keep in mind that overwriting the BIOS image on SPI serial flash
 might render the machine unbootable and requires special equipment like
@@ -32,7 +32,7 @@ Linux.
     serial flash. Distros like Debian and Fedora have this prepackaged with
     name "mtd-utils".
 
- 3) Add "intel-spi.writeable=1" to the kernel command line and reboot
+ 3) Add "spi_intel.writeable=1" to the kernel command line and reboot
     the board (you can also reload the driver passing "writeable=1" as
     module parameter to modprobe).
 
-- 
2.33.0



From kernel at kempniu.pl  Thu Sep 30 06:54:07 2021
From: kernel at kempniu.pl (=?utf-8?B?TWljaGHFgiBLxJlwaWXFhA==?=)
Date: Thu, 30 Sep 2021 15:54:07 +0200
Subject: [PATCH] mtd: add MEMREAD ioctl
In-Reply-To: <20210930104721.03dc45bb@xps13>
References: <20210920070221.10173-1-kernel@kempniu.pl>
 <20210928155859.433844cb@xps13>
 <20210928162402.6bb64fcf@collabora.com>
 <20210928163519.08cd1138@xps13>
 <YVTBoAnQKYLNpOPc@larwa.hq.kempniu.pl>
 <20210930085133.13b5a228@collabora.com>
 <20210930104721.03dc45bb@xps13>
Message-ID: <YVXBf0v0AQ5+G9dt@larwa.hq.kempniu.pl>

> > > > > I remember discussing search a new READ ioctl with Sascha Hauer a few
> > > > > years back, but I can't find the discussion...    
> > > 
> > > I think this is the thread in question:
> > > 
> > >     https://www.infradead.org/pipermail/linux-mtd/2016-April/thread.html#67085
> > > 
> > > In fact, it looks like Boris beat me to preparing a draft patch adding a
> > > MEMREAD ioctl by some five years:
> > > 
> > >     https://www.infradead.org/pipermail/linux-mtd/2016-April/067187.html  
> > 
> > Exactly the one I was referring to. Note that this patch still contains
> > the unbounded malloc which I think is worth fixing, but other than
> > that and the addition of ECC stats, it looks pretty similar to yours.

Right, thanks.

> > > I guess the big question from my perspective is: should I revive Boris'
> > > original effort on the MEMREAD ioctl (which returns more detailed
> > > bitflip stats in the structure passed by user space) or would that be a
> > > waste of time because the subsystem will be switched over wholesale to a
> > > new way of doing I/O (mtd_io_op) in the foreseeable future and therefore
> > > exposing yet another ioctl to user space today would be frowned upon?
> > >   
> > 
> > That's not my call to make, but I think those 2 things are orthogonal
> > and can be addressed separately.
> 
> Agreed.

Thank you both - it sounds like I should start working on a v2 that will
make the new MEMREAD ioctl return more detailed ECC statistics to user
space.

Boris, I think a Suggested-by tag crediting you is in order for both the
unbounded malloc issue and the MEMREAD ioctl, but submitting-patches.rst
says I should not add this tag without your permission.  So, are you
okay with me adding it?

Miquel, as for the unbounded malloc issue, should I address this in a
separate (preliminary) patch or rather submit a two-patch v2 series
(unbounded malloc fix + new MEMREAD ioctl)?

-- 
Best regards,
Micha? K?pie?


From miquel.raynal at bootlin.com  Thu Sep 30 06:58:31 2021
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 30 Sep 2021 15:58:31 +0200
Subject: [PATCH] mtd: add MEMREAD ioctl
In-Reply-To: <YVXBf0v0AQ5+G9dt@larwa.hq.kempniu.pl>
References: <20210920070221.10173-1-kernel@kempniu.pl>
 <20210928155859.433844cb@xps13>
 <20210928162402.6bb64fcf@collabora.com>
 <20210928163519.08cd1138@xps13>
 <YVTBoAnQKYLNpOPc@larwa.hq.kempniu.pl>
 <20210930085133.13b5a228@collabora.com>
 <20210930104721.03dc45bb@xps13>
 <YVXBf0v0AQ5+G9dt@larwa.hq.kempniu.pl>
Message-ID: <20210930155831.672acdee@xps13>

Hi Micha?,

kernel at kempniu.pl wrote on Thu, 30 Sep 2021 15:54:07 +0200:

> > > > > > I remember discussing search a new READ ioctl with Sascha Hauer a few
> > > > > > years back, but I can't find the discussion...      
> > > > 
> > > > I think this is the thread in question:
> > > > 
> > > >     https://www.infradead.org/pipermail/linux-mtd/2016-April/thread.html#67085
> > > > 
> > > > In fact, it looks like Boris beat me to preparing a draft patch adding a
> > > > MEMREAD ioctl by some five years:
> > > > 
> > > >     https://www.infradead.org/pipermail/linux-mtd/2016-April/067187.html    
> > > 
> > > Exactly the one I was referring to. Note that this patch still contains
> > > the unbounded malloc which I think is worth fixing, but other than
> > > that and the addition of ECC stats, it looks pretty similar to yours.  
> 
> Right, thanks.
> 
> > > > I guess the big question from my perspective is: should I revive Boris'
> > > > original effort on the MEMREAD ioctl (which returns more detailed
> > > > bitflip stats in the structure passed by user space) or would that be a
> > > > waste of time because the subsystem will be switched over wholesale to a
> > > > new way of doing I/O (mtd_io_op) in the foreseeable future and therefore
> > > > exposing yet another ioctl to user space today would be frowned upon?
> > > >     
> > > 
> > > That's not my call to make, but I think those 2 things are orthogonal
> > > and can be addressed separately.  
> > 
> > Agreed.  
> 
> Thank you both - it sounds like I should start working on a v2 that will
> make the new MEMREAD ioctl return more detailed ECC statistics to user
> space.
> 
> Boris, I think a Suggested-by tag crediting you is in order for both the
> unbounded malloc issue and the MEMREAD ioctl, but submitting-patches.rst
> says I should not add this tag without your permission.  So, are you
> okay with me adding it?
> 
> Miquel, as for the unbounded malloc issue, should I address this in a
> separate (preliminary) patch or rather submit a two-patch v2 series
> (unbounded malloc fix + new MEMREAD ioctl)?

Both work as long as you keep the changes in different commits :)

Thanks,
Miqu?l


From prabhakar.csengg at gmail.com  Thu Sep 30 07:14:18 2021
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Thu, 30 Sep 2021 15:14:18 +0100
Subject: [PATCH 5/6] memory: renesas-rpc-if: Drop usage of
 RPCIF_DIRMAP_SIZE macro
In-Reply-To: <YVXBwx7rxJLRhlTI@shikoro>
References: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20210928140721.8805-6-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <YVXBwx7rxJLRhlTI@shikoro>
Message-ID: <CA+V-a8sZ0qudhbV7Fart-puNQO-ZHhDEG3OdRH=w_dbTHy2A7g@mail.gmail.com>

Hi Wolfram,

Thank you for the review.

On Thu, Sep 30, 2021 at 2:55 PM Wolfram Sang
<wsa+renesas at sang-engineering.com> wrote:
>
> On Tue, Sep 28, 2021 at 03:07:20PM +0100, Lad Prabhakar wrote:
> > RPCIF_DIRMAP_SIZE may differ on various SoC's. Instead of using
> > RPCIF_DIRMAP_SIZE macro use resource size to get dirmap size
> > which is already part of struct rpcif.
> >
> > Also make sure we return error in case devm_ioremap_resource()
> > fails for dirmap.
> >
> > Fixes: ca7d8b980b67 ("memory: add Renesas RPC-IF driver")
> > Fixes: 59e27d7c94aa ("memory: renesas-rpc-if: fix possible NULL pointer dereference of resource")
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> > Reviewed-by: Biju Das <biju.das.jz at bp.renesas.com>
>
> In general, all fine. I just think this should be split into two
> patches:
>
Sure will split this into two.

> > @@ -147,8 +147,6 @@
> >  #define RPCIF_PHYINT         0x0088  /* R/W */
> >  #define RPCIF_PHYINT_WPVAL   BIT(1)
> >
> > -#define RPCIF_DIRMAP_SIZE    0x4000000
> > -
> >  static const struct regmap_range rpcif_volatile_ranges[] = {
> >       regmap_reg_range(RPCIF_SMRDR0, RPCIF_SMRDR1),
> >       regmap_reg_range(RPCIF_SMWDR0, RPCIF_SMWDR1),
> > @@ -547,8 +545,8 @@ EXPORT_SYMBOL(rpcif_manual_xfer);
> >
> >  ssize_t rpcif_dirmap_read(struct rpcif *rpc, u64 offs, size_t len, void *buf)
> >  {
> > -     loff_t from = offs & (RPCIF_DIRMAP_SIZE - 1);
> > -     size_t size = RPCIF_DIRMAP_SIZE - from;
> > +     loff_t from = offs & (rpc->size - 1);
> > +     size_t size = rpc->size - from;
> >
> >       if (len > size)
> >               len = size;
>
> This is the second patch to split which fixes ca7d8b980b67.
>
Will split this change into a second patch but wont add a fixes tag see below..

>
> > @@ -244,7 +242,7 @@ int rpcif_sw_init(struct rpcif *rpc, struct device *dev)
> >       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap");
> >       rpc->dirmap = devm_ioremap_resource(&pdev->dev, res);
> >       if (IS_ERR(rpc->dirmap))
> > -             rpc->dirmap = NULL;
> > +             return PTR_ERR(rpc->dirmap);
> >       rpc->size = resource_size(res);
> >
> >       rpc->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
>
> This is the first patch to split which fixes 59e27d7c94aa.
>
> Makes sense?
>
Both the fixes would apply to the first patch itself i.e. when
resource_size was added in ca7d8b980b67 and later in 59e27d7c94aa
resource_size was moved online below (this would cause kernel panic
res is NULL). Do you agree?

> If you agree, you can add my tag already to the new patches:
>
> Reviewed-by: Wolfram Sang <wsa+renesas at sang-engineering.com>
>
Sure will add your RB tag.

Cheers,
Prabhakar


From boris.brezillon at collabora.com  Thu Sep 30 07:22:46 2021
From: boris.brezillon at collabora.com (Boris Brezillon)
Date: Thu, 30 Sep 2021 16:22:46 +0200
Subject: [PATCH] mtd: add MEMREAD ioctl
In-Reply-To: <YVXBf0v0AQ5+G9dt@larwa.hq.kempniu.pl>
References: <20210920070221.10173-1-kernel@kempniu.pl>
 <20210928155859.433844cb@xps13>
 <20210928162402.6bb64fcf@collabora.com>
 <20210928163519.08cd1138@xps13>
 <YVTBoAnQKYLNpOPc@larwa.hq.kempniu.pl>
 <20210930085133.13b5a228@collabora.com>
 <20210930104721.03dc45bb@xps13>
 <YVXBf0v0AQ5+G9dt@larwa.hq.kempniu.pl>
Message-ID: <20210930162246.61359ea7@collabora.com>

On Thu, 30 Sep 2021 15:54:07 +0200
Micha? K?pie? <kernel at kempniu.pl> wrote:

> Boris, I think a Suggested-by tag crediting you is in order for both the
> unbounded malloc issue and the MEMREAD ioctl, but submitting-patches.rst
> says I should not add this tag without your permission.  So, are you
> okay with me adding it?

Sure, no problem.



From wsa+renesas at sang-engineering.com  Thu Sep 30 07:40:51 2021
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Thu, 30 Sep 2021 16:40:51 +0200
Subject: [PATCH 6/6] memory: renesas-rpc-if: Add support for RZ/G2L
In-Reply-To: <20210928140721.8805-7-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20210928140721.8805-7-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <YVXMc1A4D/y4kjim@shikoro>

Hi,

>  #define RPCIF_CMNCR_IO3FV(val)	(((val) & 0x3) << 14) /* undocumented */
>  #define RPCIF_CMNCR_IO2FV(val)	(((val) & 0x3) << 12) /* undocumented */
>  #define RPCIF_CMNCR_IO0FV(val)	(((val) & 0x3) << 8)
> -#define RPCIF_CMNCR_IOFV_HIZ	(RPCIF_CMNCR_IO0FV(3) | RPCIF_CMNCR_IO2FV(3) | \
> -				 RPCIF_CMNCR_IO3FV(3))
> +#define RPCIF_CMNCR_IOFV_HIZ(val) (RPCIF_CMNCR_IO0FV(val) | RPCIF_CMNCR_IO2FV(val) | \
> +				 RPCIF_CMNCR_IO3FV(val))

Is RPCIF_CMNCR_IO3FV and RPCIF_CMNCR_IO2FV actually documented in your
datasheets? I am asking because I have a patch pending to remove writing
to undocumented locations. So, I was aboout to remove the IO3FV and
IO2FV macros.

> +#define RPCIF_PHYADJ1		0x0070	/* R/W */
> +#define RPCIF_PHYADJ2		0x0074	/* R/W */

Those are named 'PHYADD' and 'PHYWR' in the Gen3 documentation. They are
only available on a few of the Gen3 SoCs. I think the Gen3 namings make
more sense because then it becomes easily understandable that the
registers are used to write something to the PHY.

> +#define RPCIF_PHYCNT_CKSEL(v)	(((v) & 0x3) << 16)

We should add a comment here that these bits are only valid for G2L...

>  #define RPCIF_PHYCNT_STRTIM(v)	(((v) & 0x7) << 15)

and these only for Gen3.


> +static void rpcif_timing_adjust_sdr(struct rpcif *rpc)
> +{
> +	u32 data;
> +
> +	regmap_write(rpc->regmap, RPCIF_PHYADJ2, 0xA5390000);
> +	regmap_write(rpc->regmap, RPCIF_PHYADJ1, 0x80000000);
> +	regmap_write(rpc->regmap, RPCIF_PHYADJ2, 0x00008080);
> +	regmap_write(rpc->regmap, RPCIF_PHYADJ1, 0x80000022);
> +	regmap_write(rpc->regmap, RPCIF_PHYADJ2, 0x00008080);
> +	regmap_write(rpc->regmap, RPCIF_PHYADJ1, 0x80000024);

Can't we have defines for these magic values? At least in my latest Gen3
documentation, these values are explained.

> +
> +	regmap_read(rpc->regmap, RPCIF_PHYCNT, &data);
> +	regmap_write(rpc->regmap, RPCIF_PHYCNT, data | RPCIF_PHYCNT_CKSEL(3));

regmap_update_bits?

> +	if (rpc->type == RPCIF_RCAR_GEN3) {
> +		regmap_write(rpc->regmap, RPCIF_PHYCNT, RPCIF_PHYCNT_STRTIM(7) |
> +			     RPCIF_PHYCNT_PHYMEM(hyperflash ? 3 : 0) | 0x260);
> +	} else {
> +		regmap_read(rpc->regmap, RPCIF_PHYCNT, &dummy);
> +		dummy &= ~RPCIF_PHYCNT_PHYMEM_MASK;
> +		dummy |= RPCIF_PHYCNT_PHYMEM(hyperflash ? 3 : 0) | 0x260;
> +		regmap_write(rpc->regmap, RPCIF_PHYCNT, dummy);

regmap_update_bits?

Rest looks good.

Thanks and happy hacking!

   Wolfram

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210930/8d96c1fc/attachment-0001.sig>

From wsa+renesas at sang-engineering.com  Thu Sep 30 07:43:37 2021
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Thu, 30 Sep 2021 16:43:37 +0200
Subject: [PATCH 5/6] memory: renesas-rpc-if: Drop usage of
 RPCIF_DIRMAP_SIZE macro
In-Reply-To: <CA+V-a8sZ0qudhbV7Fart-puNQO-ZHhDEG3OdRH=w_dbTHy2A7g@mail.gmail.com>
References: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20210928140721.8805-6-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <YVXBwx7rxJLRhlTI@shikoro>
 <CA+V-a8sZ0qudhbV7Fart-puNQO-ZHhDEG3OdRH=w_dbTHy2A7g@mail.gmail.com>
Message-ID: <YVXNGTfOdMgkqxPT@shikoro>


> Both the fixes would apply to the first patch itself i.e. when
> resource_size was added in ca7d8b980b67 and later in 59e27d7c94aa
> resource_size was moved online below (this would cause kernel panic
> res is NULL). Do you agree?

Yes. I do wonder a little if we need the Fixes tag for ca7d8b980b67
because we fix 59e27d7c94aa which already fixes ca7d8b980b67, so there
is a chain. But maybe redundancy doesn't hurt here. I don't mind.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210930/7832e543/attachment.sig>

From wsa+renesas at sang-engineering.com  Thu Sep 30 08:01:56 2021
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Thu, 30 Sep 2021 17:01:56 +0200
Subject: [PATCH 0/6] Add SPI Multi I/O Bus Controller support for RZ/G2L
In-Reply-To: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20210928140721.8805-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <YVXRZNxrgmfROlJy@shikoro>


> This patch series adds a couple of fixes for rpc-if driver and
> adds support for RZ/G2L SoC, where the SPI Multi I/O Bus Controller
> is identical to the RPC-IF block found on R-Car Gen3 SoC's.

I did some basic testing on the Falcon board with a Renesas R-Car V3U
SoC and did not find a regression, so:

Tested-by: Wolfram Sang <wsa+renesas at sang-engineering.com>

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-mtd/attachments/20210930/b4822af7/attachment.sig>

From alexander.sverdlin at nokia.com  Thu Sep 30 08:03:28 2021
From: alexander.sverdlin at nokia.com (Alexander Sverdlin)
Date: Thu, 30 Sep 2021 17:03:28 +0200
Subject: [PATCH 3/3] Documentation / MTD: Rename the intel-spi driver
In-Reply-To: <20210930100719.2176-4-mika.westerberg@linux.intel.com>
References: <20210930100719.2176-1-mika.westerberg@linux.intel.com>
 <20210930100719.2176-4-mika.westerberg@linux.intel.com>
Message-ID: <7e898647-852d-e5f3-bda0-94fbcff88f40@nokia.com>

Hi!

On 30/09/2021 12:07, Mika Westerberg wrote:
> Since the driver is renamed (and moved) update the BIOS upgrade guide
> accordingly from intel-spi to intel-spi. Keep the guide under MTD
                   ^^^^^^^^^^^^^^^^^^^^^^
Copy-paste error.

> documentation because this is pretty much still about MTD and SPI-NOR.
> 
> Signed-off-by: Mika Westerberg <mika.westerberg at linux.intel.com>
> ---
>  Documentation/driver-api/mtd/index.rst                    | 2 +-
>  .../driver-api/mtd/{intel-spi.rst => spi-intel.rst}       | 8 ++++----
>  2 files changed, 5 insertions(+), 5 deletions(-)
>  rename Documentation/driver-api/mtd/{intel-spi.rst => spi-intel.rst} (94%)
> 
> diff --git a/Documentation/driver-api/mtd/index.rst b/Documentation/driver-api/mtd/index.rst
> index 436ba5a851d7..6a4278f409d7 100644
> --- a/Documentation/driver-api/mtd/index.rst
> +++ b/Documentation/driver-api/mtd/index.rst
> @@ -7,6 +7,6 @@ Memory Technology Device (MTD)
>  .. toctree::
>     :maxdepth: 1
>  
> -   intel-spi
> +   spi-intel

-- 
Best regards,
Alexander Sverdlin.


From macroalpha82 at gmail.com  Thu Sep 30 09:24:02 2021
From: macroalpha82 at gmail.com (Chris Morgan)
Date: Thu, 30 Sep 2021 11:24:02 -0500
Subject: [PATCH] mtd: rawnand: hynix: Add support for H27UCG8T2ETR-BC MLC NAND
Message-ID: <20210930162402.344-1-macroalpha82@gmail.com>

From: Chris Morgan <macromorgan at hotmail.com>

Add support for the H27UCG8T2ETR-BC MLC NAND. The NAND is used widely
in the NTC CHIP, is an MLC type NAND, and is 8GB in size. Neither
JEDEC nor ONFI detection identifies it correctly, so the ID is added
to the nand_ids.c file. Additionally, per the datasheet this NAND
appears to use the same paired pages scheme as the Toshiba
TC58TEG5DCLTA00 (dist3), so add support for that to enable use in
SLC emulation mode.

Tested on a NTC CHIP the device is able to write to a ubifs formatted
partition, and then have U-Boot (with proposed patches) boot from a
kernel located on that ubifs formatted partition.

Signed-off-by: Chris Morgan <macromorgan at hotmail.com>
---
 drivers/mtd/nand/raw/nand_hynix.c | 14 ++++++++++++++
 drivers/mtd/nand/raw/nand_ids.c   |  4 ++++
 2 files changed, 18 insertions(+)

diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c
index a9f50c9af109..0d4d4bbfdece 100644
--- a/drivers/mtd/nand/raw/nand_hynix.c
+++ b/drivers/mtd/nand/raw/nand_hynix.c
@@ -686,6 +686,16 @@ h27ucg8t2atrbc_choose_interface_config(struct nand_chip *chip,
 	return nand_choose_best_sdr_timings(chip, iface, NULL);
 }
 
+static int h27ucg8t2etrbc_init(struct nand_chip *chip)
+{
+	struct mtd_info *mtd = nand_to_mtd(chip);
+
+	chip->options |= NAND_NEED_SCRAMBLING;
+	mtd_set_pairing_scheme(mtd, &dist3_pairing_scheme);
+
+	return 0;
+}
+
 static int hynix_nand_init(struct nand_chip *chip)
 {
 	struct hynix_nand *hynix;
@@ -707,6 +717,10 @@ static int hynix_nand_init(struct nand_chip *chip)
 		chip->ops.choose_interface_config =
 			h27ucg8t2atrbc_choose_interface_config;
 
+	if (!strncmp("H27UCG8T2ETR-BC", chip->parameters.model,
+		     sizeof("H27UCG8T2ETR-BC") - 1))
+		h27ucg8t2etrbc_init(chip);
+
 	ret = hynix_nand_rr_init(chip);
 	if (ret)
 		hynix_nand_cleanup(chip);
diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c
index b9945791a9d7..6e41902be35f 100644
--- a/drivers/mtd/nand/raw/nand_ids.c
+++ b/drivers/mtd/nand/raw/nand_ids.c
@@ -51,6 +51,10 @@ struct nand_flash_dev nand_flash_ids[] = {
 		{ .id = {0xad, 0xde, 0x94, 0xda, 0x74, 0xc4} },
 		  SZ_8K, SZ_8K, SZ_2M, NAND_NEED_SCRAMBLING, 6, 640,
 		  NAND_ECC_INFO(40, SZ_1K) },
+	{"H27UCG8T2ETR-BC 64G 3.3V 8-bit",
+		{ .id = {0xad, 0xde, 0x14, 0xa7, 0x42, 0x4a} },
+		  SZ_16K, SZ_8K, SZ_4M, NAND_NEED_SCRAMBLING, 6, 1664,
+		  NAND_ECC_INFO(40, SZ_1K) },
 	{"TH58NVG2S3HBAI4 4G 3.3V 8-bit",
 		{ .id = {0x98, 0xdc, 0x91, 0x15, 0x76} },
 		  SZ_2K, SZ_512, SZ_128K, 0, 5, 128, NAND_ECC_INFO(8, SZ_512) },
-- 
2.30.2



