[ERD][APR-103] [COMMON]chub: ipc: add error handling
authorBoojin Kim <boojin.kim@samsung.com>
Wed, 28 Nov 2018 00:34:41 +0000 (09:34 +0900)
committerhskang <hs1218.kang@samsung.com>
Sun, 21 Apr 2019 09:09:01 +0000 (18:09 +0900)
Change-Id: Ic5dbf550e72d937386bd8884b811a6cb8f13582f
Signed-off-by: Boojin Kim <boojin.kim@samsung.com>
drivers/staging/nanohub/chub.c
drivers/staging/nanohub/chub.h
drivers/staging/nanohub/chub_dbg.c
drivers/staging/nanohub/chub_dbg.h
drivers/staging/nanohub/chub_ipc.c
drivers/staging/nanohub/chub_ipc.h

index ce41e472feed49be3f3d77567650fdcca31d8175..1cdb44303189ab04ed324085889a8ebc979f0544 100644 (file)
@@ -336,7 +336,7 @@ static void handle_debug_work(struct contexthub_ipc_info *ipc, enum chub_err_typ
        }
 }
 
-static void request_debug_work(struct contexthub_ipc_info *ipc,
+static void contexthub_handle_debug(struct contexthub_ipc_info *ipc,
        enum chub_err_type err, bool enable_wq)
 {
        dev_info(ipc->dev, "%s: err:%d(cnt:%d), enable_wq:%d\n",
@@ -484,7 +484,7 @@ int contexthub_ipc_read(struct contexthub_ipc_info *ipc, uint8_t *rx, int max_le
        return ret;
 
 fail_get_channel:
-       request_debug_work(ipc, CHUB_ERR_READ_FAIL, 0);
+       contexthub_handle_debug(ipc, CHUB_ERR_READ_FAIL, 0);
        return -EINVAL;
 }
 
@@ -503,7 +503,7 @@ int contexthub_ipc_write(struct contexthub_ipc_info *ipc,
        if (ret) {
                pr_err("%s: fails to write data: ret:%d, len:%d errcnt:%d\n",
                        __func__, ret, length, ipc->err_cnt[CHUB_ERR_WRITE_FAIL]);
-               request_debug_work(ipc, CHUB_ERR_WRITE_FAIL, 0);
+               contexthub_handle_debug(ipc, CHUB_ERR_WRITE_FAIL, 0);
                length = 0;
        } else {
                clear_err_cnt(ipc, CHUB_ERR_WRITE_FAIL);
@@ -759,7 +759,7 @@ int contexthub_ipc_write_event(struct contexthub_ipc_info *ipc,
                                "%s : chub isn't alive, should be reset. status:%d\n",
                                __func__, atomic_read(&ipc->chub_status));
                        atomic_set(&ipc->chub_status, CHUB_ST_NO_RESPONSE);
-                       request_debug_work(ipc, CHUB_ERR_CHUB_NO_RESPONSE, 0);
+                       contexthub_handle_debug(ipc, CHUB_ERR_CHUB_NO_RESPONSE, 0);
                        ret = -EINVAL;
                }
                break;
@@ -777,51 +777,52 @@ int contexthub_ipc_write_event(struct contexthub_ipc_info *ipc,
                break;
        }
 
-       if (!need_ipc)
-               return ret;
-
-       if (contexthub_get_token(ipc)) {
-               dev_warn(ipc->dev, "%s event:%d/%d fails chub isn't active, status:%d, inreset:%d\n",
-                       __func__, event, MAILBOX_EVT_MAX, atomic_read(&ipc->chub_status), atomic_read(&ipc->in_reset));
-               return -EINVAL;
-       }
-
-       /* handle ipc */
-       switch (event) {
-       case MAILBOX_EVT_ERASE_SHARED:
-               memset(ipc_get_base(IPC_REG_SHARED), 0, ipc_get_offset(IPC_REG_SHARED));
-               break;
-       case MAILBOX_EVT_DUMP_STATUS:
-               /* dump nanohub kernel status */
-               dev_info(ipc->dev, "Request to dump chub fw status\n");
-               ipc_write_debug_event(AP, (u32)MAILBOX_EVT_DUMP_STATUS);
-               ipc_add_evt(IPC_EVT_A2C, IRQ_EVT_A2C_DEBUG);
-               break;
-       case MAILBOX_EVT_WAKEUP_CLR:
-               if (atomic_read(&ipc->wakeup_chub) == CHUB_ON) {
-                       atomic_set(&ipc->wakeup_chub, CHUB_OFF);
-                       ipc_add_evt(IPC_EVT_A2C, IRQ_EVT_A2C_WAKEUP_CLR);
-               }
-               break;
-       case MAILBOX_EVT_WAKEUP:
-               if (atomic_read(&ipc->wakeup_chub) == CHUB_OFF) {
-                       atomic_set(&ipc->wakeup_chub, CHUB_ON);
-                       ipc_add_evt(IPC_EVT_A2C, IRQ_EVT_A2C_WAKEUP);
+       if (need_ipc) {
+               if (contexthub_get_token(ipc)) {
+                       dev_warn(ipc->dev, "%s event:%d/%d fails chub isn't active, status:%d, inreset:%d\n",
+                               __func__, event, MAILBOX_EVT_MAX, atomic_read(&ipc->chub_status), atomic_read(&ipc->in_reset));
+                       return -EINVAL;
                }
-               break;
-       default:
-               /* handle ipc utc */
-               if ((int)event < IPC_DEBUG_UTC_MAX) {
-                       ipc->utc_run = event;
-                       if ((int)event == IPC_DEBUG_UTC_TIME_SYNC)
-                               check_rtc_time();
-                       ipc_write_debug_event(AP, (u32)event);
-                       ipc_add_evt(IPC_EVT_A2C, IRQ_EVT_A2C_DEBUG);
-                       ret = 0;
+
+               /* handle ipc */
+               switch (event) {
+               case MAILBOX_EVT_ERASE_SHARED:
+                       memset(ipc_get_base(IPC_REG_SHARED), 0, ipc_get_offset(IPC_REG_SHARED));
+                       break;
+               case MAILBOX_EVT_DUMP_STATUS:
+                       /* dump nanohub kernel status */
+                       dev_info(ipc->dev, "Request to dump chub fw status\n");
+                       ipc_write_debug_event(AP, (u32)MAILBOX_EVT_DUMP_STATUS);
+                       ret = ipc_add_evt(IPC_EVT_A2C, IRQ_EVT_A2C_DEBUG);
+                       break;
+               case MAILBOX_EVT_WAKEUP_CLR:
+                       if (atomic_read(&ipc->wakeup_chub) == CHUB_ON) {
+                               atomic_set(&ipc->wakeup_chub, CHUB_OFF);
+                               ret = ipc_add_evt(IPC_EVT_A2C, IRQ_EVT_A2C_WAKEUP_CLR);
+                       }
+                       break;
+               case MAILBOX_EVT_WAKEUP:
+                       if (atomic_read(&ipc->wakeup_chub) == CHUB_OFF) {
+                               atomic_set(&ipc->wakeup_chub, CHUB_ON);
+                               ret = ipc_add_evt(IPC_EVT_A2C, IRQ_EVT_A2C_WAKEUP);
+                       }
+                       break;
+               default:
+                       /* handle ipc utc */
+                       if ((int)event < IPC_DEBUG_UTC_MAX) {
+                               ipc->utc_run = event;
+                               if ((int)event == IPC_DEBUG_UTC_TIME_SYNC)
+                                       check_rtc_time();
+                               ipc_write_debug_event(AP, (u32)event);
+                               ret = ipc_add_evt(IPC_EVT_A2C, IRQ_EVT_A2C_DEBUG);
+                       }
+                       break;
                }
-               break;
+               contexthub_put_token(ipc);
+
+               if (ret)
+                       ipc->err_cnt[CHUB_ERR_EVTQ_ADD]++;
        }
-       contexthub_put_token(ipc);
        return ret;
 }
 
@@ -865,7 +866,6 @@ int contexthub_poweron(struct contexthub_ipc_info *ipc)
        } else {
                ret = -EINVAL;
        }
-
        return ret;
 }
 
@@ -932,8 +932,10 @@ int contexthub_reset(struct contexthub_ipc_info *ipc, bool force_load, int dump)
                dev_info(ipc->dev, "%s: wait for ipc user free: %d\n", __func__, atomic_read(&ipc->in_use_ipc));
        } while (atomic_read(&ipc->in_use_ipc));
 
-       if (dump)
+       if (dump) {
+               ipc->err_cnt[CHUB_ERR_NONE] = dump;
                chub_dbg_dump_hw(ipc, ipc->cur_err);
+       }
 
        dev_info(ipc->dev, "%s: start reset status:%d\n", __func__, atomic_read(&ipc->chub_status));
        if (!ipc->block_reset) {
@@ -991,7 +993,7 @@ int contexthub_download_image(struct contexthub_ipc_info *ipc, enum ipc_region r
        const struct firmware *entry;
        int ret;
 
-       dev_info(ipc->dev, "%s: enter for bl:%d\n", reg == IPC_REG_BL);
+       dev_info(ipc->dev, "%s: enter for bl:%d\n", __func__, reg == IPC_REG_BL);
        if (reg == IPC_REG_BL)
                ret = request_firmware(&entry, "bl.unchecked.bin", ipc->dev);
        else if (reg == IPC_REG_OS)
@@ -1016,7 +1018,7 @@ static void handle_irq(struct contexthub_ipc_info *ipc, enum irq_evt_chub evt)
 {
        switch (evt) {
        case IRQ_EVT_C2A_DEBUG:
-               request_debug_work(ipc, CHUB_ERR_NANOHUB, 1);
+               contexthub_handle_debug(ipc, CHUB_ERR_NANOHUB, 1);
                break;
        case IRQ_EVT_C2A_INT:
                if (atomic_read(&ipc->irq1_apInt) == C2A_OFF) {
@@ -1099,7 +1101,7 @@ static irqreturn_t contexthub_irq_handler(int irq, void *data)
                       status, ipc_hw_read_int_status_reg(AP),
                       ipc_hw_read_int_gen_reg(AP));
                ipc_hw_clear_all_int_pend_reg(AP);
-               request_debug_work(ipc, err, 1);
+               contexthub_handle_debug(ipc, err, 1);
        } else {
                clear_err_cnt(ipc, CHUB_ERR_EVTQ_EMTPY);
                clear_err_cnt(ipc, CHUB_ERR_EVTQ_NO_HW_TRIGGER);
@@ -1115,7 +1117,7 @@ static irqreturn_t contexthub_irq_wdt_handler(int irq, void *data)
        dev_info(ipc->dev, "%s called\n", __func__);
        disable_irq_nosync(ipc->irq_wdt);
        ipc->irq_wdt_disabled = 1;
-       request_debug_work(ipc, CHUB_ERR_FW_WDT, 1);
+       contexthub_handle_debug(ipc, CHUB_ERR_FW_WDT, 1);
 
        return IRQ_HANDLED;
 }
@@ -1392,7 +1394,7 @@ static int chub_itmon_notifier(struct notifier_block *nb,
                (!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);
-               request_debug_work(data, CHUB_ERR_ITMON, 1);
+               contexthub_handle_debug(data, CHUB_ERR_ITMON, 1);
                return NOTIFY_OK;
        }
 
@@ -1490,23 +1492,43 @@ static int contexthub_ipc_remove(struct platform_device *pdev)
 static int contexthub_suspend(struct device *dev)
 {
        struct contexthub_ipc_info *ipc = dev_get_drvdata(dev);
+#ifdef CONFIG_CHRE_SENSORHUB_HAL
        struct nanohub_data *data = ipc->data;
+#endif
+
+       if (atomic_read(&ipc->chub_status) != CHUB_ST_RUN)
+               return 0;
 
-       pr_info("nanohub log to kernel off\n");
-       ipc_set_chub_kernel_log(KERNEL_LOG_OFF);
+       dev_dbg(dev, "nanohub log to kernel off\n");
+       ipc_hw_write_shared_reg(AP, MAILBOX_REQUEST_KLOG_OFF, SR_3);
+       ipc_hw_gen_interrupt(AP, IRQ_EVT_CHUB_ALIVE);
 
+#ifdef CONFIG_CHRE_SENSORHUB_HAL
        return nanohub_suspend(data->iio_dev);
+#else
+       return 0;
+#endif
 }
 
 static int contexthub_resume(struct device *dev)
 {
        struct contexthub_ipc_info *ipc = dev_get_drvdata(dev);
+#ifdef CONFIG_CHRE_SENSORHUB_HAL
        struct nanohub_data *data = ipc->data;
+#endif
 
-       pr_info("nanohub log to kernel on\n");
-       ipc_set_chub_kernel_log(KERNEL_LOG_ON);
+       if (atomic_read(&ipc->chub_status) != CHUB_ST_RUN)
+               return 0;
 
+       dev_dbg(dev, "nanohub log to kernel on\n");
+       ipc_hw_write_shared_reg(AP, MAILBOX_REQUEST_KLOG_ON, SR_3);
+       ipc_hw_gen_interrupt(AP, IRQ_EVT_CHUB_ALIVE);
+
+#ifdef CONFIG_CHRE_SENSORHUB_HAL
        return nanohub_resume(data->iio_dev);
+#else
+       return 0;
+#endif
 }
 
 static SIMPLE_DEV_PM_OPS(contexthub_pm_ops, contexthub_suspend, contexthub_resume);
index e7605af621197a8e9ec246011c5aa470127d22d1..c6c6f98c5e512e2c62f7969694bd8a8c70eb9892 100644 (file)
@@ -124,15 +124,16 @@ struct chub_alive {
 
 enum chub_err_type {
        CHUB_ERR_NONE,
-       CHUB_ERR_EVTQ_EMTPY, /* ap error */
+       CHUB_ERR_EVTQ_ADD, /* ap error */
+       CHUB_ERR_EVTQ_EMTPY,
        CHUB_ERR_READ_FAIL,
        CHUB_ERR_WRITE_FAIL,
-       CHUB_ERR_EVTQ_NO_HW_TRIGGER,
-       CHUB_ERR_CHUB_NO_RESPONSE, /* 5 */
+       CHUB_ERR_EVTQ_NO_HW_TRIGGER, /* 5 */
+       CHUB_ERR_CHUB_NO_RESPONSE,
        CHUB_ERR_ITMON,
        CHUB_ERR_FW_FAULT, /* chub error */
-       CHUB_ERR_FW_WDT, /* 8 */
-       CHUB_ERR_NEED_RESET,
+       CHUB_ERR_FW_WDT,
+       CHUB_ERR_NEED_RESET, /* 10 */
        CHUB_ERR_FW_ERROR = CHUB_ERR_NEED_RESET,
        CHUB_ERR_COMMS_NACK, /* ap comms error */
        CHUB_ERR_COMMS_BUSY,
@@ -151,6 +152,8 @@ struct contexthub_baaw_info {
 
 #define CHUB_IRQ_PIN_MAX (5)
 struct contexthub_ipc_info {
+       u32 cur_err;
+       int err_cnt[CHUB_ERR_MAX];
        struct device *dev;
        struct nanohub_data *data;
        struct nanohub_platform_data *pdata;
@@ -182,8 +185,6 @@ struct contexthub_ipc_info {
        int irq_mailbox;
        int irq_wdt;
        bool irq_wdt_disabled;
-       int err_cnt[CHUB_ERR_MAX];
-       u32 cur_err;
        int utc_run;
        int powermode;
        int block_reset;
index 4d03a0d29312046e935afbf8a3499d1da281ea7d..fa8d0f64187f6ac5a408bef5d4447d9e51b90563 100644 (file)
@@ -152,6 +152,7 @@ static void chub_dbg_dump_status(struct contexthub_ipc_info *ipc)
        log_flush(ipc->fw_log);
 }
 
+
 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);
@@ -583,7 +584,7 @@ int chub_dbg_init(struct contexthub_ipc_info *chub)
            (void *)p_dbg_dump;
        p_dbg_dump->info[area].size = bin_attr_chub_bin_sram.size;
 
-       dev_dbg(dev,
+       dev_info(dev,
                "%s(%pa) is mapped on %p (sram %p: startoffset:%d) with size of %u, dump size %u\n",
                "dump buffer", &chub_rmem->base, phys_to_virt(chub_rmem->base),
                &p_dbg_dump->sram[p_dbg_dump->sram_start],
index 50d09e094cbf3c90fc50b0e6ba3e331d46353e3b..27273a5aa9a573e5e8b04312d3c3020d97d26214 100644 (file)
@@ -26,4 +26,5 @@ void *chub_dbg_get_memory(enum dbg_dump_area area);
 void chub_dbg_dump_hw(struct contexthub_ipc_info *ipc, enum chub_err_type reason);
 void chub_dbg_print_hw(struct contexthub_ipc_info *ipc);
 int chub_dbg_check_and_download_image(struct contexthub_ipc_info *ipc);
+void chub_dbg_dump_on_reset(struct contexthub_ipc_info *ipc);
 #endif /* __CHUB_DEBUG_H */
index 79944659f60b3b35bf5ecb55b8bf48f6751afb9c..7ffc3124867b663d245044d24ea60d5a980463dc 100644 (file)
@@ -15,6 +15,7 @@
 #if defined(SEOS)
 #include <seos.h>
 #include <errno.h>
+#include <cmsis.h>
 #elif defined(EMBOS)
 #include <Device.h>
 #define EINVAL 22
@@ -263,6 +264,23 @@ void *ipc_get_chub_map(void)
        return ipc_map;
 }
 
+#ifdef CHUB_IPC
+#define DISABLE_IRQ() __disable_irq();
+#define ENABLE_IRQ() __enable_irq();
+static inline void busywait(u32 ms)
+{
+       msleep(ms);
+}
+#else /* AP IPC doesn't need it */
+#define DISABLE_IRQ() do {} while(0)
+#define ENABLE_IRQ() do {} while(0)
+static inline void busywait(u32 ms)
+{
+       (void)ms;
+       cpu_relax();
+}
+#endif
+
 #ifndef USE_IPC_BUF
 static inline bool __ipc_queue_empty(struct ipc_buf *ipc_data)
 {
@@ -285,6 +303,7 @@ int ipc_write_data(enum ipc_data_list dir, void *tx, u16 length)
        struct ipc_buf *ipc_data = ipc_get_base(reg);
 
        if (length <= PACKET_SIZE_MAX) {
+               DISABLE_IRQ();
                if (!__ipc_queue_full(ipc_data)) {
                        struct ipc_channel_buf *ipc;
 
@@ -300,6 +319,7 @@ int ipc_write_data(enum ipc_data_list dir, void *tx, u16 length)
                        CSP_PRINTF_INFO("%s: %s: is full\n", NAME_PREFIX, __func__);
                        ret = -EINVAL;
                }
+               ENABLE_IRQ();
        } else {
                CSP_PRINTF_INFO("%s: %s: invalid size:%d\n",
                        NAME_PREFIX, __func__, length);
@@ -310,9 +330,13 @@ int ipc_write_data(enum ipc_data_list dir, void *tx, u16 length)
                enum ipc_evt_list evtq = (dir == IPC_DATA_C2A) ? IPC_EVT_C2A : IPC_EVT_A2C;
 
                ret = ipc_add_evt(evtq, IRQ_EVT_CH0);
+               if (ret)
+                       CSP_PRINTF_INFO("%s: %s: fail by add_evt\n",
+                       NAME_PREFIX, __func__);
        } else {
                CSP_PRINTF_INFO("%s: %s: error: eq:%d, dq:%d\n",
                        NAME_PREFIX, __func__, ipc_data->eq, ipc_data->dq);
+               ipc_dump();
        }
        return ret;
 }
@@ -321,17 +345,19 @@ void *ipc_read_data(enum ipc_data_list dir, u32 *len)
 {
        enum ipc_region reg = (dir == IPC_DATA_C2A) ? IPC_REG_IPC_C2A : IPC_REG_IPC_A2C;
        struct ipc_buf *ipc_data = ipc_get_base(reg);
+       void *buf = NULL;
 
+       DISABLE_IRQ();
        if (!__ipc_queue_empty(ipc_data)) {
                struct ipc_channel_buf *ipc;
 
                ipc = &ipc_data->ch[ipc_data->dq];
                *len = ipc->size;
                ipc_data->dq = (ipc_data->dq + 1) % IPC_CH_BUF_NUM;
-               return ipc->buf;
+               buf = ipc->buf;
        }
-
-       return NULL;
+       ENABLE_IRQ();
+       return buf;
 }
 #else
 static inline void ipc_copy_bytes(u8 *dst, u8 *src, int size)
@@ -652,6 +678,7 @@ struct ipc_evt_buf *ipc_get_evt(enum ipc_evt_list evtq)
        struct ipc_evt *ipc_evt = &ipc_map->evt[evtq];
        struct ipc_evt_buf *cur_evt = NULL;
 
+       DISABLE_IRQ();
        if (ipc_evt->ctrl.dq != __raw_readl(&ipc_evt->ctrl.eq)) {
                cur_evt = &ipc_evt->data[ipc_evt->ctrl.dq];
                cur_evt->status = IPC_EVT_DQ;
@@ -662,11 +689,12 @@ struct ipc_evt_buf *ipc_get_evt(enum ipc_evt_list evtq)
                ipc_evt->ctrl.dq = EVT_Q_INT(ipc_evt->ctrl.dq + 1);
                __raw_writel(0, &ipc_evt->ctrl.full);
        }
+       ENABLE_IRQ();
 
        return cur_evt;
 }
 
-#define EVT_WAIT_TIME (10)
+#define EVT_WAIT_TIME (5)
 #define MAX_TRY_CNT (5)
 
 int ipc_add_evt(enum ipc_evt_list evtq, enum irq_evt_chub evt)
@@ -674,48 +702,43 @@ int ipc_add_evt(enum ipc_evt_list evtq, enum irq_evt_chub evt)
        struct ipc_evt *ipc_evt = &ipc_map->evt[evtq];
        enum ipc_owner owner = (evtq < IPC_EVT_AP_MAX) ? AP : IPC_OWN_MAX;
        struct ipc_evt_buf *cur_evt = NULL;
-#if defined(CHUB_IPC)
        int trycnt = 0;
-#endif
+       u32 pending;
 
        if (!ipc_evt || (owner != AP)) {
                CSP_PRINTF_ERROR("%s: %s: invalid ipc_evt, owner:%d\n", NAME_PREFIX, __func__, owner);
                return -1;
        }
 
-#if 0
-       /* check index due to sram corruption */
-       if ((__raw_readl(&ipc_evt->ctrl.eq) > IPC_EVT_NUM) ||
-               (__raw_readl(&ipc_evt->ctrl.dq) > IPC_EVT_NUM) ||
-               (__raw_readl(&ipc_evt->ctrl.full) > 1) ||
-               (__raw_readl(&ipc_evt->ctrl.empty) > 1)) {
-               CSP_PRINTF_ERROR("%s: invalid index: eq:%d, dq:%d, full:%d, empty:%d\n",
-                       __func__, ipc_evt->ctrl.eq, ipc_evt->ctrl.dq,
-                       ipc_evt->ctrl.full, ipc_evt->ctrl.empty);
-               return -1;
-       }
-#endif
+retry:
+       DISABLE_IRQ();
        if (!__raw_readl(&ipc_evt->ctrl.full)) {
                cur_evt = &ipc_evt->data[ipc_evt->ctrl.eq];
                if (!cur_evt) {
                        CSP_PRINTF_ERROR("%s: invalid cur_evt\n", __func__);
+                       ENABLE_IRQ();
                        return -1;
                }
 
                /* wait pending clear on irq pend */
-               if (ipc_hw_read_gen_int_status_reg(AP, ipc_evt->ctrl.irq)) {
-                       CSP_PRINTF_ERROR("%s: irq:%d pending:0x%x\n", __func__, ipc_evt->ctrl.irq, ipc_hw_read_int_status_reg(AP));
-#if defined(CHUB_IPC)
+               pending = ipc_hw_read_gen_int_status_reg(AP, ipc_evt->ctrl.irq);
+               if (pending) {
+                       CSP_PRINTF_ERROR("%s: %s: irq:%d pending:0x%x->0x%x\n",
+                               NAME_PREFIX, __func__, ipc_evt->ctrl.irq, pending, ipc_hw_read_int_status_reg(AP));
             /* don't sleep on ap */
                        do {
-                               trycnt++;
-                               msleep(EVT_WAIT_TIME);
-                       } while (ipc_hw_read_gen_int_status_reg(AP, ipc_evt->ctrl.irq) && (trycnt < MAX_TRY_CNT));
-
+                               busywait(EVT_WAIT_TIME);
+                       } while (ipc_hw_read_gen_int_status_reg(AP, ipc_evt->ctrl.irq) && (trycnt++ < MAX_TRY_CNT));
                        CSP_PRINTF_INFO("%s: %s: pending irq wait: pend:%d irq %d during %d times\n",
                                NAME_PREFIX, __func__, ipc_hw_read_gen_int_status_reg(AP, ipc_evt->ctrl.irq),
                                ipc_evt->ctrl.irq, trycnt);
-#endif
+
+                       if (ipc_hw_read_gen_int_status_reg(AP, ipc_evt->ctrl.irq)) {
+                               CSP_PRINTF_ERROR("%s: %s: fail to add evt by pending:0x%x\n",
+                                       NAME_PREFIX, __func__, ipc_hw_read_gen_int_status_reg(AP, ipc_evt->ctrl.irq));
+                               ENABLE_IRQ();
+                               return -1;
+                       }
                }
                cur_evt->evt = evt;
                cur_evt->status = IPC_EVT_EQ;
@@ -725,25 +748,22 @@ int ipc_add_evt(enum ipc_evt_list evtq, enum irq_evt_chub evt)
                if (ipc_evt->ctrl.eq == __raw_readl(&ipc_evt->ctrl.dq))
                        __raw_writel(1, &ipc_evt->ctrl.full);
        } else {
-#if defined(CHUB_IPC)
+               ENABLE_IRQ();
                do {
-                       trycnt++;
-                       msleep(EVT_WAIT_TIME);
-               } while (ipc_evt->ctrl.full && (trycnt < MAX_TRY_CNT));
+                       busywait(EVT_WAIT_TIME);
+               } while (ipc_evt->ctrl.full && (trycnt++ < MAX_TRY_CNT));
 
                if (!__raw_readl(&ipc_evt->ctrl.full)) {
                        CSP_PRINTF_INFO("%s: %s: evt %d during %d ms is full\n",
                                        NAME_PREFIX, __func__, evt, EVT_WAIT_TIME * trycnt);
-                       return -1;
+                       goto retry;
                } else {
-                       CSP_PRINTF_ERROR("%s: %s: fail to add evt\n", NAME_PREFIX, __func__);
+                       CSP_PRINTF_ERROR("%s: %s: fail to add evt by full\n", NAME_PREFIX, __func__);
+                       ipc_dump();
                        return -1;
                }
-#else
-               CSP_PRINTF_ERROR("%s: %s: fail to add evt\n", NAME_PREFIX, __func__);
-               return -1;
-#endif
        }
+       ENABLE_IRQ();
 
        if (owner != IPC_OWN_MAX) {
 #if defined(AP_IPC)
@@ -754,7 +774,6 @@ int ipc_add_evt(enum ipc_evt_list evtq, enum irq_evt_chub evt)
                else
                        return -1;
        }
-
        return 0;
 }
 
@@ -765,8 +784,8 @@ void ipc_print_evt(enum ipc_evt_list evtq)
        struct ipc_evt *ipc_evt = &ipc_map->evt[evtq];
        int i;
 
-       CSP_PRINTF_INFO("%s: evt-%s: eq:%d dq:%d full:%d irq:%d\n",
-                       NAME_PREFIX, IPC_GET_EVT_NAME(evtq), ipc_evt->ctrl.eq,
+       CSP_PRINTF_INFO("%s: evt(%p)-%s: eq:%d dq:%d full:%d irq:%d\n",
+                       NAME_PREFIX, ipc_evt, IPC_GET_EVT_NAME(evtq), ipc_evt->ctrl.eq,
                        ipc_evt->ctrl.dq, ipc_evt->ctrl.full,
                        ipc_evt->ctrl.irq);
 
index f59fb04bf381200ad36958b1bdecf96930b1e870..bbb11a22b7e74db930b378115d205c6b02829f33 100644 (file)
@@ -85,6 +85,8 @@
 #define KERNEL_LOG_OFF         (0x0)
 
 #define READY_TO_GO 99
+#define MAILBOX_REQUEST_KLOG_ON (0x1)
+#define MAILBOX_REQUEST_KLOG_OFF (0x2)
 
 struct chub_bootargs {
        char magic[16];