Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 09/13] mtd: spi-nor: Rework write_sr()
From: Tudor.Ambarus @ 2019-09-11  9:41 UTC (permalink / raw)
  To: marek.vasut, miquel.raynal, richard, vigneshr, joel, andrew,
	matthias.bgg, vz, boris.brezillon, linux-mtd, linux-arm-kernel
  Cc: Tudor.Ambarus
In-Reply-To: <20190911094031.17615-1-tudor.ambarus@microchip.com>

From: Tudor Ambarus <tudor.ambarus@microchip.com>

The Status Register can be written with one or two bytes.

Merge:
static int write_sr(struct spi_nor *nor, u8 val)
static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
into
static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)

Avoid duplicating code by moving the calls to spi_nor_write_enable() and
spi_nor_wait_till_ready() inside spi_nor_write_sr().

Move the spi_nor_wait_till_ready() together with the spi_nor_ready()
methods to avoid forward declarations.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 426 +++++++++++++++++++-----------------------
 1 file changed, 190 insertions(+), 236 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 781564c9ec2f..a903717788f4 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -537,25 +537,198 @@ static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
 	return ret;
 }
 
+static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
+{
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_XRDSR, 1),
+				   SPI_MEM_OP_NO_ADDR,
+				   SPI_MEM_OP_NO_DUMMY,
+				   SPI_MEM_OP_DATA_IN(1, sr, 1));
+
+		return spi_mem_exec_op(nor->spimem, &op);
+	}
+
+	return nor->controller_ops->read_reg(nor, SPINOR_OP_XRDSR, sr, 1);
+}
+
+static int s3an_sr_ready(struct spi_nor *nor)
+{
+	int ret;
+
+	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
+	if (ret < 0) {
+		dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
+		return ret;
+	}
+
+	return !!(nor->bouncebuf[0] & XSR_RDY);
+}
+
+static int spi_nor_clear_sr(struct spi_nor *nor)
+{
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 1),
+				   SPI_MEM_OP_NO_ADDR,
+				   SPI_MEM_OP_NO_DUMMY,
+				   SPI_MEM_OP_NO_DATA);
+
+		return spi_mem_exec_op(nor->spimem, &op);
+	}
+
+	return nor->controller_ops->write_reg(nor, SPINOR_OP_CLSR, NULL, 0);
+}
+
+static int spi_nor_sr_ready(struct spi_nor *nor)
+{
+	int ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
+
+	if (ret)
+		return ret;
+
+	if (nor->flags & SNOR_F_USE_CLSR &&
+	    nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
+		if (nor->bouncebuf[0] & SR_E_ERR)
+			dev_err(nor->dev, "Erase Error occurred\n");
+		else
+			dev_err(nor->dev, "Programming Error occurred\n");
+
+		spi_nor_clear_sr(nor);
+		return -EIO;
+	}
+
+	return !(nor->bouncebuf[0] & SR_WIP);
+}
+
+static int spi_nor_clear_fsr(struct spi_nor *nor)
+{
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 1),
+				   SPI_MEM_OP_NO_ADDR,
+				   SPI_MEM_OP_NO_DUMMY,
+				   SPI_MEM_OP_NO_DATA);
+
+		return spi_mem_exec_op(nor->spimem, &op);
+	}
+
+	return nor->controller_ops->write_reg(nor, SPINOR_OP_CLFSR, NULL, 0);
+}
+
+static int spi_nor_fsr_ready(struct spi_nor *nor)
+{
+	int ret = spi_nor_read_fsr(nor, &nor->bouncebuf[0]);
+
+	if (ret)
+		return ret;
+
+	if (nor->bouncebuf[0] & (FSR_E_ERR | FSR_P_ERR)) {
+		if (nor->bouncebuf[0] & FSR_E_ERR)
+			dev_err(nor->dev, "Erase operation failed.\n");
+		else
+			dev_err(nor->dev, "Program operation failed.\n");
+
+		if (nor->bouncebuf[0] & FSR_PT_ERR)
+			dev_err(nor->dev,
+				"Attempted to modify a protected sector.\n");
+
+		spi_nor_clear_fsr(nor);
+		return -EIO;
+	}
+
+	return nor->bouncebuf[0] & FSR_READY;
+}
+
+static int spi_nor_ready(struct spi_nor *nor)
+{
+	int sr, fsr;
+
+	if (nor->flags & SNOR_F_READY_XSR_RDY)
+		sr = s3an_sr_ready(nor);
+	else
+		sr = spi_nor_sr_ready(nor);
+	if (sr < 0)
+		return sr;
+	fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1;
+	if (fsr < 0)
+		return fsr;
+	return sr && fsr;
+}
+
 /*
- * Write status register 1 byte
- * Returns negative if error occurred.
+ * Service routine to read status register until ready, or timeout occurs.
+ * Returns non-zero if error.
+ */
+static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor,
+						unsigned long timeout_jiffies)
+{
+	unsigned long deadline;
+	int timeout = 0, ret;
+
+	deadline = jiffies + timeout_jiffies;
+
+	while (!timeout) {
+		if (time_after_eq(jiffies, deadline))
+			timeout = 1;
+
+		ret = spi_nor_ready(nor);
+		if (ret < 0)
+			return ret;
+		if (ret)
+			return 0;
+
+		cond_resched();
+	}
+
+	dev_err(nor->dev, "flash operation timed out\n");
+
+	return -ETIMEDOUT;
+}
+
+static int spi_nor_wait_till_ready(struct spi_nor *nor)
+{
+	return spi_nor_wait_till_ready_with_timeout(nor,
+						    DEFAULT_READY_WAIT_JIFFIES);
+}
+
+/**
+ * spi_nor_write_sr() - Write the Status Register.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @sr:		buffer to write to the Status Register.
+ * len:		number of bytes to write to the Status Register.
+ *
+ * Return: 0 on success, -errno otherwise.
  */
-static int write_sr(struct spi_nor *nor, u8 val)
+static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)
 {
-	nor->bouncebuf[0] = val;
+	int ret;
+
+	ret = spi_nor_write_enable(nor);
+	if (ret)
+		return ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR, 1),
 				   SPI_MEM_OP_NO_ADDR,
 				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+				   SPI_MEM_OP_DATA_OUT(len, sr, 1));
 
-		return spi_mem_exec_op(nor->spimem, &op);
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
+						     sr, len);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
-					      nor->bouncebuf, 1);
+	if (ret) {
+		dev_err(nor->dev, "error while writing Status Register\n");
+		return ret;
+	}
+
+	ret = spi_nor_wait_till_ready(nor);
+
+	return ret;
 }
 
 static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
@@ -741,161 +914,6 @@ static int winbond_set_4byte(struct spi_nor *nor, bool enable)
 	return ret;
 }
 
-static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
-{
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_XRDSR, 1),
-				   SPI_MEM_OP_NO_ADDR,
-				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_IN(1, sr, 1));
-
-		return spi_mem_exec_op(nor->spimem, &op);
-	}
-
-	return nor->controller_ops->read_reg(nor, SPINOR_OP_XRDSR, sr, 1);
-}
-
-static int s3an_sr_ready(struct spi_nor *nor)
-{
-	int ret;
-
-	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
-	if (ret < 0) {
-		dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
-		return ret;
-	}
-
-	return !!(nor->bouncebuf[0] & XSR_RDY);
-}
-
-static int spi_nor_clear_sr(struct spi_nor *nor)
-{
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 1),
-				   SPI_MEM_OP_NO_ADDR,
-				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_NO_DATA);
-
-		return spi_mem_exec_op(nor->spimem, &op);
-	}
-
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_CLSR, NULL, 0);
-}
-
-static int spi_nor_sr_ready(struct spi_nor *nor)
-{
-	int ret = spi_nor_read_sr(nor, &nor->bouncebuf[0]);
-
-	if (ret)
-		return ret;
-
-	if (nor->flags & SNOR_F_USE_CLSR &&
-	    nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
-		if (nor->bouncebuf[0] & SR_E_ERR)
-			dev_err(nor->dev, "Erase Error occurred\n");
-		else
-			dev_err(nor->dev, "Programming Error occurred\n");
-
-		spi_nor_clear_sr(nor);
-		return -EIO;
-	}
-
-	return !(nor->bouncebuf[0] & SR_WIP);
-}
-
-static int spi_nor_clear_fsr(struct spi_nor *nor)
-{
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 1),
-				   SPI_MEM_OP_NO_ADDR,
-				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_NO_DATA);
-
-		return spi_mem_exec_op(nor->spimem, &op);
-	}
-
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_CLFSR, NULL, 0);
-}
-
-static int spi_nor_fsr_ready(struct spi_nor *nor)
-{
-	int ret = spi_nor_read_fsr(nor, &nor->bouncebuf[0]);
-
-	if (ret)
-		return ret;
-
-	if (nor->bouncebuf[0] & (FSR_E_ERR | FSR_P_ERR)) {
-		if (nor->bouncebuf[0] & FSR_E_ERR)
-			dev_err(nor->dev, "Erase operation failed.\n");
-		else
-			dev_err(nor->dev, "Program operation failed.\n");
-
-		if (nor->bouncebuf[0] & FSR_PT_ERR)
-			dev_err(nor->dev,
-				"Attempted to modify a protected sector.\n");
-
-		spi_nor_clear_fsr(nor);
-		return -EIO;
-	}
-
-	return nor->bouncebuf[0] & FSR_READY;
-}
-
-static int spi_nor_ready(struct spi_nor *nor)
-{
-	int sr, fsr;
-
-	if (nor->flags & SNOR_F_READY_XSR_RDY)
-		sr = s3an_sr_ready(nor);
-	else
-		sr = spi_nor_sr_ready(nor);
-	if (sr < 0)
-		return sr;
-	fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1;
-	if (fsr < 0)
-		return fsr;
-	return sr && fsr;
-}
-
-/*
- * Service routine to read status register until ready, or timeout occurs.
- * Returns non-zero if error.
- */
-static int spi_nor_wait_till_ready_with_timeout(struct spi_nor *nor,
-						unsigned long timeout_jiffies)
-{
-	unsigned long deadline;
-	int timeout = 0, ret;
-
-	deadline = jiffies + timeout_jiffies;
-
-	while (!timeout) {
-		if (time_after_eq(jiffies, deadline))
-			timeout = 1;
-
-		ret = spi_nor_ready(nor);
-		if (ret < 0)
-			return ret;
-		if (ret)
-			return 0;
-
-		cond_resched();
-	}
-
-	dev_err(nor->dev, "flash operation timed out\n");
-
-	return -ETIMEDOUT;
-}
-
-static int spi_nor_wait_till_ready(struct spi_nor *nor)
-{
-	return spi_nor_wait_till_ready_with_timeout(nor,
-						    DEFAULT_READY_WAIT_JIFFIES);
-}
-
 /*
  * Erase the whole flash memory
  *
@@ -1376,15 +1394,7 @@ static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask)
 {
 	int ret;
 
-	ret = spi_nor_write_enable(nor);
-	if (ret)
-		return ret;
-
-	ret = write_sr(nor, status_new);
-	if (ret)
-		return ret;
-
-	ret = spi_nor_wait_till_ready(nor);
+	ret = spi_nor_write_sr(nor, &status_new, 1);
 	if (ret)
 		return ret;
 
@@ -1714,49 +1724,6 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	return ret;
 }
 
-/*
- * Write status Register and configuration register with 2 bytes
- * The first byte will be written to the status register, while the
- * second byte will be written to the configuration register.
- * Return negative if error occurred.
- */
-static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
-{
-	int ret;
-
-	ret = spi_nor_write_enable(nor);
-	if (ret)
-		return ret;
-
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR, 1),
-				   SPI_MEM_OP_NO_ADDR,
-				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_OUT(2, sr_cr, 1));
-
-		ret = spi_mem_exec_op(nor->spimem, &op);
-	} else {
-		ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR,
-						     sr_cr, 2);
-	}
-
-	if (ret < 0) {
-		dev_err(nor->dev,
-			"error while writing configuration register\n");
-		return -EINVAL;
-	}
-
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret) {
-		dev_err(nor->dev,
-			"timeout while writing configuration register\n");
-		return ret;
-	}
-
-	return 0;
-}
-
 /**
  * macronix_quad_enable() - set QE bit in Status Register.
  * @nor:	pointer to a 'struct spi_nor'
@@ -1778,13 +1745,9 @@ static int macronix_quad_enable(struct spi_nor *nor)
 	if (nor->bouncebuf[0] & SR_QUAD_EN_MX)
 		return 0;
 
-	ret = spi_nor_write_enable(nor);
-	if (ret)
-		return ret;
-
-	write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
+	nor->bouncebuf[0] |= SR_QUAD_EN_MX;
 
-	ret = spi_nor_wait_till_ready(nor);
+	ret = spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
 	if (ret)
 		return ret;
 
@@ -1831,7 +1794,7 @@ static int spansion_quad_enable(struct spi_nor *nor)
 
 	sr_cr[0] = 0;
 	sr_cr[1] = CR_QUAD_EN_SPAN;
-	ret = write_sr_cr(nor, sr_cr);
+	ret = spi_nor_write_sr(nor, sr_cr, 2);
 	if (ret)
 		return ret;
 
@@ -1873,7 +1836,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
 
 	sr_cr[1] = CR_QUAD_EN_SPAN;
 
-	return write_sr_cr(nor, sr_cr);
+	return spi_nor_write_sr(nor, sr_cr, 2);
 }
 
 /**
@@ -1909,7 +1872,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
-	ret = write_sr_cr(nor, sr_cr);
+	ret = spi_nor_write_sr(nor, sr_cr, 2);
 	if (ret)
 		return ret;
 
@@ -2027,19 +1990,10 @@ static int spi_nor_clear_sr_bp(struct spi_nor *nor)
 	if (ret)
 		return ret;
 
-	ret = spi_nor_write_enable(nor);
-	if (ret)
-		return ret;
+	nor->bouncebuf[0] &= mask;
 
-	ret = write_sr(nor, nor->bouncebuf[0] & ~mask);
-	if (ret) {
-		dev_err(nor->dev, "write to status register failed\n");
-		return ret;
-	}
+	ret = spi_nor_write_sr(nor, &nor->bouncebuf[0], 1);
 
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret)
-		dev_err(nor->dev, "timeout while writing status register\n");
 	return ret;
 }
 
@@ -2078,7 +2032,7 @@ static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
 
 		sr_cr[0] &= ~mask;
 
-		ret = write_sr_cr(nor, sr_cr);
+		ret = spi_nor_write_sr(nor, sr_cr, 2);
 		if (ret)
 			dev_err(nor->dev, "16-bit write register failed\n");
 		return ret;
-- 
2.9.5


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 10/13] mtd: spi-nor: Rework spi_nor_read/write_sr2()
From: Tudor.Ambarus @ 2019-09-11  9:41 UTC (permalink / raw)
  To: marek.vasut, miquel.raynal, richard, vigneshr, joel, andrew,
	matthias.bgg, vz, boris.brezillon, linux-mtd, linux-arm-kernel
  Cc: Tudor.Ambarus
In-Reply-To: <20190911094031.17615-1-tudor.ambarus@microchip.com>

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Move the methods up in the file, where the other Register
operations reside.

The error is reported inside each SR2 function, to spare the callers
of duplicating code.

Constify sr2 in spi_nor_write_sr2(). Do the spi_nor_write_enable() and
spi_nor_wait_till_ready() inside spi_nor_write_sr2(), as the
spi_nor_write_sr() does.

While modyfing sr2_bit7_quad_enable(), add a new line for better code
readability.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 118 ++++++++++++++++++++++++++----------------
 1 file changed, 74 insertions(+), 44 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index a903717788f4..b720c0003b27 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -731,6 +731,74 @@ static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)
 	return ret;
 }
 
+/**
+ * spi_nor_write_sr2() - Write the Status Register 2 using the
+ * SPINOR_OP_WRSR2 (3eh) command.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @sr2:	buffer to write to the Status Register.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2)
+{
+	int ret;
+
+	ret = spi_nor_write_enable(nor);
+	if (ret)
+		return ret;
+
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR2, 1),
+				   SPI_MEM_OP_NO_ADDR,
+				   SPI_MEM_OP_NO_DUMMY,
+				   SPI_MEM_OP_DATA_OUT(1, sr2, 1));
+
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR2,
+						     sr2, 1);
+	}
+
+	if (ret)
+		dev_err(nor->dev, "error while writing Status Register 2\n");
+
+	ret = spi_nor_wait_till_ready(nor);
+
+	return ret;
+}
+
+/**
+ * spi_nor_read_sr2() - Read the Status Register 2 using the
+ * SPINOR_OP_RDSR2 (3fh) command.
+ * @nor:	pointer to 'struct spi_nor'
+ * @sr2:	buffer where the value of the Status Register will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
+{
+	int ret;
+
+	if (nor->spimem) {
+		struct spi_mem_op op =
+			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR2, 1),
+				   SPI_MEM_OP_NO_ADDR,
+				   SPI_MEM_OP_NO_DUMMY,
+				   SPI_MEM_OP_DATA_IN(1, sr2, 1));
+
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2,
+						    sr2, 1);
+	}
+
+	if (ret)
+		dev_err(nor->dev, "error while reading Status Register 2\n");
+
+	return ret;
+}
+
 static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
 {
 	return mtd->priv;
@@ -1889,36 +1957,6 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
 	return 0;
 }
 
-static int spi_nor_write_sr2(struct spi_nor *nor, u8 *sr2)
-{
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR2, 1),
-				   SPI_MEM_OP_NO_ADDR,
-				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_OUT(1, sr2, 1));
-
-		return spi_mem_exec_op(nor->spimem, &op);
-	}
-
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_WRSR2, sr2, 1);
-}
-
-static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
-{
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR2, 1),
-				   SPI_MEM_OP_NO_ADDR,
-				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_IN(1, sr2, 1));
-
-		return spi_mem_exec_op(nor->spimem, &op);
-	}
-
-	return nor->controller_ops->read_reg(nor, SPINOR_OP_RDSR2, sr2, 1);
-}
-
 /**
  * sr2_bit7_quad_enable() - set QE bit in Status Register 2.
  * @nor:	pointer to a 'struct spi_nor'
@@ -1940,31 +1978,23 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
 	ret = spi_nor_read_sr2(nor, sr2);
 	if (ret)
 		return ret;
+
 	if (*sr2 & SR2_QUAD_EN_BIT7)
 		return 0;
 
 	/* Update the Quad Enable bit. */
 	*sr2 |= SR2_QUAD_EN_BIT7;
 
