From 63453e0a3fe07e029e63aa1335bad78a6ac7e821 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Mon, 11 Jun 2018 15:51:06 +0000 Subject: [PATCH 1/8] Add 64bit flag to config for rpi Signed-off-by: Pascal Vizeli --- buildroot-external/board/raspberrypi/post-image.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/buildroot-external/board/raspberrypi/post-image.sh b/buildroot-external/board/raspberrypi/post-image.sh index 074a0adec..6eb2497ae 100755 --- a/buildroot-external/board/raspberrypi/post-image.sh +++ b/buildroot-external/board/raspberrypi/post-image.sh @@ -42,6 +42,11 @@ cp -r ${BINARIES_DIR}/rpi-firmware/overlays ${BOOT_DATA}/ echo "dwc_otg.lpm_enable=0 console=tty1" > ${BOOT_DATA}/cmdline.txt +# Enable 64bit support +if [ "$BOARD_ID" == "rpi3-64" ]; then + echo "arm_64bit=1" >> ${BOOT_DATA}/config.txt +fi + # Create other layers create_boot_image ${BINARIES_DIR} create_overlay_image ${BINARIES_DIR} From d6f5c337e1ac51d816fd7dd775ddf61365c42e52 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 12 Jun 2018 13:53:17 +0000 Subject: [PATCH 2/8] Allow more log with new partition layout Signed-off-by: Pascal Vizeli --- buildroot-external/rootfs-overlay/etc/systemd/journald.conf | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/buildroot-external/rootfs-overlay/etc/systemd/journald.conf b/buildroot-external/rootfs-overlay/etc/systemd/journald.conf index ae8fa73a9..76991c0c7 100644 --- a/buildroot-external/rootfs-overlay/etc/systemd/journald.conf +++ b/buildroot-external/rootfs-overlay/etc/systemd/journald.conf @@ -1,6 +1,5 @@ [Journal] Storage=auto Compress=yes -SystemMaxUse=8M -RuntimeMaxUse=8M - +SystemMaxUse=12M +RuntimeMaxUse=10M From fb235891e9eac026129bb35dd14191bc80d18cfe Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 12 Jun 2018 16:03:52 +0200 Subject: [PATCH 3/8] cleanup --- README.md | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/README.md b/README.md index 9073eb16b..d67b9bd63 100644 --- a/README.md +++ b/README.md @@ -13,23 +13,6 @@ Hass.io OS based on [buildroot](https://buildroot.org/). It's a hypervisor for D - ZRAM LZ4 for /tmp, /var, swap - Run every supervisor -## Schemas -![](misc/hassio-os-partition.png?raw=true) - -# Customize - -Provide a file with the name `hassos.json` in your data partition and the following structure: - -```json -{ - "supervisor": "repo/image", - "supervisor_args": "optional / custom docker arguments", - "cli": "repo/image", - "cli_args": "optional / custom docker arguments", - "hostname": "default hostname" -} -``` - # Building Running `sudo ./enter.sh` will get you into the build Docker container. `make -C /build/buildroot BR2_EXTERNAL=/build/buildroot-external xy_defconfig` From 9f6a339ec703bca0fee8dbab311266283ae2b9db Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 12 Jun 2018 14:31:50 +0000 Subject: [PATCH 4/8] fix old bootstate Signed-off-by: Pascal Vizeli --- .../systemd/system/local-fs.target.wants/var.mount | 1 - buildroot-external/rootfs-overlay/mnt/state/.empty | 0 .../usr/lib/systemd/system/mnt-state.mount | 14 -------------- 3 files changed, 15 deletions(-) delete mode 120000 buildroot-external/rootfs-overlay/etc/systemd/system/local-fs.target.wants/var.mount delete mode 100644 buildroot-external/rootfs-overlay/mnt/state/.empty delete mode 100644 buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-state.mount diff --git a/buildroot-external/rootfs-overlay/etc/systemd/system/local-fs.target.wants/var.mount b/buildroot-external/rootfs-overlay/etc/systemd/system/local-fs.target.wants/var.mount deleted file mode 120000 index c58bb744e..000000000 --- a/buildroot-external/rootfs-overlay/etc/systemd/system/local-fs.target.wants/var.mount +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/systemd/system/var.mount \ No newline at end of file diff --git a/buildroot-external/rootfs-overlay/mnt/state/.empty b/buildroot-external/rootfs-overlay/mnt/state/.empty deleted file mode 100644 index e69de29bb..000000000 diff --git a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-state.mount b/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-state.mount deleted file mode 100644 index 10cb32d3e..000000000 --- a/buildroot-external/rootfs-overlay/usr/lib/systemd/system/mnt-state.mount +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=HassOS bootstate partition -DefaultDependencies=no -Before=umount.target -After=local-fs.target rauc.service -Conflicts=umount.target - -[Mount] -What=LABEL=hassos-bootstate -Where=/mnt/state -Type=ext2 - -[Install] -WantedBy=local-fs.target From fa79721f3da4d1b31de83240ac8b41ee072a946c Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 12 Jun 2018 15:00:38 +0000 Subject: [PATCH 5/8] Fix boot problems with RPi 3+ Signed-off-by: Pascal Vizeli --- buildroot-external/board/raspberrypi/rpi3-64/uboot.config | 2 ++ buildroot-external/board/raspberrypi/rpi3/uboot.config | 2 ++ 2 files changed, 4 insertions(+) diff --git a/buildroot-external/board/raspberrypi/rpi3-64/uboot.config b/buildroot-external/board/raspberrypi/rpi3-64/uboot.config index 22cdb3a31..146b73e26 100644 --- a/buildroot-external/board/raspberrypi/rpi3-64/uboot.config +++ b/buildroot-external/board/raspberrypi/rpi3-64/uboot.config @@ -1,3 +1,5 @@ CONFIG_TARGET_RPI_3=y CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_DEFAULT_DEVICE_TREE="bcm2837-rpi-3-b" +CONFIG_PHYLIB=y +CONFIG_USB_ETHER_LAN78XX=y diff --git a/buildroot-external/board/raspberrypi/rpi3/uboot.config b/buildroot-external/board/raspberrypi/rpi3/uboot.config index 487219591..33ccec60d 100644 --- a/buildroot-external/board/raspberrypi/rpi3/uboot.config +++ b/buildroot-external/board/raspberrypi/rpi3/uboot.config @@ -1,3 +1,5 @@ CONFIG_TARGET_RPI_3_32B=y CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_DEFAULT_DEVICE_TREE="bcm2837-rpi-3-b" +CONFIG_PHYLIB=y +CONFIG_USB_ETHER_LAN78XX=y From f1461081f5cef7d61a762b0dd7166247fd6fefee Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 12 Jun 2018 17:03:22 +0200 Subject: [PATCH 6/8] Bump version --- buildroot-external/info | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildroot-external/info b/buildroot-external/info index e40eda88e..dc9962bfd 100644 --- a/buildroot-external/info +++ b/buildroot-external/info @@ -1,5 +1,5 @@ VERSION_MAJOR=0 -VERSION_BUILD=4 +VERSION_BUILD=5 HASSOS_NAME="HassOS" HASSOS_ID="hassos" From dd3935a786ea06853ecccb585f73aa92a7dd2ad3 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 12 Jun 2018 18:03:03 +0000 Subject: [PATCH 7/8] Fix pi problem Signed-off-by: Pascal Vizeli --- .../board/raspberrypi/uboot-boot.sh | 4 +-- .../board/raspberrypi/uboot.config | 1 - ...NetworkManager-allow-to-wait-on-boot.patch | 35 ------------------- ...spberry-pi-firmware-for-kernel-4.14.patch} | 0 .../network-manager/network-manager.mk | 4 --- 5 files changed, 2 insertions(+), 42 deletions(-) delete mode 100644 buildroot-patches/0006-NetworkManager-allow-to-wait-on-boot.patch rename buildroot-patches/{0007-Pump-raspberry-pi-firmware-for-kernel-4.14.patch => 0006-Pump-raspberry-pi-firmware-for-kernel-4.14.patch} (100%) diff --git a/buildroot-external/board/raspberrypi/uboot-boot.sh b/buildroot-external/board/raspberrypi/uboot-boot.sh index 6a3ed9f81..8b0b6649d 100644 --- a/buildroot-external/board/raspberrypi/uboot-boot.sh +++ b/buildroot-external/board/raspberrypi/uboot-boot.sh @@ -36,12 +36,12 @@ for BOOT_SLOT in "${BOOT_ORDER}"; do done if test -n "${bootargs}"; then - saveenv + #saveenv else echo "No valid slot found, resetting tries to 3" setenv BOOT_A_LEFT 3 setenv BOOT_B_LEFT 3 - saveenv + #saveenv reset fi diff --git a/buildroot-external/board/raspberrypi/uboot.config b/buildroot-external/board/raspberrypi/uboot.config index 00cf88bf2..acc0e2a45 100644 --- a/buildroot-external/board/raspberrypi/uboot.config +++ b/buildroot-external/board/raspberrypi/uboot.config @@ -7,7 +7,6 @@ CONFIG_CMD_GPIO=y CONFIG_CMD_MMC=y CONFIG_CMD_USB=y CONFIG_OF_EMBED=y -CONFIG_ENV_EXT4_INTERFACE="mmc" CONFIG_DM_KEYBOARD=y CONFIG_DM_MMC=y CONFIG_MMC_SDHCI=y diff --git a/buildroot-patches/0006-NetworkManager-allow-to-wait-on-boot.patch b/buildroot-patches/0006-NetworkManager-allow-to-wait-on-boot.patch deleted file mode 100644 index 667065f09..000000000 --- a/buildroot-patches/0006-NetworkManager-allow-to-wait-on-boot.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 590565bc07f563f978004727dc817dc89527377a Mon Sep 17 00:00:00 2001 -From: Pascal Vizeli -Date: Sat, 31 Mar 2018 16:58:14 +0200 -Subject: [PATCH 1/1] NetworkManager: allow to wait on boot - -Signed-off-by: Pascal Vizeli ---- - package/network-manager/network-manager.mk | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/package/network-manager/network-manager.mk b/package/network-manager/network-manager.mk -index a520aad..fb2012a 100644 ---- a/package/network-manager/network-manager.mk -+++ b/package/network-manager/network-manager.mk -@@ -93,6 +93,7 @@ endef - - define NETWORK_MANAGER_INSTALL_INIT_SYSTEMD - mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants -+ mkdir -p $(TARGET_DIR)/etc/systemd/system/network-online.target.wants - - ln -sf /usr/lib/systemd/system/NetworkManager.service \ - $(TARGET_DIR)/etc/systemd/system/dbus-org.freedesktop.NetworkManager.service -@@ -100,6 +101,9 @@ define NETWORK_MANAGER_INSTALL_INIT_SYSTEMD - ln -sf /usr/lib/systemd/system/NetworkManager.service \ - $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/NetworkManager.service - -+ ln -sf /usr/lib/systemd/system/NetworkManager-wait-online.service \ -+ $(TARGET_DIR)/etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service -+ - ln -sf /usr/lib/systemd/system/NetworkManager-dispatcher.service \ - $(TARGET_DIR)/etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service - endef --- -2.7.4 - diff --git a/buildroot-patches/0007-Pump-raspberry-pi-firmware-for-kernel-4.14.patch b/buildroot-patches/0006-Pump-raspberry-pi-firmware-for-kernel-4.14.patch similarity index 100% rename from buildroot-patches/0007-Pump-raspberry-pi-firmware-for-kernel-4.14.patch rename to buildroot-patches/0006-Pump-raspberry-pi-firmware-for-kernel-4.14.patch diff --git a/buildroot/package/network-manager/network-manager.mk b/buildroot/package/network-manager/network-manager.mk index fb2012ac0..a520aad9c 100644 --- a/buildroot/package/network-manager/network-manager.mk +++ b/buildroot/package/network-manager/network-manager.mk @@ -93,7 +93,6 @@ endef define NETWORK_MANAGER_INSTALL_INIT_SYSTEMD mkdir -p $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants - mkdir -p $(TARGET_DIR)/etc/systemd/system/network-online.target.wants ln -sf /usr/lib/systemd/system/NetworkManager.service \ $(TARGET_DIR)/etc/systemd/system/dbus-org.freedesktop.NetworkManager.service @@ -101,9 +100,6 @@ define NETWORK_MANAGER_INSTALL_INIT_SYSTEMD ln -sf /usr/lib/systemd/system/NetworkManager.service \ $(TARGET_DIR)/etc/systemd/system/multi-user.target.wants/NetworkManager.service - ln -sf /usr/lib/systemd/system/NetworkManager-wait-online.service \ - $(TARGET_DIR)/etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service - ln -sf /usr/lib/systemd/system/NetworkManager-dispatcher.service \ $(TARGET_DIR)/etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service endef From 73ac253a0fa1f9c646db99fe2d6fd2657ec3fa63 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 12 Jun 2018 20:53:05 +0000 Subject: [PATCH 8/8] Fix bug with RPi3 SDHCI Signed-off-by: Pascal Vizeli --- .../board/raspberrypi/uboot-boot.sh | 4 +- .../board/raspberrypi/uboot.config | 1 - ...irqify-bcm2835-sdhost-and-fix-writes.patch | 409 ++++++++++++++++++ 3 files changed, 411 insertions(+), 3 deletions(-) create mode 100644 buildroot-external/patches/uboot/0002-mmc-unirqify-bcm2835-sdhost-and-fix-writes.patch diff --git a/buildroot-external/board/raspberrypi/uboot-boot.sh b/buildroot-external/board/raspberrypi/uboot-boot.sh index 8b0b6649d..6a3ed9f81 100644 --- a/buildroot-external/board/raspberrypi/uboot-boot.sh +++ b/buildroot-external/board/raspberrypi/uboot-boot.sh @@ -36,12 +36,12 @@ for BOOT_SLOT in "${BOOT_ORDER}"; do done if test -n "${bootargs}"; then - #saveenv + saveenv else echo "No valid slot found, resetting tries to 3" setenv BOOT_A_LEFT 3 setenv BOOT_B_LEFT 3 - #saveenv + saveenv reset fi diff --git a/buildroot-external/board/raspberrypi/uboot.config b/buildroot-external/board/raspberrypi/uboot.config index acc0e2a45..c89061bf2 100644 --- a/buildroot-external/board/raspberrypi/uboot.config +++ b/buildroot-external/board/raspberrypi/uboot.config @@ -18,7 +18,6 @@ CONFIG_PINCTRL=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_DWC2=y -CONFIG_USB_STORAGE=y CONFIG_USB_KEYBOARD=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_SMSC95XX=y diff --git a/buildroot-external/patches/uboot/0002-mmc-unirqify-bcm2835-sdhost-and-fix-writes.patch b/buildroot-external/patches/uboot/0002-mmc-unirqify-bcm2835-sdhost-and-fix-writes.patch new file mode 100644 index 000000000..62d84c820 --- /dev/null +++ b/buildroot-external/patches/uboot/0002-mmc-unirqify-bcm2835-sdhost-and-fix-writes.patch @@ -0,0 +1,409 @@ +From patchwork Wed May 23 20:24:51 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [U-Boot] mmc: Unirqify bcm2835_sdhost and fix writes +X-Patchwork-Submitter: Alexander Graf +X-Patchwork-Id: 919394 +X-Patchwork-Delegate: agraf@suse.de +Message-Id: <20180523202451.68781-1-agraf@suse.de> +To: u-boot@lists.denx.de +Date: Wed, 23 May 2018 22:24:51 +0200 +From: Alexander Graf +List-Id: U-Boot discussion + +The bcm2835 sdhost driver has a problem with "write multiple" commands. +It seems to boil down to the fact that the controller dislikes its FIFO +to get drained at the end of a block when a write multiple blocks command +is in flight. + +The easy fix is to simply get rid of all the IRQ driven logic and make +the driver push as much data into the FIFO as it can. That way we never +drain and we never run into the problem. + +Reported-by: Jan Leonhardt +Signed-off-by: Alexander Graf +--- + drivers/mmc/bcm2835_sdhost.c | 265 ++++++++----------------------------------- + 1 file changed, 47 insertions(+), 218 deletions(-) + +diff --git a/drivers/mmc/bcm2835_sdhost.c b/drivers/mmc/bcm2835_sdhost.c +index 96428333b0..1ce019af57 100644 +--- a/drivers/mmc/bcm2835_sdhost.c ++++ b/drivers/mmc/bcm2835_sdhost.c +@@ -163,7 +163,6 @@ struct bcm2835_host { + int clock; /* Current clock speed */ + unsigned int max_clk; /* Max possible freq */ + unsigned int blocks; /* remaining PIO blocks */ +- int irq; /* Device IRQ */ + + u32 ns_per_fifo_word; + +@@ -173,14 +172,7 @@ struct bcm2835_host { + + struct mmc_cmd *cmd; /* Current command */ + struct mmc_data *data; /* Current data request */ +- bool data_complete:1;/* Data finished before cmd */ + bool use_busy:1; /* Wait for busy interrupt */ +- bool wait_data_complete:1; /* Wait for data */ +- +- /* for threaded irq handler */ +- bool irq_block; +- bool irq_busy; +- bool irq_data; + + struct udevice *dev; + struct mmc *mmc; +@@ -240,17 +232,9 @@ static void bcm2835_reset_internal(struct bcm2835_host *host) + writel(host->cdiv, host->ioaddr + SDCDIV); + } + +-static int bcm2835_finish_command(struct bcm2835_host *host); +- +-static void bcm2835_wait_transfer_complete(struct bcm2835_host *host) ++static int bcm2835_wait_transfer_complete(struct bcm2835_host *host) + { +- int timediff; +- u32 alternate_idle; +- +- alternate_idle = (host->data->flags & MMC_DATA_READ) ? +- SDEDM_FSM_READWAIT : SDEDM_FSM_WRITESTART1; +- +- timediff = 0; ++ int timediff = 0; + + while (1) { + u32 edm, fsm; +@@ -261,7 +245,10 @@ static void bcm2835_wait_transfer_complete(struct bcm2835_host *host) + if ((fsm == SDEDM_FSM_IDENTMODE) || + (fsm == SDEDM_FSM_DATAMODE)) + break; +- if (fsm == alternate_idle) { ++ ++ if ((fsm == SDEDM_FSM_READWAIT) || ++ (fsm == SDEDM_FSM_WRITESTART1) || ++ (fsm == SDEDM_FSM_READDATA)) { + writel(edm | SDEDM_FORCE_DATA_MODE, + host->ioaddr + SDEDM); + break; +@@ -273,9 +260,11 @@ static void bcm2835_wait_transfer_complete(struct bcm2835_host *host) + "wait_transfer_complete - still waiting after %d retries\n", + timediff); + bcm2835_dumpregs(host); +- return; ++ return -ETIMEDOUT; + } + } ++ ++ return 0; + } + + static int bcm2835_transfer_block_pio(struct bcm2835_host *host, bool is_read) +@@ -322,6 +311,9 @@ static int bcm2835_transfer_block_pio(struct bcm2835_host *host, bool is_read) + fsm_state != SDEDM_FSM_READCRC)) || + (!is_read && + (fsm_state != SDEDM_FSM_WRITEDATA && ++ fsm_state != SDEDM_FSM_WRITEWAIT1 && ++ fsm_state != SDEDM_FSM_WRITEWAIT2 && ++ fsm_state != SDEDM_FSM_WRITECRC && + fsm_state != SDEDM_FSM_WRITESTART1 && + fsm_state != SDEDM_FSM_WRITESTART2))) { + hsts = readl(host->ioaddr + SDHSTS); +@@ -358,9 +350,8 @@ static int bcm2835_transfer_pio(struct bcm2835_host *host) + + is_read = (host->data->flags & MMC_DATA_READ) != 0; + ret = bcm2835_transfer_block_pio(host, is_read); +- +- if (host->wait_data_complete) +- bcm2835_wait_transfer_complete(host); ++ if (ret) ++ return ret; + + sdhsts = readl(host->ioaddr + SDHSTS); + if (sdhsts & (SDHSTS_CRC16_ERROR | +@@ -379,21 +370,8 @@ static int bcm2835_transfer_pio(struct bcm2835_host *host) + return ret; + } + +-static void bcm2835_set_transfer_irqs(struct bcm2835_host *host) +-{ +- u32 all_irqs = SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN | +- SDHCFG_BUSY_IRPT_EN; +- +- host->hcfg = (host->hcfg & ~all_irqs) | +- SDHCFG_DATA_IRPT_EN | +- SDHCFG_BUSY_IRPT_EN; +- +- writel(host->hcfg, host->ioaddr + SDHCFG); +-} +- +-static +-void bcm2835_prepare_data(struct bcm2835_host *host, struct mmc_cmd *cmd, +- struct mmc_data *data) ++static void bcm2835_prepare_data(struct bcm2835_host *host, struct mmc_cmd *cmd, ++ struct mmc_data *data) + { + WARN_ON(host->data); + +@@ -401,14 +379,9 @@ void bcm2835_prepare_data(struct bcm2835_host *host, struct mmc_cmd *cmd, + if (!data) + return; + +- host->wait_data_complete = cmd->cmdidx != MMC_CMD_READ_MULTIPLE_BLOCK; +- host->data_complete = false; +- + /* Use PIO */ + host->blocks = data->blocks; + +- bcm2835_set_transfer_irqs(host); +- + writel(data->blocksize, host->ioaddr + SDHBCT); + writel(data->blocks, host->ioaddr + SDHBLC); + } +@@ -483,36 +456,6 @@ static int bcm2835_send_command(struct bcm2835_host *host, struct mmc_cmd *cmd, + return 0; + } + +-static int bcm2835_transfer_complete(struct bcm2835_host *host) +-{ +- int ret = 0; +- +- WARN_ON(!host->data_complete); +- +- host->data = NULL; +- +- return ret; +-} +- +-static void bcm2835_finish_data(struct bcm2835_host *host) +-{ +- host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); +- writel(host->hcfg, host->ioaddr + SDHCFG); +- +- host->data_complete = true; +- +- if (host->cmd) { +- /* Data managed to finish before the +- * command completed. Make sure we do +- * things in the proper order. +- */ +- dev_dbg(dev, "Finished early - HSTS %08x\n", +- readl(host->ioaddr + SDHSTS)); +- } else { +- bcm2835_transfer_complete(host); +- } +-} +- + static int bcm2835_finish_command(struct bcm2835_host *host) + { + struct mmc_cmd *cmd = host->cmd; +@@ -562,8 +505,6 @@ static int bcm2835_finish_command(struct bcm2835_host *host) + + /* Processed actual command. */ + host->cmd = NULL; +- if (host->data && host->data_complete) +- ret = bcm2835_transfer_complete(host); + + return ret; + } +@@ -608,159 +549,44 @@ static int bcm2835_check_data_error(struct bcm2835_host *host, u32 intmask) + return ret; + } + +-static void bcm2835_busy_irq(struct bcm2835_host *host) +-{ +- if (WARN_ON(!host->cmd)) { +- bcm2835_dumpregs(host); +- return; +- } +- +- if (WARN_ON(!host->use_busy)) { +- bcm2835_dumpregs(host); +- return; +- } +- host->use_busy = false; +- +- bcm2835_finish_command(host); +-} +- +-static void bcm2835_data_irq(struct bcm2835_host *host, u32 intmask) ++static int bcm2835_transmit(struct bcm2835_host *host) + { ++ u32 intmask = readl(host->ioaddr + SDHSTS); + int ret; + +- /* +- * There are no dedicated data/space available interrupt +- * status bits, so it is necessary to use the single shared +- * data/space available FIFO status bits. It is therefore not +- * an error to get here when there is no data transfer in +- * progress. +- */ +- if (!host->data) +- return; +- ++ /* Check for errors */ + ret = bcm2835_check_data_error(host, intmask); + if (ret) +- goto finished; +- +- if (host->data->flags & MMC_DATA_WRITE) { +- /* Use the block interrupt for writes after the first block */ +- host->hcfg &= ~(SDHCFG_DATA_IRPT_EN); +- host->hcfg |= SDHCFG_BLOCK_IRPT_EN; +- writel(host->hcfg, host->ioaddr + SDHCFG); +- bcm2835_transfer_pio(host); +- } else { +- bcm2835_transfer_pio(host); +- host->blocks--; +- if ((host->blocks == 0)) +- goto finished; +- } +- return; ++ return ret; + +-finished: +- host->hcfg &= ~(SDHCFG_DATA_IRPT_EN | SDHCFG_BLOCK_IRPT_EN); +- writel(host->hcfg, host->ioaddr + SDHCFG); +-} +- +-static void bcm2835_data_threaded_irq(struct bcm2835_host *host) +-{ +- if (!host->data) +- return; +- if ((host->blocks == 0)) +- bcm2835_finish_data(host); +-} +- +-static void bcm2835_block_irq(struct bcm2835_host *host) +-{ +- if (WARN_ON(!host->data)) { +- bcm2835_dumpregs(host); +- return; +- } +- +- WARN_ON(!host->blocks); +- if ((--host->blocks == 0)) +- bcm2835_finish_data(host); +- else +- bcm2835_transfer_pio(host); +-} ++ ret = bcm2835_check_cmd_error(host, intmask); ++ if (ret) ++ return ret; + +-static irqreturn_t bcm2835_irq(int irq, void *dev_id) +-{ +- irqreturn_t result = IRQ_NONE; +- struct bcm2835_host *host = dev_id; +- u32 intmask; +- +- intmask = readl(host->ioaddr + SDHSTS); +- +- writel(SDHSTS_BUSY_IRPT | +- SDHSTS_BLOCK_IRPT | +- SDHSTS_SDIO_IRPT | +- SDHSTS_DATA_FLAG, +- host->ioaddr + SDHSTS); +- +- if (intmask & SDHSTS_BLOCK_IRPT) { +- bcm2835_check_data_error(host, intmask); +- host->irq_block = true; +- result = IRQ_WAKE_THREAD; ++ /* Handle wait for busy end */ ++ if (host->use_busy && (intmask & SDHSTS_BUSY_IRPT)) { ++ writel(SDHSTS_BUSY_IRPT, host->ioaddr + SDHSTS); ++ host->use_busy = false; ++ bcm2835_finish_command(host); + } + +- if (intmask & SDHSTS_BUSY_IRPT) { +- if (!bcm2835_check_cmd_error(host, intmask)) { +- host->irq_busy = true; +- result = IRQ_WAKE_THREAD; +- } else { +- result = IRQ_HANDLED; ++ /* Handle PIO data transfer */ ++ if (host->data) { ++ ret = bcm2835_transfer_pio(host); ++ if (ret) ++ return ret; ++ host->blocks--; ++ if (host->blocks == 0) { ++ /* Wait for command to complete for real */ ++ ret = bcm2835_wait_transfer_complete(host); ++ if (ret) ++ return ret; ++ /* Transfer complete */ ++ host->data = NULL; + } + } + +- /* There is no true data interrupt status bit, so it is +- * necessary to qualify the data flag with the interrupt +- * enable bit. +- */ +- if ((intmask & SDHSTS_DATA_FLAG) && +- (host->hcfg & SDHCFG_DATA_IRPT_EN)) { +- bcm2835_data_irq(host, intmask); +- host->irq_data = true; +- result = IRQ_WAKE_THREAD; +- } +- +- return result; +-} +- +-static irqreturn_t bcm2835_threaded_irq(int irq, void *dev_id) +-{ +- struct bcm2835_host *host = dev_id; +- +- if (host->irq_block) { +- host->irq_block = false; +- bcm2835_block_irq(host); +- } +- +- if (host->irq_busy) { +- host->irq_busy = false; +- bcm2835_busy_irq(host); +- } +- +- if (host->irq_data) { +- host->irq_data = false; +- bcm2835_data_threaded_irq(host); +- } +- +- return IRQ_HANDLED; +-} +- +-static void bcm2835_irq_poll(struct bcm2835_host *host) +-{ +- u32 intmask; +- +- while (1) { +- intmask = readl(host->ioaddr + SDHSTS); +- if (intmask & (SDHSTS_BUSY_IRPT | SDHSTS_BLOCK_IRPT | +- SDHSTS_SDIO_IRPT | SDHSTS_DATA_FLAG)) { +- bcm2835_irq(0, host); +- bcm2835_threaded_irq(0, host); +- return; +- } +- } ++ return 0; + } + + static void bcm2835_set_clock(struct bcm2835_host *host, unsigned int clock) +@@ -864,8 +690,11 @@ static int bcm2835_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + } + + /* Wait for completion of busy signal or data transfer */ +- while (host->use_busy || host->data) +- bcm2835_irq_poll(host); ++ while (host->use_busy || host->data) { ++ ret = bcm2835_transmit(host); ++ if (ret) ++ break; ++ } + + return ret; + } +