!1290 Add support for HiSilicon v3xx SPI NOR flash controller driver

From: @cloudyyy1234 
Reviewed-by: @young1c, @yiyangyang, @Lostwayzxc 
Signed-off-by: @Lostwayzxc
This commit is contained in:
openeuler-ci-bot 2023-11-14 14:40:25 +00:00 committed by Gitee
commit 87afc929ff
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
41 changed files with 5860 additions and 3 deletions

View File

@ -32,7 +32,7 @@
Name: kernel
Version: 4.19.90
Release: %{hulkrelease}.0241
Release: %{hulkrelease}.0243
Summary: Linux Kernel
License: GPLv2
URL: http://www.kernel.org/
@ -849,8 +849,48 @@ fi
%endif
%changelog
* TUE Nov 14 2023 YunYi Yang <yangyunyi2@huawei.com> - 4.19.90-2311.2.0.0243
- config: arm64: Build HiSilicon SPI/SFC driver as module
- spi: hisi-sfc-v3xx: drop unnecessary ACPI_PTR and related ifendif protection
- spi: hisi-sfc-v3xx: fix potential irq race condition
- spi: hisi-sfc-v3xx: add address mode check
- spi: hisi-sfc-v3xx: extend version checking compatibility
- spi: hisi-sfc-v3xx: add support for IRQ mode
- spi: hisi-sfc-v3xx: factor out the bit definition of interrupt register
- spi: hisi-sfc-v3xx: factor out bus config and transfer functions
- spi: hisi-sfc-v3xx: factor out IO modes configuration
- spi: Remove CONFIG_ prefix from Kconfig select
- spi: hisi-sfc-v3xx: add error check after per operation
- spi: HiSilicon v3xx: Use DMI quirk to set controller buswidth override bits
- spi: HiSilicon v3xx: Properly set CMD_CONFIG for Dual/Quad modes
- spi: Allow SPI controller override device buswidth
- spi: Add HiSilicon v3xx SPI NOR flash controller driver
- spi/acpi: avoid spurious matches during slave enumeration
- spi/acpi: fix incorrect ACPI parent check
- spi/acpi: enumerate all SPI slaves in the namespace
- driver core: platform: return -ENXIO for missing GpioInt
- driver: platform: Support parsing GpioInt 0 in platform_get_irq()
- spi: spi-mem: Fix build error without CONFIG_SPI_MEM
- spi: spi-mem: Add SPI_MEM_NO_DATA to the spi_mem_data_dir enum
- sh: Replace CONFIG_MTD_M25P80 with CONFIG_MTD_SPI_NOR in sh7757lcr_defconfig
- powerpc: Drop CONFIG_MTD_M25P80 in 85xx-hw.config
- m68k: Drop CONFIG_MTD_M25P80 in stmark2_defconfig
- mips: Drop CONFIG_MTD_M25P80 in various defconfig files
- ARM: shmobile: defconfig: Refresh config CONFIG_MTD_M25P80 for v5.4-rc1
- mtd: spi-nor: core: Fix an issue of releasing resources during read/write
- mtd: spi-nor: fix kernel-doc for spi_nor::spimem
- mtd: spi-nor: Pointer parameter for CR in spi_nor_read_cr()
- mtd: spi-nor: Pointer parameter for FSR in spi_nor_read_fsr()
- mtd: spi-nor: Pointer parameter for SR in spi_nor_read_sr()
- mtd: spi-nor: Stop compare with negative in Reg Ops methods
- mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods
- mtd: spi-nor: Fix direction of the write_sr() transfer
- mtd: spi-nor: Move m25p80 code in spi-nor.c
- mtd: spi-nor: always use bounce buffer for register read/writes
- mtd: spi-nor: Add support for mx25u12835f
- spi: add support for octal mode I/O data transfer
* TUE Nov 14 2023 Li Xiaodong <lixiaodong67@huawei.com> - 4.19.90-2311.2.0.0241
* TUE Nov 14 2023 Li Xiaodong <lixiaodong67@huawei.com> - 4.19.90-2311.2.0.0242
- !2793 handle uninitialized numa nodes gracefully.
- !2789 linux-4.19.y inclusion
- arch/x86/mm/numa: Do not initialize nodes twice
@ -915,7 +955,7 @@ fi
- i2c: add phytium i2c driver DT binding docs
- Net: ethernet: Support 3snic 3s9xx network card
* Mon Nov 13 2023 mingqian218472 <hangmingqian.zhang@huawei.com> - 4.19.90-2311.1.0.0240
* Mon Nov 13 2023 mingqian218472 <hangmingqian.zhang@huawei.com> - 4.19.90-2311.1.0.0241
- Add feature for nfs client support multipath
* Mon Nov 13 2023 Yu Liao <liaoyu15@huawei.com> - 4.19.90-2311.1.0.0240

View File

