From c79428cbdd037501f32c988bf06e2cd5f78e9806 Mon Sep 17 00:00:00 2001 From: Boojin Kim Date: Fri, 28 Dec 2018 15:12:28 +0900 Subject: [PATCH] [ERD][APR-103] [COMMON]chub: update runtimelog Change-Id: If46dc6e92bfc6504d77eddf3052260354499a43e Signed-off-by: Boojin Kim --- drivers/staging/nanohub/chub.c | 254 ++++++++++++++++++----------- drivers/staging/nanohub/chub.h | 12 +- drivers/staging/nanohub/chub_dbg.c | 3 - drivers/staging/nanohub/chub_ipc.c | 145 ++++++++++------ drivers/staging/nanohub/chub_ipc.h | 19 ++- 5 files changed, 280 insertions(+), 153 deletions(-) diff --git a/drivers/staging/nanohub/chub.c b/drivers/staging/nanohub/chub.c index 4364779ba75f..0660853c825e 100644 --- a/drivers/staging/nanohub/chub.c +++ b/drivers/staging/nanohub/chub.c @@ -64,13 +64,33 @@ const char *os_image[SENSOR_VARIATION] = { "os.checked_8.bin", }; +#define USE_NO_PANIC_ON_POWERON /* hack for panic */ static DEFINE_MUTEX(reset_mutex); static DEFINE_MUTEX(pmu_shutdown_mutex); +static DEFINE_MUTEX(log_mutex); + +void chub_wake_event(struct chub_alive *event) +{ + atomic_set(&event->flag, 1); + wake_up_interruptible_sync(&event->event); +} + +static int chub_wait_event(struct chub_alive *event) +{ + atomic_set(&event->flag, 0); + return wait_event_interruptible_timeout(event->event, + atomic_read(&event->flag), + msecs_to_jiffies(WAIT_TIMEOUT_MS * 2)); +} static int contexthub_get_token(struct contexthub_ipc_info *ipc) { - if (atomic_read(&ipc->in_reset)) + if (atomic_read(&ipc->in_reset)) { + dev_warn(ipc->dev, "%s fails to get token, status:%d, inreset:%d, token:%d\n", + __func__, atomic_read(&ipc->chub_status), atomic_read(&ipc->in_reset), + atomic_read(&ipc->in_use_ipc)); return -EINVAL; + } atomic_inc(&ipc->in_use_ipc); return 0; @@ -288,15 +308,13 @@ static inline void read_put_unlocked(struct contexthub_ipc_info *ipc) /* simple alive check function : don't use ipc map */ static bool contexthub_lowlevel_alive(struct contexthub_ipc_info *ipc) { - int val; + int ret; - ipc->chub_alive_lock.flag = 0; + atomic_set(&ipc->chub_alive_lock.flag, 0); ipc_hw_gen_interrupt(AP, IRQ_EVT_CHUB_ALIVE); - val = wait_event_timeout(ipc->chub_alive_lock.event, - ipc->chub_alive_lock.flag, - msecs_to_jiffies(WAIT_TIMEOUT_MS)); - dev_info(ipc->dev, "%s done: ret:%d\n", __func__, val); - return ipc->chub_alive_lock.flag; + ret = chub_wait_event(&ipc->chub_alive_lock); + dev_info(ipc->dev, "%s done: ret:%d\n", __func__, ret); + return atomic_read(&ipc->chub_alive_lock.flag); } #define CHUB_RESET_THOLD (10) @@ -423,9 +441,7 @@ static void contexthub_select_os(struct contexthub_ipc_info *ipc) __func__, atomic_read(&ipc->chub_status)); dev_info(ipc->dev, "%s done: wakeup interrupt\n", __func__); - - ipc->poweron_lock.flag = 1; - wake_up(&ipc->poweron_lock.event); + chub_wake_event(&ipc->poweron_lock); } static DEFINE_MUTEX(dbg_mutex); @@ -450,23 +466,39 @@ static void handle_debug_work_func(struct work_struct *work) } } -static void print_rtlog(struct contexthub_ipc_info *ipc) +void contexthub_print_rtlog(struct contexthub_ipc_info *ipc, bool loop) { - if (contexthub_get_token(ipc)) { - pr_info("%s: fails to get token\n", __func__); - atomic_set(&ipc->log_work_active, 0); - return; + if (!atomic_read(&ipc->log_work_active)) { + if (contexthub_get_token(ipc)) { + dev_warn(ipc->dev, "%s: get token\n", __func__); + return; + } + ipc_logbuf_outprint(&ipc->chub_rt_log, loop); + contexthub_put_token(ipc); } - ipc_logbuf_outprint(&ipc->chub_rt_log); - contexthub_put_token(ipc); } static void handle_log_work_func(struct work_struct *work) { struct contexthub_ipc_info *ipc = - container_of(work, struct contexthub_ipc_info, debug_work); + container_of(work, struct contexthub_ipc_info, log_work); + int retrycnt = 0; - print_rtlog(ipc); +retry: + if (contexthub_get_token(ipc)) { + chub_wait_event(&ipc->reset_lock); + if (!retrycnt) { + retrycnt++; + goto retry; + } + atomic_set(&ipc->log_work_active, 0); + return; + } + ipc_logbuf_flush_on(1); + ipc_logbuf_outprint(&ipc->chub_rt_log, 100); + ipc_logbuf_flush_on(0); + contexthub_put_token(ipc); + atomic_set(&ipc->log_work_active, 0); } static inline void clear_err_cnt(struct contexthub_ipc_info *ipc, enum chub_err_type err) @@ -519,6 +551,8 @@ int contexthub_ipc_read(struct contexthub_ipc_info *ipc, uint8_t *rx, int max_le clear_err_cnt(ipc, CHUB_ERR_READ_FAIL); ret = contexthub_read_process(rx, rxbuf, size); } + + ipc_logbuf_outprint(&ipc->chub_rt_log, 0); contexthub_put_token(ipc); return ret; @@ -598,8 +632,12 @@ static int contexthub_hw_reset(struct contexthub_ipc_info *ipc, ipc->read_lock.flag = 0; ipc_hw_write_shared_reg(AP, ipc->os_load, SR_BOOT_MODE); ipc_set_chub_clk((u32)ipc->clkrate); - ipc_set_chub_bootmode(BOOTMODE_COLD); - +#ifdef CONFIG_CONTEXTHUB_DEBUG_MODE + ipc->chub_rt_log.loglevel = CHUB_RT_LOG_DUMP; +#else + ipc->chub_rt_log.loglevel = CHUB_RT_LOG_OFF; +#endif + ipc_set_chub_bootmode(BOOTMODE_COLD, ipc->chub_rt_log.loglevel); switch (event) { case MAILBOX_EVT_POWER_ON: #ifdef NEED_TO_RTC_SYNC @@ -678,6 +716,7 @@ static int contexthub_hw_reset(struct contexthub_ipc_info *ipc, return ret; else { /* wait active */ + dev_info(ipc->dev, "%s: alive check\n", __func__); trycnt = 0; do { msleep(WAIT_CHUB_MS); @@ -740,8 +779,7 @@ int contexthub_get_sensortype(struct contexthub_ipc_info *ipc, char *buf) } while (ret); if (ret) { - dev_warn(ipc->dev, "%s fails to get token, status:%d, inreset:%d\n", - __func__, atomic_read(&ipc->chub_status), atomic_read(&ipc->in_reset)); + dev_warn(ipc->dev, "%s fails to get token\n", __func__); return -EINVAL; } } @@ -839,15 +877,24 @@ int contexthub_ipc_write_event(struct contexthub_ipc_info *ipc, dev_info(ipc->dev, "%s : chub is alive", __func__); } else if (ipc->sel_os == true) { dev_err(ipc->dev, - "%s : chub isn't alive, should be reset. status:%d\n", - __func__, atomic_read(&ipc->chub_status)); - if (atomic_read(&ipc->chub_status) == CHUB_ST_POWER_ON) { - atomic_set(&ipc->chub_status, CHUB_ST_NO_RESPONSE); - /* hack don't make panic with chub poweron */ - contexthub_reset(ipc, 1, CHUB_ERR_NONE); - } else { + "%s : chub isn't alive, should be reset. status:%d, inreset:%d\n", + __func__, atomic_read(&ipc->chub_status), atomic_read(&ipc->in_reset)); + if (!atomic_read(&ipc->in_reset)) { +#ifdef USE_NO_PANIC_ON_POWERON + if (atomic_read(&ipc->chub_status) == CHUB_ST_POWER_ON) { + atomic_set(&ipc->chub_status, CHUB_ST_NO_RESPONSE); + /* hack don't make panic with chub poweron */ + contexthub_reset(ipc, 1, CHUB_ERR_NONE); + } else { + atomic_set(&ipc->chub_status, CHUB_ST_NO_RESPONSE); + contexthub_handle_debug(ipc, CHUB_ERR_CHUB_NO_RESPONSE, 0); + } +#else atomic_set(&ipc->chub_status, CHUB_ST_NO_RESPONSE); contexthub_handle_debug(ipc, CHUB_ERR_CHUB_NO_RESPONSE, 0); +#endif + } else { + dev_info(ipc->dev, "%s: skip to handle debug in reset\n", __func__); } ret = -EINVAL; } @@ -873,8 +920,8 @@ int contexthub_ipc_write_event(struct contexthub_ipc_info *ipc, return -EINVAL; } if (contexthub_get_token(ipc)) { - dev_warn(ipc->dev, "%s event:%d/%d fails to get token, status:%d, inreset:%d\n", - __func__, event, MAILBOX_EVT_MAX, atomic_read(&ipc->chub_status), atomic_read(&ipc->in_reset)); + dev_warn(ipc->dev, "%s event:%d/%d fails get token\n", + __func__, event, MAILBOX_EVT_MAX); return -EINVAL; } @@ -930,12 +977,16 @@ int contexthub_poweron(struct contexthub_ipc_info *ipc) struct chub_bootargs *map; if (!atomic_read(&ipc->chub_status)) { + memset_io(ipc->sram, 0, ipc->sram_size); ret = contexthub_download_image(ipc, IPC_REG_BL); if (ret) { dev_warn(dev, "fails to download bootloader\n"); return ret; } + if (ipc_get_offset(IPC_REG_DUMP) != ipc->sram_size) + dev_warn(dev, "sram size doen't match kernel:%d, fw:%d\n", ipc->sram_size, ipc_get_offset(IPC_REG_DUMP)); + ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_INIT_IPC); if (ret) { dev_warn(dev, "fails to init ipc\n"); @@ -966,17 +1017,10 @@ int contexthub_poweron(struct contexthub_ipc_info *ipc) dev_warn(dev, "contexthub failed to power-on"); else { dev_info(dev, "%s: wait for multi-os poweron\n", __func__); - - ipc->poweron_lock.flag = 0; - ret = wait_event_timeout(ipc->chub_alive_lock.event, - ipc->poweron_lock.flag, - msecs_to_jiffies(WAIT_TIMEOUT_MS)); - dev_info(dev, "%s: multi-os poweron %s, ret:%d\n", __func__, - atomic_read(&ipc->chub_status) == CHUB_ST_RUN ? "success" : "fails", ret); -#ifdef CONFIG_CONTEXTHUB_DEBUG_MODE - ipc->chub_rt_log.loglevel = 1; -#endif - contexthub_ipc_write_event(ipc, MAILBOX_EVT_RT_LOGLEVEL); + ret = chub_wait_event(&ipc->poweron_lock); + dev_info(dev, "%s: multi-os poweron %s, status:%d, ret:%d, flag:%d\n", __func__, + atomic_read(&ipc->chub_status) == CHUB_ST_RUN ? "success" : "fails", + atomic_read(&ipc->chub_status), ret, ipc->poweron_lock.flag); } } } else { @@ -1039,26 +1083,22 @@ int contexthub_reset(struct contexthub_ipc_info *ipc, bool force_load, enum chub } atomic_inc(&ipc->in_reset); + /* wait for ipc free */ do { msleep(WAIT_CHUB_MS); if (++trycnt > RESET_WAIT_TRY_CNT) { dev_info(ipc->dev, "%s: can't get lock. in_use_ipc: %d\n", __func__, atomic_read(&ipc->in_use_ipc)); - atomic_dec(&ipc->in_reset); - mutex_unlock(&reset_mutex); - return -EINVAL; + ret = -EINVAL; + goto out; } 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)); + /* debug dump */ chub_dbg_dump_hw(ipc, err); -#ifdef CONFIG_CONTEXTHUB_DEBUG_MODE - if (err) - panic("%s: %d, %d\n", __func__, err, ipc->cur_err); -#endif - dev_info(ipc->dev, "%s: start reset status:%d\n", __func__, atomic_read(&ipc->chub_status)); if (!ipc->block_reset) { /* core reset */ @@ -1066,16 +1106,19 @@ int contexthub_reset(struct contexthub_ipc_info *ipc, bool force_load, enum chub msleep(100); /* wait for shut down time */ } + /* shutdown */ mutex_lock(&pmu_shutdown_mutex); dev_info(ipc->dev, "%s: enter shutdown\n", __func__); ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_SHUTDOWN); if (ret) { dev_err(ipc->dev, "%s: shutdown fails, ret:%d\n", __func__, ret); + mutex_unlock(&pmu_shutdown_mutex); goto out; } dev_info(ipc->dev, "%s: out shutdown\n", __func__); mutex_unlock(&pmu_shutdown_mutex); + /* image download */ if (ipc->block_reset || force_load) { ret = contexthub_download_image(ipc, IPC_REG_BL); if (!ret) { @@ -1084,25 +1127,30 @@ int contexthub_reset(struct contexthub_ipc_info *ipc, bool force_load, enum chub else /* use previous binary */ ret = contexthub_download_and_check_image(ipc, IPC_REG_OS); - if (ret) + if (ret) { dev_err(ipc->dev, "%s: download os fails\n", __func__); + ret = -EINVAL; + goto out; + } } else { dev_err(ipc->dev, "%s: download bl fails\n", __func__); + ret = -EINVAL; goto out; } } - + /* reset */ ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_RESET); - if (ret) + if (ret) { dev_err(ipc->dev, "%s: reset fails, ret:%d\n", __func__, ret); - else { + } else { dev_info(ipc->dev, "%s: chub reseted! (cnt:%d)\n", __func__, ipc->err_cnt[CHUB_ERR_RESET_CNT]); ipc->err_cnt[CHUB_ERR_RESET_CNT]++; atomic_set(&ipc->in_use_ipc, 0); - atomic_dec(&ipc->in_reset); } out: + chub_wake_event(&ipc->reset_lock); + atomic_dec(&ipc->in_reset); mutex_unlock(&reset_mutex); return ret; @@ -1129,7 +1177,7 @@ int contexthub_download_image(struct contexthub_ipc_info *ipc, enum ipc_region r reg == IPC_REG_BL, __func__); return ret; } - memcpy(ipc_get_base(reg), entry->data, entry->size); + memcpy_toio(ipc_get_base(reg), entry->data, entry->size); dev_info(ipc->dev, "%s: bl:%d, bin(size:%d) on %lx\n", __func__, reg == IPC_REG_BL, (int)entry->size, (unsigned long)ipc_get_base(reg)); release_firmware(entry); @@ -1153,8 +1201,7 @@ static void handle_irq(struct contexthub_ipc_info *ipc, enum irq_evt_chub evt) atomic_set(&ipc->irq1_apInt, C2A_OFF); break; case IRQ_EVT_C2A_LOG: - print_rtlog(ipc); - return; + break; default: if (evt < IRQ_EVT_CH_MAX) { int lock; @@ -1169,11 +1216,15 @@ static void handle_irq(struct contexthub_ipc_info *ipc, enum irq_evt_chub evt) } else { dev_warn(ipc->dev, "%s: invalid %d event", __func__, evt); + return; } break; }; - if (ipc->chub_rt_log.loglevel) - print_rtlog(ipc); + if (ipc_logbuf_filled() && !atomic_read(&ipc->log_work_active)) { + ipc->log_work_reqcnt++; /* debug */ + atomic_set(&ipc->log_work_active, 1); + schedule_work(&ipc->log_work); + } } static irqreturn_t contexthub_irq_handler(int irq, void *data) @@ -1199,8 +1250,7 @@ static irqreturn_t contexthub_irq_handler(int irq, void *data) } /* set wakeup flag for chub_alive_lock */ - ipc->chub_alive_lock.flag = 1; - wake_up(&ipc->chub_alive_lock.event); + chub_wake_event(&ipc->chub_alive_lock); } #ifndef CHECK_HW_TRIGGER @@ -1304,6 +1354,32 @@ error: extern int cal_dll_apm_enable(void); #endif +static void __iomem *get_iomem(struct platform_device *pdev, + const char *name, u32 *size) +{ + struct resource *res; + void __iomem *ret; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); + if (IS_ERR_OR_NULL(res)) { + dev_err(&pdev->dev, "Failed to get %s\n", name); + return ERR_PTR(-EINVAL); + } + + ret = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ret)) { + dev_err(&pdev->dev, "fails to get %s\n", name); + return ERR_PTR(-EINVAL); + } + + if (size) + *size = resource_size(res); + dev_info(&pdev->dev, "%s: %s(%p) is mapped on %p with size of %zu", + __func__, name, (void *)res->start, ret, (size_t)resource_size(res)); + + return ret; +} + static __init int contexthub_ipc_hw_init(struct platform_device *pdev, struct contexthub_ipc_info *chub) { @@ -1389,44 +1465,27 @@ static __init int contexthub_ipc_hw_init(struct platform_device *pdev, #endif /* get MAILBOX SFR */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mailbox"); - chub->mailbox = devm_ioremap_resource(dev, res); - if (IS_ERR(chub->mailbox)) { - dev_err(dev, "fails to get mailbox sfr\n"); + chub->mailbox = get_iomem(pdev, "mailbox", NULL); + if (IS_ERR(chub->mailbox)) return PTR_ERR(chub->mailbox); - } /* get SRAM base */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); - chub->sram = devm_ioremap_resource(dev, res); - if (IS_ERR(chub->sram)) { - dev_err(dev, "fails to get sram\n"); - return PTR_ERR(chub->sram); - } + chub->sram = get_iomem(pdev, "sram", &chub->sram_size); + if (IS_ERR(chub->sram)) + return PTR_ERR(chub->sram); /* get chub gpr base */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dumpgpr"); - chub->chub_dumpgpr = devm_ioremap_resource(dev, res); - if (IS_ERR(chub->chub_dumpgpr)) { - dev_err(dev, "fails to get dumpgpr\n"); + chub->chub_dumpgpr = get_iomem(pdev, "dumpgpr", NULL); + if (IS_ERR(chub->chub_dumpgpr)) return PTR_ERR(chub->chub_dumpgpr); - } - /* get pmu reset base */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "chub_reset"); - chub->pmu_chub_reset = devm_ioremap_resource(dev, res); - if (IS_ERR(chub->pmu_chub_reset)) { - dev_err(dev, "fails to get dumpgpr\n"); + chub->pmu_chub_reset = get_iomem(pdev, "chub_reset", NULL); + if (IS_ERR(chub->pmu_chub_reset)) return PTR_ERR(chub->pmu_chub_reset); - } - /* get chub baaw base */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "chub_baaw"); - chub->chub_baaw = devm_ioremap_resource(dev, res); - if (IS_ERR(chub->chub_baaw)) { - pr_err("driver failed to get chub_baaw\n"); - chub->chub_baaw = 0; /* it can be set on other-side (vts) */ - } + chub->chub_baaw = get_iomem(pdev, "chub_baaw", NULL); + if (IS_ERR(chub->chub_baaw)) + return PTR_ERR(chub->chub_baaw); #if defined(CONFIG_SOC_EXYNOS9610) /* get cmu qch base */ @@ -1596,6 +1655,7 @@ static int contexthub_ipc_probe(struct platform_device *pdev) chub->data->irq2 = 0; #endif chub->chub_rt_log.loglevel = 0; + spin_lock_init(&chub->logout_lock); atomic_set(&chub->in_use_ipc, 0); atomic_set(&chub->chub_status, CHUB_ST_NO_POWER); atomic_set(&chub->in_reset, 0); @@ -1614,22 +1674,26 @@ static int contexthub_ipc_probe(struct platform_device *pdev) attributes[i].attr.name); } init_waitqueue_head(&chub->poweron_lock.event); + init_waitqueue_head(&chub->reset_lock.event); init_waitqueue_head(&chub->read_lock.event); init_waitqueue_head(&chub->chub_alive_lock.event); + atomic_set(&chub->poweron_lock.flag, 0); + atomic_set(&chub->chub_alive_lock.flag, 0); INIT_WORK(&chub->debug_work, handle_debug_work_func); INIT_WORK(&chub->log_work, handle_log_work_func); + chub->log_work_reqcnt = 0; #ifdef CONFIG_EXYNOS_ITMON chub->itmon_nb.notifier_call = chub_itmon_notifier; itmon_notifier_chain_register(&chub->itmon_nb); #endif /* init fw runtime log */ - chub->chub_rt_log.buffer = vzalloc(SZ_512K); + chub->chub_rt_log.buffer = vzalloc(SZ_512K * 2); if (!chub->chub_rt_log.buffer) { ret = -ENOMEM; goto err; } - chub->chub_rt_log.buffer_size = SZ_512K; + chub->chub_rt_log.buffer_size = SZ_512K * 2; chub->chub_rt_log.write_index = 0; dev_info(chub->dev, "%s with %s FW and %lu clk is done\n", diff --git a/drivers/staging/nanohub/chub.h b/drivers/staging/nanohub/chub.h index b6aab7a13dd5..478da0d12f49 100644 --- a/drivers/staging/nanohub/chub.h +++ b/drivers/staging/nanohub/chub.h @@ -113,7 +113,7 @@ struct recv_ctrl { }; struct chub_alive { - unsigned int flag; + atomic_t flag; wait_queue_head_t event; }; @@ -161,13 +161,17 @@ struct contexthub_ipc_info { wait_queue_head_t wakeup_wait; struct work_struct debug_work; struct work_struct log_work; + int log_work_reqcnt; + spinlock_t logout_lock; struct read_wait read_lock; #ifdef USE_IPC_BUF u8 rxbuf[PACKET_SIZE_MAX]; #endif struct chub_alive chub_alive_lock; struct chub_alive poweron_lock; + struct chub_alive reset_lock; void __iomem *sram; + u32 sram_size; void __iomem *mailbox; void __iomem *chub_dumpgpr; void __iomem *chub_baaw; @@ -182,8 +186,6 @@ struct contexthub_ipc_info { struct runtimelog_buf chub_rt_log; unsigned long clkrate; atomic_t log_work_active; - atomic_t chub_status; - atomic_t in_reset; atomic_t irq1_apInt; atomic_t wakeup_chub; atomic_t in_use_ipc; @@ -192,6 +194,8 @@ struct contexthub_ipc_info { bool irq_wdt_disabled; int utc_run; int powermode; + atomic_t chub_status; + atomic_t in_reset; int block_reset; bool sel_os; bool os_load; @@ -307,5 +311,7 @@ int contexthub_reset(struct contexthub_ipc_info *ipc, bool force_load, enum chub int contexthub_wakeup(struct contexthub_ipc_info *data, int evt); int contexthub_request(struct contexthub_ipc_info *ipc); void contexthub_release(struct contexthub_ipc_info *ipc); +void chub_wake_event(struct chub_alive *event); int contexthub_get_sensortype(struct contexthub_ipc_info *ipc, char *buf); +void contexthub_print_rtlog(struct contexthub_ipc_info *ipc, bool loop); #endif diff --git a/drivers/staging/nanohub/chub_dbg.c b/drivers/staging/nanohub/chub_dbg.c index 0c9e57ea76eb..563868958aa1 100644 --- a/drivers/staging/nanohub/chub_dbg.c +++ b/drivers/staging/nanohub/chub_dbg.c @@ -244,9 +244,6 @@ static ssize_t chub_bin_dram_read(struct file *file, struct kobject *kobj, struct bin_attribute *battr, char *buf, loff_t off, size_t size) { - struct device *dev = kobj_to_dev(kobj); - - dev_info(dev, "%s(%p: %lld, %zu)\n", __func__, battr->private, off, size); memcpy(buf, battr->private + off, size); return size; } diff --git a/drivers/staging/nanohub/chub_ipc.c b/drivers/staging/nanohub/chub_ipc.c index 0ec43f1d618b..07a5271de84b 100644 --- a/drivers/staging/nanohub/chub_ipc.c +++ b/drivers/staging/nanohub/chub_ipc.c @@ -164,11 +164,12 @@ u32 ipc_get_chub_clk(void) return map->chubclk; } -void ipc_set_chub_bootmode(u16 bootmode) +void ipc_set_chub_bootmode(u16 bootmode, u16 rtlog) { struct chub_bootargs *map = ipc_get_base(IPC_REG_BL_MAP); map->bootmode = bootmode; + map->runtimelog = rtlog; } u16 ipc_get_chub_bootmode(void) @@ -178,16 +179,23 @@ u16 ipc_get_chub_bootmode(void) return map->bootmode; } -void ipc_set_ap_wake(u16 wake) +u16 ipc_get_chub_rtlogmode(void) { struct chub_bootargs *map = ipc_get_base(IPC_REG_BL_MAP); + return map->runtimelog; +} + +void ipc_set_ap_wake(u16 wake) +{ + struct ipc_map_area *map = ipc_get_base(IPC_REG_IPC); + map->wake = wake; } u16 ipc_get_ap_wake(void) { - struct chub_bootargs *map = ipc_get_base(IPC_REG_BL_MAP); + struct ipc_map_area *map = ipc_get_base(IPC_REG_IPC); return map->wake; } @@ -291,19 +299,19 @@ void *ipc_get_chub_map(void) ipc_addr[IPC_REG_IPC_SENSORINFO].base = &ipc_map->sensormap; ipc_addr[IPC_REG_IPC_SENSORINFO].offset = sizeof(u8) * SENSOR_TYPE_MAX; +#ifdef SEOS ipc_map->logbuf.eq = 0; ipc_map->logbuf.dq = 0; ipc_map->logbuf.full = 0; ipc_map->logbuf.dbg_full_cnt = 0; - ipc_map->logbuf.loglevel = 0; ipc_map->logbuf.logbuf.eq = 0; ipc_map->logbuf.logbuf.dq = 0; ipc_map->logbuf.logbuf.full = 0; ipc_map->logbuf.errcnt= 0; ipc_map->logbuf.fw_num = 0; ipc_map->logbuf.ap_num = 0; + ipc_map->logbuf.loglevel = ipc_get_chub_rtlogmode(); -#ifdef SEOS if (!ipc_have_sensor_info(&ipc_map->sensormap)) { CSP_PRINTF_INFO("%s: ipc set sensormap and maic: :%p\n", __func__, &ipc_map->sensormap); memset(&ipc_map->sensormap, 0, sizeof(struct sensor_map)); @@ -312,8 +320,8 @@ void *ipc_get_chub_map(void) #endif CSP_PRINTF_INFO - ("%s: contexthub map information(v%u)\n bl(%p %d)\n os(%p %d)\n ipc(%p %d)\n ram(%p %d)\n shared(%p %d)\n dump(%p %d)\n", - NAME_PREFIX, map->ipc_version, + ("%s: contexthub map information(v%u, bootmode:%d, rtmode:%d)\n bl(%p %d)\n os(%p %d)\n ipc(%p %d)\n ram(%p %d)\n shared(%p %d)\n dump(%p %d)\n", + NAME_PREFIX, map->ipc_version, ipc_get_chub_bootmode(), ipc_get_chub_rtlogmode(), ipc_addr[IPC_REG_BL].base, ipc_addr[IPC_REG_BL].offset, ipc_addr[IPC_REG_OS].base, ipc_addr[IPC_REG_OS].offset, ipc_addr[IPC_REG_IPC].base, ipc_addr[IPC_REG_IPC].offset, @@ -676,9 +684,9 @@ static void ipc_print_logbuf(void) { struct ipc_logbuf *logbuf = &ipc_map->logbuf; - CSP_PRINTF_INFO("%s: channel: eq:%d, dq:%d, size:%d, full:%d, dbg_full_cnt:%d, err:%d, fw:%lld, ap:%lld\n", + CSP_PRINTF_INFO("%s: channel: eq:%d, dq:%d, size:%d, full:%d, dbg_full_cnt:%d, err(overwrite):%d, ipc-reqcnt:%d, fw:%lld, ap:%lld\n", NAME_PREFIX, logbuf->eq, logbuf->dq, logbuf->size, logbuf->full, logbuf->dbg_full_cnt, - logbuf->errcnt, logbuf->fw_num, logbuf->ap_num); + logbuf->errcnt, logbuf->reqcnt, logbuf->fw_num, logbuf->ap_num); CSP_PRINTF_INFO("%s: raw: eq:%d, dq:%d, size:%d, full:%d\n", NAME_PREFIX, logbuf->logbuf.eq, logbuf->logbuf.dq, logbuf->logbuf.size, logbuf->logbuf.full); } @@ -871,8 +879,10 @@ retry: /* wait pending clear on irq pend */ 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)); + CSP_PRINTF_ERROR("%s: %s: irq:%d pending:0x%x->(direct-src:%d, src:0x%x, dst:0x%x)\n", + NAME_PREFIX, __func__, ipc_evt->ctrl.irq, pending, ipc_get_owner(AP), + __raw_readl((char *)ipc_own[AP].base + REG_MAILBOX_INTGR0), + __raw_readl((char *)ipc_own[AP].base + REG_MAILBOX_INTGR1)); /* don't sleep on ap */ do { busywait(EVT_WAIT_TIME); @@ -953,7 +963,7 @@ void ipc_dump(void) return; } - CSP_PRINTF_INFO("%s: %s: a2x event\n", NAME_PREFIX, __func__); + CSP_PRINTF_INFO("%s: %s: a2x event, magic:%s\n", NAME_PREFIX, __func__, ipc_map->magic); ipc_print_evt(IPC_EVT_A2C); CSP_PRINTF_INFO("%s: %s: c2a event\n", NAME_PREFIX, __func__); ipc_print_evt(IPC_EVT_C2A); @@ -1011,6 +1021,7 @@ void *ipc_logbuf_inbase(bool force) return NULL; } +#undef UES_LOG_FLUSH_TRSHOLD void ipc_logbuf_req_flush(struct logbuf_content *log, bool force) { if (log) { @@ -1019,17 +1030,31 @@ void ipc_logbuf_req_flush(struct logbuf_content *log, bool force) /* debug check overwrite */ log->size = logbuf->fw_num++; if (ipc_map) { - u32 eq = logbuf->eq; - u32 dq = logbuf->dq; - u32 logcnt = (eq >= dq) ? (eq - dq) : (eq + (logbuf->size - dq)); - - if (((ipc_get_ap_wake() == AP_WAKE) && (logcnt > LOGBUF_FLUSH_THRESHOLD)) || force) { - DISABLE_IRQ(); - if (!logbuf->flush_req) { - logbuf->flush_req = 1; - ipc_add_evt_in_critical(IPC_EVT_C2A, IRQ_EVT_C2A_LOG); + if (!logbuf->flush_req && !logbuf->flush_active) { +#ifdef UES_LOG_FLUSH_TRSHOLD + u32 eq = logbuf->eq; + u32 dq = logbuf->dq; + u32 logcnt = (eq >= dq) ? (eq - dq) : (eq + (logbuf->size - dq)); + + if (((ipc_get_ap_wake() == AP_WAKE) && (logcnt > LOGBUF_FLUSH_THRESHOLD)) || force) { + DISABLE_IRQ(); + if (!logbuf->flush_req) { + logbuf->flush_req = 1; + ipc_add_evt_in_critical(IPC_EVT_C2A, IRQ_EVT_C2A_LOG); + } + ENABLE_IRQ(); } - ENABLE_IRQ(); +#else + if ((ipc_get_ap_wake() == AP_WAKE) || force) { + DISABLE_IRQ(); + if (!logbuf->flush_req) { + logbuf->flush_req = 1; + logbuf->reqcnt++; + ipc_add_evt_in_critical(IPC_EVT_C2A, IRQ_EVT_C2A_LOG); + } + ENABLE_IRQ(); + } +#endif } } } @@ -1041,48 +1066,71 @@ void ipc_logbuf_req_flush(struct logbuf_content *log, bool force) #endif #ifdef AP_IPC -void ipc_logbuf_outprint(struct runtimelog_buf *rt_buf) +#define LOGFILE_NUM_SIZE (10) + +void ipc_logbuf_flush_on(bool on) +{ + struct ipc_logbuf *logbuf; + + if (ipc_map) { + logbuf = &ipc_map->logbuf; + logbuf->flush_active = on; + } +} + +bool ipc_logbuf_filled(void) +{ + struct ipc_logbuf *logbuf; + + if (ipc_map) { + logbuf = &ipc_map->logbuf; + return logbuf->eq != logbuf->dq; + } + return 0; +} + +void ipc_logbuf_outprint(struct runtimelog_buf *rt_buf, u32 loop) { if (ipc_map) { struct logbuf_content *log; struct ipc_logbuf *logbuf = &ipc_map->logbuf; int eq; - int retrycnt = 0; + int len; retry: eq = logbuf->eq; + if (eq >= LOGBUF_NUM || logbuf->dq >= LOGBUF_NUM) { + pr_err("%s: index err:%d, eq:%d, dq:%d\n", __func__, eq, logbuf->dq); + return; + } + if (logbuf->full) { logbuf->full = 0; - logbuf->dq = logbuf->eq; + logbuf->dq = (eq + 1) % LOGBUF_NUM; } while (eq != logbuf->dq) { log = &logbuf->log[logbuf->dq]; + len = strlen((char *)log); - /* debug check overwrite */ - if (logbuf->ap_num != log->size) { - logbuf->ap_num = log->size; - logbuf->errcnt++; - } - logbuf->ap_num++; - - if (logbuf->loglevel == CHUB_RT_LOG_DUMP_PRT) - CSP_PRINTF_INFO("%s: %s", NAME_PREFIX, (char *)log); + if (len <= LOGBUF_DATA_SIZE) { + if (logbuf->loglevel == CHUB_RT_LOG_DUMP_PRT) + CSP_PRINTF_INFO("%s: %s", NAME_PREFIX, (char *)log); - if (rt_buf) { - int len = strlen((char *)log); - - if (rt_buf->write_index + len > rt_buf->buffer_size) - rt_buf->write_index = 0; - memcpy(rt_buf->buffer + rt_buf->write_index, (char *)log, len); - rt_buf->write_index += len; + if (rt_buf) { + if (rt_buf->write_index + len + LOGFILE_NUM_SIZE > rt_buf->buffer_size) + rt_buf->write_index = 0; + len = sprintf(rt_buf->buffer + rt_buf->write_index, "%8lld:%s", log->size, log); + rt_buf->write_index += len; + } + } else { + pr_err("%s: size err:%d, eq:%d, dq:%d\n", __func__, len, eq, logbuf->dq); } logbuf->dq = (logbuf->dq + 1) % LOGBUF_NUM; } - - if ((eq != logbuf->eq) && !retrycnt) { - CSP_PRINTF_INFO("%s: retry: flush:%d, cnt:%d, eq:%d->%d, dq:%d\n", - NAME_PREFIX, logbuf->flush_req, logbuf->dbg_full_cnt, eq, logbuf->eq, logbuf->dq); + msleep(10); + if ((eq != logbuf->eq) && loop) { + loop--; goto retry; } @@ -1104,7 +1152,7 @@ enum ipc_fw_loglevel ipc_logbuf_loglevel(enum ipc_fw_loglevel loglevel, int set) return 0; } #else -#define ipc_logbuf_outprint(a) ((void)0) +#define ipc_logbuf_outprint(a) ((void)0, 0) #define ipc_logbuf_loglevel(a, b) ((void)0) #endif @@ -1114,6 +1162,11 @@ void ipc_set_owner(enum ipc_owner owner, void *base, enum ipc_direction dir) ipc_own[owner].src = dir; } +enum ipc_direction ipc_get_owner(enum ipc_owner owner) +{ + return ipc_own[owner].src; +} + int ipc_hw_read_int_start_index(enum ipc_owner owner) { if (ipc_own[owner].src) diff --git a/drivers/staging/nanohub/chub_ipc.h b/drivers/staging/nanohub/chub_ipc.h index 5c8b9d59a84b..2443706aa8c7 100644 --- a/drivers/staging/nanohub/chub_ipc.h +++ b/drivers/staging/nanohub/chub_ipc.h @@ -98,7 +98,7 @@ struct chub_bootargs { u32 dump_end; u32 chubclk; u16 bootmode; - u16 wake; + u16 runtimelog; #if defined(LOCAL_POWERGATE) u32 psp; u32 msp; @@ -113,7 +113,7 @@ struct chub_bootargs { * logbuf / logbuf_ctrl */ #define IPC_BUF_NUM (IRQ_EVT_CH_MAX) -#define IPC_EVT_NUM (30) +#define IPC_EVT_NUM (50) enum sr_num { SR_0 = 0, @@ -320,7 +320,7 @@ struct ipc_log_content { #define LOGBUF_SIZE (64) #define LOGBUF_NUM (80) #define LOGBUF_DATA_SIZE (LOGBUF_SIZE - sizeof(u64)) -#define LOGBUF_FLUSH_THRESHOLD (LOGBUF_NUM / 4) +#define LOGBUF_FLUSH_THRESHOLD (LOGBUF_NUM / 2) struct logbuf_content{ char buf[LOGBUF_DATA_SIZE]; @@ -353,12 +353,14 @@ struct ipc_logbuf { u32 eq; /* write owner chub (index_writer) */ u32 dq; /* read onwer ap (index_reader) */ u32 size; - u8 dbg_full_cnt; u8 full; u8 flush_req; + u8 flush_active; u8 loglevel; /* for debug */ + int dbg_full_cnt; int errcnt; + int reqcnt; u64 fw_num; u64 ap_num; /* rawlevel logout */ @@ -462,6 +464,7 @@ struct ipc_debug { struct ipc_map_area { char persist[CHUB_PERSISTBUF_SIZE]; char magic[16]; + u16 wake; struct ipc_buf data[IPC_DATA_MAX]; struct ipc_evt evt[IPC_EVT_MAX]; struct ipc_debug dbg; @@ -540,7 +543,9 @@ int ipc_hw_read_int_start_index(enum ipc_owner owner); /* logbuf functions */ enum ipc_fw_loglevel ipc_logbuf_loglevel(enum ipc_fw_loglevel loglevel, int set); void *ipc_logbuf_inbase(bool force); -void ipc_logbuf_outprint(struct runtimelog_buf *rt_buf); +void ipc_logbuf_flush_on(bool on); +bool ipc_logbuf_filled(void); +void ipc_logbuf_outprint(struct runtimelog_buf *rt_buf, u32 loop); void ipc_logbuf_req_flush(struct logbuf_content *log, bool force); /* evt functions */ struct ipc_evt_buf *ipc_get_evt(enum ipc_evt_list evt); @@ -549,6 +554,7 @@ int ipc_add_evt_in_critical(enum ipc_evt_list evtq, enum irq_evt_chub evt); void ipc_print_evt(enum ipc_evt_list evt); /* mailbox hw access */ void ipc_set_owner(enum ipc_owner owner, void *base, enum ipc_direction dir); +enum ipc_direction ipc_get_owner(enum ipc_owner owner); unsigned int ipc_hw_read_gen_int_status_reg(enum ipc_owner owner, int irq); void ipc_hw_write_shared_reg(enum ipc_owner owner, unsigned int val, int num); unsigned int ipc_hw_read_shared_reg(enum ipc_owner owner, int num); @@ -572,7 +578,8 @@ u64 ipc_read_val(enum ipc_owner owner); void ipc_write_val(enum ipc_owner owner, u64 result); void ipc_set_chub_clk(u32 clk); u32 ipc_get_chub_clk(void); -void ipc_set_chub_bootmode(u16 bootmode); +void ipc_set_chub_bootmode(u16 bootmode, u16 rtlog); +u16 ipc_get_chub_rtlogmode(void); u16 ipc_get_chub_bootmode(void); void ipc_set_ap_wake(u16 wake); u16 ipc_get_ap_wake(void); -- 2.20.1