diff --git a/README.md b/README.md index c1a4b7a6c9..0c80db8e9e 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ _Ignore any "WARNING: No feed for package..." from the install feeds step._ Set the default configuration for Ci40 by running the following command (this sets version numbers and OPKG URLs): - $ cat target/linux/pistachio/creator-platform-cascoda-default.config > .config + $ cat target/linux/pistachio/creator-platform-default-cascoda.config > .config Complete the configuration process by running menuconfig: @@ -98,7 +98,7 @@ Example output for V0.9.4: - openwrt-0.9.4-pistachio-marduk-marduk_ca8210-rootfs.tar.gz - pistachio_marduk_ca8210.dtb -By default the version number is blank if you do not use the creator-platform-cascoda-default.config for loading the configuration. +By default the version number is blank if you do not use the creator-platform-default-cascoda.config for loading the configuration. ## Customising your OpenWrt You can configure OpenWrt from scratch but it's best to start from a base profile diff --git a/package/utils/busybox/patches/302-wget-run-s_client-helper-with-servername-HOST.patch b/package/utils/busybox/patches/302-wget-run-s_client-helper-with-servername-HOST.patch new file mode 100644 index 0000000000..da60faa5a1 --- /dev/null +++ b/package/utils/busybox/patches/302-wget-run-s_client-helper-with-servername-HOST.patch @@ -0,0 +1,107 @@ +diff --git a/networking/wget.c b/networking/wget.c +index 37950ed..653d807 100644 +--- a/networking/wget.c ++++ b/networking/wget.c +@@ -62,9 +62,10 @@ + //config: a helper program to talk over HTTPS. + //config: + //config: OpenSSL has a simple SSL client for debug purposes. +-//config: If you select "openssl" helper, wget will effectively call +-//config: "openssl s_client -quiet -connect IP:443 2>/dev/null" +-//config: and pipe its data through it. ++//config: If you select "openssl" helper, wget will effectively run: ++//config: "openssl s_client -quiet -connect hostname:443 ++//config: -servername hostname 2>/dev/null" and pipe its data ++//config: through it. -servername is not used if hostname is numeric. + //config: Note inconvenient API: host resolution is done twice, + //config: and there is no guarantee openssl's idea of IPv6 address + //config: format is the same as ours. +@@ -349,6 +350,30 @@ static void set_alarm(void) + # define clear_alarm() ((void)0) + #endif + ++#if ENABLE_FEATURE_WGET_OPENSSL ++/* ++ * is_ip_address() attempts to verify whether or not a string ++ * contains an IPv4 or IPv6 address (vs. an FQDN). The result ++ * of inet_pton() can be used to determine this. ++ * ++ * TODO add proper error checking when inet_pton() returns -1 ++ * (some form of system error has occurred, and errno is set) ++ */ ++static int is_ip_address(const char *string) ++{ ++ struct sockaddr_in sa; ++ ++ int result = inet_pton(AF_INET, string, &(sa.sin_addr)); ++# if ENABLE_FEATURE_IPV6 ++ if (result == 0) { ++ struct sockaddr_in6 sa6; ++ result = inet_pton(AF_INET6, string, &(sa6.sin6_addr)); ++ } ++# endif ++ return (result == 1); ++} ++#endif ++ + static FILE *open_socket(len_and_sockaddr *lsa) + { + int fd; +@@ -629,6 +654,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ + static int spawn_https_helper_openssl(const char *host, unsigned port) + { + char *allocated = NULL; ++ char *servername; + int sp[2]; + int pid; + IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) +@@ -639,12 +665,14 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) + + if (!strchr(host, ':')) + host = allocated = xasprintf("%s:%u", host, port); ++ servername = xstrdup(host); ++ strrchr(servername, ':')[0] = '\0'; + + fflush_all(); + pid = xvfork(); + if (pid == 0) { + /* Child */ +- char *argv[6]; ++ char *argv[8]; + + close(sp[0]); + xmove_fd(sp[1], 0); +@@ -656,12 +684,22 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) + */ + xmove_fd(2, 3); + xopen("/dev/null", O_RDWR); ++ memset(&argv, 0, sizeof(argv)); + argv[0] = (char*)"openssl"; + argv[1] = (char*)"s_client"; + argv[2] = (char*)"-quiet"; + argv[3] = (char*)"-connect"; + argv[4] = (char*)host; +- argv[5] = NULL; ++ /* ++ * Per RFC 6066 Section 3, the only permitted values in the ++ * TLS server_name (SNI) field are FQDNs (DNS hostnames). ++ * IPv4 and IPv6 addresses, port numbers are not allowed. ++ */ ++ if (!is_ip_address(servername)) { ++ argv[5] = (char*)"-servername"; ++ argv[6] = (char*)servername; ++ } ++ + BB_EXECVP(argv[0], argv); + xmove_fd(3, 2); + # if ENABLE_FEATURE_WGET_SSL_HELPER +@@ -674,6 +712,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) + } + + /* Parent */ ++ free(servername); + free(allocated); + close(sp[1]); + # if ENABLE_FEATURE_WGET_SSL_HELPER +-- +cgit v0.12 diff --git a/target/linux/pistachio/creator-platform-all-cascoda.config b/target/linux/pistachio/creator-platform-all-cascoda.config new file mode 100755 index 0000000000..3b3a8a5cc1 --- /dev/null +++ b/target/linux/pistachio/creator-platform-all-cascoda.config @@ -0,0 +1,30 @@ +CONFIG_TARGET_pistachio=y +CONFIG_TARGET_pistachio_marduk=y +CONFIG_TARGET_pistachio_marduk_marduk_ca8210=y +CONFIG_BUSYBOX_CUSTOM=y +CONFIG_BUSYBOX_CONFIG_FEATURE_WGET_OPENSSL=y +CONFIG_PACKAGE_uboot-pistachio_marduk=y +CONFIG_ALL=y +CONFIG_IB=y +CONFIG_SDK=y +CONFIG_MAKE_TOOLCHAIN=y +CONFIG_KERNEL_KALLSYMS=y +CONFIG_IMAGEOPT=y +CONFIG_LOCALMIRROR="https://downloads.creatordev.io/pistachio/marduk/dl" +CONFIG_OPENSSL_WITH_EC=y +CONFIG_PACKAGE_ca-certificates=y +CONFIG_PACKAGE_libopenssl=y +CONFIG_PACKAGE_openssl-util=y +CONFIG_PACKAGE_opkg-smime=y +# CONFIG_PACKAGE_usign is not set +CONFIG_PACKAGE_zlib=y +# CONFIG_SIGNED_PACKAGES is not set +CONFIG_VERSIONOPT=y +CONFIG_VERSION_DIST="OpenWrt" +CONFIG_VERSION_NICK="Ci40All" +CONFIG_VERSION_NUMBER="0.9.4" +CONFIG_VERSION_REPO="https://downloads.creatordev.io/pistachio/marduk/packages" +CONFIG_VERSION_MANUFACTURER="Imagination Technologies" +CONFIG_VERSION_MANUFACTURER_URL="www.imgtec.com" +CONFIG_VERSION_PRODUCT="Creator Ci40(Marduk)" +CONFIG_VERSION_HWREV="Ci40 with CA8210" diff --git a/target/linux/pistachio/creator-platform-all.config b/target/linux/pistachio/creator-platform-all.config new file mode 100755 index 0000000000..1cf0694cb5 --- /dev/null +++ b/target/linux/pistachio/creator-platform-all.config @@ -0,0 +1,30 @@ +CONFIG_TARGET_pistachio=y +CONFIG_TARGET_pistachio_marduk=y +CONFIG_TARGET_pistachio_marduk_marduk_cc2520=y +CONFIG_BUSYBOX_CUSTOM=y +CONFIG_BUSYBOX_CONFIG_FEATURE_WGET_OPENSSL=y +CONFIG_PACKAGE_uboot-pistachio_marduk=y +CONFIG_ALL=y +CONFIG_IB=y +CONFIG_SDK=y +CONFIG_MAKE_TOOLCHAIN=y +CONFIG_KERNEL_KALLSYMS=y +CONFIG_IMAGEOPT=y +CONFIG_LOCALMIRROR="https://downloads.creatordev.io/pistachio/marduk/dl" +CONFIG_OPENSSL_WITH_EC=y +CONFIG_PACKAGE_ca-certificates=y +CONFIG_PACKAGE_libopenssl=y +CONFIG_PACKAGE_openssl-util=y +CONFIG_PACKAGE_opkg-smime=y +# CONFIG_PACKAGE_usign is not set +CONFIG_PACKAGE_zlib=y +# CONFIG_SIGNED_PACKAGES is not set +CONFIG_VERSIONOPT=y +CONFIG_VERSION_DIST="OpenWrt" +CONFIG_VERSION_NICK="Ci40All" +CONFIG_VERSION_NUMBER="0.9.4" +CONFIG_VERSION_REPO="https://downloads.creatordev.io/pistachio/marduk/packages" +CONFIG_VERSION_MANUFACTURER="Imagination Technologies" +CONFIG_VERSION_MANUFACTURER_URL="www.imgtec.com" +CONFIG_VERSION_PRODUCT="Creator Ci40(Marduk)" +CONFIG_VERSION_HWREV="Ci40 with CC2520" diff --git a/target/linux/pistachio/creator-platform-cascoda-default.config b/target/linux/pistachio/creator-platform-cascoda-default.config deleted file mode 100755 index 7a38dd8e4e..0000000000 --- a/target/linux/pistachio/creator-platform-cascoda-default.config +++ /dev/null @@ -1,14 +0,0 @@ -CONFIG_TARGET_pistachio=y -CONFIG_TARGET_pistachio_marduk=y -CONFIG_TARGET_pistachio_marduk_marduk_ca8210=y -CONFIG_IMAGEOPT=y -CONFIG_LOCALMIRROR="http://downloads.creatordev.io/pistachio/marduk/dl" -CONFIG_VERSIONOPT=y -CONFIG_VERSION_DIST="OpenWrt" -CONFIG_VERSION_NICK="Ci40" -CONFIG_VERSION_NUMBER="0.9.4" -CONFIG_VERSION_REPO="http://downloads.creatordev.io/pistachio/marduk/packages" -CONFIG_VERSION_MANUFACTURER="Imagination Technologies" -CONFIG_VERSION_MANUFACTURER_URL="www.imgtec.com" -CONFIG_VERSION_PRODUCT="Creator Ci40(Marduk)" -CONFIG_VERSION_HWREV="Rev5 with CA8210" diff --git a/target/linux/pistachio/creator-platform-default-cascoda.config b/target/linux/pistachio/creator-platform-default-cascoda.config new file mode 100755 index 0000000000..22d5ec7c13 --- /dev/null +++ b/target/linux/pistachio/creator-platform-default-cascoda.config @@ -0,0 +1,24 @@ +CONFIG_TARGET_pistachio=y +CONFIG_TARGET_pistachio_marduk=y +CONFIG_TARGET_pistachio_marduk_marduk_ca8210=y +CONFIG_BUSYBOX_CUSTOM=y +CONFIG_BUSYBOX_CONFIG_FEATURE_WGET_OPENSSL=y +CONFIG_IMAGEOPT=y +CONFIG_LOCALMIRROR="https://downloads.creatordev.io/pistachio/marduk/dl" +CONFIG_OPENSSL_WITH_EC=y +CONFIG_PACKAGE_ca-certificates=y +CONFIG_PACKAGE_libopenssl=y +CONFIG_PACKAGE_openssl-util=y +CONFIG_PACKAGE_opkg-smime=y +# CONFIG_PACKAGE_usign is not set +CONFIG_PACKAGE_zlib=y +# CONFIG_SIGNED_PACKAGES is not set +CONFIG_VERSIONOPT=y +CONFIG_VERSION_DIST="OpenWrt" +CONFIG_VERSION_NICK="Ci40" +CONFIG_VERSION_NUMBER="0.9.4" +CONFIG_VERSION_REPO="https://downloads.creatordev.io/pistachio/marduk/packages" +CONFIG_VERSION_MANUFACTURER="Imagination Technologies" +CONFIG_VERSION_MANUFACTURER_URL="www.imgtec.com" +CONFIG_VERSION_PRODUCT="Creator Ci40(Marduk)" +CONFIG_VERSION_HWREV="Ci40 with CA8210" diff --git a/target/linux/pistachio/creator-platform-default.config b/target/linux/pistachio/creator-platform-default.config index f44f4cfddb..391c1b59d0 100755 --- a/target/linux/pistachio/creator-platform-default.config +++ b/target/linux/pistachio/creator-platform-default.config @@ -1,14 +1,24 @@ CONFIG_TARGET_pistachio=y CONFIG_TARGET_pistachio_marduk=y CONFIG_TARGET_pistachio_marduk_marduk_cc2520=y +CONFIG_BUSYBOX_CUSTOM=y +CONFIG_BUSYBOX_CONFIG_FEATURE_WGET_OPENSSL=y CONFIG_IMAGEOPT=y -CONFIG_LOCALMIRROR="http://downloads.creatordev.io/pistachio/marduk/dl" +CONFIG_LOCALMIRROR="https://downloads.creatordev.io/pistachio/marduk/dl" +CONFIG_OPENSSL_WITH_EC=y +CONFIG_PACKAGE_ca-certificates=y +CONFIG_PACKAGE_libopenssl=y +CONFIG_PACKAGE_openssl-util=y +CONFIG_PACKAGE_opkg-smime=y +# CONFIG_PACKAGE_usign is not set +CONFIG_PACKAGE_zlib=y +# CONFIG_SIGNED_PACKAGES is not set CONFIG_VERSIONOPT=y CONFIG_VERSION_DIST="OpenWrt" CONFIG_VERSION_NICK="Ci40" CONFIG_VERSION_NUMBER="0.9.4" -CONFIG_VERSION_REPO="http://downloads.creatordev.io/pistachio/marduk/packages" +CONFIG_VERSION_REPO="https://downloads.creatordev.io/pistachio/marduk/packages" CONFIG_VERSION_MANUFACTURER="Imagination Technologies" CONFIG_VERSION_MANUFACTURER_URL="www.imgtec.com" CONFIG_VERSION_PRODUCT="Creator Ci40(Marduk)" -CONFIG_VERSION_HWREV="Rev4 with CC2520" +CONFIG_VERSION_HWREV="Ci40 with CC2520" diff --git a/target/linux/pistachio/image/Makefile b/target/linux/pistachio/image/Makefile index 968ea683bf..eefffa7266 100644 --- a/target/linux/pistachio/image/Makefile +++ b/target/linux/pistachio/image/Makefile @@ -87,7 +87,7 @@ endif endef define Image/BuildKernel - $(call MkDTB,$($(PROFILE)_DEVICE_DTS)) + $(if $(IB),,$(call MkDTB,$($(PROFILE)_DEVICE_DTS))) $(call Image/BuildKernel/uImage,$(PROFILE)) endef diff --git a/target/linux/pistachio/patches-4.1/0167-spi-img-spfi-finish-every-transfer-cleanly.patch b/target/linux/pistachio/patches-4.1/0167-spi-img-spfi-finish-every-transfer-cleanly.patch new file mode 100644 index 0000000000..144d277389 --- /dev/null +++ b/target/linux/pistachio/patches-4.1/0167-spi-img-spfi-finish-every-transfer-cleanly.patch @@ -0,0 +1,126 @@ +From 945ab372e207cc137c1487867e7617f3d19f44a8 Mon Sep 17 00:00:00 2001 +From: Ionela Voinescu +Date: Wed, 10 Aug 2016 11:42:26 +0100 +Subject: spi: img-spfi: finish every transfer cleanly + +Before this change, the interrupt status bit that signaled +the end of a tranfers was cleared in the wait_all_done +function. That functionality triggered issues for DMA +duplex transactions where the wait function was called +twice, in both the TX and RX callbacks. + +In order to fix the issue, clear all interrupt data bits +at the end of a PIO transfer or at the end of both TX and RX +duplex transfers, if the transfer is not a pending tranfer +(command waiting for data). After that, the status register +is checked for new incoming data or new data requests to be +signaled. If SPFI finished cleanly, no new interrupt data +bits should be set. + +Change-Id: I8f46a199ad4e0a43a2a32cacaf4569cbce598f15 +Signed-off-by: Ionela Voinescu +--- + drivers/spi/spi-img-spfi.c | 49 +++++++++++++++++++++++++++++++++------------- + 1 file changed, 35 insertions(+), 14 deletions(-) + +diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c +index d2ec8a6..c68f357 100644 +--- a/drivers/spi/spi-img-spfi.c ++++ b/drivers/spi/spi-img-spfi.c +@@ -82,6 +82,14 @@ + #define SPFI_INTERRUPT_SDE BIT(1) + #define SPFI_INTERRUPT_SDTRIG BIT(0) + ++#define SPFI_INTERRUPT_DATA_BITS (SPFI_INTERRUPT_SDHF |\ ++ SPFI_INTERRUPT_SDFUL |\ ++ SPFI_INTERRUPT_GDEX32BIT |\ ++ SPFI_INTERRUPT_GDHF |\ ++ SPFI_INTERRUPT_GDFUL |\ ++ SPFI_INTERRUPT_ALLDONETRIG |\ ++ SPFI_INTERRUPT_GDEX8BIT) ++ + /* + * There are four parallel FIFOs of 16 bytes each. The word buffer + * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an +@@ -143,6 +151,23 @@ static inline void spfi_reset(struct img_spfi *spfi) + spfi_writel(spfi, 0, SPFI_CONTROL); + } + ++static inline void spfi_finish(struct img_spfi *spfi) ++{ ++ if (!(spfi->complete)) ++ return; ++ ++ /* Clear data bits as all transfers(TX and RX) have finished */ ++ spfi_writel(spfi, SPFI_INTERRUPT_DATA_BITS, SPFI_INTERRUPT_CLEAR); ++ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & SPFI_INTERRUPT_DATA_BITS) { ++ dev_err(spfi->dev, "SPFI did not finish transfer cleanly.\n"); ++ spfi_reset(spfi); ++ } ++ /* Disable SPFI for it not to interfere with pending transactions */ ++ spfi_writel(spfi, ++ spfi_readl(spfi, SPFI_CONTROL) & ~SPFI_CONTROL_SPFI_EN, ++ SPFI_CONTROL); ++} ++ + static int spfi_wait_all_done(struct img_spfi *spfi) + { + unsigned long timeout = jiffies + msecs_to_jiffies(50); +@@ -151,19 +176,9 @@ static int spfi_wait_all_done(struct img_spfi *spfi) + return 0; + + while (time_before(jiffies, timeout)) { +- u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); +- +- if (status & SPFI_INTERRUPT_ALLDONETRIG) { +- spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG, +- SPFI_INTERRUPT_CLEAR); +- /* +- * Disable SPFI for it not to interfere with +- * pending transactions +- */ +- spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL) +- & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL); ++ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & ++ SPFI_INTERRUPT_ALLDONETRIG) + return 0; +- } + cpu_relax(); + } + +@@ -295,6 +310,8 @@ static int img_spfi_start_pio(struct spi_master *master, + } + + ret = spfi_wait_all_done(spfi); ++ spfi_finish(spfi); ++ + if (ret < 0) + return ret; + +@@ -310,8 +327,10 @@ static void img_spfi_dma_rx_cb(void *data) + + spin_lock_irqsave(&spfi->lock, flags); + spfi->rx_dma_busy = false; +- if (!spfi->tx_dma_busy) ++ if (!spfi->tx_dma_busy) { ++ spfi_finish(spfi); + spi_finalize_current_transfer(spfi->master); ++ } + spin_unlock_irqrestore(&spfi->lock, flags); + } + +@@ -324,8 +343,10 @@ static void img_spfi_dma_tx_cb(void *data) + + spin_lock_irqsave(&spfi->lock, flags); + spfi->tx_dma_busy = false; +- if (!spfi->rx_dma_busy) ++ if (!spfi->rx_dma_busy) { ++ spfi_finish(spfi); + spi_finalize_current_transfer(spfi->master); ++ } + spin_unlock_irqrestore(&spfi->lock, flags); + } + +-- +2.6.2 + diff --git a/target/linux/pistachio/patches-4.4/0131-spi-img-spfi-finish-every-transfer-cleanly.patch b/target/linux/pistachio/patches-4.4/0131-spi-img-spfi-finish-every-transfer-cleanly.patch new file mode 100755 index 0000000000..fc81506c13 --- /dev/null +++ b/target/linux/pistachio/patches-4.4/0131-spi-img-spfi-finish-every-transfer-cleanly.patch @@ -0,0 +1,117 @@ +From 6133f95661afd3fae856ba7019a909197d686dd4 Mon Sep 17 00:00:00 2001 +From: Ionela Voinescu +Date: Wed, 10 Aug 2016 11:42:26 +0100 +Subject: [PATCH] spi: img-spfi: finish every transfer cleanly + +At the end of a tranfer, if the tranfer is not pending, +all data bits in the interrupt register should be cleared. +If SPFI did not finish cleanly, new incomming data or new +data requests will be signaled. + +Clearing the status bits for interrupts was done before in +the wait function. That functionality triggered issues +for DMA duplex transactions where the wait function was +called twice: in both TX and RX callbacks. + +Change-Id: I8f46a199ad4e0a43a2a32cacaf4569cbce598f15 +Signed-off-by: Ionela Voinescu +--- + +diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c +index 37b0d36..4d62b82 100644 +--- a/drivers/spi/spi-img-spfi.c ++++ b/drivers/spi/spi-img-spfi.c +@@ -83,6 +83,14 @@ + #define SPFI_INTERRUPT_SDE BIT(1) + #define SPFI_INTERRUPT_SDTRIG BIT(0) + ++#define SPFI_INTERRUPT_DATA_BITS (SPFI_INTERRUPT_SDHF |\ ++ SPFI_INTERRUPT_SDFUL |\ ++ SPFI_INTERRUPT_GDEX32BIT |\ ++ SPFI_INTERRUPT_GDHF |\ ++ SPFI_INTERRUPT_GDFUL |\ ++ SPFI_INTERRUPT_ALLDONETRIG |\ ++ SPFI_INTERRUPT_GDEX8BIT) ++ + /* + * 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 @@ + spfi_writel(spfi, 0, SPFI_CONTROL); + } + ++static inline void spfi_finish(struct img_spfi *spfi) ++{ ++ if (!(spfi->complete)) ++ return; ++ ++ /* Clear data bits as all transfers(TX and RX) have finished */ ++ spfi_writel(spfi, SPFI_INTERRUPT_DATA_BITS, SPFI_INTERRUPT_CLEAR); ++ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & SPFI_INTERRUPT_DATA_BITS) { ++ dev_err(spfi->dev, "SPFI did not finish transfer cleanly.\n"); ++ spfi_reset(spfi); ++ } ++ /* Disable SPFI for it not to interfere with pending transactions */ ++ spfi_writel(spfi, ++ spfi_readl(spfi, SPFI_CONTROL) & ~SPFI_CONTROL_SPFI_EN, ++ SPFI_CONTROL); ++} ++ + static int spfi_wait_all_done(struct img_spfi *spfi) + { + unsigned long timeout = jiffies + msecs_to_jiffies(50); +@@ -152,19 +177,9 @@ + return 0; + + while (time_before(jiffies, timeout)) { +- u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS); +- +- if (status & SPFI_INTERRUPT_ALLDONETRIG) { +- spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG, +- SPFI_INTERRUPT_CLEAR); +- /* +- * Disable SPFI for it not to interfere with +- * pending transactions +- */ +- spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL) +- & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL); ++ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & ++ SPFI_INTERRUPT_ALLDONETRIG) + return 0; +- } + cpu_relax(); + } + +@@ -296,6 +311,8 @@ + } + + ret = spfi_wait_all_done(spfi); ++ spfi_finish(spfi); ++ + if (ret < 0) + return ret; + +@@ -311,8 +328,10 @@ + + spin_lock_irqsave(&spfi->lock, flags); + spfi->rx_dma_busy = false; +- if (!spfi->tx_dma_busy) ++ if (!spfi->tx_dma_busy) { ++ spfi_finish(spfi); + spi_finalize_current_transfer(spfi->master); ++ } + spin_unlock_irqrestore(&spfi->lock, flags); + } + +@@ -325,8 +344,10 @@ + + spin_lock_irqsave(&spfi->lock, flags); + spfi->tx_dma_busy = false; +- if (!spfi->rx_dma_busy) ++ if (!spfi->rx_dma_busy) { ++ spfi_finish(spfi); + spi_finalize_current_transfer(spfi->master); ++ } + spin_unlock_irqrestore(&spfi->lock, flags); + } +