Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 122607
b: refs/heads/master
c: be4ea89
h: refs/heads/master
i:
  122605: b9e4f15
  122603: fd03bbd
  122599: f0fd62b
  122591: 92e2513
v: v3
  • Loading branch information
Ben Hutchings authored and David S. Miller committed Dec 13, 2008
1 parent b7e09c7 commit a2ab7dc
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 24 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1ab00629f06fb3c47de6373cd92d086f33775444
refs/heads/master: be4ea89c8df06f48d0d64cf1d9d20009e83c77c8
58 changes: 37 additions & 21 deletions trunk/drivers/net/sfc/falcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -1607,24 +1607,37 @@ void falcon_fini_interrupt(struct efx_nic *efx)

#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t)

static int falcon_spi_poll(struct efx_nic *efx)
{
efx_oword_t reg;
falcon_read(efx, &reg, EE_SPI_HCMD_REG_KER);
return EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN) ? -EBUSY : 0;
}

/* Wait for SPI command completion */
static int falcon_spi_wait(struct efx_nic *efx)
{
unsigned long timeout = jiffies + DIV_ROUND_UP(HZ, 10);
efx_oword_t reg;
bool cmd_en, timer_active;
/* Most commands will finish quickly, so we start polling at
* very short intervals. Sometimes the command may have to
* wait for VPD or expansion ROM access outside of our
* control, so we allow up to 100 ms. */
unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 10);
int i;

for (i = 0; i < 10; i++) {
if (!falcon_spi_poll(efx))
return 0;
udelay(10);
}

for (;;) {
falcon_read(efx, &reg, EE_SPI_HCMD_REG_KER);
cmd_en = EFX_OWORD_FIELD(reg, EE_SPI_HCMD_CMD_EN);
timer_active = EFX_OWORD_FIELD(reg, EE_WR_TIMER_ACTIVE);
if (!cmd_en && !timer_active)
if (!falcon_spi_poll(efx))
return 0;
if (time_after_eq(jiffies, timeout)) {
EFX_ERR(efx, "timed out waiting for SPI\n");
return -ETIMEDOUT;
}
cpu_relax();
schedule_timeout_uninterruptible(1);
}
}

Expand All @@ -1643,8 +1656,8 @@ int falcon_spi_cmd(const struct efx_spi_device *spi,
return -EINVAL;
BUG_ON(!mutex_is_locked(&efx->spi_lock));

/* Check SPI not currently being accessed */
rc = falcon_spi_wait(efx);
/* Check that previous command is not still running */
rc = falcon_spi_poll(efx);
if (rc)
return rc;

Expand Down Expand Up @@ -1700,26 +1713,29 @@ efx_spi_munge_command(const struct efx_spi_device *spi,
return command | (((address >> 8) & spi->munge_address) << 3);
}

int falcon_spi_fast_wait(const struct efx_spi_device *spi)
/* Wait up to 10 ms for buffered write completion */
int falcon_spi_wait_write(const struct efx_spi_device *spi)
{
struct efx_nic *efx = spi->efx;
unsigned long timeout = jiffies + 1 + DIV_ROUND_UP(HZ, 100);
u8 status;
int i, rc;

/* Wait up to 1000us for flash/EEPROM to finish a fast operation. */
for (i = 0; i < 50; i++) {
udelay(20);
int rc;

for (;;) {
rc = falcon_spi_cmd(spi, SPI_RDSR, -1, NULL,
&status, sizeof(status));
if (rc)
return rc;
if (!(status & SPI_STATUS_NRDY))
return 0;
if (time_after_eq(jiffies, timeout)) {
EFX_ERR(efx, "SPI write timeout on device %d"
" last status=0x%02x\n",
spi->device_id, status);
return -ETIMEDOUT;
}
schedule_timeout_uninterruptible(1);
}
EFX_ERR(spi->efx,
"timed out waiting for device %d last status=0x%02x\n",
spi->device_id, status);
return -ETIMEDOUT;
}

int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
Expand Down Expand Up @@ -1773,7 +1789,7 @@ int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
if (rc)
break;

rc = falcon_spi_fast_wait(spi);
rc = falcon_spi_wait_write(spi);
if (rc)
break;

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/sfc/mtd.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ static int efx_spi_unlock(const struct efx_spi_device *spi)
rc = falcon_spi_cmd(spi, SPI_WRSR, -1, &status, NULL, sizeof(status));
if (rc)
return rc;
rc = falcon_spi_fast_wait(spi);
rc = falcon_spi_wait_write(spi);
if (rc)
return rc;

Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/sfc/spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ struct efx_spi_device {

int falcon_spi_cmd(const struct efx_spi_device *spi, unsigned int command,
int address, const void* in, void *out, size_t len);
int falcon_spi_fast_wait(const struct efx_spi_device *spi);
int falcon_spi_wait_write(const struct efx_spi_device *spi);
int falcon_spi_read(const struct efx_spi_device *spi, loff_t start,
size_t len, size_t *retlen, u8 *buffer);
int falcon_spi_write(const struct efx_spi_device *spi, loff_t start,
Expand Down

0 comments on commit a2ab7dc

Please sign in to comment.