Lines Matching +full:cmd +full:- +full:timeout +full:- +full:ms

1 // SPDX-License-Identifier: GPL-2.0
19 #include <linux/fsi-sbefifo.h>
38 * The SBEFIFO is a pipe-like FSI device for communicating with
50 #define SBEFIFO_UP 0x00 /* FSI -> Host */
51 #define SBEFIFO_DOWN 0x40 /* Host -> FSI */
53 /* Per-bank registers */
85 SBE_STATE_IPLING = 0x1, // IPL'ing - autonomous mode (transient)
86 SBE_STATE_ISTEP = 0x2, // ISTEP - Running IPL by steps (transient)
92 SBE_STATE_QUIESCE = 0x8, // Final state - needs SBE reset to get out
103 #define sbefifo_vacant(sts) (SBEFIFO_FIFO_DEPTH - sbefifo_populated(sts))
106 /* Reset request timeout in ms */
109 /* Timeouts for commands in ms */
151 return sysfs_emit(buf, "%d\n", sbefifo->timed_out ? 1 : 0); in timeout_show()
153 static DEVICE_ATTR_RO(timeout);
172 ffdc_sz -= 3; in __sbefifo_dump_ffdc()
186 dev_warn(dev, "+---- SBE FFDC package %d for async err -----+\n", in __sbefifo_dump_ffdc()
189 dev_warn(dev, "+---- SBE FFDC package %d for cmd %02x:%02x -----+\n", in __sbefifo_dump_ffdc()
193 dev_warn(dev, "|-------------------------------------------|\n"); in __sbefifo_dump_ffdc()
200 ffdc_sz--; in __sbefifo_dump_ffdc()
201 if ((i & 3) == 3 || i == (w0 - 1)) { in __sbefifo_dump_ffdc()
209 dev_warn(dev, "+-------------------------------------------+\n"); in __sbefifo_dump_ffdc()
221 int sbefifo_parse_status(struct device *dev, u16 cmd, __be32 *response, in sbefifo_parse_status() argument
228 pr_debug("sbefifo: cmd %04x, response too small: %zd\n", in sbefifo_parse_status()
229 cmd, resp_len); in sbefifo_parse_status()
230 return -ENXIO; in sbefifo_parse_status()
232 dh = be32_to_cpu(response[resp_len - 1]); in sbefifo_parse_status()
234 dev_err(dev, "SBE cmd %02x:%02x status offset out of range: %d/%zd\n", in sbefifo_parse_status()
235 cmd >> 8, cmd & 0xff, dh, resp_len); in sbefifo_parse_status()
236 return -ENXIO; in sbefifo_parse_status()
238 s0 = be32_to_cpu(response[resp_len - dh]); in sbefifo_parse_status()
239 s1 = be32_to_cpu(response[resp_len - dh + 1]); in sbefifo_parse_status()
240 if (((s0 >> 16) != 0xC0DE) || ((s0 & 0xffff) != cmd)) { in sbefifo_parse_status()
241 dev_err(dev, "SBE cmd %02x:%02x, status signature invalid: 0x%08x 0x%08x\n", in sbefifo_parse_status()
242 cmd >> 8, cmd & 0xff, s0, s1); in sbefifo_parse_status()
243 return -ENXIO; in sbefifo_parse_status()
246 ffdc_sz = dh - 3; in sbefifo_parse_status()
247 dev_warn(dev, "SBE error cmd %02x:%02x status=%04x:%04x\n", in sbefifo_parse_status()
248 cmd >> 8, cmd & 0xff, s1 >> 16, s1 & 0xffff); in sbefifo_parse_status()
250 sbefifo_dump_ffdc(dev, &response[resp_len - dh + 2], in sbefifo_parse_status()
254 *data_len = resp_len - dh; in sbefifo_parse_status()
269 rc = fsi_device_read(sbefifo->fsi_dev, reg, &raw_word, in sbefifo_regr()
283 return fsi_device_write(sbefifo->fsi_dev, reg, &raw_word, in sbefifo_regw()
293 rc = fsi_slave_read(sbefifo->fsi_dev->slave, CFAM_GP_MBOX_SBM_ADDR, in sbefifo_check_sbe_state()
301 return -ESHUTDOWN; in sbefifo_check_sbe_state()
306 return -ESHUTDOWN; in sbefifo_check_sbe_state()
308 return -EBUSY; in sbefifo_check_sbe_state()
317 return -ESHUTDOWN; in sbefifo_check_sbe_state()
322 sbefifo->async_ffdc = true; in sbefifo_check_sbe_state()
330 return fsi_device_read(sbefifo->fsi_dev, SBEFIFO_DOWN, word, in sbefifo_down_read()
336 return fsi_device_write(sbefifo->fsi_dev, SBEFIFO_UP, &word, in sbefifo_up_write()
342 struct device *dev = &sbefifo->fsi_dev->dev; in sbefifo_request_reset()
350 sbefifo->broken = true; in sbefifo_request_reset()
371 sbefifo->broken = false; in sbefifo_request_reset()
379 return -ETIMEDOUT; in sbefifo_request_reset()
384 struct device *dev = &sbefifo->fsi_dev->dev; in sbefifo_cleanup_hw()
396 if (sbefifo->broken) in sbefifo_cleanup_hw()
404 sbefifo->broken = true; in sbefifo_cleanup_hw()
413 sbefifo->broken = true; in sbefifo_cleanup_hw()
422 sbefifo->broken = true; in sbefifo_cleanup_hw()
426 sbefifo->broken = false; in sbefifo_cleanup_hw()
451 u32 *status, unsigned long timeout) in sbefifo_wait() argument
453 struct device *dev = &sbefifo->fsi_dev->dev; in sbefifo_wait()
463 end_time = jiffies + timeout; in sbefifo_wait()
473 return -ENXIO; in sbefifo_wait()
480 sysfs_notify(&sbefifo->dev.kobj, NULL, dev_attr_timeout.attr.name); in sbefifo_wait()
481 sbefifo->timed_out = true; in sbefifo_wait()
482 dev_err(dev, "%s FIFO Timeout (%u ms)! status=%08x\n", in sbefifo_wait()
483 up ? "UP" : "DOWN", jiffies_to_msecs(timeout), sts); in sbefifo_wait()
484 return -ETIMEDOUT; in sbefifo_wait()
488 sbefifo->timed_out = false; in sbefifo_wait()
497 struct device *dev = &sbefifo->fsi_dev->dev; in sbefifo_send_command()
499 unsigned long timeout; in sbefifo_send_command() local
503 dev_dbg(dev, "sending command (%zd words, cmd=%04x)\n", in sbefifo_send_command()
507 timeout = msecs_to_jiffies(SBEFIFO_TIMEOUT_START_CMD); in sbefifo_send_command()
510 rc = sbefifo_wait(sbefifo, true, &status, timeout); in sbefifo_send_command()
513 timeout = msecs_to_jiffies(sbefifo->timeout_in_cmd_ms); in sbefifo_send_command()
522 while (len--) { in sbefifo_send_command()
529 remaining -= chunk; in sbefifo_send_command()
530 vacant -= chunk; in sbefifo_send_command()
535 rc = sbefifo_wait(sbefifo, true, &status, timeout); in sbefifo_send_command()
549 struct device *dev = &sbefifo->fsi_dev->dev; in sbefifo_read_response()
551 unsigned long timeout; in sbefifo_read_response() local
559 timeout = msecs_to_jiffies(sbefifo->timeout_start_rsp_ms); in sbefifo_read_response()
562 rc = sbefifo_wait(sbefifo, false, &status, timeout); in sbefifo_read_response()
564 dev_dbg(dev, "timeout waiting (%u ms)\n", jiffies_to_msecs(timeout)); in sbefifo_read_response()
567 timeout = msecs_to_jiffies(SBEFIFO_TIMEOUT_IN_RSP); in sbefifo_read_response()
576 while(len--) { in sbefifo_read_response()
594 sbefifo->broken = true; in sbefifo_read_response()
608 sbefifo->broken = true; in sbefifo_read_response()
612 return overflow ? -EOVERFLOW : 0; in sbefifo_read_response()
618 return -EFAULT; in sbefifo_read_response()
630 return -EIO; in sbefifo_read_response()
648 struct device *dev = &sbefifo->fsi_dev->dev; in sbefifo_collect_async_ffdc()
653 __be32 cmd[2]; in sbefifo_collect_async_ffdc() local
656 sbefifo->async_ffdc = false; in sbefifo_collect_async_ffdc()
665 cmd[0] = cpu_to_be32(2); in sbefifo_collect_async_ffdc()
666 cmd[1] = cpu_to_be32(SBEFIFO_CMD_GET_SBE_FFDC); in sbefifo_collect_async_ffdc()
667 rc = sbefifo_do_command(sbefifo, cmd, 2, &ffdc_iter); in sbefifo_collect_async_ffdc()
672 ffdc_sz = SBEFIFO_MAX_FFDC_SIZE - iov_iter_count(&ffdc_iter); in sbefifo_collect_async_ffdc()
691 struct device *dev = &sbefifo->fsi_dev->dev; in __sbefifo_submit()
694 if (sbefifo->dead) in __sbefifo_submit()
695 return -ENODEV; in __sbefifo_submit()
700 return -EINVAL; in __sbefifo_submit()
709 if (sbefifo->async_ffdc) in __sbefifo_submit()
713 if (rc != 0 && rc != -EOVERFLOW) in __sbefifo_submit()
728 * sbefifo_submit() - Submit and SBE fifo command and receive response
731 * @cmd_len: The command size (in 32-bit words)
736 * overflows, returns -EOVERFLOW
748 return -ENODEV; in sbefifo_submit()
751 return -ENODEV; in sbefifo_submit()
752 if (WARN_ON_ONCE(sbefifo->magic != SBEFIFO_MAGIC)) in sbefifo_submit()
753 return -ENODEV; in sbefifo_submit()
755 return -EINVAL; in sbefifo_submit()
764 rc = mutex_lock_interruptible(&sbefifo->lock); in sbefifo_submit()
768 mutex_unlock(&sbefifo->lock); in sbefifo_submit()
771 rbytes -= iov_iter_count(&resp_iter); in sbefifo_submit()
784 if (is_vmalloc_addr(user->pending_cmd)) in sbefifo_release_command()
785 vfree(user->pending_cmd); in sbefifo_release_command()
786 user->pending_cmd = NULL; in sbefifo_release_command()
787 user->pending_len = 0; in sbefifo_release_command()
792 struct sbefifo *sbefifo = container_of(inode->i_cdev, struct sbefifo, cdev); in sbefifo_user_open()
797 return -ENOMEM; in sbefifo_user_open()
799 file->private_data = user; in sbefifo_user_open()
800 user->sbefifo = sbefifo; in sbefifo_user_open()
801 user->cmd_page = (void *)__get_free_page(GFP_KERNEL); in sbefifo_user_open()
802 if (!user->cmd_page) { in sbefifo_user_open()
804 return -ENOMEM; in sbefifo_user_open()
806 mutex_init(&user->file_lock); in sbefifo_user_open()
807 user->cmd_timeout_ms = SBEFIFO_TIMEOUT_IN_CMD; in sbefifo_user_open()
808 user->read_timeout_ms = SBEFIFO_TIMEOUT_START_RSP; in sbefifo_user_open()
816 struct sbefifo_user *user = file->private_data; in sbefifo_user_read()
824 return -EINVAL; in sbefifo_user_read()
825 sbefifo = user->sbefifo; in sbefifo_user_read()
827 return -EINVAL; in sbefifo_user_read()
829 mutex_lock(&user->file_lock); in sbefifo_user_read()
831 /* Cronus relies on -EAGAIN after a short read */ in sbefifo_user_read()
832 if (user->pending_len == 0) { in sbefifo_user_read()
833 rc = -EAGAIN; in sbefifo_user_read()
836 if (user->pending_len < 8) { in sbefifo_user_read()
837 rc = -EINVAL; in sbefifo_user_read()
840 cmd_len = user->pending_len >> 2; in sbefifo_user_read()
848 rc = mutex_lock_interruptible(&sbefifo->lock); in sbefifo_user_read()
851 sbefifo->timeout_in_cmd_ms = user->cmd_timeout_ms; in sbefifo_user_read()
852 sbefifo->timeout_start_rsp_ms = user->read_timeout_ms; in sbefifo_user_read()
853 rc = __sbefifo_submit(sbefifo, user->pending_cmd, cmd_len, &resp_iter); in sbefifo_user_read()
854 sbefifo->timeout_start_rsp_ms = SBEFIFO_TIMEOUT_START_RSP; in sbefifo_user_read()
855 sbefifo->timeout_in_cmd_ms = SBEFIFO_TIMEOUT_IN_CMD; in sbefifo_user_read()
856 mutex_unlock(&sbefifo->lock); in sbefifo_user_read()
861 rc = len - iov_iter_count(&resp_iter); in sbefifo_user_read()
864 mutex_unlock(&user->file_lock); in sbefifo_user_read()
871 struct sbefifo_user *user = file->private_data; in sbefifo_user_write()
876 return -EINVAL; in sbefifo_user_write()
877 sbefifo = user->sbefifo; in sbefifo_user_write()
879 return -EINVAL; in sbefifo_user_write()
881 return -EINVAL; in sbefifo_user_write()
883 mutex_lock(&user->file_lock); in sbefifo_user_write()
885 /* Can we use the pre-allocate buffer ? If not, allocate */ in sbefifo_user_write()
887 user->pending_cmd = user->cmd_page; in sbefifo_user_write()
889 user->pending_cmd = vmalloc(len); in sbefifo_user_write()
890 if (!user->pending_cmd) { in sbefifo_user_write()
891 rc = -ENOMEM; in sbefifo_user_write()
896 if (copy_from_user(user->pending_cmd, buf, len)) { in sbefifo_user_write()
897 rc = -EFAULT; in sbefifo_user_write()
902 if (len == 4 && be32_to_cpu(*(__be32 *)user->pending_cmd) == in sbefifo_user_write()
906 user->pending_len = 0; in sbefifo_user_write()
909 rc = mutex_lock_interruptible(&sbefifo->lock); in sbefifo_user_write()
912 rc = sbefifo_request_reset(user->sbefifo); in sbefifo_user_write()
913 mutex_unlock(&sbefifo->lock); in sbefifo_user_write()
920 user->pending_len = len; in sbefifo_user_write()
922 if (!user->pending_len) in sbefifo_user_write()
925 mutex_unlock(&user->file_lock); in sbefifo_user_write()
933 struct sbefifo_user *user = file->private_data; in sbefifo_user_release()
936 return -EINVAL; in sbefifo_user_release()
939 free_page((unsigned long)user->cmd_page); in sbefifo_user_release()
947 struct device *dev = &user->sbefifo->dev; in sbefifo_cmd_timeout()
948 u32 timeout; in sbefifo_cmd_timeout() local
950 if (get_user(timeout, (__u32 __user *)argp)) in sbefifo_cmd_timeout()
951 return -EFAULT; in sbefifo_cmd_timeout()
953 if (timeout == 0) { in sbefifo_cmd_timeout()
954 user->cmd_timeout_ms = SBEFIFO_TIMEOUT_IN_CMD; in sbefifo_cmd_timeout()
955 dev_dbg(dev, "Command timeout reset to %us\n", user->cmd_timeout_ms / 1000); in sbefifo_cmd_timeout()
959 user->cmd_timeout_ms = timeout * 1000; /* user timeout is in sec */ in sbefifo_cmd_timeout()
960 dev_dbg(dev, "Command timeout set to %us\n", timeout); in sbefifo_cmd_timeout()
966 struct device *dev = &user->sbefifo->dev; in sbefifo_read_timeout()
967 u32 timeout; in sbefifo_read_timeout() local
969 if (get_user(timeout, (__u32 __user *)argp)) in sbefifo_read_timeout()
970 return -EFAULT; in sbefifo_read_timeout()
972 if (timeout == 0) { in sbefifo_read_timeout()
973 user->read_timeout_ms = SBEFIFO_TIMEOUT_START_RSP; in sbefifo_read_timeout()
974 dev_dbg(dev, "Timeout reset to %us\n", user->read_timeout_ms / 1000); in sbefifo_read_timeout()
978 user->read_timeout_ms = timeout * 1000; /* user timeout is in sec */ in sbefifo_read_timeout()
979 dev_dbg(dev, "Timeout set to %us\n", timeout); in sbefifo_read_timeout()
983 static long sbefifo_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) in sbefifo_user_ioctl() argument
985 struct sbefifo_user *user = file->private_data; in sbefifo_user_ioctl()
986 int rc = -ENOTTY; in sbefifo_user_ioctl()
989 return -EINVAL; in sbefifo_user_ioctl()
991 mutex_lock(&user->file_lock); in sbefifo_user_ioctl()
992 switch (cmd) { in sbefifo_user_ioctl()
1000 mutex_unlock(&user->file_lock); in sbefifo_user_ioctl()
1017 put_device(&sbefifo->fsi_dev->dev); in sbefifo_free()
1038 return -ENOMEM; in sbefifo_probe()
1043 return -ENODEV; in sbefifo_probe()
1046 sbefifo->magic = SBEFIFO_MAGIC; in sbefifo_probe()
1047 sbefifo->fsi_dev = fsi_dev; in sbefifo_probe()
1049 mutex_init(&sbefifo->lock); in sbefifo_probe()
1050 sbefifo->timeout_in_cmd_ms = SBEFIFO_TIMEOUT_IN_CMD; in sbefifo_probe()
1051 sbefifo->timeout_start_rsp_ms = SBEFIFO_TIMEOUT_START_RSP; in sbefifo_probe()
1054 sbefifo->dev.type = &fsi_cdev_type; in sbefifo_probe()
1055 sbefifo->dev.parent = dev; in sbefifo_probe()
1056 sbefifo->dev.release = sbefifo_free; in sbefifo_probe()
1057 device_initialize(&sbefifo->dev); in sbefifo_probe()
1060 rc = fsi_get_new_minor(fsi_dev, fsi_dev_sbefifo, &sbefifo->dev.devt, &didx); in sbefifo_probe()
1064 dev_set_name(&sbefifo->dev, "sbefifo%d", didx); in sbefifo_probe()
1065 cdev_init(&sbefifo->cdev, &sbefifo_fops); in sbefifo_probe()
1066 rc = cdev_device_add(&sbefifo->cdev, &sbefifo->dev); in sbefifo_probe()
1069 rc, dev_name(&sbefifo->dev)); in sbefifo_probe()
1074 for_each_available_child_of_node(dev->of_node, np) { in sbefifo_probe()
1075 snprintf(child_name, sizeof(child_name), "%s-dev%d", in sbefifo_probe()
1076 dev_name(&sbefifo->dev), child_idx++); in sbefifo_probe()
1083 device_create_file(&sbefifo->dev, &dev_attr_timeout); in sbefifo_probe()
1087 fsi_free_minor(sbefifo->dev.devt); in sbefifo_probe()
1089 put_device(&sbefifo->dev); in sbefifo_probe()
1098 if (dev->of_node) in sbefifo_unregister_child()
1099 of_node_clear_flag(dev->of_node, OF_POPULATED); in sbefifo_unregister_child()
1110 device_remove_file(&sbefifo->dev, &dev_attr_timeout); in sbefifo_remove()
1112 mutex_lock(&sbefifo->lock); in sbefifo_remove()
1113 sbefifo->dead = true; in sbefifo_remove()
1114 mutex_unlock(&sbefifo->lock); in sbefifo_remove()
1116 cdev_device_del(&sbefifo->cdev, &sbefifo->dev); in sbefifo_remove()
1117 fsi_free_minor(sbefifo->dev.devt); in sbefifo_remove()
1119 put_device(&sbefifo->dev); in sbefifo_remove()