diff --git a/drivers/net/wireless/cnss2/debug.c b/drivers/net/wireless/cnss2/debug.c index 34b5cff14af9..4bb083bd1009 100644 --- a/drivers/net/wireless/cnss2/debug.c +++ b/drivers/net/wireless/cnss2/debug.c @@ -509,13 +509,14 @@ static ssize_t cnss_runtime_pm_debug_write(struct file *fp, } else if (sysfs_streq(cmd, "resume")) { ret = cnss_pci_pm_runtime_resume(pci_priv); } else if (sysfs_streq(cmd, "get")) { - ret = cnss_pci_pm_runtime_get(pci_priv); + ret = cnss_pci_pm_runtime_get(pci_priv, RTPM_ID_CNSS); } else if (sysfs_streq(cmd, "get_noresume")) { - cnss_pci_pm_runtime_get_noresume(pci_priv); + cnss_pci_pm_runtime_get_noresume(pci_priv, RTPM_ID_CNSS); } else if (sysfs_streq(cmd, "put_autosuspend")) { - ret = cnss_pci_pm_runtime_put_autosuspend(pci_priv); + ret = cnss_pci_pm_runtime_put_autosuspend(pci_priv, + RTPM_ID_CNSS); } else if (sysfs_streq(cmd, "put_noidle")) { - cnss_pci_pm_runtime_put_noidle(pci_priv); + cnss_pci_pm_runtime_put_noidle(pci_priv, RTPM_ID_CNSS); } else if (sysfs_streq(cmd, "mark_last_busy")) { cnss_pci_pm_runtime_mark_last_busy(pci_priv); } else if (sysfs_streq(cmd, "resume_bus")) { @@ -535,6 +536,17 @@ static ssize_t cnss_runtime_pm_debug_write(struct file *fp, static int cnss_runtime_pm_debug_show(struct seq_file *s, void *data) { + struct cnss_plat_data *plat_priv = s->private; + struct cnss_pci_data *pci_priv; + int i; + + if (!plat_priv) + return -ENODEV; + + pci_priv = plat_priv->bus_priv; + if (!pci_priv) + return -ENODEV; + seq_puts(s, "\nUsage: echo > /cnss/runtime_pm\n"); seq_puts(s, " can be one of below:\n"); seq_puts(s, "usage_count: get runtime PM usage count\n"); @@ -548,6 +560,25 @@ static int cnss_runtime_pm_debug_show(struct seq_file *s, void *data) seq_puts(s, "resume_bus: do bus resume only\n"); seq_puts(s, "suspend_bus: do bus suspend only\n"); + seq_puts(s, "\nStats:\n"); + seq_printf(s, "%s: %u\n", "get count", + atomic_read(&pci_priv->pm_stats.runtime_get)); + seq_printf(s, "%s: %u\n", "put count", + atomic_read(&pci_priv->pm_stats.runtime_put)); + seq_printf(s, "%-10s%-10s%-10s%-15s%-15s\n", + "id:", "get", "put", "get time(us)", "put time(us)"); + for (i = 0; i < RTPM_ID_MAX; i++) { + seq_printf(s, "%d%-9s", i, ":"); + seq_printf(s, "%-10d", + atomic_read(&pci_priv->pm_stats.runtime_get_id[i])); + seq_printf(s, "%-10d", + atomic_read(&pci_priv->pm_stats.runtime_put_id[i])); + seq_printf(s, "%-15llu", + pci_priv->pm_stats.runtime_get_timestamp_id[i]); + seq_printf(s, "%-15llu\n", + pci_priv->pm_stats.runtime_put_timestamp_id[i]); + } + return 0; } diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index 04804da77e80..6c98bb2089c6 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -575,7 +575,7 @@ int cnss_pci_debug_reg_read(struct cnss_pci_data *pci_priv, u32 offset, if (ret) goto out; - ret = cnss_pci_pm_runtime_get_sync(pci_priv); + ret = cnss_pci_pm_runtime_get_sync(pci_priv, RTPM_ID_CNSS); if (ret < 0) goto runtime_pm_put; @@ -595,7 +595,7 @@ force_wake_put: cnss_pci_force_wake_put(pci_priv); runtime_pm_put: cnss_pci_pm_runtime_mark_last_busy(pci_priv); - cnss_pci_pm_runtime_put_autosuspend(pci_priv); + cnss_pci_pm_runtime_put_autosuspend(pci_priv, RTPM_ID_CNSS); out: return ret; } @@ -610,7 +610,7 @@ int cnss_pci_debug_reg_write(struct cnss_pci_data *pci_priv, u32 offset, if (ret) goto out; - ret = cnss_pci_pm_runtime_get_sync(pci_priv); + ret = cnss_pci_pm_runtime_get_sync(pci_priv, RTPM_ID_CNSS); if (ret < 0) goto runtime_pm_put; @@ -630,7 +630,7 @@ force_wake_put: cnss_pci_force_wake_put(pci_priv); runtime_pm_put: cnss_pci_pm_runtime_mark_last_busy(pci_priv); - cnss_pci_pm_runtime_put_autosuspend(pci_priv); + cnss_pci_pm_runtime_put_autosuspend(pci_priv, RTPM_ID_CNSS); out: return ret; } @@ -1553,7 +1553,7 @@ static void cnss_pci_time_sync_work_hdlr(struct work_struct *work) if (cnss_pci_is_device_down(&pci_priv->pci_dev->dev)) return; - if (cnss_pci_pm_runtime_get_sync(pci_priv) < 0) + if (cnss_pci_pm_runtime_get_sync(pci_priv, RTPM_ID_CNSS) < 0) goto runtime_pm_put; cnss_pci_update_timestamp(pci_priv); @@ -1562,7 +1562,7 @@ static void cnss_pci_time_sync_work_hdlr(struct work_struct *work) runtime_pm_put: cnss_pci_pm_runtime_mark_last_busy(pci_priv); - cnss_pci_pm_runtime_put_autosuspend(pci_priv); + cnss_pci_pm_runtime_put_autosuspend(pci_priv, RTPM_ID_CNSS); } static int cnss_pci_start_time_sync_update(struct cnss_pci_data *pci_priv) @@ -2877,6 +2877,30 @@ int cnss_wlan_pm_control(struct device *dev, bool vote) } EXPORT_SYMBOL(cnss_wlan_pm_control); +static void cnss_pci_pm_runtime_get_record(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id) +{ + if (id >= RTPM_ID_MAX) + return; + + atomic_inc(&pci_priv->pm_stats.runtime_get); + atomic_inc(&pci_priv->pm_stats.runtime_get_id[id]); + pci_priv->pm_stats.runtime_get_timestamp_id[id] = + cnss_get_host_timestamp(pci_priv->plat_priv); +} + +static void cnss_pci_pm_runtime_put_record(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id) +{ + if (id >= RTPM_ID_MAX) + return; + + atomic_inc(&pci_priv->pm_stats.runtime_put); + atomic_inc(&pci_priv->pm_stats.runtime_put_id[id]); + pci_priv->pm_stats.runtime_put_timestamp_id[id] = + cnss_get_host_timestamp(pci_priv->plat_priv); +} + void cnss_pci_pm_runtime_show_usage_count(struct cnss_pci_data *pci_priv) { struct device *dev; @@ -2926,7 +2950,8 @@ int cnss_pci_pm_runtime_resume(struct cnss_pci_data *pci_priv) return pm_runtime_resume(dev); } -int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv) +int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id) { struct device *dev; enum rpm_status status; @@ -2941,10 +2966,13 @@ int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv) cnss_pr_vdbg("Runtime PM resume is requested by %ps\n", (void *)_RET_IP_); + cnss_pci_pm_runtime_get_record(pci_priv, id); + return pm_runtime_get(dev); } -int cnss_pci_pm_runtime_get_sync(struct cnss_pci_data *pci_priv) +int cnss_pci_pm_runtime_get_sync(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id) { struct device *dev; enum rpm_status status; @@ -2959,18 +2987,23 @@ int cnss_pci_pm_runtime_get_sync(struct cnss_pci_data *pci_priv) cnss_pr_vdbg("Runtime PM resume is requested by %ps\n", (void *)_RET_IP_); + cnss_pci_pm_runtime_get_record(pci_priv, id); + return pm_runtime_get_sync(dev); } -void cnss_pci_pm_runtime_get_noresume(struct cnss_pci_data *pci_priv) +void cnss_pci_pm_runtime_get_noresume(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id) { if (!pci_priv) return; + cnss_pci_pm_runtime_get_record(pci_priv, id); pm_runtime_get_noresume(&pci_priv->pci_dev->dev); } -int cnss_pci_pm_runtime_put_autosuspend(struct cnss_pci_data *pci_priv) +int cnss_pci_pm_runtime_put_autosuspend(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id) { struct device *dev; @@ -2984,10 +3017,13 @@ int cnss_pci_pm_runtime_put_autosuspend(struct cnss_pci_data *pci_priv) return -EINVAL; } + cnss_pci_pm_runtime_put_record(pci_priv, id); + return pm_runtime_put_autosuspend(&pci_priv->pci_dev->dev); } -void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv) +void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id) { struct device *dev; @@ -3001,6 +3037,7 @@ void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv) return; } + cnss_pci_pm_runtime_put_record(pci_priv, id); pm_runtime_put_noidle(&pci_priv->pci_dev->dev); } @@ -4342,7 +4379,7 @@ static int cnss_mhi_pm_runtime_get(struct mhi_controller *mhi_ctrl, void *priv) { struct cnss_pci_data *pci_priv = priv; - return cnss_pci_pm_runtime_get(pci_priv); + return cnss_pci_pm_runtime_get(pci_priv, RTPM_ID_MHI); } static void cnss_mhi_pm_runtime_put_noidle(struct mhi_controller *mhi_ctrl, @@ -4350,7 +4387,7 @@ static void cnss_mhi_pm_runtime_put_noidle(struct mhi_controller *mhi_ctrl, { struct cnss_pci_data *pci_priv = priv; - cnss_pci_pm_runtime_put_noidle(pci_priv); + cnss_pci_pm_runtime_put_noidle(pci_priv, RTPM_ID_MHI); } void cnss_pci_add_fw_prefix_name(struct cnss_pci_data *pci_priv, diff --git a/drivers/net/wireless/cnss2/pci.h b/drivers/net/wireless/cnss2/pci.h index ae0beda5eeb1..d417a81e6152 100644 --- a/drivers/net/wireless/cnss2/pci.h +++ b/drivers/net/wireless/cnss2/pci.h @@ -31,6 +31,12 @@ enum pci_link_status { PCI_DEF, }; +enum cnss_rtpm_id { + RTPM_ID_CNSS, + RTPM_ID_MHI, + RTPM_ID_MAX, +}; + struct cnss_msi_user { char *name; int num_vectors; @@ -59,6 +65,15 @@ struct cnss_misc_reg { u32 val; }; +struct cnss_pm_stats { + atomic_t runtime_get; + atomic_t runtime_put; + atomic_t runtime_get_id[RTPM_ID_MAX]; + atomic_t runtime_put_id[RTPM_ID_MAX]; + u64 runtime_get_timestamp_id[RTPM_ID_MAX]; + u64 runtime_put_timestamp_id[RTPM_ID_MAX]; +}; + struct cnss_pci_data { struct pci_dev *pci_dev; struct cnss_plat_data *plat_priv; @@ -71,6 +86,7 @@ struct cnss_pci_data { struct pci_saved_state *saved_state; struct pci_saved_state *default_state; struct msm_pcie_register_event msm_pci_event; + struct cnss_pm_stats pm_stats; atomic_t auto_suspended; atomic_t drv_connected; u8 drv_connected_last; @@ -198,11 +214,16 @@ int cnss_pci_call_driver_modem_status(struct cnss_pci_data *pci_priv, void cnss_pci_pm_runtime_show_usage_count(struct cnss_pci_data *pci_priv); int cnss_pci_pm_request_resume(struct cnss_pci_data *pci_priv); int cnss_pci_pm_runtime_resume(struct cnss_pci_data *pci_priv); -int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv); -int cnss_pci_pm_runtime_get_sync(struct cnss_pci_data *pci_priv); -void cnss_pci_pm_runtime_get_noresume(struct cnss_pci_data *pci_priv); -int cnss_pci_pm_runtime_put_autosuspend(struct cnss_pci_data *pci_priv); -void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv); +int cnss_pci_pm_runtime_get(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id); +int cnss_pci_pm_runtime_get_sync(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id); +void cnss_pci_pm_runtime_get_noresume(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id); +int cnss_pci_pm_runtime_put_autosuspend(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id); +void cnss_pci_pm_runtime_put_noidle(struct cnss_pci_data *pci_priv, + enum cnss_rtpm_id id); void cnss_pci_pm_runtime_mark_last_busy(struct cnss_pci_data *pci_priv); int cnss_pci_update_status(struct cnss_pci_data *pci_priv, enum cnss_driver_status status);