Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b970f20d authored by Kiran Gunda's avatar Kiran Gunda
Browse files

slim_msm_ngd: Add IPC logging support



Add IPC logging support for improved debugging
per device, and in memory to avoid using kernel
dmesg logs.

Logs are captured in four levels.
1) error level ---> All fatal errors are logged
2) warn level  ---> error level logs +
Warning messages are logged
3) Info level  ---> Error level +
warn level + the required information
for debugging is logged
4) Debug level ----> error level + warn level +
info level logs + extra information
for debugging are logged

Procedure to change the debug level at runtime:
==============================================
cd sys/devices/ctrl_num(eg:1234).slim
echo <log_level> > debug_mask

Procedure to collect the logs at run time:
=========================================
adb shell cat sys/kernel/debug/ipc_logging/ctrl_num.slim/log_cont
|tee slimbus.txt

CRs-Fixed: 645838
Change-Id: If183533472ee61b2d8cf458d228dd4ae2124dd37
Signed-off-by: default avatarKiran Gunda <kgunda@codeaurora.org>
parent bb27c068
Loading
Loading
Loading
Loading
+135 −58
Original line number Diff line number Diff line
@@ -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();
@@ -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,
@@ -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);
	}
@@ -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));
@@ -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);
@@ -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);
		/*
@@ -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);
@@ -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);
@@ -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.
@@ -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;
@@ -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;
@@ -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;
				}
@@ -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;
@@ -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;
	}
@@ -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 */
@@ -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);
@@ -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 ||
@@ -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);
@@ -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;
@@ -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);
@@ -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;
@@ -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) |
@@ -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) {
@@ -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;
@@ -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) {
@@ -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;
@@ -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)
@@ -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++;
@@ -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;
@@ -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;
@@ -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;
		}
@@ -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 */
@@ -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;
		}
	}
@@ -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;
		}
		/*
@@ -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;
@@ -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;
}

@@ -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);
@@ -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;
		}

@@ -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)
@@ -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;
@@ -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");
@@ -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:
@@ -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;
}
@@ -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);
@@ -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;
}

@@ -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;
}

@@ -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
@@ -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 */
+10 −10
Original line number Diff line number Diff line
@@ -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;
		}
	}
@@ -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
@@ -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
@@ -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;
	}
@@ -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;
	}
@@ -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;
	}

@@ -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;
	}
+56 −0
Original line number Diff line number Diff line
@@ -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
@@ -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 {
@@ -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);