summaryrefslogtreecommitdiffstats
path: root/drivers/fsi/fsi-sbefifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fsi/fsi-sbefifo.c')
-rw-r--r--drivers/fsi/fsi-sbefifo.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c
index 84cb965bfed5..52328adef643 100644
--- a/drivers/fsi/fsi-sbefifo.c
+++ b/drivers/fsi/fsi-sbefifo.c
@@ -124,6 +124,7 @@ struct sbefifo {
bool broken;
bool dead;
bool async_ffdc;
+ bool timed_out;
};
struct sbefifo_user {
@@ -136,6 +137,14 @@ struct sbefifo_user {
static DEFINE_MUTEX(sbefifo_ffdc_mutex);
+static ssize_t timeout_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct sbefifo *sbefifo = container_of(dev, struct sbefifo, dev);
+
+ return sysfs_emit(buf, "%d\n", sbefifo->timed_out ? 1 : 0);
+}
+static DEVICE_ATTR_RO(timeout);
static void __sbefifo_dump_ffdc(struct device *dev, const __be32 *ffdc,
size_t ffdc_sz, bool internal)
@@ -462,11 +471,14 @@ static int sbefifo_wait(struct sbefifo *sbefifo, bool up,
break;
}
if (!ready) {
+ sysfs_notify(&sbefifo->dev.kobj, NULL, dev_attr_timeout.attr.name);
+ sbefifo->timed_out = true;
dev_err(dev, "%s FIFO Timeout ! status=%08x\n", up ? "UP" : "DOWN", sts);
return -ETIMEDOUT;
}
dev_vdbg(dev, "End of wait status: %08x\n", sts);
+ sbefifo->timed_out = false;
*status = sts;
return 0;
@@ -740,7 +752,9 @@ int sbefifo_submit(struct device *dev, const __be32 *command, size_t cmd_len,
iov_iter_kvec(&resp_iter, WRITE, &resp_iov, 1, rbytes);
/* Perform the command */
- mutex_lock(&sbefifo->lock);
+ rc = mutex_lock_interruptible(&sbefifo->lock);
+ if (rc)
+ return rc;
rc = __sbefifo_submit(sbefifo, command, cmd_len, &resp_iter);
mutex_unlock(&sbefifo->lock);
@@ -820,7 +834,9 @@ static ssize_t sbefifo_user_read(struct file *file, char __user *buf,
iov_iter_init(&resp_iter, WRITE, &resp_iov, 1, len);
/* Perform the command */
- mutex_lock(&sbefifo->lock);
+ rc = mutex_lock_interruptible(&sbefifo->lock);
+ if (rc)
+ goto bail;
rc = __sbefifo_submit(sbefifo, user->pending_cmd, cmd_len, &resp_iter);
mutex_unlock(&sbefifo->lock);
if (rc < 0)
@@ -875,7 +891,9 @@ static ssize_t sbefifo_user_write(struct file *file, const char __user *buf,
user->pending_len = 0;
/* Trigger reset request */
- mutex_lock(&sbefifo->lock);
+ rc = mutex_lock_interruptible(&sbefifo->lock);
+ if (rc)
+ goto bail;
rc = sbefifo_request_reset(user->sbefifo);
mutex_unlock(&sbefifo->lock);
if (rc == 0)
@@ -993,6 +1011,8 @@ static int sbefifo_probe(struct device *dev)
child_name);
}
+ device_create_file(&sbefifo->dev, &dev_attr_timeout);
+
return 0;
err_free_minor:
fsi_free_minor(sbefifo->dev.devt);
@@ -1018,6 +1038,8 @@ static int sbefifo_remove(struct device *dev)
dev_dbg(dev, "Removing sbefifo device...\n");
+ device_remove_file(&sbefifo->dev, &dev_attr_timeout);
+
mutex_lock(&sbefifo->lock);
sbefifo->dead = true;
mutex_unlock(&sbefifo->lock);