diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2022-04-21 11:16:09 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2022-04-21 11:16:09 +0200 |
commit | 4811863eae2d1e710862e10d7171edbe8041056f (patch) | |
tree | 8899ceeff211b381ec7f08e2dc6c8a3d44f4a1e7 /drivers | |
parent | 7a942b81e4d10b4f729c19b09b5d330bfeb6ba0e (diff) | |
parent | aaac1c35ed14c81a8ffc93874f8b004deae9e172 (diff) | |
download | barebox-4811863eae2d1e710862e10d7171edbe8041056f.tar.gz barebox-4811863eae2d1e710862e10d7171edbe8041056f.tar.xz |
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/ide-sff.c | 2 | ||||
-rw-r--r-- | drivers/gpio/gpio-clps711x.c | 10 | ||||
-rw-r--r-- | drivers/gpio/gpiolib.c | 26 | ||||
-rw-r--r-- | drivers/mci/mci_spi.c | 31 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/spi-nor.c | 2 | ||||
-rw-r--r-- | drivers/net/designware_eqos.c | 14 | ||||
-rw-r--r-- | drivers/net/phy/Kconfig | 6 | ||||
-rw-r--r-- | drivers/net/phy/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/phy/dp83td510.c | 45 | ||||
-rw-r--r-- | drivers/net/phy/mv88e6xxx/chip.c | 28 | ||||
-rw-r--r-- | drivers/net/phy/mv88e6xxx/chip.h | 1 | ||||
-rw-r--r-- | drivers/net/phy/mv88e6xxx/port.c | 12 | ||||
-rw-r--r-- | drivers/net/phy/mv88e6xxx/port.h | 2 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 13 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 29 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 17 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 8 |
17 files changed, 189 insertions, 58 deletions
diff --git a/drivers/ata/ide-sff.c b/drivers/ata/ide-sff.c index 7884b62bab..69055e0585 100644 --- a/drivers/ata/ide-sff.c +++ b/drivers/ata/ide-sff.c @@ -96,7 +96,7 @@ static int ata_wait_busy(struct ide_port *ide, unsigned timeout) { uint8_t status; uint64_t start = get_time_ns(); - uint64_t toffs = timeout * 1000 * 1000; + uint64_t toffs = timeout * MSECOND; do { status = ata_rd_status(ide); diff --git a/drivers/gpio/gpio-clps711x.c b/drivers/gpio/gpio-clps711x.c index 67bce79bc3..a1965b33e4 100644 --- a/drivers/gpio/gpio-clps711x.c +++ b/drivers/gpio/gpio-clps711x.c @@ -25,17 +25,15 @@ static int clps711x_gpio_probe(struct device_d *dev) return PTR_ERR(iores); dat = IOMEM(iores->start); + iores = dev_request_mem_resource(dev, 1); + if (IS_ERR(iores)) + return PTR_ERR(iores); + switch (id) { case 3: - iores = dev_request_mem_resource(dev, 1); - if (IS_ERR(iores)) - return PTR_ERR(iores); dir_inv = IOMEM(iores->start); break; default: - iores = dev_request_mem_resource(dev, 1); - if (IS_ERR(iores)) - return PTR_ERR(iores); dir = IOMEM(iores->start); break; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f709d11f75..c9b33bcd6c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -414,22 +414,19 @@ free_array: } EXPORT_SYMBOL(gpio_array_to_id); -static int gpiochip_find_base(int start, int ngpio) +static int gpiochip_find_base(int ngpio) { int i; int spare = 0; int base = -ENOSPC; - if (start < 0) - start = 0; - - for (i = start; i < ARCH_NR_GPIOS; i++) { + for (i = ARCH_NR_GPIOS - 1; i >= 0; i--) { struct gpio_chip *chip = gpio_desc[i].chip; if (!chip) { spare++; if (spare == ngpio) { - base = i + 1 - ngpio; + base = i; break; } } else { @@ -614,14 +611,17 @@ int gpiochip_add(struct gpio_chip *chip) { int base, i; - base = gpiochip_find_base(chip->base, chip->ngpio); - if (base < 0) - return base; - - if (chip->base >= 0 && chip->base != base) - return -EBUSY; + if (chip->base >= 0) { + for (i = 0; i < chip->ngpio; i++) { + if (gpio_desc[chip->base + i].chip) + return -EBUSY; + } + } else { + chip->base = gpiochip_find_base(chip->ngpio); + if (chip->base < 0) + return -ENOSPC; + } - chip->base = base; list_add_tail(&chip->list, &chip_list); diff --git a/drivers/mci/mci_spi.c b/drivers/mci/mci_spi.c index ed3ddf890f..6ae2824edd 100644 --- a/drivers/mci/mci_spi.c +++ b/drivers/mci/mci_spi.c @@ -18,6 +18,8 @@ #include <mci.h> #include <crc.h> #include <crc7.h> +#include <of.h> +#include <gpiod.h> #define to_spi_host(mci) container_of(mci, struct mmc_spi_host, mci) #define spi_setup(spi) spi->master->setup(spi) @@ -47,6 +49,7 @@ struct mmc_spi_host { struct mci_host mci; struct spi_device *spi; struct device_d *dev; + int detect_pin; /* for bulk data transfers */ struct spi_transfer t_tx; @@ -351,8 +354,23 @@ static int mmc_spi_init(struct mci_host *mci, struct device_d *mci_dev) return 0; } +static int spi_mci_card_present(struct mci_host *mci) +{ + struct mmc_spi_host *host = to_spi_host(mci); + int ret; + + /* No gpio, assume card is present */ + if (!gpio_is_valid(host->detect_pin)) + return 1; + + ret = gpio_get_value(host->detect_pin); + + return ret == 0 ? 1 : 0; +} + static int spi_mci_probe(struct device_d *dev) { + struct device_node *np = dev_of_node(dev); struct spi_device *spi = (struct spi_device *)dev->type_data; struct mmc_spi_host *host; void *ones; @@ -362,6 +380,7 @@ static int spi_mci_probe(struct device_d *dev) host->mci.send_cmd = mmc_spi_request; host->mci.set_ios = mmc_spi_set_ios; host->mci.init = mmc_spi_init; + host->mci.card_present = spi_mci_card_present; host->mci.hw_dev = dev; /* MMC and SD specs only seem to care that sampling is on the @@ -415,14 +434,26 @@ static int spi_mci_probe(struct device_d *dev) host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34; host->mci.host_caps = MMC_CAP_SPI; + host->detect_pin = -EINVAL; + + if (np) { + host->mci.devname = xstrdup(of_alias_get(np)); + host->detect_pin = gpiod_get(dev, NULL, GPIOD_IN); + } mci_register(&host->mci); return 0; } +static __maybe_unused struct of_device_id spi_mci_compatible[] = { + { .compatible = "mmc-spi-slot" }, + { /* sentinel */ } +}; + static struct driver_d spi_mci_driver = { .name = "spi_mci", .probe = spi_mci_probe, + .of_compatible = DRV_OF_COMPAT(spi_mci_compatible), }; device_spi_driver(spi_mci_driver); diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index cf532b1399..0ed7fd3d04 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -697,6 +697,8 @@ static const struct spi_device_id spi_nor_ids[] = { SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "is25wp128", INFO(0x9d7018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "is25wp256", INFO(0x9d7019, 0, 64 * 1024, 512, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "is25lq128", INFO(0x9d6018, 0, 64 * 1024, 256, 0) }, /* Macronix */ diff --git a/drivers/net/designware_eqos.c b/drivers/net/designware_eqos.c index 8d2a21c220..6b372e4274 100644 --- a/drivers/net/designware_eqos.c +++ b/drivers/net/designware_eqos.c @@ -112,6 +112,8 @@ struct eqos_mtl_regs { #define EQOS_MTL_RXQ0_OPERATION_MODE_RFA_MASK 0x3f #define EQOS_MTL_RXQ0_OPERATION_MODE_EHFC BIT(7) #define EQOS_MTL_RXQ0_OPERATION_MODE_RSF BIT(5) +#define EQOS_MTL_RXQ0_OPERATION_MODE_FEP BIT(4) +#define EQOS_MTL_RXQ0_OPERATION_MODE_FUP BIT(3) #define EQOS_MTL_RXQ0_DEBUG_PRXQ_SHIFT 16 #define EQOS_MTL_RXQ0_DEBUG_PRXQ_MASK 0x7fff @@ -415,9 +417,11 @@ static int eqos_start(struct eth_device *edev) /* Before we reset the mac, we must insure the PHY is not powered down * as the dw controller needs all clock domains to be running, including * the PHY clock, to come out of a mac reset. */ - ret = phy_resume(edev->phydev); - if (ret) - return ret; + if (edev->phydev) { + ret = phy_resume(edev->phydev); + if (ret) + return ret; + } /* Configure MTL */ @@ -433,7 +437,9 @@ static int eqos_start(struct eth_device *edev) /* Enable Store and Forward mode for RX, since no jumbo frame */ setbits_le32(&eqos->mtl_regs->rxq0_operation_mode, - EQOS_MTL_RXQ0_OPERATION_MODE_RSF); + EQOS_MTL_RXQ0_OPERATION_MODE_RSF | + EQOS_MTL_RXQ0_OPERATION_MODE_FEP | + EQOS_MTL_RXQ0_OPERATION_MODE_FUP); /* Transmit/Receive queue fifo size; use all RAM for 1 queue */ val = readl(&eqos->mac_regs->hw_feature1); diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 9f74335443..cd20e1de27 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -29,6 +29,12 @@ config DP83867_PHY help Currently supports the DP83867 PHY. +config DP83TD510_PHY + tristate "Texas Instruments DP83TD510 Ethernet 10Base-T1L PHY" + help + Support for the DP83TD510 Ethernet 10Base-T1L PHY. This PHY supports + a 10M single pair Ethernet connection for up to 1000 meter cable. + config LXT_PHY bool "Driver for the Intel LXT PHYs" help diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 54b83e06dd..83f46f11d3 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -17,4 +17,5 @@ obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o obj-$(CONFIG_MDIO_BUS_MUX) += mdio-mux.o obj-$(CONFIG_MDIO_BUS_MUX_GPIO) += mdio-mux-gpio.o obj-$(CONFIG_DP83867_PHY) += dp83867.o +obj-$(CONFIG_DP83TD510_PHY) += dp83td510.o diff --git a/drivers/net/phy/dp83td510.c b/drivers/net/phy/dp83td510.c new file mode 100644 index 0000000000..44c551e795 --- /dev/null +++ b/drivers/net/phy/dp83td510.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <common.h> +#include <linux/phy.h> + +#define DP83TD510E_PHY_ID 0x20000181 + +#define DP83TD510E_PHY_STS 0x10 +#define DP83TD510E_LINK_STATUS BIT(0) + +static int dp83td510_read_status(struct phy_device *phydev) +{ + u16 phy_sts; + + phy_sts = phy_read(phydev, DP83TD510E_PHY_STS); + + phydev->link = !!(phy_sts & DP83TD510E_LINK_STATUS); + if (phydev->link) { + phydev->duplex = DUPLEX_FULL; + phydev->speed = SPEED_10; + } else { + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; + } + + return 0; +} + +static int dp83td510_config_init(struct phy_device *phydev) +{ + phydev->supported = SUPPORTED_10baseT_Full | SUPPORTED_Autoneg; + phydev->advertising = SUPPORTED_10baseT_Full | SUPPORTED_Autoneg; + + return 0; +} + +static struct phy_driver dp83td510_driver[] = { + { + PHY_ID_MATCH_MODEL(DP83TD510E_PHY_ID), + .drv.name = "TI DP83TD510E", + .read_status = dp83td510_read_status, + .config_init = dp83td510_config_init, + } +}; +device_phy_drivers(dp83td510_driver); diff --git a/drivers/net/phy/mv88e6xxx/chip.c b/drivers/net/phy/mv88e6xxx/chip.c index ae59d134e7..a7d707095b 100644 --- a/drivers/net/phy/mv88e6xxx/chip.c +++ b/drivers/net/phy/mv88e6xxx/chip.c @@ -36,6 +36,7 @@ enum mv88e6xxx_model { MV88E6190X, MV88E6191, MV88E6240, + MV88E6250, MV88E6290, MV88E6320, MV88E6321, @@ -224,6 +225,18 @@ static const struct mv88e6xxx_ops mv88e6240_ops = { .port_link_state = mv88e6352_port_link_state, }; +static const struct mv88e6xxx_ops mv88e6250_ops = { + /* MV88E6XXX_FAMILY_6250 */ + .get_eeprom = mv88e6xxx_g2_get_eeprom16, + .set_eeprom = mv88e6xxx_g2_set_eeprom16, + .phy_read = mv88e6xxx_g2_smi_phy_read, + .phy_write = mv88e6xxx_g2_smi_phy_write, + .port_set_link = mv88e6xxx_port_set_link, + .port_set_duplex = mv88e6xxx_port_set_duplex, + .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, + .port_set_speed = mv88e6250_port_set_speed, +}; + static const struct mv88e6xxx_ops mv88e6290_ops = { /* MV88E6XXX_FAMILY_6390 */ .get_eeprom = mv88e6xxx_g2_get_eeprom8, @@ -525,6 +538,17 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { .ops = &mv88e6240_ops, }, + [MV88E6250] = { + .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6250, + .family = MV88E6XXX_FAMILY_6250, + .name = "Marvell 88E6250", + .num_ports = 7, + .port_base_addr = 0x08, + .global1_addr = 0xf, + .global2_addr = 0x7, + .ops = &mv88e6250_ops, + }, + [MV88E6290] = { .prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6290, .family = MV88E6XXX_FAMILY_6390, @@ -932,6 +956,10 @@ static const struct of_device_id mv88e6xxx_of_match[] = { .data = &mv88e6xxx_table[MV88E6085], }, { + .compatible = "marvell,mv88e6250", + .data = &mv88e6xxx_table[MV88E6250], + }, + { .compatible = "marvell,mv88e6190", .data = &mv88e6xxx_table[MV88E6190], }, diff --git a/drivers/net/phy/mv88e6xxx/chip.h b/drivers/net/phy/mv88e6xxx/chip.h index 12037ca95c..30fdac9a9f 100644 --- a/drivers/net/phy/mv88e6xxx/chip.h +++ b/drivers/net/phy/mv88e6xxx/chip.h @@ -19,6 +19,7 @@ enum mv88e6xxx_family { MV88E6XXX_FAMILY_6165, /* 6123 6161 6165 */ MV88E6XXX_FAMILY_6185, /* 6108 6121 6122 6131 6152 6155 6182 6185 */ MV88E6XXX_FAMILY_6320, /* 6320 6321 */ + MV88E6XXX_FAMILY_6250, /* 6250 */ MV88E6XXX_FAMILY_6341, /* 6141 6341 */ MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */ MV88E6XXX_FAMILY_6352, /* 6172 6176 6240 6352 */ diff --git a/drivers/net/phy/mv88e6xxx/port.c b/drivers/net/phy/mv88e6xxx/port.c index 79694e5237..93a789e658 100644 --- a/drivers/net/phy/mv88e6xxx/port.c +++ b/drivers/net/phy/mv88e6xxx/port.c @@ -277,6 +277,18 @@ int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) return mv88e6xxx_port_set_speed(chip, port, speed, false, false); } +/* Support 10, 100 (e.g. 88E6250 family) */ +int mv88e6250_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) +{ + if (speed == SPEED_MAX) + speed = 100; + + if (speed > 100) + return -EOPNOTSUPP; + + return mv88e6xxx_port_set_speed(chip, port, speed, false, false); +} + /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */ int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) { diff --git a/drivers/net/phy/mv88e6xxx/port.h b/drivers/net/phy/mv88e6xxx/port.h index f47f392b87..4bc5072948 100644 --- a/drivers/net/phy/mv88e6xxx/port.h +++ b/drivers/net/phy/mv88e6xxx/port.h @@ -90,6 +90,7 @@ #define MV88E6XXX_PORT_SWITCH_ID_PROD_6191 0x1910 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6185 0x1a70 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6240 0x2400 +#define MV88E6XXX_PORT_SWITCH_ID_PROD_6250 0x2500 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6290 0x2900 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6321 0x3100 #define MV88E6XXX_PORT_SWITCH_ID_PROD_6141 0x3400 @@ -121,6 +122,7 @@ int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link); int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup); int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); +int mv88e6250_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 85cdd7862f..adff9dadd1 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -54,6 +54,13 @@ int phy_update_status(struct phy_device *phydev) return ret; } + /* + * If the phy is a fixed-link, set it to active state to trigger + * MAC configuration + */ + if (!phydev->bus && !phydev->link) + phydev->link = 1; + if (phydev->speed == oldspeed && phydev->duplex == oldduplex && phydev->link == oldlink) return 0; @@ -311,7 +318,7 @@ struct phy_device *of_phy_register_fixed_link(struct device_node *np, phydev->dev.parent = &edev->dev; phydev->registered = 1; - phydev->link = 1; + phydev->link = 0; if (of_property_read_u32(np, "speed", &phydev->speed)) return NULL; @@ -401,10 +408,6 @@ static int phy_device_attach(struct phy_device *phy, struct eth_device *edev, phy->adjust_link = adjust_link; - /* If the phy is a fixed-link, then call adjust_link directly */ - if (!phy->bus && adjust_link) - adjust_link(edev); - return 0; } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index fe432952ec..60764222af 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -436,7 +436,8 @@ static int event_ready(struct xhci_ctrl *ctrl) * @param expected TRB type expected from Event TRB * @return pointer to event trb */ -union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected) +union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected, + unsigned int timeout_ms) { trb_type type; uint64_t start = get_time_ns(); @@ -460,16 +461,8 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected) BUG_ON(GET_COMP_CODE( le32_to_cpu(event->generic.field[2])) != COMP_SUCCESS); - else - dev_err(ctrl->dev, "Unexpected XHCI event TRB, skipping... " - "(%08x %08x %08x %08x)\n", - le32_to_cpu(event->generic.field[0]), - le32_to_cpu(event->generic.field[1]), - le32_to_cpu(event->generic.field[2]), - le32_to_cpu(event->generic.field[3])); - xhci_acknowledge_event(ctrl); - } while (!is_timeout_non_interruptible(start, 5 * SECOND)); + } while (!is_timeout_non_interruptible(start, timeout_ms * MSECOND)); if (expected == TRB_TRANSFER) return NULL; @@ -495,7 +488,7 @@ static void abort_td(struct usb_device *udev, int ep_index) xhci_queue_command(ctrl, NULL, udev->slot_id, ep_index, TRB_STOP_RING); - event = xhci_wait_for_event(ctrl, TRB_TRANSFER); + event = xhci_wait_for_event(ctrl, TRB_TRANSFER, XHCI_TIMEOUT_DEFAULT); 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); @@ -503,7 +496,7 @@ static void abort_td(struct usb_device *udev, int ep_index) != COMP_STOP))); xhci_acknowledge_event(ctrl); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); 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); @@ -511,7 +504,7 @@ static void abort_td(struct usb_device *udev, int ep_index) xhci_queue_command(ctrl, (void *)((uintptr_t)ring->enqueue | ring->cycle_state), udev->slot_id, ep_index, TRB_SET_DEQ); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); 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); @@ -557,7 +550,7 @@ static void record_transfer_result(struct usb_device *udev, * @return returns 0 if successful else -1 on failure */ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, - int length, void *buffer) + int length, void *buffer, unsigned int timeout_ms) { int num_trbs = 0; struct xhci_generic_trb *start_trb; @@ -726,7 +719,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, giveback_first_trb(udev, ep_index, start_cycle, start_trb); - event = xhci_wait_for_event(ctrl, TRB_TRANSFER); + event = xhci_wait_for_event(ctrl, TRB_TRANSFER, timeout_ms); if (!event) { dev_dbg(&udev->dev, "XHCI bulk transfer timed out, aborting...\n"); abort_td(udev, ep_index); @@ -767,7 +760,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, */ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, struct devrequest *req, int length, - void *buffer) + void *buffer, unsigned int timeout_ms) { int ret; int start_cycle; @@ -936,7 +929,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, giveback_first_trb(udev, ep_index, start_cycle, start_trb); - event = xhci_wait_for_event(ctrl, TRB_TRANSFER); + event = xhci_wait_for_event(ctrl, TRB_TRANSFER, timeout_ms); if (!event) goto abort; field = le32_to_cpu(event->trans_event.flags); @@ -959,7 +952,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, if (GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len)) == COMP_SHORT_TX) { /* Short data stage, clear up additional status stage event */ - event = xhci_wait_for_event(ctrl, TRB_TRANSFER); + event = xhci_wait_for_event(ctrl, TRB_TRANSFER, timeout_ms); if (!event) goto abort; BUG_ON(TRB_TO_SLOT_ID(field) != slot_id); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7336a0911a..ce93d345f9 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -443,7 +443,7 @@ static int xhci_configure_endpoints(struct usb_device *udev, bool ctx_change) xhci_flush_cache((uintptr_t)in_ctx->bytes, in_ctx->size); xhci_queue_command(ctrl, in_ctx->bytes, udev->slot_id, 0, ctx_change ? TRB_EVAL_CONTEXT : TRB_CONFIG_EP); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id); @@ -629,7 +629,7 @@ static int xhci_address_device(struct usb_device *udev, int root_portnr) ctrl_ctx->drop_flags = 0; xhci_queue_command(ctrl, (void *)ctrl_ctx, slot_id, 0, TRB_ADDR_DEV); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); 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))) { @@ -704,7 +704,7 @@ static int _xhci_alloc_device(struct usb_device *udev) } xhci_queue_command(ctrl, NULL, 0, 0, TRB_ENABLE_SLOT); - event = xhci_wait_for_event(ctrl, TRB_COMPLETION); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); BUG_ON(GET_COMP_CODE(le32_to_cpu(event->event_cmd.status)) != COMP_SUCCESS); @@ -1097,7 +1097,7 @@ static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, * (at most) one TD. A TD (comprised of sg list entries) can * take several service intervals to transmit. */ - return xhci_bulk_tx(udev, pipe, length, buffer); + return xhci_bulk_tx(udev, pipe, length, buffer, 0); } /** @@ -1115,7 +1115,7 @@ static int _xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe, if (usb_pipetype(pipe) != PIPE_BULK) return -EINVAL; - return xhci_bulk_tx(udev, pipe, length, buffer); + return xhci_bulk_tx(udev, pipe, length, buffer, timeout_ms); } /** @@ -1131,7 +1131,8 @@ static int _xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe, */ static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer, int length, - struct devrequest *setup, int root_portnr) + struct devrequest *setup, int root_portnr, + unsigned int timeout_ms) { struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); int ret = 0; @@ -1155,7 +1156,7 @@ static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe, } } - return xhci_ctrl_tx(udev, pipe, setup, length, buffer); + return xhci_ctrl_tx(udev, pipe, setup, length, buffer, timeout_ms); } static int xhci_lowlevel_init(struct xhci_ctrl *ctrl) @@ -1239,7 +1240,7 @@ static int xhci_submit_control_msg(struct usb_device *udev, } return _xhci_submit_control_msg(udev, pipe, buffer, length, setup, - root_portnr); + root_portnr, timeout_ms); } static int xhci_submit_bulk_msg(struct usb_device *udev, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 401fa65637..e445438e81 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1247,11 +1247,13 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr, u32 slot_id, u32 ep_index, trb_type cmd); void xhci_acknowledge_event(struct xhci_ctrl *ctrl); -union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected); +#define XHCI_TIMEOUT_DEFAULT 5000 +union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected, + unsigned int timeout_ms); int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, - int length, void *buffer); + int length, void *buffer, unsigned int timeout_ms); int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, - struct devrequest *req, int length, void *buffer); + struct devrequest *req, int length, void *buffer, unsigned int timeout_ms); int xhci_check_maxpacket(struct usb_device *udev); void xhci_flush_cache(uintptr_t addr, u32 type_len); void xhci_inval_cache(uintptr_t addr, u32 type_len); |