From: Boojin Kim Date: Wed, 21 Nov 2018 01:53:51 +0000 (+0900) Subject: [ERD][APR-103] [COMMON]chub: fix wrong confict fix X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=0f25e13d95c3804a5b5001f7c5390048dbf2f242;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [ERD][APR-103] [COMMON]chub: fix wrong confict fix This patch recoveries '[9610] chub: ipc: version 181024' patch that is removed by 'chub : support multi-os for various sensors' patch confict. Change-Id: I5ae5f6ad21c2af3ddf75382ca5576e05518b5ea2 Signed-off-by: Boojin Kim --- diff --git a/drivers/staging/nanohub/chub.c b/drivers/staging/nanohub/chub.c index bb51e5328e9b..dc5842c20b0e 100644 --- a/drivers/staging/nanohub/chub.c +++ b/drivers/staging/nanohub/chub.c @@ -48,7 +48,6 @@ #define SENSOR_VARIATION 10 #define WAIT_TIMEOUT_MS (1000) - enum { CHUB_ON, CHUB_OFF }; enum { C2A_ON, C2A_OFF }; @@ -66,23 +65,19 @@ const char *os_image[SENSOR_VARIATION] = { static DEFINE_MUTEX(reset_mutex); static DEFINE_MUTEX(pmu_shutdown_mutex); -static inline int contexthub_get_token(struct contexthub_ipc_info *ipc, enum access_type acc) + +static int contexthub_get_token(struct contexthub_ipc_info *ipc) { - if (acc == HW_ACCESS) { - mutex_lock(&pmu_shutdown_mutex); - dev_info(ipc->dev, "%s: enter shutdown\n", __func__); - } - else if (acc == IPC_ACCESS) - return (atomic_read(&ipc->chub_status) == CHUB_ST_RUN) && !atomic_read(&ipc->in_reset); - return true; + if (atomic_read(&ipc->in_reset)) + return -EINVAL; + + atomic_inc(&ipc->in_use_ipc); + return 0; } -static inline void contexthub_put_token(struct contexthub_ipc_info *ipc, enum access_type acc) +static void contexthub_put_token(struct contexthub_ipc_info *ipc) { - if (acc == HW_ACCESS) { - dev_info(ipc->dev, "%s: out shutdown\n", __func__); - mutex_unlock(&pmu_shutdown_mutex); - } + atomic_dec(&ipc->in_use_ipc); } /* host interface functions */ @@ -99,16 +94,9 @@ int contexthub_is_run(struct contexthub_ipc_info *ipc) } /* request contexthub to host driver */ -int contexthub_request(struct contexthub_ipc_info *ipc, enum access_type acc) +int contexthub_request(struct contexthub_ipc_info *ipc) { - if (!contexthub_get_token(ipc, acc)) { - dev_info(ipc->dev, "%s: %s isn't accesable: chub_status: %d, in_reset:%d\n", - __func__, (acc == HW_ACCESS) ? "hw" : "ipc", - atomic_read(&ipc->chub_status), atomic_read(&ipc->in_reset)); - return -EINVAL; - } - - if ((acc == HW_ACCESS) || !ipc->powermode) + if (!ipc->powermode) return 0; #ifdef CONFIG_CHRE_SENSORHUB_HAL @@ -119,11 +107,9 @@ int contexthub_request(struct contexthub_ipc_info *ipc, enum access_type acc) } /* rlease contexthub to host driver */ -void contexthub_release(struct contexthub_ipc_info *ipc, enum access_type acc) +void contexthub_release(struct contexthub_ipc_info *ipc) { - contexthub_put_token(ipc, acc); - - if ((acc == HW_ACCESS) || !ipc->powermode) + if (!ipc->powermode) return; #ifdef CONFIG_CHRE_SENSORHUB_HAL @@ -246,7 +232,7 @@ static int contexthub_ipc_drv_init(struct contexthub_ipc_info *chub) #endif ret = chub_dbg_init(chub_dev); if (ret) - dev_err(chub_dev, "%s: failed. ret:%d\n", __func__, ret); + dev_err(chub_dev, "%s: fails. ret:%d\n", __func__, ret); return ret; } @@ -312,43 +298,19 @@ static bool contexthub_lowlevel_alive(struct contexthub_ipc_info *ipc) return ipc->chub_alive_lock.flag; } +#define CHUB_RESET_THOLD (5) /* handle errors of chub driver and fw */ static void handle_debug_work(struct contexthub_ipc_info *ipc, enum chub_err_type err) { int need_reset; int alive = contexthub_lowlevel_alive(ipc); - /* handle fw dbg */ - if (err == CHUB_ERR_NANOHUB) { - enum ipc_debug_event event = ipc_read_debug_event(AP); - - dev_info(ipc->dev, "%s: fw dbg event:%d\n", __func__, event); - switch (event) { - case IPC_DEBUG_CHUB_PRINT_LOG: - log_flush(ipc->fw_log); - break; - default: - dev_warn(ipc->dev, "Contexthub request invalid event:%d\n", event); - break; - }; - - ipc_write_debug_event(AP, 0); - return; - } - - /* handle err */ - ipc->err_cnt[err]++; - dev_info(ipc->dev, "%s: err:%d, alive:%d, status:%d, in-reset:%d\n", __func__, err, alive, __raw_readl(&ipc->chub_status), __raw_readl(&ipc->in_reset)); - if ((atomic_read(&ipc->chub_status) == CHUB_ST_ERR) || !alive) need_reset = 1; - /* dump hw & sram into file */ - chub_dbg_dump_hw(ipc, err); - /* reset */ if (need_reset) { #if defined(CHUB_RESET_ENABLE) @@ -357,13 +319,11 @@ static void handle_debug_work(struct contexthub_ipc_info *ipc, enum chub_err_typ dev_info(ipc->dev, "%s: request silent reset. err:%d, alive:%d, status:%d, in-reset:%d\n", __func__, err, alive, __raw_readl(&ipc->chub_status), __raw_readl(&ipc->in_reset)); - - ret = contexthub_reset(ipc, 0); + ret = contexthub_reset(ipc, 0, err); if (ret) - dev_warn(ipc->dev, "%s: failed to reset:%d. status:%d\n", + dev_warn(ipc->dev, "%s: fails to reset:%d. status:%d\n", __func__, ret, __raw_readl(&ipc->chub_status)); else - /* TODO: recovery */ dev_info(ipc->dev, "%s: chub reset! should be recovery\n", __func__); #else @@ -376,36 +336,48 @@ static void handle_debug_work(struct contexthub_ipc_info *ipc, enum chub_err_typ } } -#define CHUB_RESET_THOLD (5) static void request_debug_work(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", __func__, err, ipc->err_cnt[err], enable_wq); - /* get fw err */ + if (err < CHUB_ERR_NEED_RESET) { + if (ipc->err_cnt[err] > CHUB_RESET_THOLD) { + atomic_set(&ipc->chub_status, CHUB_ST_ERR); + ipc->err_cnt[err] = 0; + dev_info(ipc->dev, "%s: err:%d(cnt:%d), enter error status\n", + __func__, err, ipc->err_cnt[err]); + } else { + ipc->err_cnt[err]++; + return; + } + } + + /* get chub-fw err */ if (err == CHUB_ERR_NANOHUB) { - enum ipc_debug_event fw_evt = ipc_read_debug_event(AP); - if (fw_evt == IPC_DEBUG_CHUB_FAULT) { - err = CHUB_ERR_FW_FAULT; - ipc_write_debug_event(AP, 0); + enum ipc_debug_event fw_evt; + + if (contexthub_get_token(ipc)) { + dev_warn(ipc->dev, "%s: get token\n", __func__); + return; } - else if ((fw_evt == IPC_DEBUG_CHUB_ASSERT) || (fw_evt == IPC_DEBUG_CHUB_ERROR)) { + fw_evt = ipc_read_debug_event(AP); + if (fw_evt == IPC_DEBUG_CHUB_FAULT) + err = CHUB_ERR_FW_FAULT; + else if ((fw_evt == IPC_DEBUG_CHUB_ASSERT) || (fw_evt == IPC_DEBUG_CHUB_ERROR)) err = CHUB_ERR_FW_ERROR; - ipc_write_debug_event(AP, 0); - } + else + dev_warn(ipc->dev, "%s: unsupported fw_evt: %d\n", fw_evt); + + ipc_write_debug_event(AP, 0); + contexthub_put_token(ipc); } /* set status in CHUB_ST_ERR */ if ((err == CHUB_ERR_ITMON) || (err == CHUB_ERR_FW_WDT) || (err == CHUB_ERR_FW_FAULT)) atomic_set(&ipc->chub_status, CHUB_ST_ERR); - if (err < CHUB_ERR_NEED_RESET) - if (ipc->err_cnt[err] > CHUB_RESET_THOLD) { - atomic_set(&ipc->chub_status, CHUB_ST_ERR); - ipc->err_cnt[err] = 0; - } - /* handle err */ if (enable_wq) { ipc->cur_err |= (1 << err); @@ -460,7 +432,6 @@ static void handle_debug_work_func(struct work_struct *work) return; } - mutex_lock(&dbg_mutex); dev_info(ipc->dev, "%s: cur_err:0x%x\n", __func__, ipc->cur_err); for (i = 0; i < CHUB_ERR_MAX; i++) { if (ipc->cur_err & (1 << i)) { @@ -469,7 +440,12 @@ static void handle_debug_work_func(struct work_struct *work) ipc->cur_err &= ~(1 << i); } } - mutex_unlock(&dbg_mutex); +} + +static inline void clear_err_cnt(struct contexthub_ipc_info *ipc, enum chub_err_type err) +{ + if (ipc->err_cnt[err]) + ipc->err_cnt[err] = 0; } int contexthub_ipc_read(struct contexthub_ipc_info *ipc, uint8_t *rx, int max_length, @@ -480,11 +456,6 @@ int contexthub_ipc_read(struct contexthub_ipc_info *ipc, uint8_t *rx, int max_le int ret; void *rxbuf; - if (!contexthub_get_token(ipc, IPC_ACCESS)) { - dev_warn(ipc->dev, "no-active: read failed\n"); - return 0; - } - if (!ipc->read_lock.flag) { spin_lock_irqsave(&ipc->read_lock.event.lock, flag); read_get_locked(ipc); @@ -496,7 +467,7 @@ int contexthub_ipc_read(struct contexthub_ipc_info *ipc, uint8_t *rx, int max_le spin_unlock_irqrestore(&ipc->read_lock.event.lock, flag); if (ret < 0) dev_warn(ipc->dev, - "failed to get read ret:%d timeout:%d, flag:0x%x", + "fails to get read ret:%d timeout:%d, flag:0x%x", ret, timeout, ipc->read_lock.flag); if (!ipc->read_lock.flag) @@ -505,6 +476,11 @@ int contexthub_ipc_read(struct contexthub_ipc_info *ipc, uint8_t *rx, int max_le ipc->read_lock.flag--; + if (contexthub_get_token(ipc)) { + dev_warn(ipc->dev, "no-active: read fails\n"); + return 0; + } + #ifdef USE_IPC_BUF rxbuf = ipc->rxbuf; size = ipc_read_data(IPC_DATA_C2A, rxbuf); @@ -513,12 +489,13 @@ int contexthub_ipc_read(struct contexthub_ipc_info *ipc, uint8_t *rx, int max_le #endif if (size > 0) { - contexthub_put_token(ipc, IPC_ACCESS); - return contexthub_read_process(rx, rxbuf, size); + clear_err_cnt(ipc, CHUB_ERR_READ_FAIL); + ret = contexthub_read_process(rx, rxbuf, size); } + contexthub_put_token(ipc); + return ret; fail_get_channel: - contexthub_put_token(ipc, IPC_ACCESS); request_debug_work(ipc, CHUB_ERR_READ_FAIL, 0); return -EINVAL; } @@ -528,19 +505,21 @@ int contexthub_ipc_write(struct contexthub_ipc_info *ipc, { int ret; - if (!contexthub_get_token(ipc, IPC_ACCESS)) { - dev_warn(ipc->dev, "no-active: write failed\n"); + if (contexthub_get_token(ipc)) { + dev_warn(ipc->dev, "no-active: write fails\n"); return 0; } ret = ipc_write_data(IPC_DATA_A2C, tx, (u16)length); + contexthub_put_token(ipc); if (ret) { - pr_err("%s: failed to write data: ret:%d, len:%d errcnt:%d\n", + 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); length = 0; + } else { + clear_err_cnt(ipc, CHUB_ERR_WRITE_FAIL); } - contexthub_put_token(ipc, IPC_ACCESS); return length; } @@ -651,7 +630,7 @@ static int contexthub_hw_reset(struct contexthub_ipc_info *ipc, } else { ret = -EINVAL; dev_warn(ipc->dev, - "failed to contexthub power on. Status is %d\n", + "fails to contexthub power on. Status is %d\n", atomic_read(&ipc->chub_status)); } break; @@ -684,7 +663,7 @@ static int contexthub_hw_reset(struct contexthub_ipc_info *ipc, __func__, atomic_read(&ipc->chub_status)); return 0; } else { - dev_warn(ipc->dev, "%s failed. contexthub status is %d\n", + dev_warn(ipc->dev, "%s fails. contexthub status is %d\n", __func__, atomic_read(&ipc->chub_status)); return -ETIMEDOUT; } @@ -730,7 +709,7 @@ int contexthub_ipc_write_event(struct contexthub_ipc_info *ipc, ret = contexthub_hw_reset(ipc, event); } else { dev_err(ipc->dev, - "contexthub status isn't shutdown. failed to reset\n"); + "contexthub status isn't shutdown. fails to reset\n"); ret = -EINVAL; } break; @@ -774,7 +753,7 @@ int contexthub_ipc_write_event(struct contexthub_ipc_info *ipc, REG_CHUB_RESET_CHUB_CONFIGURATION); } else { dev_err(ipc->dev, - "failed to shutdown contexthub. cpu_status: 0x%x\n", + "fails to shutdown contexthub. cpu_status: 0x%x\n", val); return -EINVAL; } @@ -804,9 +783,6 @@ int contexthub_ipc_write_event(struct contexthub_ipc_info *ipc, ipc_hw_mask_irq(AP, IRQ_EVT_C2A_INT); ipc_hw_mask_irq(AP, IRQ_EVT_C2A_INTCLR); break; - case MAILBOX_EVT_ERASE_SHARED: - memset(ipc_get_base(IPC_REG_SHARED), 0, ipc_get_offset(IPC_REG_SHARED)); - break; default: need_ipc = 1; break; @@ -815,14 +791,17 @@ int contexthub_ipc_write_event(struct contexthub_ipc_info *ipc, if (!need_ipc) return ret; - if (!contexthub_get_token(ipc, IPC_ACCESS)) { - dev_warn(ipc->dev, "%s event:%d/%d failed chub isn't active\n", - __func__, event, MAILBOX_EVT_MAX); + 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"); @@ -849,12 +828,11 @@ int contexthub_ipc_write_event(struct contexthub_ipc_info *ipc, check_rtc_time(); ipc_write_debug_event(AP, (u32)event); ipc_add_evt(IPC_EVT_A2C, IRQ_EVT_A2C_DEBUG); - return 0; + ret = 0; } break; } - - contexthub_put_token(ipc, IPC_ACCESS); + contexthub_put_token(ipc); return ret; } @@ -867,13 +845,13 @@ int contexthub_poweron(struct contexthub_ipc_info *ipc) if (!atomic_read(&ipc->chub_status)) { ret = contexthub_download_image(ipc, IPC_REG_BL); if (ret) { - dev_warn(dev, "failed to download bootloader\n"); + dev_warn(dev, "fails to download bootloader\n"); return ret; } ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_INIT_IPC); if (ret) { - dev_warn(dev, "failed to init ipc\n"); + dev_warn(dev, "fails to init ipc\n"); return ret; } @@ -882,12 +860,12 @@ int contexthub_poweron(struct contexthub_ipc_info *ipc) ret = contexthub_download_image(ipc, IPC_REG_OS); if (ret) { - dev_warn(dev, "failed to download kernel\n"); + dev_warn(dev, "fails to download kernel\n"); return ret; } ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_POWER_ON); if (ret) { - dev_warn(dev, "failed to poweron\n"); + dev_warn(dev, "fails to poweron\n"); return ret; } @@ -913,7 +891,7 @@ static int contexthub_download_and_check_image(struct contexthub_ipc_info *ipc, memcpy_fromio(fw, ipc_get_base(reg), ipc_get_offset(reg)); ret = contexthub_download_image(ipc, reg); if (ret) { - dev_err(ipc->dev, "%s: download bl(%d) failed\n", __func__, reg == IPC_REG_BL); + dev_err(ipc->dev, "%s: download bl(%d) fails\n", __func__, reg == IPC_REG_BL); goto out; } @@ -922,7 +900,7 @@ static int contexthub_download_and_check_image(struct contexthub_ipc_info *ipc, int i; u32 *fw_image = (u32 *)ipc_get_base(reg); - dev_err(ipc->dev, "%s: fw(%lx) doesn't match with size %d\n", + dev_err(ipc->dev, "%s: fw(%lx) doens't match with size %d\n", __func__, (unsigned long)ipc_get_base(reg), ipc_get_offset(reg)); for (i = 0; i < ipc_get_offset(reg) / 4; i++) if (fw[i] != fw_image[i]) { @@ -939,12 +917,13 @@ out: return ret; } -int contexthub_reset(struct contexthub_ipc_info *ipc, bool force_load) +int contexthub_reset(struct contexthub_ipc_info *ipc, bool force_load, int dump) { int ret; + int trycnt; - dev_info(ipc->dev, "%s: force:%d, status:%d, in-reset:%d\n", - __func__, force_load, atomic_read(&ipc->chub_status), atomic_read(&ipc->in_reset)); + dev_info(ipc->dev, "%s: force:%d, status:%d, in-reset:%d, user:%d\n", + __func__, force_load, atomic_read(&ipc->chub_status), atomic_read(&ipc->in_reset), atomic_read(&ipc->in_use_ipc)); mutex_lock(&reset_mutex); if (!force_load && (atomic_read(&ipc->chub_status) == CHUB_ST_RUN)) { mutex_unlock(&reset_mutex); @@ -952,9 +931,19 @@ int contexthub_reset(struct contexthub_ipc_info *ipc, bool force_load) return 0; } atomic_inc(&ipc->in_reset); -#ifndef CONFIG_CHRE_SENSORHUB_HAL /* retry exam */ -retry: -#endif + + do { + msleep(WAIT_CHUB_MS); + if (++trycnt > RESET_WAIT_TRY_CNT) { + dev_info(ipc->dev, "%s: cann't get lock. force reset: %d\n", __func__, atomic_read(&ipc->in_use_ipc)); + break; + } + 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) + chub_dbg_dump_hw(ipc, dump); + dev_info(ipc->dev, "%s: start reset status:%d\n", __func__, atomic_read(&ipc->chub_status)); if (!ipc->block_reset) { /* core reset */ @@ -966,7 +955,7 @@ retry: 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 failed, ret:%d\n", __func__, ret); + dev_err(ipc->dev, "%s: shutdonw fails, ret:%d\n", __func__, ret); goto out; } dev_info(ipc->dev, "%s: out shutdown\n", __func__); @@ -981,51 +970,26 @@ retry: ret = contexthub_download_and_check_image(ipc, IPC_REG_OS); if (ret) { - dev_err(ipc->dev, "%s: os download failed\n", __func__); + dev_err(ipc->dev, "%s: download os fails\n", __func__); goto out; } } else { - dev_err(ipc->dev, "%s: bl download failed\n", __func__); + dev_err(ipc->dev, "%s: download bl fails\n", __func__); goto out; } } ret = contexthub_ipc_write_event(ipc, MAILBOX_EVT_RESET); if (ret) - dev_err(ipc->dev, "%s: reset failed, ret:%d\n", __func__, ret); + dev_err(ipc->dev, "%s: reset fails, ret:%d\n", __func__, ret); else { - dev_info(ipc->dev, "%s: chub was reset! (cnt:%d)\n", + 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); -#ifndef CONFIG_CHRE_SENSORHUB_HAL - ret = request_wakeup(ipc->data); - if (ret) - dev_err(ipc->dev, "%s: failed to wakeup after reset, ret:%d\n", __func__, ret); - else - release_wakeup(ipc->data); - if (ipc->irq_wdt && ipc->irq_wdt_disabled) { - enable_irq(ipc->irq_wdt); - ipc->irq_wdt_disabled = 0; - } -#endif } - out: - if (!ret) { - dev_info(ipc->dev, "%s: chub reseted and work (cnt:%d)\n", - __func__, ipc->err_cnt[CHUB_ERR_RESET_CNT]); - ipc->err_cnt[CHUB_ERR_RESET_CNT] = 0; - } else { -#ifndef CONFIG_CHRE_SENSORHUB_HAL - atomic_inc(&ipc->in_reset); - if (ipc->err_cnt[CHUB_ERR_RESET_CNT] > CHUB_RESET_THOLD) - msleep(WAIT_TIMEOUT_MS * CHUB_RESET_THOLD); - else - msleep(WAIT_TIMEOUT_MS); - goto retry; -#endif - } mutex_unlock(&reset_mutex); return ret; @@ -1049,7 +1013,6 @@ int contexthub_download_image(struct contexthub_ipc_info *ipc, enum ipc_region r return ret; } memcpy(ipc_get_base(reg), entry->data, entry->size); - dev_info(ipc->dev, "image name : %s\n", ipc->os_name); 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); @@ -1143,10 +1106,11 @@ static irqreturn_t contexthub_irq_handler(int irq, void *data) err, start_index, cur_evt, evt, irq_num, status, ipc_hw_read_int_status_reg(AP), ipc_hw_read_int_gen_reg(AP)); - ipc->err_cnt[err]++; ipc_hw_clear_all_int_pend_reg(AP); - if (ipc->err_cnt[err] > CHUB_RESET_THOLD) - request_debug_work(ipc, err, 1); + request_debug_work(ipc, err, 1); + } else { + clear_err_cnt(ipc, CHUB_ERR_EVTQ_EMTPY); + clear_err_cnt(ipc, CHUB_ERR_EVTQ_NO_HW_TRIGGER); } return IRQ_HANDLED; } @@ -1156,7 +1120,7 @@ static irqreturn_t contexthub_irq_wdt_handler(int irq, void *data) { struct contexthub_ipc_info *ipc = data; - dev_info(ipc->dev, "%s called\n", __func__); + dev_info(ipc->dev, "%s calledn", __func__); disable_irq_nosync(ipc->irq_wdt); ipc->irq_wdt_disabled = 1; request_debug_work(ipc, CHUB_ERR_FW_WDT, 1); @@ -1205,6 +1169,7 @@ static __init int contexthub_ipc_hw_init(struct platform_device *pdev, struct resource *res; const char *os; const char *resetmode; + const char *selectos; struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; const char *string_array[10]; @@ -1235,6 +1200,16 @@ static __init int contexthub_ipc_hw_init(struct platform_device *pdev, else chub->block_reset = 0; + /* get os select from dt */ + selectos = of_get_property(node, "os-select", NULL); + if (!selectos || strcmp(selectos, "true")) { + dev_info(dev,"multi os disabled : %s\n", selectos); + chub->sel_os = true; + } else { + dev_info(dev,"multi os enabled : %s\n", selectos); + chub->sel_os = false; + } + /* get mailbox interrupt */ chub->irq_mailbox = irq_of_parse_and_map(node, 0); if (chub->irq_mailbox < 0) { @@ -1274,7 +1249,7 @@ static __init int contexthub_ipc_hw_init(struct platform_device *pdev, res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mailbox"); chub->mailbox = devm_ioremap_resource(dev, res); if (IS_ERR(chub->mailbox)) { - dev_err(dev, "failed to get mailbox sfr\n"); + dev_err(dev, "fails to get mailbox sfr\n"); return PTR_ERR(chub->mailbox); } @@ -1282,7 +1257,7 @@ static __init int contexthub_ipc_hw_init(struct platform_device *pdev, res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); chub->sram = devm_ioremap_resource(dev, res); if (IS_ERR(chub->sram)) { - dev_err(dev, "failed to get sram\n"); + dev_err(dev, "fails to get sram\n"); return PTR_ERR(chub->sram); } @@ -1290,7 +1265,7 @@ static __init int contexthub_ipc_hw_init(struct platform_device *pdev, res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dumpgpr"); chub->chub_dumpgrp = devm_ioremap_resource(dev, res); if (IS_ERR(chub->chub_dumpgrp)) { - dev_err(dev, "failed to get dumpgrp\n"); + dev_err(dev, "fails to get dumpgrp\n"); return PTR_ERR(chub->chub_dumpgrp); } @@ -1298,7 +1273,7 @@ static __init int contexthub_ipc_hw_init(struct platform_device *pdev, 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, "failed to get dumpgrp\n"); + dev_err(dev, "fails to get dumpgrp\n"); return PTR_ERR(chub->pmu_chub_reset); } @@ -1377,7 +1352,7 @@ static __init int contexthub_ipc_hw_init(struct platform_device *pdev, chub_clk_len = of_property_count_strings(node, "clock-names"); of_property_read_string_array(node, "clock-names", string_array, chub_clk_len); - for (i = 0 ; i < chub_clk_len; i++){ + for (i = 0; i < chub_clk_len; i++) { clk = devm_clk_get_and_prepare(dev, string_array[i]); if (!clk) return -ENODEV; @@ -1402,7 +1377,7 @@ static ssize_t chub_reset(struct device *dev, const char *buf, size_t count) { struct contexthub_ipc_info *ipc = dev_get_drvdata(dev); - int ret = contexthub_reset(ipc, 1); + int ret = contexthub_reset(ipc, 1, 0); return ret < 0 ? ret : count; } @@ -1477,7 +1452,7 @@ static int contexthub_ipc_probe(struct platform_device *pdev) chub->data->irq1 = IRQ_EVT_A2C_WAKEUP; chub->data->irq2 = 0; #endif - + atomic_set(&chub->in_use_ipc, 0); atomic_set(&chub->chub_status, CHUB_ST_NO_POWER); atomic_set(&chub->in_reset, 0); chub->powermode = 0; /* updated by fw bl */ @@ -1520,6 +1495,24 @@ static int contexthub_ipc_remove(struct platform_device *pdev) return 0; } +static int contexthub_suspend(struct device *dev) +{ + struct contexthub_ipc_info *ipc = dev_get_drvdata(dev); + struct nanohub_data *data = ipc->data; + + return nanohub_suspend(data->iio_dev); +} + +static int contexthub_resume(struct device *dev) +{ + struct contexthub_ipc_info *ipc = dev_get_drvdata(dev); + struct nanohub_data *data = ipc->data; + + return nanohub_resume(data->iio_dev); +} + +static SIMPLE_DEV_PM_OPS(contexthub_pm_ops, contexthub_suspend, contexthub_resume); + static const struct of_device_id contexthub_ipc_match[] = { {.compatible = "samsung,exynos-nanohub"}, {}, @@ -1532,7 +1525,8 @@ static struct platform_driver samsung_contexthub_ipc_driver = { .name = "nanohub-ipc", .owner = THIS_MODULE, .of_match_table = contexthub_ipc_match, - }, + .pm = &contexthub_pm_ops, + }, }; int nanohub_mailbox_init(void) diff --git a/drivers/staging/nanohub/chub.h b/drivers/staging/nanohub/chub.h index 75aee40d02b4..595d0c4c7890 100644 --- a/drivers/staging/nanohub/chub.h +++ b/drivers/staging/nanohub/chub.h @@ -29,6 +29,7 @@ #include "chub_log.h" #define WAIT_TRY_CNT (3) +#define RESET_WAIT_TRY_CNT (10) #define WAIT_CHUB_MS (100) /* utils for nanohub main */ @@ -177,6 +178,7 @@ struct contexthub_ipc_info { atomic_t in_reset; atomic_t irq1_apInt; atomic_t wakeup_chub; + atomic_t in_use_ipc; int irq_mailbox; int irq_wdt; bool irq_wdt_disabled; @@ -285,8 +287,6 @@ struct contexthub_ipc_info { #define IPC_HW_WRITE_BAAW_CHUB3(base, val) \ __raw_writel((val), (base) + REG_BAAW_D_CHUB3) -enum access_type { HW_ACCESS, IPC_ACCESS }; - int contexthub_ipc_write_event(struct contexthub_ipc_info *data, enum mailbox_event event); int contexthub_ipc_read(struct contexthub_ipc_info *ipc, @@ -295,10 +295,8 @@ int contexthub_ipc_write(struct contexthub_ipc_info *ipc, uint8_t *tx, int length, int timeout); int contexthub_poweron(struct contexthub_ipc_info *data); int contexthub_download_image(struct contexthub_ipc_info *data, enum ipc_region reg); -int contexthub_reset(struct contexthub_ipc_info *ipc, bool force_load); +int contexthub_reset(struct contexthub_ipc_info *ipc, bool force_load, int dump_id); int contexthub_wakeup(struct contexthub_ipc_info *data, int evt); - -int contexthub_is_run(struct contexthub_ipc_info *ipc); -int contexthub_request(struct contexthub_ipc_info *ipc, enum access_type acc); -void contexthub_release(struct contexthub_ipc_info *ipc, enum access_type acc); +int contexthub_request(struct contexthub_ipc_info *ipc); +void contexthub_release(struct contexthub_ipc_info *ipc); #endif diff --git a/drivers/staging/nanohub/chub_dbg.c b/drivers/staging/nanohub/chub_dbg.c index 880446d592df..cf3f4b47c5b2 100644 --- a/drivers/staging/nanohub/chub_dbg.c +++ b/drivers/staging/nanohub/chub_dbg.c @@ -450,9 +450,9 @@ static ssize_t chub_wakeup_store(struct device *dev, return ret; if (event) - ret = contexthub_request(ipc, IPC_ACCESS); + ret = contexthub_request(ipc); else - contexthub_release(ipc, IPC_ACCESS); + contexthub_release(ipc); return ret ? ret : count; } diff --git a/drivers/staging/nanohub/main.c b/drivers/staging/nanohub/main.c index d86b8825bf3d..bbc95877e7f8 100644 --- a/drivers/staging/nanohub/main.c +++ b/drivers/staging/nanohub/main.c @@ -743,7 +743,7 @@ static int nanohub_hw_reset(struct nanohub_data *data) } #elif defined(CONFIG_NANOHUB_MAILBOX) #ifdef CHUB_RESET_ENABLE - ret = contexthub_reset(data->pdata->mailbox_client, 0); + ret = contexthub_reset(data->pdata->mailbox_client, 0, CHUB_ERR_COMMS); #else ret = -EINVAL; #endif @@ -858,7 +858,7 @@ static ssize_t nanohub_download_bl(struct device *dev, return ret < 0 ? ret : count; #elif defined(CONFIG_NANOHUB_MAILBOX) - ret = contexthub_reset(data->pdata->mailbox_client, 1); + ret = contexthub_reset(data->pdata->mailbox_client, 1, 0); return ret < 0 ? ret : count; #endif