diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-07-03 09:21:25 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-07-03 09:21:25 +0200 |
commit | b9b667a0c7596474f9eb30008e837aa88574ceb7 (patch) | |
tree | 34cdf00a87171cd4030513b85e7de801385abecd /drivers/fsi | |
parent | c1829acefc08c2f9a11e769750ea875b0a663af3 (diff) | |
parent | 371975b0b07520c85098652d561639837a60a905 (diff) | |
download | linux-b9b667a0c7596474f9eb30008e837aa88574ceb7.tar.gz linux-b9b667a0c7596474f9eb30008e837aa88574ceb7.tar.bz2 linux-b9b667a0c7596474f9eb30008e837aa88574ceb7.zip |
Merge tag 'fsi-for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/joel/fsi into char-misc-next
Joel writes:
FSI changes for 5.3
- Add MAINTAINERS entry. There is now a git tree and a mailing
list/patchwork for collecting FSI patches
- Bug fix for error driver registration error paths
- Correction for the OCC hwmon driver to meet the spec
* tag 'fsi-for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/joel/fsi:
fsi/core: Fix error paths on CFAM init
OCC: FSI and hwmon: Add sequence numbering
MAINTAINERS: Add FSI subsystem
Diffstat (limited to 'drivers/fsi')
-rw-r--r-- | drivers/fsi/fsi-core.c | 32 | ||||
-rw-r--r-- | drivers/fsi/fsi-occ.c | 15 |
2 files changed, 32 insertions, 15 deletions
diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 1d83f3ba478b..1f76740f33b6 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -1029,6 +1029,14 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) } + rc = fsi_slave_set_smode(slave); + if (rc) { + dev_warn(&master->dev, + "can't set smode on slave:%02x:%02x %d\n", + link, id, rc); + goto err_free; + } + /* Allocate a minor in the FSI space */ rc = __fsi_get_new_minor(slave, fsi_dev_cfam, &slave->dev.devt, &slave->cdev_idx); @@ -1040,17 +1048,14 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) rc = cdev_device_add(&slave->cdev, &slave->dev); if (rc) { dev_err(&slave->dev, "Error %d creating slave device\n", rc); - goto err_free; + goto err_free_ida; } - rc = fsi_slave_set_smode(slave); - if (rc) { - dev_warn(&master->dev, - "can't set smode on slave:%02x:%02x %d\n", - link, id, rc); - kfree(slave); - return -ENODEV; - } + /* Now that we have the cdev registered with the core, any fatal + * failures beyond this point will need to clean up through + * cdev_device_del(). Fortunately though, nothing past here is fatal. + */ + if (master->link_config) master->link_config(master, link, slave->t_send_delay, @@ -1067,10 +1072,13 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) dev_dbg(&master->dev, "failed during slave scan with: %d\n", rc); - return rc; + return 0; - err_free: - put_device(&slave->dev); +err_free_ida: + fsi_free_minor(slave->dev.devt); +err_free: + of_node_put(slave->dev.of_node); + kfree(slave); return rc; } diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c index a2301cea1cbb..7da9c81759ac 100644 --- a/drivers/fsi/fsi-occ.c +++ b/drivers/fsi/fsi-occ.c @@ -412,6 +412,7 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, msecs_to_jiffies(OCC_CMD_IN_PRG_WAIT_MS); struct occ *occ = dev_get_drvdata(dev); struct occ_response *resp = response; + u8 seq_no; u16 resp_data_length; unsigned long start; int rc; @@ -426,6 +427,8 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, mutex_lock(&occ->occ_lock); + /* Extract the seq_no from the command (first byte) */ + seq_no = *(const u8 *)request; rc = occ_putsram(occ, OCC_SRAM_CMD_ADDR, request, req_len); if (rc) goto done; @@ -441,11 +444,17 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, if (rc) goto done; - if (resp->return_status == OCC_RESP_CMD_IN_PRG) { + if (resp->return_status == OCC_RESP_CMD_IN_PRG || + resp->seq_no != seq_no) { rc = -ETIMEDOUT; - if (time_after(jiffies, start + timeout)) - break; + if (time_after(jiffies, start + timeout)) { + dev_err(occ->dev, "resp timeout status=%02x " + "resp seq_no=%d our seq_no=%d\n", + resp->return_status, resp->seq_no, + seq_no); + goto done; + } set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(wait_time); |