diff mbox series

[v4] mtd: spi-nor: intel-spi: Avoid crossing 4K address boundary on read/write

Message ID 20190319171749.19052-1-alexander.sverdlin@nokia.com
State Accepted
Delegated to: Ambarus Tudor
Headers show
Series [v4] mtd: spi-nor: intel-spi: Avoid crossing 4K address boundary on read/write | expand

Commit Message

Alexander A Sverdlin March 19, 2019, 5:18 p.m. UTC
From: Alexander Sverdlin <alexander.sverdlin@nokia.com>

It was observed that reads crossing 4K address boundary are failing.

This limitation is mentioned in Intel documents:

Intel(R) 9 Series Chipset Family Platform Controller Hub (PCH) Datasheet:

"5.26.3 Flash Access
Program Register Access:
* Program Register Accesses are not allowed to cross a 4 KB boundary..."

Enhanced Serial Peripheral Interface (eSPI)
Interface Base Specification (for Client and Server Platforms):

"5.1.4 Address
For other memory transactions, the address may start or end at any byte
boundary. However, the address and payload length combination must not
cross the naturally aligned address boundary of the corresponding Maximum
Payload Size. It must not cross a 4 KB address boundary."

Avoid this by splitting an operation crossing the boundary into two
operations.

Cc: stable@vger.kernel.org
Reported-by: Romain Porte <romain.porte@nokia.com>
Tested-by: Pascal Fabreges <pascal.fabreges@nokia.com>
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
---
Changelog:
v2: More macros! As suggested by Mika.
v3: Actually compiled. Sorry Mika, the lines are really long now.
v4: Add "mtd:" to the subject

 drivers/mtd/spi-nor/intel-spi.c | 8 ++++++++
 1 file changed, 8 insertions(+)

Comments

Tudor Ambarus March 20, 2019, 6:49 a.m. UTC | #1
Mika,

Would you please add your Acked-by again? It's dropped in v4.

Looks good for me, below is my R-b.

Thanks!

On 03/19/2019 07:18 PM, Sverdlin, Alexander (Nokia - DE/Ulm) wrote:
> External E-Mail
> 
> 
> From: Alexander Sverdlin <alexander.sverdlin@nokia.com>
> 
> It was observed that reads crossing 4K address boundary are failing.
> 
> This limitation is mentioned in Intel documents:
> 
> Intel(R) 9 Series Chipset Family Platform Controller Hub (PCH) Datasheet:
> 
> "5.26.3 Flash Access
> Program Register Access:
> * Program Register Accesses are not allowed to cross a 4 KB boundary..."
> 
> Enhanced Serial Peripheral Interface (eSPI)
> Interface Base Specification (for Client and Server Platforms):
> 
> "5.1.4 Address
> For other memory transactions, the address may start or end at any byte
> boundary. However, the address and payload length combination must not
> cross the naturally aligned address boundary of the corresponding Maximum
> Payload Size. It must not cross a 4 KB address boundary."
> 
> Avoid this by splitting an operation crossing the boundary into two
> operations.
> 
> Cc: stable@vger.kernel.org
> Reported-by: Romain Porte <romain.porte@nokia.com>
> Tested-by: Pascal Fabreges <pascal.fabreges@nokia.com>
> Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>

