pistachio: Make patches and configuration apply on to of 5.4
authorHauke Mehrtens <hauke@hauke-m.de>
Sun, 9 Aug 2020 17:47:17 +0000 (19:47 +0200)
committerHauke Mehrtens <hauke@hauke-m.de>
Fri, 21 Aug 2020 09:46:13 +0000 (11:46 +0200)
This refreshes the patches, removes patches already applied upstream and
removes the SPI NAND framework to use the upstream version.

In addition it also refreshes the kernel configuration.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
18 files changed:
target/linux/pistachio/Makefile
target/linux/pistachio/config-5.4
target/linux/pistachio/patches-5.4/101-dmaengine-img-mdc-Handle-early-status-read.patch
target/linux/pistachio/patches-5.4/102-spi-img-spfi-Implement-dual-and-quad-mode.patch
target/linux/pistachio/patches-5.4/103-spi-img-spfi-set-device-select-bits-for-SPFI-port-st.patch [deleted file]
target/linux/pistachio/patches-5.4/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch
target/linux/pistachio/patches-5.4/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch
target/linux/pistachio/patches-5.4/106-spi-img-spfi-finish-every-transfer-cleanly.patch
target/linux/pistachio/patches-5.4/107-clockevents-Retry-programming-min-delta-up-to-10-tim.patch [deleted file]
target/linux/pistachio/patches-5.4/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch
target/linux/pistachio/patches-5.4/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch
target/linux/pistachio/patches-5.4/401-mtd-nor-support-mtd-name-from-device-tree.patch
target/linux/pistachio/patches-5.4/411-mtd-nand-Check-length-of-ID-before-reading-bits-per-.patch [deleted file]
target/linux/pistachio/patches-5.4/412-mtd-nand-Add-JEDEC-manufacturer-ID-for-Gigadevice.patch [deleted file]
target/linux/pistachio/patches-5.4/413-mtd-Introduce-SPI-NAND-framework.patch [deleted file]
target/linux/pistachio/patches-5.4/414-mtd-spi-nand-Support-Gigadevice-GD5F.patch [deleted file]
target/linux/pistachio/patches-5.4/901-MIPS-DTS-img-marduk-add-nor-partition-name.patch
target/linux/pistachio/patches-5.4/902-MIPS-DTS-img-marduk-add-nand-device-support.patch

index c13f63bd1840c6ec72f88eb0361083c9d88b3f89..0bf04dcc56fe94741f76e1a12e4bfddfe6e497c8 100644 (file)
@@ -14,6 +14,7 @@ CPU_TYPE:=24kc
 CPU_SUBTYPE:=24kf
 
 KERNEL_PATCHVER:=4.14
+KERNEL_TESTING_PATCHVER:=5.4
 
 include $(INCLUDE_DIR)/target.mk
 
index 8b24b68a051f6a550a9f0f93e5b557595493093c..c4637c1372755cb7c2bfe2d0377aca89c665d3c3 100644 (file)
@@ -1,23 +1,21 @@
-CONFIG_ARCH_BINFMT_ELF_STATE=y
+CONFIG_ARCH_32BIT_OFF_T=y
 CONFIG_ARCH_CLOCKSOURCE_DATA=y
-CONFIG_ARCH_DISCARD_MEMBLOCK=y
+CONFIG_ARCH_HAS_DMA_COHERENT_TO_PFN=y
+CONFIG_ARCH_HAS_DMA_PREP_COHERENT=y
+CONFIG_ARCH_HAS_DMA_WRITE_COMBINE=y
 CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
-# CONFIG_ARCH_HAS_GCOV_PROFILE_ALL is not set
-# CONFIG_ARCH_HAS_SG_CHAIN is not set
-# CONFIG_ARCH_HAS_STRICT_KERNEL_RWX is not set
-# CONFIG_ARCH_HAS_STRICT_MODULE_RWX is not set
+CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE=y
+CONFIG_ARCH_HAS_UNCACHED_SEGMENT=y
 CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
-CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
 CONFIG_ARCH_MMAP_RND_BITS_MAX=15
 CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-# CONFIG_ARCH_OPTIONAL_KERNEL_RWX is not set
-# CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT is not set
 CONFIG_ARCH_SUPPORTS_UPROBES=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 CONFIG_ARCH_USE_BUILTIN_BSWAP=y
+CONFIG_ARCH_USE_MEMREMAP_PROT=y
 CONFIG_ARCH_USE_QUEUED_RWLOCKS=y
 CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
 CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_SD=y
@@ -31,12 +29,13 @@ CONFIG_CLKSRC_PISTACHIO=y
 CONFIG_CLONE_BACKWARDS=y
 CONFIG_COMMON_CLK=y
 # CONFIG_COMMON_CLK_BOSTON is not set
+CONFIG_COMPAT_32BIT_TIME=y
 CONFIG_CONNECTOR=y
 CONFIG_CPU_GENERIC_DUMP_TLB=y
+CONFIG_CPU_HAS_LOAD_STORE_LR=y
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_CPU_HAS_RIXI=y
 CONFIG_CPU_HAS_SYNC=y
-# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
 CONFIG_CPU_IDLE=y
 CONFIG_CPU_IDLE_GOV_LADDER=y
 CONFIG_CPU_IDLE_GOV_MENU=y
@@ -49,7 +48,6 @@ CONFIG_CPU_MIPSR2_IRQ_VI=y
 CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
 CONFIG_CPU_PM=y
 CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_R4K_FPU=y
 CONFIG_CPU_RMAP=y
 CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
 CONFIG_CPU_SUPPORTS_HIGHMEM=y
@@ -64,6 +62,8 @@ CONFIG_CRYPTO_CRC32C=y
 CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_HASH_INFO=y
+CONFIG_CRYPTO_LIB_SHA256=y
 CONFIG_CRYPTO_LZO=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
@@ -74,34 +74,46 @@ CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_RNG2=y
 CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_CRYPTO_ZSTD=y
 CONFIG_CSRC_R4K=y
 CONFIG_DMADEVICES=y
 CONFIG_DMA_ENGINE=y
 CONFIG_DMA_NONCOHERENT=y
+CONFIG_DMA_NONCOHERENT_CACHE_SYNC=y
 CONFIG_DMA_OF=y
 CONFIG_DMA_VIRTUAL_CHANNELS=y
 CONFIG_DTC=y
-# CONFIG_DWMAC_DWC_QOS_ETH is not set
 CONFIG_DWMAC_GENERIC=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_EARLY_PRINTK_8250=y
+CONFIG_EFI_EARLYCON=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_EXT4_FS_SECURITY=y
 CONFIG_FIXED_PHY=y
+CONFIG_FONT_8x16=y
+CONFIG_FONT_AUTOSELECT=y
+CONFIG_FONT_SUPPORT=y
+CONFIG_FS_IOMAP=y
 CONFIG_FS_MBCACHE=y
 CONFIG_FS_POSIX_ACL=y
+CONFIG_FW_LOADER_PAGED_BUF=y
 CONFIG_GENERIC_ALLOCATOR=y
 CONFIG_GENERIC_ATOMIC64=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_IO=y
+CONFIG_GENERIC_GETTIMEOFDAY=y
+CONFIG_GENERIC_IOMAP=y
 CONFIG_GENERIC_IRQ_CHIP=y
 CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
 CONFIG_GENERIC_IRQ_IPI=y
 CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_LIB_ASHLDI3=y
+CONFIG_GENERIC_LIB_ASHRDI3=y
+CONFIG_GENERIC_LIB_CMPDI2=y
+CONFIG_GENERIC_LIB_LSHRDI3=y
+CONFIG_GENERIC_LIB_UCMPDI2=y
 CONFIG_GENERIC_PCI_IOMAP=y
 CONFIG_GENERIC_PHY=y
 CONFIG_GENERIC_PINCONF=y
@@ -112,21 +124,18 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIOLIB_IRQCHIP=y
-# CONFIG_GRO_CELLS is not set
 CONFIG_HANDLE_DOMAIN_IRQ=y
 CONFIG_HARDWARE_WATCHPOINTS=y
 CONFIG_HAS_DMA=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT_MAP=y
-# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
-# CONFIG_HAVE_ARCH_BITREVERSE is not set
+CONFIG_HAVE_ARCH_COMPILER_H=y
 CONFIG_HAVE_ARCH_JUMP_LABEL=y
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
-# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
+CONFIG_HAVE_ASM_MODVERSIONS=y
 CONFIG_HAVE_CBPF_JIT=y
-CONFIG_HAVE_CC_STACKPROTECTOR=y
 CONFIG_HAVE_CLK=y
 CONFIG_HAVE_CLK_PREPARE=y
 CONFIG_HAVE_CONTEXT_TRACKING=y
@@ -134,27 +143,30 @@ CONFIG_HAVE_COPY_THREAD_TLS=y
 CONFIG_HAVE_C_RECORDMCOUNT=y
 CONFIG_HAVE_DEBUG_KMEMLEAK=y
 CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
-CONFIG_HAVE_DMA_API_DEBUG=y
 CONFIG_HAVE_DMA_CONTIGUOUS=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FAST_GUP=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_HAVE_GENERIC_VDSO=y
 CONFIG_HAVE_IDE=y
+CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
 CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
 CONFIG_HAVE_KVM=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_HAVE_MEMBLOCK=y
+CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION=y
 CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
 CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
 CONFIG_HAVE_NET_DSA=y
 CONFIG_HAVE_OPROFILE=y
 CONFIG_HAVE_PERF_EVENTS=y
 CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_RSEQ=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_HOTPLUG_CPU=y
+CONFIG_HZ=250
+CONFIG_HZ_250=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_IMG=y
@@ -171,6 +183,7 @@ CONFIG_JBD2=y
 CONFIG_LEDS_PWM=y
 CONFIG_LIBFDT=y
 CONFIG_LKDTM=y
+CONFIG_LOCK_DEBUGGING_SUPPORT=y
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_LZO_COMPRESS=y
 CONFIG_LZO_DECOMPRESS=y
@@ -179,11 +192,14 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0
 CONFIG_MDIO_BUS=y
 CONFIG_MDIO_DEVICE=y
+CONFIG_MEMFD_CREATE=y
 CONFIG_MFD_SYSCON=y
 CONFIG_MICREL_PHY=y
+CONFIG_MIGRATION=y
 CONFIG_MIPS=y
 CONFIG_MIPS_ASID_BITS=8
 CONFIG_MIPS_ASID_SHIFT=0