-	ret = spi_nor_write_enable(nor);
-	if (ret)
-		return ret;
-
 	ret = spi_nor_write_sr2(nor, sr2);
-	if (ret < 0) {
-		dev_err(nor->dev, "error while writing status register 2\n");
-		return -EINVAL;
-	}
-
-	ret = spi_nor_wait_till_ready(nor);
-	if (ret < 0) {
-		dev_err(nor->dev, "timeout while writing status register 2\n");
+	if (ret)
 		return ret;
-	}
 
 	/* Read back and check it. */
 	ret = spi_nor_read_sr2(nor, sr2);
-	if (!(ret > 0 && (*sr2 & SR2_QUAD_EN_BIT7))) {
+	if (ret)
+		return ret;
+
+	if (!(*sr2 & SR2_QUAD_EN_BIT7)) {
 		dev_err(nor->dev, "SR2 Quad bit not set\n");
 		return -EINVAL;
 	}
-- 
2.9.5


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 11/13] mtd: spi-nor: Report error in spi_nor_xread_sr()
From: Tudor.Ambarus @ 2019-09-11  9:41 UTC (permalink / raw)
  To: marek.vasut, miquel.raynal, richard, vigneshr, joel, andrew,
	matthias.bgg, vz, boris.brezillon, linux-mtd, linux-arm-kernel
  Cc: Tudor.Ambarus
In-Reply-To: <20190911094031.17615-1-tudor.ambarus@microchip.com>

From: Tudor Ambarus <tudor.ambarus@microchip.com>

The error is reported inside spi_nor_xread_sr(), to spare the
callers of duplicating code.

Add method description. Drop unnecessary cast to int when reporting
the error. Comparing the return code with zero is enough, drop the
checking for negative return values.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index b720c0003b27..0505bf6c197e 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -537,8 +537,17 @@ static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
 	return ret;
 }
 
+/**
+ * spi_nor_xread_sr() - Read the Status Register on S3AN flashes.
+ * @nor:	pointer to 'struct spi_nor'
+ * @sr:		buffer where the value of the Status Register will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
 static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
 {
+	int ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_XRDSR, 1),
@@ -546,10 +555,16 @@ static int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_DATA_IN(1, sr, 1));
 
-		return spi_mem_exec_op(nor->spimem, &op);
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_XRDSR,
+						    sr, 1);
 	}
 
-	return nor->controller_ops->read_reg(nor, SPINOR_OP_XRDSR, sr, 1);
+	if (ret)
+		dev_err(nor->dev, "error %d reading XRDSR\n", ret);
+
+	return ret;
 }
 
 static int s3an_sr_ready(struct spi_nor *nor)
@@ -557,10 +572,8 @@ static int s3an_sr_ready(struct spi_nor *nor)
 	int ret;
 
 	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
-	if (ret < 0) {
-		dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
+	if (ret)
 		return ret;
-	}
 
 	return !!(nor->bouncebuf[0] & XSR_RDY);
 }
@@ -2797,10 +2810,8 @@ static int s3an_nor_setup(struct spi_nor *nor,
 	int ret;
 
 	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
-	if (ret < 0) {
-		dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
+	if (ret)
 		return ret;
-	}
 
 	nor->erase_opcode = SPINOR_OP_XSE;
 	nor->program_opcode = SPINOR_OP_XPP;
-- 
2.9.5


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 12/13] mtd: spi-nor: Void return type for spi_nor_clear_sr/fsr()
From: Tudor.Ambarus @ 2019-09-11  9:41 UTC (permalink / raw)
  To: marek.vasut, miquel.raynal, richard, vigneshr, joel, andrew,
	matthias.bgg, vz, boris.brezillon, linux-mtd, linux-arm-kernel
  Cc: Tudor.Ambarus
In-Reply-To: <20190911094031.17615-1-tudor.ambarus@microchip.com>

From: Tudor Ambarus <tudor.ambarus@microchip.com>

spi_nor_clear_sr() and spi_nor_clear_fsr() are called just in case
of errors. The callers didn't check their return value. Make them
of type void and print an error in case the operations fail.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 36 ++++++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 0505bf6c197e..e0fbf9c00d24 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -578,8 +578,16 @@ static int s3an_sr_ready(struct spi_nor *nor)
 	return !!(nor->bouncebuf[0] & XSR_RDY);
 }
 
-static int spi_nor_clear_sr(struct spi_nor *nor)
+/**
+ * spi_nor_clear_sr() - Clear the Status Register 1.
+ * @nor:        pointer to 'struct spi_nor'
+ *
+ * Prints error in case the operation fails.
+ */
+static void spi_nor_clear_sr(struct spi_nor *nor)
 {
+	int ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLSR, 1),
@@ -587,10 +595,14 @@ static int spi_nor_clear_sr(struct spi_nor *nor)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_NO_DATA);
 
-		return spi_mem_exec_op(nor->spimem, &op);
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->write_reg(nor, SPINOR_OP_CLSR,
+						     NULL, 0);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_CLSR, NULL, 0);
+	if (ret)
+		dev_err(nor->dev, "error %d clearing Status Register 1\n", ret);
 }
 
 static int spi_nor_sr_ready(struct spi_nor *nor)
@@ -614,8 +626,16 @@ static int spi_nor_sr_ready(struct spi_nor *nor)
 	return !(nor->bouncebuf[0] & SR_WIP);
 }
 
-static int spi_nor_clear_fsr(struct spi_nor *nor)
+/**
+ * spi_nor_clear_fsr() - Clear the Flag Status Register.
+ * @nor:        pointer to 'struct spi_nor'
+ *
+ * Prints error in case the operation fails.
+ */
+static void spi_nor_clear_fsr(struct spi_nor *nor)
 {
+	int ret;
+
 	if (nor->spimem) {
 		struct spi_mem_op op =
 			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_CLFSR, 1),
@@ -623,10 +643,14 @@ static int spi_nor_clear_fsr(struct spi_nor *nor)
 				   SPI_MEM_OP_NO_DUMMY,
 				   SPI_MEM_OP_NO_DATA);
 
-		return spi_mem_exec_op(nor->spimem, &op);
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->write_reg(nor, SPINOR_OP_CLFSR,
+						     NULL, 0);
 	}
 
-	return nor->controller_ops->write_reg(nor, SPINOR_OP_CLFSR, NULL, 0);
+	if (ret)
+		dev_err(nor->dev, "error %d clearing FSR\n", ret);
 }
 
 static int spi_nor_fsr_ready(struct spi_nor *nor)
-- 
2.9.5


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH 13/13] mtd: spi-nor: Drop duplicated new line
From: Tudor.Ambarus @ 2019-09-11  9:41 UTC (permalink / raw)
  To: marek.vasut, miquel.raynal, richard, vigneshr, joel, andrew,
	matthias.bgg, vz, boris.brezillon, linux-mtd, linux-arm-kernel
  Cc: Tudor.Ambarus
In-Reply-To: <20190911094031.17615-1-tudor.ambarus@microchip.com>

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Two new lines, remove one.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index e0fbf9c00d24..22d0775cf2ba 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -841,7 +841,6 @@ static struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
 	return mtd->priv;
 }
 
