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

Commit 95c37f4c authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mhi: core: Add OOB and DB mode event IPC log and count"

parents 85a19b6d c8ee6b3e
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -352,6 +352,11 @@ static int mhi_init_debugfs_mhi_chan_open(struct inode *inode, struct file *fp)
	return single_open(fp, mhi_debugfs_mhi_chan_show, inode->i_private);
}

static int mhi_init_debugfs_mhi_vote_open(struct inode *inode, struct file *fp)
{
	return single_open(fp, mhi_debugfs_mhi_vote_show, inode->i_private);
}

static const struct file_operations debugfs_state_ops = {
	.open = mhi_init_debugfs_mhi_states_open,
	.release = single_release,
@@ -370,6 +375,12 @@ static const struct file_operations debugfs_chan_ops = {
	.read = seq_read,
};

static const struct file_operations debugfs_vote_ops = {
	.open = mhi_init_debugfs_mhi_vote_open,
	.release = single_release,
	.read = seq_read,
};

DEFINE_DEBUGFS_ATTRIBUTE(debugfs_trigger_reset_fops, NULL,
			 mhi_debugfs_trigger_reset, "%llu\n");

@@ -395,6 +406,8 @@ void mhi_init_debugfs(struct mhi_controller *mhi_cntrl)
				   &debugfs_ev_ops);
	debugfs_create_file_unsafe("chan", 0444, dentry, mhi_cntrl,
				   &debugfs_chan_ops);
	debugfs_create_file_unsafe("vote", 0444, dentry, mhi_cntrl,
				   &debugfs_vote_ops);
	debugfs_create_file_unsafe("reset", 0444, dentry, mhi_cntrl,
				   &debugfs_trigger_reset_fops);
	mhi_cntrl->dentry = dentry;
+4 −0
Original line number Diff line number Diff line
@@ -706,6 +706,9 @@ struct mhi_chan {
	struct completion completion;
	rwlock_t lock;
	struct list_head node;

	/* stats */
	u64 mode_change;
};

struct tsync_node {
@@ -749,6 +752,7 @@ extern struct mhi_bus mhi_bus;
struct mhi_controller *find_mhi_controller_by_name(const char *name);

/* debug fs related functions */
int mhi_debugfs_mhi_vote_show(struct seq_file *m, void *d);
int mhi_debugfs_mhi_chan_show(struct seq_file *m, void *d);
int mhi_debugfs_mhi_event_show(struct seq_file *m, void *d);
int mhi_debugfs_mhi_states_show(struct seq_file *m, void *d);
+70 −15
Original line number Diff line number Diff line
@@ -560,9 +560,9 @@ int mhi_queue_dma(struct mhi_device *mhi_dev,
		mhi_tre->dword[1] = MHI_TRE_DATA_DWORD1(mhi_chan->bei, 1, 0, 0);
	}

	MHI_VERB("chan:%d WP:0x%llx TRE:0x%llx 0x%08x 0x%08x\n", mhi_chan->chan,
		 (u64)mhi_to_physical(tre_ring, mhi_tre), mhi_tre->ptr,
		 mhi_tre->dword[0], mhi_tre->dword[1]);
	MHI_VERB("chan:%d WP:0x%llx TRE:0x%llx 0x%08x 0x%08x rDB %d\n",
		mhi_chan->chan, (u64)mhi_to_physical(tre_ring, mhi_tre),
		mhi_tre->ptr, mhi_tre->dword[0], mhi_tre->dword[1], ring_db);

	/* increment WP */
	mhi_add_ring_element(mhi_cntrl, tre_ring);
@@ -990,6 +990,7 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
	unsigned long flags = 0;
	bool ring_db = true;
	int n_free_tre, n_queued_tre;
	unsigned long rflags;