> ---
> Changelog:
> v2: More macros! As suggested by Mika.
> v3: Actually compiled. Sorry Mika, the lines are really long now.
> v4: Add "mtd:" to the subject
> 
>  drivers/mtd/spi-nor/intel-spi.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c
> index af0a220..d60cbf2 100644
> --- a/drivers/mtd/spi-nor/intel-spi.c
> +++ b/drivers/mtd/spi-nor/intel-spi.c
> @@ -632,6 +632,10 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len,
>  	while (len > 0) {
>  		block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
>  
> +		/* Read cannot cross 4K boundary */
> +		block_size = min_t(loff_t, from + block_size,
> +				   round_up(from + 1, SZ_4K)) - from;
> +
>  		writel(from, ispi->base + FADDR);
>  
>  		val = readl(ispi->base + HSFSTS_CTL);
> @@ -685,6 +689,10 @@ static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len,
>  	while (len > 0) {
>  		block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
>  
> +		/* Write cannot cross 4K boundary */
> +		block_size = min_t(loff_t, to + block_size,
> +				   round_up(to + 1, SZ_4K)) - to;
> +
>  		writel(to, ispi->base + FADDR);
>  
>  		val = readl(ispi->base + HSFSTS_CTL);
>
Mika Westerberg March 20, 2019, 7:39 a.m. UTC | #2
On Wed, Mar 20, 2019 at 06:49:19AM +0000, Tudor.Ambarus@microchip.com wrote:
> Mika,
> 
> Would you please add your Acked-by again? It's dropped in v4.

Sure.

> Looks good for me, below is my R-b.
> 
> Thanks!
> 
> On 03/19/2019 07:18 PM, Sverdlin, Alexander (Nokia - DE/Ulm) wrote:
> > External E-Mail
> > 
> > 
> > From: Alexander Sverdlin <alexander.sverdlin@nokia.com>
> > 
> > It was observed that reads crossing 4K address boundary are failing.
> > 
> > This limitation is mentioned in Intel documents:
> > 
> > Intel(R) 9 Series Chipset Family Platform Controller Hub (PCH) Datasheet:
> > 
> > "5.26.3 Flash Access
> > Program Register Access:
> > * Program Register Accesses are not allowed to cross a 4 KB boundary..."
> > 
> > Enhanced Serial Peripheral Interface (eSPI)
> > Interface Base Specification (for Client and Server Platforms):
> > 
> > "5.1.4 Address
> > For other memory transactions, the address may start or end at any byte
> > boundary. However, the address and payload length combination must not
> > cross the naturally aligned address boundary of the corresponding Maximum
> > Payload Size. It must not cross a 4 KB address boundary."
> > 
> > Avoid this by splitting an operation crossing the boundary into two
> > operations.
> > 
> > Cc: stable@vger.kernel.org
> > Reported-by: Romain Porte <romain.porte@nokia.com>
> > Tested-by: Pascal Fabreges <pascal.fabreges@nokia.com>
> > Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
> 
> Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tudor Ambarus March 21, 2019, 4:48 p.m. UTC | #3
On 03/19/2019 07:18 PM, Sverdlin, Alexander (Nokia - DE/Ulm) wrote:
> From: Alexander Sverdlin <alexander.sverdlin@nokia.com>
> 
> It was observed that reads crossing 4K address boundary are failing.
> 
> This limitation is mentioned in Intel documents:
> 
> Intel(R) 9 Series Chipset Family Platform Controller Hub (PCH) Datasheet:
> 
> "5.26.3 Flash Access
> Program Register Access:
> * Program Register Accesses are not allowed to cross a 4 KB boundary..."
> 
> Enhanced Serial Peripheral Interface (eSPI)
> Interface Base Specification (for Client and Server Platforms):
> 
> "5.1.4 Address
> For other memory transactions, the address may start or end at any byte
> boundary. However, the address and payload length combination must not
> cross the naturally aligned address boundary of the corresponding Maximum
> Payload Size. It must not cross a 4 KB address boundary."
> 
> Avoid this by splitting an operation crossing the boundary into two
> operations.
> 
> Cc: stable@vger.kernel.org
> Reported-by: Romain Porte <romain.porte@nokia.com>
> Tested-by: Pascal Fabreges <pascal.fabreges@nokia.com>
> Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
> ---
> Changelog:
> v2: More macros! As suggested by Mika.
> v3: Actually compiled. Sorry Mika, the lines are really long now.
> v4: Add "mtd:" to the subject
> 
>  drivers/mtd/spi-nor/intel-spi.c | 8 ++++++++
>  1 file changed, 8 insertions(+)

Applied to http://git.infradead.org/linux-mtd.git, spi-nor/next. Thanks.
diff mbox series

Patch

diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c
index af0a220..d60cbf2 100644
--- a/drivers/mtd/spi-nor/intel-spi.c
+++ b/drivers/mtd/spi-nor/intel-spi.c
@@ -632,6 +632,10 @@  static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len,
 	while (len > 0) {
 		block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
 
+		/* Read cannot cross 4K boundary */
+		block_size = min_t(loff_t, from + block_size,
+				   round_up(from + 1, SZ_4K)) - from;
+
 		writel(from, ispi->base + FADDR);
 
 		val = readl(ispi->base + HSFSTS_CTL);
@@ -685,6 +689,10 @@  static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len,
 	while (len > 0) {
 		block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ);
 
+		/* Write cannot cross 4K boundary */
+		block_size = min_t(loff_t, to + block_size,
+				   round_up(to + 1, SZ_4K)) - to;
+
 		writel(to, ispi->base + FADDR);
 
 		val = readl(ispi->base + HSFSTS_CTL);