-
 static u8 spi_nor_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
 {
 	size_t i;
-- 
2.9.5


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v1 3/3] scsi: ufs-mediatek: enable auto suspend capability
From: Stanley Chu @ 2019-09-11  9:41 UTC (permalink / raw)
  To: linux-scsi, martin.petersen, avri.altman, alim.akhtar,
	pedrom.sousa, sthumma, jejb, bvanassche
  Cc: marc.w.gonzalez, andy.teng, chun-hung.wu, kuohong.wang, evgreen,
	subhashj, linux-mediatek, peter.wang, vivek.gautam, matthias.bgg,
	Stanley Chu, linux-arm-kernel, beanhuo
In-Reply-To: <1568194890-24439-1-git-send-email-stanley.chu@mediatek.com>

Enable auto suspend capability in MediaTek UFS driver.

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/scsi/ufs/ufs-mediatek.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c
index 0f6ff33ce52e..b7b177c6194c 100644
--- a/drivers/scsi/ufs/ufs-mediatek.c
+++ b/drivers/scsi/ufs/ufs-mediatek.c
@@ -117,6 +117,11 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on,
 	return ret;
 }
 
+static void ufs_mtk_set_caps(struct ufs_hba *hba)
+{
+	hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND;
+}
+
 /**
  * ufs_mtk_init - find other essential mmio bases
  * @hba: host controller instance
@@ -147,6 +152,8 @@ static int ufs_mtk_init(struct ufs_hba *hba)
 	if (err)
 		goto out_variant_clear;
 
+	ufs_mtk_set_caps(hba);
+
 	/*
 	 * ufshcd_vops_init() is invoked after
 	 * ufshcd_setup_clock(true) in ufshcd_hba_init() thus
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v1] scsi: allow auto suspend override by low-level driver
From: Stanley Chu @ 2019-09-11  9:41 UTC (permalink / raw)
  To: linux-scsi, martin.petersen, avri.altman, alim.akhtar,
	pedrom.sousa, sthumma, jejb, bvanassche
  Cc: marc.w.gonzalez, andy.teng, chun-hung.wu, kuohong.wang, evgreen,
	subhashj, linux-mediatek, peter.wang, vivek.gautam, matthias.bgg,
	Stanley Chu, linux-arm-kernel, beanhuo

Until now the scsi mid-layer forbids runtime suspend till userspace
enables it. This is mainly to quarantine some disks with broken
runtime power management or have high latencies executing suspend
resume callbacks. If the userspace doesn't enable the runtime suspend
the underlying hardware will be always on even when it is not doing
any useful work and thus wasting power.

Some low-level drivers for the controllers can efficiently use runtime
power management to reduce power consumption and improve battery life.

This patchset allows runtime suspend parameters override within the LLD itself
instead of waiting for userspace to control the power management, and
make UFS as the first user of this capability.

Stanley Chu (3):
  scsi: core: allow auto suspend override by low-level driver
  scsi: ufs: override auto suspend tunables for ufs
  scsi: ufs-mediatek: enable auto suspend capability

 drivers/scsi/scsi_sysfs.c       |  3 ++-
 drivers/scsi/sd.c               |  3 +++
 drivers/scsi/ufs/ufs-mediatek.c |  7 +++++++
 drivers/scsi/ufs/ufshcd.c       |  8 ++++++++
 drivers/scsi/ufs/ufshcd.h       | 10 ++++++++++
 include/scsi/scsi_device.h      |  2 +-
 6 files changed, 31 insertions(+), 2 deletions(-)

-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v1 2/3] scsi: ufs: override auto suspend tunables for ufs
From: Stanley Chu @ 2019-09-11  9:41 UTC (permalink / raw)
  To: linux-scsi, martin.petersen, avri.altman, alim.akhtar,
	pedrom.sousa, sthumma, jejb, bvanassche
  Cc: marc.w.gonzalez, andy.teng, chun-hung.wu, kuohong.wang, evgreen,
	subhashj, linux-mediatek, peter.wang, vivek.gautam, matthias.bgg,
	Stanley Chu, linux-arm-kernel, beanhuo
In-Reply-To: <1568194890-24439-1-git-send-email-stanley.chu@mediatek.com>

Rework from previous work by:
Sujit Reddy Thumma <sthumma@codeaurora.org>

Override auto suspend tunables for UFS device LUNs during
initialization so as to efficiently manage background operations
and the power consumption.

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/scsi/ufs/ufshcd.c |  8 ++++++++
 drivers/scsi/ufs/ufshcd.h | 10 ++++++++++
 2 files changed, 18 insertions(+)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 30b752c61b97..d253a018a73b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -88,6 +88,9 @@
 /* Interrupt aggregation default timeout, unit: 40us */
 #define INT_AGGR_DEF_TO	0x02
 
+/* default delay of autosuspend: 2000 ms */
+#define RPM_AUTOSUSPEND_DELAY_MS 2000
+
 #define ufshcd_toggle_vreg(_dev, _vreg, _on)				\
 	({                                                              \
 		int _ret;                                               \
@@ -4612,9 +4615,14 @@ static int ufshcd_change_queue_depth(struct scsi_device *sdev, int depth)
  */
 static int ufshcd_slave_configure(struct scsi_device *sdev)
 {
+	struct ufs_hba *hba = shost_priv(sdev->host);
 	struct request_queue *q = sdev->request_queue;
 
 	blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1);
+
+	if (ufshcd_is_rpm_autosuspend_allowed(hba))
+		sdev->rpm_autosuspend_delay = RPM_AUTOSUSPEND_DELAY_MS;
+
 	return 0;
 }
 
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index a43c7135f33d..99ea416519af 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -714,6 +714,12 @@ struct ufs_hba {
 	 * the performance of ongoing read/write operations.
 	 */
 #define UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND (1 << 5)
+	/*
+	 * This capability allows host controller driver to automatically
+	 * enable runtime power management by itself instead of waiting
+	 * for userspace to control the power management.
+	 */
+#define UFSHCD_CAP_RPM_AUTOSUSPEND (1 << 6)
 
 	struct devfreq *devfreq;
 	struct ufs_clk_scaling clk_scaling;
@@ -747,6 +753,10 @@ static inline bool ufshcd_can_autobkops_during_suspend(struct ufs_hba *hba)
 {
 	return hba->caps & UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
 }
+static inline bool ufshcd_is_rpm_autosuspend_allowed(struct ufs_hba *hba)
+{
+	return hba->caps & UFSHCD_CAP_RPM_AUTOSUSPEND;
+}
 
 static inline bool ufshcd_is_intr_aggr_allowed(struct ufs_hba *hba)
 {
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v1 1/3] scsi: core: allow auto suspend override by low-level driver
From: Stanley Chu @ 2019-09-11  9:41 UTC (permalink / raw)
  To: linux-scsi, martin.petersen, avri.altman, alim.akhtar,
	pedrom.sousa, sthumma, jejb, bvanassche
  Cc: marc.w.gonzalez, andy.teng, chun-hung.wu, kuohong.wang, evgreen,
	subhashj, linux-mediatek, peter.wang, vivek.gautam, matthias.bgg,
	Stanley Chu, linux-arm-kernel, beanhuo
In-Reply-To: <1568194890-24439-1-git-send-email-stanley.chu@mediatek.com>

Rework from previous work by:
Sujit Reddy Thumma <sthumma@codeaurora.org>

Until now the scsi mid-layer forbids runtime suspend till userspace
enables it. This is mainly to quarantine some disks with broken
runtime power management or have high latencies executing suspend
resume callbacks. If the userspace doesn't enable the runtime suspend
the underlying hardware will be always on even when it is not doing
any useful work and thus wasting power.

Some low-level drivers for the controllers can efficiently use runtime
power management to reduce power consumption and improve battery life.
Allow runtime suspend parameters override within the LLD itself
instead of waiting for userspace to control the power management.

Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
---
 drivers/scsi/scsi_sysfs.c  | 3 ++-
 drivers/scsi/sd.c          | 3 +++
 include/scsi/scsi_device.h | 2 +-
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 64c96c7828ee..66a8a5c74352 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1300,7 +1300,8 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
 	device_enable_async_suspend(&sdev->sdev_gendev);
 	scsi_autopm_get_target(starget);
 	pm_runtime_set_active(&sdev->sdev_gendev);
-	pm_runtime_forbid(&sdev->sdev_gendev);
+	if (sdev->rpm_autosuspend_delay <= 0)
+		pm_runtime_forbid(&sdev->sdev_gendev);
 	pm_runtime_enable(&sdev->sdev_gendev);
 	scsi_autopm_put_target(starget);
 
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 149d406aacc9..2218d57c4c0c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -3371,6 +3371,9 @@ static int sd_probe(struct device *dev)
 	}
 
 	blk_pm_runtime_init(sdp->request_queue, dev);
+	if (sdp->rpm_autosuspend_delay > 0)
+		pm_runtime_set_autosuspend_delay(dev,
+						 sdp->rpm_autosuspend_delay);
 	device_add_disk(dev, gd, NULL);
 	if (sdkp->capacity)
 		sd_dif_config_host(sdkp);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 202f4d6a4342..133b282fae5a 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -199,7 +199,7 @@ struct scsi_device {
 	unsigned broken_fua:1;		/* Don't set FUA bit */
 	unsigned lun_in_cdb:1;		/* Store LUN bits in CDB[1] */
 	unsigned unmap_limit_for_ws:1;	/* Use the UNMAP limit for WRITE SAME */
-
+	int rpm_autosuspend_delay;
 	atomic_t disk_events_disable_depth; /* disable depth for disk events */
 
 	DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [RFC, v3, 3/4] media: platform: Add Mediatek MDP3 driver KConfig
From: Bibby Hsieh @ 2019-09-11  9:41 UTC (permalink / raw)
  To: hans.verkuil, laurent.pinchart+renesas, tfiga, matthias.bgg,
	mchehab
  Cc: devicetree, Sean.Cheng, Rynn.Wu, srv_heupstream, daoyuan huang,
	holmes.chiou, Jerry-ch.Chen, jungo.lin, sj.huang, yuzhao,
	linux-mediatek, Ping-Hsun Wu, zwisler, christie.yu, frederic.chen,
	linux-arm-kernel, linux-media

From: daoyuan huang <daoyuan.huang@mediatek.com>

This patch adds Kconfig for Mediatek Media Data Path 3 (MDP3)
driver. MDP3 is used to do scaling and color format conversion.

Signed-off-by: Ping-Hsun Wu <ping-hsun.wu@mediatek.com>
Signed-off-by: daoyuan huang <daoyuan.huang@mediatek.com>
---
 drivers/media/platform/Kconfig  | 19 +++++++++++++++++++
 drivers/media/platform/Makefile |  1 +
 2 files changed, 20 insertions(+)

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 8a19654b393a..b38071650768 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -240,6 +240,25 @@ config VIDEO_MEDIATEK_MDP
 	    To compile this driver as a module, choose M here: the
 	    module will be called mtk-mdp.
 
+config VIDEO_MEDIATEK_MDP3
+	tristate "Mediatek MDP v3 driver"
+	depends on MTK_IOMMU || COMPILE_TEST
+	depends on VIDEO_DEV && VIDEO_V4L2
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on HAS_DMA
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_MEM2MEM_DEV
+	select VIDEO_MEDIATEK_VPU
+	select MTK_CMDQ
+	select MTK_SCP
+	default n
+	help
+	    It is a v4l2 driver and present in Mediatek MT8183 SoC.
+	    The driver supports for scaling and color space conversion.
+
+	    To compile this driver as a module, choose M here: the
+	    module will be called mtk-mdp3.
+
 config VIDEO_MEDIATEK_VCODEC
 	tristate "Mediatek Video Codec driver"
 	depends on MTK_IOMMU || COMPILE_TEST
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 7cbbd925124c..14c1ecce5378 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -89,6 +89,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VPU)	+= mtk-vpu/
 obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC)	+= mtk-vcodec/
 
 obj-$(CONFIG_VIDEO_MEDIATEK_MDP)	+= mtk-mdp/
+obj-$(CONFIG_VIDEO_MEDIATEK_MDP3)	+= mtk-mdp3/
 
 obj-$(CONFIG_VIDEO_MEDIATEK_JPEG)	+= mtk-jpeg/
 
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH 2/2] gpio: iproc-gpio: Handle interrupts for multiple instances
From: Linus Walleij @ 2019-09-11  9:42 UTC (permalink / raw)
  To: Srinath Mannam
  Cc: Scott Branden, Rayagonda Kokatanur, Ray Jui,
	linux-kernel@vger.kernel.org, bcm-kernel-feedback-list, Linux ARM
In-Reply-To: <1567054348-19685-3-git-send-email-srinath.mannam@broadcom.com>

On Thu, Aug 29, 2019 at 5:52 AM Srinath Mannam
<srinath.mannam@broadcom.com> wrote:

> From: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com>
>
> When multiple instance of iproc-gpio chips are present, a fix up
> message[1] is printed during the probe of second and later instances.
>
> This issue is because driver sharing same irq_chip data structure
> among multiple instances of driver.
>
> Fix this by allocating irq_chip data structure per instance of
> iproc-gpio.
>
> [1] fix up message addressed by this patch
> [  7.862208] gpio gpiochip2: (689d0000.gpio): detected irqchip that
>    is shared with multiple gpiochips: please fix the driver.
>
> Fixes: 616043d58a89 ("pinctrl: Rename gpio driver from cygnus to iproc")
> Signed-off-by: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com>