+CONFIG_MIPS_CBPF_JIT=y
 CONFIG_MIPS_CLOCK_VSYSCALL=y
 CONFIG_MIPS_CM=y
 # CONFIG_MIPS_CMDLINE_DTB_EXTEND is not set
@@ -192,37 +208,34 @@ CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER=y
 CONFIG_MIPS_CPC=y
 CONFIG_MIPS_CPS=y
 # CONFIG_MIPS_CPS_CPUIDLE is not set
-# CONFIG_MIPS_CPS_NS16550 is not set
+# CONFIG_MIPS_CPS_NS16550_BOOL is not set
 CONFIG_MIPS_CPS_PM=y
 CONFIG_MIPS_CPU_SCACHE=y
 # CONFIG_MIPS_ELF_APPENDED_DTB is not set
 CONFIG_MIPS_EXTERNAL_TIMER=y
 CONFIG_MIPS_GIC=y
-# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
 CONFIG_MIPS_L1_CACHE_SHIFT=5
-# CONFIG_MIPS_MACHINE is not set
 CONFIG_MIPS_MT=y
 CONFIG_MIPS_MT_FPAFF=y
 CONFIG_MIPS_MT_SMP=y
 CONFIG_MIPS_NO_APPENDED_DTB=y
+CONFIG_MIPS_NR_CPU_NR_MAP=4
 CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
 # CONFIG_MIPS_RAW_APPENDED_DTB is not set
 CONFIG_MIPS_SPRAM=y
-# CONFIG_MIPS_VPE_LOADER is not set
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK=y
 CONFIG_MMC_DW=y
+# CONFIG_MMC_DW_BLUEFIELD is not set
 # CONFIG_MMC_DW_EXYNOS is not set
+# CONFIG_MMC_DW_HI3798CV200 is not set
 # CONFIG_MMC_DW_K3 is not set
 CONFIG_MMC_DW_PLTFM=y
 CONFIG_MODULES_USE_ELF_REL=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_M25P80=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_CORE=y
 CONFIG_MTD_SPI_NAND=y
-CONFIG_MTD_SPI_NAND_DEVICES=y
 CONFIG_MTD_SPI_NOR=y
 CONFIG_MTD_SPI_NOR_USE_4K_SECTORS=y
 CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=16384
@@ -242,7 +255,6 @@ CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
 CONFIG_NO_HZ=y
 CONFIG_NO_HZ_COMMON=y
 CONFIG_NO_HZ_IDLE=y
-# CONFIG_NO_IOPORT_MAP is not set
 CONFIG_NR_CPUS=4
 CONFIG_OF=y
 CONFIG_OF_ADDRESS=y
@@ -250,14 +262,17 @@ CONFIG_OF_EARLY_FLATTREE=y
 CONFIG_OF_FLATTREE=y
 CONFIG_OF_GPIO=y
 CONFIG_OF_IRQ=y
+CONFIG_OF_KOBJ=y
 CONFIG_OF_MDIO=y
 CONFIG_OF_NET=y
 CONFIG_PADATA=y
+CONFIG_PAGE_POOL=y
 CONFIG_PCI_DRIVERS_LEGACY=y
 CONFIG_PERF_USE_VMALLOC=y
 CONFIG_PGTABLE_LEVELS=2
 # CONFIG_PGTABLE_MAPPING is not set
 CONFIG_PHYLIB=y
+CONFIG_PHYLINK=y
 CONFIG_PHY_PISTACHIO_USB=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_PISTACHIO=y
@@ -279,9 +294,7 @@ CONFIG_RATIONAL=y
 CONFIG_RCU_NEED_SEGCBLIST=y
 CONFIG_RCU_STALL_COMMON=y
 CONFIG_REGMAP=y
-CONFIG_REGMAP_I2C=y
 CONFIG_REGMAP_MMIO=y
-CONFIG_REGMAP_SPI=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_GPIO=y
@@ -294,18 +307,22 @@ CONFIG_SCHED_INFO=y
 CONFIG_SCSI=y
 CONFIG_SCSI_SPI_ATTRS=y
 CONFIG_SERIAL_8250_DW=y
-# CONFIG_SERIAL_8250_FSL is not set
+CONFIG_SERIAL_8250_DWLIB=y
+CONFIG_SERIAL_MCTRL_GPIO=y
 CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SGL_ALLOC=y
 CONFIG_SG_POOL=y
 CONFIG_SMP=y
 CONFIG_SMP_UP=y
 CONFIG_SPI=y
 CONFIG_SPI_IMG_SPFI=y
 CONFIG_SPI_MASTER=y
+CONFIG_SPI_MEM=y
 CONFIG_SRAM=y
 CONFIG_SRCU=y
 CONFIG_STMMAC_ETH=y
 CONFIG_STMMAC_PLATFORM=y
+# CONFIG_STMMAC_SELFTESTS is not set
 CONFIG_SWPHY=y
 CONFIG_SYNC_R4K=y
 CONFIG_SYSCTL_EXCEPTION_TRACE=y
@@ -321,6 +338,7 @@ CONFIG_SYS_SUPPORTS_RELOCATABLE=y
 CONFIG_SYS_SUPPORTS_SCHED_SMT=y
 CONFIG_SYS_SUPPORTS_SMP=y
 CONFIG_SYS_SUPPORTS_ZBOOT=y
+CONFIG_TARGET_ISA_REV=2
 CONFIG_TICK_CPU_ACCOUNTING=y
 CONFIG_TIMER_OF=y
 CONFIG_TIMER_PROBE=y
@@ -331,12 +349,12 @@ CONFIG_UBIFS_FS=y
 # CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
 CONFIG_UBIFS_FS_LZO=y
 CONFIG_UBIFS_FS_ZLIB=y
+CONFIG_UBIFS_FS_ZSTD=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_COMMON=y
 CONFIG_USB_DWC2=y
 CONFIG_USB_DWC2_DUAL_ROLE=y
-# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set
 CONFIG_USB_EHCI_HCD=y
 # CONFIG_USB_EHCI_HCD_PLATFORM is not set
 CONFIG_USB_GADGET=y
@@ -348,7 +366,10 @@ CONFIG_USE_OF=y
 CONFIG_WATCHDOG_CORE=y
 CONFIG_WEAK_ORDERING=y
 CONFIG_XPS=y
+CONFIG_XXHASH=y
 CONFIG_ZLIB_DEFLATE=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZSMALLOC=y
 # CONFIG_ZSMALLOC_STAT is not set
+CONFIG_ZSTD_COMPRESS=y
+CONFIG_ZSTD_DECOMPRESS=y
index 92293f8796071139d713277b5d2984008bf8efb0..031a4e3e5eedd65a431de80a6d1e57e1c415e444 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: Damien Horsley <damien.horsley@imgtec.com>
 
 --- a/drivers/dma/img-mdc-dma.c
 +++ b/drivers/dma/img-mdc-dma.c
