!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:
commit
87afc929ff
46
kernel.spec
46
kernel.spec
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
42
patches/0324-mtd-spi-nor-Add-support-for-mx25u12835f.patch
Normal file
42
patches/0324-mtd-spi-nor-Add-support-for-mx25u12835f.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
1362
patches/0326-mtd-spi-nor-Move-m25p80-code-in-spi-nor.c.patch
Normal file
1362
patches/0326-mtd-spi-nor-Move-m25p80-code-in-spi-nor.c.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
66
patches/0345-spi-acpi-fix-incorrect-ACPI-parent-check.patch
Normal file
66
patches/0345-spi-acpi-fix-incorrect-ACPI-parent-check.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
244
patches/0356-spi-hisi-sfc-v3xx-add-support-for-IRQ-mode.patch
Normal file
244
patches/0356-spi-hisi-sfc-v3xx-add-support-for-IRQ-mode.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
104
patches/0358-spi-hisi-sfc-v3xx-add-address-mode-check.patch
Normal file
104
patches/0358-spi-hisi-sfc-v3xx-add-address-mode-check.patch
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
39
series.conf
39
series.conf
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user