{
int ret;
- /* TODO: add wait lock */
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;
+ }
+#endif
ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_SHUTDOWN);
if (ret) {
pr_err("%s: shutdonw fails, ret:%d\n", __func__, 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
return ret;
}
dev_info(ipc->dev, "%s: bootloader(size:0x%x) on %lx\n",
__func__, (int)entry->size,
(unsigned long)ipc_get_base(IPC_REG_BL));
-
release_firmware(entry);
} else {
ret = request_firmware(&entry, ipc->os_name, ipc->dev);
return ret;
}
memcpy(ipc_get_base(IPC_REG_OS), entry->data, entry->size);
- release_firmware(entry);
-
dev_info(ipc->dev, "%s: %s(size:0x%x) on %lx\n", __func__,
ipc->os_name, (int)entry->size,
(unsigned long)ipc_get_base(IPC_REG_OS));
+ release_firmware(entry);
}
return 0;
container_of(work, struct contexthub_ipc_info, utc_work);
int trycnt = 0;
+#if 0
while (ipc->utc_run) {
msleep(20000);
ipc_write_val(AP, sched_clock());
if (!(++trycnt % 10))
log_flush(ipc->fw_log);
};
+#endif
dev_dbg(ipc->dev, "%s is done with %d try\n", __func__, trycnt);
}
if (need_reset)
goto do_reset;
- log_flush(ipc->fw_log);
/* chub fw error */
switch (event) {
case IPC_DEBUG_CHUB_FULL_LOG:
ipc->err_cnt[fw_err]++;
do_reset:
- dev_info(ipc->dev, "%s: reset chub due to irq trigger error:%d\n",
- __func__, err);
- /* req to chub fw dump */
- ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_DUMP_STATUS);
- /* dump log into file */
- log_dump_all(err);
+ dev_info(ipc->dev, "%s: error:%d, alive:%d\n",
+ __func__, err, alive);
+
/* dump hw & sram into file */
chub_dbg_dump_hw(ipc, err);
if (need_reset) {
dev_info(ipc->dev, "%s: chub reset! should be recovery\n",
__func__);
if (CHUB_ERR_NANOHUB_WDT == CHUB_ERR_NANOHUB_WDT)
- enable_irq(ipc->irq_wdt);
+ if (ipc->irq_wdt)
+ enable_irq(ipc->irq_wdt);
}
+ } else {
+ /* dump log into file: DO NOT logbuf dueto sram corruption */
+ log_dump_all(err);
}
}
return IRQ_HANDLED;
}
+#ifdef WDT_ENABLE
static irqreturn_t contexthub_irq_wdt_handler(int irq, void *data)
{
struct contexthub_ipc_info *ipc = data;
return IRQ_HANDLED;
}
+#endif
static int contexthub_get_cmgp_clocks(struct device *dev)
{
return ret;
}
+#ifdef WDT_ENABLE
/* get wdt interrupt optionally */
chub->irq_wdt = irq_of_parse_and_map(node, 1);
if (chub->irq_wdt > 0) {
} else {
dev_info(dev, "don't use wdt irq:%d\n", irq);
}
+#endif
/* get MAILBOX SFR */
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mailbox");
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);
out:
set_fs(old_fs);
}
-#else
-#define chub_dbg_write_file(a) do { } while (0)
#endif
void chub_dbg_dump_hw(struct contexthub_ipc_info *ipc, int reason)
ipc_get_base(IPC_REG_DUMP),
ipc_get_chub_mem_size());
+#ifdef CONFIG_CONTEXTHUB_DEBUG
/* write file */
dev_dbg(ipc->dev,
"%s: write file: sram:%p, dram:%p(off:%d), size:%d\n",
chub_dbg_write_file(ipc->dev, "sram",
&p_dbg_dump->sram[p_dbg_dump->sram_start],
ipc_get_chub_mem_size());
+#endif
}
contexthub_release(ipc);
}
return 0;
}
+ chub_dbg_dump_status(ipc);
contexthub_ipc_write_event(ipc, MAILBOX_EVT_DUMP_STATUS);
contexthub_release(ipc);
static inline int ipc_io_data(enum ipc_data_list dir, u8 *buf, u16 length)
{
struct ipc_buf *ipc_data;
- int eq;
- int dq;
+ u32 eq;
+ u32 dq;
int useful = 0;
u8 size_lower;
u8 size_upper;
eq = ipc_data->eq;
dq = ipc_data->dq;
+ /* check index due to sram corruption */
+ if ((eq > IPC_DATA_SIZE) || (dq > IPC_DATA_SIZE) ||
+ (ipc_data->full > 1) || (ipc_data->empty > 1)) {
+ CSP_PRINTF_ERROR("%s: invalid index:%d, %d, %d, %d\n",
+ __func__, eq, dq, ipc_data->full, ipc_data->empty);
+ return -1;
+ }
+
#ifdef USE_IPC_BUF_LOG
CSP_PRINTF_INFO("%s: dir:%s(w:%d, r:%d, cnt:%d), e:%d d:%d, empty:%d, full:%d, ipc_data:%p, len:%d\n",
__func__, dir ? "a2c" : "c2a", ipc_data->cnt_dbg_wt,
return ret;
}
+#ifdef CONFIG_NANOHUB_MAILBOX /* remove invalid error check */
+static inline void contexthub_update_result(struct nanohub_data *data, int err)
+{
+ struct contexthub_ipc_info *ipc = data->pdata->mailbox_client;
+
+ if (!err)
+ ipc->err_cnt[CHUB_ERR_COMMS] = 0;
+ else {
+ ipc->err_cnt[CHUB_ERR_COMMS]++;
+
+ if (err == ERROR_NACK)
+ ipc->err_cnt[CHUB_ERR_COMMS_NACK]++;
+ else if (err == ERROR_BUSY)
+ ipc->err_cnt[CHUB_ERR_COMMS_BUSY]++;
+ else
+ ipc->err_cnt[CHUB_ERR_COMMS_BUSY]++;
+ }
+}
+#else
+#define contexthub_update_err_cnt(a, b) do { } while (0)
+#endif
+
static int get_reply(struct nanohub_data *data, struct nanohub_packet *response,
uint32_t seq)
{
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;
ret = ERROR_NACK;
}
+ contexthub_update_result(data, ret);
return ret;
}