-@@ -620,25 +620,33 @@ static enum dma_status mdc_tx_status(str
+@@ -618,25 +618,33 @@ static enum dma_status mdc_tx_status(str
                        (MDC_CMDS_PROCESSED_CMDS_DONE_MASK + 1);
  
                /*
index 15a5d3c806fce5f9b6c39d0fdb13e19ef1b4904a..9966ae71a9b4ef1bfda7ef391f7c63f0d52bf2c7 100644 (file)
@@ -28,7 +28,7 @@ Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
 
 --- a/drivers/spi/spi-img-spfi.c
 +++ b/drivers/spi/spi-img-spfi.c
-@@ -40,7 +40,8 @@
+@@ -37,7 +37,8 @@
  #define SPFI_CONTROL_SOFT_RESET                       BIT(11)
  #define SPFI_CONTROL_SEND_DMA                 BIT(10)
  #define SPFI_CONTROL_GET_DMA                  BIT(9)
@@ -38,7 +38,7 @@ Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
  #define SPFI_CONTROL_TMODE_SHIFT              5
  #define SPFI_CONTROL_TMODE_MASK                       0x7
  #define SPFI_CONTROL_TMODE_SINGLE             0
-@@ -51,6 +52,10 @@
+@@ -48,6 +49,10 @@
  #define SPFI_TRANSACTION                      0x18
  #define SPFI_TRANSACTION_TSIZE_SHIFT          16
  #define SPFI_TRANSACTION_TSIZE_MASK           0xffff
@@ -49,7 +49,7 @@ Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
  
  #define SPFI_PORT_STATE                               0x1c
  #define SPFI_PORT_STATE_DEV_SEL_SHIFT         20
-@@ -87,6 +92,7 @@
+@@ -84,6 +89,7 @@
   */
  #define SPFI_32BIT_FIFO_SIZE                  64
  #define SPFI_8BIT_FIFO_SIZE                   16
@@ -57,7 +57,7 @@ Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
  
  struct img_spfi {
        struct device *dev;
-@@ -103,6 +109,8 @@ struct img_spfi {
+@@ -100,6 +106,8 @@ struct img_spfi {
        struct dma_chan *tx_ch;
        bool tx_dma_busy;
        bool rx_dma_busy;
@@ -66,7 +66,7 @@ Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
  };
  
  struct img_spfi_device_data {
-@@ -123,9 +131,11 @@ static inline void spfi_start(struct img
+@@ -120,9 +128,11 @@ static inline void spfi_start(struct img
  {
        u32 val;
  
@@ -81,7 +81,7 @@ Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
  }
  
  static inline void spfi_reset(struct img_spfi *spfi)
-@@ -138,12 +148,21 @@ static int spfi_wait_all_done(struct img
+@@ -135,12 +145,21 @@ static int spfi_wait_all_done(struct img
  {
        unsigned long timeout = jiffies + msecs_to_jiffies(50);
  
diff --git a/target/linux/pistachio/patches-5.4/103-spi-img-spfi-set-device-select-bits-for-SPFI-port-st.patch b/target/linux/pistachio/patches-5.4/103-spi-img-spfi-set-device-select-bits-for-SPFI-port-st.patch
deleted file mode 100644 (file)
index ba70348..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-From 145f5369510b86cd55c659388a26a0cc267f8874 Mon Sep 17 00:00:00 2001
-From: Ionela Voinescu <ionela.voinescu@imgtec.com>
-Date: Mon, 1 Feb 2016 10:58:08 +0000
-Subject: spi: img-spfi: set device select bits for SPFI port state
-
-Even if the chip select line is not controlled by the SPFI
-hardware, the device select bits need to be set to specify
-the chip select line in use for the hardware to know what
-parameters to use for the current transfer.
-
-Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
----
- drivers/spi/spi-img-spfi.c | 3 +++
- 1 file changed, 3 insertions(+)
-
---- a/drivers/spi/spi-img-spfi.c
-+++ b/drivers/spi/spi-img-spfi.c
-@@ -438,6 +438,9 @@ static int img_spfi_prepare(struct spi_m
-       u32 val;
-       val = spfi_readl(spfi, SPFI_PORT_STATE);
-+      val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK <<
-+               SPFI_PORT_STATE_DEV_SEL_SHIFT);
-+      val |= msg->spi->chip_select << SPFI_PORT_STATE_DEV_SEL_SHIFT;
-       if (msg->spi->mode & SPI_CPHA)
-               val |= SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select);
-       else
index 6c9e6b5a768f4f5591dd0dff8b01a3d3b9ebd5ec..9050dae187db193a34dbd211c2b691b7af8d586d 100644 (file)
@@ -15,7 +15,7 @@ Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
 
 --- a/drivers/spi/spi-img-spfi.c
 +++ b/drivers/spi/spi-img-spfi.c
-@@ -437,18 +437,23 @@ static int img_spfi_prepare(struct spi_m
+@@ -434,18 +434,23 @@ static int img_spfi_prepare(struct spi_m
        struct img_spfi *spfi = spi_master_get_devdata(master);
        u32 val;
  
@@ -44,7 +44,7 @@ Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
        spfi_writel(spfi, val, SPFI_PORT_STATE);
  
        return 0;
-@@ -548,11 +553,15 @@ static void img_spfi_config(struct spi_m
+@@ -545,11 +550,15 @@ static void img_spfi_config(struct spi_m
        div = DIV_ROUND_UP(clk_get_rate(spfi->spfi_clk), xfer->speed_hz);
        div = clamp(512 / (1 << get_count_order(div)), 1, 128);
  
index 0067b0ea4ac0f8dd9adfce576c8c6c79649a5f8e..182897cd5a058d5fe899923845106030cd643430 100644 (file)
@@ -29,7 +29,7 @@ Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
 
 --- a/drivers/spi/spi-img-spfi.c
 +++ b/drivers/spi/spi-img-spfi.c
-@@ -346,12 +346,11 @@ static int img_spfi_start_dma(struct spi
+@@ -343,12 +343,11 @@ static int img_spfi_start_dma(struct spi
                if (xfer->len % 4 == 0) {
                        rxconf.src_addr = spfi->phys + SPFI_RX_32BIT_VALID_DATA;
                        rxconf.src_addr_width = 4;
@@ -43,7 +43,7 @@ Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
                dmaengine_slave_config(spfi->rx_ch, &rxconf);
  
                rxdesc = dmaengine_prep_slave_sg(spfi->rx_ch, xfer->rx_sg.sgl,
-@@ -370,12 +369,11 @@ static int img_spfi_start_dma(struct spi
+@@ -367,12 +366,11 @@ static int img_spfi_start_dma(struct spi
                if (xfer->len % 4 == 0) {
                        txconf.dst_addr = spfi->phys + SPFI_TX_32BIT_VALID_DATA;
                        txconf.dst_addr_width = 4;
index 0f958314e3be49d7e600076e3e9f1473c945bec7..cffb72ee336656a6cc6a1239b32d6b0ddea0bed0 100644 (file)
@@ -24,7 +24,7 @@ Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
 
 --- a/drivers/spi/spi-img-spfi.c
 +++ b/drivers/spi/spi-img-spfi.c
-@@ -83,6 +83,14 @@
+@@ -80,6 +80,14 @@
  #define SPFI_INTERRUPT_SDE                    BIT(1)
  #define SPFI_INTERRUPT_SDTRIG                 BIT(0)
  
@@ -39,7 +39,7 @@ Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
  /*
   * There are four parallel FIFOs of 16 bytes each.  The word buffer
   * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an
-@@ -144,6 +152,23 @@ static inline void spfi_reset(struct img
+@@ -141,6 +149,23 @@ static inline void spfi_reset(struct img
        spfi_writel(spfi, 0, SPFI_CONTROL);
  }
  
@@ -63,7 +63,7 @@ Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
  static int spfi_wait_all_done(struct img_spfi *spfi)
  {
        unsigned long timeout = jiffies + msecs_to_jiffies(50);
-@@ -152,19 +177,9 @@ static int spfi_wait_all_done(struct img
+@@ -149,19 +174,9 @@ static int spfi_wait_all_done(struct img
                return 0;
  
        while (time_before(jiffies, timeout)) {
@@ -85,7 +85,7 @@ Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
                cpu_relax();
        }
  
-@@ -296,6 +311,8 @@ static int img_spfi_start_pio(struct spi
+@@ -293,6 +308,8 @@ static int img_spfi_start_pio(struct spi
        }
  
        ret = spfi_wait_all_done(spfi);
@@ -94,7 +94,7 @@ Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
        if (ret < 0)
                return ret;
  
-@@ -311,8 +328,10 @@ static void img_spfi_dma_rx_cb(void *dat
+@@ -308,8 +325,10 @@ static void img_spfi_dma_rx_cb(void *dat
  
        spin_lock_irqsave(&spfi->lock, flags);
        spfi->rx_dma_busy = false;
@@ -106,7 +106,7 @@ Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
        spin_unlock_irqrestore(&spfi->lock, flags);
  }
  
-@@ -325,8 +344,10 @@ static void img_spfi_dma_tx_cb(void *dat
+@@ -322,8 +341,10 @@ static void img_spfi_dma_tx_cb(void *dat
  
        spin_lock_irqsave(&spfi->lock, flags);
        spfi->tx_dma_busy = false;
diff --git a/target/linux/pistachio/patches-5.4/107-clockevents-Retry-programming-min-delta-up-to-10-tim.patch b/target/linux/pistachio/patches-5.4/107-clockevents-Retry-programming-min-delta-up-to-10-tim.patch
deleted file mode 100644 (file)
index 857823b..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-From b46f8c74afdd30cd52bfdcc2231470a0bab04416 Mon Sep 17 00:00:00 2001
-From: James Hogan <james.hogan@imgtec.com>
-Date: Fri, 22 Apr 2016 18:22:45 +0100
-Subject: clockevents: Retry programming min delta up to 10 times
-
-Under virtualisation it is possible to get unexpected latency during a
-clockevent device's set_next_event() callback which can make it return
--ETIME even for a delta based on min_delta_ns.
-
-The clockevents_program_min_delta() implementation for
-CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=n doesn't handle retries when this
-happens, nor does clockevents_program_event() or its callers when force
-is true (for example hrtimer_reprogram()). This can result in hangs
-until the clock event device does a full period.
-
-It isn't appropriate to use MIN_ADJUST in this case as occasional
-hypervisor induced high latency will cause min_delta_ns to quickly
-increase to the maximum.
-Instead, borrow the retry pattern from the MIN_ADJUST case, but without
-making adjustments. We retry up to 10 times before giving up.
-
-(picked https://patchwork.kernel.org/patch/8909491/)
-
-Signed-off-by: James Hogan <james.hogan@imgtec.com>
----
- kernel/time/clockevents.c | 26 +++++++++++++++++++-------
- 1 file changed, 19 insertions(+), 7 deletions(-)
-
---- a/kernel/time/clockevents.c
-+++ b/kernel/time/clockevents.c
-@@ -281,16 +281,28 @@ static int clockevents_program_min_delta
- {
-       unsigned long long clc;
-       int64_t delta;
-+      int i;
--      delta = dev->min_delta_ns;
--      dev->next_event = ktime_add_ns(ktime_get(), delta);
-+      for (i = 0;;) {
-+              delta = dev->min_delta_ns;
-+              dev->next_event = ktime_add_ns(ktime_get(), delta);
--      if (clockevent_state_shutdown(dev))
--              return 0;
-+              if (clockevent_state_shutdown(dev))
-+                      return 0;
--      dev->retries++;
--      clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
--      return dev->set_next_event((unsigned long) clc, dev);
-+              dev->retries++;
-+              clc = ((unsigned long long) delta * dev->mult) >> dev->shift;
-+              if (dev->set_next_event((unsigned long) clc, dev) == 0)
-+                      return 0;
-+
-+              if (++i > 9) {
-+                      /*
-+                       * We tried 10 times to program the device with the
-+                       * given min_delta_ns. Get out of here.
-+                       */
-+                      return -ETIME;
-+              }
-+      }
- }
- #endif /* CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST */
index 5329ad62d0b4b72996206faa1e384352dfcd543e..6fddbe269afc6aa0db2252c76eaa37995383a4dd 100644 (file)
@@ -20,7 +20,7 @@ Signed-off-by: Govindraj Raja <Govindraj.Raja@imgtec.com>
 
 --- a/drivers/clk/pistachio/clk-pistachio.c
 +++ b/drivers/clk/pistachio/clk-pistachio.c
-@@ -44,7 +44,7 @@ static struct pistachio_gate pistachio_g
+@@ -41,7 +41,7 @@ static struct pistachio_gate pistachio_g
        GATE(CLK_AUX_ADC_INTERNAL, "aux_adc_internal", "sys_internal_div",
             0x104, 22),
        GATE(CLK_AUX_ADC, "aux_adc", "aux_adc_div", 0x104, 23),
@@ -29,7 +29,7 @@ Signed-off-by: Govindraj Raja <Govindraj.Raja@imgtec.com>
        GATE(CLK_BT, "bt", "bt_div", 0x104, 25),
        GATE(CLK_BT_DIV4, "bt_div4", "bt_div4_div", 0x104, 26),
        GATE(CLK_BT_DIV8, "bt_div8", "bt_div8_div", 0x104, 27),
-@@ -54,6 +54,7 @@ static struct pistachio_gate pistachio_g
+@@ -51,6 +51,7 @@ static struct pistachio_gate pistachio_g
  static struct pistachio_fixed_factor pistachio_ffs[] __initdata = {
        FIXED_FACTOR(CLK_WIFI_DIV4, "wifi_div4", "wifi_pll", 4),
        FIXED_FACTOR(CLK_WIFI_DIV8, "wifi_div8", "wifi_pll", 8),
@@ -39,7 +39,7 @@ Signed-off-by: Govindraj Raja <Govindraj.Raja@imgtec.com>
  static struct pistachio_div pistachio_divs[] __initdata = {
 --- a/include/dt-bindings/clock/pistachio-clk.h
 +++ b/include/dt-bindings/clock/pistachio-clk.h
-@@ -21,6 +21,7 @@
+@@ -18,6 +18,7 @@
  /* Fixed-factor clocks */
  #define CLK_WIFI_DIV4                 16
  #define CLK_WIFI_DIV8                 17
index 22fc42b98809380dcb562ae9e3ebfb9074ebfc40..cec424a0cec8c5aaea45c4d2914f9adf39545350 100644 (file)
@@ -28,7 +28,7 @@ Signed-off-by: Ian Pozella <Ian.Pozella@imgtec.com>
 
 --- a/arch/mips/boot/dts/img/pistachio_marduk.dts
 +++ b/arch/mips/boot/dts/img/pistachio_marduk.dts
-@@ -120,7 +120,7 @@
+@@ -117,7 +117,7 @@
  
  &sdhost {
        status = "okay";
@@ -37,7 +37,7 @@ Signed-off-by: Ian Pozella <Ian.Pozella@imgtec.com>
        disable-wp;
  };
  
-@@ -130,6 +130,7 @@
+@@ -127,6 +127,7 @@
  
  &pin_sdhost_data {
        drive-strength = <2>;
index 065a0b77bcd931766a53c76dffcf2621304c47d7..5d2f9284ab2afcd808e5f90b7f78f1e96d109054 100644 (file)
@@ -10,17 +10,17 @@ Signed-off-by: Abhimanyu Vishwakarma <Abhimanyu.Vishwakarma@imgtec.com>
 
 --- a/drivers/mtd/spi-nor/spi-nor.c
 +++ b/drivers/mtd/spi-nor/spi-nor.c
-@@ -2671,6 +2671,7 @@ int spi_nor_scan(struct spi_nor *nor, co
-       struct device *dev = nor->dev;
+@@ -4931,6 +4931,7 @@ int spi_nor_scan(struct spi_nor *nor, co
        struct mtd_info *mtd = &nor->mtd;
        struct device_node *np = spi_nor_get_flash_node(nor);
+       struct spi_nor_flash_parameter *params = &nor->params;
 +      const char __maybe_unused *of_mtd_name = NULL;
        int ret;
        int i;
  
-@@ -2746,7 +2747,12 @@ int spi_nor_scan(struct spi_nor *nor, co
-               spi_nor_wait_till_ready(nor);
-       }
+@@ -4993,7 +4994,12 @@ int spi_nor_scan(struct spi_nor *nor, co
+       /* Init flash parameters based on flash_info struct and SFDP */
+       spi_nor_init_params(nor);
  
 -      if (!mtd->name)
 +#ifdef CONFIG_MTD_OF_PARTS
diff --git a/target/linux/pistachio/patches-5.4/411-mtd-nand-Check-length-of-ID-before-reading-bits-per-.patch b/target/linux/pistachio/patches-5.4/411-mtd-nand-Check-length-of-ID-before-reading-bits-per-.patch
deleted file mode 100644 (file)
index 3311de6..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-From 42ebff638003be18fab503b37de4ad7853244e95 Mon Sep 17 00:00:00 2001
-From: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
-Date: Sat, 25 Feb 2017 15:58:22 +0000
-Subject: mtd: nand: Check length of ID before reading bits per cell
-
-The table-based NAND identification currently reads the number
-of bits per cell from the 3rd byte of the extended ID. This is done
-for the so-called 'full ID' devices; i.e. devices that have a known
-length ID.
-
-However, if the ID length is shorter than three, there's no 3rd byte,
-and so it's wrong to read the bits per cell from there. Fix this by
-adding a check for the ID length.
-
-(picked from http://lists.infradead.org/pipermail/linux-mtd/2014-December/056764.html)
-
-Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
----
- drivers/mtd/nand/nand_base.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/nand_base.c
-+++ b/drivers/mtd/nand/nand_base.c
-@@ -3803,7 +3803,8 @@ static bool find_full_id_nand(struct nan
-               mtd->erasesize = type->erasesize;
-               mtd->oobsize = type->oobsize;
--              chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
-+              if (type->id_len > 2)
-+                      chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
-               chip->chipsize = (uint64_t)type->chipsize << 20;
-               chip->options |= type->options;
-               chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
diff --git a/target/linux/pistachio/patches-5.4/412-mtd-nand-Add-JEDEC-manufacturer-ID-for-Gigadevice.patch b/target/linux/pistachio/patches-5.4/412-mtd-nand-Add-JEDEC-manufacturer-ID-for-Gigadevice.patch
deleted file mode 100644 (file)
index a967124..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From a4bc33b205fd9b1db862f1e45173dba57b0fa57f Mon Sep 17 00:00:00 2001
-From: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
-Date: Sat, 25 Feb 2017 15:43:09 +0000
-Subject: mtd: nand: Add JEDEC manufacturer ID for Gigadevice
-
-This commit adds Gigadevice to the list of manufacturer ID and name strings.
-
-(picked from http://lists.infradead.org/pipermail/linux-mtd/2014-December/056765.html)
-
-Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
----
- drivers/mtd/nand/nand_ids.c | 1 +
- include/linux/mtd/rawnand.h    | 1 +
- 2 files changed, 2 insertions(+)
-
---- a/drivers/mtd/nand/nand_ids.c
-+++ b/drivers/mtd/nand/nand_ids.c
-@@ -184,6 +184,7 @@ static const struct nand_manufacturer na
-       {NAND_MFR_SANDISK, "SanDisk"},
-       {NAND_MFR_INTEL, "Intel"},
-       {NAND_MFR_ATO, "ATO"},
-+      {NAND_MFR_GIGADEVICE, "Gigadevice"},
-       {NAND_MFR_WINBOND, "Winbond"},
- };
---- a/include/linux/mtd/rawnand.h
-+++ b/include/linux/mtd/rawnand.h
-@@ -1014,6 +1014,7 @@ static inline void *nand_get_manufacture
- #define NAND_MFR_SANDISK      0x45
- #define NAND_MFR_INTEL                0x89
- #define NAND_MFR_ATO          0x9b
-+#define NAND_MFR_GIGADEVICE   0xc8
- #define NAND_MFR_WINBOND      0xef
diff --git a/target/linux/pistachio/patches-5.4/413-mtd-Introduce-SPI-NAND-framework.patch b/target/linux/pistachio/patches-5.4/413-mtd-Introduce-SPI-NAND-framework.patch
deleted file mode 100644 (file)
index d1189ee..0000000
+++ /dev/null
@@ -1,707 +0,0 @@
-From 082a89a78e29b15008284df90441747cb742f149 Mon Sep 17 00:00:00 2001
-From: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
-Date: Tue, 2 Dec 2014 09:58:52 -0300
-Subject: mtd: Introduce SPI NAND framework
-
-Add a new framework, to support SPI NAND devices. The framework registers
-a NAND chip and handles the generic SPI NAND protocol, calling device-specific
-hooks for each SPI NAND command.
-
-The following is the stack design, from userspace to hardware. This commit
-adds the "SPI NAND core" layer.
-
-    Userspace
-  ------------------
-    MTD
-  ------------------
-    NAND core
-  ------------------
-    SPI NAND core
-  ------------------
-    SPI NAND device
-  ------------------
-    SPI core
-  ------------------
-    SPI master
-  ------------------
-    Hardware
-
-(based on http://lists.infradead.org/pipermail/linux-mtd/2014-December/056763.html)
-
-Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
-Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
-Signed-off-by: Ian Pozella <Ian.Pozella@imgtec.com>
----
- drivers/mtd/Kconfig                  |   2 +
- drivers/mtd/Makefile                 |   1 +
- drivers/mtd/spi-nand/Kconfig         |   7 +
- drivers/mtd/spi-nand/Makefile        |   1 +
- drivers/mtd/spi-nand/spi-nand-base.c | 566 +++++++++++++++++++++++++++++++++++
- include/linux/mtd/spi-nand.h         |  54 ++++
- 6 files changed, 631 insertions(+)
- create mode 100644 drivers/mtd/spi-nand/Kconfig
- create mode 100644 drivers/mtd/spi-nand/Makefile
- create mode 100644 drivers/mtd/spi-nand/spi-nand-base.c
- create mode 100644 include/linux/mtd/spi-nand.h
-
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -373,6 +373,8 @@ source "drivers/mtd/onenand/Kconfig"
- source "drivers/mtd/lpddr/Kconfig"
-+source "drivers/mtd/spi-nand/Kconfig"
-+
- source "drivers/mtd/spi-nor/Kconfig"
- source "drivers/mtd/ubi/Kconfig"
---- a/drivers/mtd/Makefile
-+++ b/drivers/mtd/Makefile
-@@ -37,6 +37,7 @@ inftl-objs           := inftlcore.o inftlmount.o
- obj-y         += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/
-+obj-$(CONFIG_MTD_SPI_NAND)    += spi-nand/
- obj-$(CONFIG_MTD_SPI_NOR)     += spi-nor/
- obj-$(CONFIG_MTD_UBI)         += ubi/
---- /dev/null
-+++ b/drivers/mtd/spi-nand/Kconfig
-@@ -0,0 +1,7 @@
-+menuconfig MTD_SPI_NAND
-+      tristate "SPI NAND device support"
-+      depends on MTD
-+      select MTD_NAND
-+      help
-+        This is the framework for the SPI NAND.
-+
---- /dev/null
-+++ b/drivers/mtd/spi-nand/Makefile
-@@ -0,0 +1 @@
-+obj-$(CONFIG_MTD_SPI_NAND)            += spi-nand-base.o
---- /dev/null
-+++ b/drivers/mtd/spi-nand/spi-nand-base.c
-@@ -0,0 +1,566 @@
-+/*
-+ * Copyright (C) 2014 Imagination Technologies Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License.
-+ *
-+ * Notes:
-+ * 1. Erase and program operations need to call write_enable() first,
-+ *    to clear the enable bit. This bit is cleared automatically after
-+ *    the erase or program operation.
-+ *
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/err.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/mtd/rawnand.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/spi-nand.h>
-+#include <linux/of.h>
-+#include <linux/slab.h>
-+
-+/* Registers common to all devices */
-+#define SPI_NAND_LOCK_REG             0xa0
-+#define SPI_NAND_PROT_UNLOCK_ALL      0x0
-+
-+#define SPI_NAND_FEATURE_REG          0xb0
-+#define SPI_NAND_ECC_EN                       BIT(4)
-+#define SPI_NAND_QUAD_EN              BIT(0)
-+
-+#define SPI_NAND_STATUS_REG           0xc0
-+#define SPI_NAND_STATUS_REG_ECC_MASK  0x3
-+#define SPI_NAND_STATUS_REG_ECC_SHIFT 4
-+#define SPI_NAND_STATUS_REG_PROG_FAIL BIT(3)
-+#define SPI_NAND_STATUS_REG_ERASE_FAIL        BIT(2)
-+#define SPI_NAND_STATUS_REG_WREN      BIT(1)
-+#define SPI_NAND_STATUS_REG_BUSY      BIT(0)
-+
-+#define SPI_NAND_CMD_BUF_LEN          8
-+
-+/* Rewind and fill the buffer with 0xff */
-+static void spi_nand_clear_buffer(struct spi_nand *snand)
-+{
-+      snand->buf_start = 0;
-+      memset(snand->data_buf, 0xff, snand->buf_size);
-+}
-+
-+static int spi_nand_enable_ecc(struct spi_nand *snand)
-+{
-+      int ret;
-+
-+      ret = snand->read_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
-+      if (ret)
-+              return ret;
-+
-+      snand->buf[0] |= SPI_NAND_ECC_EN;
-+      ret = snand->write_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
-+      if (ret)
-+              return ret;
-+      snand->ecc = true;
-+
-+      return 0;
-+}
-+
-+static int spi_nand_disable_ecc(struct spi_nand *snand)
-+{
-+      int ret;
-+
-+      ret = snand->read_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
-+      if (ret)
-+              return ret;
-+
-+      snand->buf[0] &= ~SPI_NAND_ECC_EN;
-+      ret = snand->write_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
-+      if (ret)
-+              return ret;
-+      snand->ecc = false;
-+
-+      return 0;
-+}
-+
-+static int spi_nand_enable_quad(struct spi_nand *snand)
-+{
-+      int ret;
-+
-+      ret = snand->read_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
-+      if (ret)
-+              return ret;
-+
-+      snand->buf[0] |= SPI_NAND_QUAD_EN;
-+      ret = snand->write_reg(snand, SPI_NAND_FEATURE_REG, snand->buf);
-+      if (ret)
-+              return ret;
-+
-+      return 0;
-+}
-+/*
-+ * Wait until the status register busy bit is cleared.
-+ * Returns a negatie errno on error or time out, and a non-negative status
-+ * value if the device is ready.
-+ */
-+static int spi_nand_wait_till_ready(struct spi_nand *snand)
-+{
-+      unsigned long deadline = jiffies + msecs_to_jiffies(100);
-+      bool timeout = false;
-+      int ret;
-+
-+      /*
-+       * Perhaps we should set a different timeout for each
-+       * operation (reset, read, write, erase).
-+       */
-+      while (!timeout) {
-+              if (time_after_eq(jiffies, deadline))
-+                      timeout = true;
-+
-+              ret = snand->read_reg(snand, SPI_NAND_STATUS_REG, snand->buf);
-+              if (ret < 0) {
-+                      dev_err(snand->dev, "error reading status register\n");
-+                      return ret;
-+              } else if (!(snand->buf[0] & SPI_NAND_STATUS_REG_BUSY)) {
-+                      return snand->buf[0];
-+              }
-+
-+              cond_resched();
-+      }
-+
-+      dev_err(snand->dev, "operation timed out\n");
-+
-+      return -ETIMEDOUT;
-+}
-+
-+static int spi_nand_reset(struct spi_nand *snand)
-+{
-+      int ret;
-+
-+      ret = snand->reset(snand);
-+      if (ret < 0) {
-+              dev_err(snand->dev, "reset command failed\n");
-+              return ret;
-+      }
-+
-+      /*
-+       * The NAND core won't wait after a device reset, so we need
-+       * to do that here.
-+       */
-+      ret = spi_nand_wait_till_ready(snand);
-+      if (ret < 0)
-+              return ret;
-+      return 0;
-+}
-+
-+static int spi_nand_status(struct spi_nand *snand)
-+{
-+      int ret, status;
-+
-+      ret = snand->read_reg(snand, SPI_NAND_STATUS_REG, snand->buf);
-+      if (ret < 0) {
-+              dev_err(snand->dev, "error reading status register\n");
-+              return ret;
-+      }
-+      status = snand->buf[0];
-+
-+      /* Convert this into standard NAND_STATUS values */
-+      if (status & SPI_NAND_STATUS_REG_BUSY)
-+              snand->buf[0] = 0;
-+      else
-+              snand->buf[0] = NAND_STATUS_READY;
-+
-+      if (status & SPI_NAND_STATUS_REG_PROG_FAIL ||
-+          status & SPI_NAND_STATUS_REG_ERASE_FAIL)
-+              snand->buf[0] |= NAND_STATUS_FAIL;
-+
-+      /*
-+       * Since we unlock the entire device at initialization, unconditionally
-+       * set the WP bit to indicate it's not protected.
-+       */
-+      snand->buf[0] |= NAND_STATUS_WP;
-+      return 0;
-+}
-+
-+static int spi_nand_erase(struct spi_nand *snand, int page_addr)
-+{
-+      int ret;
-+
-+      ret = snand->write_enable(snand);
-+      if (ret < 0) {
-+              dev_err(snand->dev, "write enable command failed\n");
-+              return ret;
-+      }
-+
-+      ret = snand->block_erase(snand, page_addr);
-+      if (ret < 0) {
-+              dev_err(snand->dev, "block erase command failed\n");
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static int spi_nand_write(struct spi_nand *snand)
-+{
-+      int ret;
-+
-+      /* Enable quad mode */
-+      ret = spi_nand_enable_quad(snand);
-+      if (ret) {
-+              dev_err(snand->dev, "error %d enabling quad mode\n", ret);
-+              return ret;
-+      }
-+      /* Store the page to cache */
-+      ret = snand->store_cache(snand, 0, snand->buf_size, snand->data_buf);
-+      if (ret < 0) {
-+              dev_err(snand->dev, "error %d storing page 0x%x to cache\n",
-+                      ret, snand->page_addr);
-+              return ret;
-+      }
-+
-+      ret = snand->write_enable(snand);
-+      if (ret < 0) {
-+              dev_err(snand->dev, "write enable command failed\n");
-+              return ret;
-+      }
-+
-+      /* Get page from the device cache into our internal buffer */
-+      ret = snand->write_page(snand, snand->page_addr);
-+      if (ret < 0) {
-+              dev_err(snand->dev, "error %d reading page 0x%x from cache\n",
-+                      ret, snand->page_addr);
-+              return ret;
-+      }
-+
-+      return 0;
-+}
-+
-+static int spi_nand_read_id(struct spi_nand *snand)
-+{
-+      int ret;
-+
-+      ret = snand->read_id(snand, snand->data_buf);
-+      if (ret < 0) {
-+              dev_err(snand->dev, "error %d reading ID\n", ret);
-+              return ret;
-+      }
-+      return 0;
-+}
-+
-+static int spi_nand_read_page(struct spi_nand *snand, unsigned int page_addr,
-+                            unsigned int page_offset, size_t length)
-+{
-+      unsigned int corrected = 0, ecc_error = 0;
-+      int ret;
-+
-+      /* Load a page into the cache register */
-+      ret = snand->load_page(snand, page_addr);
-+      if (ret < 0) {
-+              dev_err(snand->dev, "error %d loading page 0x%x to cache\n",
-+                      ret, page_addr);
-+              return ret;
-+      }
-+
-+      ret = spi_nand_wait_till_ready(snand);
-+      if (ret < 0)
-+              return ret;
-+
-+      if (snand->ecc) {
-+              snand->get_ecc_status(ret, &corrected, &ecc_error);
-+              snand->bitflips = corrected;
-+
-+              /*
-+               * If there's an ECC error, print a message and notify MTD
-+               * about it. Then complete the read, to load actual data on
-+               * the buffer (instead of the status result).
-+               */
-+              if (ecc_error) {
-+                      dev_err(snand->dev,
-+                              "internal ECC error reading page 0x%x\n",
-+                              page_addr);
-+                      snand->nand_chip.mtd.ecc_stats.failed++;
-+              } else {
-+                      snand->nand_chip.mtd.ecc_stats.corrected += corrected;
-+              }
-+      }
-+
-+      /* Enable quad mode */
-+      ret = spi_nand_enable_quad(snand);
-+      if (ret) {
-+              dev_err(snand->dev, "error %d enabling quad mode\n", ret);
-+              return ret;
-+      }
-+      /* Get page from the device cache into our internal buffer */
-+      ret = snand->read_cache(snand, page_offset, length, snand->data_buf);
-+      if (ret < 0) {
-+              dev_err(snand->dev, "error %d reading page 0x%x from cache\n",
-+                      ret, page_addr);
-+              return ret;
-+      }
-+      return 0;
-+}
-+
-+static u8 spi_nand_read_byte(struct mtd_info *mtd)
-+{
-+      struct nand_chip *chip = mtd_to_nand(mtd);
-+      struct spi_nand *snand = nand_get_controller_data(chip);
-+      char val = 0xff;
-+
-+      if (snand->buf_start < snand->buf_size)
-+              val = snand->data_buf[snand->buf_start++];
-+      return val;
-+}
-+
-+static void spi_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
-+{
-+      struct nand_chip *chip = mtd_to_nand(mtd);
-+      struct spi_nand *snand = nand_get_controller_data(chip);
-+      size_t n = min_t(size_t, len, snand->buf_size - snand->buf_start);
-+
-+      memcpy(snand->data_buf + snand->buf_start, buf, n);
-+      snand->buf_start += n;
-+}
-+
-+static void spi_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len)
-+{
-+      struct nand_chip *chip = mtd_to_nand(mtd);
-+      struct spi_nand *snand = nand_get_controller_data(chip);
-+      size_t n = min_t(size_t, len, snand->buf_size - snand->buf_start);
-+
-+      memcpy(buf, snand->data_buf + snand->buf_start, n);
-+      snand->buf_start += n;
-+}
-+
-+static int spi_nand_write_page_hwecc(struct mtd_info *mtd,
-+              struct nand_chip *chip, const uint8_t *buf, int oob_required,
-+              int page)
-+{
-+      chip->write_buf(mtd, buf, mtd->writesize);
-+      chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-+
-+      return 0;
-+}
-+
-+static int spi_nand_read_page_hwecc(struct mtd_info *mtd,
-+              struct nand_chip *chip, uint8_t *buf, int oob_required,
-+              int page)
-+{
-+      struct spi_nand *snand = nand_get_controller_data(chip);
-+
-+      chip->read_buf(mtd, buf, mtd->writesize);
-+      chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
-+
-+      return snand->bitflips;
-+}
-+
-+static int spi_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
-+{
-+      struct spi_nand *snand = nand_get_controller_data(chip);
-+      int ret;
-+
-+      ret = spi_nand_wait_till_ready(snand);
-+
-+      if (ret < 0) {
-+              return NAND_STATUS_FAIL;
-+      } else if (ret & SPI_NAND_STATUS_REG_PROG_FAIL) {
-+              dev_err(snand->dev, "page program failed\n");
-+              return NAND_STATUS_FAIL;
-+      } else if (ret & SPI_NAND_STATUS_REG_ERASE_FAIL) {
-+              dev_err(snand->dev, "block erase failed\n");
-+              return NAND_STATUS_FAIL;
-+      }
-+
-+      return NAND_STATUS_READY;
-+}
-+
-+static void spi_nand_cmdfunc(struct mtd_info *mtd, unsigned int command,
-+                           int column, int page_addr)
-+{
-+      struct nand_chip *chip = mtd_to_nand(mtd);
-+      struct spi_nand *snand = nand_get_controller_data(chip);
-+
-+      /*
-+       * In case there's any unsupported command, let's make sure
-+       * we don't keep garbage around in the buffer.
-+       */
-+      if (command != NAND_CMD_PAGEPROG) {
-+              spi_nand_clear_buffer(snand);
-+              snand->page_addr = 0;
-+      }
-+
-+      switch (command) {
-+      case NAND_CMD_READ0:
-+              spi_nand_read_page(snand, page_addr, 0, mtd->writesize);
-+              break;
-+      case NAND_CMD_READOOB:
-+              spi_nand_disable_ecc(snand);
-+              spi_nand_read_page(snand, page_addr, mtd->writesize,
-+                                 mtd->oobsize);
-+              spi_nand_enable_ecc(snand);
-+              break;
-+      case NAND_CMD_READID:
-+              spi_nand_read_id(snand);
-+              break;
-+      case NAND_CMD_ERASE1:
-+              spi_nand_erase(snand, page_addr);
-+              break;
-+      case NAND_CMD_ERASE2:
-+              /* There's nothing to do here, as the erase is one-step */
-+              break;
-+      case NAND_CMD_SEQIN:
-+              snand->buf_start = column;
-+              snand->page_addr = page_addr;
-+              break;
-+      case NAND_CMD_PAGEPROG:
-+              spi_nand_write(snand);
-+              break;
-+      case NAND_CMD_STATUS:
-+              spi_nand_status(snand);
-+              break;
-+      case NAND_CMD_RESET:
-+              spi_nand_reset(snand);
-+              break;
-+      default:
-+              dev_err(&mtd->dev, "unknown command 0x%x\n", command);
-+      }
-+}
-+
-+static void spi_nand_select_chip(struct mtd_info *mtd, int chip)
-+{
-+      /* We need this to override the default */
-+}
-+
-+int spi_nand_check(struct spi_nand *snand)
-+{
-+      if (!snand->dev)
-+              return -ENODEV;
-+      if (!snand->read_cache)
-+              return -ENODEV;
-+      if (!snand->load_page)
-+              return -ENODEV;
-+      if (!snand->store_cache)
-+              return -ENODEV;
-+      if (!snand->write_page)
-+              return -ENODEV;
-+      if (!snand->write_reg)
-+              return -ENODEV;
-+      if (!snand->read_reg)
-+              return -ENODEV;
-+      if (!snand->block_erase)
-+              return -ENODEV;
-+      if (!snand->reset)
-+              return -ENODEV;
-+      if (!snand->write_enable)
-+              return -ENODEV;
-+      if (!snand->write_disable)
-+              return -ENODEV;
-+      if (!snand->get_ecc_status)
-+              return -ENODEV;
-+      return 0;
-+}
-+
-+int spi_nand_register(struct spi_nand *snand, struct nand_flash_dev *flash_ids)
-+{
-+      struct nand_chip *chip = &snand->nand_chip;
-+      struct mtd_info *mtd = nand_to_mtd(chip);
-+      struct device_node *np = snand->dev->of_node;
-+      const char __maybe_unused *of_mtd_name = NULL;
-+      int ret;
-+
-+      /* Let's check all the hooks are in-place so we don't panic later */
-+      ret = spi_nand_check(snand);
-+      if (ret)
-+              return ret;
-+
-+      nand_set_controller_data(chip, snand);
-+      nand_set_flash_node(chip, np);
-+      chip->read_buf  = spi_nand_read_buf;
-+      chip->write_buf = spi_nand_write_buf;
-+      chip->read_byte = spi_nand_read_byte;
-+      chip->cmdfunc   = spi_nand_cmdfunc;
-+      chip->waitfunc  = spi_nand_waitfunc;
-+      chip->select_chip = spi_nand_select_chip;
-+      chip->options |= NAND_NO_SUBPAGE_WRITE;
-+      chip->bits_per_cell = 1;
-+
-+      mtd_set_ooblayout(mtd, snand->ooblayout);
-+      chip->ecc.read_page     = spi_nand_read_page_hwecc;
-+      chip->ecc.write_page    = spi_nand_write_page_hwecc;
-+      chip->ecc.mode          = NAND_ECC_HW;
-+
-+      if (of_property_read_bool(np, "nand-on-flash-bbt"))
-+              chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
-+
-+#ifdef CONFIG_MTD_OF_PARTS
-+      of_property_read_string(np, "linux,mtd-name", &of_mtd_name);
-+#endif
-+      if (of_mtd_name)
-+              mtd->name = of_mtd_name;
-+      else
-+              mtd->name = snand->name;
-+      mtd->owner = THIS_MODULE;
-+
-+      /* Allocate buffer to be used to read/write the internal registers */
-+      snand->buf = kmalloc(SPI_NAND_CMD_BUF_LEN, GFP_KERNEL);
-+      if (!snand->buf)
-+              return -ENOMEM;
-+
-+      /* This is enabled at device power up but we'd better make sure */
-+      ret = spi_nand_enable_ecc(snand);
-+      if (ret)
-+              return ret;
-+
-+      /* Preallocate buffer for flash identification (NAND_CMD_READID) */
-+      snand->buf_size = SPI_NAND_CMD_BUF_LEN;
-+      snand->data_buf = kmalloc(snand->buf_size, GFP_KERNEL);
-+
-+      ret = nand_scan_ident(mtd, 1, flash_ids);
-+      if (ret)
-+              return ret;
-+
-+      /*
-+       * SPI NAND has on-die ECC, which means we can correct as much as
-+       * we are required to. This must be done after identification of
-+       * the device.
-+       */
-+      chip->ecc.strength = chip->ecc_strength_ds;
-+      chip->ecc.size = chip->ecc_step_ds;
-+
-+      /*
-+       * Unlock all the device before calling nand_scan_tail. This is needed
-+       * in case the in-flash bad block table needs to be created.
-+       * We could override __nand_unlock(), but since it's not currently used
-+       * by the NAND core we call this explicitly.
-+       */
-+      snand->buf[0] = SPI_NAND_PROT_UNLOCK_ALL;
-+      ret = snand->write_reg(snand, SPI_NAND_LOCK_REG, snand->buf);
-+      if (ret)
-+              return ret;
-+
-+      /* Free the buffer and allocate a good one, to fit a page plus OOB */
-+      kfree(snand->data_buf);
-+
-+      snand->buf_size = mtd->writesize + mtd->oobsize;
-+      snand->data_buf = kmalloc(snand->buf_size, GFP_KERNEL);
-+      if (!snand->data_buf)
-+              return -ENOMEM;
-+
-+      ret = nand_scan_tail(mtd);
-+      if (ret)
-+              return ret;
-+
-+      return mtd_device_register(mtd, NULL, 0);
-+}
-+EXPORT_SYMBOL_GPL(spi_nand_register);
-+
-+void spi_nand_unregister(struct spi_nand *snand)
-+{
-+      kfree(snand->buf);
-+      kfree(snand->data_buf);
-+}
-+EXPORT_SYMBOL_GPL(spi_nand_unregister);
-+
-+MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@imgtec.com>");
-+MODULE_DESCRIPTION("Framework for SPI NAND");
-+MODULE_LICENSE("GPL v2");
---- /dev/null
-+++ b/include/linux/mtd/spi-nand.h
-@@ -0,0 +1,54 @@
-+/*
-+ * Copyright (C) 2014 Imagination Technologies Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License.
-+ */
-+
-+#ifndef __LINUX_MTD_SPI_NAND_H
-+#define __LINUX_MTD_SPI_NAND_H
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/rawnand.h>
-+
-+struct spi_nand {
-+      struct nand_chip        nand_chip;
-+      struct device           *dev;
-+      const char              *name;
-+
-+      u8                      *buf, *data_buf;
-+      size_t                  buf_size;
-+      off_t                   buf_start;
-+      unsigned int            page_addr;
-+      unsigned int            bitflips;
-+      bool                    ecc;
-+      struct mtd_ooblayout_ops *ooblayout;
-+
-+      int (*reset)(struct spi_nand *snand);
-+      int (*read_id)(struct spi_nand *snand, u8 *buf);
-+
-+      int (*write_disable)(struct spi_nand *snand);
-+      int (*write_enable)(struct spi_nand *snand);
-+
-+      int (*read_reg)(struct spi_nand *snand, u8 opcode, u8 *buf);
-+      int (*write_reg)(struct spi_nand *snand, u8 opcode, u8 *buf);
-+      void (*get_ecc_status)(unsigned int status,
-+                             unsigned int *corrected,
-+                             unsigned int *ecc_errors);
-+
-+      int (*store_cache)(struct spi_nand *snand, unsigned int page_offset,
-+                         size_t length, u8 *write_buf);
-+      int (*write_page)(struct spi_nand *snand, unsigned int page_addr);
-+      int (*load_page)(struct spi_nand *snand, unsigned int page_addr);
-+      int (*read_cache)(struct spi_nand *snand, unsigned int page_offset,
-+                        size_t length, u8 *read_buf);
-+      int (*block_erase)(struct spi_nand *snand, unsigned int page_addr);
-+
-+      void *priv;
-+};
-+
-+int spi_nand_register(struct spi_nand *snand, struct nand_flash_dev *flash_ids);
-+void spi_nand_unregister(struct spi_nand *snand);
-+
-+#endif
diff --git a/target/linux/pistachio/patches-5.4/414-mtd-spi-nand-Support-Gigadevice-GD5F.patch b/target/linux/pistachio/patches-5.4/414-mtd-spi-nand-Support-Gigadevice-GD5F.patch
deleted file mode 100644 (file)
index 1f14610..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-From 7723e59d483a883578115a73eb87eb7fff0ff724 Mon Sep 17 00:00:00 2001
-From: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
-Date: Tue, 28 Feb 2017 10:37:24 +0000
-Subject: mtd: spi-nand: Support Gigadevice GD5F
-
-This commit uses the recently introduced SPI NAND framework to support
-the Gigadevice GD5F serial NAND device.
-
-The current support includes:
-
-  * Page read and page program operations (using on-die ECC)
-  * Page out-of-band read
-  * Erase
-  * Reset
-  * Device status retrieval
-  * Device ID retrieval
-
-(based on http://lists.infradead.org/pipermail/linux-mtd/2014-December/056769.html)
-
-Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
-Signed-off-by: Ian Pozella <Ian.Pozella@imgtec.com>
----
- drivers/mtd/spi-nand/Kconfig           |  10 +
- drivers/mtd/spi-nand/Makefile          |   1 +
- drivers/mtd/spi-nand/spi-nand-device.c | 472 +++++++++++++++++++++++++++++++++
- 3 files changed, 483 insertions(+)
- create mode 100644 drivers/mtd/spi-nand/spi-nand-device.c
-
---- a/drivers/mtd/spi-nand/Kconfig
-+++ b/drivers/mtd/spi-nand/Kconfig
-@@ -5,3 +5,13 @@ menuconfig MTD_SPI_NAND
-       help
-         This is the framework for the SPI NAND.
-+if MTD_SPI_NAND
-+
-+config MTD_SPI_NAND_DEVICES
-+      tristate "Support for SPI NAND devices"
-+      default y
-+      depends on MTD_SPI_NAND
-+      help
-+        Select this option if you require support for SPI NAND devices.
-+
-+endif # MTD_SPI_NAND
---- a/drivers/mtd/spi-nand/Makefile
-+++ b/drivers/mtd/spi-nand/Makefile
-@@ -1 +1,2 @@
- obj-$(CONFIG_MTD_SPI_NAND)            += spi-nand-base.o
-+obj-$(CONFIG_MTD_SPI_NAND_DEVICES)     += spi-nand-device.o
---- /dev/null
-+++ b/drivers/mtd/spi-nand/spi-nand-device.c
-@@ -0,0 +1,472 @@
-+/*
-+ * Copyright (C) 2014 Imagination Technologies Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; version 2 of the License.
-+ *
-+ * Notes:
-+ * 1. We avoid using a stack-allocated buffer for SPI messages. Using
-+ *    a kmalloced buffer is probably better, given we shouldn't assume
-+ *    any particular usage by SPI core.
-+ */
-+
-+#include <linux/device.h>
-+#include <linux/err.h>
-+#include <linux/errno.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/mtd/spi-nand.h>
-+#include <linux/sizes.h>
-+#include <linux/spi/spi.h>
-+
-+/* SPI NAND commands */
-+#define       SPI_NAND_WRITE_ENABLE           0x06
-+#define       SPI_NAND_WRITE_DISABLE          0x04
-+#define       SPI_NAND_GET_FEATURE            0x0f
-+#define       SPI_NAND_SET_FEATURE            0x1f
-+#define       SPI_NAND_PAGE_READ              0x13
-+#define       SPI_NAND_READ_CACHE             0x03
-+#define       SPI_NAND_FAST_READ_CACHE        0x0b
-+#define       SPI_NAND_READ_CACHE_X2          0x3b
-+#define       SPI_NAND_READ_CACHE_X4          0x6b
-+#define       SPI_NAND_READ_CACHE_DUAL_IO     0xbb
-+#define       SPI_NAND_READ_CACHE_QUAD_IO     0xeb
-+#define       SPI_NAND_READ_ID                0x9f
-+#define       SPI_NAND_PROGRAM_LOAD           0x02
-+#define       SPI_NAND_PROGRAM_LOAD4          0x32
-+#define       SPI_NAND_PROGRAM_EXEC           0x10
-+#define       SPI_NAND_PROGRAM_LOAD_RANDOM    0x84
-+#define       SPI_NAND_PROGRAM_LOAD_RANDOM4   0xc4
-+#define       SPI_NAND_BLOCK_ERASE            0xd8
-+#define       SPI_NAND_RESET                  0xff
-+
-+#define SPI_NAND_GD5F_READID_LEN      2
-+
-+#define SPI_NAND_GD5F_ECC_MASK                (BIT(0) | BIT(1) | BIT(2))
-+#define SPI_NAND_GD5F_ECC_UNCORR      (BIT(0) | BIT(1) | BIT(2))
-+#define SPI_NAND_GD5F_ECC_SHIFT               4
-+
-+static int spi_nand_gd5f_ooblayout_256_ecc(struct mtd_info *mtd, int section,
-+                                      struct mtd_oob_region *oobregion)
-+{
-+      if (section)
-+              return -ERANGE;
-+
-+      oobregion->offset = 128;
-+      oobregion->length = 128;
-+
-+      return 0;
-+}
-+
-+static int spi_nand_gd5f_ooblayout_256_free(struct mtd_info *mtd, int section,
-+                                      struct mtd_oob_region *oobregion)
-+{
-+      if (section)
-+              return -ERANGE;
-+
-+      oobregion->offset = 1;
-+      oobregion->length = 127;
-+
-+      return 0;
-+}
-+
-+static const struct mtd_ooblayout_ops spi_nand_gd5f_oob_256_ops = {
-+      .ecc = spi_nand_gd5f_ooblayout_256_ecc,
-+      .free = spi_nand_gd5f_ooblayout_256_free,
-+};
-+
-+static struct nand_flash_dev spi_nand_flash_ids[] = {
-+      {
-+              .name = "SPI NAND 512MiB 3,3V",
-+              .id = { NAND_MFR_GIGADEVICE, 0xb4 },
-+              .chipsize = 512,
-+              .pagesize = SZ_4K,
-+              .erasesize = SZ_256K,
-+              .id_len = 2,
-+              .oobsize = 256,
-+              .ecc.strength_ds = 8,
-+              .ecc.step_ds = 512,
-+      },
-+      {
-+              .name = "SPI NAND 512MiB 1,8V",
-+              .id = { NAND_MFR_GIGADEVICE, 0xa4 },
-+              .chipsize = 512,
-+              .pagesize = SZ_4K,
-+              .erasesize = SZ_256K,
-+              .id_len = 2,
-+              .oobsize = 256,
-+              .ecc.strength_ds = 8,
-+              .ecc.step_ds = 512,
-+      },
-+};
-+
-+enum spi_nand_device_variant {
-+      SPI_NAND_GENERIC,
-+      SPI_NAND_GD5F,
-+};
-+
-+struct spi_nand_device_cmd {
-+
-+      /*
-+       * Command and address. I/O errors have been observed if a
-+       * separate spi_transfer is used for command and address,
-+       * so keep them together.
-+       */
-+      u32 n_cmd;
-+      u8 cmd[5];
-+
-+      /* Tx data */
-+      u32 n_tx;
-+      u8 *tx_buf;
-+
-+      /* Rx data */
-+      u32 n_rx;
-+      u8 *rx_buf;
-+      u8 rx_nbits;
-+      u8 tx_nbits;
-+};
-+
-+struct spi_nand_device {
-+      struct spi_nand spi_nand;
-+      struct spi_device *spi;
-+
-+      struct spi_nand_device_cmd cmd;
-+};
-+
-+static int spi_nand_send_command(struct spi_device *spi,
-+                               struct spi_nand_device_cmd *cmd)
-+{
-+      struct spi_message message;
-+      struct spi_transfer x[2];
-+
-+      if (!cmd->n_cmd) {
-+              dev_err(&spi->dev, "cannot send an empty command\n");
-+              return -EINVAL;
-+      }
-+
-+      if (cmd->n_tx && cmd->n_rx) {
-+              dev_err(&spi->dev, "cannot send and receive data at the same time\n");
-+              return -EINVAL;
-+      }
-+
-+      spi_message_init(&message);
-+      memset(x, 0, sizeof(x));
-+
-+      /* Command and address */
-+      x[0].len = cmd->n_cmd;
-+      x[0].tx_buf = cmd->cmd;
-+      x[0].tx_nbits = cmd->tx_nbits;
-+      spi_message_add_tail(&x[0], &message);
-+
-+      /* Data to be transmitted */
-+      if (cmd->n_tx) {
-+              x[1].len = cmd->n_tx;
-+              x[1].tx_buf = cmd->tx_buf;
-+              x[1].tx_nbits = cmd->tx_nbits;
-+              spi_message_add_tail(&x[1], &message);
-+      }
-+
-+      /* Data to be received */
-+      if (cmd->n_rx) {
-+              x[1].len = cmd->n_rx;
-+              x[1].rx_buf = cmd->rx_buf;
-+              x[1].rx_nbits = cmd->rx_nbits;
-+              spi_message_add_tail(&x[1], &message);
-+      }
-+
-+      return spi_sync(spi, &message);
-+}
-+
-+static int spi_nand_device_reset(struct spi_nand *snand)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      cmd->n_cmd = 1;
-+      cmd->cmd[0] = SPI_NAND_RESET;
-+
-+      dev_dbg(snand->dev, "%s\n", __func__);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static int spi_nand_device_read_reg(struct spi_nand *snand, u8 opcode, u8 *buf)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      cmd->n_cmd = 2;
-+      cmd->cmd[0] = SPI_NAND_GET_FEATURE;
-+      cmd->cmd[1] = opcode;
-+      cmd->n_rx = 1;
-+      cmd->rx_buf = buf;
-+
-+      dev_dbg(snand->dev, "%s: reg 0%x\n", __func__, opcode);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static int spi_nand_device_write_reg(struct spi_nand *snand, u8 opcode, u8 *buf)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      cmd->n_cmd = 2;
-+      cmd->cmd[0] = SPI_NAND_SET_FEATURE;
-+      cmd->cmd[1] = opcode;
-+      cmd->n_tx = 1;
-+      cmd->tx_buf = buf;
-+
-+      dev_dbg(snand->dev, "%s: reg 0%x\n", __func__, opcode);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static int spi_nand_device_write_enable(struct spi_nand *snand)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      cmd->n_cmd = 1;
-+      cmd->cmd[0] = SPI_NAND_WRITE_ENABLE;
-+
-+      dev_dbg(snand->dev, "%s\n", __func__);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static int spi_nand_device_write_disable(struct spi_nand *snand)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      cmd->n_cmd = 1;
-+      cmd->cmd[0] = SPI_NAND_WRITE_DISABLE;
-+
-+      dev_dbg(snand->dev, "%s\n", __func__);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static int spi_nand_device_write_page(struct spi_nand *snand,
-+                                    unsigned int page_addr)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      cmd->n_cmd = 4;
-+      cmd->cmd[0] = SPI_NAND_PROGRAM_EXEC;
-+      cmd->cmd[1] = (u8)((page_addr & 0xff0000) >> 16);
-+      cmd->cmd[2] = (u8)((page_addr & 0xff00) >> 8);
-+      cmd->cmd[3] = (u8)(page_addr & 0xff);
-+
-+      dev_dbg(snand->dev, "%s: page 0x%x\n", __func__, page_addr);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static int spi_nand_device_store_cache(struct spi_nand *snand,
-+                                     unsigned int page_offset, size_t length,
-+                                     u8 *write_buf)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+      struct spi_device *spi = snand_dev->spi;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      cmd->n_cmd = 3;
-+      cmd->cmd[0] = spi->mode & SPI_TX_QUAD ? SPI_NAND_PROGRAM_LOAD4 :
-+                      SPI_NAND_PROGRAM_LOAD;
-+      cmd->cmd[1] = (u8)((page_offset & 0xff00) >> 8);
-+      cmd->cmd[2] = (u8)(page_offset & 0xff);
-+      cmd->n_tx = length;
-+      cmd->tx_buf = write_buf;
-+      cmd->tx_nbits = spi->mode & SPI_TX_QUAD ? 4 : 1;
-+
-+      dev_dbg(snand->dev, "%s: offset 0x%x\n", __func__, page_offset);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static int spi_nand_device_load_page(struct spi_nand *snand,
-+                                   unsigned int page_addr)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      cmd->n_cmd = 4;
-+      cmd->cmd[0] = SPI_NAND_PAGE_READ;
-+      cmd->cmd[1] = (u8)((page_addr & 0xff0000) >> 16);
-+      cmd->cmd[2] = (u8)((page_addr & 0xff00) >> 8);
-+      cmd->cmd[3] = (u8)(page_addr & 0xff);
-+
-+      dev_dbg(snand->dev, "%s: page 0x%x\n", __func__, page_addr);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static int spi_nand_device_read_cache(struct spi_nand *snand,
-+                                    unsigned int page_offset, size_t length,
-+                                    u8 *read_buf)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+      struct spi_device *spi = snand_dev->spi;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      if ((spi->mode & SPI_RX_DUAL) || (spi->mode & SPI_RX_QUAD))
-+              cmd->n_cmd = 5;
-+      else
-+              cmd->n_cmd = 4;
-+      cmd->cmd[0] = (spi->mode & SPI_RX_QUAD) ? SPI_NAND_READ_CACHE_X4 :
-+                      ((spi->mode & SPI_RX_DUAL) ? SPI_NAND_READ_CACHE_X2 :
-+                      SPI_NAND_READ_CACHE);
-+      cmd->cmd[1] = 0; /* dummy byte */
-+      cmd->cmd[2] = (u8)((page_offset & 0xff00) >> 8);
-+      cmd->cmd[3] = (u8)(page_offset & 0xff);
-+      cmd->cmd[4] = 0; /* dummy byte */
-+      cmd->n_rx = length;
-+      cmd->rx_buf = read_buf;
-+      cmd->rx_nbits = (spi->mode & SPI_RX_QUAD) ? 4 :
-+                      ((spi->mode & SPI_RX_DUAL) ? 2 : 1);
-+
-+      dev_dbg(snand->dev, "%s: offset 0x%x\n", __func__, page_offset);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static int spi_nand_device_block_erase(struct spi_nand *snand,
-+                                     unsigned int page_addr)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      cmd->n_cmd = 4;
-+      cmd->cmd[0] = SPI_NAND_BLOCK_ERASE;
-+      cmd->cmd[1] = (u8)((page_addr & 0xff0000) >> 16);
-+      cmd->cmd[2] = (u8)((page_addr & 0xff00) >> 8);
-+      cmd->cmd[3] = (u8)(page_addr & 0xff);
-+
-+      dev_dbg(snand->dev, "%s: block 0x%x\n", __func__, page_addr);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static int spi_nand_gd5f_read_id(struct spi_nand *snand, u8 *buf)
-+{
-+      struct spi_nand_device *snand_dev = snand->priv;
-+      struct spi_nand_device_cmd *cmd = &snand_dev->cmd;
-+
-+      memset(cmd, 0, sizeof(struct spi_nand_device_cmd));
-+      cmd->n_cmd = 1;
-+      cmd->cmd[0] = SPI_NAND_READ_ID;
-+      cmd->n_rx = SPI_NAND_GD5F_READID_LEN;
-+      cmd->rx_buf = buf;
-+
-+      dev_dbg(snand->dev, "%s\n", __func__);
-+
-+      return spi_nand_send_command(snand_dev->spi, cmd);
-+}
-+
-+static void spi_nand_gd5f_ecc_status(unsigned int status,
-+                                   unsigned int *corrected,
-+                                   unsigned int *ecc_error)
-+{
-+      unsigned int ecc_status = (status >> SPI_NAND_GD5F_ECC_SHIFT) &
-+                                           SPI_NAND_GD5F_ECC_MASK;
-+
-+      *ecc_error = (ecc_status == SPI_NAND_GD5F_ECC_UNCORR) ? 1 : 0;
-+      if (*ecc_error == 0)
-+              *corrected = (ecc_status > 1) ? (2 + ecc_status) : 0;
-+}
-+
-+static int spi_nand_device_probe(struct spi_device *spi)
-+{
-+      enum spi_nand_device_variant variant;
-+      struct spi_nand_device *priv;
-+      struct spi_nand *snand;
-+      int ret;
-+
-+      priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
-+      if (!priv)
-+              return -ENOMEM;
-+
-+      snand = &priv->spi_nand;
-+
-+      snand->read_cache = spi_nand_device_read_cache;
-+      snand->load_page = spi_nand_device_load_page;
-+      snand->store_cache = spi_nand_device_store_cache;
-+      snand->write_page = spi_nand_device_write_page;
-+      snand->write_reg = spi_nand_device_write_reg;
-+      snand->read_reg = spi_nand_device_read_reg;
-+      snand->block_erase = spi_nand_device_block_erase;
-+      snand->reset = spi_nand_device_reset;
-+      snand->write_enable = spi_nand_device_write_enable;
-+      snand->write_disable = spi_nand_device_write_disable;
-+      snand->dev = &spi->dev;
-+      snand->priv = priv;
-+
-+      /* This'll mean we won't need to specify any specific compatible string
-+       * for a given device, and instead just support spi-nand.
-+       */
-+      variant = spi_get_device_id(spi)->driver_data;
-+      switch (variant) {
-+      case SPI_NAND_GD5F:
-+              snand->read_id = spi_nand_gd5f_read_id;
-+              snand->get_ecc_status = spi_nand_gd5f_ecc_status;
-+              snand->ooblayout = &spi_nand_gd5f_oob_256_ops;
-+              break;
-+      default:
-+              dev_err(snand->dev, "unknown device\n");
-+              return -ENODEV;
-+      }
-+
-+      spi_set_drvdata(spi, snand);
-+      priv->spi = spi;
-+
-+      ret = spi_nand_register(snand, spi_nand_flash_ids);
-+      if (ret)
-+              return ret;
-+      return 0;
-+}
-+
-+static int spi_nand_device_remove(struct spi_device *spi)
-+{
-+      struct spi_nand *snand = spi_get_drvdata(spi);
-+
-+      spi_nand_unregister(snand);
-+
-+      return 0;
-+}
-+
-+const struct spi_device_id spi_nand_id_table[] = {
-+      { "spi-nand", SPI_NAND_GENERIC },
-+      { "gd5f", SPI_NAND_GD5F },
-+      { },
-+};
-+MODULE_DEVICE_TABLE(spi, spi_nand_id_table);
-+
-+static struct spi_driver spi_nand_device_driver = {
-+      .driver = {
-+              .name   = "spi_nand_device",
-+              .owner  = THIS_MODULE,
-+      },
-+      .id_table = spi_nand_id_table,
-+      .probe  = spi_nand_device_probe,
-+      .remove = spi_nand_device_remove,
-+};
-+module_spi_driver(spi_nand_device_driver);
-+
-+MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@imgtec.com>");
-+MODULE_DESCRIPTION("SPI NAND device support");
-+MODULE_LICENSE("GPL v2");
index 6af11eaa361c13c7ffab08df3cb743baf779fa28..a8d021373b7e084d5b219879a9a66de12eb6738c 100644 (file)
@@ -10,7 +10,7 @@ Signed-off-by: Ian Pozella <Ian.Pozella@imgtec.com>
 
 --- a/arch/mips/boot/dts/img/pistachio_marduk.dts
 +++ b/arch/mips/boot/dts/img/pistachio_marduk.dts
-@@ -90,6 +90,7 @@
+@@ -87,6 +87,7 @@
                compatible = "spansion,s25fl016k", "jedec,spi-nor";
                reg = <0>;
                spi-max-frequency = <50000000>;
index bd03f08126343d55380e782946b668d891113b6d..d95f1af94df7882f46b9b3abfe7da44c12d526e9 100644 (file)
@@ -10,12 +10,12 @@ Signed-off-by: Abhimanyu Vishwakarma <Abhimanyu.Vishwakarma@imgtec.com>
 
 --- a/arch/mips/boot/dts/img/pistachio_marduk.dts
 +++ b/arch/mips/boot/dts/img/pistachio_marduk.dts
-@@ -92,6 +92,17 @@
+@@ -89,6 +89,17 @@
                spi-max-frequency = <50000000>;
                linux,mtd-name = "spi-nor";
        };
 +      flash@1 {
-+              compatible = "gigadevice,gd5f";
++              compatible = "spi-nand";
 +              reg = <1>;
 +              spi-max-frequency = <50000000>;
 +              nand-on-flash-bbt;