Loading drivers/slimbus/slim-msm-ngd.c +135 −58 Original line number Diff line number Diff line Loading @@ -97,7 +97,7 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) writel_relaxed(stat, ngd + NGD_INT_CLR); dev->err = -EIO; dev_err(dev->dev, "NGD interrupt error:0x%x, err:%d", stat, SLIM_WARN(dev, "NGD interrupt error:0x%x, err:%d\n", stat, dev->err); /* Guarantee that error interrupts are cleared */ mb(); Loading @@ -119,7 +119,7 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) for (i = 1; i < ((len + 3) >> 2); i++) { rx_buf[i] = readl_relaxed(ngd + NGD_RX_MSG + (4 * i)); dev_dbg(dev->dev, "REG-RX data: %x\n", rx_buf[i]); SLIM_DBG(dev, "REG-RX data: %x\n", rx_buf[i]); } msm_slim_rx_enqueue(dev, rx_buf, len); writel_relaxed(NGD_INT_RX_MSG_RCVD, Loading @@ -130,8 +130,7 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) */ mb(); if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) dev_err(dev->dev, "direct message received even with RX MSGQs"); SLIM_WARN(dev, "direct msg rcvd with RX MSGQs\n"); else complete(&dev->rx_msgq_notify); } Loading @@ -140,13 +139,13 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) /* Guarantee RECONFIG DONE interrupt is cleared */ mb(); /* In satellite mode, just log the reconfig done IRQ */ dev_dbg(dev->dev, "reconfig done IRQ for NGD"); SLIM_DBG(dev, "reconfig done IRQ for NGD\n"); } if (stat & NGD_INT_IE_VE_CHG) { writel_relaxed(NGD_INT_IE_VE_CHG, ngd + NGD_INT_CLR); /* Guarantee IE VE change interrupt is cleared */ mb(); dev_err(dev->dev, "NGD IE VE change"); SLIM_DBG(dev, "NGD IE VE change\n"); } pstat = readl_relaxed(PGD_THIS_EE(PGD_PORT_INT_ST_EEn, dev->ver)); Loading @@ -161,7 +160,7 @@ static int ngd_qmi_available(struct notifier_block *n, unsigned long code, struct msm_slim_qmi *qmi = container_of(n, struct msm_slim_qmi, nb); struct msm_slim_ctrl *dev = container_of(qmi, struct msm_slim_ctrl, qmi); pr_info("Slimbus QMI NGD CB received event:%ld", code); SLIM_INFO(dev, "Slimbus QMI NGD CB received event:%ld\n", code); switch (code) { case QMI_SERVER_ARRIVE: schedule_work(&qmi->ssr_up); Loading Loading @@ -193,8 +192,7 @@ static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code, switch (code) { case SUBSYS_BEFORE_SHUTDOWN: dev_err(dev->dev, "SLIM %lu external_modem SSR notify cb", code); SLIM_INFO(dev, "SLIM %lu external_modem SSR notify cb\n", code); /* vote for runtime-pm so that ADSP doesn't go down */ msm_slim_get_ctrl(dev); /* Loading @@ -208,8 +206,8 @@ static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code, case SUBSYS_AFTER_POWERUP: if (dev->mdm.state != MSM_CTRL_DOWN) return NOTIFY_DONE; dev_err(dev->dev, "SLIM %lu external_modem SSR notify cb", code); SLIM_INFO(dev, "SLIM %lu external_modem SSR notify cb\n", code); /* vote for runtime-pm so that ADSP doesn't go down */ msm_slim_get_ctrl(dev); msm_slim_qmi_check_framer_request(dev); Loading @@ -221,7 +219,8 @@ static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code, pm_runtime_disable(dev->dev); pm_runtime_set_suspended(dev->dev); dev->state = MSM_CTRL_DOWN; pr_err("SLIM MDM SSR (active framer on MDM) dev-down"); SLIM_INFO(dev, "SLIM MDM SSR (active framer on MDM) dev-down\n"); list_for_each_entry(sbdev, &ctrl->devs, dev_list) slim_report_absent(sbdev); ngd_slim_power_up(dev, true); Loading Loading @@ -324,7 +323,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) if (dev->state == MSM_CTRL_DOWN) { u8 mc = (u8)txn->mc; int timeout; dev_err(dev->dev, "ADSP slimbus not up yet"); SLIM_INFO(dev, "ADSP slimbus not up yet\n"); /* * Messages related to data channel management can't * wait since they are holding reconfiguration lock. Loading Loading @@ -384,7 +383,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) mutex_lock(&dev->tx_lock); if (report_sat == false && dev->state != MSM_CTRL_AWAKE) { dev_err(dev->dev, "controller not ready"); SLIM_ERR(dev, "controller not ready\n"); mutex_unlock(&dev->tx_lock); msm_slim_put_ctrl(dev); return -EREMOTEIO; Loading @@ -394,6 +393,14 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) txn->mc == SLIM_MSG_MC_CONNECT_SINK || txn->mc == SLIM_MSG_MC_DISCONNECT_PORT)) { int i = 0; if (txn->mc != SLIM_MSG_MC_DISCONNECT_PORT) SLIM_INFO(dev, "Connect port: laddr 0x%x port_num %d chan_num %d\n", txn->la, txn->wbuf[0], txn->wbuf[1]); else SLIM_INFO(dev, "Disconnect port: laddr 0x%x port_num %d\n", txn->la, txn->wbuf[0]); txn->mt = SLIM_MSG_MT_DEST_REFERRED_USER; if (txn->mc == SLIM_MSG_MC_CONNECT_SOURCE) txn->mc = SLIM_USR_MC_CONNECT_SRC; Loading @@ -410,10 +417,11 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) mutex_unlock(&dev->tx_lock); ret = dev->ctrl.get_laddr(&dev->ctrl, ea, 6, &dev->pgdla); pr_debug("SLIM PGD LA:0x%x, ret:%d", dev->pgdla, ret); SLIM_DBG(dev, "SLIM PGD LA:0x%x, ret:%d\n", dev->pgdla, ret); if (ret) { pr_err("Incorrect SLIM-PGD EAPC:0x%x", SLIM_ERR(dev, "Incorrect SLIM-PGD EAPC:0x%x\n", dev->pdata.eapc); return ret; } Loading @@ -428,7 +436,8 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) wbuf[i++] = txn->wbuf[1]; ret = ngd_get_tid(ctrl, txn, &wbuf[i++], &done); if (ret) { pr_err("TID for connect/disconnect fail:%d", ret); SLIM_ERR(dev, "TID for connect/disconnect fail:%d\n", ret); goto ngd_xfer_err; } txn->len = i; Loading @@ -438,7 +447,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) txn->rl--; pbuf = msm_get_msg_buf(dev, txn->rl); if (!pbuf) { dev_err(dev->dev, "Message buffer unavailable"); SLIM_ERR(dev, "Message buffer unavailable\n"); ret = -ENOMEM; goto ngd_xfer_err; } Loading Loading @@ -492,7 +501,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) return 0; } if (dev->err) { dev_err(dev->dev, "pipe-port connect err:%d", dev->err); SLIM_ERR(dev, "pipe-port connect err:%d\n", dev->err); goto ngd_xfer_err; } /* Add port-base to port number if this is manager side port */ Loading Loading @@ -531,7 +540,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) u32 conf, stat, rx_msgq, int_stat, int_en, int_clr; void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver); dev_err(dev->dev, "TX failed :MC:0x%x,mt:0x%x, ret:%d, ver:%d", SLIM_WARN(dev, "TX failed :MC:0x%x,mt:0x%x, ret:%d, ver:%d\n", txn_mc, txn_mt, ret, dev->ver); conf = readl_relaxed(ngd); stat = readl_relaxed(ngd + NGD_STATUS); Loading @@ -540,9 +549,10 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) int_en = readl_relaxed(ngd + NGD_INT_EN); int_clr = readl_relaxed(ngd + NGD_INT_CLR); pr_err("conf:0x%x,stat:0x%x,rxmsgq:0x%x", conf, stat, rx_msgq); pr_err("int_stat:0x%x,int_en:0x%x,int_cll:0x%x", int_stat, int_en, int_clr); SLIM_WARN(dev, "conf:0x%x,stat:0x%x,rxmsgq:0x%x\n", conf, stat, rx_msgq); SLIM_WARN(dev, "int_stat:0x%x,int_en:0x%x,int_cll:0x%x\n", int_stat, int_en, int_clr); } else if (txn_mt == SLIM_MSG_MT_DEST_REFERRED_USER && (txn_mc == SLIM_USR_MC_CONNECT_SRC || txn_mc == SLIM_USR_MC_CONNECT_SINK || Loading @@ -556,8 +566,9 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) else ret = txn->ec; if (ret) { pr_err("connect/disconnect:0x%x,tid:%d err:%d", txn->mc, txn->tid, ret); SLIM_INFO(dev, "connect/disconnect:0x%x,tid:%d err:%d\n", txn->mc, txn->tid, ret); mutex_lock(&ctrl->m_ctrl); ctrl->txnt[txn->tid] = NULL; mutex_unlock(&ctrl->m_ctrl); Loading Loading @@ -612,6 +623,7 @@ static int ngd_user_msg(struct slim_controller *ctrl, u8 la, u8 mt, u8 mc, static int ngd_xferandwait_ack(struct slim_controller *ctrl, struct slim_msg_txn *txn) { struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl); int ret = ngd_xfer_msg(ctrl, txn); if (!ret) { int timeout; Loading @@ -624,8 +636,8 @@ static int ngd_xferandwait_ack(struct slim_controller *ctrl, if (ret) { if (ret != -EREMOTEIO || txn->mc != SLIM_USR_MC_CHAN_CTRL) pr_err("master msg:0x%x,tid:%d ret:%d", txn->mc, txn->tid, ret); SLIM_ERR(dev, "master msg:0x%x,tid:%d ret:%d\n", txn->mc, txn->tid, ret); mutex_lock(&ctrl->m_ctrl); ctrl->txnt[txn->tid] = NULL; mutex_unlock(&ctrl->m_ctrl); Loading @@ -636,12 +648,13 @@ static int ngd_xferandwait_ack(struct slim_controller *ctrl, static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) { int ret; int ret = 0, num_chan = 0; struct slim_pending_ch *pch; struct slim_msg_txn txn; struct slim_controller *ctrl = sb->ctrl; DECLARE_COMPLETION_ONSTACK(done); u8 wbuf[SLIM_MSGQ_BUF_LEN]; struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl); *clkgear = ctrl->clkgear; *subfrmc = 0; Loading @@ -654,7 +667,7 @@ static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) txn.rbuf = NULL; if (ctrl->sched.msgsl != ctrl->sched.pending_msgsl) { pr_debug("slim reserve BW for messaging: req: %d", SLIM_DBG(dev, "slim reserve BW for messaging: req: %d\n", ctrl->sched.pending_msgsl); txn.mc = SLIM_USR_MC_REQ_BW; wbuf[txn.len++] = ((sb->laddr & 0x1f) | Loading Loading @@ -685,7 +698,7 @@ static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) struct slim_ich *slc; slc = &ctrl->chans[pch->chan]; if (!slc) { pr_err("no channel in define?"); SLIM_WARN(dev, "no channel in define?\n"); return -ENXIO; } if (txn.len == 0) { Loading @@ -700,12 +713,14 @@ static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) wbuf[txn.len++] = slc->prrate; ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done); if (ret) { pr_err("no tid for channel define?"); SLIM_WARN(dev, "no tid for channel define?\n"); return -ENXIO; } } num_chan++; wbuf[txn.len++] = slc->chan; pr_debug("slim define chan:%d, tid:0x%x", slc->chan, txn.tid); SLIM_INFO(dev, "slim activate chan:%d, laddr: 0x%x\n", slc->chan, sb->laddr); } if (txn.len) { txn.mc = SLIM_USR_MC_DEF_ACT_CHAN; Loading @@ -730,7 +745,7 @@ static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) struct slim_ich *slc; slc = &ctrl->chans[pch->chan]; if (!slc) { pr_err("no channel in removal?"); SLIM_WARN(dev, "no channel in removal?\n"); return -ENXIO; } if (txn.len == 0) { Loading @@ -739,12 +754,13 @@ static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) (sb->laddr & 0x1f); ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done); if (ret) { pr_err("no tid for channel define?"); SLIM_WARN(dev, "no tid for channel define?\n"); return -ENXIO; } } wbuf[txn.len++] = slc->chan; pr_debug("slim remove chan:%d, tid:0x%x", slc->chan, txn.tid); SLIM_INFO(dev, "slim remove chan:%d, laddr: 0x%x\n", slc->chan, sb->laddr); } if (txn.len) { txn.mc = SLIM_USR_MC_CHAN_CTRL; Loading Loading @@ -852,7 +868,7 @@ static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf) wbuf[3] = SAT_MSG_PROT; txn.wbuf = wbuf; txn.len = 4; pr_info("SLIM SAT: Received master capability"); SLIM_INFO(dev, "SLIM SAT: Rcvd master capability\n"); if (dev->state >= MSM_CTRL_ASLEEP) { ngd_slim_setup_msg_path(dev); if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) Loading @@ -869,18 +885,20 @@ capability_retry: ret = ngd_xfer_msg(&dev->ctrl, &txn); if (!ret) { enum msm_ctrl_state prev_state = dev->state; pr_info("SLIM SAT: capability exchange successful"); SLIM_INFO(dev, "SLIM SAT: capability exchange successful\n"); dev->state = MSM_CTRL_AWAKE; if (prev_state >= MSM_CTRL_ASLEEP) complete(&dev->reconf); else pr_err("SLIM: unexpected capability, state:%d", SLIM_ERR(dev, "SLIM: unexpected capability, state:%d\n", prev_state); /* ADSP SSR, send device_up notifications */ if (prev_state == MSM_CTRL_DOWN) complete(&dev->qmi.slave_notify); } else if (ret == -EIO) { pr_info("capability message NACKed, retrying"); SLIM_WARN(dev, "capability message NACKed, retrying\n"); if (retries < INIT_MX_RETRIES) { msleep(DEF_RETRY_MS); retries++; Loading @@ -903,7 +921,8 @@ capability_retry: mutex_lock(&dev->ctrl.m_ctrl); txn = dev->ctrl.txnt[buf[3]]; if (!txn) { pr_err("LADDR response after timeout, tid:0x%x", SLIM_WARN(dev, "LADDR response after timeout, tid:0x%x\n", buf[3]); mutex_unlock(&dev->ctrl.m_ctrl); return; Loading @@ -920,7 +939,7 @@ capability_retry: mutex_lock(&dev->ctrl.m_ctrl); txn = dev->ctrl.txnt[buf[3]]; if (!txn) { pr_err("ACK received after timeout, tid:0x%x", SLIM_WARN(dev, "ACK received after timeout, tid:0x%x\n", buf[3]); mutex_unlock(&dev->ctrl.m_ctrl); return; Loading @@ -928,7 +947,7 @@ capability_retry: dev_dbg(dev->dev, "got response:tid:%d, response:0x%x", (int)buf[3], buf[4]); if (!(buf[4] & MSM_SAT_SUCCSS)) { dev_err(dev->dev, "TID:%d, NACK code:0x%x", (int)buf[3], SLIM_WARN(dev, "TID:%d, NACK code:0x%x\n", (int)buf[3], buf[4]); txn->ec = -EIO; } Loading @@ -953,7 +972,7 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart) int timeout = wait_for_completion_timeout(&dev->qmi.qmi_comp, HZ); if (!timeout) pr_err("slimbus QMI init timed out"); SLIM_ERR(dev, "slimbus QMI init timed out\n"); } /* No need to vote if contorller is not in low power mode */ Loading @@ -961,7 +980,8 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart) (cur_state == MSM_CTRL_DOWN || cur_state == MSM_CTRL_ASLEEP)) { ret = msm_slim_qmi_power_request(dev, true); if (ret) { pr_err("SLIM QMI power request failed:%d", ret); SLIM_ERR(dev, "SLIM QMI power request failed:%d\n", ret); return ret; } } Loading @@ -978,7 +998,7 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart) * For example, modem restarted when playback was active */ if (cur_state == MSM_CTRL_AWAKE) { pr_err("Subsys restart: ADSP active framer"); SLIM_INFO(dev, "Subsys restart: ADSP active framer\n"); return 0; } /* Loading @@ -998,7 +1018,8 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart) */ /* make current state as DOWN */ cur_state = MSM_CTRL_DOWN; pr_err("SLIM MDM restart: MDM active framer: reinit HW"); SLIM_INFO(dev, "SLIM MDM restart: MDM active framer: reinit HW\n"); /* disconnect BAM pipes */ if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) dev->use_rx_msgqs = MSM_MSGQ_DOWN; Loading Loading @@ -1035,11 +1056,14 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart) timeout = wait_for_completion_timeout(&dev->reconf, HZ); if (!timeout) { pr_err("Failed to receive master capability"); SLIM_ERR(dev, "Failed to receive master capability\n"); return -ETIMEDOUT; } if (cur_state == MSM_CTRL_DOWN) if (cur_state == MSM_CTRL_DOWN) { complete(&dev->ctrl_up); /* Resetting the log level */ SLIM_RST_LOGLVL(dev); } return 0; } Loading Loading @@ -1072,7 +1096,7 @@ static int ngd_slim_enable(struct msm_slim_ctrl *dev, bool enable) pm_runtime_mark_last_busy(dev->dev); pm_runtime_put(dev->dev); } else dev_err(dev->dev, "qmi init fail, ret:%d, state:%d", SLIM_ERR(dev, "qmi init fail, ret:%d, state:%d\n", ret, dev->state); } else { msm_slim_qmi_exit(dev); Loading Loading @@ -1108,7 +1132,7 @@ static int ngd_slim_rx_msgq_thread(void *data) } ret = msm_slim_rx_msgq_get(dev, buffer, index); if (ret) { dev_err(dev->dev, "rx_msgq_get() failed 0x%x\n", ret); SLIM_ERR(dev, "rx_msgq_get() failed 0x%x\n", ret); continue; } Loading Loading @@ -1193,7 +1217,7 @@ static void ngd_adsp_down(struct work_struct *work) /* device up should be called again after SSR */ list_for_each_entry(sbdev, &ctrl->devs, dev_list) slim_report_absent(sbdev); pr_info("SLIM ADSP SSR (DOWN) done"); SLIM_INFO(dev, "SLIM ADSP SSR (DOWN) done\n"); } static void ngd_adsp_up(struct work_struct *work) Loading @@ -1205,6 +1229,28 @@ static void ngd_adsp_up(struct work_struct *work) ngd_slim_enable(dev, true); } static ssize_t show_mask(struct device *device, struct device_attribute *attr, char *buf) { struct platform_device *pdev = to_platform_device(device); struct msm_slim_ctrl *dev = platform_get_drvdata(pdev); return snprintf(buf, sizeof(int), "%u\n", dev->ipc_log_mask); } static ssize_t set_mask(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(device); struct msm_slim_ctrl *dev = platform_get_drvdata(pdev); dev->ipc_log_mask = buf[0] - '0'; if (dev->ipc_log_mask > DBG_LEV) dev->ipc_log_mask = DBG_LEV; return count; } static DEVICE_ATTR(debug_mask, S_IRUGO | S_IWUSR, show_mask, set_mask); static int ngd_slim_probe(struct platform_device *pdev) { struct msm_slim_ctrl *dev; Loading Loading @@ -1249,6 +1295,26 @@ static int ngd_slim_probe(struct platform_device *pdev) dev->dev = &pdev->dev; platform_set_drvdata(pdev, dev); slim_set_ctrldata(&dev->ctrl, dev); /* Create IPC log context */ dev->ipc_slimbus_log = ipc_log_context_create(IPC_SLIMBUS_LOG_PAGES, dev_name(dev->dev)); if (!dev->ipc_slimbus_log) dev_err(&pdev->dev, "error creating ipc_logging context\n"); else { /* Initialize the log mask */ dev->ipc_log_mask = INFO_LEV; dev->default_ipc_log_mask = INFO_LEV; SLIM_INFO(dev, "start logging for slim dev %s\n", dev_name(dev->dev)); } ret = sysfs_create_file(&dev->dev->kobj, &dev_attr_debug_mask.attr); if (ret) { dev_err(&pdev->dev, "Failed to create dev. attr\n"); dev->sysfs_created = false; } else dev->sysfs_created = true; dev->base = ioremap(slim_mem->start, resource_size(slim_mem)); if (!dev->base) { dev_err(&pdev->dev, "IOremap failed\n"); Loading Loading @@ -1391,7 +1457,7 @@ static int ngd_slim_probe(struct platform_device *pdev) dev_err(dev->dev, "Failed to start notifier thread:%d\n", ret); goto err_notify_thread_create_failed; } dev_dbg(dev->dev, "NGD SB controller is up!\n"); SLIM_INFO(dev, "NGD SB controller is up!\n"); return 0; err_notify_thread_create_failed: Loading @@ -1409,6 +1475,9 @@ err_ctrl_failed: err_ioremap_bam_failed: iounmap(dev->base); err_ioremap_failed: if (dev->sysfs_created) sysfs_remove_file(&dev->dev->kobj, &dev_attr_debug_mask.attr); kfree(dev); return ret; } Loading @@ -1417,6 +1486,9 @@ static int ngd_slim_remove(struct platform_device *pdev) { struct msm_slim_ctrl *dev = platform_get_drvdata(pdev); ngd_slim_enable(dev, false); if (dev->sysfs_created) sysfs_remove_file(&dev->dev->kobj, &dev_attr_debug_mask.attr); qmi_svc_event_notifier_unregister(SLIMBUS_QMI_SVC_ID, SLIMBUS_QMI_SVC_V1, SLIMBUS_QMI_INS_ID, &dev->qmi.nb); Loading Loading @@ -1462,10 +1534,11 @@ static int ngd_slim_runtime_resume(struct device *device) if (dev->state != MSM_CTRL_DOWN) dev->state = MSM_CTRL_ASLEEP; else dev_err(device, "HW wakeup attempt during SSR"); SLIM_WARN(dev, "HW wakeup attempt during SSR\n"); } else { dev->state = MSM_CTRL_AWAKE; } SLIM_INFO(dev, "Slim runtime resume: ret %d\n", ret); return ret; } Loading @@ -1478,11 +1551,12 @@ static int ngd_slim_runtime_suspend(struct device *device) ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED); if (ret) { if (ret != -EBUSY) dev_err(device, "clk pause not entered:%d", ret); SLIM_INFO(dev, "clk pause not entered:%d\n", ret); dev->state = MSM_CTRL_AWAKE; } else { dev->state = MSM_CTRL_ASLEEP; } SLIM_INFO(dev, "Slim runtime suspend: ret %d\n", ret); return ret; } Loading @@ -1494,7 +1568,6 @@ static int ngd_slim_suspend(struct device *dev) if (!pm_runtime_enabled(dev) || (!pm_runtime_suspended(dev) && cdev->state == MSM_CTRL_IDLE)) { dev_dbg(dev, "system suspend"); ret = ngd_slim_runtime_suspend(dev); /* * If runtime-PM still thinks it's active, then make sure its Loading @@ -1521,16 +1594,20 @@ static int ngd_slim_suspend(struct device *dev) */ ret = 0; } SLIM_INFO(cdev, "system suspend\n"); return ret; } static int ngd_slim_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct msm_slim_ctrl *cdev = platform_get_drvdata(pdev); /* * Rely on runtime-PM to call resume in case it is enabled. * Even if it's not enabled, rely on 1st client transaction to do * clock/power on */ SLIM_INFO(cdev, "system resume\n"); return 0; } #endif /* CONFIG_PM_SLEEP */ Loading drivers/slimbus/slim-msm.c +10 −10 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ int msm_slim_get_ctrl(struct msm_slim_ctrl *dev) if (ret >= 0) { ref = atomic_read(&dev->dev->power.usage_count); if (ref <= 0) { dev_err(dev->dev, "reference count -ve:%d", ref); SLIM_WARN(dev, "reference count -ve:%d", ref); ret = -ENODEV; } } Loading @@ -67,7 +67,7 @@ void msm_slim_put_ctrl(struct msm_slim_ctrl *dev) pm_runtime_mark_last_busy(dev->dev); ref = atomic_read(&dev->dev->power.usage_count); if (ref <= 0) dev_err(dev->dev, "reference count mismatch:%d", ref); SLIM_WARN(dev, "reference count mismatch:%d", ref); else pm_runtime_put_sync(dev->dev); #endif Loading Loading @@ -109,7 +109,7 @@ irqreturn_t msm_slim_port_irq_handler(struct msm_slim_ctrl *dev, u32 pstat) /* clear port interrupts */ writel_relaxed(pstat, PGD_THIS_EE(PGD_PORT_INT_CL_EEn, dev->ver)); pr_info("disabled overflow/underflow for port 0x%x", pstat); SLIM_INFO(dev, "disabled overflow/underflow for port 0x%x", pstat); /* * Guarantee that port interrupt bit(s) clearing writes go Loading Loading @@ -1133,13 +1133,13 @@ static int msm_slim_qmi_send_select_inst_req(struct msm_slim_ctrl *dev, rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, req, sizeof(*req), &resp_desc, &resp, sizeof(resp), 5000); if (rc < 0) { pr_err("%s: QMI send req failed %d\n", __func__, rc); SLIM_ERR(dev, "%s: QMI send req failed %d\n", __func__, rc); return rc; } /* Check the response */ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { pr_err("%s: QMI request failed 0x%x (%s)\n", __func__, SLIM_ERR(dev, "%s: QMI request failed 0x%x (%s)\n", __func__, resp.resp.result, get_qmi_error(&resp.resp)); return -EREMOTEIO; } Loading @@ -1165,13 +1165,13 @@ static int msm_slim_qmi_send_power_request(struct msm_slim_ctrl *dev, rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, req, sizeof(*req), &resp_desc, &resp, sizeof(resp), 5000); if (rc < 0) { pr_err("%s: QMI send req failed %d\n", __func__, rc); SLIM_ERR(dev, "%s: QMI send req failed %d\n", __func__, rc); return rc; } /* Check the response */ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { pr_err("%s: QMI request failed 0x%x (%s)\n", __func__, SLIM_ERR(dev, "%s: QMI request failed 0x%x (%s)\n", __func__, resp.resp.result, get_qmi_error(&resp.resp)); return -EREMOTEIO; } Loading Loading @@ -1208,7 +1208,7 @@ int msm_slim_qmi_init(struct msm_slim_ctrl *dev, bool apps_is_master) SLIMBUS_QMI_SVC_V1, SLIMBUS_QMI_INS_ID); if (rc < 0) { pr_err("%s: QMI server not found\n", __func__); SLIM_ERR(dev, "%s: QMI server not found\n", __func__); goto qmi_connect_to_service_failed; } Loading Loading @@ -1281,12 +1281,12 @@ int msm_slim_qmi_check_framer_request(struct msm_slim_ctrl *dev) rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, NULL, 0, &resp_desc, &resp, sizeof(resp), 5000); if (rc < 0) { dev_err(dev->dev, "%s: QMI send req failed %d\n", __func__, rc); SLIM_ERR(dev, "%s: QMI send req failed %d\n", __func__, rc); return rc; } /* Check the response */ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { dev_err(dev->dev, "%s: QMI request failed 0x%x (%s)\n", SLIM_ERR(dev, "%s: QMI request failed 0x%x (%s)\n", __func__, resp.resp.result, get_qmi_error(&resp.resp)); return -EREMOTEIO; } Loading drivers/slimbus/slim-msm.h +56 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/kthread.h> #include <soc/qcom/msm_qmi_interface.h> #include <soc/qcom/subsystem_notif.h> #include <linux/ipc_logging.h> /* Per spec.max 40 bytes per received message */ #define SLIM_MSGQ_BUF_LEN 40 Loading Loading @@ -267,6 +268,10 @@ struct msm_slim_ctrl { struct msm_slim_qmi qmi; struct msm_slim_pdata pdata; struct msm_slim_mdm mdm; int default_ipc_log_mask; int ipc_log_mask; bool sysfs_created; void *ipc_slimbus_log; }; struct msm_sat_chan { Loading Loading @@ -300,6 +305,57 @@ enum rsc_grp { }; /* IPC logging stuff */ #define IPC_SLIMBUS_LOG_PAGES 5 /* Log levels */ enum { FATAL_LEV = 0U, ERR_LEV = 1U, WARN_LEV = 2U, INFO_LEV = 3U, DBG_LEV = 4U, }; /* Default IPC log level INFO */ #define SLIM_DBG(dev, x...) do { \ pr_debug(x); \ if (dev->ipc_slimbus_log && dev->ipc_log_mask >= DBG_LEV) { \ ipc_log_string(dev->ipc_slimbus_log, x); \ } \ } while (0) #define SLIM_INFO(dev, x...) do { \ pr_debug(x); \ if (dev->ipc_slimbus_log && dev->ipc_log_mask >= INFO_LEV) {\ ipc_log_string(dev->ipc_slimbus_log, x); \ } \ } while (0) /* warnings and errors show up on console always */ #define SLIM_WARN(dev, x...) do { \ pr_warn(x); \ if (dev->ipc_slimbus_log && dev->ipc_log_mask >= WARN_LEV) \ ipc_log_string(dev->ipc_slimbus_log, x); \ } while (0) /* ERROR condition in the driver sets the hs_serial_debug_mask * to ERR_FATAL level, so that this message can be seen * in IPC logging. Further errors continue to log on the console */ #define SLIM_ERR(dev, x...) do { \ pr_err(x); \ if (dev->ipc_slimbus_log && dev->ipc_log_mask >= ERR_LEV) { \ ipc_log_string(dev->ipc_slimbus_log, x); \ dev->default_ipc_log_mask = dev->ipc_log_mask; \ dev->ipc_log_mask = FATAL_LEV; \ } \ } while (0) #define SLIM_RST_LOGLVL(dev) { \ dev->ipc_log_mask = dev->default_ipc_log_mask; \ } int msm_slim_rx_enqueue(struct msm_slim_ctrl *dev, u32 *buf, u8 len); int msm_slim_rx_dequeue(struct msm_slim_ctrl *dev, u8 *buf); int msm_slim_get_ctrl(struct msm_slim_ctrl *dev); Loading Loading
drivers/slimbus/slim-msm-ngd.c +135 −58 Original line number Diff line number Diff line Loading @@ -97,7 +97,7 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) writel_relaxed(stat, ngd + NGD_INT_CLR); dev->err = -EIO; dev_err(dev->dev, "NGD interrupt error:0x%x, err:%d", stat, SLIM_WARN(dev, "NGD interrupt error:0x%x, err:%d\n", stat, dev->err); /* Guarantee that error interrupts are cleared */ mb(); Loading @@ -119,7 +119,7 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) for (i = 1; i < ((len + 3) >> 2); i++) { rx_buf[i] = readl_relaxed(ngd + NGD_RX_MSG + (4 * i)); dev_dbg(dev->dev, "REG-RX data: %x\n", rx_buf[i]); SLIM_DBG(dev, "REG-RX data: %x\n", rx_buf[i]); } msm_slim_rx_enqueue(dev, rx_buf, len); writel_relaxed(NGD_INT_RX_MSG_RCVD, Loading @@ -130,8 +130,7 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) */ mb(); if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) dev_err(dev->dev, "direct message received even with RX MSGQs"); SLIM_WARN(dev, "direct msg rcvd with RX MSGQs\n"); else complete(&dev->rx_msgq_notify); } Loading @@ -140,13 +139,13 @@ static irqreturn_t ngd_slim_interrupt(int irq, void *d) /* Guarantee RECONFIG DONE interrupt is cleared */ mb(); /* In satellite mode, just log the reconfig done IRQ */ dev_dbg(dev->dev, "reconfig done IRQ for NGD"); SLIM_DBG(dev, "reconfig done IRQ for NGD\n"); } if (stat & NGD_INT_IE_VE_CHG) { writel_relaxed(NGD_INT_IE_VE_CHG, ngd + NGD_INT_CLR); /* Guarantee IE VE change interrupt is cleared */ mb(); dev_err(dev->dev, "NGD IE VE change"); SLIM_DBG(dev, "NGD IE VE change\n"); } pstat = readl_relaxed(PGD_THIS_EE(PGD_PORT_INT_ST_EEn, dev->ver)); Loading @@ -161,7 +160,7 @@ static int ngd_qmi_available(struct notifier_block *n, unsigned long code, struct msm_slim_qmi *qmi = container_of(n, struct msm_slim_qmi, nb); struct msm_slim_ctrl *dev = container_of(qmi, struct msm_slim_ctrl, qmi); pr_info("Slimbus QMI NGD CB received event:%ld", code); SLIM_INFO(dev, "Slimbus QMI NGD CB received event:%ld\n", code); switch (code) { case QMI_SERVER_ARRIVE: schedule_work(&qmi->ssr_up); Loading Loading @@ -193,8 +192,7 @@ static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code, switch (code) { case SUBSYS_BEFORE_SHUTDOWN: dev_err(dev->dev, "SLIM %lu external_modem SSR notify cb", code); SLIM_INFO(dev, "SLIM %lu external_modem SSR notify cb\n", code); /* vote for runtime-pm so that ADSP doesn't go down */ msm_slim_get_ctrl(dev); /* Loading @@ -208,8 +206,8 @@ static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code, case SUBSYS_AFTER_POWERUP: if (dev->mdm.state != MSM_CTRL_DOWN) return NOTIFY_DONE; dev_err(dev->dev, "SLIM %lu external_modem SSR notify cb", code); SLIM_INFO(dev, "SLIM %lu external_modem SSR notify cb\n", code); /* vote for runtime-pm so that ADSP doesn't go down */ msm_slim_get_ctrl(dev); msm_slim_qmi_check_framer_request(dev); Loading @@ -221,7 +219,8 @@ static int mdm_ssr_notify_cb(struct notifier_block *n, unsigned long code, pm_runtime_disable(dev->dev); pm_runtime_set_suspended(dev->dev); dev->state = MSM_CTRL_DOWN; pr_err("SLIM MDM SSR (active framer on MDM) dev-down"); SLIM_INFO(dev, "SLIM MDM SSR (active framer on MDM) dev-down\n"); list_for_each_entry(sbdev, &ctrl->devs, dev_list) slim_report_absent(sbdev); ngd_slim_power_up(dev, true); Loading Loading @@ -324,7 +323,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) if (dev->state == MSM_CTRL_DOWN) { u8 mc = (u8)txn->mc; int timeout; dev_err(dev->dev, "ADSP slimbus not up yet"); SLIM_INFO(dev, "ADSP slimbus not up yet\n"); /* * Messages related to data channel management can't * wait since they are holding reconfiguration lock. Loading Loading @@ -384,7 +383,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) mutex_lock(&dev->tx_lock); if (report_sat == false && dev->state != MSM_CTRL_AWAKE) { dev_err(dev->dev, "controller not ready"); SLIM_ERR(dev, "controller not ready\n"); mutex_unlock(&dev->tx_lock); msm_slim_put_ctrl(dev); return -EREMOTEIO; Loading @@ -394,6 +393,14 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) txn->mc == SLIM_MSG_MC_CONNECT_SINK || txn->mc == SLIM_MSG_MC_DISCONNECT_PORT)) { int i = 0; if (txn->mc != SLIM_MSG_MC_DISCONNECT_PORT) SLIM_INFO(dev, "Connect port: laddr 0x%x port_num %d chan_num %d\n", txn->la, txn->wbuf[0], txn->wbuf[1]); else SLIM_INFO(dev, "Disconnect port: laddr 0x%x port_num %d\n", txn->la, txn->wbuf[0]); txn->mt = SLIM_MSG_MT_DEST_REFERRED_USER; if (txn->mc == SLIM_MSG_MC_CONNECT_SOURCE) txn->mc = SLIM_USR_MC_CONNECT_SRC; Loading @@ -410,10 +417,11 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) mutex_unlock(&dev->tx_lock); ret = dev->ctrl.get_laddr(&dev->ctrl, ea, 6, &dev->pgdla); pr_debug("SLIM PGD LA:0x%x, ret:%d", dev->pgdla, ret); SLIM_DBG(dev, "SLIM PGD LA:0x%x, ret:%d\n", dev->pgdla, ret); if (ret) { pr_err("Incorrect SLIM-PGD EAPC:0x%x", SLIM_ERR(dev, "Incorrect SLIM-PGD EAPC:0x%x\n", dev->pdata.eapc); return ret; } Loading @@ -428,7 +436,8 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) wbuf[i++] = txn->wbuf[1]; ret = ngd_get_tid(ctrl, txn, &wbuf[i++], &done); if (ret) { pr_err("TID for connect/disconnect fail:%d", ret); SLIM_ERR(dev, "TID for connect/disconnect fail:%d\n", ret); goto ngd_xfer_err; } txn->len = i; Loading @@ -438,7 +447,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) txn->rl--; pbuf = msm_get_msg_buf(dev, txn->rl); if (!pbuf) { dev_err(dev->dev, "Message buffer unavailable"); SLIM_ERR(dev, "Message buffer unavailable\n"); ret = -ENOMEM; goto ngd_xfer_err; } Loading Loading @@ -492,7 +501,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) return 0; } if (dev->err) { dev_err(dev->dev, "pipe-port connect err:%d", dev->err); SLIM_ERR(dev, "pipe-port connect err:%d\n", dev->err); goto ngd_xfer_err; } /* Add port-base to port number if this is manager side port */ Loading Loading @@ -531,7 +540,7 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) u32 conf, stat, rx_msgq, int_stat, int_en, int_clr; void __iomem *ngd = dev->base + NGD_BASE(dev->ctrl.nr, dev->ver); dev_err(dev->dev, "TX failed :MC:0x%x,mt:0x%x, ret:%d, ver:%d", SLIM_WARN(dev, "TX failed :MC:0x%x,mt:0x%x, ret:%d, ver:%d\n", txn_mc, txn_mt, ret, dev->ver); conf = readl_relaxed(ngd); stat = readl_relaxed(ngd + NGD_STATUS); Loading @@ -540,9 +549,10 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) int_en = readl_relaxed(ngd + NGD_INT_EN); int_clr = readl_relaxed(ngd + NGD_INT_CLR); pr_err("conf:0x%x,stat:0x%x,rxmsgq:0x%x", conf, stat, rx_msgq); pr_err("int_stat:0x%x,int_en:0x%x,int_cll:0x%x", int_stat, int_en, int_clr); SLIM_WARN(dev, "conf:0x%x,stat:0x%x,rxmsgq:0x%x\n", conf, stat, rx_msgq); SLIM_WARN(dev, "int_stat:0x%x,int_en:0x%x,int_cll:0x%x\n", int_stat, int_en, int_clr); } else if (txn_mt == SLIM_MSG_MT_DEST_REFERRED_USER && (txn_mc == SLIM_USR_MC_CONNECT_SRC || txn_mc == SLIM_USR_MC_CONNECT_SINK || Loading @@ -556,8 +566,9 @@ static int ngd_xfer_msg(struct slim_controller *ctrl, struct slim_msg_txn *txn) else ret = txn->ec; if (ret) { pr_err("connect/disconnect:0x%x,tid:%d err:%d", txn->mc, txn->tid, ret); SLIM_INFO(dev, "connect/disconnect:0x%x,tid:%d err:%d\n", txn->mc, txn->tid, ret); mutex_lock(&ctrl->m_ctrl); ctrl->txnt[txn->tid] = NULL; mutex_unlock(&ctrl->m_ctrl); Loading Loading @@ -612,6 +623,7 @@ static int ngd_user_msg(struct slim_controller *ctrl, u8 la, u8 mt, u8 mc, static int ngd_xferandwait_ack(struct slim_controller *ctrl, struct slim_msg_txn *txn) { struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl); int ret = ngd_xfer_msg(ctrl, txn); if (!ret) { int timeout; Loading @@ -624,8 +636,8 @@ static int ngd_xferandwait_ack(struct slim_controller *ctrl, if (ret) { if (ret != -EREMOTEIO || txn->mc != SLIM_USR_MC_CHAN_CTRL) pr_err("master msg:0x%x,tid:%d ret:%d", txn->mc, txn->tid, ret); SLIM_ERR(dev, "master msg:0x%x,tid:%d ret:%d\n", txn->mc, txn->tid, ret); mutex_lock(&ctrl->m_ctrl); ctrl->txnt[txn->tid] = NULL; mutex_unlock(&ctrl->m_ctrl); Loading @@ -636,12 +648,13 @@ static int ngd_xferandwait_ack(struct slim_controller *ctrl, static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) { int ret; int ret = 0, num_chan = 0; struct slim_pending_ch *pch; struct slim_msg_txn txn; struct slim_controller *ctrl = sb->ctrl; DECLARE_COMPLETION_ONSTACK(done); u8 wbuf[SLIM_MSGQ_BUF_LEN]; struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl); *clkgear = ctrl->clkgear; *subfrmc = 0; Loading @@ -654,7 +667,7 @@ static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) txn.rbuf = NULL; if (ctrl->sched.msgsl != ctrl->sched.pending_msgsl) { pr_debug("slim reserve BW for messaging: req: %d", SLIM_DBG(dev, "slim reserve BW for messaging: req: %d\n", ctrl->sched.pending_msgsl); txn.mc = SLIM_USR_MC_REQ_BW; wbuf[txn.len++] = ((sb->laddr & 0x1f) | Loading Loading @@ -685,7 +698,7 @@ static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) struct slim_ich *slc; slc = &ctrl->chans[pch->chan]; if (!slc) { pr_err("no channel in define?"); SLIM_WARN(dev, "no channel in define?\n"); return -ENXIO; } if (txn.len == 0) { Loading @@ -700,12 +713,14 @@ static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) wbuf[txn.len++] = slc->prrate; ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done); if (ret) { pr_err("no tid for channel define?"); SLIM_WARN(dev, "no tid for channel define?\n"); return -ENXIO; } } num_chan++; wbuf[txn.len++] = slc->chan; pr_debug("slim define chan:%d, tid:0x%x", slc->chan, txn.tid); SLIM_INFO(dev, "slim activate chan:%d, laddr: 0x%x\n", slc->chan, sb->laddr); } if (txn.len) { txn.mc = SLIM_USR_MC_DEF_ACT_CHAN; Loading @@ -730,7 +745,7 @@ static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) struct slim_ich *slc; slc = &ctrl->chans[pch->chan]; if (!slc) { pr_err("no channel in removal?"); SLIM_WARN(dev, "no channel in removal?\n"); return -ENXIO; } if (txn.len == 0) { Loading @@ -739,12 +754,13 @@ static int ngd_allocbw(struct slim_device *sb, int *subfrmc, int *clkgear) (sb->laddr & 0x1f); ret = ngd_get_tid(ctrl, &txn, &wbuf[txn.len++], &done); if (ret) { pr_err("no tid for channel define?"); SLIM_WARN(dev, "no tid for channel define?\n"); return -ENXIO; } } wbuf[txn.len++] = slc->chan; pr_debug("slim remove chan:%d, tid:0x%x", slc->chan, txn.tid); SLIM_INFO(dev, "slim remove chan:%d, laddr: 0x%x\n", slc->chan, sb->laddr); } if (txn.len) { txn.mc = SLIM_USR_MC_CHAN_CTRL; Loading Loading @@ -852,7 +868,7 @@ static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf) wbuf[3] = SAT_MSG_PROT; txn.wbuf = wbuf; txn.len = 4; pr_info("SLIM SAT: Received master capability"); SLIM_INFO(dev, "SLIM SAT: Rcvd master capability\n"); if (dev->state >= MSM_CTRL_ASLEEP) { ngd_slim_setup_msg_path(dev); if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) Loading @@ -869,18 +885,20 @@ capability_retry: ret = ngd_xfer_msg(&dev->ctrl, &txn); if (!ret) { enum msm_ctrl_state prev_state = dev->state; pr_info("SLIM SAT: capability exchange successful"); SLIM_INFO(dev, "SLIM SAT: capability exchange successful\n"); dev->state = MSM_CTRL_AWAKE; if (prev_state >= MSM_CTRL_ASLEEP) complete(&dev->reconf); else pr_err("SLIM: unexpected capability, state:%d", SLIM_ERR(dev, "SLIM: unexpected capability, state:%d\n", prev_state); /* ADSP SSR, send device_up notifications */ if (prev_state == MSM_CTRL_DOWN) complete(&dev->qmi.slave_notify); } else if (ret == -EIO) { pr_info("capability message NACKed, retrying"); SLIM_WARN(dev, "capability message NACKed, retrying\n"); if (retries < INIT_MX_RETRIES) { msleep(DEF_RETRY_MS); retries++; Loading @@ -903,7 +921,8 @@ capability_retry: mutex_lock(&dev->ctrl.m_ctrl); txn = dev->ctrl.txnt[buf[3]]; if (!txn) { pr_err("LADDR response after timeout, tid:0x%x", SLIM_WARN(dev, "LADDR response after timeout, tid:0x%x\n", buf[3]); mutex_unlock(&dev->ctrl.m_ctrl); return; Loading @@ -920,7 +939,7 @@ capability_retry: mutex_lock(&dev->ctrl.m_ctrl); txn = dev->ctrl.txnt[buf[3]]; if (!txn) { pr_err("ACK received after timeout, tid:0x%x", SLIM_WARN(dev, "ACK received after timeout, tid:0x%x\n", buf[3]); mutex_unlock(&dev->ctrl.m_ctrl); return; Loading @@ -928,7 +947,7 @@ capability_retry: dev_dbg(dev->dev, "got response:tid:%d, response:0x%x", (int)buf[3], buf[4]); if (!(buf[4] & MSM_SAT_SUCCSS)) { dev_err(dev->dev, "TID:%d, NACK code:0x%x", (int)buf[3], SLIM_WARN(dev, "TID:%d, NACK code:0x%x\n", (int)buf[3], buf[4]); txn->ec = -EIO; } Loading @@ -953,7 +972,7 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart) int timeout = wait_for_completion_timeout(&dev->qmi.qmi_comp, HZ); if (!timeout) pr_err("slimbus QMI init timed out"); SLIM_ERR(dev, "slimbus QMI init timed out\n"); } /* No need to vote if contorller is not in low power mode */ Loading @@ -961,7 +980,8 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart) (cur_state == MSM_CTRL_DOWN || cur_state == MSM_CTRL_ASLEEP)) { ret = msm_slim_qmi_power_request(dev, true); if (ret) { pr_err("SLIM QMI power request failed:%d", ret); SLIM_ERR(dev, "SLIM QMI power request failed:%d\n", ret); return ret; } } Loading @@ -978,7 +998,7 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart) * For example, modem restarted when playback was active */ if (cur_state == MSM_CTRL_AWAKE) { pr_err("Subsys restart: ADSP active framer"); SLIM_INFO(dev, "Subsys restart: ADSP active framer\n"); return 0; } /* Loading @@ -998,7 +1018,8 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart) */ /* make current state as DOWN */ cur_state = MSM_CTRL_DOWN; pr_err("SLIM MDM restart: MDM active framer: reinit HW"); SLIM_INFO(dev, "SLIM MDM restart: MDM active framer: reinit HW\n"); /* disconnect BAM pipes */ if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) dev->use_rx_msgqs = MSM_MSGQ_DOWN; Loading Loading @@ -1035,11 +1056,14 @@ static int ngd_slim_power_up(struct msm_slim_ctrl *dev, bool mdm_restart) timeout = wait_for_completion_timeout(&dev->reconf, HZ); if (!timeout) { pr_err("Failed to receive master capability"); SLIM_ERR(dev, "Failed to receive master capability\n"); return -ETIMEDOUT; } if (cur_state == MSM_CTRL_DOWN) if (cur_state == MSM_CTRL_DOWN) { complete(&dev->ctrl_up); /* Resetting the log level */ SLIM_RST_LOGLVL(dev); } return 0; } Loading Loading @@ -1072,7 +1096,7 @@ static int ngd_slim_enable(struct msm_slim_ctrl *dev, bool enable) pm_runtime_mark_last_busy(dev->dev); pm_runtime_put(dev->dev); } else dev_err(dev->dev, "qmi init fail, ret:%d, state:%d", SLIM_ERR(dev, "qmi init fail, ret:%d, state:%d\n", ret, dev->state); } else { msm_slim_qmi_exit(dev); Loading Loading @@ -1108,7 +1132,7 @@ static int ngd_slim_rx_msgq_thread(void *data) } ret = msm_slim_rx_msgq_get(dev, buffer, index); if (ret) { dev_err(dev->dev, "rx_msgq_get() failed 0x%x\n", ret); SLIM_ERR(dev, "rx_msgq_get() failed 0x%x\n", ret); continue; } Loading Loading @@ -1193,7 +1217,7 @@ static void ngd_adsp_down(struct work_struct *work) /* device up should be called again after SSR */ list_for_each_entry(sbdev, &ctrl->devs, dev_list) slim_report_absent(sbdev); pr_info("SLIM ADSP SSR (DOWN) done"); SLIM_INFO(dev, "SLIM ADSP SSR (DOWN) done\n"); } static void ngd_adsp_up(struct work_struct *work) Loading @@ -1205,6 +1229,28 @@ static void ngd_adsp_up(struct work_struct *work) ngd_slim_enable(dev, true); } static ssize_t show_mask(struct device *device, struct device_attribute *attr, char *buf) { struct platform_device *pdev = to_platform_device(device); struct msm_slim_ctrl *dev = platform_get_drvdata(pdev); return snprintf(buf, sizeof(int), "%u\n", dev->ipc_log_mask); } static ssize_t set_mask(struct device *device, struct device_attribute *attr, const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(device); struct msm_slim_ctrl *dev = platform_get_drvdata(pdev); dev->ipc_log_mask = buf[0] - '0'; if (dev->ipc_log_mask > DBG_LEV) dev->ipc_log_mask = DBG_LEV; return count; } static DEVICE_ATTR(debug_mask, S_IRUGO | S_IWUSR, show_mask, set_mask); static int ngd_slim_probe(struct platform_device *pdev) { struct msm_slim_ctrl *dev; Loading Loading @@ -1249,6 +1295,26 @@ static int ngd_slim_probe(struct platform_device *pdev) dev->dev = &pdev->dev; platform_set_drvdata(pdev, dev); slim_set_ctrldata(&dev->ctrl, dev); /* Create IPC log context */ dev->ipc_slimbus_log = ipc_log_context_create(IPC_SLIMBUS_LOG_PAGES, dev_name(dev->dev)); if (!dev->ipc_slimbus_log) dev_err(&pdev->dev, "error creating ipc_logging context\n"); else { /* Initialize the log mask */ dev->ipc_log_mask = INFO_LEV; dev->default_ipc_log_mask = INFO_LEV; SLIM_INFO(dev, "start logging for slim dev %s\n", dev_name(dev->dev)); } ret = sysfs_create_file(&dev->dev->kobj, &dev_attr_debug_mask.attr); if (ret) { dev_err(&pdev->dev, "Failed to create dev. attr\n"); dev->sysfs_created = false; } else dev->sysfs_created = true; dev->base = ioremap(slim_mem->start, resource_size(slim_mem)); if (!dev->base) { dev_err(&pdev->dev, "IOremap failed\n"); Loading Loading @@ -1391,7 +1457,7 @@ static int ngd_slim_probe(struct platform_device *pdev) dev_err(dev->dev, "Failed to start notifier thread:%d\n", ret); goto err_notify_thread_create_failed; } dev_dbg(dev->dev, "NGD SB controller is up!\n"); SLIM_INFO(dev, "NGD SB controller is up!\n"); return 0; err_notify_thread_create_failed: Loading @@ -1409,6 +1475,9 @@ err_ctrl_failed: err_ioremap_bam_failed: iounmap(dev->base); err_ioremap_failed: if (dev->sysfs_created) sysfs_remove_file(&dev->dev->kobj, &dev_attr_debug_mask.attr); kfree(dev); return ret; } Loading @@ -1417,6 +1486,9 @@ static int ngd_slim_remove(struct platform_device *pdev) { struct msm_slim_ctrl *dev = platform_get_drvdata(pdev); ngd_slim_enable(dev, false); if (dev->sysfs_created) sysfs_remove_file(&dev->dev->kobj, &dev_attr_debug_mask.attr); qmi_svc_event_notifier_unregister(SLIMBUS_QMI_SVC_ID, SLIMBUS_QMI_SVC_V1, SLIMBUS_QMI_INS_ID, &dev->qmi.nb); Loading Loading @@ -1462,10 +1534,11 @@ static int ngd_slim_runtime_resume(struct device *device) if (dev->state != MSM_CTRL_DOWN) dev->state = MSM_CTRL_ASLEEP; else dev_err(device, "HW wakeup attempt during SSR"); SLIM_WARN(dev, "HW wakeup attempt during SSR\n"); } else { dev->state = MSM_CTRL_AWAKE; } SLIM_INFO(dev, "Slim runtime resume: ret %d\n", ret); return ret; } Loading @@ -1478,11 +1551,12 @@ static int ngd_slim_runtime_suspend(struct device *device) ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED); if (ret) { if (ret != -EBUSY) dev_err(device, "clk pause not entered:%d", ret); SLIM_INFO(dev, "clk pause not entered:%d\n", ret); dev->state = MSM_CTRL_AWAKE; } else { dev->state = MSM_CTRL_ASLEEP; } SLIM_INFO(dev, "Slim runtime suspend: ret %d\n", ret); return ret; } Loading @@ -1494,7 +1568,6 @@ static int ngd_slim_suspend(struct device *dev) if (!pm_runtime_enabled(dev) || (!pm_runtime_suspended(dev) && cdev->state == MSM_CTRL_IDLE)) { dev_dbg(dev, "system suspend"); ret = ngd_slim_runtime_suspend(dev); /* * If runtime-PM still thinks it's active, then make sure its Loading @@ -1521,16 +1594,20 @@ static int ngd_slim_suspend(struct device *dev) */ ret = 0; } SLIM_INFO(cdev, "system suspend\n"); return ret; } static int ngd_slim_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct msm_slim_ctrl *cdev = platform_get_drvdata(pdev); /* * Rely on runtime-PM to call resume in case it is enabled. * Even if it's not enabled, rely on 1st client transaction to do * clock/power on */ SLIM_INFO(cdev, "system resume\n"); return 0; } #endif /* CONFIG_PM_SLEEP */ Loading
drivers/slimbus/slim-msm.c +10 −10 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ int msm_slim_get_ctrl(struct msm_slim_ctrl *dev) if (ret >= 0) { ref = atomic_read(&dev->dev->power.usage_count); if (ref <= 0) { dev_err(dev->dev, "reference count -ve:%d", ref); SLIM_WARN(dev, "reference count -ve:%d", ref); ret = -ENODEV; } } Loading @@ -67,7 +67,7 @@ void msm_slim_put_ctrl(struct msm_slim_ctrl *dev) pm_runtime_mark_last_busy(dev->dev); ref = atomic_read(&dev->dev->power.usage_count); if (ref <= 0) dev_err(dev->dev, "reference count mismatch:%d", ref); SLIM_WARN(dev, "reference count mismatch:%d", ref); else pm_runtime_put_sync(dev->dev); #endif Loading Loading @@ -109,7 +109,7 @@ irqreturn_t msm_slim_port_irq_handler(struct msm_slim_ctrl *dev, u32 pstat) /* clear port interrupts */ writel_relaxed(pstat, PGD_THIS_EE(PGD_PORT_INT_CL_EEn, dev->ver)); pr_info("disabled overflow/underflow for port 0x%x", pstat); SLIM_INFO(dev, "disabled overflow/underflow for port 0x%x", pstat); /* * Guarantee that port interrupt bit(s) clearing writes go Loading Loading @@ -1133,13 +1133,13 @@ static int msm_slim_qmi_send_select_inst_req(struct msm_slim_ctrl *dev, rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, req, sizeof(*req), &resp_desc, &resp, sizeof(resp), 5000); if (rc < 0) { pr_err("%s: QMI send req failed %d\n", __func__, rc); SLIM_ERR(dev, "%s: QMI send req failed %d\n", __func__, rc); return rc; } /* Check the response */ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { pr_err("%s: QMI request failed 0x%x (%s)\n", __func__, SLIM_ERR(dev, "%s: QMI request failed 0x%x (%s)\n", __func__, resp.resp.result, get_qmi_error(&resp.resp)); return -EREMOTEIO; } Loading @@ -1165,13 +1165,13 @@ static int msm_slim_qmi_send_power_request(struct msm_slim_ctrl *dev, rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, req, sizeof(*req), &resp_desc, &resp, sizeof(resp), 5000); if (rc < 0) { pr_err("%s: QMI send req failed %d\n", __func__, rc); SLIM_ERR(dev, "%s: QMI send req failed %d\n", __func__, rc); return rc; } /* Check the response */ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { pr_err("%s: QMI request failed 0x%x (%s)\n", __func__, SLIM_ERR(dev, "%s: QMI request failed 0x%x (%s)\n", __func__, resp.resp.result, get_qmi_error(&resp.resp)); return -EREMOTEIO; } Loading Loading @@ -1208,7 +1208,7 @@ int msm_slim_qmi_init(struct msm_slim_ctrl *dev, bool apps_is_master) SLIMBUS_QMI_SVC_V1, SLIMBUS_QMI_INS_ID); if (rc < 0) { pr_err("%s: QMI server not found\n", __func__); SLIM_ERR(dev, "%s: QMI server not found\n", __func__); goto qmi_connect_to_service_failed; } Loading Loading @@ -1281,12 +1281,12 @@ int msm_slim_qmi_check_framer_request(struct msm_slim_ctrl *dev) rc = qmi_send_req_wait(dev->qmi.handle, &req_desc, NULL, 0, &resp_desc, &resp, sizeof(resp), 5000); if (rc < 0) { dev_err(dev->dev, "%s: QMI send req failed %d\n", __func__, rc); SLIM_ERR(dev, "%s: QMI send req failed %d\n", __func__, rc); return rc; } /* Check the response */ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { dev_err(dev->dev, "%s: QMI request failed 0x%x (%s)\n", SLIM_ERR(dev, "%s: QMI request failed 0x%x (%s)\n", __func__, resp.resp.result, get_qmi_error(&resp.resp)); return -EREMOTEIO; } Loading
drivers/slimbus/slim-msm.h +56 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include <linux/kthread.h> #include <soc/qcom/msm_qmi_interface.h> #include <soc/qcom/subsystem_notif.h> #include <linux/ipc_logging.h> /* Per spec.max 40 bytes per received message */ #define SLIM_MSGQ_BUF_LEN 40 Loading Loading @@ -267,6 +268,10 @@ struct msm_slim_ctrl { struct msm_slim_qmi qmi; struct msm_slim_pdata pdata; struct msm_slim_mdm mdm; int default_ipc_log_mask; int ipc_log_mask; bool sysfs_created; void *ipc_slimbus_log; }; struct msm_sat_chan { Loading Loading @@ -300,6 +305,57 @@ enum rsc_grp { }; /* IPC logging stuff */ #define IPC_SLIMBUS_LOG_PAGES 5 /* Log levels */ enum { FATAL_LEV = 0U, ERR_LEV = 1U, WARN_LEV = 2U, INFO_LEV = 3U, DBG_LEV = 4U, }; /* Default IPC log level INFO */ #define SLIM_DBG(dev, x...) do { \ pr_debug(x); \ if (dev->ipc_slimbus_log && dev->ipc_log_mask >= DBG_LEV) { \ ipc_log_string(dev->ipc_slimbus_log, x); \ } \ } while (0) #define SLIM_INFO(dev, x...) do { \ pr_debug(x); \ if (dev->ipc_slimbus_log && dev->ipc_log_mask >= INFO_LEV) {\ ipc_log_string(dev->ipc_slimbus_log, x); \ } \ } while (0) /* warnings and errors show up on console always */ #define SLIM_WARN(dev, x...) do { \ pr_warn(x); \ if (dev->ipc_slimbus_log && dev->ipc_log_mask >= WARN_LEV) \ ipc_log_string(dev->ipc_slimbus_log, x); \ } while (0) /* ERROR condition in the driver sets the hs_serial_debug_mask * to ERR_FATAL level, so that this message can be seen * in IPC logging. Further errors continue to log on the console */ #define SLIM_ERR(dev, x...) do { \ pr_err(x); \ if (dev->ipc_slimbus_log && dev->ipc_log_mask >= ERR_LEV) { \ ipc_log_string(dev->ipc_slimbus_log, x); \ dev->default_ipc_log_mask = dev->ipc_log_mask; \ dev->ipc_log_mask = FATAL_LEV; \ } \ } while (0) #define SLIM_RST_LOGLVL(dev) { \ dev->ipc_log_mask = dev->default_ipc_log_mask; \ } int msm_slim_rx_enqueue(struct msm_slim_ctrl *dev, u32 *buf, u8 len); int msm_slim_rx_dequeue(struct msm_slim_ctrl *dev, u8 *buf); int msm_slim_get_ctrl(struct msm_slim_ctrl *dev); Loading