Patch applied, I had to rewrite it a bit to fit the new code that
set up the irqchip when adding the gpio_chip, please check that
the result works.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v1 1/1] pinctrl: iproc: Add 'get_direction' support
From: Linus Walleij @ 2019-09-11  9:44 UTC (permalink / raw)
  To: Rayagonda Kokatanur
  Cc: Scott Branden, Ray Jui, linux-kernel@vger.kernel.org,
	open list:GPIO SUBSYSTEM, bcm-kernel-feedback-list, Linux ARM
In-Reply-To: <1568178685-30738-1-git-send-email-rayagonda.kokatanur@broadcom.com>

On Wed, Sep 11, 2019 at 6:16 AM Rayagonda Kokatanur
<rayagonda.kokatanur@broadcom.com> wrote:

> Add 'get_direction' support to the iProc GPIO driver.
>
> Signed-off-by: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com>

Patch applied, thanks for doing this!

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [virtio-dev] Re: [PATCH v9 0/8] stg mail -e --version=v9 \
From: David Hildenbrand @ 2019-09-11  9:50 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Yang Zhang, Pankaj Gupta, kvm list, Catalin Marinas,
	Alexander Duyck, Michal Hocko, linux-mm, Alexander Duyck, will,
	Andrea Arcangeli, virtio-dev, Konrad Rzeszutek Wilk,
	Matthew Wilcox, Wang, Wei W, ying.huang, Rik van Riel,
	Dr. David Alan Gilbert, Dan Williams, lcapitulino,
	linux-arm-kernel, Oscar Salvador, Nitesh Narayan Lal, Dave Hansen,
	LKML, Paolo Bonzini, Andrew Morton, Fengguang Wu,
	Kirill A. Shutemov
In-Reply-To: <20190911051819-mutt-send-email-mst@kernel.org>

On 11.09.19 11:23, Michael S. Tsirkin wrote:
> On Tue, Sep 10, 2019 at 06:22:37PM +0200, David Hildenbrand wrote:
>> On 10.09.19 18:18, Dr. David Alan Gilbert wrote:
>>> * Alexander Duyck (alexander.duyck@gmail.com) wrote:
>>>> On Tue, Sep 10, 2019 at 7:47 AM Michal Hocko <mhocko@kernel.org> wrote:
>>>>>
>>>>> On Tue 10-09-19 07:42:43, Alexander Duyck wrote:
>>>>>> On Tue, Sep 10, 2019 at 5:42 AM Michal Hocko <mhocko@kernel.org> wrote:
>>>>>>>
>>>>>>> I wanted to review "mm: Introduce Reported pages" just realize that I
>>>>>>> have no clue on what is going on so returned to the cover and it didn't
>>>>>>> really help much. I am completely unfamiliar with virtio so please bear
>>>>>>> with me.
>>>>>>>
>>>>>>> On Sat 07-09-19 10:25:03, Alexander Duyck wrote:
>>>>>>> [...]
>>>>>>>> This series provides an asynchronous means of reporting to a hypervisor
>>>>>>>> that a guest page is no longer in use and can have the data associated
>>>>>>>> with it dropped. To do this I have implemented functionality that allows
>>>>>>>> for what I am referring to as unused page reporting
>>>>>>>>
>>>>>>>> The functionality for this is fairly simple. When enabled it will allocate
>>>>>>>> statistics to track the number of reported pages in a given free area.
>>>>>>>> When the number of free pages exceeds this value plus a high water value,
>>>>>>>> currently 32, it will begin performing page reporting which consists of
>>>>>>>> pulling pages off of free list and placing them into a scatter list. The
>>>>>>>> scatterlist is then given to the page reporting device and it will perform
>>>>>>>> the required action to make the pages "reported", in the case of
>>>>>>>> virtio-balloon this results in the pages being madvised as MADV_DONTNEED
>>>>>>>> and as such they are forced out of the guest. After this they are placed
>>>>>>>> back on the free list,
>>>>>>>
>>>>>>> And here I am reallly lost because "forced out of the guest" makes me
>>>>>>> feel that those pages are no longer usable by the guest. So how come you
>>>>>>> can add them back to the free list. I suspect understanding this part
>>>>>>> will allow me to understand why we have to mark those pages and prevent
>>>>>>> merging.
>>>>>>
>>>>>> Basically as the paragraph above mentions "forced out of the guest"
>>>>>> really is just the hypervisor calling MADV_DONTNEED on the page in
>>>>>> question. So the behavior is the same as any userspace application
>>>>>> that calls MADV_DONTNEED where the contents are no longer accessible
>>>>>> from userspace and attempting to access them will result in a fault
>>>>>> and the page being populated with a zero fill on-demand page, or a
>>>>>> copy of the file contents if the memory is file backed.
>>>>>
>>>>> As I've said I have no idea about virt so this doesn't really tell me
>>>>> much. Does that mean that if somebody allocates such a page and tries to
>>>>> access it then virt will handle a fault and bring it back?
>>>>
>>>> Actually I am probably describing too much as the MADV_DONTNEED is the
>>>> hypervisor behavior in response to the virtio-balloon notification. A
>>>> more thorough explanation of it can be found by just running "man
>>>> madvise", probably best just to leave it at that since I am probably
>>>> confusing things by describing hypervisor behavior in a kernel patch
>>>> set.
>>>>
>>>> For the most part all the page reporting really does is provide a way
>>>> to incrementally identify unused regions of memory in the buddy
>>>> allocator. That in turn is used by virtio-balloon in a polling thread
>>>> to report to the hypervisor what pages are not in use so that it can
>>>> make a decision on what to do with the pages now that it knows they
>>>> are unused.
>>>>
>>>> All this is providing is just a report and it is optional if the
>>>> hypervisor will act on it or not. If the hypervisor takes some sort of
>>>> action on the page, then the expectation is that the hypervisor will
>>>> use some sort of mechanism such as a page fault to discover when the
>>>> page is used again.
>>>
>>> OK, that's interestingly different (but OK) from some other schemes that
>>> hav ebeen described which *require* the guest to somehow indicate the
>>> page is in use before starting to use the page again.
>>>
>>
>> virtio-balloon also has a mode where the guest would not have to
>> indicate to the host before re-using a page. Only
>> VIRTIO_BALLOON_F_MUST_TELL_HOST enforces this. So it's not completely new.
> 
> VIRTIO_BALLOON_F_MUST_TELL_HOST is a bit different.
> When it's not set, guest still must tell host about
> pages in use, it just can batch these notifications
> sending them possibly after page has been used.
> So even with VIRTIO_BALLOON_F_MUST_TELL_HOST off you don't
> skip the notification.
> 

I don't think so

VIRTIO_BALLOON_F_MUST_TELL_HOST     0 /* Tell before reclaiming pages */

commit bf50e69f63d21091e525185c3ae761412be0ba72
Author: Dave Hansen <dave@linux.vnet.ibm.com>
Date:   Thu Apr 7 10:43:25 2011 -0700

    virtio balloon: kill tell-host-first logic

[...]

    But, if the bit is _not_ set, we are under no obligation to
    reverse the order; we're under no obligation to do _anything_.
    As of now, qemu-kvm defines the bit, but doesn't set it.


Old code simply told the hypervisor afterwards, but only for little
performance gain. It is not strictly necessary.

> From hypervisor point of view, this feature is very much like adding
> page to the balloon and immediately taking it out of the balloon again,
> just doing it in one operation.
> 
> The main difference is the contents of the page, which matters
> with poisoning: in that case hypervisor is expected to hand
> back page with the poisoning content. Not so with regular
> deflate where page contents is undefined.
> 
> Well and also the new interface is optimized for large chunks
> of memory since we'll likely be dealing with such.
> 
>>> Dave
>>
>>
>> -- 
>>
>> Thanks,
>>
>> David / dhildenb


-- 

Thanks,

David / dhildenb

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH] gpio/mpc8xxx: change irq handler from chained to normal
From: Hui Song @ 2019-09-11  9:45 UTC (permalink / raw)
  To: Shawn Guo, Li Yang, Rob Herring, Mark Rutland, Linus Walleij,
	Bartosz Golaszewski
  Cc: devicetree, Song Hui, linux-kernel, linux-arm-kernel, linux-gpio

From: Song Hui <hui.song_1@nxp.com>

More than one gpio controllers can share one interrupt, change the
driver to request shared irq.

Signed-off-by: Laurentiu Tudor <Laurentiu.Tudor@nxp.com>
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Song Hui <hui.song_1@nxp.com>
---
Changes in v4:
	- convert 'pr_err' to 'dev_err'.
Changes in v3:
	- update the patch description.
Changes in v2:
	- delete the compatible of ls1088a.
 drivers/gpio/gpio-mpc8xxx.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 16a47de..e16591b 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/gpio/driver.h>
 #include <linux/bitops.h>
+#include <linux/interrupt.h>
 
 #define MPC8XXX_GPIO_PINS	32
 
@@ -127,10 +128,9 @@ static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
 		return -ENXIO;
 }
 
-static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc)
+static irqreturn_t mpc8xxx_gpio_irq_cascade(int irq, void *data)
 {
-	struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
-	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct mpc8xxx_gpio_chip *mpc8xxx_gc = (struct mpc8xxx_gpio_chip *)data;
 	struct gpio_chip *gc = &mpc8xxx_gc->gc;
 	unsigned int mask;
 
@@ -139,8 +139,8 @@ static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc)
 	if (mask)
 		generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
 						     32 - ffs(mask)));
-	if (chip->irq_eoi)
-		chip->irq_eoi(&desc->irq_data);
+
+	return IRQ_HANDLED;
 }
 
 static void mpc8xxx_irq_unmask(struct irq_data *d)
@@ -388,7 +388,7 @@ static int mpc8xxx_probe(struct platform_device *pdev)
 
 	ret = gpiochip_add_data(gc, mpc8xxx_gc);
 	if (ret) {
-		pr_err("%pOF: GPIO chip registration failed with status %d\n",
+		dev_err("%pOF: GPIO chip registration failed with status %d\n",
 		       np, ret);
 		goto err;
 	}
@@ -409,8 +409,14 @@ static int mpc8xxx_probe(struct platform_device *pdev)
 	if (devtype->gpio_dir_in_init)
 		devtype->gpio_dir_in_init(gc);
 
-	irq_set_chained_handler_and_data(mpc8xxx_gc->irqn,
-					 mpc8xxx_gpio_irq_cascade, mpc8xxx_gc);
+	ret = request_irq(mpc8xxx_gc->irqn, mpc8xxx_gpio_irq_cascade,
+		IRQF_NO_THREAD | IRQF_SHARED, "gpio-cascade", mpc8xxx_gc);
+	if (ret) {
+		dev_err("%s: failed to request_irq(%d), ret = %d\n",
+				np->full_name, mpc8xxx_gc->irqn, ret);
+		goto err;
+	}
+
 	return 0;
 err:
 	iounmap(mpc8xxx_gc->regs);
-- 
2.9.5


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH] pinctrl: bcm: remove redundant assignment to pointer log
From: Linus Walleij @ 2019-09-11  9:57 UTC (permalink / raw)
  To: Colin King
  Cc: Scott Branden, Ray Jui, kernel-janitors,
	linux-kernel@vger.kernel.org, open list:GPIO SUBSYSTEM,
	bcm-kernel-feedback-list, Linux ARM
In-Reply-To: <20190905140919.29283-1-colin.king@canonical.com>

On Thu, Sep 5, 2019 at 3:09 PM Colin King <colin.king@canonical.com> wrote:

> From: Colin Ian King <colin.king@canonical.com>
>
> The pointer log is being initialized with a value that is never read
> and is being re-assigned a little later on. The assignment is
> redundant and hence can be removed.
>
> Addresses-Coverity: ("Unused value")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>

Patch applied.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH] gpio/mpc8xxx: change irq handler from chained to normal
From: Hui Song @ 2019-09-11  9:52 UTC (permalink / raw)
  To: Shawn Guo, Li Yang, Rob Herring, Mark Rutland, Linus Walleij,
	Bartosz Golaszewski
  Cc: devicetree, Song Hui, linux-kernel, linux-arm-kernel, linux-gpio

From: Song Hui <hui.song_1@nxp.com>

More than one gpio controllers can share one interrupt, change the
driver to request shared irq.

Signed-off-by: Laurentiu Tudor <Laurentiu.Tudor@nxp.com>
Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com>
Signed-off-by: Song Hui <hui.song_1@nxp.com>
---
Changes in v4:
	- convert 'pr_err' to 'dev_err'.
Changes in v3:
	- update the patch description.
Changes in v2:
	- delete the compatible of ls1088a.
 drivers/gpio/gpio-mpc8xxx.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 16a47de..e16591b 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -22,6 +22,7 @@
 #include <linux/irq.h>
 #include <linux/gpio/driver.h>
 #include <linux/bitops.h>
