Loading drivers/bus/mhi/core/mhi_init.c +13 −0 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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"); Loading @@ -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; Loading drivers/bus/mhi/core/mhi_internal.h +4 −0 Original line number Diff line number Diff line Loading @@ -706,6 +706,9 @@ struct mhi_chan { struct completion completion; rwlock_t lock; struct list_head node; /* stats */ u64 mode_change; }; struct tsync_node { Loading Loading @@ -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); Loading drivers/bus/mhi/core/mhi_main.c +70 −15 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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 Loading @@ -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; Loading Loading @@ -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; } Loading Loading
drivers/bus/mhi/core/mhi_init.c +13 −0 Original line number Diff line number Diff line Loading @@ -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, Loading @@ -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"); Loading @@ -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; Loading
drivers/bus/mhi/core/mhi_internal.h +4 −0 Original line number Diff line number Diff line Loading @@ -706,6 +706,9 @@ struct mhi_chan { struct completion completion; rwlock_t lock; struct list_head node; /* stats */ u64 mode_change; }; struct tsync_node { Loading Loading @@ -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); Loading
drivers/bus/mhi/core/mhi_main.c +70 −15 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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 Loading @@ -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; Loading Loading @@ -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; } Loading