diff options
Diffstat (limited to 'drivers/fsi')
-rw-r--r-- | drivers/fsi/cf-fsi-fw.h | 2 | ||||
-rw-r--r-- | drivers/fsi/fsi-core.c | 32 | ||||
-rw-r--r-- | drivers/fsi/fsi-occ.c | 15 | ||||
-rw-r--r-- | drivers/fsi/fsi-sbefifo.c | 4 | ||||
-rw-r--r-- | drivers/fsi/fsi-scom.c | 10 |
5 files changed, 36 insertions, 27 deletions
diff --git a/drivers/fsi/cf-fsi-fw.h b/drivers/fsi/cf-fsi-fw.h index 712df0461911..1118eaf7ee39 100644 --- a/drivers/fsi/cf-fsi-fw.h +++ b/drivers/fsi/cf-fsi-fw.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ #ifndef __CF_FSI_FW_H #define __CF_FSI_FW_H 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); diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c index d92f5b87c251..f54df9ebc8b3 100644 --- a/drivers/fsi/fsi-sbefifo.c +++ b/drivers/fsi/fsi-sbefifo.c @@ -289,11 +289,11 @@ static int sbefifo_check_sbe_state(struct sbefifo *sbefifo) switch ((sbm & CFAM_SBM_SBE_STATE_MASK) >> CFAM_SBM_SBE_STATE_SHIFT) { case SBE_STATE_UNKNOWN: return -ESHUTDOWN; + case SBE_STATE_DMT: + return -EBUSY; case SBE_STATE_IPLING: case SBE_STATE_ISTEP: case SBE_STATE_MPIPL: - case SBE_STATE_DMT: - return -EBUSY; case SBE_STATE_RUNTIME: case SBE_STATE_DUMP: /* Not sure about that one */ break; diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index 81dc01ac2351..343153d47e5b 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * SCOM FSI Client device driver * * Copyright (C) IBM Corporation 2016 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERGCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/fsi.h> |