#include <linux/rtc.h>
#include <linux/clk.h>
#include <linux/timekeeping.h>
+#ifdef CONFIG_EXYNOS_ITMON
+#include <soc/samsung/exynos-itmon.h>
+#endif
#ifdef CONFIG_CHRE_SENSORHUB_HAL
#include "main.h"
atomic_dec(&ipc->read_lock.cnt);
}
+static void enable_debug_workqueue(struct contexthub_ipc_info *ipc, enum chub_err_type err)
+{
+ ipc->err_cnt[err]++;
+ ipc->active_err |= (1 << err);
+
+ dev_info(ipc->dev, "%s: err:%d(cnt:%d), active:0x%x\n",
+ __func__, err, ipc->err_cnt[err], ipc->active_err);
+
+ if (err == CHUB_ERR_ITMON) {
+ chub_dbg_dump_gpr(ipc);
+ chub_dbg_dump_ram(ipc, err);
+ chub_dbg_print_hw(ipc);
+ } else {
+ schedule_work(&ipc->debug_work);
+ }
+}
+
int contexthub_ipc_read(struct contexthub_ipc_info *ipc, uint8_t *rx, int max_length,
int timeout)
{
#endif
fail_get_channel:
- ipc->err_cnt[CHUB_ERR_READ_FAIL]++;
- dev_err(ipc->dev,
- "%s: fails to get data errcnt:%d\n",
- __func__, ipc->err_cnt[CHUB_ERR_READ_FAIL]);
- schedule_work(&ipc->debug_work);
+ enable_debug_workqueue(ipc, CHUB_ERR_READ_FAIL);
return -EINVAL;
}
ret = ipc_write_data(IPC_DATA_A2C, tx, (u16)length);
if (ret) {
- ipc->err_cnt[CHUB_ERR_WRITE_FAIL]++;
pr_err("%s: fails to write data: ret:%d, len:%d errcnt:%d\n",
__func__, ret, length, ipc->err_cnt[CHUB_ERR_WRITE_FAIL]);
- schedule_work(&ipc->debug_work);
+ enable_debug_workqueue(ipc, CHUB_ERR_WRITE_FAIL);
length = 0;
}
return length;
if (atomic_read(&ipc->chub_status) == CHUB_ST_RUN ||
atomic_read(&ipc->chub_status) == CHUB_ST_NO_RESPONSE) {
atomic_set(&ipc->chub_status, CHUB_ST_NO_RESPONSE);
- ipc->err_cnt[CHUB_ERR_CHUB_NO_RESPONSE]++;
- schedule_work(&ipc->debug_work);
+ enable_debug_workqueue(ipc, CHUB_ERR_CHUB_NO_RESPONSE);
}
ret = -EINVAL;
}
ipc_write_debug_event(AP, (u32)event);
ipc_add_evt(IPC_EVT_A2C, IRQ_EVT_A2C_DEBUG);
}
-
return ret;
}
int ret;
dev_info(ipc->dev, "%s\n", __func__);
-#if 0
- spin_lock(&ipc->reset_lock);
- if (atomic_read(&ipc->chub_status) == CHUB_ST_RUN) {
- spin_unlock(&ipc->reset_lock);
- pr_err("%s: chub already reset. run: %d\n",
- __func__, atomic_read(&ipc->chub_status));
- return 0;
+ if (atomic_read(&ipc->in_reset)) {
+ dev_info(ipc->dev, "%s is in-progress\n", __func__);
+ return -EINVAL;
}
-#endif
+
+ atomic_inc(&ipc->in_reset);
ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_SHUTDOWN);
if (ret) {
- pr_err("%s: shutdonw fails, ret:%d\n", __func__, ret);
+ dev_err(ipc->dev, "%s: shutdonw fails, ret:%d\n", __func__, ret);
return ret;
}
if (ipc->block_reset) {
if (!ret) {
ret = contexthub_download_image(ipc, 0);
if (ret) {
- pr_err("%s: download os fails\n", __func__);
+ dev_err(ipc->dev, "%s: download os fails\n", __func__);
return ret;
}
} else {
- pr_err("%s: download bl fails\n", __func__);
+ dev_err(ipc->dev, "%s: download bl fails\n", __func__);
return ret;
}
}
ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_RESET);
if (ret)
- pr_err("%s: reset fails, ret:%d\n", __func__, ret);
-#if 0
- spin_unlock(&ipc->reset_lock);
-#endif
+ dev_err(ipc->dev, "%s: reset fails, ret:%d\n", __func__, ret);
+ else
+ dev_info(ipc->dev, "%s: chub reseted! (cnt:%d)\n",
+ __func__, atomic_read(&ipc->in_reset));
+
+ atomic_dec(&ipc->in_reset);
return ret;
}
{
struct contexthub_ipc_info *ipc =
container_of(work, struct contexthub_ipc_info, debug_work);
- enum ipc_debug_event event = ipc_read_debug_event(AP);
- enum CHUB_ERR_TYPE fw_err = 0;
+ enum ipc_debug_event event = 0;
+ enum chub_err_type err = 0;
bool need_reset = 0;
bool alive = contexthub_lowlevel_alive(ipc);
- int err = 0;
int ret;
int i;
- dev_info(ipc->dev, "%s: fw_err:%d, alive:%d\n",
- __func__, event, alive);
+ dev_info(ipc->dev, "%s: active_err:0x%x, alive:%d\n",
+ __func__, ipc->active_err, alive);
if (!alive || ipc->err_cnt[CHUB_ERR_NANOHUB_WDT]) {
need_reset = 1;
goto do_reset;
}
- for (i = 0; i < CHUB_ERR_MAX; i++) {
- if (ipc->err_cnt[i])
- dev_info(ipc->dev, "%s: err%d-%d\n",
- __func__, i, ipc->err_cnt[i]);
- /* if error is bigger than MAX_ERR_CNT, should be reset */
- if (ipc->err_cnt[i] > MAX_ERR_CNT) {
+ /* print error status */
+ for (i = 0; i < CHUB_ERR_CHUB_MAX; i++) {
+ if (ipc->active_err & (1 << i)) {
+ dev_info(ipc->dev, "%s: err%d-%d, active_err:0x%x\n",
+ __func__, i, ipc->err_cnt[i], ipc->active_err);
+ ipc->active_err &= ~(1 << i);
err = i;
- need_reset = 1;
}
}
-
- if (need_reset)
- goto do_reset;
-
- /* chub fw error */
- switch (event) {
- case IPC_DEBUG_CHUB_FULL_LOG:
- dev_warn(ipc->dev,
- "Contexthub notified that logbuf is full\n");
- break;
- case IPC_DEBUG_CHUB_PRINT_LOG:
- break;
- case IPC_DEBUG_CHUB_FAULT:
- dev_warn(ipc->dev, "Contexthub notified fault\n");
- err = CHUB_ERR_NANOHUB_FAULT;
- break;
- case IPC_DEBUG_CHUB_ASSERT:
- dev_warn(ipc->dev, "Contexthub notified assert\n");
- err = CHUB_ERR_NANOHUB_ASSERT;
- break;
- case IPC_DEBUG_CHUB_ERROR:
- dev_warn(ipc->dev, "Contexthub notified error\n");
- err = CHUB_ERR_NANOHUB_ERROR;
- break;
- default:
- break;
+ /* print comms error status */
+ for (i = CHUB_ERR_MAX + 1; i < CHUB_ERR_COMMS_MAX; i++) {
+ if (ipc->err_cnt[i])
+ dev_info(ipc->dev, "%s: comms: err%d-%d\n",
+ __func__, i, ipc->err_cnt[i]);
}
- if (event) /* clear dbg event */
+ /* check chub fw error */
+ event = ipc_read_debug_event(AP);
+ if (event) {
+ switch (event) {
+ case IPC_DEBUG_CHUB_FULL_LOG:
+ dev_warn(ipc->dev,
+ "Contexthub notified that logbuf is full\n");
+ break;
+ case IPC_DEBUG_CHUB_PRINT_LOG:
+ break;
+ case IPC_DEBUG_CHUB_FAULT:
+ dev_warn(ipc->dev, "Contexthub notified fault\n");
+ err = CHUB_ERR_NANOHUB_FAULT;
+ break;
+ case IPC_DEBUG_CHUB_ASSERT:
+ dev_warn(ipc->dev, "Contexthub notified assert\n");
+ err = CHUB_ERR_NANOHUB_ASSERT;
+ break;
+ case IPC_DEBUG_CHUB_ERROR:
+ dev_warn(ipc->dev, "Contexthub notified error\n");
+ err = CHUB_ERR_NANOHUB_ERROR;
+ break;
+ default:
+ break;
+ }
+
+ /* clear dbg event */
ipc_write_debug_event(AP, 0);
- if (err)
- ipc->err_cnt[fw_err]++;
+ if (err)
+ ipc->err_cnt[err]++;
+ }
do_reset:
dev_info(ipc->dev, "%s: error:%d, alive:%d\n",
/* dump hw & sram into file */
chub_dbg_dump_hw(ipc, err);
if (need_reset) {
+#ifdef CHUB_RESET_ENABLE
ret = contexthub_reset(ipc);
if (ret)
dev_warn(ipc->dev, "%s: fails to reset %d.\n",
if (ipc->irq_wdt)
enable_irq(ipc->irq_wdt);
}
+#endif
} else {
/* dump log into file: DO NOT logbuf dueto sram corruption */
log_dump_all(err);
switch (evt) {
case IRQ_EVT_C2A_DEBUG:
- schedule_work(&ipc->debug_work);
+ enable_debug_workqueue(ipc, CHUB_ERR_NANOHUB);
break;
case IRQ_EVT_C2A_INT:
if (atomic_read(&ipc->irq1_apInt) == C2A_OFF) {
int start_index = ipc_hw_read_int_start_index(AP);
unsigned int status = ipc_hw_read_int_status_reg(AP);
struct ipc_evt_buf *cur_evt;
- enum CHUB_ERR_TYPE err = 0;
+ enum chub_err_type err = 0;
enum irq_chub evt = 0;
int irq_num = IRQ_EVT_CHUB_ALIVE + start_index;
ipc_hw_read_int_gen_reg(AP));
ipc->err_cnt[err]++;
ipc_hw_clear_all_int_pend_reg(AP);
- schedule_work(&ipc->debug_work);
+ enable_debug_workqueue(ipc, err);
}
return IRQ_HANDLED;
}
-#ifdef WDT_ENABLE
+#ifdef CHUB_RESET_ENABLE
static irqreturn_t contexthub_irq_wdt_handler(int irq, void *data)
{
struct contexthub_ipc_info *ipc = data;
dev_info(ipc->dev, "%s calledn", __func__);
- ipc->err_cnt[CHUB_ERR_NANOHUB_WDT]++;
disable_irq_nosync(ipc->irq_wdt);
- schedule_work(&ipc->debug_work);
+ enable_debug_workqueue(ipc, CHUB_ERR_NANOHUB_WDT);
return IRQ_HANDLED;
}
return ret;
}
-#ifdef WDT_ENABLE
+#ifdef CHUB_RESET_ENABLE
/* get wdt interrupt optionally */
chub->irq_wdt = irq_of_parse_and_map(node, 1);
if (chub->irq_wdt > 0) {
__ATTR(reset, 0220, NULL, chub_reset),
};
+#ifdef CONFIG_EXYNOS_ITMON
+static int chub_itmon_notifier(struct notifier_block *nb,
+ unsigned long action, void *nb_data)
+{
+ struct contexthub_ipc_info *data = container_of(nb, struct contexthub_ipc_info, itmon_nb);
+ struct itmon_notifier *itmon_data = nb_data;
+
+ if (itmon_data && itmon_data->master &&
+ ((!strncmp("CM4_SHUB_CD", itmon_data->master, sizeof("CM4_SHUB_CD") - 1)) ||
+ (!strncmp("CM4_SHUB_P", itmon_data->master, sizeof("CM4_SHUB_P") - 1)) ||
+ (!strncmp("PDMA_SHUB", itmon_data->master, sizeof("PDMA_SHUB") - 1)))) {
+ dev_info(data->dev, "%s: chub(%s) itmon detected: action:%d!!\n",
+ __func__, itmon_data->master, action);
+ enable_debug_workqueue(data, CHUB_ERR_ITMON);
+ return NOTIFY_OK;
+ }
+
+ return NOTIFY_DONE;
+}
+#endif
+
static int contexthub_ipc_probe(struct platform_device *pdev)
{
struct contexthub_ipc_info *chub;
#endif
atomic_set(&chub->chub_status, CHUB_ST_NO_POWER);
+ atomic_set(&chub->in_reset, 0);
chub->powermode = 0; /* updated by fw bl */
+ chub->active_err = 0;
chub->dev = &pdev->dev;
platform_set_drvdata(pdev, chub);
contexthub_config_init(chub);
attributes[i].attr.name);
}
- spin_lock_init(&chub->reset_lock);
init_waitqueue_head(&chub->read_lock.event);
init_waitqueue_head(&chub->chub_alive_lock.event);
INIT_WORK(&chub->debug_work, handle_debug_work_func);
#ifdef CONFIG_CONTEXTHUB_DEBUG
INIT_WORK(&chub->utc_work, handle_utc_work_func);
#endif
+#ifdef CONFIG_EXYNOS_ITMON
+ chub->itmon_nb.notifier_call = chub_itmon_notifier;
+ itmon_notifier_chain_register(&chub->itmon_nb);
+#endif
dev_info(chub->dev, "%s with %s FW and %lu clk is done\n",
__func__, chub->os_name, chub->clkrate);
wait_queue_head_t event;
};
-enum CHUB_ERR_TYPE {
+enum chub_err_type {
CHUB_ERR_NONE,
CHUB_ERR_EVTQ_EMTPY, /* ap error */
CHUB_ERR_READ_FAIL,
CHUB_ERR_WRITE_FAIL,
CHUB_ERR_EVTQ_NO_HW_TRIGGER,
CHUB_ERR_CHUB_NO_RESPONSE,
- CHUB_ERR_COMMS_NACK,
- CHUB_ERR_COMMS_BUSY,
- CHUB_ERR_COMMS_UNKNOWN,
- CHUB_ERR_COMMS,
+ CHUB_ERR_ITMON,
+ CHUB_ERR_NANOHUB,
+ CHUB_ERR_CHUB_MAX,
CHUB_ERR_NANOHUB_FAULT, /* chub error */
CHUB_ERR_NANOHUB_ASSERT,
CHUB_ERR_NANOHUB_ERROR,
CHUB_ERR_NANOHUB_WDT,
+ CHUB_ERR_COMMS_NACK,
+ CHUB_ERR_COMMS_BUSY,
+ CHUB_ERR_COMMS_UNKNOWN,
+ CHUB_ERR_COMMS,
+ CHUB_ERR_COMMS_MAX,
CHUB_ERR_MAX,
};
struct LOG_BUFFER *dd_log_buffer;
unsigned long clkrate;
atomic_t chub_status;
+ atomic_t in_reset;
atomic_t irq1_apInt;
atomic_t wakeup_chub;
- spinlock_t reset_lock;
int irq_mailbox;
int irq_wdt;
int err_cnt[CHUB_ERR_MAX];
+ u32 active_err;
int utc_run;
int powermode;
int block_reset;
bool os_load;
char os_name[MAX_FILE_LEN];
+ struct notifier_block itmon_nb;
#ifdef CONFIG_CONTEXTHUB_DEBUG
struct work_struct utc_work;
#endif
static struct dbg_dump *p_dbg_dump;
static struct reserved_mem *chub_rmem;
-void chub_dbg_dump_gpr(struct contexthub_ipc_info *ipc)
+void chub_dbg_print_hw(struct contexthub_ipc_info *ipc)
{
- int ret = contexthub_request(ipc);
+ if (p_dbg_dump) {
+ int i;
+ struct dbg_dump *p_dump = p_dbg_dump;
- if (ret) {
- pr_err("%s: fails to contexthub_request\n", __func__);
- return;
+ dev_info(ipc->dev, "%s: err:%d, time:%lld\n",
+ __func__, p_dump->reason, p_dump->time);
+
+ for (i = 0; i <= GPR_PC_INDEX; i++)
+ pr_info("gpr: R%d: 0x%x\n", i, p_dump->gpr[i]);
+
+ print_hex_dump(KERN_CONT, "dram:",
+ DUMP_PREFIX_OFFSET, 16, 1, p_dbg_dump, sizeof(struct dbg_dump), false);
+#if 0
+ print_hex_dump(KERN_CONT, "sram:",
+ DUMP_PREFIX_OFFSET, 16, 1, &p_dbg_dump->sram[p_dbg_dump->sram_start],
+ ipc_get_chub_mem_size(), false);
+#endif
}
+}
+void chub_dbg_dump_gpr(struct contexthub_ipc_info *ipc)
+{
if (p_dbg_dump) {
int i;
struct dbg_dump *p_dump = p_dbg_dump;
+ if (contexthub_request(ipc)) {
+ pr_err("%s: fails to contexthub_request\n", __func__);
+ return;
+ }
+
IPC_HW_WRITE_DUMPGPR_CTRL(ipc->chub_dumpgrp, 0x1);
/* dump GPR */
for (i = 0; i <= GPR_PC_INDEX - 1; i++)
i * 4);
p_dump->gpr[GPR_PC_INDEX] =
readl(ipc->chub_dumpgrp + REG_CHUB_DUMPGPR_PCR);
- }
- contexthub_release(ipc);
+ contexthub_release(ipc);
+ }
}
static u32 get_dbg_dump_size(void)
}
#endif
-void chub_dbg_dump_hw(struct contexthub_ipc_info *ipc, int reason)
+/* dump hw into dram (chub reserved mem) */
+void chub_dbg_dump_ram(struct contexthub_ipc_info *ipc, enum chub_err_type reason)
{
- int ret = contexthub_request(ipc);
-
- if (ret) {
- pr_err("%s: fails to contexthub_request\n", __func__);
- return;
- }
-
if (p_dbg_dump) {
+ if (contexthub_request(ipc)) {
+ pr_err("%s: fails to contexthub_request\n", __func__);
+ return;
+ }
+
p_dbg_dump->time = sched_clock();
p_dbg_dump->reason = reason;
- /* dump GPR */
- chub_dbg_dump_gpr(ipc);
/* dump SRAM to reserved DRAM */
memcpy_fromio(&p_dbg_dump->sram[p_dbg_dump->sram_start],
ipc_get_base(IPC_REG_DUMP),
ipc_get_chub_mem_size());
+ contexthub_release(ipc);
+ }
+}
+
+void chub_dbg_dump_hw(struct contexthub_ipc_info *ipc, enum chub_err_type reason)
+{
+ dev_info(ipc->dev, "%s: reason:%d\n", __func__, reason);
+ chub_dbg_dump_gpr(ipc);
+ chub_dbg_dump_ram(ipc, reason);
+
+ if (p_dbg_dump) {
#ifdef CONFIG_CONTEXTHUB_DEBUG
+ if (contexthub_request(ipc)) {
+ pr_err("%s: fails to contexthub_request\n", __func__);
+ return;
+ }
+
/* write file */
- dev_dbg(ipc->dev,
+ dev_info(ipc->dev,
"%s: write file: sram:%p, dram:%p(off:%d), size:%d\n",
__func__, ipc_get_base(IPC_REG_DUMP),
&p_dbg_dump->sram[p_dbg_dump->sram_start],
p_dbg_dump->sram_start, ipc_get_chub_mem_size());
+
chub_dbg_write_file(ipc->dev, "dram",
p_dbg_dump, sizeof(struct dbg_dump));
+
chub_dbg_write_file(ipc->dev, "sram",
&p_dbg_dump->sram[p_dbg_dump->sram_start],
ipc_get_chub_mem_size());
+
+ contexthub_release(ipc);
#endif
}
- contexthub_release(ipc);
}
void chub_dbg_check_and_download_image(struct contexthub_ipc_info *ipc)
[IPC_DEBUG_UTC_CHECK_CPU_UTIL] = "utilization",
[IPC_DEBUG_UTC_HEAP_DEBUG] = "heap",
[IPC_DEBUG_UTC_HANG] = "hang",
- [IPC_DEBUG_NANOHUB_CHUB_ALIVE] = "alive",
};
-static ssize_t chub_utc_show(struct device *kobj,
+
+static ssize_t chub_alive_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int index = 0;
+ struct contexthub_ipc_info *ipc = dev_get_drvdata(dev);
+ int ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_CHUB_ALIVE);
+
+ if (!ret)
+ index += sprintf(buf, "chub alive\n");
+ else
+ index += sprintf(buf, "chub isn't alive\n");
+
+ return index;
+}
+
+static ssize_t chub_utc_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int i;
err = kstrtol(&buf[0], 10, &event);
if (!err) {
- if (event == IPC_DEBUG_NANOHUB_CHUB_ALIVE)
- event = MAILBOX_EVT_CHUB_ALIVE;
-
- if (event != MAILBOX_EVT_CHUB_ALIVE) {
- err = contexthub_request(ipc);
- if (err)
- pr_err("%s: fails to request contexthub. ret:%d\n", __func__, err);
- }
+ err = contexthub_request(ipc);
+ if (err)
+ pr_err("%s: fails to request contexthub. ret:%d\n", __func__, err);
contexthub_ipc_write_event(ipc, event);
- if (event != MAILBOX_EVT_CHUB_ALIVE)
- contexthub_release(ipc);
-
+ contexthub_release(ipc);
return count;
} else {
return 0;
__ATTR(dump_hw, 0220, NULL, chub_set_dump_hw_store),
__ATTR(utc, 0664, chub_utc_show, chub_utc_store),
__ATTR(ipc_test, 0220, NULL, chub_ipc_store),
+ __ATTR(alive, 0440, chub_alive_show, NULL),
__ATTR(wakeup, 0220, NULL, chub_wakeup_store),
};
int chub_dbg_init(struct device *dev);
void *chub_dbg_get_memory(enum dbg_dump_area area);
-void chub_dbg_dump_hw(struct contexthub_ipc_info *ipc, int reason);
+void chub_dbg_dump_hw(struct contexthub_ipc_info *ipc, enum chub_err_type reason);
+void chub_dbg_dump_ram(struct contexthub_ipc_info *ipc, enum chub_err_type reason);
+void chub_dbg_dump_gpr(struct contexthub_ipc_info *ipc);
+void chub_dbg_print_hw(struct contexthub_ipc_info *ipc);
void chub_dbg_dump_status(struct contexthub_ipc_info *ipc);
void chub_dbg_check_and_download_image(struct contexthub_ipc_info *ipc);
#endif /* __CHUB_DEBUG_H */
else if (eq < dq)
useful = dq - eq;
else if (ipc_data->full) {
- CSP_PRINTF_ERROR("%s is full\n", __func__);
+ CSP_PRINTF_ERROR("%s is full(eq:%d, dq:%d, f:%d, e:%d)\n",
+ __func__, ipc_data->eq, ipc_data->dq, ipc_data->full, ipc_data->empty);
return -1;
} else {
useful = IPC_DATA_SIZE;
/* check length */
if (length + sizeof(u16) > useful) {
CSP_PRINTF_ERROR
- ("%s: no buffer. len:%d, remain:%d, eq:%d, dq:%d\n",
- __func__, length, useful, eq, dq);
+ ("%s: no buffer. len:%d, remain:%d eq:%d, dq:%d (eq:%d, dq:%d, f:%d, e:%d)\n",
+ __func__, length, useful, eq, dq, ipc_data->eq, ipc_data->dq, ipc_data->full, ipc_data->empty);
return -1;
}
else if (eq < dq)
useful = (IPC_DATA_SIZE - dq) + eq;
else if (ipc_data->empty) {
- CSP_PRINTF_ERROR("%s is empty\n", __func__);
+ CSP_PRINTF_ERROR("%s is empty (eq:%d, dq:%d, f:%d, e:%d)\n",
+ __func__, ipc_data->eq, ipc_data->dq, ipc_data->full, ipc_data->empty);
return 0;
} else {
useful = IPC_DATA_SIZE;
#endif
if (useful < sizeof(u16) + size_to_read) {
- CSP_PRINTF_ERROR("%s: no enought read size: useful:%d, read_to_size:%d,%d\n",
- __func__, useful, size_to_read, sizeof(u16));
+ CSP_PRINTF_ERROR("%s: no enough read size: useful:%d, read_to_size:%d,%d (eq:%d, dq:%d, f:%d, e:%d)\n",
+ __func__, useful, size_to_read, sizeof(u16),
+ ipc_data->eq, ipc_data->dq, ipc_data->full, ipc_data->empty);
return 0;
}
IPC_DEBUG_UTC_IPC_TEST_START,
IPC_DEBUG_UTC_IPC_TEST_END,
IPC_DEBUG_UTC_MAX,
- IPC_DEBUG_NANOHUB_CHUB_ALIVE = IPC_DEBUG_UTC_MAX,
IPC_DEBUG_NANOHUB_MAX,
IPC_DEBUG_DUMP_STATUS,
IPC_DEBUG_FLUSH_LOG,
struct log_kernel_buffer *kernel_buffer = &info->kernel_buffer;
unsigned int index_writer = buffer->index_writer;
+ /* check logbuf index dueto sram corruption */
+ if ((buffer->index_reader >= ipc_get_offset(IPC_REG_LOG))
+ || (buffer->index_writer >= ipc_get_offset(IPC_REG_LOG))) {
+ dev_err(info->dev, "%s(%d): offset is corrupted. index_writer=%u, index_reader=%u, size=%u-%u\n",
+ __func__, info->id, buffer->index_writer, buffer->index_reader, buffer->size,
+ ipc_get_offset(IPC_REG_LOG));
+
+ return;
+ }
+
if (buffer->index_reader == index_writer)
return;
struct LOG_BUFFER *buffer = info->log_buffer;
u32 wrap_index = buffer->index_writer;
+ /* check logbuf index dueto sram corruption */
+ if ((buffer->index_reader >= ipc_get_offset(IPC_REG_LOG))
+ || (buffer->index_writer >= ipc_get_offset(IPC_REG_LOG))) {
+ dev_err(info->dev, "%s(%d): offset is corrupted. index_writer=%u, index_reader=%u, size=%u-%u\n",
+ __func__, info->id, buffer->index_writer, buffer->index_reader, buffer->size,
+ ipc_get_offset(IPC_REG_LOG));
+ return;
+ }
+
snprintf(save_file_name, sizeof(save_file_name),
"/data/nano-%02d-%02d-%06u.log", info->id, err,
(u32)(sched_clock() / NSEC_PER_SEC));
ret = ERROR_NACK;
else if (response->reason == CMD_COMMS_BUSY)
ret = ERROR_BUSY;
- else
- pr_warn("nanohub: invalid reason %d\n", __func__, response->reason);
}
if (response->seq != seq)
b[i + 24]);
}
ret = ERROR_NACK;
- pr_warn("nanohub: invalid seq %d\n", __func__,
- response->reason);
}
return ret;
uint32_t seq, uint8_t *rx, size_t rx_len)
{
int ret;
+ struct contexthub_ipc_info *ipc = data->pdata->mailbox_client;
+
+ if (atomic_read(&ipc->in_reset)) {
+ dev_err(ipc->dev, "%s: chub reset in-progress\n", __func__);
+ return ERROR_BUSY;
+ }
ret = data->comms.write(data, (uint8_t *)&pad->packet, packet_size,
data->comms.timeout_write);
uint32_t seq;
struct timespec ts;
s64 boottime;
+ struct contexthub_ipc_info *ipc = data->pdata->mailbox_client;
+
+ if (atomic_read(&ipc->in_reset)) {
+ packet_free(pad);
+ dev_err(ipc->dev, "%s: chub reset in-progress\n", __func__);
+ return ERROR_BUSY;
+ }
if (pad == NULL)
return ERROR_NACK;