@ -0,0 +1,94 @@
From dedb0ed826070a5a8c6b3a02688f5bafccb9c263 Mon Sep 17 00:00:00 2001
From: Yogesh Narayan Gaur <yogeshnarayan.gaur@nxp.com>
Date: Mon, 3 Dec 2018 08:39:06 +0000
Subject: [PATCH 01/39] spi: add support for octal mode I/O data transfer
mainline inclusion
from mainline-v5.0-rc1
commit 6b03061f882de49b83ccf44beb3a12c920a2da1b
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6b03061f882de49b83ccf44beb3a12c920a2da1b
----------------------------------------------------------------------------
Add flags for Octal mode I/O data transfer
Required for the SPI controller which can do the data transfer (TX/RX)
on 8 data lines e.g. NXP FlexSPI controller.
SPI_TX_OCTAL: transmit with 8 wires
SPI_RX_OCTAL: receive with 8 wires
Signed-off-by: Yogesh Gaur <yogeshnarayan.gaur@nxp.com>
Reviewed-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
include/linux/spi/spi.h
---
drivers/spi/spi.c | 12 ++++++++++--
include/linux/spi/spi.h | 3 +++
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index d2334bfae076..08c7c8ee3271 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1593,6 +1593,9 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
case 4:
spi->mode |= SPI_TX_QUAD;
break;
+ case 8:
+ spi->mode |= SPI_TX_OCTAL;
+ break;
default:
dev_warn(&ctlr->dev,
"spi-tx-bus-width %d not supported\n",
@@ -1611,6 +1614,9 @@ static int of_spi_parse_dt(struct spi_controller *ctlr, struct spi_device *spi,
case 4:
spi->mode |= SPI_RX_QUAD;
break;
+ case 8:
+ spi->mode |= SPI_RX_OCTAL;
+ break;
default:
dev_warn(&ctlr->dev,
"spi-rx-bus-width %d not supported\n",
@@ -2857,14 +2863,16 @@ int spi_setup(struct spi_device *spi)
/* if it is SPI_3WIRE mode, DUAL and QUAD should be forbidden
*/
if ((spi->mode & SPI_3WIRE) && (spi->mode &
- (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD)))
+ (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL |
+ SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL)))
return -EINVAL;
/* help drivers fail *cleanly* when they need options
* that aren't supported with their current controller
*/
bad_bits = spi->mode & ~spi->controller->mode_bits;
ugly_bits = bad_bits &
- (SPI_TX_DUAL | SPI_TX_QUAD | SPI_RX_DUAL | SPI_RX_QUAD);
+ (SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL |
+ SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL);
if (ugly_bits) {
dev_warn(&spi->dev,
"setup: ignoring unsupported mode bits %x\n",
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 1c0a0fa34586..80d6bd6e46c5 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -163,6 +163,9 @@ struct spi_device {
#define SPI_TX_QUAD 0x200 /* transmit with 4 wires */
#define SPI_RX_DUAL 0x400 /* receive with 2 wires */
#define SPI_RX_QUAD 0x800 /* receive with 4 wires */
+#define SPI_CS_WORD 0x1000 /* toggle cs after each word */
+#define SPI_TX_OCTAL 0x2000 /* transmit with 8 wires */
+#define SPI_RX_OCTAL 0x4000 /* receive with 8 wires */
int irq;
void *controller_state;
void *controller_data;
--
2.27.0

View File

@ -0,0 +1,42 @@
From 4f934b660a1bd32920a9953bbeec8e4f107aa47b Mon Sep 17 00:00:00 2001
From: Alexander Sverdlin <alexander.sverdlin@nokia.com>
Date: Fri, 13 Jul 2018 15:06:46 +0200
Subject: [PATCH 02/39] mtd: spi-nor: Add support for mx25u12835f
mainline inclusion
from mainline-v5.0-rc1
commit 81554171373018b83f3554b9e725d2b5bf1844a5
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=81554171373018b83f3554b9e725d2b5bf1844a5
----------------------------------------------------------------------------
This chip supports dual and quad read and uniform 4K-byte erase.
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/mtd/spi-nor/spi-nor.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 2e183425facd..5440e33b360c 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1088,6 +1088,8 @@ static const struct flash_info spi_nor_ids[] = {
{ "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
+ { "mx25u12835f", INFO(0xc22538, 0, 64 * 1024, 256,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_4B_OPCODES) },
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
--
2.27.0

View File

@ -0,0 +1,326 @@
From 32b2c87f0bc38bca34563d24d35086b5442413d9 Mon Sep 17 00:00:00 2001
From: Vignesh Raghavendra <vigneshr@ti.com>
Date: Tue, 6 Aug 2019 10:40:39 +0530
Subject: [PATCH 03/39] mtd: spi-nor: always use bounce buffer for register
read/writes
mainline inclusion
from mainline-v5.4-rc1
commit f173f26a4d543fa57e6ed9505bbbbf9bec61f544
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f173f26a4d543fa57e6ed9505bbbbf9bec61f544
----------------------------------------------------------------------------
spi-mem layer expects all buffers passed to it to be DMA'able. But
spi-nor layer mostly allocates buffers on stack for reading/writing to
registers and therefore are not DMA'able. Introduce bounce buffer to be
used to read/write to registers. This ensures that buffer passed to
spi-mem layer during register read/writes is DMA'able. With this change
nor->cmd-buf is no longer used, so drop it.
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
drivers/mtd/spi-nor/spi-nor.c
include/linux/mtd/spi-nor.h
---
drivers/mtd/spi-nor/spi-nor.c | 78 +++++++++++++++++++----------------
include/linux/mtd/spi-nor.h | 7 +++-
2 files changed, 48 insertions(+), 37 deletions(-)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 5440e33b360c..7771d4519245 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -105,15 +105,14 @@ static const struct flash_info *spi_nor_match_id(const char *name);
static int read_sr(struct spi_nor *nor)
{
int ret;
- u8 val;
- ret = nor->read_reg(nor, SPINOR_OP_RDSR, &val, 1);
+ ret = nor->read_reg(nor, SPINOR_OP_RDSR, nor->bouncebuf, 1);
if (ret < 0) {
pr_err("error %d reading SR\n", (int) ret);
return ret;
}
- return val;
+ return nor->bouncebuf[0];
}
/*
@@ -124,15 +123,14 @@ static int read_sr(struct spi_nor *nor)
static int read_fsr(struct spi_nor *nor)
{
int ret;
- u8 val;
- ret = nor->read_reg(nor, SPINOR_OP_RDFSR, &val, 1);
+ ret = nor->read_reg(nor, SPINOR_OP_RDFSR, nor->bouncebuf, 1);
if (ret < 0) {
pr_err("error %d reading FSR\n", ret);
return ret;
}
- return val;
+ return nor->bouncebuf[0];
}
/*
@@ -143,15 +141,14 @@ static int read_fsr(struct spi_nor *nor)
static int read_cr(struct spi_nor *nor)
{
int ret;
- u8 val;
- ret = nor->read_reg(nor, SPINOR_OP_RDCR, &val, 1);
+ ret = nor->read_reg(nor, SPINOR_OP_RDCR, nor->bouncebuf, 1);
if (ret < 0) {
dev_err(nor->dev, "error %d reading CR\n", ret);
return ret;
}
- return val;
+ return nor->bouncebuf[0];
}
/*
@@ -160,8 +157,8 @@ static int read_cr(struct spi_nor *nor)
*/
static inline int write_sr(struct spi_nor *nor, u8 val)
{
- nor->cmd_buf[0] = val;
- return nor->write_reg(nor, SPINOR_OP_WRSR, nor->cmd_buf, 1);
+ nor->bouncebuf[0] = val;
+ return nor->write_reg(nor, SPINOR_OP_WRSR, nor->bouncebuf, 1);
}
/*
@@ -293,31 +290,31 @@ static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info,
* We must clear the register to enable normal behavior.
*/
write_enable(nor);
- nor->cmd_buf[0] = 0;
- nor->write_reg(nor, SPINOR_OP_WREAR, nor->cmd_buf, 1);
+ nor->bouncebuf[0] = 0;
+ nor->write_reg(nor, SPINOR_OP_WREAR,
+ nor->bouncebuf, 1);
write_disable(nor);
}
return status;
default:
/* Spansion style */
- nor->cmd_buf[0] = enable << 7;
- return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1);
+ nor->bouncebuf[0] = enable << 7;
+ return nor->write_reg(nor, SPINOR_OP_BRWR, nor->bouncebuf, 1);
}
}
static int s3an_sr_ready(struct spi_nor *nor)
{
int ret;
- u8 val;
- ret = nor->read_reg(nor, SPINOR_OP_XRDSR, &val, 1);
+ ret = nor->read_reg(nor, SPINOR_OP_XRDSR, nor->bouncebuf, 1);
if (ret < 0) {
dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
return ret;
}
- return !!(val & XSR_RDY);
+ return !!(nor->bouncebuf[0] & XSR_RDY);
}
static inline int spi_nor_sr_ready(struct spi_nor *nor)
@@ -476,7 +473,6 @@ static loff_t spi_nor_s3an_addr_convert(struct spi_nor *nor, unsigned int addr)
*/
static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
{
- u8 buf[SPI_NOR_MAX_ADDR_WIDTH];
int i;
if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT)
@@ -490,11 +486,12 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
* control
*/
for (i = nor->addr_width - 1; i >= 0; i--) {
- buf[i] = addr & 0xff;
+ nor->bouncebuf[i] = addr & 0xff;
addr >>= 8;
}
- return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width);
+ return nor->write_reg(nor, nor->erase_opcode, nor->bouncebuf,
+ nor->addr_width);
}
/*
@@ -1271,7 +1268,7 @@ static const struct flash_info spi_nor_ids[] = {
static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
{
int tmp;
- u8 id[SPI_NOR_MAX_ID_LEN];
+ u8 *id = nor->bouncebuf;
const struct flash_info *info;
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
@@ -1571,9 +1568,11 @@ static int write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
*/
static int spansion_quad_enable(struct spi_nor *nor)
{
- u8 sr_cr[2] = {0, CR_QUAD_EN_SPAN};
+ u8 *sr_cr = nor->bouncebuf;
int ret;
+ sr_cr[0] = 0;
+ sr_cr[1] = CR_QUAD_EN_SPAN;
ret = write_sr_cr(nor, sr_cr);
if (ret)
return ret;
@@ -1603,7 +1602,7 @@ static int spansion_quad_enable(struct spi_nor *nor)
*/
static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
{
- u8 sr_cr[2];
+ u8 *sr_cr = nor->bouncebuf;
int ret;
/* Keep the current value of the Status Register. */
@@ -1634,7 +1633,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
static int spansion_read_cr_quad_enable(struct spi_nor *nor)
{
struct device *dev = nor->dev;
- u8 sr_cr[2];
+ u8 *sr_cr = nor->bouncebuf;
int ret;
/* Check current Quad Enable bit value. */
@@ -1685,22 +1684,22 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
*/
static int sr2_bit7_quad_enable(struct spi_nor *nor)
{
- u8 sr2;
+ u8 *sr2 = nor->bouncebuf;
int ret;
/* Check current Quad Enable bit value. */
- ret = nor->read_reg(nor, SPINOR_OP_RDSR2, &sr2, 1);
+ ret = nor->read_reg(nor, SPINOR_OP_RDSR2, sr2, 1);
if (ret)
return ret;
- if (sr2 & SR2_QUAD_EN_BIT7)
+ if (*sr2 & SR2_QUAD_EN_BIT7)
return 0;
/* Update the Quad Enable bit. */
- sr2 |= SR2_QUAD_EN_BIT7;
+ *sr2 |= SR2_QUAD_EN_BIT7;
write_enable(nor);
- ret = nor->write_reg(nor, SPINOR_OP_WRSR2, &sr2, 1);
+ ret = nor->write_reg(nor, SPINOR_OP_WRSR2, sr2, 1);
if (ret < 0) {
dev_err(nor->dev, "error while writing status register 2\n");
return -EINVAL;
@@ -1713,8 +1712,8 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
}
/* Read back and check it. */
- ret = nor->read_reg(nor, SPINOR_OP_RDSR2, &sr2, 1);
- if (!(ret > 0 && (sr2 & SR2_QUAD_EN_BIT7))) {
+ ret = nor->read_reg(nor, SPINOR_OP_RDSR2, sr2, 1);
+ if (!(ret > 0 && (*sr2 & SR2_QUAD_EN_BIT7))) {
dev_err(nor->dev, "SR2 Quad bit not set\n");
return -EINVAL;
}
@@ -1736,9 +1735,8 @@ static int spi_nor_check(struct spi_nor *nor)
static int s3an_nor_scan(const struct flash_info *info, struct spi_nor *nor)
{
int ret;
- u8 val;
- ret = nor->read_reg(nor, SPINOR_OP_XRDSR, &val, 1);
+ ret = nor->read_reg(nor, SPINOR_OP_XRDSR, nor->bouncebuf, 1);
if (ret < 0) {
dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
return ret;
@@ -1760,7 +1758,7 @@ static int s3an_nor_scan(const struct flash_info *info, struct spi_nor *nor)
* The current addressing mode can be read from the XRDSR register
* and should not be changed, because is a destructive operation.
*/
- if (val & XSR_PAGESIZE) {
+ if (nor->bouncebuf[0] & XSR_PAGESIZE) {
/* Flash in Power of 2 mode */
nor->page_size = (nor->page_size == 264) ? 256 : 512;
nor->mtd.writebufsize = nor->page_size;
@@ -2819,6 +2817,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
nor->read_proto = SNOR_PROTO_1_1_1;
nor->write_proto = SNOR_PROTO_1_1_1;
+ /*
+ * We need the bounce buffer early to read/write registers when going
+ * through the spi-mem layer (buffers have to be DMA-able).
+ */
+ nor->bouncebuf_size = PAGE_SIZE;
+ nor->bouncebuf = devm_kmalloc(dev, nor->bouncebuf_size,
+ GFP_KERNEL);
+ if (!nor->bouncebuf)
+ return -ENOMEM;
+
if (name)
info = spi_nor_match_id(name);
/* Try to auto-detect if chip name wasn't specified or not found */
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index c922e97f205a..66431fd2a48b 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -249,6 +249,9 @@ struct flash_info;
* @mtd: point to a mtd_info structure
* @lock: the lock for the read/write/erase/lock/unlock operations
* @dev: point to a spi device, or a spi nor controller device.
+ * @bouncebuf: bounce buffer used when the buffer passed by the MTD
+ * layer is not DMA-able
+ * @bouncebuf_size: size of the bounce buffer
* @info: spi-nor part JDEC MFR id and other info
* @page_size: the page size of the SPI NOR
* @addr_width: number of address bytes
@@ -261,7 +264,6 @@ struct flash_info;
* @read_proto: the SPI protocol for read operations
* @write_proto: the SPI protocol for write operations
* @reg_proto the SPI protocol for read_reg/write_reg/erase operations
- * @cmd_buf: used by the write_reg
* @prepare: [OPTIONAL] do some preparations for the
* read/write/erase/lock/unlock operations
* @unprepare: [OPTIONAL] do some post work after the
@@ -284,6 +286,8 @@ struct spi_nor {
struct mtd_info mtd;
struct mutex lock;
struct device *dev;
+ u8 *bouncebuf;
+ size_t bouncebuf_size;
const struct flash_info *info;
u32 page_size;
u8 addr_width;
@@ -296,7 +300,6 @@ struct spi_nor {
enum spi_nor_protocol reg_proto;
bool sst_write_second;
u32 flags;
- u8 cmd_buf[SPI_NOR_MAX_CMD_SIZE];
int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
--
2.27.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
From 1389e9a38b24a3e0dcf0b5dd62c99a57756619fb Mon Sep 17 00:00:00 2001
From: Tudor Ambarus <tudor.ambarus@microchip.com>
Date: Fri, 4 Oct 2019 10:47:55 +0000
Subject: [PATCH 05/39] mtd: spi-nor: Fix direction of the write_sr() transfer
mainline inclusion
from mainline-v5.4-rc3
commit 41e086e1550646344dd47d3462ca2d19caabb943
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=41e086e1550646344dd47d3462ca2d19caabb943
----------------------------------------------------------------------------
write_sr() sends data to the SPI memory, fix the direction.
Fixes: b35b9a10362d ("mtd: spi-nor: Move m25p80 code in spi-nor.c")
Reported-by: John Garry <john.garry@huawei.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Tested-by: John Garry <john.garry@huawei.com>
Acked-by: Vignesh Raghavendra <vigneshr@ti.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/mtd/spi-nor/spi-nor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 0161662768e7..33dace0b4c8b 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -345,7 +345,7 @@ static inline int write_sr(struct spi_nor *nor, u8 val)
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(1, nor->bouncebuf, 1));
return spi_mem_exec_op(nor->spimem, &op);
}
--
2.27.0

View File

@ -0,0 +1,412 @@
From 2a3bbff9e6e53d35b55a9439b14ba3a81662bb11 Mon Sep 17 00:00:00 2001
From: Tudor Ambarus <tudor.ambarus@microchip.com>
Date: Tue, 29 Oct 2019 11:16:49 +0000
Subject: [PATCH 06/39] mtd: spi-nor: Prepend spi_nor_ to all Reg Ops methods
mainline inclusion
from mainline-v5.5-rc1
commit 567c2983efb9a4b3d26a221b477346d927092b8a
category: cleanup
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=567c2983efb9a4b3d26a221b477346d927092b8a
----------------------------------------------------------------------------
All the core functions should begin with "spi_nor_".
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
drivers/mtd/spi-nor/spi-nor.c
---
drivers/mtd/spi-nor/spi-nor.c | 97 ++++++++++++++++++-----------------
1 file changed, 49 insertions(+), 48 deletions(-)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 33dace0b4c8b..0809018daf4c 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -251,7 +251,7 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
* Return the status register value.
* Returns negative if error occurred.
*/
-static int read_sr(struct spi_nor *nor)
+static int spi_nor_read_sr(struct spi_nor *nor)
{
int ret;
@@ -280,7 +280,7 @@ static int read_sr(struct spi_nor *nor)
* Return the status register value.
* Returns negative if error occurred.
*/
-static int read_fsr(struct spi_nor *nor)
+static int spi_nor_read_fsr(struct spi_nor *nor)
{
int ret;
@@ -309,7 +309,7 @@ static int read_fsr(struct spi_nor *nor)
* location. Return the configuration register value.
* Returns negative if error occurred.
*/
-static int read_cr(struct spi_nor *nor)
+static int spi_nor_read_cr(struct spi_nor *nor)
{
int ret;
@@ -337,7 +337,7 @@ static int read_cr(struct spi_nor *nor)
* Write status register 1 byte
* Returns negative if error occurred.
*/
-static inline int write_sr(struct spi_nor *nor, u8 val)
+static int spi_nor_write_sr(struct spi_nor *nor, u8 val)
{
nor->bouncebuf[0] = val;
if (nor->spimem) {
@@ -357,7 +357,7 @@ static inline int write_sr(struct spi_nor *nor, u8 val)
* Set write enable latch with Write Enable command.
* Returns negative if error occurred.
*/
-static inline int write_enable(struct spi_nor *nor)
+static int spi_nor_write_enable(struct spi_nor *nor)
{
if (nor->spimem) {
struct spi_mem_op op =
@@ -375,7 +375,7 @@ static inline int write_enable(struct spi_nor *nor)
/*
* Send write disable instruction to the chip.
*/
-static inline int write_disable(struct spi_nor *nor)
+static int spi_nor_write_disable(struct spi_nor *nor)
{
if (nor->spimem) {
struct spi_mem_op op =
@@ -538,11 +538,11 @@ static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info,
case SNOR_MFR_MACRONIX:
case SNOR_MFR_WINBOND:
if (need_wren)
- write_enable(nor);
+ spi_nor_write_enable(nor);
status = macronix_set_4byte(nor, enable);
if (need_wren)
- write_disable(nor);
+ spi_nor_write_disable(nor);
if (!status && !enable &&
JEDEC_MFR(info) == SNOR_MFR_WINBOND) {
@@ -552,9 +552,9 @@ static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info,
* 3-byte-address reads come from the second 16M.
* We must clear the register to enable normal behavior.
*/
- write_enable(nor);
+ spi_nor_write_enable(nor);
spi_nor_write_ear(nor, 0);
- write_disable(nor);
+ spi_nor_write_disable(nor);
}
return status;
@@ -609,7 +609,7 @@ static int spi_nor_clear_sr(struct spi_nor *nor)
static inline int spi_nor_sr_ready(struct spi_nor *nor)
{
- int sr = read_sr(nor);
+ int sr = spi_nor_read_sr(nor);
if (sr < 0)
return sr;
@@ -643,7 +643,7 @@ static int spi_nor_clear_fsr(struct spi_nor *nor)
static inline int spi_nor_fsr_ready(struct spi_nor *nor)
{
- int fsr = read_fsr(nor);
+ int fsr = spi_nor_read_fsr(nor);
if (fsr < 0)
return fsr;
@@ -721,7 +721,7 @@ static int spi_nor_wait_till_ready(struct spi_nor *nor)
*
* Returns 0 if successful, non-zero otherwise.
*/
-static int erase_chip(struct spi_nor *nor)
+static int spi_nor_erase_chip(struct spi_nor *nor)
{
dev_dbg(nor->dev, " %lldKiB\n", (long long)(nor->mtd.size >> 10));
@@ -848,9 +848,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
unsigned long timeout;
- write_enable(nor);
+ spi_nor_write_enable(nor);
- if (erase_chip(nor)) {
+ if (spi_nor_erase_chip(nor)) {
ret = -EIO;
goto erase_err;
}
@@ -876,7 +876,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
/* "sector"-at-a-time erase */
} else {
while (len) {
- write_enable(nor);
+ spi_nor_write_enable(nor);
ret = spi_nor_erase_sector(nor, addr);
if (ret)
@@ -891,7 +891,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
}
}
- write_disable(nor);
+ spi_nor_write_disable(nor);
erase_err:
spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE);
@@ -900,12 +900,13 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
}
/* Write status register and ensure bits in mask match written values */
-static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask)
+static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
+ u8 mask)
{
int ret;
- write_enable(nor);
- ret = write_sr(nor, status_new);
+ spi_nor_write_enable(nor);
+ ret = spi_nor_write_sr(nor, status_new);
if (ret)
return ret;
@@ -913,7 +914,7 @@ static int write_sr_and_check(struct spi_nor *nor, u8 status_new, u8 mask)
if (ret)
return ret;
- ret = read_sr(nor);
+ ret = spi_nor_read_sr(nor);
if (ret < 0)
return ret;
@@ -1019,7 +1020,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
bool use_top;
- status_old = read_sr(nor);
+ status_old = spi_nor_read_sr(nor);
if (status_old < 0)
return status_old;
@@ -1081,7 +1082,7 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
if ((status_new & mask) < (status_old & mask))
return -EINVAL;
- return write_sr_and_check(nor, status_new, mask);
+ return spi_nor_write_sr_and_check(nor, status_new, mask);
}
/*
@@ -1099,7 +1100,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
bool use_top;
- status_old = read_sr(nor);
+ status_old = spi_nor_read_sr(nor);
if (status_old < 0)
return status_old;
@@ -1164,7 +1165,7 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
if ((status_new & mask) > (status_old & mask))
return -EINVAL;
- return write_sr_and_check(nor, status_new, mask);
+ return spi_nor_write_sr_and_check(nor, status_new, mask);
}
/*
@@ -1178,7 +1179,7 @@ static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
{
int status;
- status = read_sr(nor);
+ status = spi_nor_read_sr(nor);
if (status < 0)
return status;
@@ -1709,7 +1710,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
if (ret)
return ret;
- write_enable(nor);
+ spi_nor_write_enable(nor);
nor->sst_write_second = false;
@@ -1748,14 +1749,14 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
}
nor->sst_write_second = false;
- write_disable(nor);
+ spi_nor_write_disable(nor);
ret = spi_nor_wait_till_ready(nor);
if (ret)
goto sst_write_err;
/* Write out trailing byte if it exists. */
if (actual != len) {
- write_enable(nor);
+ spi_nor_write_enable(nor);
nor->program_opcode = SPINOR_OP_BP;
ret = spi_nor_write_data(nor, to, 1, buf + actual);
@@ -1766,7 +1767,7 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
ret = spi_nor_wait_till_ready(nor);
if (ret)
goto sst_write_err;
- write_disable(nor);
+ spi_nor_write_disable(nor);
actual += 1;
}
sst_write_err:
@@ -1819,7 +1820,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT)
addr = spi_nor_s3an_addr_convert(nor, addr);
- write_enable(nor);
+ spi_nor_write_enable(nor);
ret = spi_nor_write_data(nor, addr, page_remain, buf + i);
if (ret < 0)
goto write_err;
@@ -1858,21 +1859,21 @@ static int macronix_quad_enable(struct spi_nor *nor)
{
int ret, val;
- val = read_sr(nor);
+ val = spi_nor_read_sr(nor);
if (val < 0)
return val;
if (val & SR_QUAD_EN_MX)
return 0;
- write_enable(nor);
+ spi_nor_write_enable(nor);
- write_sr(nor, val | SR_QUAD_EN_MX);
+ spi_nor_write_sr(nor, val | SR_QUAD_EN_MX);
ret = spi_nor_wait_till_ready(nor);
if (ret)
return ret;
- ret = read_sr(nor);
+ ret = spi_nor_read_sr(nor);
if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
dev_err(nor->dev, "Macronix Quad bit not set\n");
return -EINVAL;
@@ -1887,11 +1888,11 @@ static int macronix_quad_enable(struct spi_nor *nor)
* 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)
+static int spi_nor_write_sr_cr(struct spi_nor *nor, u8 *sr_cr)
{
int ret;
- write_enable(nor);
+ spi_nor_write_enable(nor);
if (nor->spimem) {
struct spi_mem_op op =
@@ -1952,12 +1953,12 @@ 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_cr(nor, sr_cr);
if (ret)
return ret;
/* read back and check it */
- ret = read_cr(nor);
+ ret = spi_nor_read_cr(nor);
if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
dev_err(nor->dev, "Spansion Quad bit not set\n");
return -EINVAL;
@@ -1985,7 +1986,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
int ret;
/* Keep the current value of the Status Register. */
- ret = read_sr(nor);
+ ret = spi_nor_read_sr(nor);
if (ret < 0) {
dev_err(nor->dev, "error while reading status register\n");
return -EINVAL;
@@ -1993,7 +1994,7 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
sr_cr[0] = ret;
sr_cr[1] = CR_QUAD_EN_SPAN;
- return write_sr_cr(nor, sr_cr);
+ return spi_nor_write_sr_cr(nor, sr_cr);
}
/**
@@ -2016,7 +2017,7 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
int ret;
/* Check current Quad Enable bit value. */
- ret = read_cr(nor);
+ ret = spi_nor_read_cr(nor);
if (ret < 0) {
dev_err(dev, "error while reading configuration register\n");
return -EINVAL;
@@ -2028,19 +2029,19 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
sr_cr[1] = ret | CR_QUAD_EN_SPAN;
/* Keep the current value of the Status Register. */
- ret = read_sr(nor);
+ ret = spi_nor_read_sr(nor);
if (ret < 0) {
dev_err(dev, "error while reading status register\n");
return -EINVAL;
}
sr_cr[0] = ret;
- ret = write_sr_cr(nor, sr_cr);
+ ret = spi_nor_write_sr_cr(nor, sr_cr);
if (ret)
return ret;
/* Read back and check it. */
- ret = read_cr(nor);
+ ret = spi_nor_read_cr(nor);
if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
dev_err(nor->dev, "Spansion Quad bit not set\n");
return -EINVAL;
@@ -2076,7 +2077,7 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
/* Update the Quad Enable bit. */
*sr2 |= SR2_QUAD_EN_BIT7;
- write_enable(nor);
+ spi_nor_write_enable(nor);
ret = spi_nor_write_sr2(nor, sr2);
if (ret < 0) {
@@ -3123,8 +3124,8 @@ static int spi_nor_init(struct spi_nor *nor)
JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
nor->info->flags & SPI_NOR_HAS_LOCK) {
- write_enable(nor);
- write_sr(nor, 0);
+ spi_nor_write_enable(nor);
+ spi_nor_write_sr(nor, 0);
spi_nor_wait_till_ready(nor);
}
--
2.27.0

View File

@ -0,0 +1,124 @@
From 3462ae48d7dd80fffd0f61a8cd885a7a9016931a Mon Sep 17 00:00:00 2001
From: Tudor Ambarus <tudor.ambarus@microchip.com>
Date: Tue, 29 Oct 2019 11:16:54 +0000
Subject: [PATCH 07/39] mtd: spi-nor: Stop compare with negative in Reg Ops
methods
mainline inclusion
from mainline-v5.5-rc1
commit ebe04bfe26dd816839d3d24fdeb5f6bed430a3df
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ebe04bfe26dd816839d3d24fdeb5f6bed430a3df
----------------------------------------------------------------------------
spi_mem_exec_op()
nor->controller_ops->write_reg()
nor->controller_ops->read_reg()
spi_nor_wait_till_ready()
Return 0 on success, -errno otherwise.
Stop compare with negative and compare with zero in all the register
operations methods.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
drivers/mtd/spi-nor/spi-nor.c
---
drivers/mtd/spi-nor/spi-nor.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 0809018daf4c..0c9f58d8819c 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -267,7 +267,7 @@ static int spi_nor_read_sr(struct spi_nor *nor)
ret = nor->read_reg(nor, SPINOR_OP_RDSR, nor->bouncebuf, 1);
}
- if (ret < 0) {
+ if (ret) {
pr_err("error %d reading SR\n", (int) ret);
return ret;
}
@@ -296,7 +296,7 @@ static int spi_nor_read_fsr(struct spi_nor *nor)
ret = nor->read_reg(nor, SPINOR_OP_RDFSR, nor->bouncebuf, 1);
}
- if (ret < 0) {
+ if (ret) {
pr_err("error %d reading FSR\n", ret);
return ret;
}
@@ -325,7 +325,7 @@ static int spi_nor_read_cr(struct spi_nor *nor)
ret = nor->read_reg(nor, SPINOR_OP_RDCR, nor->bouncebuf, 1);
}
- if (ret < 0) {
+ if (ret) {
dev_err(nor->dev, "error %d reading CR\n", ret);
return ret;
}
@@ -584,7 +584,7 @@ static int s3an_sr_ready(struct spi_nor *nor)
int ret;
ret = spi_nor_xread_sr(nor, nor->bouncebuf);
- if (ret < 0) {
+ if (ret) {
dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
return ret;
}
@@ -1640,7 +1640,7 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
tmp = nor->read_reg(nor, SPINOR_OP_RDID, id,
SPI_NOR_MAX_ID_LEN);
}
- if (tmp < 0) {
+ if (tmp) {
dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
return ERR_PTR(tmp);
}
@@ -2080,20 +2080,23 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
spi_nor_write_enable(nor);
ret = spi_nor_write_sr2(nor, sr2);
- if (ret < 0) {
+ if (ret) {
dev_err(nor->dev, "error while writing status register 2\n");
return -EINVAL;
}
ret = spi_nor_wait_till_ready(nor);
- if (ret < 0) {
+ if (ret) {
dev_err(nor->dev, "timeout while writing status register 2\n");
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;
}
@@ -2119,7 +2122,7 @@ static int s3an_nor_scan(const struct flash_info *info, struct spi_nor *nor)
int ret;
ret = spi_nor_xread_sr(nor, nor->bouncebuf);
- if (ret < 0) {
+ if (ret) {
dev_err(nor->dev, "error %d reading XRDSR\n", (int) ret);
return ret;
}
--
2.27.0

View File

@ -0,0 +1,258 @@
From b5eb1d02d31155f46aab15b435f9bff0a2e83097 Mon Sep 17 00:00:00 2001
From: Tudor Ambarus <tudor.ambarus@microchip.com>
Date: Thu, 24 Oct 2019 15:55:34 +0300
Subject: [PATCH 08/39] mtd: spi-nor: Pointer parameter for SR in
spi_nor_read_sr()
mainline inclusion
from mainline-v5.5-rc1
commit cd1718f5c49d53539c99f45a485ca0e0ac7f0a99
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cd1718f5c49d53539c99f45a485ca0e0ac7f0a99
----------------------------------------------------------------------------
Let the callers pass the pointer to the DMA-able buffer where
the value of the Status Register will be written. This way we
avoid the casts between int and u8, which can be confusing.
Callers stop compare the return value of spi_nor_read_sr() with negative,
spi_nor_read_sr() returns 0 on success and -errno otherwise.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
drivers/mtd/spi-nor/spi-nor.c
---
drivers/mtd/spi-nor/spi-nor.c | 101 ++++++++++++++++++----------------
1 file changed, 55 insertions(+), 46 deletions(-)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 0c9f58d8819c..3a10b5939cd2 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -246,12 +246,15 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len,
return nor->write(nor, to, len, buf);
}
-/*
- * Read the status register, returning its value in the location
- * Return the status register value.
- * Returns negative if error occurred.
+/**
+ * spi_nor_read_sr() - Read the Status Register.
+ * @nor: pointer to 'struct spi_nor'.
+ * @sr: pointer to a DMA-able buffer where the value of the
+ * Status Register will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
*/
-static int spi_nor_read_sr(struct spi_nor *nor)
+static int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
{
int ret;
@@ -260,19 +263,17 @@ static int spi_nor_read_sr(struct spi_nor *nor)
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 1),
SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+ SPI_MEM_OP_DATA_IN(1, sr, 1));
ret = spi_mem_exec_op(nor->spimem, &op);
} else {
- ret = nor->read_reg(nor, SPINOR_OP_RDSR, nor->bouncebuf, 1);
+ ret = nor->read_reg(nor, SPINOR_OP_RDSR, sr, 1);
}
- if (ret) {
+ if (ret)
pr_err("error %d reading SR\n", (int) ret);
- return ret;
- }
- return nor->bouncebuf[0];
+ return ret;
}
/*
@@ -609,12 +610,14 @@ static int spi_nor_clear_sr(struct spi_nor *nor)
static inline int spi_nor_sr_ready(struct spi_nor *nor)
{
- int sr = spi_nor_read_sr(nor);
- if (sr < 0)
- return sr;
+ int ret = spi_nor_read_sr(nor, nor->bouncebuf);
- if (nor->flags & SNOR_F_USE_CLSR && sr & (SR_E_ERR | SR_P_ERR)) {
- if (sr & SR_E_ERR)
+ 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");
@@ -623,7 +626,7 @@ static inline int spi_nor_sr_ready(struct spi_nor *nor)
return -EIO;
}
- return !(sr & SR_WIP);
+ return !(nor->bouncebuf[0] & SR_WIP);
}
static int spi_nor_clear_fsr(struct spi_nor *nor)
@@ -914,8 +917,8 @@ static int spi_nor_write_sr_and_check(struct spi_nor *nor, u8 status_new,
if (ret)
return ret;
- ret = spi_nor_read_sr(nor);
- if (ret < 0)
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ if (ret)
return ret;
return ((ret & mask) != (status_new & mask)) ? -EIO : 0;
@@ -1013,16 +1016,18 @@ static int stm_is_unlocked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len,
static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
{
struct mtd_info *mtd = &nor->mtd;
- int status_old, status_new;
+ int ret, status_old, status_new;
u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
u8 shift = ffs(mask) - 1, pow, val;
loff_t lock_len;
bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
bool use_top;
- status_old = spi_nor_read_sr(nor);
- if (status_old < 0)
- return status_old;
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ if (ret)
+ return ret;
+
+ status_old = nor->bouncebuf[0];
/* If nothing in our range is unlocked, we don't need to do anything */
if (stm_is_locked_sr(nor, ofs, len, status_old))
@@ -1093,16 +1098,18 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
{
struct mtd_info *mtd = &nor->mtd;
- int status_old, status_new;
+ int ret, status_old, status_new;
u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
u8 shift = ffs(mask) - 1, pow, val;
loff_t lock_len;
bool can_be_top = true, can_be_bottom = nor->flags & SNOR_F_HAS_SR_TB;
bool use_top;
- status_old = spi_nor_read_sr(nor);
- if (status_old < 0)
- return status_old;
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ if (ret)
+ return ret;
+
+ status_old = nor->bouncebuf[0];
/* If nothing in our range is locked, we don't need to do anything */
if (stm_is_unlocked_sr(nor, ofs, len, status_old))
@@ -1177,13 +1184,13 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
*/
static int stm_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
{
- int status;
+ int ret;
- status = spi_nor_read_sr(nor);
- if (status < 0)
- return status;
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ if (ret)
+ return ret;
- return stm_is_locked_sr(nor, ofs, len, status);
+ return stm_is_locked_sr(nor, ofs, len, nor->bouncebuf[0]);
}
static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
@@ -1857,24 +1864,28 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
*/
static int macronix_quad_enable(struct spi_nor *nor)
{
- int ret, val;
+ int ret;
- val = spi_nor_read_sr(nor);
- if (val < 0)
- return val;
- if (val & SR_QUAD_EN_MX)
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ if (ret)
+ return ret;
+
+ if (nor->bouncebuf[0] & SR_QUAD_EN_MX)
return 0;
spi_nor_write_enable(nor);
- spi_nor_write_sr(nor, val | SR_QUAD_EN_MX);
+ spi_nor_write_sr(nor, nor->bouncebuf[0] | SR_QUAD_EN_MX);
ret = spi_nor_wait_till_ready(nor);
if (ret)
return ret;
- ret = spi_nor_read_sr(nor);
- if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
+ ret = spi_nor_read_sr(nor, nor->bouncebuf);
+ if (ret)
+ return ret;
+
+ if (!(nor->bouncebuf[0] & SR_QUAD_EN_MX)) {
dev_err(nor->dev, "Macronix Quad bit not set\n");
return -EINVAL;
}
@@ -1986,12 +1997,11 @@ static int spansion_no_read_cr_quad_enable(struct spi_nor *nor)
int ret;
/* Keep the current value of the Status Register. */
- ret = spi_nor_read_sr(nor);
- if (ret < 0) {
+ ret = spi_nor_read_sr(nor, sr_cr);
+ if (ret) {
dev_err(nor->dev, "error while reading status register\n");
return -EINVAL;
}
- sr_cr[0] = ret;
sr_cr[1] = CR_QUAD_EN_SPAN;
return spi_nor_write_sr_cr(nor, sr_cr);
@@ -2029,12 +2039,11 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
sr_cr[1] = ret | CR_QUAD_EN_SPAN;
/* Keep the current value of the Status Register. */
- ret = spi_nor_read_sr(nor);
- if (ret < 0) {
+ ret = spi_nor_read_sr(nor, sr_cr);
+ if (ret) {
dev_err(dev, "error while reading status register\n");
return -EINVAL;
}
- sr_cr[0] = ret;
ret = spi_nor_write_sr_cr(nor, sr_cr);
if (ret)
--
2.27.0

View File

@ -0,0 +1,120 @@
From 7ac30bd8a32bd1b992f5c252b5608c9c26e4be26 Mon Sep 17 00:00:00 2001
From: Tudor Ambarus <tudor.ambarus@microchip.com>
Date: Thu, 24 Oct 2019 16:40:13 +0300
Subject: [PATCH 09/39] mtd: spi-nor: Pointer parameter for FSR in
spi_nor_read_fsr()
mainline inclusion
from mainline-v5.5-rc1
commit 5ce1b49ccb52fc3dd5679d8c523a3e8b5c812fb0
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=5ce1b49ccb52fc3dd5679d8c523a3e8b5c812fb0
----------------------------------------------------------------------------
Let the callers pass the pointer to the DMA-able buffer where
the value of the Flag Status Register will be written. This way we
avoid the casts between int and u8, which can be confusing.
Caller stops compare the return value of spi_nor_read_fsr() with negative,
spi_nor_read_fsr() returns 0 on success and -errno otherwise.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
drivers/mtd/spi-nor/spi-nor.c
---
drivers/mtd/spi-nor/spi-nor.c | 38 ++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 3a10b5939cd2..766ad458197e 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -276,12 +276,15 @@ static int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
return ret;
}
-/*
- * Read the flag status register, returning its value in the location
- * Return the status register value.
- * Returns negative if error occurred.
+/**
+ * spi_nor_read_fsr() - Read the Flag Status Register.
+ * @nor: pointer to 'struct spi_nor'
+ * @fsr: pointer to a DMA-able buffer where the value of the
+ * Flag Status Register will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
*/
-static int spi_nor_read_fsr(struct spi_nor *nor)
+static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr)
{
int ret;
@@ -290,19 +293,17 @@ static int spi_nor_read_fsr(struct spi_nor *nor)
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDFSR, 1),
SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+ SPI_MEM_OP_DATA_IN(1, fsr, 1));
ret = spi_mem_exec_op(nor->spimem, &op);
} else {
- ret = nor->read_reg(nor, SPINOR_OP_RDFSR, nor->bouncebuf, 1);
+ ret = nor->read_reg(nor, SPINOR_OP_RDFSR, fsr, 1);
}
- if (ret) {
+ if (ret)
pr_err("error %d reading FSR\n", ret);
- return ret;
- }
- return nor->bouncebuf[0];
+ return ret;
}
/*
@@ -646,17 +647,18 @@ static int spi_nor_clear_fsr(struct spi_nor *nor)
static inline int spi_nor_fsr_ready(struct spi_nor *nor)
{
- int fsr = spi_nor_read_fsr(nor);
- if (fsr < 0)
- return fsr;
+ int ret = spi_nor_read_fsr(nor, nor->bouncebuf);
+
+ if (ret)
+ return ret;
- if (fsr & (FSR_E_ERR | FSR_P_ERR)) {
- if (fsr & FSR_E_ERR)
+ 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 (fsr & FSR_PT_ERR)
+ if (nor->bouncebuf[0] & FSR_PT_ERR)
dev_err(nor->dev,
"Attempted to modify a protected sector.\n");
@@ -664,7 +666,7 @@ static inline int spi_nor_fsr_ready(struct spi_nor *nor)
return -EIO;
}
- return fsr & FSR_READY;
+ return nor->bouncebuf[0] & FSR_READY;
}
static int spi_nor_ready(struct spi_nor *nor)
--
2.27.0

View File

@ -0,0 +1,136 @@
From 09f73e2e9bba97398fa7a66affaa0e820ac16b5c Mon Sep 17 00:00:00 2001
From: Tudor Ambarus <tudor.ambarus@microchip.com>
Date: Thu, 24 Oct 2019 16:59:55 +0300
Subject: [PATCH 10/39] mtd: spi-nor: Pointer parameter for CR in
spi_nor_read_cr()
mainline inclusion
from mainline-v5.5-rc1
commit b662d398ccf114a80c92140287a6507efb3e2dfc
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b662d398ccf114a80c92140287a6507efb3e2dfc
----------------------------------------------------------------------------
Let the callers pass the pointer to the DMA-able buffer where
the value of the Configuration Register will be written. This way we
avoid the casts between int and u8, which can be confusing.
Callers stop compare the return value of spi_nor_read_cr() with negative,
spi_nor_read_cr() returns 0 on success and -errno otherwise.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
drivers/mtd/spi-nor/spi-nor.c
---
drivers/mtd/spi-nor/spi-nor.c | 46 ++++++++++++++++++++---------------
1 file changed, 27 insertions(+), 19 deletions(-)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 766ad458197e..f1e92f63cab6 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -306,12 +306,16 @@ static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr)
return ret;
}
-/*
- * Read configuration register, returning its value in the
- * location. Return the configuration register value.
- * Returns negative if error occurred.
+/**
+ * spi_nor_read_cr() - Read the Configuration Register using the
+ * SPINOR_OP_RDCR (35h) command.
+ * @nor: pointer to 'struct spi_nor'
+ * @cr: pointer to a DMA-able buffer where the value of the
+ * Configuration Register will be written.
+ *
+ * Return: 0 on success, -errno otherwise.
*/
-static int spi_nor_read_cr(struct spi_nor *nor)
+static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
{
int ret;
@@ -320,19 +324,17 @@ static int spi_nor_read_cr(struct spi_nor *nor)
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDCR, 1),
SPI_MEM_OP_NO_ADDR,
SPI_MEM_OP_NO_DUMMY,
- SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1));
+ SPI_MEM_OP_DATA_IN(1, cr, 1));
ret = spi_mem_exec_op(nor->spimem, &op);
} else {
- ret = nor->read_reg(nor, SPINOR_OP_RDCR, nor->bouncebuf, 1);
+ ret = nor->read_reg(nor, SPINOR_OP_RDCR, cr, 1);
}
- if (ret) {
+ if (ret)
dev_err(nor->dev, "error %d reading CR\n", ret);
- return ret;
- }
- return nor->bouncebuf[0];
+ return ret;
}
/*
@@ -1971,8 +1973,11 @@ static int spansion_quad_enable(struct spi_nor *nor)
return ret;
/* read back and check it */
- ret = spi_nor_read_cr(nor);
- if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
+ ret = spi_nor_read_cr(nor, nor->bouncebuf);
+ if (ret)
+ return ret;
+
+ if (!(nor->bouncebuf[0] & CR_QUAD_EN_SPAN)) {
dev_err(nor->dev, "Spansion Quad bit not set\n");
return -EINVAL;
}
@@ -2029,16 +2034,16 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
int ret;
/* Check current Quad Enable bit value. */
- ret = spi_nor_read_cr(nor);
- if (ret < 0) {
+ ret = spi_nor_read_cr(nor, &sr_cr[1]);
+ if (ret) {
dev_err(dev, "error while reading configuration register\n");
return -EINVAL;
}
- if (ret & CR_QUAD_EN_SPAN)
+ if (sr_cr[1] & CR_QUAD_EN_SPAN)
return 0;
- sr_cr[1] = ret | CR_QUAD_EN_SPAN;
+ sr_cr[1] |= CR_QUAD_EN_SPAN;
/* Keep the current value of the Status Register. */
ret = spi_nor_read_sr(nor, sr_cr);
@@ -2052,8 +2057,11 @@ static int spansion_read_cr_quad_enable(struct spi_nor *nor)
return ret;
/* Read back and check it. */
- ret = spi_nor_read_cr(nor);
- if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) {
+ ret = spi_nor_read_cr(nor, &sr_cr[1]);
+ if (ret)
+ return ret;
+
+ if (!(sr_cr[1] & CR_QUAD_EN_SPAN)) {
dev_err(nor->dev, "Spansion Quad bit not set\n");
return -EINVAL;
}
--
2.27.0

View File

@ -0,0 +1,49 @@
From 9eaef9e96377baccef091f6247b064e09b91394a Mon Sep 17 00:00:00 2001
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Date: Fri, 3 Apr 2020 23:50:57 +0300
Subject: [PATCH 11/39] mtd: spi-nor: fix kernel-doc for spi_nor::spimem
mainline inclusion
from mainline-v5.8-rc1
commit 1f241ad2a093b889122bd6bfdce57551d21bba5b
category: cleanup
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=1f241ad2a093b889122bd6bfdce57551d21bba5b
----------------------------------------------------------------------------
When adding the 'spimem' field to 'struct spi_nor', a grammar mistake
("point" instead of "pointer") was made -- fix it and convert the SPI
acronym to uppercase and fully spell out "memory", while at it...
Fixes: b35b9a10362 ("mtd: spi-nor: Move m25p80 code in spi-nor.c")
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
include/linux/mtd/spi-nor.h
---
include/linux/mtd/spi-nor.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index ac5e2656e9b3..98d7794ceedb 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -249,8 +249,8 @@ struct flash_info;
* struct spi_nor - Structure for defining a the SPI NOR layer
* @mtd: point to a mtd_info structure
* @lock: the lock for the read/write/erase/lock/unlock operations
- * @dev: point to a spi device, or a spi nor controller device.
- * @spimem: point to the spi mem device
+ * @dev: pointer to an SPI device or an SPI NOR controller device
+ * @spimem: pointer to the SPI memory device
* @bouncebuf: bounce buffer used when the buffer passed by the MTD
* layer is not DMA-able
* @bouncebuf_size: size of the bounce buffer
--
2.27.0

View File

@ -0,0 +1,105 @@
From a30685e70936de07484b543dd506ba78e2dda7e9 Mon Sep 17 00:00:00 2001
From: Xiang Chen <chenxiang66@hisilicon.com>
Date: Sat, 22 May 2021 11:53:14 +0000
Subject: [PATCH 12/39] mtd: spi-nor: core: Fix an issue of releasing resources
during read/write
mainline inclusion
from mainline-v5.13-rc1
commit be94215be1ab19e5d38f50962f611c88d4bfc83a
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=be94215be1ab19e5d38f50962f611c88d4bfc83a
----------------------------------------------------------------------------
commit be94215be1ab19e5d38f50962f611c88d4bfc83a upstream.
If rmmod the driver during read or write, the driver will release the
resources which are used during read or write, so it is possible to
refer to NULL pointer.
Use the testcase "mtd_debug read /dev/mtd0 0xc00000 0x400000 dest_file &
sleep 0.5;rmmod spi_hisi_sfc_v3xx.ko", the issue can be reproduced in
hisi_sfc_v3xx driver.
To avoid the issue, fill the interface _get_device and _put_device of
mtd_info to grab the reference to the spi controller driver module, so
the request of rmmod the driver is rejected before read/write is finished.
Fixes: b199489d37b2 ("mtd: spi-nor: add the framework for SPI NOR")
Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Tested-by: Michael Walle <michael@walle.cc>
Tested-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Michael Walle <michael@walle.cc>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/1617262486-4223-1-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Chen Jun <chenjun102@huawei.com>
Acked-by: Weilong Chen <chenweilong@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
drivers/mtd/spi-nor/core.c
---
drivers/mtd/spi-nor/spi-nor.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index f1e92f63cab6..9792b776cc4c 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -3190,6 +3190,36 @@ static void spi_nor_resume(struct mtd_info *mtd)
dev_err(dev, "resume() failed\n");
}
+static int spi_nor_get_device(struct mtd_info *mtd)
+{
+ struct spi_nor *nor = mtd_to_spi_nor(mtd);
+ struct device *dev;
+
+ if (nor->spimem)
+ dev = nor->spimem->spi->controller->dev.parent;
+ else
+ dev = nor->dev;
+
+ if (!try_module_get(dev->driver->owner))
+ return -ENODEV;
+
+ return 0;
+}
+
+static void spi_nor_put_device(struct mtd_info *mtd)
+{
+ struct spi_nor *nor = mtd_to_spi_nor(mtd);
+ struct device *dev;
+
+ if (nor->spimem)
+ dev = nor->spimem->spi->controller->dev.parent;
+ else
+ dev = nor->dev;
+
+ module_put(dev->driver->owner);
+}
+
+
void spi_nor_restore(struct spi_nor *nor)
{
/* restore the addressing mode */
@@ -3292,6 +3322,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
mtd->_erase = spi_nor_erase;
mtd->_read = spi_nor_read;
mtd->_resume = spi_nor_resume;
+ mtd->_get_device = spi_nor_get_device;
+ mtd->_put_device = spi_nor_put_device;
/* NOR protection support for STmicro/Micron chips and similar */
if (JEDEC_MFR(info) == SNOR_MFR_MICRON ||
--
2.27.0

View File

@ -0,0 +1,46 @@
From 6dc80f062988a0251723db031b4e89cbc899550f Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Fri, 25 Oct 2019 15:53:25 +0200
Subject: [PATCH 13/39] ARM: shmobile: defconfig: Refresh config
CONFIG_MTD_M25P80 for v5.4-rc1
mainline inclusion
from mainline-v5.5-rc1
commit 51e0f6a1917831373e153eca2fb27902f0f8bc7b
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=51e0f6a1917831373e153eca2fb27902f0f8bc7b
----------------------------------------------------------------------------
Update the defconfig for Renesas ARM boards:
- Drop CONFIG_MTD_M25P80=y (removed in commit b35b9a10362d2034 ("mtd:
spi-nor: Move m25p80 code in spi-nor.c")),
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20191025135325.32242-1-geert+renesas@glider.be
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
arch/arm/configs/shmobile_defconfig
---
arch/arm/configs/shmobile_defconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index f8faf3729464..f52302ae49a6 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -65,7 +65,6 @@ CONFIG_CMA_SIZE_MBYTES=64
CONFIG_SIMPLE_PM_BUS=y
CONFIG_MTD=y
CONFIG_MTD_BLOCK=y
-CONFIG_MTD_M25P80=y
CONFIG_MTD_SPI_NOR=y
CONFIG_EEPROM_AT24=y
CONFIG_BLK_DEV_SD=y
--
2.27.0

View File

@ -0,0 +1,96 @@
From e8d9db794570db82ac042b0c661456e0f7c3af21 Mon Sep 17 00:00:00 2001
From: Bin Meng <bin.meng@windriver.com>
Date: Fri, 1 May 2020 21:25:49 -0700
Subject: [PATCH 14/39] mips: Drop CONFIG_MTD_M25P80 in various defconfig files
mainline inclusion
from mainline-v5.8-rc1
commit 9d139131e973dac0ef6207a161b228a7fcad8180
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=9d139131e973dac0ef6207a161b228a7fcad8180
----------------------------------------------------------------------------
Drop CONFIG_MTD_M25P80 that was removed in
commit b35b9a10362d ("mtd: spi-nor: Move m25p80 code in spi-nor.c")
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
arch/mips/configs/generic/board-ocelot.config
---
arch/mips/configs/ath79_defconfig | 1 -
arch/mips/configs/db1xxx_defconfig | 1 -
arch/mips/configs/generic/board-ocelot.config | 1 -
arch/mips/configs/pistachio_defconfig | 1 -
arch/mips/configs/rt305x_defconfig | 1 -
5 files changed, 5 deletions(-)
diff --git a/arch/mips/configs/ath79_defconfig b/arch/mips/configs/ath79_defconfig
index 4c47b3fd958b..7195338da194 100644
--- a/arch/mips/configs/ath79_defconfig
+++ b/arch/mips/configs/ath79_defconfig
@@ -49,7 +49,6 @@ CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_M25P80=y
CONFIG_MTD_SPI_NOR=y
CONFIG_NETDEVICES=y
# CONFIG_NET_PACKET_ENGINE is not set
diff --git a/arch/mips/configs/db1xxx_defconfig b/arch/mips/configs/db1xxx_defconfig
index 0108bb9f1e37..b517d469b1b2 100644
--- a/arch/mips/configs/db1xxx_defconfig
+++ b/arch/mips/configs/db1xxx_defconfig
@@ -105,7 +105,6 @@ CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_M25P80=y
CONFIG_MTD_SST25L=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC_BCH=y
diff --git a/arch/mips/configs/generic/board-ocelot.config b/arch/mips/configs/generic/board-ocelot.config
index aa815761d85e..7e7695e1542a 100644
--- a/arch/mips/configs/generic/board-ocelot.config
+++ b/arch/mips/configs/generic/board-ocelot.config
@@ -5,7 +5,6 @@ CONFIG_LEGACY_BOARD_OCELOT=y
CONFIG_MTD=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_BLOCK=y
-CONFIG_MTD_M25P80=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_SPI_NOR=y
diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig
index b22a3cf149b6..e524c5ced381 100644
--- a/arch/mips/configs/pistachio_defconfig
+++ b/arch/mips/configs/pistachio_defconfig
@@ -131,7 +131,6 @@ CONFIG_DEBUG_DEVRES=y
CONFIG_CONNECTOR=y
CONFIG_MTD=y
CONFIG_MTD_BLOCK=y
-CONFIG_MTD_M25P80=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BLOCK=y
diff --git a/arch/mips/configs/rt305x_defconfig b/arch/mips/configs/rt305x_defconfig
index dbe6a4639d05..6c9f3c892f5a 100644
--- a/arch/mips/configs/rt305x_defconfig
+++ b/arch/mips/configs/rt305x_defconfig
@@ -84,7 +84,6 @@ CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_OF=y
-CONFIG_MTD_M25P80=y
CONFIG_MTD_SPI_NOR=y
CONFIG_EEPROM_93CX6=m
CONFIG_SCSI=y
--
2.27.0

View File

@ -0,0 +1,41 @@
From 679821ee5b370e36451dd353809ce29f4a217da0 Mon Sep 17 00:00:00 2001
From: Bin Meng <bin.meng@windriver.com>
Date: Fri, 1 May 2020 21:30:21 -0700
Subject: [PATCH 15/39] m68k: Drop CONFIG_MTD_M25P80 in stmark2_defconfig
mainline inclusion
from mainline-v5.8-rc1
commit e00091071615378e66291c61ea02d02d15a2cc7e
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e00091071615378e66291c61ea02d02d15a2cc7e
----------------------------------------------------------------------------
Drop CONFIG_MTD_M25P80 that was removed in
commit b35b9a10362d ("mtd: spi-nor: Move m25p80 code in spi-nor.c")
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Signed-off-by: Greg Ungerer <gerg@linux-m68k.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
arch/m68k/configs/stmark2_defconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/m68k/configs/stmark2_defconfig b/arch/m68k/configs/stmark2_defconfig
index 3d07b1de7eb0..f2a0937f1d22 100644
--- a/arch/m68k/configs/stmark2_defconfig
+++ b/arch/m68k/configs/stmark2_defconfig
@@ -49,7 +49,6 @@ CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_ROM=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PLATRAM=y
-CONFIG_MTD_M25P80=y
CONFIG_MTD_SPI_NOR=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
--
2.27.0

View File

@ -0,0 +1,42 @@
From ff14e23b9018738156c8943d0edf556901d9fe6e Mon Sep 17 00:00:00 2001
From: Bin Meng <bin.meng@windriver.com>
Date: Fri, 1 May 2020 21:44:54 -0700
Subject: [PATCH 16/39] powerpc: Drop CONFIG_MTD_M25P80 in 85xx-hw.config
mainline inclusion
from mainline-v5.9-rc1
commit 76f09371bc05d6eb8d5a01823c9eaab768d6e934
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=76f09371bc05d6eb8d5a01823c9eaab768d6e934
----------------------------------------------------------------------------
Drop CONFIG_MTD_M25P80 that was removed in
commit b35b9a10362d ("mtd: spi-nor: Move m25p80 code in spi-nor.c")
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/1588394694-517-1-git-send-email-bmeng.cn@gmail.com
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
arch/powerpc/configs/85xx-hw.config | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/powerpc/configs/85xx-hw.config b/arch/powerpc/configs/85xx-hw.config
index c03d0fb16665..2bce8e571651 100644
--- a/arch/powerpc/configs/85xx-hw.config
+++ b/arch/powerpc/configs/85xx-hw.config
@@ -68,7 +68,6 @@ CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_M25P80=y
CONFIG_MTD_NAND_FSL_ELBC=y
CONFIG_MTD_NAND_FSL_IFC=y
CONFIG_MTD_NAND=y
--
2.27.0

View File

@ -0,0 +1,43 @@
From b76e9c7fbcd02e7062b13ab29330860d77181cc7 Mon Sep 17 00:00:00 2001
From: Bin Meng <bin.meng@windriver.com>
Date: Sat, 2 May 2020 04:04:43 -0700
Subject: [PATCH 17/39] sh: Replace CONFIG_MTD_M25P80 with CONFIG_MTD_SPI_NOR
in sh7757lcr_defconfig
mainline inclusion
from mainline-v5.9-rc1
commit bd158322ba5f6190403e6aeb53c1e7b659f9ade8
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bd158322ba5f6190403e6aeb53c1e7b659f9ade8
----------------------------------------------------------------------------
CONFIG_MTD_M25P80 was removed and replaced by CONFIG_MTD_SPI_NOR in
commit b35b9a10362d ("mtd: spi-nor: Move m25p80 code in spi-nor.c")
Signed-off-by: Bin Meng <bin.meng@windriver.com>
Signed-off-by: Rich Felker <dalias@libc.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
arch/sh/configs/sh7757lcr_defconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/sh/configs/sh7757lcr_defconfig b/arch/sh/configs/sh7757lcr_defconfig
index b0c4bc830fb8..225b82d49d6d 100644
--- a/arch/sh/configs/sh7757lcr_defconfig
+++ b/arch/sh/configs/sh7757lcr_defconfig
@@ -37,7 +37,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_FW_LOADER is not set
CONFIG_MTD=y
CONFIG_MTD_BLOCK=y
-CONFIG_MTD_M25P80=y
+CONFIG_MTD_SPI_NOR=y
CONFIG_BLK_DEV_RAM=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
--
2.27.0

View File

@ -0,0 +1,67 @@
From c95fab40e779f7e66d3643daf9a9760aeb964929 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@bootlin.com>
Date: Tue, 6 Nov 2018 17:05:31 +0100
Subject: [PATCH 18/39] spi: spi-mem: Add SPI_MEM_NO_DATA to the
spi_mem_data_dir enum
mainline inclusion
from mainline-v5.0-rc1
commit 0ebb261a0b2d090de618a383d2378d4a00834958
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0ebb261a0b2d090de618a383d2378d4a00834958
----------------------------------------------------------------------------
When defining spi_mem_op templates we don't necessarily know the size
that will be passed when the template is actually used, and basing the
supports_op() check on op->data.nbytes to know whether there will be
data transferred for a specific operation is this not possible.
Add SPI_MEM_NO_DATA to the spi_mem_data_dir enum so that we can base
our checks on op->data.dir instead of op->data.nbytes.
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-mem.c | 2 +-
include/linux/spi/spi-mem.h | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index eb72dba71d83..526b1ed5c306 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -140,7 +140,7 @@ static bool spi_mem_default_supports_op(struct spi_mem *mem,
spi_check_buswidth_req(mem, op->dummy.buswidth, true))
return false;
- if (op->data.nbytes &&
+ if (op->data.dir != SPI_MEM_NO_DATA &&
spi_check_buswidth_req(mem, op->data.buswidth,
op->data.dir == SPI_MEM_DATA_OUT))
return false;
diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
index 69ee30456864..80db2de83402 100644
--- a/include/linux/spi/spi-mem.h
+++ b/include/linux/spi/spi-mem.h
@@ -57,10 +57,12 @@
/**
* enum spi_mem_data_dir - describes the direction of a SPI memory data
* transfer from the controller perspective
+ * @SPI_MEM_NO_DATA: no data transferred
* @SPI_MEM_DATA_IN: data coming from the SPI memory
* @SPI_MEM_DATA_OUT: data sent the SPI memory
*/
enum spi_mem_data_dir {
+ SPI_MEM_NO_DATA,
SPI_MEM_DATA_IN,
SPI_MEM_DATA_OUT,
};
--
2.27.0

View File

@ -0,0 +1,80 @@
From 9fc413c03fc3aa5566c7ce9da96b6ee7e417184a Mon Sep 17 00:00:00 2001
From: YueHaibing <yuehaibing@huawei.com>
Date: Mon, 8 Apr 2019 22:39:49 +0800
Subject: [PATCH 19/39] spi: spi-mem: Fix build error without CONFIG_SPI_MEM
mainline inclusion
from mainline-v5.2-rc1
commit 72e6841608b9ce7e04515ed43693b2878936c93a
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=72e6841608b9ce7e04515ed43693b2878936c93a
----------------------------------------------------------------------------
When building with CONFIG_SPI_MEM is not set
gc warns this:
drivers/spi/spi-zynq-qspi.o: In function `zynq_qspi_supports_op':
spi-zynq-qspi.c:(.text+0x1da): undefined reference to `spi_mem_default_supports_op'
Fixes: 67dca5e580f1 ("spi: spi-mem: Add support for Zynq QSPI controller")
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
include/linux/spi/spi-mem.h
---
drivers/spi/spi-mem.c | 2 +-
include/linux/spi/spi-mem.h | 12 ++++++++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c
index 526b1ed5c306..788824ee00c7 100644
--- a/drivers/spi/spi-mem.c
+++ b/drivers/spi/spi-mem.c
@@ -126,7 +126,7 @@ static int spi_check_buswidth_req(struct spi_mem *mem, u8 buswidth, bool tx)
return -ENOTSUPP;
}
-static bool spi_mem_default_supports_op(struct spi_mem *mem,
+bool spi_mem_default_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
if (spi_check_buswidth_req(mem, op->cmd.buswidth, true))
diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
index 80db2de83402..991a394efe9c 100644
--- a/include/linux/spi/spi-mem.h
+++ b/include/linux/spi/spi-mem.h
@@ -224,6 +224,10 @@ int spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr,
void spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr,
const struct spi_mem_op *op,
struct sg_table *sg);
+
+bool spi_mem_default_supports_op(struct spi_mem *mem,
+ const struct spi_mem_op *op);
+
#else
static inline int
spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr,
@@ -239,6 +243,14 @@ spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr,
struct sg_table *sg)
{
}
+
+static inline
+bool spi_mem_default_supports_op(struct spi_mem *mem,
+ const struct spi_mem_op *op)
+{
+ return false;
+}
+
#endif /* CONFIG_SPI_MEM */
int spi_mem_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op);
--
2.27.0

View File

@ -0,0 +1,77 @@
From 65d39d8a4568e1f70da4ec8313e2cff534a2c70b Mon Sep 17 00:00:00 2001
From: Enrico Granata <egranata@chromium.org>
Date: Mon, 11 Feb 2019 11:01:12 -0800
Subject: [PATCH 20/39] driver: platform: Support parsing GpioInt 0 in
platform_get_irq()
mainline inclusion
from mainline-v5.1-rc1
commit daaef255dc96834aaaad627d3271504cba3ac2dc
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=daaef255dc96834aaaad627d3271504cba3ac2dc
----------------------------------------------------------------------------
ACPI 5 added support for GpioInt resources as a way to provide
information about interrupts mediated via a GPIO controller.
Several device buses (e.g. SPI, I2C) have support for retrieving
an IRQ specified via this type of resource, and providing it
directly to the driver as an IRQ number.
This is not currently done for the platform drivers, as platform_get_irq()
does not try to parse GpioInt() resources. This requires drivers to
either have to support only one possible IRQ resource, or to have code
in place to try both as a failsafe.
While there is a possibility of ambiguity for devices that exposes
multiple IRQs, it is easy and feasible to support the common case
of devices that only expose one IRQ which would be of either type
depending on the underlying system's architecture.
This commit adds support for parsing a GpioInt resource in order
to fulfill a request for the index 0 IRQ for a platform device.
Signed-off-by: Enrico Granata <egranata@chromium.org>
Reviewed-by: Dmitry Torokhov <dtor@chromium.org>
Acked-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/base/platform.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index be8c82cc4445..77412f3509de 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -128,7 +128,20 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS);
}
- return r ? r->start : -ENXIO;
+ if (r)
+ return r->start;
+
+ /*
+ * For the index 0 interrupt, allow falling back to GpioInt
+ * resources. While a device could have both Interrupt and GpioInt
+ * resources, making this fallback ambiguous, in many common cases
+ * the device will only expose one IRQ, and this fallback
+ * allows a common code path across either kind of resource.
+ */
+ if (num == 0 && has_acpi_companion(&dev->dev))
+ return acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num);
+
+ return -ENXIO;
#endif
}
EXPORT_SYMBOL_GPL(platform_get_irq);
--
2.27.0

View File

@ -0,0 +1,83 @@
From 897f087ebc8218977d66b43ab0df30bd26ad65c3 Mon Sep 17 00:00:00 2001
From: Brian Norris <briannorris@chromium.org>
Date: Mon, 29 Jul 2019 13:49:54 -0700
Subject: [PATCH 21/39] driver core: platform: return -ENXIO for missing
GpioInt
mainline inclusion
from mainline-v5.3-rc4
commit 46c42d844211ef5902e32aa507beac0817c585e9
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=46c42d844211ef5902e32aa507beac0817c585e9
----------------------------------------------------------------------------
Commit daaef255dc96 ("driver: platform: Support parsing GpioInt 0 in
platform_get_irq()") broke the Embedded Controller driver on most LPC
Chromebooks (i.e., most x86 Chromebooks), because cros_ec_lpc expects
platform_get_irq() to return -ENXIO for non-existent IRQs.
Unfortunately, acpi_dev_gpio_irq_get() doesn't follow this convention
and returns -ENOENT instead. So we get this error from cros_ec_lpc:
couldn't retrieve IRQ number (-2)
I see a variety of drivers that treat -ENXIO specially, so rather than
fix all of them, let's fix up the API to restore its previous behavior.
I reported this on v2 of this patch:
https://lore.kernel.org/lkml/20190220180538.GA42642@google.com/
but apparently the patch had already been merged before v3 got sent out:
https://lore.kernel.org/lkml/20190221193429.161300-1-egranata@chromium.org/
and the result is that the bug landed and remains unfixed.
I differ from the v3 patch by:
* allowing for ret==0, even though acpi_dev_gpio_irq_get() specifically
documents (and enforces) that 0 is not a valid return value (noted on
the v3 review)
* adding a small comment
Reported-by: Brian Norris <briannorris@chromium.org>
Reported-by: Salvatore Bellizzi <salvatore.bellizzi@linux.seppia.net>
Cc: Enrico Granata <egranata@chromium.org>
Cc: <stable@vger.kernel.org>
Fixes: daaef255dc96 ("driver: platform: Support parsing GpioInt 0 in platform_get_irq()")
Signed-off-by: Brian Norris <briannorris@chromium.org>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Enrico Granata <egranata@google.com>
Link: https://lore.kernel.org/r/20190729204954.25510-1-briannorris@chromium.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/base/platform.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 77412f3509de..d04ac9f54b57 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -138,8 +138,13 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
* the device will only expose one IRQ, and this fallback
* allows a common code path across either kind of resource.
*/
- if (num == 0 && has_acpi_companion(&dev->dev))
- return acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num);
+ if (num == 0 && has_acpi_companion(&dev->dev)) {
+ int ret = acpi_dev_gpio_irq_get(ACPI_COMPANION(&dev->dev), num);
+
+ /* Our callers expect -ENXIO for missing IRQs. */
+ if (ret >= 0 || ret == -EPROBE_DEFER)
+ return ret;
+ }
return -ENXIO;
#endif
--
2.27.0

View File

@ -0,0 +1,258 @@
From 3fb5bcdbcd9ceaf3d8d69f8ba5a20c692c3ba105 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Date: Thu, 30 May 2019 13:16:34 +0200
Subject: [PATCH 22/39] spi/acpi: enumerate all SPI slaves in the namespace
mainline inclusion
from mainline-v5.3-rc1
commit 4c3c59544f33e97cf8557f27e05a9904ead16363
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4c3c59544f33e97cf8557f27e05a9904ead16363
----------------------------------------------------------------------------
Currently, the ACPI enumeration that takes place when registering a
SPI master only considers immediate child devices in the ACPI namespace,
rather than checking the ResourceSource field in the SpiSerialBus()
resource descriptor.
This is incorrect: SPI slaves could reside anywhere in the ACPI
namespace, and so we should enumerate the entire namespace and look for
any device that refers to the newly registered SPI master in its
resource descriptor.
So refactor the existing code and use a lookup structure so that
allocating the SPI device structure is deferred until we have identified
the device as an actual child of the controller. This approach is
loosely based on the way the I2C subsystem handles ACPI enumeration.
Note that Apple x86 hardware does not rely on SpiSerialBus() resources
in _CRS but uses nested devices below the controller's device node in
the ACPI namespace, with a special set of device properties. This means
we have to take care to only parse those properties for device nodes
that are direct children of the controller node.
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: linux-spi@vger.kernel.org
Cc: broonie@kernel.org
Cc: andy.shevchenko@gmail.com
Cc: masahisa.kojima@linaro.org
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: linux-acpi@vger.kernel.org
Cc: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi.c | 104 ++++++++++++++++++++++++++++++++--------------
1 file changed, 73 insertions(+), 31 deletions(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 08c7c8ee3271..c6e272edd806 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1732,9 +1732,18 @@ static void of_register_spi_devices(struct spi_controller *ctlr) { }
#endif
#ifdef CONFIG_ACPI
-static void acpi_spi_parse_apple_properties(struct spi_device *spi)
+struct acpi_spi_lookup {
+ struct spi_controller *ctlr;
+ u32 max_speed_hz;
+ u32 mode;
+ int irq;
+ u8 bits_per_word;
+ u8 chip_select;
+};
+
+static void acpi_spi_parse_apple_properties(struct acpi_device *dev,
+ struct acpi_spi_lookup *lookup)
{
- struct acpi_device *dev = ACPI_COMPANION(&spi->dev);
const union acpi_object *obj;
if (!x86_apple_machine)
@@ -1742,35 +1751,47 @@ static void acpi_spi_parse_apple_properties(struct spi_device *spi)
if (!acpi_dev_get_property(dev, "spiSclkPeriod", ACPI_TYPE_BUFFER, &obj)
&& obj->buffer.length >= 4)
- spi->max_speed_hz = NSEC_PER_SEC / *(u32 *)obj->buffer.pointer;
+ lookup->max_speed_hz = NSEC_PER_SEC /
+ *(u32 *)obj->buffer.pointer;
if (!acpi_dev_get_property(dev, "spiWordSize", ACPI_TYPE_BUFFER, &obj)
&& obj->buffer.length == 8)
- spi->bits_per_word = *(u64 *)obj->buffer.pointer;
+ lookup->bits_per_word = *(u64 *)obj->buffer.pointer;
if (!acpi_dev_get_property(dev, "spiBitOrder", ACPI_TYPE_BUFFER, &obj)
&& obj->buffer.length == 8 && !*(u64 *)obj->buffer.pointer)
- spi->mode |= SPI_LSB_FIRST;
+ lookup->mode |= SPI_LSB_FIRST;
if (!acpi_dev_get_property(dev, "spiSPO", ACPI_TYPE_BUFFER, &obj)
&& obj->buffer.length == 8 && *(u64 *)obj->buffer.pointer)
- spi->mode |= SPI_CPOL;
+ lookup->mode |= SPI_CPOL;
if (!acpi_dev_get_property(dev, "spiSPH", ACPI_TYPE_BUFFER, &obj)
&& obj->buffer.length == 8 && *(u64 *)obj->buffer.pointer)
- spi->mode |= SPI_CPHA;
+ lookup->mode |= SPI_CPHA;
}
static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
{
- struct spi_device *spi = data;
- struct spi_controller *ctlr = spi->controller;
+ struct acpi_spi_lookup *lookup = data;
+ struct spi_controller *ctlr = lookup->ctlr;
if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
struct acpi_resource_spi_serialbus *sb;
+ acpi_handle parent_handle;
+ acpi_status status;
sb = &ares->data.spi_serial_bus;
if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
+
+ status = acpi_get_handle(NULL,
+ sb->resource_source.string_ptr,
+ &parent_handle);
+
+ if (!status ||
+ ACPI_HANDLE(ctlr->dev.parent) != parent_handle)
+ return -ENODEV;
+
/*
* ACPI DeviceSelection numbering is handled by the
* host controller driver in Windows and can vary
@@ -1783,25 +1804,25 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
sb->device_selection);
if (cs < 0)
return cs;
- spi->chip_select = cs;
+ lookup->chip_select = cs;
} else {
- spi->chip_select = sb->device_selection;
+ lookup->chip_select = sb->device_selection;
}
- spi->max_speed_hz = sb->connection_speed;
+ lookup->max_speed_hz = sb->connection_speed;
if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
- spi->mode |= SPI_CPHA;
+ lookup->mode |= SPI_CPHA;
if (sb->clock_polarity == ACPI_SPI_START_HIGH)
- spi->mode |= SPI_CPOL;
+ lookup->mode |= SPI_CPOL;
if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
- spi->mode |= SPI_CS_HIGH;
+ lookup->mode |= SPI_CS_HIGH;
}
- } else if (spi->irq < 0) {
+ } else if (lookup->irq < 0) {
struct resource r;
if (acpi_dev_resource_interrupt(ares, 0, &r))
- spi->irq = r.start;
+ lookup->irq = r.start;
}
/* Always tell the ACPI core to skip this resource */
@@ -1811,7 +1832,9 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
static acpi_status acpi_register_spi_device(struct spi_controller *ctlr,
struct acpi_device *adev)
{
+ acpi_handle parent_handle = NULL;
struct list_head resource_list;
+ struct acpi_spi_lookup lookup;
struct spi_device *spi;
int ret;
@@ -1819,28 +1842,44 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr,
acpi_device_enumerated(adev))
return AE_OK;
- spi = spi_alloc_device(ctlr);
- if (!spi) {
- dev_err(&ctlr->dev, "failed to allocate SPI device for %s\n",
- dev_name(&adev->dev));
- return AE_NO_MEMORY;
- }
-
- ACPI_COMPANION_SET(&spi->dev, adev);
- spi->irq = -1;
+ lookup.ctlr = ctlr;
+ lookup.mode = 0;
+ lookup.bits_per_word = 0;
+ lookup.irq = -1;
INIT_LIST_HEAD(&resource_list);
ret = acpi_dev_get_resources(adev, &resource_list,
- acpi_spi_add_resource, spi);
+ acpi_spi_add_resource, &lookup);
acpi_dev_free_resource_list(&resource_list);
- acpi_spi_parse_apple_properties(spi);
+ if (ret < 0)
+ /* found SPI in _CRS but it points to another controller */
+ return AE_OK;
- if (ret < 0 || !spi->max_speed_hz) {
- spi_dev_put(spi);
+ if (!lookup.max_speed_hz &&
+ !ACPI_FAILURE(acpi_get_parent(adev->handle, &parent_handle)) &&
+ ACPI_HANDLE(ctlr->dev.parent) == parent_handle) {
+ /* Apple does not use _CRS but nested devices for SPI slaves */
+ acpi_spi_parse_apple_properties(adev, &lookup);
+ }
+
+ if (!lookup.max_speed_hz)
return AE_OK;
+
+ spi = spi_alloc_device(ctlr);
+ if (!spi) {
+ dev_err(&ctlr->dev, "failed to allocate SPI device for %s\n",
+ dev_name(&adev->dev));
+ return AE_NO_MEMORY;
}
+ ACPI_COMPANION_SET(&spi->dev, adev);
+ spi->max_speed_hz = lookup.max_speed_hz;
+ spi->mode = lookup.mode;
+ spi->irq = lookup.irq;
+ spi->bits_per_word = lookup.bits_per_word;
+ spi->chip_select = lookup.chip_select;
+
acpi_set_modalias(adev, acpi_device_hid(adev), spi->modalias,
sizeof(spi->modalias));
@@ -1872,6 +1911,8 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,
return acpi_register_spi_device(ctlr, adev);
}
+#define SPI_ACPI_ENUMERATE_MAX_DEPTH 32
+
static void acpi_register_spi_devices(struct spi_controller *ctlr)
{
acpi_status status;
@@ -1881,7 +1922,8 @@ static void acpi_register_spi_devices(struct spi_controller *ctlr)
if (!handle)
return;
- status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
+ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
+ SPI_ACPI_ENUMERATE_MAX_DEPTH,
acpi_spi_add_device, NULL, ctlr, NULL);
if (ACPI_FAILURE(status))
dev_warn(&ctlr->dev, "failed to enumerate SPI slaves\n");
--
2.27.0

View File

@ -0,0 +1,66 @@
From d6e11ded3fafb57845205b7392da6ea3257ac444 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Date: Wed, 19 Jun 2019 11:52:54 +0200
Subject: [PATCH 23/39] spi/acpi: fix incorrect ACPI parent check
mainline inclusion
from mainline-v5.3-rc1
commit b5e3cf410b486a2415ff09b12f3ef18aba9f53ff
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b5e3cf410b486a2415ff09b12f3ef18aba9f53ff
----------------------------------------------------------------------------
The ACPI device object parsing code for SPI slaves enumerates the
entire ACPI namespace to look for devices that refer to the master
in question via the 'resource_source' field in the 'SPISerialBus'
resource. If that field does not refer to a valid ACPI device or
if it refers to the wrong SPI master, we should disregard the
device.
Current, the valid device check is wrong, since it gets the
polarity of 'status' wrong. This could cause issues if the
'resource_source' field is bogus but parent_handle happens to
refer to the correct master (which is not entirely imaginary
since this code runs in a loop)
So test for ACPI_FAILURE() instead, to make the code more
self explanatory.
Fixes: 4c3c59544f33 ("spi/acpi: enumerate all SPI slaves in the namespace")
Reported-by: kbuild test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: andy.shevchenko@gmail.com
Cc: masahisa.kojima@linaro.org
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: linux-acpi@vger.kernel.org
Cc: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index c6e272edd806..59465736b574 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1788,7 +1788,7 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
sb->resource_source.string_ptr,
&parent_handle);
- if (!status ||
+ if (ACPI_FAILURE(status) ||
ACPI_HANDLE(ctlr->dev.parent) != parent_handle)
return -ENODEV;
--
2.27.0

View File

@ -0,0 +1,68 @@
From 0c9807ae12a27c3e2f1c4332b942a5b10106d0d9 Mon Sep 17 00:00:00 2001
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Date: Thu, 20 Jun 2019 14:36:49 +0200
Subject: [PATCH 24/39] spi/acpi: avoid spurious matches during slave
enumeration
mainline inclusion
from mainline-v5.3-rc1
commit b28944c6f6d3951f0c8f23f90c83ef741d30bfca
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b28944c6f6d3951f0c8f23f90c83ef741d30bfca
----------------------------------------------------------------------------
In the new SPI ACPI slave enumeration code, we use the value of
lookup.max_speed_khz as a flag to decide whether a match occurred.
However, doing so only makes sense if we initialize its value to
zero beforehand, or otherwise, random junk from the stack will
cause spurious matches.
So zero initialize the lookup struct fully, and only set the non-zero
members explicitly.
Fixes: 4c3c59544f33 ("spi/acpi: enumerate all SPI slaves in the namespace")
Cc: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: andy.shevchenko@gmail.com
Cc: masahisa.kojima@linaro.org
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Cc: linux-acpi@vger.kernel.org
Cc: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 59465736b574..69d569744ea1 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -1834,7 +1834,7 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr,
{
acpi_handle parent_handle = NULL;
struct list_head resource_list;
- struct acpi_spi_lookup lookup;
+ struct acpi_spi_lookup lookup = {};
struct spi_device *spi;
int ret;
@@ -1843,8 +1843,6 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr,
return AE_OK;
lookup.ctlr = ctlr;
- lookup.mode = 0;
- lookup.bits_per_word = 0;
lookup.irq = -1;
INIT_LIST_HEAD(&resource_list);
--
2.27.0

View File

@ -0,0 +1,373 @@
From 6304949808ee3a17a542a989c435f39c24afa697 Mon Sep 17 00:00:00 2001
From: John Garry <john.garry@huawei.com>
Date: Mon, 9 Dec 2019 22:08:09 +0800
Subject: [PATCH 25/39] spi: Add HiSilicon v3xx SPI NOR flash controller driver
mainline inclusion
from mainline-v5.6-rc1
commit a2ca53b52e007de81752bbb443d828f5950d6d04
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a2ca53b52e007de81752bbb443d828f5950d6d04
----------------------------------------------------------------------------
Add the driver for the HiSilicon v3xx SPI NOR flash controller, commonly
found in hi16xx chipsets.
This is a different controller than that in drivers/mtd/spi-nor/hisi-sfc.c;
indeed, the naming for that driver is poor, since it is really known as
FMC, and can support other memory technologies.
The driver module name is "hisi-sfc-v3xx", as recommended by HW designer,
being an attempt to provide a distinct name - v3xx being the unique
controller versioning.
Only ACPI firmware is supported.
DMA is not supported, and we just use polling mode for operation
completion notification.
The driver uses the SPI MEM OPs.
Signed-off-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1575900490-74467-3-git-send-email-john.garry@huawei.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
drivers/spi/Kconfig
---
drivers/spi/Kconfig | 9 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-hisi-sfc-v3xx.c | 284 ++++++++++++++++++++++++++++++++
3 files changed, 294 insertions(+)
create mode 100644 drivers/spi/spi-hisi-sfc-v3xx.c
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 7bfdf8d2cbf9..a6f1a5c2ea82 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -261,6 +261,15 @@ config SPI_HISI_KUNPENG
This driver can also be built as a module. If so, the module
will be called hisi-kunpeng-spi.
+config SPI_HISI_SFC_V3XX
+ tristate "HiSilicon SPI-NOR Flash Controller for Hi16XX chipsets"
+ depends on (ARM64 && ACPI) || COMPILE_TEST
+ depends on HAS_IOMEM
+ select CONFIG_MTD_SPI_NOR
+ help
+ This enables support for HiSilicon v3xx SPI-NOR flash controller
+ found in hi16xx chipsets.
+
config SPI_GPIO
tristate "GPIO-based bitbanging SPI Master"
depends on GPIOLIB || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 49c499d5e1a2..f1f733772e09 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_SPI_FSL_LPSPI) += spi-fsl-lpspi.o
obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o
obj-$(CONFIG_SPI_GPIO) += spi-gpio.o
obj-$(CONFIG_SPI_HISI_KUNPENG) += spi-hisi-kunpeng.o
+obj-$(CONFIG_SPI_HISI_SFC_V3XX) += spi-hisi-sfc-v3xx.o
obj-$(CONFIG_SPI_IMG_SPFI) += spi-img-spfi.o
obj-$(CONFIG_SPI_IMX) += spi-imx.o
obj-$(CONFIG_SPI_LANTIQ_SSC) += spi-lantiq-ssc.o
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
new file mode 100644
index 000000000000..4cf8fc80a7b7
--- /dev/null
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -0,0 +1,284 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// HiSilicon SPI NOR V3XX Flash Controller Driver for hi16xx chipsets
+//
+// Copyright (c) 2019 HiSilicon Technologies Co., Ltd.
+// Author: John Garry <john.garry@huawei.com>
+
+#include <linux/acpi.h>
+#include <linux/bitops.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
+
+#define HISI_SFC_V3XX_VERSION (0x1f8)
+
+#define HISI_SFC_V3XX_CMD_CFG (0x300)
+#define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9
+#define HISI_SFC_V3XX_CMD_CFG_RW_MSK BIT(8)
+#define HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK BIT(7)
+#define HISI_SFC_V3XX_CMD_CFG_DUMMY_CNT_OFF 4
+#define HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK BIT(3)
+#define HISI_SFC_V3XX_CMD_CFG_CS_SEL_OFF 1
+#define HISI_SFC_V3XX_CMD_CFG_START_MSK BIT(0)
+#define HISI_SFC_V3XX_CMD_INS (0x308)
+#define HISI_SFC_V3XX_CMD_ADDR (0x30c)
+#define HISI_SFC_V3XX_CMD_DATABUF0 (0x400)
+
+struct hisi_sfc_v3xx_host {
+ struct device *dev;
+ void __iomem *regbase;
+ int max_cmd_dword;
+};
+
+#define HISI_SFC_V3XX_WAIT_TIMEOUT_US 1000000
+#define HISI_SFC_V3XX_WAIT_POLL_INTERVAL_US 10
+
+static int hisi_sfc_v3xx_wait_cmd_idle(struct hisi_sfc_v3xx_host *host)
+{
+ u32 reg;
+
+ return readl_poll_timeout(host->regbase + HISI_SFC_V3XX_CMD_CFG, reg,
+ !(reg & HISI_SFC_V3XX_CMD_CFG_START_MSK),
+ HISI_SFC_V3XX_WAIT_POLL_INTERVAL_US,
+ HISI_SFC_V3XX_WAIT_TIMEOUT_US);
+}
+
+static int hisi_sfc_v3xx_adjust_op_size(struct spi_mem *mem,
+ struct spi_mem_op *op)
+{
+ struct spi_device *spi = mem->spi;
+ struct hisi_sfc_v3xx_host *host;
+ uintptr_t addr = (uintptr_t)op->data.buf.in;
+ int max_byte_count;
+
+ host = spi_controller_get_devdata(spi->master);
+
+ max_byte_count = host->max_cmd_dword * 4;
+
+ if (!IS_ALIGNED(addr, 4) && op->data.nbytes >= 4)
+ op->data.nbytes = 4 - (addr % 4);
+ else if (op->data.nbytes > max_byte_count)
+ op->data.nbytes = max_byte_count;
+
+ return 0;
+}
+
+/*
+ * memcpy_{to,from}io doesn't gurantee 32b accesses - which we require for the
+ * DATABUF registers -so use __io{read,write}32_copy when possible. For
+ * trailing bytes, copy them byte-by-byte from the DATABUF register, as we
+ * can't clobber outside the source/dest buffer.
+ *
+ * For efficient data read/write, we try to put any start 32b unaligned data
+ * into a separate transaction in hisi_sfc_v3xx_adjust_op_size().
+ */
+static void hisi_sfc_v3xx_read_databuf(struct hisi_sfc_v3xx_host *host,
+ u8 *to, unsigned int len)
+{
+ void __iomem *from;
+ int i;
+
+ from = host->regbase + HISI_SFC_V3XX_CMD_DATABUF0;
+
+ if (IS_ALIGNED((uintptr_t)to, 4)) {
+ int words = len / 4;
+
+ __ioread32_copy(to, from, words);
+
+ len -= words * 4;
+ if (len) {
+ u32 val;
+
+ to += words * 4;
+ from += words * 4;
+
+ val = __raw_readl(from);
+
+ for (i = 0; i < len; i++, val >>= 8, to++)
+ *to = (u8)val;
+ }
+ } else {
+ for (i = 0; i < DIV_ROUND_UP(len, 4); i++, from += 4) {
+ u32 val = __raw_readl(from);
+ int j;
+
+ for (j = 0; j < 4 && (j + (i * 4) < len);
+ to++, val >>= 8, j++)
+ *to = (u8)val;
+ }
+ }
+}
+
+static void hisi_sfc_v3xx_write_databuf(struct hisi_sfc_v3xx_host *host,
+ const u8 *from, unsigned int len)
+{
+ void __iomem *to;
+ int i;
+
+ to = host->regbase + HISI_SFC_V3XX_CMD_DATABUF0;
+
+ if (IS_ALIGNED((uintptr_t)from, 4)) {
+ int words = len / 4;
+
+ __iowrite32_copy(to, from, words);
+
+ len -= words * 4;
+ if (len) {
+ u32 val = 0;
+
+ to += words * 4;
+ from += words * 4;
+
+ for (i = 0; i < len; i++, from++)
+ val |= *from << i * 8;
+ __raw_writel(val, to);
+ }
+
+ } else {
+ for (i = 0; i < DIV_ROUND_UP(len, 4); i++, to += 4) {
+ u32 val = 0;
+ int j;
+
+ for (j = 0; j < 4 && (j + (i * 4) < len);
+ from++, j++)
+ val |= *from << j * 8;
+ __raw_writel(val, to);
+ }
+ }
+}
+
+static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
+ const struct spi_mem_op *op,
+ u8 chip_select)
+{
+ int ret, len = op->data.nbytes;
+ u32 config = 0;
+
+ if (op->addr.nbytes)
+ config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK;
+
+ if (op->data.dir != SPI_MEM_NO_DATA) {
+ config |= (len - 1) << HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF;
+ config |= HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK;
+ }
+
+ if (op->data.dir == SPI_MEM_DATA_OUT)
+ hisi_sfc_v3xx_write_databuf(host, op->data.buf.out, len);
+ else if (op->data.dir == SPI_MEM_DATA_IN)
+ config |= HISI_SFC_V3XX_CMD_CFG_RW_MSK;
+
+ config |= op->dummy.nbytes << HISI_SFC_V3XX_CMD_CFG_DUMMY_CNT_OFF |
+ chip_select << HISI_SFC_V3XX_CMD_CFG_CS_SEL_OFF |
+ HISI_SFC_V3XX_CMD_CFG_START_MSK;
+
+ writel(op->addr.val, host->regbase + HISI_SFC_V3XX_CMD_ADDR);
+ writel(op->cmd.opcode, host->regbase + HISI_SFC_V3XX_CMD_INS);
+
+ writel(config, host->regbase + HISI_SFC_V3XX_CMD_CFG);
+
+ ret = hisi_sfc_v3xx_wait_cmd_idle(host);
+ if (ret)
+ return ret;
+
+ if (op->data.dir == SPI_MEM_DATA_IN)
+ hisi_sfc_v3xx_read_databuf(host, op->data.buf.in, len);
+
+ return 0;
+}
+
+static int hisi_sfc_v3xx_exec_op(struct spi_mem *mem,
+ const struct spi_mem_op *op)
+{
+ struct hisi_sfc_v3xx_host *host;
+ struct spi_device *spi = mem->spi;
+ u8 chip_select = spi->chip_select;
+
+ host = spi_controller_get_devdata(spi->master);
+
+ return hisi_sfc_v3xx_generic_exec_op(host, op, chip_select);
+}
+
+static const struct spi_controller_mem_ops hisi_sfc_v3xx_mem_ops = {
+ .adjust_op_size = hisi_sfc_v3xx_adjust_op_size,
+ .exec_op = hisi_sfc_v3xx_exec_op,
+};
+
+static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct hisi_sfc_v3xx_host *host;
+ struct spi_controller *ctlr;
+ u32 version;
+ int ret;
+
+ ctlr = spi_alloc_master(&pdev->dev, sizeof(*host));
+ if (!ctlr)
+ return -ENOMEM;
+
+ ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD |
+ SPI_TX_DUAL | SPI_TX_QUAD;
+
+ host = spi_controller_get_devdata(ctlr);
+ host->dev = dev;
+
+ platform_set_drvdata(pdev, host);
+
+ host->regbase = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(host->regbase)) {
+ ret = PTR_ERR(host->regbase);
+ goto err_put_master;
+ }
+
+ ctlr->bus_num = -1;
+ ctlr->num_chipselect = 1;
+ ctlr->mem_ops = &hisi_sfc_v3xx_mem_ops;
+
+ version = readl(host->regbase + HISI_SFC_V3XX_VERSION);
+
+ switch (version) {
+ case 0x351:
+ host->max_cmd_dword = 64;
+ break;
+ default:
+ host->max_cmd_dword = 16;
+ break;
+ }
+
+ ret = devm_spi_register_controller(dev, ctlr);
+ if (ret)
+ goto err_put_master;
+
+ dev_info(&pdev->dev, "hw version 0x%x\n", version);
+
+ return 0;
+
+err_put_master:
+ spi_master_put(ctlr);
+ return ret;
+}
+
+#if IS_ENABLED(CONFIG_ACPI)
+static const struct acpi_device_id hisi_sfc_v3xx_acpi_ids[] = {
+ {"HISI0341", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(acpi, hisi_sfc_v3xx_acpi_ids);
+#endif
+
+static struct platform_driver hisi_sfc_v3xx_spi_driver = {
+ .driver = {
+ .name = "hisi-sfc-v3xx",
+ .acpi_match_table = ACPI_PTR(hisi_sfc_v3xx_acpi_ids),
+ },
+ .probe = hisi_sfc_v3xx_probe,
+};
+
+module_platform_driver(hisi_sfc_v3xx_spi_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Garry <john.garry@huawei.com>");
+MODULE_DESCRIPTION("HiSilicon SPI NOR V3XX Flash Controller Driver for hi16xx chipsets");
--
2.27.0

View File

@ -0,0 +1,79 @@
From 783917502bc47a28b0ee6b877bf56342bf6e4f9b Mon Sep 17 00:00:00 2001
From: John Garry <john.garry@huawei.com>
Date: Fri, 28 Feb 2020 23:18:49 +0800
Subject: [PATCH 26/39] spi: Allow SPI controller override device buswidth
mainline inclusion
from mainline-v5.7-rc1
commit ea23578611dce2eeaf31dcfe12cd7130cf3d1411
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ea23578611dce2eeaf31dcfe12cd7130cf3d1411
----------------------------------------------------------------------------
Currently ACPI firmware description for a SPI device does not have any
method to describe the data buswidth on the board.
So even through the controller and device may support higher modes than
standard SPI, it cannot be assumed that the board does - as such, that
device is limited to standard SPI in such a circumstance.
As a workaround, allow the controller driver supply buswidth override bits,
which are used inform the core code that the controller driver knows the
buswidth supported on that board for that device.
A host controller driver might know this info from DMI tables, for example.
Signed-off-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1582903131-160033-2-git-send-email-john.garry@huawei.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi.c | 4 +++-
include/linux/spi/spi.h | 3 +++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 69d569744ea1..a4f366a77072 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -474,6 +474,7 @@ struct spi_device *spi_alloc_device(struct spi_controller *ctlr)
spi->dev.bus = &spi_bus_type;
spi->dev.release = spidev_release;
spi->cs_gpio = -ENOENT;
+ spi->mode = ctlr->buswidth_override_bits;
spin_lock_init(&spi->statistics.lock);
@@ -1871,9 +1872,10 @@ static acpi_status acpi_register_spi_device(struct spi_controller *ctlr,
return AE_NO_MEMORY;
}
+
ACPI_COMPANION_SET(&spi->dev, adev);
spi->max_speed_hz = lookup.max_speed_hz;
- spi->mode = lookup.mode;
+ spi->mode |= lookup.mode;
spi->irq = lookup.irq;
spi->bits_per_word = lookup.bits_per_word;
spi->chip_select = lookup.chip_select;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 80d6bd6e46c5..843f187e046b 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -434,6 +434,9 @@ struct spi_controller {
/* spi_device.mode flags understood by this controller driver */
u16 mode_bits;
+ /* spi_device.mode flags override flags for this controller */
+ u32 buswidth_override_bits;
+
/* bitmask of supported bits_per_word for transfers */
u32 bits_per_word_mask;
#define SPI_BPW_MASK(bits) BIT((bits) - 1)
--
2.27.0

View File

@ -0,0 +1,91 @@
From 6c6f965aa6f867a5f3d8103df3734bcae9d18bd3 Mon Sep 17 00:00:00 2001
From: John Garry <john.garry@huawei.com>
Date: Fri, 28 Feb 2020 23:18:50 +0800
Subject: [PATCH 27/39] spi: HiSilicon v3xx: Properly set CMD_CONFIG for
Dual/Quad modes
mainline inclusion
from mainline-v5.7-rc1
commit 8fe21d6b347247227c349c9b2f7c462fae362af4
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8fe21d6b347247227c349c9b2f7c462fae362af4
----------------------------------------------------------------------------
The CMD_CONFIG register memory interface type field is not set configured
for Dual and Quad modes, so set appropriately.
This was not detected previously as we only ever operated in standard SPI
mode.
Signed-off-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1582903131-160033-3-git-send-email-john.garry@huawei.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 39 +++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index 4cf8fc80a7b7..8c2eea439d5b 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -17,6 +17,12 @@
#define HISI_SFC_V3XX_VERSION (0x1f8)
#define HISI_SFC_V3XX_CMD_CFG (0x300)
+#define HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT (1 << 17)
+#define HISI_SFC_V3XX_CMD_CFG_DUAL_IO (2 << 17)
+#define HISI_SFC_V3XX_CMD_CFG_FULL_DIO (3 << 17)
+#define HISI_SFC_V3XX_CMD_CFG_QUAD_IN_QUAD_OUT (5 << 17)
+#define HISI_SFC_V3XX_CMD_CFG_QUAD_IO (6 << 17)
+#define HISI_SFC_V3XX_CMD_CFG_FULL_QIO (7 << 17)
#define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9
#define HISI_SFC_V3XX_CMD_CFG_RW_MSK BIT(8)
#define HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK BIT(7)
@@ -161,6 +167,39 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
if (op->addr.nbytes)
config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK;
+ switch (op->data.buswidth) {
+ case 0 ... 1:
+ break;
+ case 2:
+ if (op->addr.buswidth <= 1) {
+ config |= HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT;
+ } else if (op->addr.buswidth == 2) {
+ if (op->cmd.buswidth <= 1)
+ config |= HISI_SFC_V3XX_CMD_CFG_DUAL_IO;
+ else if (op->cmd.buswidth == 2)
+ config |= HISI_SFC_V3XX_CMD_CFG_FULL_DIO;
+ else
+ return -EIO;
+ } else
+ return -EIO;
+ break;
+ case 4:
+ if (op->addr.buswidth <= 1) {
+ config |= HISI_SFC_V3XX_CMD_CFG_QUAD_IN_QUAD_OUT;
+ } else if (op->addr.buswidth == 4) {
+ if (op->cmd.buswidth <= 1)
+ config |= HISI_SFC_V3XX_CMD_CFG_QUAD_IO;
+ else if (op->cmd.buswidth == 4)
+ config |= HISI_SFC_V3XX_CMD_CFG_FULL_QIO;
+ else
+ return -EIO;
+ } else
+ return -EIO;
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
if (op->data.dir != SPI_MEM_NO_DATA) {
config |= (len - 1) << HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF;
config |= HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK;
--
2.27.0

View File

@ -0,0 +1,122 @@
From 9336c101918a51d00f6a5508cd5290be5c1596ee Mon Sep 17 00:00:00 2001
From: John Garry <john.garry@huawei.com>
Date: Fri, 28 Feb 2020 23:18:51 +0800
Subject: [PATCH 28/39] spi: HiSilicon v3xx: Use DMI quirk to set controller
buswidth override bits
mainline inclusion
from mainline-v5.7-rc1
commit 34e608b023e96f51b31274435b49c8ae61e2389f
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e608b023e96f51b31274435b49c8ae61e2389f
----------------------------------------------------------------------------
The Huawei D06 board (and variants) can support Quad mode of operation.
Since we have no current method in ACPI SPI bus device resource description
to describe this information, use DMI to detect the board, and set the
controller buswidth override bits.
Signed-off-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1582903131-160033-4-git-send-email-john.garry@huawei.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 56 ++++++++++++++++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index 8c2eea439d5b..c46812f004b7 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -7,6 +7,7 @@
#include <linux/acpi.h>
#include <linux/bitops.h>
+#include <linux/dmi.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -246,6 +247,44 @@ static const struct spi_controller_mem_ops hisi_sfc_v3xx_mem_ops = {
.exec_op = hisi_sfc_v3xx_exec_op,
};
+static int hisi_sfc_v3xx_buswidth_override_bits;
+
+/*
+ * ACPI FW does not allow us to currently set the device buswidth, so quirk it
+ * depending on the board.
+ */
+static int __init hisi_sfc_v3xx_dmi_quirk(const struct dmi_system_id *d)
+{
+ hisi_sfc_v3xx_buswidth_override_bits = SPI_RX_QUAD | SPI_TX_QUAD;
+
+ return 0;
+}
+
+static const struct dmi_system_id hisi_sfc_v3xx_dmi_quirk_table[] = {
+ {
+ .callback = hisi_sfc_v3xx_dmi_quirk,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Huawei"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "D06"),
+ },
+ },
+ {
+ .callback = hisi_sfc_v3xx_dmi_quirk,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Huawei"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TaiShan 2280 V2"),
+ },
+ },
+ {
+ .callback = hisi_sfc_v3xx_dmi_quirk,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Huawei"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "TaiShan 200 (Model 2280)"),
+ },
+ },
+ {}
+};
+
static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -261,6 +300,8 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
ctlr->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD |
SPI_TX_DUAL | SPI_TX_QUAD;
+ ctlr->buswidth_override_bits = hisi_sfc_v3xx_buswidth_override_bits;
+
host = spi_controller_get_devdata(ctlr);
host->dev = dev;
@@ -316,7 +357,20 @@ static struct platform_driver hisi_sfc_v3xx_spi_driver = {
.probe = hisi_sfc_v3xx_probe,
};
-module_platform_driver(hisi_sfc_v3xx_spi_driver);
+static int __init hisi_sfc_v3xx_spi_init(void)
+{
+ dmi_check_system(hisi_sfc_v3xx_dmi_quirk_table);
+
+ return platform_driver_register(&hisi_sfc_v3xx_spi_driver);
+}
+
+static void __exit hisi_sfc_v3xx_spi_exit(void)
+{
+ platform_driver_unregister(&hisi_sfc_v3xx_spi_driver);
+}
+
+module_init(hisi_sfc_v3xx_spi_init);
+module_exit(hisi_sfc_v3xx_spi_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("John Garry <john.garry@huawei.com>");
--
2.27.0

View File

@ -0,0 +1,88 @@
From 2863ac8e4dd2da305e6b3bbf4e653e57ea36af6b Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Fri, 17 Apr 2020 15:48:27 +0800
Subject: [PATCH 29/39] spi: hisi-sfc-v3xx: add error check after per operation
mainline inclusion
from mainline-v5.8-rc1
commit 59fc9ad5cb108bce18043281c7cf67f2b425d55d
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=59fc9ad5cb108bce18043281c7cf67f2b425d55d
----------------------------------------------------------------------------
The controller may receive instructions of accessing protected address,
or may perform failed page program. These operations will not succeed
and the controller will receive interrupts when such failure occur.
Previously we don't check the interrupts and return 0 even if such
operation fails.
Check the interrupts after per command and inform the user
if there is an error.
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Acked-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1587109707-23597-1-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index c46812f004b7..7b90ba2184ac 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -17,6 +17,11 @@
#define HISI_SFC_V3XX_VERSION (0x1f8)
+#define HISI_SFC_V3XX_INT_STAT (0x120)
+#define HISI_SFC_V3XX_INT_STAT_PP_ERR BIT(2)
+#define HISI_SFC_V3XX_INT_STAT_ADDR_IACCES BIT(5)
+#define HISI_SFC_V3XX_INT_CLR (0x12c)
+#define HISI_SFC_V3XX_INT_CLR_CLEAR (0xff)
#define HISI_SFC_V3XX_CMD_CFG (0x300)
#define HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT (1 << 17)
#define HISI_SFC_V3XX_CMD_CFG_DUAL_IO (2 << 17)
@@ -163,7 +168,7 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
u8 chip_select)
{
int ret, len = op->data.nbytes;
- u32 config = 0;
+ u32 int_stat, config = 0;
if (op->addr.nbytes)
config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK;
@@ -224,6 +229,25 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
if (ret)
return ret;
+ /*
+ * The interrupt status register indicates whether an error occurs
+ * after per operation. Check it, and clear the interrupts for
+ * next time judgement.
+ */
+ int_stat = readl(host->regbase + HISI_SFC_V3XX_INT_STAT);
+ writel(HISI_SFC_V3XX_INT_CLR_CLEAR,
+ host->regbase + HISI_SFC_V3XX_INT_CLR);
+
+ if (int_stat & HISI_SFC_V3XX_INT_STAT_ADDR_IACCES) {
+ dev_err(host->dev, "fail to access protected address\n");
+ return -EIO;
+ }
+
+ if (int_stat & HISI_SFC_V3XX_INT_STAT_PP_ERR) {
+ dev_err(host->dev, "page program operation failed\n");
+ return -EIO;
+ }
+
if (op->data.dir == SPI_MEM_DATA_IN)
hisi_sfc_v3xx_read_databuf(host, op->data.buf.in, len);
--
2.27.0

View File

@ -0,0 +1,46 @@
From 4d2691677028cbb0e588744dc738502c5d3f210a Mon Sep 17 00:00:00 2001
From: Joe Perches <joe@perches.com>
Date: Thu, 5 Mar 2020 07:15:53 -0800
Subject: [PATCH 30/39] spi: Remove CONFIG_ prefix from Kconfig select
mainline inclusion
from mainline-v5.7-rc1
commit e14572c52546c16e159c4c1814984843a119e823
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e14572c52546c16e159c4c1814984843a119e823
----------------------------------------------------------------------------
commit a2ca53b52e00 ("spi: Add HiSilicon v3xx SPI NOR flash
controller driver") likely inadvertently used a select statement
with a CONFIG_ prefix, remove the prefix.
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Joe Perches <joe@perches.com>
Acked-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/f8ac6b32a29b9a05b58a7e58ffe8b780642abbf1.camel@perches.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index a6f1a5c2ea82..4b4b8e4882bb 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -265,7 +265,7 @@ config SPI_HISI_SFC_V3XX
tristate "HiSilicon SPI-NOR Flash Controller for Hi16XX chipsets"
depends on (ARM64 && ACPI) || COMPILE_TEST
depends on HAS_IOMEM
- select CONFIG_MTD_SPI_NOR
+ select MTD_SPI_NOR
help
This enables support for HiSilicon v3xx SPI-NOR flash controller
found in hi16xx chipsets.
--
2.27.0

View File

@ -0,0 +1,178 @@
From 3a41ac28583128600bce37a94ba7716f55c51d23 Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Thu, 24 Sep 2020 20:24:27 +0800
Subject: [PATCH 31/39] spi: hisi-sfc-v3xx: factor out IO modes configuration
mainline inclusion
from mainline-v5.10-rc1
commit 2c8af6a59744b242a193118c799a45621476f8ed
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2c8af6a59744b242a193118c799a45621476f8ed
----------------------------------------------------------------------------
Factor IO modes configuration out of hisi_sfc_v3xx_generic_exec_op()
using an IO modes lookup table. This will make the process a bit clearer
and reduce the cyclomatic complexity. Simplify the IO mode definition
macros a little bit as well.
Also add the .supports_op() method for the controller mem ops, in order
to avoid OOB access.
Acked-by: John Garry <john.garry@huawei.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/1600950270-52536-2-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
drivers/spi/spi-hisi-sfc-v3xx.c
---
drivers/spi/spi-hisi-sfc-v3xx.c | 94 ++++++++++++++++++++-------------
1 file changed, 56 insertions(+), 38 deletions(-)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index 7b90ba2184ac..9203a7c06aaa 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -23,12 +23,6 @@
#define HISI_SFC_V3XX_INT_CLR (0x12c)
#define HISI_SFC_V3XX_INT_CLR_CLEAR (0xff)
#define HISI_SFC_V3XX_CMD_CFG (0x300)
-#define HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT (1 << 17)
-#define HISI_SFC_V3XX_CMD_CFG_DUAL_IO (2 << 17)
-#define HISI_SFC_V3XX_CMD_CFG_FULL_DIO (3 << 17)
-#define HISI_SFC_V3XX_CMD_CFG_QUAD_IN_QUAD_OUT (5 << 17)
-#define HISI_SFC_V3XX_CMD_CFG_QUAD_IO (6 << 17)
-#define HISI_SFC_V3XX_CMD_CFG_FULL_QIO (7 << 17)
#define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9
#define HISI_SFC_V3XX_CMD_CFG_RW_MSK BIT(8)
#define HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK BIT(7)
@@ -40,6 +34,33 @@
#define HISI_SFC_V3XX_CMD_ADDR (0x30c)
#define HISI_SFC_V3XX_CMD_DATABUF0 (0x400)
+/* IO Mode definition in HISI_SFC_V3XX_CMD_CFG */
+#define HISI_SFC_V3XX_STD (0 << 17)
+#define HISI_SFC_V3XX_DIDO (1 << 17)
+#define HISI_SFC_V3XX_DIO (2 << 17)
+#define HISI_SFC_V3XX_FULL_DIO (3 << 17)
+#define HISI_SFC_V3XX_QIQO (5 << 17)
+#define HISI_SFC_V3XX_QIO (6 << 17)
+#define HISI_SFC_V3XX_FULL_QIO (7 << 17)
+
+/*
+ * The IO modes lookup table. hisi_sfc_v3xx_io_modes[(z - 1) / 2][y / 2][x / 2]
+ * stands for x-y-z mode, as described in SFDP terminology. -EIO indicates
+ * an invalid mode.
+ */
+static const int hisi_sfc_v3xx_io_modes[2][3][3] = {
+ {
+ { HISI_SFC_V3XX_DIDO, HISI_SFC_V3XX_DIDO, HISI_SFC_V3XX_DIDO },
+ { HISI_SFC_V3XX_DIO, HISI_SFC_V3XX_FULL_DIO, -EIO },
+ { -EIO, -EIO, -EIO },
+ },
+ {
+ { HISI_SFC_V3XX_QIQO, HISI_SFC_V3XX_QIQO, HISI_SFC_V3XX_QIQO },
+ { -EIO, -EIO, -EIO },
+ { HISI_SFC_V3XX_QIO, -EIO, HISI_SFC_V3XX_FULL_QIO },
+ },
+};
+
struct hisi_sfc_v3xx_host {
struct device *dev;
void __iomem *regbase;
@@ -79,6 +100,20 @@ static int hisi_sfc_v3xx_adjust_op_size(struct spi_mem *mem,
return 0;
}
+/*
+ * The controller only supports Standard SPI mode, Duall mode and
+ * Quad mode. Double sanitize the ops here to avoid OOB access.
+ */
+static bool hisi_sfc_v3xx_supports_op(struct spi_mem *mem,
+ const struct spi_mem_op *op)
+{
+ if (op->data.buswidth > 4 || op->dummy.buswidth > 4 ||
+ op->addr.buswidth > 4 || op->cmd.buswidth > 4)
+ return false;
+
+ return spi_mem_default_supports_op(mem, op);
+}
+
/*
* memcpy_{to,from}io doesn't gurantee 32b accesses - which we require for the
* DATABUF registers -so use __io{read,write}32_copy when possible. For
@@ -167,44 +202,26 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
const struct spi_mem_op *op,
u8 chip_select)
{
- int ret, len = op->data.nbytes;
+ int ret = 0, len = op->data.nbytes, buswidth_mode;
u32 int_stat, config = 0;
if (op->addr.nbytes)
config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK;
- switch (op->data.buswidth) {
- case 0 ... 1:
- break;
- case 2:
- if (op->addr.buswidth <= 1) {
- config |= HISI_SFC_V3XX_CMD_CFG_DUAL_IN_DUAL_OUT;
- } else if (op->addr.buswidth == 2) {
- if (op->cmd.buswidth <= 1)
- config |= HISI_SFC_V3XX_CMD_CFG_DUAL_IO;
- else if (op->cmd.buswidth == 2)
- config |= HISI_SFC_V3XX_CMD_CFG_FULL_DIO;
- else
- return -EIO;
- } else
- return -EIO;
- break;
- case 4:
- if (op->addr.buswidth <= 1) {
- config |= HISI_SFC_V3XX_CMD_CFG_QUAD_IN_QUAD_OUT;
- } else if (op->addr.buswidth == 4) {
- if (op->cmd.buswidth <= 1)
- config |= HISI_SFC_V3XX_CMD_CFG_QUAD_IO;
- else if (op->cmd.buswidth == 4)
- config |= HISI_SFC_V3XX_CMD_CFG_FULL_QIO;
- else
- return -EIO;
- } else
- return -EIO;
- break;
- default:
- return -EOPNOTSUPP;
+ if (op->data.buswidth == 0 || op->data.buswidth == 1) {
+ buswidth_mode = HISI_SFC_V3XX_STD;
+ } else {
+ int data_idx, addr_idx, cmd_idx;
+
+ data_idx = (op->data.buswidth - 1) / 2;
+ addr_idx = op->addr.buswidth / 2;
+ cmd_idx = op->cmd.buswidth / 2;
+ buswidth_mode =
+ hisi_sfc_v3xx_io_modes[data_idx][addr_idx][cmd_idx];
}
+ if (buswidth_mode < 0)
+ return buswidth_mode;
+ config |= buswidth_mode;
if (op->data.dir != SPI_MEM_NO_DATA) {
config |= (len - 1) << HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF;
@@ -268,6 +285,7 @@ static int hisi_sfc_v3xx_exec_op(struct spi_mem *mem,
static const struct spi_controller_mem_ops hisi_sfc_v3xx_mem_ops = {
.adjust_op_size = hisi_sfc_v3xx_adjust_op_size,
+ .supports_op = hisi_sfc_v3xx_supports_op,
.exec_op = hisi_sfc_v3xx_exec_op,
};
--
2.27.0

View File

@ -0,0 +1,104 @@
From 1092dc3f08140ec688913cc84267e4f7ef466efe Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Thu, 24 Sep 2020 20:24:28 +0800
Subject: [PATCH 32/39] spi: hisi-sfc-v3xx: factor out bus config and transfer
functions
mainline inclusion
from mainline-v5.10-rc1
commit f6d2737720d6f6e5f4825b7203ad8b5cfcf9906c
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f6d2737720d6f6e5f4825b7203ad8b5cfcf9906c
----------------------------------------------------------------------------
In hisi_sfc_v3xx_generic_exec_op(), we will write the data to the buffer,
configure and start the transfer, read the data to the buffer and check
whether occurs an error. Factor out the config and transfer start codes
as individual functions, to make the process a bit clearer.
Acked-by: John Garry <john.garry@huawei.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/1600950270-52536-3-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 37 +++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 9 deletions(-)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index 9203a7c06aaa..02b18fdd1a50 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -198,12 +198,12 @@ static void hisi_sfc_v3xx_write_databuf(struct hisi_sfc_v3xx_host *host,
}
}
-static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
- const struct spi_mem_op *op,
- u8 chip_select)
+static int hisi_sfc_v3xx_start_bus(struct hisi_sfc_v3xx_host *host,
+ const struct spi_mem_op *op,
+ u8 chip_select)
{
- int ret = 0, len = op->data.nbytes, buswidth_mode;
- u32 int_stat, config = 0;
+ int len = op->data.nbytes, buswidth_mode;
+ u32 config = 0;
if (op->addr.nbytes)
config |= HISI_SFC_V3XX_CMD_CFG_ADDR_EN_MSK;
@@ -228,9 +228,7 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
config |= HISI_SFC_V3XX_CMD_CFG_DATA_EN_MSK;
}
- if (op->data.dir == SPI_MEM_DATA_OUT)
- hisi_sfc_v3xx_write_databuf(host, op->data.buf.out, len);
- else if (op->data.dir == SPI_MEM_DATA_IN)
+ if (op->data.dir == SPI_MEM_DATA_IN)
config |= HISI_SFC_V3XX_CMD_CFG_RW_MSK;
config |= op->dummy.nbytes << HISI_SFC_V3XX_CMD_CFG_DUMMY_CNT_OFF |
@@ -242,6 +240,25 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
writel(config, host->regbase + HISI_SFC_V3XX_CMD_CFG);
+ return 0;
+}
+
+static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
+ const struct spi_mem_op *op,
+ u8 chip_select)
+{
+ u32 int_stat;
+ int ret;
+
+ if (op->data.dir == SPI_MEM_DATA_OUT)
+ hisi_sfc_v3xx_write_databuf(host,
+ op->data.buf.out,
+ op->data.nbytes);
+
+ ret = hisi_sfc_v3xx_start_bus(host, op, chip_select);
+ if (ret)
+ return ret;
+
ret = hisi_sfc_v3xx_wait_cmd_idle(host);
if (ret)
return ret;
@@ -266,7 +283,9 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
}
if (op->data.dir == SPI_MEM_DATA_IN)
- hisi_sfc_v3xx_read_databuf(host, op->data.buf.in, len);
+ hisi_sfc_v3xx_read_databuf(host,
+ op->data.buf.in,
+ op->data.nbytes);
return 0;
}
--
2.27.0

View File

@ -0,0 +1,80 @@
From 91bf6de1a7690174b9dad2c8188c7a1fd78f5d6d Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Thu, 24 Sep 2020 20:24:29 +0800
Subject: [PATCH 33/39] spi: hisi-sfc-v3xx: factor out the bit definition of
interrupt register
mainline inclusion
from mainline-v5.10-rc1
commit aac6edff843871d7d732a6aa6f495b9eb1dea83a
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=aac6edff843871d7d732a6aa6f495b9eb1dea83a
----------------------------------------------------------------------------
The definition of the register field in the interrupt corresponding
registers are the same. So factor them out to public place.
Acked-by: John Garry <john.garry@huawei.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/1600950270-52536-4-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index 02b18fdd1a50..fbb9b837655c 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -18,10 +18,7 @@
#define HISI_SFC_V3XX_VERSION (0x1f8)
#define HISI_SFC_V3XX_INT_STAT (0x120)
-#define HISI_SFC_V3XX_INT_STAT_PP_ERR BIT(2)
-#define HISI_SFC_V3XX_INT_STAT_ADDR_IACCES BIT(5)
#define HISI_SFC_V3XX_INT_CLR (0x12c)
-#define HISI_SFC_V3XX_INT_CLR_CLEAR (0xff)
#define HISI_SFC_V3XX_CMD_CFG (0x300)
#define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9
#define HISI_SFC_V3XX_CMD_CFG_RW_MSK BIT(8)
@@ -34,6 +31,13 @@
#define HISI_SFC_V3XX_CMD_ADDR (0x30c)
#define HISI_SFC_V3XX_CMD_DATABUF0 (0x400)
+/* Common definition of interrupt bit masks */
+#define HISI_SFC_V3XX_INT_MASK_ALL (0x1ff) /* all the masks */
+#define HISI_SFC_V3XX_INT_MASK_PP_ERR BIT(2) /* page progrom error */
+#define HISI_SFC_V3XX_INT_MASK_IACCES BIT(5) /* error visiting inaccessible/
+ * protected address
+ */
+
/* IO Mode definition in HISI_SFC_V3XX_CMD_CFG */
#define HISI_SFC_V3XX_STD (0 << 17)
#define HISI_SFC_V3XX_DIDO (1 << 17)
@@ -269,15 +273,15 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
* next time judgement.
*/
int_stat = readl(host->regbase + HISI_SFC_V3XX_INT_STAT);
- writel(HISI_SFC_V3XX_INT_CLR_CLEAR,
+ writel(HISI_SFC_V3XX_INT_MASK_ALL,
host->regbase + HISI_SFC_V3XX_INT_CLR);
- if (int_stat & HISI_SFC_V3XX_INT_STAT_ADDR_IACCES) {
+ if (int_stat & HISI_SFC_V3XX_INT_MASK_IACCES) {
dev_err(host->dev, "fail to access protected address\n");
return -EIO;
}
- if (int_stat & HISI_SFC_V3XX_INT_STAT_PP_ERR) {
+ if (int_stat & HISI_SFC_V3XX_INT_MASK_PP_ERR) {
dev_err(host->dev, "page program operation failed\n");
return -EIO;
}
--
2.27.0

View File

@ -0,0 +1,244 @@
From 34f366184657baff168c7b6e8f219585a7cd5e14 Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Thu, 24 Sep 2020 20:24:30 +0800
Subject: [PATCH 34/39] spi: hisi-sfc-v3xx: add support for IRQ mode
mainline inclusion
from mainline-v5.10-rc1
commit b1dd565124bea0f3ecde87336b48c5d0e98cd5bc
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b1dd565124bea0f3ecde87336b48c5d0e98cd5bc
----------------------------------------------------------------------------
The controller can work with interrupts, so add support for it.
Then we can work under IRQ mode or Poll mode now, if firmware
doesn't declare the IRQ support, it will fall back to Poll mode.
Acked-by: John Garry <john.garry@huawei.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/1600950270-52536-5-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 137 +++++++++++++++++++++++++++-----
1 file changed, 115 insertions(+), 22 deletions(-)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index fbb9b837655c..3e695784abf4 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -7,7 +7,9 @@
#include <linux/acpi.h>
#include <linux/bitops.h>
+#include <linux/completion.h>
#include <linux/dmi.h>
+#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/platform_device.h>
@@ -17,7 +19,9 @@
#define HISI_SFC_V3XX_VERSION (0x1f8)
-#define HISI_SFC_V3XX_INT_STAT (0x120)
+#define HISI_SFC_V3XX_RAW_INT_STAT (0x120)
+#define HISI_SFC_V3XX_INT_STAT (0x124)
+#define HISI_SFC_V3XX_INT_MASK (0x128)
#define HISI_SFC_V3XX_INT_CLR (0x12c)
#define HISI_SFC_V3XX_CMD_CFG (0x300)
#define HISI_SFC_V3XX_CMD_CFG_DATA_CNT_OFF 9
@@ -33,6 +37,7 @@
/* Common definition of interrupt bit masks */
#define HISI_SFC_V3XX_INT_MASK_ALL (0x1ff) /* all the masks */
+#define HISI_SFC_V3XX_INT_MASK_CPLT BIT(0) /* command execution complete */
#define HISI_SFC_V3XX_INT_MASK_PP_ERR BIT(2) /* page progrom error */
#define HISI_SFC_V3XX_INT_MASK_IACCES BIT(5) /* error visiting inaccessible/
* protected address
@@ -69,8 +74,64 @@ struct hisi_sfc_v3xx_host {
struct device *dev;
void __iomem *regbase;
int max_cmd_dword;
+ struct completion *completion;
+ int irq;
};
+static void hisi_sfc_v3xx_disable_int(struct hisi_sfc_v3xx_host *host)
+{
+ writel(0, host->regbase + HISI_SFC_V3XX_INT_MASK);
+}
+
+static void hisi_sfc_v3xx_enable_int(struct hisi_sfc_v3xx_host *host)
+{
+ writel(HISI_SFC_V3XX_INT_MASK_ALL,
+ host->regbase + HISI_SFC_V3XX_INT_MASK);
+}
+
+static void hisi_sfc_v3xx_clear_int(struct hisi_sfc_v3xx_host *host)
+{
+ writel(HISI_SFC_V3XX_INT_MASK_ALL,
+ host->regbase + HISI_SFC_V3XX_INT_CLR);
+}
+
+/*
+ * The interrupt status register indicates whether an error occurs
+ * after per operation. Check it, and clear the interrupts for
+ * next time judgement.
+ */
+static int hisi_sfc_v3xx_handle_completion(struct hisi_sfc_v3xx_host *host)
+{
+ u32 reg;
+
+ reg = readl(host->regbase + HISI_SFC_V3XX_RAW_INT_STAT);
+ hisi_sfc_v3xx_clear_int(host);
+
+ if (reg & HISI_SFC_V3XX_INT_MASK_IACCES) {
+ dev_err(host->dev, "fail to access protected address\n");
+ return -EIO;
+ }
+
+ if (reg & HISI_SFC_V3XX_INT_MASK_PP_ERR) {
+ dev_err(host->dev, "page program operation failed\n");
+ return -EIO;
+ }
+
+ /*
+ * The other bits of the interrupt registers is not currently
+ * used and probably not be triggered in this driver. When it
+ * happens, we regard it as an unsupported error here.
+ */
+ if (!(reg & HISI_SFC_V3XX_INT_MASK_CPLT)) {
+ dev_err(host->dev,
+ "unsupported error occurred, status=0x%x\n",
+ reg);
+ return -EIO;
+ }
+
+ return 0;
+}
+
#define HISI_SFC_V3XX_WAIT_TIMEOUT_US 1000000
#define HISI_SFC_V3XX_WAIT_POLL_INTERVAL_US 10
@@ -251,9 +312,14 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
const struct spi_mem_op *op,
u8 chip_select)
{
- u32 int_stat;
+ DECLARE_COMPLETION_ONSTACK(done);
int ret;
+ if (host->irq) {
+ host->completion = &done;
+ hisi_sfc_v3xx_enable_int(host);
+ }
+
if (op->data.dir == SPI_MEM_DATA_OUT)
hisi_sfc_v3xx_write_databuf(host,
op->data.buf.out,
@@ -263,28 +329,21 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
if (ret)
return ret;
- ret = hisi_sfc_v3xx_wait_cmd_idle(host);
- if (ret)
- return ret;
-
- /*
- * The interrupt status register indicates whether an error occurs
- * after per operation. Check it, and clear the interrupts for
- * next time judgement.
- */
- int_stat = readl(host->regbase + HISI_SFC_V3XX_INT_STAT);
- writel(HISI_SFC_V3XX_INT_MASK_ALL,
- host->regbase + HISI_SFC_V3XX_INT_CLR);
+ if (host->irq) {
+ ret = wait_for_completion_timeout(host->completion,
+ usecs_to_jiffies(HISI_SFC_V3XX_WAIT_TIMEOUT_US));
+ if (!ret)
+ ret = -ETIMEDOUT;
+ else
+ ret = 0;
- if (int_stat & HISI_SFC_V3XX_INT_MASK_IACCES) {
- dev_err(host->dev, "fail to access protected address\n");
- return -EIO;
+ hisi_sfc_v3xx_disable_int(host);
+ host->completion = NULL;
+ } else {
+ ret = hisi_sfc_v3xx_wait_cmd_idle(host);
}
-
- if (int_stat & HISI_SFC_V3XX_INT_MASK_PP_ERR) {
- dev_err(host->dev, "page program operation failed\n");
+ if (hisi_sfc_v3xx_handle_completion(host) || ret)
return -EIO;
- }
if (op->data.dir == SPI_MEM_DATA_IN)
hisi_sfc_v3xx_read_databuf(host,
@@ -312,6 +371,17 @@ static const struct spi_controller_mem_ops hisi_sfc_v3xx_mem_ops = {
.exec_op = hisi_sfc_v3xx_exec_op,
};
+static irqreturn_t hisi_sfc_v3xx_isr(int irq, void *data)
+{
+ struct hisi_sfc_v3xx_host *host = data;
+
+ hisi_sfc_v3xx_disable_int(host);
+
+ complete(host->completion);
+
+ return IRQ_HANDLED;
+}
+
static int hisi_sfc_v3xx_buswidth_override_bits;
/*
@@ -378,6 +448,28 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
goto err_put_master;
}
+ host->irq = platform_get_irq(pdev, 0);
+ if (host->irq == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto err_put_master;
+ }
+
+ hisi_sfc_v3xx_disable_int(host);
+
+ if (host->irq > 0) {
+ ret = devm_request_irq(dev, host->irq, hisi_sfc_v3xx_isr, 0,
+ "hisi-sfc-v3xx", host);
+
+ if (ret) {
+ dev_err(dev,
+ "failed to request irq%d, ret = %d\n",
+ host->irq, ret);
+ host->irq = 0;
+ }
+ } else {
+ host->irq = 0;
+ }
+
ctlr->bus_num = -1;
ctlr->num_chipselect = 1;
ctlr->mem_ops = &hisi_sfc_v3xx_mem_ops;
@@ -397,7 +489,8 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
if (ret)
goto err_put_master;
- dev_info(&pdev->dev, "hw version 0x%x\n", version);
+ dev_info(&pdev->dev, "hw version 0x%x, %s mode.\n",
+ version, host->irq ? "irq" : "polling");
return 0;
--
2.27.0

View File

@ -0,0 +1,62 @@
From c09b5df3383e9a19a8a5b011c1bd7b902795b561 Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Thu, 8 Dec 2022 21:45:24 +0800
Subject: [PATCH 35/39] spi: hisi-sfc-v3xx: extend version checking
compatibility
mainline inclusion
from mainline-v5.12-rc1
commit 566c6120f095be74862bed35f557f797478abade
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=566c6120f095be74862bed35f557f797478abade
--------------------------------------------------------------------------
Currently we use concrete version to determine the max_cmd_dword.
New entries should be added for compatible hardwares of new version
or on new platform, otherwise the device will use 16 dwords instead
of 64 even if it supports, which will degrade the performance.
This will decrease the compatibility and the maintainability.
Drop the switch-case statement of the version checking. Only version
less than 0x351 supports maximum 16 command dwords.
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Acked-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1610526716-14882-1-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
Reviewed-by: Yicong Yang <yangyicong@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index 3e695784abf4..e679321c7e23 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -476,14 +476,10 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
version = readl(host->regbase + HISI_SFC_V3XX_VERSION);
- switch (version) {
- case 0x351:
+ if (version >= 0x351)
host->max_cmd_dword = 64;
- break;
- default:
+ else
host->max_cmd_dword = 16;
- break;
- }
ret = devm_spi_register_controller(dev, ctlr);
if (ret)
--
2.27.0

View File

@ -0,0 +1,104 @@
From a009f74ef5b6cf1953abd034da40e4ba27e7e1a1 Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Thu, 8 Dec 2022 21:45:25 +0800
Subject: [PATCH 36/39] spi: hisi-sfc-v3xx: add address mode check
mainline inclusion
from mainline-v5.12-rc1
commit 6d2386e36440165da782dbc5c0de40f31665e108
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6d2386e36440165da782dbc5c0de40f31665e108
--------------------------------------------------------------------------
The address mode is either 3 or 4 for the controller, which is configured
by the firmware and cannot be modified in the OS driver. Get the
firmware configuration and add address mode check in the .supports_op()
to block invalid operations.
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Acked-by: John Garry <john.garry@huawei.com>
Link: https://lore.kernel.org/r/1611740450-47975-3-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
Reviewed-by: Yicong Yang <yangyicong@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index e679321c7e23..3cb6735aaf34 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -19,6 +19,8 @@
#define HISI_SFC_V3XX_VERSION (0x1f8)
+#define HISI_SFC_V3XX_GLB_CFG (0x100)
+#define HISI_SFC_V3XX_GLB_CFG_CS0_ADDR_MODE BIT(2)
#define HISI_SFC_V3XX_RAW_INT_STAT (0x120)
#define HISI_SFC_V3XX_INT_STAT (0x124)
#define HISI_SFC_V3XX_INT_MASK (0x128)
@@ -75,6 +77,7 @@ struct hisi_sfc_v3xx_host {
void __iomem *regbase;
int max_cmd_dword;
struct completion *completion;
+ u8 address_mode;
int irq;
};
@@ -172,10 +175,18 @@ static int hisi_sfc_v3xx_adjust_op_size(struct spi_mem *mem,
static bool hisi_sfc_v3xx_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
+ struct spi_device *spi = mem->spi;
+ struct hisi_sfc_v3xx_host *host;
+
+ host = spi_controller_get_devdata(spi->master);
+
if (op->data.buswidth > 4 || op->dummy.buswidth > 4 ||
op->addr.buswidth > 4 || op->cmd.buswidth > 4)
return false;
+ if (op->addr.nbytes != host->address_mode && op->addr.nbytes)
+ return false;
+
return spi_mem_default_supports_op(mem, op);
}
@@ -425,7 +436,7 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct hisi_sfc_v3xx_host *host;
struct spi_controller *ctlr;
- u32 version;
+ u32 version, glb_config;
int ret;
ctlr = spi_alloc_master(&pdev->dev, sizeof(*host));
@@ -474,6 +485,18 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
ctlr->num_chipselect = 1;
ctlr->mem_ops = &hisi_sfc_v3xx_mem_ops;
+ /*
+ * The address mode of the controller is either 3 or 4,
+ * which is indicated by the address mode bit in
+ * the global config register. The register is read only
+ * for the OS driver.
+ */
+ glb_config = readl(host->regbase + HISI_SFC_V3XX_GLB_CFG);
+ if (glb_config & HISI_SFC_V3XX_GLB_CFG_CS0_ADDR_MODE)
+ host->address_mode = 4;
+ else
+ host->address_mode = 3;
+
version = readl(host->regbase + HISI_SFC_V3XX_VERSION);
if (version >= 0x351)
--
2.27.0

View File

@ -0,0 +1,47 @@
From 6aca11b49d76afb6bed69e0d8714744ee52b203b Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Thu, 8 Dec 2022 21:45:26 +0800
Subject: [PATCH 37/39] spi: hisi-sfc-v3xx: fix potential irq race condition
mainline inclusion
from mainline-v5.13-rc1
commit 4c84e42d29afa3dce201a4db747db2a5ba404604
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4c84e42d29afa3dce201a4db747db2a5ba404604
--------------------------------------------------------------------------
We mask the irq when the command completion is timeout. This won't
stop the already running irq handler. Use sychronize_irq() after
we mask the irq, to make sure there is no running handler.
Acked-by: John Garry <john.garry@huawei.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/1618228708-37949-2-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
Reviewed-by: Yicong Yang <yangyicong@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index 3cb6735aaf34..2636bf6be06f 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -349,6 +349,7 @@ static int hisi_sfc_v3xx_generic_exec_op(struct hisi_sfc_v3xx_host *host,
ret = 0;
hisi_sfc_v3xx_disable_int(host);
+ synchronize_irq(host->irq);
host->completion = NULL;
} else {
ret = hisi_sfc_v3xx_wait_cmd_idle(host);
--
2.27.0

View File

@ -0,0 +1,80 @@
From 06d413fe5831dcc0a9095c08eb5c0463b2343556 Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Thu, 8 Dec 2022 21:45:27 +0800
Subject: [PATCH 38/39] spi: hisi-sfc-v3xx: drop unnecessary ACPI_PTR and
related ifendif protection
mainline inclusion
from mainline-v5.13-rc1
commit 4a46f88681ca514f9cb33b39312d0ec4e2ec84da
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
CVE: NA
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4a46f88681ca514f9cb33b39312d0ec4e2ec84da
--------------------------------------------------------------------------
We use ACPI_PTR() and related ifendif protection for the id table.
This is unnecessary as the struct acpi_device_id is defined in
mod_devicetable.h and doesn't rely on ACPI. The driver doesn't
use any ACPI apis, so it can be compiled in the ACPI=n case
with no warnings.
So remove the ACPI_PTR and related ifendif protection, also
replace the header acpi.h with mod_devicetable.h.
Acked-by: John Garry <john.garry@huawei.com>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Link: https://lore.kernel.org/r/1618228708-37949-3-git-send-email-yangyicong@hisilicon.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
Reviewed-by: Yicong Yang <yangyicong@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
---
drivers/spi/spi-hisi-sfc-v3xx.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-hisi-sfc-v3xx.c b/drivers/spi/spi-hisi-sfc-v3xx.c
index 2636bf6be06f..2946604c5efd 100644
--- a/drivers/spi/spi-hisi-sfc-v3xx.c
+++ b/drivers/spi/spi-hisi-sfc-v3xx.c
@@ -5,13 +5,13 @@
// Copyright (c) 2019 HiSilicon Technologies Co., Ltd.
// Author: John Garry <john.garry@huawei.com>
-#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/completion.h>
#include <linux/dmi.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/spi/spi.h>
@@ -519,18 +519,16 @@ static int hisi_sfc_v3xx_probe(struct platform_device *pdev)
return ret;
}
-#if IS_ENABLED(CONFIG_ACPI)
static const struct acpi_device_id hisi_sfc_v3xx_acpi_ids[] = {
{"HISI0341", 0},
{}
};
MODULE_DEVICE_TABLE(acpi, hisi_sfc_v3xx_acpi_ids);
-#endif
static struct platform_driver hisi_sfc_v3xx_spi_driver = {
.driver = {
.name = "hisi-sfc-v3xx",
- .acpi_match_table = ACPI_PTR(hisi_sfc_v3xx_acpi_ids),
+ .acpi_match_table = hisi_sfc_v3xx_acpi_ids,
},
.probe = hisi_sfc_v3xx_probe,
};
--
2.27.0

View File

@ -0,0 +1,40 @@
From 573abc0cb48c35eb8d931e0cf4a76346a5b2a3d4 Mon Sep 17 00:00:00 2001
From: Yicong Yang <yangyicong@hisilicon.com>
Date: Fri, 26 Nov 2021 16:26:59 +0800
Subject: [PATCH 39/39] config: arm64: Build HiSilicon SPI/SFC driver as module
driver inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8CSBP
------------------------------------------------------------------------
Build HiSilicon SPI/SFC driver as module.
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Reviewed-by: Jay Fang <f.fangjian@huawei.com>
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
Conflicts:
arch/arm64/configs/openeuler_defconfig
---
arch/arm64/configs/openeuler_defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
index b89c386c1bc7..2c81e9dd3cab 100644
--- a/arch/arm64/configs/openeuler_defconfig
+++ b/arch/arm64/configs/openeuler_defconfig
@@ -3199,6 +3199,8 @@ CONFIG_SPI_DESIGNWARE=y
CONFIG_SPI_DW_PCI=m
# CONFIG_SPI_DW_MID_DMA is not set
CONFIG_SPI_DW_MMIO=m
+CONFIG_SPI_HISI_KUNPENG=m
+CONFIG_SPI_HISI_SFC_V3XX=m
# CONFIG_SPI_GPIO is not set
# CONFIG_SPI_FSL_SPI is not set
# CONFIG_SPI_OC_TINY is not set
--
2.27.0

View File

@ -323,3 +323,42 @@ patches/0319-ACPICA-Add-support-for-Arm-s-MPAM-ACPI-table-version.patch
patches/0320-ACPICA-ACPI-6.4-PPTT-add-new-version-of-subtable-typ.patch
patches/0321-ACPI-PPTT-Find-PPTT-processor-node-by-cache-id.patch
patches/0322-ACPI-MPAM-Adapt-to-Arm-s-MPAM-ACPI-table-version-2.patch
patches/0323-spi-add-support-for-octal-mode-I-O-data-transfer.patch
patches/0324-mtd-spi-nor-Add-support-for-mx25u12835f.patch
patches/0325-mtd-spi-nor-always-use-bounce-buffer-for-register-re.patch
patches/0326-mtd-spi-nor-Move-m25p80-code-in-spi-nor.c.patch
patches/0327-mtd-spi-nor-Fix-direction-of-the-write_sr-transfer.patch
patches/0328-mtd-spi-nor-Prepend-spi_nor_-to-all-Reg-Ops-methods.patch
patches/0329-mtd-spi-nor-Stop-compare-with-negative-in-Reg-Ops-me.patch
patches/0330-mtd-spi-nor-Pointer-parameter-for-SR-in-spi_nor_read.patch
patches/0331-mtd-spi-nor-Pointer-parameter-for-FSR-in-spi_nor_rea.patch
patches/0332-mtd-spi-nor-Pointer-parameter-for-CR-in-spi_nor_read.patch
patches/0333-mtd-spi-nor-fix-kernel-doc-for-spi_nor-spimem.patch
patches/0334-mtd-spi-nor-core-Fix-an-issue-of-releasing-resources.patch
patches/0335-ARM-shmobile-defconfig-Refresh-config-CONFIG_MTD_M25.patch
patches/0336-mips-Drop-CONFIG_MTD_M25P80-in-various-defconfig-fil.patch
patches/0337-m68k-Drop-CONFIG_MTD_M25P80-in-stmark2_defconfig.patch
patches/0338-powerpc-Drop-CONFIG_MTD_M25P80-in-85xx-hw.config.patch
patches/0339-sh-Replace-CONFIG_MTD_M25P80-with-CONFIG_MTD_SPI_NOR.patch
patches/0340-spi-spi-mem-Add-SPI_MEM_NO_DATA-to-the-spi_mem_data_.patch
patches/0341-spi-spi-mem-Fix-build-error-without-CONFIG_SPI_MEM.patch
patches/0342-driver-platform-Support-parsing-GpioInt-0-in-platfor.patch
patches/0343-driver-core-platform-return-ENXIO-for-missing-GpioIn.patch
patches/0344-spi-acpi-enumerate-all-SPI-slaves-in-the-namespace.patch
patches/0345-spi-acpi-fix-incorrect-ACPI-parent-check.patch
patches/0346-spi-acpi-avoid-spurious-matches-during-slave-enumera.patch
patches/0347-spi-Add-HiSilicon-v3xx-SPI-NOR-flash-controller-driv.patch
patches/0348-spi-Allow-SPI-controller-override-device-buswidth.patch
patches/0349-spi-HiSilicon-v3xx-Properly-set-CMD_CONFIG-for-Dual-.patch
patches/0350-spi-HiSilicon-v3xx-Use-DMI-quirk-to-set-controller-b.patch
patches/0351-spi-hisi-sfc-v3xx-add-error-check-after-per-operatio.patch
patches/0352-spi-Remove-CONFIG_-prefix-from-Kconfig-select.patch
patches/0353-spi-hisi-sfc-v3xx-factor-out-IO-modes-configuration.patch
patches/0354-spi-hisi-sfc-v3xx-factor-out-bus-config-and-transfer.patch
patches/0355-spi-hisi-sfc-v3xx-factor-out-the-bit-definition-of-i.patch
patches/0356-spi-hisi-sfc-v3xx-add-support-for-IRQ-mode.patch
patches/0357-spi-hisi-sfc-v3xx-extend-version-checking-compatibil.patch
patches/0358-spi-hisi-sfc-v3xx-add-address-mode-check.patch
patches/0359-spi-hisi-sfc-v3xx-fix-potential-irq-race-condition.patch
patches/0360-spi-hisi-sfc-v3xx-drop-unnecessary-ACPI_PTR-and-rela.patch
patches/0361-config-arm64-Build-HiSilicon-SPI-SFC-driver-as-modul.patch