+#include <linux/interrupt.h>
 
 #define MPC8XXX_GPIO_PINS	32
 
@@ -127,10 +128,9 @@ static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
 		return -ENXIO;
 }
 
-static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc)
+static irqreturn_t mpc8xxx_gpio_irq_cascade(int irq, void *data)
 {
-	struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_desc_get_handler_data(desc);
-	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct mpc8xxx_gpio_chip *mpc8xxx_gc = (struct mpc8xxx_gpio_chip *)data;
 	struct gpio_chip *gc = &mpc8xxx_gc->gc;
 	unsigned int mask;
 
@@ -139,8 +139,8 @@ static void mpc8xxx_gpio_irq_cascade(struct irq_desc *desc)
 	if (mask)
 		generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
 						     32 - ffs(mask)));
-	if (chip->irq_eoi)
-		chip->irq_eoi(&desc->irq_data);
+
+	return IRQ_HANDLED;
 }
 
 static void mpc8xxx_irq_unmask(struct irq_data *d)
@@ -388,7 +388,7 @@ static int mpc8xxx_probe(struct platform_device *pdev)
 
 	ret = gpiochip_add_data(gc, mpc8xxx_gc);
 	if (ret) {
-		pr_err("%pOF: GPIO chip registration failed with status %d\n",
+		dev_err("%pOF: GPIO chip registration failed with status %d\n",
 		       np, ret);
 		goto err;
 	}
@@ -409,8 +409,14 @@ static int mpc8xxx_probe(struct platform_device *pdev)
 	if (devtype->gpio_dir_in_init)
 		devtype->gpio_dir_in_init(gc);
 
-	irq_set_chained_handler_and_data(mpc8xxx_gc->irqn,
-					 mpc8xxx_gpio_irq_cascade, mpc8xxx_gc);
+	ret = request_irq(mpc8xxx_gc->irqn, mpc8xxx_gpio_irq_cascade,
+		IRQF_NO_THREAD | IRQF_SHARED, "gpio-cascade", mpc8xxx_gc);
+	if (ret) {
+		dev_err("%s: failed to request_irq(%d), ret = %d\n",
+				np->full_name, mpc8xxx_gc->irqn, ret);
+		goto err;
+	}
+
 	return 0;
 err:
 	iounmap(mpc8xxx_gc->regs);
-- 
2.9.5


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH 3/3] spi: mediatek: support large PA
From: Mark Brown @ 2019-09-11 10:03 UTC (permalink / raw)
  To: Luhua Xu
  Cc: Mark Rutland, devicetree, wsd_upstream, linux-kernel, linux-spi,
	Rob Herring, linux-mediatek, Matthias Brugger, linux-arm-kernel
In-Reply-To: <1568195731-3239-4-git-send-email-luhua.xu@mediatek.com>


[-- Attachment #1.1: Type: text/plain, Size: 341 bytes --]

On Wed, Sep 11, 2019 at 05:55:31AM -0400, Luhua Xu wrote:

> +	ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(addr_bits));
> +	if (ret)
> +		dev_notice(&pdev->dev, "SPI dma_set_mask(%d) failed, ret:%d\n",
> +			   addr_bits, ret);

Not sure why you picked dev_notice() over dev_err() here?
Otherwise this looks good so I'll go ahead and apply.

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 1/5] dt-bindings: gpio: aspeed: Update documentation with ast2600 controllers
From: Linus Walleij @ 2019-09-11 10:03 UTC (permalink / raw)
  To: Rashmica Gupta
  Cc: Mark Rutland,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	moderated list:ARM/ASPEED MACHINE SUPPORT,
	open list:GPIO SUBSYSTEM, Andrew Jeffery, open list,
	Bartosz Golaszewski, Rob Herring, Joel Stanley,
	moderated list:ARM/ASPEED MACHINE SUPPORT
In-Reply-To: <20190906062547.13264-1-rashmica.g@gmail.com>

On Fri, Sep 6, 2019 at 7:25 AM Rashmica Gupta <rashmica.g@gmail.com> wrote:

> The ast2600 is a new generation of SoC from ASPEED. Similarly to the
> ast2400 and ast2500, it has a GPIO controller for it's 3.3V GPIO pins.
> Additionally, it has a GPIO controller for 36 1.8V GPIO pins.  We use
> the ngpio property to differentiate between these controllers.
>
> Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>

The changes are uncontroversial (uses just standard GPIO
ngpios and adds a compatible) so patch applied.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 2/5] gpio/aspeed: Fix incorrect number of banks
From: Linus Walleij @ 2019-09-11 10:04 UTC (permalink / raw)
  To: Rashmica Gupta
  Cc: moderated list:ARM/ASPEED MACHINE SUPPORT,
	open list:GPIO SUBSYSTEM, Andrew Jeffery, open list,
	Bartosz Golaszewski, Joel Stanley,
	moderated list:ARM/ASPEED MACHINE SUPPORT
In-Reply-To: <20190906062623.13354-1-rashmica.g@gmail.com>

On Fri, Sep 6, 2019 at 7:26 AM Rashmica Gupta <rashmica.g@gmail.com> wrote:

> The current calculation for the number of GPIO banks is only correct if
> the number of GPIOs is a multiple of 32 (if there were 31 GPIOs we would
> currently say there are 0 banks, which is incorrect).
>
> Fixes: 361b79119a4b7 ('gpio: Add Aspeed driver')
>
> Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
> Reviewed-by: Andrew Jeffery <andrew@aj.id.au>

Patch applied.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 3/5] gpio/aspeed: Setup irqchip dynamically
From: Linus Walleij @ 2019-09-11 10:10 UTC (permalink / raw)
  To: Rashmica Gupta
  Cc: moderated list:ARM/ASPEED MACHINE SUPPORT,
	open list:GPIO SUBSYSTEM, Andrew Jeffery, open list,
	Bartosz Golaszewski, Joel Stanley,
	moderated list:ARM/ASPEED MACHINE SUPPORT
In-Reply-To: <20190906062644.13445-1-rashmica.g@gmail.com>

On Fri, Sep 6, 2019 at 7:26 AM Rashmica Gupta <rashmica.g@gmail.com> wrote:

> This is in preparation for adding ast2600 support. The ast2600 SoC
> requires two instances of the GPIO driver as it has two GPIO
> controllers. Each instance needs it's own irqchip.
>
> Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>

Patch applied with Joel's ACK, needed some fuzzing but
fixed it up.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [V2, 2/2] media: i2c: Add more sensor modes for ov8856 camera sensor
From: Tomasz Figa @ 2019-09-11 10:12 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Mark Rutland, Nicolas Boichat, andriy.shevchenko, srv_heupstream,
	devicetree, shengnan.wang, Louis Kuo, Sj Huang, Rob Herring,
	moderated list:ARM/Mediatek SoC support, Dongchun Zhu,
	Matthias Brugger, Cao Bing Bu, Mauro Carvalho Chehab,
	list@263.net:IOMMU DRIVERS <iommu@lists.linux-foundation.org>, Joerg Roedel <joro@8bytes.org>, ,
	Linux Media Mailing List
In-Reply-To: <20190910130446.26413-3-dongchun.zhu@mediatek.com>

Hi Sakari,

On Tue, Sep 10, 2019 at 10:05 PM <dongchun.zhu@mediatek.com> wrote:
>
> From: Dongchun Zhu <dongchun.zhu@mediatek.com>
>
> This patch mainly adds two more sensor modes for OV8856 CMOS image sensor.
> That is, the resolution of 1632*1224 and 3264*2448, corresponding to the bayer order of BGGR.
> The sensor revision also differs in some OTP register.
>
> Signed-off-by: Dongchun Zhu <dongchun.zhu@mediatek.com>
> ---
>  drivers/media/i2c/ov8856.c | 654 +++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 639 insertions(+), 15 deletions(-)
>

What do you think about the approach taken by this patch?

My understanding is that the register arrays being added by it can be
only used with 24MHz input clock, while the existing ones are for
19.2MHz. That means that this patch makes the driver expose completely
different modes (resolutions, mbus formats) depending on the input
clock. Are we okay with this?

Best regards,
Tomasz

> diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c
> index cd347d6..9ad0b73 100644
> --- a/drivers/media/i2c/ov8856.c
> +++ b/drivers/media/i2c/ov8856.c
> @@ -1,12 +1,15 @@
>  // SPDX-License-Identifier: GPL-2.0
>  // Copyright (c) 2019 Intel Corporation.
>
> +#include <linux/clk.h>
>  #include <asm/unaligned.h>
>  #include <linux/acpi.h>
>  #include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/i2c.h>
>  #include <linux/module.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
>  #include <media/v4l2-ctrls.h>
>  #include <media/v4l2-device.h>
>  #include <media/v4l2-fwnode.h>
> @@ -18,10 +21,15 @@
>  #define OV8856_LINK_FREQ_360MHZ                360000000ULL
>  #define OV8856_LINK_FREQ_180MHZ                180000000ULL
>  #define OV8856_SCLK                    144000000ULL
> -#define OV8856_MCLK                    19200000
> +#define OV8856_XVCLK                   19200000
> +#define OV8856_XVCLK_TYP               24000000
>  #define OV8856_DATA_LANES              4
>  #define OV8856_RGB_DEPTH               10
>
> +#define REG_X_ADDR_START               0x3808
> +#define X_OUTPUT_FULL_SIZE             0x0cc0
> +#define X_OUTPUT_BINNING_SIZE          0x0660
> +
>  #define OV8856_REG_CHIP_ID             0x300a
>  #define OV8856_CHIP_ID                 0x00885a
>
> @@ -29,6 +37,22 @@
>  #define OV8856_MODE_STANDBY            0x00
>  #define OV8856_MODE_STREAMING          0x01
>
> +/* define 1B module revision */
> +#define OV8856_1B_MODULE               0x02
> +
> +/* the OTP read-out buffer is at 0x7000 and 0xf is the offset
> + * of the byte in the OTP that means the module revision
> + */
> +#define OV8856_MODULE_REVISION         0x700f
> +#define OV8856_OTP_MODE_CTRL           0x3d84
> +#define OV8856_OTP_LOAD_CTRL           0x3d81
> +#define OV8856_OTP_MODE_AUTO           0x00
> +#define OV8856_OTP_LOAD_CTRL_ENABLE    BIT(0)
> +
> +/* Analog control register that decided by module revision */
> +#define OV8856_ANAL_MODE_CTRL          0x3614
> +#define OV8856_ANAL_1B_VAL             0x20
> +
>  /* vertical-timings from sensor */
>  #define OV8856_REG_VTS                 0x380e
>  #define OV8856_VTS_MAX                 0x7fff
> @@ -64,6 +88,14 @@
>
>  #define to_ov8856(_sd)                 container_of(_sd, struct ov8856, sd)
>
> +static const char * const ov8856_supply_names[] = {
> +       "dovdd",        /* Digital I/O power */
> +       "avdd",         /* Analog power */
> +       "dvdd",         /* Digital core power */
> +};
> +
> +#define OV8856_NUM_SUPPLIES ARRAY_SIZE(ov8856_supply_names)
> +
>  enum {
>         OV8856_LINK_FREQ_720MBPS,
>         OV8856_LINK_FREQ_360MBPS,
> @@ -195,11 +227,11 @@ static const struct ov8856_reg mode_3280x2464_regs[] = {
>         {0x3800, 0x00},
>         {0x3801, 0x00},
>         {0x3802, 0x00},
> -       {0x3803, 0x06},
> +       {0x3803, 0x07},
>         {0x3804, 0x0c},
>         {0x3805, 0xdf},
>         {0x3806, 0x09},
> -       {0x3807, 0xa7},
> +       {0x3807, 0xa6},
>         {0x3808, 0x0c},
>         {0x3809, 0xd0},
>         {0x380a, 0x09},
> @@ -211,7 +243,7 @@ static const struct ov8856_reg mode_3280x2464_regs[] = {
>         {0x3810, 0x00},
>         {0x3811, 0x00},
>         {0x3812, 0x00},
> -       {0x3813, 0x01},
> +       {0x3813, 0x00},
>         {0x3814, 0x01},
>         {0x3815, 0x01},
>         {0x3816, 0x00},
> @@ -316,6 +348,209 @@ static const struct ov8856_reg mode_3280x2464_regs[] = {
>         {0x5e00, 0x00}
>  };
>
> +static const struct ov8856_reg mode_3264x2448_regs[] = {
> +       {0x0103, 0x01},
> +       {0x0302, 0x3c},
> +       {0x0303, 0x01},
> +       {0x031e, 0x0c},
> +       {0x3000, 0x20},
> +       {0x3003, 0x08},
> +       {0x300e, 0x20},
> +       {0x3010, 0x00},
> +       {0x3015, 0x84},
> +       {0x3018, 0x72},
> +       {0x3021, 0x23},
> +       {0x3033, 0x24},
> +       {0x3500, 0x00},
> +       {0x3501, 0x9a},
> +       {0x3502, 0x20},
> +       {0x3503, 0x08},
> +       {0x3505, 0x83},
> +       {0x3508, 0x01},
> +       {0x3509, 0x80},
> +       {0x350c, 0x00},
> +       {0x350d, 0x80},
> +       {0x350e, 0x04},
> +       {0x350f, 0x00},
> +       {0x3510, 0x00},
> +       {0x3511, 0x02},
> +       {0x3512, 0x00},
> +       {0x3600, 0x72},
> +       {0x3601, 0x40},
> +       {0x3602, 0x30},
> +       {0x3610, 0xc5},
> +       {0x3611, 0x58},
> +       {0x3612, 0x5c},
> +       {0x3613, 0xca},
> +       {0x3614, 0x60},
> +       {0x3628, 0xff},
> +       {0x3629, 0xff},
> +       {0x362a, 0xff},
> +       {0x3633, 0x10},
> +       {0x3634, 0x10},
> +       {0x3635, 0x10},
> +       {0x3636, 0x10},
> +       {0x3663, 0x08},
> +       {0x3669, 0x34},
> +       {0x366d, 0x00},
> +       {0x366e, 0x10},
> +       {0x3706, 0x86},
> +       {0x370b, 0x7e},
> +       {0x3714, 0x23},
> +       {0x3730, 0x12},
> +       {0x3733, 0x10},
> +       {0x3764, 0x00},
> +       {0x3765, 0x00},
> +       {0x3769, 0x62},
> +       {0x376a, 0x2a},
> +       {0x376b, 0x30},
> +       {0x3780, 0x00},
> +       {0x3781, 0x24},
> +       {0x3782, 0x00},
> +       {0x3783, 0x23},
> +       {0x3798, 0x2f},
> +       {0x37a1, 0x60},
> +       {0x37a8, 0x6a},
> +       {0x37ab, 0x3f},
> +       {0x37c2, 0x04},
> +       {0x37c3, 0xf1},
> +       {0x37c9, 0x80},
> +       {0x37cb, 0x16},
> +       {0x37cc, 0x16},
> +       {0x37cd, 0x16},
> +       {0x37ce, 0x16},
> +       {0x3800, 0x00},
> +       {0x3801, 0x00},
> +       {0x3802, 0x00},
> +       {0x3803, 0x0c},
> +       {0x3804, 0x0c},
> +       {0x3805, 0xdf},
> +       {0x3806, 0x09},
> +       {0x3807, 0xa3},
> +       {0x3808, 0x0c},
> +       {0x3809, 0xc0},
> +       {0x380a, 0x09},
> +       {0x380b, 0x90},
> +       {0x380c, 0x07},
> +       {0x380d, 0x8c},
> +       {0x380e, 0x09},
> +       {0x380f, 0xb2},
> +       {0x3810, 0x00},
> +       {0x3811, 0x04},
> +       {0x3812, 0x00},
> +       {0x3813, 0x02},
> +       {0x3814, 0x01},
> +       {0x3815, 0x01},
> +       {0x3816, 0x00},
> +       {0x3817, 0x00},
> +       {0x3818, 0x00},
> +       {0x3819, 0x00},
> +       {0x3820, 0x80},
> +       {0x3821, 0x46},
> +       {0x382a, 0x01},
> +       {0x382b, 0x01},
> +       {0x3830, 0x06},
> +       {0x3836, 0x02},
> +       {0x3862, 0x04},
> +       {0x3863, 0x08},
> +       {0x3cc0, 0x33},
> +       {0x3d85, 0x17},
> +       {0x3d8c, 0x73},
> +       {0x3d8d, 0xde},
> +       {0x4001, 0xe0},
> +       {0x4003, 0x40},
> +       {0x4008, 0x00},
> +       {0x4009, 0x0b},
> +       {0x400a, 0x00},
> +       {0x400b, 0x84},
> +       {0x400f, 0x80},
> +       {0x4010, 0xf0},
> +       {0x4011, 0xff},
> +       {0x4012, 0x02},
> +       {0x4013, 0x01},
> +       {0x4014, 0x01},
> +       {0x4015, 0x01},
> +       {0x4042, 0x00},
> +       {0x4043, 0x80},
> +       {0x4044, 0x00},
> +       {0x4045, 0x80},
> +       {0x4046, 0x00},
> +       {0x4047, 0x80},
> +       {0x4048, 0x00},
> +       {0x4049, 0x80},
> +       {0x4041, 0x03},
> +       {0x404c, 0x20},
> +       {0x404d, 0x00},
> +       {0x404e, 0x20},
> +       {0x4203, 0x80},
> +       {0x4307, 0x30},
> +       {0x4317, 0x00},
> +       {0x4502, 0x50},
> +       {0x4503, 0x08},
> +       {0x4601, 0x80},
> +       {0x4800, 0x44},
> +       {0x4816, 0x53},
> +       {0x481b, 0x50},
> +       {0x481f, 0x27},
> +       {0x4823, 0x3c},
> +       {0x482b, 0x00},
> +       {0x4831, 0x66},
> +       {0x4837, 0x16},
> +       {0x483c, 0x0f},
> +       {0x484b, 0x05},
> +       {0x5000, 0x77},
> +       {0x5001, 0x0a},
> +       {0x5003, 0xc8},
> +       {0x5004, 0x04},
> +       {0x5006, 0x00},
> +       {0x5007, 0x00},
> +       {0x502e, 0x03},
> +       {0x5030, 0x41},
> +       {0x5780, 0x14},
> +       {0x5781, 0x0f},
> +       {0x5782, 0x44},
> +       {0x5783, 0x02},
> +       {0x5784, 0x01},
> +       {0x5785, 0x01},
> +       {0x5786, 0x00},
> +       {0x5787, 0x04},
> +       {0x5788, 0x02},
> +       {0x5789, 0x0f},
> +       {0x578a, 0xfd},
> +       {0x578b, 0xf5},
> +       {0x578c, 0xf5},
> +       {0x578d, 0x03},
> +       {0x578e, 0x08},
> +       {0x578f, 0x0c},
> +       {0x5790, 0x08},
> +       {0x5791, 0x04},
> +       {0x5792, 0x00},
> +       {0x5793, 0x52},
> +       {0x5794, 0xa3},
> +       {0x5795, 0x02},
> +       {0x5796, 0x20},
> +       {0x5797, 0x20},
> +       {0x5798, 0xd5},
> +       {0x5799, 0xd5},
> +       {0x579a, 0x00},
> +       {0x579b, 0x50},
> +       {0x579c, 0x00},
> +       {0x579d, 0x2c},
> +       {0x579e, 0x0c},
> +       {0x579f, 0x40},
> +       {0x57a0, 0x09},
> +       {0x57a1, 0x40},
> +       {0x59f8, 0x3d},
> +       {0x5a08, 0x02},
> +       {0x5b00, 0x02},
> +       {0x5b01, 0x10},
> +       {0x5b02, 0x03},
> +       {0x5b03, 0xcf},
> +       {0x5b05, 0x6c},
> +       {0x5e00, 0x00},
> +       {0x5e10, 0xfc}
> +};
> +
>  static const struct ov8856_reg mode_1640x1232_regs[] = {
>         {0x3000, 0x20},
>         {0x3003, 0x08},
> @@ -385,11 +620,11 @@ static const struct ov8856_reg mode_1640x1232_regs[] = {
>         {0x3800, 0x00},
>         {0x3801, 0x00},
>         {0x3802, 0x00},
> -       {0x3803, 0x06},
> +       {0x3803, 0x07},
>         {0x3804, 0x0c},
>         {0x3805, 0xdf},
>         {0x3806, 0x09},
> -       {0x3807, 0xa7},
> +       {0x3807, 0xa6},
>         {0x3808, 0x06},
>         {0x3809, 0x68},
>         {0x380a, 0x04},
> @@ -401,7 +636,7 @@ static const struct ov8856_reg mode_1640x1232_regs[] = {
>         {0x3810, 0x00},
>         {0x3811, 0x00},
>         {0x3812, 0x00},
> -       {0x3813, 0x01},
> +       {0x3813, 0x00},
>         {0x3814, 0x03},
>         {0x3815, 0x01},
>         {0x3816, 0x00},
> @@ -506,6 +741,209 @@ static const struct ov8856_reg mode_1640x1232_regs[] = {
>         {0x5e00, 0x00}
>  };
>
> +static const struct ov8856_reg mode_1632x1224_regs[] = {
> +       {0x0103, 0x01},
> +       {0x0302, 0x3c},
> +       {0x0303, 0x01},
> +       {0x031e, 0x0c},
> +       {0x3000, 0x20},
> +       {0x3003, 0x08},
> +       {0x300e, 0x20},
> +       {0x3010, 0x00},
> +       {0x3015, 0x84},
> +       {0x3018, 0x72},
> +       {0x3021, 0x23},
> +       {0x3033, 0x24},
> +       {0x3500, 0x00},
> +       {0x3501, 0x4c},
> +       {0x3502, 0xe0},
> +       {0x3503, 0x08},
> +       {0x3505, 0x83},
> +       {0x3508, 0x01},
> +       {0x3509, 0x80},
> +       {0x350c, 0x00},
> +       {0x350d, 0x80},
> +       {0x350e, 0x04},
> +       {0x350f, 0x00},
> +       {0x3510, 0x00},
> +       {0x3511, 0x02},
> +       {0x3512, 0x00},
> +       {0x3600, 0x72},
> +       {0x3601, 0x40},
> +       {0x3602, 0x30},
> +       {0x3610, 0xc5},
> +       {0x3611, 0x58},
> +       {0x3612, 0x5c},
> +       {0x3613, 0xca},
> +       {0x3614, 0x60},
> +       {0x3628, 0xff},
> +       {0x3629, 0xff},
> +       {0x362a, 0xff},
> +       {0x3633, 0x10},
> +       {0x3634, 0x10},
> +       {0x3635, 0x10},
> +       {0x3636, 0x10},
> +       {0x3663, 0x08},
> +       {0x3669, 0x34},
> +       {0x366d, 0x00},
> +       {0x366e, 0x08},
> +       {0x3706, 0x86},
> +       {0x370b, 0x7e},
> +       {0x3714, 0x27},
> +       {0x3730, 0x12},
> +       {0x3733, 0x10},
> +       {0x3764, 0x00},
> +       {0x3765, 0x00},
> +       {0x3769, 0x62},
> +       {0x376a, 0x2a},
> +       {0x376b, 0x30},
> +       {0x3780, 0x00},
> +       {0x3781, 0x24},
> +       {0x3782, 0x00},
> +       {0x3783, 0x23},
> +       {0x3798, 0x2f},
> +       {0x37a1, 0x60},
> +       {0x37a8, 0x6a},
> +       {0x37ab, 0x3f},
> +       {0x37c2, 0x14},
> +       {0x37c3, 0xf1},
> +       {0x37c9, 0x80},
> +       {0x37cb, 0x16},
> +       {0x37cc, 0x16},
> +       {0x37cd, 0x16},
> +       {0x37ce, 0x16},
> +       {0x3800, 0x00},
> +       {0x3801, 0x00},
> +       {0x3802, 0x00},
> +       {0x3803, 0x0c},
> +       {0x3804, 0x0c},
> +       {0x3805, 0xdf},
> +       {0x3806, 0x09},
> +       {0x3807, 0xa3},
> +       {0x3808, 0x06},
> +       {0x3809, 0x60},
> +       {0x380a, 0x04},
> +       {0x380b, 0xc8},
> +       {0x380c, 0x07},
> +       {0x380d, 0x8c},
> +       {0x380e, 0x09},
> +       {0x380f, 0xb2},
> +       {0x3810, 0x00},
> +       {0x3811, 0x02},
> +       {0x3812, 0x00},
> +       {0x3813, 0x02},
> +       {0x3814, 0x03},
> +       {0x3815, 0x01},
> +       {0x3816, 0x00},
> +       {0x3817, 0x00},
> +       {0x3818, 0x00},
> +       {0x3819, 0x00},
> +       {0x3820, 0x80},
> +       {0x3821, 0x47},
> +       {0x382a, 0x03},
> +       {0x382b, 0x01},
> +       {0x3830, 0x06},
> +       {0x3836, 0x02},
> +       {0x3862, 0x04},
> +       {0x3863, 0x08},
> +       {0x3cc0, 0x33},
> +       {0x3d85, 0x17},
> +       {0x3d8c, 0x73},
> +       {0x3d8d, 0xde},
> +       {0x4001, 0xe0},
> +       {0x4003, 0x40},
> +       {0x4008, 0x00},
> +       {0x4009, 0x05},
> +       {0x400a, 0x00},
> +       {0x400b, 0x84},
> +       {0x400f, 0x80},
> +       {0x4010, 0xf0},
> +       {0x4011, 0xff},
> +       {0x4012, 0x02},
> +       {0x4013, 0x01},
> +       {0x4014, 0x01},
> +       {0x4015, 0x01},
> +       {0x4042, 0x00},
> +       {0x4043, 0x80},
> +       {0x4044, 0x00},
> +       {0x4045, 0x80},
> +       {0x4046, 0x00},
> +       {0x4047, 0x80},
> +       {0x4048, 0x00},
> +       {0x4049, 0x80},
> +       {0x4041, 0x03},
> +       {0x404c, 0x20},
> +       {0x404d, 0x00},
> +       {0x404e, 0x20},
> +       {0x4203, 0x80},
> +       {0x4307, 0x30},
> +       {0x4317, 0x00},
> +       {0x4502, 0x50},
> +       {0x4503, 0x08},
> +       {0x4601, 0x80},
> +       {0x4800, 0x44},
> +       {0x4816, 0x53},
> +       {0x481b, 0x50},
> +       {0x481f, 0x27},
> +       {0x4823, 0x3c},
> +       {0x482b, 0x00},
> +       {0x4831, 0x66},
> +       {0x4837, 0x16},
> +       {0x483c, 0x0f},
> +       {0x484b, 0x05},
> +       {0x5000, 0x77},
> +       {0x5001, 0x0a},
> +       {0x5003, 0xc8},
> +       {0x5004, 0x04},
> +       {0x5006, 0x00},
> +       {0x5007, 0x00},
> +       {0x502e, 0x03},
> +       {0x5030, 0x41},
> +       {0x5795, 0x00},
> +       {0x5796, 0x10},
> +       {0x5797, 0x10},
> +       {0x5798, 0x73},
> +       {0x5799, 0x73},
> +       {0x579a, 0x00},
> +       {0x579b, 0x28},
> +       {0x579c, 0x00},
> +       {0x579d, 0x16},
> +       {0x579e, 0x06},
> +       {0x579f, 0x20},
> +       {0x57a0, 0x04},
> +       {0x57a1, 0xa0},
> +       {0x5780, 0x14},
> +       {0x5781, 0x0f},
> +       {0x5782, 0x44},
> +       {0x5783, 0x02},
> +       {0x5784, 0x01},
> +       {0x5785, 0x01},
> +       {0x5786, 0x00},
> +       {0x5787, 0x04},
> +       {0x5788, 0x02},
> +       {0x5789, 0x0f},
> +       {0x578a, 0xfd},
> +       {0x578b, 0xf5},
> +       {0x578c, 0xf5},
> +       {0x578d, 0x03},
> +       {0x578e, 0x08},
> +       {0x578f, 0x0c},
> +       {0x5790, 0x08},
> +       {0x5791, 0x04},
> +       {0x5792, 0x00},
> +       {0x5793, 0x52},
> +       {0x5794, 0xa3},
> +       {0x59f8, 0x3d},
> +       {0x5a08, 0x02},
> +       {0x5b00, 0x02},
> +       {0x5b01, 0x10},
> +       {0x5b02, 0x03},
> +       {0x5b03, 0xcf},
> +       {0x5b05, 0x6c},
> +       {0x5e00, 0x00},
> +       {0x5e10, 0xfc}
> +};
> +
>  static const char * const ov8856_test_pattern_menu[] = {
>         "Disabled",
>         "Standard Color Bar",
> @@ -548,6 +986,18 @@ static const struct ov8856_mode supported_modes[] = {
>                 .link_freq_index = OV8856_LINK_FREQ_720MBPS,
>         },
>         {
> +               .width    = 3264,
> +               .height   = 2448,
> +               .hts      = 1932,
> +               .vts_def  = 2482,
> +               .vts_min  = 2482,
> +               .reg_list = {
> +                       .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
> +                       .regs = mode_3264x2448_regs,
> +               },
> +               .link_freq_index = OV8856_LINK_FREQ_720MBPS,
> +       },
> +       {
>                 .width = 1640,
>                 .height = 1232,
>                 .hts = 3820,
> @@ -558,6 +1008,18 @@ static const struct ov8856_mode supported_modes[] = {
>                         .regs = mode_1640x1232_regs,
>                 },
>                 .link_freq_index = OV8856_LINK_FREQ_360MBPS,
> +       },
> +       {
> +               .width    = 1632,
> +               .height   = 1224,
> +               .hts      = 1932,
> +               .vts_def  = 2482,
> +               .vts_min  = 2482,
> +               .reg_list = {
> +                       .num_of_regs = ARRAY_SIZE(mode_1632x1224_regs),
> +                       .regs = mode_1632x1224_regs,
> +               },
> +               .link_freq_index = OV8856_LINK_FREQ_360MBPS,
>         }
>  };
>
> @@ -566,16 +1028,28 @@ struct ov8856 {
>         struct media_pad pad;
>         struct v4l2_ctrl_handler ctrl_handler;
>
> +       struct clk              *xvclk;
> +       struct gpio_desc        *n_shutdn_gpio;
> +       struct regulator_bulk_data supplies[OV8856_NUM_SUPPLIES];
> +
>         /* V4L2 Controls */
>         struct v4l2_ctrl *link_freq;
>         struct v4l2_ctrl *pixel_rate;
>         struct v4l2_ctrl *vblank;
>         struct v4l2_ctrl *hblank;
>         struct v4l2_ctrl *exposure;
> +       struct v4l2_mbus_framefmt       fmt;
>
>         /* Current mode */
>         const struct ov8856_mode *cur_mode;
>
> +       /* module hardware version that can be read out from register 0x700f
> +        * the register value corresponds to different hardware version
> +        * 01: 2A module revision
> +        * 02: 1B module revision
> +        */
> +       bool is_1B_revision;
> +
>         /* To serialize asynchronus callbacks */
>         struct mutex mutex;
>
> @@ -696,6 +1170,25 @@ static int ov8856_test_pattern(struct ov8856 *ov8856, u32 pattern)
>                                 OV8856_REG_VALUE_08BIT, pattern);
>  }
>
> +static int ov8856_check_revision(struct ov8856 *ov8856)
> +{
> +       int ret;
> +
> +       ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT,
> +                              OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING);
> +       if (ret)
> +               return ret;
> +
> +       ret = ov8856_write_reg(ov8856, OV8856_OTP_MODE_CTRL,
> +                              OV8856_REG_VALUE_08BIT, OV8856_OTP_MODE_AUTO);
> +       if (ret)
> +               return ret;
> +
> +       return ov8856_write_reg(ov8856, OV8856_OTP_LOAD_CTRL,
> +                               OV8856_REG_VALUE_08BIT,
> +                               OV8856_OTP_LOAD_CTRL_ENABLE);
> +}
> +
>  static int ov8856_set_ctrl(struct v4l2_ctrl *ctrl)
>  {
>         struct ov8856 *ov8856 = container_of(ctrl->handler,
> @@ -825,7 +1318,6 @@ static void ov8856_update_pad_format(const struct ov8856_mode *mode,
>  {
>         fmt->width = mode->width;
>         fmt->height = mode->height;
> -       fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
>         fmt->field = V4L2_FIELD_NONE;
>  }
>
> @@ -834,6 +1326,7 @@ static int ov8856_start_streaming(struct ov8856 *ov8856)
>         struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
>         const struct ov8856_reg_list *reg_list;
>         int link_freq_index, ret;
> +       u32 h_size;
>
>         link_freq_index = ov8856->cur_mode->link_freq_index;
>         reg_list = &link_freq_configs[link_freq_index].reg_list;
> @@ -850,6 +1343,29 @@ static int ov8856_start_streaming(struct ov8856 *ov8856)
>                 return ret;
>         }
>
> +       /* Update R3614 if the revision is 1B module */
> +       if (ov8856->is_1B_revision) {
> +               ret = ov8856_write_reg(ov8856, OV8856_ANAL_MODE_CTRL,
> +                                      OV8856_REG_VALUE_08BIT,
> +                                      OV8856_ANAL_1B_VAL);
> +               if (ret) {
> +                       dev_err(&client->dev, "failed to set R3614");
> +                       return ret;
> +               }
> +       }
> +
> +       ret = ov8856_read_reg(ov8856, REG_X_ADDR_START,
> +                             OV8856_REG_VALUE_16BIT, &h_size);
> +       if (ret) {
> +               dev_err(&client->dev, "failed to read out R3614");
> +               return ret;
> +       }
> +
> +       if (h_size == X_OUTPUT_FULL_SIZE || h_size == X_OUTPUT_BINNING_SIZE)
> +               ov8856->fmt.code = MEDIA_BUS_FMT_SBGGR10_1X10;
> +
>         ret = __v4l2_ctrl_handler_setup(ov8856->sd.ctrl_handler);
>         if (ret)
>                 return ret;
> @@ -878,6 +1394,7 @@ static int ov8856_set_stream(struct v4l2_subdev *sd, int enable)
>         struct ov8856 *ov8856 = to_ov8856(sd);
>         struct i2c_client *client = v4l2_get_subdevdata(sd);
>         int ret = 0;
> +       u32 val;
>
>         if (ov8856->streaming == enable)
>                 return 0;
> @@ -908,6 +1425,44 @@ static int ov8856_set_stream(struct v4l2_subdev *sd, int enable)
>         return ret;
>  }
>
> +static int __ov8856_power_on(struct ov8856 *ov8856)
> +{
> +       struct i2c_client *client = v4l2_get_subdevdata(&ov8856->sd);
> +       int ret;
> +
> +       ret = clk_prepare_enable(ov8856->xvclk);
> +       if (ret < 0) {
> +               dev_err(&client->dev, "failed to enable xvclk\n");
> +               return ret;
> +       }
> +
> +       gpiod_set_value_cansleep(ov8856->n_shutdn_gpio, GPIOD_OUT_LOW);
> +
> +       ret = regulator_bulk_enable(OV8856_NUM_SUPPLIES, ov8856->supplies);
> +       if (ret < 0) {
> +               dev_err(&client->dev, "failed to enable regulators\n");
> +               goto disable_clk;
> +       }
> +
> +       gpiod_set_value_cansleep(ov8856->n_shutdn_gpio, GPIOD_OUT_HIGH);
> +
> +       usleep_range(1400, 1500);
> +
> +       return 0;
> +
> +disable_clk:
> +       clk_disable_unprepare(ov8856->xvclk);
> +
> +       return ret;
> +}
> +
> +static void __ov8856_power_off(struct ov8856 *ov8856)
> +{
> +       gpiod_set_value_cansleep(ov8856->n_shutdn_gpio, 1);
> +       regulator_bulk_disable(OV8856_NUM_SUPPLIES, ov8856->supplies);
> +       clk_disable_unprepare(ov8856->xvclk);
> +}
> +
>  static int __maybe_unused ov8856_suspend(struct device *dev)
>  {
>         struct i2c_client *client = to_i2c_client(dev);
> @@ -951,6 +1506,7 @@ static int ov8856_set_format(struct v4l2_subdev *sd,
>                              struct v4l2_subdev_format *fmt)
>  {
>         struct ov8856 *ov8856 = to_ov8856(sd);
> +       struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format;
>         const struct ov8856_mode *mode;
>         s32 vblank_def, h_blank;
>
> @@ -960,7 +1516,9 @@ static int ov8856_set_format(struct v4l2_subdev *sd,
>                                       fmt->format.height);
>
>         mutex_lock(&ov8856->mutex);
> -       ov8856_update_pad_format(mode, &fmt->format);
> +       mbus_fmt->code = ov8856->fmt.code;
> +       ov8856_update_pad_format(mode, mbus_fmt);
> +       ov8856->fmt = fmt->format;
>         if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
>                 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
>         } else {
> @@ -992,13 +1550,17 @@ static int ov8856_get_format(struct v4l2_subdev *sd,
>                              struct v4l2_subdev_format *fmt)
>  {
>         struct ov8856 *ov8856 = to_ov8856(sd);
> +       struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format;
>
>         mutex_lock(&ov8856->mutex);
> -       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
> +       if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
>                 fmt->format = *v4l2_subdev_get_try_format(&ov8856->sd, cfg,
>                                                           fmt->pad);
> -       else
> -               ov8856_update_pad_format(ov8856->cur_mode, &fmt->format);
> +       } else {
> +               fmt->format = ov8856->fmt;
> +               ov8856_update_pad_format(ov8856->cur_mode, mbus_fmt);
> +               mbus_fmt->code = ov8856->fmt.code;
> +       }
>
>         mutex_unlock(&ov8856->mutex);
>
> @@ -1009,11 +1571,12 @@ static int ov8856_enum_mbus_code(struct v4l2_subdev *sd,
>                                  struct v4l2_subdev_pad_config *cfg,
>                                  struct v4l2_subdev_mbus_code_enum *code)
>  {
> -       /* Only one bayer order GRBG is supported */
> +       struct ov8856 *ov8856 = to_ov8856(sd);
> +
>         if (code->index > 0)
>                 return -EINVAL;
>
> -       code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
> +       code->code = ov8856->fmt.code;
>
>         return 0;
>  }
> @@ -1089,6 +1652,20 @@ static int ov8856_identify_module(struct ov8856 *ov8856)
>                 return -ENXIO;
>         }
>
> +       /* check sensor hardware revision */
> +       ret = ov8856_check_revision(ov8856);
> +       if (ret) {
> +               dev_err(&client->dev, "failed to check sensor revision");
> +               return ret;
> +       }
> +
> +       ret = ov8856_read_reg(ov8856, OV8856_MODULE_REVISION,
> +                             OV8856_REG_VALUE_08BIT, &val);
> +       if (ret)
> +               return ret;
> +
> +       ov8856->is_1B_revision = (val == OV8856_1B_MODULE) ? 1 : 0;
> +
>         return 0;
>  }
>
> @@ -1107,7 +1684,7 @@ static int ov8856_check_hwcfg(struct device *dev)
>                 return -ENXIO;
>
>         fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
> -       if (mclk != OV8856_MCLK) {
> +       if (mclk != OV8856_XVCLK) {
>                 dev_err(dev, "external clock %d is not supported", mclk);
>                 return -EINVAL;
>         }
> @@ -1164,6 +1741,9 @@ static int ov8856_remove(struct i2c_client *client)
>         media_entity_cleanup(&sd->entity);
>         v4l2_ctrl_handler_free(sd->ctrl_handler);
>         pm_runtime_disable(&client->dev);
> +       if (!pm_runtime_status_suspended(&client->dev))
> +               __ov8856_power_off(ov8856);
> +       pm_runtime_set_suspended(&client->dev);
>         mutex_destroy(&ov8856->mutex);
>
>         return 0;
> @@ -1172,6 +1752,7 @@ static int ov8856_remove(struct i2c_client *client)
>  static int ov8856_probe(struct i2c_client *client)
>  {
>         struct ov8856 *ov8856;
> +       unsigned int i;
>         int ret;
>
>         ret = ov8856_check_hwcfg(&client->dev);
> @@ -1186,6 +1767,42 @@ static int ov8856_probe(struct i2c_client *client)
>                 return -ENOMEM;
>
>         v4l2_i2c_subdev_init(&ov8856->sd, client, &ov8856_subdev_ops);
> +       ov8856->fmt.code = MEDIA_BUS_FMT_SGRBG10_1X10;
> +
> +       ov8856->xvclk = devm_clk_get(&client->dev, "xvclk");
> +       if (IS_ERR(ov8856->xvclk)) {
> +               dev_err(&client->dev, "failed to get xvclk\n");
> +               return -EINVAL;
> +       }
> +
> +       ret = clk_set_rate(ov8856->xvclk, OV8856_XVCLK_TYP);
> +       if (ret < 0) {
> +               dev_err(&client->dev, "failed to set xvclk rate (24MHz)\n");
> +               return ret;
> +       }
> +       if (clk_get_rate(ov8856->xvclk) != OV8856_XVCLK_TYP)
> +               dev_warn(&client->dev,
> +                        "xvclk mismatched, modes are based on 24MHz\n");
> +
> +       ov8856->n_shutdn_gpio = devm_gpiod_get(&client->dev, "reset",
> +                                              GPIOD_OUT_LOW);
> +       if (IS_ERR(ov8856->n_shutdn_gpio)) {
> +               dev_err(&client->dev, "failed to get reset-gpios\n");
> +               return -EINVAL;
> +       }
> +
> +       for (i = 0; i < OV8856_NUM_SUPPLIES; i++)
> +               ov8856->supplies[i].supply = ov8856_supply_names[i];
> +
> +       ret = devm_regulator_bulk_get(&client->dev, OV8856_NUM_SUPPLIES,
> +                                     ov8856->supplies);
> +       if (ret)
> +               dev_warn(&client->dev, "failed to get regulators\n");
> +
> +       ret = __ov8856_power_on(ov8856);
> +       if (ret)
> +               dev_warn(&client->dev, "failed to power on\n");
> +
>         ret = ov8856_identify_module(ov8856);
>         if (ret) {
>                 dev_err(&client->dev, "failed to find sensor: %d", ret);
> @@ -1251,11 +1868,18 @@ static const struct acpi_device_id ov8856_acpi_ids[] = {
>  MODULE_DEVICE_TABLE(acpi, ov8856_acpi_ids);
>  #endif
>
> +static const struct of_device_id ov8856_of_match[] = {
> +       { .compatible = "ovti,ov8856" },
> +       {},
> +};
> +MODULE_DEVICE_TABLE(of, ov8856_of_match);
> +
>  static struct i2c_driver ov8856_i2c_driver = {
>         .driver = {
>                 .name = "ov8856",
>                 .pm = &ov8856_pm_ops,
>                 .acpi_match_table = ACPI_PTR(ov8856_acpi_ids),
> +               .of_match_table = ov8856_of_match,
>         },
>         .probe_new = ov8856_probe,
>         .remove = ov8856_remove,
> --
> 2.9.2
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 4/5] gpios: Use ngpio property from device tree if available
From: Linus Walleij @ 2019-09-11 10:12 UTC (permalink / raw)
  To: Rashmica Gupta
  Cc: moderated list:ARM/ASPEED MACHINE SUPPORT,
	open list:GPIO SUBSYSTEM, Andrew Jeffery, open list,
	Bartosz Golaszewski, Joel Stanley,
	moderated list:ARM/ASPEED MACHINE SUPPORT
In-Reply-To: <20190906062727.13521-1-rashmica.g@gmail.com>

On Fri, Sep 6, 2019 at 7:27 AM Rashmica Gupta <rashmica.g@gmail.com> wrote:

> Use the ngpio property from the device tree if it exists. If it doesn't
> then fallback to the hardcoded value in the config.
>
> This is in preparation for adding ast2600 support. The ast2600 SoC has
> two GPIO controllers and so requires two instances of the GPIO driver.
> We use the ngpio property to different between them as they have
> different numbers of GPIOs.
>
> Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>

Patch applied with some fuzzing.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 5/5] gpio: Add in ast2600 details to Aspeed driver
From: Linus Walleij @ 2019-09-11 10:13 UTC (permalink / raw)
  To: Rashmica Gupta
  Cc: moderated list:ARM/ASPEED MACHINE SUPPORT,
	open list:GPIO SUBSYSTEM, Andrew Jeffery, open list,
	Bartosz Golaszewski, Joel Stanley,
	moderated list:ARM/ASPEED MACHINE SUPPORT
In-Reply-To: <20190906063737.15428-1-rashmica.g@gmail.com>

On Fri, Sep 6, 2019 at 7:37 AM Rashmica Gupta <rashmica.g@gmail.com> wrote:

> The ast2600 is a new generation of SoC from ASPEED. Similarly to the
> ast2400 and ast2500, it has a GPIO controller for it's 3.3V GPIO pins.
> Additionally, it has a GPIO controller for 1.8V GPIO pins.
>
> As the register names for both controllers are the same and the 36 1.8V
> GPIOs and the first 36 of the 3.3V GPIOs are all bidirectional, we can
> use the same configuration struct and use the ngpio property to
> differentiate between the two sets of GPIOs.
>
> Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>

Patch applied.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH V7 3/3] arm64/mm: Enable memory hot remove
From: David Hildenbrand @ 2019-09-11 10:31 UTC (permalink / raw)
  To: Catalin Marinas, Anshuman Khandual
  Cc: mark.rutland, mhocko, linux-mm, arunks, cpandya, ira.weiny, will,
	steven.price, valentin.schneider, suzuki.poulose, Robin.Murphy,
	broonie, cai, ard.biesheuvel, dan.j.williams, linux-arm-kernel,
	osalvador, steve.capper, logang, linux-kernel, akpm, mgorman
In-Reply-To: <20190910161759.GI14442@C02TF0J2HF1T.local>

On 10.09.19 18:17, Catalin Marinas wrote:
> On Tue, Sep 03, 2019 at 03:15:58PM +0530, Anshuman Khandual wrote:
>> @@ -770,6 +1022,28 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
>>  void vmemmap_free(unsigned long start, unsigned long end,
>>  		struct vmem_altmap *altmap)
>>  {
>> +#ifdef CONFIG_MEMORY_HOTPLUG
>> +	/*
>> +	 * FIXME: We should have called remove_pagetable(start, end, true).
>> +	 * vmemmap and vmalloc virtual range might share intermediate kernel
>> +	 * page table entries. Removing vmemmap range page table pages here
>> +	 * can potentially conflict with a concurrent vmalloc() allocation.
>> +	 *
>> +	 * This is primarily because vmalloc() does not take init_mm ptl for
>> +	 * the entire page table walk and it's modification. Instead it just
>> +	 * takes the lock while allocating and installing page table pages
>> +	 * via [p4d|pud|pmd|pte]_alloc(). A concurrently vanishing page table
>> +	 * entry via memory hot remove can cause vmalloc() kernel page table
>> +	 * walk pointers to be invalid on the fly which can cause corruption
>> +	 * or worst, a crash.
>> +	 *
>> +	 * So free_empty_tables() gets called where vmalloc and vmemmap range
>> +	 * do not overlap at any intermediate level kernel page table entry.
>> +	 */
>> +	unmap_hotplug_range(start, end, true);
>> +	if (!vmalloc_vmemmap_overlap)
>> +		free_empty_tables(start, end);
>> +#endif
>>  }
>>  #endif	/* CONFIG_SPARSEMEM_VMEMMAP */
> 
> I wonder whether we could simply ignore the vmemmap freeing altogether,
> just leave it around and not unmap it. This way, we could call
> unmap_kernel_range() for removing the linear map and we save some code.
> 
> For the linear map, I think we use just above 2MB of tables for 1GB of
> memory mapped (worst case with 4KB pages we need 512 pte pages). For
> vmemmap we'd use slightly above 2MB for a 64GB hotplugged memory. Do we
> expect such memory to be re-plugged again in the same range? If we do,
> then I shouldn't even bother with removing the vmmemmap.
> 

FWIW, I think we should do it cleanly.

> I don't fully understand the use-case for memory hotremove, so any
> additional info would be useful to make a decision here.
> 

Especially in virtual environment, hotremove will be relevant. For
physical environments - I have no idea how important that is for ARM.

-- 

Thanks,

David / dhildenb

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [jeyu:modules-next 3/11] arc4.c:(___ksymtab+arc4_setkey+0x8): undefined reference to `no symbol'
From: Jessica Yu @ 2019-09-11 10:32 UTC (permalink / raw)
  To: Matthias Maennich
  Cc: Arnd Bergmann, Ard Biesheuvel, Greg Kroah-Hartman, Will Deacon,
	Catalin Marinas, Martijn Coenen, linux-arm-kernel
In-Reply-To: <20190911052124.GA247847@google.com>

+++ Matthias Maennich [11/09/19 06:21 +0100]:
>On Wed, Sep 11, 2019 at 03:11:53AM +0800, kbuild test robot wrote:
>>tree:   https://kernel.googlesource.com/pub/scm/linux/kernel/git/jeyu/linux.git modules-next
>>head:   32bca2df7da27be34371a37f9bb5e2b85fdd92bd
>>commit: 8651ec01daedad26290f76beeb4736f9d2da4b87 [3/11] module: add support for symbol namespaces.
>>config: arm64-defconfig (attached as .config)
>>compiler: aarch64-linux-gcc (GCC) 7.4.0
>>reproduce:
>>       wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>>       chmod +x ~/bin/make.cross
>>       git checkout 8651ec01daedad26290f76beeb4736f9d2da4b87
>>       # save the attached .config to linux build tree
>>       GCC_VERSION=7.4.0 make.cross ARCH=arm64
>>
>>If you fix the issue, kindly add following tag
>>Reported-by: kbuild test robot <lkp@intel.com>
>>
>>All errors (new ones prefixed by >>):
>>
>>  lib/crypto/arc4.o: In function `__ksymtab_arc4_setkey':
>>>>arc4.c:(___ksymtab+arc4_setkey+0x8): undefined reference to `no symbol'
>>  lib/crypto/arc4.o: In function `__ksymtab_arc4_crypt':
>>>>arc4.c:(___ksymtab+arc4_crypt+0x8): undefined reference to `no symbol'
>
>Hmm, this is caused by the relative relocation of the 'namespace_offset'
>struct member to NULL in case there is no namespace defined:
>
>#define __KSYMTAB_ENTRY(sym, sec)					\
>	__ADDRESSABLE(sym)						\
>	asm("	.section \"___ksymtab" sec "+" #sym "\", \"a\"	\n"	\
>	    "	.balign 4					\n"	\
>	    "__ksymtab_" #sym ":				\n"	\
>	    "	.long	" #sym "- .				\n"	\
>	    "	.long	__kstrtab_" #sym "- .			\n"	\
>	    "	.long	0 - .					\n"	\
>	    	       ^^^^^^^
>	    "	.previous					\n")
>
>struct kernel_symbol {
>	int value_offset;
>	int name_offset;
>	int namespace_offset;
>};
>
>That is apparently not an issue on x86, but on arm. Not sure how to
>express a relative relocation to NULL then.
>
>I will try to solve this somehow, just wanted to check if somebody knows the
>trick here.

(Adding more CC's..)

Do we have to have a place-relative relocation there? If we can't find
a workaround, having just .long 0 for a null namespace seemed to fix the
build issues on arm64 for me at least..



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply


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