	ev_code = MHI_TRE_GET_EV_CODE(event);
	buf_ring = &mhi_chan->buf_ring;
@@ -1079,12 +1080,8 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
		break;
	} /* CC_EOT */
	case MHI_EV_CC_OOB:
	case MHI_EV_CC_DB_MODE:
	{
		unsigned long flags;

		MHI_VERB("DB_MODE/OOB Detected chan %d.\n", mhi_chan->chan);
		mhi_chan->db_cfg.db_mode = true;
		mhi_chan->mode_change++;

		/*
		 * on RSC channel IPA HW has a minimum credit requirement before
@@ -1098,14 +1095,27 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl,
				ring_db = false;
		}

		read_lock_irqsave(&mhi_cntrl->pm_lock, flags);
		MHI_VERB("OOB_MODE chan %d ring_db %d\n", mhi_chan->chan,
			ring_db);

		read_lock_irqsave(&mhi_cntrl->pm_lock, rflags);
		if (tre_ring->wp != tre_ring->rp &&
		    MHI_DB_ACCESS_VALID(mhi_cntrl) && ring_db) {
		    MHI_DB_ACCESS_VALID(mhi_cntrl) && ring_db)
			mhi_ring_chan_db(mhi_cntrl, mhi_chan);
		}
		read_unlock_irqrestore(&mhi_cntrl->pm_lock, flags);
		read_unlock_irqrestore(&mhi_cntrl->pm_lock, rflags);
		break;
	case MHI_EV_CC_DB_MODE:
		MHI_VERB("DB_MODE chan %d.\n", mhi_chan->chan);
		mhi_chan->db_cfg.db_mode = true;
		mhi_chan->mode_change++;

		read_lock_irqsave(&mhi_cntrl->pm_lock, rflags);
		if (tre_ring->wp != tre_ring->rp &&
		    MHI_DB_ACCESS_VALID(mhi_cntrl))
			mhi_ring_chan_db(mhi_cntrl, mhi_chan);

		read_unlock_irqrestore(&mhi_cntrl->pm_lock, rflags);
		break;
	}
	case MHI_EV_CC_BAD_TRE:
		MHI_ASSERT(1, "Received BAD TRE event for ring");
		break;
@@ -2245,15 +2255,60 @@ int mhi_debugfs_mhi_chan_show(struct seq_file *m, void *d)
				   chan_ctxt->pollcfg, chan_ctxt->chtype,
				   chan_ctxt->erindex);
			seq_printf(m,
				   " base:0x%llx len:0x%llx wp:0x%llx local_rp:0x%llx local_wp:0x%llx db:0x%llx\n",
				   " base:0x%llx len:0x%llx wp:0x%llx local_rp:0x%llx local_wp:0x%llx db:0x%llx mode_change:0x%llx\n",
				   chan_ctxt->rbase, chan_ctxt->rlen,
				   chan_ctxt->wp,
				   mhi_to_physical(ring, ring->rp),
				   mhi_to_physical(ring, ring->wp),
				   mhi_chan->db_cfg.db_val);
				   mhi_chan->db_cfg.db_val,
				   mhi_chan->mode_change);
			mhi_chan->mode_change = 0;
		}
	}

	return 0;
}

/* show bus/device votes for a specific device */
int mhi_device_vote_show(struct device *dev, void *data)
{
	struct mhi_device *mhi_dev;
	struct mhi_controller *mhi_cntrl;

	if (dev->bus != &mhi_bus_type)
		return 0;

	mhi_dev = to_mhi_device(dev);
	mhi_cntrl = mhi_dev->mhi_cntrl;

	/* we dont care about timesync or similar special devices */
	if (mhi_dev->dev_type == MHI_TIMESYNC_TYPE)
		return 0;

	seq_printf((struct seq_file *)data, "%s: device:%u, bus:%u\n",
		   mhi_dev->chan_name, atomic_read(&mhi_dev->dev_vote),
		   atomic_read(&mhi_dev->bus_vote));

	return 0;
}

int mhi_debugfs_mhi_vote_show(struct seq_file *m, void *d)
{
	struct mhi_controller *mhi_cntrl = m->private;
	struct mhi_device *mhi_dev;

	if (!mhi_cntrl)
		return 0;

	mhi_dev = mhi_cntrl->mhi_dev;

	seq_printf(m, "At %llu ns:\n", sched_clock());
	seq_printf(m, "%s: device:%u, bus:%u\n", mhi_dev->chan_name,
		   atomic_read(&mhi_dev->dev_vote),
		   atomic_read(&mhi_dev->bus_vote));

	device_for_each_child(mhi_cntrl->dev, m, mhi_device_vote_show);

	return 0;
}