Loading drivers/bus/mhi/controllers/mhi_qcom.c +70 −39 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <asm/arch_timer.h> #include <linux/debugfs.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/dma-direction.h> #include <linux/list.h> Loading Loading @@ -33,6 +34,34 @@ static const struct firmware_info firmware_table[] = { static int debug_mode; module_param_named(debug_mode, debug_mode, int, 0644); int mhi_debugfs_trigger_m0(void *data, u64 val) { struct mhi_controller *mhi_cntrl = data; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); MHI_LOG("Trigger M3 Exit\n"); pm_runtime_get(&mhi_dev->pci_dev->dev); pm_runtime_put(&mhi_dev->pci_dev->dev); return 0; } DEFINE_SIMPLE_ATTRIBUTE(debugfs_trigger_m0_fops, NULL, mhi_debugfs_trigger_m0, "%llu\n"); int mhi_debugfs_trigger_m3(void *data, u64 val) { struct mhi_controller *mhi_cntrl = data; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); MHI_LOG("Trigger M3 Entry\n"); pm_runtime_mark_last_busy(&mhi_dev->pci_dev->dev); pm_request_autosuspend(&mhi_dev->pci_dev->dev); return 0; } DEFINE_SIMPLE_ATTRIBUTE(debugfs_trigger_m3_fops, NULL, mhi_debugfs_trigger_m3, "%llu\n"); void mhi_deinit_pci_dev(struct mhi_controller *mhi_cntrl) { struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); Loading Loading @@ -351,6 +380,45 @@ static int mhi_lpm_enable(struct mhi_controller *mhi_cntrl, void *priv) return ret; } static int mhi_qcom_power_up(struct mhi_controller *mhi_cntrl) { enum mhi_dev_state dev_state = mhi_get_mhi_state(mhi_cntrl); const u32 delayus = 10; int itr = DIV_ROUND_UP(mhi_cntrl->timeout_ms * 1000, delayus); int ret; /* * It's possible device did not go thru a cold reset before * power up and still in error state. If device in error state, * we need to trigger a soft reset before continue with power * up */ if (dev_state == MHI_STATE_SYS_ERR) { mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); while (itr--) { dev_state = mhi_get_mhi_state(mhi_cntrl); if (dev_state != MHI_STATE_SYS_ERR) break; usleep_range(delayus, delayus << 1); } /* device still in error state, abort power up */ if (dev_state == MHI_STATE_SYS_ERR) return -EIO; } ret = mhi_async_power_up(mhi_cntrl); /* power up create the dentry */ if (mhi_cntrl->dentry) { debugfs_create_file("m0", 0444, mhi_cntrl->dentry, mhi_cntrl, &debugfs_trigger_m0_fops); debugfs_create_file("m3", 0444, mhi_cntrl->dentry, mhi_cntrl, &debugfs_trigger_m3_fops); } return ret; } static int mhi_runtime_get(struct mhi_controller *mhi_cntrl, void *priv) { struct mhi_dev *mhi_dev = priv; Loading Loading @@ -387,36 +455,6 @@ static u64 mhi_time_get(struct mhi_controller *mhi_cntrl, void *priv) return arch_counter_get_cntvct(); } int mhi_debugfs_trigger_m0(void *data, u64 val) { struct mhi_controller *mhi_cntrl = data; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); MHI_LOG("Trigger M3 Exit\n"); pm_runtime_get(&mhi_dev->pci_dev->dev); pm_runtime_put(&mhi_dev->pci_dev->dev); return 0; } int mhi_debugfs_trigger_m3(void *data, u64 val) { struct mhi_controller *mhi_cntrl = data; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); MHI_LOG("Trigger M3 Entry\n"); pm_runtime_mark_last_busy(&mhi_dev->pci_dev->dev); pm_request_autosuspend(&mhi_dev->pci_dev->dev); return 0; } DEFINE_DEBUGFS_ATTRIBUTE(debugfs_trigger_m0_fops, NULL, mhi_debugfs_trigger_m0, "%llu\n"); DEFINE_DEBUGFS_ATTRIBUTE(debugfs_trigger_m3_fops, NULL, mhi_debugfs_trigger_m3, "%llu\n"); static ssize_t timeout_ms_show(struct device *dev, struct device_attribute *attr, char *buf) Loading Loading @@ -455,7 +493,7 @@ static ssize_t power_up_store(struct device *dev, struct mhi_device *mhi_dev = to_mhi_device(dev); struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; ret = mhi_async_power_up(mhi_cntrl); ret = mhi_qcom_power_up(mhi_cntrl); if (ret) return ret; Loading Loading @@ -612,7 +650,7 @@ int mhi_pci_probe(struct pci_dev *pci_dev, /* start power up sequence */ if (!debug_mode) { ret = mhi_async_power_up(mhi_cntrl); ret = mhi_qcom_power_up(mhi_cntrl); if (ret) goto error_power_up; } Loading @@ -620,13 +658,6 @@ int mhi_pci_probe(struct pci_dev *pci_dev, pm_runtime_mark_last_busy(&pci_dev->dev); pm_runtime_allow(&pci_dev->dev); if (mhi_cntrl->dentry) { debugfs_create_file_unsafe("m0", 0444, mhi_cntrl->dentry, mhi_cntrl, &debugfs_trigger_m0_fops); debugfs_create_file_unsafe("m3", 0444, mhi_cntrl->dentry, mhi_cntrl, &debugfs_trigger_m3_fops); } MHI_LOG("Return successful\n"); return 0; Loading drivers/bus/mhi/core/mhi_internal.h +0 −3 Original line number Diff line number Diff line Loading @@ -651,7 +651,6 @@ const char *to_mhi_pm_state_str(enum MHI_PM_STATE state); void mhi_reset_chan(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan); enum mhi_ee mhi_get_exec_env(struct mhi_controller *mhi_cntrl); enum mhi_dev_state mhi_get_m_state(struct mhi_controller *mhi_cntrl); int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, enum MHI_ST_TRANSITION state); void mhi_pm_st_worker(struct work_struct *work); Loading Loading @@ -707,8 +706,6 @@ void mhi_write_db(struct mhi_controller *mhi_cntrl, void __iomem *db_addr, void mhi_ring_cmd_db(struct mhi_controller *mhi_cntrl, struct mhi_cmd *mhi_cmd); void mhi_ring_chan_db(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan); void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, enum mhi_dev_state state); int mhi_get_capability_offset(struct mhi_controller *mhi_cntrl, u32 capability, u32 *offset); int mhi_init_timesync(struct mhi_controller *mhi_cntrl); Loading drivers/bus/mhi/core/mhi_main.c +3 −3 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ enum mhi_ee mhi_get_exec_env(struct mhi_controller *mhi_cntrl) return (ret) ? MHI_EE_MAX : exec; } enum mhi_dev_state mhi_get_m_state(struct mhi_controller *mhi_cntrl) enum mhi_dev_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl) { u32 state; int ret = mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS, Loading Loading @@ -1232,7 +1232,7 @@ void mhi_ctrl_ev_task(unsigned long data) if (!ret) { write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) state = mhi_get_m_state(mhi_cntrl); state = mhi_get_mhi_state(mhi_cntrl); if (state == MHI_STATE_SYS_ERR) { MHI_ERR("MHI system error detected\n"); pm_state = mhi_tryset_pm_state(mhi_cntrl, Loading Loading @@ -1281,7 +1281,7 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) state = mhi_get_m_state(mhi_cntrl); state = mhi_get_mhi_state(mhi_cntrl); if (state == MHI_STATE_SYS_ERR) { MHI_ERR("MHI system error detected\n"); pm_state = mhi_tryset_pm_state(mhi_cntrl, Loading include/linux/mhi.h +14 −0 Original line number Diff line number Diff line Loading @@ -605,6 +605,20 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev, u64 *t_host, u64 *t_dev); /** * mhi_get_mhi_state - Return MHI state of device * @mhi_cntrl: MHI controller */ enum mhi_dev_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl); /** * mhi_set_mhi_state - Set device state * @mhi_cntrl: MHI controller * @state: state to set */ void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, enum mhi_dev_state state); #ifndef CONFIG_ARCH_QCOM #ifdef CONFIG_MHI_DEBUG Loading Loading
drivers/bus/mhi/controllers/mhi_qcom.c +70 −39 Original line number Diff line number Diff line Loading @@ -3,6 +3,7 @@ #include <asm/arch_timer.h> #include <linux/debugfs.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/dma-direction.h> #include <linux/list.h> Loading Loading @@ -33,6 +34,34 @@ static const struct firmware_info firmware_table[] = { static int debug_mode; module_param_named(debug_mode, debug_mode, int, 0644); int mhi_debugfs_trigger_m0(void *data, u64 val) { struct mhi_controller *mhi_cntrl = data; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); MHI_LOG("Trigger M3 Exit\n"); pm_runtime_get(&mhi_dev->pci_dev->dev); pm_runtime_put(&mhi_dev->pci_dev->dev); return 0; } DEFINE_SIMPLE_ATTRIBUTE(debugfs_trigger_m0_fops, NULL, mhi_debugfs_trigger_m0, "%llu\n"); int mhi_debugfs_trigger_m3(void *data, u64 val) { struct mhi_controller *mhi_cntrl = data; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); MHI_LOG("Trigger M3 Entry\n"); pm_runtime_mark_last_busy(&mhi_dev->pci_dev->dev); pm_request_autosuspend(&mhi_dev->pci_dev->dev); return 0; } DEFINE_SIMPLE_ATTRIBUTE(debugfs_trigger_m3_fops, NULL, mhi_debugfs_trigger_m3, "%llu\n"); void mhi_deinit_pci_dev(struct mhi_controller *mhi_cntrl) { struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); Loading Loading @@ -351,6 +380,45 @@ static int mhi_lpm_enable(struct mhi_controller *mhi_cntrl, void *priv) return ret; } static int mhi_qcom_power_up(struct mhi_controller *mhi_cntrl) { enum mhi_dev_state dev_state = mhi_get_mhi_state(mhi_cntrl); const u32 delayus = 10; int itr = DIV_ROUND_UP(mhi_cntrl->timeout_ms * 1000, delayus); int ret; /* * It's possible device did not go thru a cold reset before * power up and still in error state. If device in error state, * we need to trigger a soft reset before continue with power * up */ if (dev_state == MHI_STATE_SYS_ERR) { mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); while (itr--) { dev_state = mhi_get_mhi_state(mhi_cntrl); if (dev_state != MHI_STATE_SYS_ERR) break; usleep_range(delayus, delayus << 1); } /* device still in error state, abort power up */ if (dev_state == MHI_STATE_SYS_ERR) return -EIO; } ret = mhi_async_power_up(mhi_cntrl); /* power up create the dentry */ if (mhi_cntrl->dentry) { debugfs_create_file("m0", 0444, mhi_cntrl->dentry, mhi_cntrl, &debugfs_trigger_m0_fops); debugfs_create_file("m3", 0444, mhi_cntrl->dentry, mhi_cntrl, &debugfs_trigger_m3_fops); } return ret; } static int mhi_runtime_get(struct mhi_controller *mhi_cntrl, void *priv) { struct mhi_dev *mhi_dev = priv; Loading Loading @@ -387,36 +455,6 @@ static u64 mhi_time_get(struct mhi_controller *mhi_cntrl, void *priv) return arch_counter_get_cntvct(); } int mhi_debugfs_trigger_m0(void *data, u64 val) { struct mhi_controller *mhi_cntrl = data; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); MHI_LOG("Trigger M3 Exit\n"); pm_runtime_get(&mhi_dev->pci_dev->dev); pm_runtime_put(&mhi_dev->pci_dev->dev); return 0; } int mhi_debugfs_trigger_m3(void *data, u64 val) { struct mhi_controller *mhi_cntrl = data; struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl); MHI_LOG("Trigger M3 Entry\n"); pm_runtime_mark_last_busy(&mhi_dev->pci_dev->dev); pm_request_autosuspend(&mhi_dev->pci_dev->dev); return 0; } DEFINE_DEBUGFS_ATTRIBUTE(debugfs_trigger_m0_fops, NULL, mhi_debugfs_trigger_m0, "%llu\n"); DEFINE_DEBUGFS_ATTRIBUTE(debugfs_trigger_m3_fops, NULL, mhi_debugfs_trigger_m3, "%llu\n"); static ssize_t timeout_ms_show(struct device *dev, struct device_attribute *attr, char *buf) Loading Loading @@ -455,7 +493,7 @@ static ssize_t power_up_store(struct device *dev, struct mhi_device *mhi_dev = to_mhi_device(dev); struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; ret = mhi_async_power_up(mhi_cntrl); ret = mhi_qcom_power_up(mhi_cntrl); if (ret) return ret; Loading Loading @@ -612,7 +650,7 @@ int mhi_pci_probe(struct pci_dev *pci_dev, /* start power up sequence */ if (!debug_mode) { ret = mhi_async_power_up(mhi_cntrl); ret = mhi_qcom_power_up(mhi_cntrl); if (ret) goto error_power_up; } Loading @@ -620,13 +658,6 @@ int mhi_pci_probe(struct pci_dev *pci_dev, pm_runtime_mark_last_busy(&pci_dev->dev); pm_runtime_allow(&pci_dev->dev); if (mhi_cntrl->dentry) { debugfs_create_file_unsafe("m0", 0444, mhi_cntrl->dentry, mhi_cntrl, &debugfs_trigger_m0_fops); debugfs_create_file_unsafe("m3", 0444, mhi_cntrl->dentry, mhi_cntrl, &debugfs_trigger_m3_fops); } MHI_LOG("Return successful\n"); return 0; Loading
drivers/bus/mhi/core/mhi_internal.h +0 −3 Original line number Diff line number Diff line Loading @@ -651,7 +651,6 @@ const char *to_mhi_pm_state_str(enum MHI_PM_STATE state); void mhi_reset_chan(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan); enum mhi_ee mhi_get_exec_env(struct mhi_controller *mhi_cntrl); enum mhi_dev_state mhi_get_m_state(struct mhi_controller *mhi_cntrl); int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, enum MHI_ST_TRANSITION state); void mhi_pm_st_worker(struct work_struct *work); Loading Loading @@ -707,8 +706,6 @@ void mhi_write_db(struct mhi_controller *mhi_cntrl, void __iomem *db_addr, void mhi_ring_cmd_db(struct mhi_controller *mhi_cntrl, struct mhi_cmd *mhi_cmd); void mhi_ring_chan_db(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan); void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, enum mhi_dev_state state); int mhi_get_capability_offset(struct mhi_controller *mhi_cntrl, u32 capability, u32 *offset); int mhi_init_timesync(struct mhi_controller *mhi_cntrl); Loading
drivers/bus/mhi/core/mhi_main.c +3 −3 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ enum mhi_ee mhi_get_exec_env(struct mhi_controller *mhi_cntrl) return (ret) ? MHI_EE_MAX : exec; } enum mhi_dev_state mhi_get_m_state(struct mhi_controller *mhi_cntrl) enum mhi_dev_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl) { u32 state; int ret = mhi_read_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS, Loading Loading @@ -1232,7 +1232,7 @@ void mhi_ctrl_ev_task(unsigned long data) if (!ret) { write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) state = mhi_get_m_state(mhi_cntrl); state = mhi_get_mhi_state(mhi_cntrl); if (state == MHI_STATE_SYS_ERR) { MHI_ERR("MHI system error detected\n"); pm_state = mhi_tryset_pm_state(mhi_cntrl, Loading Loading @@ -1281,7 +1281,7 @@ irqreturn_t mhi_intvec_threaded_handlr(int irq_number, void *dev) write_lock_irq(&mhi_cntrl->pm_lock); if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state)) state = mhi_get_m_state(mhi_cntrl); state = mhi_get_mhi_state(mhi_cntrl); if (state == MHI_STATE_SYS_ERR) { MHI_ERR("MHI system error detected\n"); pm_state = mhi_tryset_pm_state(mhi_cntrl, Loading
include/linux/mhi.h +14 −0 Original line number Diff line number Diff line Loading @@ -605,6 +605,20 @@ int mhi_get_remote_time_sync(struct mhi_device *mhi_dev, u64 *t_host, u64 *t_dev); /** * mhi_get_mhi_state - Return MHI state of device * @mhi_cntrl: MHI controller */ enum mhi_dev_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl); /** * mhi_set_mhi_state - Set device state * @mhi_cntrl: MHI controller * @state: state to set */ void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, enum mhi_dev_state state); #ifndef CONFIG_ARCH_QCOM #ifdef CONFIG_MHI_DEBUG Loading