diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/exynos/clk-pll.h | 5 | ||||
-rw-r--r-- | drivers/i2c/i2c-uclass.c | 2 | ||||
-rw-r--r-- | drivers/mmc/renesas-sdhi.c | 14 | ||||
-rw-r--r-- | drivers/mtd/spi/Kconfig | 5 | ||||
-rw-r--r-- | drivers/mtd/spi/spi-nor-ids.c | 5 | ||||
-rw-r--r-- | drivers/power/Kconfig | 1 | ||||
-rw-r--r-- | drivers/scsi/scsi.c | 2 | ||||
-rw-r--r-- | drivers/serial/serial_s5p.c | 79 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-generic.c | 1 | ||||
-rw-r--r-- | drivers/usb/gadget/ci_udc.c | 38 | ||||
-rw-r--r-- | drivers/usb/gadget/f_fastboot.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/Kconfig | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 72 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 9 | ||||
-rw-r--r-- | drivers/virtio/virtio_rng.c | 9 | ||||
-rw-r--r-- | drivers/watchdog/s5p_wdt.c | 1 | ||||
-rw-r--r-- | drivers/watchdog/wdt-uclass.c | 3 |
17 files changed, 187 insertions, 63 deletions
diff --git a/drivers/clk/exynos/clk-pll.h b/drivers/clk/exynos/clk-pll.h index c79aac4425..7b7af5e676 100644 --- a/drivers/clk/exynos/clk-pll.h +++ b/drivers/clk/exynos/clk-pll.h @@ -5,4 +5,9 @@ * Thomas Abraham <thomas.ab@samsung.com> */ +#ifndef __EXYNOS_CLK_PLL_H +#define __EXYNOS_CLK_PLL_H + unsigned long pll145x_get_rate(unsigned int *con1, unsigned long fin_freq); + +#endif /* __EXYNOS_CLK_PLL_H */ diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index 5405067861..98f95859f3 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -427,7 +427,7 @@ int i2c_get_chip_by_phandle(const struct udevice *parent, const char *prop_name, goto err_exit; } - ret = dev_read_u32(parent, "i2cbcdev", &phandle); + ret = dev_read_u32(parent, prop_name, &phandle); if (ret) goto err_exit; diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 8cd501c5f7..97aaf1e4ec 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -318,7 +318,7 @@ static unsigned int renesas_sdhi_init_tuning(struct tmio_sd_priv *priv) RENESAS_SDHI_SCC_DTCNTL_TAPNUM_MASK; } -static void renesas_sdhi_reset_tuning(struct tmio_sd_priv *priv) +static void renesas_sdhi_reset_tuning(struct tmio_sd_priv *priv, bool clk_disable) { u32 reg; @@ -350,6 +350,12 @@ static void renesas_sdhi_reset_tuning(struct tmio_sd_priv *priv) reg = tmio_sd_readl(priv, RENESAS_SDHI_SCC_RVSCNTL); reg &= ~RENESAS_SDHI_SCC_RVSCNTL_RVSEN; tmio_sd_writel(priv, reg, RENESAS_SDHI_SCC_RVSCNTL); + + if (clk_disable) { + reg = tmio_sd_readl(priv, TMIO_SD_CLKCTL); + reg &= ~TMIO_SD_CLKCTL_SCLKEN; + tmio_sd_writel(priv, reg, TMIO_SD_CLKCTL); + } } static int renesas_sdhi_hs400(struct udevice *dev) @@ -629,7 +635,7 @@ int renesas_sdhi_execute_tuning(struct udevice *dev, uint opcode) out: if (ret < 0) { dev_warn(dev, "Tuning procedure failed\n"); - renesas_sdhi_reset_tuning(priv); + renesas_sdhi_reset_tuning(priv, true); } return ret; @@ -668,7 +674,7 @@ static int renesas_sdhi_set_ios(struct udevice *dev) (mmc->selected_mode != UHS_SDR104) && (mmc->selected_mode != MMC_HS_200) && (mmc->selected_mode != MMC_HS_400)) { - renesas_sdhi_reset_tuning(priv); + renesas_sdhi_reset_tuning(priv, mmc->clk_disable); } #endif @@ -1095,7 +1101,7 @@ static int renesas_sdhi_probe(struct udevice *dev) CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \ CONFIG_IS_ENABLED(MMC_HS400_SUPPORT) if (priv->caps & TMIO_SD_CAP_RCAR_UHS) - renesas_sdhi_reset_tuning(priv); + renesas_sdhi_reset_tuning(priv, true); #endif return 0; diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 732b076045..abed392c28 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -224,6 +224,11 @@ config SPI_FLASH_XTX Add support for various XTX (XTX Technology Limited) SPI flash chips (XT25xxx). +config SPI_FLASH_ZBIT + bool "ZBIT SPI flash support" + help + Add support for Zbit Semiconductor Inc. SPI flash chips (ZB25xxx). + endif config SPI_FLASH_USE_4K_SECTORS diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 3cb132dcff..f86e7ff8e5 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -572,5 +572,10 @@ const struct flash_info spi_nor_ids[] = { { INFO("xt25w01g", 0x0b651B, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, #endif +#ifdef CONFIG_SPI_FLASH_ZBIT + /* Zbit Semiconductor Inc. */ + { INFO("zb25vq128", 0x5e4018, 0, 64 * 1024, 256, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, +#endif { }, }; diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 2395720c99..33b8bc1214 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -56,7 +56,6 @@ choice depends on ARCH_SUNXI default AXP209_POWER if MACH_SUN4I || MACH_SUN5I || MACH_SUN7I default AXP221_POWER if MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_R40 - default AXP305_POWER if MACH_SUN50I_H616 default AXP818_POWER if MACH_SUN8I_A83T default SUNXI_NO_PMIC if MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_V3S diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index b76aadb065..1330482c16 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -374,6 +374,7 @@ static int scsi_read_capacity(struct udevice *dev, struct scsi_cmd *pccb, pccb->cmd[0] = SCSI_RD_CAPAC10; pccb->cmd[1] = pccb->lun << 5; pccb->cmdlen = 10; + pccb->dma_dir = DMA_FROM_DEVICE; pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */ pccb->datalen = 8; @@ -538,6 +539,7 @@ static int scsi_detect_dev(struct udevice *dev, int target, int lun, for (count = 0; count < 3; count++) { pccb->datalen = 0; + pccb->dma_dir = DMA_NONE; scsi_setup_test_unit_ready(pccb); err = scsi_exec(dev, pccb); if (!err) diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c index 7aeb8c0f8c..7d04dcff54 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -7,7 +7,6 @@ * based on drivers/serial/s3c64xx.c */ -#include <common.h> #include <dm.h> #include <errno.h> #include <fdtdec.h> @@ -21,32 +20,39 @@ #include <serial.h> #include <clk.h> -DECLARE_GLOBAL_DATA_PTR; - enum { PORT_S5P = 0, PORT_S5L }; +#define UFCON_FIFO_EN BIT(0) +#define UFCON_RX_FIFO_RESET BIT(1) +#define UMCON_RESET_VAL 0x0 +#define ULCON_WORD_8_BIT 0x3 +#define UCON_RX_IRQ_OR_POLLING BIT(0) +#define UCON_TX_IRQ_OR_POLLING BIT(2) +#define UCON_RX_ERR_IRQ_EN BIT(6) +#define UCON_TX_IRQ_LEVEL BIT(9) + #define S5L_RX_FIFO_COUNT_SHIFT 0 #define S5L_RX_FIFO_COUNT_MASK (0xf << S5L_RX_FIFO_COUNT_SHIFT) -#define S5L_RX_FIFO_FULL (1 << 8) +#define S5L_RX_FIFO_FULL BIT(8) #define S5L_TX_FIFO_COUNT_SHIFT 4 #define S5L_TX_FIFO_COUNT_MASK (0xf << S5L_TX_FIFO_COUNT_SHIFT) -#define S5L_TX_FIFO_FULL (1 << 9) +#define S5L_TX_FIFO_FULL BIT(9) #define S5P_RX_FIFO_COUNT_SHIFT 0 #define S5P_RX_FIFO_COUNT_MASK (0xff << S5P_RX_FIFO_COUNT_SHIFT) -#define S5P_RX_FIFO_FULL (1 << 8) +#define S5P_RX_FIFO_FULL BIT(8) #define S5P_TX_FIFO_COUNT_SHIFT 16 #define S5P_TX_FIFO_COUNT_MASK (0xff << S5P_TX_FIFO_COUNT_SHIFT) -#define S5P_TX_FIFO_FULL (1 << 24) +#define S5P_TX_FIFO_FULL BIT(24) /* Information about a serial port */ struct s5p_serial_plat { - struct s5p_uart *reg; /* address of registers in physical memory */ - u8 reg_width; /* register width */ - u8 port_id; /* uart port number */ + struct s5p_uart *reg; /* address of registers in physical memory */ + u8 reg_width; /* register width */ + u8 port_id; /* uart port number */ u8 rx_fifo_count_shift; u8 tx_fifo_count_shift; u32 rx_fifo_count_mask; @@ -59,7 +65,7 @@ struct s5p_serial_plat { * The coefficient, used to calculate the baudrate on S5P UARTs is * calculated as * C = UBRDIV * 16 + number_of_set_bits_in_UDIVSLOT - * however, section 31.6.11 of the datasheet doesn't recomment using 1 for 1, + * however, section 31.6.11 of the datasheet doesn't recommend using 1 for 1, * 3 for 2, ... (2^n - 1) for n, instead, they suggest using these constants: */ static const int udivslot[] = { @@ -83,13 +89,15 @@ static const int udivslot[] = { static void __maybe_unused s5p_serial_init(struct s5p_uart *uart) { - /* enable FIFOs, auto clear Rx FIFO */ - writel(0x3, &uart->ufcon); - writel(0, &uart->umcon); - /* 8N1 */ - writel(0x3, &uart->ulcon); + /* Enable FIFOs, auto clear Rx FIFO */ + writel(UFCON_FIFO_EN | UFCON_RX_FIFO_RESET, &uart->ufcon); + /* No auto flow control, disable nRTS signal */ + writel(UMCON_RESET_VAL, &uart->umcon); + /* 8N1, no parity bit */ + writel(ULCON_WORD_8_BIT, &uart->ulcon); /* No interrupts, no DMA, pure polling */ - writel(0x245, &uart->ucon); + writel(UCON_RX_IRQ_OR_POLLING | UCON_TX_IRQ_OR_POLLING | + UCON_RX_ERR_IRQ_EN | UCON_TX_IRQ_LEVEL, &uart->ucon); } static void __maybe_unused s5p_serial_baud(struct s5p_uart *uart, u8 reg_width, @@ -118,7 +126,7 @@ int s5p_serial_setbrg(struct udevice *dev, int baudrate) #if IS_ENABLED(CONFIG_CLK_EXYNOS) || IS_ENABLED(CONFIG_ARCH_APPLE) struct clk clk; - u32 ret; + int ret; ret = clk_get_by_index(dev, 1, &clk); if (ret < 0) @@ -213,16 +221,13 @@ static int s5p_serial_of_to_plat(struct udevice *dev) { struct s5p_serial_plat *plat = dev_get_plat(dev); const ulong port_type = dev_get_driver_data(dev); - fdt_addr_t addr; - addr = dev_read_addr(dev); - if (addr == FDT_ADDR_T_NONE) + plat->reg = dev_read_addr_ptr(dev); + if (!plat->reg) return -EINVAL; - plat->reg = (struct s5p_uart *)addr; plat->reg_width = dev_read_u32_default(dev, "reg-io-width", 1); - plat->port_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), - "id", dev_seq(dev)); + plat->port_id = dev_read_u8_default(dev, "id", dev_seq(dev)); if (port_type == PORT_S5L) { plat->rx_fifo_count_shift = S5L_RX_FIFO_COUNT_SHIFT; @@ -244,10 +249,10 @@ static int s5p_serial_of_to_plat(struct udevice *dev) } static const struct dm_serial_ops s5p_serial_ops = { - .putc = s5p_serial_putc, - .pending = s5p_serial_pending, - .getc = s5p_serial_getc, - .setbrg = s5p_serial_setbrg, + .putc = s5p_serial_putc, + .pending = s5p_serial_pending, + .getc = s5p_serial_getc, + .setbrg = s5p_serial_setbrg, }; static const struct udevice_id s5p_serial_ids[] = { @@ -257,13 +262,13 @@ static const struct udevice_id s5p_serial_ids[] = { }; U_BOOT_DRIVER(serial_s5p) = { - .name = "serial_s5p", - .id = UCLASS_SERIAL, - .of_match = s5p_serial_ids, - .of_to_plat = s5p_serial_of_to_plat, + .name = "serial_s5p", + .id = UCLASS_SERIAL, + .of_match = s5p_serial_ids, + .of_to_plat = s5p_serial_of_to_plat, .plat_auto = sizeof(struct s5p_serial_plat), - .probe = s5p_serial_probe, - .ops = &s5p_serial_ops, + .probe = s5p_serial_probe, + .ops = &s5p_serial_ops, }; #endif @@ -291,10 +296,12 @@ static inline void _debug_uart_putc(int ch) struct s5p_uart *uart = (struct s5p_uart *)CONFIG_VAL(DEBUG_UART_BASE); #if IS_ENABLED(CONFIG_ARCH_APPLE) - while (readl(&uart->ufstat) & S5L_TX_FIFO_FULL); + while (readl(&uart->ufstat) & S5L_TX_FIFO_FULL) + ; writel(ch, &uart->utxh); #else - while (readl(&uart->ufstat) & S5P_TX_FIFO_FULL); + while (readl(&uart->ufstat) & S5P_TX_FIFO_FULL) + ; writeb(ch, &uart->utxh); #endif } diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 744fde8069..6fb2de8a5a 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -610,6 +610,7 @@ static const struct udevice_id dwc3_glue_ids[] = { { .compatible = "rockchip,rk3328-dwc3", .data = (ulong)&rk_ops }, { .compatible = "rockchip,rk3399-dwc3" }, { .compatible = "rockchip,rk3568-dwc3", .data = (ulong)&rk_ops }, + { .compatible = "rockchip,rk3588-dwc3", .data = (ulong)&rk_ops }, { .compatible = "qcom,dwc3" }, { .compatible = "fsl,imx8mp-dwc3", .data = (ulong)&imx8mp_ops }, { .compatible = "fsl,imx8mq-dwc3" }, diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c index 2bfacfe59f..750d471487 100644 --- a/drivers/usb/gadget/ci_udc.c +++ b/drivers/usb/gadget/ci_udc.c @@ -13,6 +13,7 @@ #include <cpu_func.h> #include <net.h> #include <malloc.h> +#include <wait_bit.h> #include <asm/byteorder.h> #include <asm/cache.h> #include <linux/delay.h> @@ -354,12 +355,49 @@ static int ci_ep_enable(struct usb_ep *ep, return 0; } +static int ep_disable(int num, int in) +{ + struct ci_udc *udc = (struct ci_udc *)controller.ctrl->hcor; + unsigned int ep_bit, enable_bit; + int err; + + if (in) { + ep_bit = EPT_TX(num); + enable_bit = CTRL_TXE; + } else { + ep_bit = EPT_RX(num); + enable_bit = CTRL_RXE; + } + + /* clear primed buffers */ + do { + writel(ep_bit, &udc->epflush); + err = wait_for_bit_le32(&udc->epflush, ep_bit, false, 1000, false); + if (err) + return err; + } while (readl(&udc->epstat) & ep_bit); + + /* clear enable bit */ + clrbits_le32(&udc->epctrl[num], enable_bit); + + return 0; +} + static int ci_ep_disable(struct usb_ep *ep) { struct ci_ep *ci_ep = container_of(ep, struct ci_ep, ep); + int num, in, err; + + num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + in = (ci_ep->desc->bEndpointAddress & USB_DIR_IN) != 0; + + err = ep_disable(num, in); + if (err) + return err; ci_ep->desc = NULL; ep->desc = NULL; + ci_ep->req_primed = false; return 0; } diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 741775a7bc..9f322c9550 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -520,7 +520,7 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) cmdbuf[req->actual] = '\0'; cmd = fastboot_handle_command(cmdbuf, response); } else { - pr_err("buffer overflow"); + pr_err("buffer overflow\n"); fastboot_fail("buffer overflow", response); } diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index b501ea514b..35610ffc2b 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -90,7 +90,7 @@ config USB_XHCI_OMAP config USB_XHCI_PCI bool "Support for PCI-based xHCI USB controller" - depends on DM_USB + depends on DM_USB && PCI default y if X86 help Enables support for the PCI-based xHCI controller. diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index c8260cbdf9..b60661fe05 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -202,6 +202,7 @@ static dma_addr_t queue_trb(struct xhci_ctrl *ctrl, struct xhci_ring *ring, bool more_trbs_coming, unsigned int *trb_fields) { struct xhci_generic_trb *trb; + dma_addr_t addr; int i; trb = &ring->enqueue->generic; @@ -211,9 +212,11 @@ static dma_addr_t queue_trb(struct xhci_ctrl *ctrl, struct xhci_ring *ring, xhci_flush_cache((uintptr_t)trb, sizeof(struct xhci_generic_trb)); + addr = xhci_trb_virt_to_dma(ring->enq_seg, (union xhci_trb *)trb); + inc_enq(ctrl, ring, more_trbs_coming); - return xhci_trb_virt_to_dma(ring->enq_seg, (union xhci_trb *)trb); + return addr; } /** @@ -243,7 +246,8 @@ static int prepare_ring(struct xhci_ctrl *ctrl, struct xhci_ring *ep_ring, puts("WARN waiting for error on ep to be cleared\n"); return -EINVAL; case EP_STATE_HALTED: - puts("WARN halted endpoint, queueing URB anyway.\n"); + puts("WARN endpoint is halted\n"); + return -EINVAL; case EP_STATE_STOPPED: case EP_STATE_RUNNING: debug("EP STATE RUNNING.\n"); @@ -466,7 +470,8 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected) continue; type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags)); - if (type == expected) + if (type == expected || + (expected == TRB_NONE && type != TRB_PORT_STATUS)) return event; if (type == TRB_PORT_STATUS) @@ -492,8 +497,9 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected) if (expected == TRB_TRANSFER) return NULL; - printf("XHCI timeout on event type %d... cannot recover.\n", expected); - BUG(); + printf("XHCI timeout on event type %d...\n", expected); + + return NULL; } /* @@ -511,6 +517,9 @@ static void reset_ep(struct usb_device *udev, int ep_index) printf("Resetting EP %d...\n", ep_index); xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_RESET_EP); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return; + field = le32_to_cpu(event->trans_event.flags); BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id); xhci_acknowledge_event(ctrl); @@ -519,6 +528,9 @@ static void reset_ep(struct usb_device *udev, int ep_index) (void *)((uintptr_t)ring->enqueue | ring->cycle_state)); xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return; + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id || GET_COMP_CODE(le32_to_cpu( event->event_cmd.status)) != COMP_SUCCESS); @@ -538,29 +550,49 @@ static void abort_td(struct usb_device *udev, int ep_index) struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); struct xhci_ring *ring = ctrl->devs[udev->slot_id]->eps[ep_index].ring; union xhci_trb *event; + xhci_comp_code comp; + trb_type type; u64 addr; u32 field; xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_STOP_RING); - event = xhci_wait_for_event(ctrl, TRB_TRANSFER); - field = le32_to_cpu(event->trans_event.flags); - BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id); - BUG_ON(TRB_TO_EP_INDEX(field) != ep_index); - BUG_ON(GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len - != COMP_STOP))); - xhci_acknowledge_event(ctrl); + event = xhci_wait_for_event(ctrl, TRB_NONE); + if (!event) + return; - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); - BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) - != udev->slot_id || GET_COMP_CODE(le32_to_cpu( - event->event_cmd.status)) != COMP_SUCCESS); + type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags)); + if (type == TRB_TRANSFER) { + field = le32_to_cpu(event->trans_event.flags); + BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id); + BUG_ON(TRB_TO_EP_INDEX(field) != ep_index); + BUG_ON(GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len + != COMP_STOP))); + xhci_acknowledge_event(ctrl); + + event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return; + type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags)); + + } else { + printf("abort_td: Expected a TRB_TRANSFER TRB first\n"); + } + + comp = GET_COMP_CODE(le32_to_cpu(event->event_cmd.status)); + BUG_ON(type != TRB_COMPLETION || + TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) + != udev->slot_id || (comp != COMP_SUCCESS && comp + != COMP_CTX_STATE)); xhci_acknowledge_event(ctrl); addr = xhci_trb_virt_to_dma(ring->enq_seg, (void *)((uintptr_t)ring->enqueue | ring->cycle_state)); xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return; + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id || GET_COMP_CODE(le32_to_cpu( event->event_cmd.status)) != COMP_SUCCESS); @@ -644,6 +676,14 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, ep_ctx = xhci_get_ep_ctx(ctrl, virt_dev->out_ctx, ep_index); + /* + * If the endpoint was halted due to a prior error, resume it before + * the next transfer. It is the responsibility of the upper layer to + * have dealt with whatever caused the error. + */ + if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK) == EP_STATE_HALTED) + reset_ep(udev, ep_index); + ring = virt_dev->eps[ep_index].ring; /* * How much data is (potentially) left before the 64KB boundary? diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 5cacf0769e..d13cbff9b3 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -451,6 +451,9 @@ static int xhci_configure_endpoints(struct usb_device *udev, bool ctx_change) xhci_queue_command(ctrl, in_ctx->dma, udev->slot_id, 0, ctx_change ? TRB_EVAL_CONTEXT : TRB_CONFIG_EP); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return -ETIMEDOUT; + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id); @@ -647,6 +650,9 @@ static int xhci_address_device(struct usb_device *udev, int root_portnr) xhci_queue_command(ctrl, virt_dev->in_ctx->dma, slot_id, 0, TRB_ADDR_DEV); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return -ETIMEDOUT; + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != slot_id); switch (GET_COMP_CODE(le32_to_cpu(event->event_cmd.status))) { @@ -722,6 +728,9 @@ static int _xhci_alloc_device(struct usb_device *udev) xhci_queue_command(ctrl, 0, 0, 0, TRB_ENABLE_SLOT); event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + if (!event) + return -ETIMEDOUT; + BUG_ON(GET_COMP_CODE(le32_to_cpu(event->event_cmd.status)) != COMP_SUCCESS); diff --git a/drivers/virtio/virtio_rng.c b/drivers/virtio/virtio_rng.c index b85545c2ee..786359a6e3 100644 --- a/drivers/virtio/virtio_rng.c +++ b/drivers/virtio/virtio_rng.c @@ -20,7 +20,7 @@ struct virtio_rng_priv { static int virtio_rng_read(struct udevice *dev, void *data, size_t len) { int ret; - unsigned int rsize; + unsigned int rsize = 1; unsigned char buf[BUFFER_SIZE] __aligned(4); unsigned char *ptr = data; struct virtio_sg sg; @@ -29,7 +29,12 @@ static int virtio_rng_read(struct udevice *dev, void *data, size_t len) while (len) { sg.addr = buf; - sg.length = min(len, sizeof(buf)); + /* + * Work around implementations which always return 8 bytes + * less than requested, down to 0 bytes, which would + * cause an endless loop otherwise. + */ + sg.length = min(rsize ? len : len + 8, sizeof(buf)); sgs[0] = &sg; ret = virtqueue_add(priv->rng_vq, sgs, 0, 1); diff --git a/drivers/watchdog/s5p_wdt.c b/drivers/watchdog/s5p_wdt.c index 5ad7d2609f..80524a0010 100644 --- a/drivers/watchdog/s5p_wdt.c +++ b/drivers/watchdog/s5p_wdt.c @@ -6,6 +6,7 @@ #include <common.h> #include <asm/io.h> +#include <asm/arch/cpu.h> #include <asm/arch/watchdog.h> #define PRESCALER_VAL 255 diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c index ed329284de..417e8d7eef 100644 --- a/drivers/watchdog/wdt-uclass.c +++ b/drivers/watchdog/wdt-uclass.c @@ -7,6 +7,7 @@ #include <common.h> #include <cyclic.h> +#include <div64.h> #include <dm.h> #include <errno.h> #include <hang.h> @@ -141,7 +142,7 @@ int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) printf("WDT: Started %s with%s servicing %s (%ds timeout)\n", dev->name, IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", - str, priv->timeout); + str, (u32)lldiv(timeout_ms, 1000)); } return ret; |