Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sfc: Clean up waits for flash/EEPROM operations

Make falcon_spi_wait() ignore the write timer - it is only relevant to
write commands, it only works for the device that contains VPD, and it
might not be initialised properly at all.

Rename falcon_spi_fast_wait() to falcon_spi_wait_write(), reflecting
its use, and make it wait up to 10 ms (not 1 ms) since buffered writes
to EEPROM may take this long to complete.

Make both wait functions sleep instead of busy-waiting.

Replace wait for command completion at top of falcon_spi_cmd() with a
single poll; no command should be running when the function starts.

Correct some comments.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Ben Hutchings and committed by
David S. Miller
be4ea89c 1ab00629

+39 -23
+37 -21
drivers/net/sfc/falcon.c
··· 1607 1607 1608 1608 #define FALCON_SPI_MAX_LEN sizeof(efx_oword_t) 1609 1609 1610 + static int falcon_spi_poll(struct efx_nic *efx) 1611 + { 1612 + efx_oword_t reg; 1613 + falcon_read(efx, &reg, EE_SPI_HCMD_REG_KER); 1614 + return EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0; 1615 + } 1616 + 1610 1617 /* Wait for SPI command completion */ 1611 1618 static int falcon_spi_wait(struct efx_nic *efx) 1612 1619 { 1613 - unsigned long timeout = jiffies + DIV_ROUND_UP(HZ, 10); 1614 - efx_oword_t reg; 1615 - bool cmd_en, timer_active; 1620 + /* Most commands will finish quickly, so we start polling at 1621 + * very short intervals. Sometimes the command may have to 1622 + * wait for VPD or expansion ROM access outside of our 1623 + * control, so we allow up to 100 ms. */ 1624 + unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 10); 1625 + int i; 1626 + 1627 + for (i = 0; i < 10; i++) { 1628 + if (!falcon_spi_poll(efx)) 1629 + return 0; 1630 + udelay(10); 1631 + } 1616 1632 1617 1633 for (;;) { 1618 - falcon_read(efx, &reg, EE_SPI_HCMD_REG_KER); 1619 - cmd_en = EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN); 1620 - timer_active = EFX_OWORD_FIELD(reg, EE_WR_TIMER_ACTIVE); 1621 - if (!cmd_en && !timer_active) 1634 + if (!falcon_spi_poll(efx)) 1622 1635 return 0; 1623 1636 if (time_after_eq(jiffies, timeout)) { 1624 1637 EFX_ERR(efx, "timed out waiting for SPI\n"); 1625 1638 return -ETIMEDOUT; 1626 1639 } 1627 - cpu_relax(); 1640 + schedule_timeout_uninterruptible(1); 1628 1641 } 1629 1642 } 1630 1643 ··· 1656 1643 return -EINVAL; 1657 1644 BUG_ON(!mutex_is_locked(&efx->spi_lock)); 1658 1645 1659 - /* Check SPI not currently being accessed */ 1660 - rc = falcon_spi_wait(efx); 1646 + /* Check that previous command is not still running */ 1647 + rc = falcon_spi_poll(efx); 1661 1648 if (rc) 1662 1649 return rc; 1663 1650 ··· 1713 1700 return command | (((address >> 8) & spi->munge_address) << 3); 1714 1701 } 1715 1702 1716 - int falcon_spi_fast_wait(const struct efx_spi_device *spi) 1703 + /* Wait up to 10 ms for buffered write completion */ 1704 + int falcon_spi_wait_write(const struct efx_spi_device *spi) 1717 1705 { 1706 + struct efx_nic *efx = spi->efx; 1707 + unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100); 1718 1708 u8 status; 1719 - int i, rc; 1709 + int rc; 1720 1710 1721 - /* Wait up to 1000us for flash/EEPROM to finish a fast operation. */ 1722 - for (i = 0; i < 50; i++) { 1723 - udelay(20); 1724 - 1711 + for (;;) { 1725 1712 rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL, 1726 1713 &status, sizeof(status)); 1727 1714 if (rc) 1728 1715 return rc; 1729 1716 if (!(status & SPI_STATUS_NRDY)) 1730 1717 return 0; 1718 + if (time_after_eq(jiffies, timeout)) { 1719 + EFX_ERR(efx, "SPI write timeout on device %d" 1720 + " last status=0x%02x\n", 1721 + spi->device_id, status); 1722 + return -ETIMEDOUT; 1723 + } 1724 + schedule_timeout_uninterruptible(1); 1731 1725 } 1732 - EFX_ERR(spi->efx, 1733 - "timed out waiting for device %d last status=0x%02x\n", 1734 - spi->device_id, status); 1735 - return -ETIMEDOUT; 1736 1726 } 1737 1727 1738 1728 int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, ··· 1789 1773 if (rc) 1790 1774 break; 1791 1775 1792 - rc = falcon_spi_fast_wait(spi); 1776 + rc = falcon_spi_wait_write(spi); 1793 1777 if (rc) 1794 1778 break; 1795 1779
+1 -1
drivers/net/sfc/mtd.c
··· 76 76 rc = falcon_spi_cmd(spi, SPI_WRSR, -1, &status, NULL, sizeof(status)); 77 77 if (rc) 78 78 return rc; 79 - rc = falcon_spi_fast_wait(spi); 79 + rc = falcon_spi_wait_write(spi); 80 80 if (rc) 81 81 return rc; 82 82
+1 -1
drivers/net/sfc/spi.h
··· 69 69 70 70 int falcon_spi_cmd(const struct efx_spi_device *spi, unsigned int command, 71 71 int address, const void* in, void *out, size_t len); 72 - int falcon_spi_fast_wait(const struct efx_spi_device *spi); 72 + int falcon_spi_wait_write(const struct efx_spi_device *spi); 73 73 int falcon_spi_read(const struct efx_spi_device *spi, loff_t start, 74 74 size_t len, size_t *retlen, u8 *buffer); 75 75 int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,