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

Commit 43e8acfd authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "slim_msm_ngd: Add IPC logging support"

parents 7c77be90 b970f20d
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);