Skip to content

Commit

Permalink
fsi: scom: Remove retries
Browse files Browse the repository at this point in the history
On a functioning FSI link there is not need to retry a write when doing
a scom in the driver.

Allow the higher layers (eg. userspace) to attempt a retry if they want,
or to accept that the address they are talking to is not accessible.

By removing the retries we can separate the error handling from retry
logic. In particular -EBUSY was used to force the get/put scom logic to
retry.

Signed-off-by: Joel Stanley <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Joel Stanley <[email protected]>
  • Loading branch information
shenki committed Jun 4, 2021
1 parent a5c317d commit f72ddbe
Showing 1 changed file with 29 additions and 60 deletions.
89 changes: 29 additions & 60 deletions drivers/fsi/fsi-scom.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
#define XSCOM_ADDR_FORM1_HI_SHIFT 20

/* Retries */
#define SCOM_MAX_RETRIES 100 /* Retries on busy */
#define SCOM_MAX_IND_RETRIES 10 /* Retries indirect not ready */

struct scom_device {
Expand Down Expand Up @@ -249,7 +248,7 @@ static int handle_fsi2pib_status(struct scom_device *scom, uint32_t status)
return -EPERM;
if (status & SCOM_STATUS_PARITY)
return -EIO;
/* Return -EBUSY on PIB abort to force a retry */

if (status & SCOM_STATUS_PIB_ABORT)
return -EBUSY;
return 0;
Expand Down Expand Up @@ -286,69 +285,39 @@ static int handle_pib_status(struct scom_device *scom, uint8_t status)
static int put_scom(struct scom_device *scom, uint64_t value,
uint64_t addr)
{
uint32_t status, dummy = -1;
int rc, retries;

for (retries = 0; retries < SCOM_MAX_RETRIES; retries++) {
rc = raw_put_scom(scom, value, addr, &status);
if (rc) {
/* Try resetting the bridge if FSI fails */
if (rc != -ENODEV && retries == 0) {
fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG,
&dummy, sizeof(uint32_t));
rc = -EBUSY;
} else
return rc;
} else
rc = handle_fsi2pib_status(scom, status);
if (rc && rc != -EBUSY)
break;
if (rc == 0) {
rc = handle_pib_status(scom,
(status & SCOM_STATUS_PIB_RESP_MASK)
>> SCOM_STATUS_PIB_RESP_SHIFT);
if (rc && rc != -EBUSY)
break;
}
if (rc == 0)
break;
msleep(1);
}
return rc;
uint32_t status;
int rc;

rc = raw_put_scom(scom, value, addr, &status);
if (rc == -ENODEV)
return rc;

rc = handle_fsi2pib_status(scom, status);
if (rc)
return rc;

return handle_pib_status(scom,
(status & SCOM_STATUS_PIB_RESP_MASK)
>> SCOM_STATUS_PIB_RESP_SHIFT);
}

static int get_scom(struct scom_device *scom, uint64_t *value,
uint64_t addr)
{
uint32_t status, dummy = -1;
int rc, retries;

for (retries = 0; retries < SCOM_MAX_RETRIES; retries++) {
rc = raw_get_scom(scom, value, addr, &status);
if (rc) {
/* Try resetting the bridge if FSI fails */
if (rc != -ENODEV && retries == 0) {
fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG,
&dummy, sizeof(uint32_t));
rc = -EBUSY;
} else
return rc;
} else
rc = handle_fsi2pib_status(scom, status);
if (rc && rc != -EBUSY)
break;
if (rc == 0) {
rc = handle_pib_status(scom,
(status & SCOM_STATUS_PIB_RESP_MASK)
>> SCOM_STATUS_PIB_RESP_SHIFT);
if (rc && rc != -EBUSY)
break;
}
if (rc == 0)
break;
msleep(1);
}
return rc;
uint32_t status;
int rc;

rc = raw_get_scom(scom, value, addr, &status);
if (rc == -ENODEV)
return rc;

rc = handle_fsi2pib_status(scom, status);
if (rc)
return rc;

return handle_pib_status(scom,
(status & SCOM_STATUS_PIB_RESP_MASK)
>> SCOM_STATUS_PIB_RESP_SHIFT);
}

static ssize_t scom_read(struct file *filep, char __user *buf, size_t len,
Expand Down

0 comments on commit f72ddbe

Please sign in to comment.